@@ -35,6 +35,11 @@ class RouteCollection implements \IteratorAggregate, \Countable
35
35
*/
36
36
private $ resources = [];
37
37
38
+ /**
39
+ * @var int[]
40
+ */
41
+ private $ priorities = [];
42
+
38
43
public function __clone ()
39
44
{
40
45
foreach ($ this ->routes as $ name => $ route ) {
@@ -53,7 +58,7 @@ public function __clone()
53
58
*/
54
59
public function getIterator ()
55
60
{
56
- return new \ArrayIterator ($ this ->routes );
61
+ return new \ArrayIterator ($ this ->all () );
57
62
}
58
63
59
64
/**
@@ -66,11 +71,22 @@ public function count()
66
71
return \count ($ this ->routes );
67
72
}
68
73
69
- public function add (string $ name , Route $ route )
74
+ /**
75
+ * @param int $priority
76
+ */
77
+ public function add (string $ name , Route $ route/*, int $priority = 0*/ )
70
78
{
71
- unset($ this ->routes [$ name ]);
79
+ if (\func_num_args () < 3 && __CLASS__ !== static ::class && __CLASS__ !== (new \ReflectionMethod ($ this , __FUNCTION__ ))->getDeclaringClass ()->getName () && !$ this instanceof \PHPUnit \Framework \MockObject \MockObject && !$ this instanceof \Prophecy \Prophecy \ProphecySubjectInterface) {
80
+ @trigger_error (sprintf ('The "%s()" method will have a new "int $priority = 0" argument in version 6.0, not defining it is deprecated since Symfony 5.1. ' , __METHOD__ ), E_USER_DEPRECATED );
81
+ }
82
+
83
+ unset($ this ->routes [$ name ], $ this ->priorities [$ name ]);
72
84
73
85
$ this ->routes [$ name ] = $ route ;
86
+
87
+ if ($ priority = 3 <= \func_num_args () ? func_get_arg (2 ) : 0 ) {
88
+ $ this ->priorities [$ name ] = $ priority ;
89
+ }
74
90
}
75
91
76
92
/**
@@ -80,6 +96,14 @@ public function add(string $name, Route $route)
80
96
*/
81
97
public function all ()
82
98
{
99
+ if ($ this ->priorities ) {
100
+ $ priorities = $ this ->priorities ;
101
+ $ keysOrder = array_flip (array_keys ($ this ->routes ));
102
+ uksort ($ this ->routes , static function ($ n1 , $ n2 ) use ($ priorities , $ keysOrder ) {
103
+ return (($ priorities [$ n2 ] ?? 0 ) <=> ($ priorities [$ n1 ] ?? 0 )) ?: ($ keysOrder [$ n1 ] <=> $ keysOrder [$ n2 ]);
104
+ });
105
+ }
106
+
83
107
return $ this ->routes ;
84
108
}
85
109
@@ -101,7 +125,7 @@ public function get(string $name)
101
125
public function remove ($ name )
102
126
{
103
127
foreach ((array ) $ name as $ n ) {
104
- unset($ this ->routes [$ n ]);
128
+ unset($ this ->routes [$ n ], $ this -> priorities [ $ n ] );
105
129
}
106
130
}
107
131
@@ -114,8 +138,12 @@ public function addCollection(self $collection)
114
138
// we need to remove all routes with the same names first because just replacing them
115
139
// would not place the new route at the end of the merged array
116
140
foreach ($ collection ->all () as $ name => $ route ) {
117
- unset($ this ->routes [$ name ]);
141
+ unset($ this ->routes [$ name ], $ this -> priorities [ $ name ] );
118
142
$ this ->routes [$ name ] = $ route ;
143
+
144
+ if (isset ($ collection ->priorities [$ name ])) {
145
+ $ this ->priorities [$ name ] = $ collection ->priorities [$ name ];
146
+ }
119
147
}
120
148
121
149
foreach ($ collection ->getResources () as $ resource ) {
@@ -147,15 +175,20 @@ public function addPrefix(string $prefix, array $defaults = [], array $requireme
147
175
public function addNamePrefix (string $ prefix )
148
176
{
149
177
$ prefixedRoutes = [];
178
+ $ prefixedPriorities = [];
150
179
151
180
foreach ($ this ->routes as $ name => $ route ) {
152
181
$ prefixedRoutes [$ prefix .$ name ] = $ route ;
153
182
if (null !== $ name = $ route ->getDefault ('_canonical_route ' )) {
154
183
$ route ->setDefault ('_canonical_route ' , $ prefix .$ name );
155
184
}
185
+ if (isset ($ this ->priorities [$ name ])) {
186
+ $ prefixedPriorities [$ prefix .$ name ] = $ this ->priorities [$ name ];
187
+ }
156
188
}
157
189
158
190
$ this ->routes = $ prefixedRoutes ;
191
+ $ this ->priorities = $ prefixedPriorities ;
159
192
}
160
193
161
194
/**
0 commit comments