I have played a little bit and changed the structure slightly, but finally made it work. Here's my example:
Final structure:
├── pm_test.info.yml
├── pm_test.services.yml
└── src
├── Annotation
│ └── ReactionAnnotation.php
└── Plugin
├── Reaction
│ └── Test.php
├── ReactionInterface.php
└── ReactionManager.php
services.yml looks like this:
services:
plugin.manager.reaction:
class: Drupal\pm_test\Plugin\ReactionManager
parent: default_plugin_manager
Annotation class(src/Annotation/ReactionAnnotation.php
)
<?php
namespace Drupal\pm_test\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Declare a class for event reactions.
*
* Plugin Namespace: Plugin\Reaction.
*
* @see plugin_api
*
* @Annotation
*/
class ReactionAnnotation extends Plugin {
/**
* The plugin ID.
*
* @var string
*/
public $id;
/**
* The human-readable label of the plugin.
*
* @var \Drupal\Core\Annotation\Translation
*
* @ingroup plugin_translatable
*/
public $label;
}
The ReactionInterface (src/Plugin/ReactionInterface.php
)
<?php
namespace Drupal\pm_test\Plugin;
use Drupal\Component\Plugin\PluginInspectionInterface;
/**
* Defines an interface for a Reaction plugin.
*
* @see plugin_api
*/
interface ReactionInterface extends PluginInspectionInterface {
public function processEvent($event, $entity);
}
The ReactionManager(src/Plugin/ReactionManager.php
)
<?php
namespace Drupal\pm_test\Plugin;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
/**
* Defines the reaction plugin manager.
*/
class ReactionManager extends DefaultPluginManager {
/**
* Constructs a ReactionManager 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.
*/
public function __construct(
\Traversable $namespaces,
CacheBackendInterface $cache_backend,
ModuleHandlerInterface $module_handler,
) {
parent::__construct(
'Plugin/Reaction',
$namespaces,
$module_handler,
'\Drupal\pm_test\Plugin\ReactionInterface',
'\Drupal\pm_test\Annotation\ReactionAnnotation'
);
$this->alterInfo('reaction_info');
$this->setCacheBackend($cache_backend, 'reaction_info_plugins');
}
}
And finally the Test(/src/Plugin/Reaction/Test.php
):
<?php
namespace Drupal\pm_test\Plugin\Reaction;
use Drupal\Component\Plugin\PluginBase;
use Drupal\pm_test\Annotation\ReactionAnnotation;
use Drupal\pm_test\Plugin\ReactionInterface;
/**
* Test reaction.
*
* @ReactionAnnotation(
* id = "test",
* title = @Translation("Reaction for testing reactions")
* )
*/
class Test extends PluginBase implements ReactionInterface {
public function processEvent($event, $entity) {
var_export($event->title->value);
}
}
At the end, I checked the same way with drush and here's the result:
Psy Shell v0.11.18 (PHP 8.0.24 — cli) by Justin Hileman
Drush Site-Install (Drupal 9.5.9)
> $p = $container->get('plugin.manager.reaction');
= Drupal\pm_test\Plugin\ReactionManager {#7435}
> $p->getDefinitions();
= [
"test" => [
"id" => "test",
"title" => Drupal\Core\StringTranslation\TranslatableMarkup {#7452},
"class" => "Drupal\pm_test\Plugin\Reaction\Test",
"provider" => "pm_test",
],
]
In my opinion the biggest issue with your code was the Annotation. Instead of using
* @Reaction(
* id = "test",
* title = @Translation("Reaction for testing reactions")
* )
it should have been
* @ReactionAnnotation(
* id = "test",
* title = @Translation("Reaction for testing reactions")
* )
after the name of the annotation class. I hope this helps