class PermissionsPerBundle

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Config/Action/Plugin/ConfigAction/PermissionsPerBundle.php \Drupal\Core\Config\Action\Plugin\ConfigAction\PermissionsPerBundle

@internal This API is experimental.

Hierarchy

Expanded class hierarchy of PermissionsPerBundle

File

core/lib/Drupal/Core/Config/Action/Plugin/ConfigAction/PermissionsPerBundle.php, line 22

Namespace

Drupal\Core\Config\Action\Plugin\ConfigAction
View source
final class PermissionsPerBundle implements ConfigActionPluginInterface, ContainerFactoryPluginInterface {
  public function __construct(private readonly ConfigManagerInterface $configManager, private readonly EntityTypeBundleInfoInterface $entityTypeBundleInfo, private readonly string $targetEntityType) {
  }
  
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    assert(is_array($plugin_definition));
    $target_entity_type = $plugin_definition['target_entity_type'];
    return new static($container->get(ConfigManagerInterface::class), $container->get(EntityTypeBundleInfoInterface::class), $target_entity_type);
  }
  
  /**
   * {@inheritdoc}
   */
  public function apply(string $configName, mixed $value) : void {
    $role = $this->configManager
      ->loadConfigEntityByName($configName);
    if (!$role instanceof RoleInterface) {
      throw new ConfigActionException(sprintf("Cannot determine role from %s", $configName));
    }
    assert(is_string($value) || is_array($value));
    [
      $permissions,
      $except_bundles,
    ] = self::parseValue($value);
    if (empty($permissions) || !Inspector::assertAllMatch('%bundle', $permissions, TRUE)) {
      throw new ConfigActionException(sprintf("The permissions provided %s must be an array of strings that contain '%%bundle'.", var_export($value, TRUE)));
    }
    $bundles = $this->entityTypeBundleInfo
      ->getBundleInfo($this->targetEntityType);
    foreach (array_keys($bundles) as $bundle_id) {
      if (in_array($bundle_id, $except_bundles, TRUE)) {
        continue;
      }
      /** @var string[] $actual_permissions */
      $actual_permissions = str_replace('%bundle', $bundle_id, $permissions);
      array_walk($actual_permissions, $role->grantPermission(...));
    }
    $role->save();
  }
  
  /**
   * Parses the value supplied to ::apply().
   *
   * @param string|array<string|string[]> $value
   *   One of:
   *   - A single string (a permission template).
   *   - An array of strings (several permission templates).
   *   - An array with a `permissions` element, and an optional `except`
   *     element, either of which can be an array or a string. `except` accepts
   *     a single bundle, or a list of bundles, to exclude from the permissions
   *     being granted.
   *
   * @return array<int, array<int<0, max>, array<string>|string>>
   *   An indexed array with two elements: the array of permissions to grant,
   *   and the list of bundles to ignore.
   */
  private static function parseValue(string|array $value) : array {
    if (is_string($value)) {
      return [
        [
          $value,
        ],
        [],
      ];
    }
    if (array_is_list($value)) {
      return [
        $value,
        [],
      ];
    }
    $permissions = $value['permissions'] ?? [];
    $except_bundles = $value['except'] ?? [];
    return [
      (array) $permissions,
      (array) $except_bundles,
    ];
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
PermissionsPerBundle::apply public function Applies the config action. Overrides ConfigActionPluginInterface::apply
PermissionsPerBundle::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
PermissionsPerBundle::parseValue private static function Parses the value supplied to ::apply().
PermissionsPerBundle::__construct public function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.