PluginProbe
LWS Optimize – All-in-One Speed Booster & Cache Tools / 1.9
LWS Optimize – All-in-One Speed Booster & Cache Tools v1.9
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.9, at lws-optimize.php

1,592 lines 58.9 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.9
8 * Author: LWS
9 * Author URI: https://www.lws.fr
10 * Tested up to: 6.3
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 * Load translations, constants, hooks...
25 */
26 add_action('init', 'lws_op_loading');
27 function lws_op_loading()
28 {
29 if ( defined( 'WP_CLI' ) ) {
30 exit;
31 }
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 if (get_option('lws_opti_memcaching_on')) {
41 if (!file_exists(WP_CONTENT_DIR . '/object-cache.php')) {
42 file_put_contents(WP_CONTENT_DIR . '/object-cache.php', file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
43 }
44 }
45 }
46
47 function lws_op_cron_schedule($schedules)
48 {
49 $schedules[ 'threeminutes' ] = array( 'interval' => 3 * MINUTE_IN_SECONDS, 'display' => __('3 minutes') );
50 return $schedules;
51 }
52 add_filter('cron_schedules', 'lws_op_cron_schedule');
53
54 /**
55 * Create, if not already existing, a directory for the file-based cache
56 */
57 register_activation_hook(__FILE__, 'lws_op_on_activation');
58 function lws_op_on_activation()
59 {
60 set_transient('lwsop_remind_me', 691200);
61 if (!file_exists(wp_upload_dir()['basedir'] . '/lws_optimize')) {
62 @mkdir(wp_upload_dir()['basedir'] . '/lws-optimize', 0755);
63 }
64 }
65
66 /**
67 * Remove the created directory on delete
68 */
69 register_uninstall_hook(__FILE__, 'lws_op_on_delete');
70 function lws_op_on_delete()
71 {
72 $options = array(
73 'lws_op_exclude_min_css', 'lws_op_exclude_combine_css',
74 'lws_op_exclude_min_js', 'lws_op_exclude_combine_js', 'lws_op_exclude_defer_js',
75 'lws_op_exclude_min_html', 'lws_op_min_css', 'lws_op_combine_css', 'lws_op_preload_css',
76 'lws_op_min_js', 'lws_op_combine_js', 'lws_op_defer_js',
77 'lws_op_min_html', 'lws_op_delete_emoji', 'lws_op_remove_query',
78 'lws_opti_memcaching_on',
79 'lws_op_fb_cache',
80 'lws_op_compress_js',
81 'lws_op_compress_css',
82 'lws_op_force_no_lazyload_video',
83 'lws_op_force_lazyload_video',
84 'lws_op_deactivate_lazyload_iframe',
85 'lws_op_deactivate_lazyload_image',
86 'lws_op_exclude_min_css_array',
87 'lws_op_exclude_combine_css_array',
88 'lws_op_exclude_min_js_array',
89 'lws_op_exclude_combine_js_array',
90 'lws_op_exclude_defer_js_array',
91 'lws_op_exclude_min_html_array',
92 'lws_op_autoconvert_compression',
93 'lws_op_autoconvert_webp',
94 'lws_op_deactivate_lazyload',
95 'lws_op_change_max_width_media',
96 );
97
98 foreach ($options as $option){
99 delete_option($option);
100 }
101 rmdir(wp_upload_dir()['basedir'] . '/lws-optimize');
102
103 lws_op_uncompress_all_to_jpeg();
104 lws_op_delete_webp_files();
105 }
106
107 register_deactivation_hook(__FILE__, 'lws_op_on_deactivate');
108 function lws_op_on_deactivate()
109 {
110 rmdir(wp_upload_dir()['basedir'] . '/lws-optimize');
111 }
112
113 /**
114 * Enqueue any CSS or JS script needed
115 */
116 add_action('admin_enqueue_scripts', 'lws_op_scripts');
117 function lws_op_scripts()
118 {
119 if (get_current_screen()->base == ('toplevel_page_lws-op-config')) {
120 wp_enqueue_style('lws_op_css', LWS_OP_URL . "css/lws_op_stylesheet.css");
121 wp_enqueue_style('lws_cl-Poppins', 'https://fonts.googleapis.com/css?family=Poppins');
122 }
123 else{
124 wp_enqueue_style('lws_top_css_out', LWS_OP_URL . "css/lws_op_stylesheet_out.css");
125 if (!get_transient('lwsop_remind_me') && !get_option('lwsop_do_not_ask_again') && !get_option('lws_op_deactivated')){
126 add_action( 'admin_notices', 'lwsop_review_ad_plugin' );
127 }
128 }
129 }
130
131 function lwsop_review_ad_plugin(){
132 ?>
133 <script>
134 function lwsop_remind_me(){
135 var data = {
136 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('reminder_for_op')); ?>',
137 action: "lws_op_reminder_ajax",
138 data: true,
139 };
140 jQuery.post(ajaxurl, data, function(response){
141 jQuery("#lwsop_review_notice").addClass("animationFadeOut");
142 setTimeout(() => {
143 jQuery("#lwsop_review_notice").addClass("lws_hidden");
144 }, 800);
145 });
146
147 }
148
149 function lwsop_do_not_bother_me(){
150 var data = {
151 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('donotask_for_op')); ?>',
152 action: "lws_op_donotask_ajax",
153 data: true,
154 };
155 jQuery.post(ajaxurl, data, function(response){
156 jQuery("#lwsop_review_notice").addClass("animationFadeOut");
157 setTimeout(() => {
158 jQuery("#lwsop_review_notice").addClass("lws_hidden");
159 }, 800);
160 });
161 }
162 </script>
163
164 <div class="notice notice-info is-dismissible lwsop_review_block_general" id="lwsop_review_notice">
165 <div class="lwsop_circle">
166 <img class="lwsop_review_block_image" src="<?php echo esc_url(plugins_url('images/plugin_lws-optimize.svg', __FILE__))?>" width="40px" height="40px">
167 </div>
168 <div style="padding:16px">
169 <h1 class="lwsop_review_block_title"> <?php esc_html_e('Thank you for using LWS Optimize!', 'lws-optimize'); ?></h1>
170 <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>
171 <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>
172 <a class="lwsop_review_button_secondary" onclick="lwsop_remind_me()"><?php esc_html_e('Remind me later', 'lws-optimize'); ?></a>
173 <a class="lwsop_review_button_secondary" onclick="lwsop_do_not_bother_me()"><?php esc_html_e('Do not ask again', 'lws-optimize'); ?></a>
174 </div>
175 </div>
176 <?php
177 }
178
179 //AJAX Reminder//
180 add_action("wp_ajax_lws_op_reminder_ajax", "lws_op_remind_me_later");
181 function lws_op_remind_me_later(){
182 check_ajax_referer('reminder_for_op', '_ajax_nonce');
183 if (isset($_POST['data'])){
184 set_transient('lwsop_remind_me', 2592000);
185 }
186 }
187
188 //AJAX Reminder//
189 add_action("wp_ajax_lws_op_donotask_ajax", "lws_op_do_not_ask");
190 function lws_op_do_not_ask(){
191 check_ajax_referer('donotask_for_op', '_ajax_nonce');
192 if (isset($_POST['data'])){
193 update_option('lwsop_do_not_ask_again', true);
194 }
195 }
196
197
198
199
200 /**
201 * Create plugin menu in wp-admin
202 */
203 add_action('admin_menu', 'lws_op_menu_admin');
204 function lws_op_menu_admin()
205 {
206 $menu_slug = 'lws-op-config';
207 add_menu_page(__('LWS Optimize', 'lws-optimize'), 'LWS Optimize', 'manage_options', $menu_slug, 'lws_op_page', LWS_OP_URL . 'images/plugin_lws_optimize.svg');
208 }
209
210
211 // ALL FUNCTIONS DEDICATED TO THE FRONTEND TAB ###
212 //
213 //
214 /**
215 * Minimize HTML to reduce size and improve performances
216 */
217
218 if (get_option('lws_op_min_html')) {
219 add_action('wp_head', 'lws_op_minimize_html');
220 function lws_op_minimize_html()
221 {
222 global $wp;
223 $url = home_url($wp->request);
224 if ($exclude_html = json_decode(get_option('lws_op_exclude_min_html_array'), true)) {
225 if (!in_array($url, $exclude_html)) {
226 ob_start("flhm_wp_html_compression_finish");
227 }
228 } else {
229 ob_start("flhm_wp_html_compression_finish");
230 }
231 }
232 }
233
234
235 function lws_op_check_compatibility(){
236 // If another plugin in the same vein as WP Rocket is installed, deactivate the plugin
237 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')
238 || 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')){
239 update_option('lws_op_deactivated', true);
240 add_action( 'admin_notices', 'lws_op_other_cache_plugin' );
241 } else{
242 if (get_option('lws_op_deactivated') !== "blocked"){
243 delete_option('lws_op_deactivated', true);
244 }
245 }
246 }
247 add_action( 'admin_init', 'lws_op_check_compatibility' );
248
249 function lws_op_other_cache_plugin() {
250 ?>
251 <div class="notice notice-warning is-dismissible" style="padding-bottom: 10px;">
252 <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>
253 <?php if (is_plugin_active('wp-rocket/wp-rocket.php')) : ?>
254 <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>
255 <?php endif ?>
256 <?php if (is_plugin_active('powered-cache/powered-cache.php')) : ?>
257 <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>
258 <?php endif ?>
259 <?php if (is_plugin_active('wp-super-cache/wp-cache.php')) : ?>
260 <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>
261 <?php endif ?>
262 <?php if (is_plugin_active('wp-optimize/wp-optimize.php')) : ?>
263 <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>
264 <?php endif ?>
265 <?php if (is_plugin_active('wp-fastest-cache/wpFastestCache.php')) : ?>
266 <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>
267 <?php endif ?>
268 <?php if (is_plugin_active('w3-total-cache/w3-total-cache.php')) : ?>
269 <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>
270 <?php endif ?>
271 </div>
272
273 <script>
274 document.querySelectorAll('a[id^="lwsop_deactivate_button_"]').forEach(function(element){
275 element.addEventListener('click', function(event){
276 let id = (element.id).replace('lwsop_deactivate_button_', '');
277 this.parentNode.parentNode.style.pointerEvents = "none";
278 this.innerHTML = `
279 <img src="<?php echo plugin_dir_url(__FILE__); ?>/images/loading_black.svg" width="20px">
280 `;
281 var data = {
282 _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('deactivate_plugin_lwsoptimize')); ?>',
283 action: "lws_op_other_cache_plugin_ajax",
284 data: {id: id},
285 };
286 jQuery.post(ajaxurl, data, function(response){
287 location.reload();
288 });
289 })
290 });
291 </script>
292 <?php
293 }
294
295 // Greatly inspired by wp-super-minify @https://dipakgajjar.com/
296 // With the use of MrClay librairies
297 function lwsop_minify_html ($buffer) {
298 $path = plugin_dir_path( __FILE__ ) . 'classes/min';
299 $initial = strlen($buffer);
300
301 if (!class_exists('Minify_HTML')) {
302 require_once("$path/lib/Minify/HTML.php");
303 ini_set('include_path', ini_get('include_path').":$path/lib");
304 require_once("$path/lib/Minify/CSS.php");
305 require_once("$path/lib/JSMin.php");
306 require ("$path/lib/Minify/Loader.php");
307 Minify_Loader::register();
308 }
309
310 if (get_option('lws_op_compress_js')) {
311 $buffer = Minify_HTML::minify($buffer, array('jsMinifier' => array('JSMin', 'minify')));
312 }
313 if (get_option('lws_op_compress_css')) {
314 $buffer = Minify_HTML::minify($buffer, array('cssMinifier' => array('Minify_CSS', 'minify')));
315 }
316
317 $final = strlen($buffer);
318 $savings = round((($initial-$final)/$initial*100), 3);
319
320 // $buffer .= "<br/><!-- Uncompressed size: $initial bytes; Compressed size: $final bytes; $savings% savings -->";
321
322 if ($savings != 0) {
323 $buffer .= PHP_EOL . '<!--' . PHP_EOL . '*** Total size saved: ' . $savings . '% | Size before compression: ' . $initial . ' bytes | Size after compression: ' . $final . ' bytes. ***' . PHP_EOL . '-->';
324 }
325
326 return $buffer;
327 // }
328 }
329
330 // Minifying HTML
331 function lwsop_minify() {
332 if (get_option('lws_op_compress_js') || get_option('lws_op_compress_css')) {
333 ob_start('lwsop_minify_html');
334 }
335 }
336
337 add_action('get_header', 'lwsop_minify');
338
339 function lws_op_page()
340 {
341 global $wp_styles, $wp_scripts, $wpdb;
342 $frontend_opti_css = array();
343 $frontend_opti_js = array();
344 $frontend_opti_html = array();
345 $tabs_list = array(
346 array('frontend', __('Frontend', 'lws-optimize')),
347 array('medias', __('Medias', 'lws-optimize')),
348 array('caching', __('Caching', 'lws-optimize')),
349 array('plugins', __('Our others plugins', 'lws-optimize')),
350 );
351
352 //FRONTEND//
353
354 $all_options = array(
355 'lws_op_compress_js' => array(
356 __('Compress (Minify + Combine) all JS files for faster performances', 'lws-optimize'),
357 __('Compress your JS files for better performances and faster page load', 'lws-optimize'),
358 ),
359 'lws_op_compress_css' => array(
360 __('Compress (Minify + Combine) all CSS files for faster performances', 'lws-optimize'),
361 __('Compress you CSS files for faster loading and smaller files', 'lws-optimize'),
362 ),
363 'lws_op_preload_css' => array(
364 __('Preload CSS files', 'lws-optimize'),
365 __('Preload CSS files for a faster loading time', 'lws-optimize'),
366 ),
367 'lws_op_defer_js' => array(
368 __('Defer loading of JavaScript files', 'lws-optimize'),
369 __('Defer loading of JavaScript files for faster loading times', 'lws-optimize'),
370 ),
371 'lws_op_delete_emoji' => array(
372 __('Remove Wordpress emoji support from your site', 'lws-optimize'),
373 __('Remove Wordpress emoji loading to speed up the loading of your website', 'lws-optimize'),
374 ),
375 'lws_op_remove_query' => array(
376 __('Remove useless queries', 'lws-optimize'),
377 __('Remove useless queries from static files (CSS, JS...), especially "?ver" queries', 'lws-optimize'),
378 ),
379 );
380
381 if (isset($_POST['lws_op_frontend'])) :
382 foreach ($all_options as $option => $text) {
383 isset($_POST[$option]) ? update_option($option, true) : delete_option($option);
384 }
385 endif;
386
387 //MEDIA
388
389 $media_to_webp = array(
390 // 'autoconvert_compression' =>
391 // array(
392 // __('Compressing all images', 'lws-optimize'),
393 // __('Compress all images without quality loss to reduce sizes.', 'lws-optimize'),
394 // array(
395 // __('Compress', 'lws-optimize'),
396 // __('Compressed', 'lws-optimize'),
397 // __('Uncompress', 'lws-optimize'),
398 // __('Uncompressed', 'lws-optimize'),
399 // ),
400 // true, //Recommanded
401 // ),
402 'autoconvert_webp' =>
403 array(
404 __('Converting all images to the WEBP extension', 'lws-optimize'),
405 __('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'),
406 array(
407 __('Convert', 'lws-optimize'),
408 __('Converted', 'lws-optimize'),
409 __('Unconvert', 'lws-optimize'),
410 __('Unconverted', 'lws-optimize'),
411 ),
412 true, //Recommanded
413 ),
414 'change_max_width_media' =>
415 array(
416 __('Reducing the maximum width of an image', 'lws-optimize'),
417 __('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'),
418 array(
419 __('Modify', 'lws-optimize'),
420 __('Modified', 'lws-optimize'),
421 __('Modify', 'lws-optimize'),
422 __('Modified', 'lws-optimize'),
423 ),
424 false
425 ),
426 'deactivate_lazyload_iframe' =>
427 array(
428 __('Lazy loading for all iframe elements', 'lws-optimize'),
429 false, //No subtext
430 array(
431 __('Deactivate lazy loading', 'lws-optimize'),
432 __('Deactivated', 'lws-optimize'),
433 __('Activate lazy loading', 'lws-optimize'),
434 __('Activated', 'lws-optimize'),
435
436 ),
437 false,
438 ),
439 'deactivate_lazyload_image' =>
440 array(
441 __('Lazy loading for all image elements', 'lws-optimize'),
442 false,
443 array(
444 __('Deactivate lazy loading', 'lws-optimize'),
445 __('Deactivated', 'lws-optimize'),
446 __('Activate lazy loading', 'lws-optimize'),
447 __('Activated', 'lws-optimize'),
448
449 ),
450 false,
451 ),
452 'deactivate_lazyload' =>
453 array(
454 __('Lazy loading on the website', 'lws-optimize'),
455 false,
456 array(
457 __('Deactivate lazy loading', 'lws-optimize'),
458 __('Deactivated', 'lws-optimize'),
459 __('Activate lazy loading', 'lws-optimize'),
460 __('Activated', 'lws-optimize'),
461 ),
462 false,
463 ),
464 'force_lazyload_video' =>
465 array(
466 __('Forcing preloading of all video and audio elements', 'lws-optimize'),
467 false,
468 array(
469 __('Force preloading', 'lws-optimize'),
470 __('Forced', 'lws-optimize'),
471 __('Unforce preloading', 'lws-optimize'),
472 __('Unforced', 'lws-optimize'),
473 ),
474 false,
475 ),
476 'force_no_lazyload_video' =>
477 array(
478 __('Forcing no preloading of all video and audio elements', 'lws-optimize'),
479 false,
480 array(
481 __('Force the deactivation', 'lws-optimize'),
482 __('Forced', 'lws-optimize'),
483 __('Unforce the deactivation', 'lws-optimize'),
484 __('Unforced', 'lws-optimize'),
485 ),
486 false,
487 ),
488 );
489
490 get_option('lws_op_change_max_width_media') ? '' : update_option('lws_op_change_max_width_media', '2560');
491
492 $list_width = array(
493 '7680' => '7680px',
494 '3840' => '3840px',
495 '2560' => '2560px',
496 '1920' => '1920px',
497 '1080' => '1080px',
498 'disabled' => __('Disabled', 'lws-optimize'),
499 );
500
501 function dir_is_empty($dir)
502 {
503 $handle = opendir($dir);
504 while (false !== ($entry = readdir($handle))) {
505 if ($entry != "." && $entry != "..") {
506 closedir($handle);
507 return false;
508 }
509 }
510 closedir($handle);
511 return true;
512 }
513
514 $is_cache_empty = dir_is_empty(wp_upload_dir()['basedir'] . "/lws-optimize/");
515
516 include __DIR__ . '/views/tabs.php';
517 }
518
519
520 /**
521 * The loading of all JS scripts is done in parallel of the page loading, making for faster page load time
522 */
523 if (get_option('lws_op_defer_js') && !get_option('lws_op_deactivated')) {
524 add_filter('script_loader_tag', 'lws_op_defer_filter', 10, 3);
525 function lws_op_defer_filter($tag, $handle, $src)
526 {
527 if (!is_admin()) {
528 $tag = str_replace('></script>', ' defer></script>', $tag);
529 }
530 return $tag;
531 }
532 }
533
534 /**
535 * Preload all CSS scripts, for faster speed
536 */
537 if (get_option('lws_op_preload_css') && !get_option('lws_op_deactivated')) {
538 add_filter( 'style_loader_tag', 'lws_op_preload_filter', 10, 2 );
539 function lws_op_preload_filter( $html, $handle ){
540 if (strcmp($handle, 'preload-style') == 0) {
541 $fallback = '<noscript>' . $html . '</noscript>';
542 $preload = str_replace("rel='stylesheet'", "rel='preload' as='style' onload='this.rel=\"stylesheet\"'", $html);
543 $html = $preload . $fallback;
544 }
545 return $html;
546 }
547 }
548
549 /**
550 * Remove the ?ver= query on the CSS/JS files
551 * Can help with caching
552 */
553 if (get_option('lws_op_remove_query') && !get_option('lws_op_deactivated')) {
554 add_filter('style_loader_src', 'lws_op_remove_scripts_static', 10);
555 add_filter('script_loader_src', 'lws_op_remove_scripts_static', 10);
556
557 function lws_op_remove_scripts_static($src)
558 {
559 if (strpos($src, '?ver=')) {
560 $src = remove_query_arg('ver', $src);
561 }
562 return $src;
563 }
564 }
565
566 /**
567 * Disable emojis in WordPress => Emojis are still active, but managed by the visitor's browser instead of the server
568 * Better loading time as there is less files to load
569 */
570 if (get_option('lws_op_delete_emoji') && !get_option('lws_op_deactivated')) {
571 add_action('init', 'lws_op_disable_emojis');
572 function lws_op_disable_emojis()
573 {
574 remove_action('wp_head', 'print_emoji_detection_script');
575 remove_action('admin_print_scripts', 'print_emoji_detection_script');
576 remove_action('wp_print_styles', 'print_emoji_styles');
577 remove_filter('the_content_feed', 'wp_staticize_emoji');
578 remove_action('admin_print_styles', 'print_emoji_styles');
579 remove_filter('comment_text_rss', 'wp_staticize_emoji');
580 remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
581 add_filter('tiny_mce_plugins', 'lws_op_disable_emojis_tinymce');
582 }
583
584 function lws_op_disable_emojis_tinymce($plugins)
585 {
586 if (is_array($plugins)) {
587 return array_diff($plugins, array('wpemoji'));
588 } else {
589 return array();
590 }
591 }
592 }
593 //
594 //
595 // END OF FRONTEND-RELATED FUNCTIONS ###
596
597
598 // FUNCTIONS RELATED TO THE MEDIAS TAB ###
599 //
600 //
601 /**
602 * Convert all images to JPEG for better size. Duplicate saved as .old to unconvert
603 */
604 function lws_op_compress_all_to_jpeg()
605 {
606 $args = array(
607 'numberposts' => -1,
608 'post_type' => 'attachment',
609 );
610 $attachments = get_posts($args);
611 foreach ($attachments as $a) {
612 if (explode('/', $a->post_mime_type)[0] == 'image') {
613 $metadata = wp_get_attachment_metadata($a->ID);
614 $path = get_attached_file($a->ID);
615 copy($path, $path . '.old');
616 lws_op_compress_to_jpeg($path, $path, 60);
617
618 foreach ($metadata['sizes'] as $size => $data) {
619 $size_path = explode('/', $path);
620 $size_path = implode('/', array_replace($size_path, [(count($size_path) -1) => $data['file']]));
621 copy($size_path, $size_path . '.old');
622 lws_op_compress_to_jpeg($path, $path, 60);
623 }
624 }
625 }
626 }
627
628 /**
629 * Unconvert all images from JPEG to their original type from the .old saved
630 * If there is no original file, do nothing
631 */
632 function lws_op_uncompress_all_to_jpeg()
633 {
634 $args = array(
635 'numberposts' => -1,
636 'post_type' => 'attachment',
637 );
638 $attachments = get_posts($args);
639 foreach ($attachments as $a) {
640 if (explode('/', $a->post_mime_type)[0] == 'image') {
641 $metadata = wp_get_attachment_metadata($a->ID);
642 $path = get_attached_file($a->ID);
643 if (file_exists($path . '.old')) {
644 @rename($path. '.old', $path);
645 // if ($a->post_mime_type == 'image/webp') {
646 // $tmp = explode('.', $path);
647 // array_pop($tmp);
648 // $tmp = implode('.', $tmp);
649 // @rename($tmp. '.old', $tmp);
650 // }
651
652 foreach ($metadata['sizes'] as $size => $data) {
653 $size_path = explode('/', $path);
654 $size_path = implode('/', array_replace($size_path, [(count($size_path) -1) => $data['file']]));
655 @rename($size_path . '.old', $size_path);
656 //if ($a->post_mime_type == 'image/webp') {
657 // $tmp = explode('.', $size_path);
658 // array_pop($tmp);
659 // $tmp = implode('.', $tmp);
660 // @rename($tmp. '.old', $tmp);
661 // }
662 }
663 }
664 }
665 }
666 }
667
668 /**
669 * In charge of converting all the files given to it by lws_op_compress_all_to_jpeg()
670 * The source will be used to create the destination
671 */
672 function lws_op_compress_to_jpeg($source, $destination, $qualite = 75)
673 {
674 $info = getimagesize($source);
675
676 switch($info['mime']) {
677 case 'image/jpeg':
678 $image = imagecreatefromjpeg($source);
679 break;
680 case 'image/gif':
681 $image = imagecreatefromgif($source);
682 break;
683 case 'image/png':
684 $image = imagecreatefrompng($source);
685 break;
686 case 'image/webp':
687 $image = imagecreatefromwebp($source);
688 break;
689 default:
690 $image = imagecreatefromjpeg($source);
691 break;
692 }
693
694 imagejpeg($image, $destination, $qualite);
695
696 return $destination;
697 }
698
699 /**
700 * Given a PATH, create a new WEBP file at the same place
701 * Original files will not be deleted to revert the changes later
702 */
703 function lws_op_generate_webp_file($filepath)
704 {
705 if (!file_exists($filepath)) {
706 return false;
707 }
708
709 // Get image type.
710 $image_type = exif_imagetype($filepath);
711
712 switch ($image_type) {
713 case IMAGETYPE_GIF:
714 $im = imagecreatefromgif($filepath);
715 break;
716 case IMAGETYPE_JPEG:
717 $im = imagecreatefromjpeg($filepath);
718 break;
719 case IMAGETYPE_PNG:
720 $im = imagecreatefrompng($filepath);
721 break;
722 default:
723 return false;
724 }
725
726 $newImagePath = $filepath . '.webp';
727 imagepalettetotruecolor($im);
728 imagealphablending($im, false);
729 imagesavealpha($im, true);
730 imagewebp($im, $newImagePath);
731
732 return $newImagePath;
733 }
734
735 // /**
736 // * Given a PATH, sizes a name and the original file sizes, create a new WEBP file with a specific size
737 // * Original files will not be deleted to revert the changes later
738 // */
739 // function lws_op_generate_webp_file_sized($filepath, $width, $height, $bw, $bh, $name)
740 // {
741 // if (!file_exists($filepath)) {
742 // return false;
743 // }
744
745 // // Get image type.
746 // $image_type = exif_imagetype($filepath);
747
748 // switch ($image_type) {
749 // case IMAGETYPE_GIF:
750 // $im = imagecreatefromgif($filepath);
751 // break;
752 // case IMAGETYPE_JPEG:
753 // $im = imagecreatefromjpeg($filepath);
754 // break;
755 // case IMAGETYPE_PNG:
756 // $im = imagecreatefrompng($filepath);
757 // break;
758 // default:
759 // return false;
760 // }
761
762
763 // $newImagePath = $filepath . '.webp';
764 // $new_image = imagecreatetruecolor($width, $height);
765
766 // imagepalettetotruecolor($im);
767 // imagealphablending($im, false);
768 // imagesavealpha($im, true);
769
770 // imagecopyresampled($new_image, $im, 0, 0, 0, 0, $width, $height, $bw, $bh);
771 // imagewebp($im, $newImagePath);
772 // return $newImagePath;
773 // }
774
775
776 add_action('lws_op_hook_convert_webp', 'lws_op_convert_all_to_webp', 15);
777 add_action('lws_op_hook_unconvert_webp', 'lws_op_delete_webp_files', 8);
778
779
780 /**
781 * Once activated, will convert all current images to WEBP
782 * Original files will not be deleted to revert the changes later
783 */
784 function lws_op_convert_all_to_webp()
785 {
786 global $wpdb;
787 $args = array(
788 'numberposts' => -1,
789 'post_type' => 'attachment',
790 );
791 $attachments = get_posts($args);
792 foreach ($attachments as $a) {
793 if (explode('/', $a->post_mime_type)[0] == 'image' && $a->post_mime_type != 'image/webp') {
794 $id = $a->ID;
795 $path = get_attached_file($id);
796 @rename($path. '.old', $path);
797 lws_op_generate_webp_file($path);
798
799 $meta_value = $wpdb->get_var(
800 $wpdb->prepare(
801 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
802 $id
803 )
804 );
805
806 wp_update_post(array('ID' => $id, 'post_mime_type' => 'image/webp'));
807 $wpdb->query(
808 $wpdb->prepare(
809 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
810 $meta_value . '.webp',
811 $id
812 )
813 );
814
815 require_once(ABSPATH . 'wp-admin/includes/image.php');
816 $imagePath = $path . ".webp";
817
818 if ($imagePath && file_exists($imagePath)) {
819 wp_generate_attachment_metadata($id, $imagePath);
820 }
821 }
822 }
823
824 lws_op_update_posts_webp("convert");
825 }
826
827 /**
828 * Once activated, will unconvert all current images to their orignal type
829 * If there is no original file, do nothing
830 */
831 function lws_op_delete_webp_files()
832 {
833 global $wpdb;
834 $args = array(
835 'numberposts' => -1,
836 'post_type' => 'attachment',
837 );
838 $attachments = get_posts($args);
839
840 foreach ($attachments as $a) {
841 if (explode('/', $a->post_mime_type)[0] == 'image' && $a->post_mime_type == 'image/webp') {
842 $id = $a->ID;
843 $path = get_attached_file($id);
844 $filename = basename($path);
845 $extension = explode('.', $filename);
846 array_pop($extension);
847
848 $new_path = implode('.', $extension);
849 $extension = end($extension);
850 $dirname = dirname($path);
851 $new_path = $dirname . '/' . $new_path;
852
853 if (file_exists($new_path)) {
854 rename($path. '.old', $path);
855 unlink($path);
856
857 $meta_value = $wpdb->get_var(
858 $wpdb->prepare(
859 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
860 $id
861 )
862 );
863 $meta_value = explode('.', $meta_value);
864 array_pop($meta_value);
865 $meta_value = implode('.', $meta_value);
866 wp_update_post(array('ID' => $id, 'post_mime_type' => 'image/' . $extension));
867 $wpdb->query(
868 $wpdb->prepare(
869 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
870 $meta_value,
871 $id
872 )
873 );
874 }
875
876 require_once(ABSPATH . 'wp-admin/includes/image.php');
877
878 if ($new_path && file_exists($new_path)) {
879 wp_generate_attachment_metadata($id, $new_path);
880 }
881 }
882 }
883
884 lws_op_update_posts_webp("restore");
885 }
886
887 /**
888 * When a new file is uploaded, if activated, will compress it (if is an image)
889 */
890 if (get_option('lws_op_autoconvert_compression') && !get_option('lws_op_deactivated')) {
891 add_filter('wp_generate_attachment_metadata', 'lws_op_compress_to_jpeg_upload', 15, 2);
892 function lws_op_compress_to_jpeg_upload($metadata, $attachment_id)
893 {
894 if (isset($metadata['sizes'])){
895 if (isset($metadata['sizes']['mime-type'])){
896 if (explode('/', reset($metadata['sizes'])['mime-type'])[0] == 'image') {
897 $path = get_attached_file($attachment_id);
898
899 copy($path, $path . '.old');
900 lws_op_compress_to_jpeg($path, $path, 60);
901
902 foreach ($metadata['sizes'] as $size => $data) {
903 $path = explode('/', $path);
904 array_pop($path);
905 $path[] = $data['file'];
906 $path = implode('/', $path);
907 copy($path, $path . '.old');
908 lws_op_compress_to_jpeg($path, $path, 60);
909 }
910 }
911 }
912 }
913 }
914 }
915
916 /**
917 * When a new file is uploaded, if activated, will convert it to WEBP (if not already)
918 */
919 if (get_option('lws_op_autoconvert_webp') && !get_option('lws_op_deactivated')) {
920 add_filter('wp_generate_attachment_metadata', 'lws_op_webp_upload', 10, 2);
921 function lws_op_webp_upload($metadata, $attachment_id)
922 {
923 global $wpdb;
924
925 if (isset($metadata['sizes'])){
926 if (isset($metadata['sizes']['mime-type'])){
927 if (explode('/', reset($metadata['sizes'])['mime-type'])[0] == 'image' && reset($metadata['sizes'])['mime-type'] != 'image/webp') {
928 $meta = $metadata;
929 $path = get_attached_file($attachment_id);
930 lws_op_generate_webp_file($path);
931 $meta['file'] .= '.webp';
932
933 $meta_value = $wpdb->get_var(
934 $wpdb->prepare(
935 "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d",
936 $attachment_id
937 )
938 );
939 wp_update_post(array('ID' => $attachment_id, 'post_mime_type' => 'image/webp'));
940 $wpdb->get_var(
941 $wpdb->prepare(
942 "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE post_id = %d AND meta_key = '_wp_attached_file'",
943 $meta_value . '.webp',
944 $attachment_id
945 )
946 );
947
948 require_once(ABSPATH . 'wp-admin/includes/image.php');
949 wp_generate_attachment_metadata($attachment_id, $meta['file']);
950 return $meta;
951 }
952 }
953 }
954
955 return $metadata;
956 }
957 }
958
959
960 /**
961 * TODO
962 */
963 //add_action('delete_attachment', 'lws_op_restore_file_to_default_before_delete');
964 function lws_op_restore_file_to_default_before_delete($attachment_id, $post)
965 {
966 }
967
968 function lws_op_update_posts_webp($usage)
969 {
970 global $wpdb;
971 $args = array(
972 'numberposts' => -1,
973 'post_type' => 'attachment',
974 );
975 $attachments = get_posts($args);
976 foreach ($attachments as $a) {
977 if (explode('/', $a->post_mime_type)[0] == 'image') {
978 $id = $a->ID;
979 $url = wp_get_attachment_url($id);
980 if ($usage == "convert") {
981 $elements = $wpdb->get_results(
982 $wpdb->prepare(
983 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
984 WHERE post_content LIKE %s
985 ",
986 $url . '"',
987 $url . '.webp"',
988 '%' . $url . '"%'
989 )
990 );
991 } else {
992 $url = explode('.', $url);
993 array_pop($url);
994 $url = implode('.', $url);
995 $file = str_replace(get_site_url() . '/', ABSPATH, $url);
996 if (file_exists($file)) {
997 $exists = true;
998 $wpdb->get_results(
999 $wpdb->prepare(
1000 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1001 WHERE post_content LIKE %s
1002 ",
1003 $url . '.webp',
1004 $url,
1005 '%' . $url . '"%'
1006 )
1007 );
1008 }
1009 }
1010
1011 $meta = wp_get_attachment_metadata($id);
1012 foreach ($meta['sizes'] as $key => $size) {
1013 $name = $size['file'];
1014 if ($usage == "convert") {
1015 $name = explode('.', $size['file']);
1016 array_pop($name);
1017 $name = implode('.', $name);
1018
1019 $url = explode('/', wp_get_attachment_url($id));
1020 array_pop($url);
1021 $url[] = $name;
1022 $url = implode('/', $url);
1023
1024 $wpdb->get_results(
1025 $wpdb->prepare(
1026 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1027 WHERE post_content LIKE %s
1028 ",
1029 $url . '"',
1030 $url . '.webp"',
1031 '%' . $url . '"%'
1032 )
1033 );
1034 } else {
1035 $url = explode('/', wp_get_attachment_url($id));
1036 array_pop($url);
1037 $url[] = $name;
1038 $url = implode('/', $url);
1039 $file = str_replace(get_site_url() . '/', ABSPATH, $url);
1040 if (file_exists($file)) {
1041 $exists = true;
1042 $wpdb->get_results(
1043 $wpdb->prepare(
1044 "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)
1045 WHERE post_content LIKE %s
1046 ",
1047 $url . '.webp',
1048 $url,
1049 '%' . $url . '"%'
1050 )
1051 );
1052 }
1053 }
1054 }
1055 }
1056 }
1057 }
1058 //
1059 //
1060 // END OF MEDIAS-RELATED FUNCTIONS ###
1061
1062 add_action(
1063 'wp', function () {
1064 if (get_option('lws_op_force_no_lazyload_video') && !get_option('lws_op_deactivated')) {
1065 function lws_op_disable_audio_video_lazy_loading()
1066 {
1067 global $wpdb;
1068
1069 $elements = $wpdb->get_results(
1070 $wpdb->prepare(
1071 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1072 '%<video%',
1073 )
1074 );
1075
1076 foreach ($elements as $element) {
1077 $element = $element->post_content;
1078 if (str_contains($element, 'preload="none"')) {
1079 $element = str_replace('preload="none"', 'preload="auto"', $element);
1080 }
1081
1082 $wpdb->get_results(
1083 $wpdb->prepare(
1084 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1085 $element,
1086 '%<video%',
1087 )
1088 );
1089 }
1090
1091 $elements = $wpdb->get_results(
1092 $wpdb->prepare(
1093 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1094 '%<audio%',
1095 )
1096 );
1097
1098 foreach ($elements as $element) {
1099 $element = $element->post_content;
1100 if (str_contains($element, 'preload="none"')) {
1101 $element = str_replace('preload="none"', 'preload="auto"', $element);
1102 }
1103
1104 $wpdb->get_results(
1105 $wpdb->prepare(
1106 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1107 $element,
1108 '%<audio%',
1109 )
1110 );
1111 }
1112 }
1113 lws_op_disable_audio_video_lazy_loading();
1114 }
1115
1116 if (get_option('lws_op_force_lazyload_video') && !get_option('lws_op_deactivated')) {
1117 function lws_op_force_audio_video_lazy_loading()
1118 {
1119 global $wpdb;
1120
1121 $elements = $wpdb->get_results(
1122 $wpdb->prepare(
1123 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1124 '%<video%'
1125 )
1126 );
1127
1128 foreach ($elements as $element) {
1129 $element = $element->post_content;
1130 if (str_contains($element, 'autoplay')) {
1131 $element = str_replace('autoplay', '', $element);
1132 }
1133 if (str_contains($element, 'preload="auto"')) {
1134 $element = str_replace('preload="auto"', 'preload="none"', $element);
1135 }
1136 if (str_contains($element, 'preload="metadata"')) {
1137 $element = str_replace('preload="metadata"', 'preload="none"', $element);
1138 }
1139
1140 $wpdb->get_results(
1141 $wpdb->prepare(
1142 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1143 $element,
1144 '%<video%'
1145 )
1146 );
1147 }
1148
1149 $elements = $wpdb->get_results(
1150 $wpdb->prepare(
1151 "SELECT post_content FROM {$wpdb->posts} WHERE post_content LIKE %s",
1152 '%<audio%',
1153 )
1154 );
1155
1156 foreach ($elements as $element) {
1157 $element = $element->post_content;
1158 if (str_contains($element, 'autoplay')) {
1159 $element = str_replace('autoplay', '', $element);
1160 }
1161 if (str_contains($element, 'preload="auto"')) {
1162 $element = str_replace('preload="auto"', 'preload="none"', $element);
1163 }
1164 if (str_contains($element, 'preload="metadata"')) {
1165 $element = str_replace('preload="metadata"', 'preload="none"', $element);
1166 }
1167
1168 $wpdb->get_results(
1169 $wpdb->prepare(
1170 "UPDATE {$wpdb->posts} SET post_content = %s WHERE post_content LIKE %s",
1171 $element,
1172 '%<audio%',
1173 )
1174 );
1175 }
1176 }
1177
1178 lws_op_force_audio_video_lazy_loading();
1179 }
1180
1181 if (get_option('lws_op_deactivate_lazyload')) {
1182 add_filter( 'wp_lazy_loading_enabled', '__return_false' );
1183 }
1184
1185 if (get_option('lws_op_deactivate_lazyload_image')) {
1186 add_filter('wp_lazy_loading_enabled', 'lws_op_disable_image_lazy_loading', 10, 3);
1187 function lws_op_disable_image_lazy_loading($default, $tag_name, $context)
1188 {
1189 global $wp_query;
1190 if ('img' === $tag_name && 'the_content' === $context) {
1191 return false;
1192 }
1193 return $default;
1194 }
1195 }
1196
1197 if (get_option('lws_op_deactivate_lazyload_iframe')) {
1198 add_filter('wp_lazy_loading_enabled', 'lws_op_disable_iframe_lazy_loading', 10, 3);
1199 //Allows to disable lazy_load on every tags chosen ; here 'iframe' or 'img'
1200 function lws_op_disable_iframe_lazy_loading($default, $tag_name, $context)
1201 {
1202 global $wp_query;
1203 if ('iframe' === $tag_name && 'the_content' === $context) {
1204 return false;
1205 }
1206 return $default;
1207 }
1208 }
1209 }
1210 );
1211
1212 add_action("wp_ajax_lws_op_other_cache_plugin_ajax", "lws_optimize_remove_other_cache");
1213 function lws_optimize_remove_other_cache()
1214 {
1215 check_ajax_referer('deactivate_plugin_lwsoptimize', '_ajax_nonce');
1216 if (isset($_POST['action'])) {
1217 if (isset($_POST['data'])){
1218 switch(htmlspecialchars($_POST['data']['id'])){
1219 case 'wprocket':
1220 deactivate_plugins('wp-rocket/wp-rocket.php');
1221 break;
1222 case 'pc':
1223 deactivate_plugins('powered-cache/powered-cache.php');
1224 break;
1225 case 'wpsc':
1226 deactivate_plugins('wp-super-cache/wp-cache.php');
1227 break;
1228 case 'wpo':
1229 deactivate_plugins('wp-optimize/wp-optimize.php');
1230 break;
1231 case 'wpfc':
1232 deactivate_plugins('wp-fastest-cache/wpFastestCache.php');
1233 break;
1234 case 'wp3':
1235 deactivate_plugins('w3-total-cache/w3-total-cache.php');
1236 break;
1237
1238 }
1239 }
1240 }
1241 }
1242
1243
1244 add_action("wp_ajax_lws_optimize_manage_state", "lws_optimize_manage_state");
1245 function lws_optimize_manage_state()
1246 {
1247 check_ajax_referer('manage_optimize_state', '_ajax_nonce');
1248 if (isset($_POST['action'])) {
1249 if ($_POST['checked'] !== "false"){
1250 delete_option('lws_op_deactivated');
1251 }
1252 else {
1253 var_dump(update_option('lws_op_deactivated', "blocked"));
1254 }
1255 }
1256 }
1257
1258 //AJAX DL Plugin//
1259 add_action("wp_ajax_lws_op_downloadPlugin", "wp_ajax_install_plugin");
1260 //
1261
1262 //AJAX Activate Plugin//
1263 add_action("wp_ajax_lws_op_activatePlugin", "lws_op_activate_plugin");
1264 function lws_op_activate_plugin()
1265 {
1266 check_ajax_referer('activate_plugin', '_ajax_nonce');
1267 if (isset($_POST['ajax_slug'])) {
1268 switch (sanitize_textarea_field($_POST['ajax_slug'])) {
1269 case 'lws-hide-login':
1270 activate_plugin('lws-hide-login/lws-hide-login.php');
1271 break;
1272 case 'lws-sms':
1273 activate_plugin('lws-sms/lws-sms.php');
1274 break;
1275 case 'lws-tools':
1276 activate_plugin('lws-tools/lws-tools.php');
1277 break;
1278 case 'lws-affiliation':
1279 activate_plugin('lws-affiliation/lws-affiliation.php');
1280 break;
1281 case 'lws-cleaner':
1282 activate_plugin('lws-cleaner/lws-cleaner.php');
1283 break;
1284 case 'lwscache':
1285 activate_plugin('lwscache/lwscache.php');
1286 break;
1287 case 'lws-optimize':
1288 activate_plugin('lws-optimize/lws-optimize.php');
1289 break;
1290 }
1291 }
1292 wp_die();
1293 }
1294
1295 if (!get_option('lws_op_deactivated')){
1296
1297 //When file-based caching is activated
1298 if (get_option('lws_op_fb_cache') && !get_option('lws_op_deactivated')) {
1299 add_filter('template_include', 'lws_op_fb_tpl_redirect', 1);
1300 function lws_op_fb_tpl_redirect($template)
1301 {
1302 global $wp;
1303 $file = LWS_OP_UPLOADS . $wp->request . '_lws_' . get_current_user_id() . '.html';
1304 $timer = get_option('lws_op_fb_cache');
1305 if (is_file($file) && (time() - filemtime($file)) < $timer) {
1306 return $file;
1307 wp_die();
1308 } else {
1309 ob_start();
1310 add_action('wp_print_footer_scripts', 'lws_op_fb_tpl_redirect_end');
1311 return $template;
1312 }
1313 }
1314
1315 function lws_op_fb_tpl_redirect_end()
1316 {
1317 global $wp;
1318 $file = LWS_OP_UPLOADS . $wp->request . '_lws_' . get_current_user_id() . '.html';
1319 if (!is_file($file)) {
1320 file_put_contents($file, ob_get_contents());
1321 }
1322 }
1323 }
1324
1325 add_action("wp_ajax_lws_option_media_checkbox", "lws_option_media_checkbox");
1326 function lws_option_media_checkbox()
1327 {
1328 check_ajax_referer('checkbox_update_option_to_change', '_ajax_nonce');
1329 if(isset($_POST['action']) && isset($_POST['option']) && isset($_POST['checked'])) {
1330 $media_to_webp = array(
1331 'lws_op_autoconvert_compression',
1332 'lws_op_autoconvert_webp',
1333 'lws_op_deactivate_lazyload_iframe',
1334 'lws_op_deactivate_lazyload_image',
1335 'lws_op_deactivate_lazyload',
1336 'lws_op_force_lazyload_video',
1337 'lws_op_force_no_lazyload_video',
1338 );
1339 $option = sanitize_text_field($_POST['option']);
1340 $is_checked = rest_sanitize_boolean($_POST['checked']);
1341 if ($option == 'lws_op_deactivate_lazyload_iframe' || $option == 'lws_op_deactivate_lazyload_image' || $option == 'lws_op_deactivate_lazyload') :
1342 if (!$is_checked) {
1343 if (in_array($option, $media_to_webp)) {
1344 update_option($option, true);
1345 }
1346 if ($option == 'lws_op_autoconvert_webp') {
1347 wp_unschedule_event(wp_next_scheduled('lws_op_hook_unconvert_webp'), 'lws_op_hook_unconvert_webp');
1348 if (! wp_next_scheduled('lws_op_hook_convert_webp')) {
1349 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_convert_webp');
1350 }
1351 } elseif ($option == 'lws_op_autoconvert_compression') {
1352 lws_op_compress_all_to_jpeg();
1353 }
1354 }
1355 else{
1356 if (in_array($option, $media_to_webp)) {
1357 delete_option($option);
1358 }
1359 }
1360 else :
1361 if ($is_checked) {
1362 if (in_array($option, $media_to_webp)) {
1363 update_option($option, true);
1364 }
1365 if ($option == 'lws_op_autoconvert_webp') {
1366 wp_unschedule_event(wp_next_scheduled('lws_op_hook_unconvert_webp'), 'lws_op_hook_unconvert_webp');
1367 if (! wp_next_scheduled('lws_op_hook_convert_webp')) {
1368 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_convert_webp');
1369 }
1370 } elseif ($option == 'lws_op_autoconvert_compression') {
1371 lws_op_compress_all_to_jpeg();
1372 }
1373 }
1374 else{
1375 if (in_array($option, $media_to_webp)) {
1376 delete_option($option);
1377 }
1378 if ($option == 'lws_op_autoconvert_webp') {
1379 wp_unschedule_event(wp_next_scheduled('lws_op_hook_convert_webp'), 'lws_op_hook_convert_webp');
1380 if (! wp_next_scheduled('lws_op_hook_unconvert_webp')) {
1381 wp_schedule_event(time(), 'threeminutes', 'lws_op_hook_unconvert_webp');
1382 }
1383 } elseif ($option == 'lws_op_autoconvert_compression') {
1384 lws_op_uncompress_all_to_jpeg();
1385 }
1386 }
1387 endif;
1388 }
1389
1390 }
1391
1392 add_action("wp_ajax_lws_add_option_media", "lws_op_add_option");
1393 function lws_op_add_option()
1394 {
1395 check_ajax_referer('media_change_max_width', '_ajax_nonce');
1396 if(isset($_POST['action'])) {
1397 if (isset($_POST['value'])) {
1398 $value = sanitize_text_field($_POST['value']);
1399 update_option("lws_op_change_max_width_media", $value);
1400 }
1401 }
1402 wp_die();
1403 }
1404
1405 add_action("wp_ajax_lws_delete_option_media", "lws_op_delete_option");
1406 function lws_op_delete_option()
1407 {
1408 check_ajax_referer('also_media_change_max_width', '_ajax_nonce');
1409 if(isset($_POST['action'])) {
1410 delete_option("lws_op_change_max_width_media");
1411 }
1412 wp_die();
1413 }
1414
1415 if (get_option('lws_op_change_max_width_media')) {
1416 $value = get_option('lws_op_change_max_width_media');
1417 if ($value == 'disabled') {
1418 add_filter('big_image_size_threshold', '__return_false');
1419 } else {
1420 add_filter('big_image_size_threshold', 'lws_op_image_size_threshold');
1421 function lws_op_image_size_threshold($threshold)
1422 {
1423 $threshold = get_option('lws_op_change_max_width_media');
1424 return $threshold;
1425 }
1426 }
1427 }
1428
1429 add_action("wp_ajax_lws_optimize_fb_cache", "lws_optimize_fb_cache");
1430 function lws_optimize_fb_cache()
1431 {
1432 check_ajax_referer('update_fb_activate', '_ajax_nonce');
1433 if (isset($_POST['action'])) {
1434 $timer = ($_POST['timer'] !== false) ? sanitize_text_field($_POST['timer']) : '3600';
1435 update_option('lws_op_fb_cache', $timer);
1436 } else {
1437 delete_option('lws_op_fb_cache');
1438 }
1439 }
1440
1441 add_action("wp_ajax_lws_no_optimize_fb_cache", "lws_no_optimize_fb_cache");
1442 function lws_no_optimize_fb_cache()
1443 {
1444 check_ajax_referer('update_fb_deactivate', '_ajax_nonce');
1445 if (isset($_POST['action'])) {
1446 delete_option('lws_op_fb_cache');
1447 }
1448 }
1449
1450 add_action("wp_ajax_lws_clear_fb_cache", "lws_optimize_clear_cache");
1451 function lws_optimize_clear_cache()
1452 {
1453 check_ajax_referer('clear_fb_caching', '_ajax_nonce');
1454 array_map('unlink', (glob(wp_upload_dir()['basedir'] . "/lws-optimize/*") ? glob(wp_upload_dir()['basedir'] . "/lws-optimize/*") : array()));
1455 }
1456
1457 add_action("wp_ajax_lws_clear_memcached", "lws_optimize_clear_memcached");
1458 function lws_optimize_clear_memcached()
1459 {
1460 check_ajax_referer('clear_memc_caching', '_ajax_nonce');
1461 $memcached = new Memcached();
1462 $memcached->addServer('localhost', 11211);
1463 $memcached->flush(1);
1464 }
1465
1466 add_action("wp_ajax_lws_start_memcached", "lws_optimize_start_memcached");
1467 function lws_optimize_start_memcached()
1468 {
1469 check_ajax_referer('starting_memc_caching', '_ajax_nonce');
1470 if (isset($_POST['action'])) {
1471 update_option('lws_opti_memcaching_on', 1);
1472 file_put_contents(WP_CONTENT_DIR . '/object-cache.php', file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
1473 }
1474 }
1475
1476 add_action("init", "lws_optimize_force_stop_memcached");
1477 function lws_optimize_force_stop_memcached()
1478 {
1479 delete_option('lws_opti_memcaching_on');
1480 }
1481
1482 add_action("wp_ajax_lws_stop_memcached", "lws_optimize_stop_memcached");
1483 function lws_optimize_stop_memcached()
1484 {
1485 check_ajax_referer('turn_off_memc_caching', '_ajax_nonce');
1486 if (isset($_POST['action'])) {
1487 delete_option('lws_opti_memcaching_on');
1488 unlink(WP_CONTENT_DIR . '/object-cache.php');
1489 }
1490 }
1491 }
1492
1493 /**
1494 * Minify HTML files automatically
1495 * at Zuziko.com
1496 * March 5, 2021 by David Green
1497 */
1498 class FLHM_HTML_Compression
1499 {
1500 protected $flhm_compress_css = true;
1501 protected $flhm_compress_js = true;
1502 protected $flhm_info_comment = true;
1503 protected $flhm_remove_comments = true;
1504 protected $html;
1505 public function __construct($html)
1506 {
1507 if (!empty($html)) {
1508 $this->flhm_parseHTML($html);
1509 }
1510 }
1511 public function __toString()
1512 {
1513 return $this->html;
1514 }
1515 protected function flhm_bottomComment($raw, $compressed)
1516 {
1517 $raw = strlen($raw);
1518 $compressed = strlen($compressed);
1519 $savings = ($raw-$compressed) / $raw * 100;
1520 $savings = round($savings, 2);
1521 return '<!--HTML compressed, size saved '.$savings.'%. From '.$raw.' bytes, now '.$compressed.' bytes-->';
1522 }
1523 protected function flhm_minifyHTML($html)
1524 {
1525 $pattern = '/<(?<script>script).*?<\/script\s*>|<(?<style>style).*?<\/style\s*>|<!(?<comment>--).*?-->|<(?<tag>[\/\w.:-]*)(?:".*?"|\'.*?\'|[^\'">]+)*>|(?<text>((<[^!\/\w.:-])?[^<]*)+)|/si';
1526 preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
1527 $overriding = false;
1528 $raw_tag = false;
1529 $html = '';
1530 foreach ($matches as $token) {
1531 $tag = (isset($token['tag'])) ? strtolower($token['tag']) : null;
1532 $content = $token[0];
1533 if (is_null($tag)) {
1534 if (!empty($token['script'])) {
1535 $strip = $this->flhm_compress_js;
1536 } elseif (!empty($token['style'])) {
1537 $strip = $this->flhm_compress_css;
1538 } elseif ($content == '<!--wp-html-compression no compression-->') {
1539 $overriding = !$overriding;
1540 continue;
1541 } elseif ($this->flhm_remove_comments) {
1542 if (!$overriding && $raw_tag != 'textarea') {
1543 $content = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $content);
1544 }
1545 }
1546 } else {
1547 if ($tag == 'pre' || $tag == 'textarea') {
1548 $raw_tag = $tag;
1549 } elseif ($tag == '/pre' || $tag == '/textarea') {
1550 $raw_tag = false;
1551 } else {
1552 if ($raw_tag || $overriding) {
1553 $strip = false;
1554 } else {
1555 $strip = true;
1556 $content = preg_replace('/(\s+)(\w++(?<!\baction|\balt|\bcontent|\bsrc)="")/', '$1', $content);
1557 $content = str_replace(' />', '/>', $content);
1558 }
1559 }
1560 }
1561 if ($strip) {
1562 $content = $this->flhm_removeWhiteSpace($content);
1563 }
1564 $html .= $content;
1565 }
1566 return $html;
1567 }
1568 public function flhm_parseHTML($html)
1569 {
1570 $this->html = $this->flhm_minifyHTML($html);
1571 if ($this->flhm_info_comment) {
1572 $this->html .= "\n" . $this->flhm_bottomComment($html, $this->html);
1573 }
1574 }
1575 protected function flhm_removeWhiteSpace($str)
1576 {
1577 $str = str_replace("\t", ' ', $str);
1578 $str = str_replace("\n", '', $str);
1579 $str = str_replace("\r", '', $str);
1580 $str = str_replace("// The customizer requires postMessage and CORS (if the site is cross domain).", '', $str);
1581 while (stristr($str, ' ')) {
1582 $str = str_replace(' ', ' ', $str);
1583 }
1584 return $str;
1585 }
1586 }
1587 function flhm_wp_html_compression_finish($html)
1588 {
1589 return new FLHM_HTML_Compression($html);
1590 }
1591
1592