Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c4651a

Browse files
committed
[DependencyInjection] Extend TaggedIterator and TaggedLocator Attributes with able to specify defaultIndexMethod and defaultPriorityMethod for #[TaggerIterator] and #[TaggedLocator]
1 parent 626d9aa commit 8c4651a

11 files changed

+289
-12
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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,6 @@ private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot,
223223
/**
224224
* Autowires the constructor or a method.
225225
*
226-
* @return array
227-
*
228226
* @throws AutowiringFailedException
229227
*/
230228
private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments, bool $checkAttributes, int $methodIndex): array
@@ -250,13 +248,13 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
250248
foreach ($parameter->getAttributes() as $attribute) {
251249
if (TaggedIterator::class === $attribute->getName()) {
252250
$attribute = $attribute->newInstance();
253-
$arguments[$index] = new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute);
251+
$arguments[$index] = new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, false, $attribute->defaultPriorityMethod);
254252
break;
255253
}
256254

257255
if (TaggedLocator::class === $attribute->getName()) {
258256
$attribute = $attribute->newInstance();
259-
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, true));
257+
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, true, $attribute->defaultPriorityMethod));
260258
break;
261259
}
262260
}

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)