8000 feature #43386 [DependencyInjection] Extend TaggedIterator and Tagged… · symfony/symfony@f36d0e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit f36d0e0

Browse files
committed
feature #43386 [DependencyInjection] Extend TaggedIterator and TaggedLocator Attributes with able to specify defaultIndexMethod for #[TaggerIterator] and #[TaggedLocator] (fractalzombie)
This PR was merged into the 5.4 branch. Discussion ---------- [DependencyInjection] Extend TaggedIterator and TaggedLocator Attributes with able to specify defaultIndexMethod for #[TaggerIterator] and #[TaggedLocator] | Q | A | ------------- | --- | Branch? | 5.4 | Bugfix? | no | New feature? | yes (updated) | Deprecations? | no | Tickets | no ticket, the only contribution for fun and enjoy | License | MIT | Doc PR | no, it's not a new feature, this we can do through YAML, but not through new PHP attributes, now we can do it through attributes. Just extended one attribute that do not break compatibility, is optional and null. The feature only allows you to do almost the same as in YAML files, the configuration specifying defaultIndexMethod for: ``` - \ Symfony \ Component \ DependencyInjection \ Attribute \ TaggedIterator - \ Symfony \ Component \ DependencyInjection \ Attribute \ TaggedLocator ``` Commits ------- 8c4651a [DependencyInjection] Extend TaggedIterator and TaggedLocator Attributes with able to specify defaultIndexMethod and defaultPriorityMethod for #[TaggerIterator] and #[TaggedLocator]
2 parents cf8a997 + 8c4651a commit f36d0e0

11 files changed

+289
-10
lines changed

src/Symfony/Component/DependencyInjection/Attribute/TaggedIterator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class TaggedIterator
1717
public function __construct(
1818
public string $tag,
1919
public ?string $indexAttribute = null,
20+
public ?string $defaultIndexMethod = null,
21+
public ?string $defaultPriorityMethod = null,
2022
) {
2123
}
2224
}

src/Symfony/Component/DependencyInjection/Attribute/TaggedLocator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class TaggedLocator
1717
public function __construct(
1818
public string $tag,
1919
public ?string $indexAttribute = null,
20+
public ?string $defaultIndexMethod = null,
21+
public ?string $defaultPriorityMethod = null,
2022
) {
2123
}
2224
}

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ CHANGELOG
33

44
5.4
55
---
6-
6+
* Add `$defaultIndexMethod` and `$defaultPriorityMethod` to `TaggedIterator` and `TaggedLocator` attributes
77
* Add `service_closure()` to the PHP-DSL
88
* Add support for autoconfigurable attributes on methods, properties and parameters
99
* Make auto-aliases private by default

src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,13 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
252252
foreach ($parameter->getAttributes() as $attribute) {
253253
if (TaggedIterator::class === $attribute->getName()) {
254254
$attribute = $attribute->newInstance();
255-
$arguments[$index] = new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute);
255+
$arguments[$index] = new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, false, $attribute->defaultPriorityMethod);
256256
break;
257257
}
258258

259259
if (TaggedLocator::class === $attribute->getName()) {
260260
$attribute = $attribute->newInstance();
261-
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, true));
261+
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, true, $attribute->defaultPriorityMethod));
262262
break;
263263
}
264264
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Lines changed: 165 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@
3333
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooBarTaggedForDefaultPriorityClass;
3434
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooTagClass;
3535
use Symfony\Component\DependencyInjection\Tests\Fixtures\IteratorConsumer;
36+
use Symfony\Component\DependencyInjection\Tests\Fixtures\IteratorConsumerWithDefaultIndexMethod;
37+
use Symfony\Component\DependencyInjection\Tests\Fixtures\IteratorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod;
38+
use Symfony\Component\DependencyInjection\Tests\Fixtures\IteratorConsumerWithDefaultPriorityMethod;
3639
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumer;
3740
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerConsumer;
3841
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerFactory;
42+
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithDefaultIndexMethod;
43+
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod;
44+
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithDefaultPriorityMethod;
3945
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithoutIndex;
4046
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService1;
4147
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService2;
@@ -354,30 +360,85 @@ public function testTaggedServiceWithIndexAttributeAndDefaultMethodConfiguredVia
354360
$this->assertSame(['bar_tab_class_with_defaultmethod' => $container->get(BarTagClass::class), 'foo' => $container->get(FooTagClass::class)], $param);
355361
}
356362

