Sobreescritura de configuración dinámica en Drupal

config
Solucionex
22
Oct 25

tl;dr: Cómo sobreescribir configuración de manera dinámica usando servicios etiquetados como "config.factory.override".

Drupal permite sobreescribir la configuración de manera estática directamente desde el archivo settings.php. Esto se puede usar para especificar el config_aplit a usar o modificar los valores de conexión al servidor de correo, por ejemplo.

Pero, ¿qué pasa si lo que se necesita sobreescribir no son simplemente valores estáticos? ¿O lo que se necesita sobreescribir depende de otro valor dinámico como pueda ser un valor de una config_page?

En estos casos, Drupal permite sobreescritura de configuración dinámica usando un servicio etiquetado como "config.factory_override", donde puede usarse php para definir qué configuracioness hay que modificar y con qué valores.

Como ejemplo, un servicio que permite sobreescribir los colores de ckeditor (del módulo "ckeditor5_plugin_pack") a partir de los valores guardados en una config_page (con un campo llamado "ckeditor_colors" donde previamente se han guardado los colores con el formato usado por el plugin de ckeditor):

# Definición del servicio (dentro de "mymodule.services.yml"). Se sobreentiende que el archivo tiene configurado el autowire.

mymodule.config_override:
    class: Drupal\mymodule\Config\ConfigOverride
    tags:
      - { name: config.factory.override }

 

<?php

declare(strict_types=1);

namespace Drupal\mymodule\Config;

use Drupal\config_pages\ConfigPagesLoaderServiceInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;

/**
 * Custom configuration overrides.
 */
final class ConfigOverride implements ConfigFactoryOverrideInterface {

  public function __construct(
    private readonly ConfigPagesLoaderServiceInterface $configPagesLoaderService,
  ) {
  }
  
  /**
   * {@inheritdoc}
   */
  public function loadOverrides($names) {
    $config_name = 'editor.editor.full_html';
    $overrides = [];
    if (!in_array($config_name, $names)) {
      return $overrides;
    }
    $config_page = $this->configPagesLoaderService->load('theme');
    if (!$config_page || !$config_page->hasField('ckeditor_colors') || !$config_page->ckeditor_colors->value) {
      return $overrides;
    }
    $overrides[$config_name] = [
      'settings' => [
        'plugins' => [
          'ckeditor5_plugin_pack_font__font_color' => [
            'colors' => $config_page->ckeditor_colors->value,
          ],
        ],
      ],
    ];
    return $overrides;
  }
  
  /**
   * {@inheritdoc}
   */
  public function getCacheSuffix() {
    return 'MymoduleConfigOverride';
  }
  
  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    return new CacheableMetadata();
  }
  
  /**
   * {@inheritdoc}
   */
  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
    return NULL;
  }
  
}

De esta manera, se puede sobreescribir cualquier configuración de manera dinámica con los valores que se necesiten.

Es importante tener en cuenta que cualquier cosa sobreescrita directamente en el archivo settings.php tiene precedencia siempre sobre lo que se sobreescriba dinámicamente en un módulo.