PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.5.4
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.5.4
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-admin.php

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

906 lines 36.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) die('No direct access allowed');
3
4 if (!class_exists('WP_Optimize_Admin')) :
5 class WP_Optimize_Admin {
6
7 /**
8 * Class constructor
9 */
10 public function __construct() {
11 if (is_multisite()) {
12 add_action('network_admin_menu', array($this, 'admin_menu'));
13 } else {
14 add_action('admin_menu', array($this, 'admin_menu'));
15 }
16 add_action('admin_bar_menu', array($this, 'cache_admin_bar'), 100, 1);
17 }
18
19 /**
20 * Returns singleton instance object
21 *
22 * @return WP_Optimize_Admin Returns `WP_Optimize_Admin` object
23 */
24 public static function instance() {
25 static $_instance = null;
26 if (empty($_instance)) {
27 $_instance = new self();
28 }
29 return $_instance;
30 }
31
32
33 /**
34 * Builds the Tabs that should be displayed
35 *
36 * @param string $page
37 *
38 * @return array Returns all tabs specified array
39 */
40 public function get_tabs($page) {
41 // define tabs for pages.
42 $pages_tabs = array(
43 'WP-Optimize' => array(
44 'optimize' => __('Optimizations', 'wp-optimize'),
45 'tables' => __('Tables', 'wp-optimize'),
46 'settings' => __('Settings', 'wp-optimize'),
47 'table_analysis' => __('Table usage', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>'
48 ),
49 'wpo_images' => array(
50 'smush' => __('Compress images', 'wp-optimize'),
51 'dimensions' => __('Images dimensions', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
52 'unused' => __('Unused images and sizes', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
53 'lazyload' => __('Lazy-load', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
54 ),
55 'wpo_cache' => array(
56 'cache' => __('Page cache', 'wp-optimize'),
57 'preload' => __('Preload', 'wp-optimize'),
58 'advanced' => __('Advanced settings', 'wp-optimize'),
59 'gzip' => __('Gzip compression', 'wp-optimize'),
60 'settings' => __('Static file headers', 'wp-optimize') // Adds a settings tab
61 ),
62 'wpo_minify' => array(
63 "status" => __('Minify status', 'wp-optimize'),
64 "js" => __('JavaScript', 'wp-optimize').'<span class="menu-pill disabled hidden">'.__('Disabled', 'wp-optimize').'</span>',
65 "css" => __('CSS', 'wp-optimize').'<span class="menu-pill disabled hidden">'.__('Disabled', 'wp-optimize').'</span>',
66 "font" => __('Fonts', 'wp-optimize'),
67 "analytics" => __('Google Analytics', 'wp-optimize').'<span class="menu-pill premium-only">Premium</span>',
68 "settings" => __('Settings', 'wp-optimize'),
69 "preload" => __('Preload', 'wp-optimize'),
70 "advanced" => __('Advanced', 'wp-optimize')
71 ),
72 'wpo_performance' => array(
73 '404_detector' => __('Not found requests', 'wp-optimize'),
74 ),
75 'wpo_settings' => array(
76 'settings' => array(
77 'title' => __('Settings', 'wp-optimize'),
78 ),
79 // 'updraftcentral' => array(
80 // 'title' => 'UpdraftCentral'
81 // ),
82 'status' => __('System status', 'wp-optimize'),
83 ),
84 'wpo_support' => array('support' => __('Support / FAQs', 'wp-optimize')),
85 'wpo_mayalso' => array('may_also' => __('Premium / Plugin family', 'wp-optimize')),
86 );
87
88 $tabs = (array_key_exists($page, $pages_tabs)) ? $pages_tabs[$page] : array();
89 $filtered_tabs = apply_filters('wp_optimize_admin_page_'.$page.'_tabs', $tabs);
90 if (!empty($filtered_tabs) && is_array($filtered_tabs)) return $filtered_tabs;
91 return $tabs;
92 }
93
94 /**
95 * Main page structure.
96 */
97 public function display_admin() {
98 $capability_required = WP_Optimize()->capability_required();
99 $can_run_optimizations = WP_Optimize()->can_run_optimizations();
100 $can_manage_options = WP_Optimize()->can_manage_options();
101
102 if (!current_user_can($capability_required) || (!$can_run_optimizations && !$can_manage_options)) {
103 echo "Permission denied.";
104 return;
105 }
106
107 $this->register_admin_content();
108
109 echo '<div id="wp-optimize-wrap">';
110
111 WP_Optimize()->include_template('admin-page-header.php', false, array('show_notices' => !(WP_Optimize()->get_install_or_update_notice()->show_current_notice())));
112
113 do_action('wpo_admin_after_header');
114
115 echo '<div id="actions-results-area"></div>';
116
117 $pages = $this->get_submenu_items();
118
119 foreach ($pages as $page) {
120 if (isset($page['menu_slug'])) {
121 $this->display_admin_page($page['menu_slug']);
122 }
123 }
124
125 do_action('wpo_admin_before_closing_wrap');
126
127 // closes main plugin wrapper div. #wp-optimize-wrap
128 echo '</div><!-- END #wp-optimize-wrap -->';
129
130 }
131
132 /**
133 * Prepare and display admin page with $page id.
134 *
135 * @param string $page wp-optimize page id i.e. dashboard, database, images, cache, ...
136 */
137 public function display_admin_page($page) {
138
139 $active_page = TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('request', 'page', 'string', 'sanitize_text_field', '');
140
141 echo '<div class="wpo-page' . ($active_page === $page ? ' active' : '') . '" data-whichpage="'.esc_attr($page).'">';
142
143 echo '<div class="wpo-main">';
144
145 // get defined tabs for $page.
146 $tabs = $this->get_tabs($page);
147
148 // if no tabs defined for $page then use $page as $active_tab for load template, doing related actions e t.c.
149 if (empty($tabs)) {
150 $active_tab = $page;
151 } else {
152 $tab_keys = array_keys($tabs);
153 $default_tab = apply_filters('wp_optimize_admin_'.$page.'_default_tab', $tab_keys[0]);
154 $active_tab = substr(TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('get', 'tab', null, 'sanitize_text_field', ''), 12);
155 if (!in_array($active_tab, array_keys($tabs))) $active_tab = $default_tab;
156 }
157
158 do_action('wp_optimize_admin_page_'.$page, $active_tab);
159
160 // if tabs defined then display
161 if (!empty($tabs)) {
162 WP_Optimize()->include_template('admin-page-header-tabs.php', false, array('page' => $page, 'active_tab' => $active_tab, 'tabs' => $tabs, 'wpo_is_premium' => WP_Optimize::is_premium()));
163 }
164
165 foreach ($tabs as $tab_id => $tab_description) {
166 // output wrap div for tab with id #wp-optimize-nav-tab-contents-'.$page.'-'.$tab_id
167 echo '<div class="wp-optimize-nav-tab-contents" id="wp-optimize-nav-tab-'.esc_attr($page).'-'.esc_attr($tab_id).'-contents" '.(($tab_id === $active_tab) ? '' : 'style="display:none;"').'>';
168
169 echo '<div class="postbox wpo-tab-postbox">';
170 // call action for generate tab content.
171
172 do_action('wp_optimize_admin_page_'.$page.'_'.$tab_id);
173
174 // closes postbox.
175 echo '</div><!-- END .postbox -->';
176 // closes tab wrapper.
177 echo '</div><!-- END .wp-optimize-nav-tab-contents -->';
178 }
179
180 echo '</div><!-- END .wpo-main -->';
181
182 do_action('wp_optimize_admin_after_page_'.$page, $active_tab);
183
184 echo '</div><!-- END .wpo-page -->';
185
186 }
187
188 /**
189 * Define required actions for admin pages.
190 */
191 public function register_admin_content() {
192
193 do_action('wp_optimize_register_admin_content');
194
195 /**
196 * SETTINGS
197 */
198 add_action('wp_optimize_admin_page_wpo_settings_settings', array($this, 'output_dashboard_settings_tab'), 20);
199 add_action('wp_optimize_admin_page_wpo_settings_status', array($this, 'output_dashboard_status_tab'));
200
201 /**
202 * UpdraftCentral
203 */
204 // add_action('wp_optimize_admin_page_wpo_settings_updraftcentral', array($this, 'output_dashboard_updraftcentral_tab'), 20);
205
206 /**
207 * Premium / other plugins
208 */
209 add_action('wp_optimize_admin_page_wpo_mayalso_may_also', array($this, 'output_dashboard_other_plugins_tab'), 20);
210
211 /**
212 * DATABASE
213 */
214 add_action('wp_optimize_admin_page_WP-Optimize_optimize', array($this, 'output_database_optimize_tab'), 20);
215 add_action('wp_optimize_admin_page_WP-Optimize_tables', array($this, 'output_database_tables_tab'), 20);
216 add_action('wp_optimize_admin_page_WP-Optimize_settings', array($this, 'output_database_settings_tab'), 20);
217 add_action('wp_optimize_admin_page_WP-Optimize_table_analysis', array($this, 'output_table_usage_tab'), 20);
218 /**
219 * PERFORMANCE
220 */
221 add_action('wp_optimize_admin_page_wpo_performance_404_detector', array($this, 'output_performance_404_requests'), 20);
222
223 /**
224 * CACHE
225 */
226 add_action('wp_optimize_admin_page_wpo_cache_cache', array($this, 'output_page_cache_tab'), 20);
227 if (!WP_Optimize()->get_server_compatibility_instance()->does_server_handle_cache()) {
228 add_action('wp_optimize_admin_page_wpo_cache_preload', array($this, 'output_page_cache_preload_tab'), 20);
229 add_action('wp_optimize_admin_page_wpo_cache_advanced', array($this, 'output_page_cache_advanced_tab'), 20);
230 }
231 add_action('wp_optimize_admin_page_wpo_cache_gzip', array($this, 'output_cache_gzip_tab'), 20);
232 add_action('wp_optimize_admin_page_wpo_cache_settings', array($this, 'output_cache_settings_tab'), 20);
233 add_action('wpo_page_cache_advanced_settings', array($this, 'output_cloudflare_settings'), 20);
234 /**
235 * SUPPORT
236 */
237 add_action('wp_optimize_admin_page_wpo_support_support', array($this, 'output_dashboard_support_tab'), 20);
238 // Display Support page.
239
240 if (!WP_Optimize::is_premium()) {
241 /**
242 * Add action for display Images > Unused images and sizes tab.
243 */
244 add_action('wp_optimize_admin_page_wpo_images_unused', array($this, 'admin_page_wpo_images_unused'));
245
246 /**
247 * Add action for display Dashboard > Lazyload tab.
248 */
249 add_action('wp_optimize_admin_page_wpo_images_lazyload', array($this, 'admin_page_wpo_images_lazyload'));
250 } else {
251 /**
252 * Add filter for display footer review message and link.
253 */
254 add_filter('admin_footer_text', array($this, 'display_footer_review_message'));
255 }
256
257 /**
258 * Add action for display Images > Images dimensions tab.
259 */
260 add_action('wp_optimize_admin_page_wpo_images_dimensions', array($this, 'admin_page_wpo_images_dimensions'));
261 }
262
263 /**
264 * Database settings
265 */
266 public function output_database_settings_tab() {
267
268 if (WP_Optimize()->can_run_optimizations()) {
269 $wp_optimize_commands = new WP_Optimize_Commands();
270 $settings_general_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_general_settings')));
271 $settings_cleanup_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_schedule_cleanup_settings')));
272
273 WP_Optimize()->include_template('database/settings.php', false, array('settings_general_data' => $settings_general_data['data']['wp_optimize_general_settings'], 'settings_cleanup_data' => $settings_cleanup_data['data']['wp_optimize_schedule_cleanup_settings']));
274 } else {
275 $this->prevent_manage_options_info();
276 }
277 }
278
279 /**
280 * Table usage tab
281 *
282 * @return void
283 */
284 public function output_table_usage_tab() {
285 if (WP_Optimize::is_premium()) {
286 $extract = array('is_enabled' => (bool) WP_Optimize()->get_options()->get_option(WPO_DB_Table_Analysis::ENABLED_SETTING_NAME), 'dashboard' => WP_Optimize_Premium()->get_db_table_analysis_dashboard());
287 } else {
288 $extract = array('is_enabled' => false);
289 }
290 WP_Optimize()->include_template('database/table-analysis.php', false, $extract);
291 }
292
293 /**
294 * Dashboard settings
295 */
296 public function output_dashboard_settings_tab() {
297 $options = WP_Optimize()->get_options();
298
299 if (isset($_SERVER['REQUEST_METHOD']) && 'POST' === $_SERVER['REQUEST_METHOD']) {
300 // Nonce check.
301 check_admin_referer('wpo_settings');
302
303 $output = $options->save_settings($_POST);
304
305 if (isset($_POST['wp-optimize-settings'])) {
306 // save settings request sent.
307 $output = $options->save_settings($_POST);
308 }
309
310 $this->wpo_render_output_messages($output);
311 }
312
313 if (WP_Optimize()->can_manage_options()) {
314 $wp_optimize_commands = new WP_Optimize_Commands();
315 $loggers_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_logging_settings')));
316 $settings_trackback_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_trackback_toggle_settings')));
317 $settings_comments_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_comments_toggle_settings')));
318 $settings_general_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize_general_settings')));
319
320 WP_Optimize()->include_template('settings/settings.php', false, array('loggers_data' => $loggers_data['data']['wp_optimize_logging_settings'], 'settings_trackback_data' => $settings_trackback_data['data']['wp_optimize_trackback_toggle_settings'], 'settings_comments_data' => $settings_comments_data['data']['wp_optimize_comments_toggle_settings'], 'settings_general_data' => $settings_general_data['data']['wp_optimize_general_settings']));
321 } else {
322 $this->prevent_manage_options_info();
323 }
324 }
325
326 /**
327 * Outputs the system status page
328 */
329 public function output_dashboard_status_tab() {
330 WP_Optimize()->include_template('status/status-page.php');
331 }
332
333 /**
334 * UpdraftCentral settings tab
335 */
336 public function output_dashboard_updraftcentral_tab() {
337 if (WP_Optimize()->can_manage_options()) {
338 global $updraftcentral_host_plugin;
339 $updraftcentral_host_plugin->debugtools_dashboard();
340 } else {
341 $this->prevent_manage_options_info();
342 }
343 }
344
345 /**
346 * Dashboard support tab
347 */
348 public function output_dashboard_support_tab() {
349 WP_Optimize()->include_template('settings/support-and-faqs.php');
350 }
351
352 /**
353 * Dashboard Other plugins / premium tab
354 */
355 public function output_dashboard_other_plugins_tab() {
356 WP_Optimize()->include_template('settings/may-also-like.php');
357 }
358
359 /**
360 * Cache tab
361 */
362 public function output_page_cache_tab() {
363 $wpo_cache = WP_Optimize()->get_page_cache();
364 $wpo_cache_options = $wpo_cache->config->get();
365 $display = $wpo_cache->is_enabled() ? "display: block;" : "display: none;";
366 $error = is_wp_error(WP_Optimize()->get_init_page_cache_status()) ? WP_Optimize()->get_init_page_cache_status()->get_error_message() : '';
367
368 WP_Optimize()->include_template('cache/page-cache.php', false, array(
369 'wpo_cache' => $wpo_cache,
370 'active_cache_plugins' => WP_Optimize_Detect_Cache_Plugins::instance()->get_active_cache_plugins(),
371 'wpo_cache_options' => $wpo_cache_options,
372 'cache_size' => $wpo_cache->get_cache_size(),
373 'display' => $display,
374 'can_purge_the_cache' => $wpo_cache->can_purge_cache(),
375 'auto_preload_purged_contents' => $wpo_cache_options['auto_preload_purged_contents'],
376 'does_server_handle_cache' => WP_Optimize()->get_server_compatibility_instance()->does_server_handle_cache(),
377 'error' => $error,
378 ));
379 }
380
381 /**
382 * Preload tab
383 */
384 public function output_page_cache_preload_tab() {
385 $wpo_cache = WP_Optimize()->get_page_cache();
386 $wpo_cache_options = $wpo_cache->config->get();
387 $wpo_cache_preloader = WP_Optimize_Page_Cache_Preloader::instance();
388 $is_running = $wpo_cache_preloader->is_busy() && !$wpo_cache_preloader->is_cancelled();
389 $status = $wpo_cache_preloader->get_status_info();
390
391 $scheduled_types = WP_Optimize::get_schedule_types();
392 $scheduled_types = array_filter($scheduled_types, function($type) {
393 return 'wpo_once' !== $type;
394 }, ARRAY_FILTER_USE_KEY);
395 $schedule_options = array_merge(
396 array(
397 'wpo_use_cache_lifespan' => __('Same as cache lifespan', 'wp-optimize')
398 ),
399 $scheduled_types
400 );
401
402 WP_Optimize()->include_template('cache/page-cache-preload.php', false, array(
403 'wpo_cache_options' => $wpo_cache_options,
404 'is_running' => $is_running,
405 'status_message' => $status['message'] ?? '',
406 'schedule_options' => $schedule_options
407 ));
408 }
409
410 /**
411 * Advanced tab
412 */
413 public function output_page_cache_advanced_tab() {
414 $wpo_cache = WP_Optimize()->get_page_cache();
415 $wpo_cache_options = $wpo_cache->config->get();
416
417 $cache_exception_conditional_tags = is_array($wpo_cache_options['cache_exception_conditional_tags']) ? join("\n", $wpo_cache_options['cache_exception_conditional_tags']) : '';
418 $cache_include_urls = is_array($wpo_cache_options['cache_include_urls']) ? join("\n", $wpo_cache_options['cache_include_urls']) : '';
419 $cache_exception_urls = is_array($wpo_cache_options['cache_exception_urls']) ? join("\n", $wpo_cache_options['cache_exception_urls']) : '';
420 $cache_ignore_query_variables = is_array($wpo_cache_options['cache_ignore_query_variables']) ? join("\n", $wpo_cache_options['cache_ignore_query_variables']) : '';
421 $cache_exception_cookies = is_array($wpo_cache_options['cache_exception_cookies']) ? join("\n", $wpo_cache_options['cache_exception_cookies']) : '';
422 $cache_exception_browser_agents = is_array($wpo_cache_options['cache_exception_browser_agents']) ? join("\n", $wpo_cache_options['cache_exception_browser_agents']) : '';
423
424 WP_Optimize()->include_template('cache/page-cache-advanced.php', false, array(
425 'wpo_cache' => $wpo_cache,
426 'wpo_cache_options' => $wpo_cache_options,
427 'cache_include_urls' => $cache_include_urls,
428 'cache_exception_urls' => $cache_exception_urls,
429 'cache_ignore_query_variables' => $cache_ignore_query_variables,
430 'cache_exception_conditional_tags' => $cache_exception_conditional_tags,
431 'cache_exception_cookies' => $cache_exception_cookies,
432 'cache_exception_browser_agents' => $cache_exception_browser_agents,
433 ));
434 }
435
436 /**
437 * Gzip tab
438 */
439 public function output_cache_gzip_tab() {
440 $wpo_gzip_compression = WP_Optimize()->get_gzip_compression();
441 $wpo_gzip_compression_enabled = $wpo_gzip_compression->is_gzip_compression_enabled(true);
442 $wpo_gzip_headers_information = $wpo_gzip_compression->get_headers_information();
443 $is_cloudflare_site = $this->is_cloudflare_site();
444 $is_gzip_compression_section_exists = $wpo_gzip_compression->is_gzip_compression_section_exists();
445 $wpo_gzip_compression_enabled_by_wpo = $is_gzip_compression_section_exists && $wpo_gzip_compression_enabled && !$is_cloudflare_site && !(is_array($wpo_gzip_headers_information) && 'brotli' === $wpo_gzip_headers_information['compression']);
446
447 WP_Optimize()->include_template('cache/gzip-compression.php', false, array(
448 'wpo_gzip_headers_information' => $wpo_gzip_headers_information,
449 'wpo_gzip_compression_enabled' => $wpo_gzip_compression_enabled,
450 'is_cloudflare_site' => $is_cloudflare_site,
451 'wpo_gzip_compression_enabled_by_wpo' => $wpo_gzip_compression_enabled_by_wpo,
452 'wpo_gzip_compression_settings_added' => $is_gzip_compression_section_exists,
453 'info_link' => 'https://teamupdraft.com/documentation/wp-optimize/topics/caching/faqs/what-is-gzip-compression/?utm_source=wpo-plugin&utm_medium=referral&utm_campaign=paac&utm_content=lossy-compression-guide&utm_creative_format=text',
454 'faq_link' => 'https://getwpo.com/gzip-faq-link/',
455 'class_name' => (!is_wp_error($wpo_gzip_compression_enabled) && $wpo_gzip_compression_enabled ? 'wpo-enabled' : 'wpo-disabled')
456 ));
457 }
458
459 /**
460 * Cache tab
461 */
462 public function output_cache_settings_tab() {
463
464 $wpo_browser_cache = WP_Optimize()->get_browser_cache();
465 $wpo_browser_cache_enabled = $wpo_browser_cache->is_enabled();
466
467 WP_Optimize()->include_template('cache/browser-cache.php', false, array(
468 'wpo_browser_cache_enabled' => $wpo_browser_cache_enabled,
469 'is_cloudflare_handling_browser_cache' => $this->is_cloudflare_handling_browser_cache(),
470 'wpo_browser_cache_settings_added' => $wpo_browser_cache->is_browser_cache_section_exists(),
471 'class_name' => (true === $wpo_browser_cache_enabled ? 'wpo-enabled' : 'wpo-disabled'),
472 'wpo_browser_cache_expire_days' => WP_Optimize()->get_options()->get_option('browser_cache_expire_days', '28'),
473 'wpo_browser_cache_expire_hours' => WP_Optimize()->get_options()->get_option('browser_cache_expire_hours', '0'),
474 'info_link' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching',
475 'faq_link' => 'https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-ubuntu-16-04',
476 ));
477 }
478
479 /**
480 * Check if is the current site handled with Cloudflare.
481 *
482 * @return bool
483 */
484 public function is_cloudflare_site(): bool {
485 $response = wp_remote_get(home_url());
486 if (is_wp_error($response)) return false;
487
488 $cloudflare_status = wp_remote_retrieve_header($response, 'cf-cache-status');
489
490 return !empty($cloudflare_status);
491 }
492
493 /**
494 * Check if browser cache rules is handled by Cloudflare.
495 *
496 * @return bool
497 */
498 private function is_cloudflare_handling_browser_cache(): bool {
499 $response = wp_remote_get(home_url());
500 if (is_wp_error($response)) return false;
501
502 $headers = wp_remote_retrieve_headers($response);
503 return isset($headers['cf-cache-status']) && (isset($headers['cache-control']) || isset($headers['expires']));
504 }
505
506 /**
507 * Include Cloudflare settings template.
508 */
509 public function output_cloudflare_settings() {
510 if (WP_Optimize::is_premium() || !apply_filters('show_cloudflare_settings', $this->is_cloudflare_site())) return;
511
512 WP_Optimize()->include_template('cache/page-cache-cloudflare-placeholder.php');
513 }
514
515 /**
516 * Outputs the DB optimize Tab
517 */
518 public function output_database_optimize_tab() {
519 $optimizer = WP_Optimize()->get_optimizer();
520 $options = WP_Optimize()->get_options();
521
522 $nonce_passed = TeamUpdraft\WP_Optimize\Includes\Fragments\verify_nonce('_wpnonce', 'wpo_optimization');
523
524 // save options.
525 $post = TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('post', 'wp-optimize');
526
527 if ($nonce_passed && $post) $options->save_sent_manual_run_optimization_options($_POST, true); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only isset is used to check
528
529 $optimize_db = $nonce_passed && TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('post', 'optimize-db');
530
531 $optimization_results = (($nonce_passed) ? $optimizer->do_optimizations($_POST) : false); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only isset is used to check, and compared again literal string
532
533 // display optimizations table or restricted access message.
534 if (WP_Optimize()->can_run_optimizations()) {
535 $wp_optimize_commands = new WP_Optimize_Commands();
536 $status_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('all_status')));
537 $optimizations_table_data = $wp_optimize_commands->get_widgets_data(array('widgets' => array('wp_optimize')));
538 WP_Optimize()->include_template('database/optimize-table.php', false, array('optimize_db' => $optimize_db, 'optimization_results' => $optimization_results, 'load_data' => false, 'does_server_allow_table_optimization' => WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization(), 'optimizations_table_data' => $optimizations_table_data['data']['wp_optimize'], 'status_data' => $status_data['data']['all_status']));
539 } else {
540 $this->prevent_run_optimizations_message();
541 }
542 }
543
544 /**
545 * Outputs the DB Tables Tab
546 */
547 public function output_database_tables_tab() {
548 $nonce_passed = TeamUpdraft\WP_Optimize\Includes\Fragments\verify_nonce('_wpnonce', 'wpo_optimization');
549
550 $optimize_db = $nonce_passed && TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('post', 'optimize-db');
551
552 if (!WP_Optimize()->get_server_compatibility_instance()->does_server_allow_table_optimization()) {
553 $message = __('Your server takes care of table optimization', 'wp-optimize');
554 $this->prevent_run_optimizations_message($message);
555 } elseif (WP_Optimize()->can_run_optimizations()) {
556 WP_Optimize()->include_template('database/tables.php', false, array('optimize_db' => $optimize_db, 'load_data' => WP_Optimize()->template_should_include_data()));
557 } else {
558 $this->prevent_run_optimizations_message();
559 }
560 }
561
562 /**
563 * Outputs Performance 404 requests Tab
564 */
565 public function output_performance_404_requests() {
566 $wp_optimize = WP_Optimize();
567 $is_enabled = $wp_optimize->get_options()->get_option('404_detector', 0);
568
569 $detector = $wp_optimize->get_404_detector();
570 $suspicious_threshold = $detector->get_suspicious_request_count_threshold();
571
572 $report_has_data = false;
573 $requests = array();
574
575 if ($is_enabled) {
576 $requests = $detector->get_suspicious_requests();
577
578 foreach ($requests as $url_requests) {
579 foreach ($url_requests as $row) {
580 if (1 < $row->occurrences && 'grouped' === $row->row_type) {
581 if (0 === $row->non_suspicious_referrers && 1 < $row->total_referrers) {
582 continue;
583 }
584 }
585 $report_has_data = true;
586 }
587 }
588 }
589
590 $wp_optimize->include_template('performance/404-detector.php', false, array(
591 'requests' => $requests,
592 'suspicious_threshold' => $suspicious_threshold,
593 'obj_404_detector' => $detector,
594 'report_has_data' => $report_has_data,
595 'is_enabled' => $is_enabled,
596 ));
597 }
598
599 /**
600 * Runs upon the WP action admin_page_wpo_images_unused
601 */
602 public function admin_page_wpo_images_unused() {
603 WP_Optimize()->include_template('images/unused.php');
604 }
605
606 /**
607 * Runs upon the WP action wp_optimize_admin_page_wpo_images_lazyload
608 */
609 public function admin_page_wpo_images_lazyload() {
610 WP_Optimize()->include_template('images/lazyload.php');
611 }
612
613 /**
614 * Runs upon the WP action wp_optimize_admin_page_wpo_images_dimensions
615 */
616 public function admin_page_wpo_images_dimensions() {
617 $options = WP_Optimize()->get_options();
618 $image_dimensions = $options->get_option('image_dimensions');
619 $ignore_classes = $options->get_option('image_dimensions_ignore_classes');
620 WP_Optimize()->include_template('images/dimensions.php', false, array(
621 'images_dimensions_status' => $image_dimensions,
622 'ignore_classes' => $ignore_classes ?: '',
623 ));
624 }
625
626 /**
627 * Show footer review message and link.
628 *
629 * @return string
630 */
631 public function display_footer_review_message() {
632 $message = sprintf(
633 // translators: %1$s is plugin name, %2$s is 5-star rating, %3$s is link to Trustpilot, %4$s is link to G2.
634 __('Enjoyed %1$s? Please leave us a %2$s rating on %3$s or %4$s.', 'wp-optimize').' '.__('We really appreciate your support!', 'wp-optimize'),
635 '<b>WP-Optimize</b>',
636 '<span style="color:#2271b1">&starf;&starf;&starf;&starf;&starf;</span>',
637 '<a href="https://uk.trustpilot.com/review/getwpo.com" target="_blank">Trustpilot</a>',
638 '<a href="https://www.g2.com/products/wp-optimize/reviews" target="_blank">G2.com</a>'
639 );
640 return $message;
641 }
642
643 /**
644 * Adds menu in admin bar
645 */
646 public function wpo_admin_bar() {
647 $wp_admin_bar = $GLOBALS['wp_admin_bar'];
648
649 if (defined('WPOPTIMIZE_ADMINBAR_DISABLE') && WPOPTIMIZE_ADMINBAR_DISABLE) return;
650
651 // Show menu item in top bar only for super admins.
652 if (is_multisite() & !is_super_admin(get_current_user_id())) return;
653
654 // Add a link called at the top admin bar.
655 $args = array(
656 'id' => 'wp-optimize-node',
657 'title' => apply_filters('wpoptimize_admin_node_title', 'WP-Optimize')
658 );
659 $wp_admin_bar->add_node($args);
660
661 $pages = $this->get_submenu_items();
662
663 foreach ($pages as $page_id => $page) {
664
665 if (!isset($page['create_submenu']) || !$page['create_submenu']) {
666 if (isset($page['icon']) && 'separator' === $page['icon']) {
667 $args = array(
668 'id' => 'wpo-separator-'.$page_id,
669 'parent' => 'wp-optimize-node',
670 'meta' => array(
671 'class' => 'separator',
672 ),
673 );
674 $wp_admin_bar->add_node($args);
675 }
676 continue;
677 }
678
679 // 'menu_slug' => 'WP-Optimize',
680
681 $menu_page_url = menu_page_url($page['menu_slug'], false);
682
683 if (is_multisite()) {
684 $menu_page_url = network_admin_url('admin.php?page='.$page['menu_slug']);
685 }
686
687 $args = array(
688 'id' => 'wpoptimize_admin_node_'.$page_id,
689 'title' => $page['menu_title'],
690 'parent' => 'wp-optimize-node',
691 'href' => $menu_page_url,
692 );
693 $wp_admin_bar->add_node($args);
694 }
695
696 }
697
698 /**
699 * Manages the admin bar menu for caching (currently page and minify)
700 */
701 public function cache_admin_bar($wp_admin_bar) {
702 $options = WP_Optimize()->get_options();
703 if (!$options->get_option('enable_cache_in_admin_bar', true)) return;
704
705 /**
706 * The "purge cache" menu items
707 *
708 * @param array $menu_items - The menu items, in the format required by $wp_admin_bar->add_menu()
709 * @param object $wp_admin_bar
710 */
711 $menu_items = apply_filters('wpo_cache_admin_bar_menu_items', array(), $wp_admin_bar);
712
713 if (empty($menu_items) || !is_array($menu_items)) return;
714
715 $wp_admin_bar->add_menu(array(
716 'id' => 'wpo_purge_cache',
717 'title' => __('Purge cache', 'wp-optimize'),
718 'href' => '#',
719 'meta' => array(
720 'title' => __('Purge cache', 'wp-optimize'),
721 ),
722 'parent' => false,
723 ));
724
725 foreach ($menu_items as $item) {
726 $wp_admin_bar->add_menu($item);
727 }
728 }
729
730 /**
731 * Adds and displays menu and submenu pages
732 */
733 public function admin_menu() {
734
735 $capability_required = WP_Optimize()->capability_required();
736 $can_run_optimizations = WP_Optimize()->can_run_optimizations();
737 $can_manage_options = WP_Optimize()->can_manage_options();
738
739 if (!current_user_can($capability_required) || (!$can_run_optimizations && !$can_manage_options)) return;
740
741 $icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmlld0JveD0iMCAwIDE2IDE2IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc0MzE2IgogICBoZWlnaHQ9IjE2IgogICB3aWR0aD0iMTYiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnM0MzE4IiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTQzMjEiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaWQ9ImxheWVyMSI+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2EwYTVhYTtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlkPSJwYXRoNTciCiAgICAgICBkPSJtIDEwLjc2ODgwOSw2Ljc2MTYwNTEgMCwwIGMgLTAuMDE2ODgsLTAuMDE2ODc4IC0wLjAyNTMxLC0wLjA0MjE4MSAtMC4wMzM3NCwtMC4wNjc0OTkgLTAuMDA4NCwtMC4wMDgzOSAtMC4wMDg0LC0wLjAxNjg3OCAtMC4wMTY4OCwtMC4wMzM3NDMgQyA5Ljk5MjYxMTIsNS4xOTIzMzY2IDguMjIwODU1Nyw0LjU4NDg3ODEgNi43NDQzOTEyLDUuMjkzNTc5NyA1LjY3MjkwMDUsNS44MDgyMzI4IDUuMDU3MDA0Myw2Ljg4ODE2MTMgNS4wNjU0NDIsOC4wMDE4MzY1IDQuNDU3OTgyMiw3LjMxMDAwNzYgMy42OTg2NTg0LDYuNzk1MzU0NSAyLjg1NDk2NDIsNi40OTE2MjUzIDMuMjY4Mzc0Myw1LjA2NTc4MzEgNC4yNTU0OTYsMy44MTcxMTY2IDUuNjg5Nzc0NiwzLjEyNTI4NzggOC4zNjQyODMyLDEuODM0NDM2OCAxMS41NzAzMTksMi45Mzk2NzQ0IDEyLjg4NjQ4MSw1LjU4ODg3MjYgMTMuNDUxNzU1LDYuNzI3ODU5NiAxNC42NDk4MDEsNy4zNTIxOTIxIDE1Ljg0Nzg0Niw3LjIzNDA3NSAxNS43NjM0ODIsNi4zMzk3NiAxNS41MTg4MDUsNS40MzcwMDg2IDE1LjEwNTM5Niw0LjU3NjQ0MDQgMTMuMjE1NTIxLDAuNjg3MDEzNCA4LjUzMzAyMjYsLTAuOTQxMzE2MjcgNC42NDM1OTQzLDAuOTQwMTIxNzkgMi4zMjM0MzcsMi4wNjIyMzM0IDAuODA0Nzg4MTQsNC4xNzk5MDQ0IDAuMzU3NjMxMzIsNi41MzM4MDk4IDIuNDE2MjQzOCw2LjQyNDEyOSA0LjQzMjY3MTcsNy41MDQwNTc0IDUuNDM2NjY2Miw5LjQzNjExNjcgbCAwLjAwODM5LDAgYyAwLjc1OTMxOTIsMS4zNzUyMjAzIDIuNDcyMDE3OCwxLjk0MDQ5NTMgMy45MDYyOTYsMS4yNDg2NjczIDEuMDQ2MTc5OCwtMC41MDYyMTggMS42NTM2NDA4LC0xLjUzNTUyMzggMS42Nzg5NTA4LC0yLjYxNTQ1MTIgMC41ODIxNDgsMC43MDg3MDE4IDEuMzMzMDM1LDEuMjQ4NjY2OCAyLjE1OTg1NiwxLjU3NzcwNjQgLTAuNDM4NzIxLDEuMzU4MzQ3OCAtMS40MDA1MzMsMi41NDc5NTQ4IC0yLjc5MjYyNywzLjIxNDQ3ODggLTIuNTkwMTM4NywxLjI0ODY1OCAtNS42NzgwNTc0LDAuMjUzMTA0IC03LjA2MTcxNTEsLTIuMjI3MzU3IGwgMCwwIEMgMi43NjIxMDQ4LDkuNDUyOTg5NCAxLjUxMzQzODMsOC44MjAyMTkxIDAuMjgxNjQ1OTIsOC45NzIwODQ0IDAuMzgyODg3NjUsOS43OTg5MDQ2IDAuNjE5MTIzMzEsMTAuNjE3Mjg3IDAuOTk4Nzg1MiwxMS40MDE5MjIgYyAxLjg4MTQzNjgsMy44OTc4NjQgNi41NjM5MzcsNS41MjYxOTggMTAuNDYxODAwOCwzLjY0NDc2IDIuMjQ0MjI2LC0xLjA4ODM2OSAzLjczNzU2MiwtMy4xMDQ3OTYgNC4yMzUzNDIsLTUuMzc0MzMyMyAtMS45OTk1NTQsMC4wNDIxODEgLTMuOTQ4NDg2LC0xLjAyOTMwNjMgLTQuOTI3MTcsLTIuOTEwNzQzMyB6IgogICAgICAgY2xhc3M9InN0MTciIC8+CiAgPC9nPgo8L3N2Zz4K';
742
743 // Removes the admin menu items on the left WP bar.
744 if (!is_multisite() || (is_multisite() && is_network_admin())) {
745 add_menu_page("WP-Optimize", "WP-Optimize", $capability_required, "WP-Optimize", array($this, "display_admin"), $icon_svg);
746
747 $sub_menu_items = $this->get_submenu_items();
748
749 foreach ($sub_menu_items as $menu_item) {
750 if ($menu_item['create_submenu']) add_submenu_page('WP-Optimize', $menu_item['page_title'], $menu_item['menu_title'], $capability_required, $menu_item['menu_slug'], $menu_item['function']);
751 }
752 }
753
754 $options = WP_Optimize()->get_options();
755
756 if ('true' === $options->get_option('enable-admin-menu', 'false')) {
757 add_action('wp_before_admin_bar_render', array($this, 'wpo_admin_bar'));
758 }
759 }
760
761 /**
762 * Get the submenu items
763 *
764 * @return array
765 */
766 public function get_submenu_items() {
767 $sub_menu_items = array(
768 array(
769 'page_title' => __('Database', 'wp-optimize'),
770 'menu_title' => __('Database', 'wp-optimize'),
771 'menu_slug' => 'WP-Optimize',
772 'function' => array($this, 'display_admin'),
773 'icon' => 'cloud',
774 'create_submenu' => true,
775 'order' => 20,
776 ),
777 array(
778 'page_title' => __('Images', 'wp-optimize'),
779 'menu_title' => __('Images', 'wp-optimize'),
780 'menu_slug' => 'wpo_images',
781 'function' => array($this, 'display_admin'),
782 'icon' => 'images-alt2',
783 'create_submenu' => true,
784 'order' => 30,
785 ),
786 array(
787 'page_title' => __('Cache', 'wp-optimize'),
788 'menu_title' => __('Cache', 'wp-optimize'),
789 'menu_slug' => 'wpo_cache',
790 'function' => array($this, 'display_admin'),
791 'icon' => 'archive',
792 'create_submenu' => true,
793 'order' => 40,
794 ),
795 array(
796 'page_title' => __('Minify', 'wp-optimize'),
797 'menu_title' => __('Minify', 'wp-optimize'),
798 'menu_slug' => 'wpo_minify',
799 'function' => array($this, 'display_admin'),
800 'icon' => 'editor-contract',
801 'create_submenu' => true,
802 'order' => 50,
803 ),
804 array(
805 'page_title' => __('Performance', 'wp-optimize'),
806 'menu_title' => __('Performance', 'wp-optimize'),
807 'menu_slug' => 'wpo_performance',
808 'function' => array($this, 'display_admin'),
809 'icon' => 'performance',
810 'create_submenu' => true,
811 'order' => 53,
812 ),
813 array(
814 'create_submenu' => false,
815 'order' => 55,
816 'icon' => 'separator',
817 ),
818 array(
819 'page_title' => __('Settings', 'wp-optimize'),
820 'menu_title' => __('Settings', 'wp-optimize'),
821 'menu_slug' => 'wpo_settings',
822 'function' => array($this, 'display_admin'),
823 'icon' => 'admin-settings',
824 'create_submenu' => true,
825 'order' => 60,
826 ),
827 array(
828 'page_title' => __('Support & FAQs', 'wp-optimize'),
829 'menu_title' => __('Help', 'wp-optimize'),
830 'menu_slug' => 'wpo_support',
831 'function' => array($this, 'display_admin'),
832 'icon' => 'sos',
833 'create_submenu' => true,
834 'order' => 60,
835 ),
836 array(
837 'page_title' => __('Premium Upgrade', 'wp-optimize'),
838 'menu_title' => __('Premium Upgrade', 'wp-optimize'),
839 'menu_slug' => 'wpo_mayalso',
840 'function' => array($this, 'display_admin'),
841 'icon' => 'admin-plugins',
842 'create_submenu' => true,
843 'order' => 70,
844 ),
845 );
846
847 $filtered_sub_menu_items = apply_filters('wp_optimize_sub_menu_items', $sub_menu_items);
848
849 if (empty($filtered_sub_menu_items) || !is_array($filtered_sub_menu_items)) {
850 $filtered_sub_menu_items = $sub_menu_items;
851 }
852
853 usort($filtered_sub_menu_items, array($this, 'order_sort'));
854
855 return $filtered_sub_menu_items;
856 }
857
858 /**
859 * Order sorting function
860 *
861 * @param array $a
862 * @param array $b
863 *
864 * @return int
865 */
866 public function order_sort($a, $b) {
867 if ($a['order'] === $b['order']) return 0;
868 return ($a['order'] > $b['order']) ? 1 : -1;
869 }
870
871 /**
872 * Output information message for users who have no permissions to run optimizations.
873 *
874 * @param string $message Message to display
875 */
876 public function prevent_run_optimizations_message($message = '') {
877 if (empty($message)) {
878 $message = __('You have no permissions to run optimizations.', 'wp-optimize');
879 }
880 WP_Optimize()->include_template('info-message.php', false, array('message' => $message));
881 }
882
883 /**
884 * Output information message for users who have no permissions to manage settings.
885 */
886 public function prevent_manage_options_info() {
887 WP_Optimize()->include_template('info-message.php', false, array('message' => __('You have no permissions to manage WP-Optimize settings.', 'wp-optimize')));
888 }
889
890 /**
891 * Output success/error messages from $output array.
892 *
893 * @param array $output ['messages' => success messages, 'errors' => error messages]
894 */
895 private function wpo_render_output_messages($output) {
896 foreach ($output['messages'] as $item) {
897 echo '<div class="updated fade below-h2"><strong>'.esc_html($item).'</strong></div>';
898 }
899
900 foreach ($output['errors'] as $item) {
901 echo '<div class="error fade below-h2"><strong>'.esc_html($item).'</strong></div>';
902 }
903 }
904 }
905 endif;
906