PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / engine / SpellingMatchingEngine.php

SpellingMatchingEngine.php in 404 Solution 4.3.0, at includes/engine/SpellingMatchingEngine.php

83 lines 2.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Matching engine that delegates to SpellChecker::getPermalinkUsingSpelling().
9 *
10 * Uses Levenshtein distance / N-gram filtering to find the closest matching
11 * published page. Expensive, so shouldRun() filters out URL shapes that are
12 * unlikely to be useful typo corrections.
13 */
14 class ABJ_404_Solution_SpellingMatchingEngine implements ABJ_404_Solution_MatchingEngine {
15
16 /** @var ABJ_404_Solution_SpellChecker */
17 private $spellChecker;
18
19 /**
20 * @param ABJ_404_Solution_SpellChecker $spellChecker
21 */
22 public function __construct(ABJ_404_Solution_SpellChecker $spellChecker) {
23 $this->spellChecker = $spellChecker;
24 }
25
26 /** @return string */
27 public function getName(): string {
28 return __('spell check', '404-solution');
29 }
30
31 /** @param ABJ_404_Solution_MatchRequest $request */
32 public function shouldRun(ABJ_404_Solution_MatchRequest $request): bool {
33 $urlSlugOnly = $request->getUrlSlugOnly();
34
35 if ($urlSlugOnly === '') {
36 return false;
37 }
38
39 $segments = array_values(array_filter(explode('/', $urlSlugOnly)));
40 if (count($segments) === 0) {
41 return false;
42 }
43
44 $lastSegment = (string)end($segments);
45
46 if (strlen($lastSegment) > 80) {
47 return false;
48 }
49 if (substr_count($lastSegment, '-') >= 6) {
50 return false;
51 }
52 if (preg_match('/\d{4,}/', $lastSegment)) {
53 return false;
54 }
55 if (!preg_match('/[a-zA-Z]/', $lastSegment)) {
56 return false;
57 }
58
59 return true;
60 }
61
62 /** @param ABJ_404_Solution_MatchRequest $request */
63 public function match(ABJ_404_Solution_MatchRequest $request): ?ABJ_404_Solution_MatchResult {
64 $permalink = $this->spellChecker->getPermalinkUsingSpelling(
65 $request->getUrlSlugOnly(),
66 $request->getRequestedURL(),
67 $request->getOptions()
68 );
69
70 if (empty($permalink)) {
71 return null;
72 }
73
74 $id = isset($permalink['id']) && is_scalar($permalink['id']) ? (string)$permalink['id'] : '';
75 $type = isset($permalink['type']) && is_scalar($permalink['type']) ? (string)$permalink['type'] : '';
76 $link = isset($permalink['link']) && is_string($permalink['link']) ? $permalink['link'] : '';
77 $title = isset($permalink['title']) && is_string($permalink['title']) ? $permalink['title'] : '';
78 $score = isset($permalink['score']) && is_scalar($permalink['score']) ? (float)$permalink['score'] : 0.0;
79
80 return new ABJ_404_Solution_MatchResult($id, $type, $link, $title, $score, $this->getName());
81 }
82 }
83