Issue #3420982 by sorlov, alexpott: Convert EntityReferenceSelection plugin discovery to attributes

(cherry picked from commit b4a9a825ea)
merge-requests/9720/head
Lee Rowlands 2024-03-10 18:02:56 +10:00
parent 364518db9e
commit 2061b8fb28
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
13 changed files with 165 additions and 82 deletions

View File

@ -0,0 +1,65 @@
<?php
namespace Drupal\Core\Entity\Attribute;
use Drupal\Component\Plugin\Attribute\Plugin;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Defines an EntityReferenceSelection attribute for plugin discovery.
*
* Plugin Namespace: Plugin\EntityReferenceSelection
*
* For a working example, see
* \Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection
*
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
* @see plugin_api
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class EntityReferenceSelection extends Plugin {
/**
* Constructs an EntityReferenceSelection attribute.
*
* @param string $id
* The plugin ID. There are some implementation bugs that make the plugin
* available only if the ID follows a specific pattern. It must be either
* identical to group or prefixed with the group. E.g. if the group is "foo"
* the ID must be either "foo" or "foo:bar".
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $label
* The human-readable name of the selection plugin.
* @param string $group
* The selection plugin group. This property is used to allow selection
* plugins to target a specific entity type while also inheriting the code
* of an existing selection plugin. For example, if we want to override the
* NodeSelection from the 'default' selection type, we can define the
* attribute as follows:
* @code
* #[EntityReferenceSelection(
* id: "default:node_advanced",
* entity_types: ["node"],
* group: "default",
* weight: 5
* )]
* @endcode
* @param int $weight
* The weight of the plugin in its group. This property is used to select
* the "best" plugin within a group.
* @param string[] $entity_types
* (optional) An array of entity types that can be referenced by this
* plugin. Defaults to all entity types.
* @param class-string|null $deriver
* (optional) The deriver class.
*/
public function __construct(
public readonly string $id,
public readonly TranslatableMarkup $label,
public readonly string $group,
public readonly int $weight,
public readonly array $entity_types = [],
public readonly ?string $deriver = NULL
) {}
}

View File

