class ConfigActionManager
Same name in other branches
- 10 core/lib/Drupal/Core/Config/Action/ConfigActionManager.php \Drupal\Core\Config\Action\ConfigActionManager
Hierarchy
- class \Drupal\Component\Plugin\PluginManagerBase implements \Drupal\Component\Plugin\PluginManagerInterface uses \Drupal\Component\Plugin\Discovery\DiscoveryTrait
- class \Drupal\Core\Plugin\DefaultPluginManager extends \Drupal\Component\Plugin\PluginManagerBase implements \Drupal\Component\Plugin\PluginManagerInterface, \Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface, \Drupal\Core\Cache\CacheableDependencyInterface uses \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait, \Drupal\Core\Cache\UseCacheBackendTrait
- class \Drupal\Core\Config\Action\ConfigActionManager extends \Drupal\Core\Plugin\DefaultPluginManager
- class \Drupal\Core\Plugin\DefaultPluginManager extends \Drupal\Component\Plugin\PluginManagerBase implements \Drupal\Component\Plugin\PluginManagerInterface, \Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface, \Drupal\Core\Cache\CacheableDependencyInterface uses \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait, \Drupal\Core\Cache\UseCacheBackendTrait
Expanded class hierarchy of ConfigActionManager
10 files declare their use of ConfigActionManager
- ConfigActionsTest.php in core/
modules/ media/ tests/ src/ Kernel/ ConfigActionsTest.php - ConfigActionsTest.php in core/
modules/ language/ tests/ src/ Kernel/ ConfigActionsTest.php - ConfigActionsTest.php in core/
modules/ field/ tests/ src/ Kernel/ ConfigActionsTest.php - ConfigActionsTest.php in core/
modules/ contact/ tests/ src/ Kernel/ ConfigActionsTest.php - ConfigActionsTest.php in core/
modules/ node/ tests/ src/ Kernel/ ConfigActionsTest.php
File
-
core/
lib/ Drupal/ Core/ Config/ Action/ ConfigActionManager.php, line 55
Namespace
Drupal\Core\Config\ActionView source
class ConfigActionManager extends DefaultPluginManager {
/**
* Information about all deprecated plugin IDs.
*
* @var string[]
*/
private static array $deprecatedPluginIds = [
'entity_create:ensure_exists' => [
'replacement' => 'entity_create:createIfNotExists',
'message' => 'The plugin ID "entity_create:ensure_exists" is deprecated in drupal:10.3.1 and will be removed in drupal:12.0.0. Use "entity_create:createIfNotExists" instead. See https://www.drupal.org/node/3458273.',
],
'simple_config_update' => [
'replacement' => 'simpleConfigUpdate',
'message' => 'The plugin ID "simple_config_update" is deprecated in drupal:10.3.1 and will be removed in drupal:12.0.0. Use "simpleConfigUpdate" instead. See https://www.drupal.org/node/3458273.',
],
];
/**
* Constructs a new \Drupal\Core\Config\Action\ConfigActionManager object.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* Cache backend instance to use.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke the alter hook with.
* @param \Drupal\Core\Config\ConfigManagerInterface $configManager
* The config manager.
* @param \Drupal\Core\Config\StorageInterface $configStorage
* The active config storage.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typedConfig
* The typed configuration manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigManagerInterface $configManager, StorageInterface $configStorage, TypedConfigManagerInterface $typedConfig, ConfigFactoryInterface $configFactory) {
assert($namespaces instanceof \ArrayAccess, '$namespaces can be accessed like an array');
// Enable this namespace to be searched for plugins.
$namespaces[__NAMESPACE__] = 'core/lib/Drupal/Core/Config/Action';
parent::__construct('Plugin/ConfigAction', $namespaces, $module_handler, ConfigActionPluginInterface::class, ConfigAction::class);
$this->alterInfo('config_action');
$this->setCacheBackend($cache_backend, 'config_action');
}
/**
* Applies a config action.
*
* @param string $action_id
* The ID of the action to apply. This can be a complete configuration
* action plugin ID or a shorthand action ID that is available for the
* entity type of the provided configuration name.
* @param string $configName
* The configuration name. This may be the full name of a config object, or
* it may contain wildcards (to target all config entities of a specific
* type, or a subset thereof). See
* ConfigActionManager::getConfigNamesMatchingExpression() for more detail.
* @param mixed $data
* The data for the action.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
* Thrown when the config action cannot be found.
* @throws \Drupal\Core\Config\Action\ConfigActionException
* Thrown when the config action fails to apply.
*
* @see \Drupal\Core\Config\Action\ConfigActionManager::getConfigNamesMatchingExpression()
*/
public function applyAction(string $action_id, string $configName, mixed $data) : void {
if (!$this->hasDefinition($action_id)) {
// Get the full plugin ID from the shorthand map, if it is available.
$entity_type = $this->configManager
->getEntityTypeIdByName($configName);
if ($entity_type) {
$action_id = $this->getShorthandActionIdsForEntityType($entity_type)[$action_id] ?? $action_id;
}
}
try {
/** @var \Drupal\Core\Config\Action\ConfigActionPluginInterface $action */
$action = $this->createInstance($action_id);
} catch (PluginNotFoundException $e) {
$entity_type = $this->configManager
->getEntityTypeIdByName($configName);
if ($entity_type) {
$action_ids = $this->getShorthandActionIdsForEntityType($entity_type);
$valid_ids = implode(', ', array_keys($action_ids));
throw new PluginNotFoundException($action_id, sprintf('The "%s" entity does not support the "%s" config action. Valid config actions for %s are: %s', $entity_type, $action_id, $entity_type, $valid_ids));
}
throw $e;
}
foreach ($this->getConfigNamesMatchingExpression($configName) as $name) {
$action->apply($name, $data);
$typed_config = $this->typedConfig
->createFromNameAndData($name, $this->configFactory
->get($name)
->getRawData());
// All config objects are mappings.
assert($typed_config instanceof Mapping);
foreach ($typed_config->getConstraints() as $constraint) {
// Only validate the config if it has explicitly been marked as being
// validatable.
if ($constraint instanceof FullyValidatableConstraint) {
/** @var \Symfony\Component\Validator\ConstraintViolationList $violations */
$violations = $typed_config->validate();
if (count($violations) > 0) {
throw new InvalidConfigException($violations, $typed_config);
}
break;
}
}
}
}
/**
* Gets the names of all active config objects that match an expression.
*
* @param string $expression
* The expression to match. This may be the full name of a config object,
* or it may contain wildcards (to target all config entities of a specific
* type, or a subset thereof). For example:
* - `user.role.*` would target all user roles.
* - `user.role.anonymous` would target only the anonymous user role.
* - `core.entity_view_display.node.*.default` would target the default
* view display of every content type.
* - `core.entity_form_display.*.*.default` would target the default form
* display of every bundle of every entity type.
* The expression MUST begin with the prefix of a config entity type --
* for example, `field.field.` in the case of fields, or `user.role.` for
* user roles. The prefix cannot contain wildcards.
*
* @return string[]
* The names of all active config objects that match the expression.
*
* @throws \Drupal\Core\Config\Action\ConfigActionException
* Thrown if the expression does not match any known config entity type's
* prefix, or if the expression cannot be parsed.
*/
private function getConfigNamesMatchingExpression(string $expression) : array {
// If there are no wildcards, we can return the config name as-is.
if (!str_contains($expression, '.*')) {
return [
$expression,
];
}
$entity_type = $this->configManager
->getEntityTypeIdByName($expression);
if (empty($entity_type)) {
throw new ConfigActionException("No installed config entity type uses the prefix in the expression '{$expression}'. Either there is a typo in the expression or this recipe should install an additional module or depend on another recipe.");
}
/** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type */
$entity_type = $this->configManager
->getEntityTypeManager()
->getDefinition($entity_type);
$prefix = $entity_type->getConfigPrefix();
// Convert the expression to a regular expression. We assume that * should
// match the characters allowed by
// \Drupal\Core\Config\ConfigBase::validateName(), which is permissive.
$expression = str_replace('\\*', '[^.:?*<>"\'\\/\\\\]+', preg_quote($expression));
$matches = @preg_grep("/^{$expression}\$/", $this->configStorage
->listAll("{$prefix}."));
if ($matches === FALSE) {
throw new ConfigActionException("The expression '{$expression}' could not be parsed.");
}
return $matches;
}
/**
* Gets a map of shorthand action IDs to plugin IDs for an entity type.
*
* @param string $entityType
* The entity type ID to get the map for.
*
* @return string[]
* An array of plugin IDs keyed by shorthand action ID for the provided
* entity type.
*/
protected function getShorthandActionIdsForEntityType(string $entityType) : array {
$map = [];
foreach ($this->getDefinitions() as $plugin_id => $definition) {
if (in_array($entityType, $definition['entity_types'], TRUE) || in_array('*', $definition['entity_types'], TRUE)) {
$regex = '/' . PluginBase::DERIVATIVE_SEPARATOR . '([^' . PluginBase::DERIVATIVE_SEPARATOR . ']*)$/';
$action_id = preg_match($regex, $plugin_id, $matches) ? $matches[1] : $plugin_id;
if (isset($map[$action_id])) {
throw new DuplicateConfigActionIdException(sprintf('The plugins \'%s\' and \'%s\' both resolve to the same shorthand action ID for the \'%s\' entity type', $plugin_id, $map[$action_id], $entityType));
}
$map[$action_id] = $plugin_id;
}
}
return $map;
}
/**
* {@inheritdoc}
*/
public function alterDefinitions(&$definitions) : void {
// Adds backwards compatibility for plugins that have been renamed.
foreach (self::$deprecatedPluginIds as $legacy => $new_plugin_id) {
$definitions[$legacy] = $definitions[$new_plugin_id['replacement']];
}
parent::alterDefinitions($definitions);
}
/**
* {@inheritdoc}
*/
public function createInstance($plugin_id, array $configuration = []) {
$instance = parent::createInstance($plugin_id, $configuration);
// Trigger deprecation notices for renamed plugins.
if (array_key_exists($plugin_id, self::$deprecatedPluginIds)) {
// phpcs:ignore Drupal.Semantics.FunctionTriggerError
@trigger_error(self::$deprecatedPluginIds[$plugin_id]['message'], E_USER_DEPRECATED);
}
return $instance;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
ConfigActionManager::$deprecatedPluginIds | private static | property | Information about all deprecated plugin IDs. | ||
ConfigActionManager::alterDefinitions | public | function | Invokes the hook to alter the definitions if the alter hook is set. | Overrides DefaultPluginManager::alterDefinitions | |
ConfigActionManager::applyAction | public | function | Applies a config action. | ||
ConfigActionManager::createInstance | public | function | Overrides PluginManagerBase::createInstance | ||
ConfigActionManager::getConfigNamesMatchingExpression | private | function | Gets the names of all active config objects that match an expression. | ||
ConfigActionManager::getShorthandActionIdsForEntityType | protected | function | Gets a map of shorthand action IDs to plugin IDs for an entity type. | ||
ConfigActionManager::__construct | public | function | Constructs a new \Drupal\Core\Config\Action\ConfigActionManager object. | Overrides DefaultPluginManager::__construct | |
DefaultPluginManager::$additionalAnnotationNamespaces | protected | property | Additional annotation namespaces. | ||
DefaultPluginManager::$alterHook | protected | property | Name of the alter hook if one should be invoked. | ||
DefaultPluginManager::$cacheKey | protected | property | The cache key. | ||
DefaultPluginManager::$cacheTags | protected | property | An array of cache tags to use for the cached definitions. | ||
DefaultPluginManager::$defaults | protected | property | A set of defaults to be referenced by $this->processDefinition(). | 12 | |
DefaultPluginManager::$moduleExtensionList | protected | property | The module extension list. | ||
DefaultPluginManager::$moduleHandler | protected | property | The module handler to invoke the alter hook. | 1 | |
DefaultPluginManager::$namespaces | protected | property | An object of root paths that are traversable. | ||
DefaultPluginManager::$pluginDefinitionAnnotationName | protected | property | The name of the annotation that contains the plugin definition. | ||
DefaultPluginManager::$pluginDefinitionAttributeName | protected | property | The name of the attribute that contains the plugin definition. | ||
DefaultPluginManager::$pluginInterface | protected | property | The interface each plugin should implement. | 1 | |
DefaultPluginManager::$subdir | protected | property | The subdirectory within a namespace to look for plugins. | ||
DefaultPluginManager::alterInfo | protected | function | Sets the alter hook name. | ||
DefaultPluginManager::clearCachedDefinitions | public | function | Clears static and persistent plugin definition caches. | Overrides CachedDiscoveryInterface::clearCachedDefinitions | 11 |
DefaultPluginManager::extractProviderFromDefinition | protected | function | Extracts the provider from a plugin definition. | ||
DefaultPluginManager::findDefinitions | protected | function | Finds plugin definitions. | 7 | |
DefaultPluginManager::getCacheContexts | public | function | The cache contexts associated with this object. | Overrides CacheableDependencyInterface::getCacheContexts | |
DefaultPluginManager::getCachedDefinitions | protected | function | Returns the cached plugin definitions of the decorated discovery class. | ||
DefaultPluginManager::getCacheMaxAge | public | function | The maximum age for which this object may be cached. | Overrides CacheableDependencyInterface::getCacheMaxAge | |
DefaultPluginManager::getCacheTags | public | function | The cache tags associated with this object. | Overrides CacheableDependencyInterface::getCacheTags | |
DefaultPluginManager::getDefinitions | public | function | Gets the definition of all plugins for this type. | Overrides DiscoveryTrait::getDefinitions | 2 |
DefaultPluginManager::getDiscovery | protected | function | Gets the plugin discovery. | Overrides PluginManagerBase::getDiscovery | 16 |
DefaultPluginManager::getFactory | protected | function | Gets the plugin factory. | Overrides PluginManagerBase::getFactory | |
DefaultPluginManager::processDefinition | public | function | Performs extra processing on plugin definitions. | 14 | |
DefaultPluginManager::providerExists | protected | function | Determines if the provider of a definition exists. | 5 | |
DefaultPluginManager::setCacheBackend | public | function | Initialize the cache backend. | ||
DefaultPluginManager::setCachedDefinitions | protected | function | Sets a cache of plugin definitions for the decorated discovery class. | ||
DefaultPluginManager::useCaches | public | function | Disable the use of caches. | Overrides CachedDiscoveryInterface::useCaches | 1 |
DiscoveryCachedTrait::$definitions | protected | property | Cached definitions array. | 1 | |
DiscoveryCachedTrait::getDefinition | public | function | Overrides DiscoveryTrait::getDefinition | 3 | |
DiscoveryTrait::doGetDefinition | protected | function | Gets a specific plugin definition. | ||
DiscoveryTrait::hasDefinition | public | function | |||
PluginManagerBase::$discovery | protected | property | The object that discovers plugins managed by this manager. | ||
PluginManagerBase::$factory | protected | property | The object that instantiates plugins managed by this manager. | ||
PluginManagerBase::$mapper | protected | property | The object that returns the preconfigured plugin instance appropriate for a particular runtime condition. | ||
PluginManagerBase::getFallbackPluginId | protected | function | Gets a fallback id for a missing plugin. | 6 | |
PluginManagerBase::getInstance | public | function | 6 | ||
PluginManagerBase::handlePluginNotFound | protected | function | Allows plugin managers to specify custom behavior if a plugin is not found. | 1 | |
UseCacheBackendTrait::$cacheBackend | protected | property | Cache backend instance. | ||
UseCacheBackendTrait::$useCaches | protected | property | Flag whether caches should be used or skipped. | ||
UseCacheBackendTrait::cacheGet | protected | function | Fetches from the cache backend, respecting the use caches flag. | ||
UseCacheBackendTrait::cacheSet | protected | function | Stores data in the persistent cache, respecting the use caches flag. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.