2

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.

1 Answer 1

2

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!

1
  • Thank you for sharing this! Very helpful. A suggestion would be to add use Drupal\Core\Config\StorageInterface; to your CustomConfigOverriderDisableAds class since you refer to it in the signature of createConfigObject().
    – apotek
    Commented Apr 10 at 5:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.