Plugin Directory

Changeset 2852021


Ignore:
Timestamp:
01/20/2023 06:00:01 PM (3 years ago)
Author:
wpblast
Message:

Release 1.8.5

Location:
wpblast
Files:
6 added
40 edited
1 copied

Legend:

Unmodified
Added
Removed
  • wpblast/tags/1.8.5/changelog.txt

    r2830275 r2852021  
    11== Changelog ==
     2= 1.8.5 =
     3Release Date: December 13th, 2022
     4
     5- Improve performance on large websites
     6- Improve advanced-cache updates for nitropack and wp rocket
     7- Improve mu-plugins updates for nitropack
     8
    29= 1.8.4 =
    310Release Date: December 7th, 2022
  • wpblast/tags/1.8.5/globals.php

    r2781302 r2852021  
    44use Smartfire\Wordpress\WPBlast\Settings;
    55
    6 if (!defined('WPBLAST_PLUGIN_DIR')) {
    7     define('WPBLAST_PLUGIN_DIR', __DIR__ . '/../../..');
     6// This is to allow to use require instead of require_once but still have the file loaded once
     7// This happened because when the plugin is activated by wordpress, the variables scope is empty but still the file has been loaded
     8// This happened when activating the plugin after loading was left in the advanced-cache file
     9if (!isset($wpblast_globals_loaded)) {
     10
     11    if (!defined('WPBLAST_PLUGIN_DIR')) {
     12        define('WPBLAST_PLUGIN_DIR', __DIR__ . '/../../..');
     13    }
     14
     15    $autoloader = require('autoload.php');
     16    $autoloader('Smartfire\\Wordpress\\WPBlast\\', __DIR__ . '/src/Smartfire/Wordpress/WPBlast/');
     17
     18    $smartfire_wpblast_config = new Config(['config_dir_path' => WP_CONTENT_DIR . '/wpblast-config']);
     19    $smartfire_wpblast_settings = new Settings();
     20
     21    $wpblast_globals_loaded = true;
    822}
    9 
    10 $autoloader = require('autoload.php');
    11 $autoloader('Smartfire\\Wordpress\\WPBlast\\', __DIR__ . '/src/Smartfire/Wordpress/WPBlast/');
    12 
    13 $smartfire_wpblast_config = new Config(['config_dir_path' => WP_CONTENT_DIR . '/wpblast-config']);
    14 $smartfire_wpblast_settings = new Settings();
  • wpblast/tags/1.8.5/inc/generate-config-functions.php

    r2807381 r2852021  
    2222}
    2323
    24 add_action('wpblast_activate', function () {
    25     add_action('admin_init', 'wpblast_generate_config_file');
     24add_action('wpblast_plugin_updated', function () {
     25    add_action('init', 'wpblast_generate_config_file');
    2626});
    2727add_action('wpblast_updated_crawler_list', 'wpblast_generate_config_file');
    2828add_action('wpblast_updated_options', 'wpblast_generate_config_file');
    2929
    30 add_action('wpblast_deactivate', function () {
     30add_action('wpblast_deactivated', function () {
    3131    global $smartfire_wpblast_config;
    3232    $path = $smartfire_wpblast_config->get_config_file_path()['path'];
  • wpblast/tags/1.8.5/inc/mu-plugins-functions.php

    r2830275 r2852021  
    11<?php
     2
     3defined('ABSPATH') || exit;
    24
    35function wpblast_display_error($message)
    46{
    57    $class = 'notice notice-error';
     8    printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), esc_html($message));
     9}
     10
     11function wpblast_display_warning($message)
     12{
     13    $class = 'notice notice-warning';
    614    printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), esc_html($message));
    715}
     
    3947function wpblast_require_mu_plugin($data)
    4048{
    41     // Installer
    42     add_action('wpblast_activate', function () use ($data) {
     49    // In case of update
     50    add_action('wpblast_plugin_updated', function () use ($data) {
    4351        wpblast_install_mu_plugin($data);
    4452    });
    4553
    46     // Update checker
     54    // In case a difference exist between installed version and current version or in case the mu-plugin triggered an error
    4755    add_action('admin_init', function () use ($data) {
    4856        if (isset($data['slug'])) {
    49             if (!defined('WPBLAST_MU_PLUGIN-' . $data['slug']) || !defined('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug']) || WPBLAST_PLUGIN_VERSION !== constant('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug'])) {
     57            if (defined('WPBLAST_MU_PLUGIN_ERROR') || !defined('WPBLAST_MU_PLUGIN-' . $data['slug']) || !defined('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug']) || WPBLAST_PLUGIN_VERSION !== constant('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug'])) {
    5058                wpblast_install_mu_plugin($data);
    5159            }
     
    6876        $codeHeader = isset($data['code']) && isset($data['code']['header']) ? $data['code']['header'] : '';
    6977        $codeBody = isset($data['code']) && isset($data['code']['body']) ? $data['code']['body'] : '';
     78        $codeDeactivationCondition = '';
     79        if (isset($data['code']) && isset($data['code']['deactivationCondition'])) {
     80            $codeDeactivationCondition = '
     81add_action(\'admin_init\', function () {
     82    if(' . $data['code']['deactivationCondition'] . ') {
     83        wpblast_uninstall_mu_plugin([
     84            \'slug\' => \'' . $slug . '\'
     85        ]);
     86    }
     87});';
     88        }
    7089        wpblast_require_mu_plugin_dir(); // create mu-plugins directory if needed
    7190        $muPluginFile = realpath(WP_CONTENT_DIR) . '/mu-plugins/' . $slug . '.php';
    7291        $code = '<?php
    7392/*
    74 Plugin Name:  ' . $name . '
    75 Plugin URI:   https://www.wp-blast.com
    76 Description:  ' . $description . '
    77 Version:      ' . $version . '
    78 Author: WP Blast
    79 License: Apache 2.0
    80 License URI: http://www.apache.org/licenses/LICENSE-2.0
     93' . 'Plugin Name' . ':  ' . $name . '
     94' . 'Plugin URI' . ':   https://www.wp-blast.com
     95' . 'Description' . ':  ' . $description . '
     96' . 'Version' . ':      ' . $version . '
     97' . 'Author' . ': WP Blast
     98' . 'License' . ': Apache 2.0
     99' . 'License URI' . ': http://www.apache.org/licenses/LICENSE-2.0
    81100*/
    82101// THIS FILE HAS BEEN AUTO-GENERATED
     
    87106
    88107defined( \'ABSPATH\' ) || exit;
     108
     109// WPBLAST-DEACTIVATION-HOOK-START
     110' . $codeDeactivationCondition . '
     111// WPBLAST-DEACTIVATION-HOOK-END
    89112
    90113if(!defined(\'WPBLAST_MU_PLUGIN-' . $slug . '\')) {
  • wpblast/tags/1.8.5/inc/rest-functions.php

    r2807381 r2852021  
    6868function wpblast_generate_cache_item_action()
    6969{
     70    global $smartfire_wpblast_settings;
    7071    if (isset($_GET['wpblast_nonce']) && isset($_GET['url']) && $_GET['url'] !== '') {
    7172        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    7273        if (wp_verify_nonce($nonce, 'wp_rest')) {
    7374            $url = urldecode(esc_url_raw(wp_unslash($_GET['url'])));
    74             $settings = new Settings();
    75             $settings->init();
    7675            $response = wp_remote_get($url, [
    77                 'user-agent' => $settings->getCrawlerCacheGen(), // use WP Blast Crawler to force cache gen
     76                'user-agent' => $smartfire_wpblast_settings->getCrawlerCacheGen(), // use WP Blast Crawler to force cache gen
    7877                'headers' => [
    7978                    'WPBLAST-FORCE-GENERATION' => '1',
    80                     'WPBLAST-TOKEN' => base64_encode($settings->getUsername() . ':' . $settings->getPassword()),
     79                    'WPBLAST-TOKEN' => base64_encode($smartfire_wpblast_settings->getUsername() . ':' . $smartfire_wpblast_settings->getPassword()),
    8180                ],
    82                 'timeout'     => $settings->getTimeout(),
     81                'timeout'     => $smartfire_wpblast_settings->getTimeout(),
    8382            ]);
    8483            $httpCode = wp_remote_retrieve_response_code($response);
     
    104103function wpblast_update_plugin_data()
    105104{
     105    global $smartfire_wpblast_settings;
    106106    if (isset($_GET['wpblast_nonce'])) {
    107107        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    108108        if (wp_verify_nonce($nonce, 'wp_rest')) {
    109             $settings = new Settings();
    110             $settings->init();
    111             $settings->getPluginData(true); // force update to wp blast
     109            $smartfire_wpblast_settings->getPluginData(true); // force update to wp blast
    112110            return new WP_REST_Response(
    113111                [
     
    126124function wpblast_update_user_account()
    127125{
     126    global $smartfire_wpblast_settings;
    128127    if (isset($_GET['wpblast_nonce'])) {
    129128        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    130129        if (wp_verify_nonce($nonce, 'wp_rest')) {
    131             $settings = new Settings();
    132             $settings->init();
    133             $settings->getAccount(true); // force update of user account
     130            $smartfire_wpblast_settings->getAccount(true); // force update of user account
    134131            return new WP_REST_Response(
    135132                [
     
    148145function wpblast_update_crawler_list()
    149146{
     147    global $smartfire_wpblast_settings;
    150148    if (isset($_GET['wpblast_nonce'])) {
    151149        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    152150        if (wp_verify_nonce($nonce, 'wp_rest')) {
    153             $settings = new Settings();
    154             $settings->init();
    155             $settings->getCrawlerAutoRegexp(true); // force update of crawler list
     151            $smartfire_wpblast_settings->getCrawlerAutoRegexp(true); // force update of crawler list
    156152            return new WP_REST_Response(
    157153                [
     
    170166function wpblast_get_status()
    171167{
     168    global $smartfire_wpblast_settings;
    172169    header('Content-Type: application/javascript');
    173170    // Call WP Blast server for status
    174171
    175     $settings = new Settings();
    176     $settings->init();
    177 
    178     $response = wp_remote_get($settings->getWebsite() . '/?method=getWpBlastStatus&domain=' . urlencode($settings->getUsername()) . '&plugin_token=' . $settings->getPassword(), [
     172    $response = wp_remote_get($smartfire_wpblast_settings->getWebsite() . '/?method=getWpBlastStatus&domain=' . urlencode($smartfire_wpblast_settings->getUsername()) . '&plugin_token=' . $smartfire_wpblast_settings->getPassword(), [
    179173        'user-agent' => Settings::WPBLAST_UA_PLUGIN,
    180174        'timeout' => 15,
     
    201195function wpblast_get_sitemap($request)
    202196{
     197    global $smartfire_wpblast_settings;
    203198    if (isset($_GET['wpblast_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['wpblast_nonce'])), 'wp_rest')) {
    204         $settings = new Settings();
    205         $settings->init();
    206199
    207200        if (isset($request['items'])) {
    208201            $items = $request['items'];
    209             $settings->updateSitemapScores($items);
    210         }
    211 
    212         $sitemap = $settings->getWebsiteSitemap('active');
    213 
    214         $settings->cleanExpiredCache(); // delete expired cache item
     202            $smartfire_wpblast_settings->updateSitemapScores($items);
     203        }
     204
     205        $sitemap = $smartfire_wpblast_settings->getWebsiteSitemap('active');
     206
     207        $smartfire_wpblast_settings->cleanExpiredCache(); // delete expired cache item
    215208
    216209        $response = [
     
    231224function wpblast_update_active_pages($request)
    232225{
     226    global $smartfire_wpblast_settings;
    233227    if (isset($_GET['wpblast_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['wpblast_nonce'])), 'wp_rest')) {
    234         $settings = new Settings();
    235         $settings->init();
    236228
    237229        if (isset($request['activeUrls'])) {
    238230            $activeUrls = $request['activeUrls'];
    239             $settings->updateActivePages($activeUrls);
    240         }
    241 
    242         $sitemap = $settings->getWebsiteSitemap('active');
    243 
    244         $settings->cleanExpiredCache(); // delete expired cache item
     231            $smartfire_wpblast_settings->updateActivePages($activeUrls);
     232        }
     233
     234        $sitemap = $smartfire_wpblast_settings->getWebsiteSitemap('active');
     235
     236        $smartfire_wpblast_settings->cleanExpiredCache(); // delete expired cache item
    245237
    246238        $response = [
  • wpblast/tags/1.8.5/inc/third-party/advanced-cache.php

    r2830275 r2852021  
    55defined('ABSPATH') || exit;
    66
    7 require_once __DIR__ . '/../../globals.php';
    8 
    9 if (!defined('WPBLAST_ADVANCED_CACHE')) {
    10     define('WPBLAST_ADVANCED_CACHE', true);
    11 }
     7require __DIR__ . '/../../globals.php';
    128
    139if (Bootstrap::should_blast()) {
  • wpblast/tags/1.8.5/inc/third-party/hummingbird-performance/hummingbird-performance-functions.php

    r2807419 r2852021  
    3131    }
    3232
    33     add_action('wpblast_activate', 'wpblast_wphb_clear_cache');
    34     add_action('wpblast_deactivate', 'wpblast_wphb_clear_cache');
     33    add_action('wpblast_plugin_updated', 'wpblast_wphb_clear_cache');
     34    add_action('wpblast_deactivated', 'wpblast_wphb_clear_cache');
     35    add_action('wpblast_purge_cache_third_party', 'wpblast_wphb_clear_cache');
    3536    add_action('wpblast_updated_crawler_list', 'wpblast_wphb_clear_cache');
    3637    add_action('wpblast_updated_options', 'wpblast_wphb_clear_cache');
  • wpblast/tags/1.8.5/inc/third-party/index.php

    r2830275 r2852021  
    44
    55require_once 'hummingbird-performance/hummingbird-performance-functions.php';
     6require_once 'litespeed-cache/litespeed-cache-functions.php';
    67require_once 'w3-total-cache/w3-total-cache-functions.php';
    78require_once 'wp-rocket/wp-rocket-functions.php';
  • wpblast/tags/1.8.5/inc/third-party/nitropack/nitropack-functions.php

    r2830275 r2852021  
    1515        'name' => 'WP Blast Addon - Nitropack',
    1616        'code' => [
    17             'body' => "
     17            'deactivationCondition' => "!is_plugin_active('nitropack/main.php')",
     18            'body' => '
    1819// Even if advanced-cache is not used, nitropack needs this filter added prior its execution
    1920// This will be needed for both usecase: with or without advanced-cache with nitropack
    20 require_once '" . __DIR__ . "/../../../globals.php';
    21 function wpblast_nitropack_can_serve_cache() {
    22     return !Smartfire\Wordpress\WPBlast\Bootstrap::should_blast();
     21$wpblast_globals_file = "' . __DIR__ . '/../../../globals.php' . '";
     22$wpblast_abspath = "' . ABSPATH . '";
     23
     24// Fail proof check that the WP installation hasnt been moved to another server or other folder
     25// In case path is wrong, the addon will not be detected and therefore will be installed again
     26if (file_exists($wpblast_globals_file) && ABSPATH == $wpblast_abspath) {
     27    require $wpblast_globals_file;
     28    function wpblast_nitropack_can_serve_cache() {
     29        return !Smartfire\Wordpress\WPBlast\Bootstrap::should_blast();
     30    }
     31    add_filter("nitropack_can_serve_cache", "wpblast_nitropack_can_serve_cache");
    2332}
    24 add_filter('nitropack_can_serve_cache', 'wpblast_nitropack_can_serve_cache');",
     33else {
     34    // will recreate the mu-plugin addon in case of error
     35    if(!defined("WPBLAST_MU_PLUGIN_ERROR")) {
     36        define("WPBLAST_MU_PLUGIN_ERROR", true);
     37        return;
     38    }
     39}',
    2540        ],
    2641    ]);
     
    3752    }
    3853
    39     function wpblast_nitropack_advanced_cache_file($content)
    40     {
    41         // Only insert addon in case there is a content and that addon is not existent, otherwise remove advanced cache to trigger re-generation
    42         if ($content !== '' && strpos($content, 'WPBLAST_ADVANCED_CACHE_VERSION') === false) {
    43             $content = explode('if (defined("NITROPACK_VERSION") && defined("NITROPACK_ADVANCED_CACHE_VERSION") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {', $content);
    44             $start = $content[0];
    45             $nitropack = $content[1];
    46             return $start . "
    47 // WP-BLAST ADDON START //
    48 if(!defined('WPBLAST_ADVANCED_CACHE_VERSION')) {
    49     define( 'WPBLAST_ADVANCED_CACHE_VERSION', '" . WPBLAST_PLUGIN_VERSION . "');
    50 }
    51 
    52 include_once \"" . __DIR__ . '/../advanced-cache.php' . "\";
    53 
    54 if(defined('WPBLAST_SKIP_ADVANCED_CACHE') && WPBLAST_SKIP_ADVANCED_CACHE) {
    55     return;
    56 }
    57 // WP-BLAST ADDON END //
    58 if (defined(\"NITROPACK_VERSION\") && defined(\"NITROPACK_ADVANCED_CACHE_VERSION\") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {
    59 " . $nitropack . '
    60 
    61 ';
    62         } else {
    63             // Removing advanced cache will trigger re-write by nitropack that will then allow for a rewrite of the wpblast addon
    64             return '';
    65         }
    66     }
    67     // As we are checking that a nitropack defined variable in advanced cache is present, no writing error should happen
    68     // In case of upgrade of nitropack, our variable will miss and we'll update the advanced cache file again
    69     // In case of upgrade of wpblast, a new version will be triggered that will force to remove the advanced cache file
    70     // Nitropack will recreates it and we'll add again the addon
    71     add_filter('wpblast_nitropack_advanced_cache_file', 'wpblast_nitropack_advanced_cache_file');
    72 
    73     function wpblast_nitropack_write_advanced_cache_file()
    74     {
    75         $advancedCacheFile = realpath(WP_CONTENT_DIR) . '/advanced-cache.php';
    76         $advancedCacheFileContent = @file_get_contents($advancedCacheFile);
    77         $newContent = apply_filters('wpblast_nitropack_advanced_cache_file', $advancedCacheFileContent);
    78         if (WP_DEBUG) {
    79             return file_put_contents($advancedCacheFile, $newContent);
    80         } else {
    81             return @file_put_contents($advancedCacheFile, $newContent);
    82         }
    83     }
    84 
    85     function wpblast_nitropack_remove_advanced_cache_file()
    86     {
    87         // Reset advanced-cache file so that plugin can generate a new clean one
    88         $advancedCacheFile = realpath(WP_CONTENT_DIR) . '/advanced-cache.php';
    89         if (WP_DEBUG) {
    90             return file_put_contents($advancedCacheFile, '');
    91         } else {
    92             return @file_put_contents($advancedCacheFile, '');
    93         }
    94     }
    95 
    9654    // we don't do anything if nitropack advanced cache is not active
    9755    if (function_exists('nitropack_has_advanced_cache') && nitropack_has_advanced_cache()) {
    98         if (!defined('WPBLAST_ADVANCED_CACHE') || !defined('WPBLAST_ADVANCED_CACHE_VERSION') || WPBLAST_PLUGIN_VERSION !== WPBLAST_ADVANCED_CACHE_VERSION) {
    99             // We rewrite advanced cache in case we detect a NITROPACK_ADVANCED_CACHE (this means the advanced cache is active) and we don't have a WPBLAST_ADVANCED_CACHE_VERSION, this either mean it's a first install or that the plugin nitropack has been updated or as changed the advanced-cache file
    100             add_action('plugins_loaded', 'wpblast_nitropack_write_advanced_cache_file');
    101         }
     56        wpblast_require_advanced_cache([
     57            'slug' => 'wpblast-nitropack-addon',
     58            'delimiter' => 'if (defined("NITROPACK_VERSION") && defined("NITROPACK_ADVANCED_CACHE_VERSION") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {',
     59        ]);
    10260    } else if (function_exists('nitropack_has_advanced_cache') && !nitropack_has_advanced_cache()) {
    103         // If we are installed but nitrocache has disabled the advanced_cache, we should uninstall our advanced-cache addon
    104         if (defined('WPBLAST_ADVANCED_CACHE') || defined('WPBLAST_ADVANCED_CACHE_VERSION')) {
    105             add_action('plugins_loaded', 'wpblast_nitropack_remove_advanced_cache_file');
    106         }
     61        // force uninstall of advanced-cache even if cache plugin is being let active
     62        wpblast_uninstall_advanced_cache([
     63            'slug' => 'wpblast-nitropack-addon',
     64        ]);
    10765    }
    10866
     
    11270        do_action('nitropack_execute_purge_all');
    11371    }
    114 
    11572    add_action('wpblast_purge_cache_third_party', 'wpblast_nitro_clear_cache');
    11673
    117     add_action('wpblast_deactivate', function () {
    118         wpblast_nitropack_remove_advanced_cache_file();
    119     });
     74    add_action('wpblast_plugin_updated', function($oldVersion, $newVersion) {
     75        // Compatibility upgrader before we used markers to replace our addons
     76        // This will remove advanced cache, so that nitropack can add it again and we'll add then our addon
     77        try {
     78            if ($oldVersion === false || $oldVersion === '1.8.4') {
     79                wpblast_clear_advanced_cache_file();
     80            }
     81        }
     82        catch (\Throwable $e) {} // fail proof
     83        catch (\Exception $e) {} // fail proof
     84    }, 10, 2);
    12085}
  • wpblast/tags/1.8.5/inc/third-party/w3-total-cache/w3-total-cache-functions.php

    r2807419 r2852021  
    3737    }
    3838
    39     add_action('wpblast_activate', 'wpblast_w3tc_clear_cache');
    40     add_action('wpblast_deactivate', 'wpblast_w3tc_clear_cache');
     39    add_action('wpblast_plugin_updated', 'wpblast_w3tc_clear_cache');
     40    add_action('wpblast_purge_cache_third_party', 'wpblast_w3tc_clear_cache');
     41    add_action('wpblast_deactivated', 'wpblast_w3tc_clear_cache');
    4142    add_action('wpblast_updated_crawler_list', 'wpblast_w3tc_clear_cache');
    4243    add_action('wpblast_updated_options', 'wpblast_w3tc_clear_cache');
  • wpblast/tags/1.8.5/inc/third-party/wp-fastest-cache/wp-fastest-cache-functions.php

    r2830275 r2852021  
    11<?php
    22
     3use Smartfire\Wordpress\WPBlast\Utils as Utils;
     4
    35defined('ABSPATH') || exit;
    46
     
    79if (is_plugin_active('wp-fastest-cache/wpFastestCache.php')) {
    810
    9     // We are forced to use template_redirect as the plugin would take precedence otherwise
    10     add_action('template_redirect', 'wpblast_actions_before_start_wpfc');
    11     function wpblast_actions_before_start_wpfc()
    12     {
    13         // Avoid WPSC to cache the page
    14         if (!defined('DONOTCACHEPAGE')) {
    15             define('DONOTCACHEPAGE', true);
    16         }
     11    wpblast_require_mu_plugin([
     12        'slug' => 'wpblast-wpfc-addon',
     13        'name' => 'WP Blast Addon - WP Fastest Cache',
     14        'code' => [
     15            'deactivationCondition' => "!is_plugin_active('wp-fastest-cache/wpFastestCache.php')",
     16            'body' => '
     17// Use this mu-plugin to inject a cookie in the request that will make wpfc ignore the request in case we blast the request
     18$wpblast_globals_file = "' . __DIR__ . '/../../../globals.php' . '";
     19$wpblast_abspath = "' . ABSPATH . '";
     20
     21// Fail proof check that the WP installation hasnt been moved to another server or other folder
     22// In case path is wrong, the addon will not be detected and therefore will be installed again
     23if (file_exists($wpblast_globals_file) && ABSPATH == $wpblast_abspath) {
     24    require $wpblast_globals_file;
     25    if (Smartfire\Wordpress\WPBlast\Bootstrap::should_blast()) {
     26        $_SERVER[\'HTTP_COOKIE\'] = "wpblast=1; " . (isset($_SERVER[\'HTTP_COOKIE\']) ? $_SERVER[\'HTTP_COOKIE\'] : "");
     27    }
     28}
     29else {
     30    // will recreate the mu-plugin addon in case of error
     31    if(!defined("WPBLAST_MU_PLUGIN_ERROR")) {
     32        define("WPBLAST_MU_PLUGIN_ERROR", true);
     33        return;
     34    }
     35}',
     36        ],
     37    ]);
     38
     39    function wpblast_wpfc_remove_exclude_rules()
     40    {
     41        remove_filter('pre_update_option_WpFastestCacheExclude', 'wpblast_wpfc_inject_option_WpFastestCacheExclude'); // remove filter so our plugin wouldn't add the rule again
     42        remove_action('delete_option_WpFastestCacheExclude', 'wpblast_wpfc_add_exclude_rules'); // remove filter so our plugin wouldn't add the rule again
     43        $rules_json = get_option('WpFastestCacheExclude');
     44        if (isset($rules_json) && $rules_json !== false && $rules_json !== '') {
     45            $parsedContent = json_decode($rules_json);
     46            $uaIndex = [];
     47            $cookieIndex = [];
     48            foreach ($parsedContent as $key => $value) {
     49                if (isset($value->type) && $value->type === 'useragent' && isset($value->content) && strpos($value->content, 'WP-BLAST') !== false) {
     50                    array_push($uaIndex, $key);
     51                }
     52                if (isset($value->type) && $value->type === 'cookie' && isset($value->content) && strpos($value->content, 'wpblast') !== false) {
     53                    array_push($cookieIndex, $key);
     54                }
     55            }
     56            // Remove the keys
     57            // This should only have one single key but in case an error happened, this will clean every rules
     58            if (isset($uaIndex)) {
     59                foreach ($uaIndex as $uaIdx) {
     60                    array_splice($parsedContent, $uaIdx, 1);
     61                }
     62            }
     63            if (isset($cookieIndex)) {
     64                foreach ($cookieIndex as $cookieIdx) {
     65                    array_splice($parsedContent, $cookieIdx, 1);
     66                }
     67            }
     68
     69            if (count($parsedContent) > 0) {
     70                update_option('WpFastestCacheExclude', Utils::format_json_encode($parsedContent));
     71            } else {
     72                delete_option('WpFastestCacheExclude');
     73            }
     74        }
     75
     76        // Force update of htaccess on wpfc side
     77        try {
     78            include_once(__DIR__ . '/../../../../wp-fastest-cache/inc/admin.php');
     79            if (class_exists('WpFastestCacheAdmin')) {
     80                $wpfc = new WpFastestCacheAdmin();
     81                // only way of retriggering it is to simulate activation
     82                $options = get_option('WpFastestCache');
     83                if (isset($options) && $options !== false) {
     84                    $post = json_decode($options, true);
     85                    $wpfc->modifyHtaccess($post);
     86                }
     87            }
     88        }
     89        catch (\Throwable $e) {} // fail proof
     90        catch (\Exception $e) {} // fail proof
    1791    }
    1892
     
    2397        do_action('wpfc_clear_all_site_cache');
    2498    }
    25 
    26     add_action('wpblast_activate', 'wpblast_wpfc_clear_cache');
    27     add_action('wpblast_deactivate', 'wpblast_wpfc_clear_cache');
    28     add_action('wpblast_updated_crawler_list', 'wpblast_wpfc_clear_cache');
    29     add_action('wpblast_updated_options', 'wpblast_wpfc_clear_cache');
    30 }
     99    add_action('wpblast_purge_cache_third_party', 'wpblast_wpfc_clear_cache');
     100
     101    function wpblast_wpfc_activate()
     102    {
     103        wpblast_wpfc_add_exclude_rules();
     104    }
     105    add_action('wpblast_plugin_updated', function($oldVersion, $newVersion) {
     106        // Compatibility upgrader to reset possible cache with WP Blast content
     107        try {
     108            if ($oldVersion === false || $oldVersion === '1.8.4') {
     109                wpblast_wpfc_clear_cache();
     110            }
     111        }
     112        catch (\Throwable $e) {} // fail proof
     113        catch (\Exception $e) {} // fail proof
     114        try {
     115            wpblast_wpfc_activate();
     116        }
     117        catch (\Throwable $e) {} // fail proof
     118        catch (\Exception $e) {} // fail proof
     119    }, 10, 2);
     120
     121    add_action('wpblast_updated_crawler_list', 'wpblast_wpfc_add_exclude_rules'); // should update exclude rules
     122    add_action('wpblast_updated_options', 'wpblast_wpfc_add_exclude_rules');
     123
     124    function wpblast_wpfc_deactivated()
     125    {
     126        // should be executed with deactivated to have the plugin being deactivated and no more requests
     127        wpblast_wpfc_remove_exclude_rules();
     128    }
     129    add_action('wpblast_deactivated', 'wpblast_wpfc_deactivated'); // should disable exclude rules and mu-plugin
     130}
     131
     132// Should be added whether the plugin is active or not so that in case wpblast is already enabled and wpfc is activated, we can inject our rules
     133// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid -- WpFastestCacheExclude is the name of the option
     134function wpblast_wpfc_inject_option_WpFastestCacheExclude($content)
     135{
     136    $parsedContent = [];
     137    try {
     138        if (isset($content) && $content !== '') {
     139            $parsedContent = json_decode($content);
     140        }
     141    }
     142    catch (\Throwable $e) {} // fail proof
     143    catch (\Exception $e) {} // fail proof
     144    if (!is_array($parsedContent)) {
     145        $parsedContent = [];
     146    }
     147    $ruleUAExist = false;
     148    $ruleCookieExist = false;
     149    $crawlers = apply_filters('wpblast_crawlers_full', '');
     150    foreach ($parsedContent as $key => $value) {
     151        if (isset($value->type) && $value->type === 'useragent' && isset($value->content) && strpos($value->content, 'WP-BLAST') !== false) {
     152            $ruleUAExist = true;
     153            $parsedContent[$key]->content = '^(' . str_replace([' ', '\\\\ '], '\\ ', $crawlers) . ').*'; // force update with new value
     154            $parsedContent[$key]->editable = false; // re-add editable false, otherwise, when the user save, this property gets stripped
     155        }
     156        if (isset($value->type) && $value->type === 'cookie' && isset($value->content) && strpos($value->content, 'wpblast') !== false) {
     157            $ruleCookieExist = true;
     158            $parsedContent[$key]->content = 'wpblast'; // force update with new value
     159            $parsedContent[$key]->editable = false; // re-add editable false, otherwise, when the user save, this property gets stripped
     160        }
     161    }
     162    if ($ruleUAExist === false) {
     163        if ($crawlers !== '') {
     164            $new_rule = new stdClass();
     165            $new_rule->prefix = 'contain';
     166            $new_rule->content = '^(' . str_replace([' ', '\\\\ '], '\\ ', $crawlers) . ').*';
     167            $new_rule->type = 'useragent';
     168            $new_rule->editable = false;
     169            array_push($parsedContent, $new_rule);
     170        }
     171    }
     172    if ($ruleCookieExist === false) {
     173        $new_rule = new stdClass();
     174        $new_rule->prefix = 'contain';
     175        $new_rule->content = 'wpblast';
     176        $new_rule->type = 'cookie';
     177        $new_rule->editable = false;
     178        array_push($parsedContent, $new_rule);
     179    }
     180
     181    return Utils::format_json_encode($parsedContent);
     182}
     183add_filter('pre_update_option_WpFastestCacheExclude', 'wpblast_wpfc_inject_option_WpFastestCacheExclude');
     184
     185function wpblast_wpfc_add_exclude_rules()
     186{
     187    $rules_json = get_option('WpFastestCacheExclude');
     188    if ($rules_json === false) {
     189        add_option('WpFastestCacheExclude', wpblast_wpfc_inject_option_WpFastestCacheExclude('[]'), '', 'yes'); // add our rules if no option exists
     190    } else {
     191        update_option('WpFastestCacheExclude', $rules_json); // will then trigger hook that will inject our rule
     192    }
     193
     194    // Force update of htaccess on wpfc side
     195    try {
     196        include_once(__DIR__ . '/../../../../wp-fastest-cache/inc/admin.php');
     197        if (class_exists('WpFastestCacheAdmin')) {
     198            $wpfc = new WpFastestCacheAdmin();
     199            // only way of retriggering it is to simulate activation
     200            $options = get_option('WpFastestCache');
     201            if (isset($options) && $options !== false) {
     202                $post = json_decode($options, true);
     203                $wpfc->modifyHtaccess($post);
     204            }
     205        }
     206    }
     207    catch (\Throwable $e) {} // fail proof
     208    catch (\Exception $e) {} // fail proof
     209}
     210add_action('delete_option_WpFastestCacheExclude', 'wpblast_wpfc_add_exclude_rules'); // in case the plugin tries to delete the option force it to stay
     211
     212// Should be check after check of activation of plugin
     213function wpblast_wpfc_activation($plugin)
     214{
     215    if ($plugin == 'wp-fastest-cache/wpFastestCache.php') {
     216        wpblast_wpfc_add_exclude_rules(); // add exclude rules in case of activation of wpfc when wpblast is already active
     217    }
     218}
     219add_action('activated_plugin', 'wpblast_wpfc_activation');
  • wpblast/tags/1.8.5/inc/third-party/wp-rocket/wp-rocket-functions.php

    r2830275 r2852021  
    1919    function wpblast_rocket_advanced_cache_file($content)
    2020    {
    21         $content = explode("defined( 'ABSPATH' ) || exit;", $content);
    22         $start = $content[0];
    23         $wp_rocket = $content[1];
    24         return $start . "defined( 'ABSPATH' ) || exit;
    25 include \"" . __DIR__ . '/../advanced-cache.php' . "\";
    26 
    27 if(defined('WPBLAST_SKIP_ADVANCED_CACHE') && WPBLAST_SKIP_ADVANCED_CACHE) {
    28     return;
    29 }
    30 " . $wp_rocket . '
    31 
    32 ';
     21        return apply_filters('wpblast_advanced_cache_content', $content, "define( 'WP_ROCKET_ADVANCED_CACHE', true );", 'wpblast-wprocket-addon');
    3322    }
    3423    // As we are hooked on wprocket advanced_cache content, wprocket will be in charge of checking for error in filesystem in case we cannot write the advanced-cache.php file
     24    // in case of error in wprocket advanced cache, it will be recreated and our addon will be added again
    3525    // in case of upgrade, they will recreate advanced-cache.php file and call again this function
    3626    add_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
     27
     28
     29    function wpblast_advanced_cache_content_error()
     30    {
     31        return "
     32        // Trigger constant of wprocket to indicate a problem with advanced-cache
     33        if(!defined('WP_ROCKET_ADVANCED_CACHE_PROBLEM')) {
     34            define( 'WP_ROCKET_ADVANCED_CACHE_PROBLEM', true );
     35            return;
     36        }";
     37    }
     38    add_filter('wpblast_advanced_cache_content_error', 'wpblast_advanced_cache_content_error');
    3739
    3840    /**
     
    7375    }
    7476
    75     add_action('wpblast_activate', function () {
    76         add_action('admin_init', 'wpblast_rocket_refresh');
     77    add_action('wpblast_plugin_updated', function () {
     78        add_action('init', 'wpblast_rocket_refresh');
    7779    });
     80    // advanced-cache should be remove at the start of the deactivation to prevent concurrent requests bugs
    7881    add_action('wpblast_deactivate', function () {
     82        remove_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
     83        remove_filter('rocket_cache_reject_ua', 'wpblast_rocket_user_agent_reject');
     84        wpblast_rocket_refresh();
     85    });
     86    // should clean afterward to clean what could have been added during uninstallation process
     87    add_action('wpblast_deactivated', function () {
    7988        remove_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
    8089        remove_filter('rocket_cache_reject_ua', 'wpblast_rocket_user_agent_reject');
  • wpblast/tags/1.8.5/inc/third-party/wp-super-cache/wp-super-cache-functions.php

    r2807419 r2852021  
    2626    }
    2727
    28     add_action('wpblast_activate', 'wpblast_wpsc_clear_cache');
    29     add_action('wpblast_deactivate', 'wpblast_wpsc_clear_cache');
     28    add_action('wpblast_plugin_updated', 'wpblast_wpsc_clear_cache');
     29    add_action('wpblast_deactivated', 'wpblast_wpsc_clear_cache');
     30    add_action('wpblast_purge_cache_third_party', 'wpblast_wpsc_clear_cache');
    3031    add_action('wpblast_updated_crawler_list', 'wpblast_wpsc_clear_cache');
    3132    add_action('wpblast_updated_options', 'wpblast_wpsc_clear_cache');
  • wpblast/tags/1.8.5/js/wpblast-settings.js

    r2811232 r2852021  
    277277        var wpBlastSitemapUpdatedItems = [];
    278278        var wpBlastSitemapItemsToUpdateScore = [];
     279        var wpBlastIsLoadingSitemap = false;
    279280        var types = ['raw', 'blast'];
    280281        var devices = ['mobile', 'desktop'];
     
    728729            if (shouldUpdateScores && wpBlastSitemapItemsToUpdateScore.length > 0) {
    729730                // speed up update of scores in case we didn't have updated it
    730                 // Todo: add a lock to avoid having multiple parallel calls to getSitemap while the request isn't finished
    731731                wpBlastGetSitemap();
    732732            }
     
    16211621
    16221622        function wpBlastGetSitemap() {
    1623             // Get sitemap stored in website database
    1624             var dataToSend = {};
    1625             if (wpBlastSitemapItemsToUpdateScore.length > 0) {
    1626                 dataToSend['items'] = wpBlastSitemapItemsToUpdateScore;
    1627                 for (var i = 0; i < wpBlastSitemapItemsToUpdateScore.length; i++) {
    1628                     // mark this hash has updated, this will prevent an update until next reload of the page
    1629                     wpBlastSitemapUpdatedItems.push(
    1630                         wpBlastSitemapItemsToUpdateScore[i].hash +
    1631                             '-' +
    1632                             wpBlastSitemapItemsToUpdateScore[i].type +
    1633                             '-' +
    1634                             wpBlastSitemapItemsToUpdateScore[i].device,
    1635                     );
    1636                 }
    1637             }
    1638             var restUrl = '/wp-json/wpblast/v1/getSitemap?wpblast_nonce=' + wpblast_nonce; // fallback rest url
    1639             if (
    1640                 typeof wpBlastSettings !== 'undefined' &&
    1641                 wpBlastSettings.restUrls !== null &&
    1642                 wpBlastSettings.restUrls !== undefined
    1643             ) {
    1644                 if (typeof URLSearchParams !== 'undefined' && typeof URL !== 'undefined') {
    1645                     try {
    1646                         var url = new URL(wpBlastSettings.restUrls.getSiteMap);
    1647                         url.searchParams.append('wpblast_nonce', wpblast_nonce);
    1648                         restUrl = url.toString();
    1649                     } catch (e) {
     1623            // avoid a call in case a request is already loading. This is to prevent request from stacking
     1624            if (!wpBlastIsLoadingSitemap) {
     1625                // Get sitemap stored in website database
     1626                var dataToSend = {};
     1627                if (wpBlastSitemapItemsToUpdateScore.length > 0) {
     1628                    dataToSend['items'] = wpBlastSitemapItemsToUpdateScore;
     1629                    for (var i = 0; i < wpBlastSitemapItemsToUpdateScore.length; i++) {
     1630                        // mark this hash has updated, this will prevent an update until next reload of the page
     1631                        wpBlastSitemapUpdatedItems.push(
     1632                            wpBlastSitemapItemsToUpdateScore[i].hash +
     1633                                '-' +
     1634                                wpBlastSitemapItemsToUpdateScore[i].type +
     1635                                '-' +
     1636                                wpBlastSitemapItemsToUpdateScore[i].device,
     1637                        );
     1638                    }
     1639                }
     1640                var restUrl = '/wp-json/wpblast/v1/getSitemap?wpblast_nonce=' + wpblast_nonce; // fallback rest url
     1641                if (
     1642                    typeof wpBlastSettings !== 'undefined' &&
     1643                    wpBlastSettings.restUrls !== null &&
     1644                    wpBlastSettings.restUrls !== undefined
     1645                ) {
     1646                    if (typeof URLSearchParams !== 'undefined' && typeof URL !== 'undefined') {
     1647                        try {
     1648                            var url = new URL(wpBlastSettings.restUrls.getSiteMap);
     1649                            url.searchParams.append('wpblast_nonce', wpblast_nonce);
     1650                            restUrl = url.toString();
     1651                        } catch (e) {
     1652                            // Fallback url
     1653                            restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
     1654                        }
     1655                    } else {
    16501656                        // Fallback url
    16511657                        restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
    16521658                    }
    1653                 } else {
    1654                     // Fallback url
    1655                     restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
    1656                 }
    1657             }
    1658             jQuery.ajax({
    1659                 url: restUrl,
    1660                 headers: {
    1661                     'X-WP-Nonce': wpblast_nonce,
    1662                     'content-type': 'application/json',
    1663                 },
    1664                 method: 'POST',
    1665                 data: JSON.stringify(dataToSend),
    1666                 success: function (data) {
    1667                     if (data && data.response && data.response.sitemap !== undefined && data.response.data !== null) {
    1668                         wpBlastGetSitemapData(data.response.sitemap);
    1669                     }
    1670 
    1671                     // Should be update after possible update of wpBlastSitemap
    1672                     if ((isGeneratingCache || wpBlastSitemap.length === 0) && wpBlastGetSitemapFrequency !== 1000) {
    1673                         clearInterval(wpBlastGetSitemapInterval);
    1674                         wpBlastGetSitemapFrequency = 1000;
    1675                         if (window.location.search.indexOf('debug') === -1) {
    1676                             wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
    1677                         }
    1678                     } else if (
    1679                         !(isGeneratingCache || wpBlastSitemap.length === 0) &&
    1680                         wpBlastGetSitemapFrequency !== 5000
    1681                     ) {
    1682                         clearInterval(wpBlastGetSitemapInterval);
    1683                         wpBlastGetSitemapFrequency = 5000;
    1684                         if (window.location.search.indexOf('debug') === -1) {
    1685                             wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
    1686                         }
    1687                     }
    1688                 },
    1689             });
     1659                }
     1660                wpBlastIsLoadingSitemap = true;
     1661                jQuery.ajax({
     1662                    url: restUrl,
     1663                    headers: {
     1664                        'X-WP-Nonce': wpblast_nonce,
     1665                        'content-type': 'application/json',
     1666                    },
     1667                    method: 'POST',
     1668                    data: JSON.stringify(dataToSend),
     1669                    success: function (data) {
     1670                        if (
     1671                            data &&
     1672                            data.response &&
     1673                            data.response.sitemap !== undefined &&
     1674                            data.response.data !== null
     1675                        ) {
     1676                            wpBlastGetSitemapData(data.response.sitemap);
     1677                        }
     1678
     1679                        // Should be update after possible update of wpBlastSitemap
     1680                        if ((isGeneratingCache || wpBlastSitemap.length === 0) && wpBlastGetSitemapFrequency !== 1000) {
     1681                            clearInterval(wpBlastGetSitemapInterval);
     1682                            wpBlastGetSitemapFrequency = 1000;
     1683                            if (window.location.search.indexOf('debug') === -1) {
     1684                                wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
     1685                            }
     1686                        } else if (
     1687                            !(isGeneratingCache || wpBlastSitemap.length === 0) &&
     1688                            wpBlastGetSitemapFrequency !== 5000
     1689                        ) {
     1690                            clearInterval(wpBlastGetSitemapInterval);
     1691                            wpBlastGetSitemapFrequency = 5000;
     1692                            if (window.location.search.indexOf('debug') === -1) {
     1693                                wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
     1694                            }
     1695                        }
     1696                    },
     1697                    complete: function () {
     1698                        wpBlastIsLoadingSitemap = false;
     1699                    },
     1700                });
     1701            }
    16901702        }
    16911703
  • wpblast/tags/1.8.5/languages/wpblast-fr_FR.po

    r2811232 r2852021  
    398398
    399399# wpml-name: 5062b4b59571ebec36f93781a550255b
    400 msgid "This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 6000."
    401 msgstr "C'est le maximum d'urls que vous souhaitez conserver. Si le nombre est trop faible, l'efficacité du cache diminuera. S'il est trop élevé, vous pourriez avoir besoin de plus de stockage pour votre base de données. Défaut : 6000."
     400msgid "This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 20000."
     401msgstr "C'est le maximum d'urls que vous souhaitez conserver. Si le nombre est trop faible, l'efficacité du cache diminuera. S'il est trop élevé, vous pourriez avoir besoin de plus de stockage pour votre base de données. Défaut : 20000."
    402402
    403403# wpml-name: e6463ff3a7cfe9b18d6994bbd09d82b0
     
    406406
    407407# wpml-name: 733c2a0696e4e033ad552d5715fd8581
    408 msgid "This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 2000."
    409 msgstr "Nombre maximum de pages que vous souhaitez conserver en cache. Si ce nombre est trop faible, le cache sera moins efficace. Plus ce nombre est élevé, plus le cache prendra une taille importante dans votre base de données. Valeur par défaut : 2 000."
     408msgid "This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 10000."
     409msgstr "Nombre maximum de pages que vous souhaitez conserver en cache. Si ce nombre est trop faible, le cache sera moins efficace. Plus ce nombre est élevé, plus le cache prendra une taille importante dans votre base de données. Valeur par défaut : 10 000."
    410410
    411411# wpml-name: 268eebdc0ee24405bd723be444050b98
  • wpblast/tags/1.8.5/plugin.php

    r2830275 r2852021  
    22
    33/**
    4  * Plugin Name: WPBlast
     4 * Plugin Name: WP Blast
    55 * Plugin URI: https://www.wp-blast.com
    66 * Description: Improve your Wordpress SEO and performance by using dynamic rendering. Prerender your website and generate an easy-to-crawl website.
    7  * Version: 1.8.4
     7 * Version: 1.8.5
    88 * Requires at least: 4.9
    99 * Requires PHP: 5.6
     
    1919use Smartfire\Wordpress\WPBlast\Settings;
    2020
    21 define('WPBLAST_DB_VERSION', '1.2.0');
    22 define('WPBLAST_PLUGIN_VERSION', '1.8.4');
    23 
    24 require_once 'globals.php';
     21define('WPBLAST_DB_VERSION', '1.2.1'); // This is used to upgrade database scheme or force cleanup caches and new crawl
     22define('WPBLAST_PLUGIN_VERSION', '1.8.5');
     23
     24require 'globals.php';
    2525
    2626require_once 'inc/generate-config-functions.php';
     
    2828require_once 'inc/rest-functions.php';
    2929require_once 'inc/mu-plugins-functions.php';
     30require_once 'inc/advanced-cache-functions.php';
    3031require_once 'inc/third-party/index.php';
    3132
     
    6364}
    6465
     66// Registration hook
     67function wpblast_register_activation()
     68{
     69    // First install DB
     70    wpblast_install();
     71    // Then trigger update hook for third-party gen
     72    try {
     73        // also used to trigger regeneration of config or third party file updates
     74        do_action('wpblast_plugin_updated', get_option('wpblast_plugin_version'), WPBLAST_PLUGIN_VERSION);
     75
     76        // only update option at the end so that it can be trigger again in case of error
     77        update_option('wpblast_plugin_version', WPBLAST_PLUGIN_VERSION);
     78    }
     79    catch (\Throwable $e) {} // fail proof
     80    catch (\Exception $e) {} // fail proof
     81}
     82
    6583// Update check
    66 function wpblast_update_db_check()
    67 {
     84function wpblast_update_check()
     85{
     86    // Update DB check
    6887    if (get_option('wpblast_db_version') !== WPBLAST_DB_VERSION) {
    6988        wpblast_install();
     89    }
     90    // Update plugin code check
     91    if (get_option('wpblast_plugin_version') !== WPBLAST_PLUGIN_VERSION) {
     92        try {
     93            // also used to trigger regeneration of config or third party file updates
     94            do_action('wpblast_plugin_updated', get_option('wpblast_plugin_version'), WPBLAST_PLUGIN_VERSION);
     95
     96            // only update option at the end so that it can be trigger again in case of error
     97            update_option('wpblast_plugin_version', WPBLAST_PLUGIN_VERSION);
     98        }
     99        catch (\Throwable $e) {} // fail proof
     100        catch (\Exception $e) {} // fail proof
    70101    }
    71102}
     
    122153}
    123154
    124 add_action('plugins_loaded', 'wpblast_update_db_check');
    125 register_activation_hook(__FILE__, 'wpblast_install');
     155add_action('plugins_loaded', 'wpblast_update_check');
     156register_activation_hook(__FILE__, 'wpblast_register_activation');
    126157function wpblast_install()
    127158{
     
    132163
    133164        // Setup transient for first activation
     165        // This is also used to trigger again a crawl in case of upgrade
    134166        set_transient(Settings::PLUGIN_CACHE_PREFIX . '_firstActivation', time(), apply_filters('wpblast_settings_first_activation_expiration', 60 * 60 * 24 * 30));
    135167
     
    165197        }
    166198
     199        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_CacheExpiration'", ARRAY_A);
     200        if (!isset($resultPages)) {
     201            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_CacheExpiration` (`cacheExpiration`)");
     202        }
     203
     204        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_Url'", ARRAY_A);
     205        if (!isset($resultPages)) {
     206            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_Url` (`url`)");
     207        }
     208
     209        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_Active'", ARRAY_A);
     210        if (!isset($resultPages)) {
     211            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_Active` (`active`)");
     212        }
     213
     214        // also used to trigger regeneration of config or third party file updates
     215        do_action('wpblast_activate', get_option('wpblast_db_version'), WPBLAST_DB_VERSION);
     216
     217        // only update option at the end so that it can be trigger again in case of error
    167218        update_option('wpblast_db_version', WPBLAST_DB_VERSION);
    168 
    169         // also used to trigger regeneration of config or third party file updates
    170         do_action('wpblast_activate');
    171219    } catch (\Throwable $e) {
    172220        // hardcode url so that it's as pure as possible
     
    214262add_action('activated_plugin', 'wpblast_activation_redirect');
    215263
     264// This is done in two steps to prevent concurrent requests bugs
     265// In case the uninstall method takes a few seconds to process and that requests are still coming, the plugin could create new data that will not be cleaned
     266// This results in pluginData, file config or third party actions not cleaned (mainly with the action wpblast_updated_crawler_list)
    216267register_deactivation_hook(__FILE__, 'wpblast_uninstall');
    217268function wpblast_uninstall()
    218269{
     270    global $smartfire_wpblast_settings;
     271    // Ping wp-blast.com to be aware of deactivation and not trigger auto gen cache
     272    try {
     273        wp_remote_get($smartfire_wpblast_settings->getWebsite() . '/?method=deactivatePlugin&domain=' . urlencode($smartfire_wpblast_settings->getUsername()) . '&plugin_token=' . $smartfire_wpblast_settings->getPassword(), [
     274            'user-agent' => Settings::WPBLAST_UA_PLUGIN,
     275            'timeout' => 15,
     276        ]);
     277    }
     278    catch (\Throwable $e) {} // fail proof
     279    catch (\Exception $e) {} // fail proof
     280    // should remove every advanced-cache addon or mu-plugins before cleaning everything to prevent concurrent requests bugs
     281    // otherwise concurrent requests could trigger new cache that won't be cleaned
     282    try {
     283        do_action('wpblast_deactivate');
     284    }
     285    catch (\Throwable $e) {} // fail proof
     286    catch (\Exception $e) {} // fail proof
     287}
     288
     289function wpblast_uninstalled($plugin, $network_deactivating)
     290{
    219291    global $wpdb;
    220     $wpdb->wpblast_sitemap = $wpdb->prefix . Settings::WPBLAST_SITEMAP_TABLE;
    221     // Ping wp-blast.com to be aware of deactivation and not trigger auto gen cache
    222     $wpblast_settings = new Settings();
    223     $wpblast_settings->init();
    224     wp_remote_get($wpblast_settings->getWebsite() . '/?method=deactivatePlugin&domain=' . urlencode($wpblast_settings->getUsername()) . '&plugin_token=' . $wpblast_settings->getPassword(), [
    225         'user-agent' => Settings::WPBLAST_UA_PLUGIN,
    226         'timeout' => 15,
    227     ]);
    228     // Don't clean db version and settings to keep it in case of renabling but purge every other cache
    229     wpblast_remove_capability(); // clean capability
    230     do_action('wpblast_purge_cache');
    231     do_action('wpblast_purge_plugin_cache', false);
    232     // Remove table for clean uninstallation
    233     $wpdb->query("DROP TABLE IF EXISTS {$wpdb->wpblast_sitemap}");
    234     do_action('wpblast_deactivate');
    235 }
     292    if ($plugin === plugin_basename(__FILE__)) {
     293        $wpdb->wpblast_sitemap = $wpdb->prefix . Settings::WPBLAST_SITEMAP_TABLE;
     294        // Don't clean db version and settings to keep it in case of renabling but purge every other cache
     295        try {
     296            wpblast_remove_capability(); // clean capability
     297        }
     298        catch (\Throwable $e) {} // fail proof
     299        catch (\Exception $e) {} // fail proof
     300        try {
     301            do_action('wpblast_purge_plugin_cache', false);
     302        }
     303        catch (\Throwable $e) {} // fail proof
     304        catch (\Exception $e) {} // fail proof
     305        try {
     306            // Remove table for clean uninstallation
     307            $wpdb->query("DROP TABLE IF EXISTS {$wpdb->wpblast_sitemap}");
     308        }
     309        catch (\Throwable $e) {} // fail proof
     310        catch (\Exception $e) {} // fail proof
     311        try {
     312            do_action('wpblast_deactivated');
     313        }
     314        catch (\Throwable $e) {} // fail proof
     315        catch (\Exception $e) {} // fail proof
     316    }
     317}
     318add_action('deactivated_plugin', 'wpblast_uninstalled', 10, 2);
    236319
    237320function wpblast_action_links($links)
  • wpblast/tags/1.8.5/readme.txt

    r2830275 r2852021  
    55Tested up to: 6.1
    66Requires PHP: 5.6
    7 Stable tag: 1.8.4
     7Stable tag: 1.8.5
    88License: Apache 2.0
    99License URI: http://www.apache.org/licenses/LICENSE-2.0
     
    3535The plugin has been designed to allow you to get a very high technology with no headache and no-code knowledge.
    3636The default settings in the plugin should be enough for a large majority of installations. Nevertheless, you still can tweak it if needed.
    37 If you have a website with a very large number of pages (> 2000), just be sure that the maximum number of cache items and the maximum number of sitemap items are well set. If you have any doubt with your plugin configuration, just [contact us](https://www.wp-blast.com/contact/) and we'll be happy to help you configure it.
     37If you have a website with a very large number of pages (> 10000), just be sure that the maximum number of cache items and the maximum number of sitemap items are well set. If you have any doubt with your plugin configuration, just [contact us](https://www.wp-blast.com/contact/) and we'll be happy to help you configure it.
    3838
    3939### Install WP Blast from within WordPress
     
    8282
    8383== Changelog ==
    84 = 1.8.4 =
    85 Release Date: December 7th, 2022
     84= 1.8.5 =
     85Release Date: December 13th, 2022
    8686
    87 - Improve WP Rocket crawler management
    88 - Improve Nitropack compatibility
    89 - Fix error that could happened in crawler detection
     87- Improve performance on large websites
     88- Improve advanced-cache updates for nitropack and wp rocket
     89- Improve mu-plugins updates for nitropack
  • wpblast/tags/1.8.5/src/Smartfire/Wordpress/WPBlast/Config.php

    r2807381 r2852021  
    111111        }
    112112
    113         include $config_file_path['path'];
     113        // Add fail proof in case the file doesn't exist, this will fallback to default value
     114        // This could happened in case advanced cache is not cleaned and request are coming
     115        if (file_exists($config_file_path['path'])) {
     116            include $config_file_path['path'];
     117        }
    114118
    115119        $config = [
  • wpblast/tags/1.8.5/src/Smartfire/Wordpress/WPBlast/PageRender.php

    r2807381 r2852021  
    158158        }
    159159
    160         do_action('wpblast_actions_before_start');
    161 
    162160        ob_start([$this, 'render']);
    163161    }
     
    293291    }
    294292
     293    /**
     294     * This method will be executed after EVERY code php has finished
     295     * This is executed after wp has shutdown
     296     */
    295297    public function renderFor($url, $body, $static, $withScroll, $withImages)
    296298    {
     
    331333                return $body;
    332334            }
     335
     336            // Request can be blast
     337            // Use third party contribution point so that they can take action
     338            // This may avoid having cache plugins cache wpblast results
     339            // This avoid having to stop caching in case the request won't be taken in charge by wpblast (case where it's disabled or if the page isn't allowed)
     340            // This may create a bug in case of upgrade of plan with cache plugins had cached the request
     341            do_action('wpblast_actions_before_start');
     342
    333343            if ($sitemapItem === null) {
    334344                // save in db new hash before launching blasting
     
    405415            $this->settings->purgeExceededItemsCache(); // remove transitient exceeding max_cache_items
    406416            $this->settings->cleanExpiredCache(); // clean up expired cache items
     417
     418            do_action('wpblast_actions_before_render', $hash, $toUpdate);
    407419
    408420            return $content;
  • wpblast/tags/1.8.5/src/Smartfire/Wordpress/WPBlast/Settings.php

    r2830275 r2852021  
    1616    const PLUGIN_CACHE_PREFIX = 'wpblast_plugin';
    1717    const WPBLAST_SITEMAP_TABLE = 'wpblast_sitemap';
    18     const WPBLAST_UA_PLUGIN = 'WP-BLAST-Bot-Plugin 1.8.4';
     18    const WPBLAST_UA_PLUGIN = 'WP-BLAST-Bot-Plugin 1.8.5';
    1919
    2020    private $menu_name = 'wpblast';
     
    3636    private $cacheExpirationCrawlers = 60 * 60 * 24;
    3737    private $cacheGrace = 60 * 15; // 15 min
    38     private $maxCacheItemsCrawlers = 2000;
    39     private $maxSitemapItems = 6000;
     38    private $maxCacheItemsCrawlers = 10000;
     39    private $maxSitemapItems = 20000;
    4040    private $cacheCrawlerList = 60 * 60 * 24;
    4141    private $cacheUserAccount = 60 * 60 * 24;
    4242    private $updatePluginDataFrequency = 60 * 60;
    4343    private $cacheItemGarbageExpiration = 60 * 60 * 24 * 7; // a week
     44    private $purgeExceededItemsCacheRateLimit = 60; // 1 min
     45    private $cleanExpiredCacheRateLimit = 60; // 1 min
    4446    private $withImages = true;
    4547    private $withScroll = true;
     
    215217        add_filter('update_option_wpblast_crawler', [$this, 'onCrawlerOptionChange'], 10, 2);
    216218
     219        add_filter('wpblast_crawlers_cachegen', function ($regexp) {
     220            return $this->getCrawlerCacheGen();
     221        });
     222
     223        add_filter('wpblast_crawlers_regexp', function ($regexp) {
     224            return $this->getCrawlerRegexp();
     225        });
     226
     227        add_filter('wpblast_crawlers_autoregexp', function ($regexp) {
     228            return $this->getCrawlerAutoRegexp();
     229        });
     230
     231        add_filter('wpblast_crawlers_full', function ($regexp) {
     232            $crawlerCacheGen = $this->getCrawlerCacheGen();
     233            $crawlerRegexp = $this->getCrawlerRegexp();
     234            $crawlerAutoRegexp = $this->getCrawlerAutoRegexp();
     235            $returnValue = ''; // Security in case the filter is called twice
     236            if (isset($crawlerCacheGen) && $crawlerCacheGen !== '') {
     237                $returnValue .= $crawlerCacheGen;
     238            }
     239            if (isset($crawlerRegexp) && $crawlerRegexp !== '') {
     240                if ($returnValue !== '') {
     241                    $returnValue .= '|';
     242                }
     243                $returnValue .= $crawlerRegexp;
     244            }
     245            if (isset($crawlerAutoRegexp) && $crawlerAutoRegexp !== '') {
     246                if ($returnValue !== '') {
     247                    $returnValue .= '|';
     248                }
     249                $returnValue .= $crawlerAutoRegexp;
     250            }
     251            return $returnValue;
     252        });
     253
    217254        add_filter('wpblast_crawlers_list', function ($ua) {
    218255            array_push($ua, [
     
    250287        $this->updatePluginDataFrequency = apply_filters('wpblast_settings_plugin_data_expiration', $this->updatePluginDataFrequency);
    251288        $this->cacheItemGarbageExpiration = apply_filters('wpblast_settings_cache_garbage_expiration', $this->cacheItemGarbageExpiration);
     289
     290        $this->purgeExceededItemsCacheRateLimit = apply_filters('wpblast_settings_purge_exceeded_items_cache_rate_limit', $this->purgeExceededItemsCacheRateLimit);
     291        $this->cleanExpiredCacheRateLimit = apply_filters('wpblast_settings_clean_expired_cache_rate_limit', $this->cleanExpiredCacheRateLimit);
    252292
    253293        $this->server = $this->api->get_option('server', 'wpblast_home', $this->server);
     
    277317        $this->maxSitemapItems = intval($this->api->get_option('max_sitemap_items', 'wpblast_crawler', $this->maxSitemapItems));
    278318
    279         // Protection against lock of requests when there is no plugin cache yet and we need to generate it
    280         // This is a protection but this case shouldn't happen
    281         if (!isset($_SERVER['HTTP_WPBLAST_SITEMAP_GENERATION'])) {
    282             $this->getCrawlerAutoRegexp(); // update crawler list if expired
    283             $this->getAccount(); // update user account if expired
    284             $this->getPluginData(); // update plugin data to WP Blast at the given frequency
    285         }
    286 
    287319        add_action('wpblast_purge_cache', [$this, 'purgeCache']);
    288320        add_action('wpblast_purge_plugin_cache', [$this, 'purgePluginCache']);
     
    293325
    294326        $this->has_been_init = true;
     327
     328        // Protection against lock of requests when there is no plugin cache yet and we need to generate it
     329        // This is a protection but this case shouldn't happen
     330        // This has been moved after the has_been_init flag because it would trigger a second init otherwise due to trigger of getCrawlerAutoRegexp that could then trigger a generation of config and then a new init
     331        if (!isset($_SERVER['HTTP_WPBLAST_SITEMAP_GENERATION'])) {
     332            $this->getCrawlerAutoRegexp(); // update crawler list if expired
     333            $this->getAccount(); // update user account if expired
     334            $this->getPluginData(); // update plugin data to WP Blast at the given frequency
     335        }
     336    }
     337
     338    // Force check that the plugin is still active
     339    // This is used to avoid concurrent requests bugs
     340    // Bug would be to not have a cleaned uninstall in case a request finish after the uninstallation
     341    public function isPluginActive()
     342    {
     343        global $wpdb;
     344        $pluginName = plugin_basename(realpath($this->rootPluginFile));
     345        $suppress = $wpdb->suppress_errors();
     346        $row      = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'active_plugins' ) );
     347        $wpdb->suppress_errors( $suppress );
     348        if ( is_object( $row ) ) {
     349            $value = maybe_unserialize($row->option_value);
     350        }
     351        return in_array( $pluginName, $value, true ) || is_plugin_active_for_network( $pluginName );
    295352    }
    296353
     
    342399            if (isset($res)) {
    343400                $res = json_decode($res, true);
    344                 if ($res) {
     401                // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     402                // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     403                if ($res && $this->isPluginActive()) {
    345404                    $data = current_time('mysql', 1);
    346405                    set_transient(self::PLUGIN_CACHE_PREFIX . '_plugindata', $data, $this->updatePluginDataFrequency);
     
    374433            }
    375434            $res = wp_remote_retrieve_body($response);
    376             if (isset($res) && $res !== '') {
     435            // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     436            // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     437            if (isset($res) && $res !== '' && $this->isPluginActive()) {
    377438                $res = json_decode($res, true);
    378439                if (isset($res['crawlers']) && $res['crawlers'] !== '') {
     
    412473            }
    413474            $res = wp_remote_retrieve_body($response);
    414 
    415             if (isset($res) && $res !== '') {
     475            // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     476            // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     477            if (isset($res) && $res !== '' && $this->isPluginActive()) {
    416478                $res = json_decode($res, true);
    417479                if (
     
    452514                        && $userAccount['features']['maxPages'] !== $maxPagesAllowed
    453515                    ) {
    454                         $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp ORDER BY maxActive DESC, maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
    455                         $this->updateActivePages($urls);
     516                        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     517                            $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp ORDER BY maxActive DESC, maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
     518                            $this->updateActivePages($urls);
     519                        }
    456520                    }
    457521                    // Generate cache if it's a first connection
     
    484548        global $wpdb;
    485549
    486         if (count($items) > 0) {
     550        if (count($items) > 0 && $this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    487551
    488552            // Send data about hash wanted to be sure it's sync with wp-blast.com server
     
    525589                            $toUpdate['scores'] = $item['scores'];
    526590                        }
     591                        // query in foreach but is limited by the number of scores that can be retrieve through the request, it depends on the user navigating so should be only tens of scores
    527592                        $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET scores = %s WHERE hash = %s", Utils::format_json_encode($toUpdate), $hash));
    528593                    }
     
    551616        }
    552617
    553         if (count($activeUrls) > 0) {
    554             // Update every active state
    555             // This is done in a single query to allow having a lot of update of pages without doing a lot of query
    556             // First enable active page
    557             $activation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
    558 
    559             // Then disable page not in the array
    560             $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
    561 
    562             // Clean up in case too much url are active (shouldn't happened unless fraudulent call)
    563             $userAccount = $this->getAccount();
    564             if (isset($userAccount) && isset($userAccount['features']) && isset($userAccount['features']['maxPages'])) {
    565                 $maxPagesAllowed = $userAccount['features']['maxPages'];
    566                 $currentUse = $this->getNumberPagesUsed();
    567                 if (isset($currentUse) && $currentUse > $maxPagesAllowed) {
    568                     // should never be called unless fraud attempt or bug
    569                     // clean up active pages based on lastRequest, except for home url
    570                     // get urls to keep active
    571                     $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp WHERE maxActive >= 1 ORDER BY maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
    572                     // First enable active page
    573                     $activation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
    574                     // Then disable page not in the array
    575                     $deactivation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
    576                     $activation = $activation !== false && $activation2 !== false;
    577                     $deactivation = $deactivation !== false && $deactivation2 !== false;
    578                 }
    579             }
    580 
    581             if ($activation === false || $deactivation === false) {
    582                 $this->setFormView('error');
    583             }
    584         } else {
    585             // no active pages wanted, disable every pages
    586             // should never be called due to at least home url
    587             $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0"));
    588 
    589             if ($deactivation === false) {
    590                 $this->setFormView('error');
     618        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     619            if (count($activeUrls) > 0) {
     620                // Update every active state
     621                // This is done in a single query to allow having a lot of update of pages without doing a lot of query
     622                // First enable active page
     623                $activation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
     624
     625                // Then disable page not in the array
     626                $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
     627
     628                // Clean up in case too much url are active (shouldn't happened unless fraudulent call)
     629                $userAccount = $this->getAccount();
     630                if (isset($userAccount) && isset($userAccount['features']) && isset($userAccount['features']['maxPages'])) {
     631                    $maxPagesAllowed = $userAccount['features']['maxPages'];
     632                    $currentUse = $this->getNumberPagesUsed();
     633                    if (isset($currentUse) && $currentUse > $maxPagesAllowed) {
     634                        // should never be called unless fraud attempt or bug
     635                        // clean up active pages based on lastRequest, except for home url
     636                        // get urls to keep active
     637                        $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp WHERE maxActive >= 1 ORDER BY maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
     638                        // First enable active page
     639                        $activation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
     640                        // Then disable page not in the array
     641                        $deactivation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
     642                        $activation = $activation !== false && $activation2 !== false;
     643                        $deactivation = $deactivation !== false && $deactivation2 !== false;
     644                    }
     645                }
     646
     647                if ($activation === false || $deactivation === false) {
     648                    $this->setFormView('error');
     649                }
     650            } else {
     651                // no active pages wanted, disable every pages
     652                // should never be called due to at least home url
     653                $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0"));
     654
     655                if ($deactivation === false) {
     656                    $this->setFormView('error');
     657                }
    591658            }
    592659        }
     
    683750            // avoid getting cache value to avoid loading every cache of the website in ram
    684751            // prioritize by newest url by default
    685             if ($orderBy === 'url') {
    686                 $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration FROM {$wpdb->wpblast_sitemap} ORDER BY CHAR_LENGTH(url) ASC", ARRAY_A);
    687             } else if ($orderBy === 'active') {
    688                 // hashVariables used for cache section in admin to have details on a row
    689                 // request used by admin settings page and have specific fields / ! \
    690                 $sitemap = $wpdb->get_results("SELECT active, hash, hashVariables, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY active DESC, nbRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
    691             } else {
    692                 // send scores to wp-blast.com so that the server can know the scores saved in database by the plugin
    693                 $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     752            if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     753                if ($orderBy === 'url') {
     754                    $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration FROM {$wpdb->wpblast_sitemap} ORDER BY CHAR_LENGTH(url) ASC", ARRAY_A);
     755                } else if ($orderBy === 'active') {
     756                    // hashVariables used for cache section in admin to have details on a row
     757                    // request used by admin settings page and have specific fields / ! \
     758                    $sitemap = $wpdb->get_results("SELECT active, hash, hashVariables, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY active DESC, nbRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     759                } else {
     760                    // send scores to wp-blast.com so that the server can know the scores saved in database by the plugin
     761                    $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     762                }
    694763            }
    695764
     
    706775    {
    707776        global $wpdb;
    708         $urlUntrailingSlashed = untrailingslashit($url);
    709         $nb = $wpdb->get_var($wpdb->prepare("SELECT MAX(active) AS active FROM {$wpdb->wpblast_sitemap} WHERE (url = %s OR url = CONCAT(%s, '/')) GROUP BY REPLACE(url, %s, '')", [$urlUntrailingSlashed, $urlUntrailingSlashed, '?' . PageRender::WPBLAST_CRAWLER]));
    710         $nb = intval($nb);
    711         if ($nb >= 1) {
    712             return true;
    713         } else {
     777        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     778            $urlUntrailingSlashed = untrailingslashit($url);
     779            $nb = $wpdb->get_var($wpdb->prepare("SELECT MAX(active) AS active FROM {$wpdb->wpblast_sitemap} WHERE (url = %s OR url = CONCAT(%s, '/')) GROUP BY REPLACE(url, %s, '')", [$urlUntrailingSlashed, $urlUntrailingSlashed, '?' . PageRender::WPBLAST_CRAWLER]));
     780            $nb = intval($nb);
     781            if ($nb >= 1) {
     782                return true;
     783            } else {
     784                return false;
     785            }
     786        }
     787        else {
    714788            return false;
    715789        }
     
    722796        if (isset($hash)) {
    723797            if (!isset($this->sitemapItems[$hash])) {
    724                 $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]), ARRAY_A);
    725                 if (isset($item)) {
    726                     $this->sitemapItems[$hash] = $item;
    727                 } else {
     798                if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     799                    $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]), ARRAY_A);
     800                    if (isset($item)) {
     801                        $this->sitemapItems[$hash] = $item;
     802                    } else {
     803                        return null;
     804                    }
     805                }
     806                else {
    728807                    return null;
    729808                }
     
    738817    {
    739818        global $wpdb;
    740 
    741         if (isset($hash)) {
     819        if (isset($hash) && $this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    742820            $itemId = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]));
    743821
     
    825903        if (isset($_GET[self::WPBLAST_PURGE_CACHE])) {
    826904            unset($_GET[self::WPBLAST_PURGE_CACHE]);
    827             $this->purgeCache();
     905            do_action('wpblast_purge_cache');
    828906            echo '<div>
    829907  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Cache has been cleared', 'wpblast') . '</div>
     
    833911        if (isset($_GET[self::WPBLAST_PURGE_PLUGIN_CACHE])) {
    834912            unset($_GET[self::WPBLAST_PURGE_PLUGIN_CACHE]);
    835             $this->purgePluginCache(true);
     913            do_action('wpblast_purge_plugin_cache');
    836914            echo '<div>
    837915  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Cache has been cleared', 'wpblast') . '</div>
     
    841919        if (isset($_GET[self::WPBLAST_PURGE_SITEMAP])) {
    842920            unset($_GET[self::WPBLAST_PURGE_SITEMAP]);
    843             $this->purgeSitemap();
     921            do_action('wpblast_purge_sitemap');
    844922            echo '<div>
    845923  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Sitemap has been cleared', 'wpblast') . '</div>
     
    849927        if (isset($_GET[self::WPBLAST_PURGE_PAGES_SCORES])) {
    850928            unset($_GET[self::WPBLAST_PURGE_PAGES_SCORES]);
    851             $this->purgePagesScores();
     929            do_action('wpblast_purge_pages_scores');
    852930            echo '<div>
    853931  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Pages scores has been cleared', 'wpblast') . '</div>
     
    12021280                'name' => 'max_cache_items',
    12031281                'label' => __('Maximum cache items', 'wpblast'),
    1204                 'desc' => __('This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 2000.', 'wpblast'),
     1282                'desc' => __('This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 10000.', 'wpblast'),
    12051283                'type' => 'number',
    12061284                'default' => $this->maxCacheItemsCrawlers,
     
    12091287                'name' => 'max_sitemap_items',
    12101288                'label' => __('Maximum sitemap items', 'wpblast'),
    1211                 'desc' => __('This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 6000.', 'wpblast'),
     1289                'desc' => __('This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 20000.', 'wpblast'),
    12121290                'type' => 'number',
    12131291                'default' => $this->maxSitemapItems,
     
    15911669        global $wpdb;
    15921670
    1593         if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    1594             // Get cache items to delete: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
    1595             // Limit range is bigint unsigned max value
    1596             $idsToDelete = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxSitemapItems()]));
    1597 
    1598             // Get items to clear: use this in two steps to avoid using nested query that could create an incompatibility
    1599             if (count($idsToDelete) > 0) {
    1600                 $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE id IN (" . implode(', ', array_fill(0, count($idsToDelete), '%s')) . ')', $idsToDelete));
    1601             }
    1602 
    1603             // Get cache items to keep: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
    1604             // Limit range is bigint unsigned max value
    1605             $idsToUpdate = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxCacheItemsCrawlers()]));
    1606 
    1607             // Clean cache value
    1608             if (count($idsToUpdate) > 0) {
    1609                 $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET cache = '', cacheExpiration = 0, lastGen = NULL WHERE id IN (" . implode(', ', array_fill(0, count($idsToUpdate), '%s')) . ')', $idsToUpdate));
    1610             }
     1671        $purgeExceededItemsCacheTimestamp = get_transient(self::PLUGIN_CACHE_PREFIX . '_purgeExceededItemsCacheTimestamp');
     1672        // Rate limit calls to this method to avoid overloading the server
     1673        if (!$purgeExceededItemsCacheTimestamp || ($purgeExceededItemsCacheTimestamp + $this->purgeExceededItemsCacheRateLimit < time())) {
     1674            if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     1675                // Get cache items to delete: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
     1676                // Limit range is bigint unsigned max value
     1677                $idsToDelete = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxSitemapItems()]));
     1678   
     1679                // Get items to clear: use this in two steps to avoid using nested query that could create an incompatibility
     1680                if (count($idsToDelete) > 0) {
     1681                    $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE id IN (" . implode(', ', array_fill(0, count($idsToDelete), '%s')) . ')', $idsToDelete));
     1682                }
     1683   
     1684                // Get cache items to keep: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
     1685                // Limit range is bigint unsigned max value
     1686                $idsToUpdate = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxCacheItemsCrawlers()]));
     1687   
     1688                // Clean cache value
     1689                if (count($idsToUpdate) > 0) {
     1690                    $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET cache = '', cacheExpiration = 0, lastGen = NULL WHERE id IN (" . implode(', ', array_fill(0, count($idsToUpdate), '%s')) . ')', $idsToUpdate));
     1691                }
     1692            }
     1693
     1694            $data = time();
     1695            set_transient(self::PLUGIN_CACHE_PREFIX . '_purgeExceededItemsCacheTimestamp', $data, 60 * 60 * 24 * 7); // transient is kept a week
    16111696        }
    16121697    }
     
    16151700    {
    16161701        global $wpdb;
     1702
     1703        $cleanExpiredCacheTimestamp = get_transient(self::PLUGIN_CACHE_PREFIX . '_cleanExpiredCacheTimestamp');
     1704        // Rate limit calls to this method to avoid overloading the server
     1705        if (!$cleanExpiredCacheTimestamp || ($cleanExpiredCacheTimestamp + $this->cleanExpiredCacheRateLimit < time())) {
    16171706
    16181707        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     
    16221711            // Remove items that have not been requested for a long time: this is a big clean up to avoid the table getting bigger and bigger with no legitimate content
    16231712            $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE (lastRequest IS NOT NULL AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(lastRequest) >= %d) OR (lastRequest IS NULL AND dateAdd IS NOT NULL AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(dateAdd) >= %d)", [$this->getCacheItemGarbageExpiration(), $this->getCacheItemGarbageExpiration()]));
     1713        }
     1714
     1715        $data = time();
     1716            set_transient(self::PLUGIN_CACHE_PREFIX . '_cleanExpiredCacheTimestamp', $data, 60 * 60 * 24 * 7); // transient is kept a week
    16241717        }
    16251718    }
  • wpblast/trunk/changelog.txt

    r2830275 r2852021  
    11== Changelog ==
     2= 1.8.5 =
     3Release Date: December 13th, 2022
     4
     5- Improve performance on large websites
     6- Improve advanced-cache updates for nitropack and wp rocket
     7- Improve mu-plugins updates for nitropack
     8
    29= 1.8.4 =
    310Release Date: December 7th, 2022
  • wpblast/trunk/globals.php

    r2781302 r2852021  
    44use Smartfire\Wordpress\WPBlast\Settings;
    55
    6 if (!defined('WPBLAST_PLUGIN_DIR')) {
    7     define('WPBLAST_PLUGIN_DIR', __DIR__ . '/../../..');
     6// This is to allow to use require instead of require_once but still have the file loaded once
     7// This happened because when the plugin is activated by wordpress, the variables scope is empty but still the file has been loaded
     8// This happened when activating the plugin after loading was left in the advanced-cache file
     9if (!isset($wpblast_globals_loaded)) {
     10
     11    if (!defined('WPBLAST_PLUGIN_DIR')) {
     12        define('WPBLAST_PLUGIN_DIR', __DIR__ . '/../../..');
     13    }
     14
     15    $autoloader = require('autoload.php');
     16    $autoloader('Smartfire\\Wordpress\\WPBlast\\', __DIR__ . '/src/Smartfire/Wordpress/WPBlast/');
     17
     18    $smartfire_wpblast_config = new Config(['config_dir_path' => WP_CONTENT_DIR . '/wpblast-config']);
     19    $smartfire_wpblast_settings = new Settings();
     20
     21    $wpblast_globals_loaded = true;
    822}
    9 
    10 $autoloader = require('autoload.php');
    11 $autoloader('Smartfire\\Wordpress\\WPBlast\\', __DIR__ . '/src/Smartfire/Wordpress/WPBlast/');
    12 
    13 $smartfire_wpblast_config = new Config(['config_dir_path' => WP_CONTENT_DIR . '/wpblast-config']);
    14 $smartfire_wpblast_settings = new Settings();
  • wpblast/trunk/inc/generate-config-functions.php

    r2807381 r2852021  
    2222}
    2323
    24 add_action('wpblast_activate', function () {
    25     add_action('admin_init', 'wpblast_generate_config_file');
     24add_action('wpblast_plugin_updated', function () {
     25    add_action('init', 'wpblast_generate_config_file');
    2626});
    2727add_action('wpblast_updated_crawler_list', 'wpblast_generate_config_file');
    2828add_action('wpblast_updated_options', 'wpblast_generate_config_file');
    2929
    30 add_action('wpblast_deactivate', function () {
     30add_action('wpblast_deactivated', function () {
    3131    global $smartfire_wpblast_config;
    3232    $path = $smartfire_wpblast_config->get_config_file_path()['path'];
  • wpblast/trunk/inc/mu-plugins-functions.php

    r2830275 r2852021  
    11<?php
     2
     3defined('ABSPATH') || exit;
    24
    35function wpblast_display_error($message)
    46{
    57    $class = 'notice notice-error';
     8    printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), esc_html($message));
     9}
     10
     11function wpblast_display_warning($message)
     12{
     13    $class = 'notice notice-warning';
    614    printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), esc_html($message));
    715}
     
    3947function wpblast_require_mu_plugin($data)
    4048{
    41     // Installer
    42     add_action('wpblast_activate', function () use ($data) {
     49    // In case of update
     50    add_action('wpblast_plugin_updated', function () use ($data) {
    4351        wpblast_install_mu_plugin($data);
    4452    });
    4553
    46     // Update checker
     54    // In case a difference exist between installed version and current version or in case the mu-plugin triggered an error
    4755    add_action('admin_init', function () use ($data) {
    4856        if (isset($data['slug'])) {
    49             if (!defined('WPBLAST_MU_PLUGIN-' . $data['slug']) || !defined('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug']) || WPBLAST_PLUGIN_VERSION !== constant('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug'])) {
     57            if (defined('WPBLAST_MU_PLUGIN_ERROR') || !defined('WPBLAST_MU_PLUGIN-' . $data['slug']) || !defined('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug']) || WPBLAST_PLUGIN_VERSION !== constant('WPBLAST_MU_PLUGIN_VERSION-' . $data['slug'])) {
    5058                wpblast_install_mu_plugin($data);
    5159            }
     
    6876        $codeHeader = isset($data['code']) && isset($data['code']['header']) ? $data['code']['header'] : '';
    6977        $codeBody = isset($data['code']) && isset($data['code']['body']) ? $data['code']['body'] : '';
     78        $codeDeactivationCondition = '';
     79        if (isset($data['code']) && isset($data['code']['deactivationCondition'])) {
     80            $codeDeactivationCondition = '
     81add_action(\'admin_init\', function () {
     82    if(' . $data['code']['deactivationCondition'] . ') {
     83        wpblast_uninstall_mu_plugin([
     84            \'slug\' => \'' . $slug . '\'
     85        ]);
     86    }
     87});';
     88        }
    7089        wpblast_require_mu_plugin_dir(); // create mu-plugins directory if needed
    7190        $muPluginFile = realpath(WP_CONTENT_DIR) . '/mu-plugins/' . $slug . '.php';
    7291        $code = '<?php
    7392/*
    74 Plugin Name:  ' . $name . '
    75 Plugin URI:   https://www.wp-blast.com
    76 Description:  ' . $description . '
    77 Version:      ' . $version . '
    78 Author: WP Blast
    79 License: Apache 2.0
    80 License URI: http://www.apache.org/licenses/LICENSE-2.0
     93' . 'Plugin Name' . ':  ' . $name . '
     94' . 'Plugin URI' . ':   https://www.wp-blast.com
     95' . 'Description' . ':  ' . $description . '
     96' . 'Version' . ':      ' . $version . '
     97' . 'Author' . ': WP Blast
     98' . 'License' . ': Apache 2.0
     99' . 'License URI' . ': http://www.apache.org/licenses/LICENSE-2.0
    81100*/
    82101// THIS FILE HAS BEEN AUTO-GENERATED
     
    87106
    88107defined( \'ABSPATH\' ) || exit;
     108
     109// WPBLAST-DEACTIVATION-HOOK-START
     110' . $codeDeactivationCondition . '
     111// WPBLAST-DEACTIVATION-HOOK-END
    89112
    90113if(!defined(\'WPBLAST_MU_PLUGIN-' . $slug . '\')) {
  • wpblast/trunk/inc/rest-functions.php

    r2807381 r2852021  
    6868function wpblast_generate_cache_item_action()
    6969{
     70    global $smartfire_wpblast_settings;
    7071    if (isset($_GET['wpblast_nonce']) && isset($_GET['url']) && $_GET['url'] !== '') {
    7172        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    7273        if (wp_verify_nonce($nonce, 'wp_rest')) {
    7374            $url = urldecode(esc_url_raw(wp_unslash($_GET['url'])));
    74             $settings = new Settings();
    75             $settings->init();
    7675            $response = wp_remote_get($url, [
    77                 'user-agent' => $settings->getCrawlerCacheGen(), // use WP Blast Crawler to force cache gen
     76                'user-agent' => $smartfire_wpblast_settings->getCrawlerCacheGen(), // use WP Blast Crawler to force cache gen
    7877                'headers' => [
    7978                    'WPBLAST-FORCE-GENERATION' => '1',
    80                     'WPBLAST-TOKEN' => base64_encode($settings->getUsername() . ':' . $settings->getPassword()),
     79                    'WPBLAST-TOKEN' => base64_encode($smartfire_wpblast_settings->getUsername() . ':' . $smartfire_wpblast_settings->getPassword()),
    8180                ],
    82                 'timeout'     => $settings->getTimeout(),
     81                'timeout'     => $smartfire_wpblast_settings->getTimeout(),
    8382            ]);
    8483            $httpCode = wp_remote_retrieve_response_code($response);
     
    104103function wpblast_update_plugin_data()
    105104{
     105    global $smartfire_wpblast_settings;
    106106    if (isset($_GET['wpblast_nonce'])) {
    107107        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    108108        if (wp_verify_nonce($nonce, 'wp_rest')) {
    109             $settings = new Settings();
    110             $settings->init();
    111             $settings->getPluginData(true); // force update to wp blast
     109            $smartfire_wpblast_settings->getPluginData(true); // force update to wp blast
    112110            return new WP_REST_Response(
    113111                [
     
    126124function wpblast_update_user_account()
    127125{
     126    global $smartfire_wpblast_settings;
    128127    if (isset($_GET['wpblast_nonce'])) {
    129128        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    130129        if (wp_verify_nonce($nonce, 'wp_rest')) {
    131             $settings = new Settings();
    132             $settings->init();
    133             $settings->getAccount(true); // force update of user account
     130            $smartfire_wpblast_settings->getAccount(true); // force update of user account
    134131            return new WP_REST_Response(
    135132                [
     
    148145function wpblast_update_crawler_list()
    149146{
     147    global $smartfire_wpblast_settings;
    150148    if (isset($_GET['wpblast_nonce'])) {
    151149        $nonce = sanitize_text_field(wp_unslash($_GET['wpblast_nonce']));
    152150        if (wp_verify_nonce($nonce, 'wp_rest')) {
    153             $settings = new Settings();
    154             $settings->init();
    155             $settings->getCrawlerAutoRegexp(true); // force update of crawler list
     151            $smartfire_wpblast_settings->getCrawlerAutoRegexp(true); // force update of crawler list
    156152            return new WP_REST_Response(
    157153                [
     
    170166function wpblast_get_status()
    171167{
     168    global $smartfire_wpblast_settings;
    172169    header('Content-Type: application/javascript');
    173170    // Call WP Blast server for status
    174171
    175     $settings = new Settings();
    176     $settings->init();
    177 
    178     $response = wp_remote_get($settings->getWebsite() . '/?method=getWpBlastStatus&domain=' . urlencode($settings->getUsername()) . '&plugin_token=' . $settings->getPassword(), [
     172    $response = wp_remote_get($smartfire_wpblast_settings->getWebsite() . '/?method=getWpBlastStatus&domain=' . urlencode($smartfire_wpblast_settings->getUsername()) . '&plugin_token=' . $smartfire_wpblast_settings->getPassword(), [
    179173        'user-agent' => Settings::WPBLAST_UA_PLUGIN,
    180174        'timeout' => 15,
     
    201195function wpblast_get_sitemap($request)
    202196{
     197    global $smartfire_wpblast_settings;
    203198    if (isset($_GET['wpblast_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['wpblast_nonce'])), 'wp_rest')) {
    204         $settings = new Settings();
    205         $settings->init();
    206199
    207200        if (isset($request['items'])) {
    208201            $items = $request['items'];
    209             $settings->updateSitemapScores($items);
    210         }
    211 
    212         $sitemap = $settings->getWebsiteSitemap('active');
    213 
    214         $settings->cleanExpiredCache(); // delete expired cache item
     202            $smartfire_wpblast_settings->updateSitemapScores($items);
     203        }
     204
     205        $sitemap = $smartfire_wpblast_settings->getWebsiteSitemap('active');
     206
     207        $smartfire_wpblast_settings->cleanExpiredCache(); // delete expired cache item
    215208
    216209        $response = [
     
    231224function wpblast_update_active_pages($request)
    232225{
     226    global $smartfire_wpblast_settings;
    233227    if (isset($_GET['wpblast_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['wpblast_nonce'])), 'wp_rest')) {
    234         $settings = new Settings();
    235         $settings->init();
    236228
    237229        if (isset($request['activeUrls'])) {
    238230            $activeUrls = $request['activeUrls'];
    239             $settings->updateActivePages($activeUrls);
    240         }
    241 
    242         $sitemap = $settings->getWebsiteSitemap('active');
    243 
    244         $settings->cleanExpiredCache(); // delete expired cache item
     231            $smartfire_wpblast_settings->updateActivePages($activeUrls);
     232        }
     233
     234        $sitemap = $smartfire_wpblast_settings->getWebsiteSitemap('active');
     235
     236        $smartfire_wpblast_settings->cleanExpiredCache(); // delete expired cache item
    245237
    246238        $response = [
  • wpblast/trunk/inc/third-party/advanced-cache.php

    r2830275 r2852021  
    55defined('ABSPATH') || exit;
    66
    7 require_once __DIR__ . '/../../globals.php';
    8 
    9 if (!defined('WPBLAST_ADVANCED_CACHE')) {
    10     define('WPBLAST_ADVANCED_CACHE', true);
    11 }
     7require __DIR__ . '/../../globals.php';
    128
    139if (Bootstrap::should_blast()) {
  • wpblast/trunk/inc/third-party/hummingbird-performance/hummingbird-performance-functions.php

    r2807419 r2852021  
    3131    }
    3232
    33     add_action('wpblast_activate', 'wpblast_wphb_clear_cache');
    34     add_action('wpblast_deactivate', 'wpblast_wphb_clear_cache');
     33    add_action('wpblast_plugin_updated', 'wpblast_wphb_clear_cache');
     34    add_action('wpblast_deactivated', 'wpblast_wphb_clear_cache');
     35    add_action('wpblast_purge_cache_third_party', 'wpblast_wphb_clear_cache');
    3536    add_action('wpblast_updated_crawler_list', 'wpblast_wphb_clear_cache');
    3637    add_action('wpblast_updated_options', 'wpblast_wphb_clear_cache');
  • wpblast/trunk/inc/third-party/index.php

    r2830275 r2852021  
    44
    55require_once 'hummingbird-performance/hummingbird-performance-functions.php';
     6require_once 'litespeed-cache/litespeed-cache-functions.php';
    67require_once 'w3-total-cache/w3-total-cache-functions.php';
    78require_once 'wp-rocket/wp-rocket-functions.php';
  • wpblast/trunk/inc/third-party/nitropack/nitropack-functions.php

    r2830275 r2852021  
    1515        'name' => 'WP Blast Addon - Nitropack',
    1616        'code' => [
    17             'body' => "
     17            'deactivationCondition' => "!is_plugin_active('nitropack/main.php')",
     18            'body' => '
    1819// Even if advanced-cache is not used, nitropack needs this filter added prior its execution
    1920// This will be needed for both usecase: with or without advanced-cache with nitropack
    20 require_once '" . __DIR__ . "/../../../globals.php';
    21 function wpblast_nitropack_can_serve_cache() {
    22     return !Smartfire\Wordpress\WPBlast\Bootstrap::should_blast();
     21$wpblast_globals_file = "' . __DIR__ . '/../../../globals.php' . '";
     22$wpblast_abspath = "' . ABSPATH . '";
     23
     24// Fail proof check that the WP installation hasnt been moved to another server or other folder
     25// In case path is wrong, the addon will not be detected and therefore will be installed again
     26if (file_exists($wpblast_globals_file) && ABSPATH == $wpblast_abspath) {
     27    require $wpblast_globals_file;
     28    function wpblast_nitropack_can_serve_cache() {
     29        return !Smartfire\Wordpress\WPBlast\Bootstrap::should_blast();
     30    }
     31    add_filter("nitropack_can_serve_cache", "wpblast_nitropack_can_serve_cache");
    2332}
    24 add_filter('nitropack_can_serve_cache', 'wpblast_nitropack_can_serve_cache');",
     33else {
     34    // will recreate the mu-plugin addon in case of error
     35    if(!defined("WPBLAST_MU_PLUGIN_ERROR")) {
     36        define("WPBLAST_MU_PLUGIN_ERROR", true);
     37        return;
     38    }
     39}',
    2540        ],
    2641    ]);
     
    3752    }
    3853
    39     function wpblast_nitropack_advanced_cache_file($content)
    40     {
    41         // Only insert addon in case there is a content and that addon is not existent, otherwise remove advanced cache to trigger re-generation
    42         if ($content !== '' && strpos($content, 'WPBLAST_ADVANCED_CACHE_VERSION') === false) {
    43             $content = explode('if (defined("NITROPACK_VERSION") && defined("NITROPACK_ADVANCED_CACHE_VERSION") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {', $content);
    44             $start = $content[0];
    45             $nitropack = $content[1];
    46             return $start . "
    47 // WP-BLAST ADDON START //
    48 if(!defined('WPBLAST_ADVANCED_CACHE_VERSION')) {
    49     define( 'WPBLAST_ADVANCED_CACHE_VERSION', '" . WPBLAST_PLUGIN_VERSION . "');
    50 }
    51 
    52 include_once \"" . __DIR__ . '/../advanced-cache.php' . "\";
    53 
    54 if(defined('WPBLAST_SKIP_ADVANCED_CACHE') && WPBLAST_SKIP_ADVANCED_CACHE) {
    55     return;
    56 }
    57 // WP-BLAST ADDON END //
    58 if (defined(\"NITROPACK_VERSION\") && defined(\"NITROPACK_ADVANCED_CACHE_VERSION\") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {
    59 " . $nitropack . '
    60 
    61 ';
    62         } else {
    63             // Removing advanced cache will trigger re-write by nitropack that will then allow for a rewrite of the wpblast addon
    64             return '';
    65         }
    66     }
    67     // As we are checking that a nitropack defined variable in advanced cache is present, no writing error should happen
    68     // In case of upgrade of nitropack, our variable will miss and we'll update the advanced cache file again
    69     // In case of upgrade of wpblast, a new version will be triggered that will force to remove the advanced cache file
    70     // Nitropack will recreates it and we'll add again the addon
    71     add_filter('wpblast_nitropack_advanced_cache_file', 'wpblast_nitropack_advanced_cache_file');
    72 
    73     function wpblast_nitropack_write_advanced_cache_file()
    74     {
    75         $advancedCacheFile = realpath(WP_CONTENT_DIR) . '/advanced-cache.php';
    76         $advancedCacheFileContent = @file_get_contents($advancedCacheFile);
    77         $newContent = apply_filters('wpblast_nitropack_advanced_cache_file', $advancedCacheFileContent);
    78         if (WP_DEBUG) {
    79             return file_put_contents($advancedCacheFile, $newContent);
    80         } else {
    81             return @file_put_contents($advancedCacheFile, $newContent);
    82         }
    83     }
    84 
    85     function wpblast_nitropack_remove_advanced_cache_file()
    86     {
    87         // Reset advanced-cache file so that plugin can generate a new clean one
    88         $advancedCacheFile = realpath(WP_CONTENT_DIR) . '/advanced-cache.php';
    89         if (WP_DEBUG) {
    90             return file_put_contents($advancedCacheFile, '');
    91         } else {
    92             return @file_put_contents($advancedCacheFile, '');
    93         }
    94     }
    95 
    9654    // we don't do anything if nitropack advanced cache is not active
    9755    if (function_exists('nitropack_has_advanced_cache') && nitropack_has_advanced_cache()) {
    98         if (!defined('WPBLAST_ADVANCED_CACHE') || !defined('WPBLAST_ADVANCED_CACHE_VERSION') || WPBLAST_PLUGIN_VERSION !== WPBLAST_ADVANCED_CACHE_VERSION) {
    99             // We rewrite advanced cache in case we detect a NITROPACK_ADVANCED_CACHE (this means the advanced cache is active) and we don't have a WPBLAST_ADVANCED_CACHE_VERSION, this either mean it's a first install or that the plugin nitropack has been updated or as changed the advanced-cache file
    100             add_action('plugins_loaded', 'wpblast_nitropack_write_advanced_cache_file');
    101         }
     56        wpblast_require_advanced_cache([
     57            'slug' => 'wpblast-nitropack-addon',
     58            'delimiter' => 'if (defined("NITROPACK_VERSION") && defined("NITROPACK_ADVANCED_CACHE_VERSION") && NITROPACK_VERSION == NITROPACK_ADVANCED_CACHE_VERSION && nitropack_is_dropin_cache_allowed()) {',
     59        ]);
    10260    } else if (function_exists('nitropack_has_advanced_cache') && !nitropack_has_advanced_cache()) {
    103         // If we are installed but nitrocache has disabled the advanced_cache, we should uninstall our advanced-cache addon
    104         if (defined('WPBLAST_ADVANCED_CACHE') || defined('WPBLAST_ADVANCED_CACHE_VERSION')) {
    105             add_action('plugins_loaded', 'wpblast_nitropack_remove_advanced_cache_file');
    106         }
     61        // force uninstall of advanced-cache even if cache plugin is being let active
     62        wpblast_uninstall_advanced_cache([
     63            'slug' => 'wpblast-nitropack-addon',
     64        ]);
    10765    }
    10866
     
    11270        do_action('nitropack_execute_purge_all');
    11371    }
    114 
    11572    add_action('wpblast_purge_cache_third_party', 'wpblast_nitro_clear_cache');
    11673
    117     add_action('wpblast_deactivate', function () {
    118         wpblast_nitropack_remove_advanced_cache_file();
    119     });
     74    add_action('wpblast_plugin_updated', function($oldVersion, $newVersion) {
     75        // Compatibility upgrader before we used markers to replace our addons
     76        // This will remove advanced cache, so that nitropack can add it again and we'll add then our addon
     77        try {
     78            if ($oldVersion === false || $oldVersion === '1.8.4') {
     79                wpblast_clear_advanced_cache_file();
     80            }
     81        }
     82        catch (\Throwable $e) {} // fail proof
     83        catch (\Exception $e) {} // fail proof
     84    }, 10, 2);
    12085}
  • wpblast/trunk/inc/third-party/w3-total-cache/w3-total-cache-functions.php

    r2807419 r2852021  
    3737    }
    3838
    39     add_action('wpblast_activate', 'wpblast_w3tc_clear_cache');
    40     add_action('wpblast_deactivate', 'wpblast_w3tc_clear_cache');
     39    add_action('wpblast_plugin_updated', 'wpblast_w3tc_clear_cache');
     40    add_action('wpblast_purge_cache_third_party', 'wpblast_w3tc_clear_cache');
     41    add_action('wpblast_deactivated', 'wpblast_w3tc_clear_cache');
    4142    add_action('wpblast_updated_crawler_list', 'wpblast_w3tc_clear_cache');
    4243    add_action('wpblast_updated_options', 'wpblast_w3tc_clear_cache');
  • wpblast/trunk/inc/third-party/wp-fastest-cache/wp-fastest-cache-functions.php

    r2830275 r2852021  
    11<?php
    22
     3use Smartfire\Wordpress\WPBlast\Utils as Utils;
     4
    35defined('ABSPATH') || exit;
    46
     
    79if (is_plugin_active('wp-fastest-cache/wpFastestCache.php')) {
    810
    9     // We are forced to use template_redirect as the plugin would take precedence otherwise
    10     add_action('template_redirect', 'wpblast_actions_before_start_wpfc');
    11     function wpblast_actions_before_start_wpfc()
    12     {
    13         // Avoid WPSC to cache the page
    14         if (!defined('DONOTCACHEPAGE')) {
    15             define('DONOTCACHEPAGE', true);
    16         }
     11    wpblast_require_mu_plugin([
     12        'slug' => 'wpblast-wpfc-addon',
     13        'name' => 'WP Blast Addon - WP Fastest Cache',
     14        'code' => [
     15            'deactivationCondition' => "!is_plugin_active('wp-fastest-cache/wpFastestCache.php')",
     16            'body' => '
     17// Use this mu-plugin to inject a cookie in the request that will make wpfc ignore the request in case we blast the request
     18$wpblast_globals_file = "' . __DIR__ . '/../../../globals.php' . '";
     19$wpblast_abspath = "' . ABSPATH . '";
     20
     21// Fail proof check that the WP installation hasnt been moved to another server or other folder
     22// In case path is wrong, the addon will not be detected and therefore will be installed again
     23if (file_exists($wpblast_globals_file) && ABSPATH == $wpblast_abspath) {
     24    require $wpblast_globals_file;
     25    if (Smartfire\Wordpress\WPBlast\Bootstrap::should_blast()) {
     26        $_SERVER[\'HTTP_COOKIE\'] = "wpblast=1; " . (isset($_SERVER[\'HTTP_COOKIE\']) ? $_SERVER[\'HTTP_COOKIE\'] : "");
     27    }
     28}
     29else {
     30    // will recreate the mu-plugin addon in case of error
     31    if(!defined("WPBLAST_MU_PLUGIN_ERROR")) {
     32        define("WPBLAST_MU_PLUGIN_ERROR", true);
     33        return;
     34    }
     35}',
     36        ],
     37    ]);
     38
     39    function wpblast_wpfc_remove_exclude_rules()
     40    {
     41        remove_filter('pre_update_option_WpFastestCacheExclude', 'wpblast_wpfc_inject_option_WpFastestCacheExclude'); // remove filter so our plugin wouldn't add the rule again
     42        remove_action('delete_option_WpFastestCacheExclude', 'wpblast_wpfc_add_exclude_rules'); // remove filter so our plugin wouldn't add the rule again
     43        $rules_json = get_option('WpFastestCacheExclude');
     44        if (isset($rules_json) && $rules_json !== false && $rules_json !== '') {
     45            $parsedContent = json_decode($rules_json);
     46            $uaIndex = [];
     47            $cookieIndex = [];
     48            foreach ($parsedContent as $key => $value) {
     49                if (isset($value->type) && $value->type === 'useragent' && isset($value->content) && strpos($value->content, 'WP-BLAST') !== false) {
     50                    array_push($uaIndex, $key);
     51                }
     52                if (isset($value->type) && $value->type === 'cookie' && isset($value->content) && strpos($value->content, 'wpblast') !== false) {
     53                    array_push($cookieIndex, $key);
     54                }
     55            }
     56            // Remove the keys
     57            // This should only have one single key but in case an error happened, this will clean every rules
     58            if (isset($uaIndex)) {
     59                foreach ($uaIndex as $uaIdx) {
     60                    array_splice($parsedContent, $uaIdx, 1);
     61                }
     62            }
     63            if (isset($cookieIndex)) {
     64                foreach ($cookieIndex as $cookieIdx) {
     65                    array_splice($parsedContent, $cookieIdx, 1);
     66                }
     67            }
     68
     69            if (count($parsedContent) > 0) {
     70                update_option('WpFastestCacheExclude', Utils::format_json_encode($parsedContent));
     71            } else {
     72                delete_option('WpFastestCacheExclude');
     73            }
     74        }
     75
     76        // Force update of htaccess on wpfc side
     77        try {
     78            include_once(__DIR__ . '/../../../../wp-fastest-cache/inc/admin.php');
     79            if (class_exists('WpFastestCacheAdmin')) {
     80                $wpfc = new WpFastestCacheAdmin();
     81                // only way of retriggering it is to simulate activation
     82                $options = get_option('WpFastestCache');
     83                if (isset($options) && $options !== false) {
     84                    $post = json_decode($options, true);
     85                    $wpfc->modifyHtaccess($post);
     86                }
     87            }
     88        }
     89        catch (\Throwable $e) {} // fail proof
     90        catch (\Exception $e) {} // fail proof
    1791    }
    1892
     
    2397        do_action('wpfc_clear_all_site_cache');
    2498    }
    25 
    26     add_action('wpblast_activate', 'wpblast_wpfc_clear_cache');
    27     add_action('wpblast_deactivate', 'wpblast_wpfc_clear_cache');
    28     add_action('wpblast_updated_crawler_list', 'wpblast_wpfc_clear_cache');
    29     add_action('wpblast_updated_options', 'wpblast_wpfc_clear_cache');
    30 }
     99    add_action('wpblast_purge_cache_third_party', 'wpblast_wpfc_clear_cache');
     100
     101    function wpblast_wpfc_activate()
     102    {
     103        wpblast_wpfc_add_exclude_rules();
     104    }
     105    add_action('wpblast_plugin_updated', function($oldVersion, $newVersion) {
     106        // Compatibility upgrader to reset possible cache with WP Blast content
     107        try {
     108            if ($oldVersion === false || $oldVersion === '1.8.4') {
     109                wpblast_wpfc_clear_cache();
     110            }
     111        }
     112        catch (\Throwable $e) {} // fail proof
     113        catch (\Exception $e) {} // fail proof
     114        try {
     115            wpblast_wpfc_activate();
     116        }
     117        catch (\Throwable $e) {} // fail proof
     118        catch (\Exception $e) {} // fail proof
     119    }, 10, 2);
     120
     121    add_action('wpblast_updated_crawler_list', 'wpblast_wpfc_add_exclude_rules'); // should update exclude rules
     122    add_action('wpblast_updated_options', 'wpblast_wpfc_add_exclude_rules');
     123
     124    function wpblast_wpfc_deactivated()
     125    {
     126        // should be executed with deactivated to have the plugin being deactivated and no more requests
     127        wpblast_wpfc_remove_exclude_rules();
     128    }
     129    add_action('wpblast_deactivated', 'wpblast_wpfc_deactivated'); // should disable exclude rules and mu-plugin
     130}
     131
     132// Should be added whether the plugin is active or not so that in case wpblast is already enabled and wpfc is activated, we can inject our rules
     133// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid -- WpFastestCacheExclude is the name of the option
     134function wpblast_wpfc_inject_option_WpFastestCacheExclude($content)
     135{
     136    $parsedContent = [];
     137    try {
     138        if (isset($content) && $content !== '') {
     139            $parsedContent = json_decode($content);
     140        }
     141    }
     142    catch (\Throwable $e) {} // fail proof
     143    catch (\Exception $e) {} // fail proof
     144    if (!is_array($parsedContent)) {
     145        $parsedContent = [];
     146    }
     147    $ruleUAExist = false;
     148    $ruleCookieExist = false;
     149    $crawlers = apply_filters('wpblast_crawlers_full', '');
     150    foreach ($parsedContent as $key => $value) {
     151        if (isset($value->type) && $value->type === 'useragent' && isset($value->content) && strpos($value->content, 'WP-BLAST') !== false) {
     152            $ruleUAExist = true;
     153            $parsedContent[$key]->content = '^(' . str_replace([' ', '\\\\ '], '\\ ', $crawlers) . ').*'; // force update with new value
     154            $parsedContent[$key]->editable = false; // re-add editable false, otherwise, when the user save, this property gets stripped
     155        }
     156        if (isset($value->type) && $value->type === 'cookie' && isset($value->content) && strpos($value->content, 'wpblast') !== false) {
     157            $ruleCookieExist = true;
     158            $parsedContent[$key]->content = 'wpblast'; // force update with new value
     159            $parsedContent[$key]->editable = false; // re-add editable false, otherwise, when the user save, this property gets stripped
     160        }
     161    }
     162    if ($ruleUAExist === false) {
     163        if ($crawlers !== '') {
     164            $new_rule = new stdClass();
     165            $new_rule->prefix = 'contain';
     166            $new_rule->content = '^(' . str_replace([' ', '\\\\ '], '\\ ', $crawlers) . ').*';
     167            $new_rule->type = 'useragent';
     168            $new_rule->editable = false;
     169            array_push($parsedContent, $new_rule);
     170        }
     171    }
     172    if ($ruleCookieExist === false) {
     173        $new_rule = new stdClass();
     174        $new_rule->prefix = 'contain';
     175        $new_rule->content = 'wpblast';
     176        $new_rule->type = 'cookie';
     177        $new_rule->editable = false;
     178        array_push($parsedContent, $new_rule);
     179    }
     180
     181    return Utils::format_json_encode($parsedContent);
     182}
     183add_filter('pre_update_option_WpFastestCacheExclude', 'wpblast_wpfc_inject_option_WpFastestCacheExclude');
     184
     185function wpblast_wpfc_add_exclude_rules()
     186{
     187    $rules_json = get_option('WpFastestCacheExclude');
     188    if ($rules_json === false) {
     189        add_option('WpFastestCacheExclude', wpblast_wpfc_inject_option_WpFastestCacheExclude('[]'), '', 'yes'); // add our rules if no option exists
     190    } else {
     191        update_option('WpFastestCacheExclude', $rules_json); // will then trigger hook that will inject our rule
     192    }
     193
     194    // Force update of htaccess on wpfc side
     195    try {
     196        include_once(__DIR__ . '/../../../../wp-fastest-cache/inc/admin.php');
     197        if (class_exists('WpFastestCacheAdmin')) {
     198            $wpfc = new WpFastestCacheAdmin();
     199            // only way of retriggering it is to simulate activation
     200            $options = get_option('WpFastestCache');
     201            if (isset($options) && $options !== false) {
     202                $post = json_decode($options, true);
     203                $wpfc->modifyHtaccess($post);
     204            }
     205        }
     206    }
     207    catch (\Throwable $e) {} // fail proof
     208    catch (\Exception $e) {} // fail proof
     209}
     210add_action('delete_option_WpFastestCacheExclude', 'wpblast_wpfc_add_exclude_rules'); // in case the plugin tries to delete the option force it to stay
     211
     212// Should be check after check of activation of plugin
     213function wpblast_wpfc_activation($plugin)
     214{
     215    if ($plugin == 'wp-fastest-cache/wpFastestCache.php') {
     216        wpblast_wpfc_add_exclude_rules(); // add exclude rules in case of activation of wpfc when wpblast is already active
     217    }
     218}
     219add_action('activated_plugin', 'wpblast_wpfc_activation');
  • wpblast/trunk/inc/third-party/wp-rocket/wp-rocket-functions.php

    r2830275 r2852021  
    1919    function wpblast_rocket_advanced_cache_file($content)
    2020    {
    21         $content = explode("defined( 'ABSPATH' ) || exit;", $content);
    22         $start = $content[0];
    23         $wp_rocket = $content[1];
    24         return $start . "defined( 'ABSPATH' ) || exit;
    25 include \"" . __DIR__ . '/../advanced-cache.php' . "\";
    26 
    27 if(defined('WPBLAST_SKIP_ADVANCED_CACHE') && WPBLAST_SKIP_ADVANCED_CACHE) {
    28     return;
    29 }
    30 " . $wp_rocket . '
    31 
    32 ';
     21        return apply_filters('wpblast_advanced_cache_content', $content, "define( 'WP_ROCKET_ADVANCED_CACHE', true );", 'wpblast-wprocket-addon');
    3322    }
    3423    // As we are hooked on wprocket advanced_cache content, wprocket will be in charge of checking for error in filesystem in case we cannot write the advanced-cache.php file
     24    // in case of error in wprocket advanced cache, it will be recreated and our addon will be added again
    3525    // in case of upgrade, they will recreate advanced-cache.php file and call again this function
    3626    add_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
     27
     28
     29    function wpblast_advanced_cache_content_error()
     30    {
     31        return "
     32        // Trigger constant of wprocket to indicate a problem with advanced-cache
     33        if(!defined('WP_ROCKET_ADVANCED_CACHE_PROBLEM')) {
     34            define( 'WP_ROCKET_ADVANCED_CACHE_PROBLEM', true );
     35            return;
     36        }";
     37    }
     38    add_filter('wpblast_advanced_cache_content_error', 'wpblast_advanced_cache_content_error');
    3739
    3840    /**
     
    7375    }
    7476
    75     add_action('wpblast_activate', function () {
    76         add_action('admin_init', 'wpblast_rocket_refresh');
     77    add_action('wpblast_plugin_updated', function () {
     78        add_action('init', 'wpblast_rocket_refresh');
    7779    });
     80    // advanced-cache should be remove at the start of the deactivation to prevent concurrent requests bugs
    7881    add_action('wpblast_deactivate', function () {
     82        remove_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
     83        remove_filter('rocket_cache_reject_ua', 'wpblast_rocket_user_agent_reject');
     84        wpblast_rocket_refresh();
     85    });
     86    // should clean afterward to clean what could have been added during uninstallation process
     87    add_action('wpblast_deactivated', function () {
    7988        remove_filter('rocket_advanced_cache_file', 'wpblast_rocket_advanced_cache_file');
    8089        remove_filter('rocket_cache_reject_ua', 'wpblast_rocket_user_agent_reject');
  • wpblast/trunk/inc/third-party/wp-super-cache/wp-super-cache-functions.php

    r2807419 r2852021  
    2626    }
    2727
    28     add_action('wpblast_activate', 'wpblast_wpsc_clear_cache');
    29     add_action('wpblast_deactivate', 'wpblast_wpsc_clear_cache');
     28    add_action('wpblast_plugin_updated', 'wpblast_wpsc_clear_cache');
     29    add_action('wpblast_deactivated', 'wpblast_wpsc_clear_cache');
     30    add_action('wpblast_purge_cache_third_party', 'wpblast_wpsc_clear_cache');
    3031    add_action('wpblast_updated_crawler_list', 'wpblast_wpsc_clear_cache');
    3132    add_action('wpblast_updated_options', 'wpblast_wpsc_clear_cache');
  • wpblast/trunk/js/wpblast-settings.js

    r2811232 r2852021  
    277277        var wpBlastSitemapUpdatedItems = [];
    278278        var wpBlastSitemapItemsToUpdateScore = [];
     279        var wpBlastIsLoadingSitemap = false;
    279280        var types = ['raw', 'blast'];
    280281        var devices = ['mobile', 'desktop'];
     
    728729            if (shouldUpdateScores && wpBlastSitemapItemsToUpdateScore.length > 0) {
    729730                // speed up update of scores in case we didn't have updated it
    730                 // Todo: add a lock to avoid having multiple parallel calls to getSitemap while the request isn't finished
    731731                wpBlastGetSitemap();
    732732            }
     
    16211621
    16221622        function wpBlastGetSitemap() {
    1623             // Get sitemap stored in website database
    1624             var dataToSend = {};
    1625             if (wpBlastSitemapItemsToUpdateScore.length > 0) {
    1626                 dataToSend['items'] = wpBlastSitemapItemsToUpdateScore;
    1627                 for (var i = 0; i < wpBlastSitemapItemsToUpdateScore.length; i++) {
    1628                     // mark this hash has updated, this will prevent an update until next reload of the page
    1629                     wpBlastSitemapUpdatedItems.push(
    1630                         wpBlastSitemapItemsToUpdateScore[i].hash +
    1631                             '-' +
    1632                             wpBlastSitemapItemsToUpdateScore[i].type +
    1633                             '-' +
    1634                             wpBlastSitemapItemsToUpdateScore[i].device,
    1635                     );
    1636                 }
    1637             }
    1638             var restUrl = '/wp-json/wpblast/v1/getSitemap?wpblast_nonce=' + wpblast_nonce; // fallback rest url
    1639             if (
    1640                 typeof wpBlastSettings !== 'undefined' &&
    1641                 wpBlastSettings.restUrls !== null &&
    1642                 wpBlastSettings.restUrls !== undefined
    1643             ) {
    1644                 if (typeof URLSearchParams !== 'undefined' && typeof URL !== 'undefined') {
    1645                     try {
    1646                         var url = new URL(wpBlastSettings.restUrls.getSiteMap);
    1647                         url.searchParams.append('wpblast_nonce', wpblast_nonce);
    1648                         restUrl = url.toString();
    1649                     } catch (e) {
     1623            // avoid a call in case a request is already loading. This is to prevent request from stacking
     1624            if (!wpBlastIsLoadingSitemap) {
     1625                // Get sitemap stored in website database
     1626                var dataToSend = {};
     1627                if (wpBlastSitemapItemsToUpdateScore.length > 0) {
     1628                    dataToSend['items'] = wpBlastSitemapItemsToUpdateScore;
     1629                    for (var i = 0; i < wpBlastSitemapItemsToUpdateScore.length; i++) {
     1630                        // mark this hash has updated, this will prevent an update until next reload of the page
     1631                        wpBlastSitemapUpdatedItems.push(
     1632                            wpBlastSitemapItemsToUpdateScore[i].hash +
     1633                                '-' +
     1634                                wpBlastSitemapItemsToUpdateScore[i].type +
     1635                                '-' +
     1636                                wpBlastSitemapItemsToUpdateScore[i].device,
     1637                        );
     1638                    }
     1639                }
     1640                var restUrl = '/wp-json/wpblast/v1/getSitemap?wpblast_nonce=' + wpblast_nonce; // fallback rest url
     1641                if (
     1642                    typeof wpBlastSettings !== 'undefined' &&
     1643                    wpBlastSettings.restUrls !== null &&
     1644                    wpBlastSettings.restUrls !== undefined
     1645                ) {
     1646                    if (typeof URLSearchParams !== 'undefined' && typeof URL !== 'undefined') {
     1647                        try {
     1648                            var url = new URL(wpBlastSettings.restUrls.getSiteMap);
     1649                            url.searchParams.append('wpblast_nonce', wpblast_nonce);
     1650                            restUrl = url.toString();
     1651                        } catch (e) {
     1652                            // Fallback url
     1653                            restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
     1654                        }
     1655                    } else {
    16501656                        // Fallback url
    16511657                        restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
    16521658                    }
    1653                 } else {
    1654                     // Fallback url
    1655                     restUrl = wpBlastSettings.restUrls.getSiteMap + '?wpblast_nonce=' + wpblast_nonce;
    1656                 }
    1657             }
    1658             jQuery.ajax({
    1659                 url: restUrl,
    1660                 headers: {
    1661                     'X-WP-Nonce': wpblast_nonce,
    1662                     'content-type': 'application/json',
    1663                 },
    1664                 method: 'POST',
    1665                 data: JSON.stringify(dataToSend),
    1666                 success: function (data) {
    1667                     if (data && data.response && data.response.sitemap !== undefined && data.response.data !== null) {
    1668                         wpBlastGetSitemapData(data.response.sitemap);
    1669                     }
    1670 
    1671                     // Should be update after possible update of wpBlastSitemap
    1672                     if ((isGeneratingCache || wpBlastSitemap.length === 0) && wpBlastGetSitemapFrequency !== 1000) {
    1673                         clearInterval(wpBlastGetSitemapInterval);
    1674                         wpBlastGetSitemapFrequency = 1000;
    1675                         if (window.location.search.indexOf('debug') === -1) {
    1676                             wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
    1677                         }
    1678                     } else if (
    1679                         !(isGeneratingCache || wpBlastSitemap.length === 0) &&
    1680                         wpBlastGetSitemapFrequency !== 5000
    1681                     ) {
    1682                         clearInterval(wpBlastGetSitemapInterval);
    1683                         wpBlastGetSitemapFrequency = 5000;
    1684                         if (window.location.search.indexOf('debug') === -1) {
    1685                             wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
    1686                         }
    1687                     }
    1688                 },
    1689             });
     1659                }
     1660                wpBlastIsLoadingSitemap = true;
     1661                jQuery.ajax({
     1662                    url: restUrl,
     1663                    headers: {
     1664                        'X-WP-Nonce': wpblast_nonce,
     1665                        'content-type': 'application/json',
     1666                    },
     1667                    method: 'POST',
     1668                    data: JSON.stringify(dataToSend),
     1669                    success: function (data) {
     1670                        if (
     1671                            data &&
     1672                            data.response &&
     1673                            data.response.sitemap !== undefined &&
     1674                            data.response.data !== null
     1675                        ) {
     1676                            wpBlastGetSitemapData(data.response.sitemap);
     1677                        }
     1678
     1679                        // Should be update after possible update of wpBlastSitemap
     1680                        if ((isGeneratingCache || wpBlastSitemap.length === 0) && wpBlastGetSitemapFrequency !== 1000) {
     1681                            clearInterval(wpBlastGetSitemapInterval);
     1682                            wpBlastGetSitemapFrequency = 1000;
     1683                            if (window.location.search.indexOf('debug') === -1) {
     1684                                wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
     1685                            }
     1686                        } else if (
     1687                            !(isGeneratingCache || wpBlastSitemap.length === 0) &&
     1688                            wpBlastGetSitemapFrequency !== 5000
     1689                        ) {
     1690                            clearInterval(wpBlastGetSitemapInterval);
     1691                            wpBlastGetSitemapFrequency = 5000;
     1692                            if (window.location.search.indexOf('debug') === -1) {
     1693                                wpBlastGetSitemapInterval = setInterval(wpBlastGetSitemap, wpBlastGetSitemapFrequency);
     1694                            }
     1695                        }
     1696                    },
     1697                    complete: function () {
     1698                        wpBlastIsLoadingSitemap = false;
     1699                    },
     1700                });
     1701            }
    16901702        }
    16911703
  • wpblast/trunk/languages/wpblast-fr_FR.po

    r2811232 r2852021  
    398398
    399399# wpml-name: 5062b4b59571ebec36f93781a550255b
    400 msgid "This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 6000."
    401 msgstr "C'est le maximum d'urls que vous souhaitez conserver. Si le nombre est trop faible, l'efficacité du cache diminuera. S'il est trop élevé, vous pourriez avoir besoin de plus de stockage pour votre base de données. Défaut : 6000."
     400msgid "This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 20000."
     401msgstr "C'est le maximum d'urls que vous souhaitez conserver. Si le nombre est trop faible, l'efficacité du cache diminuera. S'il est trop élevé, vous pourriez avoir besoin de plus de stockage pour votre base de données. Défaut : 20000."
    402402
    403403# wpml-name: e6463ff3a7cfe9b18d6994bbd09d82b0
     
    406406
    407407# wpml-name: 733c2a0696e4e033ad552d5715fd8581
    408 msgid "This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 2000."
    409 msgstr "Nombre maximum de pages que vous souhaitez conserver en cache. Si ce nombre est trop faible, le cache sera moins efficace. Plus ce nombre est élevé, plus le cache prendra une taille importante dans votre base de données. Valeur par défaut : 2 000."
     408msgid "This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 10000."
     409msgstr "Nombre maximum de pages que vous souhaitez conserver en cache. Si ce nombre est trop faible, le cache sera moins efficace. Plus ce nombre est élevé, plus le cache prendra une taille importante dans votre base de données. Valeur par défaut : 10 000."
    410410
    411411# wpml-name: 268eebdc0ee24405bd723be444050b98
  • wpblast/trunk/plugin.php

    r2830275 r2852021  
    22
    33/**
    4  * Plugin Name: WPBlast
     4 * Plugin Name: WP Blast
    55 * Plugin URI: https://www.wp-blast.com
    66 * Description: Improve your Wordpress SEO and performance by using dynamic rendering. Prerender your website and generate an easy-to-crawl website.
    7  * Version: 1.8.4
     7 * Version: 1.8.5
    88 * Requires at least: 4.9
    99 * Requires PHP: 5.6
     
    1919use Smartfire\Wordpress\WPBlast\Settings;
    2020
    21 define('WPBLAST_DB_VERSION', '1.2.0');
    22 define('WPBLAST_PLUGIN_VERSION', '1.8.4');
    23 
    24 require_once 'globals.php';
     21define('WPBLAST_DB_VERSION', '1.2.1'); // This is used to upgrade database scheme or force cleanup caches and new crawl
     22define('WPBLAST_PLUGIN_VERSION', '1.8.5');
     23
     24require 'globals.php';
    2525
    2626require_once 'inc/generate-config-functions.php';
     
    2828require_once 'inc/rest-functions.php';
    2929require_once 'inc/mu-plugins-functions.php';
     30require_once 'inc/advanced-cache-functions.php';
    3031require_once 'inc/third-party/index.php';
    3132
     
    6364}
    6465
     66// Registration hook
     67function wpblast_register_activation()
     68{
     69    // First install DB
     70    wpblast_install();
     71    // Then trigger update hook for third-party gen
     72    try {
     73        // also used to trigger regeneration of config or third party file updates
     74        do_action('wpblast_plugin_updated', get_option('wpblast_plugin_version'), WPBLAST_PLUGIN_VERSION);
     75
     76        // only update option at the end so that it can be trigger again in case of error
     77        update_option('wpblast_plugin_version', WPBLAST_PLUGIN_VERSION);
     78    }
     79    catch (\Throwable $e) {} // fail proof
     80    catch (\Exception $e) {} // fail proof
     81}
     82
    6583// Update check
    66 function wpblast_update_db_check()
    67 {
     84function wpblast_update_check()
     85{
     86    // Update DB check
    6887    if (get_option('wpblast_db_version') !== WPBLAST_DB_VERSION) {
    6988        wpblast_install();
     89    }
     90    // Update plugin code check
     91    if (get_option('wpblast_plugin_version') !== WPBLAST_PLUGIN_VERSION) {
     92        try {
     93            // also used to trigger regeneration of config or third party file updates
     94            do_action('wpblast_plugin_updated', get_option('wpblast_plugin_version'), WPBLAST_PLUGIN_VERSION);
     95
     96            // only update option at the end so that it can be trigger again in case of error
     97            update_option('wpblast_plugin_version', WPBLAST_PLUGIN_VERSION);
     98        }
     99        catch (\Throwable $e) {} // fail proof
     100        catch (\Exception $e) {} // fail proof
    70101    }
    71102}
     
    122153}
    123154
    124 add_action('plugins_loaded', 'wpblast_update_db_check');
    125 register_activation_hook(__FILE__, 'wpblast_install');
     155add_action('plugins_loaded', 'wpblast_update_check');
     156register_activation_hook(__FILE__, 'wpblast_register_activation');
    126157function wpblast_install()
    127158{
     
    132163
    133164        // Setup transient for first activation
     165        // This is also used to trigger again a crawl in case of upgrade
    134166        set_transient(Settings::PLUGIN_CACHE_PREFIX . '_firstActivation', time(), apply_filters('wpblast_settings_first_activation_expiration', 60 * 60 * 24 * 30));
    135167
     
    165197        }
    166198
     199        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_CacheExpiration'", ARRAY_A);
     200        if (!isset($resultPages)) {
     201            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_CacheExpiration` (`cacheExpiration`)");
     202        }
     203
     204        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_Url'", ARRAY_A);
     205        if (!isset($resultPages)) {
     206            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_Url` (`url`)");
     207        }
     208
     209        $resultPages = $wpdb->get_row("SHOW INDEXES FROM {$wpdb->wpblast_sitemap} WHERE key_name = 'WPBlast_Sitemap_Active'", ARRAY_A);
     210        if (!isset($resultPages)) {
     211            $wpdb->query("ALTER TABLE {$wpdb->wpblast_sitemap} ADD INDEX `WPBlast_Sitemap_Active` (`active`)");
     212        }
     213
     214        // also used to trigger regeneration of config or third party file updates
     215        do_action('wpblast_activate', get_option('wpblast_db_version'), WPBLAST_DB_VERSION);
     216
     217        // only update option at the end so that it can be trigger again in case of error
    167218        update_option('wpblast_db_version', WPBLAST_DB_VERSION);
    168 
    169         // also used to trigger regeneration of config or third party file updates
    170         do_action('wpblast_activate');
    171219    } catch (\Throwable $e) {
    172220        // hardcode url so that it's as pure as possible
     
    214262add_action('activated_plugin', 'wpblast_activation_redirect');
    215263
     264// This is done in two steps to prevent concurrent requests bugs
     265// In case the uninstall method takes a few seconds to process and that requests are still coming, the plugin could create new data that will not be cleaned
     266// This results in pluginData, file config or third party actions not cleaned (mainly with the action wpblast_updated_crawler_list)
    216267register_deactivation_hook(__FILE__, 'wpblast_uninstall');
    217268function wpblast_uninstall()
    218269{
     270    global $smartfire_wpblast_settings;
     271    // Ping wp-blast.com to be aware of deactivation and not trigger auto gen cache
     272    try {
     273        wp_remote_get($smartfire_wpblast_settings->getWebsite() . '/?method=deactivatePlugin&domain=' . urlencode($smartfire_wpblast_settings->getUsername()) . '&plugin_token=' . $smartfire_wpblast_settings->getPassword(), [
     274            'user-agent' => Settings::WPBLAST_UA_PLUGIN,
     275            'timeout' => 15,
     276        ]);
     277    }
     278    catch (\Throwable $e) {} // fail proof
     279    catch (\Exception $e) {} // fail proof
     280    // should remove every advanced-cache addon or mu-plugins before cleaning everything to prevent concurrent requests bugs
     281    // otherwise concurrent requests could trigger new cache that won't be cleaned
     282    try {
     283        do_action('wpblast_deactivate');
     284    }
     285    catch (\Throwable $e) {} // fail proof
     286    catch (\Exception $e) {} // fail proof
     287}
     288
     289function wpblast_uninstalled($plugin, $network_deactivating)
     290{
    219291    global $wpdb;
    220     $wpdb->wpblast_sitemap = $wpdb->prefix . Settings::WPBLAST_SITEMAP_TABLE;
    221     // Ping wp-blast.com to be aware of deactivation and not trigger auto gen cache
    222     $wpblast_settings = new Settings();
    223     $wpblast_settings->init();
    224     wp_remote_get($wpblast_settings->getWebsite() . '/?method=deactivatePlugin&domain=' . urlencode($wpblast_settings->getUsername()) . '&plugin_token=' . $wpblast_settings->getPassword(), [
    225         'user-agent' => Settings::WPBLAST_UA_PLUGIN,
    226         'timeout' => 15,
    227     ]);
    228     // Don't clean db version and settings to keep it in case of renabling but purge every other cache
    229     wpblast_remove_capability(); // clean capability
    230     do_action('wpblast_purge_cache');
    231     do_action('wpblast_purge_plugin_cache', false);
    232     // Remove table for clean uninstallation
    233     $wpdb->query("DROP TABLE IF EXISTS {$wpdb->wpblast_sitemap}");
    234     do_action('wpblast_deactivate');
    235 }
     292    if ($plugin === plugin_basename(__FILE__)) {
     293        $wpdb->wpblast_sitemap = $wpdb->prefix . Settings::WPBLAST_SITEMAP_TABLE;
     294        // Don't clean db version and settings to keep it in case of renabling but purge every other cache
     295        try {
     296            wpblast_remove_capability(); // clean capability
     297        }
     298        catch (\Throwable $e) {} // fail proof
     299        catch (\Exception $e) {} // fail proof
     300        try {
     301            do_action('wpblast_purge_plugin_cache', false);
     302        }
     303        catch (\Throwable $e) {} // fail proof
     304        catch (\Exception $e) {} // fail proof
     305        try {
     306            // Remove table for clean uninstallation
     307            $wpdb->query("DROP TABLE IF EXISTS {$wpdb->wpblast_sitemap}");
     308        }
     309        catch (\Throwable $e) {} // fail proof
     310        catch (\Exception $e) {} // fail proof
     311        try {
     312            do_action('wpblast_deactivated');
     313        }
     314        catch (\Throwable $e) {} // fail proof
     315        catch (\Exception $e) {} // fail proof
     316    }
     317}
     318add_action('deactivated_plugin', 'wpblast_uninstalled', 10, 2);
    236319
    237320function wpblast_action_links($links)
  • wpblast/trunk/readme.txt

    r2830275 r2852021  
    55Tested up to: 6.1
    66Requires PHP: 5.6
    7 Stable tag: 1.8.4
     7Stable tag: 1.8.5
    88License: Apache 2.0
    99License URI: http://www.apache.org/licenses/LICENSE-2.0
     
    3535The plugin has been designed to allow you to get a very high technology with no headache and no-code knowledge.
    3636The default settings in the plugin should be enough for a large majority of installations. Nevertheless, you still can tweak it if needed.
    37 If you have a website with a very large number of pages (> 2000), just be sure that the maximum number of cache items and the maximum number of sitemap items are well set. If you have any doubt with your plugin configuration, just [contact us](https://www.wp-blast.com/contact/) and we'll be happy to help you configure it.
     37If you have a website with a very large number of pages (> 10000), just be sure that the maximum number of cache items and the maximum number of sitemap items are well set. If you have any doubt with your plugin configuration, just [contact us](https://www.wp-blast.com/contact/) and we'll be happy to help you configure it.
    3838
    3939### Install WP Blast from within WordPress
     
    8282
    8383== Changelog ==
    84 = 1.8.4 =
    85 Release Date: December 7th, 2022
     84= 1.8.5 =
     85Release Date: December 13th, 2022
    8686
    87 - Improve WP Rocket crawler management
    88 - Improve Nitropack compatibility
    89 - Fix error that could happened in crawler detection
     87- Improve performance on large websites
     88- Improve advanced-cache updates for nitropack and wp rocket
     89- Improve mu-plugins updates for nitropack
  • wpblast/trunk/src/Smartfire/Wordpress/WPBlast/Config.php

    r2807381 r2852021  
    111111        }
    112112
    113         include $config_file_path['path'];
     113        // Add fail proof in case the file doesn't exist, this will fallback to default value
     114        // This could happened in case advanced cache is not cleaned and request are coming
     115        if (file_exists($config_file_path['path'])) {
     116            include $config_file_path['path'];
     117        }
    114118
    115119        $config = [
  • wpblast/trunk/src/Smartfire/Wordpress/WPBlast/PageRender.php

    r2807381 r2852021  
    158158        }
    159159
    160         do_action('wpblast_actions_before_start');
    161 
    162160        ob_start([$this, 'render']);
    163161    }
     
    293291    }
    294292
     293    /**
     294     * This method will be executed after EVERY code php has finished
     295     * This is executed after wp has shutdown
     296     */
    295297    public function renderFor($url, $body, $static, $withScroll, $withImages)
    296298    {
     
    331333                return $body;
    332334            }
     335
     336            // Request can be blast
     337            // Use third party contribution point so that they can take action
     338            // This may avoid having cache plugins cache wpblast results
     339            // This avoid having to stop caching in case the request won't be taken in charge by wpblast (case where it's disabled or if the page isn't allowed)
     340            // This may create a bug in case of upgrade of plan with cache plugins had cached the request
     341            do_action('wpblast_actions_before_start');
     342
    333343            if ($sitemapItem === null) {
    334344                // save in db new hash before launching blasting
     
    405415            $this->settings->purgeExceededItemsCache(); // remove transitient exceeding max_cache_items
    406416            $this->settings->cleanExpiredCache(); // clean up expired cache items
     417
     418            do_action('wpblast_actions_before_render', $hash, $toUpdate);
    407419
    408420            return $content;
  • wpblast/trunk/src/Smartfire/Wordpress/WPBlast/Settings.php

    r2830275 r2852021  
    1616    const PLUGIN_CACHE_PREFIX = 'wpblast_plugin';
    1717    const WPBLAST_SITEMAP_TABLE = 'wpblast_sitemap';
    18     const WPBLAST_UA_PLUGIN = 'WP-BLAST-Bot-Plugin 1.8.4';
     18    const WPBLAST_UA_PLUGIN = 'WP-BLAST-Bot-Plugin 1.8.5';
    1919
    2020    private $menu_name = 'wpblast';
     
    3636    private $cacheExpirationCrawlers = 60 * 60 * 24;
    3737    private $cacheGrace = 60 * 15; // 15 min
    38     private $maxCacheItemsCrawlers = 2000;
    39     private $maxSitemapItems = 6000;
     38    private $maxCacheItemsCrawlers = 10000;
     39    private $maxSitemapItems = 20000;
    4040    private $cacheCrawlerList = 60 * 60 * 24;
    4141    private $cacheUserAccount = 60 * 60 * 24;
    4242    private $updatePluginDataFrequency = 60 * 60;
    4343    private $cacheItemGarbageExpiration = 60 * 60 * 24 * 7; // a week
     44    private $purgeExceededItemsCacheRateLimit = 60; // 1 min
     45    private $cleanExpiredCacheRateLimit = 60; // 1 min
    4446    private $withImages = true;
    4547    private $withScroll = true;
     
    215217        add_filter('update_option_wpblast_crawler', [$this, 'onCrawlerOptionChange'], 10, 2);
    216218
     219        add_filter('wpblast_crawlers_cachegen', function ($regexp) {
     220            return $this->getCrawlerCacheGen();
     221        });
     222
     223        add_filter('wpblast_crawlers_regexp', function ($regexp) {
     224            return $this->getCrawlerRegexp();
     225        });
     226
     227        add_filter('wpblast_crawlers_autoregexp', function ($regexp) {
     228            return $this->getCrawlerAutoRegexp();
     229        });
     230
     231        add_filter('wpblast_crawlers_full', function ($regexp) {
     232            $crawlerCacheGen = $this->getCrawlerCacheGen();
     233            $crawlerRegexp = $this->getCrawlerRegexp();
     234            $crawlerAutoRegexp = $this->getCrawlerAutoRegexp();
     235            $returnValue = ''; // Security in case the filter is called twice
     236            if (isset($crawlerCacheGen) && $crawlerCacheGen !== '') {
     237                $returnValue .= $crawlerCacheGen;
     238            }
     239            if (isset($crawlerRegexp) && $crawlerRegexp !== '') {
     240                if ($returnValue !== '') {
     241                    $returnValue .= '|';
     242                }
     243                $returnValue .= $crawlerRegexp;
     244            }
     245            if (isset($crawlerAutoRegexp) && $crawlerAutoRegexp !== '') {
     246                if ($returnValue !== '') {
     247                    $returnValue .= '|';
     248                }
     249                $returnValue .= $crawlerAutoRegexp;
     250            }
     251            return $returnValue;
     252        });
     253
    217254        add_filter('wpblast_crawlers_list', function ($ua) {
    218255            array_push($ua, [
     
    250287        $this->updatePluginDataFrequency = apply_filters('wpblast_settings_plugin_data_expiration', $this->updatePluginDataFrequency);
    251288        $this->cacheItemGarbageExpiration = apply_filters('wpblast_settings_cache_garbage_expiration', $this->cacheItemGarbageExpiration);
     289
     290        $this->purgeExceededItemsCacheRateLimit = apply_filters('wpblast_settings_purge_exceeded_items_cache_rate_limit', $this->purgeExceededItemsCacheRateLimit);
     291        $this->cleanExpiredCacheRateLimit = apply_filters('wpblast_settings_clean_expired_cache_rate_limit', $this->cleanExpiredCacheRateLimit);
    252292
    253293        $this->server = $this->api->get_option('server', 'wpblast_home', $this->server);
     
    277317        $this->maxSitemapItems = intval($this->api->get_option('max_sitemap_items', 'wpblast_crawler', $this->maxSitemapItems));
    278318
    279         // Protection against lock of requests when there is no plugin cache yet and we need to generate it
    280         // This is a protection but this case shouldn't happen
    281         if (!isset($_SERVER['HTTP_WPBLAST_SITEMAP_GENERATION'])) {
    282             $this->getCrawlerAutoRegexp(); // update crawler list if expired
    283             $this->getAccount(); // update user account if expired
    284             $this->getPluginData(); // update plugin data to WP Blast at the given frequency
    285         }
    286 
    287319        add_action('wpblast_purge_cache', [$this, 'purgeCache']);
    288320        add_action('wpblast_purge_plugin_cache', [$this, 'purgePluginCache']);
     
    293325
    294326        $this->has_been_init = true;
     327
     328        // Protection against lock of requests when there is no plugin cache yet and we need to generate it
     329        // This is a protection but this case shouldn't happen
     330        // This has been moved after the has_been_init flag because it would trigger a second init otherwise due to trigger of getCrawlerAutoRegexp that could then trigger a generation of config and then a new init
     331        if (!isset($_SERVER['HTTP_WPBLAST_SITEMAP_GENERATION'])) {
     332            $this->getCrawlerAutoRegexp(); // update crawler list if expired
     333            $this->getAccount(); // update user account if expired
     334            $this->getPluginData(); // update plugin data to WP Blast at the given frequency
     335        }
     336    }
     337
     338    // Force check that the plugin is still active
     339    // This is used to avoid concurrent requests bugs
     340    // Bug would be to not have a cleaned uninstall in case a request finish after the uninstallation
     341    public function isPluginActive()
     342    {
     343        global $wpdb;
     344        $pluginName = plugin_basename(realpath($this->rootPluginFile));
     345        $suppress = $wpdb->suppress_errors();
     346        $row      = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'active_plugins' ) );
     347        $wpdb->suppress_errors( $suppress );
     348        if ( is_object( $row ) ) {
     349            $value = maybe_unserialize($row->option_value);
     350        }
     351        return in_array( $pluginName, $value, true ) || is_plugin_active_for_network( $pluginName );
    295352    }
    296353
     
    342399            if (isset($res)) {
    343400                $res = json_decode($res, true);
    344                 if ($res) {
     401                // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     402                // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     403                if ($res && $this->isPluginActive()) {
    345404                    $data = current_time('mysql', 1);
    346405                    set_transient(self::PLUGIN_CACHE_PREFIX . '_plugindata', $data, $this->updatePluginDataFrequency);
     
    374433            }
    375434            $res = wp_remote_retrieve_body($response);
    376             if (isset($res) && $res !== '') {
     435            // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     436            // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     437            if (isset($res) && $res !== '' && $this->isPluginActive()) {
    377438                $res = json_decode($res, true);
    378439                if (isset($res['crawlers']) && $res['crawlers'] !== '') {
     
    412473            }
    413474            $res = wp_remote_retrieve_body($response);
    414 
    415             if (isset($res) && $res !== '') {
     475            // check that the plugin hasn't been deactivated while we were waiting for the result of the request
     476            // otherwise, we could save in database and trigger an action while the plugin shouldn't be activated
     477            if (isset($res) && $res !== '' && $this->isPluginActive()) {
    416478                $res = json_decode($res, true);
    417479                if (
     
    452514                        && $userAccount['features']['maxPages'] !== $maxPagesAllowed
    453515                    ) {
    454                         $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp ORDER BY maxActive DESC, maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
    455                         $this->updateActivePages($urls);
     516                        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     517                            $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp ORDER BY maxActive DESC, maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
     518                            $this->updateActivePages($urls);
     519                        }
    456520                    }
    457521                    // Generate cache if it's a first connection
     
    484548        global $wpdb;
    485549
    486         if (count($items) > 0) {
     550        if (count($items) > 0 && $this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    487551
    488552            // Send data about hash wanted to be sure it's sync with wp-blast.com server
     
    525589                            $toUpdate['scores'] = $item['scores'];
    526590                        }
     591                        // query in foreach but is limited by the number of scores that can be retrieve through the request, it depends on the user navigating so should be only tens of scores
    527592                        $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET scores = %s WHERE hash = %s", Utils::format_json_encode($toUpdate), $hash));
    528593                    }
     
    551616        }
    552617
    553         if (count($activeUrls) > 0) {
    554             // Update every active state
    555             // This is done in a single query to allow having a lot of update of pages without doing a lot of query
    556             // First enable active page
    557             $activation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
    558 
    559             // Then disable page not in the array
    560             $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
    561 
    562             // Clean up in case too much url are active (shouldn't happened unless fraudulent call)
    563             $userAccount = $this->getAccount();
    564             if (isset($userAccount) && isset($userAccount['features']) && isset($userAccount['features']['maxPages'])) {
    565                 $maxPagesAllowed = $userAccount['features']['maxPages'];
    566                 $currentUse = $this->getNumberPagesUsed();
    567                 if (isset($currentUse) && $currentUse > $maxPagesAllowed) {
    568                     // should never be called unless fraud attempt or bug
    569                     // clean up active pages based on lastRequest, except for home url
    570                     // get urls to keep active
    571                     $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp WHERE maxActive >= 1 ORDER BY maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
    572                     // First enable active page
    573                     $activation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
    574                     // Then disable page not in the array
    575                     $deactivation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
    576                     $activation = $activation !== false && $activation2 !== false;
    577                     $deactivation = $deactivation !== false && $deactivation2 !== false;
    578                 }
    579             }
    580 
    581             if ($activation === false || $deactivation === false) {
    582                 $this->setFormView('error');
    583             }
    584         } else {
    585             // no active pages wanted, disable every pages
    586             // should never be called due to at least home url
    587             $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0"));
    588 
    589             if ($deactivation === false) {
    590                 $this->setFormView('error');
     618        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     619            if (count($activeUrls) > 0) {
     620                // Update every active state
     621                // This is done in a single query to allow having a lot of update of pages without doing a lot of query
     622                // First enable active page
     623                $activation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
     624
     625                // Then disable page not in the array
     626                $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($activeUrls), '%s')) . ')', $activeUrls));
     627
     628                // Clean up in case too much url are active (shouldn't happened unless fraudulent call)
     629                $userAccount = $this->getAccount();
     630                if (isset($userAccount) && isset($userAccount['features']) && isset($userAccount['features']['maxPages'])) {
     631                    $maxPagesAllowed = $userAccount['features']['maxPages'];
     632                    $currentUse = $this->getNumberPagesUsed();
     633                    if (isset($currentUse) && $currentUse > $maxPagesAllowed) {
     634                        // should never be called unless fraud attempt or bug
     635                        // clean up active pages based on lastRequest, except for home url
     636                        // get urls to keep active
     637                        $urls = $wpdb->get_col($wpdb->prepare("SELECT url FROM (SELECT MAX(active) AS maxActive, REPLACE(url, %s, '') as url, MAX(lastRequest) AS maxLastRequest FROM {$wpdb->wpblast_sitemap} GROUP BY REPLACE(url, %s, '')) AS tmp WHERE maxActive >= 1 ORDER BY maxLastRequest DESC LIMIT 0, %d", '?' . PageRender::WPBLAST_CRAWLER, '?' . PageRender::WPBLAST_CRAWLER, $maxPagesAllowed));
     638                        // First enable active page
     639                        $activation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 1 WHERE url IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
     640                        // Then disable page not in the array
     641                        $deactivation2 = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0 WHERE url NOT IN (" . implode(', ', array_fill(0, count($urls), '%s')) . ')', $urls));
     642                        $activation = $activation !== false && $activation2 !== false;
     643                        $deactivation = $deactivation !== false && $deactivation2 !== false;
     644                    }
     645                }
     646
     647                if ($activation === false || $deactivation === false) {
     648                    $this->setFormView('error');
     649                }
     650            } else {
     651                // no active pages wanted, disable every pages
     652                // should never be called due to at least home url
     653                $deactivation = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET active = 0"));
     654
     655                if ($deactivation === false) {
     656                    $this->setFormView('error');
     657                }
    591658            }
    592659        }
     
    683750            // avoid getting cache value to avoid loading every cache of the website in ram
    684751            // prioritize by newest url by default
    685             if ($orderBy === 'url') {
    686                 $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration FROM {$wpdb->wpblast_sitemap} ORDER BY CHAR_LENGTH(url) ASC", ARRAY_A);
    687             } else if ($orderBy === 'active') {
    688                 // hashVariables used for cache section in admin to have details on a row
    689                 // request used by admin settings page and have specific fields / ! \
    690                 $sitemap = $wpdb->get_results("SELECT active, hash, hashVariables, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY active DESC, nbRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
    691             } else {
    692                 // send scores to wp-blast.com so that the server can know the scores saved in database by the plugin
    693                 $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     752            if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     753                if ($orderBy === 'url') {
     754                    $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration FROM {$wpdb->wpblast_sitemap} ORDER BY CHAR_LENGTH(url) ASC", ARRAY_A);
     755                } else if ($orderBy === 'active') {
     756                    // hashVariables used for cache section in admin to have details on a row
     757                    // request used by admin settings page and have specific fields / ! \
     758                    $sitemap = $wpdb->get_results("SELECT active, hash, hashVariables, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY active DESC, nbRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     759                } else {
     760                    // send scores to wp-blast.com so that the server can know the scores saved in database by the plugin
     761                    $sitemap = $wpdb->get_results("SELECT active, hash, url, dateAdd, dateUpdate, lastRequest, nbRequest, lastGen, cacheExpiration, scores FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC, CHAR_LENGTH(url) ASC", ARRAY_A);
     762                }
    694763            }
    695764
     
    706775    {
    707776        global $wpdb;
    708         $urlUntrailingSlashed = untrailingslashit($url);
    709         $nb = $wpdb->get_var($wpdb->prepare("SELECT MAX(active) AS active FROM {$wpdb->wpblast_sitemap} WHERE (url = %s OR url = CONCAT(%s, '/')) GROUP BY REPLACE(url, %s, '')", [$urlUntrailingSlashed, $urlUntrailingSlashed, '?' . PageRender::WPBLAST_CRAWLER]));
    710         $nb = intval($nb);
    711         if ($nb >= 1) {
    712             return true;
    713         } else {
     777        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     778            $urlUntrailingSlashed = untrailingslashit($url);
     779            $nb = $wpdb->get_var($wpdb->prepare("SELECT MAX(active) AS active FROM {$wpdb->wpblast_sitemap} WHERE (url = %s OR url = CONCAT(%s, '/')) GROUP BY REPLACE(url, %s, '')", [$urlUntrailingSlashed, $urlUntrailingSlashed, '?' . PageRender::WPBLAST_CRAWLER]));
     780            $nb = intval($nb);
     781            if ($nb >= 1) {
     782                return true;
     783            } else {
     784                return false;
     785            }
     786        }
     787        else {
    714788            return false;
    715789        }
     
    722796        if (isset($hash)) {
    723797            if (!isset($this->sitemapItems[$hash])) {
    724                 $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]), ARRAY_A);
    725                 if (isset($item)) {
    726                     $this->sitemapItems[$hash] = $item;
    727                 } else {
     798                if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     799                    $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]), ARRAY_A);
     800                    if (isset($item)) {
     801                        $this->sitemapItems[$hash] = $item;
     802                    } else {
     803                        return null;
     804                    }
     805                }
     806                else {
    728807                    return null;
    729808                }
     
    738817    {
    739818        global $wpdb;
    740 
    741         if (isset($hash)) {
     819        if (isset($hash) && $this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    742820            $itemId = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} WHERE hash = %s", [$hash]));
    743821
     
    825903        if (isset($_GET[self::WPBLAST_PURGE_CACHE])) {
    826904            unset($_GET[self::WPBLAST_PURGE_CACHE]);
    827             $this->purgeCache();
     905            do_action('wpblast_purge_cache');
    828906            echo '<div>
    829907  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Cache has been cleared', 'wpblast') . '</div>
     
    833911        if (isset($_GET[self::WPBLAST_PURGE_PLUGIN_CACHE])) {
    834912            unset($_GET[self::WPBLAST_PURGE_PLUGIN_CACHE]);
    835             $this->purgePluginCache(true);
     913            do_action('wpblast_purge_plugin_cache');
    836914            echo '<div>
    837915  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Cache has been cleared', 'wpblast') . '</div>
     
    841919        if (isset($_GET[self::WPBLAST_PURGE_SITEMAP])) {
    842920            unset($_GET[self::WPBLAST_PURGE_SITEMAP]);
    843             $this->purgeSitemap();
     921            do_action('wpblast_purge_sitemap');
    844922            echo '<div>
    845923  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Sitemap has been cleared', 'wpblast') . '</div>
     
    849927        if (isset($_GET[self::WPBLAST_PURGE_PAGES_SCORES])) {
    850928            unset($_GET[self::WPBLAST_PURGE_PAGES_SCORES]);
    851             $this->purgePagesScores();
     929            do_action('wpblast_purge_pages_scores');
    852930            echo '<div>
    853931  <div class="notice notice-success is-dismissible inline" style="line-height: 1.4; padding: 11px 15px; font-size: 14px; margin: 25px 20px 0 2px;">' . esc_html__('Pages scores has been cleared', 'wpblast') . '</div>
     
    12021280                'name' => 'max_cache_items',
    12031281                'label' => __('Maximum cache items', 'wpblast'),
    1204                 'desc' => __('This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 2000.', 'wpblast'),
     1282                'desc' => __('This is the maximum number of cache items you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 10000.', 'wpblast'),
    12051283                'type' => 'number',
    12061284                'default' => $this->maxCacheItemsCrawlers,
     
    12091287                'name' => 'max_sitemap_items',
    12101288                'label' => __('Maximum sitemap items', 'wpblast'),
    1211                 'desc' => __('This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 6000.', 'wpblast'),
     1289                'desc' => __('This is the maximum number of urls you want to keep. If the number is too low, cache efficiency would decrease. If the number is too high, you could end up having a very huge database. Default: 20000.', 'wpblast'),
    12121290                'type' => 'number',
    12131291                'default' => $this->maxSitemapItems,
     
    15911669        global $wpdb;
    15921670
    1593         if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
    1594             // Get cache items to delete: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
    1595             // Limit range is bigint unsigned max value
    1596             $idsToDelete = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxSitemapItems()]));
    1597 
    1598             // Get items to clear: use this in two steps to avoid using nested query that could create an incompatibility
    1599             if (count($idsToDelete) > 0) {
    1600                 $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE id IN (" . implode(', ', array_fill(0, count($idsToDelete), '%s')) . ')', $idsToDelete));
    1601             }
    1602 
    1603             // Get cache items to keep: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
    1604             // Limit range is bigint unsigned max value
    1605             $idsToUpdate = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxCacheItemsCrawlers()]));
    1606 
    1607             // Clean cache value
    1608             if (count($idsToUpdate) > 0) {
    1609                 $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET cache = '', cacheExpiration = 0, lastGen = NULL WHERE id IN (" . implode(', ', array_fill(0, count($idsToUpdate), '%s')) . ')', $idsToUpdate));
    1610             }
     1671        $purgeExceededItemsCacheTimestamp = get_transient(self::PLUGIN_CACHE_PREFIX . '_purgeExceededItemsCacheTimestamp');
     1672        // Rate limit calls to this method to avoid overloading the server
     1673        if (!$purgeExceededItemsCacheTimestamp || ($purgeExceededItemsCacheTimestamp + $this->purgeExceededItemsCacheRateLimit < time())) {
     1674            if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     1675                // Get cache items to delete: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
     1676                // Limit range is bigint unsigned max value
     1677                $idsToDelete = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxSitemapItems()]));
     1678   
     1679                // Get items to clear: use this in two steps to avoid using nested query that could create an incompatibility
     1680                if (count($idsToDelete) > 0) {
     1681                    $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE id IN (" . implode(', ', array_fill(0, count($idsToDelete), '%s')) . ')', $idsToDelete));
     1682                }
     1683   
     1684                // Get cache items to keep: use this in two steps to avoid using nested query that could create an incompatibility, avoid using DELETE FROM not in to avoid concurrent requests bugs
     1685                // Limit range is bigint unsigned max value
     1686                $idsToUpdate = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->wpblast_sitemap} ORDER BY lastRequest DESC LIMIT %d, 18446744073709551615", [$this->getMaxCacheItemsCrawlers()]));
     1687   
     1688                // Clean cache value
     1689                if (count($idsToUpdate) > 0) {
     1690                    $wpdb->query($wpdb->prepare("UPDATE {$wpdb->wpblast_sitemap} SET cache = '', cacheExpiration = 0, lastGen = NULL WHERE id IN (" . implode(', ', array_fill(0, count($idsToUpdate), '%s')) . ')', $idsToUpdate));
     1691                }
     1692            }
     1693
     1694            $data = time();
     1695            set_transient(self::PLUGIN_CACHE_PREFIX . '_purgeExceededItemsCacheTimestamp', $data, 60 * 60 * 24 * 7); // transient is kept a week
    16111696        }
    16121697    }
     
    16151700    {
    16161701        global $wpdb;
     1702
     1703        $cleanExpiredCacheTimestamp = get_transient(self::PLUGIN_CACHE_PREFIX . '_cleanExpiredCacheTimestamp');
     1704        // Rate limit calls to this method to avoid overloading the server
     1705        if (!$cleanExpiredCacheTimestamp || ($cleanExpiredCacheTimestamp + $this->cleanExpiredCacheRateLimit < time())) {
    16171706
    16181707        if ($this->tableExists(self::WPBLAST_SITEMAP_TABLE)) {
     
    16221711            // Remove items that have not been requested for a long time: this is a big clean up to avoid the table getting bigger and bigger with no legitimate content
    16231712            $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->wpblast_sitemap} WHERE (lastRequest IS NOT NULL AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(lastRequest) >= %d) OR (lastRequest IS NULL AND dateAdd IS NOT NULL AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(dateAdd) >= %d)", [$this->getCacheItemGarbageExpiration(), $this->getCacheItemGarbageExpiration()]));
     1713        }
     1714
     1715        $data = time();
     1716            set_transient(self::PLUGIN_CACHE_PREFIX . '_cleanExpiredCacheTimestamp', $data, 60 * 60 * 24 * 7); // transient is kept a week
    16241717        }
    16251718    }
Note: See TracChangeset for help on using the changeset viewer.