summaryrefslogtreecommitdiffstatshomepage
path: root/core/modules/navigation/src/Plugin/ConfigAction/AddNavigationBlock.php
blob: 4d6cce59d8d27e9648c68137a5d4d4540d8a516b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php

declare(strict_types=1);

namespace Drupal\navigation\Plugin\ConfigAction;

use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Config\Action\Attribute\ConfigAction;
use Drupal\Core\Config\Action\ConfigActionException;
use Drupal\Core\Config\Action\ConfigActionPluginInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\layout_builder\SectionComponent;
use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @internal
 *   This API is experimental.
 */
#[ConfigAction(
  id: 'addNavigationBlock',
  admin_label: new TranslatableMarkup('Add navigation block'),
)]
final class AddNavigationBlock implements ConfigActionPluginInterface, ContainerFactoryPluginInterface {

  public function __construct(
    protected readonly SectionStorageManagerInterface $sectionStorageManager,
    protected readonly UuidInterface $uuidGenerator,
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    return new static(
      $container->get(SectionStorageManagerInterface::class),
      $container->get(UuidInterface::class),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function apply(string $configName, mixed $value): void {
    if ($configName !== 'navigation.block_layout') {
      throw new ConfigActionException('addNavigationBlock can only be executed for the navigation.block_layout config.');
    }
    // Load the navigation section storage.
    $navigation_storage = $this->sectionStorageManager->load('navigation', [
      'navigation' => new Context(new ContextDefinition('string'), 'navigation'),
    ]);
    if (!$navigation_storage instanceof SectionStorageInterface) {
      throw new ConfigActionException('Unable to load Navigation Layout storage.');
    }

    $section = $navigation_storage->getSection(0);
    // Create the component from the recipe values.
    $delta = $value['delta'] ?? 0;
    // Weight is set to 0 because it is irrelevant now. It will be adjusted to
    // its final value in insertComponent() or appendComponent().
    $component = [
      'uuid' => $this->uuidGenerator->generate(),
      'region' => $section->getDefaultRegion(),
      'weight' => 0,
      'configuration' => $value['configuration'] ?? [],
      'additional' => $value['additional'] ?? [],
    ];

    // Insert the new component in Navigation.
    $new_component = SectionComponent::fromArray($component);
    try {
      $section->insertComponent($delta, $new_component);
    }
    catch (\OutOfBoundsException) {
      $section->appendComponent($new_component);
    }
    $navigation_storage->save();
  }

}