annotate core/lib/Drupal/Core/Site/Settings.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Site;
Chris@0 4
Chris@0 5 use Drupal\Component\Utility\Crypt;
Chris@0 6 use Drupal\Core\Database\Database;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * Read only settings that are initialized with the class.
Chris@0 10 *
Chris@0 11 * @ingroup utility
Chris@0 12 */
Chris@0 13 final class Settings {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Array with the settings.
Chris@0 17 *
Chris@0 18 * @var array
Chris@0 19 */
Chris@0 20 private $storage = [];
Chris@0 21
Chris@0 22 /**
Chris@0 23 * Singleton instance.
Chris@0 24 *
Chris@0 25 * @var \Drupal\Core\Site\Settings
Chris@0 26 */
Chris@0 27 private static $instance = NULL;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * Constructor.
Chris@0 31 *
Chris@0 32 * @param array $settings
Chris@0 33 * Array with the settings.
Chris@0 34 */
Chris@0 35 public function __construct(array $settings) {
Chris@0 36 $this->storage = $settings;
Chris@0 37 self::$instance = $this;
Chris@0 38 }
Chris@0 39
Chris@0 40 /**
Chris@0 41 * Returns the settings instance.
Chris@0 42 *
Chris@0 43 * A singleton is used because this class is used before the container is
Chris@0 44 * available.
Chris@0 45 *
Chris@0 46 * @return \Drupal\Core\Site\Settings
Chris@0 47 *
Chris@0 48 * @throws \BadMethodCallException
Chris@0 49 * Thrown when the settings instance has not been initialized yet.
Chris@0 50 */
Chris@0 51 public static function getInstance() {
Chris@0 52 if (self::$instance === NULL) {
Chris@0 53 throw new \BadMethodCallException('Settings::$instance is not initialized yet. Whatever you are trying to do, it might be too early for that. You could call Settings::initialize(), but it is probably better to wait until it is called in the regular way. Also check for recursions.');
Chris@0 54 }
Chris@0 55 return self::$instance;
Chris@0 56 }
Chris@0 57
Chris@0 58 /**
Chris@0 59 * Protects creating with clone.
Chris@0 60 */
Chris@0 61 private function __clone() {
Chris@0 62 }
Chris@0 63
Chris@0 64 /**
Chris@0 65 * Prevents settings from being serialized.
Chris@0 66 */
Chris@0 67 public function __sleep() {
Chris@0 68 throw new \LogicException('Settings can not be serialized. This probably means you are serializing an object that has an indirect reference to the Settings object. Adjust your code so that is not necessary.');
Chris@0 69 }
Chris@0 70
Chris@0 71 /**
Chris@0 72 * Returns a setting.
Chris@0 73 *
Chris@0 74 * Settings can be set in settings.php in the $settings array and requested
Chris@0 75 * by this function. Settings should be used over configuration for read-only,
Chris@0 76 * possibly low bootstrap configuration that is environment specific.
Chris@0 77 *
Chris@0 78 * @param string $name
Chris@0 79 * The name of the setting to return.
Chris@0 80 * @param mixed $default
Chris@0 81 * (optional) The default value to use if this setting is not set.
Chris@0 82 *
Chris@0 83 * @return mixed
Chris@0 84 * The value of the setting, the provided default if not set.
Chris@0 85 */
Chris@0 86 public static function get($name, $default = NULL) {
Chris@17 87 if ($name === 'install_profile' && isset(self::$instance->storage[$name])) {
Chris@17 88 @trigger_error('To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996', E_USER_DEPRECATED);
Chris@17 89 }
Chris@0 90 return isset(self::$instance->storage[$name]) ? self::$instance->storage[$name] : $default;
Chris@0 91 }
Chris@0 92
Chris@0 93 /**
Chris@0 94 * Returns all the settings. This is only used for testing purposes.
Chris@0 95 *
Chris@0 96 * @return array
Chris@0 97 * All the settings.
Chris@0 98 */
Chris@0 99 public static function getAll() {
Chris@0 100 return self::$instance->storage;
Chris@0 101 }
Chris@0 102
Chris@0 103 /**
Chris@0 104 * Bootstraps settings.php and the Settings singleton.
Chris@0 105 *
Chris@0 106 * @param string $app_root
Chris@0 107 * The app root.
Chris@0 108 * @param string $site_path
Chris@0 109 * The current site path.
Chris@0 110 * @param \Composer\Autoload\ClassLoader $class_loader
Chris@0 111 * The class loader that is used for this request. Passed by reference and
Chris@0 112 * exposed to the local scope of settings.php, so as to allow it to be
Chris@0 113 * decorated with Symfony's ApcClassLoader, for example.
Chris@0 114 *
Chris@0 115 * @see default.settings.php
Chris@0 116 */
Chris@0 117 public static function initialize($app_root, $site_path, &$class_loader) {
Chris@0 118 // Export these settings.php variables to the global namespace.
Chris@0 119 global $config_directories, $config;
Chris@0 120 $settings = [];
Chris@0 121 $config = [];
Chris@0 122 $databases = [];
Chris@0 123
Chris@0 124 if (is_readable($app_root . '/' . $site_path . '/settings.php')) {
Chris@0 125 require $app_root . '/' . $site_path . '/settings.php';
Chris@0 126 }
Chris@0 127
Chris@0 128 // Initialize Database.
Chris@0 129 Database::setMultipleConnectionInfo($databases);
Chris@0 130
Chris@0 131 // Initialize Settings.
Chris@0 132 new Settings($settings);
Chris@0 133 }
Chris@0 134
Chris@0 135 /**
Chris@0 136 * Gets a salt useful for hardening against SQL injection.
Chris@0 137 *
Chris@0 138 * @return string
Chris@0 139 * A salt based on information in settings.php, not in the database.
Chris@0 140 *
Chris@0 141 * @throws \RuntimeException
Chris@0 142 */
Chris@0 143 public static function getHashSalt() {
Chris@0 144 $hash_salt = self::$instance->get('hash_salt');
Chris@0 145 // This should never happen, as it breaks user logins and many other
Chris@0 146 // services. Therefore, explicitly notify the user (developer) by throwing
Chris@0 147 // an exception.
Chris@0 148 if (empty($hash_salt)) {
Chris@0 149 throw new \RuntimeException('Missing $settings[\'hash_salt\'] in settings.php.');
Chris@0 150 }
Chris@0 151
Chris@0 152 return $hash_salt;
Chris@0 153 }
Chris@0 154
Chris@0 155 /**
Chris@0 156 * Generates a prefix for APCu user cache keys.
Chris@0 157 *
Chris@0 158 * A standardized prefix is useful to allow visual inspection of an APCu user
Chris@0 159 * cache. By default, this method will produce a unique prefix per site using
Chris@0 160 * the hash salt. If the setting 'apcu_ensure_unique_prefix' is set to FALSE
Chris@0 161 * then if the caller does not provide a $site_path only the Drupal root will
Chris@14 162 * be used. This allows tests to use the same prefix ensuring that the number
Chris@14 163 * of APCu items created during a full test run is kept to a minimum.
Chris@0 164 * Additionally, if a multi site implementation does not use site specific
Chris@0 165 * module directories setting apcu_ensure_unique_prefix would allow the sites
Chris@0 166 * to share APCu cache items.
Chris@0 167 *
Chris@0 168 * @param $identifier
Chris@0 169 * An identifier for the prefix. For example, 'class_loader' or
Chris@0 170 * 'cache_backend'.
Chris@0 171 *
Chris@0 172 * @return string
Chris@0 173 * The prefix for APCu user cache keys.
Chris@14 174 *
Chris@14 175 * @see https://www.drupal.org/project/drupal/issues/2926309
Chris@0 176 */
Chris@0 177 public static function getApcuPrefix($identifier, $root, $site_path = '') {
Chris@0 178 if (static::get('apcu_ensure_unique_prefix', TRUE)) {
Chris@0 179 return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . hash_hmac('sha256', $identifier, static::get('hash_salt') . '.' . $root . '/' . $site_path);
Chris@0 180 }
Chris@0 181 return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . Crypt::hashBase64($root . '/' . $site_path);
Chris@0 182 }
Chris@0 183
Chris@0 184 }