You are here

FarmUpdate.php in farmOS 2.x

Namespace

Drupal\farm_update

File

modules/core/update/src/FarmUpdate.php
View source
<?php

namespace Drupal\farm_update;

use Drupal\config_update\ConfigDiffer;
use Drupal\config_update\ConfigListerWithProviders;
use Drupal\config_update\ConfigReverter;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Psr\Log\LoggerInterface;

/**
 * Farm update service.
 */
class FarmUpdate implements FarmUpdateInterface {
  use StringTranslationTrait;

  /**
   * The logger.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The entity manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityManager;

  /**
   * The config differ.
   *
   * @var \Drupal\config_update\ConfigDiffer
   */
  protected $configDiff;

  /**
   * The config lister.
   *
   * @var \Drupal\config_update\ConfigListerWithProviders
   */
  protected $configList;

  /**
   * The config reverter.
   *
   * @var \Drupal\config_update\ConfigReverter
   */
  protected $configUpdate;

  /**
   * Constructs a FarmUpdate object.
   *
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity type manager.
   * @param \Drupal\config_update\ConfigDiffer $config_diff
   *   The config differ.
   * @param \Drupal\config_update\ConfigListerWithProviders $config_list
   *   The config lister.
   * @param \Drupal\config_update\ConfigReverter $config_update
   *   The config reverter.
   */
  public function __construct(LoggerInterface $logger, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_manager, ConfigDiffer $config_diff, ConfigListerWithProviders $config_list, ConfigReverter $config_update) {
    $this->logger = $logger;
    $this->moduleHandler = $module_handler;
    $this->entityManager = $entity_manager;
    $this->configDiff = $config_diff;
    $this->configList = $config_list;
    $this->configUpdate = $config_update;
  }

  /**
   * {@inheritdoc}
   */
  public function rebuild() : void {

    // Get a list of excluded config.
    $exclude_config = $this
      ->getExcludedItems();

    // Build a list of config to revert, without excluded config.
    $revert_config = array_diff($this
      ->getDifferentItems('type', 'system.all'), $exclude_config);

    // Iterate through config items and revert them.
    foreach ($revert_config as $name) {

      // Get the config type and bail if simple configuration.
      // The lister gives NULL if simple configuration.
      $type = $this->configList
        ->getTypeNameByConfigName($name);
      if ($type === NULL) {
        continue;
      }

      // Get the config short name.
      $shortname = $this
        ->getConfigShortname($type, $name);

      // Perform the operation.
      $result = $this->configUpdate
        ->revert($type, $shortname);

      // Log the result.
      if ($result) {
        $this->logger
          ->notice($this
          ->t('Reverted config: @config', [
          '@config' => $name,
        ]));
      }
      else {
        $this->logger
          ->error($this
          ->t('Failed to revert config: @config', [
          '@config' => $name,
        ]));
      }
    }
  }

  /**
   * Lists excluded config items.
   *
   * Lists config items that should be excluded from all automatic updates.
   *
   * @return array
   *   An array of config item names.
   */
  protected function getExcludedItems() {

    // Ask modules for config exclusions.
    $exclude_config = $this->moduleHandler
      ->invokeAll('farm_update_exclude_config');

    // Load farm_update.settings to get additional exclusions.
    $settings_exclude_config = \Drupal::config('farm_update.settings')
      ->get('exclude_config');
    if (!empty($settings_exclude_config)) {
      $exclude_config = array_merge($exclude_config, $settings_exclude_config);
    }

    // Always exclude this module's configuration.
    // This isn't strictly necessary because we don't provide default config
    // in config/install. But in the unlikely event that a custom module does
    // provide this config, and then it is somehow overridden by another means,
    // it would be reverted. So we exclude it here just to be extra safe.
    $exclude_config[] = 'farm_update.settings';
    return $exclude_config;
  }

  /**
   * Lists differing config items.
   *
   * Lists config items that differ from the versions provided by your
   * installed modules, themes, or install profile. See config-diff to show
   * what the differences are.
   *
   * This method is copied directly from ConfigUpdateUiCliService.
   *
   * @param string $type
   *   Run the report for: module, theme, profile, or "type" for config entity
   *   type.
   * @param string $name
   *   The machine name of the module, theme, etc. to report on. See
   *   config-list-types to list types for config entities; you can also use
   *   system.all for all types, or system.simple for simple config.
   *
   * @return array
   *   An array of differing configuration items.
   *
   * @see \Drupal\config_update_ui\ConfigUpdateUiCliService::getDifferentItems()
   */
  protected function getDifferentItems($type, $name) {
    [
      $activeList,
      $installList,
      $optionalList,
    ] = $this->configList
      ->listConfig($type, $name);
    $addedItems = array_diff($activeList, $installList, $optionalList);
    $activeAndAddedItems = array_diff($activeList, $addedItems);
    $differentItems = [];
    foreach ($activeAndAddedItems as $name) {
      $active = $this->configUpdate
        ->getFromActive('', $name);
      $extension = $this->configUpdate
        ->getFromExtension('', $name);
      if (!$this->configDiff
        ->same($active, $extension)) {
        $differentItems[] = $name;
      }
    }
    sort($differentItems);
    return $differentItems;
  }

  /**
   * Gets the config item shortname given the type and name.
   *
   * This method is copied directly from ConfigUpdateUiCliService.
   *
   * @param string $type
   *   The type of the config item.
   * @param string $name
   *   The name of the config item.
   *
   * @return string
   *   The shortname for the configuration item.
   *
   * @see \Drupal\config_update_ui\ConfigUpdateUiCliService::getConfigShortname()
   */
  protected function getConfigShortname($type, $name) {
    $shortname = $name;
    if ($type != 'system.simple') {
      $definition = $this->entityManager
        ->getDefinition($type);
      $prefix = $definition
        ->getConfigPrefix() . '.';
      if (strpos($name, $prefix) === 0) {
        $shortname = substr($name, strlen($prefix));
      }
    }
    return $shortname;
  }

}

Classes

Namesort descending Description
FarmUpdate Farm update service.