Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wp-optimize/compatibility/class-wp-optimize-server-compatibility.php
+++ b/wp-optimize/compatibility/class-wp-optimize-server-compatibility.php
@@ -0,0 +1,74 @@
+<?php
+if (!defined('ABSPATH')) die('No direct access allowed');
+
+if (!class_exists('WP_Optimize_Server_Compatibility')) :
+/**
+ * Adds compatibility for Servers.
+ */
+class WP_Optimize_Server_Compatibility {
+
+ /**
+ * Returns singleton instance
+ *
+ * @return WP_Optimize_Server_Compatibility
+ */
+ public static function get_instance() {
+ static $instance = null;
+ if (null === $instance) {
+ $instance = new WP_Optimize_Server_Compatibility();
+ }
+ return $instance;
+ }
+
+ /**
+ * Detects whether the server handles cache. e.g. Nginx cache
+ *
+ * @return bool
+ */
+ public function does_server_handle_cache(): bool {
+ return $this->is_kinsta();
+ }
+
+ /**
+ * Detects whether the server supports table optimization.
+ *
+ * Some servers prevent table optimization
+ * because InnoDB engine does not optimize table
+ * instead it drops tables and recreates them,
+ * which results in elevated disk write operations
+ *
+ * @return bool
+ */
+ public function does_server_allow_table_optimization(): bool {
+ return !$this->is_kinsta();
+ }
+
+ /**
+ * Detects whether the server supports local webp conversion tools
+ *
+ * @return bool
+ */
+ public function does_server_allow_local_webp_conversion(): bool {
+ return !$this->is_kinsta();
+ }
+
+ /**
+ * Detects if the platform is Kinsta or not
+ *
+ * @return bool Returns true if it is a Kinsta platform, otherwise returns false
+ */
+ private function is_kinsta(): bool {
+ $is_kinsta = isset($_SERVER['KINSTA_CACHE_ZONE']);
+
+ /**
+ * Filter whether the server is detected as Kinsta.
+ *
+ * Allows overriding the default detection logic in case
+ * Kinsta changes environment variables or for edge cases.
+ *
+ * @param bool $is_kinsta Detected Kinsta status.
+ */
+ return (bool) apply_filters('wpo_is_kinsta_server', $is_kinsta);
+ }
+}
+endif;
--- a/wp-optimize/includes/class-updraft-smush-manager-commands.php
+++ b/wp-optimize/includes/class-updraft-smush-manager-commands.php
@@ -277,84 +277,20 @@
*/
public function update_webp_options($data) {
$webp_instance = WP_Optimize()->get_webp_instance();
- $options = array();
- $options['webp_conversion'] = isset($data['webp_conversion']) ? filter_var($data['webp_conversion'], FILTER_VALIDATE_BOOLEAN) : false;
-
- // Only run checks when trying to enable WebP
- if ($options['webp_conversion']) {
- //Run checks if we are enabling webp conversion
- if ($this->is_only_shell_converters_available() && !$webp_instance->shell_functions_available()) {
- $webp_instance->disable_webp_conversion();
- $webp_instance->log("Required WebP shell functions are not available on the server, disabling WebP conversion");
- return new WP_Error('update_failed_no_shell_functions', __('Required WebP shell functions are not available on the server.', 'wp-optimize'));
- }
-
- // Run conversion test if not already done and set necessary option value
- if ($webp_instance->should_run_webp_conversion_test()) {
- $converter_status = WPO_WebP_Test_Run::get_converter_status();
-
- if (!$webp_instance->is_webp_conversion_successful()) {
- $webp_instance->disable_webp_conversion();
- $webp_instance->log("No working WebP converter was found on the server when updating WebP options, disabling WebP conversion");
- return new WP_Error('update_failed_no_working_webp_converter', __('No working WebP converter was found on the server.', 'wp-optimize'));
- }
-
- $options['webp_conversion_test'] = true;
- $options['webp_converters'] = $converter_status['working_converters'];
- }
-
- // Run serving methods tests and set necessary option values
- // Not possible to test alter html since test is browser based
- $webp_instance->save_htaccess_rules();
- if (!$webp_instance->is_webp_redirection_possible()) {
- $webp_instance->empty_htaccess_file();
- $options['redirection_possible'] = 'false';
- } else {
- $options['redirection_possible'] = 'true';
- }
- }
-
- $success = $this->task_manager->update_smush_options($options);
-
- if (!$success) {
- $webp_instance->disable_webp_conversion();
- $webp_instance->log("WebP options could not be updated");
- return new WP_Error('update_failed', __('WebP options could not be updated.', 'wp-optimize'));
+ $result = $webp_instance->save_webp_settings($data);
+ if (is_wp_error($result)) {
+ return $result;
}
- // Setup daily CRON only when enabling WebP and Delete daily CRON when disabling WebP
- if ($options['webp_conversion']) {
- $webp_instance->init_webp_cron_scheduler();
- } else {
- $webp_instance->remove_webp_cron_schedules();
- $webp_instance->empty_htaccess_file();
- }
-
- do_action('wpo_save_images_settings');
-
$response = array();
$response['status'] = true;
- $response['saved'] = $success;
+ $response['saved'] = $result;
$response['summary'] = __('WebP options updated successfully.', 'wp-optimize');
return $response;
}
/**
- * Checks if only shell converters available for WebP conversion.
- *
- * @return boolean
- */
- private function is_only_shell_converters_available() {
- $available_converters = WP_Optimize()->get_options()->get_option('webp_converters');
- $available_converters = is_array($available_converters) ? $available_converters : array();
- $converters_with_shell = WPO_WebP_Test_Run::get_converters_with_shell();
- $available_with_shell = array_intersect($available_converters, $converters_with_shell);
-
- return count($available_converters) > 0 && count($available_converters) === count($available_with_shell);
- }
-
- /**
* Updates smush related options
*
* @param array $data - Sent in via AJAX
--- a/wp-optimize/includes/class-wp-optimize-admin.php
+++ b/wp-optimize/includes/class-wp-optimize-admin.php
@@ -223,7 +223,7 @@
* CACHE
*/
add_action('wp_optimize_admin_page_wpo_cache_cache', array($this, 'output_page_cache_tab'), 20);
- if (!WP_Optimize()->does_server_handles_cache()) {
+ if (!WP_Optimize()->get_server_compatibility_instance()->does_server_handle_cache()) {
add_action('wp_optimize_admin_page_wpo_cache_preload', array($this, 'output_page_cache_preload_tab'), 20);
add_action('wp_optimize_admin_page_wpo_cache_advanced', array($this, 'output_page_cache_advanced_tab'), 20);
}
@@ -314,8 +314,9 @@
$loggers_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_logging_settings')));
$settings_trackback_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_trackback_toggle_settings')));
$settings_comments_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_comments_toggle_settings')));
+ $settings_general_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_general_settings')));
- WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data['data']['wp_optimize_logging_settings'], 'settings_trackback_data' => $settings_trackback_data['data']['wp_optimize_trackback_toggle_settings'], 'settings_comments_data' => $settings_comments_data['data']['wp_optimize_comments_toggle_settings']));
+ WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data['data']['wp_optimize_logging_settings'], 'settings_trackback_data' => $settings_trackback_data['data']['wp_optimize_trackback_toggle_settings'], 'settings_comments_data' => $settings_comments_data['data']['wp_optimize_comments_toggle_settings'], 'settings_general_data' => $settings_general_data['data']['wp_optimize_general_settings']));
} else {
$this->prevent_manage_options_info();
}
@@ -371,7 +372,7 @@
'display' => $display,
'can_purge_the_cache' => $wpo_cache->can_purge_cache(),
'auto_preload_purged_contents' => $wpo_cache_options['auto_preload_purged_contents'],
- 'does_server_handles_cache' => WP_Optimize()->does_server_handles_cache(),
+ 'does_server_handle_cache' => WP_Optimize()->get_server_compatibility_instance()->does_server_handle_cache(),
'error' => $error,
));
}
@@ -533,7 +534,7 @@
$wp_optimize_commands = new WP_Optimize_Commands();
$status_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('all_status')));
$optimizations_table_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize')));
- WP_Optimize()->include_template('database/optimize-table.php', false, array('optimize_db' => $optimize_db, 'optimization_results' => $optimization_results, 'load_data' => false, 'does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization(), 'optimizations_table_data' => $optimizations_table_data['data']['wp_optimize'], 'status_data' => $status_data['data']['all_status']));
+ WP_Optimize()->include_template('database/optimize-table.php', false, array('optimize_db' => $optimize_db, 'optimization_results' => $optimization_results, 'load_data' => false, 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization(), 'optimizations_table_data' => $optimizations_table_data['data']['wp_optimize'], 'status_data' => $status_data['data']['all_status']));
} else {
$this->prevent_run_optimizations_message();
}
@@ -547,7 +548,7 @@
$optimize_db = $nonce_passed && TeamUpdraftWP_OptimizeIncludesFragmentsfetch_superglobal('post', 'optimize-db');
- if (!WP_Optimize()->does_server_allows_table_optimization()) {
+ if (!WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization()) {
$message = __('Your server takes care of table optimization', 'wp-optimize');
$this->prevent_run_optimizations_message($message);
} elseif (WP_Optimize()->can_run_optimizations()) {
@@ -558,31 +559,36 @@
}
/**
- * Outputs the Performance 404 requests Tab
+ * Outputs Performance 404 requests Tab
*/
public function output_performance_404_requests() {
$wp_optimize = WP_Optimize();
$is_enabled = $wp_optimize->get_options()->get_option('404_detector', 0);
-
+
$detector = $wp_optimize->get_404_detector();
-
- $requests = $detector->get_suspicious_requests();
-
+ $suspicious_threshold = $detector->get_suspicious_request_count_threshold();
+
$report_has_data = false;
- foreach ($requests as $url_requests) {
- foreach ($url_requests as $row) {
- if (1 < $row->occurrences && 'grouped' === $row->row_type) {
- if (0 === $row->non_suspicious_referrers && 1 < $row->total_referrers) {
- continue;
+ $requests = array();
+
+ if ($is_enabled) {
+ $requests = $detector->get_suspicious_requests();
+
+ foreach ($requests as $url_requests) {
+ foreach ($url_requests as $row) {
+ if (1 < $row->occurrences && 'grouped' === $row->row_type) {
+ if (0 === $row->non_suspicious_referrers && 1 < $row->total_referrers) {
+ continue;
+ }
}
+ $report_has_data = true;
}
- $report_has_data = true;
}
}
$wp_optimize->include_template('performance/404-detector.php', false, array(
'requests' => $requests,
- 'suspicious_threshold' => $detector->get_suspicious_request_count_threshold(),
+ 'suspicious_threshold' => $suspicious_threshold,
'obj_404_detector' => $detector,
'report_has_data' => $report_has_data,
'is_enabled' => $is_enabled,
--- a/wp-optimize/includes/class-wp-optimize-browser-cache.php
+++ b/wp-optimize/includes/class-wp-optimize-browser-cache.php
@@ -194,13 +194,13 @@
if ($enable) {
// translators: %s is a file name
- $message = sprintf(__("We can't update your %s file.", 'wp-optimize'), $this->_htaccess->get_filename()) . ' ' . __('Please try to add following lines manually:', 'wp-optimize');
+ $message = sprintf(__("We can't update your %s file.", 'wp-optimize'), $this->_htaccess->get_filename()) . ' ' . __('Please try to add following lines manually:', 'wp-optimize');
$output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
join(PHP_EOL, $this->_htaccess->get_flat_array($cache_section)).
PHP_EOL . $this->_htaccess->get_section_end_comment());
} else {
// translators: %s is a file name
- $message = sprintf(__("We can't update your %s file.", 'wp-optimize'), $this->_htaccess->get_filename()) . ' ' . __('Please try to remove following lines manually:', 'wp-optimize');
+ $message = sprintf(__("We can't update your %s file.", 'wp-optimize'), $this->_htaccess->get_filename()) . ' ' . __('Please try to remove following lines manually:', 'wp-optimize');
$output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
' ... ... ... '.
PHP_EOL . $this->_htaccess->get_section_end_comment());
--- a/wp-optimize/includes/class-wp-optimize-commands.php
+++ b/wp-optimize/includes/class-wp-optimize-commands.php
@@ -25,7 +25,7 @@
public function enable_or_disable_feature($data) {
$type = (string) $data['type'];
- $enable = (boolean) $data['enable'];
+ $enable = (bool) $data['enable'];
$options = array($type => $enable);
@@ -306,8 +306,9 @@
$loggers_data = $this->get_wp_optimize_logging_settings_data();
$settings_trackback_data = $this->get_wp_optimize_trackback_toggle_settings_data();
$settings_comments_data = $this->get_wp_optimize_comments_toggle_settings_data();
+ $settings_general_data = $this->get_wp_optimize_general_settings_data();
- WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data, 'settings_trackback_data' => $settings_trackback_data, 'settings_comments_data' => $settings_comments_data));
+ WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data, 'settings_trackback_data' => $settings_trackback_data, 'settings_comments_data' => $settings_comments_data, 'settings_general_data' => $settings_general_data));
} else {
$wpo_admin->prevent_manage_options_info();
}
@@ -538,7 +539,7 @@
public function get_wp_optimize_contents() {
$status_data = $this->get_all_status_data();
$optimization_data = $this->get_wp_optimize_data();
- $content = WP_Optimize()->include_template('database/optimize-table.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data(), 'does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization(), 'optimizations_table_data' => $optimization_data, 'status_data' => $status_data));
+ $content = WP_Optimize()->include_template('database/optimize-table.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data(), 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization(), 'optimizations_table_data' => $optimization_data, 'status_data' => $status_data));
if (WP_Optimize()->is_updraft_central_request()) {
$content .= $this->get_status_box_contents();
@@ -862,7 +863,7 @@
* @return array
*/
public function get_database_tabs() {
- return array_merge(array('optimizations' => $this->get_optimizations_table(), 'does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization()), $this->get_table_list());
+ return array_merge(array('optimizations' => $this->get_optimizations_table(), 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization()), $this->get_table_list());
}
/**
@@ -1415,12 +1416,12 @@
$wp_optimize = WP_Optimize();
$optimizations = $this->optimizer->sort_optimizations($this->optimizer->get_optimizations());
- $does_server_allows_table_optimization = $wp_optimize->does_server_allows_table_optimization();
+ $does_server_allow_table_optimization = $wp_optimize->get_server_compatibility_instance()->does_server_allow_table_optimization();
$optimizations_data = array();
foreach ($optimizations as $id => $optimization) {
- if ('optimizetables' == $id && false === $does_server_allows_table_optimization) continue;
+ if ('optimizetables' == $id && false === $does_server_allow_table_optimization) continue;
// If we don't want to show optimization on the first tab.
if (false === $optimization->display_in_optimizations_list()) continue;
// This is an array, with attributes dom_id, activated, settings_label, info; all values are strings.
@@ -1730,11 +1731,14 @@
$revisions_retention_count = (int) $this->options->get_option('revisions-retention-count', '2');
$revisions_retention_enabled = 'true' === $this->options->get_option('revisions-retention-enabled');
+ $minify_or_cache_enabled = WP_Optimize()->get_page_cache()->is_enabled() || wp_optimize_minify_config()->get('enabled');
+
return array(
'retention_period' => $retention_period,
'retention_enabled' => $retention_enabled,
'revisions_retention_count' => $revisions_retention_count,
'revisions_retention_enabled' => $revisions_retention_enabled,
+ 'minify_or_cache_enabled' => $minify_or_cache_enabled,
);
}
@@ -1938,7 +1942,7 @@
// Backwards compatibility:
if ('wpo_otherweekly' == $schedule_type_saved_id) $schedule_type_saved_id = 'wpo_fortnightly';
- $schedule_types = $wp_optimize::get_schedule_types();
+ $schedule_types = WP_Optimize::get_schedule_types();
$schedule_options = array_map(
function ($value, $key) use ($schedule_type_saved_id) {
@@ -1958,12 +1962,12 @@
$optimizations_data = array();
- $does_server_allows_table_optimization = WP_Optimize()->does_server_allows_table_optimization();
+ $does_server_allow_table_optimization = WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization();
foreach ($optimizations as $id => $optimization) {
if (empty($optimization->available_for_auto)) continue;
- if ('optimizetables' == $id && false === $does_server_allows_table_optimization) continue;
+ if ('optimizetables' == $id && false === $does_server_allow_table_optimization) continue;
$auto_id = $optimization->get_auto_id();
@@ -2004,7 +2008,7 @@
} else {
$wp_optimize_premium = WP_Optimize_Premium();
$auto_options = $wp_optimize_premium->get_scheduled_optimizations();
-
+ $auto_optimizations = $wp_optimize_premium->get_auto_optimizations();
$next_optimization_timestamp = 0;
@@ -2017,7 +2021,7 @@
}
}
- $all_provided_optimizations = array_values(WP_Optimize_Premium::get_auto_optimizations());
+ $all_provided_optimizations = array_values($auto_optimizations);
$all_schedule_types = WP_Optimize::get_schedule_types();
$week_days = WP_Optimize_Premium::get_week_days();
$days = WP_Optimize_Premium::get_days();
@@ -2116,7 +2120,7 @@
'next_optimization' => $next_optimization_timestamp ? esc_html(gmdate(get_option('date_format') . ' ' . get_option('time_format'), $next_optimization_timestamp)) : '',
'is_auto_innodb' => $this->options->get_option('auto-innodb'),
'scheduled_optimizations' => $auto_options,
- 'auto_optimizations' => $wp_optimize_premium->get_auto_optimizations(),
+ 'auto_optimizations' => $auto_optimizations,
'warning_url' => $wp_optimize->wp_optimize_url('https://teamupdraft.com/documentation/wp-optimize/topics/database-optimization/faqs/', __('Warning: you should read the FAQ about the risks of this operation first.', 'wp-optimize'), '', '', true)
);
}
--- a/wp-optimize/includes/class-wp-optimize-database-information.php
+++ b/wp-optimize/includes/class-wp-optimize-database-information.php
@@ -537,6 +537,8 @@
if (!in_array($wpo, $plugin_tables['tm_tasks'], true)) {
$plugin_tables['tm_tasks'][] = $wpo;
}
+
+ $plugin_tables = array_merge($plugin_tables, $this->get_learndash_tables());
return $plugin_tables;
}
@@ -550,12 +552,33 @@
public function get_table_plugin($table) {
global $wpdb;
+ $plugins = array();
+ $original_table = $table;
// delete table prefix.
$table = preg_replace('/^'.$wpdb->prefix.'([0-9]+_)?/', '', $table);
$plugins_tables = $this->get_all_plugin_tables_relationship();
+ // If a direct match exists.
if (array_key_exists($table, $plugins_tables)) {
- return $plugins_tables[$table];
+ $plugins = $plugins_tables[$table];
+ }
+
+ // special handling for tables when plugins use custom prefix.
+ foreach ($plugins_tables as $plugin_table => $plugin_names) {
+ if (false === strpos($plugin_table, '*')) {
+ continue;
+ }
+
+ // support for wildcard * in table names.
+ $pattern = '/^'.str_replace('*', '.*', preg_quote($plugin_table, '/')).'$/';
+
+ if (preg_match($pattern, $original_table)) {
+ $plugins = array_merge($plugins, $plugin_names);
+ }
+ }
+
+ if (!empty($plugins)) {
+ return array_unique($plugins);
}
return false;
@@ -689,4 +712,25 @@
set_transient('wpo_' . $table->Name . '_count', $rows_count, 24*60*60);
}
}
+
+ /**
+ * Get a list of LearnDash tables with plugin slug for each of them.
+ *
+ * @return array
+ */
+ private function get_learndash_tables() {
+ $table_names = array(
+ '*pro_quiz_category',
+ '*pro_quiz_form',
+ '*pro_quiz_lock',
+ '*pro_quiz_prerequisite',
+ '*pro_quiz_question',
+ '*pro_quiz_statistic',
+ '*pro_quiz_statistic_ref',
+ '*pro_quiz_template',
+ '*pro_quiz_toplist',
+ );
+
+ return array_fill_keys($table_names, array('sfwd-lms'));
+ }
}
--- a/wp-optimize/includes/class-wp-optimize-heartbeat.php
+++ b/wp-optimize/includes/class-wp-optimize-heartbeat.php
@@ -64,6 +64,8 @@
* @return array|void
*/
public function receive_heartbeat($response, $data) {
+ $allowed_smush_commands = Updraft_Smush_Manager_Commands::get_allowed_ajax_commands();
+ $capability_required = current_user_can(WP_Optimize()->capability_required());
$commands = new Updraft_Smush_Manager_Commands(Updraft_Smush_Manager::instance());
$commands->heartbeat_command = true;
@@ -79,7 +81,20 @@
} else {
$command_name = key($command);
if ('updraft_smush_ajax' === $command_name) {
+
+ if (!$capability_required) {
+ continue;
+ }
+
$command_data = current($command);
+
+ if (empty($command_data['subaction'])) {
+ continue;
+ }
+
+ if (!in_array($command_data['subaction'], $allowed_smush_commands, true)) {
+ continue;
+ }
$command_data_param = null;
if (isset($command_data['data'])) {
@@ -88,13 +103,13 @@
$_REQUEST['subaction'] = $command_data['subaction'];
$_REQUEST['data'] = $command_data_param;
-
- ob_start();
-
+
if (!is_callable(array($commands, $command_data['subaction']))) {
continue;
}
+ ob_start();
+
$method = new ReflectionMethod($commands, $command_data['subaction']);
$command_response = $method->invokeArgs($commands, array($command_data_param));
--- a/wp-optimize/includes/class-wp-optimize-performance.php
+++ b/wp-optimize/includes/class-wp-optimize-performance.php
@@ -41,6 +41,7 @@
* @return void
*/
public function init() {
+
add_filter('site_health_navigation_tabs', array($this, 'add_health_tab'));
add_action('site_health_tab_content', array($this, 'site_health_tab_content'));
--- a/wp-optimize/includes/class-wp-optimize-preloader.php
+++ b/wp-optimize/includes/class-wp-optimize-preloader.php
@@ -16,13 +16,22 @@
$this->options = WP_Optimize()->get_options();
// setup loggers
- $this->set_loggers(WP_Optimize()->wpo_loggers());
+ add_action('init', array($this, 'setup_loggers'));
add_action('wpo_' . $this->preload_type . '_preload_continue', array($this, 'process_tasks_queue'));
add_filter('updraft_interrupt_tasks_queue_'.$this->task_type, array($this, 'maybe_interrupt_queue'), 20);
}
/**
+ * Setup loggers
+ *
+ * @return void
+ */
+ public function setup_loggers() {
+ $this->set_loggers(WP_Optimize()->wpo_loggers());
+ }
+
+ /**
* Get a schedule interval
*
* @param string $schedule_key The schedule to check
--- a/wp-optimize/includes/class-wp-optimize-table-management.php
+++ b/wp-optimize/includes/class-wp-optimize-table-management.php
@@ -23,7 +23,7 @@
}
/**
- * Returns singleton instance of this class
+ * Returns a singleton instance of this class
*
* @return WP_Optimize_Table_Management Singleton Instance
*/
@@ -40,20 +40,33 @@
*
* @return void
*/
- public function create_plugin_tables() {
+ public function create_plugin_tables(): void {
/* @var $util WP_Optimize_Table_Interface */
foreach ($this->plugin_utils as $util) {
$table_name = $util->get_table_name();
+ $table_description = $util->describe();
- if (!$this->table_exists($table_name)) {
- $table_description = $util->describe();
- $create_table = $this->generate_create_statement($table_name, $table_description);
-
- require_once ABSPATH.'wp-admin/includes/upgrade.php';
+ $this->create_table($table_name, $table_description);
+ }
+ }
- dbDelta($create_table);
- }
+ /**
+ * Create the table if it does not exist.
+ *
+ * @param string $table_name The name of the table that needs to be checked and if not exists, then create it
+ * @param array $table_description Table definition provider
+ *
+ * @return void
+ */
+ private function create_table($table_name, $table_description): void {
+ if ($this->table_exists($table_name)) {
+ return;
}
+
+ $create_table = $this->generate_create_statement($table_name, $table_description);
+
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+ dbDelta($create_table);
}
/**
--- a/wp-optimize/includes/class-wpo-onboarding.php
+++ b/wp-optimize/includes/class-wpo-onboarding.php
@@ -54,19 +54,6 @@
}
/**
- * Prevent cloning of the instance
- */
- private function __clone() {
- }
-
- /**
- * Prevent unserializing of the instance
- */
- public function __wakeup() {
- throw new Exception("Cannot unserialize singleton");
- }
-
- /**
* Setup hooks.
*
* @return void
@@ -80,24 +67,6 @@
}
/**
- * Get Steps Ids from a step fields array
- *
- * @param array $step_fields Step Fields data
- *
- * @return array
- */
- private function get_step_ids(array $step_fields): array {
- $step_ids = array();
- if (!empty($step_fields)) {
- foreach ($step_fields as $step) {
- $step_ids[] = $step['id'];
- }
- }
-
- return $step_ids;
- }
-
- /**
* Get Features Status
*
* @param array $settings Settings data
@@ -106,7 +75,7 @@
* @return void
*/
public function update_step_settings(array $settings, array $step_fields): void {
- $steps = $this->get_step_ids($step_fields);
+ $step_ids = array_flip(array_column($step_fields, 'id'));
if (empty($settings)) {
return;
@@ -114,7 +83,7 @@
foreach ($settings as $setting) {
if (empty($setting['id'])) continue;
- if (!in_array($setting['id'], $steps)) continue;
+ if (!isset($step_ids[$setting['id']])) continue;
$is_lock = isset($setting['is_lock']) ? (bool) $setting['is_lock'] : false;
if ($is_lock) {
@@ -150,9 +119,9 @@
}
if ('enable_webp_conversion_onboarding' === $id) {
- $smush_settings = array();
- $smush_settings['webp_conversion'] = $value;
- WP_Optimize()->get_task_manager()->commands->update_webp_options($smush_settings);
+ $webp_data = array();
+ $webp_data['webp_conversion'] = $value;
+ WP_Optimize()->get_webp_instance()->save_webp_settings($webp_data);
}
if ('enable_lazy_load_onboarding' === $id) {
@@ -235,19 +204,19 @@
private function intro_step(): array {
$intro_bullets = $this->get_intro_bullets();
- $note_1 = $this->is_premium ? __( "Premium plugin", 'wp-optimize' ) : __( "Free plugin", 'wp-optimize' );
- $note_2 = __( "Quick setup", 'wp-optimize' );
- $note_3 = __( "No tech skills needed", 'wp-optimize' );
+ $note_1 = $this->is_premium ? __("Premium plugin", 'wp-optimize') : __("Free plugin", 'wp-optimize');
+ $note_2 = __("Quick setup", 'wp-optimize');
+ $note_3 = __("No tech skills needed", 'wp-optimize');
$bottom_note = $note_1 . ' • ' . $note_2 . ' • ' . $note_3;
return array(
'id' => 'intro',
'type' => 'intro',
- 'title' => __( 'Let's get started!', 'wp-optimize' ),
- 'subtitle' => __( "Speed up and optimize your WordPress site with ease, trusted by over 1 million sites.", 'wp-optimize' ),
+ 'title' => __('Let's get started!', 'wp-optimize'),
+ 'subtitle' => __("Speed up and optimize your WordPress site with ease, trusted by over 1 million sites.", 'wp-optimize'),
'intro_bullets' => $intro_bullets,
'button' => array(
'id' => 'start',
- 'label' => __( 'Start', 'wp-optimize' ),
+ 'label' => __('Start', 'wp-optimize'),
'icon' => 'magic-wand',
),
'note' => $bottom_note,
@@ -268,12 +237,12 @@
'id' => 'license',
'type' => 'license',
'icon' => 'user-lock',
- 'title' => __( 'Connect and activate your license', 'wp-optimize' ),
+ 'title' => __('Connect and activate your license', 'wp-optimize'),
'title_conditional' => array(
- 'licenseActivated' => __( 'License activated!', 'wp-optimize' ),
- 'isUpdating' => __( 'Activating your Premium license...', 'wp-optimize' ),
+ 'licenseActivated' => __('License activated!', 'wp-optimize'),
+ 'isUpdating' => __('Activating your Premium license...', 'wp-optimize'),
),
- 'subtitle' => __( 'Please enter your TeamUpdraft credentials to start using Premium features.', 'wp-optimize' ),
+ 'subtitle' => __('Please enter your TeamUpdraft credentials to start using Premium features.', 'wp-optimize'),
'subtitle_conditional' => array(
'licenseActivated' => '',
'isUpdating' => '',
@@ -282,17 +251,17 @@
array(
'id' => 'registration_email',
'type' => 'email',
- 'label' => __( 'Email', 'wp-optimize' ),
+ 'label' => __('Email', 'wp-optimize'),
),
array(
'id' => 'registration_password',
'type' => 'password',
- 'label' => __( 'Password', 'wp-optimize' ),
+ 'label' => __('Password', 'wp-optimize'),
),
),
'button' => array(
'id' => 'activate',
- 'label'=> __( 'Confirm and activate', 'wp-optimize' ),
+ 'label'=> __('Confirm and activate', 'wp-optimize'),
'icon' => 'EastRoundedIcon',
)
);
@@ -309,18 +278,18 @@
'id' => 'page_features',
'type' => 'settings',
'icon' => 'settings',
- 'title' => __( 'Enable best-practice settings', 'wp-optimize' ),
- 'subtitle' => __( 'We've pre-selected core settings to speed up and optimize your site.', 'wp-optimize' ).' '.__( 'You can tweak them anytime.', 'wp-optimize' ),
+ 'title' => __('Enable best-practice settings', 'wp-optimize'),
+ 'subtitle' => __('We've pre-selected core settings to speed up and optimize your site.', 'wp-optimize').' '.__('You can tweak them anytime.', 'wp-optimize'),
'fields' => $features,
'button' => array(
'id' => 'save',
- 'label'=> __( 'Save and continue', 'wp-optimize' ),
+ 'label'=> __('Save and continue', 'wp-optimize'),
'icon' => 'EastRoundedIcon',
),
'skip_step' => array(
'icon' => 'info',
'tooltip' => array(
- 'text' => __( 'All above features will be disabled if you skip.', 'wp-optimize' ),
+ 'text' => __('All above features will be disabled if you skip.', 'wp-optimize'),
),
)
);
@@ -337,12 +306,12 @@
'id' => 'email',
'type' => 'email',
'icon' => 'mail',
- 'title' => __( 'Get lightning-fast insights!', 'wp-optimize' ),
- 'subtitle' => __( 'Join our newsletter for speed-optimization tips and best practices.', 'wp-optimize' ).' '.__( 'Delivered straight to your inbox.', 'wp-optimize' ),
+ 'title' => __('Get lightning-fast insights!', 'wp-optimize'),
+ 'subtitle' => __('Join our newsletter for speed-optimization tips and best practices.', 'wp-optimize').' '.__('Delivered straight to your inbox.', 'wp-optimize'),
'fields' => $email_fields,
'button' => array(
'id' => 'save',
- 'label'=> __( 'Save and continue', 'wp-optimize' ),
+ 'label'=> __('Save and continue', 'wp-optimize'),
'icon' => 'EastRoundedIcon',
),
);
@@ -359,13 +328,13 @@
'type' => 'plugins',
'icon' => 'plugin',
'first_run_only' => false,
- 'title' => __( 'Recommended for your setup', 'wp-optimize' ),
+ 'title' => __('Recommended for your setup', 'wp-optimize'),
'title_conditional' => array(
- 'all_installed' => __( 'Best-practice plugins enabled', 'wp-optimize' ),
+ 'all_installed' => __('Best-practice plugins enabled', 'wp-optimize'),
),
- 'subtitle' => __( 'We've carefully handpicked these plugins to match your website's setup, so everything works just the way it should.', 'wp-optimize' ),
+ 'subtitle' => __('We've carefully handpicked these plugins to match your website's setup, so everything works just the way it should.', 'wp-optimize'),
'subtitle_conditional' => array(
- 'all_installed' => __( 'Wow, your site already meets all our plugin recommendations, let's move on!', 'wp-optimize' ),
+ 'all_installed' => __('Wow, your site already meets all our plugin recommendations, let's move on!', 'wp-optimize'),
),
'fields' => array(
array(
@@ -375,7 +344,7 @@
),
'button' => array(
'id' => 'save',
- 'label' => __( 'Install and continue', 'wp-optimize' ),
+ 'label' => __('Install and continue', 'wp-optimize'),
'icon' => 'EastRoundedIcon',
),
);
@@ -392,11 +361,11 @@
'id' => 'go_premium',
'type' => 'go_premium',
'icon' => 'bolt',
- 'title' => __( 'Upgrade to Premium', 'wp-optimize' ),
- 'subtitle' => __( 'The complete optimization suite with safe defaults and expert help.', 'wp-optimize' ),
+ 'title' => __('Upgrade to Premium', 'wp-optimize'),
+ 'subtitle' => __('The complete optimization suite with safe defaults and expert help.', 'wp-optimize'),
'bullets' => $go_premium_step_bullets,
'enable_premium_btn' => true,
- 'premium_btn_text' => __( 'Upgrade to Premium', 'wp-optimize' ),
+ 'premium_btn_text' => __('Upgrade to Premium', 'wp-optimize'),
);
}
@@ -414,9 +383,9 @@
'id' => 'completed',
'type' => 'completed',
'icon' => 'CheckRoundedIcon',
- 'title' => __( 'You're all set!', 'wp-optimize' ),
+ 'title' => __('You're all set!', 'wp-optimize'),
'title_conditional' => array(
- 'isInstalling' => __( 'Almost done, finalizing...', 'wp-optimize' ),
+ 'isInstalling' => __('Almost done, finalizing...', 'wp-optimize'),
),
'subtitle' => $last_step_subtitle,
'subtitle_conditional' => array(
@@ -425,7 +394,7 @@
'bullets' => $last_step_bullets,
'button' => array(
'id' => 'finish',
- 'label' => __( 'Go to settings', 'wp-optimize' ),
+ 'label' => __('Go to settings', 'wp-optimize'),
),
);
}
@@ -442,23 +411,7 @@
return false;
}
- try {
- /*
- * The is_connected() method is protected in class Updraft_Manager_Updater_1_9.
- * So we cannot call it directly from outside the class without using ReflectionClass.
- */
- $reflection = new ReflectionClass($updraft_updater_instance);
- if (!$reflection->hasMethod('is_connected')) {
- return false;
- }
- $method = $reflection->getMethod('is_connected');
- $method->setAccessible(true);
-
- return (bool) $method->invoke($updraft_updater_instance);
- } catch (Throwable $e) {
- // Any exception results in returning false
- return false;
- }
+ return (bool) $updraft_updater_instance->is_connected();
}
/**
@@ -548,14 +501,14 @@
'id' => 'email_reports_mailinglist',
'key' => 'email_reports_mailinglist',
'type' => 'email',
- 'label' => __( 'Email', 'wp-optimize'),
+ 'label' => __('Email', 'wp-optimize'),
'default' => '',
),
array(
'id' => 'tips_tricks_mailinglist',
'key' => 'tips_tricks_mailinglist',
'type' => 'checkbox',
- 'label' => __( 'I agree to receive emails with tips, updates and marketing content.', 'wp-optimize').' '.__( 'I understand I can unsubscribe at any time.', 'wp-optimize' ),
+ 'label' => __('I agree to receive emails with tips, updates and marketing content.', 'wp-optimize').' '.__('I understand I can unsubscribe at any time.', 'wp-optimize'),
'default' => false,
'show_privacy_link' => true,
),
@@ -579,18 +532,13 @@
}
$webp_instance = WP_Optimize()->get_webp_instance();
- $webp_tooltip = __( 'Serve modern WebP images for smaller downloads.', 'wp-optimize' );
+ $webp_tooltip = __('Serve modern WebP images for smaller downloads.', 'wp-optimize');
$is_lock_webp = false;
- if (!$webp_instance->shell_functions_available()) {
+ $webp_result = $webp_instance->evaluate_webp_capability();
+ if (!$webp_result['is_available']) {
$is_lock_webp = true;
- $webp_tooltip = __( 'Required WebP shell functions are not available on your server.', 'wp-optimize' );
- } elseif ($webp_instance->should_run_webp_conversion_test()) {
- WPO_WebP_Test_Run::get_converter_status();
- if (!$webp_instance->is_webp_conversion_successful()) {
- $is_lock_webp = true;
- $webp_tooltip = __( 'No working WebP converter was found on your server.', 'wp-optimize' );
- }
+ $webp_tooltip = $webp_result['message'];
}
return array(
@@ -599,9 +547,9 @@
'key' => 'enable_caching_onboarding',
'type' => 'checkbox',
'subtype' => 'switch',
- 'label' => __( 'Page caching', 'wp-optimize' ),
+ 'label' => __('Page caching', 'wp-optimize'),
'tooltip' => array(
- 'text' => __( 'Cache full pages for faster repeat visits.', 'wp-optimize' ),
+ 'text' => __('Cache full pages for faster repeat visits.', 'wp-optimize'),
),
'default' => true,
),
@@ -610,9 +558,9 @@
'key' => 'enable_minify_onboarding',
'type' => 'checkbox',
'subtype' => 'switch',
- 'label' => __( 'Minify static assets', 'wp-optimize' ),
+ 'label' => __('Minify static assets', 'wp-optimize'),
'tooltip' => array(
- 'text' => __( 'Shrink HTML, CSS and JavaScript files for quicker loads.', 'wp-optimize' ),
+ 'text' => __('Shrink HTML, CSS and JavaScript files for quicker loads.', 'wp-optimize'),
),
'default' => true,
),
@@ -621,9 +569,9 @@
'key' => 'enable_image_compression_onboarding',
'type' => 'checkbox',
'subtype' => 'switch',
- 'label' => __( 'Image compression', 'wp-optimize' ),
+ 'label' => __('Image compression', 'wp-optimize'),
'tooltip' => array(
- 'text' => __( 'Automatically reduce image file sizes on upload to improve page load speed.', 'wp-optimize' ).' '.__( 'In settings, you can adjust compression quality as well as manually compress existing images.', 'wp-optimize' ),
+ 'text' => __('Automatically reduce image file sizes on upload to improve page load speed.', 'wp-optimize').' '.__('In settings, you can adjust compression quality as well as manually compress existing images.', 'wp-optimize'),
),
'default' => true,
),
@@ -633,7 +581,7 @@
'type' => 'checkbox',
'subtype' => 'switch',
'is_lock' => $is_lock_webp,
- 'label' => __( 'WebP conversion', 'wp-optimize' ),
+ 'label' => __('WebP conversion', 'wp-optimize'),
'tooltip' => array(
'text' => $webp_tooltip,
),
@@ -650,7 +598,7 @@
'heading' => array(
'text' => $is_lock ? $premium_heading : ''
),
- 'text' => $is_lock ? $premium_text : __( 'Load images and videos only when they enter the viewport.', 'wp-optimize' ),
+ 'text' => $is_lock ? $premium_text : __('Load images and videos only when they enter the viewport.', 'wp-optimize'),
),
'default' => !$is_lock,
),
@@ -665,7 +613,7 @@
'heading' => array(
'text' => $is_lock ? $premium_heading : ''
),
- 'text' => $is_lock ? $premium_text : __( 'Auto-add missing width and height to improve load speed and reduce layout shifts.', 'wp-optimize' ),
+ 'text' => $is_lock ? $premium_text : __('Auto-add missing width and height to improve load speed and reduce layout shifts.', 'wp-optimize'),
),
'default' => !$is_lock,
),
@@ -683,7 +631,7 @@
$upgrade_url_tooltip = WP_Optimize_Utils::add_utm_params($this->upgrade_url, $this->get_utm_params_to_override('upgrade-to-premium', 'tooltip'), true);
$text = sprintf(
// translators: %s: Text with Link
- __( '%s to unlock this and other advanced options.', 'wp-optimize' ), '<a href="'.$upgrade_url_tooltip.'" class="underline" target="_blank">' . __( 'Upgrade to Premium', 'wp-optimize' ) . '</a>');
+ __('%s to unlock this and other advanced options.', 'wp-optimize'), '<a href="'.esc_url($upgrade_url_tooltip).'" class="underline" target="_blank">' . __('Upgrade to Premium', 'wp-optimize') . '</a>');
return array($heading, $text);
}
@@ -697,23 +645,23 @@
return array(
array(
'icon' => 'database',
- 'title' => __( 'Clean database', 'wp-optimize' ),
- 'desc' => __( 'Remove unnecessary data to keep your site fast.', 'wp-optimize' ),
+ 'title' => __('Clean database', 'wp-optimize'),
+ 'desc' => __('Remove unnecessary data to keep your site fast.', 'wp-optimize'),
),
array(
'icon' => 'compress',
- 'title' => __( 'Compress images', 'wp-optimize' ),
- 'desc' => __( 'Reduce image sizes for quicker page loads.', 'wp-optimize' ),
+ 'title' => __('Compress images', 'wp-optimize'),
+ 'desc' => __('Reduce image sizes for quicker page loads.', 'wp-optimize'),
),
array(
'icon' => 'cache',
- 'title' => __( 'Cache pages', 'wp-optimize' ),
- 'desc' => __( 'Store pages for instant loading.', 'wp-optimize' ),
+ 'title' => __('Cache pages', 'wp-optimize'),
+ 'desc' => __('Store pages for instant loading.', 'wp-optimize'),
),
array(
'icon' => 'minify',
- 'title' => __( 'Minify code', 'wp-optimize' ),
- 'desc' => __( 'Shrink CSS, JavaScript, and HTML for better performance.', 'wp-optimize' ),
+ 'title' => __('Minify code', 'wp-optimize'),
+ 'desc' => __('Shrink CSS, JavaScript, and HTML for better performance.', 'wp-optimize'),
),
);
}
@@ -753,9 +701,9 @@
$onboarding->mailing_list = array($this->is_premium ? self::MAILING_LIST_PREMIUM_ID : self::MAILING_LIST_FREE_ID);
$onboarding->mailing_list_endpoint = self::MAILING_LIST_ENDPOINT;
$onboarding->caller_slug = $this->caller_slug;
- $onboarding->capability = 'manage_options';
+ $onboarding->capability = $this->is_multisite ? 'manage_network_options' : 'manage_options';
$onboarding->support_url = $support_link;
- $onboarding->privacy_url_label = __( 'Privacy Policy.', 'wp-optimize' );
+ $onboarding->privacy_url_label = __('Privacy Policy.', 'wp-optimize');
$onboarding->privacy_statement_url = WP_Optimize_Utils::add_utm_params('https://teamupdraft.com/privacy/', $this->get_utm_params_to_override('privacy-statement'));
$onboarding->forgot_password_url = WP_Optimize_Utils::add_utm_params('https://teamupdraft.com/my-account/lost-password/', $this->get_utm_params_to_override('forgot-password'));
$onboarding->documentation_url = WP_Optimize_Utils::add_utm_params('https://teamupdraft.com/documentation/wp-optimize/', $this->get_utm_params_to_override('documentation'));
@@ -764,7 +712,7 @@
$onboarding->version = WPO_VERSION;
$onboarding->languages_dir = WPO_PLUGIN_MAIN_PATH . 'languages';
$onboarding->text_domain = 'wp-optimize';
- $onboarding->exit_wizard_text = __( 'Exit setup', 'wp-optimize' );
+ $onboarding->exit_wizard_text = __('Exit setup', 'wp-optimize');
$onboarding->reload_settings_page_on_finish = true;
$onboarding->udmupdater_muid = 2;
$onboarding->udmupdater_slug = 'wp-optimize-premium';
--- a/wp-optimize/includes/class-wpo-page-optimizer.php
+++ b/wp-optimize/includes/class-wpo-page-optimizer.php
@@ -110,7 +110,8 @@
* @return boolean
*/
private function should_initialise() {
- // Skip admin, AJAX, WP-CLI, cron, and page builder edit modes.
+
+ // Skip admin, AJAX, WP-CLI, cron, static assets and page builder edit modes.
if (is_admin() || $this->is_ajax() || $this->is_wp_cli() || $this->is_cron_job() || $this->is_static_asset_request() || WPO_Page_Builder_Compatibility::instance()->is_edit_mode()) {
return false;
}
--- a/wp-optimize/includes/class-wpo-uninstall.php
+++ b/wp-optimize/includes/class-wpo-uninstall.php
@@ -9,6 +9,17 @@
* Actions to be performed upon plugin uninstallation
*/
public static function actions() {
+ $is_premium_active = WP_Optimize()->is_active('premium');
+ $is_free_active = WP_Optimize()->is_active();
+
+ if (!$is_premium_active) {
+ self::delete_premium_cache_data();
+ }
+
+ if ($is_premium_active || $is_free_active) {
+ return;
+ }
+
WP_Optimize()->get_gzip_compression()->disable();
WP_Optimize()->get_browser_cache()->disable();
WP_Optimize()->get_options()->delete_all_options();
@@ -18,6 +29,23 @@
WP_Optimize()->get_table_management()->delete_plugin_tables();
Updraft_Tasks_Activation::uninstall(WPO_PLUGIN_SLUG);
self::delete_wpo_folder();
+
+ $htaccess_file = self::get_upload_basedir() . '.htaccess';
+ if (is_file($htaccess_file) && 0 === filesize($htaccess_file)) {
+ wp_delete_file($htaccess_file);
+ }
+
+ wp_clear_scheduled_hook('process_smush_tasks');
+ WP_Optimize()->wpo_cron_deactivate();
+ }
+
+ /**
+ * Delete cache data created by premium-only features.
+ *
+ * Only runs when premium is not active, to avoid wiping premium data
+ * while the premium version is still installed.
+ */
+ private static function delete_premium_cache_data() {
if (class_exists('WPO_Gravatar_Data')) {
wpo_delete_files(WPO_Gravatar_Data::WPO_CACHE_GRAVATAR_DIR);
}
@@ -29,14 +57,6 @@
if (class_exists('WP_Optimize_Lazy_Load')) {
WP_Optimize_Lazy_Load::instance()->delete_image_cache();
}
-
- $htaccess_file = self::get_upload_basedir() . '.htaccess';
- if (is_file($htaccess_file) && 0 === filesize($htaccess_file)) {
- wp_delete_file($htaccess_file);
- }
-
- wp_clear_scheduled_hook('process_smush_tasks');
- WP_Optimize()->wpo_cron_deactivate();
}
/**
@@ -72,27 +92,46 @@
}
/**
- * Delete `uploads/wpo` sub folders and if it is empty delete the folder itself
+ * Returns an array of known files in `uploads/wpo` root folder
+ *
+ * @return array
+ */
+ private static function get_wpo_root_files() {
+ return array(
+ 'wpo-plugins-tables-list.json'
+ );
+ }
+
+ /**
+ * Delete `uploads/wpo` folder, its known sub folders, and known files
*/
public static function delete_wpo_folder() {
$wpo_folder = self::get_upload_basedir() . trailingslashit('wpo');
require_once WPO_PLUGIN_MAIN_PATH . 'cache/file-based-page-cache-functions.php';
- if (is_dir($wpo_folder)) {
- $wpo_sub_folders = self::get_wpo_sub_folders();
- foreach ($wpo_sub_folders as $folder) {
- wpo_delete_files($wpo_folder . $folder);
- }
-
- // phpcs:disable
- // Generic.PHP.NoSilencedErrors.Discouraged -- suppress warning if it arises due to race condition
- // WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Not applicable in this context
- $files = @scandir($wpo_folder);
- if (false === $files) return;
- if (2 === count($files)) {
- @rmdir($wpo_folder);
- }
- // phpcs:enable
+
+ if (!is_dir($wpo_folder)) {
+ return;
+ }
+
+ $wpo_sub_folders = self::get_wpo_sub_folders();
+ foreach ($wpo_sub_folders as $folder) {
+ wpo_delete_files($wpo_folder . $folder);
+ }
+
+ // Delete known root-level files
+ $wpo_root_files = self::get_wpo_root_files();
+ foreach ($wpo_root_files as $file) {
+ wpo_delete_files($wpo_folder . $file, false);
+ }
+
+ // phpcs:disable
+ // Generic.PHP.NoSilencedErrors.Discouraged -- suppress warning if it arises due to race condition
+ // WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Not applicable in this context
+ $files = @scandir($wpo_folder);
+ if (false !== $files && 2 === count($files)) {
+ @rmdir($wpo_folder);
}
+ // phpcs:enable
}
}
--- a/wp-optimize/includes/tables/class-wp-optimize-table-404-detector.php
+++ b/wp-optimize/includes/tables/class-wp-optimize-table-404-detector.php
@@ -13,11 +13,11 @@
private $table_name = '404_detector';
/**
- * Complete table name with prefix
+ * Complete table name with a prefix
*
* @return string
*/
- public function get_table_name() {
+ public function get_table_name(): string {
global $wpdb;
return $wpdb->base_prefix . 'wpo_' . $this->table_name;
@@ -28,7 +28,7 @@
*
* @return array
*/
- public function describe() {
+ public function describe(): array {
return array(
'fields' => array(
'url' => 'TEXT NOT NULL',
--- a/wp-optimize/includes/tables/interface-wp-optimize-table-interface.php
+++ b/wp-optimize/includes/tables/interface-wp-optimize-table-interface.php
@@ -10,7 +10,7 @@
*
* @return string
*/
- public function get_table_name();
+ public function get_table_name(): string;
/**
* Return an array with `dbDelta()` field strings (and keys)
@@ -21,7 +21,7 @@
*
* @return array
*/
- public function describe();
+ public function describe(): array;
/**
* Returns singleton instance
--- a/wp-optimize/minify/class-wp-optimize-minify-front-end.php
+++ b/wp-optimize/minify/class-wp-optimize-minify-front-end.php
@@ -367,7 +367,7 @@
}
/**
- * Enable defer for JavaScript (WP 4.1 and above) and remove query strings for ignored files
+ * Enable defer for JavaScript and remove query strings for ignored and all non-minified files
*
* @param string $tag
* @param string $handle
@@ -381,8 +381,9 @@
$ignore_list = WP_Optimize_Minify_Functions::compile_ignore_list($exclude_js);
// Should this defer the Poly fills for IE?
$blacklist = WP_Optimize_Minify_Functions::get_ie_blacklist();
+
// no query strings
- if (false !== stripos($src, '?ver')) {
+ if (false !== stripos($src, '?ver') && WP_Optimize_Minify_Functions::is_already_minified($src)) {
$srcf = stristr($src, '?ver', true);
$tag = str_ireplace($src, $srcf, $tag);
$src = $srcf;
@@ -573,24 +574,28 @@
$uniq[$key] = $handle;
}
}
+
+ $version = '?ver=' . (!empty($version) ? $version : $wp_styles->default_version);
+ $href_versioned = $href . $version;
+
// Exclude specific CSS files from PageSpeedIndex?
if (WP_Optimize_Minify_Functions::in_arrayi($href, $async_css)) {
- WP_Optimize_Minify_Print::exclude_style($href);
+ WP_Optimize_Minify_Print::exclude_style($href_versioned);
$done = array_merge($done, array($handle));
continue;
}
// Fonts Awesome Processing
if (WP_Optimize_Minify_Functions::is_font_awesome($href)) {
if ('inline' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::inline_style($handle, $href);
+ WP_Optimize_Minify_Print::inline_style($handle, $href_versioned);
$done = array_merge($done, array($handle));
continue;
} elseif ('async' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::async_style($href, $mediatype);
+ WP_Optimize_Minify_Print::async_style($href_versioned, $mediatype);
$done = array_merge($done, array($handle));
continue;
} elseif ('exclude' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::exclude_style($href);
+ WP_Optimize_Minify_Print::exclude_style($href_versioned);
$done = array_merge($done, array($handle));
continue;
}
@@ -804,7 +809,7 @@
if (!file_exists($file)) {
// code and log initialization
- $log_header = "PROCESSED on ".gmdate('r')." from ".home_url(add_query_arg(null, null));
+ $log_header = $this->get_log_header();
$log = array(
'header' => $log_header,
'files' => array()
@@ -992,7 +997,8 @@
foreach ($async_js as $l) {
if (stripos($href, $l) !== false) {
// print code if there are no linebreaks, or return
- WP_Optimize_Minify_Print::async_script($href);
+ $href_versioned = $href . (!empty($wp_scripts->registered[$handle]->ver) ? '?ver=' . $wp_scripts->registered[$handle]->ver : '');
+ WP_Optimize_Minify_Print::async_script($href_versioned);
$skipjs = true;
$done = array_merge($done, array($handle));
break;
@@ -1079,7 +1085,7 @@
if (!file_exists($file)) {
// code and log initialization
- $log_header = "PROCESSED on ".gmdate('r')." from ".home_url(add_query_arg(null, null));
+ $log_header = $this->get_log_header();
$log = array(
'header' => $log_header,
'files' => array()
@@ -1315,7 +1321,8 @@
$skipjs = false;
foreach ($async_js as $l) {
if (stripos($href, $l) !== false) {
- WP_Optimize_Minify_Print::async_script($href);
+ $href_versioned = $href . (!empty($wp_scripts->registered[$handle]->ver) ? '?ver=' . $wp_scripts->registered[$handle]->ver : '');
+ WP_Optimize_Minify_Print::async_script($href_versioned);
$skipjs = true;
$done = array_merge($done, array($handle));
break;
@@ -1433,7 +1440,7 @@
if (!file_exists($file)) {
// code and log initialization
- $log_header = "PROCESSED on ".gmdate('r')." from ".home_url(add_query_arg(null, null));
+ $log_header = $this->get_log_header();
$log = array(
'header' => $log_header,
'files' => array()
@@ -1788,24 +1795,27 @@
continue;
}
+ $version = '?ver=' . (!empty($version) ? $version : $wp_styles->default_version);
+ $href_versioned = $href . $version;
+
// Exclude specific CSS files from PageSpeedIndex?
if (is_array($async_css) && WP_Optimize_Minify_Functions::in_arrayi($href, $async_css)) {
- WP_Optimize_Minify_Print::exclude_style($href);
+ WP_Optimize_Minify_Print::exclude_style($href_versioned);
$done = array_merge($done, array($handle));
continue;
}
if (WP_Optimize_Minify_Functions::is_font_awesome($href)) {
if ('inline' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::inline_style($handle, $href);
+ WP_Optimize_Minify_Print::inline_style($handle, $href_versioned);
$done = array_merge($done, array($handle));
continue;
} elseif ('async' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::async_style($href, $mediatype);
+ WP_Optimize_Minify_Print::async_style($href_versioned, $mediatype);
$done = array_merge($done, array($handle));
continue;
} elseif ('exclude' === $this->options['fawesome_method']) {
- WP_Optimize_Minify_Print::exclude_style($href);
+ WP_Optimize_Minify_Print::exclude_style($href_versioned);
$done = array_merge($done, array($handle));
continue;
}
@@ -1895,7 +1905,7 @@
if (!file_exists($file)) {
// code and log initialization
- $log_header = "PROCESSED on ".gmdate('r')." from ".home_url(add_query_arg(null, null));
+ $log_header = $this->get_log_header();
$log = array(
'header' => $log_header,
'files' => array()
@@ -2071,7 +2081,7 @@
}
// code and log initialization
- $log_header = "PROCESSED on ".gmdate('r')." from ".home_url(add_query_arg(null, null));
+ $log_header = $this->get_log_header();
$log = array(
'header' => $log_header,
'files' => array()
@@ -2092,7 +2102,7 @@
$enable_minification = $minify_js && !WP_Optimize_Minify_Functions::is_minified_css_js_filename($href);
$json = WP_Optimize_Minify_Functions::download_and_minify($href, null, $enable_minification, 'js', $handle_no_slash, $version);
if ($this->options['debug']) {
- echo "<!-- wpo_min DEBUG: Uncached file processing now for " . esc_html($handle) . " / " . esc_html($href) . " / " . esc_html($version) . " -->n";
+ $buffer .= "<!-- wpo_min DEBUG: Uncached file processing now for " . esc_html($handle) . " / " . esc_html($href) . " / " . esc_html($version) . " -->n";
}
WP_Optimize_Minify_Cache_Functions::set_transient($tkey, $json);
}
@@ -2744,4 +2754,15 @@
}
return false;
}
+
+ /**
+ * Returns the log header with the current date and url
+ *
+ * @return string
+ */
+ private function get_log_header() {
+ $request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '';
+ $log_header = "PROCESSED on ".gmdate('r')." from ".home_url($request_uri);
+ return $log_header;
+ }
}
--- a/wp-optimize/minify/class-wp-optimize-minify-functions.php
+++ b/wp-optimize/minify/class-wp-optimize-minify-functions.php
@@ -734,13 +734,23 @@
* @return string
*/
public static function remove_cssjs_ver($src) {
- if (stripos($src, '?ver=')) {
+ if (stripos($src, '?ver=') && self::is_already_minified($src)) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
/**
+ * Determine if the source is already minified (served from minify cache)
+ *
+ * @param string $src
+ * @return boolean
+ */
+ public static function is_already_minified($src) {
+ return false !== strpos($src, 'cache/wpo-minify');
+ }
+
+ /**
* Rewrite cache files to http, https or dynamic
*
* @param string $url
@@ -1076,7 +1086,7 @@
* @return boolean
*/
public static function is_font_awesome($href) {
- return (boolean) preg_match('/font[-_]?awesome/i', $href);
+ return (bool) preg_match('/font[-_]?awesome/i', $href);
}
/**
--- a/wp-optimize/templates/cache/browser-cache.php
+++ b/wp-optimize/templates/cache/browser-cache.php
@@ -87,6 +87,7 @@
<?php
}
?></div>
+ <div id="wpo_browser_cache_error_message" class="notice notice-error" style="display: none;"></div>
<pre id="wpo_browser_cache_output" style="display: none;"></pre>
<?php
}
--- a/wp-optimize/templates/cache/page-cache.php
+++ b/wp-optimize/templates/cache/page-cache.php
@@ -1,5 +1,5 @@
<?php if (!defined('WPO_VERSION')) die('No direct access allowed'); ?>
-<?php if ($does_server_handles_cache) : ?>
+<?php if ($does_server_handle_cache) : ?>
<div class="wpo-info highlight-dashicons">
<h3><?php esc_html_e('Your web hosting company/server handles:', 'wp-optimize'); ?></h3>
<p><?php esc_html_e('Page caching', 'wp-optimize'); ?><span class="dashicons dashicons-saved"></span></p>
--- a/wp-optimize/templates/images/smush.php
+++ b/wp-optimize/templates/images/smush.php
@@ -80,7 +80,7 @@
<?php if (WPO_USE_WEBP_CONVERSION) : ?>
<h3><?php esc_html_e('WebP conversion', 'wp-optimize');?></h3>
- <?php if ($does_server_allows_local_webp_conversion) : ?>
+ <?php if ($does_server_allow_local_webp_conversion) : ?>
<input type="checkbox" id="enable_webp_conversion" name="webp_conversion" <?php checked($smush_options['webp_conversion']); ?> class="smush-options webp_conversion">
<label for="enable_webp_conversion"><?php esc_html_e('Create WebP version of image', 'wp-optimize');?></label>
<span tabindex="0" data-tooltip="<?php esc_attr_e('Creates WebP image format and serves it whenever possible.', 'wp-optimize');?>"><span class="dashicons dashicons-editor-help"></span> </span>
@@ -100,7 +100,7 @@
</div>
<button type="button" class="button button-link w