Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
127 / 127 |
|
100.00% |
30 / 30 |
CRAP | |
100.00% |
1 / 1 |
NukeContext | |
100.00% |
127 / 127 |
|
100.00% |
30 / 30 |
63 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
8 | |||
getAction | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getTarget | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
getPattern | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNamespaces | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getLimit | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDateFrom | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getDateTo | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getIncludeRedirects | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getIncludeTalkPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAllPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMinPageSize | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMaxPageSize | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAssociatedPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getOriginalPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNukeAccessStatus | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRequestContext | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
willUseTemporaryAccounts | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasTarget | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasOriginalPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
validate | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
6 | |||
validatePrompt | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
validateDate | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
4 | |||
getDeleteReason | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
6 | |||
getNukeMaxAge | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
getNukeMaxAgeInDays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getRecentChangesMaxAgeInDays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
calculateSearchNotices | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
5 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Nuke; |
4 | |
5 | use DateTime; |
6 | use Exception; |
7 | use MediaWiki\Context\IContextSource; |
8 | use MediaWiki\MainConfigNames; |
9 | use Wikimedia\IPUtils; |
10 | |
11 | /** |
12 | * Groups all Nuke-related filters and request data into a single object. |
13 | * This reduces the work involved in keeping track of every single filter |
14 | * that gets added into Nuke by keeping it all in a central place. |
15 | */ |
16 | class NukeContext { |
17 | |
18 | /** |
19 | * The active "action" for the special page. This determines which stage in the Nuke |
20 | * form we're in. This is one of the `ACTION_*` constants on {@link SpecialNuke}: |
21 | * - {@link SpecialNuke::ACTION_PROMPT} |
22 | * - {@link SpecialNuke::ACTION_LIST} |
23 | * - {@link SpecialNuke::ACTION_CONFIRM} |
24 | * - {@link SpecialNuke::ACTION_DELETE} |
25 | * |
26 | * @var string |
27 | */ |
28 | private string $action = SpecialNuke::ACTION_PROMPT; |
29 | |
30 | /** |
31 | * The target actor. Can be a username (normal or temporary account) or |
32 | * IP address. When not provided, this is an empty string. |
33 | * |
34 | * @var string |
35 | */ |
36 | private string $target = ''; |
37 | |
38 | /** |
39 | * The listed target actor. Used when the action is `delete` or `confirm`, replacing |
40 | * {@link $target} to ensure that the target from which the pages belong is what's shown |
41 | * instead of what's on the input box at request time (T380297). When not provided, this |
42 | * is an empty string. When this is an empty string, it implies the value of $target |
43 | * should be used. |
44 | * |
45 | * @var string |
46 | */ |
47 | private string $listedTarget = ''; |
48 | |
49 | /** |
50 | * The title matching pattern. As of 1.44, this is an SQL LIKE pattern, which uses |
51 | * `%` as the wildcard character. When not provided, this is an empty string. |
52 | * |
53 | * @var string |
54 | */ |
55 | private string $pattern = ''; |
56 | |
57 | /** |
58 | * An array of namespace IDs where the query will run. When not provided, this is `null`. |
59 | * When `null`, this implicitly means all namespaces should be included. |
60 | * |
61 | * @var int[]|null |
62 | */ |
63 | private ?array $namespaces = null; |
64 | |
65 | /** |
66 | * The maximum number of pages to get. This limit also applies after hooks run; the |
67 | * final list of pages must never be larger than this value. |
68 | * |
69 | * @var int |
70 | */ |
71 | private int $limit = 500; |
72 | |
73 | /** |
74 | * The date from which the Nuke search should be performed. Only page creations after this |
75 | * value should be returned. When not provided, this is an empty string. |
76 | * |
77 | * @var string |
78 | */ |
79 | private string $dateFrom = ''; |
80 | |
81 | /** |
82 | * The date to which the Nuke search should be performed. Only page creations before this |
83 | * value should be returned. When not provided, this is an empty string. |
84 | * |
85 | * @var string |
86 | */ |
87 | private string $dateTo = ''; |
88 | |
89 | /** |
90 | * Whether to include talk pages in the search. When not provided, this is `false`. |
91 | * |
92 | * @var bool |
93 | */ |
94 | private bool $includeTalkPages = false; |
95 | |
96 | /** |
97 | * Whether to include redirects in the search. When not provided, this is `false`. |
98 | * |
99 | * @var bool |
100 | */ |
101 | private bool $includeRedirects = false; |
102 | |
103 | /** |
104 | * The list of pages to delete. Only applicable for the `confirm` and `delete` actions. |
105 | * When not provided, this is an empty array. |
106 | * |
107 | * @var string[] |
108 | */ |
109 | private array $pages = []; |
110 | |
111 | /** |
112 | * The list of pages associated with the target to delete. Only applicable for the `confirm` |
113 | * and `delete` actions. When not provided, this is an empty array. |
114 | * |
115 | * @var string[] |
116 | */ |
117 | private array $associatedPages = []; |
118 | |
119 | /** |
120 | * The original list of pages provided to the user. When on the `confirm` and `delete` |
121 | * actions, this is required to show pages that were deselected by the user during the |
122 | * `list` action, allowing users to follow up on found but deselected pages. When not |
123 | * provided, this is an empty array. |
124 | * |
125 | * @var string[] |
126 | */ |
127 | private array $originalPages = []; |
128 | |
129 | /** |
130 | * Whether support for temporary accounts is enabled. |
131 | * |
132 | * @var bool |
133 | */ |
134 | private bool $useTemporaryAccounts = false; |
135 | |
136 | /** |
137 | * The current status of the user's access to Nuke. |
138 | * |
139 | * @var int |
140 | */ |
141 | private int $nukeAccessStatus = self::NUKE_ACCESS_INTERNAL_ERROR; |
142 | |
143 | /** |
144 | * Constants for nuke access status. |
145 | */ |
146 | public const NUKE_ACCESS_INTERNAL_ERROR = 0; |
147 | public const NUKE_ACCESS_GRANTED = 1; |
148 | public const NUKE_ACCESS_NO_PERMISSION = 2; |
149 | public const NUKE_ACCESS_BLOCKED = 3; |
150 | |
151 | /** |
152 | * The minimum size of pages to list, in bytes. This is used to limit the size of the |
153 | * pages shown to the user. When not provided, this is by default 0 (no limit). |
154 | * |
155 | * @var int |
156 | */ |
157 | private int $minPageSize = 0; |
158 | |
159 | /** |
160 | * The maximum size of pages to list, in bytes. This is used to limit the size of the |
161 | * pages shown to the user. When not provided, this is by default null. |
162 | * |
163 | * Negatives are treated as no-ops, so this is what we default to. |
164 | * |
165 | * @var int |
166 | */ |
167 | private int $maxPageSize = -1; |
168 | |
169 | /** |
170 | * Originating request context of the query. |
171 | * |
172 | * @var IContextSource |
173 | */ |
174 | private IContextSource $requestContext; |
175 | |
176 | /** |
177 | * Create a new NukeContext without transforming most parameters. |
178 | * |
179 | * @param array $params |
180 | */ |
181 | public function __construct( array $params ) { |
182 | $this->requestContext = $params['requestContext']; |
183 | $this->useTemporaryAccounts = $params['useTemporaryAccounts'] ?? $this->useTemporaryAccounts; |
184 | |
185 | $this->action = $params['action'] ?? $this->action; |
186 | $this->target = $params['target'] ?? $this->target; |
187 | $this->listedTarget = $params['listedTarget'] ?? $this->listedTarget; |
188 | $this->pattern = $params['pattern'] ?? $this->pattern; |
189 | $this->namespaces = $params['namespaces'] ?? $this->namespaces; |
190 | $this->limit = $params['limit'] ?? $this->limit; |
191 | |
192 | if ( isset( $params['dateFrom'] ) && $params['dateFrom'] ) { |
193 | $this->dateFrom = $params['dateFrom']; |
194 | } |
195 | if ( isset( $params['dateTo'] ) && $params['dateTo'] ) { |
196 | $this->dateTo = $params['dateTo']; |
197 | } |
198 | |
199 | $this->includeTalkPages = $params['includeTalkPages'] ?? $this->includeTalkPages; |
200 | $this->includeRedirects = $params['includeRedirects'] ?? $this->includeRedirects; |
201 | |
202 | $this->pages = $params['pages'] ?? $this->pages; |
203 | $this->associatedPages = $params['associatedPages'] ?? $this->associatedPages; |
204 | |
205 | if ( $this->action == 'delete' || $this->action == 'confirm' ) { |
206 | if ( $params['listedTarget'] ) { |
207 | $this->listedTarget = $params['listedTarget']; |
208 | } |
209 | $this->originalPages = $params['originalPages'] ?? $this->originalPages; |
210 | } |
211 | |
212 | $this->nukeAccessStatus = $params['nukeAccessStatus'] ?? $this->nukeAccessStatus; |
213 | |
214 | $this->minPageSize = $params['minPageSize']; |
215 | $this->maxPageSize = $params['maxPageSize']; |
216 | } |
217 | |
218 | /** |
219 | * Returns {@link $action}. |
220 | * @return string |
221 | */ |
222 | public function getAction(): string { |
223 | return $this->action; |
224 | } |
225 | |
226 | /** |
227 | * Returns the target of the request: {@link $target} if {@link $action} is "delete" or |
228 | * "confirm", {@link listedTarget} otherwise. |
229 | * |
230 | * @param string|null $action The action to use. Uses {@link $action} by default. |
231 | * @return string |
232 | */ |
233 | public function getTarget( ?string $action = null ): string { |
234 | $action ??= $this->action; |
235 | |
236 | if ( $action == 'delete' || $action == 'confirm' ) { |
237 | if ( $this->listedTarget ) { |
238 | // "target" might be different, if the user typed in a different name before |
239 | // hitting "Continue". We still want to show the pages from the user currently |
240 | // shown on the form. |
241 | return $this->listedTarget; |
242 | } else { |
243 | // No provided target. This may be an incomplete request or a test. |
244 | // Fall back to using $target. |
245 | return $this->target; |
246 | } |
247 | } else { |
248 | return $this->target; |
249 | } |
250 | } |
251 | |
252 | /** |
253 | * Returns {@link $pattern}. |
254 | * @return string |
255 | */ |
256 | public function getPattern(): string { |
257 | return $this->pattern; |
258 | } |
259 | |
260 | /** |
261 | * Returns {@link $namespaces}. |
262 | * @return int[]|null |
263 | */ |
264 | public function getNamespaces(): ?array { |
265 | return $this->namespaces; |
266 | } |
267 | |
268 | /** |
269 | * Returns {@link $limit}. |
270 | * @return int |
271 | */ |
272 | public function getLimit(): int { |
273 | return $this->limit; |
274 | } |
275 | |
276 | /** |
277 | * Returns {@link $dateFrom} in DateTime format. The value of `$dateFrom` should first be |
278 | * validated with {@link validateDate}. |
279 | * |
280 | * FIXME: Doc should be changed to throw DateMalformedStringException in PHP 8.3+. |
281 | * |
282 | * @return DateTime|null |
283 | * @throws Exception |
284 | */ |
285 | public function getDateFrom(): ?DateTime { |
286 | if ( !$this->dateFrom ) { |
287 | return null; |
288 | } |
289 | return new DateTime( "{$this->dateFrom}T00:00:00Z" ); |
290 | } |
291 | |
292 | /** |
293 | * Returns {@link $dateTo} in DateTime format.The value of `$dateFrom` should first be |
294 | * validated with {@link validateDate}. |
295 | * |
296 | * FIXME: Doc should be changed to throw DateMalformedStringException in PHP 8.3+. |
297 | * |
298 | * @return DateTime|null |
299 | * @throws Exception |
300 | */ |
301 | public function getDateTo(): ?DateTime { |
302 | if ( !$this->dateTo ) { |
303 | return null; |
304 | } |
305 | return new DateTime( "{$this->dateTo}T00:00:00Z" ); |
306 | } |
307 | |
308 | /** |
309 | * Returns {@link $includeRedirects}. |
310 | * @return bool |
311 | */ |
312 | public function getIncludeRedirects(): bool { |
313 | return $this->includeRedirects; |
314 | } |
315 | |
316 | /** |
317 | * Returns {@link $includeTalkPages}. |
318 | * @return bool |
319 | */ |
320 | public function getIncludeTalkPages(): bool { |
321 | return $this->includeTalkPages; |
322 | } |
323 | |
324 | /** |
325 | * Returns a merger of {@link $pages} and {@link $associatedPages}. |
326 | * @return string[] |
327 | */ |
328 | public function getAllPages(): array { |
329 | return array_merge( $this->getPages(), $this->getAssociatedPages() ); |
330 | } |
331 | |
332 | /** |
333 | * Returns {@link $minPageSize}. |
334 | * |
335 | * @return int |
336 | */ |
337 | public function getMinPageSize(): int { |
338 | return $this->minPageSize; |
339 | } |
340 | |
341 | /** |
342 | * Returns {@link $maxPageSize}. |
343 | * |
344 | * @return int |
345 | */ |
346 | public function getMaxPageSize(): int { |
347 | return $this->maxPageSize; |
348 | } |
349 | |
350 | /** |
351 | * Returns {@link $pages}. |
352 | * @return string[] |
353 | */ |
354 | public function getPages(): array { |
355 | return $this->pages; |
356 | } |
357 | |
358 | /** |
359 | * Returns {@link $associatedPages}. |
360 | * @return string[] |
361 | */ |
362 | public function getAssociatedPages(): array { |
363 | return $this->associatedPages; |
364 | } |
365 | |
366 | /** |
367 | * Returns {@link $originalPages}. |
368 | * @return string[] |
369 | */ |
370 | public function getOriginalPages(): array { |
371 | return $this->originalPages; |
372 | } |
373 | |
374 | /** |
375 | * Returns {@link $nukeAccessStatus}. |
376 | * @return int |
377 | */ |
378 | public function getNukeAccessStatus(): int { |
379 | return $this->nukeAccessStatus; |
380 | } |
381 | |
382 | /** |
383 | * Returns {@link requestContext}. |
384 | * @return IContextSource |
385 | */ |
386 | public function getRequestContext(): IContextSource { |
387 | return $this->requestContext; |
388 | } |
389 | |
390 | /** |
391 | * Returns {@link $useTemporaryAccounts}. |
392 | * @return bool |
393 | */ |
394 | public function willUseTemporaryAccounts(): bool { |
395 | return $this->useTemporaryAccounts; |
396 | } |
397 | |
398 | /** |
399 | * Returns whether a target was specified. |
400 | * |
401 | * @return bool |
402 | */ |
403 | public function hasTarget(): bool { |
404 | return $this->target != ''; |
405 | } |
406 | |
407 | /** |
408 | * Returns whether this request has pages selected. |
409 | * |
410 | * @return bool |
411 | */ |
412 | public function hasPages(): bool { |
413 | return count( $this->pages ) > 0; |
414 | } |
415 | |
416 | /** |
417 | * Returns whether this request has pages shown to the user. |
418 | * |
419 | * @return bool |
420 | */ |
421 | public function hasOriginalPages(): bool { |
422 | return count( $this->originalPages ) > 0; |
423 | } |
424 | |
425 | /** |
426 | * Validate values for all stages of Nuke. Includes filter validation, and validation prior to |
427 | * running any "confirm"/"delete" stages. Determines what error messages should be shown to |
428 | * the user. Returns `true` on success, a string value containing the error for failures. |
429 | * |
430 | * @return string|true |
431 | */ |
432 | public function validate() { |
433 | $promptValidation = $this->validatePrompt(); |
434 | if ( $promptValidation !== true ) { |
435 | return $promptValidation; |
436 | } |
437 | |
438 | if ( |
439 | ( |
440 | // This is a confirm/delete |
441 | $this->action == SpecialNuke::ACTION_CONFIRM || |
442 | $this->action == SpecialNuke::ACTION_DELETE |
443 | ) && |
444 | // No pages were selected or provided. |
445 | !$this->hasPages() |
446 | ) { |
447 | if ( !$this->hasOriginalPages() ) { |
448 | // No page list was requested. This is an early confirm attempt without having |
449 | // listed the pages at all. Show the list form again. |
450 | return $this->requestContext->msg( 'nuke-nolist' )->text(); |
451 | } else { |
452 | // Pages were not requested but a page list exists. The user did not select any |
453 | // pages. Show the list form again. |
454 | return $this->requestContext->msg( 'nuke-noselected' )->text(); |
455 | } |
456 | } |
457 | |
458 | return true; |
459 | } |
460 | |
461 | /** |
462 | * Validate values for the "list" or "prompt" stages of Nuke. Determines what error |
463 | * messages should be shown to the user. Returns `true` on success, a string value containing |
464 | * the error for failures. |
465 | * |
466 | * Any error returned by this function should be something that blocks the search process. |
467 | * |
468 | * @return string|true |
469 | */ |
470 | public function validatePrompt() { |
471 | $fromValidationResult = $this->validateDate( $this->dateFrom ); |
472 | if ( $fromValidationResult !== true ) { |
473 | return $fromValidationResult; |
474 | } |
475 | |
476 | $toValidationResult = $this->validateDate( $this->dateTo ); |
477 | if ( $toValidationResult !== true ) { |
478 | return $toValidationResult; |
479 | } |
480 | |
481 | return true; |
482 | } |
483 | |
484 | /** |
485 | * Validate a date-related filter. Checks if the date is before the Nuke max age. |
486 | * |
487 | * @param string $value The value to validate |
488 | * @return string|true |
489 | */ |
490 | protected function validateDate( string $value ) { |
491 | if ( $value == '' ) { |
492 | // No value is valid. |
493 | return true; |
494 | } |
495 | |
496 | $now = ( new DateTime() ) |
497 | ->setTime( 0, 0 ) |
498 | ->getTimestamp(); |
499 | $maxAge = $this->getNukeMaxAge(); |
500 | |
501 | try { |
502 | $timestamp = ( new DateTime( $value . "T00:00:00Z" ) ) |
503 | ->getTimestamp(); |
504 | if ( $timestamp < $now - $maxAge ) { |
505 | return $this->requestContext->msg( |
506 | 'nuke-date-limited', |
507 | $this->requestContext->getLanguage()->formatTimePeriod( $maxAge, [ |
508 | 'avoid' => 'avoidhours', |
509 | 'noabbrevs' => true |
510 | ] ) |
511 | )->text(); |
512 | } |
513 | } catch ( \Exception $e ) { |
514 | // FIXME: This should be changed to use DateMalformedStringException when MediaWiki |
515 | // begins using PHP 8.3 as a minimum. |
516 | return $this->requestContext->msg( 'htmlform-date-invalid' )->text(); |
517 | } |
518 | return true; |
519 | } |
520 | |
521 | /** |
522 | * Get the user-provided deletion reason, or a default deletion reason if one wasn't |
523 | * provided. |
524 | * |
525 | * @return string |
526 | */ |
527 | public function getDeleteReason(): string { |
528 | $context = $this->requestContext; |
529 | $target = $this->target; |
530 | $request = $context->getRequest(); |
531 | |
532 | if ( $this->useTemporaryAccounts && IPUtils::isValid( $target ) ) { |
533 | $defaultReason = $context->msg( 'nuke-defaultreason-tempaccount' ) |
534 | ->inContentLanguage() |
535 | ->text(); |
536 | } else { |
537 | $defaultReason = $target === '' |
538 | ? $context->msg( 'nuke-multiplepeople' )->inContentLanguage()->text() |
539 | : $context->msg( 'nuke-defaultreason', $target )->inContentLanguage()->text(); |
540 | } |
541 | |
542 | $dropdownSelection = $request->getText( 'wpDeleteReasonList', 'other' ); |
543 | $reasonInput = $request->getText( 'wpReason', $defaultReason ); |
544 | |
545 | if ( $dropdownSelection === 'other' ) { |
546 | return $reasonInput; |
547 | } elseif ( $reasonInput !== '' ) { |
548 | // Entry from drop down menu + additional comment |
549 | $separator = $context->msg( 'colon-separator' )->inContentLanguage()->text(); |
550 | return $dropdownSelection . $separator . $reasonInput; |
551 | } else { |
552 | return $dropdownSelection; |
553 | } |
554 | } |
555 | |
556 | /** |
557 | * Get the maximum age in seconds that a page can be before it cannot be deleted by Nuke. |
558 | * |
559 | * @param bool $useRCMaxAge Whether to use `$wgRCMaxAge` as a fallback. |
560 | * @return int |
561 | */ |
562 | public function getNukeMaxAge( bool $useRCMaxAge = true ): int { |
563 | $maxAge = $this->requestContext->getConfig()->get( NukeConfigNames::MaxAge ); |
564 | // If no Nuke-specific max age was set, this should match the value of `$wgRCMaxAge`. |
565 | if ( !$maxAge && $useRCMaxAge ) { |
566 | $maxAge = $this->requestContext->getConfig()->get( MainConfigNames::RCMaxAge ); |
567 | } |
568 | return $maxAge; |
569 | } |
570 | |
571 | /** |
572 | * Get the maximum age in days that a page can be before it cannot be deleted by Nuke when a username is provided. |
573 | * |
574 | * @return float |
575 | */ |
576 | public function getNukeMaxAgeInDays(): float { |
577 | $secondsInADay = 86400; |
578 | return round( $this->requestContext->getConfig()->get( NukeConfigNames::MaxAge ) / $secondsInADay ); |
579 | } |
580 | |
581 | /** |
582 | * Get the maximum age in days that a page can be before it cannot be deleted by Nuke when no username is provided. |
583 | * |
584 | * @return float |
585 | */ |
586 | public function getRecentChangesMaxAgeInDays(): float { |
587 | $secondsInADay = 86400; |
588 | return round( $this->requestContext->getConfig()->get( MainConfigNames::RCMaxAge ) / $secondsInADay ); |
589 | } |
590 | |
591 | /** |
592 | * Calculate any search notices that need to be displayed with the results. |
593 | * This is based on the search parameters. |
594 | * |
595 | * @return string[] Array of i18n strings to display as a search notice |
596 | */ |
597 | public function calculateSearchNotices(): array { |
598 | $notices = []; |
599 | |
600 | // first check if any values are being ignored |
601 | $ignoringValues = false; |
602 | |
603 | if ( $this->maxPageSize < 0 ) { |
604 | // if the maximum is negative, it's invalid |
605 | // it is allowed to have it be 0, |
606 | // because a 0-byte page can exist |
607 | // the QueryBuilder code will ignore negative values |
608 | $notices[] = "nuke-searchnotice-negmax"; |
609 | $ignoringValues = true; |
610 | } |
611 | if ( $this->minPageSize < 0 ) { |
612 | // if the minimum is negative, then it's not really a minimum |
613 | // tell the user the QueryBuilder code will ignore it |
614 | // this is last because we can still return results if the minimum is negative |
615 | $notices[] = "nuke-searchnotice-negmin"; |
616 | $ignoringValues = true; |
617 | } |
618 | |
619 | // if we're not ignoring either, check for incompatibility |
620 | if ( !$ignoringValues ) { |
621 | if ( $this->minPageSize > $this->maxPageSize ) { |
622 | // if the maximum is less than the minimum then |
623 | // there's no way any results can be returned |
624 | $notices[] = "nuke-searchnotice-minmorethanmax"; |
625 | } |
626 | } |
627 | |
628 | return $notices; |
629 | } |
630 | |
631 | } |