Problem/Motivation

When using annotated classes, it is easy for the definition to be converted to an object. See \Drupal\Core\Entity\Annotation\EntityType::get() for an example.

However, if using another form of discovery like YAML, there is no means to convert the array to an object.

Proposed resolution

Introduce a discovery decorator that transforms arrays into a specified classed definition object.

Remaining tasks

User interface changes

N/A

API changes

API addition (not really even, just a new cool thing to use?)

Data model changes

N/A

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett created an issue. See original summary.

tim.plunkett’s picture

Status: Active » Needs review
FileSize
1.8 KB
tim.plunkett’s picture

Bump

jibran’s picture

Status: Needs review » Reviewed & tested by the community

This is straight forward. Where else in the core can we use it?

tim.plunkett’s picture

I don't believe we can use it any other places without some very ugly ArrayAccess BC, and not sure we want that.

But IMO, any new plugin type in contrib or core should be using object-based plugin definitions.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tim.plunkett’s picture

Version: 8.4.x-dev » 8.3.x-dev
EclipseGc’s picture

++

xjm’s picture

Version: 8.3.x-dev » 8.4.x-dev

Note that issues like this should be targeted against 8.4.x, but can be considered for backport once they are committed to that branch. See the updated alpha release policy. Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

We should have an explicit test of this functionality outside of the experimental layout module then. Just in case we remove the experimental module (unlikely though that is).

effulgentsia’s picture

Also, since this is a move from @internal to not, we should review the entire class, not just the diff.

The code being moved includes this:

  /**
   * The name of the annotation that contains the plugin definition.
   *
   * The class corresponding to this name must implement
   * \Drupal\Component\Annotation\AnnotationInterface.
   *
   * @var string|null
   */
  protected $pluginDefinitionAnnotationName;

  /**
   * ObjectDefinitionDiscoveryDecorator constructor.
   *
   * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
   *   The discovery object that is being decorated.
   * @param string $plugin_definition_annotation_name
   *   The name of the annotation that contains the plugin definition.
   */
  public function __construct(DiscoveryInterface $decorated, $plugin_definition_annotation_name) {
    $this->decorated = $decorated;
    $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
  }
  1. I think the comment about AnnotationInterface needs to be in the docs of the constructor. Either in addition to or instead of the docs of the protected property.
  2. AnnotationInterface doesn't extend PluginDefinitionInterface or its companions from the other recent issues. Wouldn't that then cause problems? Especially since the default in DefaultPluginManager::__construct() is Drupal\Component\Annotation\Plugin, which also doesn't implement those interfaces. So we might need docs here saying there's in practice additional expectations for $plugin_definition_annotation_name, and we might want to consider changing DefaultPluginManager's default value to something that meets those expectations.
tim.plunkett’s picture

Assigned: Unassigned » tim.plunkett

#10: will do

#11:
1) sure
2) Annotation != Definition
All of our annotations implement AnnotationInterface.
The return value of \Drupal\Component\Annotation\AnnotationInterface::get() is a definition. This is either an array or PluginDefinitionInterface.
I'm not sure what you want changed here.

tim.plunkett’s picture

Assigned: tim.plunkett » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
3.66 KB
4.82 KB
effulgentsia’s picture

+++ b/core/lib/Drupal/Component/Plugin/Discovery/ObjectDefinitionDiscoveryDecorator.php
@@ -1,20 +1,9 @@
  * Ensures that all array-based definitions are converted to objects.
...
+   *   The name of the annotation that contains the plugin definition. The class
+   *   corresponding to this name must implement
+   *   \Drupal\Component\Annotation\AnnotationInterface.

These two comments are contradictory. If all that's required is that the annotation class implements AnnotationInterface, then its get() method might return either an array or an object. So the statement at the top that ObjectDefinitionDiscoveryDecorator "ensures that all array-based definitions are converted to objects" is incorrect.

tim.plunkett’s picture

Agreed that it is confusing.
@effulgentsia and I discussed this at length, and he proposed a new name: AnnotationBridgeDecorator
I think the new name and the rewording of the docs is a big improvement.

tim.plunkett’s picture

@effulgentsia also suggested moving the namespace to match \Drupal\Component\Annotation\Plugin\Discovery\AnnotatedClassDiscovery.

tim.plunkett’s picture

Interdiff since #2, last time RTBC.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

This is a task to move the internal api to public so this makes it a feature request and I think we should have a change record for this 'feature request' so that core and contrib can use it as mentioned in #5.

+++ b/core/tests/Drupal/Tests/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecoratorTest.php
@@ -0,0 +1,61 @@
+    $expected = [

Let's add a comment that both discovers are converted to object.

The code looks good. The test looks good. My comments are just minor improvements, can be ignored if someone disagrees, and not commit blocker so RTBC.

effulgentsia’s picture

Thanks, @jibran! Ticking credit box for review.

  • effulgentsia committed 09769ab on 8.4.x
    Issue #2822752 by tim.plunkett, jibran: Allow object-based plugin...

  • effulgentsia committed 1ca7de3 on 8.3.x
    Issue #2822752 by tim.plunkett, jibran: Allow object-based plugin...
effulgentsia’s picture

Version: 8.4.x-dev » 8.3.x-dev
Status: Reviewed & tested by the community » Fixed

Pushed to 8.4.x. Cherry picked to 8.3.x, because it's low disruption and provides a great pattern by which contrib plugin managers can use object definitions with YAML discovery without each such contrib module creating their own solution, like LayoutPluginManager had to do prior to this issue.

Per #18, a CR to inform people of this addition (or maybe a single consolidated CR for all the improvements to using object definitions) would be great. As would be the follow-up to add a comment within the test coverage.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.