@@ -65,31 +65,57 @@ public function getRoutes(): array
65
65
*/
66
66
public function addRoute (string $ prefix , $ route , string $ staticPrefix = null )
67
67
{
68
- $ this ->guardAgainstAddingNotAcceptedRoutes ($ prefix );
69
68
if (null === $ staticPrefix ) {
70
69
list ($ prefix , $ staticPrefix ) = $ this ->getCommonPrefix ($ prefix , $ prefix );
71
70
}
72
71
73
72
for ($ i = \count ($ this ->items ) - 1 ; 0 <= $ i ; --$ i ) {
74
73
$ item = $ this ->items [$ i ];
75
74
76
- if ($ item instanceof self && $ item ->accepts ($ prefix )) {
77
- $ item ->addRoute ($ prefix , $ route , $ staticPrefix );
75
+ list ($ commonPrefix , $ commonStaticPrefix ) = $ this ->getCommonPrefix ($ prefix , $ this ->prefixes [$ i ]);
78
76
79
- return ;
80
- }
77
+ if ( $ this -> prefix === $ commonPrefix ) {
78
+ // the new route and a previous one have no common prefix, let's see if they are exclusive to each others
81
79
82
- if ($ this ->groupWithItem ($ i , $ prefix , $ staticPrefix , $ route )) {
83
- return ;
84
- }
80
+ if ($ this ->prefix !== $ staticPrefix && $ this ->prefix !== $ this ->staticPrefixes [$ i ]) {
81
+ // the new route and the previous one have exclusive static prefixes
82
+ continue ;
83
+ }
85
84
86
- if ($ this ->staticPrefixes [$ i ] !== $ this ->prefixes [$ i ] && 0 === strpos ($ staticPrefix , $ this ->staticPrefixes [$ i ])) {
87
- break ;
85
+ if ($ this ->prefix === $ staticPrefix && $ this ->prefix === $ this ->staticPrefixes [$ i ]) {
86
+ // the new route and the previous one have no static prefix
87
+ break ;
88
+ }
89
+
90
+ if ($ this ->prefixes [$ i ] !== $ this ->staticPrefixes [$ i ] && $ this ->prefix === $ this ->staticPrefixes [$ i ]) {
91
+ // the previous route is non-static and has no static prefix
92
+ break ;
93
+ }
94
+
95
+ if ($ prefix !== $ staticPrefix && $ this ->prefix === $ staticPrefix ) {
96
+ // the new route is non-static and has no static prefix
97
+ break ;
98
+ }
99
+
100
+ continue ;
88
101
}
89
102
90
- if ($ staticPrefix !== $ prefix && 0 === strpos ($ this ->staticPrefixes [$ i ], $ staticPrefix )) {
91
- break ;
103
+ if ($ item instanceof self && $ this ->prefixes [$ i ] === $ commonPrefix ) {
104
+ // the new route is a child of a previous one, let's nest it
105
+ $ item ->addRoute ($ prefix , $ route , $ staticPrefix );
106
+ } else {
107
+ // the new route and a previous one have a common prefix, let's merge them
108
+ $ child = new self ($ commonPrefix );
109
+ list ($ child ->prefixes [0 ], $ child ->staticPrefixes [0 ]) = $ child ->getCommonPrefix ($ this ->prefixes [$ i ], $ this ->prefixes [$ i ]);
110
+ list ($ child ->prefixes [1 ], $ child ->staticPrefixes [1 ]) = $ child ->getCommonPrefix ($ prefix , $ prefix );
111
+ $ child ->items = array ($ this ->items [$ i ], $ route );
112
+
113
+ $ this ->staticPrefixes [$ i ] = $ commonStaticPrefix ;
114
+ $ this ->prefixes [$ i ] = $ commonPrefix ;
115
+ $ this ->items [$ i ] = $ child ;
92
116
}
117
+
118
+ return ;
93
119
}
94
120
95
121
// No optimised case was found, in this case we simple add the route for possible
@@ -115,38 +141,6 @@ public function populateCollection(RouteCollection $routes): RouteCollection
115
141
return $ routes ;
116
142
}
117
143
118
- /**
119
- * Tries to combine a route with another route or group.
120
- */
121
- private function groupWithItem (int $ i , string $ prefix , string $ staticPrefix , $ route ): bool
122
- {
123
- list ($ commonPrefix , $ commonStaticPrefix ) = $ this ->getCommonPrefix ($ prefix , $ this ->prefixes [$ i ]);
124
-
125
- if (\strlen ($ this ->prefix ) >= \strlen ($ commonPrefix )) {
126
- return false ;
127
- }
128
-
129
- $ child = new self ($ commonPrefix );
130
-
131
- $ child ->staticPrefixes = array ($ this ->staticPrefixes [$ i ], $ staticPrefix );
132
- $ child ->prefixes = array ($ this ->prefixes [$ i ], $ prefix );
133
- $ child ->items = array ($ this ->items [$ i ], $ route );
134
-
135
- $ this ->staticPrefixes [$ i ] = $ commonStaticPrefix ;
136
- $ this ->prefixes [$ i ] = $ commonPrefix ;
137
- $ this ->items [$ i ] = $ child ;
138
-
139
- return true ;
140
- }
141
-
142
- /**
143
- * Checks whether a prefix can be contained within the group.
144
- */
145
- private function accepts (string $ prefix ): bool
146
- {
147
- return 0 === strpos ($ prefix , $ this ->prefix ) && '? ' !== ($ prefix [\strlen ($ this ->prefix )] ?? '' );
148
- }
149
-
150
144
/**
151
145
* Gets the full and static common prefixes between two route patterns.
152
146
*
@@ -195,18 +189,4 @@ private function getCommonPrefix(string $prefix, string $anotherPrefix): array
195
189
196
190
return array (substr ($ prefix , 0 , $ i ), substr ($ prefix , 0 , $ staticLength ?? $ i ));
197
191
}
198
-
199
- /**
200
- * Guards against adding incompatible prefixes in a group.
201
- *
202
- * @throws \LogicException when a prefix does not belong in a group
203
- */
204
- private function guardAgainstAddingNotAcceptedRoutes (string $ prefix ): void
205
- {
206
- if (!$ this ->accepts ($ prefix )) {
207
- $ message = sprintf ('Could not add route with prefix %s to collection with prefix %s ' , $ prefix , $ this ->prefix );
208
-
209
- throw new \LogicException ($ message );
210
- }
211
- }
212
192
}
0 commit comments