357-
public function testTaggedIteratorWithMultipleIndexAttribute()
363+
/**
364+
* @requires PHP 8
365+
*/
366+
public function testTaggedIteratorWithDefaultIndexMethodConfiguredViaAttribute()
358367
{
359368
$container = new ContainerBuilder();
360369
$container->register(BarTagClass::class)
361370
->setPublic(true)
362-
->addTag('foo_bar', ['foo' => 'bar'])
363-
->addTag('foo_bar', ['foo' => 'bar_duplicate'])
371+
->addTag('foo_bar')
364372
;
365373
$container->register(FooTagClass::class)
366374
->setPublic(true)
367375
->addTag('foo_bar')
376+
;
377+
$container->register(IteratorConsumerWithDefaultIndexMethod::class)
378+
->setAutowired(true)
379+
->setPublic(true)
380+
;
381+
382+
$container->compile();
383+
384+
$s = $container->get(IteratorConsumerWithDefaultIndexMethod::class);
385+
386+
$param = iterator_to_array($s->getParam()->getIterator());
387+
$this->assertSame(['bar_tag_class' => $container->get(BarTagClass::class), 'foo_tag_class' => $container->get(FooTagClass::class)], $param);
388+
}
389+
390+
/**
391+
* @requires PHP 8
392+
*/
393+
public function testTaggedIteratorWithDefaultPriorityMethodConfiguredViaAttribute()
394+
{
395+
$container = new ContainerBuilder();
396+
$container->register(BarTagClass::class)
397+
->setPublic(true)
368398
->addTag('foo_bar')
369399
;
370-
$container->register(FooBarTaggedClass::class)
371-
->addArgument(new TaggedIteratorArgument('foo_bar', 'foo'))
400+
$container->register(FooTagClass::class)
401+
->setPublic(true)
402+
->addTag('foo_bar')
403+
;
404+
$container->register(IteratorConsumerWithDefaultPriorityMethod::class)
405+
->setAutowired(true)
372406
->setPublic(true)
373407
;
374408

375409
$container->compile();
376410

377-
$s = $container->get(FooBarTaggedClass::class);
411+
$s = $container->get(IteratorConsumerWithDefaultPriorityMethod::class);
412+
413+
$param = iterator_to_array($s->getParam()->getIterator());
414+
$this->assertSame([0 => $container->get(FooTagClass::class), 1 => $container->get(BarTagClass::class)], $param);
415+
}
416+
417+
/**
418+
* @requires PHP 8
419+
*/
420+
public function testTaggedIteratorWithDefaultIndexMethodAndWithDefaultPriorityMethodConfiguredViaAttribute()
421+
{
422+
$container = new ContainerBuilder();
423+
$container->register(BarTagClass::class)
424+
->setPublic(true)
425+
->addTag('foo_bar')
426+
;
427+
$container->register(FooTagClass::class)
428+
->setPublic(true)
429+
->addTag('foo_bar')
430+
;
431+
$container->register(IteratorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod::class)
432+
->setAutowired(true)
433+
->setPublic(true)
434+
;
435+
436+
$container->compile();
437+
438+
$s = $container->get(IteratorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod::class);
378439

379440
$param = iterator_to_array($s->getParam()->getIterator());
380-
$this->assertSame(['bar' => $container->get(BarTagClass::class), 'bar_duplicate' => $container->get(BarTagClass::class), 'foo_tag_class' => $container->get(FooTagClass::class)], $param);
441+
$this->assertSame(['foo_tag_class' => $container->get(FooTagClass::class), 'bar_tag_class' => $container->get(BarTagClass::class)], $param);
381442
}
382443

