Score:2

How to temporarily override configuration?

br flag

I want to be able to contextually modify configuration variables, i.e. within a page controller.

Example

I have a custom ad module which besides other settings has an option to globally disable or enable ads. In general the ads are enabled (\Drupal::configFactory()->get('custom_ads.settings')->get('active') === true).

On some pages (provided by custom page controller) I want to disable ads. Therefore I was thinking that the easiest way without modifying the custom ad module would be to set custom_ads.settings.active to false for that specific pages.

I will provide my working solution as answer to this question and would like to have some review comments, especially regarding caching, to be sure to not miss anything that may result in poor performance or worse in disabling ads in general.

Score:0
br flag

Answering my question and looking forward to review: I just had to implement a new class that implements ConfigFactoryOverrideInterface, following the d.o. documentation on Configuration override system > Providing overrides from modules:

namespace Drupal\custom\Config;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;

class CustomConfigOverriderDisableAds implements ConfigFactoryOverrideInterface {

  /**
   * {@inheritdoc}
   */
  public function loadOverrides($names) {
    $overrides = [];
    if (in_array('custom_ads.settings', $names)) {
      // Disables ads from custom_ads module.
      $overrides['custom_ads.settings'] = ['active' => false];
    }
    return $overrides;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheSuffix() {
    return 'CustomConfigOverriderDisableAds';
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    return new CacheableMetadata();
  }

  /**
   * {@inheritdoc}
   */
  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
    return NULL;
  }
}

In my custom controller I just had to conditionally add the override:

namespace Drupal\custom\Controller;

use Drupal\custom\Config\CustomConfigOverriderDisableAds;
use Drupal\Core\Controller\ControllerBase;

class CustomPathController extends ControllerBase {

  /**
   * Display custom page.
   */
  public function content() {
    // Add the config override to disable ads for this route.
    \Drupal::configFactory()->addOverride(new CustomConfigOverriderDisableAds());
    return [
      '#type' => 'inline_template',
      '#template' => 'Custom content',
    ];
  }

}

Do not add the custom overrider to custom.services.yml, otherwise it will always get called!

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.