PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | wp-optimize.php +834 -1150 3.2.3 → 4.7.0 View file →
@@ -1,13 +1,15 @@
1 1 <?php
2 2 /**
3 3 Plugin Name: WP-Optimize - Clean, Compress, Cache
4 -Plugin URI: https://getwpo.com
4 +Plugin URI: https://teamupdraft.com/wp-optimize
5 5 Description: WP-Optimize makes your site fast and efficient. It cleans the database, compresses images and caches pages. Fast sites attract more traffic and users.
6 -Version: 3.2.3
6 +Version: 4.7.0
7 +Requires at least: 4.9
8 +Requires PHP: 7.2
7 9 Update URI: https://wordpress.org/plugins/wp-optimize/
8 -Author: David Anderson, Ruhani Rabin, Team Updraft
9 -Author URI: https://updraftplus.com
10 +Author: TeamUpdraft, DavidAnderson
11 +Author URI: https://teamupdraft.com/wp-optimize?utm_source=wpo-wp-dir&utm_medium=referral&utm_campaign=plugin-dir&utm_content=teamupdraft&utm_creative_format=author
10 12 Text Domain: wp-optimize
11 13 Domain Path: /languages
12 14 License: GPLv2 or later
13 15 */
@@ -15,55 +17,81 @@
15 17 if (!defined('ABSPATH')) die('No direct access allowed');
16 18
17 19 // Check to make sure if WP_Optimize is already call and returns.
18 20 if (!class_exists('WP_Optimize')) :
19 -define('WPO_VERSION', '3.2.3');
21 +define('WPO_VERSION', '4.7.0');
20 22 define('WPO_PLUGIN_URL', plugin_dir_url(__FILE__));
21 23 define('WPO_PLUGIN_MAIN_PATH', plugin_dir_path(__FILE__));
24 +define('WPO_PLUGIN_SLUG', plugin_basename(__FILE__));
22 25 define('WPO_PREMIUM_NOTIFICATION', false);
23 -define('WPO_MINIFY_PHP_VERSION_MET', version_compare(PHP_VERSION, '5.4', '>=') ? true : false);
26 +define('WPO_REQUIRED_PHP_VERSION', '7.2');
27 +define('WPO_REQUIRED_WP_VERSION', '4.9');
28 +if (!defined('WPO_USE_WEBP_CONVERSION')) define('WPO_USE_WEBP_CONVERSION', true);
29 +require_once(WPO_PLUGIN_MAIN_PATH.'includes/fragments/input-processing.php');
24 30
25 31 class WP_Optimize {
26 32
27 - public $premium_version_link = 'https://getwpo.com/buy/';
33 + public $premium_version_link = 'https://teamupdraft.com/wp-optimize/pricing/?utm_source=wpo-plugin&utm_medium=referral&utm_campaign=paac&utm_creative_format=overlay';
28 34
29 35 private $template_directories;
30 36
31 37 protected static $_instance = null;
32 38
33 - protected static $_optimizer_instance = null;
39 + protected $_cache_init_status = null;
34 40
35 - protected static $_options_instance = null;
41 + /**
42 + * An array of schedule types
43 + *
44 + * @param boolean $placeholder Determines whether a placeholder select option should be included or not
45 + *
46 + * @return array An array of schedule types
47 + */
48 + public static function get_schedule_types($placeholder = false) {
49 + $schedule_types = array(
50 + 'wpo_daily' => __('Daily', 'wp-optimize'),
51 + 'wpo_weekly' => __('Weekly', 'wp-optimize'),
52 + 'wpo_fortnightly' => __('Fortnightly', 'wp-optimize'),
53 + 'wpo_monthly' => __('Monthly', 'wp-optimize'),
54 + );
36 55
37 - protected static $_minify_instance = null;
56 + $schedule_types = apply_filters('wp_optimize_schedule_types', $schedule_types);
57 + if (true === $placeholder) {
58 + $schedule_types = array_merge(array('' => __('Select schedule', 'wp-optimize')), $schedule_types);
59 + }
60 + return $schedule_types;
61 + }
38 62
39 - protected static $_notices_instance = null;
40 -
41 - protected static $_logger_instance = null;
42 -
43 - protected static $_browser_cache = null;
44 -
45 - protected static $_db_info = null;
46 -
47 - protected static $_cache = null;
48 -
49 - protected static $_gzip_compression = null;
50 -
51 63 /**
52 64 * Class constructor
53 65 */
54 66 public function __construct() {
55 67
68 + spl_autoload_register(array($this, 'loader'));
69 +
70 + // Don't process when accessing without normal WordPress core loading.
71 + if (!defined('WPINC')) return;
72 +
73 + $bypass_instance = $this->get_bypass_instance();
74 + if ($bypass_instance->should_bypass()) {
75 + // Show a bypass notice in the admin bar
76 + $bypass_instance->show_admin_notice();
77 + if (!headers_sent()) {
78 + header('WPO-Bypass-Mode: active');
79 + }
80 + return;
81 + }
82 +
56 83 // Checks if premium is installed along with plugins needed.
57 84 add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
58 85
59 - register_activation_hook(__FILE__, 'wpo_activation_actions');
60 - register_deactivation_hook(__FILE__, 'wpo_deactivation_actions');
61 - register_uninstall_hook(__FILE__, 'wpo_uninstall_actions');
62 -
86 + register_activation_hook(__FILE__, array('WPO_Activation', 'actions'));
87 + register_deactivation_hook(__FILE__, array('WPO_Deactivation', 'actions'));
88 + register_uninstall_hook(__FILE__, array('WPO_Uninstall', 'actions'));
89 +
90 + WPO_Page_Optimizer::instance()->maybe_initialise();
91 +
92 + $this->load_admin();
63 93 add_action('admin_init', array($this, 'admin_init'));
64 - add_action('admin_menu', array($this, 'admin_menu'));
65 - add_action('admin_bar_menu', array($this, 'cache_admin_bar'), 100, 1);
66 94
67 95 add_filter("plugin_action_links_".plugin_basename(__FILE__), array($this, 'plugin_settings_link'));
68 96 add_action('wpo_cron_event2', array($this, 'cron_action'));
69 97 add_filter('cron_schedules', array($this, 'cron_schedules'));
@@ -69,22 +97,24 @@
69 97 add_filter('cron_schedules', array($this, 'cron_schedules'));
70 98
71 99 if (!$this->get_options()->get_option('installed-for', false)) $this->get_options()->update_option('installed-for', time());
72 100
73 - if (!self::is_premium()) {
74 - add_action('auto_option_settings', array($this->get_options(), 'auto_option_settings'));
75 - }
101 + add_action('admin_footer-upload.php', array($this, 'add_smush_popup_template'));
76 102
77 103 add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
78 104
79 105 add_action('wp_enqueue_scripts', array($this, 'frontend_enqueue_scripts'));
80 106
81 - add_action('wp_ajax_wp_optimize_ajax', array($this, 'wp_optimize_ajax_handler'));
107 + if ($this->get_options()->get_option('404_detector', 0)) {
108 + WP_Optimize_Performance::get_instance($this->get_404_detector())->hook_404_handler();
109 + }
82 110
111 + $this->load_ajax_handler();
112 +
83 113 // Show update to Premium notice for non-premium multisite.
84 114 add_action('wpo_additional_options', array($this, 'show_multisite_update_to_premium_notice'));
85 115
86 - // Action column (show repair button if need).
116 + // Action column (show repair button, if needed).
87 117 add_filter('wpo_tables_list_additional_column_data', array($this, 'tables_list_additional_column_data'), 15, 2);
88 118
89 119 /**
90 120 * Add action for display Images > Compress images tab.
@@ -90,22 +120,188 @@
90 120 * Add action for display Images > Compress images tab.
91 121 */
92 122 add_action('wp_optimize_admin_page_wpo_images_smush', array($this, 'admin_page_wpo_images_smush'));
93 123
94 - include_once(WPO_PLUGIN_MAIN_PATH.'includes/updraftcentral.php');
124 + include_once(WPO_PLUGIN_MAIN_PATH.'includes/updraftcentral/updraftcentral.php');
95 125
96 126 include_once(WPO_PLUGIN_MAIN_PATH.'includes/backward-compatibility-functions.php');
97 127
98 128 register_shutdown_function(array($this, 'log_fatal_errors'));
99 129
100 - $this->schedule_plugin_cron_tasks();
101 -
102 130 add_action('wpo_admin_before_closing_wrap', array($this, 'load_modal_template'), 20);
103 131
104 132 add_action('upgrader_process_complete', array($this, 'detect_active_plugins_and_themes_updates'), 10, 2);
133 +
134 + $import_done_hooks = array(
135 + 'import_end', // WordPress importer
136 + 'pmxi_after_xml_import', // wp all import
137 + );
138 +
139 + $db_update_hooks = apply_filters('wp_optimize_db_update_hooks', $import_done_hooks);
140 +
141 + foreach ($db_update_hooks as $hook) {
142 + add_action($hook, array($this, 'maybe_schedule_update_record_count_event'));
143 + }
144 + add_action('wpo_update_record_count_event', array($this->get_db_info(), 'wpo_update_record_count'));
145 +
146 + add_action('wpo_reset_stats_counter', array($this, 'reset_stats_counters'));
147 +
148 + $this->schedule_reset_stats_counters_event();
149 +
105 150 }
106 151
107 152 /**
153 + * Reset stats counter at the start of each month
154 + */
155 + public function reset_stats_counters() {
156 + // Save current total cleaned as previous month data
157 + $options = $this->get_options();
158 + $last_month_total_cleaned = $options->get_option('total-cleaned-current-month');
159 + $options->update_option('total-cleaned-previous-month', $last_month_total_cleaned);
160 + $options->update_option('total-cleaned-current-month', '0');
161 + $this->schedule_reset_stats_counters_event();
162 + }
163 +
164 + /**
165 + * Schedule the reset of stat's counter at the start of each month
166 + */
167 + private function schedule_reset_stats_counters_event() {
168 + if (!wp_next_scheduled('wpo_reset_stats_counter')) {
169 + $next_reset = strtotime('first day of next month midnight');
170 + wp_schedule_single_event($next_reset, 'wpo_reset_stats_counter');
171 + }
172 + }
173 +
174 + /**
175 + * Returns Onboarding class instance
176 + *
177 + * @return WPO_Onboarding
178 + */
179 + public function get_onboarding() {
180 + return WPO_Onboarding::instance();
181 + }
182 +
183 + /**
184 + * Check if minimum requirements for WP-Optimize is met or not.
185 + *
186 + * @return bool
187 + */
188 + public function is_minimum_requirement_met() {
189 + global $wp_version;
190 + return (version_compare(WPO_REQUIRED_PHP_VERSION, PHP_VERSION, '<=') && version_compare(WPO_REQUIRED_WP_VERSION, $wp_version, '<='));
191 + }
192 +
193 + /**
194 + * Add admin notice about minimum server requirements.
195 + */
196 + public function add_notice_minimum_requirements_not_met() {
197 + add_action('admin_notices', array($this, 'output_minimum_requirements_notice'));
198 + }
199 +
200 + /**
201 + * Deactivate the plugin programmatically
202 + */
203 + public function deactivate_plugin() {
204 + if (!function_exists('deactivate_plugins')) {
205 + require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
206 + }
207 + deactivate_plugins(plugin_basename(__FILE__));
208 + }
209 +
210 + /**
211 + * Die after stating minimum requirements
212 + */
213 + public function die_minimum_requirement_not_met() {
214 + $message = $this->get_minimum_requirements_notice_message();
215 + $message .= ' <a href="'.esc_url(admin_url('plugins.php')).'">'.esc_html__('Back to Plugins.', 'wp-optimize').'</a>';
216 + wp_die(wp_kses_post($message));
217 + }
218 +
219 + /**
220 + * Autoloads classes.
221 + *
222 + * @param string $class_name The name of the class.
223 + */
224 + public function loader($class_name) {
225 + $dirs = $this->get_class_directories();
226 +
227 + foreach ($dirs as $dir) {
228 + $class_file = WPO_PLUGIN_MAIN_PATH . trailingslashit($dir) . 'class-' . str_replace('_', '-', strtolower($class_name)) . '.php';
229 + if (file_exists($class_file)) {
230 + require_once($class_file);
231 + return;
232 + }
233 +
234 + $interface_file = WPO_PLUGIN_MAIN_PATH . trailingslashit($dir) . 'interface-' . str_replace('_', '-', strtolower($class_name)) . '.php';
235 + if (file_exists($interface_file)) {
236 + require_once($interface_file);
237 + return;
238 + }
239 + }
240 +
241 + // Include PHP Minify - https://github.com/matthiasmullie/minify
242 + if (strpos($class_name, 'MatthiasMullie') !== false) {
243 + $class_name_parts = explode('\\', $class_name);
244 + $class_file = WPO_PLUGIN_MAIN_PATH.'vendor/'.strtolower($class_name_parts[0]).'/'.strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $class_name_parts[1])).'/src/'.implode('/', array_slice($class_name_parts, 2)).'.php';
245 + if (file_exists($class_file)) {
246 + require_once($class_file);
247 + return;
248 + }
249 + }
250 +
251 + if ('Minify_HTML' === $class_name) {
252 + require_once WPO_PLUGIN_MAIN_PATH.'vendor/mrclay/minify/lib/Minify/HTML.php';
253 + }
254 + }
255 +
256 + /**
257 + * Returns an array of class directories
258 + *
259 + * @return array
260 + */
261 + private function get_class_directories() {
262 + return array(
263 + 'cache',
264 + 'compatibility',
265 + 'includes',
266 + 'includes/tables',
267 + 'includes/list-tables',
268 + 'includes/dashboard',
269 + 'includes/gravatars',
270 + 'includes/lcp',
271 + 'minify',
272 + 'optimizations',
273 + 'webp',
274 + 'includes/updraftcentral',
275 + );
276 + }
277 +
278 + /**
279 + * Initialize Admin class to load admin UI
280 + */
281 + private function load_admin() {
282 + $this->get_admin_instance();
283 + }
284 +
285 + /**
286 + * Returns Bypass class instance
287 + *
288 + * @return WP_Optimize_Bypass
289 + */
290 + private function get_bypass_instance() {
291 + return WP_Optimize_Bypass::instance();
292 + }
293 +
294 + /**
295 + * Returns Admin class instance
296 + *
297 + * @return WP_Optimize_Admin
298 + */
299 + public function get_admin_instance() {
300 + return WP_Optimize_Admin::instance();
301 + }
302 +
303 + /**
108 304 * Detect when an active plugin or theme is updated, and trigger an action
109 305 *
110 306 * @param object $upgrader_object
111 307 * @param array $options
@@ -117,19 +313,31 @@
117 313 $should_purge_cache = false;
118 314 $skin = $upgrader_object->skin;
119 315 if ('plugin' === $options['type']) {
120 316 // A plugin is updated using the default update system (upgrader_overwrote_package is used for the upload method)
121 - if (property_exists($skin, 'plugin_active') && $skin->plugin_active) {
122 - $should_purge_cache = true;
317 + $plugins = array();
318 + if (!empty($options['plugin'])) {
319 + $plugins = array($options['plugin']);
320 + } elseif (!empty($options['plugins']) && is_array($options['plugins'])) {
321 + $plugins = $options['plugins'];
123 322 }
323 +
324 + foreach ($plugins as $plugin) {
325 + if (!empty($plugin) && ! is_wp_error($upgrader_object->result)) {
326 + if (is_plugin_active($plugin)) {
327 + $should_purge_cache = true;
328 + break;
329 + }
330 + }
331 + }
124 332 } elseif ('theme' === $options['type']) {
125 333 $active_theme = get_stylesheet();
126 334 $parent_theme = get_template();
127 335 // A theme is updated using the upload system
128 - if (isset($options['action']) && 'install' === $options['action'] && 'update-theme' === $skin->options['overwrite']) {
336 + if (isset($options['action']) && 'install' === $options['action'] && isset($skin->options['overwrite']) && 'update-theme' === $skin->options['overwrite']) {
129 337 $updated_theme = $upgrader_object->result['destination_name'];
130 338 // Check if the theme is in use
131 - if ($active_theme == $updated_theme || $parent_theme == $updated_theme) {
339 + if ($active_theme === $updated_theme || $parent_theme === $updated_theme) {
132 340 $should_purge_cache = true;
133 341 }
134 342 // A theme is updated using the classic update system
135 343 } elseif (isset($options['action']) && 'update' === $options['action'] && isset($options['themes']) && is_array($options['themes'])) {
@@ -145,13 +353,25 @@
145 353 */
146 354 if ($should_purge_cache) do_action('wpo_active_plugin_or_theme_updated');
147 355
148 356 }
357 +
358 + /**
359 + * Sets a flag to indicate an import action is done, if needed
360 + */
361 + public function maybe_schedule_update_record_count_event() {
362 + if (!wp_next_scheduled('wpo_update_record_count_event')) {
363 + wp_schedule_single_event(time() + 60, 'wpo_update_record_count_event');
364 + }
365 + }
149 366
150 367 public function admin_page_wpo_images_smush() {
151 368 $options = Updraft_Smush_Manager()->get_smush_options();
152 - $custom = 100 != $options['image_quality'] && 90 != $options['image_quality'] ? true : false;
153 - $this->include_template('images/smush.php', false, array('smush_options' => $options, 'custom' => $custom, 'does_server_allows_local_webp_conversion' => $this->does_server_allows_local_webp_conversion()));
369 + $custom = 90 >= $options['image_quality'] && 65 <= $options['image_quality'];
370 + $sites = $this->get_sites();
371 + $compression_server_hint = Updraft_Smush_Manager()->get_compression_server_hint();
372 + $this->include_template('images/smush.php', false, array('smush_options' => $options, 'custom' => $custom, 'sites' => $sites, 'does_server_allow_local_webp_conversion' => $this->get_server_compatibility_instance()->does_server_allow_local_webp_conversion(), 'compression_server_hint' => $compression_server_hint));
373 + $this->add_smush_popup_template();
154 374 }
155 375
156 376 public static function instance() {
157 377 if (empty(self::$_instance)) {
@@ -159,105 +379,109 @@
159 379 }
160 380 return self::$_instance;
161 381 }
162 382
163 - public static function get_optimizer() {
164 - if (empty(self::$_optimizer_instance)) {
165 - if (!class_exists('WP_Optimizer')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimizer.php');
166 - self::$_optimizer_instance = new WP_Optimizer();
383 + public function get_optimizer() {
384 + return WP_Optimizer::instance();
385 + }
386 +
387 + /**
388 + * Adds 3rd party plugin compatibilities.
389 + */
390 + public function load_compatibilities() {
391 + global $wp_version;
392 +
393 + if (class_exists('Polylang')) {
394 + WPO_Polylang_Compatibility::instance();
167 395 }
168 - return self::$_optimizer_instance;
396 +
397 + if (version_compare($wp_version, '5.2', '<')) {
398 + WPO_WP_Kses_Compatibility::instance();
399 + }
400 +
401 + WPO_Page_Builder_Compatibility::instance();
402 + WPO_KD_Submissions_Compatibility::instance();
403 +
404 + if (class_exists('Custom_Permalinks')) {
405 + WPO_Custom_Permalink_Compatibility::instance();
406 + }
407 +
408 + if (class_exists('TRP_Translate_Press')) {
409 + WPO_TranslatePress_Compatibility::instance();
410 + }
411 +
412 + do_action('wpo_load_compatibilities');
169 413 }
170 414
171 415 /**
172 - * Get and instanciate WP_Optimize_Minify
416 + * Get and instantiate WP_Optimize_Minify
173 417 *
174 418 * @return WP_Optimize_Minify
175 419 */
176 420 public function get_minify() {
177 - if (empty(self::$_minify_instance)) {
178 - if (!class_exists('WP_Optimize_Minify')) {
179 - include_once WPO_PLUGIN_MAIN_PATH.'minify/class-wp-optimize-minify.php';
180 - }
181 - self::$_minify_instance = new WP_Optimize_Minify();
182 - }
183 - return self::$_minify_instance;
421 + return WP_Optimize_Minify::instance();
184 422 }
185 423
186 - public static function get_options() {
187 - if (empty(self::$_options_instance)) {
188 - if (!class_exists('WP_Optimize_Options')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimize-options.php');
189 - self::$_options_instance = new WP_Optimize_Options();
190 - }
191 - return self::$_options_instance;
424 + public function get_options() {
425 + return WP_Optimize_Options::instance();
192 426 }
193 427
194 - public static function get_notices() {
195 - if (empty(self::$_notices_instance)) {
196 - if (!class_exists('WP_Optimize_Notices')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/wp-optimize-notices.php');
197 - self::$_notices_instance = new WP_Optimize_Notices();
198 - }
199 - return self::$_notices_instance;
428 + public function get_notices() {
429 + return WP_Optimize_Notices::instance();
200 430 }
201 431
202 432 /**
203 - * Returns instance if WPO_Page_Cache class.
433 + * Get and instantiate WP_Optimize_Delay_JS
204 434 *
205 - * @return WPO_Page_Cache
435 + * @return WP_Optimize_Delay_JS
206 436 */
207 - public function get_page_cache() {
208 - if (!class_exists('WPO_Page_Cache')) include_once(WPO_PLUGIN_MAIN_PATH.'cache/class-wpo-page-cache.php');
209 -
210 - return WPO_Page_Cache::instance();
437 + private function get_delay_js() {
438 + return WP_Optimize_Delay_JS::instance();
211 439 }
212 440
213 441 /**
214 - * Returns instance if WP_Optimize_WebP class.
442 + * Returns instance of WPO_Page_Optimizer class.
215 443 *
216 - * @return WP_Optimize_WebP
444 + * @return WPO_Page_Optimizer
217 445 */
218 - public function get_webp_instance() {
219 - if (defined('WPO_USE_WEBP_CONVERSION') && true === WPO_USE_WEBP_CONVERSION) {
220 - if (!class_exists('WP_Optimize_WebP')) {
221 - include_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wp-optimize-webp.php';
222 - }
223 - return WP_Optimize_WebP::get_instance();
224 - }
446 + public function get_page_optimizer() {
447 + return WPO_Page_Optimizer::instance();
225 448 }
226 449
227 450 /**
228 - * Detects if the platform is Kinsta or not
451 + * Returns instance 404 Detector Cron class.
229 452 *
230 - * @return bool Returns true if it is Kinsta platform, otherwise returns false
453 + * @return WP_Optimize_404_Detector_Cron
231 454 */
232 - private function is_kinsta() {
233 - return isset($_SERVER['KINSTA_CACHE_ZONE']);
455 + private function get_404_detector_cron() {
456 + return WP_Optimize_404_Detector_Cron::get_instance();
234 457 }
235 458
236 459 /**
237 - * Detects whether the server handles cache. eg. Nginx cache
460 + * Returns instance of WPO_Page_Cache class.
461 + *
462 + * @return WPO_Page_Cache
238 463 */
239 - private function does_server_handles_cache() {
240 - return $this->is_kinsta();
464 + public function get_page_cache() {
465 + return WPO_Page_Cache::instance();
241 466 }
242 467
243 468 /**
244 - * Detects whether the server supports table optimization.
469 + * Returns instance of WP_Optimize_WebP class.
245 470 *
246 - * Some servers prevent table optimization
247 - * because InnoDB engine does not optimize table
248 - * instead it drops tables and recreate them
249 - * which results in elevated disk write operations
471 + * @return WP_Optimize_WebP
250 472 */
251 - public function does_server_allows_table_optimization() {
252 - return !$this->is_kinsta();
473 + public function get_webp_instance() {
474 + return WP_Optimize_WebP::get_instance();
253 475 }
254 476
255 477 /**
256 - * Detects whether the server supports local webp conversion tools
478 + * Returns instance of WP_Optimize_Server_Compatibility class.
479 + *
480 + * @return WP_Optimize_Server_Compatibility
257 481 */
258 - private function does_server_allows_local_webp_conversion() {
259 - return !$this->is_kinsta();
482 + public function get_server_compatibility_instance(): WP_Optimize_Server_Compatibility {
483 + return WP_Optimize_Server_Compatibility::get_instance();
260 484 }
261 485
262 486 /**
263 487 * Create instance of WP_Optimize_Browser_Cache.
@@ -263,14 +487,10 @@
263 487 * Create instance of WP_Optimize_Browser_Cache.
264 488 *
265 489 * @return WP_Optimize_Browser_Cache
266 490 */
267 - public static function get_browser_cache() {
268 - if (empty(self::$_browser_cache)) {
269 - if (!class_exists('WP_Optimize_Browser_Cache')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimize-browser-cache.php');
270 - self::$_browser_cache = new WP_Optimize_Browser_Cache();
271 - }
272 - return self::$_browser_cache;
491 + public function get_browser_cache() {
492 + return WP_Optimize_Browser_Cache::instance();
273 493 }
274 494
275 495 /**
276 496 * Returns WP_Optimize_Database_Information instance.
@@ -277,13 +497,9 @@
277 497 *
278 498 * @return WP_Optimize_Database_Information
279 499 */
280 500 public function get_db_info() {
281 - if (empty(self::$_db_info)) {
282 - if (!class_exists('WP_Optimize_Database_Information')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/wp-optimize-database-information.php');
283 - self::$_db_info = new WP_Optimize_Database_Information();
284 - }
285 - return self::$_db_info;
501 + return WP_Optimize_Database_Information::instance();
286 502 }
287 503
288 504 /**
289 505 * Returns instance of WP_Optimize_Gzip_Compression.
@@ -289,14 +505,10 @@
289 505 * Returns instance of WP_Optimize_Gzip_Compression.
290 506 *
291 507 * @return WP_Optimize_Gzip_Compression
292 508 */
293 - static public function get_gzip_compression() {
294 - if (empty(self::$_gzip_compression)) {
295 - if (!class_exists('WP_Optimize_Gzip_Compression')) include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimize-gzip-compression.php');
296 - self::$_gzip_compression = new WP_Optimize_Gzip_Compression();
297 - }
298 - return self::$_gzip_compression;
509 + public function get_gzip_compression() {
510 + return WP_Optimize_Gzip_Compression::instance();
299 511 }
300 512
301 513 /**
302 514 * Create instance of WP_Optimize_Htaccess.
@@ -304,14 +516,9 @@
304 516 * @param string $htaccess_file absolute path to htaccess file, by default it use .htaccess in WordPress root directory.
305 517 * @return WP_Optimize_Htaccess
306 518 */
307 519 public static function get_htaccess($htaccess_file = '') {
308 - if (!class_exists('WP_Optimize_Cache')) {
309 - include_once(WPO_PLUGIN_MAIN_PATH . '/includes/class-wp-optimize-htaccess.php');
310 - }
311 -
312 - return new WP_Optimize_Htaccess($htaccess_file);
313 -
520 + return new WP_Optimize_Htaccess($htaccess_file);
314 521 }
315 522
316 523 /**
317 524 * Return instance of Updraft_Logger
@@ -317,14 +524,10 @@
317 524 * Return instance of Updraft_Logger
318 525 *
319 526 * @return Updraft_Logger
320 527 */
321 - public static function get_logger() {
322 - if (empty(self::$_logger_instance)) {
323 - include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-updraft-logger.php');
324 - self::$_logger_instance = new Updraft_Logger();
325 - }
326 - return self::$_logger_instance;
528 + public function get_logger() {
529 + return Updraft_Logger::instance();
327 530 }
328 531
329 532 /**
330 533 * Check if the current page belongs to WP-Optimize.
@@ -340,41 +543,63 @@
340 543 /**
341 544 * Enqueue scripts and styles on WP-Optimize pages.
342 545 */
343 546 public function admin_enqueue_scripts() {
344 - $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
345 - $min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
346 - $min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
547 + global $wp_version;
548 + $enqueue_version = $this->get_enqueue_version();
549 + $min_or_not = $this->get_min_or_not_string();
550 + $min_or_not_internal = $this->get_min_or_not_internal_string();
347 551
348 552 // Register or enqueue common scripts
349 553 wp_register_script('wp-optimize-send-command', WPO_PLUGIN_URL.'js/send-command'.$min_or_not_internal.'.js', array(), $enqueue_version);
350 554 wp_localize_script('wp-optimize-send-command', 'wp_optimize_send_command_data', array('nonce' => wp_create_nonce('wp-optimize-ajax-nonce')));
555 + wp_register_script('wp-optimize-block-ui', WPO_PLUGIN_URL.'js/blockUI'.$min_or_not_internal.'.js', array('jquery'), $enqueue_version);
351 556 wp_enqueue_style('wp-optimize-global', WPO_PLUGIN_URL.'css/wp-optimize-global'.$min_or_not_internal.'.css', array(), $enqueue_version);
352 557
353 558 // load scripts and styles only on WP-Optimize pages.
354 559 if (!$this->is_wpo_page()) return;
560 +
561 + wp_enqueue_script( 'jquery-ui-tooltip' );
562 + // Defeat other plugins/themes which dump their jQuery UI CSS onto our settings page
563 + wp_deregister_style('jquery-ui');
564 + wp_enqueue_style('jquery-ui', WPO_PLUGIN_URL.'css/jquery-ui.custom' . $min_or_not_internal . '.css', array(), $enqueue_version);
565 +
566 +
567 + wp_enqueue_script('select2', WPO_PLUGIN_URL . 'js/select2/select2' . $min_or_not . '.js', array('jquery'), $enqueue_version);
568 + wp_enqueue_style('select2', WPO_PLUGIN_URL . 'css/select2/select2' . $min_or_not . '.css', array(), $enqueue_version);
355 569
356 570 wp_enqueue_script('jquery-serialize-json', WPO_PLUGIN_URL.'js/serialize-json/jquery.serializejson'.$min_or_not.'.js', array('jquery'), $enqueue_version);
357 571
358 572 wp_register_script('updraft-queue-js', WPO_PLUGIN_URL.'js/queue'.$min_or_not_internal.'.js', array(), $enqueue_version);
573 +
359 574 wp_enqueue_script('wp-optimize-modal', WPO_PLUGIN_URL.'js/modal'.$min_or_not_internal.'.js', array('jquery', 'backbone', 'wp-util'), $enqueue_version);
360 - wp_enqueue_script('wp-optimize-cache-js', WPO_PLUGIN_URL.'js/cache'.$min_or_not_internal.'.js', array('wp-optimize-send-command', 'smush-js'), $enqueue_version);
361 - wp_enqueue_script('wp-optimize-admin-js', WPO_PLUGIN_URL.'js/wpoadmin'.$min_or_not_internal.'.js', array('jquery', 'updraft-queue-js', 'wp-optimize-send-command', 'smush-js', 'wp-optimize-modal'), $enqueue_version);
575 + wp_enqueue_script('wp-optimize-cache-js', WPO_PLUGIN_URL.'js/cache'.$min_or_not_internal.'.js', array('wp-optimize-send-command', 'smush-js', 'wp-optimize-heartbeat-js', 'wp-optimize-block-ui'), $enqueue_version);
576 + wp_enqueue_script('wp-optimize-admin-js', WPO_PLUGIN_URL.'js/wpoadmin'.$min_or_not_internal.'.js', array('jquery', 'updraft-queue-js', 'wp-optimize-send-command', 'smush-js', 'wp-optimize-modal', 'wp-optimize-cache-js', 'wp-optimize-heartbeat-js'), $enqueue_version);
362 577 wp_enqueue_style('wp-optimize-admin-css', WPO_PLUGIN_URL.'css/wp-optimize-admin'.$min_or_not_internal.'.css', array(), $enqueue_version);
363 - // Using tablesorter to help with organising the DB size on Table Information
364 - // https://github.com/Mottie/tablesorter
365 - wp_enqueue_script('tablesorter-js', WPO_PLUGIN_URL.'js/tablesorter/jquery.tablesorter'.$min_or_not.'.js', array('jquery', 'wp-optimize-send-command'), $enqueue_version);
578 + // Using table sorter to help with organising the DB size on Table Information
579 + // https://github.com/tofsjonas/sortable/
580 + wp_enqueue_script('sortable-js', WPO_PLUGIN_URL.'js/sortable/sortable'.$min_or_not.'.js', array('wp-optimize-send-command'), $enqueue_version);
581 + wp_enqueue_script('sortable-a11y-js', WPO_PLUGIN_URL.'js/sortable/sortable.a11y'.$min_or_not.'.js', array('wp-optimize-send-command'), $enqueue_version);
366 582
367 - wp_enqueue_script('tablesorter-widgets-js', WPO_PLUGIN_URL.'js/tablesorter/jquery.tablesorter.widgets'.$min_or_not.'.js', array('jquery'), $enqueue_version);
583 + wp_enqueue_style('sortable-css', WPO_PLUGIN_URL.'css/sortable/sortable'.$min_or_not_internal.'.css', array(), $enqueue_version);
368 584
369 - // wp_enqueue_style('tablesorter-css', WPO_PLUGIN_URL.'css/tablesorter/theme.default.min.css', array(), $enqueue_version);
370 -
371 585 $js_variables = $this->wpo_js_translations();
372 586 $js_variables['loggers_classes_info'] = $this->get_loggers_classes_info();
373 -
374 587 wp_localize_script('wp-optimize-admin-js', 'wpoptimize', $js_variables);
375 588
376 589 do_action('wpo_premium_scripts_styles', $min_or_not_internal, $min_or_not, $enqueue_version);
590 +
591 + $status_report_dependencies = array('wp-optimize-admin-js');
592 +
593 + // Only include wp-api-fetch if WP >= 5.0
594 + if (version_compare($wp_version, '5.0', '>=')) {
595 + $status_report_dependencies[] = 'wp-api-fetch';
596 + }
597 +
598 + wp_enqueue_script('wp-optimize-status-report', WPO_PLUGIN_URL.'js/status'.$min_or_not_internal.'.js', $status_report_dependencies, $enqueue_version);
599 +
600 + wp_enqueue_script('js-zip', WPO_PLUGIN_URL.'/js/jszip/jszip' . $min_or_not . '.js', array(), $enqueue_version);
601 +
377 602 }
378 603
379 604 /**
380 605 * Enqueue any required front-end scripts
@@ -381,11 +606,11 @@
381 606 *
382 607 * @return void
383 608 */
384 609 public function frontend_enqueue_scripts() {
385 - if (!current_user_can('manage_options') || !is_admin_bar_showing()) return;
386 - $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
387 - $min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
610 + if (!$this->current_user_can('manage_options') || !is_admin_bar_showing()) return;
611 + $enqueue_version = $this->get_enqueue_version();
612 + $min_or_not_internal = $this->get_min_or_not_internal_string();
388 613
389 614 // Register or enqueue common scripts
390 615 wp_enqueue_style('wp-optimize-global', WPO_PLUGIN_URL.'css/wp-optimize-global'.$min_or_not_internal.'.css', array(), $enqueue_version);
391 616 }
@@ -391,8 +616,10 @@
391 616 }
392 617
393 618 /**
394 619 * Load Task Manager
620 + *
621 + * @return Updraft_Smush_Manager
395 622 */
396 623 public function get_task_manager() {
397 624 include_once(WPO_PLUGIN_MAIN_PATH.'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php');
398 625
@@ -397,14 +624,14 @@
397 624 include_once(WPO_PLUGIN_MAIN_PATH.'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php');
398 625
399 626 Updraft_Tasks_Activation::check_updates();
400 627
401 - include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php');
402 - include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php');
403 - include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task.php');
628 + include_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php');
629 + include_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php');
630 + include_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task.php');
404 631
405 - include_once(WPO_PLUGIN_MAIN_PATH . '/includes/class-updraft-smush-task.php');
406 - include_once(WPO_PLUGIN_MAIN_PATH . '/includes/class-updraft-smush-manager.php');
632 + include_once(WPO_PLUGIN_MAIN_PATH . 'includes/class-updraft-smush-task.php');
633 + include_once(WPO_PLUGIN_MAIN_PATH . 'includes/class-updraft-smush-manager.php');
407 634
408 635 return Updraft_Smush_Manager();
409 636 }
410 637
@@ -410,9 +637,9 @@
410 637
411 638 /**
412 639 * Indicate whether we have an associated instance of WP-Optimize Premium or not.
413 640 *
414 - * @returns Boolean
641 + * @returns bool
415 642 */
416 643 public static function is_premium() {
417 644 if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php') && function_exists('WP_Optimize_Premium')) {
418 645 $wp_optimize_premium = WP_Optimize_Premium();
@@ -427,9 +654,9 @@
427 654 * @return bool
428 655 */
429 656 public function is_apache_server() {
430 657 global $is_apache;
431 - return $is_apache;
658 + return (bool) $is_apache;
432 659 }
433 660
434 661 /**
435 662 * Check if script running on IIS web server.
@@ -473,16 +700,23 @@
473 700 * Checks if this is the premium version and loads it. It also ensures that if the free version is installed then it is disabled with an appropriate error message.
474 701 */
475 702 public function plugins_loaded() {
476 703
477 - if (is_multisite()) {
478 - add_action('network_admin_menu', array($this, 'admin_menu'));
704 + if (!$this->is_minimum_requirement_met()) {
705 + $this->add_notice_minimum_requirements_not_met();
706 + $this->deactivate_plugin();
707 + WPO_Deactivation::actions();
708 + return;
479 709 }
480 710
481 - if ($this->does_server_handles_cache()) {
711 + if (is_admin() && $this->current_user_can()) {
712 + WP_Optimize_Heartbeat::get_instance();
713 + }
714 +
715 + if ($this->get_server_compatibility_instance()->does_server_handle_cache()) {
482 716 add_filter('wp_optimize_admin_page_wpo_cache_tabs', array($this, 'filter_cache_tabs'), 99, 1);
483 717
484 - // If newly migrated to server that handles cache, disable wpo cache
718 + // If newly migrated to a server that handles cache, disable wpo cache
485 719 $cache = $this->get_page_cache();
486 720 if ($cache->is_enabled()) {
487 721 $cache->disable();
488 722 }
@@ -494,23 +728,28 @@
494 728 if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php') && !class_exists('WP_Optimize_Premium')) {
495 729 include_once(WPO_PLUGIN_MAIN_PATH.'premium.php');
496 730 }
497 731
732 + if (!self::is_premium()) {
733 + $this->get_server_compatibility_instance()->maybe_disable_unsupported_table_optimization();
734 + add_action('auto_option_settings', array($this->get_options(), 'auto_option_settings'));
735 + }
736 +
498 737 // load defaults
499 - WP_Optimize()->get_options()->set_default_options();
738 + $this->get_options()->set_default_options();
500 739
501 - // Initialize loggers.
502 - $this->setup_loggers();
740 + // Initialize loggers.
741 + add_action('init', array($this, 'setup_loggers'));
503 742
504 743 if ($this->is_active('premium') && false !== ($free_plugin = $this->is_active('free'))) {
505 744 if (!function_exists('deactivate_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php');
506 745 deactivate_plugins($free_plugin);
507 746
508 - // If WPO_ADVANCED_CACHE is defined, we empty advanced-cache.php to regenerate later. Otherwise it contains the path to free.
747 + // If WPO_ADVANCED_CACHE is defined, we empty advanced-cache.php to regenerate later. Otherwise, it contains the path to free.
509 748 if (defined('WPO_ADVANCED_CACHE') && WPO_ADVANCED_CACHE) {
510 749 $advanced_cache_filename = trailingslashit(WP_CONTENT_DIR) . 'advanced-cache.php';
511 750
512 - if (!is_file($advanced_cache_filename) && is_writable(dirname($advanced_cache_filename)) || (is_file($advanced_cache_filename) && is_writable($advanced_cache_filename))) {
751 + if (!is_file($advanced_cache_filename) && wp_is_writable(dirname($advanced_cache_filename)) || (is_file($advanced_cache_filename) && wp_is_writable($advanced_cache_filename))) {
513 752 file_put_contents($advanced_cache_filename, '');
514 753 }
515 754 }
516 755
@@ -518,27 +757,71 @@
518 757 add_action('admin_notices', array($this, 'show_admin_notice_premium'));
519 758 return;
520 759 }
521 760
522 - // Loads the task manager
523 - $this->get_task_manager();
761 + add_action('init', array($this, 'init'));
524 762
525 - // Loads the language file.
526 - load_plugin_textdomain('wp-optimize', false, dirname(plugin_basename(__FILE__)) . '/languages');
763 + // add_filter('updraftcentral_host_plugins', array($this, 'attach_updraftcentral_host'));
764 + // if (file_exists(WPO_PLUGIN_MAIN_PATH.'central/factory.php')) include_once(WPO_PLUGIN_MAIN_PATH.'central/factory.php');
765 + }
527 766
528 - // Load page cache.
529 - $this->get_page_cache();
767 + /**
768 + * Methods needed to be run in init hook.
769 + *
770 + * @return void
771 + */
772 + public function init() {
773 + $this->load_language_file();
774 + $this->schedule_plugin_cron_tasks();
530 775 $this->init_page_cache();
776 + $this->get_minify();
777 + $this->get_delay_js();
531 778
532 - // Include minify
533 - $this->get_minify();
779 + // Load 3rd party plugin compatibilities.
780 + $this->load_compatibilities();
781 +
534 782 $this->run_updates();
535 - $this->get_webp_instance();
783 +
784 + // We need this here because webp can be unavailable because of server moves
785 + // This deletes already converted webp images and original image file when a media is deleted
786 + WP_Optimize_WebP_Images::get_instance();
787 +
788 + // Loads the task manager
789 + $this->get_task_manager();
790 +
791 + // Include WebP
792 + if (WPO_USE_WEBP_CONVERSION) {
793 + $this->get_webp_instance();
794 + }
795 +
796 + $this->get_onboarding()->init();
536 797 }
537 798
538 799 /**
539 - * Filter cache tabs (when it is Kinsta)
800 + * Loads the language file.
540 801 *
802 + * @return void
803 + */
804 + private function load_language_file() {
805 + load_plugin_textdomain('wp-optimize', false, dirname(plugin_basename(__FILE__)) . '/languages');
806 + }
807 +
808 + /**
809 + * Attach this wp-optimize plugin as host of the UpdraftCentral libraries
810 + * (e.g. "central" folder)
811 + *
812 + * @param array $hosts List of plugins having the "central" library integrated into them
813 + *
814 + * @return array
815 + */
816 + public function attach_updraftcentral_host($hosts) {
817 + $hosts[] = 'wp-optimize';
818 + return $hosts;
819 + }
820 +
821 + /**
822 + * Filter cache tabs (when the server handles it or do not allow it, like Kinsta)
823 + *
541 824 * @param array $tabs An array of tabs
542 825 *
543 826 * @return array $tabs An array of tabs
544 827 */
@@ -552,18 +835,18 @@
552 835
553 836 /**
554 837 * Check whether one of free/Premium is active (whether it is this instance or not)
555 838 *
556 - * @param String $which - 'free' or 'premium'
839 + * @param string $which - 'free' or 'premium'
557 840 *
558 - * @return String|Boolean - plugin path (if installed) or false if not
841 + * @return string|boolean - plugin path (if installed) or false if not
559 842 */
560 - private function is_active($which = 'free') {
843 + public function is_active($which = 'free') {
561 844 $active_plugins = $this->get_active_plugins();
562 845 foreach ($active_plugins as $file) {
563 846 if ('wp-optimize.php' == basename($file)) {
564 847 $plugin_dir = WP_PLUGIN_DIR.'/'.dirname($file);
565 - if (('free' == $which && !file_exists($plugin_dir.'/premium.php')) || ('free' != $which && file_exists($plugin_dir.'/premium.php'))) return $file;
848 + if (('free' === $which && !file_exists($plugin_dir.'/premium.php')) || ('free' !== $which && file_exists($plugin_dir.'/premium.php'))) return $file;
566 849 }
567 850 }
568 851 return false;
569 852 }
@@ -570,14 +853,13 @@
570 853
571 854 /**
572 855 * Gets an array of plugins active on either the current site, or site-wide
573 856 *
574 - * @return Array - a list of plugin paths (relative to the plugin directory)
857 + * @return array - a list of plugin paths (relative to the plugin directory)
575 858 */
576 859 private function get_active_plugins() {
577 -
578 860 // Gets all active plugins on the current site
579 - $active_plugins = get_option('active_plugins');
861 + $active_plugins = (array) get_option('active_plugins', array());
580 862
581 863 if (is_multisite()) {
582 864 $network_active_plugins = get_site_option('active_sitewide_plugins');
583 865 if (!empty($network_active_plugins)) {
@@ -611,9 +893,9 @@
611 893
612 894 // Loops around each plugin available.
613 895 foreach ($get_plugins as $key => $value) {
614 896 // If the plugin name matches that of the specified name, it will gather details.
615 - if ($value['Name'] != $name && $value['TextDomain'] != $name) continue;
897 + if ($value['Name'] !== $name && $value['TextDomain'] !== $name) continue;
616 898 $plugin_info['installed'] = true;
617 899 $plugin_info['name'] = $key;
618 900 $plugin_info['version'] = $value['Version'];
619 901 if (in_array($key, $active_plugins)) {
@@ -627,10 +909,10 @@
627 909 /**
628 910 * This is a notice to show users that premium is installed
629 911 */
630 912 public function show_admin_notice_premium() {
631 - echo '<div id="wp-optimize-premium-installed-warning" class="error"><p>'.__('WP-Optimize (Free) has been de-activated, because WP-Optimize Premium is active.', 'wp-optimize').'</p></div>';
632 - if (isset($_GET['activate'])) unset($_GET['activate']);
913 + echo '<div id="wp-optimize-premium-installed-warning" class="error"><p>'.esc_html__('WP-Optimize (Free) has been de-activated, because WP-Optimize Premium is active.', 'wp-optimize').'</p></div>';
914 + if (isset($_GET['activate'])) unset($_GET['activate']); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only unsetting value, not using it.
633 915 }
634 916
635 917 /**
636 918 * Show update to Premium notice for non-premium multisite.
@@ -637,9 +919,9 @@
637 919 */
638 920 public function show_multisite_update_to_premium_notice() {
639 921 if (!is_multisite() || self::is_premium()) return;
640 922
641 - echo '<p><a href="'.$this->premium_version_link.'">'.__('New feature: WP-Optimize Premium can now optimize all sites within a multisite install, not just the main one.', 'wp-optimize').'</a></p>';
923 + echo '<p><a href="'.esc_url($this->premium_version_link). '&utm_content=multisite-upsell' .'">'.esc_html__('New feature: WP-Optimize Premium can now optimize all sites within a multisite install, not just the main one.', 'wp-optimize').'</a></p>';
642 924 }
643 925
644 926 public function admin_init() {
645 927 $pagenow = $GLOBALS['pagenow'];
@@ -645,634 +927,116 @@
645 927 $pagenow = $GLOBALS['pagenow'];
646 928
647 929 $this->register_template_directories();
648 930
649 - if (('index.php' == $pagenow && current_user_can('update_plugins')) || ('index.php' == $pagenow && defined('WP_OPTIMIZE_FORCE_DASHNOTICE') && WP_OPTIMIZE_FORCE_DASHNOTICE)) {
931 + if (('index.php' === $pagenow && $this->current_user_can('update_plugins')) || ('index.php' === $pagenow && defined('WP_OPTIMIZE_FORCE_DASHNOTICE') && WP_OPTIMIZE_FORCE_DASHNOTICE)) {
650 932 $options = $this->get_options();
651 933
652 934 $dismissed_until = $options->get_option('dismiss_dash_notice_until', 0);
653 935
654 - if (file_exists(WPO_PLUGIN_MAIN_PATH . '/index.html')) {
655 - $installed = filemtime(WPO_PLUGIN_MAIN_PATH . '/index.html');
936 + if (file_exists(WPO_PLUGIN_MAIN_PATH . 'index.html')) {
937 + $installed = filemtime(WPO_PLUGIN_MAIN_PATH . 'index.html');
656 938 $installed_for = (time() - $installed);
657 939 }
658 940
659 941 if (($installed && time() > $dismissed_until && $installed_for > (14 * 86400) && !defined('WP_OPTIMIZE_NOADS_B')) || (defined('WP_OPTIMIZE_FORCE_DASHNOTICE') && WP_OPTIMIZE_FORCE_DASHNOTICE)) {
660 - add_action('all_admin_notices', array($this, 'show_admin_notice_upgradead'));
942 + add_action('all_admin_notices', array($this, 'show_admin_notice_upgraded'));
661 943 }
662 944 }
663 - $this->install_or_update_notice = $this->get_install_or_update_notice();
664 - }
665 945
666 - /**
667 - * Get the install or update notice instance
668 - *
669 - * @return WP_Optimize_Install_Or_Update_Notice
670 - */
671 - private function get_install_or_update_notice() {
672 - static $instance = null;
673 - if (is_a($instance, 'WP_Optimize_Install_Or_Update_Notice')) return $instance;
674 - include_once WPO_PLUGIN_MAIN_PATH . 'includes/class-wp-optimize-install-or-update-notice.php';
675 - $instance = new WP_Optimize_Install_Or_Update_Notice();
676 - return $instance;
677 - }
678 -
679 - public function show_admin_notice_upgradead() {
680 - $this->include_template('notices/thanks-for-using-main-dash.php');
681 - }
682 -
683 - public function capability_required() {
684 - return apply_filters('wp_optimize_capability_required', 'manage_options');
685 - }
686 -
687 - public function wp_optimize_ajax_handler() {
688 - $nonce = empty($_POST['nonce']) ? '' : $_POST['nonce'];
689 -
690 - if (!wp_verify_nonce($nonce, 'wp-optimize-ajax-nonce') || empty($_POST['subaction'])) {
691 - wp_send_json(array(
692 - 'result' => false,
693 - 'error_code' => 'security_check',
694 - 'error_message' => __('The security check failed; try refreshing the page.', 'wp-optimize')
695 - ));
946 + if ($this->is_wp_smush_installed()) {
947 + add_filter('transient_wp-smush-conflict_check', array($this, 'modify_wp_smush_conflict_check'), 9, 1);
696 948 }
697 -
698 - $subaction = $_POST['subaction'];
699 - $data = isset($_POST['data']) ? $_POST['data'] : null;
700 -
701 - if (!current_user_can($this->capability_required())) {
702 - wp_send_json(array(
703 - 'result' => false,
704 - 'error_code' => 'security_check',
705 - 'error_message' => __('You are not allowed to run this command.', 'wp-optimize')
706 - ));
949 + if ($this->get_options()->get_option('404_detector', 0)) {
950 + WP_Optimize_Performance::get_instance($this->get_404_detector())->init();
707 951 }
708 -
709 -
710 - // Currently the settings are only available to network admins.
711 - if (is_multisite() && !current_user_can('manage_network_options')) {
712 - /**
713 - * Filters the commands allowed to the subsite admins. Other commands are only available to network admin. Only used in a multisite context.
714 - */
715 - $allowed_commands = apply_filters('wpo_multisite_allowed_commands', array('check_server_status', 'compress_single_image', 'restore_single_image'));
716 - if (!in_array($subaction, $allowed_commands)) wp_send_json(array(
717 - 'result' => false,
718 - 'error_code' => 'update_failed',
719 - 'error_message' => __('Options can only be saved by network admin', 'wp-optimize')
720 - ));
721 - }
722 -
723 - $options = $this->get_options();
724 -
725 - $results = array();
726 -
727 - // Some commands that are available via AJAX only.
728 - if (in_array($subaction, array('dismiss_dash_notice_until', 'dismiss_season'))) {
729 - $options->update_option($subaction, (time() + 366 * 86400));
730 - } elseif (in_array($subaction, array('dismiss_page_notice_until', 'dismiss_notice'))) {
731 - $options->update_option($subaction, (time() + 84 * 86400));
732 - } elseif ('dismiss_review_notice' == $subaction) {
733 - if (empty($data['dismiss_forever'])) {
734 - $options->update_option($subaction, time() + 84*86400);
735 - } else {
736 - $options->update_option($subaction, 100 * (365.25 * 86400));
737 - }
738 - } else {
739 - // Other commands, available for any remote method.
740 - if (!class_exists('WP_Optimize_Commands')) include_once(WPO_PLUGIN_MAIN_PATH . 'includes/class-commands.php');
741 - if (!class_exists('WP_Optimize_Minify_Commands')) include_once(WPO_PLUGIN_MAIN_PATH . 'minify/class-wp-optimize-minify-commands.php');
742 - if (!class_exists('WP_Optimize_Cache_Commands')) include_once(WPO_PLUGIN_MAIN_PATH . 'cache/class-cache-commands.php');
743 -
744 - $commands = new WP_Optimize_Commands();
745 - $minify_commands = new WP_Optimize_Minify_Commands();
746 -
747 -
748 - if (self::is_premium()) {
749 - if (!class_exists('WP_Optimize_Cache_Commands_Premium')) include_once(WPO_PLUGIN_MAIN_PATH . 'cache/class-cache-commands-premium.php');
750 - $cache_commands = new WP_Optimize_Cache_Commands_Premium();
751 - } else {
752 - $cache_commands = new WP_Optimize_Cache_Commands();
753 - }
754 -
755 - // check if called command not in main commands class and exist in cache commands class then change class.
756 - if (!is_callable(array($commands, $subaction)) && is_callable(array($minify_commands, $subaction))) {
757 - $commands = $minify_commands;
758 - }
759 -
760 - // check if called command not in main commands class and exist in cache commands class then change class.
761 - if (!is_callable(array($commands, $subaction)) && is_callable(array($cache_commands, $subaction))) {
762 - $commands = $cache_commands;
763 - }
764 -
765 - if (!is_callable(array($commands, $subaction))) {
766 - error_log("WP-Optimize: ajax_handler: no such command (".$subaction.")");
767 - $results = array(
768 - 'result' => false,
769 - 'error_code' => 'command_not_found',
770 - 'error_message' => sprintf(__('The command "%s" was not found', 'wp-optimize'), $subaction)
771 - );
772 - } else {
773 - $results = call_user_func(array($commands, $subaction), $data);
774 -
775 - // clean status box content, it broke json sometimes.
776 - if (isset($results['status_box_contents'])) {
777 - $results['status_box_contents'] = str_replace(array("\n", "\t"), '', $results['status_box_contents']);
778 - }
779 -
780 - if (is_wp_error($results)) {
781 - $results = array(
782 - 'result' => false,
783 - 'error_code' => $results->get_error_code(),
784 - 'error_message' => $results->get_error_message(),
785 - 'error_data' => $results->get_error_data(),
786 - );
787 - }
788 -
789 - // if nothing was returned for some reason, set as result null.
790 - if (empty($results)) {
791 - $results = array(
792 - 'result' => null
793 - );
794 - }
795 - }
796 - }
797 -
798 - $result = json_encode($results);
799 -
800 - // Requires PHP 5.3+
801 - $json_last_error = function_exists('json_last_error') ? json_last_error() : false;
802 -
803 - // if json_encode returned error then return error.
804 - if ($json_last_error) {
805 - $result = array(
806 - 'result' => false,
807 - 'error_code' => $json_last_error,
808 - 'error_message' => 'json_encode error : '.$json_last_error,
809 - 'error_data' => '',
810 - );
811 -
812 - $result = json_encode($result);
813 - }
814 -
815 - echo $result;
816 -
817 - die;
818 952 }
819 953
820 954 /**
821 - * Builds the Tabs that should be displayed
955 + * Checks whether the WP Smush plugin is active or not
822 956 *
823 - * @return array Returns all tabs specified
957 + * @return bool
824 958 */
825 - public function get_tabs($page) {
826 - // define tabs for pages.
827 - $pages_tabs = array(
828 - 'WP-Optimize' => array(
829 - 'optimize' => __('Optimizations', 'wp-optimize'),
830 - 'tables' => __('Tables', 'wp-optimize'),
831 - 'settings' => __('Settings', 'wp-optimize'),
832 - ),
833 - 'wpo_images' => array(
834 - 'smush' => __('Compress images', 'wp-optimize'),
835 - 'unused' => __('Unused images and sizes', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
836 - 'lazyload' => __('Lazy-load', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
837 - ),
838 - 'wpo_cache' => array(
839 - 'cache' => __('Page cache', 'wp-optimize'),
840 - 'preload' => __('Preload', 'wp-optimize'),
841 - 'advanced' => __('Advanced settings', 'wp-optimize'),
842 - 'gzip' => __('Gzip compression', 'wp-optimize'),
843 - 'settings' => __('Static file headers', 'wp-optimize') // Adds a settings tab
844 - ),
845 - 'wpo_minify' => array(
846 - "status" => __('Minify status', 'wp-optimize'),
847 - "js" => __('JavaScript', 'wp-optimize').'<span class="menu-pill disabled hidden">'.__('Disabled', 'wp-optimize').'</span>',
848 - "css" => __('CSS', 'wp-optimize').'<span class="menu-pill disabled hidden">'.__('Disabled', 'wp-optimize').'</span>',
849 - "font" => __('Fonts', 'wp-optimize'),
850 - "preload" => __('Preload', 'wp-optimize'),
851 - "settings" => __('Settings', 'wp-optimize'),
852 - "advanced" => __('Advanced', 'wp-optimize')
853 - ),
854 - 'wpo_settings' => array(
855 - 'settings' => array(
856 - 'title' => __('Settings', 'wp-optimize'),
857 - ),
858 - ),
859 - 'wpo_support' => array('support' => __('Support / FAQs', 'wp-optimize')),
860 - 'wpo_mayalso' => array('may_also' => __('Premium / Plugin family', 'wp-optimize')),
861 - );
862 -
863 - $tabs = (array_key_exists($page, $pages_tabs)) ? $pages_tabs[$page] : array();
864 -
865 - return apply_filters('wp_optimize_admin_page_'.$page.'_tabs', $tabs);
959 + private function is_wp_smush_installed() {
960 + return is_plugin_active('wp-smushit/wp-smush.php');
866 961 }
867 962
868 963 /**
869 - * Main page structure.
964 + * Remove WPO plugin name from WP Smushit transient value
965 + *
966 + * @return array $active_plugins
870 967 */
871 - public function display_admin() {
872 - $capability_required = $this->capability_required();
968 + public function modify_wp_smush_conflict_check($active_plugins) {
969 + // This can be boolean value since it is return value of get_transient
970 + if (!is_array($active_plugins)) return $active_plugins;
873 971
874 - if (!current_user_can($capability_required) || (!$this->can_run_optimizations() && !$this->can_manage_options())) {
875 - echo "Permission denied.";
876 - return;
972 + if (false !== ($key = array_search('WP-Optimize - Clean, Compress, Cache', $active_plugins))) {
973 + unset($active_plugins[$key]);
877 974 }
878 -
879 - $this->register_admin_content();
880 -
881 - echo '<div id="wp-optimize-wrap">';
882 -
883 - $this->include_template('admin-page-header.php', false, array('show_notices' => !($this->get_install_or_update_notice()->show_current_notice())));
884 -
885 - do_action('wpo_admin_after_header');
886 -
887 - echo '<div id="actions-results-area"></div>';
888 -
889 - $pages = $this->get_submenu_items();
890 -
891 - foreach ($pages as $page) {
892 - if (isset($page['menu_slug'])) {
893 - $this->display_admin_page($page['menu_slug']);
894 - }
895 - }
896 -
897 - do_action('wpo_admin_before_closing_wrap');
898 -
899 - // closes main plugin wrapper div. #wp-optimize-wrap
900 - echo '</div><!-- END #wp-optimize-wrap -->';
901 -
975 + return $active_plugins;
902 976 }
903 977
904 978 /**
905 - * Prepare and display admin page with $page id.
979 + * Get the installation or update notice instance
906 980 *
907 - * @param string $page wp-optimize page id i.e. dashboard, database, images, cache, ...
981 + * @return WP_Optimize_Install_Or_Update_Notice
908 982 */
909 - public function display_admin_page($page) {
910 -
911 - $active_page = !empty($_REQUEST['page']) ? $_REQUEST['page'] : '';
912 -
913 - echo '<div class="wpo-page' . ($active_page == $page ? ' active' : '') . '" data-whichpage="'.$page.'">';
914 -
915 - echo '<div class="wpo-main">';
916 -
917 - // get defined tabs for $page.
918 - $tabs = $this->get_tabs($page);
919 -
920 - // if no tabs defined for $page then use $page as $active_tab for load template, doing related actions e t.c.
921 - if (empty($tabs)) {
922 - $active_tab = $page;
923 - } else {
924 - $tab_keys = array_keys($tabs);
925 - $default_tab = apply_filters('wp_optimize_admin_'.$page.'_default_tab', $tab_keys[0]);
926 - $active_tab = isset($_GET['tab']) ? substr($_GET['tab'], 12) : $default_tab;
927 - if (!in_array($active_tab, array_keys($tabs))) $active_tab = $default_tab;
928 - }
929 -
930 - do_action('wp_optimize_admin_page_'.$page, $active_tab);
931 -
932 - // if tabs defined then display
933 - if (!empty($tabs)) {
934 - $this->include_template('admin-page-header-tabs.php', false, array('page' => $page, 'active_tab' => $active_tab, 'tabs' => $tabs, 'wpo_is_premium' => self::is_premium()));
935 - }
936 -
937 - foreach ($tabs as $tab_id => $tab_description) {
938 - // output wrap div for tab with id #wp-optimize-nav-tab-contents-'.$page.'-'.$tab_id
939 - echo '<div class="wp-optimize-nav-tab-contents" id="wp-optimize-nav-tab-'.$page.'-'.$tab_id.'-contents" '.(($tab_id == $active_tab) ? '' : 'style="display:none;"').'>';
940 -
941 - echo '<div class="postbox wpo-tab-postbox">';
942 - // call action for generate tab content.
943 -
944 - do_action('wp_optimize_admin_page_'.$page.'_'.$tab_id);
945 -
946 - // closes postbox.
947 - echo '</div><!-- END .postbox -->';
948 - // closes tab wrapper.
949 - echo '</div><!-- END .wp-optimize-nav-tab-contents -->';
950 - }
951 -
952 - echo '</div><!-- END .wpo-main -->';
953 -
954 - do_action('wp_optimize_admin_after_page_'.$page, $active_tab);
955 -
956 - echo '</div><!-- END .wpo-page -->';
957 -
983 + public function get_install_or_update_notice() {
984 + static $instance = null;
985 + if (is_a($instance, 'WP_Optimize_Install_Or_Update_Notice')) return $instance;
986 + $instance = new WP_Optimize_Install_Or_Update_Notice();
987 + return $instance;
958 988 }
959 989
960 990 /**
961 - * Define required actions for admin pages.
991 + * Display an admin notice for an upgraded version.
962 992 */
963 - public function register_admin_content() {
964 -
965 - do_action('wp_optimize_register_admin_content');
966 -
967 - /**
968 - * SETTINGS
969 - */
970 - add_action('wp_optimize_admin_page_wpo_settings_settings', array($this, 'output_dashboard_settings_tab'), 20);
971 -
972 - /**
973 - * Premium / other plugins
974 - */
975 - add_action('wp_optimize_admin_page_wpo_mayalso_may_also', array($this, 'output_dashboard_other_plugins_tab'), 20);
976 -
977 - /**
978 - * DATABASE
979 - */
980 - add_action('wp_optimize_admin_page_WP-Optimize_optimize', array($this, 'output_database_optimize_tab'), 20);
981 - add_action('wp_optimize_admin_page_WP-Optimize_tables', array($this, 'output_database_tables_tab'), 20);
982 - add_action('wp_optimize_admin_page_WP-Optimize_settings', array($this, 'output_database_settings_tab'), 20);
983 -
984 - /**
985 - * CACHE
986 - */
987 - add_action('wp_optimize_admin_page_wpo_cache_cache', array($this, 'output_page_cache_tab'), 20);
988 - if (!$this->does_server_handles_cache()) {
989 - add_action('wp_optimize_admin_page_wpo_cache_preload', array($this, 'output_page_cache_preload_tab'), 20);
990 - add_action('wp_optimize_admin_page_wpo_cache_advanced', array($this, 'output_page_cache_advanced_tab'), 20);
991 - }
992 - add_action('wp_optimize_admin_page_wpo_cache_gzip', array($this, 'output_cache_gzip_tab'), 20);
993 - add_action('wp_optimize_admin_page_wpo_cache_settings', array($this, 'output_cache_settings_tab'), 20);
994 - add_action('wpo_page_cache_advanced_settings', array($this, 'output_cloudflare_settings'), 20);
995 - /**
996 - * SUPPORT
997 - */
998 - add_action('wp_optimize_admin_page_wpo_support_support', array($this, 'output_dashboard_support_tab'), 20);
999 - // Display Support page.
1000 -
1001 - if (!self::is_premium()) {
1002 - /**
1003 - * Add action for display Images > Unused images and sizes tab.
1004 - */
1005 - add_action('wp_optimize_admin_page_wpo_images_unused', array($this, 'admin_page_wpo_images_unused'));
1006 -
1007 - /**
1008 - * Add action for display Dashboard > Lazyload tab.
1009 - */
1010 - add_action('wp_optimize_admin_page_wpo_images_lazyload', array($this, 'admin_page_wpo_images_lazyload'));
1011 - } else {
1012 - /**
1013 - * Add filter for display footer review message and link.
1014 - */
1015 - add_filter('admin_footer_text', array($this, 'display_footer_review_message'));
1016 - }
1017 - }
1018 -
1019 - /**
1020 - * Database settings
1021 - */
1022 - public function output_database_settings_tab() {
1023 -
1024 - if ($this->can_manage_options()) {
1025 - $this->include_template('database/settings.php');
1026 - } else {
1027 - $this->prevent_manage_options_info();
1028 - }
1029 - }
1030 -
1031 - /**
1032 - * Dashboard settings
1033 - */
1034 - public function output_dashboard_settings_tab() {
1035 - $options = $this->get_options();
1036 -
1037 - if ('POST' == $_SERVER['REQUEST_METHOD']) {
1038 - // Nonce check.
1039 - check_admin_referer('wpo_settings');
1040 -
1041 - $output = $options->save_settings($_POST);
1042 -
1043 - if (isset($_POST['wp-optimize-settings'])) {
1044 - // save settings request sent.
1045 - $output = $options->save_settings($_POST);
1046 - }
1047 -
1048 - $this->wpo_render_output_messages($output);
1049 - }
1050 -
1051 - if ($this->can_manage_options()) {
1052 - $this->include_template('settings/settings.php');
1053 - } else {
1054 - $this->prevent_manage_options_info();
1055 - }
1056 - }
1057 -
1058 - /**
1059 - * Dashboard support tab
1060 - */
1061 - public function output_dashboard_support_tab() {
1062 - WP_Optimize()->include_template('settings/support-and-faqs.php');
1063 - }
1064 -
1065 - /**
1066 - * Dashboard Other plugins / premium tab
1067 - */
1068 - public function output_dashboard_other_plugins_tab() {
1069 - $this->include_template('settings/may-also-like.php');
1070 - }
1071 -
1072 - /**
1073 - * Cache tab
1074 - */
1075 - public function output_page_cache_tab() {
1076 - $wpo_cache = $this->get_page_cache();
1077 - $wpo_cache_options = $wpo_cache->config->get();
1078 - $display = $wpo_cache->is_enabled() ? "style='display:block'" : "style='display:none'";
1079 -
1080 - WP_Optimize()->include_template('cache/page-cache.php', false, array(
1081 - 'wpo_cache' => $wpo_cache,
1082 - 'active_cache_plugins' => WP_Optimize_Detect_Cache_Plugins::instance()->get_active_cache_plugins(),
1083 - 'wpo_cache_options' => $wpo_cache_options,
1084 - 'cache_size' => $this->get_page_cache()->get_cache_size(),
1085 - 'display' => $display,
1086 - 'can_purge_the_cache' => $this->can_purge_the_cache(),
1087 - 'does_server_handles_cache' => $this->does_server_handles_cache(),
993 + public function show_admin_notice_upgraded() {
994 + $this->include_template('notices/thanks-for-using-main-dash.php', false, array(
995 + 'is_premium' => WP_Optimize::is_premium()
1088 996 ));
1089 997 }
1090 998
1091 999 /**
1092 - * Preload tab
1000 + * Returns required capability string
1001 + *
1002 + * @return string
1093 1003 */
1094 - public function output_page_cache_preload_tab() {
1095 - $wpo_cache = $this->get_page_cache();
1096 - $wpo_cache_options = $wpo_cache->config->get();
1097 - $wpo_cache_preloader = WP_Optimize_Page_Cache_Preloader::instance();
1098 - $is_running = $wpo_cache_preloader->is_running();
1099 - $status = $wpo_cache_preloader->get_status_info();
1004 + public function capability_required() {
1005 + $capability = is_multisite() ? 'manage_network_options' : 'manage_options';
1100 1006
1101 - WP_Optimize()->include_template('cache/page-cache-preload.php', false, array(
1102 - 'wpo_cache_options' => $wpo_cache_options,
1103 - 'is_running' => $is_running,
1104 - 'status_message' => isset($status['message']) ? $status['message'] : '',
1105 - 'schedule_options' => array(
1106 - 'wpo_use_cache_lifespan' => __('Same as cache lifespan', 'wp-optimize'),
1107 - 'wpo_daily' => __('Daily', 'wp-optimize'),
1108 - 'wpo_weekly' => __('Weekly', 'wp-optimize'),
1109 - 'wpo_fortnightly' => __('Fortnightly', 'wp-optimize'),
1110 - 'wpo_monthly' => __('Monthly (approx. - every 30 days)', 'wp-optimize')
1111 - )
1112 - ));
1113 - }
1007 + $filtered_capability = apply_filters('wp_optimize_capability_required', $capability);
1114 1008
1115 - /**
1116 - * Advanced tab
1117 - */
1118 - public function output_page_cache_advanced_tab() {
1119 - $wpo_cache = $this->get_page_cache();
1120 - $wpo_cache_options = $wpo_cache->config->get();
1121 -
1122 - $cache_exception_urls = is_array($wpo_cache_options['cache_exception_urls']) ? join("\n", $wpo_cache_options['cache_exception_urls']) : '';
1123 - $cache_exception_cookies = is_array($wpo_cache_options['cache_exception_cookies']) ? join("\n", $wpo_cache_options['cache_exception_cookies']) : '';
1124 - $cache_exception_browser_agents = is_array($wpo_cache_options['cache_exception_browser_agents']) ? join("\n", $wpo_cache_options['cache_exception_browser_agents']) : '';
1125 -
1126 - WP_Optimize()->include_template('cache/page-cache-advanced.php', false, array(
1127 - 'wpo_cache' => $this->get_page_cache(),
1128 - 'wpo_cache_options' => $wpo_cache_options,
1129 - 'cache_exception_urls' => $cache_exception_urls,
1130 - 'cache_exception_cookies' => $cache_exception_cookies,
1131 - 'cache_exception_browser_agents' => $cache_exception_browser_agents,
1132 - ));
1009 + return is_string($filtered_capability) ? $filtered_capability : $capability;
1133 1010 }
1134 1011
1135 1012 /**
1136 - * Gzip tab
1137 - */
1138 - public function output_cache_gzip_tab() {
1139 - $wpo_gzip_compression = $this->get_gzip_compression();
1140 - $wpo_gzip_compression_enabled = $wpo_gzip_compression->is_gzip_compression_enabled(true);
1141 - $wpo_gzip_headers_information = $wpo_gzip_compression->get_headers_information();
1142 - $is_cloudflare_site = $this->is_cloudflare_site();
1143 - $is_gzip_compression_section_exists = $wpo_gzip_compression->is_gzip_compression_section_exists();
1144 - $wpo_gzip_compression_enabled_by_wpo = $is_gzip_compression_section_exists && $wpo_gzip_compression_enabled && !$is_cloudflare_site && !(is_array($wpo_gzip_headers_information) && 'brotli' == $wpo_gzip_headers_information['compression']);
1145 -
1146 - WP_Optimize()->include_template('cache/gzip-compression.php', false, array(
1147 - 'wpo_gzip_headers_information' => $wpo_gzip_headers_information,
1148 - 'wpo_gzip_compression_enabled' => $wpo_gzip_compression_enabled,
1149 - 'is_cloudflare_site' => $is_cloudflare_site,
1150 - 'wpo_gzip_compression_enabled_by_wpo' => $wpo_gzip_compression_enabled_by_wpo,
1151 - 'wpo_gzip_compression_settings_added' => $is_gzip_compression_section_exists,
1152 - 'info_link' => 'https://getwpo.com/gzip-compression-explained/',
1153 - 'faq_link' => 'https://getwpo.com/gzip-faq-link/',
1154 - 'class_name' => (!is_wp_error($wpo_gzip_compression_enabled) && $wpo_gzip_compression_enabled ? 'wpo-enabled' : 'wpo-disabled')
1155 - ));
1156 - }
1157 -
1158 - /**
1159 - * Cache tab
1160 - */
1161 - public function output_cache_settings_tab() {
1162 -
1163 - $wpo_browser_cache = $this->get_browser_cache();
1164 - $wpo_browser_cache_enabled = $wpo_browser_cache->is_enabled();
1165 -
1166 - WP_Optimize()->include_template('cache/browser-cache.php', false, array(
1167 - 'wpo_browser_cache_enabled' => $wpo_browser_cache_enabled,
1168 - 'is_cloudflare_site' => $this->is_cloudflare_site(),
1169 - 'wpo_browser_cache_settings_added' => $wpo_browser_cache->is_browser_cache_section_exists(),
1170 - 'class_name' => (true === $wpo_browser_cache_enabled ? 'wpo-enabled' : 'wpo-disabled'),
1171 - 'wpo_browser_cache_expire_days' => $this->get_options()->get_option('browser_cache_expire_days', '28'),
1172 - 'wpo_browser_cache_expire_hours' => $this->get_options()->get_option('browser_cache_expire_hours', '0'),
1173 - 'info_link' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching',
1174 - 'faq_link' => 'https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-ubuntu-16-04',
1175 - ));
1176 - }
1177 -
1178 - /**
1179 - * Check if is the current site handled with Cloudflare.
1013 + * Check if the current user has a given capability.
1014 + * If no capability is provided, it checks for the default capability required to access WP-Optimize.
1180 1015 *
1016 + * @param string|null $capability The capability to check. Null = use default.
1181 1017 * @return bool
1182 1018 */
1183 - public function is_cloudflare_site() {
1184 - return isset($_SERVER['HTTP_CF_RAY']);
1185 - }
1186 -
1187 - /**
1188 - * Include Cloudflare settings template.
1189 - */
1190 - public function output_cloudflare_settings() {
1191 - if (self::is_premium() || !apply_filters('show_cloudflare_settings', $this->is_cloudflare_site())) return;
1192 -
1193 - WP_Optimize()->include_template('cache/page-cache-cloudflare-placeholder.php');
1194 - }
1195 -
1196 - /**
1197 - * Outputs the DB optimize Tab
1198 - */
1199 - public function output_database_optimize_tab() {
1200 - $optimizer = $this->get_optimizer();
1201 - $options = $this->get_options();
1202 -
1203 - // check if nonce passed.
1204 - $nonce_passed = (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'wpo_optimization')) ? true : false;
1205 -
1206 - // save options.
1207 - if ($nonce_passed && isset($_POST['wp-optimize'])) $options->save_sent_manual_run_optimization_options($_POST, true);
1208 -
1209 - $optimize_db = ($nonce_passed && isset($_POST["optimize-db"])) ? true : false;
1210 -
1211 - $optimization_results = (($nonce_passed) ? $optimizer->do_optimizations($_POST) : false);
1212 -
1213 - // display optimizations table or restricted access message.
1214 - if ($this->can_run_optimizations()) {
1215 - $this->include_template('database/optimize-table.php', false, array('optimize_db' => $optimize_db, 'optimization_results' => $optimization_results, 'load_data' => false, 'does_server_allows_table_optimization' => $this->does_server_allows_table_optimization()));
1216 - } else {
1217 - $this->prevent_run_optimizations_message();
1019 + public function current_user_can($capability = null) {
1020 + if (null === $capability) {
1021 + $capability = $this->capability_required(); // falls back to default
1218 1022 }
1219 - }
1220 1023
1221 - /**
1222 - * Outputs the DB Tables Tab
1223 - */
1224 - public function output_database_tables_tab() {
1225 - // check if nonce passed.
1226 - $nonce_passed = (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'wpo_optimization')) ? true : false;
1227 -
1228 - $optimize_db = ($nonce_passed && isset($_POST["optimize-db"])) ? true : false;
1229 -
1230 - if (!$this->does_server_allows_table_optimization()) {
1231 - $message = __('Your server takes care of table optimization', 'wp-optimize');
1232 - $this->prevent_run_optimizations_message($message);
1233 - } elseif ($this->can_run_optimizations()) {
1234 - $this->include_template('database/tables.php', false, array('optimize_db' => $optimize_db, 'load_data' => WP_Optimize()->template_should_include_data()));
1235 - } else {
1236 - $this->prevent_run_optimizations_message();
1024 + if (current_user_can($capability)) {
1025 + return true;
1237 1026 }
1238 - }
1239 1027
1240 - /**
1241 - * Runs upon the WP action admin_page_wpo_images_unused
1242 - */
1243 - public function admin_page_wpo_images_unused() {
1244 - WP_Optimize()->include_template('images/unused.php');
1028 + return false;
1245 1029 }
1246 1030
1247 1031 /**
1248 - * Runs upon the WP action wp_optimize_admin_page_wpo_images_lazyload
1249 - */
1250 - public function admin_page_wpo_images_lazyload() {
1251 - WP_Optimize()->include_template('images/lazyload.php');
1252 - }
1253 -
1254 - /**
1255 - * Show footer review message and link.
1256 - *
1257 - * @return string
1258 - */
1259 - public function display_footer_review_message() {
1260 - $message = sprintf(
1261 - __('Enjoyed %s? Please leave us a %s rating. We really appreciate your support!', 'wp-optimize'),
1262 - '<b>WP-Optimize</b>',
1263 - '<a href="https://www.g2.com/products/wp-optimize/reviews" target="_blank">&starf;&starf;&starf;&starf;&starf;</a>'
1264 - );
1265 - return $message;
1266 - }
1267 -
1268 - /**
1269 1032 * Returns array of translations used in javascript code.
1270 1033 *
1271 1034 * @return array
1272 1035 */
1273 1036 public function wpo_js_translations() {
1274 - return apply_filters('wpo_js_translations', array(
1037 + $log_message = __('For more details, please check your logs configured in logging destinations settings.', 'wp-optimize');
1038 + $translations = array(
1275 1039 'automatic_backup_before_optimizations' => __('Automatic backup before optimizations', 'wp-optimize'),
1276 1040 'error_unexpected_response' => __('An unexpected response was received.', 'wp-optimize'),
1277 1041 'optimization_complete' => __('Optimization complete', 'wp-optimize'),
1278 1042 'with_warnings' => __('(with warnings - open the browser console for more details)', 'wp-optimize'),
@@ -1278,8 +1042,9 @@
1278 1042 'with_warnings' => __('(with warnings - open the browser console for more details)', 'wp-optimize'),
1279 1043 'optimizing_table' => __('Optimizing table:', 'wp-optimize'),
1280 1044 'run_optimizations' => __('Run optimizations', 'wp-optimize'),
1281 1045 'table_optimization_timeout' => 120000,
1046 + 'add' => __('Add', 'wp-optimize'),
1282 1047 'cancel' => __('Cancel', 'wp-optimize'),
1283 1048 'cancelling' => __('Cancelling...', 'wp-optimize'),
1284 1049 'enable' => __('Enable', 'wp-optimize'),
1285 1050 'disable' => __('Disable', 'wp-optimize'),
@@ -1285,11 +1050,14 @@
1285 1050 'disable' => __('Disable', 'wp-optimize'),
1286 1051 'please_select_settings_file' => __('Please, select settings file.', 'wp-optimize'),
1287 1052 'are_you_sure_you_want_to_remove_logging_destination' => __('Are you sure you want to remove this logging destination?', 'wp-optimize'),
1288 1053 'fill_all_settings_fields' => __('Before saving, you need to complete the currently incomplete settings (or remove them).', 'wp-optimize'),
1289 - 'table_was_not_repaired' => __('%s was not repaired. For more details, please check the logs (configured in your logging destinations settings).', 'wp-optimize'),
1290 - 'table_was_not_deleted' => __('%s was not deleted. For more details, please check your logs configured in logging destinations settings.', 'wp-optimize'),
1291 - 'table_was_not_converted' => __('%s was not converted to InnoDB. For more details, please check your logs configured in logging destinations settings.', 'wp-optimize'),
1054 + // translators: %s is the table name
1055 + 'table_was_not_repaired' => __('%s was not repaired.', 'wp-optimize') . ' ' . $log_message,
1056 + // translators: %s is the table name
1057 + 'table_was_not_deleted' => __('%s was not deleted.', 'wp-optimize') . ' ' . $log_message,
1058 + // translators: %s is the table name
1059 + 'table_was_not_converted' => __('%s was not converted to InnoDB.', 'wp-optimize') . ' ' . $log_message,
1292 1060 'please_use_positive_integers' => __('Please use positive integers.', 'wp-optimize'),
1293 1061 'please_use_valid_values' => __('Please use valid values.', 'wp-optimize'),
1294 1062 'update' => __('Update', 'wp-optimize'),
1295 1063 'run_now' => __('Run now', 'wp-optimize'),
@@ -1297,129 +1065,87 @@
1297 1065 'loading_urls' => __('Loading URLs...', 'wp-optimize'),
1298 1066 'current_cache_size' => __('Current cache size:', 'wp-optimize'),
1299 1067 'number_of_files' => __('Number of files:', 'wp-optimize'),
1300 1068 'toggle_info' => __('Show information', 'wp-optimize'),
1069 + 'delete_file' => __('Delete', 'wp-optimize'),
1070 + 'deleting' => __('Deleting...', 'wp-optimize'),
1301 1071 'added_to_list' => __('Added to the list', 'wp-optimize'),
1302 1072 'added_notice' => __('The file was added to the list', 'wp-optimize'),
1303 1073 'save_notice' => __('Save the changes', 'wp-optimize'),
1074 + 'saving' => __('Saving...', 'wp-optimize'),
1075 + 'clearing_cache' => __('Clearing cache...', 'wp-optimize'),
1076 + 'creating_cache' => __('Creating cache...', 'wp-optimize'),
1304 1077 'page_refresh' => __('Refreshing the page to reflect changes...', 'wp-optimize'),
1078 + 'cache_file_not_found' => __('Cache file was not found.', 'wp-optimize'),
1305 1079 'settings_have_been_deleted_successfully' => __('WP-Optimize settings have been deleted successfully.', 'wp-optimize'),
1306 1080 'loading_data' => __('Loading data...', 'wp-optimize'),
1307 - 'spinner_src' => esc_attr(admin_url('images/spinner-2x.gif')),
1081 + 'spinner_src' => esc_url(admin_url('images/spinner-2x.gif')),
1082 + 'logo_src' => esc_url(WPO_PLUGIN_URL.'images/notices/wp_optimize_logo.png'),
1308 1083 'settings_page_url' => is_multisite() ? network_admin_url('admin.php?page=wpo_settings') : admin_url('admin.php?page=wpo_settings'),
1309 1084 'sites' => $this->get_sites(),
1310 - 'user_always_ignores_table_delete_warning' => (get_user_meta(get_current_user_id(), 'wpo-ignores-table-delete-warning', true)) ? true : false,
1085 + 'user_always_ignores_table_deletion_warning' => (bool) get_user_meta(get_current_user_id(), 'wpo-ignores-table-deletion-warning', true),
1086 + 'user_always_ignores_post_meta_deletion_warning' => (bool) get_user_meta(get_current_user_id(), 'wpo-ignores-post-meta-deletion-warning', true),
1087 + 'user_always_ignores_orphaned_relationship_data_deletion_warning' => (bool) get_user_meta(get_current_user_id(), 'wpo-ignores-orphaned-relationship-data-deletion-warning', true),
1311 1088 'post_meta_tweak_completed' => __('The tweak has been performed.', 'wp-optimize'),
1312 1089 'no_minified_assets' => __('No minified files are present', 'wp-optimize'),
1313 - ));
1314 - }
1315 -
1316 - public function wpo_admin_bar() {
1317 - $wp_admin_bar = $GLOBALS['wp_admin_bar'];
1318 -
1319 - if (defined('WPOPTIMIZE_ADMINBAR_DISABLE') && WPOPTIMIZE_ADMINBAR_DISABLE) return;
1320 -
1321 - // Show menu item in top bar only for super admins.
1322 - if (is_multisite() & !is_super_admin(get_current_user_id())) return;
1323 -
1324 - // Add a link called at the top admin bar.
1325 - $args = array(
1326 - 'id' => 'wp-optimize-node',
1327 - 'title' => apply_filters('wpoptimize_admin_node_title', 'WP-Optimize')
1090 + 'network_site_url' => network_site_url(),
1091 + 'export_settings_file_name' => 'wpoptimize-settings-'.sanitize_title(get_bloginfo('name')).'.json',
1092 + 'import_select_file' => __('You have not yet selected a file to import.', 'wp-optimize'),
1093 + 'import_invalid_json_file' => __('Error: The chosen file is corrupt.', 'wp-optimize') . ' ' . __('Please choose a valid WP-Optimize export file.', 'wp-optimize'),
1094 + 'importing' => __('Importing...', 'wp-optimize'),
1095 + 'importing_data_from' => __('This will import data from:', 'wp-optimize'),
1096 + 'exported_on' => __('Which was exported on:', 'wp-optimize'),
1097 + 'continue_import' => __('Do you want to carry out the import?', 'wp-optimize'),
1098 + 'select_destination' => __('Select destination', 'wp-optimize'),
1099 + 'show' => __('Show', 'wp-optimize'),
1100 + 'hide' => __('Hide', 'wp-optimize'),
1101 + 'please_wait' => __('Please wait a moment...', 'wp-optimize'),
1102 + 'clipboard_failed' => __('Copy to clipboard failed, please do it manually', 'wp-optimize'),
1103 + 'clipboard_success' => __('System status has been copied to the clipboard', 'wp-optimize'),
1104 + 'high_table_count_threshold' => WP_Optimizer::HIGH_TABLE_COUNT_THRESHOLD,
1105 + // translators: 1: starting table count, 2: ending table count
1106 + 'loading_tables_in_batches' => esc_html__('Loading tables %1$s to %2$s', 'wp-optimize'),
1107 + // translators: %s time to finish
1108 + 'time_left' => esc_html__('Aproximate time to finish: %s', 'wp-optimize'),
1109 + 'done_reloading' => esc_html__('Done, reloading', 'wp-optimize'),
1110 + 'show_information' => __('Show information', 'wp-optimize'),
1111 + 'hide_information' => __('Hide information', 'wp-optimize'),
1112 + 'data_not_available' => __('Not available', 'wp-optimize'),
1113 + 'something_wrong_try_again' => __('Something went wrong; please try again.', 'wp-optimize'),
1114 + 'db_tables_scan_pending_list' => __('Your database tables need to be scanned before they can be listed.', 'wp-optimize'),
1115 + 'db_tables_scan_pending_optimize' => __('Your database tables need to be scanned before they can be optimized.', 'wp-optimize'),
1116 + 'db_tables_scan_button' => __('Scan tables', 'wp-optimize')
1328 1117 );
1329 - $wp_admin_bar->add_node($args);
1330 -
1331 - $pages = $this->get_submenu_items();
1332 -
1333 - foreach ($pages as $page_id => $page) {
1334 -
1335 - if (!isset($page['create_submenu']) || !$page['create_submenu']) {
1336 - if (isset($page['icon']) && 'separator' == $page['icon']) {
1337 - $args = array(
1338 - 'id' => 'wpo-separator-'.$page_id,
1339 - 'parent' => 'wp-optimize-node',
1340 - 'meta' => array(
1341 - 'class' => 'separator',
1342 - ),
1343 - );
1344 - $wp_admin_bar->add_node($args);
1345 - }
1346 - continue;
1347 - }
1348 -
1349 - // 'menu_slug' => 'WP-Optimize',
1350 -
1351 - $menu_page_url = menu_page_url($page['menu_slug'], false);
1352 -
1353 - if (is_multisite()) {
1354 - $menu_page_url = network_admin_url('admin.php?page='.$page['menu_slug']);
1355 - }
1356 -
1357 - $args = array(
1358 - 'id' => 'wpoptimize_admin_node_'.$page_id,
1359 - 'title' => $page['menu_title'],
1360 - 'parent' => 'wp-optimize-node',
1361 - 'href' => $menu_page_url,
1362 - );
1363 - $wp_admin_bar->add_node($args);
1364 - }
1365 -
1118 + $filtered_translations = apply_filters('wpo_js_translations', $translations);
1119 + return is_array($filtered_translations) ? $filtered_translations : $translations;
1366 1120 }
1367 1121
1368 1122 /**
1369 - * Manages the admin bar menu for caching (currently page and minify)
1370 - */
1371 - public function cache_admin_bar($wp_admin_bar) {
1372 -
1373 - $options = $this->get_options();
1374 - if (!$options->get_option('enable_cache_in_admin_bar', true)) return;
1375 -
1376 - /**
1377 - * The "purge cache" menu items
1378 - *
1379 - * @param array $menu_items - The menu items, in the format required by $wp_admin_bar->add_menu()
1380 - * @param object $wp_admin_bar
1381 - */
1382 - $menu_items = apply_filters('wpo_cache_admin_bar_menu_items', array(), $wp_admin_bar);
1383 -
1384 - if (empty($menu_items) || !is_array($menu_items)) return;
1385 -
1386 - $wp_admin_bar->add_menu(array(
1387 - 'id' => 'wpo_purge_cache',
1388 - 'title' => __('Purge cache', 'wp-optimize'),
1389 - 'href' => '#',
1390 - 'meta' => array(
1391 - 'title' => __('Purge cache', 'wp-optimize'),
1392 - ),
1393 - 'parent' => false,
1394 - ));
1395 -
1396 - foreach ($menu_items as $item) {
1397 - $wp_admin_bar->add_menu($item);
1398 - }
1399 - }
1400 -
1401 - /**
1402 1123 * Add settings link on plugin page
1403 1124 *
1404 - * @param string $links Passing through the URL to be used within the HREF.
1405 - * @return string Returns the Links.
1125 + * @param array $links Passing through the URL to be used within the HREF.
1126 + * @return array Returns the Links.
1406 1127 */
1407 1128 public function plugin_settings_link($links) {
1408 1129
1409 1130 $admin_page_url = $this->get_options()->admin_page_url();
1410 1131 $settings_page_url = $this->get_options()->admin_page_url('wpo_settings');
1132 + $database_page_url = $this->get_options()->admin_page_url('wpo_database');
1411 1133
1412 - if (false == self::is_premium()) {
1413 - $premium_link = '<a href="' . esc_url($this->premium_version_link) . '" target="_blank">' . __('Premium', 'wp-optimize') . '</a>';
1134 + if (!self::is_premium()) {
1135 + $premium_link = '<a href="' . esc_url($this->premium_version_link) . '&utm_content=plugin-page' . '" target="_blank">' . esc_html__('Premium', 'wp-optimize') . '</a>';
1414 1136 array_unshift($links, $premium_link);
1415 1137 }
1416 1138
1417 - $settings_link = '<a href="' . esc_url($settings_page_url) . '">' . __('Settings', 'wp-optimize') . '</a>';
1139 + $settings_link = '<a href="' . esc_url($settings_page_url) . '">' . esc_html__('Settings', 'wp-optimize') . '</a>';
1418 1140 array_unshift($links, $settings_link);
1419 1141
1420 - $optimize_link = '<a href="' . esc_url($admin_page_url) . '">' . __('Optimize', 'wp-optimize') . '</a>';
1142 + $optimize_link = '<a href="' . esc_url($database_page_url) . '">' . esc_html__('Optimize', 'wp-optimize') . '</a>';
1421 1143 array_unshift($links, $optimize_link);
1144 +
1145 + $dashboard_link = '<a href="' . esc_url($admin_page_url) . '">' . esc_html__('Overview', 'wp-optimize') . '</a>';
1146 + array_unshift($links, $dashboard_link);
1147 +
1422 1148 return $links;
1423 1149 }
1424 1150
1425 1151 /**
@@ -1433,9 +1159,9 @@
1433 1159 public function tables_list_additional_column_data($content, $table_info) {
1434 1160 if ($table_info->is_needing_repair) {
1435 1161 $content .= '<div class="wpo_button_wrap">'
1436 1162 . '<button class="button button-secondary run-single-table-repair" data-table="' . esc_attr($table_info->Name) . '">' . __('Repair', 'wp-optimize') . '</button>'
1437 - . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1163 + . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">' // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- N/A
1438 1164 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1439 1165 . '</div>';
1440 1166 }
1441 1167
@@ -1442,18 +1168,18 @@
1442 1168 // table belongs to plugin.
1443 1169 if ($table_info->can_be_removed) {
1444 1170 $content .= '<div>'
1445 1171 . '<button class="button button-secondary run-single-table-delete" data-table="' . esc_attr($table_info->Name) . '">' . __('Remove', 'wp-optimize') . '</button>'
1446 - . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1172 + . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">' // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- N/A
1447 1173 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1448 1174 . '</div>';
1449 1175 }
1450 1176
1451 1177 // Add option for MyISAM to InnoDB conversion.
1452 - if ('MyISAM' == $table_info->Engine) {
1178 + if ('MyISAM' === $table_info->Engine) {
1453 1179 $content .= '<div class="wpo_button_convert wpo_button_wrap">'
1454 1180 . '<button class="button button-secondary toinnodb" data-table="' . esc_attr($table_info->Name) . '">' . __('Convert to InnoDB', 'wp-optimize') . '</button>'
1455 - . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1181 + . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">' // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- N/A
1456 1182 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1457 1183 . '</div>';
1458 1184
1459 1185 }
@@ -1463,15 +1189,26 @@
1463 1189
1464 1190 /**
1465 1191 * Initialize WP-Optimize page cache.
1466 1192 */
1467 - public function init_page_cache() {
1193 + private function init_page_cache() {
1468 1194 if ($this->get_page_cache()->config->get_option('enable_page_caching', false)) {
1469 - $this->get_page_cache()->enable();
1195 + if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
1196 + $this->_cache_init_status = $this->get_page_cache()->enable();
1197 + }
1470 1198 }
1471 1199 }
1472 1200
1473 1201 /**
1202 + * Get init_page_cache() status.
1203 + *
1204 + * @return bool|WP_Error
1205 + */
1206 + public function get_init_page_cache_status() {
1207 + return $this->_cache_init_status;
1208 + }
1209 +
1210 + /**
1474 1211 * Schedules cron event based on selected schedule type
1475 1212 *
1476 1213 * @return void
1477 1214 */
@@ -1479,17 +1216,17 @@
1479 1216 $gmt_offset = (int) (3600 * get_option('gmt_offset'));
1480 1217
1481 1218 $options = $this->get_options();
1482 1219
1483 - if ($options->get_option('schedule') === false) {
1220 + if (false === $options->get_option('schedule')) {
1484 1221 $options->set_default_options();
1485 1222 } else {
1486 - if ('true' == $options->get_option('schedule')) {
1223 + if ('true' === $options->get_option('schedule')) {
1487 1224 if (!wp_next_scheduled('wpo_cron_event2')) {
1488 1225 $schedule_type = $options->get_option('schedule-type', 'wpo_weekly');
1489 1226
1490 1227 // Backward compatibility
1491 - if ('wpo_otherweekly' == $schedule_type) $schedule_type = 'wpo_fortnightly';
1228 + if ('wpo_otherweekly' === $schedule_type) $schedule_type = 'wpo_fortnightly';
1492 1229
1493 1230 $this_time = (86400 * 7);
1494 1231
1495 1232 switch ($schedule_type) {
@@ -1510,10 +1247,17 @@
1510 1247 break;
1511 1248 }
1512 1249
1513 1250 add_action('wpo_cron_event2', array($this, 'cron_action'));
1514 - wp_schedule_event((current_time("timestamp", 0) + $this_time - $gmt_offset), $schedule_type, 'wpo_cron_event2');
1515 - WP_Optimize()->log('running wp_schedule_event()');
1251 + $result = wp_schedule_event((current_time("timestamp", 0) + $this_time - $gmt_offset), $schedule_type, 'wpo_cron_event2');
1252 + $this->log('running wp_schedule_event()');
1253 + if (is_wp_error($result)) {
1254 + $error_msg = $result->get_error_message();
1255 + $this->log($error_msg);
1256 + $this->log(print_r($result, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- Using for debugging purpose, logged into separate file
1257 + } else {
1258 + $this->log($result);
1259 + }
1516 1260 }
1517 1261 }
1518 1262 }
1519 1263 }
@@ -1518,13 +1262,31 @@
1518 1262 }
1519 1263 }
1520 1264
1521 1265 /**
1522 - * Clears all cron events
1266 + * Unschedules WP-Optimize cron events on deactivation.
1523 1267 *
1524 1268 * @return void
1525 1269 */
1526 1270 public function wpo_cron_deactivate() {
1271 + if (is_multisite()) {
1272 + $sites = $this->get_sites();
1273 + foreach ($sites as $site) {
1274 + switch_to_blog($site->blog_id);
1275 + $this->unschedule_wpo_cron_jobs();
1276 + restore_current_blog();
1277 + }
1278 + } else {
1279 + $this->unschedule_wpo_cron_jobs();
1280 + }
1281 + }
1282 +
1283 + /**
1284 + * Unschedules all WP-Optimize cron jobs on the current site.
1285 + *
1286 + * @return void
1287 + */
1288 + private function unschedule_wpo_cron_jobs() {
1527 1289 $cron_jobs = _get_cron_array();
1528 1290 foreach ($cron_jobs as $job) {
1529 1291 foreach (array_keys($job) as $hook) {
1530 1292 if (preg_match('/^wpo_/', $hook)) wp_unschedule_hook($hook);
@@ -1570,8 +1332,12 @@
1570 1332 /**
1571 1333 * Run updates on plugin activation.
1572 1334 */
1573 1335 public function run_updates() {
1336 +
1337 + if (!defined('WPO_CACHE_FILES_DIR')) define('WPO_CACHE_FILES_DIR', untrailingslashit(WP_CONTENT_DIR).'/cache/wpo-cache');
1338 +
1339 + require_once(WPO_PLUGIN_MAIN_PATH . 'cache/file-based-page-cache-functions.php');
1574 1340 include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimize-updates.php');
1575 1341 WP_Optimize_Updates::check_updates();
1576 1342 }
1577 1343
@@ -1582,128 +1348,21 @@
1582 1348 * @return string
1583 1349 */
1584 1350 public function show_admin_warning_overdue_crons($howmany) {
1585 1351 $ret = '<div class="updated below-h2"><p>';
1586 - $ret .= '<strong>'.__('Warning', 'wp-optimize').':</strong> '.sprintf(__('WordPress has a number (%d) of scheduled tasks which are overdue. Unless this is a development site, this probably means that the scheduler in your WordPress install is not working.', 'wp-optimize'), $howmany).' <a href="'.apply_filters('wpoptimize_com_link', "https://getwpo.com/faqs/the-scheduler-in-my-wordpress-installation-is-not-working-what-should-i-do/").'">'.__('Read this page for a guide to possible causes and how to fix it.', 'wp-optimize').'</a>';
1352 + // translators: %d is number of overdue cron jobs
1353 + $ret .= '<strong>'.esc_html__('Warning', 'wp-optimize').':</strong> '.sprintf(esc_html__('WordPress has a number (%d) of scheduled tasks which are overdue.', 'wp-optimize'), $howmany).' '. esc_html__('Unless this is a development site, this probably means that the scheduler in your WordPress install is not working.', 'wp-optimize').' <a target="_blank" href="'.esc_url(apply_filters('wpoptimize_com_link', "https://teamupdraft.com/blog/the-scheduler-in-wordpress-is-not-working-what-should-i-do/")).'">'.esc_html__('Read this page for a guide to possible causes and how to fix it.', 'wp-optimize').'</a>';
1587 1354 $ret .= '</p></div>';
1588 1355 return $ret;
1589 1356 }
1590 1357
1591 - public function admin_menu() {
1592 -
1593 - $capability_required = $this->capability_required();
1594 -
1595 - if (!current_user_can($capability_required) || (!$this->can_run_optimizations() && !$this->can_manage_options())) return;
1596 -
1597 - $icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmlld0JveD0iMCAwIDE2IDE2IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc0MzE2IgogICBoZWlnaHQ9IjE2IgogICB3aWR0aD0iMTYiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnM0MzE4IiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTQzMjEiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaWQ9ImxheWVyMSI+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2EwYTVhYTtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlkPSJwYXRoNTciCiAgICAgICBkPSJtIDEwLjc2ODgwOSw2Ljc2MTYwNTEgMCwwIGMgLTAuMDE2ODgsLTAuMDE2ODc4IC0wLjAyNTMxLC0wLjA0MjE4MSAtMC4wMzM3NCwtMC4wNjc0OTkgLTAuMDA4NCwtMC4wMDgzOSAtMC4wMDg0LC0wLjAxNjg3OCAtMC4wMTY4OCwtMC4wMzM3NDMgQyA5Ljk5MjYxMTIsNS4xOTIzMzY2IDguMjIwODU1Nyw0LjU4NDg3ODEgNi43NDQzOTEyLDUuMjkzNTc5NyA1LjY3MjkwMDUsNS44MDgyMzI4IDUuMDU3MDA0Myw2Ljg4ODE2MTMgNS4wNjU0NDIsOC4wMDE4MzY1IDQuNDU3OTgyMiw3LjMxMDAwNzYgMy42OTg2NTg0LDYuNzk1MzU0NSAyLjg1NDk2NDIsNi40OTE2MjUzIDMuMjY4Mzc0Myw1LjA2NTc4MzEgNC4yNTU0OTYsMy44MTcxMTY2IDUuNjg5Nzc0NiwzLjEyNTI4NzggOC4zNjQyODMyLDEuODM0NDM2OCAxMS41NzAzMTksMi45Mzk2NzQ0IDEyLjg4NjQ4MSw1LjU4ODg3MjYgMTMuNDUxNzU1LDYuNzI3ODU5NiAxNC42NDk4MDEsNy4zNTIxOTIxIDE1Ljg0Nzg0Niw3LjIzNDA3NSAxNS43NjM0ODIsNi4zMzk3NiAxNS41MTg4MDUsNS40MzcwMDg2IDE1LjEwNTM5Niw0LjU3NjQ0MDQgMTMuMjE1NTIxLDAuNjg3MDEzNCA4LjUzMzAyMjYsLTAuOTQxMzE2MjcgNC42NDM1OTQzLDAuOTQwMTIxNzkgMi4zMjM0MzcsMi4wNjIyMzM0IDAuODA0Nzg4MTQsNC4xNzk5MDQ0IDAuMzU3NjMxMzIsNi41MzM4MDk4IDIuNDE2MjQzOCw2LjQyNDEyOSA0LjQzMjY3MTcsNy41MDQwNTc0IDUuNDM2NjY2Miw5LjQzNjExNjcgbCAwLjAwODM5LDAgYyAwLjc1OTMxOTIsMS4zNzUyMjAzIDIuNDcyMDE3OCwxLjk0MDQ5NTMgMy45MDYyOTYsMS4yNDg2NjczIDEuMDQ2MTc5OCwtMC41MDYyMTggMS42NTM2NDA4LC0xLjUzNTUyMzggMS42Nzg5NTA4LC0yLjYxNTQ1MTIgMC41ODIxNDgsMC43MDg3MDE4IDEuMzMzMDM1LDEuMjQ4NjY2OCAyLjE1OTg1NiwxLjU3NzcwNjQgLTAuNDM4NzIxLDEuMzU4MzQ3OCAtMS40MDA1MzMsMi41NDc5NTQ4IC0yLjc5MjYyNywzLjIxNDQ3ODggLTIuNTkwMTM4NywxLjI0ODY1OCAtNS42NzgwNTc0LDAuMjUzMTA0IC03LjA2MTcxNTEsLTIuMjI3MzU3IGwgMCwwIEMgMi43NjIxMDQ4LDkuNDUyOTg5NCAxLjUxMzQzODMsOC44MjAyMTkxIDAuMjgxNjQ1OTIsOC45NzIwODQ0IDAuMzgyODg3NjUsOS43OTg5MDQ2IDAuNjE5MTIzMzEsMTAuNjE3Mjg3IDAuOTk4Nzg1MiwxMS40MDE5MjIgYyAxLjg4MTQzNjgsMy44OTc4NjQgNi41NjM5MzcsNS41MjYxOTggMTAuNDYxODAwOCwzLjY0NDc2IDIuMjQ0MjI2LC0xLjA4ODM2OSAzLjczNzU2MiwtMy4xMDQ3OTYgNC4yMzUzNDIsLTUuMzc0MzMyMyAtMS45OTk1NTQsMC4wNDIxODEgLTMuOTQ4NDg2LC0xLjAyOTMwNjMgLTQuOTI3MTcsLTIuOTEwNzQzMyB6IgogICAgICAgY2xhc3M9InN0MTciIC8+CiAgPC9nPgo8L3N2Zz4K';
1598 -
1599 - // Removes the admin menu items on the left WP bar.
1600 - if (!is_multisite() || (is_multisite() && is_network_admin())) {
1601 - add_menu_page("WP-Optimize", "WP-Optimize", $capability_required, "WP-Optimize", array($this, "display_admin"), $icon_svg);
1602 -
1603 - $sub_menu_items = $this->get_submenu_items();
1604 -
1605 - foreach ($sub_menu_items as $menu_item) {
1606 - if ($menu_item['create_submenu']) add_submenu_page('WP-Optimize', $menu_item['page_title'], $menu_item['menu_title'], $capability_required, $menu_item['menu_slug'], $menu_item['function']);
1607 - }
1608 - }
1609 -
1610 - $options = $this->get_options();
1611 -
1612 - if ($options->get_option('enable-admin-menu', 'false') == 'true') {
1613 - add_action('wp_before_admin_bar_render', array($this, 'wpo_admin_bar'));
1614 - }
1615 - }
1616 -
1617 1358 /**
1618 - * Get the submenu items
1359 + * Normalizes path string
1619 1360 *
1620 - * @return array
1361 + * @param string $path
1362 + *
1363 + * @return string
1621 1364 */
1622 - public function get_submenu_items() {
1623 - $sub_menu_items = array(
1624 - array(
1625 - 'page_title' => __('Database', 'wp-optimize'),
1626 - 'menu_title' => __('Database', 'wp-optimize'),
1627 - 'menu_slug' => 'WP-Optimize',
1628 - 'function' => array($this, 'display_admin'),
1629 - 'icon' => 'cloud',
1630 - 'create_submenu' => true,
1631 - 'order' => 20,
1632 - ),
1633 - array(
1634 - 'page_title' => __('Images', 'wp-optimize'),
1635 - 'menu_title' => __('Images', 'wp-optimize'),
1636 - 'menu_slug' => 'wpo_images',
1637 - 'function' => array($this, 'display_admin'),
1638 - 'icon' => 'images-alt2',
1639 - 'create_submenu' => true,
1640 - 'order' => 30,
1641 - ),
1642 - array(
1643 - 'page_title' => __('Cache', 'wp-optimize'),
1644 - 'menu_title' => __('Cache', 'wp-optimize'),
1645 - 'menu_slug' => 'wpo_cache',
1646 - 'function' => array($this, 'display_admin'),
1647 - 'icon' => 'archive',
1648 - 'create_submenu' => true,
1649 - 'order' => 40,
1650 - ),
1651 - array(
1652 - 'page_title' => __('Minify', 'wp-optimize'),
1653 - 'menu_title' => __('Minify', 'wp-optimize'),
1654 - 'menu_slug' => 'wpo_minify',
1655 - 'function' => array($this, 'display_admin'),
1656 - 'icon' => 'dashboard',
1657 - 'create_submenu' => true,
1658 - 'order' => 50,
1659 - ),
1660 - array(
1661 - 'create_submenu' => false,
1662 - 'order' => 55,
1663 - 'icon' => 'separator',
1664 - ),
1665 - array(
1666 - 'page_title' => __('Settings', 'wp-optimize'),
1667 - 'menu_title' => __('Settings', 'wp-optimize'),
1668 - 'menu_slug' => 'wpo_settings',
1669 - 'function' => array($this, 'display_admin'),
1670 - 'icon' => 'admin-settings',
1671 - 'create_submenu' => true,
1672 - 'order' => 60,
1673 - ),
1674 - array(
1675 - 'page_title' => __('Support & FAQs', 'wp-optimize'),
1676 - 'menu_title' => __('Help', 'wp-optimize'),
1677 - 'menu_slug' => 'wpo_support',
1678 - 'function' => array($this, 'display_admin'),
1679 - 'icon' => 'sos',
1680 - 'create_submenu' => true,
1681 - 'order' => 60,
1682 - ),
1683 - array(
1684 - 'page_title' => __('Premium Upgrade', 'wp-optimize'),
1685 - 'menu_title' => __('Premium Upgrade', 'wp-optimize'),
1686 - 'menu_slug' => 'wpo_mayalso',
1687 - 'function' => array($this, 'display_admin'),
1688 - 'icon' => 'admin-plugins',
1689 - 'create_submenu' => true,
1690 - 'order' => 70,
1691 - ),
1692 - );
1693 -
1694 - $sub_menu_items = apply_filters('wp_optimize_sub_menu_items', $sub_menu_items);
1695 -
1696 - usort($sub_menu_items, array($this, 'order_sort'));
1697 -
1698 - return $sub_menu_items;
1699 - }
1700 -
1701 - public function order_sort($a, $b) {
1702 - if ($a['order'] == $b['order']) return 0;
1703 - return ($a['order'] > $b['order']) ? 1 : -1;
1704 - }
1705 -
1706 1365 private function wp_normalize_path($path) {
1707 1366 // Wp_normalize_path is not present before WP 3.9.
1708 1367 if (function_exists('wp_normalize_path')) return wp_normalize_path($path);
1709 1368 // Taken from WP 4.6.
@@ -1714,24 +1373,38 @@
1714 1373 }
1715 1374 return $path;
1716 1375 }
1717 1376
1377 + /**
1378 + * Returns templates directory path
1379 + *
1380 + * @return string
1381 + */
1718 1382 public function get_templates_dir() {
1719 - return apply_filters('wp_optimize_templates_dir', $this->wp_normalize_path(WPO_PLUGIN_MAIN_PATH.'templates'));
1383 + $templates_dir = $this->wp_normalize_path(WPO_PLUGIN_MAIN_PATH.'templates');
1384 + $filtered_templates_dir = apply_filters('wp_optimize_templates_dir', $templates_dir);
1385 + return is_string($filtered_templates_dir) ? $filtered_templates_dir : $templates_dir;
1720 1386 }
1721 1387
1388 + /**
1389 + * Returns templates URL
1390 + *
1391 + * @return string
1392 + */
1722 1393 public function get_templates_url() {
1723 - return apply_filters('wp_optimize_templates_url', WPO_PLUGIN_URL.'/templates');
1394 + $templates_url = WPO_PLUGIN_URL . 'templates';
1395 + $filtered_templates_url = apply_filters('wp_optimize_templates_url', $templates_url);
1396 + return is_string($filtered_templates_url) ? $filtered_templates_url : $templates_url;
1724 1397 }
1725 1398
1726 1399 /**
1727 1400 * Return or output view content
1728 1401 *
1729 - * @param String $path - path to template, usually relative to templates/ within the WP-O directory
1730 - * @param Boolean $return_instead_of_echo - what to do with the results
1731 - * @param Array $extract_these - key/value pairs for substitution into the scope of the template
1402 + * @param string $path - path to template, usually relative to templates/ within the WP-O directory
1403 + * @param boolean $return_instead_of_echo - what to do with the results
1404 + * @param array $extract_these - key/value pairs for substitution into the scope of the template
1732 1405 *
1733 - * @return String|Void
1406 + * @return string|void
1734 1407 */
1735 1408 public function include_template($path, $return_instead_of_echo = false, $extract_these = array()) {
1736 1409 if ($return_instead_of_echo) ob_start();
1737 1410
@@ -1751,10 +1424,10 @@
1751 1424
1752 1425 do_action('wp_optimize_before_template', $path, $template_file, $return_instead_of_echo, $extract_these);
1753 1426
1754 1427 if (!file_exists($template_file)) {
1755 - error_log("WP Optimize: template not found: ".$template_file);
1756 - echo __('Error:', 'wp-optimize').' '.__('template not found', 'wp-optimize')." (".$path.")";
1428 + error_log("WP Optimize: template not found: ".$template_file); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Using for debugging purpose such as incomplete installation
1429 + echo esc_html__('Error:', 'wp-optimize').' '.esc_html__('template not found', 'wp-optimize')." (".esc_html($path).")";
1757 1430 } else {
1758 1431 extract($extract_these);
1759 1432 // The following are useful variables which can be used in the template.
1760 1433 // They appear as unused, but may be used in the $template_file.
@@ -1781,9 +1454,9 @@
1781 1454 $templates_dir = $this->get_templates_dir();
1782 1455
1783 1456 if ($dh = opendir($templates_dir)) {
1784 1457 while (($file = readdir($dh)) !== false) {
1785 - if ('.' == $file || '..' == $file) continue;
1458 + if ('.' === $file || '..' === $file) continue;
1786 1459 if (is_dir($templates_dir.'/'.$file)) {
1787 1460 $template_directories[$file] = $templates_dir.'/'.$file;
1788 1461 }
1789 1462 }
@@ -1813,9 +1486,9 @@
1813 1486 * Format Bytes Into KB/MB
1814 1487 *
1815 1488 * @param mixed $bytes Number of bytes to be converted.
1816 1489 * @param integer $decimals the number of decimal digits
1817 - * @return integer return the correct format size.
1490 + * @return string return the correct format size.
1818 1491 */
1819 1492 public function format_size($bytes, $decimals = 2) {
1820 1493 if (!is_numeric($bytes)) return __('N/A', 'wp-optimize');
1821 1494
@@ -1826,9 +1499,9 @@
1826 1499 } elseif (1024 <= $bytes) {
1827 1500 $bytes = number_format($bytes / 1024, $decimals) . ' KB';
1828 1501 } elseif (1 < $bytes) {
1829 1502 $bytes = $bytes . ' bytes';
1830 - } elseif (1 == $bytes) {
1503 + } elseif (1 === (int) $bytes) {
1831 1504 $bytes = $bytes . ' byte';
1832 1505 } else {
1833 1506 $bytes = '0 bytes';
1834 1507 }
@@ -1836,15 +1509,16 @@
1836 1509 return $bytes;
1837 1510 }
1838 1511
1839 1512 /**
1840 - * Format a timestamp into a juman readable date time
1513 + * Format a timestamp into a human-readable date time
1841 1514 *
1842 - * @param int $timestamp
1515 + * @param int $timestamp Epoch timestamp to convert
1516 + * @param string $separator String separator
1843 1517 * @return string
1844 1518 */
1845 - public function format_date_time($timestamp) {
1846 - return date_i18n(get_option('date_format').' @ '.get_option('time_format'), ($timestamp + get_option('gmt_offset') * 3600));
1519 + public function format_date_time($timestamp, $separator = ' @ ') {
1520 + return date_i18n(get_option('date_format'). $separator .get_option('time_format'), ($timestamp + get_option('gmt_offset') * 3600));
1847 1521 }
1848 1522
1849 1523 /**
1850 1524 * Executed this function on cron event.
@@ -1856,10 +1530,10 @@
1856 1530 $optimizer = $this->get_optimizer();
1857 1531 $options = $this->get_options();
1858 1532
1859 1533 $this->log('WPO: Starting cron_action()');
1860 -
1861 - if ('true' == $options->get_option('schedule')) {
1534 + $options->update_option('last-optimized', time());
1535 + if ('true' === $options->get_option('schedule')) {
1862 1536 $this_options = $options->get_option('auto');
1863 1537
1864 1538 // Currently the output of the optimizations is not saved/used/logged.
1865 1539 $optimizer->do_optimizations($this_options, 'auto');
@@ -1871,14 +1545,17 @@
1871 1545 * Schedule cron tasks used by plugin.
1872 1546 *
1873 1547 * @return void
1874 1548 */
1875 - public function schedule_plugin_cron_tasks() {
1549 + private function schedule_plugin_cron_tasks() {
1876 1550 if (!wp_next_scheduled('wpo_weekly_cron_tasks')) {
1877 - wp_schedule_event(current_time("timestamp", 0), 'weekly', 'wpo_weekly_cron_tasks');
1551 + wp_schedule_event(current_time("timestamp", 0), 'wpo_weekly', 'wpo_weekly_cron_tasks');
1878 1552 }
1879 1553
1880 1554 add_action('wpo_weekly_cron_tasks', array($this, 'do_weekly_cron_tasks'));
1555 +
1556 + // Run 404 detector cron.
1557 + $this->get_404_detector_cron();
1881 1558 }
1882 1559
1883 1560 /**
1884 1561 * Do plugin background tasks.
@@ -1891,32 +1568,75 @@
1891 1568 }
1892 1569
1893 1570 /**
1894 1571 * This will customize a URL with a correct Affiliate link
1895 - * This function can be update to suit any URL as longs as the URL is passed
1572 + * This function can be updated to suit any URL as longs as the URL is passed
1896 1573 *
1897 - * @param String $url - URL to be check to see if it an updraftplus match.
1898 - * @param String $text - Text to be entered within the href a tags.
1899 - * @param String $html - Any specific HTML to be added.
1900 - * @param String $class - Specify a class for the href (including the attribute label)
1901 - * @param Boolean $return_instead_of_echo - if set, then the result will be returned, not echo-ed.
1902 - *
1903 - * @return String|void
1574 + * @param string $url - URL to check to see if it is an updraftplus match.
1575 + * @param ?string $text - Text to be entered within the href a tags.
1576 + * @param ?string $html - Any specific HTML to be added. Supplied parameter will not be escaped in this function. Provide escaped, safe HTML
1577 + * @param string|array $attrs - Specify the HTML attributes as an array or string. Use the array format for multiple attributes (e.g., array( "class" => "lorem-ipsum", "title" => "Highlighting text" )), and use the string format for a single attribute (e.g., 'class="lorem-ipsum"').
1578 + * @param bool $return_instead_of_echo - if set, then the result will be returned, not echo-ed.
1579 + * @return string|void
1904 1580 */
1905 - public function wp_optimize_url($url, $text, $html = '', $class = '', $return_instead_of_echo = false) {
1581 + public function wp_optimize_url($url, $text = '', $html = '', $attrs = '', $return_instead_of_echo = false) {
1906 1582 // Check if the URL is UpdraftPlus.
1907 1583 $url = $this->maybe_add_affiliate_params($url); // Return URL - check if there is HTML such as images.
1908 - if ('' != $html) {
1909 - $result = '<a '.$class.' href="'.esc_attr($url).'">'.$html.'</a>';
1584 +
1585 + // Check if the variable $text is empty (null value included), otherwise assign $html.
1586 + $content = empty($text) ? $html : esc_html($text);
1587 +
1588 + // Check if $attrs is an array to convert the attributes into a string line.
1589 + $str_attrs = '';
1590 + if (is_array($attrs)) {
1591 + foreach ($attrs as $attr => $value) {
1592 + $str_attrs .= $attr . '="' . esc_attr($value) . '" ';
1593 + }
1910 1594 } else {
1911 - $result = '<a '.$class.' href="'.esc_attr($url).'">'.htmlspecialchars($text).'</a>';
1595 + // If $attrs is empty, the `explode` function will only return an empty array.
1596 + $attrs = explode('=', $attrs);
1597 + // Check if $attrs in positions 1 and 2 are not empty and exist; otherwise, return an empty string.
1598 + $str_attrs = !empty($attrs[0]) && !empty($attrs[1]) ? $attrs[0] . '="' . esc_attr(str_replace('"', '', $attrs[1])) . '"' : '';
1912 1599 }
1600 +
1601 + // Check if it is necessary to add a target value if the url is external
1602 + $is_external_url = $this->is_external_url($url);
1603 + if ($is_external_url) {
1604 + $str_attrs = preg_replace('/\s+target="_blank"/i', '', $str_attrs);
1605 + $str_attrs .= ' target="_blank"';
1606 + }
1607 +
1608 + $result = sprintf(
1609 + '<a href="%s" %s>%s</a>',
1610 + esc_url($url),
1611 + $str_attrs,
1612 + wp_kses_post($content)
1613 + );
1614 +
1913 1615 if ($return_instead_of_echo) return $result;
1914 - echo $result;
1616 + echo wp_kses_post($result);
1915 1617 }
1618 +
1619 + /**
1620 + * Check if a URL is external
1621 + *
1622 + * @param string $url
1623 + * @return bool
1624 + */
1625 + public function is_external_url($url) {
1626 + if (empty($url)) {
1627 + return false;
1628 + }
1629 +
1630 + $current_domain = wp_parse_url(home_url(), PHP_URL_HOST);
1631 + $url = wp_parse_url($url, PHP_URL_HOST);
1916 1632
1633 + // Compare the domains and return true if they are different
1634 + return $current_domain !== $url;
1635 + }
1636 +
1917 1637 /**
1918 - * Get an URL with an eventual affiliate ID
1638 + * Get a URL with an eventual affiliate ID
1919 1639 *
1920 1640 * @param string $url
1921 1641 * @return string
1922 1642 */
@@ -1928,9 +1648,10 @@
1928 1648
1929 1649 // Apply filters.
1930 1650 $url = apply_filters('wpoptimize_updraftplus_com_link', $url);
1931 1651 }
1932 - return apply_filters('wpoptimize_maybe_add_affiliate_params', $url);
1652 + $filtered_url = apply_filters('wpoptimize_maybe_add_affiliate_params', $url);
1653 + return is_string($filtered_url) ? $filtered_url : $url;
1933 1654 }
1934 1655
1935 1656 /**
1936 1657 * Setup WPO logger(s)
@@ -1991,9 +1712,9 @@
1991 1712 // check for previous version options format.
1992 1713 $keys = array_keys($saved_loggers);
1993 1714
1994 1715 // if options stored in old format then reformat it.
1995 - if (false == is_numeric($keys[0])) {
1716 + if (false === is_numeric($keys[0])) {
1996 1717 $_saved_loggers = array();
1997 1718 foreach ($saved_loggers as $logger_id => $enabled) {
1998 1719 if ($enabled) {
1999 1720 $_saved_loggers[] = $logger_id;
@@ -2024,9 +1745,9 @@
2024 1745 foreach (array_keys($logger_options) as $option_name) {
2025 1746 if (array_key_exists($option_name, $options_keys)) {
2026 1747 $options_keys[$option_name]++;
2027 1748 } else {
2028 - $options_keys[$option_name] = 0;
1749 + $options_keys[$option_name] = 0;
2029 1750 }
2030 1751
2031 1752 $option_value = isset($logger_additional_options[$option_name][$options_keys[$option_name]]) ? $logger_additional_options[$option_name][$options_keys[$option_name]] : '';
2032 1753
@@ -2051,11 +1772,10 @@
2051 1772 $loggers[] = $logger;
2052 1773 }
2053 1774 }
2054 1775
2055 - $loggers = apply_filters('wp_optimize_loggers', $loggers);
2056 -
2057 - return $loggers;
1776 + $filtered_loggers = apply_filters('wp_optimize_loggers', $loggers);
1777 + return is_array($filtered_loggers) ? $filtered_loggers : $loggers;
2058 1778 }
2059 1779
2060 1780 /**
2061 1781 * Returns associative array with logger class name in a key and path to class file in a value.
@@ -2123,17 +1843,17 @@
2123 1843 return (is_multisite() && self::is_premium());
2124 1844 }
2125 1845
2126 1846 /**
2127 - * Returns true if current user can run optimizations.
1847 + * Returns true if the current user can run optimizations.
2128 1848 *
2129 1849 * @return bool
2130 1850 */
2131 - public function can_run_optimizations() {
1851 + public function can_run_optimizations(): bool {
2132 1852 // we don't check permissions for cron jobs.
2133 1853 if (defined('DOING_CRON') && DOING_CRON) return true;
2134 1854
2135 - if (self::is_premium() && false == user_can(get_current_user_id(), 'wpo_run_optimizations')) return false;
1855 + if (self::is_premium() && false === user_can(get_current_user_id(), 'wpo_run_optimizations')) return false;
2136 1856 return true;
2137 1857 }
2138 1858
2139 1859 /**
@@ -2146,40 +1866,8 @@
2146 1866 return true;
2147 1867 }
2148 1868
2149 1869 /**
2150 - * CHeck if current user can purge the cache.
2151 - *
2152 - * @return bool
2153 - */
2154 - public function can_purge_the_cache() {
2155 - if (self::is_premium()) {
2156 - return WP_Optimize_Premium()->can_purge_the_cache();
2157 - }
2158 -
2159 - return true;
2160 - }
2161 -
2162 - /**
2163 - * Output information message for users who have no permissions to run optimizations.
2164 - *
2165 - * @param string $message Message to display
2166 - */
2167 - public function prevent_run_optimizations_message($message = '') {
2168 - if (empty($message)) {
2169 - $message = __('You have no permissions to run optimizations.', 'wp-optimize');
2170 - }
2171 - $this->include_template('info-message.php', false, array('message' => $message));
2172 - }
2173 -
2174 - /**
2175 - * Output information message for users who have no permissions to manage settings.
2176 - */
2177 - public function prevent_manage_options_info() {
2178 - $this->include_template('info-message.php', false, array('message' => __('You have no permissions to manage WP-Optimize settings.', 'wp-optimize')));
2179 - }
2180 -
2181 - /**
2182 1870 * Returns list of all sites in multisite
2183 1871 *
2184 1872 * @return array
2185 1873 */
@@ -2184,36 +1872,18 @@
2184 1872 * @return array
2185 1873 */
2186 1874 public function get_sites() {
2187 1875 $sites = array();
2188 - // check if function get_sites exists (since 4.6.0) else use wp_get_sites.
2189 1876 if (function_exists('get_sites')) {
2190 1877 $sites = get_sites(array('network_id' => null, 'deleted' => 0, 'number' => 999999));
2191 - } elseif (function_exists('wp_get_sites')) {
2192 - $sites = wp_get_sites(array('network_id' => null, 'deleted' => 0, 'limit' => 999999));
2193 1878 }
2194 1879 return $sites;
2195 1880 }
2196 1881
2197 1882 /**
2198 - * Output success/error messages from $output array.
2199 - *
2200 - * @param array $output ['messages' => success messages, 'errors' => error messages]
2201 - */
2202 - private function wpo_render_output_messages($output) {
2203 - foreach ($output['messages'] as $item) {
2204 - echo '<div class="updated fade below-h2"><strong>'.$item.'</strong></div>';
2205 - }
2206 -
2207 - foreach ($output['errors'] as $item) {
2208 - echo '<div class="error fade below-h2"><strong>'.$item.'</strong></div>';
2209 - }
2210 - }
2211 -
2212 - /**
2213 1883 * Returns script memory limit in megabytes.
2214 1884 *
2215 - * @param bool $memory_limit
1885 + * @param string|bool $memory_limit
2216 1886 * @return int
2217 1887 */
2218 1888 public function get_memory_limit($memory_limit = false) {
2219 1889 // Returns in megabytes
@@ -2267,9 +1937,9 @@
2267 1937 $mp = (is_numeric($mp) && $mp > 0) ? $mp : 1048576;
2268 1938 // 32MB
2269 1939 if ($mp < 33554432) {
2270 1940 $save = $wpdb->show_errors(false);
2271 - @$wpdb->query("SET GLOBAL max_allowed_packet=33554432");// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
1941 + @$wpdb->query("SET GLOBAL max_allowed_packet=33554432");// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress errors from displaying
2272 1942 $wpdb->show_errors($save);
2273 1943
2274 1944 $mp = (int) $wpdb->get_var("SELECT @@session.max_allowed_packet");
2275 1945 // Default to 1MB
@@ -2283,8 +1953,10 @@
2283 1953 * Converts shorthand memory notation value to bytes.
2284 1954 * From http://php.net/manual/en/function.ini-get.php
2285 1955 *
2286 1956 * @param string $val shorthand memory notation value.
1957 + *
1958 + * @return string
2287 1959 */
2288 1960 public function return_bytes($val) {
2289 1961 $val = trim($val);
2290 1962 $last = strtolower($val[strlen($val)-1]);
@@ -2316,9 +1988,9 @@
2316 1988
2317 1989 /**
2318 1990 * Close browser connection and continue script work. - Taken from UpdraftPlus
2319 1991 *
2320 - * @param array $txt Response to browser; this must be JSON (or if not, alter the Content-Type header handling below)
1992 + * @param string $txt Response to browser; this must be JSON (or if not, alter the Content-Type header handling below)
2321 1993 * @return void
2322 1994 */
2323 1995 public function close_browser_connection($txt = '') {
2324 1996 if (!headers_sent()) {
@@ -2323,8 +1995,9 @@
2323 1995 public function close_browser_connection($txt = '') {
2324 1996 if (!headers_sent()) {
2325 1997 // Close browser connection so that it can resume AJAX polling
2326 1998 header('Content-Length: '.(empty($txt) ? '0' : 4+strlen($txt)));
1999 + header('Content-Type: application/json');
2327 2000 header('Connection: close');
2328 2001 header('Content-Encoding: none');
2329 2002 }
2330 2003
@@ -2329,9 +2002,9 @@
2329 2002 }
2330 2003
2331 2004 if (session_id()) session_write_close();
2332 2005 echo "\r\n\r\n";
2333 - echo $txt;
2006 + echo $txt; // phpcs:ignore WordPress.Security.EscapeOutput -- Output is already escaped
2334 2007 // These two added - 19-Feb-15 - started being required on local dev machine, for unknown reason (probably some plugin that started an output buffer).
2335 2008 $ob_level = ob_get_level();
2336 2009 while ($ob_level > 0) {
2337 2010 ob_end_flush();
@@ -2338,50 +2011,22 @@
2338 2011 $ob_level--;
2339 2012 }
2340 2013 flush();
2341 2014 if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();
2015 + if (function_exists('litespeed_finish_request')) litespeed_finish_request();
2342 2016 }
2343 2017
2344 2018 /**
2345 - * Get the current theme's style.css headers
2346 - *
2347 - * @return array|WP_Error
2348 - */
2349 - public function get_stylesheet_headers() {
2350 - static $headers;
2351 - if (isset($headers)) return $headers;
2352 -
2353 - $style = get_template_directory_uri() . '/style.css';
2354 -
2355 - /**
2356 - * Filters wp_remote_get parameters, when checking if browser cache is enabled.
2357 - *
2358 - * @param array $request_params Default parameters
2359 - */
2360 - $request_params = apply_filters('wpoptimize_get_stylesheet_headers_args', array('timeout' => 10));
2361 -
2362 - // trying to load style.css.
2363 - $response = wp_remote_get($style, $request_params);
2364 -
2365 - if (is_a($response, 'WP_Error')) return $response;
2366 -
2367 - $headers = wp_remote_retrieve_headers($response);
2368 -
2369 - if (is_a($headers, 'Requests_Utility_CaseInsensitiveDictionary')) {
2370 - $headers = $headers->getAll();
2371 - }
2372 -
2373 - return $headers;
2374 - }
2375 -
2376 - /**
2377 2019 * Try to change PHP script time limit.
2378 2020 */
2379 2021 public function change_time_limit() {
2380 2022 $time_limit = (defined('WP_OPTIMIZE_SET_TIME_LIMIT') && WP_OPTIMIZE_SET_TIME_LIMIT > 15) ? WP_OPTIMIZE_SET_TIME_LIMIT : 1800;
2381 2023
2382 - // Try to reduce the chances of PHP self-terminating via reaching max_execution_time.
2383 - @set_time_limit($time_limit); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
2024 + // phpcs:disable
2025 + // Generic.PHP.NoSilencedErrors.Discouraged -- Try to reduce the chances of PHP self-terminating via reaching max_execution_time.
2026 + // Squiz.PHP.DiscouragedFunctions.Discouraged -- Try to reduce the chances of PHP self-terminating via reaching max_execution_time.
2027 + @set_time_limit($time_limit);
2028 + // phpcs:enable
2384 2029 }
2385 2030
2386 2031 /**
2387 2032 * Does the request come from UDC
@@ -2398,11 +2043,11 @@
2398 2043 * @return boolean
2399 2044 */
2400 2045 public function template_should_include_data() {
2401 2046 /**
2402 - * Filters wether data should be included in certain templates or not.
2047 + * Filters whether data should be included in certain templates or not.
2403 2048 */
2404 - return apply_filters('wpo_template_should_include_data', $this->is_updraft_central_request());
2049 + return (bool) apply_filters('wpo_template_should_include_data', $this->is_updraft_central_request());
2405 2050 }
2406 2051
2407 2052 /**
2408 2053 * Load the templates for the modal window
@@ -2411,8 +2056,18 @@
2411 2056 $this->include_template('modal.php');
2412 2057 }
2413 2058
2414 2059 /**
2060 + * Adds compress popup template
2061 + */
2062 + public function add_smush_popup_template() {
2063 + if ($this->current_user_can()) {
2064 + $compression_server_hint = Updraft_Smush_Manager()->get_compression_server_hint();
2065 + $this->include_template('images/smush-popup.php', false, array('compression_server_hint' => $compression_server_hint));
2066 + }
2067 + }
2068 +
2069 + /**
2415 2070 * Delete transients and semaphores data from options table.
2416 2071 */
2417 2072 public function delete_transients_and_semaphores() {
2418 2073 global $wpdb;
@@ -2428,8 +2083,9 @@
2428 2083 'wpo_semaphore_%',
2429 2084 '_transient_timeout_wpo_%',
2430 2085 '_transient_wpo_%',
2431 2086 'updraft_lock_wpo_%',
2087 + 'wpo_last_scheduled_%',
2432 2088 );
2433 2089
2434 2090 $where_parts = array();
2435 2091 foreach ($masks as $mask) {
@@ -2435,85 +2091,113 @@
2435 2091 foreach ($masks as $mask) {
2436 2092 $where_parts[] = "(`option_name` LIKE '{$mask}')";
2437 2093 }
2438 2094
2439 - $wpdb->query("DELETE FROM {$wpdb->options} WHERE " . join(' OR ', $where_parts));
2095 + $where_clause = implode(' OR ', $where_parts);
2096 + $wpdb->query($wpdb->prepare("DELETE FROM `{$wpdb->options}` WHERE %s", $where_clause));
2440 2097 }
2441 2098
2442 2099 /**
2443 2100 * Prevents bots from indexing plugins list
2101 + *
2102 + * @param string $output
2103 + * @return string
2444 2104 */
2445 2105 public function robots_txt($output) {
2446 2106 $upload_dir = wp_upload_dir();
2447 - $path = parse_url($upload_dir['baseurl']);
2448 - $output .= "\nDisallow: " . str_replace($path['scheme'].'://'.$path['host'], '', $upload_dir['baseurl']) . "/wpo-plugins-tables-list.json\n";
2107 + $path = wp_parse_url($upload_dir['baseurl']);
2108 + $output .= "\nUser-agent: *";
2109 + $output .= "\nDisallow: " . str_replace($path['scheme'].'://'.$path['host'], '', $upload_dir['baseurl']) . "/wpo/wpo-plugins-tables-list.json\n";
2449 2110 return $output;
2450 2111 }
2451 -}
2452 2112
2453 -/**
2454 - * Plugin activation actions.
2455 - */
2456 -function wpo_activation_actions() {
2457 - // If plugin activated by not a Network Administrator then deactivate plugin and show message.
2458 - if (is_multisite() && !is_network_admin()) {
2459 - deactivate_plugins(plugin_basename(__FILE__));
2460 - wp_die(__('Only Network Administrator can activate WP-Optimize plugin.', 'wp-optimize').
2461 - ' <a href="'.admin_url('plugins.php').'">'.__('go back', 'wp-optimize').'</a>');
2113 + /**
2114 + * Returns desired enqueue version string
2115 + *
2116 + * @return string Enqueue version as string
2117 + */
2118 + public function get_enqueue_version() {
2119 + return (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
2462 2120 }
2463 2121
2464 - // On activation, check if last-optimized option exists. If not, add 'newly-activated' option.
2465 - if (!WP_Optimize()->get_options()->get_option('last-optimized', false)) {
2466 - WP_Optimize()->get_options()->update_option('newly-activated', true);
2122 + /**
2123 + * Returns script suffix string
2124 + *
2125 + * @return string empty or `.min` suffix string
2126 + */
2127 + public function get_min_or_not_string() {
2128 + return (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
2467 2129 }
2468 2130
2469 - WP_Optimize()->get_options()->set_default_options();
2470 - WP_Optimize()->get_minify()->plugin_activate();
2131 + /**
2132 + * Returns script suffix string with WPO_VERSION
2133 + *
2134 + * @return string empty or min suffix with wpo_version string
2135 + */
2136 + public function get_min_or_not_internal_string() {
2137 + return (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-' . str_replace('.', '-', WPO_VERSION) . '.min';
2138 + }
2471 2139
2472 - WP_Optimize::get_gzip_compression()->restore();
2473 - WP_Optimize::get_browser_cache()->restore();
2140 + /**
2141 + * Instantiate Ajax handling class
2142 + */
2143 + private function load_ajax_handler() {
2144 + WPO_Ajax::get_instance();
2145 + }
2474 2146
2475 - if (!class_exists('Updraft_Tasks_Activation')) require_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php');
2476 - Updraft_Tasks_Activation::init_db();
2477 - Updraft_Tasks_Activation::reinstall_if_needed();
2147 + /**
2148 + * Get instance of WP_Optimize_Table_Management
2149 + *
2150 + * @return WP_Optimize_Table_Management
2151 + */
2152 + public function get_table_management() {
2153 + return WP_Optimize_Table_Management::get_instance();
2154 + }
2478 2155
2479 - // run premium activation actions.
2480 - if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php')) {
2481 - if (!class_exists('WP_Optimize_Premium')) {
2482 - include_once(WPO_PLUGIN_MAIN_PATH.'premium.php');
2156 + /**
2157 + * Get instance of WP_Optimize_404_Detector
2158 + *
2159 + * @return WP_Optimize_404_Detector
2160 + */
2161 + public function get_404_detector() {
2162 + return WP_Optimize_404_Detector::get_instance();
2483 2163 }
2484 2164
2485 - WP_Optimize_Premium()->plugin_activation_actions();
2165 + /**
2166 + * Returns the message used to notify the user that the PHP version or WordPress version doesn't meet the requirements.
2167 + *
2168 + * @return string
2169 + */
2170 + public function get_minimum_requirements_notice_message() {
2171 + // translators: %1$s is minimum required PHP version, %2$s is minimum required WordPress version
2172 + return sprintf(esc_html__('WP-Optimize requires a minimum PHP version of %1$s and WordPress version of %2$s or higher', 'wp-optimize'), esc_html(WPO_REQUIRED_PHP_VERSION), esc_html(WPO_REQUIRED_WP_VERSION));
2486 2173 }
2174 +
2175 + /**
2176 + * Output notice when PHP version or WordPress version is not meet for WP-Optimize.
2177 + *
2178 + * @return void
2179 + */
2180 + public function output_minimum_requirements_notice() {
2181 + ?>
2182 + <div class="notice notice-error is-dismissible">
2183 + <p><?php echo $this->get_minimum_requirements_notice_message(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is already escaped ?></p>
2184 + </div>
2185 + <?php
2186 + }
2487 2187 }
2488 2188
2489 2189 /**
2490 - * Plugin deactivation actions.
2190 + * Unschedule specific tasks:
2191 + * `wpo_cron_event2` => DB optimizations
2192 + * `wpo_weekly_cron_tasks` => ex: plugin.json auto update
2193 + *
2194 + * @return void
2491 2195 */
2492 -function wpo_deactivation_actions() {
2493 - WP_Optimize()->wpo_cron_deactivate();
2494 - WP_Optimize()->get_page_cache()->disable();
2495 - WP_Optimize()->get_minify()->plugin_deactivate();
2496 - WP_Optimize::get_gzip_compression()->disable();
2497 - WP_Optimize::get_browser_cache()->disable();
2498 -}
2499 -
2500 2196 function wpo_cron_deactivate() {
2501 2197 WP_Optimize()->log('running wpo_cron_deactivate()');
2502 2198 wp_clear_scheduled_hook('wpo_cron_event2');
2503 2199 wp_clear_scheduled_hook('wpo_weekly_cron_tasks');
2504 -}
2505 -
2506 -/**
2507 - * Plugin uninstall actions.
2508 - */
2509 -function wpo_uninstall_actions() {
2510 - WP_Optimize::get_gzip_compression()->disable();
2511 - WP_Optimize::get_browser_cache()->disable();
2512 - WP_Optimize()->get_options()->delete_all_options();
2513 - WP_Optimize()->get_minify()->plugin_uninstall();
2514 - WP_Optimize()->get_options()->wipe_settings();
2515 - WP_Optimize()->delete_transients_and_semaphores();
2516 2200 }
2517 2201
2518 2202 function WP_Optimize() {
2519 2203 return WP_Optimize::instance();