1

I defined an enum in a custom module:

namespace Drupal\my_module\Enum;

enum BuildType: string {
  case Apple = 'apple_build';
  case Orange = 'orange_build';
}

And I want to use it in settings.php to change the config directory of the site:

settings.php:

$build_type = BuildType::from(getenv('build_type'));

$settings['config_sync_directory'] = dirname(DRUPAL_ROOT) . '/config/base_' . $build_type->value;

$settings['custom_translations_directory'] = dirname(DRUPAL_ROOT) . '/translations/' . $build_type->value;

However, when I do this, I get a namespace error:

Error: Class "Drupal\my_module\Enum\BuildType" not found in /var/www/html/web/sites/default/settings.custom.php on line 14 #0 /var/www/html/web/sites/default/settings.php(32): include()

How can I correctly namespace my enum for use in settings.php?

2
  • Is your module enabled? Also please post the "use" statement you included. May 26 at 17:04
  • Since the error is about Drupal\my_module\Enum\BuildType, it must be use Drupal\my_module\Enum\BuildType;.
    – apaderno
    May 26 at 17:38

2 Answers 2

2

The settings.php file is loaded from DrupalKernel::initializeSettings(), which is called from DrupalKernel::handle() before DrupalKernel::boot().

See the code in Settings::initialize(), called by DrupalKernel::initializeSettings().

if (is_readable($app_root . '/' . $site_path . '/settings.php')) {
  require $app_root . '/' . $site_path . '/settings.php';
}

This means that when the code in settings.php is executed, the dependency injection container hasn't yet initialized, the services aren't yet available, and modules are not loaded. Classes/interfaces/traits defined from contributed/custom modules are not yet available either.

Since the settings.php file does not have access to classes/interfaces a module defines, it should load the file containing the class/interface definition directly or define the class/interface itself. Since the settings.php file is loaded with require, the code to load the class file or declaring the class should be wrapped in an if statement.

if (!class_exists('BuildType')) {
  // Load the class file or declare the class.
}
3
  • Unfortunately, when I tried defining the enum inside a file included by settings.php, I get an error when I run a command such as drush site-install minimal: Cannot declare enum BuildType, because the name is already in use in /var/www/html/web/sites/default/settings.my_module.php. Simply adding an enum definition to settings.php triggers this error. May 27 at 3:44
  • When you get that error, was the enum defined in a single place?
    – apaderno
    May 27 at 15:14
  • 1
    Anyway, since the settings.php is loaded with require, the class declaration should be put between if (!class_exists('BuildType') { and }, in the settings.php file.
    – apaderno
    May 27 at 17:58
0

Here's the final code based on apaderno's answer:

settings.php:

if (!class_exists('BuildType') {
  enum BuildType: string {
    case Apple = 'apple_build';
    case Orange = 'orange_build';
  }
}

$build_type = BuildType::from(getenv('build_type'));

$settings['config_sync_directory'] = dirname(DRUPAL_ROOT) . '/config/base_' . $build_type->value;

$settings['custom_translations_directory'] = dirname(DRUPAL_ROOT) . '/translations/' . $build_type->value;

Your Answer

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

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