Plugin Directory

Changeset 3362313


Ignore:
Timestamp:
09/16/2025 08:20:26 AM (5 months ago)
Author:
aurelienlws
Message:

Updated logs to add a refresh button ; Fixed missing translations ; Added a Feedback button

Location:
lws-optimize
Files:
377 added
7 edited

Legend:

Unmodified
Added
Removed
  • lws-optimize/trunk/Classes/Admin/LwsOptimizeManageAdmin.php

    r3360302 r3362313  
    33namespace Lws\Classes\Admin;
    44
    5 class LwsOptimizeManageAdmin
     5use Lws\Classes\LwsOptimize;
     6
     7class LwsOptimizeManageAdmin extends LwsOptimize
    68{
    79    public $version = "3.2.4.3";
     
    3537        }, 0);
    3638
     39        if (is_admin()) {
     40            // Change configuration state for the differents element of LWSOptimize
     41            add_action("wp_ajax_lws_optimize_checkboxes_action", [$this, "lws_optimize_manage_config"]);
     42            add_action("wp_ajax_lws_optimize_checkboxes_action_delayed", [$this, "lws_optimize_manage_config_delayed"]);
     43            add_action("wp_ajax_lws_optimize_exclusions_changes_action", [$this, "lws_optimize_manage_exclusions"]);
     44            add_action("wp_ajax_lws_optimize_exclusions_media_changes_action", [$this, "lws_optimize_manage_exclusions_media"]);
     45            add_action("wp_ajax_lws_optimize_fetch_exclusions_action", [$this, "lws_optimize_fetch_exclusions"]);
     46            // Activate the "preload" option for the file-based cache
     47            add_action("wp_ajax_lwsop_start_preload_fb", [$this, "lwsop_preload_fb"]);
     48            add_action("wp_ajax_lwsop_change_preload_amount", [$this, "lwsop_change_preload_amount"]);
     49
     50            add_action("wp_ajax_lwsop_regenerate_cache", [$this, "lwsop_regenerate_cache"]);
     51            add_action("wp_ajax_lwsop_regenerate_cache_general", [$this, "lwsop_regenerate_cache_general"]);
     52
     53            // Fetch an array containing every URLs that should get purged each time an autopurge starts
     54            add_action("wp_ajax_lwsop_get_specified_url", [$this, "lwsop_specified_urls_fb"]);
     55            // Update the specified-URLs array
     56            add_action("wp_ajax_lwsop_save_specified_url", [$this, "lwsop_save_specified_urls_fb"]);
     57            // Fetch an array containing every URLs that should not be cached
     58            add_action("wp_ajax_lwsop_get_excluded_url", [$this, "lwsop_exclude_urls_fb"]);
     59            add_action("wp_ajax_lwsop_get_excluded_cookies", [$this, "lwsop_exclude_cookies_fb"]);
     60            // Update the excluded-URLs array
     61            add_action("wp_ajax_lwsop_save_excluded_url", [$this, "lwsop_save_urls_fb"]);
     62            add_action("wp_ajax_lwsop_save_excluded_cookies", [$this, "lwsop_save_cookies_fb"]);
     63
     64            // Get or set the URLs that should get preloaded on the website
     65            add_action("wp_ajax_lws_optimize_add_url_to_preload", [$this, "lwsop_get_url_preload"]);
     66            add_action("wp_ajax_lws_optimize_set_url_to_preload", [$this, "lwsop_set_url_preload"]);
     67
     68            // Get or set the URLs to the fonts that should get preloaded on the website
     69            add_action("wp_ajax_lws_optimize_add_font_to_preload", [$this, "lwsop_get_url_preload_font"]);
     70            add_action("wp_ajax_lws_optimize_set_url_to_preload_font", [$this, "lwsop_set_url_preload_font"]);
     71
     72            // Reload the stats of the filebased cache
     73            add_action("wp_ajax_lwsop_reload_stats", [$this, "lwsop_reload_stats"]);
     74
     75            // Get when the next database maintenance will happen
     76            add_action("wp_ajax_lws_optimize_get_database_cleaning_time", [$this, "lws_optimize_get_database_cleaning_time"]);
     77
     78            add_action("wp_ajax_lwsop_check_preload_update", [$this, "lwsop_check_preload_update"]);
     79
     80            add_action("wp_ajax_lws_clear_fb_cache", [$this, "lws_optimize_clear_cache"]);
     81            add_action("wp_ajax_lws_op_clear_all_caches", [$this, "lws_op_clear_all_caches"]);
     82            add_action("wp_ajax_lws_clear_opcache", [$this, "lws_clear_opcache"]);
     83            add_action("wp_ajax_lws_clear_html_fb_cache", [$this, "lws_optimize_clear_htmlcache"]);
     84            add_action("wp_ajax_lws_clear_style_fb_cache", [$this, "lws_optimize_clear_stylecache"]);
     85            add_action("wp_ajax_lws_clear_currentpage_fb_cache", [$this, "lws_optimize_clear_currentcache"]);
     86
     87
     88            add_action("wp_ajax_lws_optimize_fb_cache_change_status", [$this, "lws_optimize_set_fb_status"]);
     89            add_action("wp_ajax_lws_optimize_fb_cache_change_cache_time", [$this, "lws_optimize_set_fb_timer"]);
     90
     91            add_action("wp_ajax_lwsop_regenerate_logs", [$this, "lwsop_regenerate_logs"]);
     92
     93            add_action("wp_ajax_lwsOp_sendFeedbackUser", [$this, "lwsOp_sendFeedbackUser"]);
     94        }
     95
     96        add_action("wp_ajax_lwsop_deactivate_temporarily", [$this, "lwsop_deactivate_temporarily"]);
     97        add_action("wp_ajax_lws_optimize_do_pagespeed", [$this, "lwsop_do_pagespeed_test"]);
     98        add_action("wp_ajax_lwsop_dump_dynamic_cache", [$this, "lwsop_dump_dynamic_cache"]);
     99        add_action("wp_ajax_lws_optimize_activate_cleaner", [$this, "lws_optimize_activate_cleaner"]);
     100
     101        // Launch the weekly DB cleanup
     102        add_action("lws_optimize_maintenance_db_weekly", [$this, "lws_optimize_create_maintenance_db_options"]);
     103        add_action("wp_ajax_lws_optimize_set_maintenance_db_options", [$this, "lws_optimize_set_maintenance_db_options"]);
     104        add_action("wp_ajax_lws_optimize_get_maintenance_db_options", [$this, "lws_optimize_manage_maintenance_get"]);
     105
     106        add_action('wp_ajax_lwsop_change_optimize_configuration', [$this, "lwsop_get_setup_optimize"]);
     107
    37108        // Add the LwsOptimize button on the admin-bar
    38109        if (!function_exists("is_user_logged_in")) {
     
    72143    public function lws_optimize_options_page()
    73144    {
     145        include_once LWS_OP_DIR . '/views/feedback_button.php';
     146
    74147        // Only load this file, everything else will be loaded within tabs.php
    75148        include_once LWS_OP_DIR . '/views/main_page.php';
     
    316389        ) {
    317390            add_option('lws_optimize_deactivate_temporarily', true, time() + 86400);
    318             $GLOBALS['lws_optimize']->lws_optimize_set_cache_htaccess();
    319             $GLOBALS['lws_optimize']->lws_optimize_reset_header_htaccess();
    320             $GLOBALS['lws_optimize']->lwsop_dump_all_dynamic_caches();
     391            $this->lws_optimize_set_cache_htaccess();
     392            $this->lws_optimize_reset_header_htaccess();
     393            $this->lwsop_dump_all_dynamic_caches();
    321394            add_action('admin_notices', [$this, 'lws_optimize_warning_incompatibiliy']);
    322395        }
     
    371444
    372445        // // Remove Dynamic Cache at the same time
    373         // $GLOBALS['lws_optimize']->lws_optimize_set_cache_htaccess();
    374         // $GLOBALS['lws_optimize']->lws_optimize_reset_header_htaccess();
    375         // $GLOBALS['lws_optimize']->lwsop_dump_all_dynamic_caches();
     446        // $this->lws_optimize_set_cache_htaccess();
     447        // $this->lws_optimize_reset_header_htaccess();
     448        // $this->lwsop_dump_all_dynamic_caches();
    376449
    377450        wp_die(json_encode(array('code' => "SUCCESS", "data" => $result)), JSON_PRETTY_PRINT);
    378451    }
     452
     453
     454
     455    /**
     456     * Set the 'state' of each action defined by the ID "lws_optimize_*_check" as such :
     457     * [name]['state'] = "true"/"false"
     458     */
     459    public function lws_optimize_manage_config()
     460    {
     461        check_ajax_referer('nonce_lws_optimize_checkboxes_config', '_ajax_nonce');
     462        if (!isset($_POST['action']) || !isset($_POST['data'])) {
     463            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     464        }
     465
     466        // IMPORTANT: Get a fresh copy of options from the database
     467        $optimize_options = get_option('lws_optimize_config_array', []);
     468
     469        $id = sanitize_text_field($_POST['data']['type']);
     470        $state = sanitize_text_field($_POST['data']['state']);
     471        $tab = sanitize_text_field($_POST['data']['tab']);
     472
     473        if ($state !== "false" && $state !== "true") {
     474            $state = "false";
     475        }
     476
     477        if (preg_match('/lws_optimize_(.*?)_check/', $id, $match) !== 1) {
     478            wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
     479        }
     480
     481        // The $element to update
     482        $element = $match[1];
     483
     484        $optimize_options[$element]['state'] = $state;
     485
     486        // In case it is the dynamic cache, we need to check which type (cpanel/lws) it is and whether it CAN be activated
     487        if ($element == "dynamic_cache") {
     488            $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLE'] ?? null;
     489            if ($fastest_cache_status === null) {
     490                $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLED'] ?? null;
     491            }
     492            $lwscache_status = $_SERVER['lwscache'] ?? null;
     493
     494            if ($lwscache_status == "Off") {
     495                $lwscache_status = false;
     496            } elseif ($lwscache_status == "On") {
     497                $lwscache_status = true;
     498            }
     499
     500            if ($fastest_cache_status == "0") {
     501                $fastest_cache_status = false;
     502            } elseif ($fastest_cache_status == "1") {
     503                $fastest_cache_status = true;
     504            }
     505
     506
     507            if ($lwscache_status === null && $fastest_cache_status === null) {
     508                $optimize_options[$element]['state'] = "false";
     509                update_option('lws_optimize_config_array', $optimize_options);
     510                wp_die(json_encode(array('code' => "INCOMPATIBLE", "data" => "LWSCache is incompatible with this hosting. Use LWS.")), JSON_PRETTY_PRINT);
     511            }
     512
     513            if ($lwscache_status == false && $fastest_cache_status === null) {
     514                $optimize_options[$element]['state'] = "false";
     515                update_option('lws_optimize_config_array', $optimize_options);
     516                wp_die(json_encode(array('code' => "PANEL_CACHE_OFF", "data" => "LWSCache is not activated on LWSPanel.")), JSON_PRETTY_PRINT);
     517            }
     518
     519            if ($lwscache_status === null && $fastest_cache_status == false) {
     520                $optimize_options[$element]['state'] = "false";
     521                update_option('lws_optimize_config_array', $optimize_options);
     522                wp_die(json_encode(array('code' => "CPANEL_CACHE_OFF", "data" => "Varnish is not activated on cPanel.")), JSON_PRETTY_PRINT);
     523            }
     524        } elseif ($element == "maintenance_db") {
     525            if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
     526                wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
     527            }
     528            if ($state == "true") {
     529                wp_schedule_event(time() + 604800, 'weekly', 'lws_optimize_maintenance_db_weekly');
     530            }
     531        } elseif ($element == "memcached") {
     532            if ($this->lwsop_plugin_active('redis-cache/redis-cache.php')) {
     533                $optimize_options[$element]['state'] = "false";
     534                wp_die(json_encode(array('code' => "REDIS_ALREADY_HERE", 'data' => "FAILURE", 'state' => "unknown")));
     535            }
     536            if (class_exists('Memcached')) {
     537                $memcached = new \Memcached();
     538                if (empty($memcached->getServerList())) {
     539                    $memcached->addServer('localhost', 11211);
     540                }
     541
     542                if ($memcached->getVersion() === false) {
     543                    if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
     544                        unlink(LWSOP_OBJECTCACHE_PATH);
     545                    }
     546                    wp_die(json_encode(array('code' => "MEMCACHE_NOT_WORK", 'data' => "FAILURE", 'state' => "unknown")));
     547                }
     548
     549                file_put_contents(LWSOP_OBJECTCACHE_PATH, file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
     550            } else {
     551                if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
     552                    unlink(LWSOP_OBJECTCACHE_PATH);
     553                }
     554                wp_die(json_encode(array('code' => "MEMCACHE_NOT_FOUND", 'data' => "FAILURE", 'state' => "unknown")));
     555            }
     556        } elseif ($element == "gzip_compression") {
     557            if ($state == "true") {
     558                $this->set_gzip_brotli_htaccess();
     559            } else {
     560                $this->unset_gzip_brotli_htaccess();
     561            }
     562        } elseif ($element == "htaccess_rules") {
     563            if ($state == "true") {
     564                $this->lws_optimize_set_cache_htaccess();
     565            } elseif ($state == "false") {
     566                $this->unset_cache_htaccess();
     567            }
     568        }
     569
     570        // If the tab where the option comes from is frontend, we clear the cache
     571        // as those options needs the cache to be emptied to work properly
     572        if (isset($tab) && $tab == "frontend") {
     573            $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
     574            $logger = fopen($this->log_file, 'a');
     575            fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache after configuration change' . PHP_EOL);
     576            fclose($logger);
     577        }
     578
     579        if ($element == "cache_mobile_user" || $element == "cache_logged_user") {
     580            if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
     581                $this->lws_optimize_set_cache_htaccess();
     582            }
     583        }
     584
     585        update_option('lws_optimize_config_array', $optimize_options);
     586
     587        // If correctly added and updated
     588        wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options[$element]['state'] = $state, 'type' => $element)), JSON_PRETTY_PRINT);
     589    }
     590
     591    public function lws_optimize_manage_config_delayed() {
     592        check_ajax_referer('nonce_lws_optimize_checkboxes_config', '_ajax_nonce');
     593        if (!isset($_POST['action']) || !isset($_POST['data']) || !is_array($_POST['data'])) {
     594            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     595        }
     596
     597        $optimize_options = get_option('lws_optimize_config_array', []);
     598
     599        $errors = [];
     600
     601        foreach ($_POST['data'] as $element) {
     602            $id = sanitize_text_field($element['type']);
     603            $state = sanitize_text_field($element['state']);
     604
     605            if (preg_match('/lws_optimize_(.*?)_check/', $id, $match) !== 1) {
     606                $logger = fopen($this->log_file, 'a');
     607                fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Failed to parse ID for configuration: ' . $id . PHP_EOL);
     608                fclose($logger);
     609                continue;
     610            }
     611
     612            // Get the ID of the option to update
     613            $id = $match[1];
     614
     615            // Update the state of the option
     616            $optimize_options[$id]['state'] = $state;
     617
     618            // In case it is the dynamic cache, check compatibility
     619            if ($id == "dynamic_cache") {
     620                $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLE'] ?? null;
     621                if ($fastest_cache_status === null) {
     622                    $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLED'] ?? null;
     623                }
     624                $lwscache_status = $_SERVER['lwscache'] ?? null;
     625
     626                if ($lwscache_status == "Off") {
     627                    $lwscache_status = false;
     628                } elseif ($lwscache_status == "On") {
     629                    $lwscache_status = true;
     630                }
     631
     632                if ($fastest_cache_status == "0") {
     633                    $fastest_cache_status = false;
     634                } elseif ($fastest_cache_status == "1") {
     635                    $fastest_cache_status = true;
     636                }
     637
     638                if ($lwscache_status === null && $fastest_cache_status === null) {
     639                    $optimize_options[$id]['state'] = "false";
     640                    $errors[$id] = 'INCOMPATIBLE';
     641                    $logger = fopen($this->log_file, 'a');
     642                    fwrite($logger, '[' . date('Y-m-d H:i:s') . '] LWSCache is incompatible with this hosting' . PHP_EOL);
     643                    fclose($logger);
     644                    continue;
     645                }
     646
     647                if ($lwscache_status == false && $fastest_cache_status === null) {
     648                    $optimize_options[$id]['state'] = "false";
     649                    $errors[$id] = 'PANEL_CACHE_OFF';
     650                    $logger = fopen($this->log_file, 'a');
     651                    fwrite($logger, '[' . date('Y-m-d H:i:s') . '] LWSCache is not activated on LWSPanel' . PHP_EOL);
     652                    fclose($logger);
     653                    continue;
     654                }
     655
     656                if ($lwscache_status === null && $fastest_cache_status == false) {
     657                    $optimize_options[$id]['state'] = "false";
     658                    $errors[$id] = 'CPANEL_CACHE_OFF';
     659                    $logger = fopen($this->log_file, 'a');
     660                    fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Varnish is not activated on cPanel' . PHP_EOL);
     661                    fclose($logger);
     662                    continue;
     663                }
     664
     665            } elseif ($id == "maintenance_db") {
     666                if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
     667                    wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
     668                }
     669                if ($state == "true") {
     670                    wp_schedule_event(time() + 604800, 'weekly', 'lws_optimize_maintenance_db_weekly');
     671                }
     672
     673            } elseif ($id == "memcached") {
     674                if ($this->lwsop_plugin_active('redis-cache/redis-cache.php')) {
     675                    $optimize_options[$id]['state'] = "false";
     676                    $errors[$id] = 'REDIS_ALREADY_HERE';
     677                    $logger = fopen($this->log_file, 'a');
     678                    fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Redis cache plugin is already active' . PHP_EOL);
     679                    fclose($logger);
     680                    continue;
     681                }
     682
     683                if (class_exists('Memcached')) {
     684                    $memcached = new \Memcached();
     685                    if (empty($memcached->getServerList())) {
     686                        $memcached->addServer('localhost', 11211);
     687                    }
     688
     689                    if ($memcached->getVersion() === false) {
     690                        if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
     691                            unlink(LWSOP_OBJECTCACHE_PATH);
     692                        }
     693                        $errors[$id] = 'MEMCACHE_NOT_WORK';
     694                        $logger = fopen($this->log_file, 'a');
     695                        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Memcached server not responding' . PHP_EOL);
     696                        fclose($logger);
     697                        continue;
     698                    }
     699
     700                    file_put_contents(LWSOP_OBJECTCACHE_PATH, file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
     701
     702                } else {
     703                    if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
     704                        unlink(LWSOP_OBJECTCACHE_PATH);
     705                    }
     706                    $errors[$id] = 'MEMCACHE_NOT_FOUND';
     707                    $logger = fopen($this->log_file, 'a');
     708                    fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Memcached extension not found' . PHP_EOL);
     709                    fclose($logger);
     710                    continue;
     711                }
     712
     713            } elseif ($id == "gzip_compression") {
     714                if ($state == "true") {
     715                    $this->set_gzip_brotli_htaccess();
     716                } else {
     717                    $this->unset_gzip_brotli_htaccess();
     718                }
     719            } elseif ($id == "htaccess_rules") {
     720                if ($state == "true") {
     721                    $this->lws_optimize_set_cache_htaccess();
     722                } elseif ($state == "false") {
     723                    $this->unset_cache_htaccess();
     724                }
     725            } elseif ($id == "preload_cache") {
     726                // Clean previous preload data
     727                delete_option('lws_optimize_sitemap_urls');
     728                delete_option('lws_optimize_preload_is_ongoing');
     729
     730                // Update preload configuration
     731                $optimize_options['filebased_cache']['preload'] = $state;
     732                $optimize_options['filebased_cache']['preload_amount'] = $optimize_options['filebased_cache']['preload_amount'] ?: 3;
     733                $optimize_options['filebased_cache']['preload_done'] = 0;
     734                $optimize_options['filebased_cache']['preload_ongoing'] = $state;
     735
     736                // Get sitemap URLs
     737                $urls = $this->get_sitemap_urls();
     738                $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
     739
     740                // Manage scheduled preload task
     741                if ($state === "false") {
     742                    // Disable scheduled preload
     743                    if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
     744                        wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
     745                    }
     746                } else {
     747                    // Enable scheduled preload
     748                    if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
     749                        wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
     750                    }
     751                    wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
     752                }
     753            }
     754        }
     755
     756        // Clear cache when updating data
     757        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
     758        $logger = fopen($this->log_file, 'a');
     759        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache after configuration change' . PHP_EOL);
     760        fclose($logger);
     761
     762        $this->after_cache_purge_preload();
     763
     764        if (function_exists("opcache_reset")) {
     765            opcache_reset();
     766        }
     767
     768        if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
     769            $this->lws_optimize_set_cache_htaccess();
     770        }
     771
     772        $optimize_options['personnalized'] = "true";
     773
     774        update_option('lws_optimize_config_array', $optimize_options);
     775
     776        // If correctly added and updated
     777        wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options, 'errors' => $errors), JSON_PRETTY_PRINT));
     778    }
     779
     780
     781
     782    /**
     783     * Add exclusions to the given action
     784     */
     785    public function lws_optimize_manage_exclusions()
     786    {
     787        check_ajax_referer('nonce_lws_optimize_exclusions_config', '_ajax_nonce');
     788        if (!isset($_POST['action']) || !isset($_POST['data'])) {
     789            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     790        }
     791
     792        // Get the ID for the currently open modal and get the action to modify
     793        $data = $_POST['data'];
     794        $id = null;
     795        foreach ($data as $var) {
     796            if ($var['name'] == "lwsoptimize_exclude_url_id") {
     797                $id = sanitize_text_field($var['value']);
     798                break;
     799            }
     800        }
     801
     802        // No ID ? Cannot proceed
     803        if (!isset($id)) {
     804            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     805        }
     806
     807        // Get the specific action from the ID
     808        if (preg_match('/lws_optimize_(.*?)_exclusion/', $id, $match) !== 1) {
     809            wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
     810        }
     811
     812        $exclusions = array();
     813
     814        // The $element to update
     815        $element = $match[1];
     816
     817        $optimize_options = get_option('lws_optimize_config_array', []);
     818
     819        // Get all exclusions
     820        foreach ($data as $var) {
     821            if ($var['name'] == "lwsoptimize_exclude_url") {
     822                if (trim($var['value']) == '') {
     823                    continue;
     824                }
     825                $exclusions[] = sanitize_text_field($var['value']);
     826            }
     827        }
     828
     829        // Add the exclusions for the $element ; each is a URL (e.g. : my-website.fr/wp-content/plugins/...)
     830        // If no config is present for the $element, it will be added
     831        $config_element = $optimize_options[$element]['exclusions'] = $exclusions;
     832
     833        update_option('lws_optimize_config_array', $optimize_options);
     834
     835        wp_die(json_encode(array('code' => "SUCCESS", "data" => $config_element, 'id' => $id)), JSON_PRETTY_PRINT);
     836    }
     837
     838    public function lws_optimize_manage_exclusions_media()
     839    {
     840        check_ajax_referer('nonce_lws_optimize_exclusions_media_config', '_ajax_nonce');
     841        if (!isset($_POST['action']) || !isset($_POST['data'])) {
     842            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     843        }
     844
     845        // Get the ID for the currently open modal and get the action to modify
     846        $data = $_POST['data'];
     847        foreach ($data as $var) {
     848            if ($var['name'] == "lwsoptimize_exclude_url_id_media") {
     849                $id = sanitize_text_field($var['value']);
     850                break;
     851            } else {
     852                $id = null;
     853            }
     854        }
     855
     856        // No ID ? Cannot proceed
     857        if (!isset($id)) {
     858            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     859        }
     860
     861        // Get the specific action from the ID
     862        if (preg_match('/lws_optimize_(.*?)_exclusion_button/', $id, $match) !== 1) {
     863            wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
     864        }
     865
     866        $exclusions = array();
     867
     868        // The $element to update
     869        $element = $match[1];
     870        // All configs for LWS Optimize
     871        $optimize_options = get_option('lws_optimize_config_array', []);
     872
     873        // Get all exclusions
     874        foreach ($data as $var) {
     875            switch ($var['name']) {
     876                case 'lwsoptimize_exclude_url':
     877                    if (trim($var['value']) == '') {
     878                        break;
     879                    }
     880                    $exclusions['css_classes'][] = sanitize_text_field($var['value']);
     881                    break;
     882                case 'lwsoptimize_gravatar':
     883                    $exclusions['media_types']['gravatar'] = true;
     884                    break;
     885                case 'lwsoptimize_thumbnails':
     886                    $exclusions['media_types']['thumbnails'] = true;
     887                    break;
     888                case 'lwsoptimize_responsive':
     889                    $exclusions['media_types']['responsive'] = true;
     890                    break;
     891                case 'lwsoptimize_iframe':
     892                    $exclusions['media_types']['iframe'] = true;
     893                    break;
     894                case 'lwsoptimize_mobile':
     895                    $exclusions['media_types']['mobile'] = true;
     896                    break;
     897                case 'lwsoptimize_video':
     898                    $exclusions['media_types']['video'] = true;
     899                    break;
     900                case 'lwsoptimize_excluded_iframes_img':
     901                    $tmp = $var['value'];
     902                    $tmp = explode(PHP_EOL, $tmp);
     903                    foreach ($tmp as $value) {
     904                        $exclusions['img_iframe'][] = trim(sanitize_text_field($value));
     905                    }
     906                    break;
     907                default:
     908                    break;
     909            }
     910        }
     911
     912        // Add the exclusions for the $element ; each is a URL (e.g. : my-website.fr/wp-content/plugins/...)
     913        // If no config is present for the $element, it will be added
     914        $config_element = $optimize_options[$element]['exclusions'] = $exclusions;
     915
     916        update_option('lws_optimize_config_array', $optimize_options);
     917        wp_die(json_encode(array('code' => "SUCCESS", "data" => $config_element, 'id' => $id)), JSON_PRETTY_PRINT);
     918    }
     919
     920    public function lws_optimize_fetch_exclusions()
     921    {
     922        check_ajax_referer('nonce_lws_optimize_fetch_exclusions', '_ajax_nonce');
     923        $optimize_options = get_option('lws_optimize_config_array', []);
     924
     925        if (!isset($_POST['action']) || !isset($_POST['data'])) {
     926            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     927        }
     928
     929        $id = sanitize_text_field($_POST['data']['type']);
     930
     931        if (preg_match('/lws_optimize_(.*?)_exclusion/', $id, $match) !== 1) {
     932            wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
     933        }
     934
     935        // The $element to update
     936        $element = $match[1];
     937        // All configs for LWS Optimize
     938
     939        // Get the exclusions
     940        $exclusions = isset($optimize_options[$element]['exclusions']) ? $optimize_options[$element]['exclusions'] : array('rs-lazyload');
     941
     942        wp_die(json_encode(array('code' => "SUCCESS", "data" => $exclusions, 'domain' => site_url())), JSON_PRETTY_PRINT);
     943    }
     944
     945
     946
     947    public function lwsop_preload_fb()
     948    {
     949        check_ajax_referer('update_fb_preload', '_ajax_nonce');
     950
     951        if (!isset($_POST['action']) || !isset($_POST['state'])) {
     952            wp_die(json_encode(['code' => "FAILED_ACTIVATE", 'data' => "Missing required parameters"]), JSON_PRETTY_PRINT);
     953        }
     954
     955        // IMPORTANT: Get a fresh copy of options from the database
     956        $optimize_options = get_option('lws_optimize_config_array', []);
     957
     958        // Clean previous preload data
     959        delete_option('lws_optimize_sitemap_urls');
     960        delete_option('lws_optimize_preload_is_ongoing');
     961
     962        $state = sanitize_text_field($_POST['state']);
     963        $amount = isset($_POST['amount']) ? absint($_POST['amount']) : 3;
     964
     965        // Update preload configuration
     966        $optimize_options['filebased_cache']['preload'] = $state;
     967        $optimize_options['filebased_cache']['preload_amount'] = $amount;
     968        $optimize_options['filebased_cache']['preload_done'] = 0;
     969        $optimize_options['filebased_cache']['preload_ongoing'] = $state;
     970
     971        // Get sitemap URLs
     972        $urls = $this->get_sitemap_urls();
     973        $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
     974
     975        // Manage scheduled preload task
     976        if ($state === "false") {
     977            // Disable scheduled preload
     978            if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
     979                wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
     980            }
     981        } else {
     982            // Enable scheduled preload
     983            if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
     984                wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
     985            }
     986            wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
     987        }
     988
     989        // Update options in database
     990        update_option('lws_optimize_config_array', $optimize_options);
     991
     992        wp_die(json_encode(['code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']]), JSON_PRETTY_PRINT);
     993    }
     994
     995    public function lwsop_change_preload_amount()
     996    {
     997        check_ajax_referer('update_fb_preload_amount', '_ajax_nonce');
     998
     999        if (isset($_POST['action'])) {
     1000            $optimize_options = get_option('lws_optimize_config_array', []);
     1001
     1002            $amount = $_POST['amount'] ? sanitize_text_field($_POST['amount']) : 3;
     1003            $optimize_options['filebased_cache']['preload_amount'] =  $amount;
     1004
     1005            update_option('lws_optimize_config_array', $optimize_options);
     1006
     1007            wp_die(json_encode(array('code' => "SUCCESS", 'data' => "DONE")));
     1008        }
     1009        wp_die(json_encode(array('code' => "FAILED_ACTIVATE", 'data' => "FAIL")));
     1010    }
     1011
     1012
     1013
     1014    // Start regenerating file-based cache (from 0 instead of just adding)
     1015    // Useful if stats are broken for some reasons
     1016    public function lwsop_regenerate_cache() {
     1017        check_ajax_referer('lws_regenerate_nonce_cache_fb', '_ajax_nonce');
     1018        $stats = $this->lwsop_recalculate_stats('regenerate');
     1019
     1020        $stats['desktop']['size'] = $this->lwsOpSizeConvert($stats['desktop']['size'] ?? 0);
     1021        $stats['mobile']['size'] = $this->lwsOpSizeConvert($stats['mobile']['size'] ?? 0);
     1022        $stats['css']['size'] = $this->lwsOpSizeConvert($stats['css']['size'] ?? 0);
     1023        $stats['js']['size'] = $this->lwsOpSizeConvert($stats['js']['size'] ?? 0);
     1024
     1025        wp_die(json_encode(array('code' => "SUCCESS", 'data' => $stats)));
     1026
     1027    }
     1028
     1029    // Regenrate cache stats
     1030    public function lwsop_regenerate_cache_general() {
     1031        check_ajax_referer('lws_regenerate_nonce_cache_fb', '_ajax_nonce');
     1032        $cache_stats = $this->lwsop_recalculate_stats('regenerate');
     1033
     1034        // Get the specifics values
     1035        $file_cache = $cache_stats['desktop']['amount'];
     1036        $file_cache_size = $this->lwsOpSizeConvert($cache_stats['desktop']['size']) ?? 0;
     1037
     1038        $mobile_cache = $cache_stats['mobile']['amount'] ?? 0;
     1039        $mobile_cache_size = $this->lwsOpSizeConvert($cache_stats['mobile']['size']) ?? 0;
     1040
     1041        $css_cache = $cache_stats['css']['amount'] ?? 0;
     1042        $css_cache_size = $this->lwsOpSizeConvert($cache_stats['css']['size']) ?? 0;
     1043
     1044        $js_cache = $cache_stats['js']['amount'] ?? 0;
     1045        $js_cache_size = $this->lwsOpSizeConvert($cache_stats['js']['size']) ?? 0;
     1046
     1047        $caches = [
     1048            'files' => [
     1049                'size' => $file_cache_size,
     1050                'title' => __('Computer Cache', 'lws-optimize'),
     1051                'alt_title' => __('Computer', 'lws-optimize'),
     1052                'amount' => $file_cache,
     1053                'id' => "lws_optimize_file_cache",
     1054                'image_file' => esc_url(plugins_url('images/ordinateur.svg', __DIR__)),
     1055                'image_alt' => "computer icon",
     1056                'width' => "60px",
     1057                'height' => "60px",
     1058            ],
     1059            'mobile' => [
     1060                'size' => $mobile_cache_size,
     1061                'title' => __('Mobile Cache', 'lws-optimize'),
     1062                'alt_title' => __('Mobile', 'lws-optimize'),
     1063                'amount' => $mobile_cache,
     1064                'id' => "lws_optimize_mobile_cache",
     1065                'image_file' => esc_url(plugins_url('images/mobile.svg', __DIR__)),
     1066                'image_alt' => "mobile icon",
     1067                'width' => "50px",
     1068                'height' => "60px",
     1069            ],
     1070            'css' => [
     1071                'size' => $css_cache_size,
     1072                'title' => __('CSS Cache', 'lws-optimize'),
     1073                'alt_title' => __('CSS', 'lws-optimize'),
     1074                'amount' => $css_cache,
     1075                'id' => "lws_optimize_css_cache",
     1076                'image_file' => esc_url(plugins_url('images/css.svg', __DIR__)),
     1077                'image_alt' => "css logo in a window icon",
     1078                'width' => "60px",
     1079                'height' => "60px",
     1080            ],
     1081            'js' => [
     1082                'size' => $js_cache_size,
     1083                'title' => __('JS Cache', 'lws-optimize'),
     1084                'alt_title' => __('JS', 'lws-optimize'),
     1085                'amount' => $js_cache,
     1086                'id' => "lws_optimize_js_cache",
     1087                'image_file' => esc_url(plugins_url('images/js.svg', __DIR__)),
     1088                'image_alt' => "js logo in a window icon",
     1089                'width' => "60px",
     1090                'height' => "60px",
     1091
     1092            ],
     1093        ];
     1094
     1095        wp_die(json_encode(array('code' => "SUCCESS", 'data' => $caches)));
     1096
     1097    }
     1098
     1099
     1100
     1101    public function lwsop_specified_urls_fb()
     1102    {
     1103        check_ajax_referer('lwsop_get_specified_url_nonce', '_ajax_nonce');
     1104        $optimize_options = get_option('lws_optimize_config_array', []);
     1105
     1106        if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['specified'])) {
     1107            wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['specified'], 'domain' => site_url()), JSON_PRETTY_PRINT));
     1108        } else {
     1109            wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
     1110        }
     1111    }
     1112
     1113    public function lwsop_save_specified_urls_fb()
     1114    {
     1115        // Add all URLs to an array, but ignore empty URLs
     1116        // If all fields are empty, remove the option from DB
     1117        check_ajax_referer('lwsop_save_specified_nonce', '_ajax_nonce');
     1118        if (isset($_POST['data'])) {
     1119            $urls = array();
     1120
     1121            $optimize_options = get_option('lws_optimize_config_array', []);
     1122
     1123            foreach ($_POST['data'] as $data) {
     1124                $value = sanitize_text_field($data['value']);
     1125                if ($value == "" || empty($value)) {
     1126                    continue;
     1127                }
     1128                $urls[] = $value;
     1129            }
     1130
     1131            $optimize_options['filebased_cache']['specified'] = $urls;
     1132
     1133            update_site_option('lws_optimize_config_array', $optimize_options);
     1134
     1135            wp_die(json_encode(array('code' => "SUCCESS", 'data' => $urls, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1136        }
     1137        wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1138    }
     1139
     1140    public function lwsop_exclude_urls_fb()
     1141    {
     1142        check_ajax_referer('lwsop_get_excluded_nonce', '_ajax_nonce');
     1143        $optimize_options = get_option('lws_optimize_config_array', []);
     1144
     1145        if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['exclusions'])) {
     1146            wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['exclusions'], 'domain' => site_url()), JSON_PRETTY_PRINT));
     1147        } else {
     1148            wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
     1149        }
     1150    }
     1151
     1152    public function lwsop_exclude_cookies_fb()
     1153    {
     1154        check_ajax_referer('lwsop_get_excluded_cookies_nonce', '_ajax_nonce');
     1155        $optimize_options = get_option('lws_optimize_config_array', []);
     1156
     1157        if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['exclusions_cookies'])) {
     1158            wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['exclusions_cookies'], 'domain' => site_url()), JSON_PRETTY_PRINT));
     1159        } else {
     1160            wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
     1161        }
     1162    }
     1163
     1164    public function lwsop_save_urls_fb()
     1165    {
     1166        // Add all URLs to an array, but ignore empty URLs
     1167        // If all fields are empty, remove the option from DB
     1168        check_ajax_referer('lwsop_save_excluded_nonce', '_ajax_nonce');
     1169
     1170        if (isset($_POST['data'])) {
     1171            $urls = array();
     1172
     1173            foreach ($_POST['data'] as $data) {
     1174                $value = sanitize_text_field($data['value']);
     1175                if ($value == "" || empty($value)) {
     1176                    continue;
     1177                }
     1178                $urls[] = $value;
     1179            }
     1180
     1181            $optimize_options = get_option('lws_optimize_config_array', []);
     1182            $optimize_options['filebased_cache']['exclusions'] = $urls;
     1183
     1184            update_option('lws_optimize_config_array', $optimize_options);
     1185
     1186            wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
     1187        }
     1188        wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1189    }
     1190
     1191    public function lwsop_save_cookies_fb()
     1192    {
     1193        // Add all Cookies to an array, but ignore empty cookies
     1194        // If all fields are empty, remove the option from DB
     1195        check_ajax_referer('lwsop_save_excluded_cookies_nonce', '_ajax_nonce');
     1196
     1197        if (isset($_POST['data'])) {
     1198            $urls = array();
     1199
     1200            foreach ($_POST['data'] as $data) {
     1201                $value = sanitize_text_field($data['value']);
     1202                if ($value == "" || empty($value)) {
     1203                    continue;
     1204                }
     1205                $urls[] = $value;
     1206            }
     1207
     1208            $optimize_options = get_option('lws_optimize_config_array', []);
     1209            $optimize_options['filebased_cache']['exclusions_cookies'] = $urls;
     1210
     1211
     1212            update_option('lws_optimize_config_array', $optimize_options);
     1213
     1214            wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
     1215        }
     1216        wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1217    }
     1218
     1219
     1220
     1221    public function lwsop_get_url_preload()
     1222    {
     1223        check_ajax_referer('nonce_lws_optimize_preloading_url_files', '_ajax_nonce');
     1224        if (!isset($_POST['action'])) {
     1225            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     1226        }
     1227
     1228        $optimize_options = get_option('lws_optimize_config_array', []);
     1229
     1230        // Get the exclusions
     1231        $preloads = isset($optimize_options['preload_css']['links']) ? $optimize_options['preload_css']['links'] : array();
     1232
     1233        wp_die(json_encode(array('code' => "SUCCESS", "data" => $preloads, 'domain' => site_url())), JSON_PRETTY_PRINT);
     1234    }
     1235
     1236    public function lwsop_set_url_preload()
     1237    {
     1238        check_ajax_referer('nonce_lws_optimize_preloading_url_files_set', '_ajax_nonce');
     1239        $optimize_options = get_option('lws_optimize_config_array', []);
     1240
     1241        if (isset($_POST['data'])) {
     1242            $urls = array();
     1243
     1244            foreach ($_POST['data'] as $data) {
     1245                $value = sanitize_text_field($data['value']);
     1246                if ($value == "" || empty($value)) {
     1247                    continue;
     1248                }
     1249                $urls[] = $value;
     1250            }
     1251            $optimize_options['preload_css']['links'] = $urls;
     1252
     1253            update_option('lws_optimize_config_array', $optimize_options);
     1254            wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
     1255        }
     1256        wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1257    }
     1258
     1259    public function lwsop_get_url_preload_font()
     1260    {
     1261        check_ajax_referer('nonce_lws_optimize_preloading_url_fonts', '_ajax_nonce');
     1262        if (!isset($_POST['action'])) {
     1263            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     1264        }
     1265
     1266        $optimize_options = get_option('lws_optimize_config_array', []);
     1267
     1268        // Get the exclusions
     1269        $preloads = isset($optimize_options['preload_font']['links']) ? $optimize_options['preload_font']['links'] : array();
     1270
     1271        wp_die(json_encode(array('code' => "SUCCESS", "data" => $preloads, 'domain' => site_url())), JSON_PRETTY_PRINT);
     1272    }
     1273
     1274    public function lwsop_set_url_preload_font()
     1275    {
     1276        check_ajax_referer('nonce_lws_optimize_preloading_url_fonts_set', '_ajax_nonce');
     1277        if (isset($_POST['data'])) {
     1278            $urls = array();
     1279
     1280            $optimize_options = get_option('lws_optimize_config_array', []);
     1281
     1282            foreach ($_POST['data'] as $data) {
     1283                $value = sanitize_text_field($data['value']);
     1284                if ($value == "" || empty($value)) {
     1285                    continue;
     1286                }
     1287                $urls[] = $value;
     1288            }
     1289
     1290            $optimize_options['preload_font']['links'] = $urls;
     1291
     1292            update_option('lws_optimize_config_array', $optimize_options);
     1293            wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
     1294        }
     1295        wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
     1296    }
     1297
     1298    /**
     1299     * Check and return the state of the preloading
     1300     */
     1301    public function lwsop_check_preload_update()
     1302    {
     1303        check_ajax_referer('lwsop_check_for_update_preload_nonce', '_ajax_nonce');
     1304
     1305        $optimize_options = get_option('lws_optimize_config_array', []);
     1306
     1307        $urls = get_option('lws_optimize_sitemap_urls', ['time' => 0, 'urls' => []]);
     1308        $time = $urls['time'] ?? 0;
     1309
     1310        // It has been more than an hour since the latest fetch from the sitemap
     1311        if ($time + 300 < time()) {
     1312            // We get the freshest data
     1313            $urls = $this->get_sitemap_urls();
     1314            if (!empty($urls)) {
     1315                update_option('lws_optimize_sitemap_urls', ['time' => time(), 'urls' => $urls]);
     1316            }
     1317        } else {
     1318            // We get the ones currently saved in base
     1319            $urls = $urls['urls'] ?? [];
     1320        }
     1321
     1322        $done = 0;
     1323
     1324        if (empty($urls)){
     1325            wp_die(json_encode(array('code' => "ERROR", "data" => $sitemap, 'message' => "Failed to get some of the datas", 'domain' => site_url())), JSON_PRETTY_PRINT);
     1326        }
     1327
     1328        foreach ($urls as $url) {
     1329            $parsed_url = parse_url($url);
     1330            $parsed_url = isset($parsed_url['path']) ? $parsed_url['path'] : '';
     1331            $path = $this->lwsOptimizeCache->lwsop_set_cachedir($parsed_url);
     1332
     1333            $file_exists = glob($path . "index*") ?? [];
     1334            if (!empty($file_exists)) {
     1335                $done++;
     1336            }
     1337        }
     1338
     1339        $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
     1340        $optimize_options['filebased_cache']['preload_done'] = $done;
     1341        $optimize_options['filebased_cache']['preload_ongoing'] = $optimize_options['filebased_cache']['preload_quantity'] - $done == 0 ? "false" : "true";
     1342
     1343        $next = wp_next_scheduled('lws_optimize_start_filebased_preload') ?? null;
     1344        if ($next != null) {
     1345            $next = get_date_from_gmt(date('Y-m-d H:i:s', $next), 'Y-m-d H:i:s');
     1346        } else {
     1347            if (!wp_next_scheduled('lws_optimize_start_filebased_preload')) {
     1348                wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
     1349            }
     1350        }
     1351
     1352        $next = wp_next_scheduled('lws_optimize_start_filebased_preload') ?? null;
     1353        if ($next != null) {
     1354            $next = get_date_from_gmt(date('Y-m-d H:i:s', $next), 'Y-m-d H:i:s');
     1355        }
     1356
     1357        $data = [
     1358            'quantity' => $optimize_options['filebased_cache']['preload_quantity'] ?? null,
     1359            'done' => $optimize_options['filebased_cache']['preload_done'] ?? null,
     1360            'ongoing' => $optimize_options['filebased_cache']['preload_ongoing'] ?? null,
     1361            'next' => $next ?? null
     1362        ];
     1363
     1364        update_option('lws_optimize_config_array', $optimize_options);
     1365
     1366        if ($data['quantity'] === null || $data['done'] === null || $data['ongoing'] === null || $data['next'] === null) {
     1367            wp_die(json_encode(array('code' => "ERROR", "data" => $data, 'message' => "Failed to get some of the datas", 'domain' => site_url())), JSON_PRETTY_PRINT);
     1368        }
     1369
     1370
     1371        wp_die(json_encode(array('code' => "SUCCESS", "data" => $data, 'domain' => site_url())), JSON_PRETTY_PRINT);
     1372    }
     1373
     1374
     1375
     1376    public function lwsop_reload_stats()
     1377    {
     1378        $stats = $this->lwsop_recalculate_stats("get");
     1379
     1380        $stats['desktop']['size'] = $this->lwsOpSizeConvert($stats['desktop']['size'] ?? 0);
     1381        $stats['mobile']['size'] = $this->lwsOpSizeConvert($stats['mobile']['size'] ?? 0);
     1382        $stats['css']['size'] = $this->lwsOpSizeConvert($stats['css']['size'] ?? 0);
     1383        $stats['js']['size'] = $this->lwsOpSizeConvert($stats['js']['size'] ?? 0);
     1384
     1385        wp_die(json_encode(array('code' => "SUCCESS", 'data' => $stats)));
     1386    }
     1387
     1388
     1389
     1390    public function lws_optimize_get_database_cleaning_time()
     1391    {
     1392        check_ajax_referer('lws_optimize_get_database_cleaning_nonce', '_ajax_nonce');
     1393        $next = wp_next_scheduled('lws_optimize_maintenance_db_weekly') ?? false;
     1394        if (!$next) {
     1395            $next = "-";
     1396        } else {
     1397            $next = get_date_from_gmt(date('Y-m-d H:i:s', intval($next)), 'Y-m-d H:i:s');
     1398        }
     1399
     1400        wp_die(json_encode(array('code' => "SUCCESS", "data" => $next)), JSON_PRETTY_PRINT);
     1401    }
     1402
     1403
     1404
     1405    /**
     1406     * Clear every caches available on Optimize
     1407    */
     1408    public function lws_op_clear_all_caches() {
     1409        check_ajax_referer('lws_op_clear_all_caches_nonce', '_ajax_nonce');
     1410
     1411        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
     1412        $logger = fopen($this->log_file, 'a');
     1413        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed all caches' . PHP_EOL);
     1414        fclose($logger);
     1415
     1416        delete_option('lws_optimize_sitemap_urls');
     1417        delete_option('lws_optimize_preload_is_ongoing');
     1418        $this->after_cache_purge_preload();
     1419
     1420        $this->lwsop_dump_all_dynamic_caches();
     1421
     1422        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1423    }
     1424
     1425    /**
     1426     * Clear the file-based cache completely
     1427     */
     1428    public function lws_optimize_clear_cache()
     1429    {
     1430        check_ajax_referer('clear_fb_caching', '_ajax_nonce');
     1431
     1432        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $GLOBALS['lws_optimize']);
     1433        $logger = fopen($this->log_file, 'a');
     1434        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache on demand' . PHP_EOL);
     1435        fclose($logger);
     1436
     1437        delete_option('lws_optimize_sitemap_urls');
     1438        delete_option('lws_optimize_preload_is_ongoing');
     1439        $this->after_cache_purge_preload();
     1440        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1441    }
     1442
     1443    public function lws_clear_opcache()
     1444    {
     1445        check_ajax_referer('clear_opcache_caching', '_ajax_nonce');
     1446        $this->lwsop_remove_opcache();
     1447        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1448    }
     1449
     1450    public function lws_optimize_clear_stylecache()
     1451    {
     1452        check_ajax_referer('clear_style_fb_caching', '_ajax_nonce');
     1453        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-css", $this);
     1454        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-js", $this);
     1455
     1456        $logger = fopen($this->log_file, 'a');
     1457        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed CSS/JS cache' . PHP_EOL);
     1458        fclose($logger);
     1459
     1460        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1461    }
     1462
     1463    public function lws_optimize_clear_htmlcache()
     1464    {
     1465        check_ajax_referer('clear_html_fb_caching', '_ajax_nonce');
     1466
     1467        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache", $this);
     1468        $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-mobile", $this);
     1469
     1470        $this->after_cache_purge_preload();
     1471
     1472        $logger = fopen($this->log_file, 'a');
     1473        fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed HTML cache' . PHP_EOL);
     1474        fclose($logger);
     1475
     1476        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1477    }
     1478
     1479    public function lws_optimize_clear_currentcache()
     1480    {
     1481        check_ajax_referer('clear_currentpage_fb_caching', '_ajax_nonce');
     1482
     1483        // Get the request_uri of the current URL to remove
     1484        // If not found, do not delete anything
     1485        $uri = esc_url($_POST['request_uri']) ?? false;
     1486
     1487        $logger = fopen($this->log_file, 'a');
     1488        fwrite($logger, '[' . date('Y-m-d H:i:s') . "] Starting to remove $uri cache" . PHP_EOL);
     1489        fclose($logger);
     1490
     1491        if ($uri === false) {
     1492            wp_die(json_encode(array('code' => 'ERROR', 'data' => "/"), JSON_PRETTY_PRINT));
     1493        }
     1494
     1495        apply_filters("lws_optimize_clear_filebased_cache", $uri, "lws_optimize_clear_currentcache");
     1496
     1497        wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
     1498    }
     1499
     1500
     1501
     1502    public function lws_optimize_set_fb_status()
     1503    {
     1504        check_ajax_referer('change_filebased_cache_status_nonce', '_ajax_nonce');
     1505
     1506        // Validate required parameters
     1507        if (!isset($_POST['timer']) || !isset($_POST['state'])) {
     1508            wp_die(json_encode(['code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()]));
     1509        }
     1510
     1511        // Get fresh copy of options
     1512        $optimize_options = get_option('lws_optimize_config_array', []);
     1513
     1514        // Sanitize inputs
     1515        $timer = sanitize_text_field($_POST['timer']);
     1516        $state = sanitize_text_field($_POST['state']) === "true" ? "true" : "false";
     1517
     1518        // Update configuration
     1519        $optimize_options['filebased_cache']['exceptions'] = $optimize_options['filebased_cache']['exceptions'] ?? [];
     1520        $optimize_options['filebased_cache']['state'] = $state;
     1521        $optimize_options['filebased_cache']['timer'] = $timer;
     1522
     1523        // Update Cloudflare TTL to match filebased cache clear timer
     1524        $this->cloudflare_manager->lws_optimize_change_cloudflare_ttl($timer);
     1525
     1526        // Update preload status if necessary
     1527        if (isset($optimize_options['filebased_cache']['preload']) && $optimize_options['filebased_cache']['preload'] == "true") {
     1528            $optimize_options['filebased_cache']['preload_ongoing'] = "true";
     1529        }
     1530
     1531        // Update all .htaccess files by removing or adding the rules
     1532        if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
     1533            $this->lws_optimize_set_cache_htaccess();
     1534        } else {
     1535            $this->unset_cache_htaccess();
     1536        }
     1537        if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
     1538            $this->set_gzip_brotli_htaccess();
     1539        } else {
     1540            $this->unset_gzip_brotli_htaccess();
     1541        }
     1542        $this->lws_optimize_reset_header_htaccess();
     1543
     1544        // Clear dynamic cache
     1545        $this->lwsop_dump_all_dynamic_caches();
     1546
     1547        // Save updated options
     1548        update_option('lws_optimize_config_array', $optimize_options);
     1549
     1550        wp_die(json_encode(['code' => "SUCCESS", 'data' => $state]), JSON_PRETTY_PRINT);
     1551    }
     1552
     1553    /**
     1554     * Change the value of the file-based cache timer. Will automatically launch a WP-Cron at the defined $timer to clear the cache
     1555     */
     1556    public function lws_optimize_set_fb_timer()
     1557    {
     1558        check_ajax_referer('change_filebased_cache_timer_nonce', '_ajax_nonce');
     1559        if (!isset($_POST['timer'])) {
     1560            wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url())));
     1561        }
     1562
     1563        $optimize_options = get_option('lws_optimize_config_array', []);
     1564
     1565        $timer = sanitize_text_field($_POST['timer']);
     1566        if (empty($timer)) {
     1567            if (empty($GLOBALS['lws_optimize_cache_timestamps']) || array_key_first($GLOBALS['lws_optimize_cache_timestamps']) === null) {
     1568                $timer = "daily";
     1569            } else {
     1570                $timer = $GLOBALS['lws_optimize_cache_timestamps'][array_key_first($GLOBALS['lws_optimize_cache_timestamps'])][0];
     1571            }
     1572        }
     1573
     1574        $fb_options = $this->lwsop_check_option('filebased_cache');
     1575        if ($fb_options['state'] === "false") {
     1576            $optimize_options['filebased_cache']['state'] = "false";
     1577        }
     1578        if (isset($optimize_options['filebased_cache']['timer']) && $optimize_options['filebased_cache']['timer'] === $timer) {
     1579            wp_die(json_encode(array('code' => "SUCCESS", "data" => $timer)), JSON_PRETTY_PRINT);
     1580        }
     1581
     1582        if ($fb_options['state'] == "true") {
     1583           $this->lws_optimize_reset_header_htaccess();
     1584        } else {
     1585            $this->unset_header_htaccess();
     1586        }
     1587
     1588        // Update all .htaccess files by removing or adding the rules
     1589        if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
     1590            $this->lws_optimize_set_cache_htaccess();
     1591        } else {
     1592            $this->unset_cache_htaccess();
     1593        }
     1594        if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
     1595            $this->set_gzip_brotli_htaccess();
     1596        } else {
     1597            $this->unset_gzip_brotli_htaccess();
     1598        }
     1599        $this->lws_optimize_reset_header_htaccess();
     1600
     1601        $optimize_options['filebased_cache']['timer'] = $timer;
     1602
     1603        // Update Cloudflare TTL to match filebased cache clear timer
     1604        $this->cloudflare_manager->lws_optimize_change_cloudflare_ttl($timer);
     1605
     1606        update_option('lws_optimize_config_array', $optimize_options);
     1607
     1608        // Remove the old event and schedule a new one with the new timer
     1609        if (wp_next_scheduled('lws_optimize_clear_filebased_cache_cron')) {
     1610            wp_unschedule_event(wp_next_scheduled('lws_optimize_clear_filebased_cache_cron'), 'lws_optimize_clear_filebased_cache_cron');
     1611        }
     1612
     1613        // Never start cron if timer is defined as zero (infinite)
     1614        if ($timer != 0) {
     1615            wp_schedule_event(time(), $timer, 'lws_optimize_clear_filebased_cache_cron');
     1616        }
     1617
     1618        wp_die(json_encode(array('code' => "SUCCESS", "data" => $timer)), JSON_PRETTY_PRINT);
     1619    }
     1620
     1621
     1622
     1623    public function lwsop_deactivate_temporarily() {
     1624        check_ajax_referer('lwsop_deactivate_temporarily_nonce', '_ajax_nonce');
     1625        if (!isset($_POST['duration'])) {
     1626            wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
     1627        }
     1628
     1629        $duration = intval($_POST['duration']);
     1630        if ($duration < 0) {
     1631            wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
     1632        }
     1633
     1634        // Get options before making any changes
     1635        $optimize_options = get_option('lws_optimize_config_array', []);
     1636
     1637        if ($duration == 0) {
     1638            delete_option('lws_optimize_deactivate_temporarily');
     1639
     1640            // Update all .htaccess files by removing or adding the rules
     1641            if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
     1642                $this->lws_optimize_set_cache_htaccess();
     1643            } else {
     1644                $this->unset_cache_htaccess();
     1645            }
     1646            if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
     1647                $this->set_gzip_brotli_htaccess();
     1648            } else {
     1649                $this->unset_gzip_brotli_htaccess();
     1650            }
     1651            $this->lws_optimize_reset_header_htaccess();
     1652        } else {
     1653            $transient_set = update_option('lws_optimize_deactivate_temporarily', time() + $duration);
     1654
     1655            // Verify that the transient is set
     1656            if (!$transient_set) {
     1657                wp_die(json_encode(array('code' => "TRANSIENT_ERROR", 'data' => "Could not set temporary deactivation"), JSON_PRETTY_PRINT));
     1658            }
     1659
     1660            // Remove .htaccess rules
     1661            $this->unset_cache_htaccess();
     1662            $this->unset_gzip_brotli_htaccess();
     1663            $this->unset_header_htaccess();
     1664
     1665            // Verify the transient was set correctly
     1666            $transient_value = get_option('lws_optimize_deactivate_temporarily', false);
     1667            if ($transient_value === false) {
     1668                wp_die(json_encode(array('code' => "TRANSIENT_VERIFY_ERROR", 'data' => "Temporary deactivation may not work correctly"), JSON_PRETTY_PRINT));
     1669            }
     1670        }
     1671
     1672        $this->lwsop_dump_all_dynamic_caches();
     1673
     1674        wp_die(json_encode(array('code' => "SUCCESS", 'data' => array('duration' => $duration)), JSON_PRETTY_PRINT));
     1675    }
     1676
     1677    public function lwsop_do_pagespeed_test()
     1678    {
     1679        check_ajax_referer('lwsop_doing_pagespeed_nonce', '_ajax_nonce');
     1680        $url = $_POST['url'] ?? null;
     1681        $type = $_POST['type'] ?? null;
     1682        $date = time();
     1683
     1684
     1685        if ($url === null || $type === null) {
     1686            wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
     1687        }
     1688
     1689        $config_array = get_option('lws_optimize_pagespeed_history', array());
     1690        $last_test = array_reverse($config_array)[0]['date'] ?? 0;
     1691
     1692
     1693        if ($last_test = strtotime($last_test) && time() - $last_test < 180) {
     1694            wp_die(json_encode(array('code' => "TOO_RECENT", 'data' => 180 - ($date - $last_test)), JSON_PRETTY_PRINT));
     1695        }
     1696
     1697        $url = esc_url($url);
     1698        $type = sanitize_text_field($type);
     1699
     1700        $response = wp_remote_get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$url&key=AIzaSyD8yyUZIGg3pGYgFOzJR1NsVztAf8dQUFQ&strategy=$type", ['timeout' => 45, 'sslverify' => false]);
     1701        if (is_wp_error($response)) {
     1702            wp_die(json_encode(array('code' => "ERROR_PAGESPEED", 'data' => $response), JSON_PRETTY_PRINT));
     1703        }
     1704
     1705        $response = json_decode($response['body'], true);
     1706        if (json_last_error() !== JSON_ERROR_NONE) {
     1707            wp_die(json_encode(array('code' => "ERROR_DECODE", 'data' => $response), JSON_PRETTY_PRINT));
     1708        }
     1709
     1710        $performance = $response['lighthouseResult']['categories']['performance']['score'] ?? null;
     1711        $speedMetric = $response['lighthouseResult']['audits']['speed-index']['displayValue'] ?? null;
     1712        $speedMetricValue = $response['lighthouseResult']['audits']['speed-index']['numericValue'] ?? null;
     1713        $speedMetricUnit = $response['lighthouseResult']['audits']['speed-index']['numericUnit'] ?? null;
     1714
     1715
     1716        $scores = [
     1717            'performance' => $performance,
     1718            'speed' => str_replace("/\s/g", "", $speedMetric),
     1719            'speed_milli' => $speedMetricValue,
     1720            'speed_unit' => $speedMetricUnit
     1721        ];
     1722
     1723        $new_pagespeed = ['date' =>  date("d M Y, H:i", $date) . " GMT+0", 'url' => $url, 'type' => $type, 'scores' => $scores];
     1724        $config_array[] = $new_pagespeed;
     1725        update_option('lws_optimize_pagespeed_history', $config_array);
     1726
     1727        $history = array_slice($config_array, -10);
     1728        $history = array_reverse($history);
     1729
     1730
     1731        wp_die(json_encode(array('code' => "SUCCESS", 'data' => $scores, 'history' => $history), JSON_PRETTY_PRINT));
     1732    }
     1733
     1734    public function lwsop_dump_dynamic_cache()
     1735    {
     1736        check_ajax_referer('lwsop_empty_d_cache_nonce', '_ajax_nonce');
     1737        wp_die($this->lwsop_dump_all_dynamic_caches());
     1738    }
     1739
     1740    public function lws_optimize_activate_cleaner()
     1741    {
     1742        check_ajax_referer('lwsop_activate_cleaner_nonce', '_ajax_nonce');
     1743        if (!isset($_POST['state'])) {
     1744            wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
     1745        }
     1746
     1747        if ($_POST['state'] == "true") {
     1748            $plugin = activate_plugin("lws-cleaner/lws-cleaner.php");
     1749            $state = "true";
     1750        } else {
     1751            $plugin = deactivate_plugins("lws-cleaner/lws-cleaner.php");
     1752            $state = "false";
     1753        }
     1754
     1755        wp_die(json_encode(array('code' => "SUCCESS", 'data' => $plugin, 'state' => $state), JSON_PRETTY_PRINT));
     1756    }
     1757
     1758
     1759
     1760    // Fetch options for maintaining DB
     1761    public function lws_optimize_manage_maintenance_get()
     1762    {
     1763        check_ajax_referer('lwsop_get_maintenance_db_nonce', '_ajax_nonce');
     1764
     1765        $optimize_options = get_option('lws_optimize_config_array', []);
     1766
     1767        if (!isset($optimize_options['maintenance_db']) || !isset($optimize_options['maintenance_db']['options'])) {
     1768            $optimize_options['maintenance_db']['options'] = array(
     1769                'myisam' => false,
     1770                'drafts' => false,
     1771                'revisions' => false,
     1772                'deleted_posts' => false,
     1773                'spam_posts' => false,
     1774                'deleted_comments' => false,
     1775                'expired_transients' => false
     1776            );
     1777            update_option('lws_optimize_config_array', $optimize_options);
     1778        }
     1779
     1780        wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options['maintenance_db']['options'], 'domain' => site_url())), JSON_PRETTY_PRINT);
     1781    }
     1782
     1783    // Update the DB options array
     1784    public function lws_optimize_set_maintenance_db_options()
     1785    {
     1786        // Add all URLs to an array, but ignore empty URLs
     1787        // If all fields are empty, remove the option from DB
     1788        check_ajax_referer('lwsop_set_maintenance_db_nonce', '_ajax_nonce');
     1789        if (!isset($_POST['formdata'])) {
     1790            $_POST['formdata'] = [];
     1791        }
     1792        $options = array();
     1793
     1794        foreach ($_POST['formdata'] as $data) {
     1795            $value = sanitize_text_field($data);
     1796            if ($value == "" || empty($value)) {
     1797                continue;
     1798            }
     1799            $options[] = $value;
     1800        }
     1801
     1802        $optimize_options = get_option('lws_optimize_config_array', []);
     1803        $optimize_options['maintenance_db']['options'] = $options;
     1804
     1805        update_option('lws_optimize_config_array', $optimize_options);
     1806
     1807        if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
     1808            wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
     1809        }
     1810        wp_die(json_encode(array('code' => "SUCCESS", "data" => $options)), JSON_PRETTY_PRINT);
     1811    }
     1812
     1813    public function lws_optimize_create_maintenance_db_options()
     1814    {
     1815        global $wpdb;
     1816        $optimize_options = get_option('lws_optimize_config_array', []);
     1817
     1818        $config_options = $optimize_options['maintenance_db']['options'];
     1819        foreach ($config_options as $options) {
     1820            switch ($options) {
     1821                case 'myisam':
     1822                    $results = $wpdb->get_results("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '{$wpdb->prefix}%' AND ENGINE = 'MyISAM' AND TABLE_SCHEMA = '" . $wpdb->dbname . "';");
     1823                    foreach ($results as $result) {
     1824                        $rows_affected = $wpdb->query($wpdb->prepare("OPTIMIZE TABLE %s", $result->table_name));
     1825                        if ($rows_affected === false) {
     1826                            error_log("lws-optimize.php::create_maintenance_db_options | The table {$result->table_name} has not been OPTIMIZED");
     1827                        }
     1828                    }
     1829                    break;
     1830                case 'drafts':
     1831                    $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}posts WHERE post_status = 'draft';");
     1832                    $wpdb->query($query);
     1833                    // Remove drafts
     1834                    break;
     1835                case 'revisions':
     1836                    $query = $wpdb->prepare("DELETE FROM `{$wpdb->prefix}posts` WHERE post_type = 'revision';");
     1837                    $wpdb->query($query);
     1838                    // Remove revisions
     1839                    break;
     1840                case 'deleted_posts':
     1841                    $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}posts WHERE post_status = 'trash' && (post_type = 'post' OR post_type = 'page');");
     1842                    $wpdb->query($query);
     1843                    // Remove trashed posts/page
     1844                    break;
     1845                case 'spam_comments':
     1846                    $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}comments WHERE comment_approved = 'spam';");
     1847                    $wpdb->query($query);
     1848                    // remove spam comments
     1849                    break;
     1850                case 'deleted_comments':
     1851                    $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}comments WHERE comment_approved = 'trash';");
     1852                    $wpdb->query($query);
     1853                    // remove deleted comments
     1854                    break;
     1855                case 'expired_transients':
     1856                    $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '%_transient_timeout_%' AND option_value < ?;", [time()]);
     1857                    $wpdb->query($query);
     1858                    // remove expired transients
     1859                    break;
     1860                default:
     1861                    break;
     1862            }
     1863        }
     1864    }
     1865
     1866
     1867
     1868    public function lwsop_get_setup_optimize()
     1869    {
     1870        check_ajax_referer('lwsop_change_optimize_configuration_nonce', '_ajax_nonce');
     1871        if (!isset($_POST['action']) || !isset($_POST['value'])) {
     1872            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     1873        }
     1874
     1875        $value = sanitize_text_field($_POST['value']);
     1876
     1877        // No value ? Cannot proceed
     1878        if (!isset($value) || !$value) {
     1879            wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
     1880        }
     1881
     1882        switch ($value) {
     1883            case 'essential':
     1884                $value = "basic";
     1885                break;
     1886            case 'optimized':
     1887                $value = "advanced";
     1888                break;
     1889            case 'max':
     1890                $value = "full";
     1891                break;
     1892            default:
     1893                $value = "basic";
     1894                break;
     1895        }
     1896
     1897
     1898        $this->lwsop_auto_setup_optimize($value);
     1899        wp_die(json_encode(array('code' => "SUCCESS", "data" => "")), JSON_PRETTY_PRINT);
     1900    }
     1901
     1902
     1903
     1904    public function lwsop_regenerate_logs()
     1905    {
     1906        check_ajax_referer('lws_regenerate_nonce_logs', '_ajax_nonce');
     1907
     1908        $dir = wp_upload_dir();
     1909        $file = $dir['basedir'] . '/lwsoptimize/debug.log';
     1910        if (empty($file)) {
     1911            $content = __('No log file found.', 'lws-optimize');
     1912        } else {
     1913            $content = esc_html(implode("\n", array_reverse(file($file, FILE_IGNORE_NEW_LINES))));
     1914        }
     1915
     1916        wp_die(json_encode(array('code' => "SUCCESS", "data" => $content)), JSON_PRETTY_PRINT);
     1917    }
     1918
     1919    public function lwsOp_sendFeedbackUser() {
     1920        check_ajax_referer('lwsOP_sendFeedbackUser', '_ajax_nonce');
     1921
     1922        if (!isset($_POST['form']) || empty($_POST['form'])) {
     1923            echo json_encode(['code' => 'ERROR_FORM', 'data' => 'No feedback data provided']);
     1924            exit;
     1925        }
     1926
     1927        $formData = $_POST['form'] ?? [];
     1928
     1929        $type = $formData['type'] ?? 'suggestion';
     1930        $name = $formData['name'] ?? 'Anonymous';
     1931        $email = $formData['email'] ?? '';
     1932        $feedback = $formData['feedback'] ?? '';
     1933        $timestamp = $formData['timestamp'] ?? date('c');
     1934        $page = $formData['page'] ?? '';
     1935
     1936        empty($name) ? $name = 'Anonyme' : $name = htmlspecialchars(trim($name));
     1937        empty($email) ? $email = 'Non renseigné' : $email = filter_var(trim($email), FILTER_SANITIZE_EMAIL);
     1938
     1939        switch ($type) {
     1940            case 'bug':
     1941                $type = 'Bug / Problème';
     1942                break;
     1943            case 'improvement':
     1944                $type = 'Amélioration';
     1945                break;
     1946            case 'other':
     1947                $type = 'Autre';
     1948                break;
     1949            case 'suggestion':
     1950            default:
     1951                $type = 'Suggestion';
     1952                break;
     1953        }
     1954
     1955        $subject = "[Feedback LWSOptimize] $type";
     1956
     1957        $html_content = "
     1958        <!DOCTYPE html>
     1959        <html>
     1960        <head>
     1961            <meta charset='UTF-8'>
     1962            <style>
     1963                body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
     1964                .container { max-width: 600px; margin: 0 auto; padding: 20px; }
     1965                .header { background-color: #007cba; color: white; padding: 15px; border-radius: 5px; }
     1966                .content { background-color: #f9f9f9; padding: 20px; border-radius: 5px; margin-top: 10px; }
     1967                .field { margin-bottom: 15px; }
     1968                .label { font-weight: bold; color: #007cba; }
     1969                .value { margin-top: 5px; }
     1970                .feedback-text { background-color: white; padding: 15px; border-left: 4px solid #007cba; }
     1971            </style>
     1972        </head>
     1973        <body>
     1974            <div class='container'>
     1975                <div class='header'>
     1976                    <h2>Nouveau feedback Auto-Installeur</h2>
     1977                </div>
     1978                <div class='content'>
     1979                    <div class='field'>
     1980                        <div class='label'>Type de feedback :</div>
     1981                        <div class='value'>$type</div>
     1982                    </div>
     1983                    <div class='field'>
     1984                        <div class='label'>Nom :</div>
     1985                        <div class='value'>$name</div>
     1986                    </div>
     1987                    <div class='field'>
     1988                        <div class='label'>Email :</div>
     1989                        <div class='value'>$email</div>
     1990                    </div>
     1991                    <div class='field'>
     1992                        <div class='label'>Domaine : </div>
     1993                        <div class='value'>{$_SERVER['MD_MASTER']}</div>
     1994                    </div>
     1995                    <div class='field'>
     1996                        <div class='label'>Page :</div>
     1997                        <div class='value'>$page</div>
     1998                    </div>
     1999                    <div class='field'>
     2000                        <div class='label'>Date/Heure :</div>
     2001                        <div class='value'>$timestamp</div>
     2002                    </div>
     2003                    <div class='field'>
     2004                        <div class='label'>Message :</div>
     2005                        <div class='feedback-text'>$feedback</div>
     2006                    </div>
     2007                </div>
     2008            </div>
     2009        </body>
     2010        </html>
     2011        ";
     2012
     2013        $headers = "MIME-Version: 1.0" . "\r\n";
     2014        $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
     2015        $headers .= "From: noreply@" . $_SERVER['HTTP_HOST'] . "\r\n";
     2016
     2017        if (mail('[email protected]', $subject, $html_content, $headers)) {
     2018            echo json_encode(['code' => 'SUCCESS', 'data' => "Mail was sent successfully"]);
     2019            exit;
     2020        } else {
     2021            echo json_encode(['code' => 'ERROR', 'data' => 'Failed to send mail']);
     2022            exit;
     2023        }
     2024    }
    3792025}
  • lws-optimize/trunk/Classes/LwsOptimize.php

    r3360302 r3362313  
    1616{
    1717    public $log_file;
    18     public $optimize_options;
    1918    public $lwsOptimizeCache;
    2019    public $lwsImageOptimization;
     
    2625    public function __construct()
    2726    {
    28         // Store the class in GLOBALS for later usage
     27        // Initialize the global LWS Optimize instance
    2928        $GLOBALS['lws_optimize'] = $this;
    3029
     
    3231        $this->setupLogfile();
    3332
    34         // Path to the object-cache file (for Memcached)
    35         define('LWSOP_OBJECTCACHE_PATH', WP_CONTENT_DIR . '/object-cache.php');
    36 
    37         // Get all the options for LWSOptimize. If none are found (first start, erased from DB), recreate the array
     33        // Get all the options for LWSOptimize. If array is not found, initialize it
    3834        $optimize_options = get_option('lws_optimize_config_array', []);
    3935        if (empty($optimize_options)) {
     36            // Generate the options
    4037            $optimize_options = $this->lwsop_auto_setup_optimize("basic", true);
    41             $this->lws_optimize_reset_header_htaccess();
    42 
    43             // Deactivate the filebased_cache preloading at first
     38
     39            // Deactivate the filebased_cache preloading
    4440            $optimize_options['filebased_cache']['preload'] = "false";
     41            delete_option('lws_optimize_preload_is_ongoing');
    4542            if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
    4643                wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
    4744            }
    4845
    49             // Deactivate the plugin on activation
    50             delete_option('lws_optimize_offline');
    51             delete_option('lws_optimize_preload_is_ongoing');
    52 
    53             $this->lws_optimize_set_cache_htaccess();
     46            // If it got installed by the LWS Auto-installer, then proceed to activate the plugin by default
     47            if (get_option('lws_from_autoinstall_optimize', false)) {
     48                delete_option("lws_from_autoinstall_optimize");
     49                delete_option('lws_optimize_offline');
     50            }
    5451
    5552            update_option('lws_optimize_config_array', $optimize_options);
    5653        }
    5754
    58         // Store the array globally to avoid updating it each time
    59         $this->optimize_options = $optimize_options;
    60 
    61         // Add custom action hooks for external cache clearing
    62         add_action('lws_optimize_clear_all_cache', [$this, 'clear_all_cache_external']);
    63         add_action('lws_optimize_clear_url_cache', [$this, 'clear_url_cache_external'], 10, 1);
    64 
    65         // If it got installed by the LWS Auto-installer, then proceed to activate it on recommended by default
    66         $auto_installer_mode = get_option('lws_from_autoinstall_optimize', false);
    67         if ($auto_installer_mode) {
    68             $this->lwsop_auto_setup_optimize("basic", true);
    69             delete_option("lws_from_autoinstall_optimize");
    70             delete_option('lws_optimize_offline');
    71         }
     55        // Start actions that will occur on plugin initialization
     56        add_action('init', [$this, "lws_optimize_init"]);
     57
     58        // Add new schedules time for crons
     59        add_filter('cron_schedules', [$this, 'lws_optimize_timestamp_crons']);
    7260
    7361        // Init the FileCache Class
     
    7664        // Init the ImageOptimization Class
    7765        $this->lwsImageOptimization = new LwsOptimizeImageOptimizationPro();
    78 
    79         add_action("wp_ajax_lwsop_deactivate_temporarily", [$this, "lwsop_deactivate_temporarily"]);
    8066
    8167        if (!get_option('lws_optimize_deactivate_temporarily')) {
     
    151137            }
    152138
     139            // Enqueue JQuery on the plugin
    153140            add_action('wp_enqueue_scripts', function () {
    154141                wp_enqueue_script('jquery');
    155142            });
    156143
     144            // Add the filters that can be used to clear all or parts of the cache
    157145            add_filter('lws_optimize_convert_media_cron', [$this, 'lws_optimize_convert_media_cron'], 10, 2);
    158146            add_filter('lws_optimize_clear_filebased_cache', [$this, 'lws_optimize_clean_filebased_cache'], 10, 2);
     
    160148            add_filter('lws_optimize_clear_all_filebased_cache', [$this, 'lws_optimize_clean_all_filebased_cache'], 10, 1);
    161149
    162 
    163 
     150            // Action to start preloading the file-based cache
    164151            add_action('lws_optimize_start_filebased_preload', [$this, 'lws_optimize_start_filebased_preload']);
    165152
     153            // If the maintenance is active but has no cron, start one
    166154            if ($this->lwsop_check_option("maintenance_db")['state'] == "true" && !wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
    167155                wp_schedule_event(time(), 'weekly', 'lws_optimize_maintenance_db_weekly');
    168156            }
    169 
    170             // Add new schedules time for crons
    171             add_filter('cron_schedules', [$this, 'lws_optimize_timestamp_crons']);
    172 
    173157
    174158            // Activate functions related to CloudFlare
     
    176160            $this->cloudflare_manager->activate_cloudflare_integration();
    177161
    178             add_action("wp_ajax_lwsop_dump_dynamic_cache", [$this, "lwsop_dump_dynamic_cache"]);
    179             add_action("wp_ajax_lws_optimize_activate_cleaner", [$this, "lws_optimize_activate_cleaner"]);
    180 
    181             // Launch the weekly DB cleanup
    182             add_action("lws_optimize_maintenance_db_weekly", [$this, "lws_optimize_create_maintenance_db_options"]);
    183             add_action("wp_ajax_lws_optimize_set_maintenance_db_options", [$this, "lws_optimize_set_maintenance_db_options"]);
    184             add_action("wp_ajax_lws_optimize_get_maintenance_db_options", [$this, "lws_optimize_manage_maintenance_get"]);
    185 
    186             add_action('wp_ajax_lwsop_change_optimize_configuration', [$this, "lwsop_get_setup_optimize"]);
    187 
    188             // If LWSOptimize is off or the cache has been deactivated, do not start the caching process
     162            // Start the file-based cache actions
    189163            if ($this->lwsop_check_option('filebased_cache')['state'] === "true") {
    190164                $this->lwsOptimizeCache->lwsop_launch_cache();
    191165            }
    192166
    193             // If the autopurge has been activated, add hooks that will clear specific cache on specific actions
    194             if (!get_option('lws_optimize_deactivate_temporarily') && $this->lwsop_check_option("autopurge")['state'] == "true") {
     167            // Start the autopurge actions
     168            if ($this->lwsop_check_option("autopurge")['state'] == "true") {
    195169                $autopurge_manager = new LwsOptimizeAutoPurge();
    196170                $autopurge_manager->start_autopurge();
    197171            }
    198 
    199             if (is_admin()) {
    200                 // Change configuration state for the differents element of LWSOptimize
    201                 add_action("wp_ajax_lws_optimize_checkboxes_action", [$this, "lws_optimize_manage_config"]);
    202                 add_action("wp_ajax_lws_optimize_checkboxes_action_delayed", [$this, "lws_optimize_manage_config_delayed"]);
    203                 add_action("wp_ajax_lws_optimize_exclusions_changes_action", [$this, "lws_optimize_manage_exclusions"]);
    204                 add_action("wp_ajax_lws_optimize_exclusions_media_changes_action", [$this, "lws_optimize_manage_exclusions_media"]);
    205                 add_action("wp_ajax_lws_optimize_fetch_exclusions_action", [$this, "lws_optimize_fetch_exclusions"]);
    206                 // Activate the "preload" option for the file-based cache
    207                 add_action("wp_ajax_lwsop_start_preload_fb", [$this, "lwsop_preload_fb"]);
    208                 add_action("wp_ajax_lwsop_change_preload_amount", [$this, "lwsop_change_preload_amount"]);
    209 
    210                 add_action("wp_ajax_lwsop_regenerate_cache", [$this, "lwsop_regenerate_cache"]);
    211                 add_action("wp_ajax_lwsop_regenerate_cache_general", [$this, "lwsop_regenerate_cache_general"]);
    212 
    213                 // Fetch an array containing every URLs that should get purged each time an autopurge starts
    214                 add_action("wp_ajax_lwsop_get_specified_url", [$this, "lwsop_specified_urls_fb"]);
    215                 // Update the specified-URLs array
    216                 add_action("wp_ajax_lwsop_save_specified_url", [$this, "lwsop_save_specified_urls_fb"]);
    217                 // Fetch an array containing every URLs that should not be cached
    218                 add_action("wp_ajax_lwsop_get_excluded_url", [$this, "lwsop_exclude_urls_fb"]);
    219                 add_action("wp_ajax_lwsop_get_excluded_cookies", [$this, "lwsop_exclude_cookies_fb"]);
    220                 // Update the excluded-URLs array
    221                 add_action("wp_ajax_lwsop_save_excluded_url", [$this, "lwsop_save_urls_fb"]);
    222                 add_action("wp_ajax_lwsop_save_excluded_cookies", [$this, "lwsop_save_cookies_fb"]);
    223 
    224                 // Get or set the URLs that should get preloaded on the website
    225                 add_action("wp_ajax_lws_optimize_add_url_to_preload", [$this, "lwsop_get_url_preload"]);
    226                 add_action("wp_ajax_lws_optimize_set_url_to_preload", [$this, "lwsop_set_url_preload"]);
    227 
    228                 // Get or set the URLs to the fonts that should get preloaded on the website
    229                 add_action("wp_ajax_lws_optimize_add_font_to_preload", [$this, "lwsop_get_url_preload_font"]);
    230                 add_action("wp_ajax_lws_optimize_set_url_to_preload_font", [$this, "lwsop_set_url_preload_font"]);
    231 
    232                 // Reload the stats of the filebased cache
    233                 add_action("wp_ajax_lwsop_reload_stats", [$this, "lwsop_reload_stats"]);
    234 
    235                 // Get when the next database maintenance will happen
    236                 add_action("wp_ajax_lws_optimize_get_database_cleaning_time", [$this, "lws_optimize_get_database_cleaning_time"]);
    237 
    238                 if (isset($this->lwsop_check_option('filebased_cache')['data']['preload']) && $this->lwsop_check_option('filebased_cache')['data']['preload'] === "true") {
    239                     add_action("wp_ajax_lwsop_check_preload_update", [$this, "lwsop_check_preload_update"]);
    240                 }
    241 
    242                 add_action("wp_ajax_lws_clear_fb_cache", [$this, "lws_optimize_clear_cache"]);
    243                 add_action("wp_ajax_lws_op_clear_all_caches", [$this, "lws_op_clear_all_caches"]);
    244                 add_action("wp_ajax_lws_clear_opcache", [$this, "lws_clear_opcache"]);
    245                 add_action("wp_ajax_lws_clear_html_fb_cache", [$this, "lws_optimize_clear_htmlcache"]);
    246                 add_action("wp_ajax_lws_clear_style_fb_cache", [$this, "lws_optimize_clear_stylecache"]);
    247                 add_action("wp_ajax_lws_clear_currentpage_fb_cache", [$this, "lws_optimize_clear_currentcache"]);
    248 
    249 
    250                 add_action("wp_ajax_lws_optimize_fb_cache_change_status", [$this, "lws_optimize_set_fb_status"]);
    251                 add_action("wp_ajax_lws_optimize_fb_cache_change_cache_time", [$this, "lws_optimize_set_fb_timer"]);
    252             }
    253         }
    254 
     172        }
     173
     174        // Update the configuration options in case they got modified
    255175        update_option('lws_optimize_config_array', $optimize_options);
    256         // Store the array globally to avoid updating it each time
    257         $this->optimize_options = $optimize_options;
    258 
    259         add_action('init', [$this, "lws_optimize_init"]);
    260         add_action("wp_ajax_lws_optimize_do_pagespeed", [$this, "lwsop_do_pagespeed_test"]);
     176
     177        // Add custom action hooks for external cache clearing
     178        add_action('lws_optimize_clear_all_cache', [$this, 'clear_all_cache_external']);
     179        add_action('lws_optimize_clear_url_cache', [$this, 'clear_url_cache_external'], 10, 1);
    261180    }
    262181
     
    368287
    369288        // Add all options referring to the WPAdmin page or the AdminBar
     289        // This will manage everything that can happen on the lws-optimize page
    370290        $admin_manager = new LwsOptimizeManageAdmin();
    371291        $admin_manager->manage_options();
     
    386306    }
    387307
    388     public function lwsop_deactivate_temporarily() {
    389         check_ajax_referer('lwsop_deactivate_temporarily_nonce', '_ajax_nonce');
    390         if (!isset($_POST['duration'])) {
    391             wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
    392         }
    393 
    394         $duration = intval($_POST['duration']);
    395         if ($duration < 0) {
    396             wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
    397         }
    398 
    399         // Get options before making any changes
    400         $optimize_options = get_option('lws_optimize_config_array', []);
    401 
    402         if ($duration == 0) {
    403             delete_option('lws_optimize_deactivate_temporarily');
    404 
    405             // Update all .htaccess files by removing or adding the rules
    406             if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
    407                 $this->lws_optimize_set_cache_htaccess();
    408             } else {
    409                 $this->unset_cache_htaccess();
    410             }
    411             if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
    412                 $this->set_gzip_brotli_htaccess();
    413             } else {
    414                 $this->unset_gzip_brotli_htaccess();
    415             }
    416             $this->lws_optimize_reset_header_htaccess();
    417         } else {
    418             $transient_set = update_option('lws_optimize_deactivate_temporarily', time() + $duration);
    419 
    420             // Verify that the transient is set
    421             if (!$transient_set) {
    422                 wp_die(json_encode(array('code' => "TRANSIENT_ERROR", 'data' => "Could not set temporary deactivation"), JSON_PRETTY_PRINT));
    423             }
    424 
    425             // Remove .htaccess rules
    426             $this->unset_cache_htaccess();
    427             $this->unset_gzip_brotli_htaccess();
    428             $this->unset_header_htaccess();
    429 
    430             // Verify the transient was set correctly
    431             $transient_value = get_option('lws_optimize_deactivate_temporarily', false);
    432             if ($transient_value === false) {
    433                 wp_die(json_encode(array('code' => "TRANSIENT_VERIFY_ERROR", 'data' => "Temporary deactivation may not work correctly"), JSON_PRETTY_PRINT));
    434             }
    435         }
    436 
    437         $this->lwsop_dump_all_dynamic_caches();
    438 
    439         wp_die(json_encode(array('code' => "SUCCESS", 'data' => array('duration' => $duration)), JSON_PRETTY_PRINT));
    440     }
    441 
     308    /**
     309     * Routine actions after an update happened
     310     */
    442311    public function lws_optimize_after_update_actions() {
    443         if (get_option('wp_lwsoptimize_post_update') && !get_option('lws_optimize_deactivate_temporarily')) {
     312        if (get_option('wp_lwsoptimize_post_update')) {
    444313            delete_option('wp_lwsoptimize_post_update');
    445314
     
    522391    }
    523392
    524     public function lwsop_dump_dynamic_cache()
    525     {
    526         check_ajax_referer('lwsop_empty_d_cache_nonce', '_ajax_nonce');
    527         wp_die($this->lwsop_dump_all_dynamic_caches());
    528     }
    529 
    530393    /**
    531394     * Purge the cache using the found purger (if exists)
     
    587450        }
    588451        return (json_encode(array('code' => "SUCCESS", 'data' => "Done"), JSON_PRETTY_PRINT));
    589     }
    590 
    591     public function lws_optimize_activate_cleaner()
    592     {
    593         check_ajax_referer('lwsop_activate_cleaner_nonce', '_ajax_nonce');
    594         if (!isset($_POST['state'])) {
    595             wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
    596         }
    597 
    598         if ($_POST['state'] == "true") {
    599             $plugin = activate_plugin("lws-cleaner/lws-cleaner.php");
    600             $state = "true";
    601         } else {
    602             $plugin = deactivate_plugins("lws-cleaner/lws-cleaner.php");
    603             $state = "false";
    604         }
    605 
    606         wp_die(json_encode(array('code' => "SUCCESS", 'data' => $plugin, 'state' => $state), JSON_PRETTY_PRINT));
    607     }
    608 
    609     public function lwsop_get_url_preload()
    610     {
    611         check_ajax_referer('nonce_lws_optimize_preloading_url_files', '_ajax_nonce');
    612         if (!isset($_POST['action'])) {
    613             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    614         }
    615 
    616         $optimize_options = get_option('lws_optimize_config_array', []);
    617 
    618         // Get the exclusions
    619         $preloads = isset($optimize_options['preload_css']['links']) ? $optimize_options['preload_css']['links'] : array();
    620 
    621         wp_die(json_encode(array('code' => "SUCCESS", "data" => $preloads, 'domain' => site_url())), JSON_PRETTY_PRINT);
    622     }
    623 
    624     public function lwsop_set_url_preload()
    625     {
    626         check_ajax_referer('nonce_lws_optimize_preloading_url_files_set', '_ajax_nonce');
    627         $optimize_options = get_option('lws_optimize_config_array', []);
    628 
    629         if (isset($_POST['data'])) {
    630             $urls = array();
    631 
    632             foreach ($_POST['data'] as $data) {
    633                 $value = sanitize_text_field($data['value']);
    634                 if ($value == "" || empty($value)) {
    635                     continue;
    636                 }
    637                 $urls[] = $value;
    638             }
    639             $optimize_options['preload_css']['links'] = $urls;
    640 
    641             update_option('lws_optimize_config_array', $optimize_options);
    642             $this->optimize_options = $optimize_options;
    643             wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
    644         }
    645         wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
    646     }
    647 
    648     public function lwsop_get_url_preload_font()
    649     {
    650         check_ajax_referer('nonce_lws_optimize_preloading_url_fonts', '_ajax_nonce');
    651         if (!isset($_POST['action'])) {
    652             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    653         }
    654 
    655         $optimize_options = get_option('lws_optimize_config_array', []);
    656 
    657         // Get the exclusions
    658         $preloads = isset($optimize_options['preload_font']['links']) ? $optimize_options['preload_font']['links'] : array();
    659 
    660         wp_die(json_encode(array('code' => "SUCCESS", "data" => $preloads, 'domain' => site_url())), JSON_PRETTY_PRINT);
    661     }
    662 
    663     public function lwsop_set_url_preload_font()
    664     {
    665         check_ajax_referer('nonce_lws_optimize_preloading_url_fonts_set', '_ajax_nonce');
    666         if (isset($_POST['data'])) {
    667             $urls = array();
    668 
    669             $optimize_options = get_option('lws_optimize_config_array', []);
    670 
    671             foreach ($_POST['data'] as $data) {
    672                 $value = sanitize_text_field($data['value']);
    673                 if ($value == "" || empty($value)) {
    674                     continue;
    675                 }
    676                 $urls[] = $value;
    677             }
    678 
    679             $optimize_options['preload_font']['links'] = $urls;
    680 
    681             update_option('lws_optimize_config_array', $optimize_options);
    682             $this->optimize_options = $optimize_options;
    683             wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
    684         }
    685         wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
    686     }
    687 
    688     public function lwsop_reload_stats()
    689     {
    690         $stats = $this->lwsop_recalculate_stats("get");
    691 
    692         $stats['desktop']['size'] = $this->lwsOpSizeConvert($stats['desktop']['size'] ?? 0);
    693         $stats['mobile']['size'] = $this->lwsOpSizeConvert($stats['mobile']['size'] ?? 0);
    694         $stats['css']['size'] = $this->lwsOpSizeConvert($stats['css']['size'] ?? 0);
    695         $stats['js']['size'] = $this->lwsOpSizeConvert($stats['js']['size'] ?? 0);
    696 
    697         wp_die(json_encode(array('code' => "SUCCESS", 'data' => $stats)));
    698452    }
    699453
     
    768522
    769523        return array_reverse(array_unique($data));
    770     }
    771 
    772     public function lwsop_preload_fb()
    773     {
    774         check_ajax_referer('update_fb_preload', '_ajax_nonce');
    775 
    776         if (!isset($_POST['action']) || !isset($_POST['state'])) {
    777             wp_die(json_encode(['code' => "FAILED_ACTIVATE", 'data' => "Missing required parameters"]), JSON_PRETTY_PRINT);
    778         }
    779 
    780         // IMPORTANT: Get a fresh copy of options from the database
    781         $optimize_options = get_option('lws_optimize_config_array', []);
    782 
    783         // Clean previous preload data
    784         delete_option('lws_optimize_sitemap_urls');
    785         delete_option('lws_optimize_preload_is_ongoing');
    786 
    787         $state = sanitize_text_field($_POST['state']);
    788         $amount = isset($_POST['amount']) ? absint($_POST['amount']) : 3;
    789 
    790         // Update preload configuration
    791         $optimize_options['filebased_cache']['preload'] = $state;
    792         $optimize_options['filebased_cache']['preload_amount'] = $amount;
    793         $optimize_options['filebased_cache']['preload_done'] = 0;
    794         $optimize_options['filebased_cache']['preload_ongoing'] = $state;
    795 
    796         // Get sitemap URLs
    797         $urls = $this->get_sitemap_urls();
    798         $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
    799 
    800         // Manage scheduled preload task
    801         if ($state === "false") {
    802             // Disable scheduled preload
    803             if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
    804                 wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
    805             }
    806         } else {
    807             // Enable scheduled preload
    808             if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
    809                 wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
    810             }
    811             wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
    812         }
    813 
    814         // Update options in database
    815         update_option('lws_optimize_config_array', $optimize_options);
    816         $this->optimize_options = $optimize_options;
    817 
    818         wp_die(json_encode(['code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']]), JSON_PRETTY_PRINT);
    819524    }
    820525
     
    1048753        update_option('lws_optimize_sitemap_urls', ['time' => time(), 'urls' => $urls]);
    1049754        delete_option('lws_optimize_preload_is_ongoing');
    1050     }
    1051 
    1052     public function lwsop_change_preload_amount()
    1053     {
    1054         check_ajax_referer('update_fb_preload_amount', '_ajax_nonce');
    1055 
    1056         if (isset($_POST['action'])) {
    1057             $optimize_options = get_option('lws_optimize_config_array', []);
    1058 
    1059             $amount = $_POST['amount'] ? sanitize_text_field($_POST['amount']) : 3;
    1060             $optimize_options['filebased_cache']['preload_amount'] =  $amount;
    1061 
    1062             update_option('lws_optimize_config_array', $optimize_options);
    1063             $this->optimize_options = $optimize_options;
    1064 
    1065             wp_die(json_encode(array('code' => "SUCCESS", 'data' => "DONE")));
    1066         }
    1067         wp_die(json_encode(array('code' => "FAILED_ACTIVATE", 'data' => "FAIL")));
    1068     }
    1069 
    1070     // Start regenerating file-based cache (from 0 instead of just adding)
    1071     // Useful if stats are broken for some reasons
    1072     public function lwsop_regenerate_cache() {
    1073         check_ajax_referer('lws_regenerate_nonce_cache_fb', '_ajax_nonce');
    1074         $stats = $this->lwsop_recalculate_stats('regenerate');
    1075 
    1076         $stats['desktop']['size'] = $this->lwsOpSizeConvert($stats['desktop']['size'] ?? 0);
    1077         $stats['mobile']['size'] = $this->lwsOpSizeConvert($stats['mobile']['size'] ?? 0);
    1078         $stats['css']['size'] = $this->lwsOpSizeConvert($stats['css']['size'] ?? 0);
    1079         $stats['js']['size'] = $this->lwsOpSizeConvert($stats['js']['size'] ?? 0);
    1080 
    1081         wp_die(json_encode(array('code' => "SUCCESS", 'data' => $stats)));
    1082 
    1083     }
    1084 
    1085     // Regenrate cache stats
    1086     public function lwsop_regenerate_cache_general() {
    1087         check_ajax_referer('lws_regenerate_nonce_cache_fb', '_ajax_nonce');
    1088         $cache_stats = $this->lwsop_recalculate_stats('regenerate');
    1089 
    1090         // Get the specifics values
    1091         $file_cache = $cache_stats['desktop']['amount'];
    1092         $file_cache_size = $this->lwsOpSizeConvert($cache_stats['desktop']['size']) ?? 0;
    1093 
    1094         $mobile_cache = $cache_stats['mobile']['amount'] ?? 0;
    1095         $mobile_cache_size = $this->lwsOpSizeConvert($cache_stats['mobile']['size']) ?? 0;
    1096 
    1097         $css_cache = $cache_stats['css']['amount'] ?? 0;
    1098         $css_cache_size = $this->lwsOpSizeConvert($cache_stats['css']['size']) ?? 0;
    1099 
    1100         $js_cache = $cache_stats['js']['amount'] ?? 0;
    1101         $js_cache_size = $this->lwsOpSizeConvert($cache_stats['js']['size']) ?? 0;
    1102 
    1103         $caches = [
    1104             'files' => [
    1105                 'size' => $file_cache_size,
    1106                 'title' => __('Computer Cache', 'lws-optimize'),
    1107                 'alt_title' => __('Computer', 'lws-optimize'),
    1108                 'amount' => $file_cache,
    1109                 'id' => "lws_optimize_file_cache",
    1110                 'image_file' => esc_url(plugins_url('images/ordinateur.svg', __DIR__)),
    1111                 'image_alt' => "computer icon",
    1112                 'width' => "60px",
    1113                 'height' => "60px",
    1114             ],
    1115             'mobile' => [
    1116                 'size' => $mobile_cache_size,
    1117                 'title' => __('Mobile Cache', 'lws-optimize'),
    1118                 'alt_title' => __('Mobile', 'lws-optimize'),
    1119                 'amount' => $mobile_cache,
    1120                 'id' => "lws_optimize_mobile_cache",
    1121                 'image_file' => esc_url(plugins_url('images/mobile.svg', __DIR__)),
    1122                 'image_alt' => "mobile icon",
    1123                 'width' => "50px",
    1124                 'height' => "60px",
    1125             ],
    1126             'css' => [
    1127                 'size' => $css_cache_size,
    1128                 'title' => __('CSS Cache', 'lws-optimize'),
    1129                 'alt_title' => __('CSS', 'lws-optimize'),
    1130                 'amount' => $css_cache,
    1131                 'id' => "lws_optimize_css_cache",
    1132                 'image_file' => esc_url(plugins_url('images/css.svg', __DIR__)),
    1133                 'image_alt' => "css logo in a window icon",
    1134                 'width' => "60px",
    1135                 'height' => "60px",
    1136             ],
    1137             'js' => [
    1138                 'size' => $js_cache_size,
    1139                 'title' => __('JS Cache', 'lws-optimize'),
    1140                 'alt_title' => __('JS', 'lws-optimize'),
    1141                 'amount' => $js_cache,
    1142                 'id' => "lws_optimize_js_cache",
    1143                 'image_file' => esc_url(plugins_url('images/js.svg', __DIR__)),
    1144                 'image_alt' => "js logo in a window icon",
    1145                 'width' => "60px",
    1146                 'height' => "60px",
    1147 
    1148             ],
    1149         ];
    1150 
    1151         wp_die(json_encode(array('code' => "SUCCESS", 'data' => $caches)));
    1152 
    1153     }
    1154 
    1155 
    1156     public function lwsop_do_pagespeed_test()
    1157     {
    1158         check_ajax_referer('lwsop_doing_pagespeed_nonce', '_ajax_nonce');
    1159         $url = $_POST['url'] ?? null;
    1160         $type = $_POST['type'] ?? null;
    1161         $date = time();
    1162 
    1163 
    1164         if ($url === null || $type === null) {
    1165             wp_die(json_encode(array('code' => "NO_PARAM", 'data' => $_POST), JSON_PRETTY_PRINT));
    1166         }
    1167 
    1168         $config_array = get_option('lws_optimize_pagespeed_history', array());
    1169         $last_test = array_reverse($config_array)[0]['date'] ?? 0;
    1170 
    1171 
    1172         if ($last_test = strtotime($last_test) && time() - $last_test < 180) {
    1173             wp_die(json_encode(array('code' => "TOO_RECENT", 'data' => 180 - ($date - $last_test)), JSON_PRETTY_PRINT));
    1174         }
    1175 
    1176         $url = esc_url($url);
    1177         $type = sanitize_text_field($type);
    1178 
    1179         $response = wp_remote_get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$url&key=AIzaSyD8yyUZIGg3pGYgFOzJR1NsVztAf8dQUFQ&strategy=$type", ['timeout' => 45, 'sslverify' => false]);
    1180         if (is_wp_error($response)) {
    1181             wp_die(json_encode(array('code' => "ERROR_PAGESPEED", 'data' => $response), JSON_PRETTY_PRINT));
    1182         }
    1183 
    1184         $response = json_decode($response['body'], true);
    1185         if (json_last_error() !== JSON_ERROR_NONE) {
    1186             wp_die(json_encode(array('code' => "ERROR_DECODE", 'data' => $response), JSON_PRETTY_PRINT));
    1187         }
    1188 
    1189         $performance = $response['lighthouseResult']['categories']['performance']['score'] ?? null;
    1190         $speedMetric = $response['lighthouseResult']['audits']['speed-index']['displayValue'] ?? null;
    1191         $speedMetricValue = $response['lighthouseResult']['audits']['speed-index']['numericValue'] ?? null;
    1192         $speedMetricUnit = $response['lighthouseResult']['audits']['speed-index']['numericUnit'] ?? null;
    1193 
    1194 
    1195         $scores = [
    1196             'performance' => $performance,
    1197             'speed' => str_replace("/\s/g", "", $speedMetric),
    1198             'speed_milli' => $speedMetricValue,
    1199             'speed_unit' => $speedMetricUnit
    1200         ];
    1201 
    1202         $new_pagespeed = ['date' =>  date("d M Y, H:i", $date) . " GMT+0", 'url' => $url, 'type' => $type, 'scores' => $scores];
    1203         $config_array[] = $new_pagespeed;
    1204         update_option('lws_optimize_pagespeed_history', $config_array);
    1205 
    1206         $history = array_slice($config_array, -10);
    1207         $history = array_reverse($history);
    1208 
    1209 
    1210         wp_die(json_encode(array('code' => "SUCCESS", 'data' => $scores, 'history' => $history), JSON_PRETTY_PRINT));
    1211     }
    1212 
    1213     public function lws_optimize_set_fb_status()
    1214     {
    1215         check_ajax_referer('change_filebased_cache_status_nonce', '_ajax_nonce');
    1216 
    1217         // Validate required parameters
    1218         if (!isset($_POST['timer']) || !isset($_POST['state'])) {
    1219             wp_die(json_encode(['code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()]));
    1220         }
    1221 
    1222         // Get fresh copy of options
    1223         $optimize_options = get_option('lws_optimize_config_array', []);
    1224 
    1225         // Sanitize inputs
    1226         $timer = sanitize_text_field($_POST['timer']);
    1227         $state = sanitize_text_field($_POST['state']) === "true" ? "true" : "false";
    1228 
    1229         // Update configuration
    1230         $optimize_options['filebased_cache']['exceptions'] = $optimize_options['filebased_cache']['exceptions'] ?? [];
    1231         $optimize_options['filebased_cache']['state'] = $state;
    1232         $optimize_options['filebased_cache']['timer'] = $timer;
    1233 
    1234         // Update Cloudflare TTL to match filebased cache clear timer
    1235         $this->cloudflare_manager->lws_optimize_change_cloudflare_ttl($timer);
    1236 
    1237         // Update preload status if necessary
    1238         if (isset($optimize_options['filebased_cache']['preload']) && $optimize_options['filebased_cache']['preload'] == "true") {
    1239             $optimize_options['filebased_cache']['preload_ongoing'] = "true";
    1240         }
    1241 
    1242         // Update all .htaccess files by removing or adding the rules
    1243         if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
    1244             $this->lws_optimize_set_cache_htaccess();
    1245         } else {
    1246             $this->unset_cache_htaccess();
    1247         }
    1248         if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
    1249             $this->set_gzip_brotli_htaccess();
    1250         } else {
    1251             $this->unset_gzip_brotli_htaccess();
    1252         }
    1253         $this->lws_optimize_reset_header_htaccess();
    1254 
    1255         // Clear dynamic cache
    1256         $this->lwsop_dump_all_dynamic_caches();
    1257 
    1258         // Save updated options
    1259         update_option('lws_optimize_config_array', $optimize_options);
    1260         $this->optimize_options = $optimize_options;
    1261 
    1262         wp_die(json_encode(['code' => "SUCCESS", 'data' => $state]), JSON_PRETTY_PRINT);
    1263755    }
    1264756
     
    18411333    }
    18421334
    1843     /**
    1844      * Change the value of the file-based cache timer. Will automatically launch a WP-Cron at the defined $timer to clear the cache
    1845      */
    1846     public function lws_optimize_set_fb_timer()
    1847     {
    1848         check_ajax_referer('change_filebased_cache_timer_nonce', '_ajax_nonce');
    1849         if (!isset($_POST['timer'])) {
    1850             wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url())));
    1851         }
    1852 
    1853         $optimize_options = get_option('lws_optimize_config_array', []);
    1854 
    1855         $timer = sanitize_text_field($_POST['timer']);
    1856         if (empty($timer)) {
    1857             if (empty($GLOBALS['lws_optimize_cache_timestamps']) || array_key_first($GLOBALS['lws_optimize_cache_timestamps']) === null) {
    1858                 $timer = "daily";
    1859             } else {
    1860                 $timer = $GLOBALS['lws_optimize_cache_timestamps'][array_key_first($GLOBALS['lws_optimize_cache_timestamps'])][0];
    1861             }
    1862         }
    1863 
    1864         $fb_options = $this->lwsop_check_option('filebased_cache');
    1865         if ($fb_options['state'] === "false") {
    1866             $optimize_options['filebased_cache']['state'] = "false";
    1867         }
    1868         if (isset($optimize_options['filebased_cache']['timer']) && $optimize_options['filebased_cache']['timer'] === $timer) {
    1869             wp_die(json_encode(array('code' => "SUCCESS", "data" => $timer)), JSON_PRETTY_PRINT);
    1870         }
    1871 
    1872         if ($fb_options['state'] == "true") {
    1873            $this->lws_optimize_reset_header_htaccess();
    1874         } else {
    1875             $this->unset_header_htaccess();
    1876         }
    1877 
    1878         // Update all .htaccess files by removing or adding the rules
    1879         if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
    1880             $this->lws_optimize_set_cache_htaccess();
    1881         } else {
    1882             $this->unset_cache_htaccess();
    1883         }
    1884         if (isset($optimize_options['gzip_compression']['state']) && $optimize_options['gzip_compression']['state'] == "true") {
    1885             $this->set_gzip_brotli_htaccess();
    1886         } else {
    1887             $this->unset_gzip_brotli_htaccess();
    1888         }
    1889         $this->lws_optimize_reset_header_htaccess();
    1890 
    1891         $optimize_options['filebased_cache']['timer'] = $timer;
    1892 
    1893         // Update Cloudflare TTL to match filebased cache clear timer
    1894         $this->cloudflare_manager->lws_optimize_change_cloudflare_ttl($timer);
    1895 
    1896         update_option('lws_optimize_config_array', $optimize_options);
    1897         $this->optimize_options = $optimize_options;
    1898 
    1899         // Remove the old event and schedule a new one with the new timer
    1900         if (wp_next_scheduled('lws_optimize_clear_filebased_cache_cron')) {
    1901             wp_unschedule_event(wp_next_scheduled('lws_optimize_clear_filebased_cache_cron'), 'lws_optimize_clear_filebased_cache_cron');
    1902         }
    1903 
    1904         // Never start cron if timer is defined as zero (infinite)
    1905         if ($timer != 0) {
    1906             wp_schedule_event(time(), $timer, 'lws_optimize_clear_filebased_cache_cron');
    1907         }
    1908 
    1909         wp_die(json_encode(array('code' => "SUCCESS", "data" => $timer)), JSON_PRETTY_PRINT);
    1910     }
    1911 
    1912     /**
    1913      * Set the 'state' of each action defined by the ID "lws_optimize_*_check" as such :
    1914      * [name]['state'] = "true"/"false"
    1915      */
    1916     public function lws_optimize_manage_config()
    1917     {
    1918         check_ajax_referer('nonce_lws_optimize_checkboxes_config', '_ajax_nonce');
    1919         if (!isset($_POST['action']) || !isset($_POST['data'])) {
    1920             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    1921         }
    1922 
    1923         // IMPORTANT: Get a fresh copy of options from the database
    1924         $optimize_options = get_option('lws_optimize_config_array', []);
    1925 
    1926         $id = sanitize_text_field($_POST['data']['type']);
    1927         $state = sanitize_text_field($_POST['data']['state']);
    1928         $tab = sanitize_text_field($_POST['data']['tab']);
    1929 
    1930         if ($state !== "false" && $state !== "true") {
    1931             $state = "false";
    1932         }
    1933 
    1934         if (preg_match('/lws_optimize_(.*?)_check/', $id, $match) !== 1) {
    1935             wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
    1936         }
    1937 
    1938         // The $element to update
    1939         $element = $match[1];
    1940 
    1941         $optimize_options[$element]['state'] = $state;
    1942 
    1943         // In case it is the dynamic cache, we need to check which type (cpanel/lws) it is and whether it CAN be activated
    1944         if ($element == "dynamic_cache") {
    1945             $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLE'] ?? null;
    1946             if ($fastest_cache_status === null) {
    1947                 $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLED'] ?? null;
    1948             }
    1949             $lwscache_status = $_SERVER['lwscache'] ?? null;
    1950 
    1951             if ($lwscache_status == "Off") {
    1952                 $lwscache_status = false;
    1953             } elseif ($lwscache_status == "On") {
    1954                 $lwscache_status = true;
    1955             }
    1956 
    1957             if ($fastest_cache_status == "0") {
    1958                 $fastest_cache_status = false;
    1959             } elseif ($fastest_cache_status == "1") {
    1960                 $fastest_cache_status = true;
    1961             }
    1962 
    1963 
    1964             if ($lwscache_status === null && $fastest_cache_status === null) {
    1965                 $optimize_options[$element]['state'] = "false";
    1966                 update_option('lws_optimize_config_array', $optimize_options);
    1967                 wp_die(json_encode(array('code' => "INCOMPATIBLE", "data" => "LWSCache is incompatible with this hosting. Use LWS.")), JSON_PRETTY_PRINT);
    1968             }
    1969 
    1970             if ($lwscache_status == false && $fastest_cache_status === null) {
    1971                 $optimize_options[$element]['state'] = "false";
    1972                 update_option('lws_optimize_config_array', $optimize_options);
    1973                 wp_die(json_encode(array('code' => "PANEL_CACHE_OFF", "data" => "LWSCache is not activated on LWSPanel.")), JSON_PRETTY_PRINT);
    1974             }
    1975 
    1976             if ($lwscache_status === null && $fastest_cache_status == false) {
    1977                 $optimize_options[$element]['state'] = "false";
    1978                 update_option('lws_optimize_config_array', $optimize_options);
    1979                 wp_die(json_encode(array('code' => "CPANEL_CACHE_OFF", "data" => "Varnish is not activated on cPanel.")), JSON_PRETTY_PRINT);
    1980             }
    1981         } elseif ($element == "maintenance_db") {
    1982             if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
    1983                 wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
    1984             }
    1985             if ($state == "true") {
    1986                 wp_schedule_event(time() + 604800, 'weekly', 'lws_optimize_maintenance_db_weekly');
    1987             }
    1988         } elseif ($element == "memcached") {
    1989             if ($this->lwsop_plugin_active('redis-cache/redis-cache.php')) {
    1990                 $optimize_options[$element]['state'] = "false";
    1991                 wp_die(json_encode(array('code' => "REDIS_ALREADY_HERE", 'data' => "FAILURE", 'state' => "unknown")));
    1992             }
    1993             if (class_exists('Memcached')) {
    1994                 $memcached = new \Memcached();
    1995                 if (empty($memcached->getServerList())) {
    1996                     $memcached->addServer('localhost', 11211);
    1997                 }
    1998 
    1999                 if ($memcached->getVersion() === false) {
    2000                     if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
    2001                         unlink(LWSOP_OBJECTCACHE_PATH);
    2002                     }
    2003                     wp_die(json_encode(array('code' => "MEMCACHE_NOT_WORK", 'data' => "FAILURE", 'state' => "unknown")));
    2004                 }
    2005 
    2006                 file_put_contents(LWSOP_OBJECTCACHE_PATH, file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
    2007             } else {
    2008                 if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
    2009                     unlink(LWSOP_OBJECTCACHE_PATH);
    2010                 }
    2011                 wp_die(json_encode(array('code' => "MEMCACHE_NOT_FOUND", 'data' => "FAILURE", 'state' => "unknown")));
    2012             }
    2013         } elseif ($element == "gzip_compression") {
    2014             if ($state == "true") {
    2015                 $this->set_gzip_brotli_htaccess();
    2016             } else {
    2017                 $this->unset_gzip_brotli_htaccess();
    2018             }
    2019         } elseif ($element == "htaccess_rules") {
    2020             if ($state == "true") {
    2021                 $this->lws_optimize_set_cache_htaccess();
    2022             } elseif ($state == "false") {
    2023                 $this->unset_cache_htaccess();
    2024             }
    2025         }
    2026 
    2027         // If the tab where the option comes from is frontend, we clear the cache
    2028         // as those options needs the cache to be emptied to work properly
    2029         if (isset($tab) && $tab == "frontend") {
    2030             $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
    2031             $logger = fopen($this->log_file, 'a');
    2032             fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache after configuration change' . PHP_EOL);
    2033             fclose($logger);
    2034         }
    2035 
    2036         if ($element == "cache_mobile_user" || $element == "cache_logged_user") {
    2037             if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
    2038                 $this->lws_optimize_set_cache_htaccess();
    2039             }
    2040         }
    2041 
    2042         update_option('lws_optimize_config_array', $optimize_options);
    2043         $this->optimize_options = $optimize_options;
    2044 
    2045         // If correctly added and updated
    2046         wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options[$element]['state'] = $state, 'type' => $element)), JSON_PRETTY_PRINT);
    2047     }
    2048 
    2049     public function lws_optimize_manage_config_delayed() {
    2050         check_ajax_referer('nonce_lws_optimize_checkboxes_config', '_ajax_nonce');
    2051         if (!isset($_POST['action']) || !isset($_POST['data']) || !is_array($_POST['data'])) {
    2052             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2053         }
    2054 
    2055         $optimize_options = get_option('lws_optimize_config_array', []);
    2056 
    2057         $errors = [];
    2058 
    2059         foreach ($_POST['data'] as $element) {
    2060             $id = sanitize_text_field($element['type']);
    2061             $state = sanitize_text_field($element['state']);
    2062 
    2063             if (preg_match('/lws_optimize_(.*?)_check/', $id, $match) !== 1) {
    2064                 $logger = fopen($this->log_file, 'a');
    2065                 fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Failed to parse ID for configuration: ' . $id . PHP_EOL);
    2066                 fclose($logger);
    2067                 continue;
    2068             }
    2069 
    2070             // Get the ID of the option to update
    2071             $id = $match[1];
    2072 
    2073             // Update the state of the option
    2074             $optimize_options[$id]['state'] = $state;
    2075 
    2076             // In case it is the dynamic cache, check compatibility
    2077             if ($id == "dynamic_cache") {
    2078                 $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLE'] ?? null;
    2079                 if ($fastest_cache_status === null) {
    2080                     $fastest_cache_status = $_SERVER['HTTP_EDGE_CACHE_ENGINE_ENABLED'] ?? null;
    2081                 }
    2082                 $lwscache_status = $_SERVER['lwscache'] ?? null;
    2083 
    2084                 if ($lwscache_status == "Off") {
    2085                     $lwscache_status = false;
    2086                 } elseif ($lwscache_status == "On") {
    2087                     $lwscache_status = true;
    2088                 }
    2089 
    2090                 if ($fastest_cache_status == "0") {
    2091                     $fastest_cache_status = false;
    2092                 } elseif ($fastest_cache_status == "1") {
    2093                     $fastest_cache_status = true;
    2094                 }
    2095 
    2096                 if ($lwscache_status === null && $fastest_cache_status === null) {
    2097                     $optimize_options[$id]['state'] = "false";
    2098                     $errors[$id] = 'INCOMPATIBLE';
    2099                     $logger = fopen($this->log_file, 'a');
    2100                     fwrite($logger, '[' . date('Y-m-d H:i:s') . '] LWSCache is incompatible with this hosting' . PHP_EOL);
    2101                     fclose($logger);
    2102                     continue;
    2103                 }
    2104 
    2105                 if ($lwscache_status == false && $fastest_cache_status === null) {
    2106                     $optimize_options[$id]['state'] = "false";
    2107                     $errors[$id] = 'PANEL_CACHE_OFF';
    2108                     $logger = fopen($this->log_file, 'a');
    2109                     fwrite($logger, '[' . date('Y-m-d H:i:s') . '] LWSCache is not activated on LWSPanel' . PHP_EOL);
    2110                     fclose($logger);
    2111                     continue;
    2112                 }
    2113 
    2114                 if ($lwscache_status === null && $fastest_cache_status == false) {
    2115                     $optimize_options[$id]['state'] = "false";
    2116                     $errors[$id] = 'CPANEL_CACHE_OFF';
    2117                     $logger = fopen($this->log_file, 'a');
    2118                     fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Varnish is not activated on cPanel' . PHP_EOL);
    2119                     fclose($logger);
    2120                     continue;
    2121                 }
    2122 
    2123             } elseif ($id == "maintenance_db") {
    2124                 if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
    2125                     wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
    2126                 }
    2127                 if ($state == "true") {
    2128                     wp_schedule_event(time() + 604800, 'weekly', 'lws_optimize_maintenance_db_weekly');
    2129                 }
    2130 
    2131             } elseif ($id == "memcached") {
    2132                 if ($this->lwsop_plugin_active('redis-cache/redis-cache.php')) {
    2133                     $optimize_options[$id]['state'] = "false";
    2134                     $errors[$id] = 'REDIS_ALREADY_HERE';
    2135                     $logger = fopen($this->log_file, 'a');
    2136                     fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Redis cache plugin is already active' . PHP_EOL);
    2137                     fclose($logger);
    2138                     continue;
    2139                 }
    2140 
    2141                 if (class_exists('Memcached')) {
    2142                     $memcached = new \Memcached();
    2143                     if (empty($memcached->getServerList())) {
    2144                         $memcached->addServer('localhost', 11211);
    2145                     }
    2146 
    2147                     if ($memcached->getVersion() === false) {
    2148                         if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
    2149                             unlink(LWSOP_OBJECTCACHE_PATH);
    2150                         }
    2151                         $errors[$id] = 'MEMCACHE_NOT_WORK';
    2152                         $logger = fopen($this->log_file, 'a');
    2153                         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Memcached server not responding' . PHP_EOL);
    2154                         fclose($logger);
    2155                         continue;
    2156                     }
    2157 
    2158                     file_put_contents(LWSOP_OBJECTCACHE_PATH, file_get_contents(LWS_OP_DIR . '/views/object-cache.php'));
    2159 
    2160                 } else {
    2161                     if (file_exists(LWSOP_OBJECTCACHE_PATH)) {
    2162                         unlink(LWSOP_OBJECTCACHE_PATH);
    2163                     }
    2164                     $errors[$id] = 'MEMCACHE_NOT_FOUND';
    2165                     $logger = fopen($this->log_file, 'a');
    2166                     fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Memcached extension not found' . PHP_EOL);
    2167                     fclose($logger);
    2168                     continue;
    2169                 }
    2170 
    2171             } elseif ($id == "gzip_compression") {
    2172                 if ($state == "true") {
    2173                     $this->set_gzip_brotli_htaccess();
    2174                 } else {
    2175                     $this->unset_gzip_brotli_htaccess();
    2176                 }
    2177             } elseif ($id == "htaccess_rules") {
    2178                 if ($state == "true") {
    2179                     $this->lws_optimize_set_cache_htaccess();
    2180                 } elseif ($state == "false") {
    2181                     $this->unset_cache_htaccess();
    2182                 }
    2183             } elseif ($id == "preload_cache") {
    2184                 // Clean previous preload data
    2185                 delete_option('lws_optimize_sitemap_urls');
    2186                 delete_option('lws_optimize_preload_is_ongoing');
    2187 
    2188                 // Update preload configuration
    2189                 $optimize_options['filebased_cache']['preload'] = $state;
    2190                 $optimize_options['filebased_cache']['preload_amount'] = $optimize_options['filebased_cache']['preload_amount'] ?: 3;
    2191                 $optimize_options['filebased_cache']['preload_done'] = 0;
    2192                 $optimize_options['filebased_cache']['preload_ongoing'] = $state;
    2193 
    2194                 // Get sitemap URLs
    2195                 $urls = $this->get_sitemap_urls();
    2196                 $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
    2197 
    2198                 // Manage scheduled preload task
    2199                 if ($state === "false") {
    2200                     // Disable scheduled preload
    2201                     if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
    2202                         wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
    2203                     }
    2204                 } else {
    2205                     // Enable scheduled preload
    2206                     if (wp_next_scheduled("lws_optimize_start_filebased_preload")) {
    2207                         wp_unschedule_event(wp_next_scheduled("lws_optimize_start_filebased_preload"), "lws_optimize_start_filebased_preload");
    2208                     }
    2209                     wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
    2210                 }
    2211             }
    2212         }
    2213 
    2214         // Clear cache when updating data
    2215         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
    2216         $logger = fopen($this->log_file, 'a');
    2217         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache after configuration change' . PHP_EOL);
    2218         fclose($logger);
    2219 
    2220         $this->after_cache_purge_preload();
    2221 
    2222         if (function_exists("opcache_reset")) {
    2223             opcache_reset();
    2224         }
    2225 
    2226         if (isset($optimize_options['htaccess_rules']['state']) && $optimize_options['htaccess_rules']['state'] == "true") {
    2227             $this->lws_optimize_set_cache_htaccess();
    2228         }
    2229 
    2230         $optimize_options['personnalized'] = "true";
    2231 
    2232         update_option('lws_optimize_config_array', $optimize_options);
    2233         $this->optimize_options = $optimize_options;
    2234 
    2235         // If correctly added and updated
    2236         wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options, 'errors' => $errors), JSON_PRETTY_PRINT));
    2237     }
    2238 
    22391335
    22401336    public function activateVarnishCache(bool $state = true) {
     
    22821378    }
    22831379
    2284     /**
    2285      * Add exclusions to the given action
    2286      */
    2287     public function lws_optimize_manage_exclusions()
    2288     {
    2289         check_ajax_referer('nonce_lws_optimize_exclusions_config', '_ajax_nonce');
    2290         if (!isset($_POST['action']) || !isset($_POST['data'])) {
    2291             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2292         }
    2293 
    2294         // Get the ID for the currently open modal and get the action to modify
    2295         $data = $_POST['data'];
    2296         $id = null;
    2297         foreach ($data as $var) {
    2298             if ($var['name'] == "lwsoptimize_exclude_url_id") {
    2299                 $id = sanitize_text_field($var['value']);
    2300                 break;
    2301             }
    2302         }
    2303 
    2304         // No ID ? Cannot proceed
    2305         if (!isset($id)) {
    2306             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2307         }
    2308 
    2309         // Get the specific action from the ID
    2310         if (preg_match('/lws_optimize_(.*?)_exclusion/', $id, $match) !== 1) {
    2311             wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
    2312         }
    2313 
    2314         $exclusions = array();
    2315 
    2316         // The $element to update
    2317         $element = $match[1];
    2318 
    2319         $optimize_options = get_option('lws_optimize_config_array', []);
    2320 
    2321         // Get all exclusions
    2322         foreach ($data as $var) {
    2323             if ($var['name'] == "lwsoptimize_exclude_url") {
    2324                 if (trim($var['value']) == '') {
    2325                     continue;
    2326                 }
    2327                 $exclusions[] = sanitize_text_field($var['value']);
    2328             }
    2329         }
    2330 
    2331         // Add the exclusions for the $element ; each is a URL (e.g. : my-website.fr/wp-content/plugins/...)
    2332         // If no config is present for the $element, it will be added
    2333         $config_element = $optimize_options[$element]['exclusions'] = $exclusions;
    2334 
    2335         update_option('lws_optimize_config_array', $optimize_options);
    2336         $this->optimize_options = $optimize_options;
    2337 
    2338         wp_die(json_encode(array('code' => "SUCCESS", "data" => $config_element, 'id' => $id)), JSON_PRETTY_PRINT);
    2339     }
    2340 
    2341     public function lws_optimize_manage_exclusions_media()
    2342     {
    2343         check_ajax_referer('nonce_lws_optimize_exclusions_media_config', '_ajax_nonce');
    2344         if (!isset($_POST['action']) || !isset($_POST['data'])) {
    2345             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2346         }
    2347 
    2348         // Get the ID for the currently open modal and get the action to modify
    2349         $data = $_POST['data'];
    2350         foreach ($data as $var) {
    2351             if ($var['name'] == "lwsoptimize_exclude_url_id_media") {
    2352                 $id = sanitize_text_field($var['value']);
    2353                 break;
    2354             } else {
    2355                 $id = null;
    2356             }
    2357         }
    2358 
    2359         // No ID ? Cannot proceed
    2360         if (!isset($id)) {
    2361             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2362         }
    2363 
    2364         // Get the specific action from the ID
    2365         if (preg_match('/lws_optimize_(.*?)_exclusion_button/', $id, $match) !== 1) {
    2366             wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
    2367         }
    2368 
    2369         $exclusions = array();
    2370 
    2371         // The $element to update
    2372         $element = $match[1];
    2373         // All configs for LWS Optimize
    2374         $optimize_options = get_option('lws_optimize_config_array', []);
    2375 
    2376         // Get all exclusions
    2377         foreach ($data as $var) {
    2378             switch ($var['name']) {
    2379                 case 'lwsoptimize_exclude_url':
    2380                     if (trim($var['value']) == '') {
    2381                         break;
    2382                     }
    2383                     $exclusions['css_classes'][] = sanitize_text_field($var['value']);
    2384                     break;
    2385                 case 'lwsoptimize_gravatar':
    2386                     $exclusions['media_types']['gravatar'] = true;
    2387                     break;
    2388                 case 'lwsoptimize_thumbnails':
    2389                     $exclusions['media_types']['thumbnails'] = true;
    2390                     break;
    2391                 case 'lwsoptimize_responsive':
    2392                     $exclusions['media_types']['responsive'] = true;
    2393                     break;
    2394                 case 'lwsoptimize_iframe':
    2395                     $exclusions['media_types']['iframe'] = true;
    2396                     break;
    2397                 case 'lwsoptimize_mobile':
    2398                     $exclusions['media_types']['mobile'] = true;
    2399                     break;
    2400                 case 'lwsoptimize_video':
    2401                     $exclusions['media_types']['video'] = true;
    2402                     break;
    2403                 case 'lwsoptimize_excluded_iframes_img':
    2404                     $tmp = $var['value'];
    2405                     $tmp = explode(PHP_EOL, $tmp);
    2406                     foreach ($tmp as $value) {
    2407                         $exclusions['img_iframe'][] = trim(sanitize_text_field($value));
    2408                     }
    2409                     break;
    2410                 default:
    2411                     break;
    2412             }
    2413         }
    2414 
    2415         // Add the exclusions for the $element ; each is a URL (e.g. : my-website.fr/wp-content/plugins/...)
    2416         // If no config is present for the $element, it will be added
    2417         $config_element = $optimize_options[$element]['exclusions'] = $exclusions;
    2418 
    2419         update_option('lws_optimize_config_array', $optimize_options);
    2420         $this->optimize_options = $optimize_options;
    2421 
    2422         wp_die(json_encode(array('code' => "SUCCESS", "data" => $config_element, 'id' => $id)), JSON_PRETTY_PRINT);
    2423     }
    2424 
    2425     public function lws_optimize_fetch_exclusions()
    2426     {
    2427         check_ajax_referer('nonce_lws_optimize_fetch_exclusions', '_ajax_nonce');
    2428         $optimize_options = get_option('lws_optimize_config_array', []);
    2429 
    2430         if (!isset($_POST['action']) || !isset($_POST['data'])) {
    2431             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    2432         }
    2433 
    2434         $id = sanitize_text_field($_POST['data']['type']);
    2435 
    2436         if (preg_match('/lws_optimize_(.*?)_exclusion/', $id, $match) !== 1) {
    2437             wp_die(json_encode(array('code' => "UNKNOWN_ID", "data" => $id)), JSON_PRETTY_PRINT);
    2438         }
    2439 
    2440         // The $element to update
    2441         $element = $match[1];
    2442         // All configs for LWS Optimize
    2443 
    2444         // Get the exclusions
    2445         $exclusions = isset($optimize_options[$element]['exclusions']) ? $optimize_options[$element]['exclusions'] : array('rs-lazyload');
    2446 
    2447         wp_die(json_encode(array('code' => "SUCCESS", "data" => $exclusions, 'domain' => site_url())), JSON_PRETTY_PRINT);
    2448     }
    2449 
    2450     /**
    2451      * Clear every caches available on Optimize
    2452     */
    2453     public function lws_op_clear_all_caches() {
    2454         check_ajax_referer('lws_op_clear_all_caches_nonce', '_ajax_nonce');
    2455 
    2456         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
    2457         $logger = fopen($this->log_file, 'a');
    2458         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed all caches' . PHP_EOL);
    2459         fclose($logger);
    2460 
    2461         delete_option('lws_optimize_sitemap_urls');
    2462         delete_option('lws_optimize_preload_is_ongoing');
    2463         $this->after_cache_purge_preload();
    2464 
    2465         $this->lwsop_dump_all_dynamic_caches();
    2466 
    2467         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2468     }
    2469 
    2470     /**
    2471      * Clear the file-based cache completely
    2472      */
    2473     public function lws_optimize_clear_cache()
    2474     {
    2475         check_ajax_referer('clear_fb_caching', '_ajax_nonce');
    2476 
    2477         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS, $this);
    2478         $logger = fopen($this->log_file, 'a');
    2479         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed cache on demand' . PHP_EOL);
    2480         fclose($logger);
    2481 
    2482         delete_option('lws_optimize_sitemap_urls');
    2483         delete_option('lws_optimize_preload_is_ongoing');
    2484         $this->after_cache_purge_preload();
    2485         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2486     }
    2487 
    2488     public function lws_clear_opcache()
    2489     {
    2490         check_ajax_referer('clear_opcache_caching', '_ajax_nonce');
    2491         $this->lwsop_remove_opcache();
    2492         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2493     }
    2494 
    2495     public function lws_optimize_clear_stylecache()
    2496     {
    2497         check_ajax_referer('clear_style_fb_caching', '_ajax_nonce');
    2498         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-css", $this);
    2499         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-js", $this);
    2500 
    2501         $logger = fopen($this->log_file, 'a');
    2502         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed CSS/JS cache' . PHP_EOL);
    2503         fclose($logger);
    2504 
    2505         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2506     }
    2507 
    2508     public function lws_optimize_clear_htmlcache()
    2509     {
    2510         check_ajax_referer('clear_html_fb_caching', '_ajax_nonce');
    2511 
    2512         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache", $this);
    2513         $this->lws_optimize_delete_directory(LWS_OP_UPLOADS . "/cache-mobile", $this);
    2514 
    2515         $this->after_cache_purge_preload();
    2516 
    2517         $logger = fopen($this->log_file, 'a');
    2518         fwrite($logger, '[' . date('Y-m-d H:i:s') . '] Removed HTML cache' . PHP_EOL);
    2519         fclose($logger);
    2520 
    2521         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2522     }
    2523 
    2524     public function lws_optimize_clear_currentcache()
    2525     {
    2526         check_ajax_referer('clear_currentpage_fb_caching', '_ajax_nonce');
    2527 
    2528         // Get the request_uri of the current URL to remove
    2529         // If not found, do not delete anything
    2530         $uri = esc_url($_POST['request_uri']) ?? false;
    2531 
    2532         $logger = fopen($this->log_file, 'a');
    2533         fwrite($logger, '[' . date('Y-m-d H:i:s') . "] Starting to remove $uri cache" . PHP_EOL);
    2534         fclose($logger);
    2535 
    2536         if ($uri === false) {
    2537             wp_die(json_encode(array('code' => 'ERROR', 'data' => "/"), JSON_PRETTY_PRINT));
    2538         }
    2539 
    2540         apply_filters("lws_optimize_clear_filebased_cache", $uri, "lws_optimize_clear_currentcache");
    2541 
    2542         wp_die(json_encode(array('code' => 'SUCCESS', 'data' => "/"), JSON_PRETTY_PRINT));
    2543     }
    25441380
    25451381    public function lws_optimize_delete_directory($dir, $class_this)
     
    26251461    }
    26261462
    2627 
    26281463    /**
    26291464     * Clean the given directory.
     
    26641499        }
    26651500    }
    2666 
    26671501
    26681502    /**
     
    28881722            return json_encode(['code' => 'SUCCESS'], JSON_PRETTY_PRINT);
    28891723        }
    2890     }
    2891 
    2892     public function lwsop_specified_urls_fb()
    2893     {
    2894         check_ajax_referer('lwsop_get_specified_url_nonce', '_ajax_nonce');
    2895         $optimize_options = get_option('lws_optimize_config_array', []);
    2896 
    2897         if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['specified'])) {
    2898             wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['specified'], 'domain' => site_url()), JSON_PRETTY_PRINT));
    2899         } else {
    2900             wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
    2901         }
    2902     }
    2903 
    2904     public function lwsop_save_specified_urls_fb()
    2905     {
    2906         // Add all URLs to an array, but ignore empty URLs
    2907         // If all fields are empty, remove the option from DB
    2908         check_ajax_referer('lwsop_save_specified_nonce', '_ajax_nonce');
    2909         if (isset($_POST['data'])) {
    2910             $urls = array();
    2911 
    2912             $optimize_options = get_option('lws_optimize_config_array', []);
    2913 
    2914             foreach ($_POST['data'] as $data) {
    2915                 $value = sanitize_text_field($data['value']);
    2916                 if ($value == "" || empty($value)) {
    2917                     continue;
    2918                 }
    2919                 $urls[] = $value;
    2920             }
    2921 
    2922             $optimize_options['filebased_cache']['specified'] = $urls;
    2923 
    2924             update_site_option('lws_optimize_config_array', $optimize_options);
    2925             $this->optimize_options = $optimize_options;
    2926 
    2927             wp_die(json_encode(array('code' => "SUCCESS", 'data' => $urls, 'domain' => site_url()), JSON_PRETTY_PRINT));
    2928         }
    2929         wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
    2930     }
    2931 
    2932     public function lwsop_exclude_urls_fb()
    2933     {
    2934         check_ajax_referer('lwsop_get_excluded_nonce', '_ajax_nonce');
    2935         $optimize_options = get_option('lws_optimize_config_array', []);
    2936 
    2937         if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['exclusions'])) {
    2938             wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['exclusions'], 'domain' => site_url()), JSON_PRETTY_PRINT));
    2939         } else {
    2940             wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
    2941         }
    2942     }
    2943 
    2944     public function lwsop_exclude_cookies_fb()
    2945     {
    2946         check_ajax_referer('lwsop_get_excluded_cookies_nonce', '_ajax_nonce');
    2947         $optimize_options = get_option('lws_optimize_config_array', []);
    2948 
    2949         if (isset($optimize_options['filebased_cache']) && isset($optimize_options['filebased_cache']['exclusions_cookies'])) {
    2950             wp_die(json_encode(array('code' => "SUCCESS", 'data' => $optimize_options['filebased_cache']['exclusions_cookies'], 'domain' => site_url()), JSON_PRETTY_PRINT));
    2951         } else {
    2952             wp_die(json_encode(array('code' => "SUCCESS", 'data' => array(), 'domain' => site_url()), JSON_PRETTY_PRINT));
    2953         }
    2954     }
    2955 
    2956     public function lwsop_save_urls_fb()
    2957     {
    2958         // Add all URLs to an array, but ignore empty URLs
    2959         // If all fields are empty, remove the option from DB
    2960         check_ajax_referer('lwsop_save_excluded_nonce', '_ajax_nonce');
    2961 
    2962         if (isset($_POST['data'])) {
    2963             $urls = array();
    2964 
    2965             foreach ($_POST['data'] as $data) {
    2966                 $value = sanitize_text_field($data['value']);
    2967                 if ($value == "" || empty($value)) {
    2968                     continue;
    2969                 }
    2970                 $urls[] = $value;
    2971             }
    2972 
    2973             $optimize_options = get_option('lws_optimize_config_array', []);
    2974             $optimize_options['filebased_cache']['exclusions'] = $urls;
    2975 
    2976             update_option('lws_optimize_config_array', $optimize_options);
    2977             $this->optimize_options = $optimize_options;
    2978 
    2979             wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
    2980         }
    2981         wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
    2982     }
    2983 
    2984     public function lwsop_save_cookies_fb()
    2985     {
    2986         // Add all Cookies to an array, but ignore empty cookies
    2987         // If all fields are empty, remove the option from DB
    2988         check_ajax_referer('lwsop_save_excluded_cookies_nonce', '_ajax_nonce');
    2989 
    2990         if (isset($_POST['data'])) {
    2991             $urls = array();
    2992 
    2993             foreach ($_POST['data'] as $data) {
    2994                 $value = sanitize_text_field($data['value']);
    2995                 if ($value == "" || empty($value)) {
    2996                     continue;
    2997                 }
    2998                 $urls[] = $value;
    2999             }
    3000 
    3001             $optimize_options = get_option('lws_optimize_config_array', []);
    3002             $optimize_options['filebased_cache']['exclusions_cookies'] = $urls;
    3003 
    3004 
    3005             update_option('lws_optimize_config_array', $optimize_options);
    3006             $this->optimize_options = $optimize_options;
    3007 
    3008             wp_die(json_encode(array('code' => "SUCCESS", "data" => $urls)), JSON_PRETTY_PRINT);
    3009         }
    3010         wp_die(json_encode(array('code' => "NO_DATA", 'data' => $_POST, 'domain' => site_url()), JSON_PRETTY_PRINT));
    30111724    }
    30121725
     
    32972010        }
    32982011        return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . '' . $unit[$i];
    3299     }
    3300 
    3301     // Fetch options for maintaining DB
    3302     public function lws_optimize_manage_maintenance_get()
    3303     {
    3304         check_ajax_referer('lwsop_get_maintenance_db_nonce', '_ajax_nonce');
    3305 
    3306         $optimize_options = get_option('lws_optimize_config_array', []);
    3307 
    3308         if (!isset($optimize_options['maintenance_db']) || !isset($optimize_options['maintenance_db']['options'])) {
    3309             $optimize_options['maintenance_db']['options'] = array(
    3310                 'myisam' => false,
    3311                 'drafts' => false,
    3312                 'revisions' => false,
    3313                 'deleted_posts' => false,
    3314                 'spam_posts' => false,
    3315                 'deleted_comments' => false,
    3316                 'expired_transients' => false
    3317             );
    3318             update_option('lws_optimize_config_array', $optimize_options);
    3319             $this->optimize_options = $optimize_options;
    3320         }
    3321 
    3322         wp_die(json_encode(array('code' => "SUCCESS", "data" => $optimize_options['maintenance_db']['options'], 'domain' => site_url())), JSON_PRETTY_PRINT);
    3323     }
    3324 
    3325     // Update the DB options array
    3326     public function lws_optimize_set_maintenance_db_options()
    3327     {
    3328         // Add all URLs to an array, but ignore empty URLs
    3329         // If all fields are empty, remove the option from DB
    3330         check_ajax_referer('lwsop_set_maintenance_db_nonce', '_ajax_nonce');
    3331         if (!isset($_POST['formdata'])) {
    3332             $_POST['formdata'] = [];
    3333         }
    3334         $options = array();
    3335 
    3336         foreach ($_POST['formdata'] as $data) {
    3337             $value = sanitize_text_field($data);
    3338             if ($value == "" || empty($value)) {
    3339                 continue;
    3340             }
    3341             $options[] = $value;
    3342         }
    3343 
    3344         $optimize_options = get_option('lws_optimize_config_array', []);
    3345         $optimize_options['maintenance_db']['options'] = $options;
    3346 
    3347         update_option('lws_optimize_config_array', $optimize_options);
    3348         $this->optimize_options = $optimize_options;
    3349 
    3350         if (wp_next_scheduled('lws_optimize_maintenance_db_weekly')) {
    3351             wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
    3352         }
    3353         wp_die(json_encode(array('code' => "SUCCESS", "data" => $options)), JSON_PRETTY_PRINT);
    3354     }
    3355 
    3356     public function lws_optimize_create_maintenance_db_options()
    3357     {
    3358         global $wpdb;
    3359         $optimize_options = get_option('lws_optimize_config_array', []);
    3360 
    3361         $config_options = $optimize_options['maintenance_db']['options'];
    3362         foreach ($config_options as $options) {
    3363             switch ($options) {
    3364                 case 'myisam':
    3365                     $results = $wpdb->get_results("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '{$wpdb->prefix}%' AND ENGINE = 'MyISAM' AND TABLE_SCHEMA = '" . $wpdb->dbname . "';");
    3366                     foreach ($results as $result) {
    3367                         $rows_affected = $wpdb->query($wpdb->prepare("OPTIMIZE TABLE %s", $result->table_name));
    3368                         if ($rows_affected === false) {
    3369                             error_log("lws-optimize.php::create_maintenance_db_options | The table {$result->table_name} has not been OPTIMIZED");
    3370                         }
    3371                     }
    3372                     break;
    3373                 case 'drafts':
    3374                     $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}posts WHERE post_status = 'draft';");
    3375                     $wpdb->query($query);
    3376                     // Remove drafts
    3377                     break;
    3378                 case 'revisions':
    3379                     $query = $wpdb->prepare("DELETE FROM `{$wpdb->prefix}posts` WHERE post_type = 'revision';");
    3380                     $wpdb->query($query);
    3381                     // Remove revisions
    3382                     break;
    3383                 case 'deleted_posts':
    3384                     $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}posts WHERE post_status = 'trash' && (post_type = 'post' OR post_type = 'page');");
    3385                     $wpdb->query($query);
    3386                     // Remove trashed posts/page
    3387                     break;
    3388                 case 'spam_comments':
    3389                     $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}comments WHERE comment_approved = 'spam';");
    3390                     $wpdb->query($query);
    3391                     // remove spam comments
    3392                     break;
    3393                 case 'deleted_comments':
    3394                     $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}comments WHERE comment_approved = 'trash';");
    3395                     $wpdb->query($query);
    3396                     // remove deleted comments
    3397                     break;
    3398                 case 'expired_transients':
    3399                     $query = $wpdb->prepare("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '%_transient_timeout_%' AND option_value < ?;", [time()]);
    3400                     $wpdb->query($query);
    3401                     // remove expired transients
    3402                     break;
    3403                 default:
    3404                     break;
    3405             }
    3406         }
    3407     }
    3408 
    3409     public function lws_optimize_get_database_cleaning_time()
    3410     {
    3411         check_ajax_referer('lws_optimize_get_database_cleaning_nonce', '_ajax_nonce');
    3412         $next = wp_next_scheduled('lws_optimize_maintenance_db_weekly') ?? false;
    3413         if (!$next) {
    3414             $next = "-";
    3415         } else {
    3416             $next = get_date_from_gmt(date('Y-m-d H:i:s', intval($next)), 'Y-m-d H:i:s');
    3417         }
    3418 
    3419         wp_die(json_encode(array('code' => "SUCCESS", "data" => $next)), JSON_PRETTY_PRINT);
    3420     }
    3421 
    3422     public function lwsop_get_setup_optimize()
    3423     {
    3424         check_ajax_referer('lwsop_change_optimize_configuration_nonce', '_ajax_nonce');
    3425         if (!isset($_POST['action']) || !isset($_POST['value'])) {
    3426             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    3427         }
    3428 
    3429         $value = sanitize_text_field($_POST['value']);
    3430 
    3431         // No value ? Cannot proceed
    3432         if (!isset($value) || !$value) {
    3433             wp_die(json_encode(array('code' => "DATA_MISSING", "data" => $_POST)), JSON_PRETTY_PRINT);
    3434         }
    3435 
    3436         switch ($value) {
    3437             case 'essential':
    3438                 $value = "basic";
    3439                 break;
    3440             case 'optimized':
    3441                 $value = "advanced";
    3442                 break;
    3443             case 'max':
    3444                 $value = "full";
    3445                 break;
    3446             default:
    3447                 $value = "basic";
    3448                 break;
    3449         }
    3450 
    3451 
    3452         $this->lwsop_auto_setup_optimize($value);
    3453         wp_die(json_encode(array('code' => "SUCCESS", "data" => "")), JSON_PRETTY_PRINT);
    34542012    }
    34552013
     
    36222180
    36232181    /**
    3624      * Check and return the state of the preloading
    3625      */
    3626     public function lwsop_check_preload_update()
    3627     {
    3628         check_ajax_referer('lwsop_check_for_update_preload_nonce', '_ajax_nonce');
    3629 
    3630         $optimize_options = get_option('lws_optimize_config_array', []);
    3631 
    3632         $urls = get_option('lws_optimize_sitemap_urls', ['time' => 0, 'urls' => []]);
    3633         $time = $urls['time'] ?? 0;
    3634 
    3635         // It has been more than an hour since the latest fetch from the sitemap
    3636         if ($time + 300 < time()) {
    3637             // We get the freshest data
    3638             $urls = $this->get_sitemap_urls();
    3639             if (!empty($urls)) {
    3640                 update_option('lws_optimize_sitemap_urls', ['time' => time(), 'urls' => $urls]);
    3641             }
    3642         } else {
    3643             // We get the ones currently saved in base
    3644             $urls = $urls['urls'] ?? [];
    3645         }
    3646 
    3647         $done = 0;
    3648 
    3649         if (empty($urls)){
    3650             wp_die(json_encode(array('code' => "ERROR", "data" => $sitemap, 'message' => "Failed to get some of the datas", 'domain' => site_url())), JSON_PRETTY_PRINT);
    3651         }
    3652 
    3653         foreach ($urls as $url) {
    3654             $parsed_url = parse_url($url);
    3655             $parsed_url = isset($parsed_url['path']) ? $parsed_url['path'] : '';
    3656             $path = $this->lwsOptimizeCache->lwsop_set_cachedir($parsed_url);
    3657 
    3658             $file_exists = glob($path . "index*") ?? [];
    3659             if (!empty($file_exists)) {
    3660                 $done++;
    3661             }
    3662         }
    3663 
    3664         $optimize_options['filebased_cache']['preload_quantity'] = count($urls);
    3665         $optimize_options['filebased_cache']['preload_done'] = $done;
    3666         $optimize_options['filebased_cache']['preload_ongoing'] = $optimize_options['filebased_cache']['preload_quantity'] - $done == 0 ? "false" : "true";
    3667 
    3668         $next = wp_next_scheduled('lws_optimize_start_filebased_preload') ?? null;
    3669         if ($next != null) {
    3670             $next = get_date_from_gmt(date('Y-m-d H:i:s', $next), 'Y-m-d H:i:s');
    3671         } else {
    3672             if (!wp_next_scheduled('lws_optimize_start_filebased_preload')) {
    3673                 wp_schedule_event(time(), "lws_minute", "lws_optimize_start_filebased_preload");
    3674             }
    3675         }
    3676 
    3677         $next = wp_next_scheduled('lws_optimize_start_filebased_preload') ?? null;
    3678         if ($next != null) {
    3679             $next = get_date_from_gmt(date('Y-m-d H:i:s', $next), 'Y-m-d H:i:s');
    3680         }
    3681 
    3682         $data = [
    3683             'quantity' => $optimize_options['filebased_cache']['preload_quantity'] ?? null,
    3684             'done' => $optimize_options['filebased_cache']['preload_done'] ?? null,
    3685             'ongoing' => $optimize_options['filebased_cache']['preload_ongoing'] ?? null,
    3686             'next' => $next ?? null
    3687         ];
    3688 
    3689         update_option('lws_optimize_config_array', $optimize_options);
    3690         $this->optimize_options = $optimize_options;
    3691 
    3692         if ($data['quantity'] === null || $data['done'] === null || $data['ongoing'] === null || $data['next'] === null) {
    3693             wp_die(json_encode(array('code' => "ERROR", "data" => $data, 'message' => "Failed to get some of the datas", 'domain' => site_url())), JSON_PRETTY_PRINT);
    3694         }
    3695 
    3696 
    3697         wp_die(json_encode(array('code' => "SUCCESS", "data" => $data, 'domain' => site_url())), JSON_PRETTY_PRINT);
    3698     }
    3699 
    3700     /**
    37012182     * Convert a certain amount (between 1 and 15) of images to the desired format.
    37022183     * The function does not check much else, whether or not anything got converted is not checked
  • lws-optimize/trunk/css/lws_op_stylesheet.css

    r3304818 r3362313  
    20142014    justify-content: center;
    20152015    gap: 3px;
     2016}
     2017
     2018
     2019.lwsop_bluebanner_logs {
     2020    background-color: #e9f4fd;
     2021    display: flex;
     2022    align-items: center;
     2023    padding: 20px 30px;
     2024    flex-direction: row;
     2025    justify-content: center;
     2026    gap: 30px;
    20162027}
    20172028
     
    47704781    }
    47714782}
     4783
     4784
     4785:root {
     4786  --ifm-color-primary: #2e8555;
     4787  --ifm-color-primary-dark: #29784c;
     4788  --ifm-color-primary-darker: #277148;
     4789  --ifm-color-primary-darkest: #205d3b;
     4790  --ifm-color-primary-light: #33925d;
     4791  --ifm-color-primary-lighter: #359962;
     4792  --ifm-color-primary-lightest: #3cad6e;
     4793  --ifm-navbar-background-color: #fff;
     4794  --ifm-color-emphasis-200: #ebedf0;
     4795  --ifm-color-emphasis-300: #dadde1;
     4796}
     4797
     4798/* Floating feedback button */
     4799.feedbackButton {
     4800  position: fixed;
     4801  bottom: 120px;
     4802  right: 20px;
     4803  background: var(--ifm-color-primary);
     4804  color: white;
     4805  border: none;
     4806  border-radius: 50px;
     4807  padding: 12px 20px;
     4808  font-size: 14px;
     4809  font-weight: 600;
     4810  cursor: pointer;
     4811  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
     4812  transition: all 0.3s ease;
     4813  z-index: 10000;
     4814  display: flex;
     4815  align-items: center;
     4816  gap: 8px;
     4817}
     4818
     4819.feedbackButton:hover {
     4820  background: var(--ifm-color-primary-dark);
     4821  transform: translateY(-2px);
     4822  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
     4823}
     4824
     4825/* Modal overlay */
     4826.modalOverlay {
     4827  position: fixed;
     4828  top: 0;
     4829  left: 0;
     4830  right: 0;
     4831  bottom: 0;
     4832  background: rgba(0, 0, 0, 0.5);
     4833  display: flex;
     4834  align-items: center;
     4835  justify-content: center;
     4836  z-index: 10001;
     4837  padding: 20px;
     4838}
     4839
     4840/* Modal content */
     4841.modalContent {
     4842  background: var(--ifm-navbar-background-color);
     4843  border-radius: 12px;
     4844  width: 100%;
     4845  max-width: 575px;
     4846  max-height: 90vh;
     4847  overflow-y: auto;
     4848  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
     4849  animation: modalAppear 0.3s ease-out;
     4850  font-family: 'Poppins';
     4851}
     4852
     4853@keyframes modalAppear {
     4854  from {
     4855    opacity: 0;
     4856    transform: scale(0.9) translateY(20px);
     4857  }
     4858  to {
     4859    opacity: 1;
     4860    transform: scale(1) translateY(0);
     4861  }
     4862}
     4863
     4864/* Modal header */
     4865.modalHeader {
     4866  display: flex;
     4867  justify-content: space-between;
     4868  align-items: center;
     4869  padding: 20px 24px;
     4870  border-bottom: 1px solid var(--ifm-color-emphasis-200);
     4871}
     4872
     4873.modalHeader h3 {
     4874  margin: 0;
     4875  color: var(--ifm-color-content);
     4876  font-size: 20px;
     4877  font-weight: 600;
     4878}
     4879
     4880.closeButton {
     4881  background: none;
     4882  border: none;
     4883  font-size: 24px;
     4884  cursor: pointer;
     4885  color: var(--ifm-color-content-secondary);
     4886  width: 32px;
     4887  height: 32px;
     4888  display: flex;
     4889  align-items: center;
     4890  justify-content: center;
     4891  border-radius: 50%;
     4892  transition: all 0.2s ease;
     4893}
     4894
     4895.closeButton:hover {
     4896  background: var(--ifm-color-emphasis-200);
     4897  color: var(--ifm-color-content);
     4898}
     4899
     4900/* Form styles */
     4901.form {
     4902  padding: 24px;
     4903}
     4904
     4905.formGroup {
     4906  margin-bottom: 20px;
     4907}
     4908
     4909.formGroup label {
     4910  display: block;
     4911  margin-bottom: 6px;
     4912  font-weight: 500;
     4913  color: var(--ifm-color-content);
     4914  font-size: 14px;
     4915}
     4916
     4917.formGroup input,
     4918.formGroup select,
     4919.formGroup textarea {
     4920  width: 100%;
     4921  max-width: 100%;
     4922  padding: 12px;
     4923  border: 1px solid var(--ifm-color-emphasis-300);
     4924  border-radius: 6px;
     4925  /* background: var(--ifm-background-color); */
     4926  color: var(--ifm-color-content);
     4927  font-size: 14px;
     4928  transition: border-color 0.2s ease;
     4929  box-sizing: border-box;
     4930}
     4931
     4932.formGroup input:focus,
     4933.formGroup select:focus,
     4934.formGroup textarea:focus {
     4935  outline: none;
     4936  border-color: var(--ifm-color-primary);
     4937  box-shadow: 0 0 0 2px var(--ifm-color-primary-lightest);
     4938}
     4939
     4940.formGroup textarea {
     4941  resize: vertical;
     4942  min-height: 100px;
     4943}
     4944
     4945/* Form actions */
     4946.formActions {
     4947  display: flex;
     4948  gap: 12px;
     4949  justify-content: flex-end;
     4950  margin-top: 24px;
     4951}
     4952
     4953.cancelButton,
     4954.submitButton {
     4955  padding: 6px 20px;
     4956  border-radius: 6px;
     4957  font-size: 14px;
     4958  font-weight: 500;
     4959  cursor: pointer;
     4960  transition: all 0.2s ease;
     4961  border: 1px solid transparent;
     4962}
     4963
     4964.cancelButton {
     4965  background: var(--ifm-color-emphasis-200);
     4966  color: var(--ifm-color-content);
     4967  border-color: var(--ifm-color-emphasis-300);
     4968}
     4969
     4970.cancelButton:hover {
     4971  background: var(--ifm-color-emphasis-300);
     4972}
     4973
     4974.submitButton {
     4975  background: var(--ifm-color-primary);
     4976  color: white;
     4977  border-color: var(--ifm-color-primary);
     4978}
     4979
     4980.submitButton:hover:not(:disabled) {
     4981  background: var(--ifm-color-primary-dark);
     4982}
     4983
     4984.submitButton:disabled {
     4985  opacity: 0.6;
     4986  cursor: not-allowed;
     4987}
     4988
     4989/* Success message */
     4990.successMessage {
     4991  padding: 24px;
     4992  text-align: center;
     4993  color: var(--ifm-color-success);
     4994  font-weight: 500;
     4995  background: var(--ifm-color-success-lightest);
     4996  border-radius: 6px;
     4997  margin: 24px;
     4998}
     4999
     5000/* Mobile responsiveness */
     5001@media (max-width: 768px) {
     5002  .modalContent {
     5003    margin: 10px;
     5004    max-height: calc(100vh - 20px);
     5005  }
     5006
     5007  .feedbackButton {
     5008    bottom: 15px;
     5009    right: 15px;
     5010    padding: 10px 16px;
     5011    font-size: 13px;
     5012  }
     5013
     5014  .formActions {
     5015    flex-direction: column;
     5016  }
     5017
     5018  .cancelButton,
     5019  .submitButton {
     5020    width: 100%;
     5021  }
     5022}
  • lws-optimize/trunk/lws-optimize.php

    r3360302 r3362313  
    99 * Plugin URI:        https://www.lws.fr/
    1010 * Description:       Reach better speed and performances with Optimize! Minification, Combination, Media convertion... Everything you need for a better website
    11  * Version:           3.3.12
     11 * Version:           3.3.13
    1212 * Author:            LWS
    1313 * Author URI:        https://www.lws.fr
     
    1919 * @package lws-optimize
    2020 *
    21  * This plugin is greatly based on a fork of WPFastestCache (https://wordpress.org/plugins/wp-fastest-cache/) by Emre Vona,
    22  * specifically the JS/CSS optimisation (minify, combine, ...) and the filebased-cache verifications (when not to cache the current page)
    2321 */
    2422
    2523if (!defined('ABSPATH')) {
    26     exit; //Exit if accessed directly
    27 }
    28 
    29 // Actions to execute when the plugin is activated / deleted / upgraded
    30 register_activation_hook(__FILE__, 'lws_optimize_activation');
    31 register_deactivation_hook(__FILE__, 'lws_optimize_deactivation');
    32 register_uninstall_hook(__FILE__, 'lws_optimize_deletion');
    33 // add_action('upgrader_process_complete', 'lws_optimize_upgrading', 10, 2);
    34 
    35 function lws_optimize_check_update() {
    36     $ancienne_version = get_option('lwsop_plugin_version', 0);
    37     $nouvelle_version = '3.2.2.1'; // Remplacez par la version actuelle du plugin.
    38 
    39     if ($ancienne_version !== $nouvelle_version) {
    40         add_option( 'wp_lwsoptimize_post_update', 1);
    41 
    42         // Mettre à jour la version en base.
    43         update_option('lwsop_plugin_version', $nouvelle_version);
    44     }
    45 }
    46 add_action('plugins_loaded', 'lws_optimize_check_update');
    47 
    48 
    49 // Actions to do when the plugin is activated
    50 function lws_optimize_activation()
    51 {
    52     // Unused
    53     set_transient('lwsop_remind_me', 691200);
     24    exit;
     25}
     26
     27
     28// Polyfills of useful PHP8+ functions for PHP < 8
     29if (!function_exists('str_starts_with')) {
     30    function str_starts_with($haystack, $needle)
     31    {
     32        return strlen($needle) === 0 || strpos($haystack, $needle) === 0;
     33    }
     34}
     35if (!function_exists('str_contains')) {
     36    function str_contains($haystack, $needle)
     37    {
     38        return strlen($needle) === 0 || strpos($haystack, $needle) !== false;
     39    }
     40}
     41if (!function_exists('str_ends_with')) {
     42    function str_ends_with($haystack, $needle)
     43    {
     44        return strlen($needle) === 0 || substr($haystack, -strlen($needle)) === $needle;
     45    }
     46}
     47
     48
     49// https://example.fr/wp-content/plugins/lws-optimize/
     50if (!defined('LWS_OP_URL')) {
     51    define('LWS_OP_URL', plugin_dir_url(__FILE__));
     52}
     53
     54// ABSPATH/wp-content/plugins/lws-optimize/
     55if (!defined('LWS_OP_DIR')) {
     56    define('LWS_OP_DIR', plugin_dir_path(__FILE__));
     57}
     58
     59// ABSPATH/wp-content/cache/lwsoptimize/
     60if (!defined('LWS_OP_UPLOADS')) {
     61    define('LWS_OP_UPLOADS', WP_CONTENT_DIR . '/cache/lwsoptimize/');
     62}
     63
     64// lws-optimize/lws-optimize.php
     65if (!defined('LWS_OP_BASENAME')) {
     66    define('LWS_OP_BASENAME', plugin_basename(__FILE__));
     67}
     68
     69// Path to the object-cache file (for Memcached)
     70if (!defined('LWSOP_OBJECTCACHE_PATH')) {
     71    define('LWSOP_OBJECTCACHE_PATH', WP_CONTENT_DIR . '/object-cache.php');
     72}
     73
     74
     75// Function declarations for hook callbacks
     76function lws_optimize_activation_callback() {
    5477    delete_option('lws_optimize_preload_is_ongoing');
    5578
    5679    $optimize_options = get_option('lws_optimize_config_array', []);
    5780
    58     $GLOBALS['lws_optimize'] ->lws_optimize_set_cache_htaccess();
    59     $GLOBALS['lws_optimize'] ->lws_optimize_reset_header_htaccess();
    60 
    61     //@deactivate_plugins("lwscache/lwscache.php");
    62 
     81    $GLOBALS['lws_optimize']->lws_optimize_set_cache_htaccess();
     82    $GLOBALS['lws_optimize']->lws_optimize_reset_header_htaccess();
    6383
    6484    // Deactivate the preloading on plugin activation to prevent issues
     
    7393
    7494        update_option('lws_optimize_config_array', $optimize_options);
    75 
    76         //wp_schedule_event(time() + 3, "lws_minute", "lws_optimize_start_filebased_preload");
    7795    }
    7896
     
    88106}
    89107
    90 // Actions to do when the plugin is deactivated
    91 function lws_optimize_deactivation()
    92 {
    93     // Deactivate the cron of the preloading and convertion
     108function lws_optimize_deactivation_callback() {
     109    delete_option('lws_optimize_preload_is_ongoing');
     110
     111    // Deactivate all crons
    94112    wp_unschedule_event(wp_next_scheduled('lws_optimize_start_filebased_preload'), 'lws_optimize_start_filebased_preload');
    95113    wp_unschedule_event(wp_next_scheduled('lws_optimize_convert_media_cron'), 'lws_optimize_convert_media_cron');
    96     // Deactivate cron for the maintenance
    97114    wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
    98     // Deactivate cron that revert the images
    99115    wp_unschedule_event(wp_next_scheduled("lwsop_revertOptimization"), "lwsop_revertOptimization");
    100116
     
    117133        file_put_contents($htaccess_file, $htaccess_content);
    118134    }
    119 
    120     delete_option('lws_optimize_preload_is_ongoing');
    121 
    122     // Unused
    123     delete_transient('lwsop_remind_me');
    124 }
    125 
    126 // Actions to do when the plugin is to be deleted
    127 function lws_optimize_deletion()
    128 {
     135}
     136
     137function lws_optimize_uninstall_callback() {
    129138    // Remove the cache folder
    130     $cache_dir = ABSPATH . 'wp-content/cache/lwsoptimize/';
     139    $cache_dir = WP_CONTENT_DIR . '/cache/lwsoptimize/';
     140    $upload_dir = WP_CONTENT_DIR . '/uploads/lwsoptimize/';
     141
     142    WP_Filesystem();
     143    global $wp_filesystem;
     144
    131145    if (file_exists($cache_dir)) {
    132         WP_Filesystem();
    133         global $wp_filesystem;
    134146        $wp_filesystem->rmdir($cache_dir, true);
    135147    }
    136148
    137     $upload_dir = ABSPATH . 'wp-content/uploads/lwsoptimize/';
    138149    if (file_exists($upload_dir)) {
    139         WP_Filesystem();
    140         global $wp_filesystem;
    141150        $wp_filesystem->rmdir($upload_dir, true);
    142151    }
    143152
    144     // Deactivate the cron of the preloading and convertion
     153        // Deactivate all crons
    145154    wp_unschedule_event(wp_next_scheduled('lws_optimize_start_filebased_preload'), 'lws_optimize_start_filebased_preload');
    146155    wp_unschedule_event(wp_next_scheduled('lws_optimize_convert_media_cron'), 'lws_optimize_convert_media_cron');
    147     // Deactivate cron for the maintenance
    148156    wp_unschedule_event(wp_next_scheduled('lws_optimize_maintenance_db_weekly'), 'lws_optimize_maintenance_db_weekly');
    149     // Deactivate cron that revert the images
    150157    wp_unschedule_event(wp_next_scheduled("lwsop_revertOptimization"), "lwsop_revertOptimization");
    151158
     
    170177
    171178    // Remove all options on delete
    172     if (get_option('lws_optimize_config_array', null) !== null) {
    173         delete_option('lws_optimize_config_array');
    174     }
    175 
     179    delete_option('lws_optimize_config_array');
    176180    delete_option('lws_optimize_preload_is_ongoing');
    177 
    178     // Unused
    179     delete_transient('lwsop_remind_me');
    180 }
    181 
    182 // Actions to do when the plugin is updated
    183 function lws_optimize_upgrading($upgrader_object, $options)
    184 {
    185     if ($options['action'] == 'update' && $options['type'] == 'plugin') {
    186         foreach ($options['plugins'] as $plugin) {
    187             // If the plugin getting updated is LWS Optimize
    188             if ($plugin == plugin_basename(__FILE__)) {
    189                 add_option( 'wp_lwsoptimize_post_update', 1);
    190             }
    191         }
    192     }
    193 }
    194 
    195 
    196 // https://example.fr/wp-content/plugins/lws-optimize/
    197 if (!defined('LWS_OP_URL')) {
    198     define('LWS_OP_URL', plugin_dir_url(__FILE__));
    199 }
    200 
    201 // ABSPATH/wp-content/plugins/lws-optimize/
    202 if (!defined('LWS_OP_DIR')) {
    203     define('LWS_OP_DIR', plugin_dir_path(__FILE__));
    204 }
    205 
    206 // ABSPATH/wp-content/cache/lwsoptimize/
    207 if (!defined('LWS_OP_UPLOADS')) {
    208     define('LWS_OP_UPLOADS', ABSPATH . 'wp-content/cache/lwsoptimize/');
    209 }
    210 
    211 // lws-optimize/lws-optimize.php
    212 if (!defined('LWS_OP_BASENAME')) {
    213     define('LWS_OP_BASENAME', plugin_basename(__FILE__));
    214 }
    215 
    216 // Polyfills of useful PHP8+ functions for PHP < 8
    217 if (!function_exists('str_starts_with')) {
    218     function str_starts_with($haystack, $needle)
    219     {
    220         return strlen($needle) === 0 || strpos($haystack, $needle) === 0;
    221     }
    222 }
    223 
    224 if (!function_exists('str_contains')) {
    225     function str_contains($haystack, $needle)
    226     {
    227         return strlen($needle) === 0 || strpos($haystack, $needle) !== false;
    228     }
    229 }
    230 
    231 if (!function_exists('str_ends_with')) {
    232     function str_ends_with($haystack, $needle)
    233     {
    234         return strlen($needle) === 0 || substr($haystack, -strlen($needle)) === $needle;
    235     }
    236 }
    237 
    238 //AJAX DL Plugin//
     181    delete_option('lws_optimize_image_api_key');
     182    delete_option('lws_optimize_cache_statistics');
     183    delete_option('lws_optimize_image_conversion_options');
     184    delete_option('lwsop_plugin_version');
     185}
     186
     187// Actions to execute when the plugin is activated / deactivated / deleted / upgraded
     188register_activation_hook(__FILE__, 'lws_optimize_activation_callback');
     189register_deactivation_hook(__FILE__, 'lws_optimize_deactivation_callback');
     190register_uninstall_hook(__FILE__, 'lws_optimize_uninstall_callback');
     191
     192add_action('plugins_loaded', function() {
     193    $ancienne_version = get_option('lwsop_plugin_version', 0);
     194    $nouvelle_version = '3.3.11'; // Remplacez par la version actuelle du plugin.
     195
     196    if ($ancienne_version !== $nouvelle_version) {
     197        add_option( 'wp_lwsoptimize_post_update', 1);
     198
     199        // Mettre à jour la version en base.
     200        update_option('lwsop_plugin_version', $nouvelle_version);
     201    }
     202});
     203
     204// Manage the "Our plugins" tab, allowing users to install our plugins
    239205add_action("wp_ajax_lws_op_downloadPlugin", "wp_ajax_install_plugin");
    240 //
    241 
    242 //AJAX Activate Plugin//
    243206add_action("wp_ajax_lws_op_activatePlugin", function()
    244207{
     
    249212                activate_plugin('lws-hide-login/lws-hide-login.php');
    250213                break;
    251             case 'lws-sms':
    252                 activate_plugin('lws-sms/lws-sms.php');
    253                 break;
    254214            case 'lws-tools':
    255215                activate_plugin('lws-tools/lws-tools.php');
     
    261221                activate_plugin('lws-cleaner/lws-cleaner.php');
    262222                break;
    263             case 'lwscache':
    264                 activate_plugin('lwscache/lwscache.php');
    265                 break;
    266             case 'lws-optimize':
    267                 activate_plugin('lws-optimize/lws-optimize.php');
    268                 break;
    269223            default:
    270224                break;
    271225        }
    272226    }
    273     wp_die();
    274227});
    275228
     
    281234}
    282235
    283 $GLOBALS['lws_optimize'] = $lwsop = new LwsOptimize();
     236$GLOBALS['lws_optimize'] = new LwsOptimize();
    284237
    285238// Register WP-CLI commands once the plugin is loaded
  • lws-optimize/trunk/readme.txt

    r3360302 r3362313  
    44Requires at least: 6.0
    55Tested up to: 6.8
    6 Stable tag: 3.3.12
     6Stable tag: 3.3.13
    77Requires PHP: 7.4
    88Author: LWS
     
    187187== Changelog ==
    188188
     189= 3.3.13 =
     190* Updated logs to add a refresh button
     191* Fixed missing translations
     192* Added a Feedback button
     193
     194
    189195= 3.3.12 =
    190196* Fixed an issue with the preload, where the cron would go over and over without stopping, repeating the same urls indefinitely
  • lws-optimize/trunk/views/logs.php

    r3360302 r3362313  
    1 <div class="lwsop_bluebanner_alt">
    2     <h2 class="lwsop_bluebanner_title">
    3         <?php esc_html_e('Cron Logs', 'lws-optimize'); ?>
    4     </h2>
    5     <div class="lwsop_bluebanner_subtitle">
    6         <?php esc_html_e('This section lets you easily view the latest logs from this plugin cron jobs. Those includes crons related to image optimization and cache preloading.', 'lws-optimize'); ?>
    7         <br>
    8         <?php esc_html_e('Log files have a maximum size of 5MB. Once this size is reached, a new file will be created. Older logs can be found in /uploads/lwsoptimize/.', 'lws-optimize'); ?>
     1<div class="lwsop_bluebanner_logs">
     2    <div>
     3        <h2 class="lwsop_bluebanner_title">
     4            <?php esc_html_e('Cron Logs', 'lws-optimize'); ?>
     5        </h2>
     6        <div class="lwsop_bluebanner_subtitle">
     7            <?php esc_html_e('This section lets you easily view the latest logs from this plugin cron jobs. Those includes crons related to image optimization and cache preloading.', 'lws-optimize'); ?>
     8            <br>
     9            <?php esc_html_e('Log files have a maximum size of 5MB. Once this size is reached, a new file will be created. Older logs can be found in /uploads/lwsoptimize/.', 'lws-optimize'); ?>
     10        </div>
    911    </div>
     12    <button type="button" class="lws_optimize_image_conversion_refresh" id="lws_op_regenerate_logs" name="lws_op_regenerate_logs">
     13        <img src="<?php echo esc_url(plugins_url('images/rafraichir.svg', __DIR__)) ?>" alt="Logo MàJ" width="12px">
     14        <span><?php esc_html_e('Refresh', 'lws-optimize'); ?></span>
     15    </button>
    1016</div>
    1117
     
    2127
    2228<div class="lwsop_contentblock">
    23     <pre style="max-height: 450px;"><?php echo $content; ?></pre>
     29    <pre id="log_dir" style="max-height: 450px;"><?php echo $content; ?></pre>
    2430</div>
     31
     32<script>
     33    let regen_logs = document.getElementById('lws_op_regenerate_logs');
     34    if (regen_logs) {
     35        regen_logs.addEventListener('click', function(){
     36            let button = this;
     37            let old_text = this.innerHTML;
     38            this.innerHTML = `
     39                <span name="loading" style="padding-left:5px">
     40                    <img style="vertical-align:sub; margin-right:5px" src="<?php echo esc_url(dirname(plugin_dir_url(__FILE__)) . '/images/loading_blue.svg') ?>" alt="" width="18px" height="18px">
     41                </span>
     42            `;
     43
     44            this.disabled = true;
     45
     46            let ajaxRequest = jQuery.ajax({
     47                url: ajaxurl,
     48                type: "POST",
     49                timeout: 120000,
     50                context: document.body,
     51                data: {
     52                    action: "lwsop_regenerate_logs",
     53                    _ajax_nonce: '<?php echo esc_attr(wp_create_nonce('lws_regenerate_nonce_logs')); ?>'
     54                },
     55                success: function(data) {
     56                    button.disabled = false;
     57                    button.innerHTML = old_text;
     58
     59                    if (data === null || typeof data != 'string') {
     60                        callPopup('error', "<?php esc_html_e('Bad data returned. Please try again', 'lws-optimize'); ?>");
     61                        return 0;
     62                    }
     63
     64                    try {
     65                        var returnData = JSON.parse(data);
     66                    } catch (e) {
     67                        callPopup('error', "<?php esc_html_e('Bad data returned. Please try again', 'lws-optimize'); ?>");
     68                        console.log(e);
     69                        return 0;
     70                    }
     71
     72                    switch (returnData['code']) {
     73                        case 'SUCCESS':
     74                            if (document.getElementById('log_dir')) {
     75                                callPopup('success', "<?php esc_html_e("Logs have been synchronized", "lws-optimize"); ?>");
     76                                document.getElementById('log_dir').innerHTML = returnData['data'];
     77                            } else {
     78                                callPopup('error', "<?php esc_html_e("Logs could not be found", "lws-optimize"); ?>");
     79                            }
     80                            break;
     81                        default:
     82                            callPopup('error', "<?php esc_html_e("Unknown data returned."); ?>");
     83                            break;
     84                    }
     85                },
     86                error: function(error) {
     87                    button.disabled = false;
     88                    button.innerHTML = old_text;
     89                    callPopup('error', "<?php esc_html_e("Unknown error.", "lws-optimize"); ?>");
     90                    console.log(error);
     91                }
     92            });
     93        });
     94    }
     95</script>
  • lws-optimize/trunk/views/main_page.php

    r3360302 r3362313  
    287287$plugins = array(
    288288    'lws-hide-login' => array('LWS Hide Login', __('This plugin <strong>hide your administration page</strong> (wp-admin) and lets you <strong>change your login page</strong> (wp-login). It offers better security as hackers will have more trouble finding the page.', 'lws-optimize'), true),
    289     'lws-optimize' => array('LWS Optimize', __('This plugin lets you boost your website\'s <strong>loading times</strong> thanks to our tools: caching, media optimisation, files minification and concatenation...', 'lws-optimize'), true),
    290289    'lws-cleaner' => array('LWS Cleaner', __('This plugin lets you <strong>clean your WordPress website</strong> in a few clics to gain speed: posts, comments, terms, users, settings, plugins, medias, files.', 'lws-optimize'), true),
    291     //'lws-sms' => array('LWS SMS', __('This plugin, designed specifically for WooCommerce, lets you <strong>send SMS automatically to your customers</strong>. You will need an account at LWS and enough credits to send SMS. Create personnalized templates, manage your SMS and sender IDs and more!', 'lws-optimize'), false),
    292290    'lws-affiliation' => array('LWS Affiliation', __('With this plugin, you can add banners and widgets on your website and use those with your <strong>affiliate account LWS</strong>. Earn money and follow the evolution of your gains on your website.', 'lws-optimize'), false),
    293     //'lwscache' => array('LWSCache', __('Based on the Varnich cache technology and NGINX, LWSCache let you <strong>speed up the loading of your pages</strong>. This plugin helps you automatically manage your LWSCache when editing pages, posts... and purging all your cache. Works only if your server use this cache.', 'lws-optimize'), false),
    294291    'lws-tools' => array('LWS Tools', __('This plugin provides you with several tools and shortcuts to manage, secure and optimise your WordPress website. Updating plugins and themes, accessing informations about your server, managing your website parameters, etc... Personnalize every aspect of your website!', 'lws-optimize'), false)
    295292);
Note: See TracChangeset for help on using the changeset viewer.