PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / trunk
10Web Booster – Website speed optimization, Cache & Page Speed optimizer vtrunk
2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / OptimizerAdmin.php
tenweb-speed-optimizer Last commit date
assets 11 months ago config 2 years ago exported 4 years ago includes 2 months ago test 4 years ago vendor 1 month ago views 11 months ago .editorconfig 3 years ago OptimizerAdmin.php 1 year ago OptimizerAdminBar.php 2 years ago OptimizerApi.php 1 month ago OptimizerCli.php 1 year ago OptimizerDataRepository.php 1 year ago changelog.txt 3 years ago config.php 1 month ago env.php 1 month ago phpcs.xml 3 years ago readme.txt 1 month ago tenweb_speed_optimizer.php 1 month ago webpack.config.js 3 years ago
OptimizerAdmin.php
1974 lines
1 <?php
2
3 namespace TenWebOptimizer;
4
5 use Plugin_Upgrader;
6 use TenWebOptimizer\WebPageCache\OptimizerWebPageCache;
7 use Theme_Upgrader;
8 use WP_Query;
9
10 /**
11 * Class OptimizerAdmin
12 */
13 class OptimizerAdmin
14 {
15 const TWO_DELAYED_DEFAULT_LIST = 'getbutton.io,//a.omappapi.com/app/js/api.min.js,' .
16 'feedbackcompany.com/includes/widgets/feedback-company-widget.min.js,snap.licdn.com/li.lms-analytics/insight.min.js,' .
17 'static.ads-twitter.com/uwt.js,platform.twitter.com/widgets.js,twq(,/sdk.js#xfbml,static.leadpages.net/leadbars/current/embed.js,' .
18 'translate.google.com/translate_a/element.js,widget.manychat.com,xfbml.customerchat.js,static.hotjar.com/c/hotjar-,' .
19 'smartsuppchat.com/loader.js,grecaptcha.execute,Tawk_API,shareaholic,sharethis,simple-share-buttons-adder,addtoany,' .
20 'font-awesome,wpdiscuz,cookie-law-info,pinit.js,/gtag/js,gtag(,/gtm.js,/gtm-,fbevents.js,fbq(,' .
21 "google-analytics.com/analytics.js,ga( ',ga(',adsbygoogle,ShopifyBuy,widget.trustpilot.com/bootstrap," .
22 'ft.sdk.min.js,apps.elfsight.com/p/platform.js,livechatinc.com/tracking.js,LiveChatWidget,/busting/facebook-tracking/,' .
23 'olark,pixel-caffeine/build/frontend.js,wp-emoji-release.min.js';
24
25 protected static $instance = null;
26
27 private $page_url;
28
29 private $TwoSettings;
30
31 const TENWEB_SO_REGENERATE_CRITICAL_ON_UPDATE = false;
32
33 private $plugins_requiring_critical_regeneration = [
34 'elementor/elementor.php',
35 'elementor-pro/elementor-pro.php',
36 'beaver-builder-lite-version/fl-builder.php',
37 'siteorigin-panels/siteorigin-panels.php',
38 'revslider/revslider.php'
39 ];
40
41 public function __construct()
42 {
43 $two_plugin_activated_flow_init = get_option('two_plugin_activated_flow_init');
44
45 if ($two_plugin_activated_flow_init === '1') {
46 delete_option('two_plugin_activated_flow_init');
47 delete_option('two_flow_speed');
48 delete_option('flow_score_check_init');
49 OptimizerUtils::add_log_for_score_check_flow('two_activate', 'start init_flow_score_check=>true');
50 OptimizerUtils::init_flow_score_check(true);
51 }
52 global $TwoSettings;
53 $this->TwoSettings = $TwoSettings;
54 $this->init_admin();
55 $this->page_url = OptimizerUtils::get_page_url();
56 $two_triggerPostOptimizationTasks = get_option('two_triggerPostOptimizationTasks');
57
58 // if (!empty($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'two_10web_connection')) {
59 // wp_verify_nonce has been changed as the request from the core service isn't able to pass nonce verification//
60 if (!empty($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'two_10web_connection')) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
61 add_action('admin_init', [$this, 'connect_to_tenweb']); //changed from in_admin_header hook, because of gallery flow, ask Hrach and Serine why
62 } elseif (isset($_GET['two_disconnect'])) {
63 if (isset($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'two_disconnect_nonce')) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
64 add_action('in_admin_header', ['\TenWebOptimizer\OptimizerAdmin', 'disconnect_from_tenweb']);
65 }
66 } elseif (!empty($_GET['new_connection_flow']) && !empty($_GET['connection_error']) && empty($_GET['old_connection_flow'])) {
67 \TenWebOptimizer\OptimizerUtils::two_redirect(OptimizerUtils::get_tenweb_connection_link('sign-up', ['old_connection_flow' => 1]));
68 }
69 add_action('delete_post', [$this, 'delete_optimized_pages_by_id']);
70 add_action('wp_trash_post', [$this, 'delete_optimized_pages_by_id']);
71
72 add_action('permalink_structure_changed', [$this, 'wp_permalink_structure_changed_'], 10, 2);
73
74 if ($this->TwoSettings->get_settings('two_enable_plugin_autoupdate') === 'on') {
75 add_filter('auto_update_plugin', [ $this, 'two_add_two_plugin_to_autoupdate' ], 10, 2);
76 }
77
78 if (get_option(TW_OPTIMIZE_PREFIX . '_cache_structure_size') && (int) get_option(TW_OPTIMIZE_PREFIX . '_cache_structure_size') > TENWEB_CACHE_STRUCTURE_ALLOWED_SIZE) {
79 self::clear_cache(false, true);
80 }
81 }
82
83 public function checkDiviSettingsChange()
84 {
85 $diviOption = get_option('et_divi');
86
87 if ($diviOption && is_array($diviOption) && isset($diviOption['divi_custom_css'])) {
88 $newCustomCSS = $diviOption['divi_custom_css'];
89 }
90
91 if (get_option(TW_OPTIMIZE_PREFIX . '_clear_cache_after_divi')
92 || (false !== get_option(TW_OPTIMIZE_PREFIX . '_old_divi_custom_css') && isset($newCustomCSS) && get_option(TW_OPTIMIZE_PREFIX . '_old_divi_custom_css') !== $newCustomCSS)) {
93 $this->diviChangesClearCache();
94 }
95 }
96
97 private function diviChangesClearCache()
98 {
99 $two_critical_pages = OptimizerUtils::getCriticalPages();
100
101 if (!is_array($two_critical_pages)) {
102 $two_critical_pages = [];
103 }
104
105 foreach ($two_critical_pages as $critical_page) {
106 if (isset($critical_page['id']) && $critical_page['id'] != 'front_page') {
107 OptimizerUtils::delete_critical_page($critical_page['id']);
108
109 if (has_action('two_page_optimized_removed')) {
110 do_action('two_page_optimized_removed', $critical_page['id']);
111 }
112 }
113 }
114 self::clear_cache();
115 delete_option(TW_OPTIMIZE_PREFIX . '_clear_cache_after_divi');
116 delete_option(TW_OPTIMIZE_PREFIX . '_old_divi_custom_css');
117 }
118
119 public function two_add_two_plugin_to_autoupdate($update, $item)
120 {
121 $plugins = [ 'tenweb-speed-optimizer' ];
122
123 if (isset($item->slug) && in_array($item->slug, $plugins)) {
124 // update plugin
125 return true;
126 }
127
128 // use default settings
129 return $update;
130 }
131
132 public function delete_optimized_pages_by_id($page_id)
133 {
134 OptimizerUtils::delete_critical_page($page_id);
135
136 if (has_action('two_page_optimized_removed')) {
137 do_action('two_page_optimized_removed', $page_id);
138 }
139 }
140
141 public function change_front_page($old_value, $value, $option)
142 {
143 // Remove new front page from list.
144 OptimizerUtils::delete_critical_page($value);
145
146 if (has_action('two_page_optimized_removed')) {
147 do_action('two_page_optimized_removed', $value);
148 }
149 self::clear_cache();
150 }
151
152 public function wp_permalink_structure_changed_($old_permalink_structure, $permalink_structure)
153 {
154 $no_optimize_pages = get_option('no_optimize_pages');
155
156 if (is_array($no_optimize_pages)) {
157 foreach ($no_optimize_pages as $key => $val) {
158 if ($key != 'front_page') {
159 $post_data = OptimizerUtils::get_permalink_name_by_id($key);
160 $no_optimize_pages[$key] = $post_data[ 'url' ];
161 }
162 }
163 update_option('no_optimize_pages', $no_optimize_pages);
164 }
165 }
166
167 public function init_admin()
168 {
169 ob_start();
170
171 // phpcs:ignore
172 if (!isset($_GET[ 'two_nooptimize' ]) && !isset($_GET[ 'two_action' ])) {
173 add_action('wp_ajax_nopriv_two_manager_clear_cache', [ $this, 'manager_clear_cache' ]);
174
175 if (current_user_can('manage_options')) {
176 add_action('admin_init', [$this, 'update']);
177 add_action('admin_init', [$this, 'redirect_after_activation'], 20);
178 add_action('admin_init', [$this, 'checkDiviSettingsChange']);
179 add_action('admin_menu', [$this, 'admin_menu']);
180 add_action('admin_enqueue_scripts', ['\TenWebOptimizer\OptimizerAdmin', 'two_enqueue_admin_assets']);
181 add_action('wp_enqueue_scripts', [$this, 'two_enqueue_assets']);
182
183 add_action('wp_ajax_two_settings', [$this, 'ajax_two_settings']);
184 add_action('wp_ajax_two_update_setting', [$this, 'ajax_two_update_setting']);
185 add_action('wp_ajax_two_critical', [$this, 'two_critical']);
186 add_action('wp_ajax_two_critical_statuses', [$this, 'two_critical_statuses']);
187 add_action('wp_ajax_two_deactivate_plugins', [$this, 'two_deactivate_plugin']);
188 add_action('wp_ajax_two_white_label', [$this, 'two_white_label']);
189 add_action('wp_ajax_two_elementor_regenerate_ccss', [$this, 'two_elementor_regenerate_ccss']);
190
191 add_filter('plugin_action_links_' . TENWEB_SO_BASENAME, [$this, 'add_action_link'], 10, 2);
192
193 if (!is_admin() && !isset($_GET['elementor-preview']) && isset($_GET['two-menu'])) { // phpcs:ignore
194 add_action('admin_bar_menu', [$this, 'two_admin_bar_menu'], 99999);
195 }
196
197 add_action('wp_ajax_two_css_options', [$this, 'save_css_options']);
198
199 add_action('wp_ajax_two_get_posts_for_critical', [$this, 'get_posts_for_critical']);
200 // TODO: BOOST-1575 Ensure that the cache for the updated post is cleared for both logged-in and non-logged-in users.
201 // Once TODO is fixed, delete the 'post_clear_all_cache' function and use the post_clear_cache.
202 //add_action('save_post', [$this, 'post_clear_cache'], 10, 3); // Clearing all the caches to handle templates. Editing a template will clear entire cache.
203 add_action('save_post', [$this, 'post_clear_all_cache'], 10, 3); // Clearing all the page caches
204
205 add_action('switch_theme', [$this, 'clear_cache'], 10, 0); // When user change theme.
206 add_action('update_option_show_on_front', [$this, 'change_front_page'], 10, 3); // When reading settings for front page are updated.
207 add_action('update_option_page_on_front', [$this, 'change_front_page'], 10, 3); // When reading settings for front page are updated.
208 add_action('wp_update_nav_menu', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When a custom menu is update.
209 add_action('update_option_sidebars_widgets', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When you change the order of widgets.
210 add_action('update_option_category_base', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When category permalink is updated.
211 add_action('update_option_tag_base', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When tag permalink is updated.
212 add_action('permalink_structure_changed', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When permalink structure is update.
213 add_action('add_link', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When a link is added.
214 add_action('edit_link', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When a link is updated.
215 add_action('delete_link', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When a link is deleted.
216 add_action('customize_save', [$this, 'clear_cache'], 10, 0); // When customizer is saved.
217 add_action('update_option_theme_mods_' . get_option('stylesheet'), [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0); // When location of a menu is updated.
218 add_action('sidebar_admin_setup', [$this, 'clear_cache'], 10, 0);
219 add_action('activated_plugin', [$this, 'clear_cache_conditionally_activate'], 10, 1);
220 add_action('upgrader_process_complete', [$this, 'clear_cache_conditionally_update'], 10, 2);
221 add_action('deactivated_plugin', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
222 add_action('_core_updated_successfully', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
223
224 //detect ContactForm7 changes
225 add_action('wpcf7_save_contact_form', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
226
227 //detect WooThemes settings changes
228 add_action('update_option_woo_options', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
229
230 // Disabled temporarily as ACF triggers save_post from front.
231 // phpcs:ignore
232 /*if ( class_exists( 'ACF' ) ) {
233 add_action( 'save_post', array('\TenWebOptimizer\OptimizerAdmin', 'acf_update_fields'), 10, 2 );
234 }*/
235
236 //detect Formidable changes
237 add_action('frm_update_form', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
238
239 //detect Contact Form by WP Forms changes
240 add_action('wpforms_builder_save_form', [$this, 'clear_cache_without_critical_css_regeneration'], 10, 0);
241 }
242 }
243 add_action('wp_ajax_two_flow_set_mode', [ $this, 'two_flow_set_mode' ]);
244 add_action('wp_ajax_two_update_flow_status', [ $this, 'two_update_flow_status' ]);
245 add_action('wp_ajax_two_finish_flow', [ $this, 'two_finish_flow' ]);
246 add_action('wp_ajax_two_flow_incompatible_plugins', [ $this, 'two_flow_incompatible_plugins' ]);
247 add_action('wp_ajax_two_clear_cloudflare_cache', [ $this, 'two_clear_cloudflare_cache' ]);
248 add_filter('two_clear_cache_action', [ $this, 'clear_cache' ], 10, 0);
249 add_action('two_clear_cache', [ $this, 'clear_cache' ], 10, 0);
250 add_action('pre_current_active_plugins', [ $this, 'add_deactivation_popup' ]);
251
252 /* show custom columns only for administrators */
253 if (strtolower(TWO_SO_ORGANIZATION_NAME) == '10web' && current_user_can('administrator')) {
254 add_action('manage_post_posts_custom_column', [ $this, 'two_manage_posts_column'], 10, 2);
255 add_action('manage_page_posts_custom_column', [ $this, 'two_manage_posts_column'], 10, 2);
256 }
257 }
258
259 public function two_manage_posts_column($column_key, $post_id)
260 {
261 if ($column_key == 'two-speed') {
262 if (get_post_status($post_id) != 'publish') {
263 return;
264 }
265 require __DIR__ . '/views/post_custom_column.php';
266 }
267 }
268
269 public function two_flow_set_mode()
270 {
271 // phpcs:ignore
272 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')
273 && isset($_POST['mode'])
274 && OptimizerUtils::check_admin_capabilities()) {
275 $two_conflicting_plugins = OptimizerUtils::get_conflicting_plugins();
276 $two_triggerPostOptimizationTasks = get_option('two_triggerPostOptimizationTasks');
277 $mode = sanitize_text_field($_POST['mode']);
278 global $TwoSettings;
279 self::set_global_mode($mode);
280
281 if (isset($_POST['test_mode']) && $_POST['test_mode'] === '1') { //if clicked on contact us we don't disable test mode
282 $TwoSettings->update_setting('two_test_mode', 'on', true);
283 } else {
284 $TwoSettings->update_setting('two_test_mode', 'off', true);
285 OptimizerUtils::update_connection_flow_progress('running', 'mode_apply_and_test_mode_disable', [$mode]);
286 }
287
288 if (empty($two_conflicting_plugins) && $two_triggerPostOptimizationTasks !== '1') {
289 update_option('two_triggerPostOptimizationTasks', '1', false);
290 }
291
292 if (isset($_POST['redirect']) && $_POST['redirect'] === '1') {
293 OptimizerUtils::two_redirect(TENWEB_DASHBOARD . '?flow_success=1&optimizing_website=' . get_site_option(TENWEB_PREFIX . '_domain_id'));
294 }
295 }
296 }
297
298 public function two_update_flow_status()
299 {
300 $return_data = [
301 'success' => false,
302 ];
303
304 // phpcs:ignore
305 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce') && isset($_POST['status']) && !empty($_POST['status']) && OptimizerUtils::check_admin_capabilities()) {
306 // 1 in-progress
307 // 2 finished (Looks good)
308 // 3 contact-us
309 // 4 contact-us button clicked (new step contact-us clicked)
310 update_option('two_flow_status', sanitize_text_field($_POST['status']));
311
312 if ($_POST['status'] === '4') {
313 OptimizerUtils::update_connection_flow_progress('running', 'contact_us_clicked');
314 } elseif ($_POST['status'] === '3') {
315 OptimizerUtils::update_connection_flow_progress('running', 'contact_us');
316 }
317 $return_data['success'] = true;
318 }
319 // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
320 echo json_encode($return_data);
321 die;
322 }
323
324 public function two_finish_flow()
325 {
326 $return_data = [
327 'success' => false,
328 ];
329
330 // phpcs:ignore
331 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce') && OptimizerUtils::check_admin_capabilities()) {
332 update_option('two_flow_status', '2');
333 OptimizerUtils::update_connection_flow_progress('done', 'connection_flow_finish');
334 $return_data['success'] = true;
335 }
336 // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
337 echo json_encode($return_data);
338 die;
339 }
340
341 public function two_flow_incompatible_plugins()
342 {
343 // phpcs:ignore
344 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) {
345 $incompatible_plugins = [];
346 $two_triggerPostOptimizationTasks = get_option('two_triggerPostOptimizationTasks');
347
348 if (isset($_POST['two_disable_incompatible_plugins']) && isset($_POST['incompatible_plugins']) && is_array($_POST['incompatible_plugins']) && !empty($_POST['incompatible_plugins'])) {
349 $incompatible_plugins = sanitize_text_field($_POST['incompatible_plugins']);
350 $two_conflicting_plugins = OptimizerUtils::get_conflicting_plugins();
351 $incompatible_plugins_inactive = [];
352
353 foreach ($incompatible_plugins as $incompatible_plugin) {
354 if (isset($two_conflicting_plugins[$incompatible_plugin])) {
355 $incompatible_plugins_inactive[] = $two_conflicting_plugins[$incompatible_plugin];
356 }
357 }
358
359 if (!empty($incompatible_plugins_inactive) && $two_triggerPostOptimizationTasks !== '1') {
360 OptimizerUtils::update_connection_flow_progress('running', 'incompatible_plugins_inactive', $incompatible_plugins_inactive);
361 }
362 deactivate_plugins($incompatible_plugins);
363 }
364
365 if ($two_triggerPostOptimizationTasks !== '1') {
366 update_option('two_triggerPostOptimizationTasks', '1', false);
367 }
368 OptimizerUtils::two_redirect(TENWEB_DASHBOARD . '?flow_success=1&optimizing_website=' . get_site_option(TENWEB_PREFIX . '_domain_id'));
369 }
370 }
371
372 public function add_deactivation_popup()
373 {
374 if (!TENWEB_SO_HOSTED_ON_10WEB && OptimizerUtils::is_tenweb_booster_connected()) {
375 include 'views/deactivation_popup.php';
376 }
377 }
378
379 public function clear_cache_conditionally_activate($plugin)
380 {
381 $exclude_critical_regeneration = true;
382
383 if ($plugin) {
384 // Regenerate criticals only if an allowed plugin is actived.
385 if (in_array($plugin, $this->plugins_requiring_critical_regeneration)) {
386 $exclude_critical_regeneration = false;
387 }
388 }
389 self::clear_cache(false, $exclude_critical_regeneration, true, true, 'front_page', false, false);
390 }
391
392 public function clear_cache_conditionally_update($upgrader, $hook_extra)
393 {
394 $exclude_critical_regeneration = true;
395
396 if ($upgrader instanceof Theme_Upgrader) {
397 // Regenerate citicals only if active theme is updated.
398 if (isset($hook_extra['themes']) && (is_array($hook_extra['themes']) && in_array(get_option('stylesheet'), $hook_extra['themes']))) {
399 $exclude_critical_regeneration = false;
400 }
401 } elseif ($upgrader instanceof Plugin_Upgrader) {
402 // Regenerate criticals only if an allowed plugin is active and updated.
403 if (isset($upgrader->skin->plugin_active) && $upgrader->skin->plugin_active &&
404 isset($hook_extra['plugins']) && (is_array($hook_extra['plugins']) && array_intersect($this->plugins_requiring_critical_regeneration, $hook_extra['plugins']))) {
405 $exclude_critical_regeneration = false;
406 }
407 }
408 self::clear_cache(false, $exclude_critical_regeneration, true, true, 'front_page', false, false);
409 }
410
411 public function clear_cache_without_critical_css_regeneration()
412 {
413 self::clear_cache(false, true, true, true, 'front_page', false, false);
414 }
415
416 public function post_clear_cache($post_ID, $post, $update)
417 {
418 if (isset($post->post_status) && $post->post_status === 'publish' && $update) {
419 $permalink = get_permalink($post_ID);
420 OptimizerWebPageCache::delete_cache_by_url($permalink);
421
422 if ('post' === $post->post_type && (int) get_option('page_for_posts') > 0) {
423 OptimizerWebPageCache::delete_cache_by_url(get_option('page_for_posts'));
424 }
425 $post_type_archive = get_post_type_archive_link($post->post_type);
426
427 if ($post_type_archive) {
428 OptimizerWebPageCache::delete_cache_by_url($post_type_archive);
429 }
430 // Add next post.
431 // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_adjacent_post_get_adjacent_post
432 $next_post = get_adjacent_post(false, '', false);
433
434 if ($next_post) {
435 OptimizerWebPageCache::delete_cache_by_url(get_permalink($next_post));
436 }
437
438 // Add next post in same category.
439 // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_adjacent_post_get_adjacent_post
440 $next_in_same_cat_post = get_adjacent_post(true, '', false);
441
442 if ($next_in_same_cat_post && $next_in_same_cat_post !== $next_post) {
443 OptimizerWebPageCache::delete_cache_by_url(get_permalink($next_in_same_cat_post));
444 }
445
446 // Add previous post.
447 // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_adjacent_post_get_adjacent_post
448 $previous_post = get_adjacent_post(false, '', true);
449
450 if ($previous_post) {
451 OptimizerWebPageCache::delete_cache_by_url(get_permalink($previous_post));
452 }
453
454 // Add previous post in same category.
455 // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_adjacent_post_get_adjacent_post
456 $previous_in_same_cat_post = get_adjacent_post(true, '', true);
457
458 if ($previous_in_same_cat_post && $previous_in_same_cat_post !== $previous_post) {
459 OptimizerWebPageCache::delete_cache_by_url(get_permalink($previous_in_same_cat_post));
460 }
461
462 // Add the author page.
463 $author_url = trailingslashit(get_author_posts_url($post->post_author));
464
465 if (trailingslashit(site_url()) !== $author_url && trailingslashit(home_url()) !== $author_url) {
466 OptimizerWebPageCache::delete_cache_by_url($author_url);
467 }
468
469 // Add all parents.
470 $parents = get_post_ancestors($post_ID);
471
472 if ((bool) $parents) {
473 foreach ($parents as $parent_id) {
474 OptimizerWebPageCache::delete_cache_by_url(get_permalink($parent_id));
475 }
476 }
477
478 OptimizerWebPageCache::delete_cache_by_url(home_url());
479
480 remove_action('save_post', [$this, 'post_clear_cache'], 10, 2);
481 }
482 }
483
484 public function post_clear_all_cache()
485 {
486 OptimizerWebPageCache::delete_all_cached_pages();
487 remove_action('save_post', [$this, 'post_clear_all_cache'], 10, 2);
488 }
489
490 public static function acf_update_fields($post_id, $post)
491 {
492 if ($post->post_type == 'acf-field-group' || $post->post_type == 'acf-field') {
493 self::clear_cache(false, true);
494 remove_action('save_post', ['\TenWebOptimizer\OptimizerAdmin', 'acf_update_fields'], 10, 2);
495 }
496 }
497
498 private static function fix_delayed_list_slashes()
499 {
500 if (empty(get_option('two_delayed_js_execution_list_updated_fix_slashes'))) {
501 global $TwoSettings;
502 $option = $TwoSettings->get_settings('two_delayed_js_execution_list');
503
504 if (!empty($option)) {
505 $option = implode('', explode('\\', $option));
506 $TwoSettings->update_setting('two_delayed_js_execution_list', stripslashes(trim($option)));
507 }
508 }
509 update_option('two_delayed_js_execution_list_updated_fix_slashes', 1);
510 }
511
512 public function connect_to_tenweb($parameters = null)
513 {
514 if (empty($parameters)) {
515 $parameters = [];
516 $parameters['email'] = !empty($_GET['email']) ? sanitize_email($_GET['email']) : null; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
517 $parameters['token'] = !empty($_GET['token']) ? sanitize_text_field($_GET['token']) : null; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
518 $parameters['new_connection_flow'] = !empty($_GET['new_connection_flow']) ? rest_sanitize_boolean($_GET['new_connection_flow']) : null; //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
519 $parameters['sign_up_from_free_plugin'] = !empty($_GET['sign_up_from_free_plugin']) ? rest_sanitize_boolean($_GET['sign_up_from_free_plugin']) : null; //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
520 }
521 $email = !empty($parameters['email']) ? sanitize_email($parameters['email']) : null;
522 $token = !empty($parameters['token']) ? sanitize_text_field($parameters['token']) : null;
523 $new_connection_flow = !empty($parameters['new_connection_flow']);
524 $sign_up_from_free_plugin = !empty($parameters['sign_up_from_free_plugin']);
525
526 if (!empty($email) && !empty($token)) {
527 $pwd = md5($token);
528 $class_login = \Tenweb_Authorization\Login::get_instance();
529 $args = [ 'connected_from' => TENWEB_SO_CONNECTED_FROM ];
530
531 if ($class_login->login($email, $pwd, $token, $args) == true && $class_login->check_logged_in()) {
532 OptimizerUtils::add_log_for_score_check_flow('connect_to_tenweb', 'start init_flow_score_check=>true');
533 OptimizerUtils::init_flow_score_check(true);
534 $two_first_connect = get_option('two_first_connect', false);
535 $date = time();
536
537 if (!$two_first_connect) {
538 //this option also used to check booster real connection when IO is connected
539 update_option('two_first_connect', $date);
540 }
541 delete_option('two_triggerPostOptimizationTasks');
542 delete_option('incompatible_plugins_active_send');
543 global $TwoSettings;
544
545 \Tenweb_Authorization\Helper::remove_error_logs();
546
547 $TwoSettings->update_setting('two_connected', '1');
548 $TwoSettings->sync_configs_with_plugin_state();
549 /*set test mode and set global mode extreme*/
550 self::set_global_mode('extreme');
551 /*-----------------------------*/
552 delete_option('two_flow_critical_start');
553 self::generateCriticalCssOnInit(true);
554 $domain_id = get_site_option(TENWEB_PREFIX . '_domain_id');
555 $url = TENWEB_DASHBOARD . '/websites?optimizing_website=' . $domain_id . '&from_plugin=' . OptimizerUtils::FROM_PLUGIN;
556
557 if ($sign_up_from_free_plugin) {
558 $url .= '&from_free_plugin=1';
559 }
560
561 if ($new_connection_flow) {
562 // Clear all unexpected output. We don't want to see a warning in rest response.
563 while (ob_get_level() !== 0) {
564 ob_end_clean();
565 }
566
567 die(json_encode(['connected_domain_id' => get_site_option(TENWEB_PREFIX . '_domain_id')])); //phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
568 }
569 OptimizerUtils::two_redirect($url);
570 } else {
571 $errors = $class_login->get_errors();
572 $err_msg = (!empty($errors)) ? $errors['message'] : 'Something went wrong. ' .
573 'If this website is already connected to the 10Web dashboard via the manager plugin, ' .
574 'please disconnect it from the manager plugin to be able to use 10Web Booster.';
575 set_site_transient('tenweb_so_auth_error_logs', $err_msg, MINUTE_IN_SECONDS);
576 }
577 }
578
579 if (is_multisite()) {
580 OptimizerUtils::two_redirect(network_admin_url() . 'admin.php?page=two_settings_page');
581 }
582 OptimizerUtils::two_redirect(get_admin_url() . 'admin.php?page=two_settings_page');
583 }
584
585 public static function disconnect_from_tenweb($silent = false)
586 {
587 global $TwoSettings;
588 $TwoSettings->update_setting('two_connected', '0');
589 $TwoSettings->sync_configs_with_plugin_state('inactive');
590 delete_option('two_flow_status');
591 delete_option('two_triggerPostOptimizationTasks');
592 delete_option('incompatible_plugins_active_send');
593 delete_option('flow_score_check_init');
594 delete_option('two_flow_score_log');
595 delete_option('two_clear_cache_from');
596 delete_option('two_flow_critical_start');
597 delete_option('wp_two_nonce_two_init_flow_score');
598 delete_option('two_activate_score_check_nonce_data');
599 //deleting option which is showing IO connection
600 delete_site_option(TENWEB_PREFIX . '_from_image_optimizer');
601 delete_site_option(TENWEB_PREFIX . '_client_referral_hash');
602 delete_site_option(TW_OPTIMIZE_PREFIX . '_saved_nonce');
603
604 $two_critical_pages = OptimizerUtils::getCriticalPages();
605
606 foreach ($two_critical_pages as $c_page) {
607 OptimizerUtils::delete_critical_page($c_page['id']);
608 }
609
610 $class_login = \Tenweb_Authorization\Login::get_instance();
611 \Tenweb_Authorization\Helper::remove_error_logs();
612 $class_login->logout(false);
613 $redirection_link = get_admin_url() . 'admin.php?page=two_settings_page';
614
615 if (isset($_GET['two_reconnect']) && isset($_GET['two_reconnect_nonce'])
616 && wp_verify_nonce(sanitize_text_field($_GET['two_reconnect_nonce']), 'two_reconnect_nonce')) {
617 $redirection_link = \TenWebOptimizer\OptimizerUtils::get_tenweb_connection_link();
618 }
619
620 if (!$silent) {
621 self::clear_cache(false, true);
622 self::two_uninstall();
623
624 if (is_multisite()) {
625 OptimizerUtils::two_redirect($redirection_link);
626 }
627 OptimizerUtils::two_redirect($redirection_link);
628 } else {
629 self::two_uninstall();
630 }
631 }
632
633 public static function get_incompatible_active_plugins()
634 {
635 $incompatiblePluginList = [];
636
637 foreach (OptimizerUtils::TWO_INCOMPATIBLE_PLUGIN_LIST as $pluginSlug => $pluginName) {
638 if (is_plugin_active($pluginSlug)) {
639 $incompatiblePluginList[] = $pluginName;
640 }
641 }
642
643 return $incompatiblePluginList;
644 }
645
646 /*
647 * check state activate and deactivate plugin
648 */
649 public function get_plugins_state()
650 {
651 $screen = get_current_screen();
652
653 if ($screen->id === 'plugins') {
654 $two_active_plugins_list = get_option('two_active_plugins_list');
655 $active_plugins_current = get_option('active_plugins');
656
657 if (is_array($two_active_plugins_list) && is_array($active_plugins_current)) {
658 $diff = array_merge(array_diff($active_plugins_current, $two_active_plugins_list), array_diff($two_active_plugins_list, $active_plugins_current));
659
660 if (!empty($diff)) {
661 self::clear_cache(false, true);
662 update_option('two_active_plugins_list', $active_plugins_current);
663 }
664 } else {
665 update_option('two_active_plugins_list', $active_plugins_current);
666 }
667 }
668 }
669
670 public function two_admin_bar_menu($wp_admin_bar)
671 {
672 $wp_admin_bar->add_menu([
673 'id' => 'two_options',
674 'title' => '10Web Booster',
675 ]);
676 }
677
678 public function two_enqueue_assets()
679 {
680 wp_register_style('two-open-sans', 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,600,700,800&display=swap');
681 $two_exclude_css = $this->TwoSettings->get_settings('two_exclude_css');
682 $two_async_css = $this->TwoSettings->get_settings('two_async_css');
683 $two_disable_css = $this->TwoSettings->get_settings('two_disable_css');
684 $two_async_page = $this->TwoSettings->get_settings('two_async_page');
685 $two_disable_page = $this->TwoSettings->get_settings('two_disable_page');
686 $two_async_all = $this->TwoSettings->get_settings('two_async_all');
687 $two_disable_css_page = [];
688 $two_async_css_page = [];
689
690 if (is_array($two_disable_page) && isset($two_disable_page[$this->page_url])) {
691 $two_disable_css_page = explode(',', $two_disable_page[$this->page_url]);
692 }
693
694 if (is_array($two_async_page) && isset($two_async_page[$this->page_url])) {
695 $two_async_css_page = explode(',', $two_async_page[$this->page_url]);
696 }
697
698 $two_async_css = explode(',', $two_async_css);
699 $two_disable_css = explode(',', $two_disable_css);
700 $two_exclude_css = explode(',', $two_exclude_css);
701
702 wp_enqueue_script('two_admin_bar_js', TENWEB_SO_URL . '/assets/js/two_admin_bar.js', ['jquery'], TENWEB_SO_VERSION);
703 wp_enqueue_style('two_admin_bar_css', TENWEB_SO_URL . '/assets/css/two_admin_bar.css', [], TENWEB_SO_VERSION);
704 wp_localize_script('two_admin_bar_js', 'two_admin_vars', [
705 'ajaxurl' => admin_url('admin-ajax.php'),
706 'ajaxnonce' => wp_create_nonce('two_ajax_nonce'),
707 'two_async_css' => json_encode($two_async_css), // phpcs:ignore
708 'two_disable_css' => json_encode($two_disable_css), // phpcs:ignore
709 'two_disable_css_page' => json_encode($two_disable_css_page), // phpcs:ignore
710 'two_async_css_page' => json_encode($two_async_css_page), // phpcs:ignore
711 'two_async_all' => $two_async_all,
712 'two_exclude_css' => $two_exclude_css,
713 ]);
714 }
715
716 public function save_css_options()
717 {
718 // phpcs:ignore
719 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) {
720 $page_url_without_pagespeed = '';
721 $two_async_css = $this->TwoSettings->get_settings('two_async_css');
722 $two_disable_css = $this->TwoSettings->get_settings('two_disable_css');
723 $two_async_page = $this->TwoSettings->get_settings('two_async_page');
724 $two_disable_page = $this->TwoSettings->get_settings('two_disable_page');
725 $two_exclude_css = $this->TwoSettings->get_settings('two_exclude_css');
726 $page_url = sanitize_url($_POST['page_url']); // phpcs:ignore
727
728 if (OptimizerUtils::get_url_query($page_url, 'PageSpeed') === 'off') {
729 $page_url_without_pagespeed = str_replace(['?PageSpeed=off', '&PageSpeed=off'], '', $page_url);
730 }
731 $page_url = OptimizerUtils::remove_domain_part($page_url);
732 $page_url_without_pagespeed = OptimizerUtils::remove_domain_part($page_url_without_pagespeed);
733 $el_id = sanitize_text_field($_POST['el_id']); // phpcs:ignore
734 $task = sanitize_text_field($_POST['task']); // phpcs:ignore
735 $state = sanitize_text_field($_POST['state']); // phpcs:ignore
736
737 if (!is_array($two_disable_page)) {
738 $two_disable_page = [];
739 }
740
741 if (!is_array($two_async_page)) {
742 $two_async_page = [];
743 }
744 $two_disable_page[$page_url] = sanitize_text_field($_POST['two_disable_page']); // phpcs:ignore
745 $two_async_page[$page_url] = sanitize_text_field($_POST['two_async_page']); // phpcs:ignore
746
747 if (!empty($page_url_without_pagespeed)) {
748 $two_disable_page[$page_url_without_pagespeed] = sanitize_text_field($_POST['two_disable_page']); // phpcs:ignore
749 $two_async_page[$page_url_without_pagespeed] = sanitize_text_field($_POST['two_async_page']); // phpcs:ignore
750 }
751 $this->TwoSettings->update_setting('two_disable_page', $two_disable_page);
752 $this->TwoSettings->update_setting('two_async_page', $two_async_page);
753
754 if ($task == 'two_async') {
755 if ($state === '1') {
756 $this->TwoSettings->update_setting('two_async_css', $two_async_css . ',' . $el_id);
757 $this->TwoSettings->update_setting('two_disable_css', str_replace(',' . $el_id, '', $two_disable_css));
758 } else {
759 $this->TwoSettings->update_setting('two_async_css', str_replace($el_id, '', $two_async_css));
760 }
761 } elseif ($task == 'two_disable') {
762 if ($state === '1') {
763 $this->TwoSettings->update_setting('two_disable_css', $two_disable_css . ',' . $el_id);
764 $this->TwoSettings->update_setting('two_async_css', str_replace(',' . $el_id, '', $two_async_css));
765 } else {
766 $this->TwoSettings->update_setting('two_disable_css', str_replace($el_id, '', $two_disable_css));
767 }
768 } elseif ($task == 'two_exclude_css') {
769 if ($state === '1') {
770 $this->TwoSettings->update_setting('two_exclude_css', $two_exclude_css . ',' . $el_id);
771 $this->TwoSettings->update_setting('two_async_css', str_replace(',' . $el_id, '', $two_async_css));
772 $this->TwoSettings->update_setting('two_disable_css', str_replace(',' . $el_id, '', $two_disable_css));
773 } else {
774 $this->TwoSettings->update_setting('two_exclude_css', str_replace($el_id, '', $two_disable_css));
775 }
776 } else {
777 $this->TwoSettings->update_setting('two_async_css', str_replace(',' . $el_id, '', $two_async_css));
778 $this->TwoSettings->update_setting('two_disable_css', str_replace(',' . $el_id, '', $two_disable_css));
779 }
780 }
781 }
782
783 public static function two_enqueue_admin_assets($hook_suffix)
784 {
785 if ($hook_suffix === 'plugins.php' && strtolower(TWO_SO_ORGANIZATION_NAME) != '10web') {
786 wp_enqueue_script('two_update_white_label_js', TENWEB_SO_URL . '/assets/js/two_update_white_label.js', [ 'jquery' ], TENWEB_SO_VERSION);
787 }
788 wp_register_style('two-open-sans', 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,600,700,800&display=swap');
789
790 if ($hook_suffix == 'toplevel_page_two_settings_page') {
791 wp_enqueue_script('two_deactivate_plugin', TENWEB_SO_URL . '/assets/js/two_deactivate_plugin.js', [ 'jquery' ], TENWEB_SO_VERSION);
792 wp_localize_script('two_deactivate_plugin', 'two_admin_vars', [
793 'ajaxurl' => admin_url('admin-ajax.php'),
794 'ajaxnonce' => wp_create_nonce('two_ajax_nonce')
795 ]);
796 $two_admin_vars = [
797 'ajaxurl' => admin_url('admin-ajax.php'),
798 'ajaxnonce' => wp_create_nonce('two_ajax_nonce')
799 ];
800 $two_critical_default_settings = get_option('two_critical_default_settings');
801 global $TwoSettings;
802
803 if (empty($two_critical_default_settings)) {
804 $TwoSettings->init_critical_defaults();
805 }
806
807 if (isset($_GET[ 'mode' ]) && 'advanced' === $_GET[ 'mode' ] && (!defined('TWO_INCOMPATIBLE_ERROR') || !TWO_INCOMPATIBLE_ERROR)) { // phpcs:ignore
808 wp_enqueue_script('two_tagsinput_js', TENWEB_SO_URL . '/assets/js/jquery.tagsinput.min.js', [ 'jquery' ], TENWEB_SO_VERSION);
809 wp_enqueue_script('two_admin_js', TENWEB_SO_URL . '/assets/js/two_admin.js', [ 'jquery' ], TENWEB_SO_VERSION);
810
811 wp_localize_script('two_admin_js', 'two_critical_options', $TwoSettings->critical_options);
812 wp_enqueue_script('datatables_js', TENWEB_SO_URL . '/assets/js/datatables.min.js', [ 'jquery' ], TENWEB_SO_VERSION);
813 wp_enqueue_script('two_jquery_multi-select_js', TENWEB_SO_URL . '/assets/js/jquery.multi-select.js', [ 'jquery' ], TENWEB_SO_VERSION);
814 wp_enqueue_style('two_admin_css', TENWEB_SO_URL . '/assets/css/two_admin.css', '', TENWEB_SO_VERSION);
815 wp_enqueue_style('two_multi-select_css', TENWEB_SO_URL . '/assets/css/multi-select.css', '', TENWEB_SO_VERSION);
816 wp_enqueue_style('jquery_tagsinput_css', TENWEB_SO_URL . '/assets/css/jquery.tagsinput.min.css', '', TENWEB_SO_VERSION);
817 wp_enqueue_style('datatables_min_css', TENWEB_SO_URL . '/assets/css/datatables.min.css', '', TENWEB_SO_VERSION);
818
819 wp_localize_script('two_admin_js', 'two_admin_vars', $two_admin_vars);
820 wp_enqueue_script('two_select2', TENWEB_SO_URL . '/assets/lib/select2/js/select2.min.js', [ 'jquery' ], TENWEB_SO_VERSION);
821 wp_enqueue_style('two_select2', TENWEB_SO_URL . '/assets/lib/select2/css/select2.min.css', '', TENWEB_SO_VERSION);
822 } else {
823 wp_enqueue_style('two_settings_basic_css', TENWEB_SO_URL . '/assets/css/settings_basic.css', ['two-open-sans'], TENWEB_SO_VERSION);
824 }
825 }
826
827 if ($hook_suffix != 'toplevel_page_two_settings_page') {
828 // Not add the css to the 10Web Booster page.
829 wp_enqueue_style('two_speed_css', TENWEB_SO_URL . '/assets/css/speed.css', ['two-open-sans'], TENWEB_SO_VERSION);
830 }
831 wp_enqueue_script('two_circle_js', TENWEB_SO_URL . '/assets/js/circle-progress.js', ['jquery'], TENWEB_SO_VERSION);
832 $is_two_advanced = isset($_GET['page']) && $_GET['page'] == 'two_settings_page' && isset($_GET['mode']) && $_GET['mode'] == 'advanced'; // phpcs:ignore
833 $optimizing_in_progress_transinent = false;
834
835 if (get_the_ID()) {
836 $optimizing_in_progress_transinent = \TenWebWpTransients\OptimizerTransients::get('two_optimize_inprogress_' . get_the_ID());
837 }
838
839 if (!$is_two_advanced) {
840 wp_enqueue_script('two_speed_js', TENWEB_SO_URL . '/assets/js/speed.js', ['jquery', 'two_circle_js'], TENWEB_SO_VERSION);
841 wp_localize_script('two_speed_js', 'two_speed', [
842 'nonce' => wp_create_nonce('two_ajax_nonce'),
843 'ajax_url' => admin_url('admin-ajax.php'),
844 'clearing' => __('Clearing...', 'tenweb-speed-optimizer'),
845 'cleared' => __('Cleared cache', 'tenweb-speed-optimizer'),
846 'clear' => __('Clear cache', 'tenweb-speed-optimizer'),
847 'optimize_entire_website' => \TenWebOptimizer\OptimizerOnInit::two_reached_limit(),
848 'critical_pages' => \TenWebOptimizer\OptimizerUtils::getCriticalPages(),
849 'front_page_id' => get_option('page_on_front'),
850 'optimizing_in_progress' => $optimizing_in_progress_transinent,
851 'two_front_page_speed' => get_option('two-front-page-speed', []),
852 'wrong_email' => __('Please enter a valid email address.', 'tenweb-speed-optimizer'),
853 'sign_up' => __('SIGN UP & CONNECT', 'tenweb-speed-optimizer'),
854 'connection_link' => esc_url(\TenWebOptimizer\OptimizerUtils::get_tenweb_connection_link()),
855 'something_wrong' => __('Something went wrong, please try again.', 'tenweb-speed-optimizer'),
856 ]);
857 wp_localize_script('two_speed_js', 'two_limit_exceed_popup_content', [
858 'exceed_url' => \TenWebOptimizer\OptimizerOnInit::two_reached_limit() ? esc_url(\TenWebOptimizer\OptimizerOnInit::two_reached_limit() . '?two_comes_from=pagesListAfterLimit') : '',
859 'exceed_title' => esc_html__('You’ve reached the Free Plan limit', 'tenweb-speed-optimizer'),
860 'exceed_desc_1' => esc_html__('Upgrade to 10Web Booster Pro to optimize all pages', 'tenweb-speed-optimizer'),
861 'exceed_desc_2' => esc_html__('and enable Cloudflare Enterprise CDN.', 'tenweb-speed-optimizer'),
862 'exceed_button_text' => esc_html__('Upgrade', 'tenweb-speed-optimizer'),
863 ]);
864 }
865 }
866
867 public function admin_menu()
868 {
869 add_menu_page(
870 TWO_SO_ORGANIZATION_NAME . ' Booster',
871 TWO_SO_ORGANIZATION_NAME . ' Booster',
872 'manage_options',
873 'two_settings_page',
874 [
875 '\TenWebOptimizer\OptimizerAdmin',
876 'settings_page',
877 ],
878 \TenWebOptimizer\OptimizerUtils::get_booster_icon(),
879 30
880 );
881 add_submenu_page(
882 '',
883 __('White Label', 'tenweb-speed-optimizer'),
884 __('White Label', 'tenweb-speed-optimizer'),
885 'manage_options',
886 'two_white_label',
887 ['\TenWebOptimizer\OptimizerAdmin', 'white_label_view']
888 );
889
890 $cloudflare_cdn_class = 'two-submenu-cdn-free';
891 $cloudflare_cdn_class_enabled = '';
892
893 if (\TenWebOptimizer\OptimizerUtils::is_paid_user()) {
894 $cloudflare_cdn_class = 'two-submenu-cdn-paid';
895 global $TwoSettings;
896
897 if ($TwoSettings->get_settings('cloudflare_cache_status') == 'on') {
898 $cloudflare_cdn_class_enabled = 'two-submenu-cdn-enabled';
899 }
900 }
901
902 if (!defined('TWO_INCOMPATIBLE_ERROR')
903 && !TENWEB_SO_HOSTED_ON_10WEB
904 && \TenWebOptimizer\OptimizerUtils::is_tenweb_booster_connected()
905 && strtolower(TWO_SO_ORGANIZATION_NAME) === '10web') {
906 add_submenu_page(
907 'two_settings_page',
908 'Main Page',
909 'Main Page',
910 'manage_options',
911 'two_settings_page',
912 [
913 '\TenWebOptimizer\OptimizerAdmin',
914 'settings_page',
915 ]
916 );
917 add_submenu_page(
918 'two_settings_page',
919 'Cloudflare CDN',
920 '<span class="' . sanitize_html_class($cloudflare_cdn_class) . ' ' . $cloudflare_cdn_class_enabled . '">Cloudflare CDN</span>',
921 'manage_options',
922 'two_cloudflare_cdn',
923 [
924 '\TenWebOptimizer\OptimizerAdmin',
925 'cloudflare_cdn_page',
926 ]
927 );
928
929 if (!\TenWebOptimizer\OptimizerUtils::is_paid_user()) {
930 add_submenu_page(
931 'two_settings_page',
932 'Customer support',
933 'Customer support',
934 'manage_options',
935 'two_customer_support',
936 [
937 '\TenWebOptimizer\OptimizerAdmin',
938 'customer_support',
939 ]
940 );
941 }
942 }
943 }
944
945 public static function white_label_view()
946 {
947 require_once __DIR__ . '/views/white_label_view.php';
948 }
949
950 public static function settings_page()
951 {
952 if (isset($_GET['mode']) && 'advanced' === $_GET['mode'] && (!defined('TWO_INCOMPATIBLE_ERROR') || !TWO_INCOMPATIBLE_ERROR)) { // phpcs:ignore
953 if (OptimizerUtils::is_wpml_active() && (empty($_GET['lang']) || $_GET['lang'] !== 'all')) { // phpcs:ignore
954 $baseUrl = sanitize_text_field($_SERVER['REQUEST_SCHEME']) . '://' . sanitize_text_field($_SERVER['SERVER_NAME']) . sanitize_text_field($_SERVER['REQUEST_URI']); // phpcs:ignore
955 $location = add_query_arg(sanitize_text_field($_SERVER['QUERY_STRING']), '', $baseUrl); // phpcs:ignore
956 $location = add_query_arg('lang', 'all', $location);
957 OptimizerUtils::two_redirect($location);
958 }
959 require_once __DIR__ . '/views/settings_view.php';
960 } else {
961 if ((!defined('TWO_INCOMPATIBLE_ERROR') || !TWO_INCOMPATIBLE_ERROR) && OptimizerUtils::is_tenweb_booster_connected() && get_option(TENWEBIO_MANAGER_PREFIX . '_domain_id')) {
962 require_once __DIR__ . '/views/settings_basic.php';
963 } else {
964 require_once __DIR__ . '/views/settings_connect.php';
965 }
966 }
967 }
968
969 public static function cloudflare_cdn_page()
970 {
971 require_once __DIR__ . '/views/cdn_page.php';
972 }
973
974 public static function referral_program_page()
975 {
976 require_once __DIR__ . '/views/referral_program_page.php';
977 }
978
979 public static function customer_support()
980 {
981 $main_class = 'two-customer-support-main';
982 $close_icon = false;
983 require_once __DIR__ . '/views/customer_support.php';
984 customer_care_html($main_class, $close_icon);
985 }
986
987 public static function get_instance()
988 {
989 if (null == self::$instance) {
990 self::$instance = new self();
991 }
992
993 return self::$instance;
994 }
995
996 public function ajax_two_settings()
997 {
998 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce') && isset($_POST['task'])) { // phpcs:ignore
999 $ajax_task = sanitize_text_field($_POST['task']);
1000 $clear_cache_from = isset($_POST['clear_cache_from']) ? sanitize_text_field($_POST['clear_cache_from']) : '';
1001
1002 if ($ajax_task === 'clear_cache') {
1003 self::clear_cache(
1004 true,
1005 true,
1006 true,
1007 true,
1008 'front_page',
1009 false,
1010 true,
1011 true,
1012 false,
1013 $clear_cache_from
1014 );
1015 } elseif ($ajax_task === 'regenerate_critical') {
1016 self::clear_cache(true, false, true, true, 'all');
1017 } elseif ($ajax_task === 'settings') {
1018 if (isset($_POST['two_critical_pages'])) {
1019 $two_critical_pages = OptimizerUtils::getCriticalPages();
1020
1021 foreach ($_POST['two_critical_pages'] as $key => $val) { // phpcs:ignore
1022 if (isset($two_critical_pages[$key]) && isset($_POST['two_critical_pages'][$key])) {
1023 if (isset($two_critical_pages[$key]['critical_css'])) {
1024 $_POST['two_critical_pages'][$key]['critical_css'] = $two_critical_pages[$key]['critical_css'];
1025 }
1026
1027 if (isset($two_critical_pages[$key]['uncritical_css'])) {
1028 $_POST['two_critical_pages'][$key]['uncritical_css'] = $two_critical_pages[$key]['uncritical_css'];
1029 }
1030
1031 if (isset($two_critical_pages[$key]['critical_fonts'])) {
1032 $_POST['two_critical_pages'][$key]['critical_fonts'] = $two_critical_pages[$key]['critical_fonts'];
1033 }
1034
1035 if (isset($two_critical_pages[$key]['critical_bg'])) {
1036 $_POST['two_critical_pages'][$key]['critical_bg'] = $two_critical_pages[$key]['critical_bg'];
1037 }
1038
1039 if (isset($two_critical_pages[$key]['status'])) {
1040 $_POST['two_critical_pages'][$key]['status'] = $two_critical_pages[$key]['status'];
1041 }
1042
1043 if (isset($two_critical_pages[$key]['critical_date'])) {
1044 $_POST['two_critical_pages'][$key]['critical_date'] = $two_critical_pages[$key]['critical_date'];
1045 }
1046
1047 if (isset($two_critical_pages[$key]['images_in_viewport'])) {
1048 $_POST['two_critical_pages'][$key]['images_in_viewport'] = $two_critical_pages[$key]['images_in_viewport'];
1049 }
1050 }
1051 }
1052 }
1053 $this->TwoSettings->set_settings($_POST);
1054 } elseif ($ajax_task == 'regenerate_webp') {
1055 $url_list = sanitize_text_field($_POST[ 'url_list' ]); // phpcs:ignore
1056 $request_webp_action = OptimizerUtils::request_webp_action('regenerate', $url_list);
1057 echo json_encode($request_webp_action); // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
1058 die;
1059 } elseif ($ajax_task == 'delete_webp') {
1060 $request_webp_action = OptimizerUtils::request_webp_action('delete');
1061 echo json_encode($request_webp_action); // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
1062 die;
1063 } elseif ($ajax_task === 'delete_logs' && !empty($_POST['log_type'])) {
1064 OptimizerLogger::delete_logs(sanitize_text_field($_POST['log_type']));
1065 wp_send_json_success();
1066 }
1067 global $TwoSettings;
1068
1069 if ($TwoSettings->get_settings('two_remove_elementor_lazyload') == 'on') {
1070 // change elementor background_lazyload to inactive
1071 if (is_plugin_active('elementor/elementor.php') && get_option('elementor_experiment-e_lazyload') != 'inactive') {
1072 update_option('elementor_experiment-e_lazyload', 'inactive', false);
1073 }
1074 }
1075 // Purge 10Web cache.
1076 do_action('tenweb_purge_all_caches');
1077 $message = apply_filters('two_save_settings_message', __('Success!', 'tenweb-speed-optimizer'));
1078 $code = apply_filters('two_save_settings_code', 0);
1079 $two_webp_delivery_working = OptimizerUtils::testWebPDelivery();
1080 echo json_encode([ 'success' => true, 'message' => $message, 'code' => $code, 'webp_delivery_status' => $two_webp_delivery_working ]); // phpcs:ignore
1081 die;
1082 }
1083 echo json_encode(['success' => false]); // phpcs:ignore
1084 die;
1085 }
1086
1087 public function ajax_two_update_setting()
1088 {
1089 if (isset($_POST[ 'nonce' ]) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) { // phpcs:ignore
1090 $name = sanitize_text_field($_POST['name']); // phpcs:ignore
1091 $value = sanitize_text_field($_POST['value']); // phpcs:ignore
1092 $this->TwoSettings->update_setting($name, $value);
1093 echo json_encode([ 'success' => true ]); // phpcs:ignore
1094 die;
1095 }
1096 echo json_encode([ 'success' => false ]); // phpcs:ignore
1097 die;
1098 }
1099
1100 public function two_critical()
1101 {
1102 $return_data = [
1103 'success' => false,
1104 ];
1105
1106 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) { // phpcs:ignore
1107 \TenWebWpTransients\OptimizerTransients::set('two_critical_in_process', '1', 360);
1108
1109 if (isset($_POST['data']['task'])) {
1110 $task = sanitize_text_field($_POST['data']['task']);
1111
1112 if ($task === 'generate') {
1113 if (isset($_POST['data'])) {
1114 $_POST['data']['initiator'] = 'manual_from_ccss_tab';
1115 }
1116 $return_data = OptimizerCriticalCss::generateCriticalCSS($_POST);
1117 } elseif ($task === 'delete' && isset($_POST['data']['page_id'])) {
1118 $page_id = sanitize_text_field($_POST['data']['page_id']);
1119 OptimizerUtils::delete_critical_page($page_id);
1120 self::clear_cache(false, true);
1121
1122 if (has_action('two_page_optimized_removed')) {
1123 do_action('two_page_optimized_removed', $page_id);
1124 }
1125 } elseif ('insert/update' === $task && isset($_POST['data']['page_id'])) {
1126 $page_id = sanitize_text_field($_POST['data']['page_id']);
1127 $two_critical_pages = $this->TwoSettings->get_settings('two_critical_pages');
1128
1129 $update_data = map_deep($_POST['data']['two_critical_pages'][$page_id], 'sanitize_text_field'); // phpcs:ignore
1130
1131 if (isset($two_critical_pages[$page_id])) {
1132 if (isset($two_critical_pages[$page_id]['critical_css'])) {
1133 $update_data['critical_css'] = $two_critical_pages[$page_id]['critical_css'];
1134 }
1135
1136 if (isset($two_critical_pages[$page_id]['uncritical_css'])) {
1137 $update_data['uncritical_css'] = $two_critical_pages[$page_id]['uncritical_css'];
1138 }
1139
1140 if (isset($two_critical_pages[$page_id]['critical_fonts'])) {
1141 $update_data['critical_fonts'] = $two_critical_pages[$page_id]['critical_fonts'];
1142 }
1143
1144 if (isset($two_critical_pages[$page_id]['critical_bg'])) {
1145 $update_data['critical_bg'] = $two_critical_pages[$page_id]['critical_bg'];
1146 }
1147
1148 if (isset($two_critical_pages[$page_id]['critical_date'])) {
1149 $update_data['critical_date'] = $two_critical_pages[$page_id]['critical_date'];
1150 }
1151 }
1152
1153 if (!is_array($two_critical_pages)) {
1154 $two_critical_pages = [];
1155 }
1156 $two_critical_pages[$page_id] = $update_data;
1157 $this->TwoSettings->update_setting('two_critical_pages', $two_critical_pages);
1158 $return_data['success'] = true;
1159 } elseif ($task === 'update_defaults') {
1160 if (isset($_POST['data']['default_settings'])) {
1161 $default_settings = map_deep($_POST['data']['default_settings'], 'sanitize_text_field'); // phpcs:ignore
1162
1163 if (empty($_POST['data']['default_settings']['default_sizes'])) {
1164 $default_settings['default_sizes'] = [];
1165 }
1166 update_option('two_critical_default_settings', $default_settings);
1167 }
1168 $return_data['success'] = true;
1169 }
1170 }
1171 }
1172 echo json_encode($return_data); // phpcs:ignore
1173 die;
1174 }
1175
1176 public function two_critical_statuses()
1177 {
1178 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) { // phpcs:ignore
1179 $two_critical_pages = OptimizerUtils::getCriticalPages();
1180 $two_critical_in_process = \TenWebWpTransients\OptimizerTransients::get('two_critical_in_process');
1181 $return_data = [
1182 'pages' => [],
1183 'status' => $two_critical_in_process,
1184 ];
1185
1186 if (is_array($two_critical_pages)) {
1187 foreach ($two_critical_pages as $page_id => $critical_page) {
1188 $critical_page_status = $critical_page[ 'status' ];
1189
1190 if ($critical_page_status == 'success') {
1191 if (!isset($critical_page[ 'critical_css' ]) || empty($critical_page[ 'critical_css' ])) {
1192 $critical_page_status = 'not_started';
1193 $two_critical_pages[ $page_id ][ 'status' ] = 'not_started';
1194 }
1195 }
1196 $return_data[ 'pages' ][] = [
1197 'page_id' => $critical_page[ 'id' ],
1198 'status' => $critical_page_status,
1199 ];
1200 }
1201 }
1202 $this->TwoSettings->update_setting('two_critical_pages', $two_critical_pages);
1203 echo json_encode($return_data, true); // phpcs:ignore
1204 die;
1205 }
1206 }
1207
1208 public function add_action_link($links, $file)
1209 {
1210 if (TENWEB_SO_BASENAME === $file) {
1211 $settings_link = '<a href="' . esc_url(admin_url('admin.php?page=two_settings_page')) . '">' . __('Settings') . '</a>';
1212 array_unshift($links, $settings_link);
1213 }
1214
1215 return $links;
1216 }
1217
1218 public function manager_clear_cache()
1219 {
1220 // this should be native WP transient as it could be set in other plugins
1221 $two_token_clear_cache = get_transient('two_token_clear_cache');
1222
1223 if (isset($_POST['two_token']) && $two_token_clear_cache === $_POST['two_token']) { // phpcs:ignore
1224 \TenWebWpTransients\OptimizerTransients::delete('two_token_clear_cache');
1225 self::clear_cache(false, !$_POST['regenerate_critical_css']); // phpcs:ignore
1226 }
1227 }
1228
1229 public function two_clear_cloudflare_cache()
1230 {
1231 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce') && OptimizerUtils::check_admin_capabilities()) { // phpcs:ignore
1232 if (isset($_POST['page_url'])) {
1233 OptimizerUtils::clear_cloudflare_cache([sanitize_url($_POST['page_url'])]); // phpcs:ignore
1234 }
1235 }
1236 }
1237
1238 public static function clear_cache(
1239 $is_json = false,
1240 $excludeCriticalRegeneration = false,
1241 $delete_tenweb_manager_cache = true,
1242 $delete_cloudflare_cache = true,
1243 $critical_regeneration_mode = 'front_page',
1244 $clear_critical = false,
1245 $clear_two_cloudflare_cache = true,
1246 $warmup_cache = true,
1247 $delete_files = false,
1248 $clear_cache_from = '',
1249 $skip_home_critical_generation = false
1250 ) {
1251 do_action('two_before_clear_cache', debug_backtrace()); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
1252 $date = time();
1253 global $TwoSettings;
1254 $TwoSettings->update_setting('two_clear_cache_date', $date);
1255 $TwoSettings->update_setting('tenweb_so_version', TENWEB_SO_VERSION);
1256 $dir = OptimizerCache::get_path();
1257 $delete_cache_db = OptimizerUtils::delete_all_cache_db();
1258 OptimizerCacheStructure::flushAllCache();
1259 $exclude_dir = null;
1260 $two_critical_status = $TwoSettings->get_settings('two_critical_status');
1261
1262 if ($excludeCriticalRegeneration) {
1263 $exclude_dir = 'critical';
1264 }
1265 $cache_file_delete_status = true;
1266
1267 if ($delete_files) {
1268 $cache_file_delete_status = OptimizerUtils::delete_all_cache_file($dir, [$dir, $dir . 'css', $dir . 'js', $dir . 'critical'], $exclude_dir);
1269 } else {
1270 \TenWebOptimizer\WebPageCache\OptimizerWebPageCacheWP::get_instance()->delete_all_cache();
1271 }
1272 OptimizerUtils::purge_pagespeed_cache();
1273
1274 if ($delete_tenweb_manager_cache) {
1275 do_action('tenweb_purge_all_caches', false);
1276 }
1277
1278 if ($delete_cloudflare_cache) {
1279 OptimizerUtils::flushCloudflareCache();
1280 }
1281 wp_cache_flush();
1282
1283 $success = false;
1284
1285 if ($cache_file_delete_status && $delete_cache_db) {
1286 $success = true;
1287 }
1288
1289 OptimizerUtils::clear_third_party_cache();
1290
1291 if (!$excludeCriticalRegeneration && $two_critical_status === 'true') {
1292 OptimizerUtils::regenerate_critical($critical_regeneration_mode);
1293 }
1294
1295 if ($clear_critical) {
1296 self::clear_critical_cache($skip_home_critical_generation);
1297 }
1298
1299 OptimizerLogger::add_clear_cache_log($is_json, $excludeCriticalRegeneration, $delete_tenweb_manager_cache, $delete_cloudflare_cache, $critical_regeneration_mode, $clear_critical);
1300
1301 if ($clear_two_cloudflare_cache) {
1302 OptimizerUtils::clear_cloudflare_cache([], $clear_cache_from);
1303 }
1304
1305 if ($warmup_cache) {
1306 OptimizerUtils::warmup_cache();
1307 }
1308
1309 //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
1310 do_action('two_after_clear_cache', debug_backtrace());
1311
1312 if ($is_json) {
1313 echo json_encode(['success' => $success]); // phpcs:ignore
1314 die;
1315 }
1316
1317 return $success;
1318 }
1319
1320 public static function clear_critical_cache($skip_home_critical_generation = false)
1321 {
1322 global $TwoSettings;
1323 $two_critical_pages = OptimizerUtils::getCriticalPages();
1324 $home_critical = false;
1325
1326 if (is_array($two_critical_pages)) {
1327 foreach ($two_critical_pages as $id => $page) {
1328 if (!$home_critical && $id === 'front_page') {
1329 $home_critical = true;
1330 }
1331 $two_critical_pages[$id]['status'] = 'not_started';
1332 unset($two_critical_pages[$id]['critical_css'], $two_critical_pages[$id]['uncritical_css'], $two_critical_pages[$id]['critical_fonts'], $two_critical_pages[$id]['critical_bg'], $two_critical_pages[$id]['critical_date']);
1333 }
1334 $TwoSettings->update_setting('two_critical_pages', $two_critical_pages);
1335 }
1336 $prefix = 'critical/two_*.*';
1337 OptimizerUtils::delete_files_by_prefix($prefix);
1338
1339 if ($home_critical && ! $skip_home_critical_generation) {
1340 OptimizerCriticalCss::generate_critical_css_by_id('front_page');
1341 }
1342 }
1343
1344 public static function two_activate($networkwide)
1345 {
1346 $access_token = get_site_option(TENWEB_PREFIX . '_access_token', false);
1347
1348 if (!$access_token) {
1349 update_option('two_plugin_activated_flow_init', '1');
1350 }
1351
1352 if (function_exists('is_multisite') && is_multisite()) {
1353 // Check if it is a network activation - if so, run the activation function for each blog id.
1354 if ($networkwide) {
1355 global $wpdb;
1356 // Get all blog ids.
1357 $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); // phpcs:ignore
1358
1359 foreach ($blogids as $blog_id) {
1360 switch_to_blog($blog_id);
1361 self::activate();
1362 restore_current_blog();
1363 }
1364
1365 return;
1366 }
1367 }
1368 add_option('redirect_after_activation_option', true);
1369 self::activate();
1370 }
1371
1372 public static function activate()
1373 {
1374 global $TwoSettings;
1375 $two_version = get_option('tw_optimize_version');
1376
1377 if ($two_version === false) {
1378 $TwoSettings->set_default_settings();
1379 }
1380 self::set_additional_settings();
1381
1382 if (\Tenweb_Authorization\Login::get_instance()->check_logged_in()) {
1383 $TwoSettings->update_setting('two_connected', '1');
1384
1385 $habit_version = '2.8.1';
1386
1387 if (version_compare($two_version, $habit_version, '<') && !TENWEB_SO_HOSTED_ON_10WEB) {
1388 $nonce = uniqid('two_activate_score_check_', false);
1389 update_option('two_activate_score_check_nonce_data', $nonce);
1390 wp_remote_post(admin_url('admin-ajax.php'), [
1391 'timeout' => 5, // phpcs:ignore
1392 'redirection' => 5,
1393 'httpversion' => '1.0',
1394 'blocking' => false,
1395 'body' => [
1396 'action' => 'two_activate_score_check',
1397 'nonce' => $nonce
1398 ],
1399 'cookies' => []
1400 ]);
1401 }
1402 $TwoSettings->sync_configs_with_plugin_state();
1403 } else {
1404 $TwoSettings->update_setting('two_connected', '0');
1405 }
1406 $TwoSettings->update_setting('two_critical_url_args', 'PageSpeed=off&two_nooptimize=1&two_action=generating_critical_css');
1407 OptimizerUtils::testWebPDelivery();
1408 self::add_two_delayed_js_execution_list();
1409
1410 if (TENWEB_SO_HOSTED_ON_10WEB && strpos(get_site_url(), 'TENWEBLXC') === false) { //if hosted on 10web
1411 // Set WebP delivery to on by default.
1412 if (false === $TwoSettings->get_settings('two_enable_nginx_webp_delivery')) {
1413 $TwoSettings->update_setting('two_enable_nginx_webp_delivery', 'on');
1414 }
1415
1416 if (!$two_version || self::TENWEB_SO_REGENERATE_CRITICAL_ON_UPDATE) {
1417 self::generateCriticalCssOnInit();
1418 }
1419 } elseif (!TENWEB_SO_HOSTED_ON_10WEB) { //connected website
1420 if (\Tenweb_Authorization\Login::get_instance()->check_logged_in() && (!$two_version || self::TENWEB_SO_REGENERATE_CRITICAL_ON_UPDATE)) {
1421 if (!empty(\TenWebOptimizer\OptimizerUtils::TWOConnected()) && empty(\TenWebOptimizer\OptimizerUtils::IOConnected())) {
1422 self::generateCriticalCssOnInit();
1423 }
1424 } elseif (!$two_version) {
1425 if (defined('TENWEB_SO_AUTOCONNECT') && TENWEB_SO_AUTOCONNECT) {
1426 $two_php_not_compatible = defined('TWO_INCOMPATIBLE_ERROR') && TWO_INCOMPATIBLE_ERROR;
1427 $two_connect_link = $two_php_not_compatible ? '' : OptimizerUtils::get_tenweb_connection_link();
1428 OptimizerUtils::two_redirect($two_connect_link, false);
1429 }
1430 }
1431 }
1432 }
1433
1434 public static function generateCriticalCssOnInit($rightAfterConnect = false)
1435 {
1436 $two_version = get_option('tw_optimize_version');
1437 $two_critical_pages = OptimizerUtils::getCriticalPages();
1438
1439 if (empty($two_critical_pages)) {
1440 OptimizerCriticalCss::generate_critical_css_by_id('front_page', $rightAfterConnect);
1441 } else {
1442 if ($two_version === false || version_compare($two_version, '1.54.6', '<')) {
1443 if (OptimizerUtils::is_wpml_active()) {
1444 OptimizerUtils::add_wpml_home_pages_into_critical_pages($two_critical_pages, $two_critical_pages[ 'front_page' ][ 'url' ]);
1445 }
1446 }
1447
1448 if (TENWEB_SO_HOSTED_ON_10WEB) {
1449 OptimizerUtils::regenerate_critical('all', $rightAfterConnect);
1450 } elseif (\Tenweb_Authorization\Login::get_instance()->check_logged_in()) {
1451 if ($rightAfterConnect) {
1452 OptimizerUtils::update_critical_statuses($two_critical_pages, 'not_started');
1453 OptimizerCriticalCss::generate_critical_css_by_id('front_page', $rightAfterConnect);
1454 } else {
1455 OptimizerUtils::regenerate_critical('front_page', $rightAfterConnect);
1456 }
1457 }
1458 }
1459 }
1460
1461 public function update()
1462 {
1463 $version = get_option('tw_optimize_version');
1464 $new_version = TENWEB_SO_VERSION;
1465
1466 if (version_compare($version, $new_version, '<')) {
1467 if (defined('TENWEB_CONNECTED_SPEED')
1468 && \Tenweb_Authorization\Login::get_instance()->check_logged_in()
1469 && \Tenweb_Authorization\Login::get_instance()->get_connection_type() == TENWEB_CONNECTED_SPEED
1470 && empty(get_option('two_first_connect', false))
1471 && version_compare($version, '2.19.49', '<')
1472 && empty(OptimizerUtils::IOConnected())) {
1473 // this option also used to check booster real connection when IO is connected
1474 // and if you connected your site before November 2022 you don't have this option
1475 // so in WordPress admin you see Connection screen with Optimize button, to fix that we set that option
1476
1477 update_option('two_first_connect', time());
1478 }
1479 global $TwoSettings;
1480 /* Update TW optimize version */
1481 update_option('tw_optimize_version', $new_version);
1482 self::add_two_delayed_js_execution_list();
1483 self::fix_delayed_list_slashes();
1484 self::set_additional_settings();
1485 $two_critical_sizes = $TwoSettings->get_settings('two_critical_sizes');
1486
1487 if ($two_critical_sizes === false) {
1488 $TwoSettings->set_critical_defaults();
1489 }
1490
1491 if ($TwoSettings->get_settings('two_critical_status') === 'true' && $TwoSettings->get_settings('two_critical_font_status', null) === null) {
1492 $TwoSettings->update_setting('two_critical_font_status', 'true');
1493 }
1494
1495 if (!$TwoSettings->get_settings('two_page_cache_life_time')) {
1496 $TwoSettings->update_setting('two_page_cache_life_time', $TwoSettings->get_default_setting('two_page_cache_life_time'));
1497 }
1498
1499 \TenWebOptimizer\WebPageCache\OptimizerWebPageCacheWP::get_instance()->store_page_cache_configs();
1500
1501 if (TENWEB_SO_HOSTED_ON_10WEB
1502 || (\Tenweb_Authorization\Login::get_instance()->check_logged_in() && \TenWebOptimizer\OptimizerUtils::TWOConnected())) {
1503 \Tenweb_Authorization\Helper::check_site_state(true);
1504 self::clear_cache(false, !self::TENWEB_SO_REGENERATE_CRITICAL_ON_UPDATE);
1505 }
1506 }
1507 }
1508
1509 public static function two_uninstall()
1510 {
1511 $site_options = [
1512 TENWEB_PREFIX . '_is_available',
1513 'two_flow_mode_select',
1514 'two_conflicting_plugins',
1515 'two_flow_speed',
1516 TENWEB_PREFIX . '_client_referral_hash'];
1517 $options = [
1518 'two_first_connect',
1519 'two_delayed_js_execution_list_updated',
1520 'two_delayed_js_execution_list_updated_fix_slashes',
1521 'two_active_plugins_list',
1522 'two_optimized_date_front_page',
1523 'two_optimization_notif_status',
1524 'two_clear_cache_logs',
1525 'two_default_mode',
1526 'two_optimized_date',
1527 'two_page_speed',
1528 'two_critical_blocked',
1529 'no_optimize_pages',
1530 'two_triggerPostOptimizationTasks',
1531 'two_flow_status',
1532 'two-front-page-speed',
1533 'two_mode_front_page',
1534 'two_optimization_notif_status',
1535 'two_triggerPostOptimizationTasks',
1536 'two_flow_status',
1537 'two_performance_requests_logs',
1538 'two_clear_cache_logs',
1539 'two_critical_css_logs',
1540 'two_serve_not_optimized_page_logs',
1541 'tw_optimize_version'
1542 ];
1543
1544 foreach ($site_options as $option) {
1545 delete_site_option($option);
1546 }
1547
1548 foreach ($options as $option) {
1549 delete_option($option);
1550 }
1551
1552 foreach (wp_load_alloptions() as $option => $value) {
1553 if (0 === strpos($option, \TenWebWpTransients\OptimizerTransients::TRANSIENT_KEY) ||
1554 0 === strpos($option, \TenWebWpTransients\OptimizerTransients::TRANSIENT_TIMEOUT_KEY)) {
1555 delete_option($option);
1556 }
1557 }
1558 }
1559
1560 public static function two_deactivate()
1561 {
1562 // Disable WebP delivery on plugin deactivation.
1563 global $TwoSettings;
1564
1565 $two_critical_pages = OptimizerUtils::getCriticalPages();
1566
1567 if (is_array($two_critical_pages)) {
1568 foreach ($two_critical_pages as $id => $page) {
1569 if (isset($page['status']) && $page['status'] == 'in_progress') {
1570 $page['status'] = 'not_started';
1571 }
1572 $critical_key = 'two_critical_' . $id;
1573 $critical_in_progress_key = 'two_critical_in_progress_' . $id;
1574 \TenWebWpTransients\OptimizerTransients::delete($critical_key);
1575 \TenWebWpTransients\OptimizerTransients::delete($critical_in_progress_key);
1576 }
1577 $TwoSettings->update_setting('two_critical_pages', $two_critical_pages);
1578 }
1579
1580 $timestamp = wp_next_scheduled('two_daily_cron_hook');
1581
1582 if ($timestamp) {
1583 wp_unschedule_event($timestamp, 'two_daily_cron_hook');
1584 }
1585
1586 $TwoSettings->update_setting('two_enable_nginx_webp_delivery', '');
1587
1588 if (isset($_GET['two_disconnect'])) {
1589 if (isset($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'two_disconnect_nonce')) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1590 self::disconnect_from_tenweb(true);
1591 }
1592 }
1593 self::clear_cache(false, true, true, true, 'front_page', false, true, false, true);
1594 $TwoSettings->sync_configs_with_plugin_state('inactive');
1595 //call IO deactivation hook
1596 \TenWebIO\Init::deactivate();
1597 \Tenweb_Authorization\Helper::check_site_state(true, null, null, ['tenweb-speed-optimizer' => 0]);
1598 }
1599
1600 private static function add_two_delayed_js_execution_list()
1601 {
1602 global $TwoSettings;
1603 $two_delayed_js_execution_list_updated = get_option('two_delayed_js_execution_list_updated');
1604
1605 if ($two_delayed_js_execution_list_updated != '1') {
1606 $two_delayed_js_execution_list = $TwoSettings->get_settings('two_delayed_js_execution_list');
1607 $default_data = self::TWO_DELAYED_DEFAULT_LIST;
1608
1609 if (isset($two_delayed_js_execution_list) && $two_delayed_js_execution_list && !empty($two_delayed_js_execution_list)) {
1610 $default_data = $two_delayed_js_execution_list . ',' . $default_data;
1611 }
1612
1613 $TwoSettings->update_setting(
1614 'two_delayed_js_execution_list',
1615 $default_data
1616 );
1617 update_option('two_delayed_js_execution_list_updated', '1');
1618 }
1619 }
1620
1621 public function get_posts_for_critical()
1622 {
1623 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) { // phpcs:ignore
1624 die('Invalid nonce');
1625 }
1626 $return = [];
1627 $two_critical_pages = OptimizerUtils::getCriticalPages();
1628 $is_wpml_active = OptimizerUtils::is_wpml_active();
1629
1630 if (!isset($two_critical_pages[ 'front_page' ])) {
1631 $flag_url = null;
1632
1633 if ($is_wpml_active) {
1634 $flag_url = OptimizerUtils::get_wpml_post_flag_url('front_page');
1635 }
1636 $return[] = [ 'front_page', 'Home', site_url(), $flag_url];
1637 }
1638
1639 if ($is_wpml_active) {
1640 do_action('wpml_switch_language', 'all'); // to get translated posts to
1641 }
1642
1643 add_filter('posts_where', [ $this, 'title_filter' ], 10, 2);
1644 $search_params = [
1645 'post_type' => 'any',
1646 'post_status' => 'publish',
1647 'posts_per_page' => 50 // phpcs:ignore
1648 ];
1649
1650 if (isset($_GET['q'])) {
1651 $search_params[ 'search_post_title' ] = sanitize_text_field($_GET['q']);
1652 }
1653 $search_results = new WP_Query($search_params);
1654
1655 if ($search_results->have_posts()) {
1656 while ($search_results->have_posts()) {
1657 $search_results->the_post();
1658
1659 if (!isset($two_critical_pages[$search_results->post->ID])) {
1660 if ('page' !== get_option('show_on_front')
1661 || !get_option('page_on_front') || get_option('page_on_front') != $search_results->post->ID
1662 ) {
1663 // shorten the title a little
1664 $title = (mb_strlen($search_results->post->post_title) > 50) ? mb_substr($search_results->post->post_title, 0, 49) . '...' : $search_results->post->post_title;
1665 $flag_url = null;
1666
1667 if ($is_wpml_active) {
1668 $flag_url = OptimizerUtils::get_wpml_post_flag_url($search_results->post->ID);
1669 }
1670 $return[] = [ $search_results->post->ID, $title, get_permalink($search_results->post->ID), $flag_url ];
1671 }
1672 }
1673 }
1674 }
1675 remove_filter('posts_where', [ $this, 'title_filter' ]);
1676 echo json_encode($return); // phpcs:ignore
1677 die;
1678 }
1679
1680 public static function title_filter($where, $wp_query)
1681 {
1682 global $wpdb;
1683
1684 if ($search_term = $wp_query->get('search_post_title')) {
1685 $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql($search_term) . '%\'';
1686 }
1687
1688 return $where;
1689 }
1690
1691 public function redirect_after_activation()
1692 {
1693 /* added to send site state after plugin activation as it was not working in two_activate function */
1694 if (get_option('redirect_after_activation_option', false) && \Tenweb_Authorization\Login::get_instance()->check_logged_in()) {
1695 \Tenweb_Authorization\Helper::check_site_state(true);
1696 }
1697
1698 if (!TENWEB_SO_HOSTED_ON_10WEB && get_option('redirect_after_activation_option', false)
1699 && (!\Tenweb_Authorization\Login::get_instance()->check_logged_in()
1700 || (empty(\TenWebOptimizer\OptimizerUtils::TWOConnected())
1701 && !empty(\TenWebOptimizer\OptimizerUtils::IOConnected())))) {
1702 delete_option('redirect_after_activation_option');
1703 OptimizerUtils::two_redirect(admin_url('admin.php?page=two_settings_page&two_after_activation=true'));
1704 }
1705 delete_option('redirect_after_activation_option');
1706 }
1707
1708 public static function two_deactivate_plugin()
1709 {
1710 if (isset($_POST['nonce'], $_POST['plugin_slug']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce') && current_user_can('deactivate_plugins')) { // phpcs:ignore
1711 $two_incompatible_plugins = OptimizerUtils::get_conflicting_plugins();
1712 $plugin_slug = sanitize_text_field($_POST['plugin_slug']);
1713
1714 if (array_key_exists($plugin_slug, $two_incompatible_plugins)) {
1715 deactivate_plugins($plugin_slug);
1716 }
1717 }
1718 }
1719
1720 public static function two_white_label()
1721 {
1722 if (isset($_POST['nonce'], $_POST['company_name'], $_POST['support_url']) && wp_verify_nonce($_POST['nonce'], 'two_ajax_nonce')) { // phpcs:ignore
1723 $company_name = trim(sanitize_text_field($_POST['company_name']));
1724 $support_url = trim(sanitize_url($_POST['support_url'])); // phpcs:ignore_
1725 update_option('two_so_organization_name', $company_name);
1726 update_option('two_so_organization_support_url', $support_url);
1727 }
1728 }
1729
1730 public static function set_global_mode($mode)
1731 {
1732 global $TwoSettings;
1733 $mode_list = OptimizerUtils::get_modes();
1734 $settings_names = $TwoSettings->settings_names;
1735
1736 foreach ($mode_list[$mode] as $key => $val) {
1737 if ($key === 'two_delay_all_js_execution') {
1738 if ($val) {
1739 $TwoSettings->update_setting('two_delay_all_js_execution', 'on');
1740 } else {
1741 $TwoSettings->update_setting('two_delay_all_js_execution', '');
1742 }
1743 } elseif (isset($settings_names[$key])) {
1744 $TwoSettings->update_setting($key, $val);
1745 } elseif ($key === 'critical_enabled') {
1746 if ($val) {
1747 $TwoSettings->update_setting('two_critical_status', 'true');
1748 } else {
1749 $TwoSettings->update_setting('two_critical_status', '');
1750 }
1751 }
1752 }
1753 update_option('two_default_mode', $mode_list[$mode]);
1754 }
1755
1756 private static function set_additional_settings()
1757 {
1758 global $TwoSettings;
1759
1760 if (!get_option('two_set_not_optimizable_and_turn_off_mode_settings_v2')) {
1761 // This option 'two_set_not_disabled_pages' shouldn't be deleted in uninstall
1762 $TwoSettings->update_setting('two_non_optimizable_speed_optimizer_pages', '/wp-admin/, /xmlrpc.php, wp-.*.php, \/feed(\/)*, index.php, sitemap(_index)?.xml, /store.*,/cart.*, /my-account.*, /checkout.*, /addons.*, well-known, acme-challenge');
1763
1764 $two_optimized_pages = \TenWebOptimizer\OptimizerUtils::getCriticalPages();
1765
1766 $args = [
1767 'post_type' => 'page',
1768 'meta_key' => 'two_mode',
1769 ];
1770 $optimized_posts = new WP_Query($args);
1771
1772 if (isset($optimized_posts->posts)) {
1773 foreach ($optimized_posts->posts as $post) {
1774 if (isset($post->ID) && !isset($two_optimized_pages[$post->ID])) {
1775 $two_optimized_pages[$post->ID] = [
1776 'id' => $post->ID,
1777 'url' => get_permalink($post->ID),
1778 ];
1779 }
1780 }
1781 }
1782
1783 $so_pages_list = [];
1784
1785 if (is_array($two_optimized_pages)) {
1786 foreach ($two_optimized_pages as $so_page) {
1787 if (isset($so_page['id'], $so_page['url'])) {
1788 $so_page_data = [
1789 'page_id' => $so_page['id'],
1790 'url' => $so_page['url'],
1791 ];
1792
1793 if ($so_page['id'] === 'front_page') {
1794 $page_mode = get_option('two_mode_front_page');
1795 } elseif (false !== strpos($so_page['id'], 'term_')) {
1796 $so_page['id'] = (int) ltrim($so_page['id'], 'term_');
1797 $so_page_data['page_id'] = 'term_' . (int) ltrim($so_page_data['page_id'], 'term_');
1798 $page_mode = get_term_meta($so_page['id'], 'two_mode', true);
1799 } elseif (false !== strpos($so_page['id'], 'user_')) {
1800 $so_page['id'] = (int) ltrim($so_page['id'], 'user_');
1801 $so_page_data['page_id'] = 'user_' . (int) ltrim($so_page_data['page_id'], 'user_');
1802 $page_mode = get_user_meta($so_page['id'], 'two_mode', true);
1803 } else {
1804 $so_page['id'] = (int) $so_page['id'];
1805 $so_page_data['page_id'] = (int) $so_page_data['page_id'];
1806 $page_mode = get_post_meta($so_page['id'], 'two_mode', true);
1807 }
1808
1809 if (is_array($page_mode) && isset($page_mode['mode']) && $page_mode['mode'] == 'no_optimize') {
1810 $so_pages_list[$so_page_data['page_id']] = $so_page_data['url'];
1811 }
1812 }
1813 }
1814
1815 $no_optimize_pages_list = get_option('no_optimize_pages');
1816
1817 if (is_array($no_optimize_pages_list)) {
1818 foreach ($so_pages_list as $id) {
1819 if (isset($no_optimize_pages_list[$id])) {
1820 $so_pages_list[$id] = $no_optimize_pages_list[$id];
1821 }
1822 }
1823 }
1824
1825 update_option('no_optimize_pages', $so_pages_list, false);
1826 }
1827
1828 update_option('two_set_not_optimizable_and_turn_off_mode_settings_v2', 1, false);
1829 }
1830
1831 if (!get_option('two_set_dispatch_events')) {
1832 $TwoSettings->update_setting('two_events_after_load', ['DOMContentLoaded', 'Load', 'Click']);
1833 update_option('two_set_dispatch_events', '1');
1834 }
1835
1836 if (!get_option('two_set_generate_ccss_on_load')) {
1837 if (TWO_ALWAYS_CRITICAL && !TENWEB_SO_HOSTED_ON_10WEB) {
1838 $TwoSettings->update_setting('two_generate_ccss_on_load', ['page']);
1839 } else {
1840 $TwoSettings->update_setting('two_generate_ccss_on_load', []);
1841 }
1842 update_option('two_set_generate_ccss_on_load', '1');
1843 }
1844 $set_compress_html_default = get_option('two_set_compress_html_default');
1845
1846 if ($set_compress_html_default != '1') {
1847 $TwoSettings->update_setting(
1848 'two_serve_gzip',
1849 'on'
1850 );
1851 update_option('two_set_compress_html_default', '1');
1852 }
1853 }
1854
1855 public function two_elementor_regenerate_ccss()
1856 {
1857 $two_critical_pages = OptimizerUtils::getCriticalPages();
1858
1859 if (!is_array($two_critical_pages)) {
1860 $two_critical_pages = [];
1861 }
1862 global $TwoSettings;
1863 $two_critical_status = $TwoSettings->get_settings('two_critical_status');
1864 $return_data = [
1865 'success' => false,
1866 ];
1867
1868 // phpcs:ignore
1869 if (isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'two_elementor_regenerate_ccss')
1870 && $two_critical_status) {
1871 $post_types = isset($_POST['allowed_post_types']) ? sanitize_text_field($_POST['allowed_post_types']) : '';
1872 $allowed_post_types = explode(',', $post_types);
1873 $page_id = isset($_POST['page_id']) ? sanitize_text_field($_POST['page_id']) : '';
1874
1875 if (in_array(get_post_type($page_id), $allowed_post_types)) {
1876 if (get_option('page_on_front') == $page_id) {
1877 $page_id = 'front_page';
1878 }
1879
1880 foreach ($two_critical_pages as $critical_page) {
1881 if (isset($critical_page['id']) && $critical_page['id'] == $page_id) {
1882 OptimizerCriticalCss::generate_critical_css_by_id($page_id, false, 'auto_from_elementor_page_edit');
1883 $return_data = [
1884 'success' => true,
1885 ];
1886 }
1887 }
1888 }
1889 }
1890 // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
1891 echo json_encode($return_data);
1892 die;
1893 }
1894
1895 // get and set flow_id and notif_id for starting optimization flow
1896 public static function setFlowIdNotificationId()
1897 {
1898 $nonce = isset($_POST['nonce']) ? sanitize_text_field($_POST['nonce']) : '';
1899
1900 if (!wp_verify_nonce($nonce, 'two_ajax_nonce') || !OptimizerUtils::check_admin_capabilities()) {
1901 die('Permission Denied.');
1902 }
1903 $domain_id = (int) get_option(TENWEBIO_MANAGER_PREFIX . '_domain_id', 0);
1904
1905 if ($domain_id) {
1906 $access_token = get_site_option(TENWEB_PREFIX . '_access_token');
1907 $response = wp_remote_post(TENWEB_API_URL . '/domains/' . $domain_id . '/products/run-booster-flow', [
1908 'method' => 'POST',
1909 'timeout' => 1500, // phpcs:ignore
1910 'headers' => [
1911 'Authorization' => 'Bearer ' . $access_token,
1912 'Accept' => 'application/x.10webmanager.v1+json'
1913 ],
1914 ]);
1915
1916 if (!is_wp_error($response) && isset($response['body'], $response['response']['code']) && $response['response']['code'] === 200) {
1917 $response_body = json_decode($response['body'], true);
1918
1919 if ($response_body['data'] && $response_body['status'] == 'ok') {
1920 if (isset($response_body['data']['flow_id'])) {
1921 update_site_option(TENWEB_PREFIX . '_flow_id', $response_body['data']['flow_id']);
1922 }
1923
1924 if (isset($response_body['data']['notification_id'])) {
1925 update_site_option(TENWEB_PREFIX . '_notification_id', $response_body['data']['notification_id']);
1926 }
1927 }
1928 } else {
1929 //just for easy check if something went wrong
1930 update_option('two_connection_after_io', [$response], false);
1931 }
1932 }
1933 self::startTheFlow();
1934 }
1935
1936 public static function startTheFlow()
1937 {
1938 $class_login = \Tenweb_Authorization\Login::get_instance();
1939
1940 if ($class_login->check_logged_in()) {
1941 OptimizerUtils::add_log_for_score_check_flow('connect_to_tenweb', 'start init_flow_score_check=>true');
1942 OptimizerUtils::init_flow_score_check(true);
1943 $two_first_connect = get_option('two_first_connect', false);
1944 $date = time();
1945
1946 if (!$two_first_connect) {
1947 //this option also used to check booster real connection when IO is connected
1948 update_option('two_first_connect', $date);
1949 }
1950 delete_option('two_triggerPostOptimizationTasks');
1951 delete_option('incompatible_plugins_active_send');
1952 global $TwoSettings;
1953
1954 \Tenweb_Authorization\Helper::remove_error_logs();
1955
1956 $TwoSettings->update_setting('two_connected', '1');
1957 $TwoSettings->sync_configs_with_plugin_state();
1958 /*set test mode and set global mode extreme*/
1959 self::set_global_mode('extreme');
1960 /*-----------------------------*/
1961 delete_option('two_flow_critical_start');
1962 self::generateCriticalCssOnInit(true);
1963 $domain_id = get_site_option(TENWEB_PREFIX . '_domain_id');
1964 $url = TENWEB_DASHBOARD . '/websites?optimizing_website=' . $domain_id . '&from_plugin=' . OptimizerUtils::FROM_PLUGIN . '&two_only_optimize=1';
1965 $sign_up_from_free_plugin = !empty($_GET['sign_up_from_free_plugin']) ? rest_sanitize_boolean($_GET['sign_up_from_free_plugin']) : null; //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1966
1967 if (!empty($sign_up_from_free_plugin)) {
1968 $url .= '&from_free_plugin=1';
1969 }
1970 wp_send_json_success($url);
1971 }
1972 }
1973 }
1974