function ConfigSync::buildForm

Same name and namespace in other branches
  1. 9 core/modules/config/src/Form/ConfigSync.php \Drupal\config\Form\ConfigSync::buildForm()
  2. 8.9.x core/modules/config/src/Form/ConfigSync.php \Drupal\config\Form\ConfigSync::buildForm()
  3. 11.x core/modules/config/src/Form/ConfigSync.php \Drupal\config\Form\ConfigSync::buildForm()

Overrides FormInterface::buildForm

File

core/modules/config/src/Form/ConfigSync.php, line 217

Class

ConfigSync
Construct the storage changes in a configuration synchronization form.

Namespace

Drupal\config\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
    $form['actions'] = [
        '#type' => 'actions',
    ];
    $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this->t('Import all'),
    ];
    $syncStorage = $this->importTransformer
        ->transform($this->syncStorage);
    $source_list = $syncStorage->listAll();
    $storage_comparer = new StorageComparer($syncStorage, $this->activeStorage);
    $storage_comparer->createChangelist();
    if (empty($source_list) || !$storage_comparer->hasChanges()) {
        $form['no_changes'] = [
            '#type' => 'table',
            '#header' => [
                $this->t('Name'),
                $this->t('Operations'),
            ],
            '#rows' => [],
            '#empty' => empty($source_list) ? $this->t('There is no staged configuration.') : $this->t('The staged configuration is identical to the active configuration.'),
        ];
        $form['actions']['#access'] = FALSE;
        return $form;
    }
    elseif (!$storage_comparer->validateSiteUuid()) {
        $this->messenger()
            ->addError($this->t('The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site.'));
        $form['actions']['#access'] = FALSE;
        return $form;
    }
    // A list of changes will be displayed, so check if the user should be
    // warned of potential losses to configuration.
    if ($this->snapshotStorage
        ->exists('core.extension')) {
        $snapshot_comparer = new StorageComparer($this->activeStorage, $this->snapshotStorage);
        $snapshot_comparer->createChangelist();
        if (!$form_state->getUserInput() && $snapshot_comparer->hasChanges()) {
            $change_list = [];
            foreach ($snapshot_comparer->getAllCollectionNames() as $collection) {
                foreach ($snapshot_comparer->getChangelist(NULL, $collection) as $config_names) {
                    if (empty($config_names)) {
                        continue;
                    }
                    foreach ($config_names as $config_name) {
                        $change_list[] = $config_name;
                    }
                }
            }
            sort($change_list);
            $message = [
                [
                    '#markup' => $this->t('The following items in your active configuration have changes since the last import that may be lost on the next import.'),
                ],
                [
                    '#theme' => 'item_list',
                    '#items' => $change_list,
                ],
            ];
            $this->messenger()
                ->addWarning($this->renderer
                ->renderInIsolation($message));
        }
    }
    // Store the comparer for use in the submit.
    $form_state->set('storage_comparer', $storage_comparer);
    // Add the AJAX library to the form for dialog support.
    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
    foreach ($storage_comparer->getAllCollectionNames() as $collection) {
        if ($collection != StorageInterface::DEFAULT_COLLECTION) {
            $form[$collection]['collection_heading'] = [
                '#type' => 'html_tag',
                '#tag' => 'h2',
                '#value' => $this->t('@collection configuration collection', [
                    '@collection' => $collection,
                ]),
            ];
        }
        foreach ($storage_comparer->getChangelist(NULL, $collection) as $config_change_type => $config_names) {
            if (empty($config_names)) {
                continue;
            }
            // @todo A table caption would be more appropriate, but does not have the
            //   visual importance of a heading.
            $form[$collection][$config_change_type]['heading'] = [
                '#type' => 'html_tag',
                '#tag' => 'h3',
            ];
            switch ($config_change_type) {
                case 'create':
                    $form[$collection][$config_change_type]['heading']['#value'] = $this->formatPlural(count($config_names), '@count new', '@count new');
                    break;
                case 'update':
                    $form[$collection][$config_change_type]['heading']['#value'] = $this->formatPlural(count($config_names), '@count changed', '@count changed');
                    break;
                case 'delete':
                    $form[$collection][$config_change_type]['heading']['#value'] = $this->formatPlural(count($config_names), '@count removed', '@count removed');
                    break;
                case 'rename':
                    $form[$collection][$config_change_type]['heading']['#value'] = $this->formatPlural(count($config_names), '@count renamed', '@count renamed');
                    break;
            }
            $form[$collection][$config_change_type]['list'] = [
                '#type' => 'table',
                '#header' => [
                    $this->t('Name'),
                    $this->t('Operations'),
                ],
            ];
            foreach ($config_names as $config_name) {
                if ($config_change_type == 'rename') {
                    $names = $storage_comparer->extractRenameNames($config_name);
                    $route_options = [
                        'source_name' => $names['old_name'],
                        'target_name' => $names['new_name'],
                    ];
                    $config_name = $this->t('@source_name to @target_name', [
                        '@source_name' => $names['old_name'],
                        '@target_name' => $names['new_name'],
                    ]);
                }
                else {
                    $route_options = [
                        'source_name' => $config_name,
                    ];
                }
                if ($collection != StorageInterface::DEFAULT_COLLECTION) {
                    $route_name = 'config.diff_collection';
                    $route_options['collection'] = $collection;
                }
                else {
                    $route_name = 'config.diff';
                }
                $links['view_diff'] = [
                    'title' => $this->t('View differences'),
                    'url' => Url::fromRoute($route_name, $route_options),
                    'attributes' => [
                        'class' => [
                            'use-ajax',
                        ],
                        'data-dialog-type' => 'modal',
                        'data-dialog-options' => json_encode([
                            'width' => 700,
                        ]),
                    ],
                ];
                $form[$collection][$config_change_type]['list']['#rows'][] = [
                    'name' => $config_name,
                    'operations' => [
                        'data' => [
                            '#type' => 'operations',
                            '#links' => $links,
                        ],
                    ],
                ];
            }
        }
    }
    return $form;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.