Problem/Motivation

The documentation for the constructor in \Drupal\Component\Plugin\ContextAwarePluginBase indicates that the context key can be used to define context values in the configuration array. The call to createContextFromConfiguration supports this, however the functionality does not work as intended due to a typo.

I came across this issue while developing a custom context aware plugin type that makes use of derivatives each with a unique context. In order to supply the context I passed it in via the configuration array however this then lead to an unexpected error when trying to access the value that had apparently not been set.

Proposed resolution

Change the constructor in core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php by removing the rogue "s" such that it reads $this->context instead of $this->contexts.

In the meantime until the bug is fixed developers will need to override the constructor to manually call createContextFromConfiguration.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dbalcomb created an issue. See original summary.

rakesh.gectcr’s picture

Status: Active » Needs review
FileSize
659 bytes

Let me check the , will the patch get failed or not ?

Berdir’s picture

Issue tags: +Needs tests

I can confirm that there clearly is a mismatch but apparently nothing in core uses this. We definitely need some tests to show how this is supposed to work.

Xano’s picture

Issue tags: -Needs tests
FileSize
3.04 KB

A related problem here is that plugin configuration is internal. Constructors shouldn't document its structure, as the allowed configuration is equal to whatever ConfigurablePluginInterface::getConfiguration() returns: an array with arbitrary content, as decided by the plugin itself. This is what caused this problem to be hidden in the first place.

This patch builds upon @rakesh.gectcr's original solution, but also deprecates the aforementioned behavior, and documents the better alternative approach.

Status: Needs review » Needs work

The last submitted patch, 4: drupal_2623050_4.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
928 bytes
3.11 KB

Status: Needs review » Needs work

The last submitted patch, 6: drupal_2623050_6.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
2.1 KB
5.21 KB
tim.plunkett’s picture

Status: Needs review » Needs work
+++ b/core/modules/node/src/Tests/Condition/NodeConditionTest.php
@@ -79,7 +79,9 @@ function testConditions() {
     // Test Constructor injection.
-    $condition = $manager->createInstance('node_type', array('bundles' => array('article' => 'article'), 'context' => array('node' => $article)));
+    /** @var \Drupal\node\Plugin\Condition\NodeType $condition */
+    $condition = $manager->createInstance('node_type', array('bundles' => array('article' => 'article')));
+    $condition->setContextValue('node', $article);
     $this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.');

+++ b/core/modules/user/src/Tests/Condition/UserRoleConditionTest.php
@@ -141,7 +141,9 @@ public function testConditions() {
     // Test Constructor injection.
-    $condition = $this->manager->createInstance('user_role', array('roles' => array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID), 'context' => array('user' => $this->authenticated)));
+    /** @var \Drupal\user\Plugin\Condition\UserRole $condition */
+    $condition = $this->manager->createInstance('user_role', array('roles' => array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)));
+    $condition->setContextValue('user', $this->authenticated);
     $this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.');

This is explicitly testing the constructor injection of context. Please revert.

Xano’s picture

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

cilefen’s picture

Issue tags: -Novice

I don't think a Novice can review this.

Status: Needs review » Needs work

The last submitted patch, 10: drupal_2623050_10.patch, failed testing.

The last submitted patch, 10: drupal_2623050_10.patch, failed testing.

Xano’s picture

Re-roll.

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

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

benjifisher’s picture

Issue summary: View changes
Status: Needs review » Needs work

I noticed this typo, then found that this issue had already been posted. Fixing the typo would be a one-line change as in the original patch (although the test coverage is a lot more than that). So I am curious why you replace

    $context_configuration = isset($configuration['context']) ? $configuration['context'] : [];
    unset($configuration['context']);

    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->contexts = $this->createContextFromConfiguration($context_configuration);

with

    parent::__construct($configuration, $plugin_id, $plugin_definition);
    if (isset($configuration['context'])) {
      trigger_error(sprintf('Passing contexts in plugin configuration has been deprecated, because contexts are no real plugin configuration. Use %s::setContext() instead.', static::class), E_USER_DEPRECATED);
      $context_configuration = $configuration['context'];
      unset($configuration['context']);
      $this->context = $this->createContextFromConfiguration($context_configuration);
    }

This does the following:

  1. Fix the typo.
  2. Move the unset() from before the parent constructor to after (at which point it is irrelevant).
  3. Add a deprecation notice.
  4. Move the definition of $this->context inside an if block.

Of these, (1) is the original point of this issue. Does (2) make a difference? You explained your reasons for (3) in #4. I do not know enough to agree or disagree with that decision, but it seems like scope creep for this issue. I also do not know whether (4) is a good idea, but it is a change, and might break some code.

The deprecation notice is not translatable. Also, there is a typo (or grammatical mistake). If we decide to keep it, I suggest something like

      $message = t('Passing contexts in plugin configuration has been deprecated, because contexts are not real plugin configuration. Use %method instead.', array('%method' => static::class . '::setContext()'));
      trigger_error($message, E_USER_DEPRECATED);

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.

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

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

Version: 8.5.x-dev » 8.6.x-dev

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

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Lendude’s picture

Status: Needs work » Closed (duplicate)
Issue tags: +Bug Smash Initiative