/** * Overrides \Drupal\Core\Config\StorageComparer::addChangelistUpdate() to * use the comparison provided by \Drupal\config_update\ConfigDiffInterface * to determine available updates. * * \Drupal\config_update\ConfigDiffInterface::same() includes normalization * that may reduce false positives resulting from either expected differences * between provided and installed configuration (for example, the presence or * absence of a UUID value) or incidental ordering differences. * * The list of updates is sorted so that dependencies are created before * configuration entities that depend on them. For example, field storages * should be updated before fields. * * @param string $collection * The storage collection to operate on. */ protected function addChangelistUpdate($collection) { foreach (array_intersect($this->sourceNames[$collection], $this->targetNames[$collection]) as $name) { $source_data = $this->getSourceStorage($collection)->read($name); $target_data = $this->getTargetStorage($collection)->read($name); if (!$this->configDiff->same($source_data, $target_data)) { $this->addChangeList($collection, 'update', array($name)); } } }
/** * Returns a form element for the given overrides. * * @param array $package * A package array. * @param array $overrides * An array of overrides. * @param array $missing * An array of missing config. * * @return array * A form element. */ protected function diffOutput($package, $overrides, $missing = array()) { $element = array(); $config = $this->featuresManager->getConfigCollection(); $components = array_merge($missing, $overrides); $header = array( array('data' => '', 'class' => 'diff-marker'), array('data' => t('Active site config'), 'class' => 'diff-context'), array('data' => '', 'class' => 'diff-marker'), array('data' => t('Feature code config'), 'class' => 'diff-context'), ); foreach ($components as $name) { $rows[] = array(array('data' => $name, 'colspan' => 4, 'header' => TRUE)); if (!isset($config[$name])) { $details = array( '#markup' => t('Component in feature missing from active config.'), ); } else { $active = $this->featuresManager->getActiveStorage()->read($name); $extension = $this->featuresManager->getExtensionStorage()->read($name); if (empty($extension)) { $details = array( '#markup' => t('Dependency detected in active config but not exported to the feature.'), ); } else { $diff = $this->configDiff->diff($active, $extension); $details = array( '#type' => 'table', '#header' => $header, '#rows' => $this->diffFormatter->format($diff), '#attributes' => array('class' => array('diff', 'features-diff')), ); } } $element[$name] = array( 'row' => array( 'data' => array( '#type' => 'details', '#title' => SafeMarkup::checkPlain($name), '#open' => TRUE, '#description' => array( 'data' => $details, ), ), ), '#attributes' => array( 'class' => 'diff-' . $package['machine_name'], ), ); } return $element; }
/** * Generates a report about config updates. * * @param string $report_type * Type of report to generate: 'type', 'module', 'theme', or 'profile'. * @param string $value * Machine name of a configuration type, module, or theme to generate the * report for. Ignored for profile, since that uses the active profile. * * @return array * Render array for the updates report. Empty if invalid or missing * report type or value. */ protected function generateReport($report_type, $value) { // Figure out what to name the report, and incidentally, validate that // $value exists for this type of report. switch ($report_type) { case 'type': if ($value == 'system.all') { $label = $this->t('All configuration'); } elseif ($value == 'system.simple') { $label = $this->t('Simple configuration'); } else { $definition = $this->configList->getType($value); if (!$definition) { return NULL; } $label = $this->t('@name configuration', array('@name' => $definition->getLabel())); } break; case 'module': $list = $this->moduleHandler->getModuleList(); if (!isset($list[$value])) { return NULL; } $label = $this->t('@name module', array('@name' => $this->moduleHandler->getName($value))); break; case 'theme': $list = $this->themeHandler->listInfo(); if (!isset($list[$value])) { return NULL; } $label = $this->t('@name theme', array('@name' => $this->themeHandler->getName($value))); break; case 'profile': $profile = Settings::get('install_profile'); $label = $this->t('@name profile', array('@name' => $this->moduleHandler->getName($profile))); break; default: return NULL; } // List the active and extension-provided config. list($active_list, $install_list, $optional_list) = $this->configList->listConfig($report_type, $value); // Build the report. $build = array(); $build['#title'] = $this->t('Configuration updates report for @label', array('@label' => $label)); $build['report_header'] = array('#markup' => '<h3>' . $this->t('Updates report') . '</h3>'); // List items missing from site. $removed = array_diff($install_list, $active_list); $build['removed'] = array('#caption' => $this->t('Missing configuration items'), '#empty' => $this->t('None: all provided configuration items are in your active configuration.')) + $this->makeReportTable($removed, 'extension', array('import')); // List optional items that are not installed. $inactive = array_diff($optional_list, $active_list); $build['inactive'] = array('#caption' => $this->t('Inactive optional items'), '#empty' => $this->t('None: all optional configuration items are in your active configuration.')) + $this->makeReportTable($inactive, 'extension', array('import')); // List items added to site, which only makes sense in the report for a // config type. $added = array_diff($active_list, $install_list, $optional_list); if ($report_type == 'type') { $build['added'] = array('#caption' => $this->t('Added configuration items'), '#empty' => $this->t('None: all active configuration items of this type were provided by modules, themes, or install profile.')) + $this->makeReportTable($added, 'active', array('export', 'delete')); } // For differences, we need to go through the array of config in both // and see if each config item is the same or not. $both = array_diff($active_list, $added); $different = array(); foreach ($both as $name) { if (!$this->configDiff->same($this->configRevert->getFromExtension('', $name), $this->configRevert->getFromActive('', $name))) { $different[] = $name; } } $build['different'] = array('#caption' => $this->t('Changed configuration items'), '#empty' => $this->t('None: no active configuration items differ from their current provided versions.')) + $this->makeReportTable($different, 'active', array('diff', 'export', 'revert')); return $build; }