383444
/**
@@ -438,6 +499,103 @@ public function testTaggedLocatorConfiguredViaAttributeWithoutIndex()
438499
self::assertSame($container->get(FooTagClass::class), $locator->get(FooTagClass::class));
439500
}
440501

502+
/**
503+
* @requires PHP 8
504+
*/
505+
public function testTaggedLocatorWithDefaultIndexMethodConfiguredViaAttribute()
506+
{
507+
$container = new ContainerBuilder();
508+
$container->register(BarTagClass::class)
509+
->setPublic(true)
510+
->addTag('foo_bar')
511+
;
512+
$container->register(FooTagClass::class)
513+
->setPublic(true)
514+
->addTag('foo_bar')
515+
;
516+
$container->register(LocatorConsumerWithDefaultIndexMethod::class)
517+
->setAutowired(true)
518+
->setPublic(true)
519+
;
520+
521+
$container->compile();
522+
523+
/** @var LocatorConsumerWithoutIndex $s */
524+
$s = $container->get(LocatorConsumerWithDefaultIndexMethod::class);
525+
526+
$locator = $s->getLocator();
527+
self::assertSame($container->get(BarTagClass::class), $locator->get('bar_tag_class'));
528+
self::assertSame($container->get(FooTagClass::class), $locator->get('foo_tag_class'));
529+
}
530+
531+
/**
532+
* @requires PHP 8
533+
*/
534+
public function testTaggedLocatorWithDefaultPriorityMethodConfiguredViaAttribute()
535+
{
536+
$container = new ContainerBuilder();
537+
$container->register(BarTagClass::class)
538+
->setPublic(true)
539+
->addTag('foo_bar')
540+
;
541+
$container->register(FooTagClass::class)
542+
->setPublic(true)
543+
->addTag('foo_bar')
544+
;
545+
$container->register(LocatorConsumerWithDefaultPriorityMethod::class)
546+
->setAutowired(true)
547+
->setPublic(true)
548+
;
549+
550+
$container->compile();
551+
552+
/** @var LocatorConsumerWithoutIndex $s */
553+
$s = $container->get(LocatorConsumerWithDefaultPriorityMethod::class);
554+
555+
$locator = $s->getLocator();
556+
557+
// We need to check priority of instances in the factories
558+
$factories = (new \ReflectionClass($locator))->getProperty('factories');
559+
$factories->setAccessible(true);
560+
561+
self::assertSame([FooTagClass::class, BarTagClass::class], array_keys($factories->getValue($locator)));
562+
}
563+
564+
/**
565+
* @requires PHP 8
566+
*/
567+
public function testTaggedLocatorWithDefaultIndexMethodAndWithDefaultPriorityMethodConfiguredViaAttribute()
568+
{
569+
$container = new ContainerBuilder();
570+
$container->register(BarTagClass::class)
571+
->setPublic(true)
572+
->addTag('foo_bar')
573+
;
574+
$container->register(FooTagClass::class)
575+
->setPublic(true)
576+
->addTag('foo_bar')
577+
;
578+
$container->register(LocatorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod::class)
579+
->setAutowired(true)
580+
->setPublic(true)
581+
;
582+
583+
$container->compile();
584+
585+
/** @var LocatorConsumerWithoutIndex $s */
586+
$s = $container->get(LocatorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod::class);
587+
588+
$locator = $s->getLocator();
589+
590+
// We need to check priority of instances in the factories
591+
$factories = (new \ReflectionClass($locator))->getProperty('factories');
592+
$factories->setAccessible(true);
593+
594+
self::assertSame(['foo_tag_class', 'bar_tag_class'], array_keys($factories->getValue($locator)));
595+
self::assertSame($container->get(BarTagClass::class), $locator->get('bar_tag_class'));
596+
self::assertSame($container->get(FooTagClass::class), $locator->get('foo_tag_class'));
597+
}
598+
441599
/**
442600
* @requires PHP 8
443601
*/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
6+
7+
final class IteratorConsumerWithDefaultIndexMethod
8+
{
9+
public function __construct(
10+
#[TaggedIterator(tag: 'foo_bar', defaultIndexMethod: 'getDefaultFooName')]
11+
private iterable $param,
12+
) {
13+
}
14+
15+
public function getParam(): iterable
16+
{
17+
return $this->param;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
6+
7+
final class IteratorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod
8+
{
9+
public function __construct(
10+
#[TaggedIterator(tag: 'foo_bar', defaultIndexMethod: 'getDefaultFooName', defaultPriorityMethod: 'getPriority')]
11+
private iterable $param,
12+
) {
13+
}
14+
15+
public function getParam(): iterable
16+
{
17+
return $this->param;
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
6+
7+
final class IteratorConsumerWithDefaultPriorityMethod
8+
{
9+
public function __construct(
10+
#[TaggedIterator(tag: 'foo_bar', defaultPriorityMethod: 'getPriority')]
11+
private iterable $param,
12+
) {
13+
}
14+
15+
public function getParam(): iterable
16+
{
17+
return $this->param;
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Psr\Container\ContainerInterface;
6+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
7+
8+
final class LocatorConsumerWithDefaultIndexMethod
9+
{
10+
public function __construct(
11+
#[TaggedLocator(tag: 'foo_bar', defaultIndexMethod: 'getDefaultFooName')]
12+
private ContainerInterface $locator,
13+
) {
14+
}
15+
16+
public function getLocator(): ContainerInterface
17+
{
18+
return $this->locator;
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Psr\Container\ContainerInterface;
6+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
7+
8+
final class LocatorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod
9+
{
10+
public function __construct(
11+
#[TaggedLocator(tag: 'foo_bar', defaultIndexMethod: 'getDefaultFooName', defaultPriorityMethod: 'getPriority')]
12+
private ContainerInterface $locator,
13+
) {
14+
}
15+
16+
public function getLocator(): ContainerInterface
17+
{
18+
return $this->locator;
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Psr\Container\ContainerInterface;
6+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
7+
8+
final class LocatorConsumerWithDefaultPriorityMethod
9+
{
10+
public function __construct(
11+
#[TaggedLocator(tag: 'foo_bar', defaultPriorityMethod: 'getPriority')]
12+
private ContainerInterface $locator,
13+
) {
14+
}
15+
16+
public function getLocator(): ContainerInterface
17+
{
18+
return $this->locator;
19+
}
20+
}

0 commit comments

Comments
 (0)
0