Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 20 |
CRAP | |
6.52% |
6 / 92 |
| ConfigFactory | |
0.00% |
0 / 1 |
|
4.76% |
1 / 21 |
2010.21 | |
6.52% |
6 / 92 |
| __construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
| getEditable | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| get | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| doGet | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 12 |
|||
| loadMultiple | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| doLoadMultiple | |
0.00% |
0 / 1 |
110 | |
0.00% |
0 / 23 |
|||
| loadOverrides | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 4 |
|||
| propagateConfigOverrideCacheability | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| reset | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 7 |
|||
| rename | |
0.00% |
0 / 1 |
2.01 | |
85.71% |
6 / 7 |
|||
| getCacheKeys | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 4 |
|||
| getConfigCacheKey | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 4 |
|||
| getConfigCacheKeys | |
100.00% |
1 / 1 |
2 | |
100.00% |
0 / 0 |
|||
| anonymous function | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 1 |
|||
| clearStaticCache | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| listAll | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| onConfigSave | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 6 |
|||
| onConfigDelete | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| getSubscribedEvents | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
| addOverride | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| createConfigObject | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Core\Config\ConfigFactory. | |
| */ | |
| namespace Drupal\Core\Config; | |
| use Drupal\Component\Utility\NestedArray; | |
| use Drupal\Core\Cache\Cache; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
| /** | |
| * Defines the configuration object factory. | |
| * | |
| * The configuration object factory instantiates a Config object for each | |
| * configuration object name that is accessed and returns it to callers. | |
| * | |
| * @see \Drupal\Core\Config\Config | |
| * | |
| * Each configuration object gets a storage object injected, which | |
| * is used for reading and writing the configuration data. | |
| * | |
| * @see \Drupal\Core\Config\StorageInterface | |
| * | |
| * @ingroup config_api | |
| */ | |
| class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface { | |
| /** | |
| * A storage instance for reading and writing configuration data. | |
| * | |
| * @var \Drupal\Core\Config\StorageInterface | |
| */ | |
| protected $storage; | |
| /** | |
| * An event dispatcher instance to use for configuration events. | |
| * | |
| * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface | |
| */ | |
| protected $eventDispatcher; | |
| /** | |
| * Cached configuration objects. | |
| * | |
| * @var \Drupal\Core\Config\Config[] | |
| */ | |
| protected $cache = array(); | |
| /** | |
| * The typed config manager. | |
| * | |
| * @var \Drupal\Core\Config\TypedConfigManagerInterface | |
| */ | |
| protected $typedConfigManager; | |
| /** | |
| * An array of config factory override objects ordered by priority. | |
| * | |
| * @var \Drupal\Core\Config\ConfigFactoryOverrideInterface[] | |
| */ | |
| protected $configFactoryOverrides = array(); | |
| /** | |
| * Constructs the Config factory. | |
| * | |
| * @param \Drupal\Core\Config\StorageInterface $storage | |
| * The configuration storage engine. | |
| * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher | |
| * An event dispatcher instance to use for configuration events. | |
| * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config | |
| * The typed configuration manager. | |
| */ | |
| public function __construct(StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) { | |
| $this->storage = $storage; | |
| $this->eventDispatcher = $event_dispatcher; | |
| $this->typedConfigManager = $typed_config; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getEditable($name) { | |
| return $this->doGet($name, FALSE); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function get($name) { | |
| return $this->doGet($name); | |
| } | |
| /** | |
| * Returns a configuration object for a given name. | |
| * | |
| * @param string $name | |
| * The name of the configuration object to construct. | |
| * @param bool $immutable | |
| * (optional) Create an immutable configuration object. Defaults to TRUE. | |
| * | |
| * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig | |
| * A configuration object. | |
| */ | |
| protected function doGet($name, $immutable = TRUE) { | |
| if ($config = $this->doLoadMultiple(array($name), $immutable)) { | |
| return $config[$name]; | |
| } | |
| else { | |
| // If the configuration object does not exist in the configuration | |
| // storage, create a new object. | |
| $config = $this->createConfigObject($name, $immutable); | |
| if ($immutable) { | |
| // Get and apply any overrides. | |
| $overrides = $this->loadOverrides(array($name)); | |
| if (isset($overrides[$name])) { | |
| $config->setModuleOverride($overrides[$name]); | |
| } | |
| // Apply any settings.php overrides. | |
| if (isset($GLOBALS['config'][$name])) { | |
| $config->setSettingsOverride($GLOBALS['config'][$name]); | |
| } | |
| } | |
| foreach ($this->configFactoryOverrides as $override) { | |
| $config->addCacheableDependency($override->getCacheableMetadata($name)); | |
| } | |
| return $config; | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function loadMultiple(array $names) { | |
| return $this->doLoadMultiple($names); | |
| } | |
| /** | |
| * Returns a list of configuration objects for the given names. | |
| * | |
| * @param array $names | |
| * List of names of configuration objects. | |
| * @param bool $immutable | |
| * (optional) Create an immutable configuration objects. Defaults to TRUE. | |
| * | |
| * @return \Drupal\Core\Config\Config[]|\Drupal\Core\Config\ImmutableConfig[] | |
| * List of successfully loaded configuration objects, keyed by name. | |
| */ | |
| protected function doLoadMultiple(array $names, $immutable = TRUE) { | |
| $list = array(); | |
| foreach ($names as $key => $name) { | |
| $cache_key = $this->getConfigCacheKey($name, $immutable); | |
| if (isset($this->cache[$cache_key])) { | |
| $list[$name] = $this->cache[$cache_key]; | |
| unset($names[$key]); | |
| } | |
| } | |
| // Pre-load remaining configuration files. | |
| if (!empty($names)) { | |
| // Initialise override information. | |
| $module_overrides = array(); | |
| $storage_data = $this->storage->readMultiple($names); | |
| if ($immutable && !empty($storage_data)) { | |
| // Only get module overrides if we have configuration to override. | |
| $module_overrides = $this->loadOverrides($names); | |
| } | |
| foreach ($storage_data as $name => $data) { | |
| $cache_key = $this->getConfigCacheKey($name, $immutable); | |
| $this->cache[$cache_key] = $this->createConfigObject($name, $immutable); | |
| $this->cache[$cache_key]->initWithData($data); | |
| if ($immutable) { | |
| if (isset($module_overrides[$name])) { | |
| $this->cache[$cache_key]->setModuleOverride($module_overrides[$name]); | |
| } | |
| if (isset($GLOBALS['config'][$name])) { | |
| $this->cache[$cache_key]->setSettingsOverride($GLOBALS['config'][$name]); | |
| } | |
| } | |
| $this->propagateConfigOverrideCacheability($cache_key, $name); | |
| $list[$name] = $this->cache[$cache_key]; | |
| } | |
| } | |
| return $list; | |
| } | |
| /** | |
| * Get arbitrary overrides for the named configuration objects from modules. | |
| * | |
| * @param array $names | |
| * The names of the configuration objects to get overrides for. | |
| * | |
| * @return array | |
| * An array of overrides keyed by the configuration object name. | |
| */ | |
| protected function loadOverrides(array $names) { | |
| $overrides = array(); | |
| foreach ($this->configFactoryOverrides as $override) { | |
| // Existing overrides take precedence since these will have been added | |
| // by events with a higher priority. | |
| $overrides = NestedArray::mergeDeepArray(array($override->loadOverrides($names), $overrides), TRUE); | |
| } | |
| return $overrides; | |
| } | |
| /** | |
| * Propagates cacheability of config overrides to cached config objects. | |
| * | |
| * @param string $cache_key | |
| * The key of the cached config object to update. | |
| * @param string $name | |
| * The name of the configuration object to construct. | |
| */ | |
| protected function propagateConfigOverrideCacheability($cache_key, $name) { | |
| foreach ($this->configFactoryOverrides as $override) { | |
| $this->cache[$cache_key]->addCacheableDependency($override->getCacheableMetadata($name)); | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function reset($name = NULL) { | |
| if ($name) { | |
| // Clear all cached configuration for this name. | |
| foreach ($this->getConfigCacheKeys($name) as $cache_key) { | |
| unset($this->cache[$cache_key]); | |
| } | |
| } | |
| else { | |
| $this->cache = array(); | |
| } | |
| // Clear the static list cache if supported by the storage. | |
| if ($this->storage instanceof StorageCacheInterface) { | |
| $this->storage->resetListCache(); | |
| } | |
| return $this; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function rename($old_name, $new_name) { | |
| Cache::invalidateTags($this->get($old_name)->getCacheTags()); | |
| $this->storage->rename($old_name, $new_name); | |
| // Clear out the static cache of any references to the old name. | |
| foreach ($this->getConfigCacheKeys($old_name) as $old_cache_key) { | |
| unset($this->cache[$old_cache_key]); | |
| } | |
| // Prime the cache and load the configuration with the correct overrides. | |
| $config = $this->get($new_name); | |
| $this->eventDispatcher->dispatch(ConfigEvents::RENAME, new ConfigRenameEvent($config, $old_name)); | |
| return $this; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getCacheKeys() { | |
| // Because get() adds overrides both from $GLOBALS and from | |
| // $this->configFactoryOverrides, add cache keys for each. | |
| $keys[] = 'global_overrides'; | |
| foreach($this->configFactoryOverrides as $override) { | |
| $keys[] = $override->getCacheSuffix(); | |
| } | |
| return $keys; | |
| } | |
| /** | |
| * Gets the static cache key for a given config name. | |
| * | |
| * @param string $name | |
| * The name of the configuration object. | |
| * @param bool $immutable | |
| * Whether or not the object is mutable. | |
| * | |
| * @return string | |
| * The cache key. | |
| */ | |
| protected function getConfigCacheKey($name, $immutable) { | |
| $suffix = ''; | |
| if ($immutable) { | |
| $suffix = ':' . implode(':', $this->getCacheKeys()); | |
| } | |
| return $name . $suffix; | |
| } | |
| /** | |
| * Gets all the cache keys that match the provided config name. | |
| * | |
| * @param string $name | |
| * The name of the configuration object. | |
| * | |
| * @return array | |
| * An array of cache keys that match the provided config name. | |
| */ | |
| protected function getConfigCacheKeys($name) { | |
| return array_filter(array_keys($this->cache), function($key) use ($name) { | |
| // Return TRUE if the key is the name or starts with the configuration | |
| // name plus the delimiter. | |
| return $key === $name || strpos($key, $name . ':') === 0; | |
| }); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function clearStaticCache() { | |
| $this->cache = array(); | |
| return $this; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function listAll($prefix = '') { | |
| return $this->storage->listAll($prefix); | |
| } | |
| /** | |
| * Updates stale static cache entries when configuration is saved. | |
| * | |
| * @param ConfigCrudEvent $event | |
| * The configuration event. | |
| */ | |
| public function onConfigSave(ConfigCrudEvent $event) { | |
| // Ensure that the static cache contains up to date configuration objects by | |
| // replacing the data on any entries for the configuration object apart | |
| // from the one that references the actual config object being saved. | |
| $saved_config = $event->getConfig(); | |
| foreach ($this->getConfigCacheKeys($saved_config->getName()) as $cache_key) { | |
| $cached_config = $this->cache[$cache_key]; | |
| if ($cached_config !== $saved_config) { | |
| // We can not just update the data since other things about the object | |
| // might have changed. For example, whether or not it is new. | |
| $this->cache[$cache_key]->initWithData($saved_config->getRawData()); | |
| } | |
| } | |
| } | |
| /** | |
| * Removes stale static cache entries when configuration is deleted. | |
| * | |
| * @param \Drupal\Core\Config\ConfigCrudEvent $event | |
| * The configuration event. | |
| */ | |
| public function onConfigDelete(ConfigCrudEvent $event) { | |
| // Ensure that the static cache does not contain deleted configuration. | |
| foreach ($this->getConfigCacheKeys($event->getConfig()->getName()) as $cache_key) { | |
| unset($this->cache[$cache_key]); | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| static function getSubscribedEvents() { | |
| $events[ConfigEvents::SAVE][] = array('onConfigSave', 255); | |
| $events[ConfigEvents::DELETE][] = array('onConfigDelete', 255); | |
| return $events; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function addOverride(ConfigFactoryOverrideInterface $config_factory_override) { | |
| $this->configFactoryOverrides[] = $config_factory_override; | |
| } | |
| /** | |
| * Creates a configuration object. | |
| * | |
| * @param string $name | |
| * Configuration object name. | |
| * @param bool $immutable | |
| * Determines whether a mutable or immutable config object is returned. | |
| * | |
| * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig | |
| * The configuration object. | |
| */ | |
| protected function createConfigObject($name, $immutable) { | |
| if ($immutable) { | |
| return new ImmutableConfig($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); | |
| } | |
| return new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); | |
| } | |
| } |