Total Complexity | 83 |
Total Lines | 796 |
Duplicated Lines | 0 % |
Changes | 19 | ||
Bugs | 0 | Features | 1 |
Complex classes like Redirects often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Redirects, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class Redirects extends Component |
||
41 | { |
||
42 | // Constants |
||
43 | // ========================================================================= |
||
44 | |||
45 | const CACHE_KEY = 'retour_redirect_'; |
||
46 | |||
47 | const GLOBAL_REDIRECTS_CACHE_TAG = 'retour_redirects'; |
||
48 | |||
49 | const EVENT_REDIRECT_ID = 0; |
||
50 | |||
51 | /** |
||
52 | * @event RedirectEvent The event that is triggered before the redirect is saved |
||
53 | * You may set [[RedirectEvent::isValid]] to `false` to prevent the redirect from getting saved. |
||
54 | * |
||
55 | * ```php |
||
56 | * use nystudio107\retour\services\Redirects; |
||
57 | * use nystudio107\retour\events\RedirectEvent; |
||
58 | * |
||
59 | * Event::on(Redirects::class, |
||
60 | * Redirects::EVENT_BEFORE_SAVE_REDIRECT, |
||
61 | * function(RedirectEvent $event) { |
||
62 | * // potentially set $event->isValid; |
||
63 | * } |
||
64 | * ); |
||
65 | * ``` |
||
66 | */ |
||
67 | const EVENT_BEFORE_SAVE_REDIRECT = 'beforeSaveRedirect'; |
||
68 | |||
69 | /** |
||
70 | * @event RedirectEvent The event that is triggered after the redirect is saved |
||
71 | * |
||
72 | * ```php |
||
73 | * use nystudio107\retour\services\Redirects; |
||
74 | * use nystudio107\retour\events\RedirectEvent; |
||
75 | * |
||
76 | * Event::on(Redirects::class, |
||
77 | * Redirects::EVENT_AFTER_SAVE_REDIRECT, |
||
78 | * function(RedirectEvent $event) { |
||
79 | * // the redirect was saved |
||
80 | * } |
||
81 | * ); |
||
82 | * ``` |
||
83 | */ |
||
84 | const EVENT_AFTER_SAVE_REDIRECT = 'afterSaveRedirect'; |
||
85 | |||
86 | /** |
||
87 | * @event ResolveRedirectEvent The event that is triggered before Retour has attempted |
||
88 | * to resolve redirects. You may set [[ResolveRedirectEvent::redirectDestUrl]] to |
||
89 | * to the URL that it should redirect to, or null if no redirect should happen |
||
90 | * |
||
91 | * ```php |
||
92 | * use nystudio107\retour\services\Redirects; |
||
93 | * use nystudio107\retour\events\ResolveRedirectEvent; |
||
94 | * |
||
95 | * Event::on(Redirects::class, |
||
96 | * Redirects::EVENT_AFTER_SAVE_REDIRECT, |
||
97 | * function(ResolveRedirectEvent $event) { |
||
98 | * // potentially set $event->redirectDestUrl; |
||
99 | * } |
||
100 | * ); |
||
101 | * ``` |
||
102 | */ |
||
103 | const EVENT_BEFORE_RESOLVE_REDIRECT = 'beforeResolveRedirect'; |
||
104 | |||
105 | /** |
||
106 | * @event ResolveRedirectEvent The event that is triggered after Retour has attempted |
||
107 | * to resolve redirects. You may set [[ResolveRedirectEvent::redirectDestUrl]] to |
||
108 | * to the URL that it should redirect to, or null if no redirect should happen |
||
109 | * |
||
110 | * ```php |
||
111 | * use nystudio107\retour\services\Redirects; |
||
112 | * use nystudio107\retour\events\ResolveRedirectEvent; |
||
113 | * |
||
114 | * Event::on(Redirects::class, |
||
115 | * Redirects::EVENT_AFTER_RESOLVE_REDIRECT, |
||
116 | * function(ResolveRedirectEvent $event) { |
||
117 | * // potentially set $event->redirectDestUrl; |
||
118 | * } |
||
119 | * ); |
||
120 | * ``` |
||
121 | */ |
||
122 | const EVENT_AFTER_RESOLVE_REDIRECT = 'afterResolveRedirect'; |
||
123 | |||
124 | // Protected Properties |
||
125 | // ========================================================================= |
||
126 | |||
127 | /** |
||
128 | * @var null|array |
||
129 | */ |
||
130 | protected $cachedStaticRedirects; |
||
131 | |||
132 | // Public Methods |
||
133 | // ========================================================================= |
||
134 | |||
135 | /** |
||
136 | * Handle 404s by looking for redirects |
||
137 | */ |
||
138 | public function handle404() |
||
187 | } |
||
188 | } |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Do the redirect |
||
193 | * |
||
194 | * @param string $fullUrl |
||
195 | * @param string $pathOnly |
||
196 | * @param null|array $redirect |
||
197 | * |
||
198 | * @return bool false if not redirected |
||
199 | */ |
||
200 | public function doRedirect(string $fullUrl, string $pathOnly, $redirect): bool |
||
201 | { |
||
202 | $response = Craft::$app->getResponse(); |
||
203 | if ($redirect !== null) { |
||
204 | // Figure out what type of source matching was done |
||
205 | $redirectSrcMatch = $redirect['redirectSrcMatch'] ?? 'pathonly'; |
||
206 | switch ($redirectSrcMatch) { |
||
207 | case 'pathonly': |
||
208 | $url = $pathOnly; |
||
209 | break; |
||
210 | case 'fullurl': |
||
211 | $url = $fullUrl; |
||
212 | break; |
||
213 | default: |
||
214 | $url = $pathOnly; |
||
215 | break; |
||
216 | } |
||
217 | $dest = $redirect['redirectDestUrl']; |
||
218 | // If this isn't a full URL, make it one based on the appropriate site |
||
219 | if (!UrlHelper::isFullUrl($dest)) { |
||
220 | try { |
||
221 | $dest = UrlHelper::siteUrl($dest, null, null, $redirect['siteId'] ?? null); |
||
222 | } catch (\yii\base\Exception $e) { |
||
223 | } |
||
224 | } |
||
225 | if (Retour::$settings->preserveQueryString) { |
||
226 | $request = Craft::$app->getRequest(); |
||
227 | if (!empty($request->getQueryStringWithoutPath())) { |
||
228 | $dest .= '?' . $request->getQueryStringWithoutPath(); |
||
229 | } |
||
230 | } |
||
231 | $redirectMatchType = $redirect['redirectMatchType'] ?? 'notfound'; |
||
232 | // Parse reference tags for exact matches |
||
233 | if ($redirectMatchType === 'exactmatch') { |
||
234 | $dest = Craft::$app->elements->parseRefs($dest, $redirect['siteId'] ?? null); |
||
235 | } |
||
236 | $status = $redirect['redirectHttpCode']; |
||
237 | Craft::info( |
||
238 | Craft::t( |
||
239 | 'retour', |
||
240 | 'Redirecting {url} to {dest} with status {status}', |
||
241 | ['url' => $url, 'dest' => $dest, 'status' => $status] |
||
242 | ), |
||
243 | __METHOD__ |
||
244 | ); |
||
245 | // Increment the stats |
||
246 | Retour::$plugin->statistics->incrementStatistics($url, true); |
||
247 | // Handle a Retour return status > 400 to render the actual error template |
||
248 | if ($status >= 400) { |
||
249 | Retour::$currentException->statusCode = $status; |
||
250 | $errorHandler = Craft::$app->getErrorHandler(); |
||
251 | $errorHandler->exception = Retour::$currentException; |
||
252 | try { |
||
253 | $response = Craft::$app->runAction('templates/render-error'); |
||
254 | } catch (InvalidRouteException $e) { |
||
255 | Craft::error($e->getMessage(), __METHOD__); |
||
256 | } catch (\yii\console\Exception $e) { |
||
257 | Craft::error($e->getMessage(), __METHOD__); |
||
258 | } |
||
259 | } |
||
260 | // Redirect the request away; |
||
261 | $response->redirect($dest, $status)->send(); |
||
262 | try { |
||
263 | Craft::$app->end(); |
||
264 | } catch (ExitException $e) { |
||
265 | Craft::error($e->getMessage(), __METHOD__); |
||
266 | } |
||
267 | } |
||
268 | |||
269 | return false; |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * @param string $fullUrl |
||
274 | * @param string $pathOnly |
||
275 | * @param null $siteId |
||
276 | * |
||
277 | * @return array|null |
||
278 | */ |
||
279 | public function findRedirectMatch(string $fullUrl, string $pathOnly, $siteId = null) |
||
280 | { |
||
281 | // Get the current site |
||
282 | if ($siteId === null) { |
||
283 | $currentSite = Craft::$app->getSites()->currentSite; |
||
284 | if ($currentSite) { |
||
285 | $siteId = $currentSite->id; |
||
286 | } |
||
287 | } |
||
288 | // Try getting the full URL redirect from the cache |
||
289 | $redirect = $this->getRedirectFromCache($fullUrl, $siteId); |
||
290 | if ($redirect) { |
||
291 | $this->incrementRedirectHitCount($redirect); |
||
292 | $this->saveRedirectToCache($fullUrl, $redirect); |
||
293 | |||
294 | return $redirect; |
||
295 | } |
||
296 | // Try getting the path only redirect from the cache |
||
297 | $redirect = $this->getRedirectFromCache($pathOnly, $siteId); |
||
298 | if ($redirect) { |
||
299 | $this->incrementRedirectHitCount($redirect); |
||
300 | $this->saveRedirectToCache($pathOnly, $redirect); |
||
301 | |||
302 | return $redirect; |
||
303 | } |
||
304 | // Resolve static redirects |
||
305 | $redirects = $this->getAllStaticRedirects(null, $siteId); |
||
306 | $redirect = $this->resolveRedirect($fullUrl, $pathOnly, $redirects); |
||
307 | if ($redirect) { |
||
308 | return $redirect; |
||
309 | } |
||
310 | |||
311 | return null; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * @param $url |
||
316 | * @param int|null $siteId |
||
317 | * |
||
318 | * @return bool|array |
||
319 | */ |
||
320 | public function getRedirectFromCache($url, int $siteId = 0) |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * @param string $url |
||
339 | * @param array $redirect |
||
340 | */ |
||
341 | public function saveRedirectToCache($url, $redirect) |
||
342 | { |
||
343 | $cache = Craft::$app->getCache(); |
||
344 | // Get the current site id |
||
345 | $sites = Craft::$app->getSites(); |
||
346 | try { |
||
347 | $siteId = $sites->getCurrentSite()->id; |
||
348 | } catch (SiteNotFoundException $e) { |
||
349 | $siteId = 1; |
||
350 | } |
||
351 | $cacheKey = $this::CACHE_KEY.md5($url).$siteId; |
||
352 | // Create the dependency tags |
||
353 | $dependency = new TagDependency([ |
||
354 | 'tags' => [ |
||
355 | $this::GLOBAL_REDIRECTS_CACHE_TAG, |
||
356 | $this::GLOBAL_REDIRECTS_CACHE_TAG.$siteId, |
||
357 | ], |
||
358 | ]); |
||
359 | $cache->set($cacheKey, $redirect, Retour::$cacheDuration, $dependency); |
||
360 | Craft::info( |
||
361 | Craft::t( |
||
362 | 'retour', |
||
363 | 'Cached redirect saved for {url}', |
||
364 | ['url' => $url] |
||
365 | ), |
||
366 | __METHOD__ |
||
367 | ); |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * @param string $fullUrl |
||
372 | * @param string $pathOnly |
||
373 | * @param array $redirects |
||
374 | * |
||
375 | * @return array|null |
||
376 | */ |
||
377 | public function resolveRedirect(string $fullUrl, string $pathOnly, array $redirects) |
||
378 | { |
||
379 | $result = null; |
||
380 | // Throw the Redirects::EVENT_BEFORE_RESOLVE_REDIRECT event |
||
381 | $event = new ResolveRedirectEvent([ |
||
382 | 'fullUrl' => $fullUrl, |
||
383 | 'pathOnly' => $pathOnly, |
||
384 | 'redirectDestUrl' => null, |
||
385 | 'redirectHttpCode' => 301, |
||
386 | ]); |
||
387 | $this->trigger(self::EVENT_BEFORE_RESOLVE_REDIRECT, $event); |
||
388 | if ($event->redirectDestUrl !== null) { |
||
389 | return $this->resolveEventRedirect($event); |
||
390 | } |
||
391 | // Iterate through the redirects |
||
392 | foreach ($redirects as $redirect) { |
||
393 | // Figure out what type of source matching to do |
||
394 | $redirectSrcMatch = $redirect['redirectSrcMatch'] ?? 'pathonly'; |
||
395 | $redirectEnabled = (bool)$redirect['enabled']; |
||
396 | if ($redirectEnabled === true) { |
||
397 | switch ($redirectSrcMatch) { |
||
398 | case 'pathonly': |
||
399 | $url = $pathOnly; |
||
400 | break; |
||
401 | case 'fullurl': |
||
402 | $url = $fullUrl; |
||
403 | break; |
||
404 | default: |
||
405 | $url = $pathOnly; |
||
406 | break; |
||
407 | } |
||
408 | $redirectMatchType = $redirect['redirectMatchType'] ?? 'notfound'; |
||
409 | switch ($redirectMatchType) { |
||
410 | // Do a straight up match |
||
411 | case 'exactmatch': |
||
412 | if (strcasecmp($redirect['redirectSrcUrlParsed'], $url) === 0) { |
||
413 | $this->incrementRedirectHitCount($redirect); |
||
414 | $this->saveRedirectToCache($url, $redirect); |
||
415 | |||
416 | return $redirect; |
||
417 | } |
||
418 | break; |
||
419 | |||
420 | // Do a regex match |
||
421 | case 'regexmatch': |
||
422 | $matchRegEx = '`'.$redirect['redirectSrcUrlParsed'].'`i'; |
||
423 | try { |
||
424 | if (preg_match($matchRegEx, $url) === 1) { |
||
425 | $this->incrementRedirectHitCount($redirect); |
||
426 | // If we're not associated with an EntryID, handle capture group replacement |
||
427 | if ((int)$redirect['associatedElementId'] === 0) { |
||
428 | $redirect['redirectDestUrl'] = preg_replace( |
||
429 | $matchRegEx, |
||
430 | $redirect['redirectDestUrl'], |
||
431 | $url |
||
432 | ); |
||
433 | } |
||
434 | $this->saveRedirectToCache($url, $redirect); |
||
435 | |||
436 | return $redirect; |
||
437 | } |
||
438 | } catch (\Exception $e) { |
||
439 | // That's fine |
||
440 | Craft::error('Invalid Redirect Regex: '.$matchRegEx, __METHOD__); |
||
441 | } |
||
442 | |||
443 | break; |
||
444 | |||
445 | // Otherwise try to look up a plugin's method by and call it for the match |
||
446 | default: |
||
447 | $plugin = $redirectMatchType ? Craft::$app->getPlugins()->getPlugin($redirectMatchType) : null; |
||
448 | if ($plugin && method_exists($plugin, 'retourMatch')) { |
||
449 | $args = [ |
||
450 | [ |
||
451 | 'redirect' => &$redirect, |
||
452 | ], |
||
453 | ]; |
||
454 | $result = \call_user_func_array([$plugin, 'retourMatch'], $args); |
||
455 | if ($result) { |
||
456 | $this->incrementRedirectHitCount($redirect); |
||
457 | $this->saveRedirectToCache($url, $redirect); |
||
458 | |||
459 | return $redirect; |
||
460 | } |
||
461 | } |
||
462 | break; |
||
463 | } |
||
464 | } |
||
465 | } |
||
466 | // Throw the Redirects::EVENT_AFTER_RESOLVE_REDIRECT event |
||
467 | $event = new ResolveRedirectEvent([ |
||
468 | 'fullUrl' => $fullUrl, |
||
469 | 'pathOnly' => $pathOnly, |
||
470 | 'redirectDestUrl' => null, |
||
471 | 'redirectHttpCode' => 301, |
||
472 | ]); |
||
473 | $this->trigger(self::EVENT_AFTER_RESOLVE_REDIRECT, $event); |
||
474 | if ($event->redirectDestUrl !== null) { |
||
475 | return $this->resolveEventRedirect($event); |
||
476 | } |
||
477 | Craft::info( |
||
478 | Craft::t( |
||
479 | 'retour', |
||
480 | 'Not handled-> full URL: {fullUrl}, path only: {pathOnly}', |
||
481 | ['fullUrl' => $fullUrl, 'pathOnly' => $pathOnly] |
||
482 | ), |
||
483 | __METHOD__ |
||
484 | ); |
||
485 | |||
486 | return $result; |
||
487 | } |
||
488 | |||
489 | /** |
||
490 | * @param ResolveRedirectEvent $event |
||
491 | * |
||
492 | * @return null|array |
||
493 | */ |
||
494 | public function resolveEventRedirect(ResolveRedirectEvent $event) |
||
495 | { |
||
496 | $result = null; |
||
497 | |||
498 | if ($event->redirectDestUrl !== null) { |
||
499 | $redirect = new StaticRedirectsModel([ |
||
500 | 'id' => self::EVENT_REDIRECT_ID, |
||
501 | 'redirectDestUrl' => $event->redirectDestUrl, |
||
502 | 'redirectHttpCode' => $event->redirectHttpCode, |
||
503 | ]); |
||
504 | $result = $redirect->toArray(); |
||
505 | } |
||
506 | |||
507 | return $result; |
||
508 | } |
||
509 | |||
510 | /** |
||
511 | * Returns the list of matching schemes |
||
512 | * |
||
513 | * @return array |
||
514 | */ |
||
515 | public function getMatchesList(): array |
||
516 | { |
||
517 | $result = [ |
||
518 | 'exactmatch' => Craft::t('retour', 'Exact Match'), |
||
519 | 'regexmatch' => Craft::t('retour', 'RegEx Match'), |
||
520 | ]; |
||
521 | |||
522 | // Add any plugins that offer the retourMatch() method |
||
523 | foreach (Craft::$app->getPlugins()->getAllPlugins() as $plugin) { |
||
524 | /** @var Plugin $plugin */ |
||
525 | if (method_exists($plugin, 'retourMatch')) { |
||
526 | $result[$plugin->getHandle()] = $plugin->name.Craft::t('retour', ' Match'); |
||
527 | } |
||
528 | } |
||
529 | |||
530 | return $result; |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * @param null|int $limit |
||
535 | * @param int|null $siteId |
||
536 | * |
||
537 | * @return array All of the statistics |
||
538 | */ |
||
539 | public function getAllStaticRedirects($limit = null, int $siteId = null): array |
||
540 | { |
||
541 | // Cache it in our class; no need to fetch it more than once |
||
542 | if ($this->cachedStaticRedirects !== null) { |
||
543 | return $this->cachedStaticRedirects; |
||
544 | } |
||
545 | // Query the db table |
||
546 | $query = (new Query()) |
||
547 | ->from(['{{%retour_static_redirects}}']) |
||
548 | ->orderBy('redirectMatchType ASC, redirectSrcMatch ASC, hitCount DESC'); |
||
549 | if ($siteId) { |
||
550 | $query |
||
551 | ->where(['siteId' => $siteId]) |
||
552 | ->orWhere(['siteId' => null]); |
||
553 | } |
||
554 | if ($limit) { |
||
555 | $query->limit($limit); |
||
556 | } |
||
557 | $redirects = $query->all(); |
||
558 | // Cache for future accesses |
||
559 | $this->cachedStaticRedirects = $redirects; |
||
560 | |||
561 | return $redirects; |
||
562 | } |
||
563 | |||
564 | /** |
||
565 | * Return a redirect by id |
||
566 | * |
||
567 | * @param int $id |
||
568 | * |
||
569 | * @return null|array The static redirect |
||
570 | */ |
||
571 | public function getRedirectById(int $id) |
||
572 | { |
||
573 | // Query the db table |
||
574 | $redirect = (new Query()) |
||
575 | ->from(['{{%retour_static_redirects}}']) |
||
576 | ->where(['id' => $id]) |
||
577 | ->one(); |
||
578 | |||
579 | return $redirect; |
||
580 | } |
||
581 | |||
582 | /** |
||
583 | * Return a redirect by redirectSrcUrl |
||
584 | * |
||
585 | * @param string $redirectSrcUrl |
||
586 | * @param int|null $siteId |
||
587 | * |
||
588 | * @return null|array |
||
589 | */ |
||
590 | public function getRedirectByRedirectSrcUrl(string $redirectSrcUrl, int $siteId = null) |
||
591 | { |
||
592 | // Query the db table |
||
593 | $query = (new Query()) |
||
594 | ->from(['{{%retour_static_redirects}}']) |
||
595 | ->where(['redirectSrcUrl' => $redirectSrcUrl]) |
||
596 | ; |
||
597 | if ($siteId) { |
||
598 | $query |
||
599 | ->andWhere(['or', [ |
||
600 | 'siteId' => $siteId, |
||
601 | ], [ |
||
602 | 'siteId' => null, |
||
603 | ]]); |
||
604 | } |
||
605 | $redirect = $query->one(); |
||
606 | |||
607 | return $redirect; |
||
608 | } |
||
609 | |||
610 | /** |
||
611 | * Delete a redirect by id |
||
612 | * |
||
613 | * @param int $id |
||
614 | * |
||
615 | * @return int The result |
||
616 | */ |
||
617 | public function deleteRedirectById(int $id): int |
||
618 | { |
||
619 | $db = Craft::$app->getDb(); |
||
620 | // Delete a row from the db table |
||
621 | try { |
||
622 | $result = $db->createCommand()->delete( |
||
623 | '{{%retour_static_redirects}}', |
||
624 | [ |
||
625 | 'id' => $id, |
||
626 | ] |
||
627 | )->execute(); |
||
628 | } catch (Exception $e) { |
||
629 | Craft::error($e->getMessage(), __METHOD__); |
||
630 | $result = 0; |
||
631 | } |
||
632 | |||
633 | return $result; |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Increment the retour_static_redirects record |
||
638 | * |
||
639 | * @param $redirectConfig |
||
640 | */ |
||
641 | public function incrementRedirectHitCount(&$redirectConfig) |
||
642 | { |
||
643 | if ($redirectConfig !== null) { |
||
644 | $db = Craft::$app->getDb(); |
||
645 | $redirectConfig['hitCount']++; |
||
646 | $redirectConfig['hitLastTime'] = Db::prepareDateForDb(new \DateTime()); |
||
647 | Craft::debug( |
||
648 | Craft::t( |
||
649 | 'retour', |
||
650 | 'Incrementing statistics for: {redirect}', |
||
651 | ['redirect' => print_r($redirectConfig, true)] |
||
652 | ), |
||
653 | __METHOD__ |
||
654 | ); |
||
655 | // Update the existing record |
||
656 | try { |
||
657 | $rowsAffected = $db->createCommand()->update( |
||
658 | '{{%retour_static_redirects}}', |
||
659 | [ |
||
660 | 'hitCount' => $redirectConfig['hitCount'], |
||
661 | 'hitLastTime' => $redirectConfig['hitLastTime'], |
||
662 | ], |
||
663 | [ |
||
664 | 'id' => $redirectConfig['id'], |
||
665 | ] |
||
666 | )->execute(); |
||
667 | Craft::debug('Rows affected: '.$rowsAffected, __METHOD__); |
||
668 | } catch (\Exception $e) { |
||
669 | Craft::error($e->getMessage(), __METHOD__); |
||
670 | } |
||
671 | } |
||
672 | } |
||
673 | |||
674 | /** |
||
675 | * @param array $redirectConfig |
||
676 | */ |
||
677 | public function saveRedirect(array $redirectConfig) |
||
795 | } |
||
796 | |||
797 | /** |
||
798 | * Invalidate all of the redirects caches |
||
799 | */ |
||
800 | public function invalidateCaches() |
||
801 | { |
||
802 | $cache = Craft::$app->getCache(); |
||
803 | TagDependency::invalidate($cache, $this::GLOBAL_REDIRECTS_CACHE_TAG); |
||
810 | ); |
||
811 | } |
||
812 | |||
813 | /** |
||
814 | * @param $uri |
||
815 | * |
||
816 | * @return bool |
||
817 | */ |
||
818 | public function excludeUri($uri): bool |
||
836 | } |
||
837 | } |
||
838 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.