You are here

class FormOverrides in Configuration Override Warn 8

Contains logic for inspecting config forms and their overridden values.

Hierarchy

Expanded class hierarchy of FormOverrides

1 string reference to 'FormOverrides'
config_override_warn.services.yml in ./config_override_warn.services.yml
config_override_warn.services.yml
1 service uses FormOverrides
config_override_warn.form_overrides in ./config_override_warn.services.yml
Drupal\config_override_warn\FormOverrides

File

src/FormOverrides.php, line 17

Namespace

Drupal\config_override_warn
View source
class FormOverrides {

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The typed config manager.
   *
   * @var \Drupal\Core\Config\TypedConfigManagerInterface
   */
  protected $typedConfigManager;

  /**
   * Constructs the FormOverrides service.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
   *   The typed config manager.
   */
  public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager) {
    $this->configFactory = $config_factory;
    $this->typedConfigManager = $typed_config_manager;
  }

  /**
   * Get overrides for a form.
   *
   * @param \Drupal\Core\Form\FormInterface $form
   *   The form object.
   *
   * @return array
   *   A nested array of overridden config values, keyed by config name,
   *   and subkeyed by config value name.
   *   The subvalue is an array with 'original' and 'override' values of the
   *   respective config property.
   */
  public function getFormOverrides(FormInterface $form) {
    $names = $this
      ->getFormConfigNames($form);
    $overrides = [];
    foreach ($names as $name) {
      $overrides = NestedArray::mergeDeep($overrides, $this
        ->getConfigOverrideDiffs($name));
    }
    return $overrides;
  }

  /**
   * Get the config names that correspond with a form.
   *
   * @param \Drupal\Core\Form\FormInterface $form
   *   The form object.
   *
   * @return array
   *   An array of config names.
   */
  public function getFormConfigNames(FormInterface $form) {
    $names = [];
    if ($form instanceof EntityForm) {
      $entity = $form
        ->getEntity();
      if ($entity instanceof ConfigEntityInterface && !$entity
        ->isNew()) {
        $names = [
          $entity
            ->getConfigDependencyName(),
        ];
      }
    }
    elseif (method_exists($form, 'getEditableConfigNames')) {

      // Grr... this is a protected method ConfigFormBaseTrait.
      // @see https://www.drupal.org/project/drupal/issues/2095289
      $method = new \ReflectionMethod($form, 'getEditableConfigNames');
      $method
        ->setAccessible(TRUE);
      $names = $method
        ->invoke($form);
    }
    return $names;
  }

  /**
   * Get overrides for a config.
   *
   * @param string $name
   *   The name of the configuration object.
   *
   * @return array
   *   A nested array of overridden config values, keyed by config value name.
   *   The value is an array with 'original' and 'override' values of the
   *   respective config property.
   */
  public function getConfigOverrideDiffs($name) {
    $overrides = [];
    $config = $this->configFactory
      ->get($name);
    if ($config_overrides = $this
      ->getConfigOverrides($config)) {
      $definition = $this->typedConfigManager
        ->getDefinition($name);
      $keys = $this
        ->getConfigKeys($config_overrides, $definition);
      foreach ($keys as $key) {
        $original_value = $config
          ->getOriginal($key, FALSE);
        $override_value = $config
          ->get($key);

        // If both values are an array, run a diff on them to
        // reduce same values.
        // @todo Remove when https://www.drupal.org/project/config_override_warn/issues/2979946 is fixed.
        if (is_array($original_value) && is_array($override_value)) {
          $original_original_value = $original_value;
          $original_value = DiffArray::diffAssocRecursive($original_value, $override_value);
          $override_value = DiffArray::diffAssocRecursive($override_value, $original_original_value);
        }

        // Ignore identical overrides.
        if ($original_value === $override_value) {
          continue;
        }
        if ($this->configFactory
          ->get('config_override_warn.settings')
          ->get('show_values')) {
          $overrides[$name][$key] = [
            'original' => var_export($original_value, TRUE),
            'override' => var_export($override_value, TRUE),
          ];
        }
        else {
          $overrides[$name][$key] = NULL;
        }
      }
    }
    return $overrides;
  }

  /**
   * Get all overridden values from a config object.
   *
   * @param \Drupal\Core\Config\Config $config
   *   The config object.
   *
   * @return array
   *   A nested array of the overridden values on the config.
   */
  public function getConfigOverrides(Config $config) {
    $overrides = [];
    if ($config
      ->hasOverrides()) {
      $properties = [
        'moduleOverrides',
        'settingsOverrides',
      ];
      foreach ($properties as $property) {
        $reflection = new \ReflectionProperty($config, $property);
        $reflection
          ->setAccessible(TRUE);
        $property_overrides = $reflection
          ->getValue($config);
        if (isset($property_overrides) && is_array($property_overrides)) {
          $overrides = NestedArray::mergeDeepArray([
            $overrides,
            $property_overrides,
          ], TRUE);
        }
      }
    }
    return $overrides;
  }

  /**
   * Get all possible keys from a config object.
   *
   * @param array $values
   *   The root values from the config object.
   * @param array $definition
   *   The config definition for $values.
   * @param string $prefix
   *   Used for recursion of sub-keys.
   *
   * @return array
   *   An array of config keys.
   */
  protected function getConfigKeys(array $values, array $definition, $prefix = NULL) {
    $keys = [];
    foreach ($values as $key => $value) {
      if (is_array($value) && isset($definition['mapping'])) {
        $value_definition = NestedArray::getValue($definition['mapping'], explode('.', $key));
        if (isset($value_definition['type']) && $value_definition['type'] === 'mapping') {
          $keys = array_merge($keys, $this
            ->getConfigKeys($value, $value_definition, $prefix . $key . '.'));
          continue;
        }
      }
      $keys[] = $prefix . $key;
    }
    return $keys;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FormOverrides::$configFactory protected property The config factory.
FormOverrides::$typedConfigManager protected property The typed config manager.
FormOverrides::getConfigKeys protected function Get all possible keys from a config object.
FormOverrides::getConfigOverrideDiffs public function Get overrides for a config.
FormOverrides::getConfigOverrides public function Get all overridden values from a config object.
FormOverrides::getFormConfigNames public function Get the config names that correspond with a form.
FormOverrides::getFormOverrides public function Get overrides for a form.
FormOverrides::__construct public function Constructs the FormOverrides service.