devel_wizard-2.x-dev/src/Spell/SpellManager.php
src/Spell/SpellManager.php
<?php
declare(strict_types=1);
namespace Drupal\devel_wizard\Spell;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\devel_wizard\Attribute\DevelWizardSpell;
use Sweetchuck\Utils\Comparer\ComparerInterface;
class SpellManager extends DefaultPluginManager implements SpellManagerInterface {
protected ComparerInterface $definitionComparer;
public function __construct(
\Traversable $namespaces,
ModuleHandlerInterface $module_handler,
CacheBackendInterface $discovery_cache,
ComparerInterface $definitionComparer,
array $additional_annotation_namespaces = [],
) {
$this->definitionComparer = $definitionComparer;
$this->useCaches = TRUE;
$this->setCacheBackend($discovery_cache, 'devel_wizard.spell.plugin_definitions');
parent::__construct(
'Plugin/DevelWizard/Spell',
$namespaces,
$module_handler,
SpellInterface::class,
DevelWizardSpell::class,
NULL,
$additional_annotation_namespaces,
);
}
/**
* {@inheritdoc}
*/
protected function findDefinitions() {
$definitions = parent::findDefinitions();
assert($this->assertDefinitions($definitions));
uasort($definitions, $this->definitionComparer);
return $definitions;
}
/**
* @param array<string, \Drupal\devel_wizard\Spell\SpellDefinition> $definitions
*/
protected function assertDefinitions(array $definitions): bool {
foreach ($definitions as $definition) {
$this->assertDefinition($definition);
}
return TRUE;
}
protected function assertDefinition(SpellDefinition $definition): void {
$id = $definition->id();
$prefix_variants = $this->getPrefixVariants($definition->getProvider());
$is_prefix_valid = FALSE;
foreach ($prefix_variants as $prefix_variant) {
if (str_starts_with($id, $prefix_variant)) {
$is_prefix_valid = TRUE;
break;
}
}
assert(
$is_prefix_valid,
"devel_wizard.spell plugin identifier '$id' should be prefixed with the provider: {$prefix_variants[0]}",
);
}
/**
* @return array<string>
*/
protected function getPrefixVariants(string $full): array {
$variants = [];
$separator = '_';
$parts = explode($separator, $full);
for ($length = count($parts); $length > 0; $length--) {
$variants[] = implode(
$separator,
array_slice($parts, 0, $length),
);
}
return $variants;
}
/**
* {@inheritdoc}
*/
public function getGroupedDefinitions(?array $definitions = NULL, $label_key = 'label') {
$definitions = $this->getSortedDefinitions(
$definitions ?? $this->getDefinitions(),
);
$grouped_definitions = [];
foreach ($definitions as $id => $definition) {
$grouped_definitions[(string) $definition->getCategory()][$id] = $definition;
}
return $grouped_definitions;
}
/**
* {@inheritdoc}
*/
public function getCategories() {
$categories = array_unique(array_values(array_map(
function (SpellDefinition $definition) {
return $definition->getCategory();
},
$this->getDefinitions(),
)));
natcasesort($categories);
return $categories;
}
/**
* {@inheritdoc}
*/
public function getSortedDefinitions(?array $definitions = NULL) {
// Sort the plugins first by category, then by label.
$definitions = $definitions ?? $this->getDefinitions();
uasort(
$definitions,
function (SpellDefinition $a, SpellDefinition $b): int {
return strnatcasecmp($a->getCategory(), $b->getCategory())
?: strnatcasecmp($a->getLabel(), $b->getLabel());
},
);
return $definitions;
}
}
