PluginProbe ʕ •ᴥ•ʔ
Advanced Database Cleaner – Optimize & Clean Database to Speed Up Site Performance / 4.2.0
Advanced Database Cleaner – Optimize & Clean Database to Speed Up Site Performance v4.2.0
4.2.0 trunk 1.0.0 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.5 1.3.6 1.3.7 2.0.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.1.0 4.1.1
advanced-database-cleaner / includes / utils / validator / class-adbc-common-validator.php
advanced-database-cleaner / includes / utils / validator Last commit date
class-adbc-automation-validator.php 7 months ago class-adbc-common-validator.php 5 days ago class-adbc-selected-items-validator.php 3 months ago class-adbc-settings-validator.php 5 days ago class-adbc-tables-validator.php 7 months ago
class-adbc-common-validator.php
619 lines
1 <?php
2
3 // Exit if accessed directly
4 if ( ! defined( 'ABSPATH' ) )
5 exit;
6
7 /**
8 * ADBC Common validator class.
9 *
10 * This class provides functions to validate and sanitize general data used in the plugin.
11 */
12 class ADBC_Common_Validator {
13
14 /**
15 * Sanitize the DataTable filters sent by the user.
16 *
17 * @param WP_REST_Request $filters_request The filters request.
18 *
19 * @return array The sanitized filters.
20 */
21 public static function sanitize_filters( WP_REST_Request $filters_request ) {
22
23 $sanitized_filters = [
24 'size' => sanitize_key( $filters_request->get_param( 'size' ) ),
25 'size_unit' => sanitize_text_field( $filters_request->get_param( 'sizeUnit' ) ), // KB, MB, GB
26 'table_status' => sanitize_key( $filters_request->get_param( 'tableStatus' ) ),
27 'prefix_status' => sanitize_key( $filters_request->get_param( 'prefixStatus' ) ),
28 'belongs_to' => sanitize_key( $filters_request->get_param( 'belongsTo' ) ),
29 'current_page' => sanitize_key( $filters_request->get_param( 'currentPage' ) ),
30 'items_per_page' => sanitize_key( $filters_request->get_param( 'itemsPerPage' ) ),
31 'sort_by' => sanitize_text_field( $filters_request->get_param( 'sortBy' ) ),
32 'sort_order' => sanitize_text_field( $filters_request->get_param( 'sortOrder' ) ),
33 'items_type' => $filters_request->get_param( 'itemsType' ),
34 'expired' => sanitize_key( $filters_request->get_param( 'expired' ) ),
35 'duplicated' => sanitize_key( $filters_request->get_param( 'duplicated' ) ),
36 'unused' => sanitize_key( $filters_request->get_param( 'unused' ) ),
37 'has_action' => sanitize_key( $filters_request->get_param( 'hasAction' ) ),
38 'search_for' => $filters_request->get_param( 'search' ), // Don't sanitize this to not break the search query. We assure security later.
39 'search_in' => sanitize_key( $filters_request->get_param( 'searchIn' ) ),
40 'site_id' => sanitize_key( $filters_request->get_param( 'site' ) ),
41 'belongs_to_plugin_slug' => sanitize_text_field( $filters_request->get_param( 'belongsToPluginSlug' ) ),
42 'belongs_to_theme_slug' => sanitize_text_field( $filters_request->get_param( 'belongsToThemeSlug' ) ),
43 'show_manual_corrections_only' => $filters_request->get_param( 'showManualCorrectionsOnly' ),
44 'autoload' => sanitize_key( $filters_request->get_param( 'autoload' ) ),
45 'start_date' => $filters_request->get_param( 'startDate' ),
46 'end_date' => $filters_request->get_param( 'endDate' ),
47 'frequency' => sanitize_key( $filters_request->get_param( 'frequency' ) ),
48 'interval' => $filters_request->get_param( 'interval' ),
49 'post_types_posts_count' => sanitize_key( $filters_request->get_param( 'postTypesPostsCount' ) ),
50 'post_types_visibility' => sanitize_key( $filters_request->get_param( 'postTypesVisibility' ) ),
51 ];
52
53 // Sanitize and validate common filters
54 $sanitized_filters['size'] = absint( $sanitized_filters['size'] );
55 $sanitized_filters['size_unit'] = in_array( $sanitized_filters['size_unit'], [ 'B', 'KB', 'MB', 'GB' ] ) ? $sanitized_filters['size_unit'] : 'KB';
56 $sanitized_filters['table_status'] = in_array( $sanitized_filters['table_status'], [ 'all', 'to_optimize', 'to_repair' ] ) ? $sanitized_filters['table_status'] : 'all';
57 $sanitized_filters['prefix_status'] = in_array( $sanitized_filters['prefix_status'], [ 'all', 'valid_prefix', 'invalid_prefix' ] ) ? $sanitized_filters['prefix_status'] : 'all';
58 $sanitized_filters['belongs_to'] =
59 in_array( $sanitized_filters['belongs_to'], [ 'all', 'not_scanned', 'plugins', 'themes', 'wordpress', 'orphans', 'unknown' ] ) ? $sanitized_filters['belongs_to'] : 'all';
60 $sanitized_filters['current_page'] = self::sanitize_validate_current_page( $sanitized_filters['current_page'] );
61 $sanitized_filters['items_per_page'] = self::sanitize_validate_limit( $sanitized_filters['items_per_page'] );
62 // $sanitized_filters['sort_by'] SQL queries will check if the column exists.
63 $sanitized_filters['sort_order'] = in_array( $sanitized_filters['sort_order'], [ 'ASC', 'DESC' ] ) ? $sanitized_filters['sort_order'] : 'ASC';
64 $sanitized_filters['items_type'] = self::sanitize_items_type( $sanitized_filters['items_type'] );
65 $sanitized_filters['expired'] = in_array( $sanitized_filters['expired'], [ 'all', 'yes', 'no' ], true ) ? $sanitized_filters['expired'] : 'all';
66 $sanitized_filters['duplicated'] = in_array( $sanitized_filters['duplicated'], [ 'all', 'yes', 'no' ], true ) ? $sanitized_filters['duplicated'] : 'all';
67 $sanitized_filters['unused'] = in_array( $sanitized_filters['unused'], [ 'all', 'yes', 'no' ], true ) ? $sanitized_filters['unused'] : 'all';
68 $sanitized_filters['has_action'] = in_array( $sanitized_filters['has_action'], [ 'all', 'yes', 'no' ], true ) ? $sanitized_filters['has_action'] : 'all';
69 $sanitized_filters['autoload'] = in_array( $sanitized_filters['autoload'], [ 'all', 'yes', 'no' ] ) ? $sanitized_filters['autoload'] : 'all';
70
71 // In free set premium filters to default values since they are not supported in free version.
72 if ( ADBC_VERSION_TYPE === "FREE" ) {
73 $sanitized_filters['search_for'] = '';
74 $sanitized_filters['search_in'] = 'name';
75 $sanitized_filters['site_id'] = 'all';
76 $sanitized_filters['belongs_to_plugin_slug'] = '';
77 $sanitized_filters['belongs_to_theme_slug'] = '';
78 $sanitized_filters['show_manual_corrections_only'] = false;
79 $sanitized_filters['start_date'] = null;
80 $sanitized_filters['end_date'] = null;
81 $sanitized_filters['frequency'] = 'all';
82 $sanitized_filters['interval'] = 'all';
83 $sanitized_filters['post_types_posts_count'] = 0;
84 $sanitized_filters['post_types_visibility'] = 'all';
85 } else {
86 // In premium, sanitize the premium filters.
87 ADBC_Premium_Common_Validator::sanitize_filters( $sanitized_filters );
88 }
89
90 return $sanitized_filters;
91
92 }
93
94 /**
95 * Checks if the given value equals "0" or "1".
96 *
97 * @param string $key The key of the value to check (not used in this method).
98 * @param string $value The value to check.
99 * @return bool True if the value equals "0" or "1", false otherwise.
100 */
101 public static function is_string_equals_0_or_1( $key, $value ) {
102 return ( $value === "0" || $value === "1" );
103 }
104
105 /**
106 * Checks if the given value is a valid number that is between the specified min and max values.
107 *
108 * @param string $value The value to check.
109 * @param int $min The minimum value.
110 * @param int $max The maximum value.
111 * @return bool True if the value is a number between min and max, false otherwise.
112 */
113 public static function is_number_between_min_and_max( $value, $min, $max ) {
114 return ( is_numeric( $value ) && $value >= $min && $value <= $max );
115 }
116
117 /**
118 * Validates the action data for the given action and items type sent by the user.
119 *
120 * @param string $action The action to validate (e.g., 'optimize_tables', 'delete_options'...).
121 * @param string $items_type The type of items (e.g., 'tables', 'options'...).
122 * @param WP_REST_Request $request_data The request data containing the action and selected items, etc. sent by the user to the endpoint.
123 * @param bool $keep_prefix Whether to keep the prefix in the returned table names (used only for tables).
124 *
125 * @return array|string An array of valid items or an error message if validation fails.
126 */
127 public static function validate_endpoint_action_data( $action, $items_type, $request_data, $keep_prefix = true ) {
128
129 // Get params
130 $action_type = $request_data->get_param( 'actionType' );
131 $selected_items = $request_data->get_param( 'selectedItems' );
132
133 // Check action is valid
134 if ( $action_type !== $action )
135 return "Invalid action.";
136
137 // Delete invalid items from the selected tables and return valid ones.
138 $selected_items = ADBC_Selected_Items_Validator::remove_invalid_selected_items( $items_type, $selected_items, $keep_prefix );
139
140 // Check empty.
141 if ( empty( $selected_items ) )
142 return "No items to process";
143
144 return $selected_items;
145 }
146
147 /**
148 * Validates the data sent by the user to get_column_value_from_table endpoint.
149 *
150 * @param string $items_type The type of items (e.g., 'options', 'transients').
151 * @param int $site_id The site ID.
152 * @param int $row_id The row ID to get the value from.
153 * @param string $transient_found_in The transient found in, if applicable (e.g., 'options', 'sitemeta').
154 *
155 * @return array|string An array with success status, message, and data or an error message if validation fails.
156 */
157 public static function validate_get_column_value_endpoint_data( $items_type, $site_id, $row_id, $transient_found_in ) {
158
159 $answer = [ "success" => false, "message" => "", "data" => []];
160
161 // Check items type is valid
162 if ( ! in_array( $items_type, [ 'options', 'transients', 'posts_meta', 'users_meta', 'revisions', 'auto_drafts', 'trashed_posts', 'unapproved_comments', 'spam_comments', 'trashed_comments', 'pingbacks', 'trackbacks', 'unused_postmeta', 'duplicated_postmeta', 'unused_commentmeta', 'duplicated_commentmeta', 'unused_usermeta', 'duplicated_usermeta', 'unused_termmeta', 'duplicated_termmeta', 'unused_relationships', 'expired_transients', 'oembed_caches', 'actionscheduler_completed_actions', 'actionscheduler_failed_actions', 'actionscheduler_canceled_actions', 'actionscheduler_completed_logs', 'actionscheduler_failed_logs', 'actionscheduler_canceled_logs', 'actionscheduler_orphan_logs', 'woocommerce_orphaned_customer_analytics', 'woocommerce_orphaned_product_variations' ], true ) )
163 $answer['message'] = "Invalid items type.";
164
165 // Check site ID is valid
166 if ( ! is_numeric( $site_id ) || $site_id < 0 )
167 $answer['message'] = "Invalid site ID.";
168
169 // Check row ID is valid
170 if ( ! is_numeric( $row_id ) || $row_id < 0 )
171 $answer['message'] = "Invalid row ID.";
172
173 // Check if transient_found_in is valid
174 if ( $items_type === 'expired_transients' && ! in_array( $transient_found_in, [ 'options', 'sitemeta' ], true ) )
175 $answer['message'] = "Invalid transient_found_in parameter.";
176
177 // Get the site prefix
178 $site_prefix = ADBC_Sites::instance()->get_prefix_from_site_id( $site_id );
179 if ( $site_prefix === null )
180 $answer['message'] = "Cannot find the site prefix.";
181
182 // Check if there is an error
183 if ( ! empty( $answer['message'] ) )
184 return $answer;
185
186 // Prepare the table name and column names based on the items type
187 switch ( $items_type ) {
188 case 'options':
189 $answer['data'] = [
190 'table_name' => $site_prefix . 'options',
191 'column_id' => "option_id",
192 'column_name' => "option_value"
193 ];
194 break;
195
196 case 'posts_meta':
197 $answer['data'] = [
198 'table_name' => $site_prefix . 'postmeta',
199 'column_id' => "meta_id",
200 'column_name' => "meta_value"
201 ];
202 break;
203
204 case 'users_meta':
205 $answer['data'] = [
206 'table_name' => $site_prefix . 'usermeta',
207 'column_id' => "umeta_id",
208 'column_name' => "meta_value"
209 ];
210 break;
211
212 case 'revisions':
213 case 'auto_drafts':
214 case 'trashed_posts':
215 $answer['data'] = [
216 'table_name' => $site_prefix . 'posts',
217 'column_id' => "ID",
218 'column_name' => "post_content"
219 ];
220 break;
221
222 case 'unapproved_comments':
223 case 'spam_comments':
224 case 'trashed_comments':
225 case 'pingbacks':
226 case 'trackbacks':
227 $answer['data'] = [
228 'table_name' => $site_prefix . 'comments',
229 'column_id' => "comment_ID",
230 'column_name' => "comment_content"
231 ];
232 break;
233
234 case 'unused_postmeta':
235 case 'duplicated_postmeta':
236 case 'oembed_caches':
237 $answer['data'] = [
238 'table_name' => $site_prefix . 'postmeta',
239 'column_id' => "meta_id",
240 'column_name' => "meta_value"
241 ];
242 break;
243
244 case 'unused_commentmeta':
245 case 'duplicated_commentmeta':
246 $answer['data'] = [
247 'table_name' => $site_prefix . 'commentmeta',
248 'column_id' => "meta_id",
249 'column_name' => "meta_value"
250 ];
251 break;
252
253 case 'unused_termmeta':
254 case 'duplicated_termmeta':
255 $answer['data'] = [
256 'table_name' => $site_prefix . 'termmeta',
257 'column_id' => "meta_id",
258 'column_name' => "meta_value"
259 ];
260 break;
261
262 case 'unused_usermeta':
263 case 'duplicated_usermeta':
264 $answer['data'] = [
265 'table_name' => $site_prefix . 'usermeta',
266 'column_id' => "umeta_id",
267 'column_name' => "meta_value"
268 ];
269 break;
270
271 case 'unused_relationships':
272 $answer['data'] = [
273 'table_name' => $site_prefix . 'term_relationships',
274 'column_id' => "object_id",
275 'column_name' => "term_order"
276 ];
277 break;
278
279 case 'expired_transients':
280 case 'transients':
281 switch ( $transient_found_in ) {
282 case 'sitemeta':
283 $answer['data'] = [
284 'table_name' => $site_prefix . 'sitemeta',
285 'column_id' => "meta_id",
286 'column_name' => "meta_value"
287 ];
288 break;
289 case 'options':
290 $answer['data'] = [
291 'table_name' => $site_prefix . 'options',
292 'column_id' => "option_id",
293 'column_name' => "option_value"
294 ];
295 break;
296 }
297 break;
298
299 case 'actionscheduler_completed_actions':
300 case 'actionscheduler_failed_actions':
301 case 'actionscheduler_canceled_actions':
302 $answer['data'] = [
303 'table_name' => $site_prefix . 'actionscheduler_actions',
304 'column_id' => "action_id",
305 'column_name' => "args"
306 ];
307 break;
308 case 'actionscheduler_completed_logs':
309 case 'actionscheduler_failed_logs':
310 case 'actionscheduler_canceled_logs':
311 case 'actionscheduler_orphan_logs':
312 $answer['data'] = [
313 'table_name' => $site_prefix . 'actionscheduler_logs',
314 'column_id' => "log_id",
315 'column_name' => "message"
316 ];
317 break;
318 case 'woocommerce_orphaned_customer_analytics':
319 $answer['data'] = [
320 'table_name' => $site_prefix . 'wc_customer_lookup',
321 'column_id' => "customer_id",
322 'column_name' => "email"
323 ];
324 break;
325 case 'woocommerce_orphaned_product_variations':
326 $answer['data'] = [
327 'table_name' => $site_prefix . 'posts',
328 'column_id' => "ID",
329 'column_name' => "post_content"
330 ];
331 break;
332 }
333
334 $answer['success'] = true;
335 return $answer;
336 }
337
338 /**
339 * Validates two optional dates for use as REST filter parameters.
340 *
341 * If only one date is valid, it is returned while the other slot is `null`.
342 * If both dates are present they must be chronological and, when `$max_days`
343 * is > 0, their span must not exceed that limit.
344 *
345 * @param string|null $start_date The start date in the specified format.
346 * @param string|null $end_date The end date in the specified format.
347 * @param string $date_format The date format to use for parsing the dates.
348 * @param int $max_days The maximum number of days allowed between the start and end dates.
349 *
350 * @return array [ start|null, end|null ]
351 */
352 public static function validate_filter_date_range( $start_date = null, $end_date = null, $date_format = 'Y-m-d', $max_days = 0 ) {
353
354 $result = [ null, null ];
355 $start_obj = null;
356 $end_obj = null;
357
358 /*— individually validate ------------------------------------------------*/
359 if ( ! empty( $start_date ) ) {
360 $start_obj = ADBC_Common_Utils::parse_date( $start_date, $date_format );
361 if ( $start_obj ) {
362 $result[0] = $start_obj->format( $date_format );
363 }
364 }
365 if ( ! empty( $end_date ) ) {
366 $end_obj = ADBC_Common_Utils::parse_date( $end_date, $date_format );
367 if ( $end_obj ) {
368 $result[1] = $end_obj->format( $date_format );
369 }
370 }
371
372 /*— both dates supplied? apply cross checks ------------------------------*/
373 if ( $start_obj && $end_obj ) {
374 // chronology
375 if ( $start_obj > $end_obj ) {
376 return [ null, null ];
377 }
378 // length restriction
379 if ( $max_days > 0 && $start_obj->diff( $end_obj )->days > $max_days ) {
380 return [ null, null ];
381 }
382 }
383
384 return $result;
385
386 }
387
388 /**
389 * Validates a *complete* date range. Anything off → `[null, null]`.
390 *
391 * Use when the caller must provide both dates and (optionally) stay within
392 * `$max_days`.
393 *
394 * @param string $start_date The start date in the specified format.
395 * @param string $end_date The end date in the specified format.
396 * @param string $date_format The date format to use for parsing the dates.
397 * @param int $max_days The maximum number of days allowed between the start and end dates.
398 *
399 * @return array [ start|null, end|null ]
400 */
401 public static function validate_strict_date_range( $start_date, $end_date, $date_format = 'Y-m-d', $max_days = 0 ) {
402
403 $invalid = [ null, null ];
404
405 /*— both dates must be present ------------------------------------------*/
406 if ( empty( $start_date ) || empty( $end_date ) ) {
407 return $invalid;
408 }
409
410 $start_obj = ADBC_Common_Utils::parse_date( $start_date, $date_format );
411 $end_obj = ADBC_Common_Utils::parse_date( $end_date, $date_format );
412
413 if ( ! $start_obj || ! $end_obj ) {
414 return $invalid;
415 }
416
417 /*— chronology and (optional) length ------------------------------------*/
418 if ( $start_obj > $end_obj ) {
419 return $invalid;
420 }
421 if ( $max_days > 0 && $start_obj->diff( $end_obj )->days > $max_days ) {
422 return $invalid;
423 }
424
425 return [
426 $start_obj->format( $date_format ),
427 $end_obj->format( $date_format ),
428 ];
429
430 }
431
432 /**
433 * Sanitize the items type sent by the user.
434 *
435 * @param string $items_type The items type.
436 *
437 * @return string The sanitized items type, empty string if invalid.
438 */
439 public static function sanitize_items_type( $items_type ) {
440
441 $items_type = sanitize_key( $items_type );
442
443 $valid_items = array_merge(
444 [
445 'options',
446 'tables',
447 'cron_jobs',
448 'transients',
449 'posts_meta',
450 'users_meta',
451 'post_types',
452 ],
453 ADBC_Cleanup_Type_Registry::get_all_items_type()
454 );
455
456 $valid_items_type = in_array( $items_type, $valid_items, true );
457
458 return $valid_items_type ? $items_type : '';
459
460 }
461
462 /**
463 * Sanitize an array of items types sent by the user.
464 *
465 * @param array $items_types The array of items types.
466 *
467 * @return array The sanitized array of items types, empty array if all invalid.
468 */
469 public static function sanitize_items_types( $items_types ) {
470
471 if ( ! is_array( $items_types ) ) {
472 return [];
473 }
474
475 $validated_items_types = [];
476
477 foreach ( $items_types as $item_type ) {
478 $sanitized = self::sanitize_items_type( $item_type );
479 if ( $sanitized !== '' ) {
480 $validated_items_types[] = $sanitized;
481 }
482 }
483
484 return $validated_items_types;
485
486 }
487
488 /**
489 * Validate the manual categorization sent by the user.
490 *
491 * @param string $manual_categorization The manual categorization.
492 * @return string|bool The error message if the manual categorization is invalid, true otherwise.
493 */
494 public static function is_manual_categorization_valid( $manual_categorization ) {
495
496 $generic_error_msg = "Invalid manual correction.";
497
498 // Check if three keys exist in the manual categorization associative array: type, slug and send_to_server
499 if ( ! is_array( $manual_categorization ) ||
500 ! key_exists( 'type', $manual_categorization ) ||
501 ! key_exists( 'slug', $manual_categorization ) ||
502 ! key_exists( 'send_to_server', $manual_categorization ) )
503 return $generic_error_msg . ' #1';
504
505 $correction_category = $manual_categorization['type'];
506 if ( ! is_string( $correction_category ) || ! in_array( $correction_category, [ 'p', 't', 'w', 'o', 'u' ], true ) )
507 return $generic_error_msg . ' #2';
508
509 $slug = $manual_categorization['slug'];
510 if ( ! is_string( $slug ) )
511 return $generic_error_msg . ' #3';
512
513 $is_custom = key_exists( 'is_custom', $manual_categorization );
514 if ( $is_custom && ! in_array( $manual_categorization['is_custom'], [ true, 1, '1' ], true ) )
515 return $generic_error_msg . ' #7';
516
517 if ( $is_custom ) {
518
519 // Custom addons are stored as regular plugin/theme manual corrections, but do not need to be installed.
520 if ( ! in_array( $correction_category, [ 'p', 't' ], true ) )
521 return $generic_error_msg . ' #8';
522
523 // WordPress-compatible slugs: lowercase ASCII letters, numbers, hyphens and underscores.
524 if ( strlen( $slug ) > 200 || preg_match( '/^[a-z0-9_-]+$/', $slug ) !== 1 )
525 return $generic_error_msg . ' #9';
526
527 if ( ! key_exists( 'name', $manual_categorization ) || ! is_string( $manual_categorization['name'] ) )
528 return $generic_error_msg . ' #10';
529
530 $addon_name = trim( $manual_categorization['name'] );
531 $addon_name_length = preg_match_all( '/./us', $addon_name ); // Count the number of Unicode characters in the string.
532 if ( $addon_name === '' || $addon_name_length === false || $addon_name_length > 200 || preg_match( '/[\x00-\x1F\x7F]/', $addon_name ) )
533 return $generic_error_msg . ' #11';
534
535 } else {
536
537 if ( in_array( $correction_category, [ 'w', 'o', 'u' ], true ) && ! in_array( $slug, [ 'w', 'o', 'u' ], true ) )
538 return $generic_error_msg . ' #3';
539
540 if ( $correction_category === 'p' && ! ADBC_Plugins::instance()->is_plugin_slug_currently_installed( $slug ) )
541 return $generic_error_msg . ' #4';
542
543 if ( $correction_category === 't' && ! ADBC_Themes::instance()->is_theme_slug_currently_installed( $slug ) )
544 return $generic_error_msg . ' #5';
545
546 }
547
548 $send_correction_to_server = $manual_categorization['send_to_server'];
549
550 if ( ! in_array( $send_correction_to_server, [ '0', '1' ], true ) )
551 return $generic_error_msg . ' #6';
552
553 return true;
554 }
555
556 /**
557 * Validate the offset sent by the user.
558 *
559 * @param int $offset The offset.
560 *
561 * @return int The sanitized offset, 0 if invalid.
562 */
563 public static function sanitize_validate_offset( $offset ) {
564
565 // Sanitize the offset
566 $offset = absint( $offset );
567
568 if ( $offset < 0 )
569 return 0;
570
571 return $offset;
572
573 }
574
575 /**
576 * Validate the limit sent by the user.
577 *
578 * @param int $limit The limit.
579 *
580 * @return int The sanitized limit, 50 if invalid and 1000 max.
581 */
582 public static function sanitize_validate_limit( $limit ) {
583
584 // Sanitize the limit
585 $limit = absint( $limit );
586
587 // Limit the limit to 50 if less than 1
588 if ( $limit < 1 )
589 return 50;
590
591 // Limit the limit to 1000
592 if ( $limit > 1000 )
593 return 1000;
594
595 return $limit;
596
597 }
598
599 /**
600 * Sanitize and validate the current page sent by the user.
601 *
602 * @param int $current_page The current page.
603 *
604 * @return int The sanitized current page, 1 if invalid.
605 */
606 public static function sanitize_validate_current_page( $current_page ) {
607
608 // Sanitize the current page
609 $current_page = absint( $current_page );
610
611 // If current page is less than 1, set it to 1
612 if ( $current_page < 1 )
613 return 1;
614
615 return $current_page;
616
617 }
618
619 }