@@ -65,31 +65,57 @@ public function getRoutes(): array
6565 */
6666 public function addRoute (string $ prefix , $ route , string $ staticPrefix = null )
6767 {
68- $ this ->guardAgainstAddingNotAcceptedRoutes ($ prefix );
6968 if (null === $ staticPrefix ) {
7069 list ($ prefix , $ staticPrefix ) = $ this ->getCommonPrefix ($ prefix , $ prefix );
7170 }
7271
7372 for ($ i = \count ($ this ->items ) - 1 ; 0 <= $ i ; --$ i ) {
7473 $ item = $ this ->items [$ i ];
7574
76- if ($ item instanceof self && $ item ->accepts ($ prefix )) {
77- $ item ->addRoute ($ prefix , $ route , $ staticPrefix );
75+ list ($ commonPrefix , $ commonStaticPrefix ) = $ this ->getCommonPrefix ($ prefix , $ this ->prefixes [$ i ]);
7876
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
8179
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+ }
8584
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 ;
88101 }
89102
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 ;
92116 }
117+
118+ return ;
93119 }
94120
95121 // 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
115141 return $ routes ;
116142 }
117143
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-
150144 /**
151145 * Gets the full and static common prefixes between two route patterns.
152146 *
@@ -195,18 +189,4 @@ private function getCommonPrefix(string $prefix, string $anotherPrefix): array
195189
196190 return array (substr ($ prefix , 0 , $ i ), substr ($ prefix , 0 , $ staticLength ?? $ i ));
197191 }
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- }
212192}
0 commit comments