@ -4,6 +4,7 @@ namespace Drupal\Core\Entity\EntityReferenceSelection;
use Drupal\Component\Plugin\FallbackPluginManagerInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
@ -25,7 +26,7 @@ class SelectionPluginManager extends DefaultPluginManager implements SelectionPl
$this->alterInfo('entity_reference_selection');
$this->setCacheBackend($cache_backend, 'entity_reference_selection_plugins');
parent::__construct('Plugin/EntityReferenceSelection', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface', 'Drupal\Core\Entity\Annotation\EntityReferenceSelection');
parent::__construct('Plugin/EntityReferenceSelection', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface', EntityReferenceSelection::class, 'Drupal\Core\Entity\Annotation\EntityReferenceSelection');
}
/**

View File

@ -2,17 +2,23 @@
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Defines a fallback plugin for missing entity_reference selection plugins.
*
* @EntityReferenceSelection(
* id = "broken",
* label = @Translation("Broken/Missing")
* )
* Note this plugin does not appear in the UI and is only used when a plugin can
* not found.
*/
#[EntityReferenceSelection(
id: "broken",
label: new TranslatableMarkup("Broken/Missing"),
group: '',
weight: -100,
)]
class Broken extends SelectionPluginBase {
/**

View File

@ -4,6 +4,7 @@ namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
@ -12,11 +13,13 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\user\EntityOwnerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -31,15 +34,14 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
* @see \Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver
* @see plugin_api
*
* @EntityReferenceSelection(
* id = "default",
* label = @Translation("Default"),
* group = "default",
* weight = 0,
* deriver = "Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver"
* )
*/
#[EntityReferenceSelection(
id: "default",
label: new TranslatableMarkup("Default"),
group: "default",
weight: 0,
deriver: DefaultSelectionDeriver::class,
)]
class DefaultSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface, SelectionWithAutocreateInterface {
/**

View File

@ -4,20 +4,21 @@ namespace Drupal\comment\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\comment\CommentInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Provides specific access control for the comment entity type.
*
* @EntityReferenceSelection(
* id = "default:comment",
* label = @Translation("Comment selection"),
* entity_types = {"comment"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:comment",
label: new TranslatableMarkup("Comment selection"),
entity_types: ["comment"],
group: "default",
weight: 1
)]
class CommentSelection extends DefaultSelection {
/**

View File

@ -2,20 +2,21 @@
namespace Drupal\file\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\file\FileInterface;
/**
* Provides specific access control for the file entity type.
*
* @EntityReferenceSelection(
* id = "default:file",
* label = @Translation("File selection"),
* entity_types = {"file"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:file",
label: new TranslatableMarkup("File selection"),
entity_types: ["file"],
group: "default",
weight: 1
)]
class FileSelection extends DefaultSelection {
/**

View File

@ -2,19 +2,20 @@
namespace Drupal\media\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Provides specific access control for the media entity type.
*
* @EntityReferenceSelection(
* id = "default:media",
* label = @Translation("Media selection"),
* entity_types = {"media"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:media",
label: new TranslatableMarkup("Media selection"),
entity_types: ["media"],
group: "default",
weight: 1
)]
class MediaSelection extends DefaultSelection {
/**

View File

@ -2,20 +2,21 @@
namespace Drupal\node\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\node\NodeInterface;
/**
* Provides specific access control for the node entity type.
*
* @EntityReferenceSelection(
* id = "default:node",
* label = @Translation("Node selection"),
* entity_types = {"node"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:node",
label: new TranslatableMarkup("Node selection"),
entity_types: ["node"],
group: "default",
weight: 1
)]
class NodeSelection extends DefaultSelection {
/**

View File

@ -2,17 +2,19 @@
namespace Drupal\entity_reference_test\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Allows access to all entities except for the host entity.
*
* @EntityReferenceSelection(
* id = "entity_test_all_except_host",
* label = @Translation("All except host entity."),
* group = "entity_test_all_except_host"
* )
*/
#[EntityReferenceSelection(
id: "entity_test_all_except_host",
label: new TranslatableMarkup("All except host entity."),
group: "entity_test_all_except_host",
weight: 0
)]
class AllExceptHostEntity extends DefaultSelection {
/**

View File

@ -3,21 +3,22 @@
namespace Drupal\taxonomy\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* Provides specific access control for the taxonomy_term entity type.
*
* @EntityReferenceSelection(
* id = "default:taxonomy_term",
* label = @Translation("Taxonomy Term selection"),
* entity_types = {"taxonomy_term"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:taxonomy_term",
label: new TranslatableMarkup("Taxonomy Term selection"),
entity_types: ["taxonomy_term"],
group: "default",
weight: 1
)]
class TermSelection extends DefaultSelection {
/**

View File

@ -4,6 +4,7 @@ namespace Drupal\user\Plugin\EntityReferenceSelection;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
@ -12,21 +13,21 @@ use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides specific access control for the user entity type.
*
* @EntityReferenceSelection(
* id = "default:user",
* label = @Translation("User selection"),
* entity_types = {"user"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:user",
label: new TranslatableMarkup("User selection"),
entity_types: ["user"],
group: "default",
weight: 1
)]
class UserSelection extends DefaultSelection {
/**

View File

@ -3,6 +3,7 @@
namespace Drupal\views\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
@ -20,14 +21,13 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Plugin implementation of the 'selection' entity_reference.
*
* @EntityReferenceSelection(
* id = "views",
* label = @Translation("Views: Filter by an entity reference view"),
* group = "views",
* weight = 0
* )
*/
#[EntityReferenceSelection(
id: "views",
label: new TranslatableMarkup("Views: Filter by an entity reference view"),
group: "views",
weight: 0
)]
class ViewsSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface {
use StringTranslationTrait;

View File

@ -3,21 +3,22 @@
namespace Drupal\workspaces\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides specific access control for the workspace entity type.
*
* @EntityReferenceSelection(
* id = "default:workspace",
* label = @Translation("Workspace selection"),
* entity_types = {"workspace"},
* group = "default",
* weight = 1
* )
*/
#[EntityReferenceSelection(
id: "default:workspace",
label: new TranslatableMarkup("Workspace selection"),
entity_types: ["workspace"],
group: "default",
weight: 1
)]
class WorkspaceSelection extends DefaultSelection {
/**