@@ -105,42 +105,18 @@ protected function doFindOneByData(array $data)
105
105
$ result = null ;
106
106
107
107
$ requestPath = $ data [UrlRewrite::REQUEST_PATH ];
108
-
109
- $ data [UrlRewrite::REQUEST_PATH ] = [
108
+ $ decodedRequestPath = urldecode ( $ requestPath );
109
+ $ data [UrlRewrite::REQUEST_PATH ] = array_unique ( [
110
110
rtrim ($ requestPath , '/ ' ),
111
111
rtrim ($ requestPath , '/ ' ) . '/ ' ,
112
- ];
112
+ rtrim ($ decodedRequestPath , '/ ' ),
113
+ rtrim ($ decodedRequestPath , '/ ' ) . '/ ' ,
114
+ ]);
113
115
114
116
$ resultsFromDb = $ this ->connection ->fetchAll ($ this ->prepareSelect ($ data ));
115
-
116
- if (count ($ resultsFromDb ) === 1 ) {
117
- $ resultFromDb = current ($ resultsFromDb );
118
- $ redirectTypes = [OptionProvider::TEMPORARY , OptionProvider::PERMANENT ];
119
-
120
- // If request path matches the DB value or it's redirect - we can return result from DB
121
- $ canReturnResultFromDb = ($ resultFromDb [UrlRewrite::REQUEST_PATH ] === $ requestPath
122
- || in_array ((int )$ resultFromDb [UrlRewrite::REDIRECT_TYPE ], $ redirectTypes , true ));
123
-
124
- // Otherwise return 301 redirect to request path from DB results
125
- $ result = $ canReturnResultFromDb ? $ resultFromDb : [
126
- UrlRewrite::ENTITY_TYPE => 'custom ' ,
127
- UrlRewrite::ENTITY_ID => '0 ' ,
128
- UrlRewrite::REQUEST_PATH => $ requestPath ,
129
- UrlRewrite::TARGET_PATH => $ resultFromDb [UrlRewrite::REQUEST_PATH ],
130
- UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT ,
131
- UrlRewrite::STORE_ID => $ resultFromDb [UrlRewrite::STORE_ID ],
132
- UrlRewrite::DESCRIPTION => null ,
133
- UrlRewrite::IS_AUTOGENERATED => '0 ' ,
134
- UrlRewrite::METADATA => null ,
135
- ];
136
- } else {
137
- // If we have 2 results - return the row that matches request path
138
- foreach ($ resultsFromDb as $ resultFromDb ) {
139
- if ($ resultFromDb [UrlRewrite::REQUEST_PATH ] === $ requestPath ) {
140
- $ result = $ resultFromDb ;
141
- break ;
142
- }
143
- }
117
+ if ($ resultsFromDb ) {
118
+ $ urlRewrite = $ this ->extractMostRelevantUrlRewrite ($ requestPath , $ resultsFromDb );
119
+ $ result = $ this ->prepareUrlRewrite ($ requestPath , $ urlRewrite );
144
120
}
145
121
146
122
return $ result ;
@@ -149,6 +125,75 @@ protected function doFindOneByData(array $data)
149
125
return $ this ->connection ->fetchRow ($ this ->prepareSelect ($ data ));
150
126
}
151
127
128
+ /**
129
+ * Extract most relevant url rewrite from url rewrites list
130
+ *
131
+ * @param string $requestPath
132
+ * @param array $urlRewrites
133
+ * @return array|null
134
+ */
135
+ private function extractMostRelevantUrlRewrite (string $ requestPath , array $ urlRewrites ): ?array
136
+ {
137
+ $ prioritizedUrlRewrites = [];
138
+ foreach ($ urlRewrites as $ urlRewrite ) {
139
+ switch (true ) {
140
+ case $ urlRewrite [UrlRewrite::REQUEST_PATH ] === $ requestPath :
141
+ $ priority = 1 ;
142
+ break ;
143
+ case $ urlRewrite [UrlRewrite::REQUEST_PATH ] === urldecode ($ requestPath ):
144
+ $ priority = 2 ;
145
+ break ;
146
+ case rtrim ($ urlRewrite [UrlRewrite::REQUEST_PATH ], '/ ' ) === rtrim ($ requestPath , '/ ' ):
147
+ $ priority = 3 ;
148
+ break ;
149
+ case rtrim ($ urlRewrite [UrlRewrite::REQUEST_PATH ], '/ ' ) === rtrim (urldecode ($ requestPath ), '/ ' ):
150
+ $ priority = 4 ;
151
+ break ;
152
+ default :
153
+ $ priority = 5 ;
154
+ break ;
155
+ }
156
+ $ prioritizedUrlRewrites [$ priority ] = $ urlRewrite ;
157
+ }
158
+ ksort ($ prioritizedUrlRewrites );
159
+
160
+ return array_shift ($ prioritizedUrlRewrites );
161
+ }
162
+
163
+ /**
164
+ * Prepare url rewrite
165
+ *
166
+ * If request path matches the DB value or it's redirect - we can return result from DB
167
+ * Otherwise return 301 redirect to request path from DB results
168
+ *
169
+ * @param string $requestPath
170
+ * @param array $urlRewrite
171
+ * @return array
172
+ */
173
+ private function prepareUrlRewrite (string $ requestPath , array $ urlRewrite ): array
174
+ {
175
+ $ redirectTypes = [OptionProvider::TEMPORARY , OptionProvider::PERMANENT ];
176
+ $ canReturnResultFromDb = (
177
+ in_array ($ urlRewrite [UrlRewrite::REQUEST_PATH ], [$ requestPath , urldecode ($ requestPath )], true )
178
+ || in_array ((int ) $ urlRewrite [UrlRewrite::REDIRECT_TYPE ], $ redirectTypes , true )
179
+ );
180
+ if (!$ canReturnResultFromDb ) {
181
+ $ urlRewrite = [
182
+ UrlRewrite::ENTITY_TYPE => 'custom ' ,
183
+ UrlRewrite::ENTITY_ID => '0 ' ,
184
+ UrlRewrite::REQUEST_PATH => $ requestPath ,
185
+ UrlRewrite::TARGET_PATH => $ urlRewrite [UrlRewrite::REQUEST_PATH ],
186
+ UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT ,
187
+ UrlRewrite::STORE_ID => $ urlRewrite [UrlRewrite::STORE_ID ],
188
+ UrlRewrite::DESCRIPTION => null ,
189
+ UrlRewrite::IS_AUTOGENERATED => '0 ' ,
190
+ UrlRewrite::METADATA => null ,
191
+ ];
192
+ }
193
+
194
+ return $ urlRewrite ;
195
+ }
196
+
152
197
/**
153
198
* Delete old URLs from DB.
154
199
*
0 commit comments