Problem/Motivation

Symfony services can have arrays as arguments that contain services that are wrapped in a memoizing closure.

Those arguments are then converted to \Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument by the container builder.

They are not supported by \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::dumpValue().

Proposed resolution

Convert \Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument to an array so we can dump it.

Remaining tasks

User interface changes

None

API changes

No change.

Data model changes

None

Comments

bonrita created an issue. See original summary.

bonrita’s picture

Issue summary: View changes
bonrita’s picture

Version: 8.8.x-dev » 8.9.x-dev
bonrita’s picture

Assigned: bonrita » Unassigned
bonrita’s picture

StatusFileSize
new2.34 KB
bonrita’s picture

bonrita’s picture

StatusFileSize
new3.68 KB
bonrita’s picture

StatusFileSize
new1.8 KB
new3.91 KB
bonrita’s picture

Status: Needs work » Needs review
bonrita’s picture

Status: Needs review » Active
bonrita’s picture

StatusFileSize
new2.7 KB
new4.03 KB
longwave’s picture

Status: Active » Needs review
bonrita’s picture

This patch is not part of this issue. It is here to combine all the patches that patch the '\Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper' file so as to prevent conflicts.
It combines issues: 3108020, 3108039 and 2961380

Status: Needs review » Needs work

The last submitted patch, 13: combined-patches-for-issues-2961380-3108020-3108039.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

bonrita’s picture

StatusFileSize
new7.04 KB
bonrita’s picture

bonrita’s picture

Status: Needs work » Needs review
bonrita’s picture

Category: Task » Feature request

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.

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.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.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

cyberwolf’s picture

The provided patch does not handle ServiceClosureArgument correctly. The class that will be using this argument, ServiceLocatorTrait, expects it to be a callable and passes itself as an argument when calling it. The return value should be the actual service. See ServiceLocatorTrait::get():

return $this->factories[$id]($this);

Instead, with the patch the service itself is dumped thus $this->factories[$id] is already the service.

I tried to modify OptimizedPhpArrayDumper a bit and use a closure for the factory instead, however dumping closures is not supported. So eventually I had to use an additional class for the factory. Unfortunately I had to use the static \Drupal::getContainer() in this class. Maybe better solutions for this problem exist, but I'm out of ideas at the moment. Symfony's PhpDumper has a lot more freedom and flexibility in this regards, as it can just just any possible PHP code.

Changes in OptimizedPhpArrayDumper:

elseif ($value instanceof ServiceClosureArgument) {
      $reference = $value->getValues();
      /** @var Reference $reference */
      $reference = reset($reference);

      // We use a special Invokable class here, as closures can not be
      // serialized.
      // @see \Symfony\Component\DependencyInjection\Dumper::PhpDumper::dumpValue().
      return new DumpedServiceClosureArgument((string) $reference);
    }

The additional class:

namespace Drupal\Component\DependencyInjection\Dumper;

use Psr\Container\ContainerInterface;

class DumpedServiceClosureArgument {

  public function __construct(protected string $serviceId) {

  }

  public function __invoke(ContainerInterface $serviceLocator) {
    $container = \Drupal::getContainer();
    return $container->get($this->serviceId);
  }

}
longwave’s picture

cyberwolf’s picture

StatusFileSize
new3.01 KB

I tought another approach, based on how 'private_service' is done. ServiceClosureArgument is dumped now to a stdClass and then in the container itself it's converted to a closure.

Attached a patch based on the 9.5.x branch.

I am not sure when / under which conditions Drupal\Component\DependencyInjection\PhpArrayContainer is used though, so I could not verify my changes in there.

cyberwolf’s picture

StatusFileSize
new3 KB

Patch in #27 contained a mistake, attaching a new one.

longwave’s picture

cyberwolf’s picture

Assigned: Unassigned » cyberwolf
Status: Needs review » Needs work

Thanks! I will have a closer look at the other patch, it seems pretty close to my last attempt but might contain some stuff I missed.
I am preparing unit tests as well.

cyberwolf’s picture

StatusFileSize
new5.14 KB
new8.77 KB
cyberwolf’s picture

Status: Needs work » Needs review
cyberwolf’s picture

Assigned: cyberwolf » Unassigned
longwave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for adding the tests. This looks OK to me and will simplify swapping out the event dispatcher for Symfony's one.

alexpott’s picture

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

I think we need a CR record here to tell people that we now support this. The patch looks good.

borisson_’s picture

Added a draft change record, we should add an example in the change record of how this looks in a services file. I don't understand this enough to add a good example.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

znerol’s picture

Status: Needs work » Needs review
znerol’s picture

Status: Needs review » Needs work
Issue tags: -Needs change record +Needs reroll

#31 fails to apply, needs a reroll.

sagarchauhan’s picture

Status: Needs work » Needs review
StatusFileSize
new8.75 KB
new6.2 KB

Rerolled patch on #31

sagarchauhan’s picture

StatusFileSize
new8.72 KB
new6.1 KB

Reuploading the patch after fixing issues.

znerol’s picture

Status: Needs review » Reviewed & tested by the community

No substantial changes since #34, hence RTBC.

I removed the service declaration from the change record, since that isn't working with the custom YamlFileLoader Drupal is currently using. But for service definitions built programmatically, this patch still brings some benefits.

znerol’s picture

(also added a change record)

longwave’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs reroll

Committed and pushed 92e703a69a to 11.x. Thanks!

Let's continue in #2909185: Replace ContainerAwareEventDispatcher with Symfony EventDispatcher which should become almost trivial now.

  • longwave committed 92e703a6 on 11.x
    Issue #3108020 by bonrita, Cyberwolf, sagarchauhan, znerol, borisson_:...

Status: Fixed » Closed (fixed)

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

dpi’s picture

Just created a new issue for following up on ServiceClosureArgument with private services: #3391860: ServiceClosureArgument with private service references original non-existent service