@@ -65,61 +65,69 @@ private function findAndSortTaggedServices(string|TaggedIteratorArgument $tagNam
6565 $ class = $ definition ->getClass ();
6666 $ class = $ container ->getParameterBag ()->resolveValue ($ class ) ?: null ;
6767 $ reflector = null !== $ class ? $ container ->getReflectionClass ($ class ) : null ;
68- $ checkTaggedItem = !$ definition ->hasTag ($ definition ->isAutoconfigured () ? 'container.ignore_attributes ' : $ tagName );
68+ $ loadFromDefaultMethods = $ reflector && null !== $ defaultPriorityMethod ;
69+ $ phpAttributes = $ definition ->isAutoconfigured () && !$ definition ->hasTag ('container.ignore_attributes ' ) ? $ reflector ?->getAttributes(AsTaggedItem::class) : [];
70+
71+ foreach ($ phpAttributes ??= [] as $ i => $ attribute ) {
72+ $ attribute = $ attribute ->newInstance ();
73+ $ phpAttributes [$ i ] = [
74+ 'priority ' => $ attribute ->priority ,
75+ $ indexAttribute ?? '' => $ attribute ->index ,
76+ ];
77+ if (null === $ defaultPriority ) {
78+ $ defaultPriority = $ attribute ->priority ?? 0 ;
79+ $ defaultIndex = $ attribute ->index ;
80+ }
81+ }
82+ if (1 >= \count ($ phpAttributes )) {
83+ $ phpAttributes = [];
84+ }
85+
86+ for ($ i = 0 ; $ i < \count ($ attributes ); ++$ i ) {
87+ if (!($ attribute = $ attributes [$ i ]) && $ phpAttributes ) {
88+ array_splice ($ attributes , $ i --, 1 , $ phpAttributes );
89+ continue ;
90+ }
6991
70- foreach ($ attributes as $ attribute ) {
7192 $ index = $ priority = null ;
7293
7394 if (isset ($ attribute ['priority ' ])) {
7495 $ priority = $ attribute ['priority ' ];
75- } elseif (null === $ defaultPriority && $ defaultPriorityMethod && $ reflector ) {
76- $ defaultPriority = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultPriorityMethod , $ tagName , 'priority ' , $ checkTaggedItem );
96+ } elseif ($ loadFromDefaultMethods ) {
97+ $ defaultPriority = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultPriorityMethod , $ tagName , 'priority ' ) ?? $ defaultPriority ;
98+ $ defaultIndex = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultIndexMethod ?? 'getDefaultName ' , $ tagName , $ indexAttribute ) ?? $ defaultIndex ;
99+ $ loadFromDefaultMethods = false ;
77100 }
78101 $ priority ??= $ defaultPriority ??= 0 ;
79102
80103 if (null === $ indexAttribute && !$ defaultIndexMethod && !$ needsIndexes ) {
81- $ services [] = [$ priority , ++ $ i , null , $ serviceId , null ];
104+ $ services [] = [$ priority , $ i , null , $ serviceId , null ];
82105 continue 2 ;
83106 }
84107
85108 if (null !== $ indexAttribute && isset ($ attribute [$ indexAttribute ])) {
86109 $ index = $ parameterBag ->resolveValue ($ attribute [$ indexAttribute ]);
87110 }
88- if (null === $ index && null === $ defaultIndex && $ defaultPriorityMethod && $ reflector ) {
89- $ defaultIndex = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultIndexMethod ?? 'getDefaultName ' , $ tagName , $ indexAttribute , $ checkTaggedItem );
111+ if (null === $ index && $ loadFromDefaultMethods ) {
112+ $ defaultPriority = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultPriorityMethod , $ tagName , 'priority ' ) ?? $ defaultPriority ;
113+ $ defaultIndex = PriorityTaggedServiceUtil::getDefault ($ serviceId , $ reflector , $ defaultIndexMethod ?? 'getDefaultName ' , $ tagName , $ indexAttribute ) ?? $ defaultIndex ;
114+ $ loadFromDefaultMethods = false ;
90115 }
91116 $ index ??= $ defaultIndex ??= $ definition ->getTag ('container.decorator ' )[0 ]['id ' ] ?? $ serviceId ;
92117
93- $ services [] = [$ priority , ++$ i , $ index , $ serviceId , $ class ];
94- }
95-
96- if ($ reflector ) {
97- $ attributes = $ reflector ->getAttributes (AsTaggedItem::class);
98- $ attributeCount = \count ($ attributes );
99-
100- foreach ($ attributes as $ attribute ) {
101- $ instance = $ attribute ->newInstance ();
102-
103- if (!$ instance ->index && 1 < $ attributeCount ) {
104- throw new InvalidArgumentException (\sprintf ('Attribute "%s" on class "%s" cannot have an empty index when repeated. ' , AsTaggedItem::class, $ class ));
105- }
106-
107- $ services [] = [$ instance ->priority ?? 0 , ++$ i , $ instance ->index ?? $ serviceId , $ serviceId , $ class ];
108- }
118+ $ services [] = [$ priority , $ i , $ index , $ serviceId , $ class ];
109119 }
110120 }
111121
112122 uasort ($ services , static fn ($ a , $ b ) => $ b [0 ] <=> $ a [0 ] ?: $ a [1 ] <=> $ b [1 ]);
113123
114124 $ refs = [];
115125 foreach ($ services as [, , $ index , $ serviceId , $ class ]) {
116- if (!$ class ) {
117- $ reference = new Reference ($ serviceId );
118- } elseif ($ index === $ serviceId ) {
119- $ reference = new TypedReference ($ serviceId , $ class );
120- } else {
121- $ reference = new TypedReference ($ serviceId , $ class , ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE , $ index );
122- }
126+ $ reference = match (true ) {
127+ !$ class => new Reference ($ serviceId ),
128+ $ index === $ serviceId => new TypedReference ($ serviceId , $ class ),
129+ default => new TypedReference ($ serviceId , $ class , ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE , $ index ),
130+ };
123131
124132 if (null === $ index ) {
125133 $ refs [] = $ reference ;
@@ -137,25 +145,16 @@ private function findAndSortTaggedServices(string|TaggedIteratorArgument $tagNam
137145 */
138146class PriorityTaggedServiceUtil
139147{
140- public static function getDefault (string $ serviceId , \ReflectionClass $ r , string $ defaultMethod , string $ tagName , ?string $ indexAttribute, bool $ checkTaggedItem ): string |int |null
148+ public static function getDefault (string $ serviceId , \ReflectionClass $ r , string $ defaultMethod , string $ tagName , ?string $ indexAttribute ): string |int |null
141149 {
142- $ class = $ r ->getName ();
143-
144- if (!$ checkTaggedItem && !$ r ->hasMethod ($ defaultMethod )) {
145- return null ;
146- }
147-
148- if ($ checkTaggedItem && !$ r ->hasMethod ($ defaultMethod )) {
149- foreach ($ r ->getAttributes (AsTaggedItem::class) as $ attribute ) {
150- return 'priority ' === $ indexAttribute ? $ attribute ->newInstance ()->priority : $ attribute ->newInstance ()->index ;
151- }
152-
150+ if (!$ r ->hasMethod ($ defaultMethod )) {
153151 return null ;
154152 }
155153
156154 if ($ r ->isInterface ()) {
157155 return null ;
158156 }
157+ $ class = $ r ->name ;
159158
160159 if (null !== $ indexAttribute ) {
161160 $ service = $ class !== $ serviceId ? \sprintf ('service "%s" ' , $ serviceId ) : 'on the corresponding service ' ;
0 commit comments