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
wp-optimize / includes / class-wp-optimize-commands.php

class-wp-optimize-commands.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 4.7.0, at includes/class-wp-optimize-commands.php

2,510 lines 80.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) die('No direct access allowed');
4
5 /**
6 * All commands that are intended to be available for calling from any sort of control interface (e.g. wp-admin, UpdraftCentral) go in here. All public methods should either return the data to be returned, or a WP_Error with associated error code, message and error data.
7 */
8 class WP_Optimize_Commands {
9
10 private $optimizer;
11
12 protected $options;
13
14 private $wpo_sites; // used in get_optimizations_info command.
15
16 public function __construct() {
17 $this->optimizer = WP_Optimize()->get_optimizer();
18 $this->options = WP_Optimize()->get_options();
19 }
20
21 public function get_version() {
22 return WPO_VERSION;
23 }
24
25 public function enable_or_disable_feature($data) {
26
27 $type = (string) $data['type'];
28 $enable = (bool) $data['enable'];
29
30 $options = array($type => $enable);
31
32 return $this->optimizer->trackback_comment_actions($options);
33 }
34
35 public function save_manual_run_optimization_options($sent_options) {
36 return $this->options->save_sent_manual_run_optimization_options($sent_options);
37 }
38
39 public function get_status_box_contents() {
40 $status_data = $this->get_all_status_data();
41
42 return WP_Optimize()->include_template('database/status-box-contents.php', true, $status_data);
43 }
44
45 /**
46 * Get the database tabs information.
47 *
48 * @return string auto cleanup content.
49 */
50 public function get_settings_auto_cleanup_contents() {
51 $settings_cleanup_data = $this->get_wp_optimize_schedule_cleanup_settings_data();
52
53 return WP_Optimize()->include_template('database/settings-auto-cleanup.php', true, array('show_innodb_option' => WP_Optimize()->template_should_include_data() && $this->optimizer->show_innodb_force_optimize(), 'settings_cleanup_data' => $settings_cleanup_data));
54 }
55
56 /**
57 * Get the settings tab information.
58 *
59 * @return string logging settings content.
60 */
61 public function get_logging_settings_contents() {
62 $loggers_data = $this->get_wp_optimize_logging_settings_data();
63 return WP_Optimize()->include_template('settings/settings-logging.php', true, array('loggers_data' => $loggers_data));
64 }
65
66 /**
67 * Get the database tabs information
68 *
69 * @return string database table optimization rendered content
70 */
71 public function get_optimizations_table() {
72
73 $optimization_data = $this->get_wp_optimize_data();
74
75 return WP_Optimize()->include_template('database/optimizations-table.php', true, $optimization_data);
76 }
77
78 /**
79 * [For UpdraftCentral] Returns the file content containing the list of unused images
80 *
81 * @return WP_Error|void
82 */
83 public function download_csv() {
84 if (!WP_Optimize()->current_user_can()) {
85 return $this->request_error('insufficient_privilege');
86 }
87
88 WP_Optimize()->get_optimizer()->get_optimization('images')->output_csv();
89 }
90
91 /**
92 * [For UpdraftCentral] Retrieves the tabs and their corresponding contents, assets basing
93 * from the current page or section requested (e.g. database, images, cache, minify or settings)
94 *
95 * @param array $params Parameters needed for the requested action
96 * @return array|WP_Error
97 */
98 public function get_section($params) {
99 if (!WP_Optimize()->current_user_can()) {
100 return $this->request_error('insufficient_privilege');
101 }
102
103 $section_id = $params['section'];
104 $section = $this->get_section_to_tab_name($section_id);
105 $tabs = WP_Optimize()->get_admin_instance()->get_tabs($section);
106
107 // We remove the UpdraftCentral management tab when managing WP-Optimize
108 // plugin from the UpdraftCentral dashboard if it exists.
109 if (isset($tabs['updraftcentral'])) unset($tabs['updraftcentral']);
110
111 $this->load_action_hooks_for_content($section_id);
112 return array(
113 'tabs' => $tabs,
114 'tabs_content' => $this->get_tab_contents($tabs, $section),
115 'assets' => $this->get_localized_variables(),
116 'wposmush' => $this->get_wposmush(),
117 'is_premium' => WP_Optimize::is_premium(),
118 'modal_template' => WP_Optimize()->include_template('modal.php', true),
119 );
120 }
121
122 /**
123 * [For UpdraftCentral] Retrieves the list of items to optimize from the current database
124 *
125 * @return array|WP_Error
126 */
127 public function get_database_tabs_info() {
128 if (!WP_Optimize()->current_user_can()) {
129 return $this->request_error('insufficient_privilege');
130 }
131
132 return $this->get_database_tabs();
133 }
134
135 /**
136 * [For UpdraftCentral] Processes specific Smush commands from ajax requests
137 *
138 * @param array $params Parameters needed for the requested action
139 * @return array|WP_Error
140 */
141 public function updraft_smush_ajax($params) {
142 if (!WP_Optimize()->current_user_can()) {
143 return $this->request_error('insufficient_privilege');
144 }
145
146 $subaction = $params['subaction'];
147 $data = $params['data'];
148
149 $allowed_commands = Updraft_Smush_Manager_Commands::get_allowed_ajax_commands();
150 if (in_array($subaction, $allowed_commands)) {
151 if (in_array($subaction, array('get_smush_logs', 'process_bulk_smush'))) {
152 switch ($subaction) {
153 case 'get_smush_logs':
154 $results = $this->get_smush_logs();
155 break;
156 case 'process_bulk_smush':
157 $results = $this->process_bulk_smush($data);
158 break;
159 default:
160 break;
161 }
162 } else {
163 if (!empty($data)) {
164 $results = call_user_func(array(Updraft_Smush_Manager()->commands, $subaction), $data);
165 } else {
166 $results = call_user_func(array(Updraft_Smush_Manager()->commands, $subaction));
167 }
168 }
169
170 if (is_wp_error($results)) {
171 return $this->request_error($results->get_error_code(), null, array(
172 'status' => true,
173 'error_message' => $results->get_error_message(),
174 'error_data' => $results->get_error_data(),
175 ));
176 } else {
177 return $results;
178 }
179 } else {
180 return $this->request_error('command_not_found');
181 }
182 }
183
184 /**
185 * [For UpdraftCentral] Processes general WP-Optimize commands from ajax requests
186 *
187 * @param array $params Parameters needed for the requested action
188 * @return array|WP_Error
189 */
190 public function handle_ajax_requests($params) {
191 if (!WP_Optimize()->current_user_can()) {
192 return $this->request_error('insufficient_privilege');
193 }
194
195 $subaction = $params['subaction'];
196 $data = $params['data'];
197
198 $response = array();
199 if (is_multisite() && !WP_Optimize()->current_user_can('manage_network_options')) {
200 $allowed_multisite_commands = apply_filters('wpo_multisite_allowed_commands', array('check_server_status', 'compress_single_image', 'restore_single_image'));
201
202 if (!in_array($subaction, $allowed_multisite_commands)) {
203 return $this->request_error('network_admin_only');
204 }
205 }
206
207 $dismiss_actions = array(
208 'dismiss_dash_notice_until',
209 'dismiss_season',
210 'dismiss_page_notice_until',
211 'dismiss_notice',
212 'dismiss_review_notice',
213 );
214
215 if (in_array($subaction, $dismiss_actions)) {
216 $options = WP_Optimize()->get_options();
217
218 // Some commands that are available via AJAX only.
219 if (in_array($subaction, array('dismiss_dash_notice_until', 'dismiss_season'))) {
220 $options->update_option($subaction, (time() + 366 * 86400));
221 } elseif (in_array($subaction, array('dismiss_page_notice_until', 'dismiss_notice'))) {
222 $options->update_option($subaction, (time() + 84 * 86400));
223 } elseif ('dismiss_review_notice' === $subaction) {
224 if (empty($data['dismiss_forever'])) {
225 $options->update_option($subaction, time() + 84 * 86400);
226 } else {
227 $options->update_option($subaction, 100 * (365.25 * 86400));
228 }
229 }
230
231 } else {
232 $commands = new WP_Optimize_Commands();
233
234 $minify_commands = new WP_Optimize_Minify_Commands();
235 if (!is_callable(array($commands, $subaction)) && is_callable(array($minify_commands, $subaction))) {
236 $commands = $minify_commands;
237 }
238
239 if (WP_Optimize::is_premium()) {
240 $cache_commands = new WP_Optimize_Cache_Commands_Premium();
241 } else {
242 $cache_commands = new WP_Optimize_Cache_Commands();
243 }
244
245 if (!is_callable(array($commands, $subaction)) && is_callable(array($cache_commands, $subaction))) {
246 $commands = $cache_commands;
247 }
248
249 // Check if command is valid
250 if (!is_callable(array($commands, $subaction))) {
251 return $this->request_error('command_not_found');
252 } else {
253 $response = call_user_func(array($commands, $subaction), $data);
254 if (is_wp_error($response)) {
255 return $this->request_error($response->get_error_code(), null, array(
256 'error_message' => $response->get_error_message(),
257 'error_data' => $response->get_error_data(),
258 ));
259 } elseif (empty($response)) {
260 $response = array(
261 'result' => null
262 );
263 } else {
264 if (isset($response['status_box_contents'])) {
265 $response['status_box_contents'] = str_replace(array("\n", "\t"), '', $response['status_box_contents']);
266 }
267 }
268 }
269 }
270
271 return $response;
272 }
273
274 /**
275 * [For UpdraftCentral] Retrieves a list of posts to purge as options to be displayed under
276 * cache - advanced settings
277 *
278 * @param array $params Parameters needed for the requested action
279 * @return array|WP_Error
280 */
281 public function get_posts_list($params) {
282 if (!WP_Optimize()->current_user_can()) {
283 return $this->request_error('insufficient_privilege');
284 }
285
286 $response = array();
287 if (WP_Optimize::is_premium()) {
288 $commands = new WP_Optimize_Cache_Commands_Premium();
289 if (is_callable(array($commands, 'get_posts_list'))) {
290 $response = $commands->get_posts_list($params);
291 }
292 }
293
294 return $response;
295 }
296
297 /**
298 * [For UpdraftCentral] loads the settings page
299 *
300 * @return void
301 */
302 public function output_dashboard_settings_tab() {
303 $wpo_admin = WP_Optimize()->get_admin_instance();
304
305 if (WP_Optimize()->can_manage_options()) {
306 $loggers_data = $this->get_wp_optimize_logging_settings_data();
307 $settings_trackback_data = $this->get_wp_optimize_trackback_toggle_settings_data();
308 $settings_comments_data = $this->get_wp_optimize_comments_toggle_settings_data();
309 $settings_general_data = $this->get_wp_optimize_general_settings_data();
310
311 WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data, 'settings_trackback_data' => $settings_trackback_data, 'settings_comments_data' => $settings_comments_data, 'settings_general_data' => $settings_general_data));
312 } else {
313 $wpo_admin->prevent_manage_options_info();
314 }
315 }
316
317 /**
318 * [For UpdraftCentral] Retrieves Smush JS variables
319 *
320 * @return array
321 */
322 private function get_wposmush() {
323 if (!class_exists('Updraft_Smush_Manager')) return array();
324
325 $js_variables = Updraft_Smush_Manager()->smush_js_translations();
326 $js_variables['ajaxurl'] = admin_url('admin-ajax.php');
327 $js_variables['features'] = Updraft_Smush_Manager()->get_features();
328
329 return $js_variables;
330 }
331
332 /**
333 * [For UpdraftCentral] Execute smush process in bulk
334 *
335 * @param array $data Parameters to be pass as argument for the requested action
336 * @return string
337 */
338 private function process_bulk_smush($data) {
339 ob_start();
340 Updraft_Smush_Manager()->commands->process_bulk_smush($data);
341 $content = ob_get_contents();
342 ob_end_clean();
343
344 return $content;
345 }
346
347 /**
348 * [For UpdraftCentral] Retrieves the content of a Smush log file
349 *
350 * @return string|false|WP_Error
351 */
352 private function get_smush_logs() {
353 $logfile = Updraft_Smush_Manager()->get_logfile_path();
354 if (!file_exists($logfile)) {
355 Updraft_Smush_Manager()->write_log_header();
356 }
357
358 if (is_file($logfile)) {
359 return file_get_contents($logfile);
360 } else {
361 return $this->request_error('log_file_not_exist');
362 }
363 }
364
365 /**
366 * [For UpdraftCentral] Loads the WP-Optimize hooks needed to pull the tab contents for
367 * the requested page/section
368 *
369 * @param string $section_id The id of the page or section where the content is to be pulled from
370 * @return void
371 */
372 private function load_action_hooks_for_content($section_id) {
373 $wpo = WP_Optimize();
374 $wpo_admin = $wpo->get_admin_instance();
375
376 // dashboard
377 if ('dashboard' === $section_id) {
378 add_action('wp_optimize_admin_page_WP-Optimize_dashboard', array($wpo_admin, 'output_dashboard'), 20);
379 }
380
381 // Database
382 if ('database' === $section_id) {
383 add_action('wp_optimize_admin_page_wpo_database_optimize', array($wpo_admin, 'output_database_optimize_tab'), 20);
384 add_action('wp_optimize_admin_page_wpo_database_tables', array($wpo_admin, 'output_database_tables_tab'), 20);
385 add_action('wp_optimize_admin_page_wpo_database_settings', array($wpo_admin, 'output_database_settings_tab'), 20);
386 }
387
388 // Images
389 if ('images' === $section_id) {
390 add_action('wp_optimize_admin_page_wpo_images_smush', array($wpo, 'admin_page_wpo_images_smush'));
391
392 if (!WP_Optimize::is_premium()) {
393 add_action('wp_optimize_admin_page_wpo_images_unused', array($wpo_admin, 'admin_page_wpo_images_unused'));
394 add_action('wp_optimize_admin_page_wpo_images_lazyload', array($wpo_admin, 'admin_page_wpo_images_lazyload'));
395 }
396 }
397
398 // Cache
399 if ('cache' === $section_id) {
400 add_action('wp_optimize_admin_page_wpo_cache_cache', array($wpo_admin, 'output_page_cache_tab'), 20);
401 add_action('wp_optimize_admin_page_wpo_cache_preload', array($wpo_admin, 'output_page_cache_preload_tab'), 20);
402 add_action('wp_optimize_admin_page_wpo_cache_advanced', array($wpo_admin, 'output_page_cache_advanced_tab'), 20);
403 add_action('wp_optimize_admin_page_wpo_cache_gzip', array($wpo_admin, 'output_cache_gzip_tab'), 20);
404 add_action('wp_optimize_admin_page_wpo_cache_settings', array($wpo_admin, 'output_cache_settings_tab'), 20);
405 }
406
407 // Minify
408 if ('minify' === $section_id) {
409 if (class_exists('WP_Optimize_Minify_Admin')) {
410 do_action('wp_optimize_register_admin_content');
411 }
412 }
413
414 // Settings
415 if ('settings' === $section_id) {
416 add_action('wp_optimize_admin_page_wpo_settings_settings', array($this, 'output_dashboard_settings_tab'), 20);
417 }
418 }
419
420 /**
421 * [For UpdraftCentral] Execute the hooks needed to pull the content of the tabs under the requested page/section
422 *
423 * @param array $tabs The list of tabs available under the current page/section
424 * @param string $section The id of the page or section
425 * @return array
426 */
427 private function get_tab_contents($tabs, $section) {
428 $contents = array();
429
430 foreach ($tabs as $tab_id => $tab_description) {
431 ob_start();
432 // output wrap div for tab with id #wp-optimize-nav-tab-contents-'.$section.'-'.$tab_id
433 echo '<div class="wp-optimize-nav-tab-contents" id="wp-optimize-nav-tab-'.esc_attr($section).'-'.esc_attr($tab_id).'-contents">';
434
435 echo '<div class="postbox wpo-tab-postbox">';
436
437 // call action for generate tab content.
438 do_action('wp_optimize_admin_page_'.$section.'_'.$tab_id);
439
440 // closes postbox.
441 echo '</div><!-- END .postbox -->';
442 // closes tab wrapper.
443 echo '</div><!-- END .wp-optimize-nav-tab-contents -->';
444 $tab_content = ob_get_contents();
445 ob_end_clean();
446
447 $contents[$tab_id] = $tab_content;
448 }
449
450 return $contents;
451 }
452
453 /**
454 * [For UpdraftCentral] Replaces the names/id used in UpdraftCentral with the actual name used in WP-Optimize
455 *
456 * @param string $section_id The id of the page or section
457 * @return string
458 */
459 private function get_section_to_tab_name($section_id) {
460 $tab = '';
461 switch ($section_id) {
462 case 'dashboard':
463 $tab = 'WP-Optimize';
464 break;
465 default:
466 $tab = 'wpo_'.$section_id;
467 break;
468 }
469 return $tab;
470 }
471
472 /**
473 * [For UpdraftCentral] Retrieves the localized scripts/variables (e.g. translations, etc.) used by WP-Optimize
474 *
475 * @return array
476 */
477 private function get_localized_variables() {
478 $wpo = WP_Optimize();
479 $js_variables = $wpo->wpo_js_translations();
480 $js_variables['loggers_classes_info'] = $wpo->get_loggers_classes_info();
481 $js_variables['ajaxurl'] = admin_url('admin-ajax.php');
482
483 $localized_variables = array(
484 'wpoptimize' => $js_variables,
485 'wp_optimize_send_command_data' => array('nonce' => wp_create_nonce('wp-optimize-ajax-nonce')),
486 'wpo_heartbeat_ajax' => array(
487 'ajaxurl' => admin_url('admin-ajax.php'),
488 'nonce' => wp_create_nonce('heartbeat-nonce'),
489 'interval' => WPO_Ajax::HEARTBEAT_INTERVAL
490 ),
491 );
492
493 if (WP_Optimize::is_premium()) {
494 $localized_variables = array_merge($localized_variables, array(
495 'wp_optimize_minify_premium' => array(
496 'home_url' => home_url()
497 )
498 ));
499 }
500
501 return array(
502 'localize' => $localized_variables,
503 );
504 }
505
506 /**
507 * [For UpdraftCentral] Returns a WP_Error response for the current request
508 *
509 * @param string $code The error code
510 * @param ?string $message_key The key to use to query any translatable message if applicable
511 * @param array $additional_data Any additional data to return
512 * @return WP_Error
513 */
514 public function request_error($code, $message_key = null, $additional_data = array()) {
515 global $updraftcentral_host_plugin;
516
517 $error_message = $updraftcentral_host_plugin->retrieve_show_message($code);
518 if (!is_null($message_key) && $code !== $message_key) {
519 $error_message = $updraftcentral_host_plugin->retrieve_show_message($message_key);
520 }
521
522 $data = array(
523 'result' => false,
524 'error_code' => $code,
525 'error_message' => $error_message,
526 'error' => true,
527 'code' => $code,
528 'message' => $error_message,
529 );
530
531 if (!empty($additional_data)) {
532 $data = array_merge($data, $additional_data);
533 }
534
535 return new WP_Error($code, $error_message, $data);
536 }
537
538 /**
539 * Pulls and return the "WP Optimize" template contents. Primarily used for UpdraftCentral
540 * content display through ajax request.
541 *
542 * @return array An array containing the WPO translations and the "WP Optimize" tab's rendered contents
543 */
544 public function get_wp_optimize_contents() {
545 $status_data = $this->get_all_status_data();
546 $optimization_data = $this->get_wp_optimize_data();
547 $content = WP_Optimize()->include_template('database/optimize-table.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data(), 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization(), 'optimizations_table_data' => $optimization_data, 'status_data' => $status_data));
548
549 if (WP_Optimize()->is_updraft_central_request()) {
550 $content .= $this->get_status_box_contents();
551 }
552
553 return array(
554 'content' => $content,
555 'translations' => $this->get_js_translation()
556 );
557 }
558
559 /**
560 * Pulls and return the "Table Information" template contents. Primarily used for UpdraftCentral
561 * content display through ajax request.
562 *
563 * @return array An array containing the WPO translations and the "Table Information" tab's rendered contents
564 */
565 public function get_table_information_contents() {
566 $table_list_data = $this->get_table_list_data();
567 $content = WP_Optimize()->include_template('database/tables.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data(), 'table_list_data' => $table_list_data['data']));
568
569 return array(
570 'content' => $content,
571 'translations' => $this->get_js_translation()
572 );
573 }
574
575 /**
576 * Pulls and return the "Settings" template contents. Primarily used for UpdraftCentral
577 * content display through ajax request.
578 *
579 * @return array An array containing the WPO translations and the "Settings" tab's rendered contents
580 */
581 public function get_settings_contents() {
582 $admin_settings = '<form action="#" method="post" enctype="multipart/form-data" name="settings_form" id="settings_form">';
583
584 $settings_general_data = $this->get_wp_optimize_general_settings_data();
585 $admin_settings .= WP_Optimize()->include_template('database/settings-general.php', true, $settings_general_data);
586
587 $settings_cleanup_data = $this->get_wp_optimize_schedule_cleanup_settings_data();
588 $admin_settings .= WP_Optimize()->include_template('database/settings-auto-cleanup.php', true, array('show_innodb_option' => WP_Optimize()->template_should_include_data() && $this->optimizer->show_innodb_force_optimize(), 'settings_cleanup_data' => $settings_cleanup_data));
589
590 $loggers_data = $this->get_wp_optimize_logging_settings_data();
591 $admin_settings .= WP_Optimize()->include_template('settings/settings-logging.php', true, array('loggers_data' => $loggers_data));
592
593 $admin_settings .= '<input id="wp-optimize-settings-save" class="button button-primary" type="submit" name="wp-optimize-settings" value="' . esc_attr__('Save settings', 'wp-optimize') .'" />';
594 $admin_settings .= '</form>';
595
596 $settings_trackback_data = $this->get_wp_optimize_trackback_toggle_settings_data();
597 $settings_comments_data = $this->get_wp_optimize_comments_toggle_settings_data();
598 $admin_settings .= WP_Optimize()->include_template('settings/settings-trackback-and-comments.php', true, array('settings_trackback_data' => $settings_trackback_data, 'settings_comments_data' => $settings_comments_data));
599
600 $content = $admin_settings;
601
602 return array(
603 'content' => $content,
604 'translations' => $this->get_js_translation()
605 );
606 }
607
608 /**
609 * Returns array of translations used by the WPO plugin. Primarily used for UpdraftCentral
610 * consumption.
611 *
612 * @param array $params Optional parameters for the translation request
613 * @return array The WPO translations
614 */
615 public function get_js_translation($params = array()) {
616 $translations = WP_Optimize()->wpo_js_translations();
617
618 // Make sure that we include the loggers classes info whenever applicable before
619 // returning the translations to UpdraftCentral.
620 if (is_callable(array(WP_Optimize(), 'get_loggers_classes_info'))) {
621 $translations['loggers_classes_info'] = WP_Optimize()->get_loggers_classes_info();
622 }
623
624 if (isset($params['return_formatted_response'])) {
625 return array(
626 'error' => false,
627 'data' => array(
628 'translations' => $translations,
629 )
630 );
631 }
632
633 return $translations;
634 }
635
636 /**
637 * Save settings command.
638 *
639 * @param string $data
640 * @return array
641 */
642 public function save_settings($data) {
643
644 parse_str(stripslashes($data), $posted_settings);
645
646 $saved_settings = $this->options->save_settings($posted_settings);
647 // We now have $posted_settings as an array.
648 return array(
649 'save_results' => $saved_settings,
650 'status_box_contents' => $this->get_status_box_contents(),
651 'optimizations_table' => $this->get_optimizations_table(),
652 'settings_auto_cleanup_contents' => $this->get_settings_auto_cleanup_contents(),
653 'logging_settings_contents' => $this->get_logging_settings_contents(),
654 );
655 }
656
657 /**
658 * Wipe settings command.
659 *
660 * @return bool|int
661 */
662 public function wipe_settings() {
663 $result = $this->options->wipe_settings();
664
665 $onboarding = WP_Optimize()->get_onboarding();
666 $onboarding->activate_onboarding_wizard();
667
668 return $result;
669 }
670
671 /**
672 * Save lazy load settings.
673 *
674 * @param string $data
675 * @return array
676 */
677 public function save_lazy_load_settings($data) {
678 parse_str(stripslashes($data), $posted_settings);
679
680 return array(
681 'save_result' => $this->options->save_lazy_load_settings($posted_settings)
682 );
683 }
684
685 /**
686 * This sends the selected tick value over to the save function
687 * within class-wp-optimize-options.php
688 *
689 * @param array $data An array of data that includes true or false for click option.
690 * @return array
691 */
692 public function save_auto_backup_option($data) {
693 return array('save_auto_backup_option' => $this->options->save_auto_backup_option($data));
694 }
695
696 /**
697 * Save option which sites to optimize in multisite mode.
698 *
699 * @param array $data Array of settings.
700 * @return bool
701 */
702 public function save_site_settings($data) {
703 if (!isset($data['wpo-sites'])) {
704 // this means no site selected
705 $data['wpo-sites'] = array();
706 }
707 return $this->options->save_wpo_sites_option($data['wpo-sites']);
708 }
709
710 /**
711 * Perform the requested optimization
712 *
713 * @param array $params Should have keys 'optimization_id' and 'data'.
714 * @return array
715 */
716 public function do_optimization($params) {
717
718 if (!isset($params['optimization_id'])) {
719 $results = array(
720 'result' => false,
721 'messages' => array(),
722 'errors' => array(
723 __('No optimization was indicated.', 'wp-optimize')
724 )
725 );
726 } else {
727 $optimization_id = $params['optimization_id'];
728 $data = $params['data'] ?? array();
729 $include_ui_elements = $data['include_ui_elements'] ?? false;
730
731 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
732
733 $result = is_a($optimization, 'WP_Optimization') ? $optimization->do_optimization() : null;
734
735 if (null !== $result) {
736 WP_Optimize()->get_options()->update_option('last-optimized', time());
737 }
738
739 $results = array(
740 'result' => $result,
741 'messages' => array(),
742 'errors' => array(),
743 );
744
745 if ($include_ui_elements) {
746 $results['status_box_contents'] = $this->get_status_box_contents();
747 }
748
749 if (is_wp_error($optimization)) {
750 $results['errors'][] = $optimization->get_error_message().' ('.$optimization->get_error_code().')';
751 }
752
753 if ($include_ui_elements && $optimization->get_changes_table_data()) {
754 $table_list = $this->get_table_list();
755 $results['table_list'] = $table_list['table_list'];
756 $results['total_size'] = $table_list['total_size'];
757 }
758 }
759 return $results;
760 }
761
762 /**
763 * Preview command, used to show information about data should be optimized in popup tool.
764 *
765 * @param array $params Should have keys 'optimization_id', 'offset' and 'limit'.
766 *
767 * @return array
768 */
769 public function preview($params) {
770 if (!isset($params['optimization_id'])) {
771 $results = array(
772 'result' => false,
773 'messages' => array(),
774 'errors' => array(
775 __('No optimization was indicated.', 'wp-optimize')
776 )
777 );
778 } else {
779 $optimization_id = $params['optimization_id'];
780 $data = $params['data'] ?? array();
781 $params['offset'] = isset($params['offset']) ? (int) $params['offset'] : 0;
782 $params['limit'] = isset($params['limit']) ? (int) $params['limit'] : 50;
783
784 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
785
786 if (is_a($optimization, 'WP_Optimization')) {
787 if (isset($params['site_id'])) {
788 $optimization->switch_to_blog((int) $params['site_id']);
789 }
790 $result = $optimization->preview($params);
791 } else {
792 $result = null;
793 }
794
795 $results = array(
796 'result' => $result,
797 'messages' => array(),
798 'errors' => array()
799 );
800 }
801
802 return $results;
803 }
804
805 /**
806 * Get information about requested optimization.
807 *
808 * @param array $params Should have keys 'optimization_id' and 'data'.
809 * @return array
810 */
811 public function get_optimization_info($params) {
812 if (!isset($params['optimization_id'])) {
813 $results = array(
814 'result' => false,
815 'messages' => array(),
816 'errors' => array(
817 __('No optimization was indicated.', 'wp-optimize')
818 )
819 );
820 } else {
821 $optimization_id = $params['optimization_id'];
822 $data = $params['data'] ?? array();
823 $include_ui_elements = $data['include_ui_elements'] ?? false;
824
825 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
826 $result = is_a($optimization, 'WP_Optimization') ? $optimization->get_optimization_info() : null;
827
828 $results = array(
829 'result' => $result,
830 'messages' => array(),
831 'errors' => array(),
832 );
833
834 if ($include_ui_elements) {
835 $results['status_box_contents'] = $this->get_status_box_contents();
836 }
837 }
838
839 return $results;
840 }
841
842 /**
843 * Get the data for the tables tab
844 *
845 * @param array $data
846 * @return array
847 */
848 public function get_table_list($data = array()) {
849 if (isset($data['refresh_plugin_json']) && filter_var($data['refresh_plugin_json'], FILTER_VALIDATE_BOOLEAN)) WP_Optimize()->get_db_info()->update_plugin_json();
850
851 $table_list_data = $this->get_table_list_data();
852
853 if (WP_Optimize()->is_updraft_central_request()) {
854 return $table_list_data;
855 }
856
857 $size = $this->optimizer->get_current_db_size();
858
859 $tables_data = array(
860 'table_list' => WP_Optimize()->include_template('database/tables-body.php', true, $table_list_data['data']),
861 'total_size' => $size[0],
862 );
863
864 $filtered_tables_data = apply_filters('wpo_get_tables_data', $tables_data);
865 if (!empty($filtered_tables_data) && is_array($filtered_tables_data)) return $filtered_tables_data;
866 return $tables_data;
867 }
868
869 /**
870 * Get the database tabs information
871 *
872 * @return array
873 */
874 public function get_database_tabs() {
875 $optimizer = $this->optimizer;
876 $scan_pending = $optimizer->is_table_count_too_high() && !$optimizer->is_large_table_count_scan_complete();
877
878 $result = array(
879 'optimizations' => $this->get_optimizations_table(),
880 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization(),
881 'scan_pending' => $scan_pending,
882 );
883
884 if (!$scan_pending) {
885 $result = array_merge($result, $this->get_table_list());
886 }
887
888 return $result;
889 }
890
891 /**
892 * Do action wp_optimize_after_optimizations
893 * used in ajax request after all optimizations completed
894 *
895 * @return boolean
896 */
897 public function optimizations_done() {
898
899 $this->options->update_option('total-cleaned', 0);
900 // Run action after all optimizations completed.
901 do_action('wp_optimize_after_optimizations');
902
903 return true;
904 }
905
906 /**
907 * Return information about all optimizations.
908 *
909 * @param array $params
910 * @return array
911 */
912 public function get_optimizations_info($params) {
913 $this->wpo_sites = $params['wpo-sites'] ?? 0;
914
915 add_filter('get_optimization_blogs', array($this, 'get_optimization_blogs_filter'));
916
917 $results = array();
918 $optimizations = $this->optimizer->get_optimizations();
919
920 foreach ($optimizations as $optimization_id => $optimization) {
921 if (false === $optimization->display_in_optimizations_list()) continue;
922
923 $results[$optimization_id] = $optimization->get_settings_html();
924 }
925
926 return $results;
927 }
928
929 /**
930 * Filter for get_optimizations_blogs function, used in get_optimizations_info command.
931 * Not intended for direct usage as a command (is used internally as a WP filter)
932 *
933 * The class variable $wpo_sites is used for performing the filtering.
934 *
935 * @param array $sites - unfiltered list of sites
936 * @return array - after filtering
937 */
938 public function get_optimization_blogs_filter($sites) {
939 $sites = array();
940
941 if (!empty($this->wpo_sites)) {
942 foreach ($this->wpo_sites as $site) {
943 if ('all' !== $site) $sites[] = $site;
944 }
945 }
946
947 return $sites;
948 }
949
950 /**
951 * Checks overdue crons and return message
952 *
953 * @return array
954 */
955 public function check_overdue_crons() {
956 $overdue_crons = WP_Optimize()->howmany_overdue_crons();
957
958 if ($overdue_crons >= 4) {
959 return array('m' => WP_Optimize()->show_admin_warning_overdue_crons($overdue_crons));
960 }
961
962 return array();
963 }
964
965 /**
966 * Enable or disable Gzip compression.
967 *
968 * @param array $params - ['enable' => true|false]
969 * @return array
970 */
971 public function enable_gzip_compression($params) {
972 return WP_Optimize()->get_gzip_compression()->enable_gzip_command_handler($params);
973 }
974
975 /**
976 * Get the current gzip compression status
977 *
978 * @return array
979 */
980 public function get_gzip_compression_status() {
981 $status = WP_Optimize()->get_gzip_compression()->is_gzip_compression_enabled(false);
982 return is_wp_error($status) ? array('error' => __('We could not determine if Gzip compression is enabled.', 'wp-optimize'), 'code' => $status->get_error_code(), 'message' => $status->get_error_message()) : array('status' => $status);
983 }
984
985 /**
986 * Get compression test results html formatted
987 *
988 * @return array
989 */
990 public function get_compression_test_results_html() {
991 $results_html = WP_Optimize()->get_gzip_compression()->get_compression_test_results_html();
992 $gzip_compression_control_panel = WP_Optimize_Admin::instance()->get_gzip_compression_control_panel();
993
994 return array(
995 'results_html' => $results_html,
996 'gzip_compression_control_panel' => $gzip_compression_control_panel,
997 );
998 }
999
1000 /**
1001 * Import WP-Optimize settings.
1002 *
1003 * @param array $params array with 'settings' item where 'settings' json-encoded string.
1004 *
1005 * @return array - the results of the import operation
1006 */
1007 public function import_settings($params) {
1008 if (empty($params['settings'])) {
1009 return array('errors' => array(__('Please upload a valid settings file.', 'wp-optimize')));
1010 }
1011
1012 $settings = json_decode($params['settings'], true);
1013
1014 // check if valid json file posted
1015 if (JSON_ERROR_NONE !== json_last_error() || empty($settings)) {
1016 return array('errors' => array(__('Please upload a valid settings file.', 'wp-optimize')));
1017 }
1018
1019 $cache_settings = $settings['cache_settings'];
1020 $minify_settings = $settings['minify_settings'];
1021 $smush_settings = $settings['smush_settings'];
1022 $database_settings = $settings['database_settings'];
1023
1024 $cache = WP_Optimize()->get_page_cache();
1025 $cache->create_folders();
1026 $cache_enable_result = null;
1027 if ($cache_settings['enable_page_caching']) {
1028 $cache_enable_result = $cache->enable();
1029 }
1030
1031 $wpo_browser_cache = WP_Optimize()->get_browser_cache();
1032 if (isset($cache_settings['enable_browser_cache']) && $cache_settings['enable_browser_cache']) {
1033 $browser_cache = array(
1034 'browser_cache_expire_days' => $cache_settings['browser_cache_expire_days'],
1035 'browser_cache_expire_hours' => $cache_settings['browser_cache_expire_hours']
1036 );
1037 $wpo_browser_cache->enable_browser_cache_command_handler($browser_cache);
1038 }
1039
1040 $message = '';
1041 $cache_result = WP_Optimize()->get_page_cache()->config->update($cache_settings);
1042 $minify_result = WP_Optimize()->get_minify()->minify_commands->save_minify_settings($minify_settings);
1043 $smush_result = WP_Optimize()->get_task_manager()->commands->update_smush_options($smush_settings);
1044 $webp_result = WP_Optimize()->get_task_manager()->commands->update_webp_options($smush_settings);
1045 $this->save_settings($database_settings);
1046
1047 if (is_wp_error($cache_enable_result)) {
1048 $message .= $cache_enable_result->get_error_message() . PHP_EOL;
1049 }
1050
1051 if (is_wp_error($cache_result)) {
1052 $message .= $cache_result->get_error_message() . PHP_EOL;
1053 }
1054
1055 if (!$minify_result['success']) {
1056 $message .= isset($minify_result['message']) ? $minify_result['message'] . PHP_EOL : '';
1057 $message .= isset($minify_result['error']) ? $minify_result['error'] . PHP_EOL : '';
1058 }
1059
1060 if (is_wp_error($smush_result)) {
1061 $message .= $smush_result->get_error_message() . PHP_EOL;
1062 }
1063
1064 if (is_wp_error($webp_result)) {
1065 $message .= $webp_result->get_error_message() . PHP_EOL;
1066 }
1067
1068 return array(
1069 'success' => true,
1070 'message' => empty($message) ? __('The settings were imported successfully.', 'wp-optimize') : $message
1071 );
1072 }
1073
1074 /**
1075 * Dismiss install or updated notice
1076 *
1077 * @return array
1078 */
1079 public function dismiss_install_or_update_notice() {
1080 if (!is_a(WP_Optimize()->get_install_or_update_notice(), 'WP_Optimize_Install_Or_Update_Notice') || !is_callable(array(WP_Optimize()->get_install_or_update_notice(), 'dismiss'))) {
1081 return array('errors' => array('The notice could not be dismissed. The method "dismiss" on the object instance "install_or_update_notice" does not seem to exist.'));
1082 }
1083
1084 if (!WP_Optimize()->get_install_or_update_notice()->dismiss()) {
1085 return array('errors' => array('The notice could not be dismissed. The settings could not be updated'));
1086 }
1087
1088 return array();
1089 }
1090
1091 /**
1092 * Run images trash command.
1093 *
1094 * @param array $params
1095 *
1096 * @return array
1097 */
1098 public function images_trash_command($params) {
1099 if (!class_exists('WP_Optimize_Images_Trash_Manager_Commands')) {
1100 return array(
1101 'errors' => array('WP_Optimize_Images_Trash_Manager_Commands class not found'),
1102 );
1103 }
1104
1105 // get posted command.
1106 $trash_command = $params['images_trash_command'] ?? '';
1107 // check if command is allowed.
1108 $allowed_commands = WP_Optimize_Images_Trash_Manager_Commands::get_allowed_ajax_commands();
1109
1110 if (!in_array($trash_command, $allowed_commands)) {
1111 return array(
1112 'errors' => array('No such command found'),
1113 );
1114 }
1115
1116 $results = call_user_func(array(WP_Optimize_Images_Trash_Manager()->commands, $trash_command), $params);
1117
1118 if (is_wp_error($results)) {
1119 $results = array(
1120 'errors' => array($results->get_error_message()),
1121 );
1122 }
1123
1124 return $results;
1125 }
1126
1127 /**
1128 * Power tweak handling
1129 *
1130 * @param array $params
1131 * @return array
1132 */
1133 public function power_tweak($params) {
1134 global $wp_optimize_premium;
1135 if (!is_a($wp_optimize_premium, 'WP_Optimize_Premium') || !property_exists($wp_optimize_premium, 'power_tweaks') || !isset($params['sub_action'])) return array(
1136 'errors' => array(__('No such command found', 'wp-optimize')),
1137 );
1138
1139 $action = $params['sub_action'];
1140 $data = $params['data'] ?: array();
1141 if (!isset($data['tweak'])) return array(
1142 'errors' => array(__('No tweak provided', 'wp-optimize'))
1143 );
1144
1145 $tweak = sanitize_title($data['tweak']);
1146 $pt = $wp_optimize_premium->power_tweaks;
1147 switch($action) {
1148 case 'activate':
1149 $result = $pt->activate($tweak);
1150 break;
1151 case 'deactivate':
1152 $result = $pt->deactivate($tweak);
1153 break;
1154 case 'run':
1155 $result = $pt->run($tweak);
1156 break;
1157 }
1158 if ($result && !is_wp_error($result)) {
1159 return is_array($result) ? array_merge(array('success' => true), $result) : array('success' => true, 'message' => $result);
1160 } else {
1161 // translators: %s is an action/command
1162 $error_message = is_wp_error($result) ? $result->get_error_message() : sprintf(__('The command %s failed', 'wp-optimize'), $action);
1163 return array(
1164 'success' => false,
1165 'errors' => array($error_message)
1166 );
1167 }
1168 }
1169
1170 /**
1171 * Ignores the table deletion warning for the current user
1172 *
1173 * @return array
1174 */
1175 public function user_ignores_table_deletion_warning() {
1176 return array(
1177 'success' => update_user_meta(get_current_user_id(), 'wpo-ignores-table-deletion-warning', true)
1178 );
1179 }
1180
1181 /**
1182 * Ignores the post meta deletion warning for the current user
1183 *
1184 * @return array
1185 */
1186 public function user_ignores_post_meta_deletion_warning() {
1187 return array(
1188 'success' => update_user_meta(get_current_user_id(), 'wpo-ignores-post-meta-deletion-warning', true)
1189 );
1190 }
1191
1192 /**
1193 * Ignores the orphaned relationship data deletion warning for the current user
1194 *
1195 * @return array
1196 */
1197 public function user_ignores_orphaned_relationship_data_deletion_warning() {
1198 return array(
1199 'success' => update_user_meta(get_current_user_id(), 'wpo-ignores-orphaned-relationship-data-deletion-warning', true)
1200 );
1201 }
1202
1203 /**
1204 * Exports unused images as a CSV file to the `uploads` folder
1205 *
1206 * @return array
1207 */
1208 public function export_csv() {
1209 WP_Optimization_images::instance()->output_csv();
1210 return array(
1211 'success' => true
1212 );
1213 }
1214
1215 /**
1216 * Create background tasks and execute it in sequenced AJAX calls
1217 *
1218 * @return array
1219 */
1220 public function load_tables_in_batches() {
1221 $optimizer = WP_Optimizer::instance();
1222 $options = WP_Optimize()->get_options();
1223
1224 $start_clean = $optimizer->maybe_restart_scan_job();
1225
1226 if (true == (bool) $start_clean) {
1227
1228 $tables = array();
1229
1230 $tables_count = $optimizer->scan_job_init();
1231
1232 $offset = 0;
1233 while ($offset < $tables_count) {
1234 $optimizer->add_load_tables_task($offset);
1235
1236 $offset += WP_Optimizer::HIGH_TABLE_COUNT_THRESHOLD;
1237 }
1238 $optimizer->flush_tasks();
1239 } else {
1240 $tables = $options->get_option(WP_Optimizer::TABLES_LIST_OPTION_NAME);
1241 $tables = is_array($tables) ? $tables : array();
1242 $tables_count = $options->get_option(WP_Optimizer::TABLES_LIST_COUNT_OPTION_NAME);
1243 $tables_count = false !== $tables_count ? $tables_count : 0;
1244 }
1245
1246 $optimizer->do_next_load_table_task();
1247
1248 if (!$optimizer->is_task_queue_empty() || $start_clean) {
1249 $continue = true;
1250 } else {
1251 $continue = false;
1252 }
1253
1254 $done = 0;
1255 if (false !== $tables) {
1256 $done = count($tables);
1257 }
1258
1259 if (false === $tables_count) {
1260 $tables_count = 0;
1261 }
1262
1263 return array(
1264 'success' => true,
1265 'continue' => $continue,
1266 'total' => $tables_count,
1267 'done' => $done
1268 );
1269 }
1270
1271 /**
1272 * Build the HTML for the status report tab
1273 *
1274 * @return array
1275 */
1276 public function generate_status_report() {
1277 $status_data = $this->get_wp_optimize_status_report_data();
1278
1279 $html = WP_Optimize()->include_template('status/status-page-ajax.php', true, array(
1280 'report_data' => $status_data['report_data']
1281 ));
1282
1283 return array(
1284 'success' => true,
1285 'html' => $html,
1286 'replaceable_md_tags' => $status_data['replaceable_md_tags']
1287 );
1288 }
1289
1290 /**
1291 * Gz compress text logs using `gzencode` to generate valid gzip files
1292 *
1293 * @return array
1294 */
1295 public function generate_logs_zip() {
1296 $wpo_server_information = new WP_Optimize_Server_Information();
1297
1298 $logs = $wpo_server_information->get_logs();
1299
1300 $gz_available = function_exists('gzencode');
1301 $data = array();
1302 foreach ($logs as $path => $content) {
1303 if ($gz_available) {
1304 $log_content = gzencode($content);
1305
1306 if (false === $log_content) {
1307 $log_content = $content;
1308 $gz_available = false;
1309 }
1310 } else {
1311 $log_content = $content;
1312 }
1313
1314 $data[] = array(
1315 'src' => base64_encode($log_content),
1316 'name' => basename($path),
1317 'compressed' => $gz_available
1318 );
1319 }
1320
1321 return array(
1322 'success' => true,
1323 'data' => $data
1324 );
1325 }
1326
1327 /**
1328 * Save images dimensions options
1329 *
1330 * @param array $settings Settings data
1331 * @return array
1332 */
1333 public function save_images_dimension_option($settings) {
1334 $options = WP_Optimize()->get_options();
1335
1336 if (!empty($settings["images_dimensions"]) && "true" === $settings["images_dimensions"]) {
1337 $is_updated = $options->update_option('image_dimensions', 1);
1338 } else {
1339 $is_updated = $options->update_option('image_dimensions', 0);
1340 }
1341
1342 if ($is_updated || $options->update_option('image_dimensions_ignore_classes', sanitize_text_field($settings['ignore_classes']))) {
1343 wpo_cache_flush();
1344 }
1345
1346 return array(
1347 'success' => true
1348 );
1349 }
1350
1351 /**
1352 * Truncate 404 Logs Table
1353 *
1354 * @return array
1355 */
1356 public function truncate_404_logs() {
1357 global $wpdb;
1358 $log_table_name = WP_Optimize_Table_404_Detector::get_instance()->get_table_name();
1359 $success = false;
1360 $message = __('No 404 logs found.', 'wp-optimize');
1361 // Check if the table has any rows
1362 $log_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM `" .esc_sql($log_table_name) . "`");
1363 if ($log_count > 0) {
1364 if ($wpdb->query("TRUNCATE TABLE `" .esc_sql($log_table_name) . "`")) {
1365 $success = true;
1366 // translators: %s is the number of logs deleted
1367 $message = sprintf(_n('%s entry deleted from the 404 error log.', '%s entries deleted from the 404 error log.', $log_count, 'wp-optimize'), $log_count);
1368 } else {
1369 $message = __('An error occurred while deleting the 404 logs.', 'wp-optimize');
1370 }
1371 }
1372
1373 return array(
1374 'success' => $success,
1375 'message' => $message
1376 );
1377 }
1378
1379 // UDC specific endpoints.
1380
1381 /**
1382 * Get multiple widgets data.
1383 *
1384 * @param array $args Args.
1385 *
1386 * @return array
1387 */
1388 public function get_widgets_data($args) {
1389 // Widgets.
1390 $widgets = isset($args['widgets']) ? $args['widgets'] : array();
1391
1392 // Return early if no widgets supplied.
1393 if (!is_array($widgets) || empty($widgets)) {
1394 return array('error' => false, 'data' => array());
1395 }
1396
1397 // Get the data for each widget.
1398 $data = array();
1399
1400 // Loop through the widgets and get their data.
1401 foreach ($widgets as $widget) {
1402 $method = 'get_' . $widget . '_data';
1403
1404 if (method_exists($this, $method)) {
1405 $data[$widget] = $this->$method($args);
1406 }
1407 }
1408
1409 return array('error' => false, 'data' => $data);
1410 }
1411
1412 // Helper functions.
1413
1414 /**
1415 * Get the data for tables.
1416 *
1417 * @return array
1418 */
1419 public function get_table_list_data() {
1420 $wp_optimize = WP_Optimize();
1421
1422 $size = $this->optimizer->get_current_db_size();
1423
1424 $table_list = array();
1425
1426 // Check for InnoDB tables.
1427 // Check for windows servers.
1428 $tablesstatus = $wp_optimize->get_optimizer()->get_tables();
1429 $is_multisite_mode = $wp_optimize->is_multisite_mode();
1430 $no = 0;
1431 $row_usage = 0;
1432 $data_usage = 0;
1433 $index_usage = 0;
1434 $overhead_usage = 0;
1435 $small_overhead_size = 1048576;
1436
1437 foreach ($tablesstatus as $tablestatus) {
1438 $table_info = array();
1439
1440 $table_info['index'] = ++$no;
1441 $table_info['table_name'] = $tablestatus->Name;
1442 $table_info['Engine'] = $tablestatus->Engine;
1443 $table_info['is_optimizable'] = $tablestatus->is_optimizable ? 1 : 0;
1444 $table_info['blog_id'] = $tablestatus->blog_id;
1445 $table_info['plugin_status'] = $tablestatus->plugin_status;
1446 $table_info['Rows'] = intval($tablestatus->Rows);
1447 $table_info['Data_length'] = intval($tablestatus->Data_length);
1448 $table_info['Formatted_Data_length'] = $wp_optimize->format_size($tablestatus->Data_length);
1449 $table_info['Index_length'] = $tablestatus->Index_length;
1450 $table_info['Formatted_Index_length'] = $wp_optimize->format_size($tablestatus->Index_length);
1451 $table_info['Data_free'] = intval($tablestatus->Data_free);
1452 $table_info['Formatted_Data_free'] = $wp_optimize->format_size($tablestatus->Data_free);
1453 $table_info['Data_should_be_cleared'] = intval($tablestatus->Data_free) > $small_overhead_size ? 1 : 0;
1454 $table_info['wp_core_table'] = $tablestatus->wp_core_table;
1455
1456 $table_list[$tablestatus->Name] = $table_info;
1457
1458 $row_usage += $tablestatus->Rows;
1459 $data_usage += $tablestatus->Data_length;
1460 $index_usage += $tablestatus->Index_length;
1461 $overhead_usage += $tablestatus->Data_free;
1462 }
1463
1464 $db_info = $this->optimizer->get_current_db_size();
1465
1466 return array(
1467 'error' => false,
1468 'data' => array(
1469 'is_multisite_mode' => $is_multisite_mode,
1470 'closed_plugins' => array('404-monitor', 'redirections'),
1471 'database_name' => DB_NAME,
1472 'database_size' => $db_info[0],
1473 'optimize_db' => false,
1474 'table_list_object_format' => $tablesstatus,
1475 'load_data' => WP_Optimize()->template_should_include_data(),
1476 'table_list' => $table_list,
1477 'total_size' => $size[0],
1478 'small_overhead_size' => $small_overhead_size,
1479 'no' => $no,
1480 'no_fomatted' => number_format_i18n($no),
1481 'row_usage' => number_format_i18n($row_usage),
1482 'data_usage' => $wp_optimize->format_size($data_usage),
1483 'index_usage' => $wp_optimize->format_size($index_usage),
1484 'tables_count' => count($table_list),
1485 // translators: %s is the number of table(s).
1486 'formatted_tables_count' => sprintf(_n('%s Table', '%s Tables', count($table_list), 'wp-optimize'), number_format_i18n(count($table_list))),
1487 'overhead_usage' => $overhead_usage,
1488 'overhead_usage_formatted' => $wp_optimize->format_size($overhead_usage),
1489 'translations' => array(
1490 'database_name' => __('Database Name', 'wp-optimize'),
1491 'refresh_data' => __('Refresh Data', 'wp-optimize'),
1492 'refreshing' => __('Refreshing...', 'wp-optimize'),
1493 'number' => __('No.', 'wp-optimize'),
1494 'table' => __('Table', 'wp-optimize'),
1495 'records' => __('Records', 'wp-optimize'),
1496 'data_size' => __('Data Size', 'wp-optimize'),
1497 'index_size' => __('Index Size', 'wp-optimize'),
1498 'type' => __('Type', 'wp-optimize'),
1499 'overhead' => __('Overhead', 'wp-optimize'),
1500 'total' => __('Total', 'wp-optimize'),
1501 'search_tables' => __('Search tables', 'wp-optimize'),
1502 'total_size_of_database' => __('Total size of database', 'wp-optimize'),
1503 ),
1504 )
1505 );
1506 }
1507
1508 /**
1509 * [For UpdraftCentral] Returns selected WP-Optimize toggleable settings optimized for quick access
1510 *
1511 * @return WP_Error|array
1512 */
1513 private function get_quick_settings_data() {
1514 if (!WP_Optimize()->current_user_can()) {
1515 return $this->request_error('insufficient_privilege');
1516 }
1517
1518 $options = WP_Optimize()->get_options();
1519 $default_lazyload_settings = array(
1520 'images' => false,
1521 'backgrounds' => false,
1522 'iframes' => false,
1523 'youtube_preview' => false,
1524 'skip_classes' => '',
1525 );
1526
1527 $lazyload = wp_parse_args($options->get_option('lazyload', array()), $default_lazyload_settings);
1528 foreach ($lazyload as $key => $value) {
1529 if ('skip_classes' !== $key) {
1530 $lazyload[$key] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
1531 }
1532 }
1533
1534 $trackbacks = $options->get_option('trackbacks_action', array());
1535 $comments = $options->get_option('comments_action', array());
1536
1537 $gzip_compression_enabled = WP_Optimize()->get_gzip_compression()->is_gzip_compression_enabled(false);
1538
1539 $settings = array(
1540 'scheduled_cleanup' => 'true' === $options->get_option('schedule'),
1541 'backup_enabled' => 'true' === $options->get_option('enable-auto-backup', 'false'),
1542 'comments' => (!empty($comments) && $comments['action']) ? true : false,
1543 'trackbacks' => (!empty($trackbacks) && $trackbacks['action']) ? true : false,
1544 'autosmush' => $options->get_option('autosmush'),
1545 'page_caching' => WP_Optimize()->get_page_cache()->is_enabled(),
1546 'minify' => wp_optimize_minify_config()->get('enabled'),
1547 'image_dimensions' => $options->get_option('image_dimensions'),
1548 '404_detector' => $options->get_option('404_detector'),
1549 'webp_conversion' => $options->get_option('webp_conversion'),
1550 'gzip_compression' => (!is_wp_error($gzip_compression_enabled) && $gzip_compression_enabled) ? true : false,
1551 );
1552
1553 $settings = array_map(function($value) {
1554 return filter_var($value, FILTER_VALIDATE_BOOLEAN);
1555 }, $settings);
1556
1557 return array_merge($settings, array('lazyload' => $lazyload));
1558 }
1559
1560 /**
1561 * [For UpdraftCentral] Saves the selected WP-Optimize toggleable settings
1562 *
1563 * @param array $settings Parameters required for the requested action
1564 *
1565 * @return WP_Error|array
1566 */
1567 public function save_quick_settings($settings) {
1568 if (!WP_Optimize()->current_user_can()) {
1569 return $this->request_error('insufficient_privilege');
1570 }
1571
1572 if (!empty($settings) && is_array($settings)) {
1573 $settings = array_map(function($value) {
1574 return filter_var($value, FILTER_VALIDATE_BOOLEAN);
1575 }, $settings);
1576 }
1577
1578 try {
1579
1580 if (isset($settings['enable-404-detector'])) {
1581 WP_Optimize()->get_options()->update_option('404_detector', (int) $settings['enable-404-detector']);
1582 }
1583
1584 if (isset($settings['enable-auto-backup'])) {
1585 WP_Optimize()->get_options()->update_option('enable-auto-backup', $settings['enable-auto-backup'] ? 'true' : 'false');
1586
1587 WP_Optimize()->get_options()->update_option('enable-auto-backup-scheduled', $settings['enable-auto-backup'] ? 'true' : 'false');
1588 }
1589
1590 if (isset($settings['enable-auto-compression'])) {
1591 Updraft_Smush_Manager()->update_smush_options(array('autosmush' => (int) $settings['enable-auto-compression']));
1592 }
1593
1594 if (isset($settings['enable-comments'])) {
1595 $this->enable_or_disable_feature(array(
1596 'type' => 'comments',
1597 'enable' => $settings['enable-comments'],
1598 ));
1599 }
1600
1601 if (isset($settings['enable-trackbacks'])) {
1602 $this->enable_or_disable_feature(array(
1603 'type' => 'trackbacks',
1604 'enable' => $settings['enable-trackbacks'],
1605 ));
1606 }
1607
1608 if (isset($settings['enable-minify'])) {
1609 wp_optimize_minify_config()->update(array('enabled' => $settings['enable-minify']));
1610 }
1611
1612 if (isset($settings['enable-page-caching'])) {
1613 $wpo_page_cache = WP_Optimize()->get_page_cache();
1614
1615 if ($settings['enable-page-caching']) {
1616 $wpo_page_cache->enable(true);
1617 } else {
1618 $wpo_page_cache->disable();
1619 }
1620 }
1621
1622 if (isset($settings['enable-scheduled-cleanup'])) {
1623 WP_Optimize()->get_options()->update_option('schedule', $settings['enable-scheduled-cleanup'] ? 'true' : 'false');
1624 }
1625
1626 if (isset($settings['enable-webp-conversion'])) {
1627 WP_Optimize()->get_webp_instance()->save_webp_settings(array('webp_conversion' => $settings['enable-webp-conversion']));
1628 }
1629
1630 if (isset($settings['enable-images-dimensions'])) {
1631 WP_Optimize()->get_options()->update_option('image_dimensions', (int) $settings['enable-images-dimensions']);
1632 }
1633
1634 if (isset($settings['enable-lazy-loading'])) {
1635 $value = (int) $settings['enable-lazy-loading'];
1636 $options = WP_Optimize()->get_options();
1637
1638 $lazyload = $options->get_option('lazyload');
1639 $lazy_settings = array(
1640 'images' => $value,
1641 'iframes' => $value,
1642 'backgrounds' => $value,
1643 'youtube_preview' => $value,
1644 'skip_classes' => !empty($lazyload['skip_classes']) ? $lazyload['skip_classes'] : '',
1645 );
1646 $options->save_lazy_load_settings(array('lazyload' => $lazy_settings));
1647 }
1648
1649 if (isset($settings['enable-gzip-compression'])) {
1650 $this->enable_gzip_compression(array('enable' => $settings['enable-gzip-compression']));
1651 }
1652
1653 } catch (Throwable $e) {
1654 return $this->request_error('quick_settings_save_error', null, array('message' => $e->getMessage(), 'settings' => $this->get_quick_settings_data()));
1655 }
1656
1657 return array('settings' => $this->get_quick_settings_data());
1658 }
1659
1660 /**
1661 * Get the data of wp-optimize widget.
1662 *
1663 * @return array
1664 */
1665 private function get_wp_optimize_data() {
1666 $wp_optimize = WP_Optimize();
1667
1668 $optimizations = $this->optimizer->sort_optimizations($this->optimizer->get_optimizations());
1669 $does_server_allow_table_optimization = $wp_optimize->get_server_compatibility_instance()->does_server_allow_table_optimization();
1670
1671 $optimizations_data = array();
1672
1673 foreach ($optimizations as $id => $optimization) {
1674 if ('optimizetables' == $id && false === $does_server_allow_table_optimization) continue;
1675 // If we don't want to show optimization on the first tab.
1676 if (false === $optimization->display_in_optimizations_list()) continue;
1677 // This is an array, with attributes dom_id, activated, settings_label, info; all values are strings.
1678 $optimization_data = $optimization->get_settings_html();
1679
1680 $optimization_data['info_raw'] = $optimization_data['info'];
1681
1682 $optimization_data['info'] = '<div>' . preg_replace('/<a\b[^>]*>(.*?)<\/a>/i', '$1', $optimization_data['info']) . '</div>';
1683
1684 $optimization_data['disable_optimization_button'] = false;
1685 $optimization_data['run_sort_order'] = $optimization->get_run_sort_order();
1686
1687 // Check if the DOM is optimize-db to generate a list of tables.
1688 if ('optimize-db' == $optimization_data['dom_id']) {
1689 // Disable optimization when too many tables exist but the batch scan hasn't run yet.
1690 // Running it now would silently optimize 0 tables because get_tables() returns empty.
1691 if ($this->optimizer->is_table_count_too_high() && !$this->optimizer->is_large_table_count_scan_complete()) {
1692 $optimization_data['disable_optimization_button'] = true;
1693 $optimization_data['activated'] = '';
1694 } else {
1695 $table_list = $this->optimizer->get_table_information();
1696
1697 // Make sure that optimization_table_inno_db is set.
1698 if ($table_list['inno_db_tables'] > 0 && 0 === $table_list['is_optimizable'] && 0 === $table_list['non_inno_db_tables']) {
1699 $optimization_data['disable_optimization_button'] = true;
1700 $optimization_data['activated'] = '';
1701 }
1702 }
1703 }
1704
1705 $optimization_data['id'] = $id;
1706 $optimizations_data[] = $optimization_data;
1707 }
1708
1709 // Backup checkbox name.
1710 $backup_checkbox_name = 'enable-auto-backup';
1711
1712 return array(
1713 'items' => $optimizations_data,
1714 'optimize_button_multiple_caption' => __('Optimize selected', 'wp-optimize'),
1715 'optimize_button_caption' => apply_filters('wpo_run_button_caption', __('Optimize all', 'wp-optimize')),
1716 'backup_checkbox_name' => $backup_checkbox_name,
1717 'backup_enabled' => 'true' == $this->options->get_option($backup_checkbox_name, 'false'),
1718 'backup_checkbox_label' => __('Take backup before optimize', 'wp-optimize'),
1719 );
1720 }
1721
1722 /**
1723 * Get wpo status data.
1724 *
1725 * @return array
1726 */
1727 private function get_status_data() {
1728 $status_data = $this->get_all_status_data();
1729
1730 $data = array(
1731 'statuses' => array(),
1732 'test' => $status_data,
1733 );
1734
1735 // Schedule optimization.
1736 $schedule_optimization_description = __('Scheduled optimization is currently disabled.', 'wp-optimize');
1737 $schedule_optimization_icon = 'error';
1738
1739 if (!empty($status_data['scheduled_optimizations_enabled'])) {
1740 if ('Never' === $status_data['last_optimized']) {
1741 $schedule_optimization_description = __('There was no scheduled optimization.', 'wp-optimize');
1742 $schedule_optimization_icon = 'warning';
1743 } else {
1744 $lastopt = $status_data['last_optimized'];
1745 if (is_numeric($status_data['last_optimized'])) {
1746 $lastopt = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $status_data['last_optimized'] + ( get_option('gmt_offset') * HOUR_IN_SECONDS ));
1747 }
1748 // translators: %s is the last schedule optimization run date.
1749 $schedule_optimization_description = sprintf(esc_html__('Last scheduled optimization was at %s', 'wp-optimize'), esc_html($lastopt));
1750 $schedule_optimization_icon = 'success';
1751 }
1752 }
1753
1754 $data['statuses'][] = array(
1755 'title' => __('Schedule Optimization', 'wp-optimize'),
1756 'description' => $schedule_optimization_description,
1757 'icon' => $schedule_optimization_icon,
1758 );
1759
1760 // Schedule cleaning.
1761 $data['statuses'][] = array(
1762 'title' => __('Schedule Cleaning', 'wp-optimize'),
1763 'description' => empty($status_data['scheduled_optimizations_enabled']) ? __('Scheduled cleaning is currently disabled.', 'wp-optimize') : __('Scheduled cleaning is enabled.', 'wp-optimize'),
1764 'icon' => empty($status_data['scheduled_optimizations_enabled']) ? 'warning' : 'success',
1765 );
1766
1767 // Data retention.
1768 $data['statuses'][] = array(
1769 'title' => __('Data Retention', 'wp-optimize'),
1770 'description' => empty($status_data['retention_enabled']) ? __('The system is not keeping recent data or any revisions.', 'wp-optimize') : __('Data retention enabled.', 'wp-optimize'),
1771 'icon' => empty($status_data['retention_enabled']) ? 'error' : 'success',
1772 );
1773
1774 return $data;
1775 }
1776
1777 /**
1778 * Get all status data.
1779 *
1780 * @return array
1781 */
1782 public function get_all_status_data() {
1783 $wp_optimize = WP_Optimize();
1784
1785 $retention_enabled = $this->options->get_option('retention-enabled', 'false') === 'true';
1786 $retention_period = $this->options->get_option('retention-period', '2');
1787 $admin_page_url = $this->options->admin_page_url();
1788
1789 $revisions_retention_enabled = $this->options->get_option('revisions-retention-enabled', 'false') === 'true';
1790 $revisions_retention_count = $this->options->get_option('revisions-retention-count', '2');
1791
1792 $last_optimized = $this->options->get_option('last-optimized', 'Never');
1793 $last_optimized_ts = $last_optimized;
1794
1795 if (!empty($last_optimized) && is_numeric($last_optimized)) {
1796 $last_optimized = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $last_optimized + (get_option('gmt_offset') * HOUR_IN_SECONDS));
1797 }
1798
1799 $scheduled_optimizations_enabled = false;
1800 $scheduled_optimizations = array();
1801
1802 if (WP_Optimize::is_premium()) {
1803 $wp_optimize_premium = WP_Optimize_Premium();
1804 $scheduled_optimizations = $wp_optimize_premium->get_scheduled_optimizations();
1805
1806 if (!empty($scheduled_optimizations)) {
1807 foreach ($scheduled_optimizations as $optimization) {
1808 if (isset($optimization['status']) && 1 === absint($optimization['status'])) {
1809 $scheduled_optimizations_enabled = true;
1810 break;
1811 }
1812 }
1813 }
1814 } else {
1815 $scheduled_optimizations_enabled = $this->options->get_option('schedule', 'false') == 'true';
1816 }
1817
1818 $total_cleaned = null;
1819 $total_cleanup_size = '';
1820 $corrupted_tables_count = null;
1821 $next_optimization_timestamp = 0;
1822
1823 if ($scheduled_optimizations_enabled) {
1824
1825 $next_optimization_timestamp = wp_next_scheduled('wpo_cron_event2');
1826 $filtered_next_optimization_timestamp = apply_filters('wpo_cron_next_event', $next_optimization_timestamp);
1827 $next_optimization_timestamp = is_int($filtered_next_optimization_timestamp) ? $filtered_next_optimization_timestamp : $next_optimization_timestamp;
1828
1829 if ($next_optimization_timestamp) {
1830
1831 $next_optimization_timestamp = $next_optimization_timestamp + 60 * 60 * get_option('gmt_offset');
1832
1833 $wp_optimize->cron_activate();
1834 }
1835
1836 $total_cleaned = $this->options->get_option('total-cleaned');
1837 $total_cleaned_num = floatval($total_cleaned);
1838
1839 if ($total_cleaned_num > 0) {
1840 $total_cleanup_size = $wp_optimize->format_size($total_cleaned);
1841 }
1842
1843 $corrupted_tables_count = $this->options->get_option('corrupted-tables-count', 0);
1844 }
1845
1846 return array(
1847 'last_optimized' => $last_optimized,
1848 'last_optimized_ts' => $last_optimized_ts,
1849 'total_cleaned' => $total_cleaned,
1850 'total_cleanup_size' => $total_cleanup_size,
1851 'corrupted_tables_count' => $corrupted_tables_count,
1852 'admin_page_url' => $admin_page_url,
1853 'retention_enabled' => $retention_enabled,
1854 'retention_period' => $retention_period,
1855 'revisions_retention_enabled' => $revisions_retention_enabled,
1856 'revisions_retention_count' => $revisions_retention_count,
1857 'scheduled_optimizations_enabled' => $scheduled_optimizations_enabled,
1858 'next_optimization_timestamp' => $next_optimization_timestamp,
1859 'scheduled_optimizations' => $scheduled_optimizations
1860 );
1861 }
1862
1863 /**
1864 * Get wp-optimize tab top nav data.
1865 *
1866 * @return array
1867 */
1868 private function get_wp_optimize_top_nav_data() {
1869 return array(
1870 'title' => __('Performance Overview', 'wp-optimize'),
1871 'table_info' => __('Table Info', 'wp-optimize'),
1872 'performance_settings' => __('Performance Settings', 'wp-optimize'),
1873 );
1874 }
1875
1876 /**
1877 * Get wp-optimize tab top nav settings page data.
1878 *
1879 * @return array
1880 */
1881 private function get_wp_optimize_settings_top_nav_data() {
1882 return array(
1883 'title' => __('Performance Settings', 'wp-optimize'),
1884 'settings_saved_prompt' => __('Changes saved automatically', 'wp-optimize'),
1885 'settings_not_saved_prompt' => __('Changes not saved - please fill all the fields', 'wp-optimize'),
1886 );
1887 }
1888
1889 /**
1890 * Get if wp-optimize premium is installed.
1891 *
1892 * @return array
1893 */
1894 private function get_is_premium_data() {
1895 $is_premium = WP_Optimize::is_premium();
1896 $upgrade_to_premium_data = array();
1897
1898 if (false === $is_premium) {
1899 $upgrade_to_premium_data = array(
1900 'heading' => __('WP-Optimize premium', 'wp-optimize'),
1901 'checklist' => array(
1902 __('Optimize individual tables', 'wp-optimize'),
1903 __('Sophisticated scheduling', 'wp-optimize'),
1904 __('Lazy loading', 'wp-optimize'),
1905 __('Optimization preview', 'wp-optimize'),
1906 __('More caching options', 'wp-optimize'),
1907 __('Remove unwanted images', 'wp-optimize'),
1908 __('Multi language & currency support', 'wp-optimize'),
1909 ),
1910 'cta' => array(
1911 'text' => __('Upgrade Now', 'wp-optimize'),
1912 'url' => 'https://teamupdraft.com/wp-optimize/pricing/',
1913 ),
1914 );
1915 }
1916
1917 return array(
1918 'is_premium' => $is_premium,
1919 'upgrade_to_premium_data' => $upgrade_to_premium_data,
1920 );
1921 }
1922
1923 /**
1924 * WIP: Get system overview data.
1925 *
1926 * @return array
1927 */
1928 private function get_system_overview_data() {
1929 $wp_optimize = WP_Optimize();
1930 $status_data = $this->get_all_status_data();
1931
1932 // Data.
1933 $data = array(
1934 'data' => array(),
1935 );
1936
1937 // Lazy load.
1938 $lazy_load_settings = $this->options->get_option('lazyload', array(
1939 'images' => false,
1940 'iframes' => false,
1941 'skip_classes' => '',
1942 ));
1943
1944 $lazy_load_enabled = $lazy_load_settings['images'] || $lazy_load_settings['iframes'];
1945
1946 if (WP_Optimize::is_premium()) {
1947 $lazy_load_enabled = $lazy_load_enabled || $lazy_load_settings['backgrounds'];
1948 }
1949
1950 $data['data'][] = array(
1951 'title' => __('Lazy loading', 'wp-optimize'),
1952 'description' => $lazy_load_enabled ? __('Enabled', 'wp-optimize') : __('Disabled', 'wp-optimize'),
1953 'status' => $lazy_load_enabled ? 'success' : 'error',
1954 );
1955
1956 // Page caching.
1957 $cache = $wp_optimize->get_page_cache();
1958 $page_caching_enabled = $cache->is_enabled();
1959 $data['data'][] = array(
1960 'title' => __('Page caching', 'wp-optimize'),
1961 'description' => $page_caching_enabled ? __('Enabled', 'wp-optimize') : __('Disabled', 'wp-optimize'),
1962 'status' => $page_caching_enabled ? 'success' : 'error',
1963 );
1964
1965 // Schedule cleaning.
1966 $data['data'][] = array(
1967 'title' => __('Scheduled clean-up', 'wp-optimize'),
1968 'description' => empty($status_data['scheduled_optimizations_enabled']) ? __('Disabled', 'wp-optimize') : __('Enabled', 'wp-optimize'),
1969 'status' => empty($status_data['scheduled_optimizations_enabled']) ? 'error' : 'success',
1970 );
1971
1972 if (!empty($status_data['scheduled_optimizations_enabled'])) {
1973 $data['data'][] = array(
1974 'title' => __('Next scheduled date', 'wp-optimize'),
1975 'description' => esc_html(gmdate(get_option('date_format') . ' ' . get_option('time_format'), $status_data['next_optimization_timestamp'])),
1976 'status' => '',
1977 );
1978 }
1979
1980 return $data;
1981 }
1982
1983 /**
1984 * Get wp-optimize general settings data.
1985 *
1986 * @return array
1987 */
1988 private function get_wp_optimize_general_settings_data() {
1989 $retention_period = max((int) $this->options->get_option('retention-period', '2'), 1);
1990 $retention_enabled = 'true' === $this->options->get_option('retention-enabled');
1991
1992 $revisions_retention_count = (int) $this->options->get_option('revisions-retention-count', '2');
1993 $revisions_retention_enabled = 'true' === $this->options->get_option('revisions-retention-enabled');
1994
1995 $minify_or_cache_enabled = WP_Optimize()->get_page_cache()->is_enabled() || wp_optimize_minify_config()->get('enabled');
1996
1997 return array(
1998 'retention_period' => $retention_period,
1999 'retention_enabled' => $retention_enabled,
2000 'revisions_retention_count' => $revisions_retention_count,
2001 'revisions_retention_enabled' => $revisions_retention_enabled,
2002 'minify_or_cache_enabled' => $minify_or_cache_enabled,
2003 );
2004 }
2005
2006 /**
2007 * Get wp-optimize trackback settings data.
2008 *
2009 * @return array
2010 */
2011 private function get_wp_optimize_trackback_toggle_settings_data() {
2012 $wp_optimize = WP_Optimize();
2013
2014 $trackback_action_arr = $this->options->get_option('trackbacks_action', array());
2015
2016 $enabled = false;
2017 $last_action_timestamp = '';
2018 $empty = true;
2019
2020 if (!empty($trackback_action_arr)) {
2021 $empty = false;
2022 $last_action_timestamp = $wp_optimize->format_date_time($trackback_action_arr['timestamp']);
2023 if ($trackback_action_arr['action']) {
2024 $enabled = true;
2025 }
2026 }
2027
2028 return array(
2029 'enabled' => $enabled,
2030 'last_action_timestamp' => $last_action_timestamp,
2031 'empty' => $empty
2032 );
2033 }
2034
2035 /**
2036 * Get wp-optimize comments settings data.
2037 *
2038 * @return array
2039 */
2040 private function get_wp_optimize_comments_toggle_settings_data() {
2041 $wp_optimize = WP_Optimize();
2042
2043 $comments_action_arr = $this->options->get_option('comments_action', array());
2044
2045 $enabled = false;
2046 $last_action_timestamp = '';
2047 $empty = true;
2048
2049 if (!empty($comments_action_arr)) {
2050 $empty = false;
2051 $last_action_timestamp = $wp_optimize->format_date_time($comments_action_arr['timestamp']);
2052 if ($comments_action_arr['action']) {
2053 $enabled = true;
2054 }
2055 }
2056
2057 return array(
2058 'enabled' => $enabled,
2059 'last_action_timestamp' => $last_action_timestamp,
2060 'empty' => $empty
2061 );
2062 }
2063
2064 /**
2065 * Get wp-optimize logging settings.
2066 *
2067 * @return array
2068 */
2069 private function get_wp_optimize_logging_settings_data() {
2070 $wp_optimize = WP_Optimize();
2071
2072 $logger_classes_info = $wp_optimize->get_loggers_classes_info();
2073
2074 $logger_classes = array();
2075 $logger_classes_fields = array();
2076
2077 foreach ($logger_classes_info as $logger_class => $logger_class_data) {
2078 if (empty($logger_class_data['available'])) {
2079 continue;
2080 }
2081
2082 $logger_classes[] = array(
2083 'value' => $logger_class,
2084 'name' => $logger_class_data['description'],
2085 );
2086
2087 // For now we only have one option for all the fields, therefore taking only one.
2088 foreach ($logger_class_data['options'] as $name => $value) {
2089 $logger_class_field_data = array(
2090 'name' => $name,
2091 'validator' => '',
2092 'placeholder' => '',
2093 'controller_value' => $logger_class,
2094 );
2095
2096 if (is_array($value)) {
2097 $logger_class_field_data['validator'] = isset($value[1]) ? $value[1] : '';
2098 $logger_class_field_data['placeholder'] = isset($value[0]) ? $value[0] : '';
2099 } else {
2100 $logger_class_field_data['placeholder'] = $value;
2101 }
2102
2103 $logger_classes_fields[] = $logger_class_field_data;
2104 }
2105 }
2106
2107 $loggers_data = array(
2108 'loggers_classes_info' => $logger_classes_info,
2109 'logger_classes' => $logger_classes,
2110 'logger_classes_fields' => $logger_classes_fields,
2111 'existing_loggers' => array(),
2112 );
2113
2114 $loggers = $wp_optimize->wpo_loggers();
2115
2116 foreach ($loggers as $logger) {
2117 $logger_data = array(
2118 'id' => strtolower(get_class($logger)),
2119 'status' => ($logger->is_enabled() && $logger->is_available()) ? 'active' : 'inactive',
2120 'status_text' => ($logger->is_enabled() && $logger->is_available()) ? __('Active', 'wp-optimize') : __('Inactive', 'wp-optimize'),
2121 'existing_logger_classes' => array(),
2122 'existing_logger_classes_fields' => array(),
2123 'description' => $logger->get_description(),
2124 'options_text' => $logger->get_options_text(),
2125 'options_list' => array(),
2126 'is_enabled' => $logger->is_enabled(),
2127 'is_available' => $logger->is_available()
2128 );
2129
2130 $options_list = $logger->get_options_list();
2131 $options_values = $logger->get_options_values();
2132
2133 $options = array();
2134
2135 if (!empty($options_list)) {
2136 foreach ($options_list as $option_name => $placeholder) {
2137 // check if settings item defined as array.
2138 if (is_array($placeholder)) {
2139 $validate = $placeholder[1];
2140 $placeholder = $placeholder[0];
2141 } else {
2142 $validate = '';
2143 }
2144
2145 $data_validate_attr = ('' !== $validate ? 'data-validate="'.esc_attr($validate).'"' : '');
2146
2147 $options[$option_name] = array(
2148 'name' => $option_name,
2149 'placeholder' => $placeholder,
2150 'value' => $options_values[$option_name],
2151 'data_validate_attr' => $data_validate_attr,
2152 );
2153
2154 }
2155 $logger_data['options_list'] = $options;
2156 }
2157
2158 foreach ($loggers_data['logger_classes'] as $classes) {
2159 $logger_data['existing_logger_classes'][] = array(
2160 'value' => $classes['value'],
2161 'name' => $classes['name'],
2162 'selected' => $logger_data['id'] === $classes['value'],
2163 );
2164 }
2165
2166 foreach ($loggers_data['logger_classes_fields'] as $field) {
2167 // If the field has existing value fill it else add as it is.
2168 if (!empty($options[$field['name']])) {
2169 $field['value'] = $options[$field['name']]['value'];
2170 $field['selected'] = true;
2171 $logger_data['existing_logger_classes_fields'][] = $field;
2172 } else {
2173 $logger_data['existing_logger_classes_fields'][] = $field;
2174 }
2175 }
2176
2177 $loggers_data['existing_loggers'][] = $logger_data;
2178 }
2179
2180 return $loggers_data;
2181 }
2182
2183 /**
2184 * Get wp-optimize schedule cleanup settings data.
2185 *
2186 * @return array
2187 */
2188 private function get_wp_optimize_schedule_cleanup_settings_data() {
2189 $is_premium = WP_Optimize::is_premium();
2190
2191 $return_data = array(
2192 'is_premium' => $is_premium,
2193 'data' => array(),
2194 );
2195 $scheduled_optimizations_enabled = false;
2196 $last_optimized_timestamp = (int) $this->options->get_option('last-optimized', 0);
2197 $next_optimization_timestamp = 0;
2198 $wp_optimize = WP_Optimize();
2199 $is_udc_request = $wp_optimize->is_updraft_central_request();
2200
2201 if (!$is_premium) {
2202 $schedule_enabled = $this->options->get_option('schedule');
2203 $scheduled_optimizations_enabled = 'true' === $schedule_enabled;
2204
2205 $schedule_type_saved_id = $this->options->get_option('schedule-type', 'wpo_weekly');
2206
2207 // Backwards compatibility:
2208 if ('wpo_otherweekly' == $schedule_type_saved_id) $schedule_type_saved_id = 'wpo_fortnightly';
2209
2210 $schedule_types = WP_Optimize::get_schedule_types();
2211
2212 $schedule_options = array_map(
2213 function ($value, $key) use ($schedule_type_saved_id) {
2214 return array(
2215 'id' => $key,
2216 'label' => $value,
2217 'selected' => ($key === $schedule_type_saved_id)
2218 );
2219 },
2220 $schedule_types,
2221 array_keys($schedule_types)
2222 );
2223
2224 $wpo_auto_options = $this->options->get_option('auto');
2225
2226 $optimizations = $this->optimizer->sort_optimizations($this->optimizer->get_optimizations());
2227
2228 $optimizations_data = array();
2229
2230 $does_server_allow_table_optimization = $wp_optimize->get_server_compatibility_instance()->does_server_allow_table_optimization();
2231
2232 foreach ($optimizations as $id => $optimization) {
2233 if (empty($optimization->available_for_auto)) continue;
2234
2235 if ('optimizetables' == $id && false === $does_server_allow_table_optimization) continue;
2236
2237 $auto_id = $optimization->get_auto_id();
2238
2239 $auto_dom_id = 'wp-optimize-auto-'.$auto_id;
2240
2241 $setting_activated = (empty($wpo_auto_options[$auto_id]) || 'false' == $wpo_auto_options[$auto_id]) ? false : true;
2242
2243 $optimizations_data[] = array(
2244 'id' => $auto_id,
2245 'dom_id' => $auto_dom_id,
2246 'activated' => $setting_activated,
2247 'label' => $optimization->settings_label(),
2248 );
2249 }
2250
2251 $return_data['data'] = array(
2252 'schedule_options' => $schedule_options,
2253 'schedule_type_saved_id' => $schedule_type_saved_id,
2254 'optimizations' => $optimizations_data,
2255 'premium_version_link' => $wp_optimize->premium_version_link,
2256 'enable_schedule' => $schedule_enabled,
2257 );
2258 } else {
2259 $wp_optimize_premium = WP_Optimize_Premium();
2260 $auto_options = $wp_optimize_premium->get_scheduled_optimizations();
2261 $auto_optimizations = $wp_optimize_premium->get_auto_optimizations();
2262
2263 if (!empty($auto_options)) {
2264 foreach ($auto_options as $optimization) {
2265 if (isset($optimization['status']) && 1 == $optimization['status']) {
2266 $scheduled_optimizations_enabled = true;
2267 break;
2268 }
2269 }
2270 }
2271
2272 $all_provided_optimizations = array_values($auto_optimizations);
2273 $all_schedule_types = WP_Optimize::get_schedule_types();
2274 $week_days = WP_Optimize_Premium::get_week_days();
2275 $days = WP_Optimize_Premium::get_days();
2276 $weeks = array('1st' => __('1st', 'wp-optimize'), '2nd' => __('2nd', 'wp-optimize'));
2277
2278 $optimizations = array();
2279
2280 foreach ($auto_options as $index => $event) {
2281 $optimization = array(
2282 'index' => $index,
2283 );
2284 if (!isset($event['optimization'])) {
2285 $event['optimization'] = array();
2286 }
2287 foreach ($event as $event_key => $value) {
2288 switch ($event_key) {
2289 case 'optimization':
2290 $optimization['optimization'] = array();
2291 foreach ($all_provided_optimizations as $this_optimization) {
2292 if (in_array($this_optimization['id'], $value)) {
2293 $this_optimization['selected'] = true;
2294 }
2295 $optimization['optimization'][] = $this_optimization;
2296 }
2297 break;
2298 case 'schedule_type':
2299 $optimization['schedule_types'] = array();
2300 foreach ($all_schedule_types as $key => $this_schedule_value) {
2301 $this_schedule_type = array();
2302 $this_schedule_type['label'] = $this_schedule_value;
2303 $this_schedule_type['selected'] = $key === $value;
2304 $this_schedule_type['value'] = $key;
2305 $optimization['schedule_types'][] = $this_schedule_type;
2306 }
2307 break;
2308 case 'date':
2309 $optimization['date'] = $value;
2310 break;
2311 case 'time':
2312 $optimization['time'] = $value;
2313 break;
2314 case 'week':
2315 $optimization['weeks'] = array();
2316 foreach ($weeks as $key => $this_week_value) {
2317 $this_week = array();
2318 $this_week['label'] = $this_week_value;
2319 $this_week['selected'] = absint($key) === absint($value);
2320 $this_week['value'] = $key;
2321 $optimization['weeks'][] = $this_week;
2322 }
2323 break;
2324 case 'day':
2325 $optimization['days'] = array();
2326 foreach ($week_days as $key => $this_week_day_value) {
2327 $this_week_day = array();
2328 $this_week_day['label'] = $this_week_day_value;
2329 $this_week_day['selected'] = absint($key) === absint($value);
2330 $this_week_day['value'] = $key;
2331 $optimization['days'][] = $this_week_day;
2332 }
2333 break;
2334 case 'day_number':
2335 $optimization['day_numbers'] = array();
2336 foreach ($days as $key => $this_day_value) {
2337 $this_day = array();
2338 $this_day['label'] = $this_day_value;
2339 $this_day['selected'] = absint($key) === absint($value);
2340 $this_day['value'] = $key;
2341 $optimization['day_numbers'][] = $this_day;
2342 }
2343 break;
2344 case 'status':
2345 $optimization['status'] = '1' === $value;
2346 break;
2347 }
2348 }
2349
2350 // Add the optimization only if it has at least one selected optimization.
2351 $has_selected_optimization = false;
2352
2353 if (!empty($optimization['optimization'])) {
2354 foreach ($optimization['optimization'] as $optimization_data) {
2355 if (true === $optimization_data['selected']) {
2356 $has_selected_optimization = true;
2357 break;
2358 }
2359 }
2360 }
2361
2362 if ($has_selected_optimization) $optimizations[] = $optimization;
2363 }
2364
2365 $return_data['data'] = array(
2366 'optimizations' => $optimizations,
2367 'provided_optimizations' => $all_provided_optimizations,
2368 'provided_schedule_types' => $all_schedule_types,
2369 'today_date' => gmdate("Y-m-d"),
2370 'weeks' => $weeks,
2371 'week_days' => $week_days,
2372 'days' => $days,
2373 'is_auto_innodb' => $this->options->get_option('auto-innodb'),
2374 'scheduled_optimizations' => $auto_options,
2375 'auto_optimizations' => $auto_optimizations,
2376 'warning_url' => $wp_optimize->wp_optimize_url('https://teamupdraft.com/documentation/wp-optimize/topics/database-optimization/faqs/', __('Warning: you should read the FAQ about the risks of this operation first.', 'wp-optimize'), '', '', true)
2377 );
2378 }
2379
2380 $return_data['data']['enabled'] = $scheduled_optimizations_enabled;
2381 $return_data['data']['next_optimization'] = '';
2382
2383 if ($scheduled_optimizations_enabled) {
2384 $next_optimization_timestamp = apply_filters('wpo_cron_next_event', wp_next_scheduled('wpo_cron_event2'));
2385
2386 if ($next_optimization_timestamp) {
2387 $return_data['data']['next_optimization'] = $is_udc_request ? (int) $next_optimization_timestamp : esc_html(gmdate(get_option('date_format') . ' ' . get_option('time_format'), $next_optimization_timestamp + 60 * 60 * get_option('gmt_offset')));
2388 }
2389 }
2390
2391 if ($is_udc_request && $last_optimized_timestamp) {
2392 $return_data['data']['last_optimized'] = (int) $last_optimized_timestamp;
2393 }
2394
2395 // Add the translations.
2396 $return_data['data']['translations'] = array(
2397 'scheduled_optimization' => __('Scheduled Optimization', 'wp-optimize'),
2398 'next_schedule_run' => __('Next scheduled run', 'wp-optimize'),
2399 'no_scheduled_optimization' => __('No scheduled optimization', 'wp-optimize'),
2400 'add_optimization_tasks' => __('Add optimization tasks', 'wp-optimize'),
2401 'select_all' => __('Select all', 'wp-optimize'),
2402 'unselect_all' => __('Un-Select All', 'wp-optimize'),
2403 'select_schedule' => __('Select schedule', 'wp-optimize'),
2404 'run_an_optimization_every' => __('Run an optimization every', 'wp-optimize'),
2405 'add_optimization' => __('Add optimization', 'wp-optimize'),
2406 );
2407
2408 return $return_data;
2409 }
2410
2411 /**
2412 * Get wp-optimize status report data.
2413 *
2414 * @return array
2415 */
2416 private function get_wp_optimize_status_report_data() {
2417 $system_status = WP_Optimize_System_Status_Report::get_instance();
2418 $report_data = $system_status->generate_report();
2419 $replaceable_md_tags = $system_status->get_replaceable_md_tags();
2420
2421 return array('report_data' => $report_data, 'replaceable_md_tags' => $replaceable_md_tags);
2422 }
2423
2424 /**
2425 * Get data for the UDC reports.
2426 *
2427 * @return array
2428 */
2429 public function get_report_data() {
2430 $wp_optimize = WP_Optimize();
2431 $schedule_types = WP_Optimize::get_schedule_types();
2432 $scheduled_optimizations_enabled = $this->options->get_option('schedule', 'false') == 'true';
2433 $schedule_frequency = '';
2434 $unused_posts_images = 0;
2435 $optimized_images_percentage = 0;
2436
2437 if (WP_Optimize::is_premium()) {
2438 $wp_optimize_premium = WP_Optimize_Premium();
2439 $scheduled_optimizations = $wp_optimize_premium->get_scheduled_optimizations();
2440
2441 if (!empty($scheduled_optimizations)) {
2442 foreach ($scheduled_optimizations as $optimization) {
2443 if (isset($optimization['status']) && 1 === absint($optimization['status'])) {
2444 $scheduled_optimizations_enabled = true;
2445 $schedule_frequency = $schedule_types[$optimization['schedule_type']] ?? '';
2446 break;
2447 }
2448 }
2449 }
2450
2451 // Force calculate unused images.
2452 WP_Optimization_images::instance()->get_optimization_info();
2453 $unused_posts_images = WP_Optimization_images::instance()->get_unused_images_count();
2454 $optimized_images_percentage = WP_Optimize_Bulk_Smush::get_instance()->get_optimized_images_percentage();
2455
2456 } elseif ($scheduled_optimizations_enabled) {
2457 $schedule_type_saved_id = $this->options->get_option('schedule-type', 'wpo_weekly');
2458
2459 // Backwards compatibility:
2460 if ('wpo_otherweekly' == $schedule_type_saved_id) $schedule_type_saved_id = 'wpo_fortnightly';
2461
2462 $schedule_frequency = $schedule_types[$schedule_type_saved_id] ?? '';
2463 }
2464
2465 $total_cleaned = $this->options->get_option('total-cleaned-previous-month');
2466 $total_cleanup_size = $wp_optimize->format_size($total_cleaned);
2467
2468 $cache = $wp_optimize->get_page_cache();
2469 $page_caching_enabled = $cache->is_enabled();
2470
2471 $minification_enabled = wp_optimize_minify_config()->get('enabled') ?? false;
2472
2473 return array(
2474 'report_data' => array(
2475 'is_premium' => WP_Optimize::is_premium(),
2476 'scheduled_optimizations_enabled' => $scheduled_optimizations_enabled,
2477 'schedule_frequency' => $schedule_frequency,
2478 'total_cleaned' => $total_cleaned,
2479 'total_cleanup_size' => $total_cleanup_size,
2480 'unused_posts_images' => $unused_posts_images,
2481 'page_caching_enabled' => $page_caching_enabled,
2482 'minification_enabled' => $minification_enabled,
2483 'optimized_images_percentage' => $optimized_images_percentage . '%',
2484 ),
2485 'variables' => array(
2486 /* translators: %s is the cleaned up memory size. */
2487 'performance_highlights' => sprintf(__('%s saved', 'wp-optimize'), $total_cleanup_size),
2488 ),
2489 );
2490 }
2491
2492 /**
2493 * Returns freshly rendered HTML for the dashboard data sections (top row + module grid).
2494 *
2495 * @return array{success: bool, top_row: string, mod_grid: string}
2496 */
2497 public function refresh_dashboard() {
2498 $data = WP_Optimize_Dashboard::instance()->get_dashboard_data();
2499
2500 $top_row = WP_Optimize()->include_template('dashboard/partials/top-row.php', true, $data);
2501 $mod_grid = WP_Optimize()->include_template('dashboard/partials/mod-grid.php', true, $data);
2502
2503 return array(
2504 'success' => true,
2505 'top_row' => $top_row,
2506 'mod_grid' => $mod_grid,
2507 );
2508 }
2509 }
2510