/**
  * 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;
  }
示例#3
0
 /**
  * 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;
 }