/** * 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)); } } }
/** * 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; }