| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -if (!defined('WPO_VERSION')) die('No direct access allowed'); | |
| 3 | +if (!defined('ABSPATH')) die('No direct access allowed'); | |
| 4 | 4 | |
| 5 | 5 | /** |
| 6 | 6 | * Parent class for all optimizations. |
| 7 | 7 | */ |
| @@ -29,10 +29,8 @@ | ||
| 29 | 29 | public $run_multisite = true; |
| 30 | 30 | |
| 31 | 31 | public $support_preview = true; // if true then optimization support preview action for optimization data. |
| 32 | 32 | |
| 33 | - protected $support_ajax_get_info = false; // set to true if optimization support getting info about optimization asynchronously. | |
| 34 | - | |
| 35 | 33 | /** |
| 36 | 34 | * This property indicates whether running this optimization is likely to change the overall table optimization state. We set this to 'true' on optimizations that run SQL OPTIMIZE commands. It is only used for the UI. Strictly, of course, any optimization that deletes something can cause increased fragmentation; so; in that sense, it would be true for every optimization; but since we are just using it to keep the UI reasonably fresh, and since there is a manual "refresh" button, we set it only on some optimizations. |
| 37 | 35 | * |
| 38 | 36 | * @var [$changes_table_data |
| @@ -96,18 +94,20 @@ | ||
| 96 | 94 | |
| 97 | 95 | protected $wpdb; |
| 98 | 96 | |
| 99 | 97 | /** |
| 100 | - * This is abstracted so as to provide future possibilities, e.g. logging. | |
| 98 | + * This is abstracted so to provide future possibilities, e.g. logging. | |
| 101 | 99 | * |
| 102 | - * @param string $sql The quesry for SQL to be ran. | |
| 103 | - * @return array Return array of results | |
| 100 | + * @param string $sql The prepared SQL query to run | |
| 101 | + * @return mixed Return array of results | |
| 104 | 102 | */ |
| 105 | 103 | protected function query($sql) { |
| 106 | 104 | $this->sql_commands[] = $sql; |
| 107 | 105 | do_action('wp_optimize_optimization_query', $sql, $this); |
| 108 | - $result = $this->wpdb->query($sql); | |
| 109 | - return apply_filters('wp_optimize_optimization_query_result', $result, $sql, $this); | |
| 106 | + $result = $this->wpdb->query($sql); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Already prepared query | |
| 107 | + $filtered_result = apply_filters('wp_optimize_optimization_query_result', $result, $sql, $this); | |
| 108 | + if (!empty($filtered_result) && is_array($filtered_result)) return $filtered_result; | |
| 109 | + return $result; | |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | /** |
| 113 | 113 | * Display or hide optimization in optimizations list. |
| @@ -127,9 +127,9 @@ | ||
| 127 | 127 | * @return array |
| 128 | 128 | */ |
| 129 | 129 | public function preview($params) { |
| 130 | 130 | return array( |
| 131 | - 'id_key' => 'id', // key used used to identify data. | |
| 131 | + 'id_key' => 'id', // key is used to identify data. | |
| 132 | 132 | 'offset' => $params['offset'], |
| 133 | 133 | 'limit' => $params['limit'], |
| 134 | 134 | 'total' => 0, |
| 135 | 135 | 'data' => array(), // returned data as associative array where keys are column names and values - database cell values. |
| @@ -139,9 +139,9 @@ | ||
| 139 | 139 | /** |
| 140 | 140 | * Convert all applicable characters to HTML entities in array. Used to prepare data for output in browser for preview. |
| 141 | 141 | * |
| 142 | 142 | * @param array $array source array |
| 143 | - * @param array $exclude_keys what items shoudn't be encoded. | |
| 143 | + * @param array $exclude_keys what items shouldn't be encoded. | |
| 144 | 144 | * |
| 145 | 145 | * @return array |
| 146 | 146 | */ |
| 147 | 147 | public function htmlentities_array($array, $exclude_keys = array()) { |
| @@ -217,9 +217,9 @@ | ||
| 217 | 217 | * This triggers the do_optimization function |
| 218 | 218 | * within class-wp-optimizer.php to kick off the optimizations. |
| 219 | 219 | * It also passed the data array from the wpadmin.js. |
| 220 | 220 | * |
| 221 | - * @return array array of results that includes sql_commands, output and meta | |
| 221 | + * @return array|object|WP_Error|WP_Optimization array of results that includes sql_commands, output and meta | |
| 222 | 222 | */ |
| 223 | 223 | public function do_optimization() { |
| 224 | 224 | return $this->optimizer->do_optimization($this); |
| 225 | 225 | } |
| @@ -227,9 +227,9 @@ | ||
| 227 | 227 | /** |
| 228 | 228 | * This gathers the optimization information to be displayed |
| 229 | 229 | * before triggering any optimizations |
| 230 | 230 | * |
| 231 | - * @return array Returns an array of optimization information | |
| 231 | + * @return array|object|WP_Error|WP_Optimization Returns an object of optimization information | |
| 232 | 232 | */ |
| 233 | 233 | public function get_optimization_info() { |
| 234 | 234 | return $this->optimizer->get_optimization_info($this); |
| 235 | 235 | } |
| @@ -255,9 +255,9 @@ | ||
| 255 | 255 | |
| 256 | 256 | // check selected sites field. |
| 257 | 257 | if (!empty($optimization_sites)) { |
| 258 | 258 | foreach ($optimization_sites as $site_id) { |
| 259 | - if ('all' == $site_id) { | |
| 259 | + if ('all' === (string) $site_id) { | |
| 260 | 260 | $all_sites = true; |
| 261 | 261 | } else { |
| 262 | 262 | $selected_sites[] = $site_id; |
| 263 | 263 | } |
| @@ -277,9 +277,11 @@ | ||
| 277 | 277 | } else { |
| 278 | 278 | $objects[] = 1; |
| 279 | 279 | } |
| 280 | 280 | |
| 281 | - return apply_filters('get_optimization_blogs', $objects); | |
| 281 | + $filtered_objects = apply_filters('get_optimization_blogs', $objects); | |
| 282 | + if (is_array($filtered_objects)) return $filtered_objects; | |
| 283 | + return $objects; | |
| 282 | 284 | } |
| 283 | 285 | |
| 284 | 286 | /** |
| 285 | 287 | * Returns true if optimization works in multisite mode |
| @@ -299,9 +301,9 @@ | ||
| 299 | 301 | return WP_Optimize()->get_sites(); |
| 300 | 302 | } |
| 301 | 303 | |
| 302 | 304 | /** |
| 303 | - * Wrapper for switch_to_blog Wordpress MU function | |
| 305 | + * Wrapper for switch_to_blog WordPress MU function | |
| 304 | 306 | * |
| 305 | 307 | * @param int $new_blog new blog id. |
| 306 | 308 | * @return bool|void - if on multisite, then always true (see https://codex.wordpress.org/Function_Reference/switch_to_blog) |
| 307 | 309 | */ |
| @@ -311,11 +313,11 @@ | ||
| 311 | 313 | } |
| 312 | 314 | } |
| 313 | 315 | |
| 314 | 316 | /** |
| 315 | - * Wrapper for restore_current_blog Wordpress MU function | |
| 317 | + * Wrapper for restore_current_blog WordPress MU function | |
| 316 | 318 | * |
| 317 | - * @return bool | |
| 319 | + * @return bool|void | |
| 318 | 320 | */ |
| 319 | 321 | public function restore_current_blog() { |
| 320 | 322 | if (function_exists('restore_current_blog') && $this->is_multisite_mode()) { |
| 321 | 323 | return restore_current_blog(); |
| @@ -324,9 +326,9 @@ | ||
| 324 | 326 | |
| 325 | 327 | /** |
| 326 | 328 | * This function adds output to the current registered output |
| 327 | 329 | * |
| 328 | - * @param array $output Array of various outputs. | |
| 330 | + * @param string $output Output message | |
| 329 | 331 | */ |
| 330 | 332 | public function register_output($output) { |
| 331 | 333 | $this->output[] = $output; |
| 332 | 334 | } |
| @@ -334,9 +336,9 @@ | ||
| 334 | 336 | /** |
| 335 | 337 | * This function adds meta-data associated with the result to the registered output |
| 336 | 338 | * |
| 337 | 339 | * @param string $key The key value. |
| 338 | - * @param string $value The value to be passed. | |
| 340 | + * @param mixed $value The value to be passed. | |
| 339 | 341 | */ |
| 340 | 342 | public function register_meta($key, $value) { |
| 341 | 343 | $this->meta[$key] = $value; |
| 342 | 344 | } |
| @@ -369,42 +371,55 @@ | ||
| 369 | 371 | |
| 370 | 372 | |
| 371 | 373 | /** |
| 372 | 374 | * The next three functions reflect the fact that historically, WP-Optimize has not, for all optimizations, used the same ID consistently throughout forms, saved settings, and saved settings for scheduled clean-ups. Mostly, it has; but some flexibility is needed for the exceptions. |
| 375 | + * | |
| 376 | + * @return string | |
| 373 | 377 | */ |
| 374 | 378 | public function get_setting_id() { |
| 375 | 379 | return empty($this->setting_id) ? 'user-'.$this->id : 'user-'.$this->setting_id; |
| 376 | 380 | } |
| 377 | 381 | |
| 382 | + /** | |
| 383 | + * This function, `get_setting_id` and `get_auto_id` functions reflect the fact that historically, WP-Optimize has not, for all optimizations, used the same ID consistently throughout forms, saved settings, and saved settings for scheduled clean-ups. Mostly, it has; but some flexibility is needed for the exceptions. | |
| 384 | + * | |
| 385 | + * @return string | |
| 386 | + */ | |
| 378 | 387 | public function get_dom_id() { |
| 379 | 388 | return empty($this->dom_id) ? 'clean-'.$this->id : $this->dom_id; |
| 380 | 389 | } |
| 381 | 390 | |
| 391 | + /** | |
| 392 | + * This function, `get_setting_id` and `get_dom_id` functions reflect the fact that historically, WP-Optimize has not, for all optimizations, used the same ID consistently throughout forms, saved settings, and saved settings for scheduled clean-ups. Mostly, it has; but some flexibility is needed for the exceptions. | |
| 393 | + * | |
| 394 | + * @return string | |
| 395 | + */ | |
| 382 | 396 | public function get_auto_id() { |
| 383 | 397 | return empty($this->auto_id) ? $this->id : $this->auto_id; |
| 384 | 398 | } |
| 385 | 399 | |
| 400 | + /** | |
| 401 | + * Checks whether this optimization has changes table data | |
| 402 | + * | |
| 403 | + * @return bool | |
| 404 | + */ | |
| 386 | 405 | public function get_changes_table_data() { |
| 387 | 406 | return empty($this->changes_table_data) ? false : true; |
| 388 | 407 | } |
| 389 | 408 | |
| 390 | - public function get_run_sort_order() { | |
| 391 | - return empty($this->run_sort_order) ? 0 : $this->run_sort_order; | |
| 392 | - } | |
| 393 | - | |
| 394 | 409 | /** |
| 395 | - * Only used if $available_for_auto is true, in which case this function should be over-ridden | |
| 410 | + * Returns the run sort order | |
| 396 | 411 | * |
| 397 | - * @return string Error message. | |
| 412 | + * @return int | |
| 398 | 413 | */ |
| 399 | - public function get_auto_option_description() { | |
| 400 | - return 'Error: missing scheduled option description ('.$this->id.')'; | |
| 414 | + public function get_run_sort_order() { | |
| 415 | + return empty($this->run_sort_order) ? 0 : $this->run_sort_order; | |
| 401 | 416 | } |
| 402 | 417 | |
| 403 | 418 | /** |
| 404 | 419 | * What is returned must be at least convertible to an array |
| 405 | 420 | * |
| 406 | - * @return array Array of results. | |
| 421 | + * @return object Results object. | |
| 407 | 422 | */ |
| 408 | 423 | public function get_results() { |
| 409 | 424 | |
| 410 | 425 | // As yet, we have no need for a dedicated object type for our results. |
| @@ -413,19 +428,19 @@ | ||
| 413 | 428 | $results->sql_commands = $this->sql_commands; |
| 414 | 429 | $results->output = $this->output; |
| 415 | 430 | $results->meta = $this->meta; |
| 416 | 431 | |
| 417 | - return apply_filters('wp_optimize_optimization_results', $results, $this->id, $this); | |
| 432 | + $filtered_results = apply_filters('wp_optimize_optimization_results', $results, $this->id, $this); | |
| 433 | + if (!empty($filtered_results) && is_object($filtered_results)) return $filtered_results; | |
| 434 | + return $results; | |
| 418 | 435 | } |
| 419 | 436 | |
| 420 | 437 | /** |
| 421 | 438 | * Generate information about optimization required for show it. |
| 422 | 439 | * |
| 423 | - * @param bool $ajax_get_info if true then information about optimization will not generated, i.e. get_optimization_info() won't call. | |
| 424 | - * | |
| 425 | 440 | * @return array |
| 426 | 441 | */ |
| 427 | - public function get_settings_html($ajax_get_info = false) { | |
| 442 | + public function get_settings_html() { | |
| 428 | 443 | |
| 429 | 444 | $wpo_user_selection = $this->options->get_main_settings(); |
| 430 | 445 | $setting_id = $this->get_setting_id(); |
| 431 | 446 | $dom_id = $this->get_dom_id(); |
| @@ -432,23 +447,22 @@ | ||
| 432 | 447 | |
| 433 | 448 | // N.B. Some of the optimizations used to have an onclick call to fCheck(). But that function was commented out, so did nothing. |
| 434 | 449 | $settings_label = $this->settings_label(); |
| 435 | 450 | |
| 436 | - $setting_activated = ((empty($wpo_user_selection[$setting_id]) || 'false' == $wpo_user_selection[$setting_id]) ? false : true); | |
| 451 | + $setting_activated = !empty($wpo_user_selection[$setting_id]) && 'false' !== $wpo_user_selection[$setting_id]; | |
| 437 | 452 | |
| 438 | - $info = ($ajax_get_info && $this->support_ajax_get_info) ? '...' : $this->get_optimization_info()->output; | |
| 453 | + $info = $this->get_optimization_info()->output; | |
| 439 | 454 | |
| 440 | 455 | $settings_html = array( |
| 441 | 456 | 'dom_id' => $dom_id, |
| 442 | 457 | 'activated' => $setting_activated, |
| 443 | 458 | 'settings_label' => $settings_label, |
| 444 | - 'info' => $info, | |
| 445 | - 'support_ajax_get_info' => $this->support_ajax_get_info | |
| 459 | + 'info' => wp_kses(join('<br>', $info), $this->allow_checkboxes()), | |
| 446 | 460 | ); |
| 447 | 461 | |
| 448 | 462 | if (empty($settings_label)) { |
| 449 | 463 | // Error_log, as this is a defect. |
| 450 | - error_log("Optimization with setting ID ".$setting_id." lacks a settings label (method: settings_label())"); | |
| 464 | + error_log("Optimization with setting ID ".$setting_id." lacks a settings label (method: settings_label())"); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Using for debugging only | |
| 451 | 465 | } |
| 452 | 466 | |
| 453 | 467 | return $settings_html; |
| 454 | 468 | } |
| @@ -462,9 +476,9 @@ | ||
| 462 | 476 | * @return string |
| 463 | 477 | */ |
| 464 | 478 | public function get_preview_link($text, $attributes = array()) { |
| 465 | 479 | // if preview is not supported then return just $text. |
| 466 | - if (false == $this->support_preview || false == WP_Optimize::is_premium()) return $text; | |
| 480 | + if (!$this->support_preview || !WP_Optimize::is_premium()) return $text; | |
| 467 | 481 | |
| 468 | 482 | $attributes = array_merge( |
| 469 | 483 | array( |
| 470 | 484 | 'title' => __('Preview found items', 'wp-optimize'), |
| @@ -482,6 +496,38 @@ | ||
| 482 | 496 | |
| 483 | 497 | $link = '<a href="#" class="wpo-optimization-preview"'.$str_attr.'>'.$text.'</a>'; |
| 484 | 498 | |
| 485 | 499 | return $link; |
| 500 | + } | |
| 501 | + | |
| 502 | + /** | |
| 503 | + * Adds input and label tags to allowed HTML tags. | |
| 504 | + * | |
| 505 | + * @return array | |
| 506 | + */ | |
| 507 | + private function allow_checkboxes() { | |
| 508 | + $allowed_html = wp_kses_allowed_html('post'); | |
| 509 | + | |
| 510 | + $allowed_html['input'] = array( | |
| 511 | + 'type' => true, | |
| 512 | + 'name' => true, | |
| 513 | + 'id' => true, | |
| 514 | + 'class' => true, | |
| 515 | + 'value' => true, | |
| 516 | + 'placeholder' => true, | |
| 517 | + 'required' => true, | |
| 518 | + 'checked' => true, | |
| 519 | + 'disabled' => true, | |
| 520 | + 'min' => true, | |
| 521 | + 'max' => true, | |
| 522 | + 'step' => true | |
| 523 | + ); | |
| 524 | + | |
| 525 | + $allowed_html['label'] = array( | |
| 526 | + 'for' => true, | |
| 527 | + 'class' => true, | |
| 528 | + 'id' => true | |
| 529 | + ); | |
| 530 | + | |
| 531 | + return $allowed_html; | |
| 486 | 532 | } |
| 487 | 533 | } |