sql_commands[] = $sql;
do_action('wp_optimize_optimization_query', $sql, $this);
$result = $this->wpdb->query($sql); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Already prepared query
$filtered_result = apply_filters('wp_optimize_optimization_query_result', $result, $sql, $this);
if (!empty($filtered_result) && is_array($filtered_result)) return $filtered_result;
return $result;
}
/**
* Display or hide optimization in optimizations list.
*
* @return bool
*/
public function display_in_optimizations_list() {
return true;
}
/**
* Returns data those should be optimized. Used to display this information in a popup tool
* for previewing and removing certain data for optimization.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
return array(
'id_key' => 'id', // key is used to identify data.
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => 0,
'data' => array(), // returned data as associative array where keys are column names and values - database cell values.
);
}
/**
* Convert all applicable characters to HTML entities in array. Used to prepare data for output in browser for preview.
*
* @param array $array source array
* @param array $exclude_keys what items shouldn't be encoded.
*
* @return array
*/
public function htmlentities_array($array, $exclude_keys = array()) {
if (!is_array($array) || empty($array)) return $array;
foreach ($array as $key => $value) {
if (in_array($key, $exclude_keys)) continue;
if (!is_array($value)) {
$array[$key] = htmlentities($value);
} else {
$array[$key] = $this->htmlentities_array($value);
}
}
return $array;
}
/**
* Do actions before get_info() function.
*/
public function before_get_info() {
$this->found_count = 0;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
}
abstract public function get_info();
/**
* Do actions before optimize() function.
*/
public function before_optimize() {
$this->processed_count = 0;
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
}
abstract public function optimize();
abstract public function settings_label();
/**
* WP_Optimization constructor.
*
* @param array $data initial data for optimization.
*/
public function __construct($data = array()) {
$class_name = get_class($this);
// Remove the prefixed WP_Optimization_.
$this->id = substr($class_name, 16);
$this->data = $data;
$this->optimizer = WP_Optimize()->get_optimizer();
$this->options = WP_Optimize()->get_options();
$this->logger = WP_Optimize()->get_logger();
$wpdb = $GLOBALS['wpdb'];
$this->wpdb = $wpdb;
$this->blogs_ids = $this->get_optimization_blogs();
$this->init();
}
/**
* This triggers the do_optimization function
* within class-wp-optimizer.php to kick off the optimizations.
* It also passed the data array from the wpadmin.js.
*
* @return array|object|WP_Error|WP_Optimization array of results that includes sql_commands, output and meta
*/
public function do_optimization() {
return $this->optimizer->do_optimization($this);
}
/**
* This gathers the optimization information to be displayed
* before triggering any optimizations
*
* @return array|object|WP_Error|WP_Optimization Returns an object of optimization information
*/
public function get_optimization_info() {
return $this->optimizer->get_optimization_info($this);
}
/**
* Returns array of blog ids
*
* @return array
*/
public function get_optimization_blogs() {
$objects = array();
if ($this->is_multisite_mode()) {
$all_sites = false;
$selected_sites = array();
// support both arrays and single values in data site id parameter.
if (isset($this->data['site_id']) && !is_array($this->data['site_id'])) {
$this->data['site_id'] = array($this->data['site_id']);
}
$optimization_sites = (isset($this->data['site_id'])) ? $this->data['site_id'] : $this->options->get_wpo_sites_option();
// check selected sites field.
if (!empty($optimization_sites)) {
foreach ($optimization_sites as $site_id) {
if ('all' === (string) $site_id) {
$all_sites = true;
} else {
$selected_sites[] = $site_id;
}
}
}
$sites = $this->get_sites();
if (!empty($sites)) {
foreach ($sites as $site) {
if ($all_sites || (in_array($site->blog_id, $selected_sites))) {
$objects[] = $site->blog_id;
}
}
} else {
$objects[] = 1;
}
} else {
$objects[] = 1;
}
$filtered_objects = apply_filters('get_optimization_blogs', $objects);
if (is_array($filtered_objects)) return $filtered_objects;
return $objects;
}
/**
* Returns true if optimization works in multisite mode
*
* @return bool
*/
public function is_multisite_mode() {
return WP_Optimize()->is_multisite_mode();
}
/**
* Returns list of all sites in multisite
*
* @return array
*/
public function get_sites() {
return WP_Optimize()->get_sites();
}
/**
* Wrapper for switch_to_blog WordPress MU function
*
* @param int $new_blog new blog id.
* @return bool|void - if on multisite, then always true (see https://codex.wordpress.org/Function_Reference/switch_to_blog)
*/
public function switch_to_blog($new_blog) {
if (function_exists('switch_to_blog') && $this->is_multisite_mode()) {
return switch_to_blog($new_blog);
}
}
/**
* Wrapper for restore_current_blog WordPress MU function
*
* @return bool|void
*/
public function restore_current_blog() {
if (function_exists('restore_current_blog') && $this->is_multisite_mode()) {
return restore_current_blog();
}
}
/**
* This function adds output to the current registered output
*
* @param string $output Output message
*/
public function register_output($output) {
$this->output[] = $output;
}
/**
* This function adds meta-data associated with the result to the registered output
*
* @param string $key The key value.
* @param mixed $value The value to be passed.
*/
public function register_meta($key, $value) {
$this->meta[$key] = $value;
}
/**
* Get meta-data added to the registered output.
*
* @return array
*/
public function get_meta() {
return $this->meta;
}
public function init() {
$this->output = array();
$this->meta = array();
$this->sql_commands = array();
list ($retention_enabled, $retention_period) = $this->optimizer->get_retain_info();
$this->retention_enabled = $retention_enabled;
$this->retention_period = $retention_period;
list($revisions_retention_enabled, $revisions_retention_count) = $this->optimizer->get_revisions_retain_info();
$this->revisions_retention_enabled = $revisions_retention_enabled;
$this->revisions_retention_count = $revisions_retention_count;
}
/**
* 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.
*
* @return string
*/
public function get_setting_id() {
return empty($this->setting_id) ? 'user-'.$this->id : 'user-'.$this->setting_id;
}
/**
* 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.
*
* @return string
*/
public function get_dom_id() {
return empty($this->dom_id) ? 'clean-'.$this->id : $this->dom_id;
}
/**
* 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.
*
* @return string
*/
public function get_auto_id() {
return empty($this->auto_id) ? $this->id : $this->auto_id;
}
/**
* Checks whether this optimization has changes table data
*
* @return bool
*/
public function get_changes_table_data() {
return empty($this->changes_table_data) ? false : true;
}
/**
* Returns the run sort order
*
* @return int
*/
public function get_run_sort_order() {
return empty($this->run_sort_order) ? 0 : $this->run_sort_order;
}
/**
* What is returned must be at least convertible to an array
*
* @return object Results object.
*/
public function get_results() {
// As yet, we have no need for a dedicated object type for our results.
$results = new stdClass;
$results->sql_commands = $this->sql_commands;
$results->output = $this->output;
$results->meta = $this->meta;
$filtered_results = apply_filters('wp_optimize_optimization_results', $results, $this->id, $this);
if (!empty($filtered_results) && is_object($filtered_results)) return $filtered_results;
return $results;
}
/**
* Generate information about optimization required for show it.
*
* @return array
*/
public function get_settings_html() {
$wpo_user_selection = $this->options->get_main_settings();
$setting_id = $this->get_setting_id();
$dom_id = $this->get_dom_id();
// N.B. Some of the optimizations used to have an onclick call to fCheck(). But that function was commented out, so did nothing.
$settings_label = $this->settings_label();
$setting_activated = !empty($wpo_user_selection[$setting_id]) && 'false' !== $wpo_user_selection[$setting_id];
$info = $this->get_optimization_info()->output;
$settings_html = array(
'dom_id' => $dom_id,
'activated' => $setting_activated,
'settings_label' => $settings_label,
'info' => wp_kses(join('
', $info), $this->allow_checkboxes()),
);
if (empty($settings_label)) {
// Error_log, as this is a defect.
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
}
return $settings_html;
}
/**
* Wrap $text as a link for preview action. If preview is not supported then return just $text.
*
* @param string $text
* @param array $attributes
*
* @return string
*/
public function get_preview_link($text, $attributes = array()) {
// if preview is not supported then return just $text.
if (!$this->support_preview || !WP_Optimize::is_premium()) return $text;
$attributes = array_merge(
array(
'title' => __('Preview found items', 'wp-optimize'),
'data-id' => $this->id,
'data-title' => $this->settings_label(),
),
$attributes
);
$str_attr = '';
foreach ($attributes as $key => $value) {
$str_attr .= ' '.$key.'="'.esc_attr($value).'"';
}
$link = ''.$text.'';
return $link;
}
/**
* Adds input and label tags to allowed HTML tags.
*
* @return array
*/
private function allow_checkboxes() {
$allowed_html = wp_kses_allowed_html('post');
$allowed_html['input'] = array(
'type' => true,
'name' => true,
'id' => true,
'class' => true,
'value' => true,
'placeholder' => true,
'required' => true,
'checked' => true,
'disabled' => true,
'min' => true,
'max' => true,
'step' => true
);
$allowed_html['label'] = array(
'for' => true,
'class' => true,
'id' => true
);
return $allowed_html;
}
}