PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | includes/class-wp-optimize-commands.php +1922 -42 3.3.0 → 4.7.0 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2
3 -if (!defined('WPO_PLUGIN_MAIN_PATH')) die('No direct access allowed');
3 +if (!defined('ABSPATH')) die('No direct access allowed');
4 4
5 5 /**
6 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 7 */
@@ -8,9 +8,9 @@
8 8 class WP_Optimize_Commands {
9 9
10 10 private $optimizer;
11 11
12 - private $options;
12 + protected $options;
13 13
14 14 private $wpo_sites; // used in get_optimizations_info command.
15 15
16 16 public function __construct() {
@@ -24,9 +24,9 @@
24 24
25 25 public function enable_or_disable_feature($data) {
26 26
27 27 $type = (string) $data['type'];
28 - $enable = (boolean) $data['enable'];
28 + $enable = (bool) $data['enable'];
29 29
30 30 $options = array($type => $enable);
31 31
32 32 return $this->optimizer->trackback_comment_actions($options);
@@ -36,9 +36,11 @@
36 36 return $this->options->save_sent_manual_run_optimization_options($sent_options);
37 37 }
38 38
39 39 public function get_status_box_contents() {
40 - return WP_Optimize()->include_template('database/status-box-contents.php', true, array('optimize_db' => false));
40 + $status_data = $this->get_all_status_data();
41 +
42 + return WP_Optimize()->include_template('database/status-box-contents.php', true, $status_data);
41 43 }
42 44
43 45 /**
44 46 * Get the database tabs information.
@@ -45,9 +47,11 @@
45 47 *
46 48 * @return string auto cleanup content.
47 49 */
48 50 public function get_settings_auto_cleanup_contents() {
49 - return WP_Optimize()->include_template('database/settings-auto-cleanup.php', true, array('optimize_db' => false, 'show_innodb_option' => WP_Optimize()->template_should_include_data() && $this->optimizer->show_innodb_force_optimize()));
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));
50 54 }
51 55
52 56 /**
53 57 * Get the settings tab information.
@@ -54,9 +58,10 @@
54 58 *
55 59 * @return string logging settings content.
56 60 */
57 61 public function get_logging_settings_contents() {
58 - return WP_Optimize()->include_template('settings/settings-logging.php', true, array('optimize_db' => false));
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));
59 64 }
60 65
61 66 /**
62 67 * Get the database tabs information
@@ -63,12 +68,475 @@
63 68 *
64 69 * @return string database table optimization rendered content
65 70 */
66 71 public function get_optimizations_table() {
67 - return WP_Optimize()->include_template('database/optimizations-table.php', true, array('does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization()));
72 +
73 + $optimization_data = $this->get_wp_optimize_data();
74 +
75 + return WP_Optimize()->include_template('database/optimizations-table.php', true, $optimization_data);
68 76 }
69 77
70 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 + /**
71 539 * Pulls and return the "WP Optimize" template contents. Primarily used for UpdraftCentral
72 540 * content display through ajax request.
73 541 *
74 542 * @return array An array containing the WPO translations and the "WP Optimize" tab's rendered contents
@@ -73,9 +541,12 @@
73 541 *
74 542 * @return array An array containing the WPO translations and the "WP Optimize" tab's rendered contents
75 543 */
76 544 public function get_wp_optimize_contents() {
77 - $content = WP_Optimize()->include_template('database/optimize-table.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data(), 'does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization()));
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 +
78 549 if (WP_Optimize()->is_updraft_central_request()) {
79 550 $content .= $this->get_status_box_contents();
80 551 }
81 552
@@ -91,9 +562,10 @@
91 562 *
92 563 * @return array An array containing the WPO translations and the "Table Information" tab's rendered contents
93 564 */
94 565 public function get_table_information_contents() {
95 - $content = WP_Optimize()->include_template('database/tables.php', true, array('optimize_db' => false, 'load_data' => WP_Optimize()->template_should_include_data()));
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']));
96 568
97 569 return array(
98 570 'content' => $content,
99 571 'translations' => $this->get_js_translation()
@@ -107,14 +579,25 @@
107 579 * @return array An array containing the WPO translations and the "Settings" tab's rendered contents
108 580 */
109 581 public function get_settings_contents() {
110 582 $admin_settings = '<form action="#" method="post" enctype="multipart/form-data" name="settings_form" id="settings_form">';
111 - $admin_settings .= WP_Optimize()->include_template('database/settings-general.php', true, array('optimize_db' => false));
112 - $admin_settings .= WP_Optimize()->include_template('database/settings-auto-cleanup.php', true, array('optimize_db' => false, 'show_innodb_option' => WP_Optimize()->template_should_include_data() && $this->optimizer->show_innodb_force_optimize()));
113 - $admin_settings .= WP_Optimize()->include_template('settings/settings-logging.php', true, array('optimize_db' => false));
114 - $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') .'" />';
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') .'" />';
115 594 $admin_settings .= '</form>';
116 - $admin_settings .= WP_Optimize()->include_template('settings/settings-trackback-and-comments.php', true, array('optimize_db' => false));
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 +
117 600 $content = $admin_settings;
118 601
119 602 return array(
120 603 'content' => $content,
@@ -125,11 +608,12 @@
125 608 /**
126 609 * Returns array of translations used by the WPO plugin. Primarily used for UpdraftCentral
127 610 * consumption.
128 611 *
612 + * @param array $params Optional parameters for the translation request
129 613 * @return array The WPO translations
130 614 */
131 - public function get_js_translation() {
615 + public function get_js_translation($params = array()) {
132 616 $translations = WP_Optimize()->wpo_js_translations();
133 617
134 618 // Make sure that we include the loggers classes info whenever applicable before
135 619 // returning the translations to UpdraftCentral.
@@ -136,8 +620,17 @@
136 620 if (is_callable(array(WP_Optimize(), 'get_loggers_classes_info'))) {
137 621 $translations['loggers_classes_info'] = WP_Optimize()->get_loggers_classes_info();
138 622 }
139 623
624 + if (isset($params['return_formatted_response'])) {
625 + return array(
626 + 'error' => false,
627 + 'data' => array(
628 + 'translations' => $translations,
629 + )
630 + );
631 + }
632 +
140 633 return $translations;
141 634 }
142 635
143 636 /**
@@ -163,12 +656,17 @@
163 656
164 657 /**
165 658 * Wipe settings command.
166 659 *
167 - * @return bool|false|int
660 + * @return bool|int
168 661 */
169 662 public function wipe_settings() {
170 - return $this->options->wipe_settings();
663 + $result = $this->options->wipe_settings();
664 +
665 + $onboarding = WP_Optimize()->get_onboarding();
666 + $onboarding->activate_onboarding_wizard();
667 +
668 + return $result;
171 669 }
172 670
173 671 /**
174 672 * Save lazy load settings.
@@ -201,8 +699,12 @@
201 699 * @param array $data Array of settings.
202 700 * @return bool
203 701 */
204 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 + }
205 707 return $this->options->save_wpo_sites_option($data['wpo-sites']);
206 708 }
207 709
208 710 /**
@@ -222,15 +724,19 @@
222 724 )
223 725 );
224 726 } else {
225 727 $optimization_id = $params['optimization_id'];
226 - $data = isset($params['data']) ? $params['data'] : array();
227 - $include_ui_elements = isset($data['include_ui_elements']) ? $data['include_ui_elements'] : false;
728 + $data = $params['data'] ?? array();
729 + $include_ui_elements = $data['include_ui_elements'] ?? false;
228 730
229 731 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
230 732
231 733 $result = is_a($optimization, 'WP_Optimization') ? $optimization->do_optimization() : null;
232 734
735 + if (null !== $result) {
736 + WP_Optimize()->get_options()->update_option('last-optimized', time());
737 + }
738 +
233 739 $results = array(
234 740 'result' => $result,
235 741 'messages' => array(),
236 742 'errors' => array(),
@@ -270,9 +776,9 @@
270 776 )
271 777 );
272 778 } else {
273 779 $optimization_id = $params['optimization_id'];
274 - $data = isset($params['data']) ? $params['data'] : array();
780 + $data = $params['data'] ?? array();
275 781 $params['offset'] = isset($params['offset']) ? (int) $params['offset'] : 0;
276 782 $params['limit'] = isset($params['limit']) ? (int) $params['limit'] : 50;
277 783
278 784 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
@@ -312,10 +818,10 @@
312 818 )
313 819 );
314 820 } else {
315 821 $optimization_id = $params['optimization_id'];
316 - $data = isset($params['data']) ? $params['data'] : array();
317 - $include_ui_elements = isset($data['include_ui_elements']) ? $data['include_ui_elements'] : false;
822 + $data = $params['data'] ?? array();
823 + $include_ui_elements = $data['include_ui_elements'] ?? false;
318 824
319 825 $optimization = $this->optimizer->get_optimization($optimization_id, $data);
320 826 $result = is_a($optimization, 'WP_Optimization') ? $optimization->get_optimization_info() : null;
321 827
@@ -341,14 +847,24 @@
341 847 */
342 848 public function get_table_list($data = array()) {
343 849 if (isset($data['refresh_plugin_json']) && filter_var($data['refresh_plugin_json'], FILTER_VALIDATE_BOOLEAN)) WP_Optimize()->get_db_info()->update_plugin_json();
344 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 +
345 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 + );
346 863
347 - return apply_filters('wpo_get_tables_data', array(
348 - 'table_list' => WP_Optimize()->include_template('database/tables-body.php', true, array('optimize_db' => false)),
349 - 'total_size' => $size[0]
350 - ));
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;
351 867 }
352 868
353 869 /**
354 870 * Get the database tabs information
@@ -355,9 +871,22 @@
355 871 *
356 872 * @return array
357 873 */
358 874 public function get_database_tabs() {
359 - return array_merge(array('optimizations' => $this->get_optimizations_table(), 'does_server_allows_table_optimization' => WP_Optimize()->does_server_allows_table_optimization()), $this->get_table_list());
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;
360 889 }
361 890
362 891 /**
363 892 * Do action wp_optimize_after_optimizations
@@ -380,9 +909,9 @@
380 909 * @param array $params
381 910 * @return array
382 911 */
383 912 public function get_optimizations_info($params) {
384 - $this->wpo_sites = isset($params['wpo-sites']) ? $params['wpo-sites'] : 0;
913 + $this->wpo_sites = $params['wpo-sites'] ?? 0;
385 914
386 915 add_filter('get_optimization_blogs', array($this, 'get_optimization_blogs_filter'));
387 916
388 917 $results = array();
@@ -419,8 +948,10 @@
419 948 }
420 949
421 950 /**
422 951 * Checks overdue crons and return message
952 + *
953 + * @return array
423 954 */
424 955 public function check_overdue_crons() {
425 956 $overdue_crons = WP_Optimize()->howmany_overdue_crons();
426 957
@@ -426,8 +957,10 @@
426 957
427 958 if ($overdue_crons >= 4) {
428 959 return array('m' => WP_Optimize()->show_admin_warning_overdue_crons($overdue_crons));
429 960 }
961 +
962 + return array();
430 963 }
431 964
432 965 /**
433 966 * Enable or disable Gzip compression.
@@ -444,18 +977,33 @@
444 977 *
445 978 * @return array
446 979 */
447 980 public function get_gzip_compression_status() {
448 - $status = WP_Optimize()->get_gzip_compression()->is_gzip_compression_enabled(true);
981 + $status = WP_Optimize()->get_gzip_compression()->is_gzip_compression_enabled(false);
449 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);
450 983 }
451 984
452 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 + /**
453 1001 * Import WP-Optimize settings.
454 1002 *
455 1003 * @param array $params array with 'settings' item where 'settings' json-encoded string.
456 1004 *
457 - * @return Array - the results of the import operation
1005 + * @return array - the results of the import operation
458 1006 */
459 1007 public function import_settings($params) {
460 1008 if (empty($params['settings'])) {
461 1009 return array('errors' => array(__('Please upload a valid settings file.', 'wp-optimize')));
@@ -462,10 +1010,10 @@
462 1010 }
463 1011
464 1012 $settings = json_decode($params['settings'], true);
465 1013
466 - // check if valid json file posted (requires PHP 5.3+)
467 - if ((function_exists('json_last_error') && 0 != json_last_error()) || empty($settings)) {
1014 + // check if valid json file posted
1015 + if (JSON_ERROR_NONE !== json_last_error() || empty($settings)) {
468 1016 return array('errors' => array(__('Please upload a valid settings file.', 'wp-optimize')));
469 1017 }
470 1018
471 1019 $cache_settings = $settings['cache_settings'];
@@ -474,10 +1022,11 @@
474 1022 $database_settings = $settings['database_settings'];
475 1023
476 1024 $cache = WP_Optimize()->get_page_cache();
477 1025 $cache->create_folders();
1026 + $cache_enable_result = null;
478 1027 if ($cache_settings['enable_page_caching']) {
479 - $cache->enable();
1028 + $cache_enable_result = $cache->enable();
480 1029 }
481 1030
482 1031 $wpo_browser_cache = WP_Optimize()->get_browser_cache();
483 1032 if (isset($cache_settings['enable_browser_cache']) && $cache_settings['enable_browser_cache']) {
@@ -491,10 +1040,15 @@
491 1040 $message = '';
492 1041 $cache_result = WP_Optimize()->get_page_cache()->config->update($cache_settings);
493 1042 $minify_result = WP_Optimize()->get_minify()->minify_commands->save_minify_settings($minify_settings);
494 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);
495 1045 $this->save_settings($database_settings);
496 1046
1047 + if (is_wp_error($cache_enable_result)) {
1048 + $message .= $cache_enable_result->get_error_message() . PHP_EOL;
1049 + }
1050 +
497 1051 if (is_wp_error($cache_result)) {
498 1052 $message .= $cache_result->get_error_message() . PHP_EOL;
499 1053 }
500 1054
@@ -506,8 +1060,12 @@
506 1060 if (is_wp_error($smush_result)) {
507 1061 $message .= $smush_result->get_error_message() . PHP_EOL;
508 1062 }
509 1063
1064 + if (is_wp_error($webp_result)) {
1065 + $message .= $webp_result->get_error_message() . PHP_EOL;
1066 + }
1067 +
510 1068 return array(
511 1069 'success' => true,
512 1070 'message' => empty($message) ? __('The settings were imported successfully.', 'wp-optimize') : $message
513 1071 );
@@ -515,9 +1073,9 @@
515 1073
516 1074 /**
517 1075 * Dismiss install or updated notice
518 1076 *
519 - * @return mixed
1077 + * @return array
520 1078 */
521 1079 public function dismiss_install_or_update_notice() {
522 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'))) {
523 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.'));
@@ -526,13 +1084,17 @@
526 1084 if (!WP_Optimize()->get_install_or_update_notice()->dismiss()) {
527 1085 return array('errors' => array('The notice could not be dismissed. The settings could not be updated'));
528 1086 }
529 1087
530 - return true;
1088 + return array();
531 1089 }
532 1090
533 1091 /**
534 1092 * Run images trash command.
1093 + *
1094 + * @param array $params
1095 + *
1096 + * @return array
535 1097 */
536 1098 public function images_trash_command($params) {
537 1099 if (!class_exists('WP_Optimize_Images_Trash_Manager_Commands')) {
538 1100 return array(
@@ -540,9 +1102,9 @@
540 1102 );
541 1103 }
542 1104
543 1105 // get posted command.
544 - $trash_command = isset($params['images_trash_command']) ? $params['images_trash_command'] : '';
1106 + $trash_command = $params['images_trash_command'] ?? '';
545 1107 // check if command is allowed.
546 1108 $allowed_commands = WP_Optimize_Images_Trash_Manager_Commands::get_allowed_ajax_commands();
547 1109
548 1110 if (!in_array($trash_command, $allowed_commands)) {
@@ -565,9 +1127,9 @@
565 1127 /**
566 1128 * Power tweak handling
567 1129 *
568 1130 * @param array $params
569 - * @return mixed
1131 + * @return array
570 1132 */
571 1133 public function power_tweak($params) {
572 1134 global $wp_optimize_premium;
573 1135 if (!is_a($wp_optimize_premium, 'WP_Optimize_Premium') || !property_exists($wp_optimize_premium, 'power_tweaks') || !isset($params['sub_action'])) return array(
@@ -574,9 +1136,9 @@
574 1136 'errors' => array(__('No such command found', 'wp-optimize')),
575 1137 );
576 1138
577 1139 $action = $params['sub_action'];
578 - $data = $params['data'] ? $params['data'] : array();
1140 + $data = $params['data'] ?: array();
579 1141 if (!isset($data['tweak'])) return array(
580 1142 'errors' => array(__('No tweak provided', 'wp-optimize'))
581 1143 );
582 1144
@@ -595,8 +1157,9 @@
595 1157 }
596 1158 if ($result && !is_wp_error($result)) {
597 1159 return is_array($result) ? array_merge(array('success' => true), $result) : array('success' => true, 'message' => $result);
598 1160 } else {
1161 + // translators: %s is an action/command
599 1162 $error_message = is_wp_error($result) ? $result->get_error_message() : sprintf(__('The command %s failed', 'wp-optimize'), $action);
600 1163 return array(
601 1164 'success' => false,
602 1165 'errors' => array($error_message)
@@ -604,19 +1167,41 @@
604 1167 }
605 1168 }
606 1169
607 1170 /**
608 - * Ignores the table delete warning for the current user
1171 + * Ignores the table deletion warning for the current user
609 1172 *
610 - * @return boolean
1173 + * @return array
611 1174 */
612 - public function user_ignores_table_delete_warning() {
1175 + public function user_ignores_table_deletion_warning() {
613 1176 return array(
614 - 'success' => update_user_meta(get_current_user_id(), 'wpo-ignores-table-delete-warning', true)
1177 + 'success' => update_user_meta(get_current_user_id(), 'wpo-ignores-table-deletion-warning', true)
615 1178 );
616 1179 }
617 1180
618 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 + /**
619 1204 * Exports unused images as a CSV file to the `uploads` folder
620 1205 *
621 1206 * @return array
622 1207 */
@@ -623,7 +1208,1302 @@
623 1208 public function export_csv() {
624 1209 WP_Optimization_images::instance()->output_csv();
625 1210 return array(
626 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,
627 2507 );
628 2508 }
629 2509 }