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

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