PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.6
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.6
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 3.8.0 All 110 releases
wp-optimize / wp-optimize.php

wp-optimize.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.6, at wp-optimize.php

1,947 lines 62.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 Plugin Name: WP-Optimize - Clean, Compress, Cache
4 Plugin URI: https://getwpo.com
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.6
7 Update URI: https://wordpress.org/plugins/wp-optimize/
8 Author: David Anderson, Ruhani Rabin, Team Updraft
9 Author URI: https://updraftplus.com
10 Text Domain: wp-optimize
11 Domain Path: /languages
12 License: GPLv2 or later
13 */
14
15 if (!defined('ABSPATH')) die('No direct access allowed');
16
17 // Check to make sure if WP_Optimize is already call and returns.
18 if (!class_exists('WP_Optimize')) :
19 define('WPO_VERSION', '3.2.6');
20 define('WPO_PLUGIN_URL', plugin_dir_url(__FILE__));
21 define('WPO_PLUGIN_MAIN_PATH', plugin_dir_path(__FILE__));
22 define('WPO_PREMIUM_NOTIFICATION', false);
23 define('WPO_MINIFY_PHP_VERSION_MET', version_compare(PHP_VERSION, '5.4', '>=') ? true : false);
24
25 class WP_Optimize {
26
27 public $premium_version_link = 'https://getwpo.com/buy/';
28
29 private $template_directories;
30
31 protected static $_instance = null;
32
33 protected static $_optimizer_instance = null;
34
35 protected static $_options_instance = null;
36
37 protected static $_minify_instance = null;
38
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 /**
52 * Class constructor
53 */
54 public function __construct() {
55 spl_autoload_register(array($this, 'loader'));
56
57 // Checks if premium is installed along with plugins needed.
58 add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
59
60 register_activation_hook(__FILE__, 'wpo_activation_actions');
61 register_deactivation_hook(__FILE__, 'wpo_deactivation_actions');
62 register_uninstall_hook(__FILE__, 'wpo_uninstall_actions');
63
64 $this->load_admin();
65 add_action('admin_init', array($this, 'admin_init'));
66 add_action('admin_bar_menu', array($this, 'cache_admin_bar'), 100, 1);
67
68 add_filter("plugin_action_links_".plugin_basename(__FILE__), array($this, 'plugin_settings_link'));
69 add_action('wpo_cron_event2', array($this, 'cron_action'));
70 add_filter('cron_schedules', array($this, 'cron_schedules'));
71
72 if (!$this->get_options()->get_option('installed-for', false)) $this->get_options()->update_option('installed-for', time());
73
74 if (!self::is_premium()) {
75 add_action('auto_option_settings', array($this->get_options(), 'auto_option_settings'));
76 }
77
78 add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
79
80 add_action('wp_enqueue_scripts', array($this, 'frontend_enqueue_scripts'));
81
82 add_action('wp_ajax_wp_optimize_ajax', array($this, 'wp_optimize_ajax_handler'));
83
84 // Show update to Premium notice for non-premium multisite.
85 add_action('wpo_additional_options', array($this, 'show_multisite_update_to_premium_notice'));
86
87 // Action column (show repair button if need).
88 add_filter('wpo_tables_list_additional_column_data', array($this, 'tables_list_additional_column_data'), 15, 2);
89
90 /**
91 * Add action for display Images > Compress images tab.
92 */
93 add_action('wp_optimize_admin_page_wpo_images_smush', array($this, 'admin_page_wpo_images_smush'));
94
95 include_once(WPO_PLUGIN_MAIN_PATH.'includes/updraftcentral.php');
96
97 include_once(WPO_PLUGIN_MAIN_PATH.'includes/backward-compatibility-functions.php');
98
99 register_shutdown_function(array($this, 'log_fatal_errors'));
100
101 $this->schedule_plugin_cron_tasks();
102
103 add_action('wpo_admin_before_closing_wrap', array($this, 'load_modal_template'), 20);
104
105 add_action('upgrader_process_complete', array($this, 'detect_active_plugins_and_themes_updates'), 10, 2);
106
107 $import_done_hooks = array(
108 'import_end', // wordpress importer
109 'pmxi_after_xml_import', // wp all import
110 );
111
112 $db_update_hooks = apply_filters('wp_optimize_db_update_hooks', $import_done_hooks);
113
114 foreach ($db_update_hooks as $hook) {
115 add_action($hook, array($this, 'maybe_schedule_update_record_count_event'));
116 }
117 add_action('wpo_update_record_count_event', array($this->get_db_info(), 'wpo_update_record_count'));
118 }
119
120 /**
121 * Auto-loads classes.
122 *
123 * @param string $class_name The name of the class.
124 */
125 private function loader($class_name) {
126 $dirs = $this->get_class_directories();
127
128 foreach ($dirs as $dir) {
129 $class_file = WPO_PLUGIN_MAIN_PATH . $dir . '/class-' . str_replace('_', '-', strtolower($class_name)) . '.php';
130 if (file_exists($class_file)) {
131 require_once($class_file);
132 return;
133 }
134 }
135 }
136
137 /**
138 * Returns an array of class directories
139 *
140 * @return array
141 */
142 private function get_class_directories() {
143 return array(
144 'cache',
145 'includes',
146 'minify',
147 'optimizations',
148 'webp',
149 );
150 }
151
152 /**
153 * Initialize Admin class to load admin UI
154 */
155 private function load_admin() {
156 $this->get_admin_instance();
157 }
158
159 /**
160 * Returns Admin class instance
161 *
162 * @return WP_Optimize_Admin
163 */
164 public function get_admin_instance() {
165 return WP_Optimize_Admin::instance();
166 }
167
168 /**
169 * Detect when an active plugin or theme is updated, and trigger an action
170 *
171 * @param object $upgrader_object
172 * @param array $options
173 * @return void
174 */
175 public function detect_active_plugins_and_themes_updates($upgrader_object, $options) {
176 if (empty($options) || !isset($options['type'])) return;
177
178 $should_purge_cache = false;
179 $skin = $upgrader_object->skin;
180 if ('plugin' === $options['type']) {
181 // A plugin is updated using the default update system (upgrader_overwrote_package is used for the upload method)
182 if (property_exists($skin, 'plugin_active') && $skin->plugin_active) {
183 $should_purge_cache = true;
184 }
185 } elseif ('theme' === $options['type']) {
186 $active_theme = get_stylesheet();
187 $parent_theme = get_template();
188 // A theme is updated using the upload system
189 if (isset($options['action']) && 'install' === $options['action'] && 'update-theme' === $skin->options['overwrite']) {
190 $updated_theme = $upgrader_object->result['destination_name'];
191 // Check if the theme is in use
192 if ($active_theme == $updated_theme || $parent_theme == $updated_theme) {
193 $should_purge_cache = true;
194 }
195 // A theme is updated using the classic update system
196 } elseif (isset($options['action']) && 'update' === $options['action'] && isset($options['themes']) && is_array($options['themes'])) {
197 // Check if the theme is in use
198 if (in_array($active_theme, $options['themes']) || in_array($parent_theme, $options['themes'])) {
199 $should_purge_cache = true;
200 }
201 }
202 }
203
204 /**
205 * Action executed when an active theme or plugin was updated
206 */
207 if ($should_purge_cache) do_action('wpo_active_plugin_or_theme_updated');
208
209 }
210
211 /**
212 * Sets a flag to indicate an import action is done, if needed
213 */
214 public function maybe_schedule_update_record_count_event() {
215 if (!wp_next_scheduled('wpo_update_record_count_event')) {
216 wp_schedule_single_event(time() + 60, 'wpo_update_record_count_event');
217 }
218 }
219
220 public function admin_page_wpo_images_smush() {
221 $options = Updraft_Smush_Manager()->get_smush_options();
222 $custom = 100 != $options['image_quality'] && 60 != $options['image_quality'] ? true : false;
223 $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()));
224 }
225
226 public static function instance() {
227 if (empty(self::$_instance)) {
228 self::$_instance = new self();
229 }
230 return self::$_instance;
231 }
232
233 public static function get_optimizer() {
234 if (empty(self::$_optimizer_instance)) {
235 self::$_optimizer_instance = new WP_Optimizer();
236 }
237 return self::$_optimizer_instance;
238 }
239
240 /**
241 * Get and instanciate WP_Optimize_Minify
242 *
243 * @return WP_Optimize_Minify
244 */
245 public function get_minify() {
246 if (empty(self::$_minify_instance)) {
247 self::$_minify_instance = new WP_Optimize_Minify();
248 }
249 return self::$_minify_instance;
250 }
251
252 public static function get_options() {
253 if (empty(self::$_options_instance)) {
254 self::$_options_instance = new WP_Optimize_Options();
255 }
256 return self::$_options_instance;
257 }
258
259 public static function get_notices() {
260 if (empty(self::$_notices_instance)) {
261 self::$_notices_instance = new WP_Optimize_Notices();
262 }
263 return self::$_notices_instance;
264 }
265
266 /**
267 * Returns instance if WPO_Page_Cache class.
268 *
269 * @return WPO_Page_Cache
270 */
271 public function get_page_cache() {
272 return WPO_Page_Cache::instance();
273 }
274
275 /**
276 * Returns instance if WP_Optimize_WebP class.
277 *
278 * @return WP_Optimize_WebP
279 */
280 public function get_webp_instance() {
281 return WP_Optimize_WebP::get_instance();
282 }
283
284 /**
285 * Detects if the platform is Kinsta or not
286 *
287 * @return bool Returns true if it is Kinsta platform, otherwise returns false
288 */
289 private function is_kinsta() {
290 return isset($_SERVER['KINSTA_CACHE_ZONE']);
291 }
292
293 /**
294 * Detects whether the server handles cache. eg. Nginx cache
295 */
296 public function does_server_handles_cache() {
297 return $this->is_kinsta();
298 }
299
300 /**
301 * Detects whether the server supports table optimization.
302 *
303 * Some servers prevent table optimization
304 * because InnoDB engine does not optimize table
305 * instead it drops tables and recreate them
306 * which results in elevated disk write operations
307 */
308 public function does_server_allows_table_optimization() {
309 return !$this->is_kinsta();
310 }
311
312 /**
313 * Detects whether the server supports local webp conversion tools
314 */
315 private function does_server_allows_local_webp_conversion() {
316 return !$this->is_kinsta();
317 }
318
319 /**
320 * Create instance of WP_Optimize_Browser_Cache.
321 *
322 * @return WP_Optimize_Browser_Cache
323 */
324 public static function get_browser_cache() {
325 if (empty(self::$_browser_cache)) {
326 self::$_browser_cache = new WP_Optimize_Browser_Cache();
327 }
328 return self::$_browser_cache;
329 }
330
331 /**
332 * Returns WP_Optimize_Database_Information instance.
333 *
334 * @return WP_Optimize_Database_Information
335 */
336 public function get_db_info() {
337 if (empty(self::$_db_info)) {
338 self::$_db_info = new WP_Optimize_Database_Information();
339 }
340 return self::$_db_info;
341 }
342
343 /**
344 * Returns instance of WP_Optimize_Gzip_Compression.
345 *
346 * @return WP_Optimize_Gzip_Compression
347 */
348 static public function get_gzip_compression() {
349 if (empty(self::$_gzip_compression)) {
350 self::$_gzip_compression = new WP_Optimize_Gzip_Compression();
351 }
352 return self::$_gzip_compression;
353 }
354
355 /**
356 * Create instance of WP_Optimize_Htaccess.
357 *
358 * @param string $htaccess_file absolute path to htaccess file, by default it use .htaccess in WordPress root directory.
359 * @return WP_Optimize_Htaccess
360 */
361 public static function get_htaccess($htaccess_file = '') {
362 return new WP_Optimize_Htaccess($htaccess_file);
363 }
364
365 /**
366 * Return instance of Updraft_Logger
367 *
368 * @return Updraft_Logger
369 */
370 public static function get_logger() {
371 if (empty(self::$_logger_instance)) {
372 self::$_logger_instance = new Updraft_Logger();
373 }
374 return self::$_logger_instance;
375 }
376
377 /**
378 * Check if the current page belongs to WP-Optimize.
379 *
380 * @return bool
381 */
382 public function is_wpo_page() {
383 $current_screen = get_current_screen();
384
385 return (bool) preg_match('/wp\-optimize/i', $current_screen->id);
386 }
387
388 /**
389 * Enqueue scripts and styles on WP-Optimize pages.
390 */
391 public function admin_enqueue_scripts() {
392 $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
393 $min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
394 $min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
395
396 // Register or enqueue common scripts
397 wp_register_script('wp-optimize-send-command', WPO_PLUGIN_URL.'js/send-command'.$min_or_not_internal.'.js', array(), $enqueue_version);
398 wp_localize_script('wp-optimize-send-command', 'wp_optimize_send_command_data', array('nonce' => wp_create_nonce('wp-optimize-ajax-nonce')));
399 wp_enqueue_style('wp-optimize-global', WPO_PLUGIN_URL.'css/wp-optimize-global'.$min_or_not_internal.'.css', array(), $enqueue_version);
400
401 // load scripts and styles only on WP-Optimize pages.
402 if (!$this->is_wpo_page()) return;
403
404 wp_enqueue_script('jquery-serialize-json', WPO_PLUGIN_URL.'js/serialize-json/jquery.serializejson'.$min_or_not.'.js', array('jquery'), $enqueue_version);
405
406 wp_register_script('updraft-queue-js', WPO_PLUGIN_URL.'js/queue'.$min_or_not_internal.'.js', array(), $enqueue_version);
407 wp_enqueue_script('wp-optimize-modal', WPO_PLUGIN_URL.'js/modal'.$min_or_not_internal.'.js', array('jquery', 'backbone', 'wp-util'), $enqueue_version);
408 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);
409 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);
410 wp_enqueue_style('wp-optimize-admin-css', WPO_PLUGIN_URL.'css/wp-optimize-admin'.$min_or_not_internal.'.css', array(), $enqueue_version);
411 // Using tablesorter to help with organising the DB size on Table Information
412 // https://github.com/Mottie/tablesorter
413 wp_enqueue_script('tablesorter-js', WPO_PLUGIN_URL.'js/tablesorter/jquery.tablesorter'.$min_or_not.'.js', array('jquery', 'wp-optimize-send-command'), $enqueue_version);
414
415 wp_enqueue_script('tablesorter-widgets-js', WPO_PLUGIN_URL.'js/tablesorter/jquery.tablesorter.widgets'.$min_or_not.'.js', array('jquery'), $enqueue_version);
416
417 // wp_enqueue_style('tablesorter-css', WPO_PLUGIN_URL.'css/tablesorter/theme.default.min.css', array(), $enqueue_version);
418
419 $js_variables = $this->wpo_js_translations();
420 $js_variables['loggers_classes_info'] = $this->get_loggers_classes_info();
421
422 wp_localize_script('wp-optimize-admin-js', 'wpoptimize', $js_variables);
423
424 do_action('wpo_premium_scripts_styles', $min_or_not_internal, $min_or_not, $enqueue_version);
425 }
426
427 /**
428 * Enqueue any required front-end scripts
429 *
430 * @return void
431 */
432 public function frontend_enqueue_scripts() {
433 if (!current_user_can('manage_options') || !is_admin_bar_showing()) return;
434 $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
435 $min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
436
437 // Register or enqueue common scripts
438 wp_enqueue_style('wp-optimize-global', WPO_PLUGIN_URL.'css/wp-optimize-global'.$min_or_not_internal.'.css', array(), $enqueue_version);
439 }
440
441 /**
442 * Load Task Manager
443 */
444 public function get_task_manager() {
445 include_once(WPO_PLUGIN_MAIN_PATH.'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php');
446
447 Updraft_Tasks_Activation::check_updates();
448
449 include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php');
450 include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php');
451 include_once(WPO_PLUGIN_MAIN_PATH . '/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task.php');
452
453 include_once(WPO_PLUGIN_MAIN_PATH . '/includes/class-updraft-smush-task.php');
454 include_once(WPO_PLUGIN_MAIN_PATH . '/includes/class-updraft-smush-manager.php');
455
456 return Updraft_Smush_Manager();
457 }
458
459 /**
460 * Indicate whether we have an associated instance of WP-Optimize Premium or not.
461 *
462 * @returns Boolean
463 */
464 public static function is_premium() {
465 if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php') && function_exists('WP_Optimize_Premium')) {
466 $wp_optimize_premium = WP_Optimize_Premium();
467 if (is_a($wp_optimize_premium, 'WP_Optimize_Premium')) return true;
468 }
469 return false;
470 }
471
472 /**
473 * Check if script running on Apache web server. $is_apache is set in wp-includes/vars.php. Also returns true if the server uses litespeed.
474 *
475 * @return bool
476 */
477 public function is_apache_server() {
478 global $is_apache;
479 return $is_apache;
480 }
481
482 /**
483 * Check if script running on IIS web server.
484 *
485 * @return bool
486 */
487 public function is_IIS_server() {
488 global $is_IIS, $is_iis7;
489 return $is_IIS || $is_iis7;
490 }
491
492 /**
493 * Check if Apache module or modules active.
494 *
495 * @param string|array $module - single Apache module name or list of Apache module names.
496 *
497 * @return bool|null - if null, the result was indeterminate
498 */
499 public function is_apache_module_loaded($module) {
500 if (!$this->is_apache_server()) return false;
501
502 if (!function_exists('apache_get_modules')) return null;
503
504 $module_loaded = true;
505
506 if (is_array($module)) {
507 foreach ($module as $single_module) {
508 if (!in_array($single_module, apache_get_modules())) {
509 $module_loaded = false;
510 break;
511 }
512 }
513 } else {
514 $module_loaded = in_array($module, apache_get_modules());
515 }
516
517 return $module_loaded;
518 }
519
520 /**
521 * 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.
522 */
523 public function plugins_loaded() {
524
525 if ($this->does_server_handles_cache()) {
526 add_filter('wp_optimize_admin_page_wpo_cache_tabs', array($this, 'filter_cache_tabs'), 99, 1);
527
528 // If newly migrated to server that handles cache, disable wpo cache
529 $cache = $this->get_page_cache();
530 if ($cache->is_enabled()) {
531 $cache->disable();
532 }
533 }
534
535 add_filter('robots_txt', array($this, 'robots_txt'), 99, 1);
536
537 // Run Premium loader if it exists
538 if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php') && !class_exists('WP_Optimize_Premium')) {
539 include_once(WPO_PLUGIN_MAIN_PATH.'premium.php');
540 }
541
542 // load defaults
543 WP_Optimize()->get_options()->set_default_options();
544
545 // Initialize loggers.
546 $this->setup_loggers();
547
548 if ($this->is_active('premium') && false !== ($free_plugin = $this->is_active('free'))) {
549 if (!function_exists('deactivate_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php');
550 deactivate_plugins($free_plugin);
551
552 // If WPO_ADVANCED_CACHE is defined, we empty advanced-cache.php to regenerate later. Otherwise it contains the path to free.
553 if (defined('WPO_ADVANCED_CACHE') && WPO_ADVANCED_CACHE) {
554 $advanced_cache_filename = trailingslashit(WP_CONTENT_DIR) . 'advanced-cache.php';
555
556 if (!is_file($advanced_cache_filename) && is_writable(dirname($advanced_cache_filename)) || (is_file($advanced_cache_filename) && is_writable($advanced_cache_filename))) {
557 file_put_contents($advanced_cache_filename, '');
558 }
559 }
560
561 // Registers the notice letting the user know it cannot be active if premium is active.
562 add_action('admin_notices', array($this, 'show_admin_notice_premium'));
563 return;
564 }
565
566 // Loads the task manager
567 $this->get_task_manager();
568
569 // Loads the language file.
570 load_plugin_textdomain('wp-optimize', false, dirname(plugin_basename(__FILE__)) . '/languages');
571
572 // Load page cache.
573 $this->get_page_cache();
574 $this->init_page_cache();
575
576 // Include minify
577 $this->get_minify();
578 $this->run_updates();
579 $this->get_webp_instance();
580 }
581
582 /**
583 * Filter cache tabs (when it is Kinsta)
584 *
585 * @param array $tabs An array of tabs
586 *
587 * @return array $tabs An array of tabs
588 */
589 public function filter_cache_tabs($tabs) {
590 unset($tabs['preload']);
591 unset($tabs['advanced']);
592 unset($tabs['gzip']);
593 unset($tabs['settings']);
594 return $tabs;
595 }
596
597 /**
598 * Check whether one of free/Premium is active (whether it is this instance or not)
599 *
600 * @param String $which - 'free' or 'premium'
601 *
602 * @return String|Boolean - plugin path (if installed) or false if not
603 */
604 private function is_active($which = 'free') {
605 $active_plugins = $this->get_active_plugins();
606 foreach ($active_plugins as $file) {
607 if ('wp-optimize.php' == basename($file)) {
608 $plugin_dir = WP_PLUGIN_DIR.'/'.dirname($file);
609 if (('free' == $which && !file_exists($plugin_dir.'/premium.php')) || ('free' != $which && file_exists($plugin_dir.'/premium.php'))) return $file;
610 }
611 }
612 return false;
613 }
614
615 /**
616 * Gets an array of plugins active on either the current site, or site-wide
617 *
618 * @return Array - a list of plugin paths (relative to the plugin directory)
619 */
620 private function get_active_plugins() {
621
622 // Gets all active plugins on the current site
623 $active_plugins = get_option('active_plugins');
624
625 if (is_multisite()) {
626 $network_active_plugins = get_site_option('active_sitewide_plugins');
627 if (!empty($network_active_plugins)) {
628 $network_active_plugins = array_keys($network_active_plugins);
629 $active_plugins = array_merge($active_plugins, $network_active_plugins);
630 }
631 }
632
633 return $active_plugins;
634 }
635
636 /**
637 * This function checks whether a specific plugin is installed, and returns information about it
638 *
639 * @param string $name Specify "Plugin Name" to return details about it.
640 * @return array Returns an array of details such as if installed, the name of the plugin and if it is active.
641 */
642 public function is_installed($name) {
643
644 // Needed to have the 'get_plugins()' function
645 include_once(ABSPATH.'wp-admin/includes/plugin.php');
646
647 // Gets all plugins available
648 $get_plugins = get_plugins();
649
650 $active_plugins = $this->get_active_plugins();
651
652 $plugin_info = array();
653 $plugin_info['installed'] = false;
654 $plugin_info['active'] = false;
655
656 // Loops around each plugin available.
657 foreach ($get_plugins as $key => $value) {
658 // If the plugin name matches that of the specified name, it will gather details.
659 if ($value['Name'] != $name && $value['TextDomain'] != $name) continue;
660 $plugin_info['installed'] = true;
661 $plugin_info['name'] = $key;
662 $plugin_info['version'] = $value['Version'];
663 if (in_array($key, $active_plugins)) {
664 $plugin_info['active'] = true;
665 }
666 break;
667 }
668 return $plugin_info;
669 }
670
671 /**
672 * This is a notice to show users that premium is installed
673 */
674 public function show_admin_notice_premium() {
675 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>';
676 if (isset($_GET['activate'])) unset($_GET['activate']);
677 }
678
679 /**
680 * Show update to Premium notice for non-premium multisite.
681 */
682 public function show_multisite_update_to_premium_notice() {
683 if (!is_multisite() || self::is_premium()) return;
684
685 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>';
686 }
687
688 public function admin_init() {
689 $pagenow = $GLOBALS['pagenow'];
690
691 $this->register_template_directories();
692
693 if (('index.php' == $pagenow && current_user_can('update_plugins')) || ('index.php' == $pagenow && defined('WP_OPTIMIZE_FORCE_DASHNOTICE') && WP_OPTIMIZE_FORCE_DASHNOTICE)) {
694 $options = $this->get_options();
695
696 $dismissed_until = $options->get_option('dismiss_dash_notice_until', 0);
697
698 if (file_exists(WPO_PLUGIN_MAIN_PATH . '/index.html')) {
699 $installed = filemtime(WPO_PLUGIN_MAIN_PATH . '/index.html');
700 $installed_for = (time() - $installed);
701 }
702
703 if (($installed && time() > $dismissed_until && $installed_for > (14 * 86400) && !defined('WP_OPTIMIZE_NOADS_B')) || (defined('WP_OPTIMIZE_FORCE_DASHNOTICE') && WP_OPTIMIZE_FORCE_DASHNOTICE)) {
704 add_action('all_admin_notices', array($this, 'show_admin_notice_upgradead'));
705 }
706 }
707 $this->install_or_update_notice = $this->get_install_or_update_notice();
708 if ($this->is_wp_smush_installed()) {
709 add_filter('transient_wp-smush-conflict_check', array($this, 'modify_wp_smush_conflict_check'), 9, 1);
710 }
711 }
712
713 /**
714 * Checks whether the WP Smush plugin is active or not
715 *
716 * @return bool
717 */
718 private function is_wp_smush_installed() {
719 return is_plugin_active('wp-smushit/wp-smush.php');
720 }
721
722 /**
723 * Remove WPO plugin name from WP Smushit transient value
724 *
725 * @return array $active_plugins
726 */
727 public function modify_wp_smush_conflict_check($active_plugins) {
728 // This can be boolean value since it is return value of get_transient
729 if (!is_array($active_plugins)) return $active_plugins;
730
731 if (false !== ($key = array_search('WP-Optimize - Clean, Compress, Cache', $active_plugins))) {
732 unset($active_plugins[$key]);
733 }
734 return $active_plugins;
735 }
736
737 /**
738 * Get the install or update notice instance
739 *
740 * @return WP_Optimize_Install_Or_Update_Notice
741 */
742 public function get_install_or_update_notice() {
743 static $instance = null;
744 if (is_a($instance, 'WP_Optimize_Install_Or_Update_Notice')) return $instance;
745 $instance = new WP_Optimize_Install_Or_Update_Notice();
746 return $instance;
747 }
748
749 public function show_admin_notice_upgradead() {
750 $this->include_template('notices/thanks-for-using-main-dash.php');
751 }
752
753 public function capability_required() {
754 return apply_filters('wp_optimize_capability_required', 'manage_options');
755 }
756
757 public function wp_optimize_ajax_handler() {
758 $nonce = empty($_POST['nonce']) ? '' : $_POST['nonce'];
759
760 if (!wp_verify_nonce($nonce, 'wp-optimize-ajax-nonce') || empty($_POST['subaction'])) {
761 wp_send_json(array(
762 'result' => false,
763 'error_code' => 'security_check',
764 'error_message' => __('The security check failed; try refreshing the page.', 'wp-optimize')
765 ));
766 }
767
768 $subaction = $_POST['subaction'];
769 $data = isset($_POST['data']) ? $_POST['data'] : null;
770
771 if (!current_user_can($this->capability_required())) {
772 wp_send_json(array(
773 'result' => false,
774 'error_code' => 'security_check',
775 'error_message' => __('You are not allowed to run this command.', 'wp-optimize')
776 ));
777 }
778
779
780 // Currently the settings are only available to network admins.
781 if (is_multisite() && !current_user_can('manage_network_options')) {
782 /**
783 * Filters the commands allowed to the subsite admins. Other commands are only available to network admin. Only used in a multisite context.
784 */
785 $allowed_commands = apply_filters('wpo_multisite_allowed_commands', array('check_server_status', 'compress_single_image', 'restore_single_image'));
786 if (!in_array($subaction, $allowed_commands)) wp_send_json(array(
787 'result' => false,
788 'error_code' => 'update_failed',
789 'error_message' => __('Options can only be saved by network admin', 'wp-optimize')
790 ));
791 }
792
793 $options = $this->get_options();
794
795 $results = array();
796
797 // Some commands that are available via AJAX only.
798 if (in_array($subaction, array('dismiss_dash_notice_until', 'dismiss_season'))) {
799 $options->update_option($subaction, (time() + 366 * 86400));
800 } elseif (in_array($subaction, array('dismiss_page_notice_until', 'dismiss_notice'))) {
801 $options->update_option($subaction, (time() + 84 * 86400));
802 } elseif ('dismiss_review_notice' == $subaction) {
803 if (empty($data['dismiss_forever'])) {
804 $options->update_option($subaction, time() + 84*86400);
805 } else {
806 $options->update_option($subaction, 100 * (365.25 * 86400));
807 }
808 } else {
809
810 $commands = new WP_Optimize_Commands();
811 $minify_commands = new WP_Optimize_Minify_Commands();
812
813
814 if (self::is_premium()) {
815 $cache_commands = new WP_Optimize_Cache_Commands_Premium();
816 } else {
817 $cache_commands = new WP_Optimize_Cache_Commands();
818 }
819
820 // check if called command not in main commands class and exist in cache commands class then change class.
821 if (!is_callable(array($commands, $subaction)) && is_callable(array($minify_commands, $subaction))) {
822 $commands = $minify_commands;
823 }
824
825 // check if called command not in main commands class and exist in cache commands class then change class.
826 if (!is_callable(array($commands, $subaction)) && is_callable(array($cache_commands, $subaction))) {
827 $commands = $cache_commands;
828 }
829
830 if (!is_callable(array($commands, $subaction))) {
831 error_log("WP-Optimize: ajax_handler: no such command (".$subaction.")");
832 $results = array(
833 'result' => false,
834 'error_code' => 'command_not_found',
835 'error_message' => sprintf(__('The command "%s" was not found', 'wp-optimize'), $subaction)
836 );
837 } else {
838 $results = call_user_func(array($commands, $subaction), $data);
839
840 // clean status box content, it broke json sometimes.
841 if (isset($results['status_box_contents'])) {
842 $results['status_box_contents'] = str_replace(array("\n", "\t"), '', $results['status_box_contents']);
843 }
844
845 if (is_wp_error($results)) {
846 $results = array(
847 'result' => false,
848 'error_code' => $results->get_error_code(),
849 'error_message' => $results->get_error_message(),
850 'error_data' => $results->get_error_data(),
851 );
852 }
853
854 // if nothing was returned for some reason, set as result null.
855 if (empty($results)) {
856 $results = array(
857 'result' => null
858 );
859 }
860 }
861 }
862
863 $result = json_encode($results);
864
865 // Requires PHP 5.3+
866 $json_last_error = function_exists('json_last_error') ? json_last_error() : false;
867
868 // if json_encode returned error then return error.
869 if ($json_last_error) {
870 $result = array(
871 'result' => false,
872 'error_code' => $json_last_error,
873 'error_message' => 'json_encode error : '.$json_last_error,
874 'error_data' => '',
875 );
876
877 $result = json_encode($result);
878 }
879
880 echo $result;
881
882 die;
883 }
884
885 /**
886 * Returns array of translations used in javascript code.
887 *
888 * @return array
889 */
890 public function wpo_js_translations() {
891 return apply_filters('wpo_js_translations', array(
892 'automatic_backup_before_optimizations' => __('Automatic backup before optimizations', 'wp-optimize'),
893 'error_unexpected_response' => __('An unexpected response was received.', 'wp-optimize'),
894 'optimization_complete' => __('Optimization complete', 'wp-optimize'),
895 'with_warnings' => __('(with warnings - open the browser console for more details)', 'wp-optimize'),
896 'optimizing_table' => __('Optimizing table:', 'wp-optimize'),
897 'run_optimizations' => __('Run optimizations', 'wp-optimize'),
898 'table_optimization_timeout' => 120000,
899 'cancel' => __('Cancel', 'wp-optimize'),
900 'cancelling' => __('Cancelling...', 'wp-optimize'),
901 'enable' => __('Enable', 'wp-optimize'),
902 'disable' => __('Disable', 'wp-optimize'),
903 'please_select_settings_file' => __('Please, select settings file.', 'wp-optimize'),
904 'are_you_sure_you_want_to_remove_logging_destination' => __('Are you sure you want to remove this logging destination?', 'wp-optimize'),
905 'fill_all_settings_fields' => __('Before saving, you need to complete the currently incomplete settings (or remove them).', 'wp-optimize'),
906 'table_was_not_repaired' => __('%s was not repaired. For more details, please check the logs (configured in your logging destinations settings).', 'wp-optimize'),
907 'table_was_not_deleted' => __('%s was not deleted. For more details, please check your logs configured in logging destinations settings.', 'wp-optimize'),
908 'table_was_not_converted' => __('%s was not converted to InnoDB. For more details, please check your logs configured in logging destinations settings.', 'wp-optimize'),
909 'please_use_positive_integers' => __('Please use positive integers.', 'wp-optimize'),
910 'please_use_valid_values' => __('Please use valid values.', 'wp-optimize'),
911 'update' => __('Update', 'wp-optimize'),
912 'run_now' => __('Run now', 'wp-optimize'),
913 'starting_preload' => __('Started preload...', 'wp-optimize'),
914 'loading_urls' => __('Loading URLs...', 'wp-optimize'),
915 'current_cache_size' => __('Current cache size:', 'wp-optimize'),
916 'number_of_files' => __('Number of files:', 'wp-optimize'),
917 'toggle_info' => __('Show information', 'wp-optimize'),
918 'added_to_list' => __('Added to the list', 'wp-optimize'),
919 'added_notice' => __('The file was added to the list', 'wp-optimize'),
920 'save_notice' => __('Save the changes', 'wp-optimize'),
921 'page_refresh' => __('Refreshing the page to reflect changes...', 'wp-optimize'),
922 'settings_have_been_deleted_successfully' => __('WP-Optimize settings have been deleted successfully.', 'wp-optimize'),
923 'loading_data' => __('Loading data...', 'wp-optimize'),
924 'spinner_src' => esc_attr(admin_url('images/spinner-2x.gif')),
925 'settings_page_url' => is_multisite() ? network_admin_url('admin.php?page=wpo_settings') : admin_url('admin.php?page=wpo_settings'),
926 'sites' => $this->get_sites(),
927 'user_always_ignores_table_delete_warning' => (get_user_meta(get_current_user_id(), 'wpo-ignores-table-delete-warning', true)) ? true : false,
928 'post_meta_tweak_completed' => __('The tweak has been performed.', 'wp-optimize'),
929 'no_minified_assets' => __('No minified files are present', 'wp-optimize'),
930 ));
931 }
932
933 /**
934 * Manages the admin bar menu for caching (currently page and minify)
935 */
936 public function cache_admin_bar($wp_admin_bar) {
937
938 $options = $this->get_options();
939 if (!$options->get_option('enable_cache_in_admin_bar', true)) return;
940
941 /**
942 * The "purge cache" menu items
943 *
944 * @param array $menu_items - The menu items, in the format required by $wp_admin_bar->add_menu()
945 * @param object $wp_admin_bar
946 */
947 $menu_items = apply_filters('wpo_cache_admin_bar_menu_items', array(), $wp_admin_bar);
948
949 if (empty($menu_items) || !is_array($menu_items)) return;
950
951 $wp_admin_bar->add_menu(array(
952 'id' => 'wpo_purge_cache',
953 'title' => __('Purge cache', 'wp-optimize'),
954 'href' => '#',
955 'meta' => array(
956 'title' => __('Purge cache', 'wp-optimize'),
957 ),
958 'parent' => false,
959 ));
960
961 foreach ($menu_items as $item) {
962 $wp_admin_bar->add_menu($item);
963 }
964 }
965
966 /**
967 * Add settings link on plugin page
968 *
969 * @param string $links Passing through the URL to be used within the HREF.
970 * @return string Returns the Links.
971 */
972 public function plugin_settings_link($links) {
973
974 $admin_page_url = $this->get_options()->admin_page_url();
975 $settings_page_url = $this->get_options()->admin_page_url('wpo_settings');
976
977 if (false == self::is_premium()) {
978 $premium_link = '<a href="' . esc_url($this->premium_version_link) . '" target="_blank">' . __('Premium', 'wp-optimize') . '</a>';
979 array_unshift($links, $premium_link);
980 }
981
982 $settings_link = '<a href="' . esc_url($settings_page_url) . '">' . __('Settings', 'wp-optimize') . '</a>';
983 array_unshift($links, $settings_link);
984
985 $optimize_link = '<a href="' . esc_url($admin_page_url) . '">' . __('Optimize', 'wp-optimize') . '</a>';
986 array_unshift($links, $optimize_link);
987 return $links;
988 }
989
990 /**
991 * Action wpo_tables_list_additional_column_data. Output button Optimize in the action column.
992 *
993 * @param string $content String for output to column
994 * @param object $table_info Object with table info.
995 *
996 * @return string
997 */
998 public function tables_list_additional_column_data($content, $table_info) {
999 if ($table_info->is_needing_repair) {
1000 $content .= '<div class="wpo_button_wrap">'
1001 . '<button class="button button-secondary run-single-table-repair" data-table="' . esc_attr($table_info->Name) . '">' . __('Repair', 'wp-optimize') . '</button>'
1002 . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1003 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1004 . '</div>';
1005 }
1006
1007 // table belongs to plugin.
1008 if ($table_info->can_be_removed) {
1009 $content .= '<div>'
1010 . '<button class="button button-secondary run-single-table-delete" data-table="' . esc_attr($table_info->Name) . '">' . __('Remove', 'wp-optimize') . '</button>'
1011 . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1012 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1013 . '</div>';
1014 }
1015
1016 // Add option for MyISAM to InnoDB conversion.
1017 if ('MyISAM' == $table_info->Engine) {
1018 $content .= '<div class="wpo_button_convert wpo_button_wrap">'
1019 . '<button class="button button-secondary toinnodb" data-table="' . esc_attr($table_info->Name) . '">' . __('Convert to InnoDB', 'wp-optimize') . '</button>'
1020 . '<img class="optimization_spinner visibility-hidden" src="' . esc_attr(admin_url('images/spinner-2x.gif')) . '" width="20" height="20" alt="...">'
1021 . '<span class="optimization_done_icon dashicons dashicons-yes visibility-hidden"></span>'
1022 . '</div>';
1023
1024 }
1025
1026 return $content;
1027 }
1028
1029 /**
1030 * Initialize WP-Optimize page cache.
1031 */
1032 public function init_page_cache() {
1033 if ($this->get_page_cache()->config->get_option('enable_page_caching', false)) {
1034 $this->get_page_cache()->enable();
1035 }
1036 }
1037
1038 /**
1039 * Schedules cron event based on selected schedule type
1040 *
1041 * @return void
1042 */
1043 public function cron_activate() {
1044 $gmt_offset = (int) (3600 * get_option('gmt_offset'));
1045
1046 $options = $this->get_options();
1047
1048 if ($options->get_option('schedule') === false) {
1049 $options->set_default_options();
1050 } else {
1051 if ('true' == $options->get_option('schedule')) {
1052 if (!wp_next_scheduled('wpo_cron_event2')) {
1053 $schedule_type = $options->get_option('schedule-type', 'wpo_weekly');
1054
1055 // Backward compatibility
1056 if ('wpo_otherweekly' == $schedule_type) $schedule_type = 'wpo_fortnightly';
1057
1058 $this_time = (86400 * 7);
1059
1060 switch ($schedule_type) {
1061 case "wpo_daily":
1062 $this_time = 86400;
1063 break;
1064
1065 case "wpo_weekly":
1066 $this_time = (86400 * 7);
1067 break;
1068
1069 case "wpo_fortnightly":
1070 $this_time = (86400 * 14);
1071 break;
1072
1073 case "wpo_monthly":
1074 $this_time = (86400 * 30);
1075 break;
1076 }
1077
1078 add_action('wpo_cron_event2', array($this, 'cron_action'));
1079 $result = wp_schedule_event((current_time("timestamp", 0) + $this_time - $gmt_offset), $schedule_type, 'wpo_cron_event2');
1080 WP_Optimize()->log('running wp_schedule_event()');
1081 if (is_wp_error($result)) {
1082 $error_msg = $result->get_error_message();
1083 WP_Optimize()->log($error_msg);
1084 WP_Optimize()->log(print_r($result, true));
1085 } else {
1086 WP_Optimize()->log($result);
1087 }
1088 }
1089 }
1090 }
1091 }
1092
1093 /**
1094 * Clears all cron events
1095 *
1096 * @return void
1097 */
1098 public function wpo_cron_deactivate() {
1099 $cron_jobs = _get_cron_array();
1100 foreach ($cron_jobs as $job) {
1101 foreach (array_keys($job) as $hook) {
1102 if (preg_match('/^wpo_/', $hook)) wp_unschedule_hook($hook);
1103 }
1104 }
1105 }
1106
1107 /**
1108 * Scheduler public functions to update schedulers
1109 *
1110 * @param array $schedules An array of schedules being passed.
1111 * @return array An array of schedules being returned.
1112 */
1113 public function cron_schedules($schedules) {
1114 $schedules['wpo_daily'] = array('interval' => 86400, 'display' => 'Once Daily');
1115 $schedules['wpo_weekly'] = array('interval' => 86400 * 7, 'display' => 'Once Weekly');
1116 $schedules['wpo_fortnightly'] = array('interval' => 86400 * 14, 'display' => 'Once Every Fortnight');
1117 $schedules['wpo_monthly'] = array('interval' => 86400 * 30, 'display' => 'Once Every Month');
1118 return $schedules;
1119 }
1120
1121 /**
1122 * Returns count of overdue cron jobs.
1123 *
1124 * @return integer
1125 */
1126 public function howmany_overdue_crons() {
1127 $how_many_overdue = 0;
1128 if (function_exists('_get_cron_array') || (is_file(ABSPATH.WPINC.'/cron.php') && include_once(ABSPATH.WPINC.'/cron.php') && function_exists('_get_cron_array'))) {
1129 $crons = _get_cron_array();
1130 if (is_array($crons)) {
1131 $timenow = time();
1132 foreach ($crons as $jt => $job) {
1133 if ($jt < $timenow) {
1134 $how_many_overdue++;
1135 }
1136 }
1137 }
1138 }
1139 return $how_many_overdue;
1140 }
1141
1142 /**
1143 * Run updates on plugin activation.
1144 */
1145 public function run_updates() {
1146 include_once(WPO_PLUGIN_MAIN_PATH.'includes/class-wp-optimize-updates.php');
1147 WP_Optimize_Updates::check_updates();
1148 }
1149
1150 /**
1151 * Returns warning about overdue crons.
1152 *
1153 * @param int $howmany count of overdue crons
1154 * @return string
1155 */
1156 public function show_admin_warning_overdue_crons($howmany) {
1157 $ret = '<div class="updated below-h2"><p>';
1158 $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>';
1159 $ret .= '</p></div>';
1160 return $ret;
1161 }
1162
1163 private function wp_normalize_path($path) {
1164 // Wp_normalize_path is not present before WP 3.9.
1165 if (function_exists('wp_normalize_path')) return wp_normalize_path($path);
1166 // Taken from WP 4.6.
1167 $path = str_replace('\\', '/', $path);
1168 $path = preg_replace('|(?<=.)/+|', '/', $path);
1169 if (':' === substr($path, 1, 1)) {
1170 $path = ucfirst($path);
1171 }
1172 return $path;
1173 }
1174
1175 public function get_templates_dir() {
1176 return apply_filters('wp_optimize_templates_dir', $this->wp_normalize_path(WPO_PLUGIN_MAIN_PATH.'templates'));
1177 }
1178
1179 public function get_templates_url() {
1180 return apply_filters('wp_optimize_templates_url', WPO_PLUGIN_URL.'/templates');
1181 }
1182
1183 /**
1184 * Return or output view content
1185 *
1186 * @param String $path - path to template, usually relative to templates/ within the WP-O directory
1187 * @param Boolean $return_instead_of_echo - what to do with the results
1188 * @param Array $extract_these - key/value pairs for substitution into the scope of the template
1189 *
1190 * @return String|Void
1191 */
1192 public function include_template($path, $return_instead_of_echo = false, $extract_these = array()) {
1193 if ($return_instead_of_echo) ob_start();
1194
1195 if (preg_match('#^([^/]+)/(.*)$#', $path, $matches)) {
1196 $prefix = $matches[1];
1197 $suffix = $matches[2];
1198 if (isset($this->template_directories[$prefix])) {
1199 $template_file = $this->template_directories[$prefix].'/'.$suffix;
1200 }
1201 }
1202
1203 if (!isset($template_file)) {
1204 $template_file = WPO_PLUGIN_MAIN_PATH.'templates/'.$path;
1205 }
1206
1207 $template_file = apply_filters('wp_optimize_template', $template_file, $path);
1208
1209 do_action('wp_optimize_before_template', $path, $template_file, $return_instead_of_echo, $extract_these);
1210
1211 if (!file_exists($template_file)) {
1212 error_log("WP Optimize: template not found: ".$template_file);
1213 echo __('Error:', 'wp-optimize').' '.__('template not found', 'wp-optimize')." (".$path.")";
1214 } else {
1215 extract($extract_these);
1216 // The following are useful variables which can be used in the template.
1217 // They appear as unused, but may be used in the $template_file.
1218 $wpdb = $GLOBALS['wpdb'];// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wpdb might be used in the included template
1219 $wp_optimize = $this;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wp_optimize might be used in the included template
1220 $optimizer = $this->get_optimizer();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $optimizer might be used in the included template
1221 $options = $this->get_options();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $options might be used in the included template
1222 $wp_optimize_notices = $this->get_notices();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wp_optimize_notices might be used in the included template
1223 include $template_file;
1224 }
1225
1226 do_action('wp_optimize_after_template', $path, $template_file, $return_instead_of_echo, $extract_these);
1227
1228 if ($return_instead_of_echo) return ob_get_clean();
1229 }
1230
1231 /**
1232 * Build a list of template directories (stored in self::$template_directories)
1233 */
1234 private function register_template_directories() {
1235
1236 $template_directories = array();
1237
1238 $templates_dir = $this->get_templates_dir();
1239
1240 if ($dh = opendir($templates_dir)) {
1241 while (($file = readdir($dh)) !== false) {
1242 if ('.' == $file || '..' == $file) continue;
1243 if (is_dir($templates_dir.'/'.$file)) {
1244 $template_directories[$file] = $templates_dir.'/'.$file;
1245 }
1246 }
1247 closedir($dh);
1248 }
1249
1250 // Optimal hook for most extensions to hook into.
1251 $this->template_directories = apply_filters('wp_optimize_template_directories', $template_directories);
1252
1253 }
1254
1255 /**
1256 * Message to debug
1257 *
1258 * @param string $message Message to insert into the log.
1259 * @param array $context array with variables used in $message like in template,
1260 * for ex.
1261 * $message = 'Hello {message}';
1262 * $context = ['message' => 'world']
1263 * 'Hello world' string will be saved in log.
1264 */
1265 public function log($message, $context = array()) {
1266 $this->get_logger()->debug($message, $context);
1267 }
1268
1269 /**
1270 * Format Bytes Into KB/MB
1271 *
1272 * @param mixed $bytes Number of bytes to be converted.
1273 * @param integer $decimals the number of decimal digits
1274 * @return integer return the correct format size.
1275 */
1276 public function format_size($bytes, $decimals = 2) {
1277 if (!is_numeric($bytes)) return __('N/A', 'wp-optimize');
1278
1279 if (1073741824 <= $bytes) {
1280 $bytes = number_format($bytes / 1073741824, $decimals) . ' GB';
1281 } elseif (1048576 <= $bytes) {
1282 $bytes = number_format($bytes / 1048576, $decimals) . ' MB';
1283 } elseif (1024 <= $bytes) {
1284 $bytes = number_format($bytes / 1024, $decimals) . ' KB';
1285 } elseif (1 < $bytes) {
1286 $bytes = $bytes . ' bytes';
1287 } elseif (1 == $bytes) {
1288 $bytes = $bytes . ' byte';
1289 } else {
1290 $bytes = '0 bytes';
1291 }
1292
1293 return $bytes;
1294 }
1295
1296 /**
1297 * Format a timestamp into a juman readable date time
1298 *
1299 * @param int $timestamp
1300 * @return string
1301 */
1302 public function format_date_time($timestamp) {
1303 return date_i18n(get_option('date_format').' @ '.get_option('time_format'), ($timestamp + get_option('gmt_offset') * 3600));
1304 }
1305
1306 /**
1307 * Executed this function on cron event.
1308 *
1309 * @return void
1310 */
1311 public function cron_action() {
1312
1313 $optimizer = $this->get_optimizer();
1314 $options = $this->get_options();
1315
1316 $this->log('WPO: Starting cron_action()');
1317 $options->update_option('last-optimized', time());
1318 if ('true' == $options->get_option('schedule')) {
1319 $this_options = $options->get_option('auto');
1320
1321 // Currently the output of the optimizations is not saved/used/logged.
1322 $optimizer->do_optimizations($this_options, 'auto');
1323 }
1324
1325 }
1326
1327 /**
1328 * Schedule cron tasks used by plugin.
1329 *
1330 * @return void
1331 */
1332 public function schedule_plugin_cron_tasks() {
1333 if (!wp_next_scheduled('wpo_weekly_cron_tasks')) {
1334 wp_schedule_event(current_time("timestamp", 0), 'weekly', 'wpo_weekly_cron_tasks');
1335 }
1336
1337 add_action('wpo_weekly_cron_tasks', array($this, 'do_weekly_cron_tasks'));
1338 }
1339
1340 /**
1341 * Do plugin background tasks.
1342 *
1343 * @return void
1344 */
1345 public function do_weekly_cron_tasks() {
1346 // add tasks here.
1347 $this->get_db_info()->update_plugin_json();
1348 }
1349
1350 /**
1351 * This will customize a URL with a correct Affiliate link
1352 * This function can be update to suit any URL as longs as the URL is passed
1353 *
1354 * @param String $url - URL to be check to see if it an updraftplus match.
1355 * @param String $text - Text to be entered within the href a tags.
1356 * @param String $html - Any specific HTML to be added.
1357 * @param String $class - Specify a class for the href (including the attribute label)
1358 * @param Boolean $return_instead_of_echo - if set, then the result will be returned, not echo-ed.
1359 *
1360 * @return String|void
1361 */
1362 public function wp_optimize_url($url, $text, $html = '', $class = '', $return_instead_of_echo = false) {
1363 // Check if the URL is UpdraftPlus.
1364 $url = $this->maybe_add_affiliate_params($url); // Return URL - check if there is HTML such as images.
1365 if ('' != $html) {
1366 $result = '<a '.$class.' href="'.esc_attr($url).'">'.$html.'</a>';
1367 } else {
1368 $result = '<a '.$class.' href="'.esc_attr($url).'">'.htmlspecialchars($text).'</a>';
1369 }
1370 if ($return_instead_of_echo) return $result;
1371 echo $result;
1372 }
1373
1374 /**
1375 * Get an URL with an eventual affiliate ID
1376 *
1377 * @param string $url
1378 * @return string
1379 */
1380 public function maybe_add_affiliate_params($url) {
1381 // Check if the URL is UpdraftPlus.
1382 if (false !== strpos($url, '//updraftplus.com')) {
1383 // Set URL with Affiliate ID.
1384 $url = add_query_arg(array('afref' => $this->get_notices()->get_affiliate_id()), $url);
1385
1386 // Apply filters.
1387 $url = apply_filters('wpoptimize_updraftplus_com_link', $url);
1388 }
1389 return apply_filters('wpoptimize_maybe_add_affiliate_params', $url);
1390 }
1391
1392 /**
1393 * Setup WPO logger(s)
1394 */
1395 public function setup_loggers() {
1396
1397 $logger = $this->get_logger();
1398 $loggers = $this->wpo_loggers();
1399
1400 if (!empty($loggers)) {
1401 foreach ($loggers as $_logger) {
1402 $logger->add_logger($_logger);
1403 }
1404 }
1405
1406 add_action('wp_optimize_after_optimizations', array($this, 'after_optimizations_logger_action'));
1407 }
1408
1409 /**
1410 * Run logger actions after all optimizations done
1411 */
1412 public function after_optimizations_logger_action() {
1413 $loggers = $this->get_logger()->get_loggers();
1414 if (!empty($loggers)) {
1415 foreach ($loggers as $logger) {
1416 if (is_a($logger, 'Updraft_Email_Logger')) {
1417 $logger->flush_log();
1418 }
1419 }
1420 }
1421 }
1422
1423 /**
1424 * Returns list of WPO loggers instances
1425 * Apply filter wp_optimize_loggers
1426 *
1427 * @return array
1428 */
1429 public function wpo_loggers() {
1430
1431 $loggers = array();
1432 $loggers_classes_by_id = array();
1433 $options_keys = array();
1434
1435 $loggers_classes = $this->get_loggers_classes();
1436
1437 foreach ($loggers_classes as $logger_class => $source) {
1438 $loggers_classes_by_id[strtolower($logger_class)] = $logger_class;
1439 }
1440
1441 $options = $this->get_options();
1442
1443 $saved_loggers = $options->get_option('logging');
1444 $logger_additional_options = $options->get_option('logging-additional');
1445
1446 // create loggers classes instances.
1447 if (!empty($saved_loggers)) {
1448 // check for previous version options format.
1449 $keys = array_keys($saved_loggers);
1450
1451 // if options stored in old format then reformat it.
1452 if (false == is_numeric($keys[0])) {
1453 $_saved_loggers = array();
1454 foreach ($saved_loggers as $logger_id => $enabled) {
1455 if ($enabled) {
1456 $_saved_loggers[] = $logger_id;
1457 }
1458 }
1459
1460 // fill email with admin.
1461 if (array_key_exists('updraft_email_logger', $saved_loggers) && $saved_loggers['updraft_email_logger']) {
1462 $logger_additional_options['updraft_email_logger'] = array(
1463 get_option('admin_email')
1464 );
1465 }
1466
1467 $saved_loggers = $_saved_loggers;
1468 }
1469
1470 foreach ($saved_loggers as $i => $logger_id) {
1471
1472 if (!array_key_exists($logger_id, $loggers_classes_by_id)) continue;
1473
1474 $logger_class = $loggers_classes_by_id[$logger_id];
1475
1476 $logger = new $logger_class();
1477
1478 $logger_options = $logger->get_options_list();
1479
1480 if (!empty($logger_options)) {
1481 foreach (array_keys($logger_options) as $option_name) {
1482 if (array_key_exists($option_name, $options_keys)) {
1483 $options_keys[$option_name]++;
1484 } else {
1485 $options_keys[$option_name] = 0;
1486 }
1487
1488 $option_value = isset($logger_additional_options[$option_name][$options_keys[$option_name]]) ? $logger_additional_options[$option_name][$options_keys[$option_name]] : '';
1489
1490 // if options in old format then get correct value.
1491 if ('' === $option_value && array_key_exists($logger_id, $logger_additional_options)) {
1492 $option_value = array_shift($logger_additional_options[$logger_id]);
1493 }
1494
1495 $logger->set_option($option_name, $option_value);
1496 }
1497 }
1498
1499 // check if logger is active.
1500 $active = (!is_array($logger_additional_options) || (array_key_exists('active', $logger_additional_options) && empty($logger_additional_options['active'][$i]))) ? false : true;
1501
1502 if ($active) {
1503 $logger->enable();
1504 } else {
1505 $logger->disable();
1506 }
1507
1508 $loggers[] = $logger;
1509 }
1510 }
1511
1512 $loggers = apply_filters('wp_optimize_loggers', $loggers);
1513
1514 return $loggers;
1515 }
1516
1517 /**
1518 * Returns associative array with logger class name in a key and path to class file in a value.
1519 *
1520 * @return array
1521 */
1522 public function get_loggers_classes() {
1523 $loggers_classes = array(
1524 'Updraft_PHP_Logger' => WPO_PLUGIN_MAIN_PATH . 'includes/class-updraft-php-logger.php',
1525 'Updraft_Email_Logger' => WPO_PLUGIN_MAIN_PATH . 'includes/class-updraft-email-logger.php',
1526 'Updraft_Ring_Logger' => WPO_PLUGIN_MAIN_PATH . 'includes/class-updraft-ring-logger.php'
1527 );
1528
1529 $loggers_classes = apply_filters('wp_optimize_loggers_classes', $loggers_classes);
1530
1531 if (!empty($loggers_classes)) {
1532 foreach ($loggers_classes as $logger_class => $logger_file) {
1533 if (!class_exists($logger_class)) {
1534 if (is_file($logger_file)) {
1535 include_once($logger_file);
1536 }
1537 }
1538 }
1539 }
1540
1541 return $loggers_classes;
1542 }
1543
1544 /**
1545 * Returns information about all loggers classes.
1546 *
1547 * @return array
1548 */
1549 public function get_loggers_classes_info() {
1550 $loggers_classes = $this->get_loggers_classes();
1551
1552 $loggers_classes_info = array();
1553
1554 if (!empty($loggers_classes)) {
1555 foreach (array_keys($loggers_classes) as $logger_class_name) {
1556
1557 if (!class_exists($logger_class_name)) continue;
1558
1559 $logger_id = strtolower($logger_class_name);
1560 $logger_class = new $logger_class_name();
1561
1562 $loggers_classes_info[$logger_id] = array(
1563 'description' => $logger_class->get_description(),
1564 'available' => $logger_class->is_available(),
1565 'allow_multiple' => $logger_class->is_allow_multiple(),
1566 'options' => $logger_class->get_options_list()
1567 );
1568 }
1569 }
1570
1571 return $loggers_classes_info;
1572 }
1573
1574 /**
1575 * Returns true if optimization works in multisite mode
1576 *
1577 * @return boolean
1578 */
1579 public function is_multisite_mode() {
1580 return (is_multisite() && self::is_premium());
1581 }
1582
1583 /**
1584 * Returns true if current user can run optimizations.
1585 *
1586 * @return bool
1587 */
1588 public function can_run_optimizations() {
1589 // we don't check permissions for cron jobs.
1590 if (defined('DOING_CRON') && DOING_CRON) return true;
1591
1592 if (self::is_premium() && false == user_can(get_current_user_id(), 'wpo_run_optimizations')) return false;
1593 return true;
1594 }
1595
1596 /**
1597 * Returns true if current user can manage plugin options.
1598 *
1599 * @return bool
1600 */
1601 public function can_manage_options() {
1602 if (self::is_premium() && false == user_can(get_current_user_id(), 'wpo_manage_settings')) return false;
1603 return true;
1604 }
1605
1606 /**
1607 * CHeck if current user can purge the cache.
1608 *
1609 * @return bool
1610 */
1611 public function can_purge_the_cache() {
1612 if (self::is_premium()) {
1613 return WP_Optimize_Premium()->can_purge_the_cache();
1614 }
1615
1616 return true;
1617 }
1618
1619 /**
1620 * Returns list of all sites in multisite
1621 *
1622 * @return array
1623 */
1624 public function get_sites() {
1625 $sites = array();
1626 // check if function get_sites exists (since 4.6.0) else use wp_get_sites.
1627 if (function_exists('get_sites')) {
1628 $sites = get_sites(array('network_id' => null, 'deleted' => 0, 'number' => 999999));
1629 } elseif (function_exists('wp_get_sites')) {
1630 $sites = wp_get_sites(array('network_id' => null, 'deleted' => 0, 'limit' => 999999));
1631 }
1632 return $sites;
1633 }
1634
1635 /**
1636 * Returns script memory limit in megabytes.
1637 *
1638 * @param bool $memory_limit
1639 * @return int
1640 */
1641 public function get_memory_limit($memory_limit = false) {
1642 // Returns in megabytes
1643 if (false == $memory_limit) $memory_limit = ini_get('memory_limit');
1644 $memory_limit = rtrim($memory_limit);
1645
1646 return $this->return_bytes($memory_limit);
1647 }
1648
1649 /**
1650 * Returns free memory in bytes.
1651 *
1652 * @return int
1653 */
1654 public function get_free_memory() {
1655 return $this->get_memory_limit() - memory_get_usage();
1656 }
1657
1658 /**
1659 * Checks PHP memory_limit and WP_MAX_MEMORY_LIMIT values and return minimal.
1660 *
1661 * @return int memory limit in bytes.
1662 */
1663 public function get_script_memory_limit() {
1664 $memory_limit = $this->get_memory_limit();
1665
1666 if (defined('WP_MAX_MEMORY_LIMIT')) {
1667 $wp_memory_limit = $this->get_memory_limit(WP_MAX_MEMORY_LIMIT);
1668
1669 if ($wp_memory_limit > 0 && $wp_memory_limit < $memory_limit) {
1670 $memory_limit = $wp_memory_limit;
1671 }
1672 }
1673
1674 return $memory_limit;
1675 }
1676
1677 /**
1678 * Returns max packet size for database.
1679 *
1680 * @return int|string
1681 */
1682 public function get_max_packet_size() {
1683 global $wpdb;
1684 static $mp = 0;
1685
1686 if ($mp > 0) return $mp;
1687
1688 $mp = (int) $wpdb->get_var("SELECT @@session.max_allowed_packet");
1689 // Default to 1MB
1690 $mp = (is_numeric($mp) && $mp > 0) ? $mp : 1048576;
1691 // 32MB
1692 if ($mp < 33554432) {
1693 $save = $wpdb->show_errors(false);
1694 @$wpdb->query("SET GLOBAL max_allowed_packet=33554432");// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
1695 $wpdb->show_errors($save);
1696
1697 $mp = (int) $wpdb->get_var("SELECT @@session.max_allowed_packet");
1698 // Default to 1MB
1699 $mp = (is_numeric($mp) && $mp > 0) ? $mp : 1048576;
1700 }
1701
1702 return $mp;
1703 }
1704
1705 /**
1706 * Converts shorthand memory notation value to bytes.
1707 * From http://php.net/manual/en/function.ini-get.php
1708 *
1709 * @param string $val shorthand memory notation value.
1710 */
1711 public function return_bytes($val) {
1712 $val = trim($val);
1713 $last = strtolower($val[strlen($val)-1]);
1714 $val = (int) $val;
1715 switch ($last) {
1716 case 'g':
1717 $val *= 1024;
1718 // no break
1719 case 'm':
1720 $val *= 1024;
1721 // no break
1722 case 'k':
1723 $val *= 1024;
1724 }
1725
1726 return $val;
1727 }
1728
1729 /**
1730 * Log fatal errors to defined log destinations.
1731 */
1732 public function log_fatal_errors() {
1733 $last_error = error_get_last();
1734
1735 if (isset($last_error['type']) && E_ERROR === $last_error['type']) {
1736 $this->get_logger()->critical($last_error['message']);
1737 }
1738 }
1739
1740 /**
1741 * Close browser connection and continue script work. - Taken from UpdraftPlus
1742 *
1743 * @param array $txt Response to browser; this must be JSON (or if not, alter the Content-Type header handling below)
1744 * @return void
1745 */
1746 public function close_browser_connection($txt = '') {
1747 if (!headers_sent()) {
1748 // Close browser connection so that it can resume AJAX polling
1749 header('Content-Length: '.(empty($txt) ? '0' : 4+strlen($txt)));
1750 header('Connection: close');
1751 header('Content-Encoding: none');
1752 }
1753
1754 if (session_id()) session_write_close();
1755 echo "\r\n\r\n";
1756 echo $txt;
1757 // These two added - 19-Feb-15 - started being required on local dev machine, for unknown reason (probably some plugin that started an output buffer).
1758 $ob_level = ob_get_level();
1759 while ($ob_level > 0) {
1760 ob_end_flush();
1761 $ob_level--;
1762 }
1763 flush();
1764 if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();
1765 }
1766
1767 /**
1768 * Get the current theme's style.css headers
1769 *
1770 * @return array|WP_Error
1771 */
1772 public function get_stylesheet_headers() {
1773 static $headers;
1774 if (isset($headers)) return $headers;
1775
1776 $style = get_template_directory_uri() . '/style.css';
1777
1778 /**
1779 * Filters wp_remote_get parameters, when checking if browser cache is enabled.
1780 *
1781 * @param array $request_params Default parameters
1782 */
1783 $request_params = apply_filters('wpoptimize_get_stylesheet_headers_args', array('timeout' => 10));
1784
1785 // trying to load style.css.
1786 $response = wp_remote_get($style, $request_params);
1787
1788 if (is_a($response, 'WP_Error')) return $response;
1789
1790 $headers = wp_remote_retrieve_headers($response);
1791
1792 if (is_a($headers, 'Requests_Utility_CaseInsensitiveDictionary')) {
1793 $headers = $headers->getAll();
1794 }
1795
1796 return $headers;
1797 }
1798
1799 /**
1800 * Try to change PHP script time limit.
1801 */
1802 public function change_time_limit() {
1803 $time_limit = (defined('WP_OPTIMIZE_SET_TIME_LIMIT') && WP_OPTIMIZE_SET_TIME_LIMIT > 15) ? WP_OPTIMIZE_SET_TIME_LIMIT : 1800;
1804
1805 // Try to reduce the chances of PHP self-terminating via reaching max_execution_time.
1806 @set_time_limit($time_limit); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
1807 }
1808
1809 /**
1810 * Does the request come from UDC
1811 *
1812 * @return boolean
1813 */
1814 public function is_updraft_central_request() {
1815 return defined('UPDRAFTCENTRAL_COMMAND') && UPDRAFTCENTRAL_COMMAND;
1816 }
1817
1818 /**
1819 * Does the data need to be included in this request. Currently only true if the request is made from UpdraftCentral.
1820 *
1821 * @return boolean
1822 */
1823 public function template_should_include_data() {
1824 /**
1825 * Filters wether data should be included in certain templates or not.
1826 */
1827 return apply_filters('wpo_template_should_include_data', $this->is_updraft_central_request());
1828 }
1829
1830 /**
1831 * Load the templates for the modal window
1832 */
1833 public function load_modal_template() {
1834 $this->include_template('modal.php');
1835 }
1836
1837 /**
1838 * Delete transients and semaphores data from options table.
1839 */
1840 public function delete_transients_and_semaphores() {
1841 global $wpdb;
1842
1843 $masks = array(
1844 'updraft_locked_wpo_%',
1845 'updraft_unlocked_wpo_%',
1846 'updraft_last_lock_time_wpo_%',
1847 'updraft_semaphore_wpo_%',
1848 'wpo_locked_%',
1849 'wpo_unlocked_%',
1850 'wpo_last_lock_time_%',
1851 'wpo_semaphore_%',
1852 '_transient_timeout_wpo_%',
1853 '_transient_wpo_%',
1854 'updraft_lock_wpo_%',
1855 );
1856
1857 $where_parts = array();
1858 foreach ($masks as $mask) {
1859 $where_parts[] = "(`option_name` LIKE '{$mask}')";
1860 }
1861
1862 $wpdb->query("DELETE FROM {$wpdb->options} WHERE " . join(' OR ', $where_parts));
1863 }
1864
1865 /**
1866 * Prevents bots from indexing plugins list
1867 */
1868 public function robots_txt($output) {
1869 $upload_dir = wp_upload_dir();
1870 $path = parse_url($upload_dir['baseurl']);
1871 $output .= "\nDisallow: " . str_replace($path['scheme'].'://'.$path['host'], '', $upload_dir['baseurl']) . "/wpo-plugins-tables-list.json\n";
1872 return $output;
1873 }
1874 }
1875
1876 /**
1877 * Plugin activation actions.
1878 */
1879 function wpo_activation_actions() {
1880 // If plugin activated by not a Network Administrator then deactivate plugin and show message.
1881 if (is_multisite() && !is_network_admin()) {
1882 deactivate_plugins(plugin_basename(__FILE__));
1883 wp_die(__('Only Network Administrator can activate WP-Optimize plugin.', 'wp-optimize').
1884 ' <a href="'.admin_url('plugins.php').'">'.__('go back', 'wp-optimize').'</a>');
1885 }
1886
1887 // On activation, check if last-optimized option exists. If not, add 'newly-activated' option.
1888 if (!WP_Optimize()->get_options()->get_option('last-optimized', false)) {
1889 WP_Optimize()->get_options()->update_option('newly-activated', true);
1890 }
1891
1892 WP_Optimize()->get_options()->set_default_options();
1893 WP_Optimize()->get_minify()->plugin_activate();
1894
1895 WP_Optimize::get_gzip_compression()->restore();
1896 WP_Optimize::get_browser_cache()->restore();
1897
1898 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');
1899 Updraft_Tasks_Activation::init_db();
1900 Updraft_Tasks_Activation::reinstall_if_needed();
1901
1902 // run premium activation actions.
1903 if (file_exists(WPO_PLUGIN_MAIN_PATH.'premium.php')) {
1904 if (!class_exists('WP_Optimize_Premium')) {
1905 include_once(WPO_PLUGIN_MAIN_PATH.'premium.php');
1906 }
1907 WP_Optimize_Premium()->plugin_activation_actions();
1908 }
1909 }
1910
1911 /**
1912 * Plugin deactivation actions.
1913 */
1914 function wpo_deactivation_actions() {
1915 WP_Optimize()->wpo_cron_deactivate();
1916 WP_Optimize()->get_page_cache()->disable();
1917 WP_Optimize()->get_minify()->plugin_deactivate();
1918 WP_Optimize::get_gzip_compression()->disable();
1919 WP_Optimize::get_browser_cache()->disable();
1920 }
1921
1922 function wpo_cron_deactivate() {
1923 WP_Optimize()->log('running wpo_cron_deactivate()');
1924 wp_clear_scheduled_hook('wpo_cron_event2');
1925 wp_clear_scheduled_hook('wpo_weekly_cron_tasks');
1926 }
1927
1928 /**
1929 * Plugin uninstall actions.
1930 */
1931 function wpo_uninstall_actions() {
1932 WP_Optimize::get_gzip_compression()->disable();
1933 WP_Optimize::get_browser_cache()->disable();
1934 WP_Optimize()->get_options()->delete_all_options();
1935 WP_Optimize()->get_minify()->plugin_uninstall();
1936 WP_Optimize()->get_options()->wipe_settings();
1937 WP_Optimize()->delete_transients_and_semaphores();
1938 }
1939
1940 function WP_Optimize() {
1941 return WP_Optimize::instance();
1942 }
1943
1944 endif;
1945
1946 $GLOBALS['wp_optimize'] = WP_Optimize();
1947