PluginProbe
LWS Optimize – All-in-One Speed Booster & Cache Tools / 1.8
LWS Optimize – All-in-One Speed Booster & Cache Tools v1.8
4.1.4 4.1.3 4.1.2 4.1.1 4.1 4.0 3.4.1 3.4 3.3.21 trunk 1.0 1.1 1.2 1.5 1.6 1.6.5 1.7 1.8 1.8.5 1.8.6 1.9 1.9.1 2.0 2.1 2.1.1 All 97 releases
lws-optimize / lws-optimize.php

lws-optimize.php in LWS Optimize – All-in-One Speed Booster & Cache Tools 1.8, at lws-optimize.php

2,158 lines 89.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Plugin Name: LWS Optimize
5 * Plugin URI: https://www.lws.fr/
6 * Description: Reach better speed and performances with Optimize! Minification, Combination, Media conversion... Everything you need for a better website
7 * Version: 1.8
8 * Author: LWS
9 * Author URI: https://www.lws.fr
10 * Tested up to: 6.2
11 * Domain Path: /languages
12 *
13 * @link https://sms.lws.fr/
14 * @since 1.0
15 * @package lws-optimize
16 */
17
18 if (!defined('ABSPATH')) {
19 exit; //Exit if accessed directly
20 }
21 global $wp_query;
22
23
24 /**
25 * Load translations, constants, hooks...
26 */
27 add_action('init', 'lws_op_loading');
28 function lws_op_loading()
29 {
30 include_once 'classes/CssCombiner.php';
31 include_once 'classes/JsCombiner.php';
32 //require_once(plugin_dir_path(__FILE__) . '/vendor/woocommerce/action-scheduler/action-scheduler.php');
33
34 define('LWS_OP_URL', plugin_dir_url(__FILE__));
35 define('LWS_OP_DIR', plugin_dir_path(__FILE__));
36
37 define('LWS_OP_UPLOADS', wp_upload_dir()['basedir'] . '/lws-optimize/');
38 load_plugin_textdomain('lws-optimize', false, dirname(plugin_basename(__FILE__)) . '/languages');
39 }
40
41 function lws_op_cron_schedule($schedules)
42 {
43 $schedules[ 'threeminutes' ] = array( 'interval' => 3 * MINUTE_IN_SECONDS, 'display' => __('3 minutes') );
44 return $schedules;
45 }
46 add_filter('cron_schedules', 'lws_op_cron_schedule');
47
48 /**
49 * Create, if not already existing, a directory for the file-based cache
50 */
51 register_activation_hook(__FILE__, 'lws_op_on_activation');
52 function lws_op_on_activation()
53 {
54 set_transient('lwsop_remind_me', 691200);
55 if (!file_exists(wp_upload_dir()['basedir'] . '/lws_optimize')) {
56 @mkdir(wp_upload_dir()['basedir'] . '/lws-optimize', 0755);
57 }
58 }
59
60 /**
61 * Remove the created directory on delete
62 */
63 register_uninstall_hook(__FILE__, 'lws_op_on_delete');
64 function lws_op_on_delete()
65 {
66 $options = array(
67 'lws_op_exclude_min_css', 'lws_op_exclude_combine_css',
68 'lws_op_exclude_min_js', 'lws_op_exclude_combine_js', 'lws_op_exclude_defer_js',
69 'lws_op_exclude_min_html', 'lws_op_min_css', 'lws_op_combine_css', 'lws_op_preload_css',
70 'lws_op_min_js', 'lws_op_combine_js', 'lws_op_defer_js',
71 'lws_op_min_html', 'lws_op_delete_emoji', 'lws_op_remove_query',
72 'lws_opti_memcaching_on',
73 'lws_op_fb_cache',
74 'lws_op_force_no_lazyload_video',
75 'lws_op_force_lazyload_video',
76 'lws_op_deactivate_lazyload_iframe',
77 'lws_op_deactivate_lazyload_image',
78 'lws_op_exclude_min_css_array',
79 'lws_op_exclude_combine_css_array',
80 'lws_op_exclude_min_js_array',
81 'lws_op_exclude_combine_js_array',
82 'lws_op_exclude_defer_js_array',
83 'lws_op_exclude_min_html_array',
84 'lws_op_autoconvert_compression',
85 'lws_op_autoconvert_webp',
86 'lws_op_deactivate_lazyload',
87 'lws_op_change_max_width_media',
88 );
89
90 foreach ($options as $option){
91 delete_option($option);
92 }
93 rmdir(wp_upload_dir()['basedir'] . '/lws-optimize');
94 }
95
96 register_deactivation_hook(__FILE__, 'lws_op_on_deactivate');
97 function lws_op_on_deactivate()
98 {
99 rmdir(wp_upload_dir()['basedir'] . '/lws-optimize');
100 }
101
102 /**
103 * Enqueue any CSS or JS script needed
104 */
105 add_action('admin_enqueue_scripts', 'lws_op_scripts');
106 function lws_op_scripts()
107 {
108 if (get_current_screen()->base == ('toplevel_page_lws-op-config')) {
109 wp_enqueue_style('lws_op_css', LWS_OP_URL . "css/lws_op_stylesheet.css");
110 wp_enqueue_style('lws_cl-Poppins', 'https://fonts.googleapis.com/css?family=Poppins');
111 }
112 else{
113 wp_enqueue_style('lws_top_css_out', LWS_OP_URL . "css/lws_op_stylesheet_out.css");
114 if (!get_transient('lwsop_remind_me') && !get_option('lwsop_do_not_ask_again') && !get_option('lws_op_deactivated')){
115 add_action( 'admin_notices', 'lwsop_review_ad_plugin' );
116 }
117 }
118 }
119
120 function lwsop_review_ad_plugin(){
121 ?>
122 <script>
123 function lwsop_remind_me(){
124 var data = {
125 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('reminder_for_op')); ?>',
126 action: "lws_op_reminder_ajax",
127 data: true,
128 };
129 jQuery.post(ajaxurl, data, function(response){
130 jQuery("#lwsop_review_notice").addClass("animationFadeOut");
131 setTimeout(() => {
132 jQuery("#lwsop_review_notice").addClass("lws_hidden");
133 }, 800);
134 });
135
136 }
137
138 function lwsop_do_not_bother_me(){
139 var data = {
140 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('donotask_for_op')); ?>',
141 action: "lws_op_donotask_ajax",
142 data: true,
143 };
144 jQuery.post(ajaxurl, data, function(response){
145 jQuery("#lwsop_review_notice").addClass("animationFadeOut");
146 setTimeout(() => {
147 jQuery("#lwsop_review_notice").addClass("lws_hidden");
148 }, 800);
149 });
150 }
151 </script>
152
153 <div class="notice notice-info is-dismissible lwsop_review_block_general" id="lwsop_review_notice">
154 <div class="lwsop_circle">
155 <img class="lwsop_review_block_image" src="<?php echo esc_url(plugins_url('images/plugin_lws-optimize.svg', __FILE__))?>" width="40px" height="40px">
156 </div>
157 <div style="padding:16px">
158 <h1 class="lwsop_review_block_title"> <?php esc_html_e('Thank you for using LWS Optimize!', 'lws-optimize'); ?></h1>
159 <p class="lwsop_review_block_desc"><?php _e('Evaluate our plugin to help others optimize and boost the performances of their WordPress website!', 'lws-optimize' ); ?></p>
160 <a class="lwsop_button_rate_plugin" href="https://wordpress.org/support/plugin/lws-optimize/reviews/" target="_blank" ><img style="margin-right: 8px;" src="<?php echo esc_url(plugins_url('images/noter.svg', __FILE__))?>" width="15px" height="15px"><?php esc_html_e('Rate', 'lws-optimize'); ?></a>
161 <a class="lwsop_review_button_secondary" onclick="lwsop_remind_me()"><?php esc_html_e('Remind me later', 'lws-optimize'); ?></a>
162 <a class="lwsop_review_button_secondary" onclick="lwsop_do_not_bother_me()"><?php esc_html_e('Do not ask again', 'lws-optimize'); ?></a>
163 </div>
164 </div>
165 <?php
166 }
167
168 //AJAX Reminder//
169 add_action("wp_ajax_lws_op_reminder_ajax", "lws_op_remind_me_later");
170 function lws_op_remind_me_later(){
171 check_ajax_referer('reminder_for_op', '_ajax_nonce');
172 if (isset($_POST['data'])){
173 set_transient('lwsop_remind_me', 2592000);
174 }
175 }
176
177 //AJAX Reminder//
178 add_action("wp_ajax_lws_op_donotask_ajax", "lws_op_do_not_ask");
179 function lws_op_do_not_ask(){
180 check_ajax_referer('donotask_for_op', '_ajax_nonce');
181 if (isset($_POST['data'])){
182 update_option('lwsop_do_not_ask_again', true);
183 }
184 }
185
186
187
188
189 /**
190 * Create plugin menu in wp-admin
191 */
192 add_action('admin_menu', 'lws_op_menu_admin');
193 function lws_op_menu_admin()
194 {
195 $menu_slug = 'lws-op-config';
196 add_menu_page(__('LWS Optimize', 'lws-optimize'), 'LWS Optimize', 'manage_options', $menu_slug, 'lws_op_page', LWS_OP_URL . 'images/plugin_lws_optimize.svg');
197 }
198
199
200 // ALL FUNCTIONS DEDICATED TO THE FRONTEND TAB ###
201 //
202 //
203 /**
204 * Minimize HTML to reduce size and improve performances
205 */
206
207 if (get_option('lws_op_min_html')) {
208 add_action('wp_head', 'lws_op_minimize_html');
209 function lws_op_minimize_html()
210 {
211 global $wp;
212 $url = home_url($wp->request);
213 if ($exclude_html = json_decode(get_option('lws_op_exclude_min_html_array'), true)) {
214 if (!in_array($url, $exclude_html)) {
215 ob_start("flhm_wp_html_compression_finish");
216 }
217 } else {
218 ob_start("flhm_wp_html_compression_finish");
219 }
220 }
221 }
222
223
224 function lws_op_check_compatibility(){
225 // If another plugin in the same vein as WP Rocket is installed, deactivate the plugin
226 if (is_plugin_active('wp-rocket/wp-rocket.php') || is_plugin_active('powered-cache/powered-cache.php') || is_plugin_active('wp-super-cache/wp-cache.php')
227 || is_plugin_active('wp-optimize/wp-optimize.php') || is_plugin_active('wp-fastest-cache/wpFastestCache.php') || is_plugin_active('w3-total-cache/w3-total-cache.php')){
228 update_option('lws_op_deactivated', true);
229 add_action( 'admin_notices', 'lws_op_other_cache_plugin' );
230 } else{
231 if (get_option('lws_op_deactivated') !== "blocked"){
232 delete_option('lws_op_deactivated', true);
233 }
234 }
235 }
236 add_action( 'admin_init', 'lws_op_check_compatibility' );
237
238 function lws_op_other_cache_plugin() {
239 ?>
240 <div class="notice notice-warning is-dismissible" style="padding-bottom: 10px;">
241 <p><?php _e( 'You already have another cache plugin installed on your website. LWS-Optimize will be inactive as long as those below are not deactivated to prevent incompatibilities: ', 'lws-optimize' ); ?></p>
242 <?php if (is_plugin_active('wp-rocket/wp-rocket.php')) : ?>
243 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">WPRocket <a class="wp-core-ui button" id="lwsop_deactivate_button_wprocket" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
244 <?php endif ?>
245 <?php if (is_plugin_active('powered-cache/powered-cache.php')) : ?>
246 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">PoweredCache <a class="wp-core-ui button" id="lwsop_deactivate_button_pc" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
247 <?php endif ?>
248 <?php if (is_plugin_active('wp-super-cache/wp-cache.php')) : ?>
249 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">WP Super Cache <a class="wp-core-ui button" id="lwsop_deactivate_button_wpsc" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
250 <?php endif ?>
251 <?php if (is_plugin_active('wp-optimize/wp-optimize.php')) : ?>
252 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">WP-Optimize <a class="wp-core-ui button" id="lwsop_deactivate_button_wpo" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
253 <?php endif ?>
254 <?php if (is_plugin_active('wp-fastest-cache/wpFastestCache.php')) : ?>
255 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">WP Fastest Cache <a class="wp-core-ui button" id="lwsop_deactivate_button_wpfc" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
256 <?php endif ?>
257 <?php if (is_plugin_active('w3-total-cache/w3-total-cache.php')) : ?>
258 <div style="display: flex; align-items: center; gap: 8px; line-height: 35px;">W3 Total Cache <a class="wp-core-ui button" id="lwsop_deactivate_button_wp3" style="display: flex; align-items: center; width: fit-content;"><?php _e('Deactivate', 'lws-optimize'); ?></a></div>
259 <?php endif ?>
260 </div>
261
262 <script>
263 document.querySelectorAll('a[id^="lwsop_deactivate_button_"]').forEach(function(element){
264 element.addEventListener('click', function(event){
265 let id = (element.id).replace('lwsop_deactivate_button_', '');
266 this.parentNode.parentNode.style.pointerEvents = "none";
267 this.innerHTML = `
268 <img src="<?php echo plugin_dir_url(__FILE__); ?>/images/loading_black.svg" width="20px">
269 `;
270 var data = {
271 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('deactivate_plugin_lwsoptimize')); ?>',
272 action: "lws_op_other_cache_plugin_ajax",
273 data: {id: id},
274 };
275 jQuery.post(ajaxurl, data, function(response){
276 location.reload();
277 });
278 })
279 });
280 </script>
281 <?php
282 }
283
284 function lws_op_page()
285 {
286 global $wp_styles, $wp_scripts, $wpdb;
287 $frontend_opti_css = array();
288 $frontend_opti_js = array();
289 $frontend_opti_html = array();
290 $tabs_list = array(
291 array('frontend', __('Frontend', 'lws-optimize')),
292 array('medias', __('Medias', 'lws-optimize')),
293 array('caching', __('Caching', 'lws-optimize')),
294 array('plugins', __('Our others plugins', 'lws-optimize')),
295 );
296
297 //FRONTEND//
298
299 if (isset($_POST['lws_op_frontend'])) :
300 $all_options_excluded = array(
301 'lws_op_exclude_min_css', 'lws_op_exclude_combine_css',
302 'lws_op_exclude_min_js', 'lws_op_exclude_combine_js', 'lws_op_exclude_defer_js',
303 'lws_op_exclude_min_html',
304 );
305
306 $all_options = array(
307 'lws_op_min_css', 'lws_op_combine_css', 'lws_op_preload_css',
308 'lws_op_min_js', 'lws_op_combine_js', 'lws_op_defer_js',
309 'lws_op_min_html', 'lws_op_delete_emoji', 'lws_op_remove_query',
310 );
311
312 foreach ($all_options as $option) {
313 isset($_POST[$option]) ? update_option($option, true) : delete_option($option);
314 }
315
316 foreach ($all_options_excluded as $option) {
317 if (isset($_POST[$option])) {
318 $data = sanitize_textarea_field($_POST[$option]);
319 $data = trim($data);
320 $data = str_replace(' ', '', $data);
321
322 if (!empty($data)) {
323 $list_data = explode(',', $data);
324 if ($option == 'lws_op_exclude_min_html') {
325 foreach ($list_data as $key => $element) {
326 $list_data[$key] = str_replace(get_site_url() . '/', ABSPATH, $element);
327 }
328 } else {
329 foreach ($list_data as $key => $element) {
330 $list_data[$key] = ABSPATH . $element;
331 }
332 }
333 update_option($option . '_array', json_encode($list_data, JSON_PRETTY_PRINT));
334 update_option($option, $data);
335 } else {
336 delete_option($option . '_array');
337 delete_option($option);
338 }
339 } else {
340 delete_option($option . '_array');
341 delete_option($option);
342 }
343 }
344 endif;
345
346
347 //CSS//
348
349 $list_css = array();
350 foreach ($wp_styles->queue as $handle) {
351 $element = $wp_styles->registered[$handle]->src;
352 if (!stripos($element, '.min.css') && !empty($element) && is_string($element)) {
353 $list_css[] = $element;
354 }
355 }
356
357 $exclude_min_css_tab = get_option('lws_op_exclude_min_css') ? json_decode(get_option('lws_op_exclude_min_css'), true) : array();
358 $exclude_combine_css_tab = get_option('lws_op_exclude_combine_css') ? json_decode(get_option('lws_op_exclude_combine_css'), true) : array();
359
360 $frontend_opti_css = array(
361 'min_css' =>
362 array(
363 __('Minify your CSS files', 'lws-optimize'),
364 __('Minify your CSS files to gain performances by reducing their size', 'lws-optimize'),
365 ),
366 'exclude_min_css' => __('Choose which files to exclude when minifying CSS files', 'lws-optimize'),
367 'combine_css' =>
368 array(
369 __('Combine CSS files', 'lws-optimize'),
370 __('Combine CSS files together to reduce HTML queries and gain in performances', 'lws-optimize'),
371 ),
372 'exclude_combine_css' => __('Choose which files to ignore when combining CSS files', 'lws-optimize'),
373 'preload_css' =>
374 array(
375 __('Preload CSS files', 'lws-optimize'),
376 __('Preload CSS files for a faster loading time', 'lws-optimize'),
377 ),
378 );
379
380
381 //JS//
382
383 $list_js = array();
384 foreach ($wp_scripts->queue as $handle) {
385 $element = $wp_scripts->registered[$handle]->src;
386 if (!stripos($element, '.min.js') && !empty($element) && is_string($element)) {
387 $list_js[] = $element;
388 }
389 }
390
391 $frontend_opti_js = array(
392 'min_js' =>
393 array(
394 __('Minify your JS files', 'lws-optimize'),
395 __('Minify your JS files to gain performances and reduce their size', 'lws-optimize'),
396 ),
397 'exclude_min_js' => __('Choose which files to exclude when minifying JS files', 'lws-optimize'),
398 'combine_js' =>
399 array(
400 __('Combine JS files', 'lws-optimize'),
401 __('Combine JS files to reduce the amount of HTML queries and gain better performances', 'lws-optimize'),
402 ),
403 'exclude_combine_js' => __('Choose which files to ignore when combining JS files', 'lws-optimize'),
404 'defer_js' =>
405 array(
406 __('Defer loading of JavaScript files', 'lws-optimize'),
407 __('Defer loading of JavaScript files for faster loading times', 'lws-optimize'),
408 ),
409 'exclude_defer_js' => __('Choose which files to ignore when defering JS files', 'lws-optimize'),
410 );
411
412 //GENERAL HTML//
413
414
415 $frontend_opti_html = array(
416 'min_html' =>
417 array(
418 __('Minify your HTML files', 'lws-optimize'),
419 __('Minify your HTML files to gain performances and reduce their size', 'lws-optimize'),
420 ),
421 'exclude_min_html' => __('Choose which files to exclude when minifying HTML files', 'lws-optimize'),
422 'delete_emoji' =>
423 array(
424 __('Remove Wordpress emoji support from your site', 'lws-optimize'),
425 __('Remove Wordpress emoji loading to speed up the loading of your website', 'lws-optimize'),
426 ),
427 'remove_query' =>
428 array(
429 __('Remove useless queries', 'lws-optimize'),
430 __('Remove useless queries from static files (CSS, JS...), especially "?ver" queries', 'lws-optimize'),
431 ),
432 );
433
434
435 //MEDIA
436
437 $media_to_webp = array(
438 'autoconvert_compression' =>
439 array(
440 __('Compressing all images', 'lws-optimize'),
441 __('Compress all images without quality loss to reduce sizes.', 'lws-optimize'),
442 array(
443 __('Compress', 'lws-optimize'),
444 __('Compressed', 'lws-optimize'),
445 __('Uncompress', 'lws-optimize'),
446 __('Uncompressed', 'lws-optimize'),
447 ),
448 true, //Recommanded
449 ),
450 'autoconvert_webp' =>
451 array(
452 __('Converting all images to the WEBP extension', 'lws-optimize'),
453 __('Convert all images to the lightweight WEBP extension to get better loading times. Depending on the amount of files to convert, it may take a while. Restoring the files will re-convert those. You can leave the page will the action in ongoing.', 'lws-optimize'),
454 array(
455 __('Convert', 'lws-optimize'),
456 __('Converted', 'lws-optimize'),
457 __('Unconvert', 'lws-optimize'),
458 __('Unconverted', 'lws-optimize'),
459 ),
460 true, //Recommanded
461 ),
462 'change_max_width_media' =>
463 array(
464 __('Reducing the maximum width of an image', 'lws-optimize'),
465 __('Reduce the maximum width of an image on this website. By default at 2560px, you may want to reduce it, allowing for smaller files, or rise it as you wish.', 'lws-optimize'),
466 array(
467 __('Modify', 'lws-optimize'),
468 __('Modified', 'lws-optimize'),
469 __('Modify', 'lws-optimize'),
470 __('Modified', 'lws-optimize'),
471 ),
472 false
473 ),
474 'deactivate_lazyload_iframe' =>
475 array(
476 __('Lazy loading for all iframe elements', 'lws-optimize'),
477 false, //No subtext
478 array(
479 __('Deactivate lazy loading', 'lws-optimize'),
480 __('Deactivated', 'lws-optimize'),
481 __('Activate lazy loading', 'lws-optimize'),
482 __('Activated', 'lws-optimize'),
483
484 ),
485 false,
486 ),
487 'deactivate_lazyload_image' =>
488 array(
489 __('Lazy loading for all image elements', 'lws-optimize'),
490 false,
491 array(
492 __('Deactivate lazy loading', 'lws-optimize'),
493 __('Deactivated', 'lws-optimize'),
494 __('Activate lazy loading', 'lws-optimize'),
495 __('Activated', 'lws-optimize'),
496
497 ),
498 false,
499 ),
500 'deactivate_lazyload' =>
501 array(
502 __('Lazy loading on the website', 'lws-optimize'),
503 false,
504 array(
505 __('Deactivate lazy loading', 'lws-optimize'),
506 __('Deactivated', 'lws-optimize'),
507 __('Activate lazy loading', 'lws-optimize'),
508 __('Activated', 'lws-optimize'),
509 ),
510 false,
511 ),
512 'force_lazyload_video' =>
513 array(
514 __('Forcing preloading of all video and audio elements', 'lws-optimize'),
515 false,
516 array(
517 __('Force preloading', 'lws-optimize'),
518 __('Forced', 'lws-optimize'),
519 __('Unforce preloading', 'lws-optimize'),
520 __('Unforced', 'lws-optimize'),
521 ),
522 false,
523 ),
524 'force_no_lazyload_video' =>
525 array(
526 __('Forcing no preloading of all video and audio elements', 'lws-optimize'),
527 false,
528 array(
529 __('Force the deactivation', 'lws-optimize'),
530 __('Forced', 'lws-optimize'),
531 __('Unforce the deactivation', 'lws-optimize'),
532 __('Unforced', 'lws-optimize'),
533 ),
534 false,
535 ),
536 );
537
538 get_option('lws_op_change_max_width_media') ? '' : update_option('lws_op_change_max_width_media', '2560');
539
540 $list_width = array(
541 '7680' => '7680px',
542 '3840' => '3840px',
543 '2560' => '2560px',
544 '1920' => '1920px',
545 '1080' => '1080px',
546 'disabled' => __('Disabled', 'lws-optimize'),
547 );
548
549 function dir_is_empty($dir)
550 {
551 $handle = opendir($dir);
552 while (false !== ($entry = readdir($handle))) {
553 if ($entry != "." && $entry != "..") {
554 closedir($handle);
555 return false;
556 }
557 }
558 closedir($handle);
559 return true;
560 }
561
562 $is_cache_empty = dir_is_empty(wp_upload_dir()['basedir'] . "/lws-optimize/");
563
564 include __DIR__ . '/views/tabs.php';
565 }
566
567 /**
568 * Either minimize, combine or minimize and combine every CSS or JS files into one for reduced download size and better loading speed
569 */
570 if (get_option('lws_op_min_css') || get_option('lws_op_combine_css') || get_option('lws_op_min_js') || get_option('lws_op_combine_js') && !get_option('lws_op_deactivated')) {
571 add_action('wp_enqueue_scripts', 'lws_op_print_scripts', 99999);
572 function lws_op_print_scripts()
573 {
574 include_once __DIR__ . '/vendor/autoload.php';
575 global $wp_scripts, $wp_styles;
576 $result = array('scripts' => array(), 'styles' => array());
577 $timestamp = time();
578
579 if (get_option('lws_op_min_css') && get_option('lws_op_combine_css')) {
580 $wp_styles->all_deps($wp_styles->queue);
581 foreach ($wp_styles->to_do as $style) {
582 $result['styles'][$style] = $wp_styles->registered[$style]->src;
583 }
584 $exclude_min_css_tab = get_option('lws_op_exclude_min_css_array') ? json_decode(get_option('lws_op_exclude_min_css_array'), true) : array();
585 $exclude_combine_css_tab = get_option('lws_op_exclude_combine_css_array') ? json_decode(get_option('lws_op_exclude_combine_css_array'), true) : array();
586 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-styles.min.css';
587 $forced_excluded_combined_css = array();
588 $http = is_ssl() ? 'https:' : 'http:';
589 if (file_exists($merged_file_location) && time() - filemtime($merged_file_location) < 129600) {
590 foreach ($result['styles'] as $handle => $style) {
591 if (!empty($style)) {
592 //Check if smth like //domain.com
593 if (!str_contains($style, $http) && str_contains($style, str_replace($http, '', get_site_url()))) {
594 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $style);
595 }
596 //Check if smth like /wp-includes/.../ + not https://fonts.google...
597 elseif (!str_contains($style, get_site_url()) && !stripos($style, 'fonts.')) {
598 $file = ABSPATH . $style;
599 }
600
601 //Check if smth like https://domain.com
602 elseif (str_contains($style, get_site_url())) {
603 $file = str_replace(get_site_url() . '/', ABSPATH, $style);
604 }
605
606 if (str_contains($file, "./")) {
607 $file = str_replace("./", '', $file);
608 }
609
610 if (str_contains($file, "//")) {
611 $file = str_replace("//", "/", $file);
612 }
613
614 if (file_exists($file) && !in_array($file, $exclude_combine_css_tab) && !in_array($file, $exclude_min_css_tab)) {
615 if (filemtime($merged_file_location) == filemtime($file)) {
616 wp_deregister_style($handle);
617 } else {
618 unlink($merged_file_location);
619 break;
620 }
621 }
622 }
623 }
624 }
625
626 if (!file_exists($merged_file_location)) {
627 $merged_styles = '';
628 $minifierCSS = new \MatthiasMullie\Minify\CSS();
629
630 foreach ($result['styles'] as $handle => $style) {
631 if (!empty($style) && !in_array($handle, $forced_excluded_combined_css)) {
632 if (!str_contains($style, $http) && str_contains($style, str_replace($http, '', get_site_url()))) {
633 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $style);
634 }
635 //Check if smth like /wp-includes/.../ + not https://fonts.google...
636 elseif (!str_contains($style, get_site_url()) && !stripos($style, 'fonts.')) {
637 $file = ABSPATH . $style;
638 }
639
640 //Check if smth like https://domain.com
641 elseif (str_contains($style, get_site_url())) {
642 $file = str_replace(get_site_url() . '/', ABSPATH, $style);
643 }
644
645 if (str_contains($file, "./")) {
646 $file = str_replace("./", '', $file);
647 }
648
649 if (str_contains($file, "//")) {
650 $file = str_replace("//", "/", $file);
651 }
652
653 if (file_exists($file) && !in_array($file, $exclude_combine_css_tab) && !in_array($file, $exclude_min_css_tab)) {
654 $minifierCSS->add($file);
655 touch($file, $timestamp);
656 }
657
658 wp_deregister_style($handle);
659 }
660 }
661 $minifierCSS->minify($merged_file_location);
662 touch($merged_file_location, $timestamp);
663 }
664 wp_enqueue_style('merged-styles-min', get_stylesheet_directory_uri() . '/merged-styles.min.css');
665 } else {
666 if (get_option('lws_op_min_css')) {
667 $wp_styles->all_deps($wp_styles->queue);
668 foreach ($wp_styles->to_do as $style) {
669 $result['styles'][$style] = $wp_styles->registered[$style]->src;
670 }
671 $exclude_min_css_tab = get_option('lws_op_exclude_min_css_array') ? json_decode(get_option('lws_op_exclude_min_css_array'), true) : array();
672 $http = is_ssl() ? 'https:' : 'http:';
673 foreach ($result['styles'] as $handle => $style) {
674 if (!stripos($style, '.min.css') && !empty($style)) {
675 //Check if smth like //domain.com
676 if (!str_contains($style, $http) && str_contains($style, str_replace($http, '', get_site_url()))) {
677 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $style);
678 }
679 //Check if smth like /wp-includes/.../ + not https://fonts.google...
680 elseif (!str_contains($style, get_site_url()) && !stripos($style, 'fonts.')) {
681 $file = ABSPATH . $style;
682 }
683
684 //Check if smth like https://domain.com
685 elseif (str_contains($style, get_site_url())) {
686 $file = str_replace(get_site_url() . '/', ABSPATH, $style);
687 }
688
689 if (str_contains($file, "./")) {
690 $file = str_replace("./", '', $file);
691 }
692
693 if (str_contains($file, "//")) {
694 $file = str_replace("//", "/", $file);
695 }
696
697 $file_min = str_replace('.css', '.min.css', $file);
698
699 if (file_exists($file_min) && !in_array($file, $exclude_min_css_tab) && (filemtime($file_min) == filemtime($file))) {
700 $wp_styles->registered[$handle]->src = str_replace('.css', '.min.css', $style);
701 } else {
702 if (!in_array($file, $exclude_min_css_tab)) {
703 $minifierCSS = new \MatthiasMullie\Minify\CSS($file);
704 $minifierCSS->minify($file_min);
705 touch($file, $timestamp);
706 touch($file_min, $timestamp);
707 $wp_styles->registered[$handle]->src = str_replace('.css', '.min.css', $style);
708 }
709 }
710 }
711 }
712 }
713
714 if (get_option('lws_op_combine_css')) {
715 $wp_styles->all_deps($wp_styles->queue);
716 foreach ($wp_styles->to_do as $style) {
717 $result['styles'][$style] = $wp_styles->registered[$style]->src;
718 }
719 $exclude_combine_css_tab = get_option('lws_op_exclude_combine_css_array') ? json_decode(get_option('lws_op_exclude_combine_css_array'), true) : array();
720 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-styles.css';
721 $forced_excluded_combined_css = array();
722 $http = is_ssl() ? 'https:' : 'http:';
723 if (file_exists($merged_file_location) && time() - filemtime($merged_file_location) < 129600) {
724 foreach ($result['styles'] as $handle => $style) {
725 if (!empty($style)) {
726 //Check if smth like //domain.com
727 if (!str_contains($style, $http) && str_contains($style, str_replace($http, '', get_site_url()))) {
728 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $style);
729 }
730 //Check if smth like /wp-includes/.../ + not https://fonts.google...
731 elseif (!str_contains($style, get_site_url()) && !stripos($style, 'fonts.')) {
732 $file = ABSPATH . $style;
733 }
734
735 //Check if smth like https://domain.com
736 elseif (str_contains($style, get_site_url())) {
737 $file = str_replace(get_site_url() . '/', ABSPATH, $style);
738 }
739
740 if (str_contains($file, "./")) {
741 $file = str_replace("./", '', $file);
742 }
743
744 if (str_contains($file, "//")) {
745 $file = str_replace("//", "/", $file);
746 }
747
748 if (!in_array($handle, $forced_excluded_combined_css) && !in_array($file, $exclude_combine_css_tab)) {
749 if (filemtime($merged_file_location) == filemtime($file)) {
750 wp_deregister_style($handle);
751 } else {
752 unlink($merged_file_location);
753 break;
754 }
755 }
756 }
757 }
758 }
759
760 if (!file_exists($merged_file_location)) {
761 $merged_styles = '';
762
763 foreach ($result['styles'] as $handle => $style) {
764 if (!empty($style) && !in_array($handle, $forced_excluded_combined_css)) {
765 if (!str_contains($style, $http) && str_contains($style, str_replace($http, '', get_site_url()))) {
766 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $style);
767 }
768 //Check if smth like /wp-includes/.../ + not https://fonts.google...
769 elseif (!str_contains($style, get_site_url()) && !stripos($style, 'fonts.')) {
770 $file = ABSPATH . $style;
771 }
772
773 //Check if smth like https://domain.com
774 elseif (str_contains($style, get_site_url())) {
775 $file = str_replace(get_site_url() . '/', ABSPATH, $style);
776 }
777
778 if (str_contains($file, "./")) {
779 $file = str_replace("./", '', $file);
780 }
781
782 if (file_exists($file) && !in_array($file, $exclude_combine_css_tab)) {
783 $localize = '';
784
785 if (is_array($wp_styles->registered[$handle]->extra) && @key_exists('data', $wp_styles->registered[$handle]->extra)) {
786 $localize = $wp_styles->registered[$handle]->extra['data'] . ';';
787 }
788
789 $tmp = file_get_contents($file);
790 $path = explode('/', $file);
791 array_pop($path);
792 $path = implode('/', $path);
793 $path = str_replace(ABSPATH, get_site_url() . '/', $path);
794
795 $tmp = str_replace("url(../", "url(" . $path . "/../", $tmp);
796 $tmp = str_replace("url('../", "url('" . $path . "/../", $tmp);
797 $tmp = str_replace('url("../', 'url("' . $path . "/../", $tmp);
798 $merged_styles .= $localize . $tmp;
799 touch($file, $timestamp);
800 wp_deregister_style($handle);
801 }
802 }
803 }
804 file_put_contents($merged_file_location, $merged_styles);
805 touch($merged_file_location, $timestamp);
806 }
807 wp_enqueue_style('merged-styles', get_stylesheet_directory_uri() . '/merged-styles.css');
808 }
809 }
810
811 if (get_option('lws_op_min_js') && get_option('lws_op_combine_js')) {
812 $wp_scripts->all_deps($wp_scripts->queue);
813 foreach ($wp_scripts->to_do as $script) {
814 $result['scripts'][$script] = $wp_scripts->registered[$script]->src;
815 }
816 $exclude_min_js_tab = get_option('lws_op_exclude_min_js_array') ? json_decode(get_option('lws_op_exclude_min_js_array'), true) : array();
817 $exclude_combine_js_tab = get_option('lws_op_exclude_combine_js_array') ? json_decode(get_option('lws_op_exclude_combine_js_array'), true) : array();
818 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-scripts.min.js';
819 $forced_excluded_combined_js = array();
820 $http = is_ssl() ? 'https:' : 'http:';
821 if (file_exists($merged_file_location) && time() - filemtime($merged_file_location) < 129600) {
822 foreach ($result['scripts'] as $handle => $script) {
823 if (str_contains($handle,"jquery")) { continue; }
824 if (!empty($script)) {
825 //Check if smth like //domain.com
826 if (!str_contains($script, $http) && str_contains($script, str_replace($http, '', get_site_url()))) {
827 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $script);
828 }
829 //Check if smth like /wp-includes/.../ + not https://fonts.google...
830 elseif (!str_contains($script, get_site_url()) && !stripos($script, 'fonts.')) {
831 $file = ABSPATH . $script;
832 }
833
834 //Check if smth like https://domain.com
835 elseif (str_contains($script, get_site_url())) {
836 $file = str_replace(get_site_url() . '/', ABSPATH, $script);
837 }
838
839 if (str_contains($file, "./")) {
840 $file = str_replace("./", '', $file);
841 }
842
843 if (str_contains($file, "//")) {
844 $file = str_replace("//", "/", $file);
845 }
846
847 if (!in_array($handle, $forced_excluded_combined_js) && !in_array($file, $exclude_combine_js_tab)) {
848 if (filemtime($merged_file_location) == filemtime($file)) {
849 wp_deregister_script($handle);
850 } else {
851 unlink($merged_file_location);
852 break;
853 }
854 }
855 }
856 }
857 }
858
859 if (!file_exists($merged_file_location)) {
860 $merged_scripts = '';
861 $minifierJS = new \MatthiasMullie\Minify\JS();
862
863 foreach ($result['scripts'] as $handle => $script) {
864 if (!empty($script) && !in_array($handle, $forced_excluded_combined_js)) {
865 if (!str_contains($script, $http) && str_contains($script, str_replace($http, '', get_site_url()))) {
866 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $script);
867 }
868 //Check if smth like /wp-includes/.../ + not https://fonts.google...
869 elseif (!str_contains($script, get_site_url()) && !stripos($script, 'fonts.')) {
870 $file = ABSPATH . $script;
871 }
872
873 //Check if smth like https://domain.com
874 elseif (str_contains($script, get_site_url())) {
875 $file = str_replace(get_site_url() . '/', ABSPATH, $script);
876 }
877
878 if (str_contains($file, "./")) {
879 $file = str_replace("./", '', $file);
880 }
881
882 if (file_exists($file) && !in_array($file, $exclude_combine_js_tab)) {
883 $minifierJS->add($file);
884 touch($file, $timestamp);
885 }
886
887 wp_deregister_script($handle);
888 }
889 }
890 $minifierJS->minify($merged_file_location);
891 touch($merged_file_location, $timestamp);
892 }
893 wp_enqueue_script('merged-scripts-min', get_stylesheet_directory_uri() . '/merged-scripts.min.js');
894 } else {
895 //JS
896 if (get_option('lws_op_min_js')) {
897 $wp_scripts->all_deps($wp_scripts->queue);
898 foreach ($wp_scripts->to_do as $script) {
899 $result['scripts'][$script] = $wp_scripts->registered[$script]->src;
900 }
901 $exclude_min_js_tab = get_option('lws_op_exclude_min_js_array') ? json_decode(get_option('lws_op_exclude_min_js_array'), true) : array();
902 $http = is_ssl() ? 'https:' : 'http:';
903 foreach ($result['scripts'] as $handle => $script) {
904 if (!stripos($script, '.min.js') && !empty($style)) {
905 //Check if smth like //domain.com
906 if (!str_contains($script, $http) && str_contains($script, str_replace($http, '', get_site_url()))) {
907 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $script);
908 }
909 //Check if smth like /wp-includes/.../ + not https://fonts.google...
910 elseif (!str_contains($script, get_site_url())) {
911 $file = ABSPATH . $script;
912 }
913
914 //Check if smth like https://domain.com
915 elseif (str_contains($script, get_site_url())) {
916 $file = str_replace(get_site_url() . '/', ABSPATH, $script);
917 }
918
919 if (str_contains($file, "./")) {
920 $file = str_replace("./", '', $file);
921 }
922
923 if (str_contains($file, "//")) {
924 $file = str_replace("//", "/", $file);
925 }
926
927 $file_min = str_replace('.js', '.min.js', $file);
928 if (file_exists($file_min) && !in_array($file, $exclude_min_js_tab) && (filemtime($file_min) == filemtime($file))) {
929 $wp_scripts->registered[$handle]->src = str_replace('.js', '.min.js', $script);
930 } else {
931 if (!in_array($file, $exclude_min_js_tab)) {
932 $minifierJS = new \MatthiasMullie\Minify\JS($file);
933 $minifierJS->minify($file_min);
934 $wp_scripts->registered[$handle]->src = str_replace('.js', '.min.js', $script);
935 }
936 }
937 }
938 }
939 }
940
941 if (get_option('lws_op_combine_js')) {
942 $wp_scripts->all_deps($wp_scripts->queue);
943 foreach ($wp_scripts->to_do as $script) {
944 $result['scripts'][$script] = $wp_scripts->registered[$script]->src;
945 }
946 $exclude_combine_js_tab = get_option('lws_op_exclude_combine_js_array') ? json_decode(get_option('lws_op_exclude_combine_js_array'), true) : array();
947 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-scripts.js';
948 $forced_excluded_combined_js = array();
949 $http = is_ssl() ? 'https:' : 'http:';
950 if (file_exists($merged_file_location) && time() - filemtime($merged_file_location) < 129600) {
951 foreach ($result['scripts'] as $handle => $script) {
952 if (str_contains($handle,"jquery")) { continue; }
953 if (!empty($script)) {
954 //Check if smth like //domain.com
955 if (!str_contains($script, $http) && str_contains($script, str_replace($http, '', get_site_url()))) {
956 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $script);
957 }
958 //Check if smth like /wp-includes/.../ + not https://fonts.google...
959 elseif (!str_contains($script, get_site_url()) && !stripos($script, 'fonts.')) {
960 $file = ABSPATH . $script;
961 }
962
963 //Check if smth like https://domain.com
964 elseif (str_contains($script, get_site_url())) {
965 $file = str_replace(get_site_url() . '/', ABSPATH, $script);
966 }
967
968 if (str_contains($file, "./")) {
969 $file = str_replace("./", '', $file);
970 }
971
972 if (str_contains($file, "//")) {
973 $file = str_replace("//", "/", $file);
974 }
975
976 if (!in_array($handle, $forced_excluded_combined_js) && !in_array($file, $exclude_combine_js_tab)) {
977 if (filemtime($merged_file_location) == filemtime($file)) {
978 wp_deregister_script($handle);
979 } else {
980 unlink($merged_file_location);
981 break;
982 }
983 }
984 }
985 }
986 }
987
988 if (!file_exists($merged_file_location)) {
989 $merged_scripts = '';
990
991 foreach ($result['scripts'] as $handle => $script) {
992 if (!empty($script) && !in_array($handle, $forced_excluded_combined_js)) {
993 if (!str_contains($script, $http) && str_contains($script, str_replace($http, '', get_site_url()))) {
994 $file = str_replace(str_replace($http, '', get_site_url() . '/'), ABSPATH, $script);
995 }
996 //Check if smth like /wp-includes/.../ + not https://fonts.google...
997 elseif (!str_contains($script, get_site_url()) && !stripos($script, 'fonts.')) {
998 $file = ABSPATH . $script;
999 }
1000
1001 //Check if smth like https://domain.com
1002 elseif (str_contains($script, get_site_url())) {
1003 $file = str_replace(get_site_url() . '/', ABSPATH, $script);
1004 }
1005
1006 if (str_contains($file, "./")) {
1007 $file = str_replace("./", '', $file);
1008 }
1009
1010 if (file_exists($file) && !in_array($file, $exclude_combine_js_tab)) {
1011 $localize = '';
1012
1013 if (is_array($wp_styles->registered[$handle]->extra) && @key_exists('data', $wp_scripts->registered[$handle]->extra)) {
1014 $localize = $wp_styles->registered[$handle]->extra['data'] . ';';
1015 }
1016
1017 $merged_scripts .= $localize . file_get_contents($file);
1018 touch($file, $timestamp);
1019 }
1020
1021 wp_deregister_script($handle);
1022 }
1023 }
1024 file_put_contents($merged_file_location, $merged_scripts);
1025 touch($merged_file_location, $timestamp);
1026 }
1027 wp_enqueue_script('merged-scripts', get_stylesheet_directory_uri() . '/merged-scripts.js', array(), false, false);
1028 }
1029 }
1030 }
1031 }
1032
1033 /**
1034 * The loading of all JS scripts is done in parallel of the page loading, making for faster page load time
1035 */
1036 if (get_option('lws_op_defer_js') && !get_option('lws_op_deactivated')) {
1037 add_filter('script_loader_tag', 'lws_op_defer_filter', 10, 3);
1038 function lws_op_defer_filter($tag, $handle, $src)
1039 {
1040 if (!is_admin()) {
1041 $tag = str_replace('></script>', ' defer></script>', $tag);
1042 }
1043 return $tag;
1044 }
1045 }
1046
1047 /**
1048 * Preload all CSS scripts, for faster speed
1049 */
1050 if (get_option('lws_op_preload_css') && !get_option('lws_op_deactivated')) {
1051 add_filter('style_loader_tag', 'lws_op_preload_css', 10, 4);
1052 function lws_op_preload_css($html, $handle, $href, $media)
1053 {
1054 if (!is_admin()) {
1055 $html = '<link rel="preload" href="' . $href . '" as="style" id="' . $handle . '" media="' . $media . '" onload="this.onload=null;this.rel=\'stylesheet\'">'
1056 . '<noscript>' . $html . '</noscript>';
1057 }
1058 return $html;
1059 }
1060 }
1061
1062 /**
1063 * Remove the ?ver= query on the CSS/JS files
1064 * Can help with caching
1065 */
1066 if (get_option('lws_op_remove_query') && !get_option('lws_op_deactivated')) {
1067 add_filter('style_loader_src', 'lws_op_remove_scripts_static', 10);
1068 add_filter('script_loader_src', 'lws_op_remove_scripts_static', 10);
1069
1070 function lws_op_remove_scripts_static($src)
1071 {
1072 if (strpos($src, '?ver=')) {
1073 $src = remove_query_arg('ver', $src);
1074 }
1075 return $src;
1076 }
1077 }
1078
1079 /**
1080 * Disable emojis in WordPress => Emojis are still active, but managed by the visitor's browser instead of the server
1081 * Better loading time as there is less files to load
1082 */
1083 if (get_option('lws_op_delete_emoji') && !get_option('lws_op_deactivated')) {
1084 add_action('init', 'lws_op_disable_emojis');
1085 function lws_op_disable_emojis()
1086 {
1087 remove_action('wp_head', 'print_emoji_detection_script');
1088 remove_action('admin_print_scripts', 'print_emoji_detection_script');
1089 remove_action('wp_print_styles', 'print_emoji_styles');
1090 remove_filter('the_content_feed', 'wp_staticize_emoji');
1091 remove_action('admin_print_styles', 'print_emoji_styles');
1092 remove_filter('comment_text_rss', 'wp_staticize_emoji');
1093 remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
1094 add_filter('tiny_mce_plugins', 'lws_op_disable_emojis_tinymce');
1095 }
1096
1097 function lws_op_disable_emojis_tinymce($plugins)
1098 {
1099 if (is_array($plugins)) {
1100 return array_diff($plugins, array('wpemoji'));
1101 } else {
1102 return array();
1103 }
1104 }
1105 }
1106 //
1107 //
1108 // END OF FRONTEND-RELATED FUNCTIONS ###
1109
1110
1111 // FUNCTIONS RELATED TO THE MEDIAS TAB ###
1112 //
1113 //
1114 /**
1115 * Convert all images to JPEG for better size. Duplicate saved as .old to unconvert
1116 */
1117 function lws_op_compress_all_to_jpeg()
1118 {
1119 $args = array(
1120 'numberposts' => -1,
1121 'post_type' => 'attachment',
1122 );
1123 $attachments = get_posts($args);
1124 foreach ($attachments as $a) {
1125 if (explode('/', $a->post_mime_type)[0] == 'image') {
1126 $metadata = wp_get_attachment_metadata($a->ID);
1127 $path = get_attached_file($a->ID);
1128 copy($path, $path . '.old');
1129 lws_op_compress_to_jpeg($path, $path, 60);
1130
1131 foreach ($metadata['sizes'] as $size => $data) {
1132 $size_path = explode('/', $path);
1133 $size_path = implode('/', array_replace($size_path, [(count($size_path) -1) => $data['file']]));
1134 copy($size_path, $size_path . '.old');
1135 lws_op_compress_to_jpeg($path, $path, 60);
1136 }
1137 }
1138 }
1139 }
1140
1141 /**
1142 * Unconvert all images from JPEG to their original type from the .old saved
1143 * If there is no original file, do nothing
1144 */
1145 function lws_op_uncompress_all_to_jpeg()
1146 {
1147 $args = array(
1148 'numberposts' => -1,
1149 'post_type' => 'attachment',
1150 );
1151 $attachments = get_posts($args);
1152 foreach ($attachments as $a) {
1153 if (explode('/', $a->post_mime_type)[0] == 'image') {
1154 $metadata = wp_get_attachment_metadata($a->ID);
1155 $path = get_attached_file($a->ID);
1156 if (file_exists($path . '.old')) {
1157 @rename($path. '.old', $path);
1158 // if ($a->post_mime_type == 'image/webp') {
1159 // $tmp = explode('.', $path);
1160 // array_pop($tmp);
1161 // $tmp = implode('.', $tmp);
1162 // @rename($tmp. '.old', $tmp);
1163 // }
1164
1165 foreach ($metadata['sizes'] as $size => $data) {
1166 $size_path = explode('/', $path);
1167 $size_path = implode('/', array_replace($size_path, [(count($size_path) -1) => $data['file']]));
1168 @rename($size_path . '.old', $size_path);
1169 //if ($a->post_mime_type == 'image/webp') {
1170 // $tmp = explode('.', $size_path);
1171 // array_pop($tmp);
1172 // $tmp = implode('.', $tmp);
1173 // @rename($tmp. '.old', $tmp);
1174 // }
1175 }
1176 }
1177 }
1178 }
1179 }
1180
1181 /**
1182 * In charge of converting all the files given to it by lws_op_compress_all_to_jpeg()
1183 * The source will be used to create the destination
1184 */
1185 function lws_op_compress_to_jpeg($source, $destination, $qualite = 60)
1186 {
1187 $info = getimagesize($source);
1188
1189 switch($info['mime']) {
1190 case 'image/jpeg':
1191 $image = imagecreatefromjpeg($source);
1192 break;
1193 case 'image/gif':
1194 $image = imagecreatefromgif($source);
1195 break;
1196 case 'image/png':
1197 $image = imagecreatefrompng($source);
1198 break;
1199 case 'image/webp':
1200 $image = imagecreatefromwebp($source);
1201 break;
1202 default:
1203 $image = imagecreatefromjpeg($source);
1204 break;
1205 }
1206
1207 imagejpeg($image, $destination, $qualite);
1208
1209 return $destination;
1210 }
1211
1212 /**
1213 * Given a PATH, create a new WEBP file at the same place
1214 * Original files will not be deleted to revert the changes later
1215 */
1216 function lws_op_generate_webp_file($filepath)
1217 {
1218 if (!file_exists($filepath)) {
1219 return false;
1220 }
1221
1222 // Get image type.
1223 $image_type = exif_imagetype($filepath);
1224
1225 switch ($image_type) {
1226 case IMAGETYPE_GIF:
1227 $im = imagecreatefromgif($filepath);
1228 break;
1229 case IMAGETYPE_JPEG:
1230 $im = imagecreatefromjpeg($filepath);
1231 break;
1232 case IMAGETYPE_PNG:
1233 $im = imagecreatefrompng($filepath);
1234 break;
1235 default:
1236 return false;
1237 }
1238
1239 $newImagePath = $filepath . '.webp';
1240 imagepalettetotruecolor($im);
1241 imagealphablending($im, false);
1242 imagesavealpha($im, true);
1243 imagewebp($im, $newImagePath);
1244
1245 return $newImagePath;
1246 }
1247
1248 /**
1249 * Given a PATH, sizes a name and the original file sizes, create a new WEBP file with a specific size
1250 * Original files will not be deleted to revert the changes later
1251 */
1252 function lws_op_generate_webp_file_sized($filepath, $width, $height, $bw, $bh, $name)
1253 {
1254 if (!file_exists($filepath)) {
1255 return false;
1256 }
1257
1258 // Get image type.
1259 $image_type = exif_imagetype($filepath);
1260
1261 switch ($image_type) {
1262 case IMAGETYPE_GIF:
1263 $im = imagecreatefromgif($filepath);
1264 break;
1265 case IMAGETYPE_JPEG:
1266 $im = imagecreatefromjpeg($filepath);
1267 break;
1268 case IMAGETYPE_PNG:
1269 $im = imagecreatefrompng($filepath);
1270 break;
1271 default:
1272 return false;
1273 }
1274
1275
1276 $newImagePath = $filepath . '.webp';
1277 $new_image = imagecreatetruecolor($width, $height);
1278
1279 imagepalettetotruecolor($im);
1280 imagealphablending($im, false);
1281 imagesavealpha($im, true);
1282
1283 imagecopyresampled($new_image, $im, 0, 0, 0, 0, $width, $height, $bw, $bh);
1284 imagewebp($im, $newImagePath);
1285 return $newImagePath;
1286 }
1287
1288
1289 add_action('lws_op_hook_convert_webp', 'lws_op_convert_all_to_webp', 15);
1290 add_action('lws_op_hook_unconvert_webp', 'lws_op_delete_webp_files', 8);
1291
1292
1293 /**
1294 * Once activated, will convert all current images to WEBP
1295 * Original files will not be deleted to revert the changes later
1296 */
1297 function lws_op_convert_all_to_webp()
1298 {
1299 global $wpdb;
1300 $args = array(
1301 'numberposts' => -1,
1302 'post_type' => 'attachment',
1303 );
1304 $attachments = get_posts($args);
1305 foreach ($attachments as $a) {
1306 if (explode('/', $a->post_mime_type)[0] == 'image' && $a->post_mime_type != 'image/webp') {
1307 $id = $a->ID;
1308 $metadata = wp_get_attachment_metadata($id);
1309 $path = get_attached_file($id);
1310 $filename = basename($path);
1311 $dirname = dirname($path);
1312 @rename($path. '.old', $path);
1313
1314 if (stripos($filename, '-scaled')) {
1315 $name = explode('.', $filename);
1316 $name[0] .= '-scaled';
1317 $name = implode('.', $name);
1318
1319 $path = explode('/', $path);
1320 array_pop($path);
1321 $path[] = $name;
1322 $path = implode('/', $path);
1323 }
1324
1325 lws_op_generate_webp_file($path);
1326 if (get_option('lws_op_autoconvert_compression')) {
1327 copy($path . '.webp', $path . '.webp.old');
1328 lws_op_compress_to_jpeg($path . '.webp', $path . '.webp', 60);
1329 }
1330
1331 $base_width = $metadata['width'];
1332 $base_height = $metadata['height'];
1333 foreach ($metadata['sizes'] as $size => $data) {
1334 $old_path = $dirname . '/' . $data['file'];
1335 $metadata['sizes'][$size]['file'] = $data['file'] . '.webp';
1336 $metadata['sizes'][$size]['mime-type'] = 'image/webp';
1337
1338 $new_path = explode('/', $path);
1339 array_pop($new_path);
1340 $new_path[] = $data['file'];
1341 $new_path = implode('/', $new_path);
1342 lws_op_generate_webp_file_sized($new_path, $data['width'], $data['height'], $base_width, $base_height, $data['file'] . '.webp');
1343 if (get_option('lws_op_autoconvert_compression')) {
1344 @rename($old_path . '.old', $old_path);
1345 copy($old_path . '.webp', $old_path . '.webp.old');
1346 lws_op_compress_to_jpeg($old_path . '.webp', $old_path . '.webp', 60);
1347 }
1348 }
1349 $meta_value = $wpdb->get_var(
1350 $wpdb->prepare(
1351 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
1352 $id
1353 )
1354 );
1355 wp_update_attachment_metadata($id, $metadata);
1356 wp_update_post(array('ID' => $id, 'post_mime_type' => 'image/webp'));
1357 $wpdb->query(
1358 $wpdb->prepare(
1359 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
1360 $meta_value . '.webp',
1361 $id
1362 )
1363 );
1364 }
1365 }
1366 lws_op_update_posts_webp("convert");
1367 }
1368
1369 /**
1370 * Once activated, will unconvert all current images to their orignal type
1371 * If there is no original file, do nothing
1372 */
1373 function lws_op_delete_webp_files()
1374 {
1375 global $wpdb;
1376 $args = array(
1377 'numberposts' => -1,
1378 'post_type' => 'attachment',
1379 );
1380 $attachments = get_posts($args);
1381 foreach ($attachments as $a) {
1382 if (explode('/', $a->post_mime_type)[0] == 'image' && $a->post_mime_type == 'image/webp') {
1383 $id = $a->ID;
1384 $metadata = wp_get_attachment_metadata($id);
1385 $path = get_attached_file($id);
1386 $filename = basename($path);
1387 $extension = explode('.', $filename);
1388 array_pop($extension);
1389
1390 $new_path = implode('.', $extension);
1391 $extension = end($extension);
1392 $dirname = dirname($path);
1393 $new_path = $dirname . '/' . $new_path;
1394 if (file_exists($new_path)) {
1395 @rename($path. '.old', $path);
1396 @unlink($path);
1397
1398 if (get_option('lws_op_autoconvert_compression')) {
1399 copy($new_path, $new_path . '.old');
1400 lws_op_compress_to_jpeg($new_path, $new_path, 60);
1401 }
1402
1403 foreach ($metadata['sizes'] as $size => $data) {
1404 $old_path = $dirname . '/' . $data['file'];
1405 $new_name = explode('.', $data['file']);
1406 array_pop($new_name);
1407 $new_name = implode('.', $new_name);
1408 $new_path_size = $dirname . '/' . $new_name;
1409 @rename($old_path . '.old', $old_path);
1410 @unlink($old_path);
1411 $metadata['sizes'][$size]['file'] = $new_name;
1412 $metadata['sizes'][$size]['mime-type'] = 'image/' . $extension;
1413
1414 if (get_option('lws_op_autoconvert_compression')) {
1415 copy($new_path_size, $new_path_size. '.old');
1416 lws_op_compress_to_jpeg($new_path_size, $new_path_size, 60);
1417 }
1418 }
1419
1420 $meta_value = $wpdb->get_var(
1421 $wpdb->prepare(
1422 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
1423 $id
1424 )
1425 );
1426 $meta_value = explode('.', $meta_value);
1427 array_pop($meta_value);
1428 $meta_value = implode('.', $meta_value);
1429 wp_update_post(array('ID' => $id, 'post_mime_type' => 'image/' . $extension));
1430 wp_update_attachment_metadata($id, $metadata);
1431 $wpdb->query(
1432 $wpdb->prepare(
1433 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
1434 $meta_value,
1435 $id
1436 )
1437 );
1438 }
1439 }
1440 }
1441 lws_op_update_posts_webp("restore");
1442 }
1443
1444 /**
1445 * When a new file is uploaded, if activated, will compress it (if is an image)
1446 */
1447 if (get_option('lws_op_autoconvert_compression') && !get_option('lws_op_deactivated')) {
1448 add_filter('wp_generate_attachment_metadata', 'lws_op_compress_to_jpeg_upload', 15, 2);
1449 function lws_op_compress_to_jpeg_upload($metadata, $attachment_id)
1450 {
1451 if ($metadata['sizes'] !== null){
1452 if (explode('/', reset($metadata['sizes'])['mime-type'])[0] == 'image') {
1453 $path = get_attached_file($attachment_id);
1454
1455 copy($path, $path . '.old');
1456 lws_op_compress_to_jpeg($path, $path, 60);
1457
1458 foreach ($metadata['sizes'] as $size => $data) {
1459 $path = explode('/', $path);
1460 array_pop($path);
1461 $path[] = $data['file'];
1462 $path = implode('/', $path);
1463 copy($path, $path . '.old');
1464 lws_op_compress_to_jpeg($path, $path, 60);
1465 }
1466 }
1467 }
1468 }
1469 }
1470
1471 /**
1472 * When a new file is uploaded, if activated, will convert it to WEBP (if not already)
1473 */
1474 if (get_option('lws_op_autoconvert_webp') && !get_option('lws_op_deactivated')) {
1475 add_filter('wp_generate_attachment_metadata', 'lws_op_webp_upload', 10, 2);
1476 function lws_op_webp_upload($metadata, $attachment_id)
1477 {
1478 global $wpdb;
1479
1480 if (explode('/', reset($metadata['sizes'])['mime-type'])[0] == 'image' && reset($metadata['sizes'])['mime-type'] != 'image/webp') {
1481 $meta = $metadata;
1482 $path = get_attached_file($attachment_id);
1483 lws_op_generate_webp_file($path);
1484 $meta['file'] .= '.webp';
1485 foreach ($meta['sizes'] as $size => $data) {
1486 $new_path = explode('/', $path);
1487 array_pop($new_path);
1488 $new_path[] = $data['file'];
1489 $new_path = implode('/', $new_path);
1490 $meta['sizes'][$size]['file'] = $data['file'] . '.webp';
1491 $meta['sizes'][$size]['mime-type'] = "image/webp";
1492 $sizes = wp_get_attachment_image_src($attachment_id, 'full');
1493 lws_op_generate_webp_file_sized($new_path, $data['width'], $data['height'], $sizes[1], $sizes[2], $data['file'] . 'webp');
1494 }
1495
1496 $meta_value = $wpdb->get_var(
1497 $wpdb->prepare(
1498 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
1499 $attachment_id
1500 )
1501 );
1502 wp_update_post(array('ID' => $attachment_id, 'post_mime_type' => 'image/webp'));
1503 $wpdb->get_var(
1504 $wpdb->prepare(
1505 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
1506 $meta_value . '.Webp',
1507 $attachment_id
1508 )
1509 );
1510 return $meta;
1511 }
1512
1513 return $metadata;
1514 }
1515 }
1516
1517
1518 /**
1519 * TODO
1520 */
1521 //add_action('delete_attachment', 'lws_op_restore_file_to_default_before_delete');
1522 function lws_op_restore_file_to_default_before_delete($attachment_id, $post)
1523 {
1524 }
1525
1526 function lws_op_update_posts_webp($usage)
1527 {
1528 global $wpdb;
1529 $args = array(
1530 'numberposts' => -1,
1531 'post_type' => 'attachment',
1532 );
1533 $attachments = get_posts($args);
1534 foreach ($attachments as $a) {
1535 if (explode('/', $a->post_mime_type)[0] == 'image') {
1536 $id = $a->ID;
1537 $url = wp_get_attachment_url($id);
1538 if ($usage == "convert") {
1539 $elements = $wpdb->get_results(
1540 $wpdb->prepare(
1541 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1542 WHERE post_content LIKE %s
1543 ",
1544 $url . '"',
1545 $url . '.webp"',
1546 '%' . $url . '"%'
1547 )
1548 );
1549 } else {
1550 $url = explode('.', $url);
1551 array_pop($url);
1552 $url = implode('.', $url);
1553 $file = str_replace(get_site_url() . '/', ABSPATH, $url);
1554 if (file_exists($file)) {
1555 $exists = true;
1556 $wpdb->get_results(
1557 $wpdb->prepare(
1558 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1559 WHERE post_content LIKE %s
1560 ",
1561 $url . '.webp',
1562 $url,
1563 '%' . $url . '"%'
1564 )
1565 );
1566 }
1567 }
1568
1569 $meta = wp_get_attachment_metadata($id);
1570 foreach ($meta['sizes'] as $key => $size) {
1571 $name = $size['file'];
1572 if ($usage == "convert") {
1573 $name = explode('.', $size['file']);
1574 array_pop($name);
1575 $name = implode('.', $name);
1576
1577 $url = explode('/', wp_get_attachment_url($id));
1578 array_pop($url);
1579 $url[] = $name;
1580 $url = implode('/', $url);
1581
1582 $wpdb->get_results(
1583 $wpdb->prepare(
1584 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1585 WHERE post_content LIKE %s
1586 ",
1587 $url . '"',
1588 $url . '.webp"',
1589 '%' . $url . '"%'
1590 )
1591 );
1592 } else {
1593 $url = explode('/', wp_get_attachment_url($id));
1594 array_pop($url);
1595 $url[] = $name;
1596 $url = implode('/', $url);
1597 $file = str_replace(get_site_url() . '/', ABSPATH, $url);
1598 if (file_exists($file)) {
1599 $exists = true;
1600 $wpdb->get_results(
1601 $wpdb->prepare(
1602 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1603 WHERE post_content LIKE %s
1604 ",
1605 $url . '.webp',
1606 $url,
1607 '%' . $url . '"%'
1608 )
1609 );
1610 }
1611 }
1612 }
1613 }
1614 }
1615 }
1616 //
1617 //
1618 // END OF MEDIAS-RELATED FUNCTIONS ###
1619
1620 add_action(
1621 'wp', function () {
1622 if (get_option('lws_op_force_no_lazyload_video') && !get_option('lws_op_deactivated')) {
1623 function lws_op_disable_audio_video_lazy_loading()
1624 {
1625 global $wpdb;
1626
1627 $elements = $wpdb->get_results(
1628 $wpdb->prepare(
1629 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1630 '%<video%',
1631 )
1632 );
1633
1634 foreach ($elements as $element) {
1635 $element = $element->post_content;
1636 if (str_contains($element, 'preload="none"')) {
1637 $element = str_replace('preload="none"', 'preload="auto"', $element);
1638 }
1639
1640 $wpdb->get_results(
1641 $wpdb->prepare(
1642 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1643 $element,
1644 '%<video%',
1645 )
1646 );
1647 }
1648
1649 $elements = $wpdb->get_results(
1650 $wpdb->prepare(
1651 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1652 '%<audio%',
1653 )
1654 );
1655
1656 foreach ($elements as $element) {
1657 $element = $element->post_content;
1658 if (str_contains($element, 'preload="none"')) {
1659 $element = str_replace('preload="none"', 'preload="auto"', $element);
1660 }
1661
1662 $wpdb->get_results(
1663 $wpdb->prepare(
1664 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1665 $element,
1666 '%<audio%',
1667 )
1668 );
1669 }
1670 }
1671 lws_op_disable_audio_video_lazy_loading();
1672 }
1673
1674 if (get_option('lws_op_force_lazyload_video')) {
1675 function lws_op_force_audio_video_lazy_loading()
1676 {
1677 global $wpdb;
1678
1679 $elements = $wpdb->get_results(
1680 $wpdb->prepare(
1681 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1682 '%<video%'
1683 )
1684 );
1685
1686 foreach ($elements as $element) {
1687 $element = $element->post_content;
1688 if (str_contains($element, 'autoplay')) {
1689 $element = str_replace('autoplay', '', $element);
1690 }
1691 if (str_contains($element, 'preload="auto"')) {
1692 $element = str_replace('preload="auto"', 'preload="none"', $element);
1693 }
1694 if (str_contains($element, 'preload="metadata"')) {
1695 $element = str_replace('preload="metadata"', 'preload="none"', $element);
1696 }
1697
1698 $wpdb->get_results(
1699 $wpdb->prepare(
1700 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1701 $element,
1702 '%<video%'
1703 )
1704 );
1705 }
1706
1707 $elements = $wpdb->get_results(
1708 $wpdb->prepare(
1709 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1710 '%<audio%',
1711 )
1712 );
1713
1714 foreach ($elements as $element) {
1715 $element = $element->post_content;
1716 if (str_contains($element, 'autoplay')) {
1717 $element = str_replace('autoplay', '', $element);
1718 }
1719 if (str_contains($element, 'preload="auto"')) {
1720 $element = str_replace('preload="auto"', 'preload="none"', $element);
1721 }
1722 if (str_contains($element, 'preload="metadata"')) {
1723 $element = str_replace('preload="metadata"', 'preload="none"', $element);
1724 }
1725
1726 $wpdb->get_results(
1727 $wpdb->prepare(
1728 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1729 $element,
1730 '%<audio%',
1731 )
1732 );
1733 }
1734 }
1735
1736 lws_op_force_audio_video_lazy_loading();
1737 }
1738
1739 if (get_option('lws_op_deactivate_lazyload')) {
1740 add_filter(
1741 'wp_lazy_loading_enabled', function () {
1742 global $wp_query;
1743 return false;
1744 }
1745 );
1746 wp_die();
1747 }
1748
1749 if (get_option('lws_op_deactivate_lazyload_image')) {
1750 add_filter('wp_lazy_loading_enabled', 'lws_op_disable_image_lazy_loading', 10, 3);
1751 function lws_op_disable_image_lazy_loading($default, $tag_name, $context)
1752 {
1753 global $wp_query;
1754 if ('img' === $tag_name && 'the_content' === $context) {
1755 return false;
1756 }
1757 return $default;
1758 }
1759 }
1760
1761 if (get_option('lws_op_deactivate_lazyload_iframe')) {
1762 add_filter('wp_lazy_loading_enabled', 'lws_op_disable_iframe_lazy_loading', 10, 3);
1763 //Allows to disable lazy_load on every tags chosen ; here 'iframe' or 'img'
1764 function lws_op_disable_iframe_lazy_loading($default, $tag_name, $context)
1765 {
1766 global $wp_query;
1767 if ('iframe' === $tag_name && 'the_content' === $context) {
1768 return false;
1769 }
1770 return $default;
1771 }
1772 }
1773 }
1774 );
1775
1776 add_action("wp_ajax_lws_op_other_cache_plugin_ajax", "lws_optimize_remove_other_cache");
1777 function lws_optimize_remove_other_cache()
1778 {
1779 check_ajax_referer('deactivate_plugin_lwsoptimize', '_ajax_nonce');
1780 if (isset($_POST['action'])) {
1781 if (isset($_POST['data'])){
1782 switch(htmlspecialchars($_POST['data']['id'])){
1783 case 'wprocket':
1784 deactivate_plugins('wp-rocket/wp-rocket.php');
1785 break;
1786 case 'pc':
1787 deactivate_plugins('powered-cache/powered-cache.php');
1788 break;
1789 case 'wpsc':
1790 deactivate_plugins('wp-super-cache/wp-cache.php');
1791 break;
1792 case 'wpo':
1793 deactivate_plugins('wp-optimize/wp-optimize.php');
1794 break;
1795 case 'wpfc':
1796 deactivate_plugins('wp-fastest-cache/wpFastestCache.php');
1797 break;
1798 case 'wp3':
1799 deactivate_plugins('w3-total-cache/w3-total-cache.php');
1800 break;
1801
1802 }
1803 }
1804 }
1805 }
1806
1807
1808 add_action("wp_ajax_lws_optimize_manage_state", "lws_optimize_manage_state");
1809 function lws_optimize_manage_state()
1810 {
1811 check_ajax_referer('manage_optimize_state', '_ajax_nonce');
1812 if (isset($_POST['action'])) {
1813 if ($_POST['checked'] !== "false"){
1814 delete_option('lws_op_deactivated');
1815 }
1816 else {
1817 var_dump(update_option('lws_op_deactivated', "blocked"));
1818 }
1819 }
1820 }
1821
1822 //AJAX DL Plugin//
1823 add_action("wp_ajax_lws_op_downloadPlugin", "wp_ajax_install_plugin");
1824 //
1825
1826 //AJAX Activate Plugin//
1827 add_action("wp_ajax_lws_op_activatePlugin", "lws_op_activate_plugin");
1828 function lws_op_activate_plugin()
1829 {
1830 check_ajax_referer('activate_plugin', '_ajax_nonce');
1831 if (isset($_POST['ajax_slug'])) {
1832 switch (sanitize_textarea_field($_POST['ajax_slug'])) {
1833 case 'lws-hide-login':
1834 activate_plugin('lws-hide-login/lws-hide-login.php');
1835 break;
1836 case 'lws-sms':
1837 activate_plugin('lws-sms/lws-sms.php');
1838 break;
1839 case 'lws-tools':
1840 activate_plugin('lws-tools/lws-tools.php');
1841 break;
1842 case 'lws-affiliation':
1843 activate_plugin('lws-affiliation/lws-affiliation.php');
1844 break;
1845 case 'lws-cleaner':
1846 activate_plugin('lws-cleaner/lws-cleaner.php');
1847 break;
1848 case 'lwscache':
1849 activate_plugin('lwscache/lwscache.php');
1850 break;
1851 case 'lws-optimize':
1852 activate_plugin('lws-optimize/lws-optimize.php');
1853 break;
1854 }
1855 }
1856 wp_die();
1857 }
1858
1859 if (!get_option('lws_op_deactivated')){
1860
1861 //When file-based caching is activated
1862 if (get_option('lws_op_fb_cache') && !get_option('lws_op_deactivated')) {
1863 add_filter('template_include', 'lws_op_fb_tpl_redirect', 1);
1864 function lws_op_fb_tpl_redirect($template)
1865 {
1866 global $wp;
1867 $file = LWS_OP_UPLOADS . $wp->request . '_lws_' . get_current_user_id() . '.html';
1868 $timer = get_option('lws_op_fb_cache');
1869 if (is_file($file) && (time() - filemtime($file)) < $timer) {
1870 return $file;
1871 wp_die();
1872 } else {
1873 ob_start();
1874 add_action('wp_print_footer_scripts', 'lws_op_fb_tpl_redirect_end');
1875 return $template;
1876 }
1877 }
1878
1879 function lws_op_fb_tpl_redirect_end()
1880 {
1881 global $wp;
1882 $file = LWS_OP_UPLOADS . $wp->request . '_lws_' . get_current_user_id() . '.html';
1883 if (!is_file($file)) {
1884 file_put_contents($file, ob_get_contents());
1885 }
1886 }
1887 }
1888
1889 add_action("wp_ajax_lws_option_media_checkbox", "lws_option_media_checkbox");
1890 function lws_option_media_checkbox()
1891 {
1892 check_ajax_referer('checkbox_update_option_to_change', '_ajax_nonce');
1893 if(isset($_POST['action']) && isset($_POST['option']) && isset($_POST['checked'])) {
1894 $media_to_webp = array(
1895 'lws_op_autoconvert_compression',
1896 'lws_op_autoconvert_webp',
1897 'lws_op_deactivate_lazyload_iframe',
1898 'lws_op_deactivate_lazyload_image',
1899 'lws_op_deactivate_lazyload',
1900 'lws_op_force_lazyload_video',
1901 'lws_op_force_no_lazyload_video',
1902 );
1903 $option = sanitize_text_field($_POST['option']);
1904 $is_checked = rest_sanitize_boolean($_POST['checked']);
1905 if ($option == 'lws_op_deactivate_lazyload_iframe' || $option == 'lws_op_deactivate_lazyload_image' || $option == 'lws_op_deactivate_lazyload') :
1906 if (!$is_checked) {
1907 if (in_array($option, $media_to_webp)) {
1908 update_option($option, true);
1909 }
1910 if ($option == 'lws_op_autoconvert_webp') {
1911 wp_unschedule_event(wp_next_scheduled('lws_op_hook_unconvert_webp'), 'lws_op_hook_unconvert_webp');
1912 if (! wp_next_scheduled('lws_op_hook_convert_webp')) {
1913 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_convert_webp');
1914 }
1915 } elseif ($option == 'lws_op_autoconvert_compression') {
1916 lws_op_compress_all_to_jpeg();
1917 }
1918 }
1919 else{
1920 if (in_array($option, $media_to_webp)) {
1921 delete_option($option);
1922 }
1923 if ($option == 'lws_op_autoconvert_webp') {
1924 wp_unschedule_event(wp_next_scheduled('lws_op_hook_convert_webp'), 'lws_op_hook_convert_webp');
1925 if (! wp_next_scheduled('lws_op_hook_unconvert_webp')) {
1926 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_unconvert_webp');
1927 }
1928 } elseif ($option == 'lws_op_autoconvert_compression') {
1929 lws_op_uncompress_all_to_jpeg();
1930 }
1931 }
1932 else :
1933 if ($is_checked) {
1934 if (in_array($option, $media_to_webp)) {
1935 update_option($option, true);
1936 }
1937 if ($option == 'lws_op_autoconvert_webp') {
1938 wp_unschedule_event(wp_next_scheduled('lws_op_hook_unconvert_webp'), 'lws_op_hook_unconvert_webp');
1939 if (! wp_next_scheduled('lws_op_hook_convert_webp')) {
1940 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_convert_webp');
1941 }
1942 } elseif ($option == 'lws_op_autoconvert_compression') {
1943 lws_op_compress_all_to_jpeg();
1944 }
1945 }
1946 else{
1947 if (in_array($option, $media_to_webp)) {
1948 delete_option($option);
1949 }
1950 if ($option == 'lws_op_autoconvert_webp') {
1951 wp_unschedule_event(wp_next_scheduled('lws_op_hook_convert_webp'), 'lws_op_hook_convert_webp');
1952 if (! wp_next_scheduled('lws_op_hook_unconvert_webp')) {
1953 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_unconvert_webp');
1954 }
1955 } elseif ($option == 'lws_op_autoconvert_compression') {
1956 lws_op_uncompress_all_to_jpeg();
1957 }
1958 }
1959 endif;
1960 }
1961
1962 }
1963
1964 add_action("wp_ajax_lws_add_option_media", "lws_op_add_option");
1965 function lws_op_add_option()
1966 {
1967 check_ajax_referer('media_change_max_width', '_ajax_nonce');
1968 if(isset($_POST['action'])) {
1969 if (isset($_POST['value'])) {
1970 $value = sanitize_text_field($_POST['value']);
1971 update_option("lws_op_change_max_width_media", $value);
1972 }
1973 }
1974 wp_die();
1975 }
1976
1977 add_action("wp_ajax_lws_delete_option_media", "lws_op_delete_option");
1978 function lws_op_delete_option()
1979 {
1980 check_ajax_referer('also_media_change_max_width', '_ajax_nonce');
1981 if(isset($_POST['action'])) {
1982 delete_option("lws_op_change_max_width_media");
1983 }
1984 wp_die();
1985 }
1986
1987 if (get_option('lws_op_change_max_width_media')) {
1988 $value = get_option('lws_op_change_max_width_media');
1989 if ($value == 'disabled') {
1990 add_filter('big_image_size_threshold', '__return_false');
1991 } else {
1992 add_filter('big_image_size_threshold', 'lws_op_image_size_threshold');
1993 function lws_op_image_size_threshold($threshold)
1994 {
1995 $threshold = get_option('lws_op_change_max_width_media');
1996 return $threshold;
1997 }
1998 }
1999 }
2000
2001 add_action("wp_ajax_lws_optimize_fb_cache", "lws_optimize_fb_cache");
2002 function lws_optimize_fb_cache()
2003 {
2004 check_ajax_referer('update_fb_activate', '_ajax_nonce');
2005 if (isset($_POST['action'])) {
2006 $timer = ($_POST['timer'] !== false) ? sanitize_text_field($_POST['timer']) : '3600';
2007 update_option('lws_op_fb_cache', $timer);
2008 } else {
2009 delete_option('lws_op_fb_cache');
2010 }
2011 }
2012
2013 add_action("wp_ajax_lws_no_optimize_fb_cache", "lws_no_optimize_fb_cache");
2014 function lws_no_optimize_fb_cache()
2015 {
2016 check_ajax_referer('update_fb_deactivate', '_ajax_nonce');
2017 if (isset($_POST['action'])) {
2018 delete_option('lws_op_fb_cache');
2019 }
2020 }
2021
2022 add_action("wp_ajax_lws_clear_fb_cache", "lws_optimize_clear_cache");
2023 function lws_optimize_clear_cache()
2024 {
2025 check_ajax_referer('clear_fb_caching', '_ajax_nonce');
2026 array_map('unlink', (glob(wp_upload_dir()['basedir'] . "/lws-optimize/*") ? glob(wp_upload_dir()['basedir'] . "/lws-optimize/*") : array()));
2027 }
2028
2029 add_action("wp_ajax_lws_clear_memcached", "lws_optimize_clear_memcached");
2030 function lws_optimize_clear_memcached()
2031 {
2032 check_ajax_referer('clear_memc_caching', '_ajax_nonce');
2033 $memcached = new Memcached();
2034 $memcached->addServer('localhost', 11211);
2035 $memcached->flush(1);
2036 }
2037
2038 add_action("wp_ajax_lws_start_memcached", "lws_optimize_start_memcached");
2039 function lws_optimize_start_memcached()
2040 {
2041 check_ajax_referer('starting_memc_caching', '_ajax_nonce');
2042 if (isset($_POST['action'])) {
2043 update_option('lws_opti_memcaching_on', 1);
2044 file_put_contents(WP_CONTENT_DIR . '/object-cache.php', file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
2045 }
2046 }
2047
2048 add_action("wp_ajax_lws_stop_memcached", "lws_optimize_stop_memcached");
2049 function lws_optimize_stop_memcached()
2050 {
2051 check_ajax_referer('turn_off_memc_caching', '_ajax_nonce');
2052 if (isset($_POST['action'])) {
2053 delete_option('lws_opti_memcaching_on');
2054 unlink(WP_CONTENT_DIR . '/object-cache.php');
2055 }
2056 }
2057 }
2058
2059 /**
2060 * Minify HTML files automatically
2061 * at Zuziko.com
2062 * March 5, 2021 by David Green
2063 */
2064 class FLHM_HTML_Compression
2065 {
2066 protected $flhm_compress_css = true;
2067 protected $flhm_compress_js = true;
2068 protected $flhm_info_comment = true;
2069 protected $flhm_remove_comments = true;
2070 protected $html;
2071 public function __construct($html)
2072 {
2073 if (!empty($html)) {
2074 $this->flhm_parseHTML($html);
2075 }
2076 }
2077 public function __toString()
2078 {
2079 return $this->html;
2080 }
2081 protected function flhm_bottomComment($raw, $compressed)
2082 {
2083 $raw = strlen($raw);
2084 $compressed = strlen($compressed);
2085 $savings = ($raw-$compressed) / $raw * 100;
2086 $savings = round($savings, 2);
2087 return '<!--HTML compressed, size saved '.$savings.'%. From '.$raw.' bytes, now '.$compressed.' bytes-->';
2088 }
2089 protected function flhm_minifyHTML($html)
2090 {
2091 $pattern = '/<(?<script>script).*?<\/script\s*>|<(?<style>style).*?<\/style\s*>|<!(?<comment>--).*?-->|<(?<tag>[\/\w.:-]*)(?:".*?"|\'.*?\'|[^\'">]+)*>|(?<text>((<[^!\/\w.:-])?[^<]*)+)|/si';
2092 preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
2093 $overriding = false;
2094 $raw_tag = false;
2095 $html = '';
2096 foreach ($matches as $token) {
2097 $tag = (isset($token['tag'])) ? strtolower($token['tag']) : null;
2098 $content = $token[0];
2099 if (is_null($tag)) {
2100 if (!empty($token['script'])) {
2101 $strip = $this->flhm_compress_js;
2102 } elseif (!empty($token['style'])) {
2103 $strip = $this->flhm_compress_css;
2104 } elseif ($content == '<!--wp-html-compression no compression-->') {
2105 $overriding = !$overriding;
2106 continue;
2107 } elseif ($this->flhm_remove_comments) {
2108 if (!$overriding && $raw_tag != 'textarea') {
2109 $content = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $content);
2110 }
2111 }
2112 } else {
2113 if ($tag == 'pre' || $tag == 'textarea') {
2114 $raw_tag = $tag;
2115 } elseif ($tag == '/pre' || $tag == '/textarea') {
2116 $raw_tag = false;
2117 } else {
2118 if ($raw_tag || $overriding) {
2119 $strip = false;
2120 } else {
2121 $strip = true;
2122 $content = preg_replace('/(\s+)(\w++(?<!\baction|\balt|\bcontent|\bsrc)="")/', '$1', $content);
2123 $content = str_replace(' />', '/>', $content);
2124 }
2125 }
2126 }
2127 if ($strip) {
2128 $content = $this->flhm_removeWhiteSpace($content);
2129 }
2130 $html .= $content;
2131 }
2132 return $html;
2133 }
2134 public function flhm_parseHTML($html)
2135 {
2136 $this->html = $this->flhm_minifyHTML($html);
2137 if ($this->flhm_info_comment) {
2138 $this->html .= "\n" . $this->flhm_bottomComment($html, $this->html);
2139 }
2140 }
2141 protected function flhm_removeWhiteSpace($str)
2142 {
2143 $str = str_replace("\t", ' ', $str);
2144 $str = str_replace("\n", '', $str);
2145 $str = str_replace("\r", '', $str);
2146 $str = str_replace("// The customizer requires postMessage and CORS (if the site is cross domain).", '', $str);
2147 while (stristr($str, ' ')) {
2148 $str = str_replace(' ', ' ', $str);
2149 }
2150 return $str;
2151 }
2152 }
2153 function flhm_wp_html_compression_finish($html)
2154 {
2155 return new FLHM_HTML_Compression($html);
2156 }
2157
2158