API page: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Dependenc...

   * Additional tag attributes supported by 'service_collector' only:
   *   - call: The method name to call on the consumer service. Defaults to
   *     'addHandler'. The called method receives two arguments:
   *     - The handler instance as first argument.
   *     - Optionally the handler's priority as second argument, if the method
   *       accepts a second parameter and its name is "priority". In any case,
   *       all handlers registered at compile time are sorted already.
   *
   * Example (YAML):
   * @code
   * tags:
   *   - { name: service_collector, tag: breadcrumb_builder, call: addBuilder }
   *   - { name: service_id_collector, tag: theme_negotiator }
   * @endcode
   *
   * Supported handler tag attributes:
   * - priority: An integer denoting the priority of the handler. Defaults to 0.

The above is incomplete and a little misleading.

Compare with the actual code:

    foreach ($params as $pos => $param) {
      if ($param->getClass()) {
        $interface = $param->getClass();
      }
      elseif ($param->getName() === 'id') {
        $id_pos = $pos;
      }
      elseif ($param->getName() === 'priority') {
        $priority_pos = $pos;
      }
      else {
        $extra_params[$param->getName()] = $pos;
      }
    }

...

      // Keep track of other tagged handlers arguments.
      foreach ($extra_params as $name => $pos) {
        $extra_arguments[$id][$pos] = isset($attributes[0][$name]) ? $attributes[0][$name] : $params[$pos]->getDefaultValue();
      }

We can see the following:

1. The handler instance must be the first parameter that has a class typehint. Apart from that, its position is not relevant. The docs though say:

> The handler instance as first argument

EDIT: nope, scratch that. Looks like a bug though, as the code has:

      $arguments[$interface_pos] = new Reference($id);

just that $interface_pos never gets set to anything other than 0.

2. The priority parameter can be in any position, so long as it is named 'priority'.

3. There can be an 'id' parameter, which gets passed the service ID if present.

4. There can in fact be any number of other parameters, which will be matched up with tag attributes on the collected services, so for example:

   * @code
   * tags:
   *   - { name: breadcrumb_builder, cake: chocolate }

will work with:

public function addHandler(MyHandlerInterface $handler, $cake) {
}

Issue fork drupal-3018091

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joachim created an issue. See original summary.

joachim’s picture

Issue summary: View changes

Oops, handler param DOES have to be first. At least for now.

shubhangi1995’s picture

Assigned: Unassigned » shubhangi1995
shubhangi1995’s picture

StatusFileSize
new1.55 KB

There is a patch with changed documentation please review:

shubhangi1995’s picture

Assigned: shubhangi1995 » Unassigned
Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 4: 3018091-12995622.patch, failed testing. View results

shubhangi1995’s picture

Assigned: Unassigned » shubhangi1995
vacho’s picture

StatusFileSize
new1.31 KB
new2.47 KB

I solve the problems with standars in patch.
For colaborate with @shubhangi1995 (congrats for contrib to drupal)

joachim’s picture

Thanks for making a patch.

However, the text the patch is adding doesn't really make much sense, and needs work for grammar too, and doesn't seem to cover all the points I mentioned. Additionally, the formatting needs cleaning up, but rather than keep rolling patches I suggest we work on text in comments first, and make a patch once something's finalized.

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.

wolffereast’s picture

I took a crack at updating the text to match what appears to be occurring:

   * Additional tag attributes supported by 'service_collector' only:
   *   - call: The method name to call on the consumer service. Defaults to
   *     'addHandler'. The called method may receive one or more arguments:
   *     - The handler instance must be the first argument.
   *     - All additional arguments will be passed through to the arguments
   *       array in the order in which they are received. 
   *     - The id and priority parameters can be used to position the id and
   *       priority values in the arguments array.

The processServiceCollectorPass sets the $interface based on the last param that returns a value for getClass():
if ($param->getClass())
It then throws an error if $interface is not set, so the requirement for the Error to throw is not related to the position of the $interface.
Then later it sets the interface_position of the arguments array to a Reference to the $id, which is the key of the array returned by the $container->findTaggedServiceIds. That key, according to the docs, is the tagged service.
foreach ($container->findTaggedServiceIds($tag) as $id => $attributes) {

$arguments[$interface_pos] = new Reference($id);

Then the $priority_pos and $id_pos are set based on their passed order.

As mentioned the $interface_position is always 0, so it is technically possible to accidentally overwrite the Reference($id) in $arguments[0] if either the priority or id are sent through in position 0. Definitely feels like a bug. Along the same lines, the array += operation for the additional arguments could result in a lost argument if one is sent through in position 0 as the $arguments[0] item will take precedence over the $extra_arguments[0].

@joachim should the issue with the interface position be a part of this ticket, or does that feel out of scope?

joachim’s picture

> @joachim should the issue with the interface position be a part of this ticket, or does that feel out of scope?

This is a documentation only issue, so yes, the bug in the code is out of scope. We can file a follow up once this is issue is fixed.

The text is a very good start, but it's not yet saying anything about the method parameter names being matched up to the tag property names.

joachim’s picture

How about this:

- The handler instance must be the first method parameter, and it must have a type hint.
- If the method has a parameter named $id, in any position, it will receive the service ID when called.
- If the method has a parameter named $priority, in any position, it will receive the value of the tag's 'priority' attribute.
- Any other method parameters whose names match the name of an attribute of the tag will receive the value of that tag attribute. The order of the method parameters and the order of the service tag attributes do not need to match.

joachim’s picture

Status: Needs work » Needs review

Setting to NR for review of the text.

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.

guilhermevp’s picture

Assigned: shubhangi1995 » guilhermevp
longwave’s picture

@joachim's suggested text in #13 looks OK to me, let's go with that.

guilhermevp’s picture

Thanks @longwave!

Sending MR, please review!

guilhermevp’s picture

Thanks @joachim, updated merge request!

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for working on this. The updated docs read well to me and the description matches my understanding of the code in ::processServiceCollectorPass().

longwave’s picture

joachim’s picture

> Given $priority is really no different to any other parameters, do we need to call it out with its own bullet point?

I guess I wrote it like that because I was working through the code's functionality. But it makes sense because 'priority' is invented by the service collector system, whereas other tags are arbitrary and would be invented by implementations.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 1e4bd68bb6 to 9.3.x and 37edc2d7ab to 9.2.x. Thanks!

  • alexpott committed 1e4bd68 on 9.3.x
    Issue #3018091 by guilhermevp, vacho, shubhangi1995, joachim, longwave,...

Status: Fixed » Closed (fixed)

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