PluginProbe
404 Solution / 4.1.13
404 Solution v4.1.13
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 / PublishedPostsProvider.php

PublishedPostsProvider.php in 404 Solution 4.1.13, at includes/PublishedPostsProvider.php

144 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4 if (!defined('ABSPATH')) {
5 exit;
6 }
7
8 /** Return some of the published pages when requested. */
9 class ABJ_404_Solution_PublishedPostsProvider {
10
11 /** Track which rows to get from the database using limit.
12 * @var integer */
13 private $currentLowRowNumber = 0;
14
15 /** When not null then use this data instead of querying the database.
16 * @var array<int, mixed>|null
17 */
18 private $dataToUse = null;
19
20 /** Tracks whether we're using user supplied data or not.
21 * @var bool */
22 private $useDataMode = false;
23
24 /** When set, only return posts with these IDs (whitelist mode).
25 * @var array<int, int>|null */
26 private $restrictedIds = null;
27
28 /** @var self|null */
29 private static $instance = null;
30
31 /** @return self */
32 public static function getInstance() {
33 if (self::$instance == null) {
34 self::$instance = new ABJ_404_Solution_PublishedPostsProvider();
35 }
36
37 return self::$instance;
38 }
39
40 /** Use this data instead of querying the database.
41 * @param array<int, mixed> $data
42 * @return void
43 */
44 function useThisData(array $data): void {
45 $this->dataToUse = $data;
46 $this->useDataMode = true;
47 }
48
49 /**
50 * Restrict results to only posts with the given IDs (whitelist mode).
51 * This enables N-gram prefiltering to limit the dataset before expensive processing.
52 *
53 * @param array<int, int|string> $ids Array of post IDs to include
54 * @return void
55 */
56 function restrictToIds(array $ids): void {
57 if (!empty($ids) && is_array($ids)) {
58 $this->restrictedIds = array_map('intval', $ids);
59 }
60 }
61
62 /**
63 * Check if we're in restricted ID mode.
64 * @return bool
65 */
66 function hasRestrictedIds() {
67 return !empty($this->restrictedIds);
68 }
69
70 /**
71 * @param int $permalinkLength Order by prioritizing things with a permalink
72 * close to this length.
73 * @param int $batchSize The number of results to return. e.g. 100.
74 * @param int|null $maxAcceptableDistance
75 * @return array<int, mixed>
76 */
77 function getNextBatch(int $permalinkLength, int $batchSize = 1000, $maxAcceptableDistance = null): array {
78 if ($this->useDataMode) {
79 return $this->getNextBatchFromLocalData($permalinkLength, $batchSize, $maxAcceptableDistance);
80 }
81
82 return $this->getNextBatchFromTheDatabase($permalinkLength, $batchSize, $maxAcceptableDistance);
83 }
84
85 /**
86 * @param int $permalinkLength
87 * @param int $batchSize
88 * @param int|null $maxAcceptableDistance
89 * @return array<int, mixed>
90 */
91 private function getNextBatchFromLocalData(int $permalinkLength, int $batchSize, $maxAcceptableDistance): array {
92 $data = $this->dataToUse ?? array();
93 // get the rows to return.
94 $rows = array_slice($data, 0, $batchSize);
95
96 // remove the rows we'll return.
97 $this->dataToUse = array_slice($data, $batchSize);
98
99 return $rows;
100 }
101
102 /**
103 * @param int $permalinkLength
104 * @param int $batchSize
105 * @param int|null $maxAcceptableDistance
106 * @return array<int, mixed>
107 */
108 private function getNextBatchFromTheDatabase(int $permalinkLength, int $batchSize, $maxAcceptableDistance): array {
109 $abj404dao = abj_service('data_access');
110
111 $orderBy = "abs(plc.url_length - " . $permalinkLength . "), wp_posts.id";
112 $limit = $this->currentLowRowNumber . ", " . $batchSize;
113 $extraWhereClause = '';
114
115 if ($maxAcceptableDistance != null) {
116 $extraWhereClause = "and abs(plc.url_length - " . $permalinkLength .
117 ") <= " . $maxAcceptableDistance;
118 }
119
120 // N-gram prefiltering: restrict to specific IDs if whitelist is set
121 if (!empty($this->restrictedIds)) {
122 $idList = implode(',', $this->restrictedIds);
123 $extraWhereClause .= " and wp_posts.id IN (" . $idList . ")";
124 }
125
126 $rows = $abj404dao->getPublishedPagesAndPostsIDs('', '', $limit, $orderBy, $extraWhereClause);
127
128 $this->currentLowRowNumber += $batchSize;
129
130 return $rows;
131 }
132
133 /** Start over at 0 when getting the next batch.
134 * @return void
135 */
136 function resetBatch(): void {
137 $this->currentLowRowNumber = 0;
138 $this->dataToUse = null;
139 $this->useDataMode = false;
140 $this->restrictedIds = null;
141 }
142
143 }
144