CreateForEachBundle.php
Namespace
Drupal\Core\Config\Action\Plugin\ConfigActionFile
-
core/
lib/ Drupal/ Core/ Config/ Action/ Plugin/ ConfigAction/ CreateForEachBundle.php
View source
<?php
declare (strict_types=1);
namespace Drupal\Core\Config\Action\Plugin\ConfigAction;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Config\Action\Attribute\ConfigAction;
use Drupal\Core\Config\Action\ConfigActionManager;
use Drupal\Core\Config\Action\ConfigActionPluginInterface;
use Drupal\Core\Config\Action\Plugin\ConfigAction\Deriver\CreateForEachBundleDeriver;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Creates config entities for each bundle of a particular entity type.
*
* An example of using this in a recipe's config actions would be:
* @code
* node.type.*:
* createForEach:
* language.content_settings.node.%bundle:
* target_entity_type_id: node
* target_bundle: %bundle
* image.style.node_%bundle_big:
* label: 'Big images for %label content'
* @endcode
* This will create two entities for each existing content type: a content
* language settings entity, and an image style. For example, for a content type
* called `blog`, this will create `language.content_settings.node.blog` and
* `image.style.node_blog_big`, with the given values. The `%bundle` and
* `%label` placeholders will be replaced with the ID and label of the content
* type, respectively.
*
* @internal
* This API is experimental.
*/
final class CreateForEachBundle implements ConfigActionPluginInterface, ContainerFactoryPluginInterface {
/**
* The placeholder which is replaced with the ID of the current bundle.
*
* @var string
*/
private const BUNDLE_PLACEHOLDER = '%bundle';
/**
* The placeholder which is replaced with the label of the current bundle.
*
* @var string
*/
private const LABEL_PLACEHOLDER = '%label';
public function __construct(ConfigManagerInterface $configManager, string $createAction, ConfigActionManager $configActionManager) {
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) : static {
// If there are no bundle entity types, this plugin should not be usable.
if (empty($plugin_definition['entity_types'])) {
throw new InvalidPluginDefinitionException($plugin_id, "The {$plugin_id} config action must be restricted to entity types that are bundles of another entity type.");
}
return new static($container->get(ConfigManagerInterface::class), $plugin_definition['create_action'], $container->get('plugin.manager.config_action'));
}
/**
* {@inheritdoc}
*/
public function apply(string $configName, mixed $value) : void {
assert(is_array($value));
$bundle = $this->configManager
->loadConfigEntityByName($configName);
assert(is_object($bundle));
$value = static::replacePlaceholders($value, [
static::BUNDLE_PLACEHOLDER => $bundle->id(),
static::LABEL_PLACEHOLDER => $bundle->label(),
]);
foreach ($value as $name => $values) {
// Invoke the actual create action via the config action manager, so that
// the created entity will be validated.
$this->configActionManager
->applyAction('entity_create:' . $this->createAction, $name, $values);
}
}
/**
* Replaces placeholders recursively.
*
* @param mixed $data
* The data to process. If this is an array, it'll be processed recursively.
* @param array $replacements
* An array whose keys are the placeholders to replace in the data, and
* whose values are the the replacements. Normally this will only mention
* the `%bundle` and `%label` placeholders. If $data is an array, the only
* placeholder that is replaced in the array's keys is `%bundle`.
*
* @return mixed
* The given $data, with the `%bundle` and `%label` placeholders replaced.
*/
private static function replacePlaceholders(mixed $data, array $replacements) : mixed {
assert(array_key_exists(static::BUNDLE_PLACEHOLDER, $replacements));
if (is_string($data)) {
$data = str_replace(array_keys($replacements), $replacements, $data);
}
elseif (is_array($data)) {
foreach ($data as $old_key => $value) {
$value = static::replacePlaceholders($value, $replacements);
// Only replace the `%bundle` placeholder in array keys.
$new_key = str_replace(static::BUNDLE_PLACEHOLDER, $replacements[static::BUNDLE_PLACEHOLDER], $old_key);
if ($old_key !== $new_key) {
unset($data[$old_key]);
}
$data[$new_key] = $value;
}
}
return $data;
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
CreateForEachBundle | Creates config entities for each bundle of a particular entity type. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.