File "class-ajax.php"
Full Path: /home/digimqhe/flashdigi.uk/comment-content/plugins/hummingbird-performance/admin/class-ajax.php
File size: 89.02 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Handle all AJAX actions in admin side
*
* @package Hummingbird
*/
namespace Hummingbird\Admin;
use Hummingbird\Core\Configs;
use Hummingbird\Core\Filesystem;
use Hummingbird\Core\Integration\Opcache;
use Hummingbird\Core\Modules\Caching\Preload;
use Hummingbird\Core\Modules\Minify;
use Hummingbird\Core\Modules\Page_Cache;
use Hummingbird\Core\Modules\Performance;
use Hummingbird\Core\Settings;
use Hummingbird\Core\Utils;
use Hummingbird\WP_Hummingbird;
use Hummingbird\Core\Modules\Caching\Fast_CGI;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class AJAX
*
* @package Hummingbird\Admin
*/
class AJAX {
/**
* AJAX constructor.
*/
public function __construct() {
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
return;
}
// React. Hide tutorials.
add_action( 'wp_ajax_wphb_react_hide_tutorials', array( $this, 'hide_tutorials' ) );
// Parse clear cache click from frontend admin bar.
add_action( 'wp_ajax_wphb_front_clear_cache', array( $this, 'clear_frontend_cache' ) );
// Parse clear full cache from admin notice.
add_action( 'wp_ajax_wphb_global_clear_cache', array( $this, 'clear_global_cache' ) );
// Clear selected module cache.
add_action( 'wp_ajax_wphb_clear_caches', array( $this, 'clear_modules_cache' ) );
// Clear Cloudflare cache from admin bar.
add_action( 'wp_ajax_wphb_front_clear_cloudflare', array( $this, 'clear_frontend_cloudflare' ) );
/**
* Multisite global cache clear.
*
* @since 2.7.0
*/
if ( is_multisite() ) {
// Get the total number of sites in a network.
add_action( 'wp_ajax_wphb_get_network_sites', array( $this, 'get_network_sites' ) );
// Clear cache on network subsites.
add_action( 'wp_ajax_wphb_clear_network_cache', array( $this, 'clear_network_cache' ) );
}
/**
* DASHBOARD AJAX ACTIONS
*/
// Dismiss notice.
add_action( 'wp_ajax_wphb_notice_dismiss', array( $this, 'notice_dismiss' ) );
// Dismiss notice.
add_action( 'wp_ajax_wphb_cf_notice_dismiss', array( $this, 'cf_notice_dismiss' ) );
// Hide upgrade summary.
add_action( 'wp_ajax_wphb_hide_upgrade_summary', array( $this, 'hide_upgrade_summary' ) );
/**
* PERFORMANCE TEST AJAX ACTIONS
*/
// Run performance test.
add_action( 'wp_ajax_wphb_performance_run_test', array( $this, 'performance_run_test' ) );
// Save performance settings.
add_action( 'wp_ajax_wphb_performance_save_settings', array( $this, 'performance_save_settings' ) );
/**
* CACHING MODULE AJAX ACTIONS
*/
// Clear cache.
add_action( 'wp_ajax_wphb_clear_module_cache', array( $this, 'clear_module_cache' ) );
/* PAGE CACHING */
// Save page caching settings.
add_action( 'wp_ajax_wphb_page_cache_save_settings', array( $this, 'page_cache_save_settings' ) );
// Save page caching settings.
add_action( 'wp_ajax_wphb_fast_cgi_save_settings', array( $this, 'fast_cgi_save_settings' ) );
// Gutenberg clear cache for post.
add_action( 'wp_ajax_wphb_gutenberg_clear_post_cache', array( $this, 'gutenberg_clear_post_cache' ) );
// Cancel cache preload.
add_action( 'wp_ajax_wphb_preload_cancel', array( $this, 'cancel_cache_preload' ) );
// Remove advanced-cache.php file.
add_action( 'wp_ajax_wphb_remove_advanced_cache', array( $this, 'remove_advanced_cache' ) );
// Disable FastCGI cache.
add_action( 'wp_ajax_wphb_disable_fast_cgi', array( $this, 'disable_fast_cgi' ) );
// Switch Cache method.
add_action( 'wp_ajax_wphb_switch_cache_method', array( $this, 'switch_cache_method' ) );
/* RSS CACHING */
// Save settings for rss caching module.
add_action( 'wp_ajax_wphb_rss_save_settings', array( $this, 'rss_save_settings' ) );
/* INTEGRATIONS */
// Save Redis settings.
add_action( 'wp_ajax_wphb_redis_save_settings', array( $this, 'redis_save_settings' ) );
// Toggle Redis object cache setting.
add_action( 'wp_ajax_wphb_redis_toggle_object_cache', array( $this, 'redis_toggle_object_cache' ) );
add_action( 'wp_ajax_wphb_redis_cache_purge', array( $this, 'redis_cache_purge' ) );
add_action( 'wp_ajax_wphb_redis_disconnect', array( $this, 'redis_disconnect' ) );
// Cloudflare connect.
add_action( 'wp_ajax_wphb_cloudflare_connect', array( $this, 'cloudflare_connect' ) );
// Cloudflare purge cache.
add_action( 'wp_ajax_wphb_cloudflare_purge_cache', array( $this, 'cloudflare_purge_cache' ) );
// Cloudflare recheck zones.
add_action( 'wp_ajax_wphb_cloudflare_recheck_zones', array( $this, 'cloudflare_recheck_zones' ) );
/* CACHE SETTINGS */
// Parse settings form.
add_action( 'wp_ajax_wphb_other_cache_save_settings', array( $this, 'save_other_cache_settings' ) );
/**
* ASSET OPTIMIZATION AJAX ACTIONS
*/
// Toggle CDN.
add_action( 'wp_ajax_wphb_minification_toggle_cdn', array( $this, 'minification_toggle_cdn' ) );
// Toggle logs.
add_action( 'wp_ajax_wphb_minification_toggle_log', array( $this, 'minification_toggle_log' ) );
// Toggle advanced minification view.
add_action( 'wp_ajax_wphb_minification_toggle_view', array( $this, 'minification_toggle_view' ) );
// Start scan.
add_action( 'wp_ajax_wphb_minification_start_check', array( $this, 'minification_start_check' ) );
// Scan check step.
add_action( 'wp_ajax_wphb_minification_check_step', array( $this, 'minification_check_step' ) );
// Cancel scan.
add_action( 'wp_ajax_wphb_minification_cancel_scan', array( $this, 'minification_cancel_scan' ) );
// Delete scan.
add_action( 'wp_ajax_wphb_minification_finish_scan', array( $this, 'minification_finish_scan' ) );
// Save critical css file.
add_action( 'wp_ajax_wphb_minification_save_extra_optimization_data', array( $this, 'minification_save_extra_optimization_data' ) );
// Update custom asset path.
add_action( 'wp_ajax_wphb_minification_update_asset_path', array( $this, 'minification_update_asset_path' ) );
// Update settings in network admin.
add_action( 'wp_ajax_wphb_minification_update_network_settings', array( $this, 'minification_update_network_settings' ) );
// Save settings.
add_action( 'wp_ajax_wphb_minification_save_exclude_list', array( $this, 'minification_save_exclude_list' ) );
// Toggle safe mode.
add_action( 'wp_ajax_wphb_minification_toggle_safe_mode', array( $this, 'minification_toggle_safe_mode' ) );
// Skip AO upgrade.
add_action( 'wp_ajax_wphb_ao_skip_upgrade', array( $this, 'minification_skip_upgrade' ) );
// Perform AO upgrade.
add_action( 'wp_ajax_wphb_ao_do_upgrade', array( $this, 'minification_do_upgrade' ) );
/**
* ADVANCED TOOLS AJAX ACTIONS
*/
// Clean database.
add_action( 'wp_ajax_wphb_advanced_db_delete_data', array( $this, 'advanced_db_delete_data' ) );
// Save settings in advanced tools module.
add_action( 'wp_ajax_wphb_advanced_save_settings', array( $this, 'advanced_save_settings' ) );
// Purge cache preloader.
add_action( 'wp_ajax_wphb_advanced_purge_cache', array( $this, 'advanced_purge_cache' ) );
// Purge asset optimization groups.
add_action( 'wp_ajax_wphb_advanced_purge_minify', array( $this, 'advanced_purge_minify' ) );
// Purge asset optimization orphaned data.
add_action( 'wp_ajax_wphb_advanced_purge_orphaned', array( $this, 'advanced_purge_orphaned' ) );
/**
* LOGGER MODULE AJAX ACTIONS
*/
add_action( 'wp_ajax_wphb_logger_clear', array( $this, 'logger_clear' ) );
/**
* SETTINGS MODULE AJAX ACTIONS
*/
add_action( 'wp_ajax_wphb_admin_settings_save_settings', array( $this, 'admin_settings_save_settings' ) );
// Reset settings.
add_action( 'wp_ajax_wphb_reset_settings', array( $this, 'reset_settings' ) );
// Export settings.
add_action( 'wp_ajax_wphb_admin_settings_export_settings', array( $this, 'admin_settings_export_settings' ) );
// Import settings.
add_action( 'wp_ajax_wphb_admin_settings_import_settings', array( $this, 'admin_settings_import_settings' ) );
// Configs.
add_action( 'wp_ajax_wphb_create_config', array( $this, 'save_config' ) );
add_action( 'wp_ajax_wphb_upload_config', array( $this, 'upload_config' ) );
add_action( 'wp_ajax_wphb_apply_config', array( $this, 'apply_config' ) );
// Clear Critical Css.
add_action( 'wp_ajax_wphb_clear_critical_css_files', array( $this, 'clear_critical_css_files_and_regenerate' ) );
// Create Critical Css.
add_action( 'wp_ajax_wphb_gutenberg_create_css_file', array( $this, 'gutenberg_create_css_file' ) );
// Re-Create Critical Css.
add_action( 'wp_ajax_wphb_gutenberg_recreate_css_file', array( $this, 'gutenberg_recreate_css_file' ) );
// Revert Critical Css.
add_action( 'wp_ajax_wphb_gutenberg_revert_css_file', array( $this, 'gutenberg_revert_css_file' ) );
// Get Critical Css status for single post.
add_action( 'wp_ajax_wphb_gutenberg_get_critical_status_for_single_post', array( $this, 'gutenberg_get_critical_status_for_single_post' ) );
// Get Critical Css status for single post.
add_action( 'wp_ajax_wphb_get_critical_status_for_queue', array( $this, 'get_critical_status_for_queue' ) );
// Toggle Delay Js.
add_action( 'wp_ajax_wphb_react_minify_toggle_delay_js', array( $this, 'minification_toggle_delay' ) );
// Toggle Critical CSS.
add_action( 'wp_ajax_wphb_react_minify_toggle_critical_css', array( $this, 'minify_toggle_critical_css' ) );
// Switch critical CSS.
add_action( 'wp_ajax_wphb_switch_to_critical_css_from_legacy', array( $this, 'wphb_switch_to_critical_css_from_legacy' ) );
// Search posts.
add_action( 'wp_ajax_wphb_search_posts', array( $this, 'wphb_search_posts' ) );
// Reset exclusions.
add_action( 'wp_ajax_wphb_reset_exclusions', array( $this, 'reset_exclusions' ) );
}
/**
* Handle clear cache button click from the frontend top admin bar.
*
* @since 1.9.3
*/
public function clear_frontend_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$pc_module = Utils::get_module( 'page_cache' );
$status = $pc_module->clear_cache();
if ( ! $status ) {
wp_send_json_error();
}
wp_send_json_success();
}
/**
* Handle clear cache button click from the frontend top admin bar.
*
* @since 1.9.3
*/
public function clear_global_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$modules = Utils::get_active_cache_modules();
foreach ( $modules as $module => $name ) {
$mod = Utils::get_module( $module );
if ( ! $mod->is_active() ) {
continue;
}
if ( 'minify' === $module ) {
$mod->clear_files();
} else {
$mod->clear_cache();
}
}
// Remove notice.
delete_option( 'wphb-notice-cache-cleaned-show' );
wp_send_json_success();
}
/**
* Clear cache from selected modules.
*
* @since 2.7.1
*/
public function clear_modules_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$modules = filter_input( INPUT_POST, 'modules', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
if ( ! $modules ) {
wp_send_json_success();
}
// Do not clear Varnish cache.
if ( ! in_array( 'varnish', $modules, true ) ) {
remove_action( 'wphb_clear_cache_url', array( Utils::get_module( 'page_cache' ), 'clear_external_cache' ) );
} else {
$key = array_search( 'varnish', $modules, true );
unset( $modules[ $key ] );
// Page cache is disabled in modules... Oh well, force manual purge.
if ( ! in_array( 'page_cache', $modules, true ) ) {
Utils::get_api()->varnish->purge_cache( '' );
}
}
// Do not clear Opcache.
if ( ! in_array( 'opcache', $modules, true ) ) {
remove_action( 'wphb_clear_cache_url', array( Opcache::get_instance(), 'purge_cache' ) );
} else {
$key = array_search( 'opcache', $modules, true );
unset( $modules[ $key ] );
// Page cache is disabled in modules... Oh well, force manual purge.
if ( ! in_array( 'page_cache', $modules, true ) ) {
Opcache::get_instance()->purge_cache();
}
}
foreach ( $modules as $module ) {
$mod = Utils::get_module( $module );
if ( false === $mod || ! $mod->is_active() ) {
continue;
}
if ( 'minify' === $module ) {
$mod->clear_files();
} else {
$mod->clear_cache();
}
}
wp_send_json_success(
array(
'message' => __( 'Cache purged.', 'wphb' ),
)
);
}
/**
* Clear Cloudflare cache from admin bar.
*
* @since 2.7.2
*/
public function clear_frontend_cloudflare() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$status = Utils::get_module( 'cloudflare' )->clear_cache();
if ( ! $status ) {
wp_send_json_error();
}
wp_send_json_success();
}
/**
* Hide tutorials on dashboard page.
*
* @since 2.7.3
*/
public function hide_tutorials() {
check_ajax_referer( 'wphb-fetch' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
update_option( 'wphb-hide-tutorials', true, false );
wp_send_json_success();
}
/**
* Get the number of subsites in a network.
*
* @since 2.7.0
*/
public function get_network_sites() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
global $wpdb;
$count = wp_cache_get( 'wphb_network_subsites' );
if ( false === $count ) {
$count = $wpdb->get_var( "SELECT COUNT( blog_id ) FROM $wpdb->blogs" ); // Db call ok.
}
wp_cache_set( 'wphb_network_subsites', $count );
wp_send_json_success( $count );
}
/**
* Clear a batch of network subsite caches.
*
* @since 2.7.0
*/
public function clear_network_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Note: we can not use Utils::get_admin_capability() because is_network_admin() does not work in ajax request.
if ( ! current_user_can( 'manage_network' ) ) {
die();
}
$sites = filter_input( INPUT_POST, 'sites', FILTER_SANITIZE_NUMBER_INT );
$offset = filter_input( INPUT_POST, 'offset', FILTER_SANITIZE_NUMBER_INT );
$args = array(
'number' => (int) $sites,
'offset' => (int) $offset,
);
$sites = get_sites( $args );
// This is quick hack to force the page cache module to not clear only main site cache.
$http_host_backup = '';
if ( isset( $_SERVER['HTTP_HOST'] ) ) {
$http_host_backup = wp_unslash( $_SERVER['HTTP_HOST'] );
$_SERVER['HTTP_HOST'] = '';
}
foreach ( $sites as $site ) {
switch_to_blog( $site->blog_id );
Utils::get_module( 'page_cache' )->clear_cache( $site->domain . $site->path, false, false );
}
// Revert the HTTP_HOST value back.
if ( ! empty( $http_host_backup ) ) {
$_SERVER['HTTP_HOST'] = $http_host_backup;
}
// Reset cached pages count.
Settings::update_setting( 'pages_cached', 0, 'page_cache' );
restore_current_blog();
wp_send_json_success();
}
/**
* *************************
* DASHBOARD AJAX ACTIONS
***************************/
/**
* Dismiss notice.
*
* @since 1.6.1
*/
public function notice_dismiss() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['id'] ) ) { // Input var okay.
die();
}
$notice_id = sanitize_text_field( wp_unslash( $_POST['id'] ) ); // Input var ok.
delete_option( 'wphb-notice-' . $notice_id . '-show' );
wp_send_json_success();
}
/**
* Dismiss Cloudflare dash notice.
*
* @since 1.7.0
*/
public function cf_notice_dismiss() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
update_site_option( 'wphb-cloudflare-dash-notice', 'dismissed' );
wp_send_json_success();
}
/**
* *************************
* PERFORMANCE TEST AJAX ACTIONS
***************************/
/**
* Run performance test.
*
* Ajax will trigger this method every 3 seconds, until 'finished' = true.
* Logic behind this:
* - Remove quick setup (if not removed) and init performance scan (if not running)
* - Running < 15 seconds - return control to ajax
* - Running 15-89 seconds - check if report is on the server, if not - return to ajax
* - Running 90+ seconds - stop performance test
*/
public function performance_run_test() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$started_at = Performance::is_doing_report();
if ( ! $started_at ) {
Utils::get_module( 'performance' )->init_scan();
wp_send_json_success( array( 'finished' => false ) );
}
$autoloaded_options_size = Utils::get_autoloaded_options_size();
$autoloaded_health = Utils::get_autoloaded_health();
$now = time();
if ( $now >= ( $started_at + 15 ) ) {
$mobile = '-';
$desktop = '-';
// If we're over 1 minute - timeout.
if ( $now >= ( $started_at + 90 ) ) {
Performance::set_doing_report( false );
wp_send_json_success(
array(
'finished' => true,
'mobileScore' => $mobile,
'desktopScore' => $desktop,
'HBSmushFeatures' => Utils::get_active_features(),
'hbPerformanceMetric' => Utils::get_performance_metric_for_mp(),
'aoStatus' => Utils::is_ao_processing() ? 'incomplete' : 'complete',
'getLCPSubmetrics' => Performance::get_lcp_submetrics_for_mp(),
'getAudits' => Performance::get_audits_for_mp(),
'coreWebVitalsMobile' => Performance::core_web_vitals_status( 'mobile' ),
'coreWebVitalsDesktop' => Performance::core_web_vitals_status(),
'hasError' => 'we’re over 1 minute - timeout',
'autoloaderSize' => $autoloaded_options_size,
'autoloaderHealth' => $autoloaded_health,
)
);
}
// The report should be finished by this time, let's get the results.
Performance::refresh_report();
$report = Performance::get_last_report();
// Do not cancel the scan if the report is not latest one.
$current_gmt_time = current_time( 'timestamp', true );
if ( $report && ! is_wp_error( $report ) ) {
$date_time = $report->data->time;
if ( ( $date_time + 120 ) < $current_gmt_time ) {
Settings::delete( 'wphb-stop-report' );
wp_send_json_success( array( 'finished' => false ) );
}
}
// Do not cancel the scan if the report is not ready. We might still have some time to wait.
if ( is_wp_error( $report ) ) {
// Check if the report is still not available on the server.
$error = $report->get_error_data( 'performance-error' );
if ( isset( $error['details'] ) && 'Performance Results not found' === $error['details'] ) {
Settings::delete( 'wphb-stop-report' );
wp_send_json_success( array( 'finished' => false ) );
}
}
/**
* On consecutive scans, sometimes a newer version of the report won't be available, and we will get the
* old version. In that case - skip and continue on the scan.
*/
if ( isset( $report ) && isset( $report->data ) && isset( $report->data->time ) && ( $now - $report->data->time ) > 300 ) {
wp_send_json_success( array( 'finished' => false ) );
}
if ( isset( $report ) && isset( $report->data->mobile->score ) ) {
$mobile = $report->data->mobile->score;
}
if ( isset( $report ) && isset( $report->data->desktop->score ) ) {
$desktop = $report->data->desktop->score;
}
wp_send_json_success(
array(
'finished' => true,
'mobileScore' => $mobile,
'desktopScore' => $desktop,
'HBSmushFeatures' => Utils::get_active_features(),
'hbPerformanceMetric' => Utils::get_performance_metric_for_mp(),
'aoStatus' => Utils::is_ao_processing() ? 'incomplete' : 'complete',
'getLCPSubmetrics' => Performance::get_lcp_submetrics_for_mp(),
'getAudits' => Performance::get_audits_for_mp(),
'coreWebVitalsMobile' => Performance::core_web_vitals_status( 'mobile' ),
'coreWebVitalsDesktop' => Performance::core_web_vitals_status(),
'hasError' => Performance::get_performance_report_error( $report ),
'autoloaderSize' => $autoloaded_options_size,
'autoloaderHealth' => $autoloaded_health,
)
);
}
// Just do nothing until the report is finished.
wp_send_json_success( array( 'finished' => false ) );
}
/**
* Process scan settings.
*
* @since 1.7.1
*/
public function performance_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
$performance = Utils::get_module( 'performance' );
$options = $performance->get_options();
// Get the data from ajax.
parse_str( sanitize_text_field( wp_unslash( $_POST['data'] ) ), $data ); // Input var ok.
// This option can only be updated on network admin.
if ( ! is_multisite() || ( is_multisite() && isset( $data['network_admin'] ) && $data['network_admin'] ) ) {
// I don't like the way this is duplicated in three different modules. This needs to be extracted.
$options['subsite_tests'] = isset( $data['subsite-tests'] ) && 'super-admins' !== $data['subsite-tests'] ? (bool) $data['subsite-tests'] : 'super-admins';
}
$performance->update_options( $options );
wp_send_json_success();
}
/**
* *************************
* CACHING MODULE AJAX ACTIONS
***************************/
/**
* Purge cache for selected module.
*
* @since 1.9.0
*/
public function clear_module_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['module'] ) ) { // Input var okay.
die();
}
$modules = array( 'page_cache', 'gravatar' );
$module = sanitize_text_field( wp_unslash( $_POST['module'] ) ); // Input var ok.
// Works only for supported modules.
if ( ! in_array( $module, $modules, true ) ) {
wp_send_json_success(
array(
'success' => false,
)
);
}
$reload = false;
$current_fast_cgi = Fast_CGI::is_fast_cgi_enabled();
$status = Utils::get_module( $module )->clear_cache();
// Make sure we reload the page if the FastCGI status has changed.
if ( 'page_cache' === $module ) {
$reload = Utils::get_api()->hosting->has_fast_cgi() !== $current_fast_cgi;
}
wp_send_json_success(
array(
'success' => $status,
'reload' => $reload,
)
);
}
/**
* Save fastCGI settings.
*
* @since 3.9.0
*/
public function fast_cgi_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
// Get the data from ajax.
parse_str( wp_unslash( $_POST['data'] ), $data ); // Input var ok.
if ( isset( $data['query_params'] ) && ! empty( $data['query_params'] ) ) {
$data['query_params'] = preg_split( '/[\r\n\t]+/', $data['query_params'] );
} else {
$data['query_params'] = '';
}
if ( isset( $data['bypass_urls'] ) && ! empty( $data['bypass_urls'] ) ) {
$data['bypass_urls'] = preg_split( '/[\r\n\t]+/', $data['bypass_urls'] );
} else {
$data['bypass_urls'] = '';
}
$data['ttl'] = trim( $data['ttl'] );
$preload = isset( $data['preload'] ) && isset( $data['preload']['enabled'] ) ? (bool) $data['preload']['enabled'] : false;
$existing_settings = Fast_CGI::wphb_fast_cgi_data();
$settings_modified = array();
if ( ! empty( $existing_settings ) ) {
if ( $data['ttl'] !== trim( $existing_settings->ttl ) ) {
$settings_modified[] = 'cache_lifetime';
}
if ( $data['bypass_urls'] !== $existing_settings->bypass_urls ) {
$settings_modified[] = 'exclude_url';
}
if ( $data['query_params'] !== $existing_settings->query_params ) {
$settings_modified[] = 'cache_query_param';
}
}
$error_message = '';
if ( ! empty( $data ) && ! empty( $settings_modified ) ) {
$response = Utils::get_api()->hosting->wphb_update_fast_cgi_settings( $data );
$error_message = is_wp_error( $response ) ? $response->get_error_message() : '';
}
$module = Utils::get_module( 'page_cache' );
$options = $module->get_options();
$preload = isset( $data['preload'] ) && isset( $data['preload']['enabled'] ) ? true : false;
$home_page = isset( $data['preload_type']['home_page'] ) ? $data['preload_type']['home_page'] : false;
$on_clear = isset( $data['preload_type']['on_clear'] ) ? $data['preload_type']['on_clear'] : false;
if ( $preload !== $options['preload'] ) {
$settings_modified[] = 'preload_caching';
} elseif ( ! empty( $preload ) && ( wp_validate_boolean( $home_page ) !== wp_validate_boolean( $options['preload_type']['home_page'] ) || wp_validate_boolean( $on_clear ) !== wp_validate_boolean( $options['preload_type']['on_clear'] ) ) ) {
$settings_modified[] = 'preload_caching';
}
// Cache preload.
$options['preload'] = $preload;
if ( $options['preload'] ) {
$options['preload_type']['home_page'] = isset( $data['preload_type']['home_page'] ) && $data['preload_type']['home_page'];
$options['preload_type']['on_clear'] = isset( $data['preload_type']['on_clear'] ) && $data['preload_type']['on_clear'];
}
$module->update_options( $options );
$settings = $module->get_settings();
$settings['settings']['comment_clear'] = isset( $data['settings']['comment_clear'] ) && $data['settings']['comment_clear'];
$settings['settings']['clear_update'] = isset( $data['settings']['clear_update'] ) && $data['settings']['clear_update'];
$module->save_settings( $settings );
if ( ! empty( $settings_modified ) ) {
Utils::get_module( 'page_cache' )->clear_cache();
}
wp_send_json_success(
array(
'success' => true,
'fastCGIResponse' => $error_message,
'settingsModified' => ! empty( $settings_modified ) ? implode( ',', $settings_modified ) : '',
'cacheLifetime' => ! empty( $data['ttl'] ) ? $data['ttl'] / 60 : $data['ttl'],
'preloadHomepage' => isset( $options['preload_type'] ) && $options['preload_type']['home_page'] ? 'enabled' : 'disabled',
)
);
}
/**
* Save page caching settings.
*
* @since 1.9.0
*/
public function page_cache_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
parse_str( wp_unslash( $_POST['data'] ), $data ); // Input var ok.
$page_types = array();
$custom_post_types = array();
$url_strings = '';
$user_agents = '';
$cookies = '';
if ( isset( $data['page_types'] ) && is_array( $data['page_types'] ) ) { // Input var ok.
$page_types = array_keys( wp_unslash( $data['page_types'] ) ); // Input var ok.
}
if ( isset( $data['custom_post_types'] ) && is_array( $data['custom_post_types'] ) ) { // Input var ok.
$custom_post_types_data = wp_unslash( $data['custom_post_types'] ); // Input var ok.
foreach ( $custom_post_types_data as $custom_post_type => $value ) {
if ( $value ) {
$custom_post_types[] = $custom_post_type;
}
}
}
$cache_settings = Page_Cache::get_default_settings();
if ( isset( $data['settings'] ) ) {
$cache_settings = wp_parse_args( $data['settings'], $cache_settings['settings'] );
} else {
$cache_settings = array_map( '__return_false', $cache_settings['settings'] );
}
$cache_settings = array_map( 'absint', $cache_settings );
if ( isset( $data['url_strings'] ) ) { // Input var ok.
$url_strings = sanitize_textarea_field( wp_unslash( $data['url_strings'] ) ); // Input var okay.
$url_strings = preg_split( '/[\r\n\t ]+/', $url_strings );
foreach ( $url_strings as $id => $string ) {
$string = str_replace( '\\', '', $string );
$string = str_replace( '/', '\/', $string );
$string = preg_replace( '/.php$/', '\\.php', $string );
$string = preg_replace( '/.xml$/', '\\.xml', $string );
$string = preg_replace( '/.yml$/', '\\.yml', $string );
$url_strings[ $id ] = $string;
}
}
if ( isset( $data['user_agents'] ) ) { // Input var ok.
$user_agents = sanitize_textarea_field( wp_unslash( $data['user_agents'] ) ); // Input var okay.
$user_agents = preg_split( '/[\r\n\t]+/', $user_agents );
}
if ( isset( $data['cookies'] ) ) { // Input var ok.
$cookies = sanitize_textarea_field( wp_unslash( $data['cookies'] ) ); // Input var okay.
$cookies = preg_split( '/[\r\n\t]+/', $cookies );
}
$settings['page_types'] = $page_types;
$settings['custom_post_types'] = $custom_post_types;
$settings['settings'] = $cache_settings;
$settings['exclude']['url_strings'] = $url_strings;
$settings['exclude']['user_agents'] = $user_agents;
$settings['exclude']['cookies'] = $cookies;
$module = Utils::get_module( 'page_cache' );
$options = $module->get_options();
$existing_settings = $module->get_settings();
$existing_options = $options;
if ( isset( $data['settings']['admins_disable_caching'] ) && 1 === absint( $data['settings']['admins_disable_caching'] ) ) {
$options['enabled'] = 'blog-admins';
} elseif ( $module->is_active() ) {
$options['enabled'] = true;
}
// Integrations.
$defaults = Settings::get_default_settings();
if ( isset( $data['integrations'] ) ) {
$options['integrations'] = wp_parse_args( $data['integrations'], $defaults['page_cache']['integrations'] );
} else {
$options['integrations'] = array_map( '__return_false', $defaults['page_cache']['integrations'] );
}
// Cache preload.
$options['preload'] = isset( $data['preload'] ) && isset( $data['preload']['enabled'] ) ? (bool) $data['preload']['enabled'] : false;
if ( $options['preload'] ) {
$options['preload_type']['home_page'] = isset( $data['preload_type']['home_page'] ) && $data['preload_type']['home_page'];
$options['preload_type']['on_clear'] = isset( $data['preload_type']['on_clear'] ) && $data['preload_type']['on_clear'];
}
// Clear cache interval. Only update, when option is enabled.
$settings['clear_interval']['enabled'] = isset( $data['clear_interval']['enabled'] );
if ( 'days' === $data['clear_interval']['period'] ) {
$interval = $data['clear_interval']['interval'] * 24;
} else {
$interval = $data['clear_interval']['interval'];
}
$settings['clear_interval']['interval'] = $interval;
$settings_modified = array();
if ( ! empty( $existing_settings ) ) {
$preload = isset( $data['preload'] ) && isset( $data['preload']['enabled'] ) ? true : false;
$home_page = isset( $data['preload_type']['home_page'] ) ? $data['preload_type']['home_page'] : false;
$on_clear = isset( $data['preload_type']['on_clear'] ) ? $data['preload_type']['on_clear'] : false;
if ( $preload !== $existing_options['preload'] ) {
$settings_modified[] = 'preload_caching';
} elseif ( ! empty( $preload ) && ( wp_validate_boolean( $home_page ) !== wp_validate_boolean( $existing_options['preload_type']['home_page'] ) || wp_validate_boolean( $on_clear ) !== wp_validate_boolean( $existing_options['preload_type']['on_clear'] ) ) ) {
$settings_modified[] = 'preload_caching';
}
$cache_identifier = isset( $data['settings']['cache_identifier'] ) ? $data['settings']['cache_identifier'] : false;
if ( wp_validate_boolean( $cache_identifier ) !== wp_validate_boolean( $existing_settings['settings']['cache_identifier'] ) ) {
$settings_modified[] = 'identify_cached_pages';
}
$debug_log = isset( $data['settings']['debug_log'] ) ? $data['settings']['debug_log'] : false;
if ( wp_validate_boolean( $debug_log ) !== wp_validate_boolean( $existing_settings['settings']['debug_log'] ) ) {
$settings_modified[] = 'debug_log';
}
$comment_clear = isset( $data['settings']['comment_clear'] ) ? $data['settings']['comment_clear'] : false;
if ( wp_validate_boolean( $comment_clear ) !== wp_validate_boolean( $existing_settings['settings']['comment_clear'] ) ) {
$settings_modified[] = 'purge_on_comment';
}
if ( $page_types !== $existing_settings['page_types'] ) {
$settings_modified[] = 'hb_page_types';
}
$clear_interval = isset( $data['clear_interval']['enabled'] ) ? $data['clear_interval']['enabled'] : false;
if ( $clear_interval !== $existing_settings['clear_interval']['enabled'] ) {
$settings_modified[] = 'hb_cache_interval';
} elseif ( ! empty( $clear_interval ) && ( $data['clear_interval']['period'] !== $existing_settings['clear_interval']['period'] || $interval !== $existing_settings['clear_interval']['interval'] ) ) {
$settings_modified[] = 'hb_cache_interval';
}
$varnish = isset( $data['integrations']['varnish'] ) ? $data['integrations']['varnish'] : false;
if ( wp_validate_boolean( $varnish ) !== wp_validate_boolean( $existing_options['integrations']['varnish'] ) ) {
$settings_modified[] = 'hb_integration_varnish';
}
$opcache = isset( $data['integrations']['opcache'] ) ? $data['integrations']['opcache'] : false;
if ( wp_validate_boolean( $opcache ) !== wp_validate_boolean( $existing_options['integrations']['opcache'] ) ) {
$settings_modified[] = 'hb_integration_opcache';
}
if ( $url_strings !== $existing_settings['exclude']['url_strings'] || $user_agents !== $existing_settings['exclude']['user_agents'] || $cookies !== $existing_settings['exclude']['cookies'] ) {
$settings_modified[] = 'hb_exclusions';
}
if ( $url_strings !== $existing_settings['exclude']['url_strings'] ) {
$settings_modified[] = 'hb_settings_url_queries';
}
$clear_update = isset( $data['settings']['clear_update'] ) ? $data['settings']['clear_update'] : false;
if ( wp_validate_boolean( $clear_update ) !== wp_validate_boolean( $existing_settings['settings']['clear_update'] ) ) {
$settings_modified[] = 'hb_settings_full_purge';
}
$mobile = isset( $data['settings']['mobile'] ) ? $data['settings']['mobile'] : false;
if ( wp_validate_boolean( $mobile ) !== wp_validate_boolean( $existing_settings['settings']['mobile'] ) ) {
$settings_modified[] = 'hb_settings_mobile';
}
}
$module->update_options( $options );
$module->save_settings( $settings );
wp_send_json_success(
array(
'success' => true,
'settingsModified' => ! empty( $settings_modified ) ? implode( ',', $settings_modified ) : 'na',
'preloadHomepage' => isset( $options['preload_type'] ) && $options['preload_type']['home_page'] ? 'enabled' : 'disabled',
)
);
}
/**
* Clear cache for selected page, when 'clear cache' button is clicked from Gutenberg post edit screen.
*
* @since 1.9.4
*/
public function gutenberg_clear_post_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) || ! isset( $_POST['postId'] ) ) { // Input var okay.
die();
}
$id = absint( wp_unslash( $_POST['postId'] ) );
Utils::get_module( 'page_cache' )->clear_cache_action( $id );
wp_send_json_success();
}
/**
* Cancel cache preloading.
*
* @since 2.1.0
*/
public function cancel_cache_preload() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
die();
}
$preloader = new Preload();
$preloader->cancel_process();
wp_send_json_success();
}
/**
* Remove the advanced-cache.php file.
*
* @since 3.1.1
*/
public function remove_advanced_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
die();
}
$adv_cache_file = dirname( get_theme_root() ) . '/advanced-cache.php';
if ( file_exists( $adv_cache_file ) ) {
unlink( $adv_cache_file );
}
wp_send_json_success();
}
/**
* Disable FastCGI cache.
*
* This duplicates Admin\Ajax\disable_fast_cgi()
*
* @since 3.4.0
*
* @return void
*/
public function disable_fast_cgi() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
die();
}
$response = Utils::get_api()->hosting->toggle_fast_cgi( false );
$error_message = is_wp_error( $response ) ? $response->get_error_message() : '';
// Get page cache module.
$page_cache = Utils::get_module( 'page_cache' );
$options = $page_cache->get_options();
// Disable page cache.
$page_cache->disable();
wp_send_json_success(
array(
'fastCGIResponse' => $error_message,
'preloadHomepage' => isset( $options['preload_type'] ) && $options['preload_type']['home_page'] ? 'enabled' : 'disabled',
)
);
}
/**
* Switch cache method.
*
* @since 3.9.0
*
* @return void
*/
public function switch_cache_method() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$method = sanitize_text_field( wp_unslash( $_POST['method'] ) ); // Input var ok.
$is_fast_cgi_activated = null;
$error_message = '';
$module = Utils::get_module( 'page_cache' );
$activate_hosting_static_cache = null;
if ( 'hosting_static_cache' === $method ) {
$activate_hosting_static_cache = true;
} elseif ( 'local_page_cache' === $method ) {
$activate_hosting_static_cache = false;
}
if ( ! is_null( $activate_hosting_static_cache ) ) {
$response = Utils::get_api()->hosting->toggle_fast_cgi( $activate_hosting_static_cache );
if ( $activate_hosting_static_cache && isset( $response->is_active ) ) {
Fast_CGI::update_fast_cgi_status( $response->is_active );
}
$error_message = is_wp_error( $response ) ? $response->get_error_message() : '';
$is_fast_cgi_activated = ! empty( $error_message ) ? 'error' : $activate_hosting_static_cache;
if ( 'hosting_static_cache' === $method ) {
$module->disable();
} elseif ( 'local_page_cache' === $method ) {
$module->toggle_service( true, true );
}
}
$options = $module->get_options();
// Clear cache is required at this point because we are changing the cache method.
$module->clear_cache();
wp_send_json_success(
array(
'isFastCGIActivated' => $is_fast_cgi_activated,
'fastCGIResponse' => $error_message,
'method' => $method,
'preloadHomepage' => isset( $options['preload_type'] ) && $options['preload_type']['home_page'] ? 'enabled' : 'disabled',
)
);
}
/**
* Connect to Cloudflare.
*
* @since 3.0.0
*/
public function cloudflare_connect() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$email = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_EMAIL );
$key = filter_input( INPUT_POST, 'key', FILTER_UNSAFE_RAW );
$key = sanitize_text_field( $key );
$token = filter_input( INPUT_POST, 'token', FILTER_UNSAFE_RAW );
$token = sanitize_text_field( $token );
$zone = filter_input( INPUT_POST, 'zone', FILTER_UNSAFE_RAW );
$zone = sanitize_text_field( $zone );
if ( ! ( $email && $key ) && ! $token && ! $zone ) {
$message = esc_html__( 'Cannot process the form. Please define either the Email/API key or the API token.', 'wphb' );
wp_send_json_error( array( 'message' => $message ) );
}
$options = Utils::get_module( 'cloudflare' )->get_options();
$options_updated = false;
if ( ! empty( $email ) && $email !== $options['email'] ) {
$options_updated = true;
$options['email'] = $email;
}
if ( ! empty( $key ) && $key !== $options['api_key'] ) {
$options_updated = true;
$options['api_key'] = $key;
}
// Only try to set token if API key is not defined.
if ( empty( $key ) && ! empty( $token ) && $token !== $options['api_key'] ) {
$options_updated = true;
$options['email'] = ''; // Email is not used with API token.
$options['api_key'] = $token;
}
// Save the current credentials, so we can try and connect with them when we check the zones below.
if ( $options_updated ) {
Utils::get_module( 'cloudflare' )->update_options( $options );
Utils::get_api()->cloudflare->refresh_auth();
}
$zones = Utils::get_module( 'cloudflare' )->get_zones_list();
// This will end processing if zones are an issue.
Utils::get_module( 'cloudflare' )->validate_zones( $zones );
// Set the module as enabled.
if ( ! $options['enabled'] ) {
$options['enabled'] = true;
Utils::get_module( 'cloudflare' )->update_options( $options );
}
$status = Utils::get_module( 'cloudflare' )->process_zones( $zones, $zone );
// Could not match a zone.
if ( ! $status ) {
wp_send_json_success( array( 'zones' => $zones ) );
}
wp_send_json_success();
}
/**
* Purge Cloudflare cache.
*/
public function cloudflare_purge_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
Utils::get_module( 'cloudflare' )->clear_cache();
wp_send_json_success();
}
/**
* Recheck Cloudflare zones.
*/
public function cloudflare_recheck_zones() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$zones = Utils::get_module( 'cloudflare' )->get_zones_list();
// This will end processing if zones are an issue.
Utils::get_module( 'cloudflare' )->validate_zones( $zones );
$status = Utils::get_module( 'cloudflare' )->process_zones( $zones );
// Could not match a zone.
if ( ! $status ) {
wp_send_json_success( array( 'zones' => $zones ) );
}
wp_send_json_success();
}
/**
* Save rss settings.
*
* @since 1.8
*/
public function rss_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
parse_str( sanitize_text_field( wp_unslash( $_POST['data'] ) ), $data ); // Input var ok.
$rss_module = Utils::get_module( 'rss' );
$options = $rss_module->get_options();
$options['duration'] = isset( $data['rss-expiry-time'] ) ? absint( $data['rss-expiry-time'] ) : 0;
$rss_module->update_options( $options );
wp_send_json_success(
array(
'success' => true,
)
);
}
/**
* Parse save cache settings form.
*
* @since 1.8.1
*/
public function save_other_cache_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
parse_str( sanitize_text_field( wp_unslash( $_POST['data'] ) ), $data ); // Input var ok.
$pc_module = Utils::get_module( 'page_cache' );
$options = $pc_module->get_options();
$options['detection'] = isset( $data['detection'] ) ? sanitize_text_field( $data['detection'] ) : 'manual';
// Remove notice if File Change Detection is set to 'auto' or 'none'.
if ( 'auto' === $options['detection'] || 'none' === $options['detection'] ) {
delete_option( 'wphb-notice-cache-cleaned-show' );
}
$pc_module->update_options( $options );
wp_send_json_success(
array(
'success' => true,
)
);
}
/**
* Save Redis cache settings.
*
* @since 2.5.0
*/
public function redis_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$host = filter_input( INPUT_POST, 'host', FILTER_UNSAFE_RAW );
$port = filter_input( INPUT_POST, 'port', FILTER_VALIDATE_INT );
$pass = filter_input( INPUT_POST, 'password', FILTER_UNSAFE_RAW );
$db = filter_input( INPUT_POST, 'db', FILTER_VALIDATE_INT );
$redis_mod = Utils::get_module( 'redis' );
$result = $redis_mod->test_redis_connection( $host, $port, $pass, $db );
if ( 'success' === $result['status'] ) {
$redis_mod->enable( $host, $port, $pass, $db );
wp_send_json_success(
array(
'success' => true,
)
);
} else {
wp_send_json_success(
array(
'success' => false,
'message' => apply_filters( 'wp_hummingbird_redis_error', $result['error'] ),
)
);
}
}
/**
* Toggle Redis object cache setting.
*
* @since 2.5.0
*/
public function redis_toggle_object_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$value = filter_input( INPUT_POST, 'value', FILTER_VALIDATE_BOOLEAN );
Utils::get_module( 'redis' )->toggle_object_cache( $value );
wp_send_json_success( array( 'success' => true ) );
}
/**
* Purge Redis cache.
*
* @since 2.5.0
*/
public function redis_cache_purge() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
Utils::get_module( 'redis' )->clear_cache();
wp_send_json_success( array( 'success' => true ) );
}
/**
* Disconnect Redis.
*
* @since 2.5.0
*/
public function redis_disconnect() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
Utils::get_module( 'redis' )->disable();
wp_send_json_success( array( 'success' => true ) );
}
/**
* *************************
* ASSET OPTIMIZATION AJAX ACTIONS
***************************/
/**
* Toggle CDN.
*
* Used on dashboard page in minification meta box and in the minification module.
* Clear files function at the end clears all cache and on first home page reload, all the files will
* be either moved to CDN or stored local.
*/
public function minification_toggle_cdn() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['value'] ) ) { // Input var okay.
die();
}
$value = filter_input( INPUT_POST, 'value', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
$minify_module = Utils::get_module( 'minify' );
$minify_module->toggle_cdn( $value );
$minify_module->clear_files();
wp_send_json_success();
}
/**
* Toggle logs.
*
* @since 1.7.2
*/
public function minification_toggle_log() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['value'] ) ) { // Input var okay.
die();
}
$value = filter_input( INPUT_POST, 'value', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
$minify = Utils::get_module( 'minify' );
$options = $minify->get_options();
$options['log'] = $value;
$minify->update_options( $options );
wp_send_json_success();
}
/**
* Toggle minification advanced view.
*
* @since 1.7.1
*/
public function minification_toggle_view() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['value'] ) ) { // Input var okay.
die();
}
$type = sanitize_text_field( wp_unslash( $_POST['value'] ) ); // Input var okay.
$available_types = array( 'basic', 'advanced' );
if ( ! in_array( $type, $available_types, true ) ) {
wp_send_json_error();
}
Settings::update_setting( 'view', $type, 'minify' );
// Hide the modal.
$hide = filter_input( INPUT_POST, 'hide', FILTER_VALIDATE_BOOLEAN );
if ( 'basic' === $type ) {
$minify = Utils::get_module( 'minify' );
$minify->set_safe_mode_status( false );
$minify->clear_cache( true, false, true );
if ( true === $hide ) {
delete_option( 'wphb-minification-show-config_modal' );
}
} elseif ( true === $hide ) {
delete_option( 'wphb-minification-show-advanced_modal' );
}
wp_send_json_success();
}
/**
* Start minification scan.
*
* Set a flag that marks the minification check files as started.
*/
public function minification_start_check() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$minify_module = Utils::get_module( 'minify' );
$minify_module->init_scan();
wp_send_json_success(
array(
'steps' => $minify_module->scanner->get_scan_steps(),
)
);
}
/**
* Process step during minification scan.
*/
public function minification_check_step() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$minify_module = Utils::get_module( 'minify' );
$urls = $minify_module->scanner->get_scan_urls();
$current_step = absint( $_POST['step'] ); // Input var ok.
$minify_module->scanner->update_current_step( $current_step );
if ( isset( $urls[ $current_step ] ) ) {
$minify_module->scanner->scan_url( $urls[ $current_step ] );
}
wp_send_json_success();
}
/**
* Cancel minification file check if cancel button pressed.
*
* @since 1.4.5
*/
public function minification_cancel_scan() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$minify_module = Utils::get_module( 'minify' );
$minify_module->toggle_service( false );
$minify_module->clear_cache();
wp_send_json_success();
}
/**
* Finish minification scan.
*/
public function minification_finish_scan() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
Utils::get_module( 'minify' )->scanner->finish_scan();
wp_send_json_success(
array(
'assets_msg' => sprintf(
/* translators: %s - number of assets */
esc_html__( '%s assets found!', 'wphb' ),
Utils::minified_files_count()
),
)
);
}
/**
* Save critical css on minification tools window.
*
* @since 1.8
*/
public function minification_save_extra_optimization_data() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['form'] ) ) { // Input var okay.
die();
}
$minify_options = Settings::get_settings( 'minify' );
$message = __( 'Settings updated', 'wphb' );
parse_str( wp_unslash( $_POST['form'] ), $form ); // Input var ok.
$prev_delay_value = Settings::get_setting( 'delay_js', 'minify' );
$prev_delay_js_exclusions = Settings::get_setting( 'delay_js_exclusions', 'minify' );
$prev_delay_js_timeout = Settings::get_setting( 'delay_js_timeout', 'minify' );
$old_critical_css_option = $minify_options['critical_css'];
$old_critical_css_mode = $minify_options['critical_css_mode'];
$old_critical_page_types = $minify_options['critical_page_types'];
$old_critical_skipped_custom_post_types = $minify_options['critical_skipped_custom_post_types'];
$old_critical_css_type = $minify_options['critical_css_type'];
$old_critical_css_remove_type = $minify_options['critical_css_remove_type'];
$old_critical_css_manual_include = Minify::get_css( 'manual-critical' );
$old_above_fold_load_stylesheet_method = $minify_options['above_fold_load_stylesheet_method'];
if ( ! empty( $form['critical_css_option'] ) ) {
Minify::save_css( $form['critical_css_advanced'], 'manual-critical' );
}
$status = Minify::save_css( $form['critical_css'] );
$delay_js = ! empty( $form['delay_js'] );
$delay_js_keywords_advanced_view = ! empty( $form['delay_js_keywords_advanced_view'] );
$delay_js_exclude_inline_js = ! empty( $form['delay_js_exclude_inline_js'] );
if ( $delay_js_keywords_advanced_view ) {
$delay_js_exclude = html_entity_decode( $form['delay_js_exclude'] ?? '' );
} else {
$delay_js_exclusions = $form['delay_js_exclusions'] ?? '';
$delay_js_exclude = html_entity_decode( is_array( $delay_js_exclusions ) ? implode( "\n", array_map( 'trim', $delay_js_exclusions ) ) : $delay_js_exclusions );
}
$delay_js_timeout = (int) $form['delay_js_timeout'];
Settings::update_setting( 'delay_js', $delay_js, 'minify' );
Settings::update_setting( 'delay_js_exclusions', $delay_js_exclude, 'minify' );
Settings::update_setting( 'delay_js_timeout', $delay_js_timeout, 'minify' );
Settings::update_setting( 'delay_js_exclude_inline_js', $delay_js_exclude_inline_js, 'minify' );
Settings::update_setting( 'delay_js_keywords_advanced_view', $delay_js_keywords_advanced_view, 'minify' );
// DelayJS exclusion rules.
$delay_exclusion_types = array(
'exclusions_files' => 'delay_js_files_exclusion',
'exclusions_posttypes' => 'delay_js_post_types_exclusion',
'exclusions_urls' => 'delay_js_post_urls_exclusion',
'exclusions_plugins' => 'delay_js_plugins_themes_exclusion',
'exclusions_trackers' => 'delay_js_ads_tracker_exclusion',
);
$delay_js_update_type = false;
$is_delay_value_updated = false;
$exclusion_value_updated = false;
$delay_js_mixpanel_values['exclusions_keywords'] = ! empty( $delay_js_exclusions ) ? $delay_js_exclusions : 'na';
foreach ( $delay_exclusion_types as $key => $type ) {
$old_exclusions = $minify_options[ $type ] ?? array();
$new_exclusions = isset( $form[ $type ] ) ? Utils::wphb_sanitize_data( $form[ $type ] ) : array();
$delay_js_mixpanel_values[ $key ] = 'exclusions_urls' === $key ? ( $new_exclusions ? array_map( 'get_permalink', $new_exclusions ) : 'na' ) : ( $new_exclusions ? $new_exclusions : 'na' );
if ( $old_exclusions !== $new_exclusions ) {
$exclusion_value_updated = true;
}
Settings::update_setting( $type, $new_exclusions, 'minify' );
}
// Track DelayJS modified values.
if ( ! empty( $delay_js ) && $prev_delay_value === $delay_js ) {
$is_modified = $prev_delay_js_exclusions !== $delay_js_exclude || $prev_delay_js_timeout !== $delay_js_timeout || $exclusion_value_updated;
if ( $is_modified ) {
$delay_js_update_type = 'modified';
$is_delay_value_updated = true;
}
}
// Critical CSS exclusion rules.
$critical_css_settings = array(
'critical_css_files_exclusion' => array(
'value' => Utils::wphb_sanitize_data( $form['critical_css_files_exclusion'] ?? array() ),
'mixpanel_key' => 'exclusions_files',
),
'critical_css_post_urls_exclusion' => array(
'value' => Utils::wphb_sanitize_data( $form['critical_css_post_urls_exclusion'] ?? array() ),
'mixpanel_key' => 'exclusions_urls',
),
'critical_css_plugins_themes_exclusion' => array(
'value' => Utils::wphb_sanitize_data( $form['critical_css_plugins_themes_exclusion'] ?? array() ),
'mixpanel_key' => 'exclusions_plugins',
),
'critical_css_keywords' => array(
'value' => Utils::wphb_sanitize_data( $form['critical_css_keywords'] ?? array() ),
'mixpanel_key' => 'exclusions_keywords',
),
'critical_page_types' => array(
'value' => array_diff( Page_Cache::get_page_types( true ), Utils::wphb_sanitize_data( $form['critical_css_post_types_exclusion'] ?? array() ) ),
'mixpanel_key' => 'exclusions_posttypes',
),
'critical_skipped_custom_post_types' => array(
'value' => array_diff( Utils::wphb_sanitize_data( $form['critical_css_post_types_exclusion'] ?? array() ), Page_Cache::get_page_types( true ) ),
'mixpanel_key' => 'exclusions_posttypes',
),
);
$critical_css_mixpanel_values = array();
$critical_css_exclusion_value_updated = false;
foreach ( $critical_css_settings as $setting_name => $setting_data ) {
$new_exclusions = $setting_data['value'];
$mixpanel_key = $setting_data['mixpanel_key'];
$old_exclusions = $minify_options[ $setting_name ] ?? array();
$mixpanel_values = 'exclusions_urls' === $mixpanel_key ? ( $new_exclusions ? array_map( 'get_permalink', $new_exclusions ) : 'na' ) : ( $new_exclusions ? $new_exclusions : 'na' );
$critical_css_mixpanel_values[ $mixpanel_key ] = 'critical_skipped_custom_post_types' === $setting_name ? ( $form['critical_css_post_types_exclusion'] ?? 'na' ) : $mixpanel_values;
if ( $old_exclusions !== $new_exclusions ) {
$critical_css_exclusion_value_updated = true;
}
Settings::update_setting( $setting_name, $new_exclusions, 'minify' );
}
// Preload fonts.
$prev_font_optimization = Settings::get_setting( 'font_optimization', 'minify' );
$prev_font_swap = Settings::get_setting( 'font_swap', 'minify' );
$font_optimization = ! empty( $form['font_optimization'] );
$preload_fonts = $form['preload_fonts'];
$preload_fonts = html_entity_decode( $preload_fonts );
$font_swap = ! empty( $form['font_swap'] );
$font_display_value = $form['font_display_value'];
$preload_fonts_mode = $form['preload_fonts_mode'];
Settings::update_setting( 'font_optimization', $font_optimization, 'minify' );
Settings::update_setting( 'preload_fonts', $preload_fonts, 'minify' );
Settings::update_setting( 'font_swap', $font_swap, 'minify' );
Settings::update_setting( 'font_display_value', $font_display_value, 'minify' );
if ( Utils::is_member() ) {
Settings::update_setting( 'preload_fonts_mode', $preload_fonts_mode, 'minify' );
}
// Track font value to MP.
$font_optimization_update_type = $prev_font_optimization !== $font_optimization ? ( ! empty( $font_optimization ) ? 'activate' : 'deactivate' ) : '';
$font_swap_update_type = $prev_font_swap !== $font_swap ? ( ! empty( $font_swap ) ? 'activate' : 'deactivate' ) : '';
// Update Critical CSS option.
$critical_css_mode = $form['critical_css_mode'];
$critical_css_option = ! empty( $form['critical_css_option'] ) && 'critical_css' === $critical_css_mode;
$critical_css_type = $form['critical_css_type'];
$critical_css_remove_type = ! empty( $form['critical_css_remove_type'] ) ? $form['critical_css_remove_type'] : '';
$is_status_tag_needs_update = false;
$above_fold_load_stylesheet_method = $form['above_fold_load_stylesheet_method'];
Settings::update_setting( 'critical_css', $critical_css_option, 'minify' );
Settings::update_setting( 'critical_css_type', $critical_css_type, 'minify' );
Settings::update_setting( 'critical_css_remove_type', $critical_css_remove_type, 'minify' );
Settings::update_setting( 'critical_css_mode', $critical_css_mode, 'minify' );
Settings::update_setting( 'above_fold_load_stylesheet_method', $above_fold_load_stylesheet_method, 'minify' );
// In Case of toggle changes generate critical css enabled, clear the data otherwise.
if ( $old_critical_css_option !== $critical_css_option || $old_critical_css_type !== $critical_css_type ) {
if ( ! empty( $critical_css_option ) ) {
$is_status_tag_needs_update = true;
$critical_status = Utils::get_module( 'critical_css' )->regenerate_critical_css();
$message = __( 'Settings updated. Generating Critical CSS, this could take about a minute.', 'wphb' );
}
}
// This will require a clear cache call.
Utils::get_module( 'page_cache' )->clear_cache();
// Track critical css modified values.
$settings_modified = array();
$settings_default = array();
$manual_inclusion = 'na';
$is_critical_value_updated = $old_critical_css_option !== $critical_css_option;
$critical_css_update_type = ! empty( $critical_css_option ) ? 'activate' : 'deactivate';
if ( ! empty( $critical_css_option ) && $old_critical_css_option === $critical_css_option ) {
if ( $old_critical_css_type !== $critical_css_type || $old_critical_css_remove_type !== $critical_css_remove_type || $old_above_fold_load_stylesheet_method !== $above_fold_load_stylesheet_method ) {
$is_critical_value_updated = true;
$critical_css_update_type = 'modified';
}
if ( $critical_css_exclusion_value_updated ) {
$settings_modified[] = 'exclusions';
} else {
$settings_default[] = 'exclusions';
}
if ( $old_critical_css_manual_include !== $form['critical_css_advanced'] ) {
$settings_modified[] = 'inclusions';
} else {
$settings_default[] = 'inclusions';
}
$manual_inclusion = ! empty( $form['critical_css_advanced'] ) ? 'active' : 'inactive';
}
$critical_css_update_type = ! empty( $settings_modified ) ? 'modified' : $critical_css_update_type;
$is_critical_value_updated = ! empty( $settings_modified ) ? true : $is_critical_value_updated;
// Track the location for mixpanel.
$location = 'eo_settings';
if ( ! empty( $form['critical_css'] ) && ! empty( $critical_css_option ) && $old_critical_css_option !== $critical_css_option && $old_critical_css_mode !== $critical_css_mode ) {
$location = 'legacy';
}
wp_send_json_success(
array(
'delay_js' => $delay_js,
'delay_js_update_type' => $delay_js_update_type,
'is_delay_value_updated' => $is_delay_value_updated,
'delay_js_timeout' => $delay_js_timeout,
'delay_js_exclude' => $delay_js_exclude,
'delayJsMixpanelValues' => $delay_js_mixpanel_values,
'excludedFiles' => ! empty( $delay_js_exclude ) ? explode( '\n', $delay_js_exclude ) : '',
'updateType' => $critical_css_update_type,
'isCriticalValueUpdated' => $is_critical_value_updated,
'critical_css' => $critical_css_option,
'settingsModified' => implode( ',', $settings_modified ),
'settingsDefault' => implode( ',', $settings_default ),
'criticalCssMixpanelValues' => $critical_css_mixpanel_values,
'manualInclusion' => $manual_inclusion,
'mode' => Utils::get_module( 'critical_css' )->get_critical_mode_for_mp(),
'location' => $location,
'success' => $status['success'],
'message' => $message,
'isStatusTagNeedsUpdate' => $is_status_tag_needs_update,
'htmlForStatusTag' => Utils::get_module( 'critical_css' )->get_html_for_status_tag(),
'fontOptimizationUpdateType' => $font_optimization_update_type,
'fontSwapUpdateType' => $font_swap_update_type,
)
);
}
/**
* Parse custom asset path directory.
*
* @since 1.9
*/
public function minification_update_asset_path() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['value'] ) ) { // Input var ok.
die();
}
$path = sanitize_text_field( wp_unslash( $_POST['value'] ) ); // Input var ok.
Utils::get_module( 'minify' )->clear_cache( false );
Filesystem::instance()->purge_ao_cache();
// Update to new setting value.
Settings::update_setting( 'file_path', $path, 'minify' );
wp_send_json_success(
array(
'success' => true,
'message' => '',
)
);
}
/**
* Reset individual file.
*
* @since 1.9.2
*/
public function minification_reset_asset() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['value'] ) ) { // Input var ok.
die();
}
$files = explode( ' ', sanitize_text_field( wp_unslash( $_POST['value'] ) ) ); // Input var ok.
$type = '';
$handle = '';
foreach ( $files as $item ) {
if ( 'css' === strtolower( $item ) ) {
$type = 'styles';
continue;
}
if ( 'js' === strtolower( $item ) ) {
$type = 'scripts';
continue;
}
$handle = $item;
}
if ( ! $handle || ! $type ) {
wp_send_json_error(
array(
'message' => __( 'Error removing asset file.', 'wphb' ),
)
);
}
Utils::get_module( 'minify' )->clear_file( $handle, $type );
wp_send_json_success(
array(
'success' => true,
)
);
}
/**
* Update network settings.
*
* @since 2.0.0
*/
public function minification_update_network_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['settings'] ) ) { // Input var okay.
die();
}
wp_parse_str( sanitize_text_field( wp_unslash( urldecode( $_POST['settings'] ) ) ), $form );
if ( isset( $form['enabled'] ) && 'super-admins' !== $form['enabled'] ) {
$form['enabled'] = (bool) $form['enabled'];
}
$minify = Utils::get_module( 'minify' );
$options = $minify->get_options();
$options['use_cdn'] = isset( $form['use_cdn'] ) && $form['use_cdn'];
$options['log'] = isset( $form['log'] ) && $form['log'];
$options['file_path'] = isset( $form['file_path'] ) ? htmlspecialchars( $form['file_path'] ) : '';
$minify->update_options( $options );
if ( ! isset( $form['network'] ) ) {
$minify->toggle_service( false, true );
} else {
$minify->toggle_service( $form['enabled'], true );
}
wp_send_json_success(
array(
'success' => true,
)
);
}
/**
* Update the CDN exclude list
*
* @since 2.4.0
*/
public function minification_save_exclude_list() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) {
die();
}
$assets = filter_input( INPUT_POST, 'data', FILTER_UNSAFE_RAW );
$assets = json_decode( html_entity_decode( $assets ), true );
Settings::update_setting( 'nocdn', $assets, 'minify' );
// This will require a clear cache call.
Utils::get_module( 'minify' )->clear_cache( false );
wp_send_json_success();
}
/**
* Skip Asset Optimization upgrade.
*
* @since 2.6.0
*/
public function minification_skip_upgrade() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
// Switch to advanced mode.
Settings::update_setting( 'view', 'advanced', 'minify' );
// Remove the upgrade modal.
delete_option( 'wphb_do_minification_upgrade' );
wp_send_json_success();
}
/**
* Perform Asset Optimization upgrade.
*
* @since 2.6.0
*/
public function minification_do_upgrade() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
Settings::update_setting( 'view', 'basic', 'minify' );
Utils::get_module( 'minify' )->clear_cache( true, true, true );
// Remove the upgrade modal.
delete_option( 'wphb_do_minification_upgrade' );
wp_send_json_success();
}
/**
* *************************
* ADVANCED TOOLS AJAX ACTIONS
***************************/
/**
* Cleanup selected data type from db.
*
* @since 1.8
*/
public function advanced_db_delete_data() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
$available_types = array( 'revisions', 'drafts', 'trash', 'spam', 'trash_comment', 'expired_transients', 'transients', 'all' );
$type = sanitize_text_field( wp_unslash( $_POST['data'] ) ); // Input var ok.
if ( ! in_array( $type, $available_types, true ) ) {
wp_send_json_error(
array(
'message' => __( 'Invalid type specified.', 'wphb' ),
)
);
}
$adv_module = Utils::get_module( 'advanced' );
$removed = $adv_module->delete_db_data( $type );
if ( ! is_array( $removed ) || ( 0 === $removed['items'] && 0 > $removed['left']->total ) ) {
wp_send_json_error(
array(
'message' => __( 'Error deleting data.', 'wphb' ),
)
);
}
wp_send_json_success(
array(
/* translators: %d: number of database entries */
'message' => sprintf( __( '%d database entries were deleted successfully.', 'wphb' ), $removed['items'] ),
'left' => $removed['left'],
)
);
}
/**
* Update settings for advanced tools.
*
* @since 1.8
*/
public function advanced_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['form'] ) ) { // Input var okay.
wp_die();
}
$form = sanitize_text_field( wp_unslash( $_POST['form'] ) ); // Input var ok.
parse_str( wp_unslash( $_POST['data'] ), $data ); // Input var ok.
$adv_module = Utils::get_module( 'advanced' );
$options = $adv_module->get_options();
$remove_query_strings = $options['query_string'];
$disable_cart_fragments = $options['cart_fragments'];
$remove_emojis = $options['emoji'];
$prefetch_dns = $options['prefetch'];
$lazy_comments = $options['lazy_load']['enabled'];
$preconnect = $options['preconnect'];
$viewport_meta = $options['viewport_meta'];
// General settings tab.
if ( 'advanced-general-settings' === $form ) {
$skip = isset( $options['query_strings_global'] ) && $options['query_strings_global'] && ! Utils::is_ajax_network_admin();
if ( ! $skip ) {
$options['query_string'] = isset( $data['query_strings'] ) && 'on' === $data['query_strings'];
$options['query_strings_global'] = isset( $data['query_strings_global'] ) && 'on' === $data['query_strings_global'];
}
if ( isset( $data['cart_fragments'] ) && 'on' === $data['cart_fragments'] ) {
$options['cart_fragments'] = isset( $data['cart_fragments_value'] ) && '1' === $data['cart_fragments_value'] ? true : 'all';
} else {
$options['cart_fragments'] = false;
}
$skip = isset( $options['emoji_global'] ) && $options['emoji_global'] && ! Utils::is_ajax_network_admin();
if ( ! $skip ) {
$options['emoji'] = isset( $data['emojis'] ) && 'on' === $data['emojis'];
$options['emoji_global'] = isset( $data['emojis_global'] ) && 'on' === $data['emojis_global'];
}
$options['post_revisions'] = '';
if ( isset( $data['post_revisions'] ) && $data['post_revisions'] >= 0 ) {
$options['post_revisions'] = $data['post_revisions'];
}
$options['viewport_meta'] = isset( $data['viewport_meta'] ) && 'on' === $data['viewport_meta'];
$options['prefetch'] = array();
if ( isset( $data['url_strings'] ) && ! empty( $data['url_strings'] ) ) {
$options['prefetch'] = preg_split( '/[\r\n\t ]+/', $data['url_strings'] );
}
$options['preconnect'] = array();
if ( isset( $data['preconnect_strings'] ) && ! empty( $data['preconnect_strings'] ) ) {
$options['preconnect'] = preg_split( '/[\r\n\t]+/', $data['preconnect_strings'] );
}
}
// Lazy load tab.
if ( 'advanced-lazy-settings' === $form ) {
$options['lazy_load'] = array(
'enabled' => isset( $data['lazy_load'] ) && 'on' === $data['lazy_load'],
'method' => isset( $data['method'] ) ? $data['method'] : 'click',
'button' => isset( $data['button'] ) ? $data['button'] : '',
'threshold' => isset( $data['threshold'] ) ? $data['threshold'] : 0,
'preload' => isset( $data['preload'] ) && 'on' === $data['preload'],
);
}
// Track MP event.
$mp_events = array();
if ( $remove_query_strings !== $options['query_string'] ) {
$mp_events[] = array( 'remove_query_strings' => $options['query_string'] );
}
if ( $disable_cart_fragments !== $options['cart_fragments'] ) {
$mp_events[] = array( 'disable_cart_fragments' => $options['cart_fragments'] );
}
if ( $remove_emojis !== $options['emoji'] ) {
$mp_events[] = array( 'remove_emojis' => $options['emoji'] );
}
if ( $prefetch_dns !== $options['prefetch'] ) {
$mp_events[] = array( 'prefetch_dns' => ! empty( $options['prefetch'] ) ? true : false );
}
if ( $preconnect !== $options['preconnect'] ) {
$mp_events[] = array( 'preconnect_domains' => ! empty( $options['preconnect'] ) ? true : false );
}
if ( $lazy_comments !== $options['lazy_load']['enabled'] ) {
$mp_events[] = array( 'lazy_comments' => $options['lazy_load']['enabled'] );
}
if ( $viewport_meta !== $options['viewport_meta'] ) {
$mp_events[] = array( 'viewport_meta' => $options['viewport_meta'] );
}
$adv_module->update_options( $options );
wp_send_json_success(
array(
'success' => true,
'mp_events' => $mp_events,
)
);
}
/**
* Purge page cache preloader.
*
* @since 2.7.0
*/
public function advanced_purge_cache() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
die();
}
$preloader = new Preload();
$preloader->clear_all_queue();
wp_send_json_success();
}
/**
* Purge asset optimization groups.
*
* @since 2.7.0
*/
public function advanced_purge_minify() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
die();
}
Utils::get_module( 'minify' )->clear_files();
wp_send_json_success();
}
/**
* Purge asset optimization orphaned data.
*
* @since 2.7.0
*/
public function advanced_purge_orphaned() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
die();
}
$rows = filter_input( INPUT_POST, 'rows', FILTER_SANITIZE_NUMBER_INT );
Utils::get_module( 'advanced' )->purge_orphaned_step( (int) $rows );
$load = sys_getloadavg();
wp_send_json_success(
array(
'highCPU' => $load[0] > 0.5,
)
);
}
/**
* *************************
* LOGGER MODULE AJAX ACTIONS
***************************/
/**
* Clear logs.
*
* @since 1.9.2
*/
public function logger_clear() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['module'] ) ) { // Input var okay.
die();
}
$slug = sanitize_text_field( wp_unslash( $_POST['module'] ) ); // Input var ok.
$module = Utils::get_module( $slug );
if ( ! $module ) {
wp_send_json_success(
array(
'success' => false,
'message' => __( 'Module not found', 'wphb' ),
)
);
}
$status = WP_Hummingbird::get_instance()->core->logger->clear( $slug );
if ( ! $status ) {
wp_send_json_success(
array(
'success' => false,
'message' => __( 'Log file not found or empty', 'wphb' ),
)
);
}
wp_send_json_success(
array(
'success' => true,
'message' => __( 'Log file purged', 'wphb' ),
)
);
}
/**
* *************************
* HUMMINGBIRD ADMIN SETTINGS AJAX ACTIONS
***************************/
/**
* Save Admin settings.
*
* @since 1.9.3
*/
public function admin_settings_save_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['form_data'] ) ) { // Input var okay.
die();
}
parse_str( sanitize_text_field( wp_unslash( $_POST['form_data'] ) ), $data ); // Input var ok.
$prev_mixpanel_value = Settings::get_setting( 'tracking', 'settings' );
$settings = Settings::get_settings( 'settings' );
foreach ( $data as $setting => $value ) {
if ( ! isset( $settings[ $setting ] ) ) {
continue;
}
if ( 'control' === $setting ) {
$settings[ $setting ] = $this->process_cache_control_settings( $data );
} else {
$settings[ $setting ] = (bool) $value;
}
}
Settings::update_settings( $settings, 'settings' );
$is_mixpanel_value_updated = $prev_mixpanel_value !== $settings['tracking'] ? true : false;
do_action( 'wphb_mixpanel_usage_tracking_value_update', $is_mixpanel_value_updated, $settings['tracking'] );
wp_send_json_success(
array(
'isMixpanelValueUpdated' => $is_mixpanel_value_updated,
'notice' => esc_html__( 'Settings updated', 'wphb' ),
)
);
}
/**
* Process cache control settings.
*
* @since 3.0.1
*
* @param array $data Form data.
*/
private function process_cache_control_settings( $data ) {
if ( false === (bool) $data['control'] ) {
return false;
}
if ( isset( $data['type'] ) && 'all' === $data['type'] ) {
return true;
}
$available_cache_types = Utils::get_active_cache_modules();
$types = array();
foreach ( $available_cache_types as $type => $name ) {
if ( ! isset( $data[ $type ] ) ) {
continue;
}
$types[] = $type;
}
return $types;
}
/**
* Reset plugin settings.
*
* @since 2.0.0
*/
public function reset_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
wp_send_json_success();
}
/**
* Deletes the flag to show upgrade summary.
*/
public function hide_upgrade_summary() {
// Check permission.
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
delete_site_option( 'wphb_show_upgrade_summary' );
wp_send_json_success();
}
/**
* Export settings.
*
* @since 2.6.0
*/
public function admin_settings_export_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$data = array(
'version' => WPHB_VERSION,
'plugins' => get_option( 'active_plugins' ),
'network_plugins' => get_site_option( 'active_sitewide_plugins' ),
'theme' => get_stylesheet(),
'settings' => array(),
);
// Right now we are exporting only asset optimization settings.
$minify_options = Settings::get_settings( 'minify' );
$data['settings']['minify'] = $minify_options;
$file_name = 'hummingbird-asset-optimization-settings.json';
header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
header( 'Content-Disposition: attachment; filename=' . $file_name );
header( 'Cache-Control: no-cache, no-store, must-revalidate' ); // HTTP 1.1.
header( 'Pragma: no-cache' ); // HTTP 1.0.
header( 'Expires: 0' ); // Proxies.
echo wp_json_encode( $data, JSON_PRETTY_PRINT );
exit();
}
/**
* Import settings.
*
* @since 2.6.0
*/
public function admin_settings_import_settings() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
if ( ! isset( $_FILES['settings_json_file'] ) ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - No settings file has been submitted.', 'wphb' ),
)
);
}
$file = $_FILES['settings_json_file'];
if ( ! isset( $file['error'] ) || is_array( $file['error'] ) ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - Something went wrong on uploading settings file.', 'wphb' ),
)
);
}
if ( $file['size'] > 1000000 ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - You selected wrong settings file.', 'wphb' ),
)
);
}
if ( 'application/json' !== $file['type'] ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - You selected wrong settings file.', 'wphb' ),
)
);
}
$content = file_get_contents( $file['tmp_name'] );
if ( empty( $content ) ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - Settings data is empty.', 'wphb' ),
)
);
}
$data = json_decode( $content, true );
if ( ! isset( $data['settings']['minify'] ) || ! is_array( $data['settings']['minify'] ) ) {
wp_send_json_error(
array(
'message' => __( 'Import failed - Asset optimization settings data not found.', 'wphb' ),
)
);
}
// Right now we are importing only asset optimization settings.
Settings::update_settings( $data['settings']['minify'], 'minify' );
wp_send_json_success(
array(
'message' => __( 'Settings imported and configured successfully.', 'wphb' ),
)
);
}
/**
* Save current settings as a config.
*
* @since 3.0.1
*/
public function save_config() {
check_ajax_referer( 'wphb-fetch' );
$capability = is_multisite() ? 'manage_network' : 'manage_options';
if ( ! current_user_can( $capability ) ) {
wp_send_json_error( null, 403 );
}
$configs = new Configs();
wp_send_json_success( $configs->get_config_from_current() );
}
/**
* Upload config from file.
*
* @since 3.0.1
*/
public function upload_config() {
check_ajax_referer( 'wphb-fetch' );
$capability = is_multisite() ? 'manage_network' : 'manage_options';
if ( ! current_user_can( $capability ) ) {
wp_send_json_error( null, 403 );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$file = isset( $_FILES['file'] ) ? wp_unslash( $_FILES['file'] ) : false;
$configs = new Configs();
$new_config = $configs->save_uploaded_config( $file );
if ( ! is_wp_error( $new_config ) ) {
wp_send_json_success( $new_config );
}
wp_send_json_error(
array( 'error_msg' => $new_config->get_error_message() )
);
}
/**
* Apply selected config.
*
* @since 3.0.1
*/
public function apply_config() {
check_ajax_referer( 'wphb-fetch' );
$capability = is_multisite() ? 'manage_network' : 'manage_options';
if ( ! current_user_can( $capability ) ) {
wp_send_json_error( null, 403 );
}
$id = filter_input( INPUT_POST, 'id', FILTER_VALIDATE_INT );
if ( ! $id ) {
// Abort if no config ID was given.
wp_send_json_error(
array( 'error_msg' => esc_html__( 'Missing config ID', 'wphb' ) )
);
}
$configs = new Configs();
$response = $configs->apply_config_by_id( $id );
if ( ! is_wp_error( $response ) ) {
wp_send_json_success();
}
wp_send_json_error(
array( 'error_msg' => esc_html( $response->get_error_message() ) )
);
}
/**
* Purge Critical css files.
*
* @since 3.6.0
*/
public function clear_critical_css_files_and_regenerate() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) { // Input var okay.
die();
}
$status = Utils::get_module( 'critical_css' )->regenerate_critical_css();
wp_send_json_success(
array(
'success' => true,
'htmlForStatusTag' => Utils::get_module( 'critical_css' )->get_html_for_status_tag(),
)
);
}
/**
* Create critical css for selected page from Gutenberg post edit screen.
*
* @since 3.6.0
*/
public function gutenberg_create_css_file() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) || ! isset( $_POST['postId'] ) ) { // Input var okay.
die();
}
$id = absint( wp_unslash( $_POST['postId'] ) );
// Also clear cache.
Utils::get_module( 'page_cache' )->clear_cache_action( $id );
$status = Utils::get_module( 'critical_css' )->create_post_css_file( $id );
$single_post_critical_css_status = Utils::get_module( 'critical_css' )->get_single_post_critical_css_status( $id );
if ( 'error' === $single_post_critical_css_status ) {
$type = get_post_type( $id ) . '-' . $id;
$get_error = Utils::get_module( 'critical_css' )->get_queue_item_by_type( $type );
$message = isset( $get_error->error_message ) ? $get_error->error_message : esc_html__( 'There was some error in generating Critical CSS', 'wphb' );
} elseif ( 'processing' === $single_post_critical_css_status ) {
$message = esc_html__( 'Critical CSS is being generated', 'wphb' );
} else {
$message = esc_html__( 'Critical CSS generated', 'wphb' );
}
wp_send_json_success(
array(
'success' => $status,
'singlePostCriticalCSSStatus' => $single_post_critical_css_status,
'message' => $message,
)
);
}
/**
* Re Create critical css for selected page from Gutenberg post edit screen.
*
* @since 3.6.0
*/
public function gutenberg_recreate_css_file() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) || ! isset( $_POST['postId'] ) ) { // Input var okay.
die();
}
$id = absint( wp_unslash( $_POST['postId'] ) );
// Also clear cache.
Utils::get_module( 'page_cache' )->clear_cache_action( $id );
$status = Utils::get_module( 'critical_css' )->recreate_post_css_file( $id );
$single_post_critical_css_status = Utils::get_module( 'critical_css' )->get_single_post_critical_css_status( $id );
$message = '';
if ( 'processing' === $single_post_critical_css_status ) {
$message = esc_html__( 'Critical CSS is being re-generated', 'wphb' );
} elseif ( 'error' === $single_post_critical_css_status ) {
$type = get_post_type( $id ) . '-' . $id;
$get_error = Utils::get_module( 'critical_css' )->get_queue_item_by_type( $type );
$message = isset( $get_error->error_message ) ? $get_error->error_message : esc_html__( 'There was some error in generating Critical CSS', 'wphb' );
} elseif ( $single_post_critical_css_status ) {
$message = esc_html__( 'Critical CSS re-generated', 'wphb' );
}
wp_send_json_success(
array(
'success' => $status,
'singlePostCriticalCSSStatus' => $single_post_critical_css_status,
'message' => $message,
)
);
}
/**
* Create critical css for selected page from Gutenberg post edit screen.
*
* @since 3.6.0
*/
public function gutenberg_revert_css_file() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) || ! isset( $_POST['postId'] ) ) { // Input var okay.
die();
}
$id = absint( wp_unslash( $_POST['postId'] ) );
// Also clear cache.
Utils::get_module( 'page_cache' )->clear_cache_action( $id );
$status = Utils::get_module( 'critical_css' )->revert_post_css_file( $id );
$single_post_critical_css_status = Utils::get_module( 'critical_css' )->get_single_post_critical_css_status( $id );
$message = esc_html__( 'Critical CSS file deleted successfully', 'wphb' );
wp_send_json_success(
array(
'success' => $status,
'singlePostCriticalCSSStatus' => $single_post_critical_css_status,
'message' => $message,
)
);
}
/**
* Get critical css status for single post.
*
* @since 3.6.0
*/
public function gutenberg_get_critical_status_for_single_post() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) || ! isset( $_POST['postId'] ) ) { // Input var okay.
die();
}
$id = absint( wp_unslash( $_POST['postId'] ) );
$type = get_post_type( $id ) . '-' . $id;
$item_detail = Utils::get_module( 'critical_css' )->get_queue_item_by_type( $type );
wp_send_json_success(
array(
'singlePostCriticalCSSStatus' => Utils::get_module( 'critical_css' )->get_single_post_critical_css_status( $id ),
'singlePostCriticalDetail' => $item_detail,
'errorCode' => Utils::get_module( 'critical_css' )->get_error_code_from_log( (array) $item_detail ),
)
);
}
/**
* Get critical css status for single post.
*
* @since 3.6.0
*/
public function get_critical_status_for_queue() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) { // Input var okay.
die();
}
$critical_css_log = Utils::get_module( 'critical_css' )->critical_css_status_for_queue();
$result = isset( $critical_css_log['result'] ) ? $critical_css_log['result'] : false;
$error_message = 'ERROR' === $result ? Utils::get_module( 'critical_css' )->critical_css_generation_complete_notice() : '';
wp_send_json_success(
array(
'criticalStatusForQueue' => $critical_css_log,
'criticalErrorMessage' => $error_message,
'errorCode' => Utils::get_module( 'critical_css' )->get_error_code_from_log(),
'htmlForStatusTag' => Utils::get_module( 'critical_css' )->get_html_for_status_tag(),
'criticalMode' => Utils::get_module( 'critical_css' )->get_critical_mode_for_mp(),
)
);
}
/**
* Toggle Delay Js.
*/
public function minification_toggle_delay() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
$value = filter_input( INPUT_POST, 'data', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
Utils::get_module( 'delayjs' )->toggle_delay_js( $value );
$pc_module = Utils::get_module( 'page_cache' );
// Clear the cache.
$status = $pc_module->clear_cache();
$notice = esc_html__( 'Settings updated', 'wphb' );
wp_send_json_success(
array(
'delay_js' => $value,
'delay_js_timeout' => Settings::get_setting( 'delay_js_timeout', 'minify' ),
'delay_js_exclude' => Settings::get_setting( 'delay_js_exclusions', 'minify' ),
'notice' => $notice,
)
);
}
/**
* Toggle Critical CSS.
*/
public function minify_toggle_critical_css() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) || ! isset( $_POST['data'] ) ) { // Input var okay.
die();
}
$value = filter_input( INPUT_POST, 'data', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
Utils::get_module( 'critical_css' )->toggle_critical_css( $value );
wp_send_json_success(
array(
'criticalCss' => $value ? 'activate' : 'deactivate',
'htmlForStatusTag' => Utils::get_module( 'critical_css' )->get_html_for_status_tag(),
'mode' => Utils::get_module( 'critical_css' )->get_critical_mode_for_mp(),
)
);
}
/**
* Switch Critical CSS.
*/
public function wphb_switch_to_critical_css_from_legacy() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) { // Input var okay.
die();
}
delete_option( 'wphb-notice-legacy-critical-css-show' );
if ( Utils::is_member() ) {
Utils::get_module( 'critical_css' )->toggle_critical_css( true );
}
wp_send_json_success();
}
/**
* Search posts for exclusions.
*/
public function wphb_search_posts() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) { // Input var okay.
die();
}
$query = filter_input( INPUT_POST, 'query', FILTER_UNSAFE_RAW );
$results = Utils::get_module( 'exclusions' )->search_posts( $query );
wp_send_json_success( $results );
}
/**
* Reset exclusions.
*
* @since 3.11.0
*/
public function reset_exclusions() {
check_ajax_referer( 'wphb-fetch', 'nonce' );
if ( ! current_user_can( Utils::get_admin_capability() ) ) {
die();
}
$exclusions = filter_input( INPUT_POST, 'value', FILTER_UNSAFE_RAW );
$type = filter_input( INPUT_POST, 'type', FILTER_UNSAFE_RAW );
$results = Utils::get_module( 'exclusions' )->reset_exclusion_to_defaults( $exclusions, $type );
wp_send_json_success();
}
}