'; function __construct( $plugin ) { $this->plugin = $plugin; // skip any admin related stuff when doing ajax, cron or rest if ( (defined( 'DOING_AJAX' ) && DOING_AJAX) || (defined( 'DOING_CRON' ) && DOING_CRON) || (defined( 'REST_REQUEST' ) && REST_REQUEST) ) { return; } add_action( 'admin_init', [ $this, 'start_session' ] ); add_action( 'admin_init', [ $this, 'register_settings' ] ); add_action( 'admin_menu', [ $this, 'register_menu' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); add_action( 'plugin_action_links_' . plugin_basename( $this->plugin->plugin_file ), [ $this, 'plugin_action_links' ] ); add_action( 'admin_notices', [ $this, 'maybe_show_advanced_cache_notice' ] ); add_action( 'admin_bar_menu', [ $this, 'add_admin_bar_button' ], 999 ); add_action( 'admin_post_wpb_clear_cache', [ $this, 'admin_clear_cache' ] ); add_action( 'admin_post_nopriv_wpb_clear_cache', [ $this, 'admin_clear_cache' ] ); add_action( 'admin_post_wpb_repair_install', [ $this, 'admin_repair_installation' ] ); add_action( 'delete_attachment', [ $this, 'delete_webp_image' ] ); add_action( 'init', [ $this, 'register_post_meta' ] ); add_action( 'add_meta_boxes', [ $this, 'post_cache_metabox' ] ); add_action( 'save_post', [ $this, 'save_post_cache_metabox' ] ); } /** * Delete the webp versions when the image is deleted * * @param int $attachment_id */ function delete_webp_image( $attachment_id ) { /** @var wpdb $wpdb */ global $wpdb; $upload_dir = wp_upload_dir()['basedir']; $meta = wp_get_attachment_metadata( $attachment_id ); if ( ! $meta || ! isset( $meta['file'] ) ) { return; } if ( ! isset( $meta['sizes'] ) ) { $meta['sizes'] = []; } $meta['sizes'][] = [ 'file' => $meta['file'] ]; $hashes = []; foreach ( $meta['sizes'] as $size ) { $image_path = trailingslashit( $upload_dir ) . $meta['file']; $ext = pathinfo( $image_path, PATHINFO_EXTENSION ); $image_webp_path = preg_replace( '/^(.+)\.' . preg_quote( $ext, '/' ) . '$/u', '$1.webp', $image_path ); $hashes[] = sha1( $image_path ); if ( file_exists( $image_webp_path ) ) { unlink( $image_webp_path ); } } $wpdb->query( $wpdb->prepare( "DELETE FROM `{$wpdb->prefix}ezcache_webp_images` WHERE `uid` IN (" . substr( str_repeat( "%d, ", count( $hashes ) ), 0, - 2 ) . ")", $hashes ) ); $wpdb->query( "OPTIMIZE TABLE `{$wpdb->prefix}ezcache_webp_images`" ); } /** * Register the post meta fields */ function register_post_meta() { if ( function_exists( 'register_post_meta' ) ) { register_post_meta( 'post', '_ezcache_do_not_cache_post', [ 'show_in_rest' => true, 'single' => true, 'type' => 'bool', 'auth_callback' => function () { return current_user_can( 'edit_posts' ); } ] ); } } /** * Register the meta box */ function post_cache_metabox() { global $post_type; if ( 'attachement' == $post_type ) { return; } add_meta_box( 'ezcache_metabox', __( 'Caching', 'ezcache' ), [ $this, 'post_cache_metabox_output' ], null, 'side' ); } /** * Render the post meta box * * @param $post */ function post_cache_metabox_output( $post ) { global $post_type_object; $value = get_post_meta( $post->ID, '_ezcache_do_not_cache_post', true ); wp_nonce_field( 'ezcache_metabox', '_eznonce' ); ?>
>
clear_cache_single( $post_id ); } else { delete_post_meta( $post_id, '_ezcache_do_not_cache_post' ); } } /** * Add settings link to the plugin action links * * @param array $links * * @return array */ function plugin_action_links( $links ) { $links[] = sprintf( '%s', admin_url( 'admin.php?page=ezcache' ), __( 'Settings' ) ); return $links; } /** * Add the menu to the admin bar * * @param WP_Admin_Bar $wp_admin_bar */ function add_admin_bar_button( $wp_admin_bar ) { if ( ! current_user_can( 'manage_options' ) ) { return; } $referer = rawurlencode( wp_unslash( remove_query_arg( 'fl_builder', $_SERVER['REQUEST_URI'] ) ) ); $svg = preg_replace( '//i', '', self::$svg ); $wp_admin_bar->add_menu( [ 'id' => 'ezcache', 'title' => $svg . __( 'ezCache', 'ezcache' ), 'href' => admin_url( 'admin.php?page=ezcache' ), ] ); $wp_admin_bar->add_menu( [ 'id' => 'ezcache-settings', 'parent' => 'ezcache', 'title' => __( 'Settings', 'ezcache' ), 'href' => admin_url( 'admin.php?page=ezcache' ), ] ); $wp_admin_bar->add_menu( [ 'id' => 'ezcache-clear-cache', 'parent' => 'ezcache', 'title' => __( 'Clear Cache', 'ezcache' ), 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=wpb_clear_cache&_wp_http_referer=' . $referer ), 'wpb-clear-cache' ), ] ); } /** * Make sure we have a session */ function start_session() { if ( session_status() == PHP_SESSION_NONE ) { session_start(); } } /** * Register settings for the plugin */ function register_settings() { register_setting( $this->plugin->plugin_settings_key . '_group', $this->plugin->plugin_settings_key ); } /** * Add the menu under the 'Settings' sidebar item */ function register_menu() { global $submenu; add_menu_page( __( 'ezCache' ), __( 'ezCache' ), 'manage_options', 'ezcache', [ $this, 'settings_page' ], 'data:image/svg+xml;base64,' . base64_encode( self::$svg ) ); $urls = [ __( 'Statistics', 'ezcache' ) => '/', __( 'Settings', 'ezcache' ) => '/settings', __( 'Advanced Settings', 'ezcache' ) => '/advanced', __( 'License', 'ezcache' ) => '/license', ]; if ( ! isset( $submenu['ezcache'] ) ) { $submenu['ezcache'] = []; } foreach ( $urls as $title => $url ) { $submenu['ezcache'][] = [ $title, 'manage_options', admin_url( 'admin.php?page=ezcache' ) . '#' . $url ]; } } /** * Render the settings page */ function settings_page() { $trans = $this->getJsTraslations(); ?>

id ) { return; } $ver = defined( 'WP_DEBUG' ) && WP_DEBUG ? time() : $this->plugin->plugin_version; wp_enqueue_script( 'ezcache-options', $this->plugin->plugin_url . '/assets/dist/js/options.js', [], $ver, true ); wp_enqueue_style( 'ezcache-options', $this->plugin->plugin_url . '/assets/dist/css/options.css', [], $ver ); wp_localize_script( 'ezcache-options', 'ezcache', [ 'assets_url' => esc_url_raw( EZCACHE_URL . '/assets' ), 'ajax_url' => esc_url_raw( admin_url( 'admin-ajax.php' ) ), 'rest_url' => esc_url_raw( rest_url() ), 'ajax_nonce' => wp_create_nonce( 'ezcache-options' ), 'rest_nonce' => wp_create_nonce( 'wp_rest' ), 'is_rtl' => is_rtl(), 'site_url' => esc_url_raw( untrailingslashit( site_url() ) ), 'trans' => $this->getJsTraslations(), 'is_https_2' => $this->check_https_2_support(), ] ); } /** * Check if current website supports HTTPS/2 * * @return bool */ protected function check_https_2_support() { if ( ! is_ssl() ) { return false; } $supports = get_transient( 'ezcache_https_2_support' ); if ( ! $supports ) { $response = wp_safe_remote_head( home_url(), [ 'httpversion' => '2.0' ] ); $supports = false; if ( ! is_wp_error( $response ) ) { $response = $response['http_response']->get_response_object(); $supports = $response->protocol_version == 2; } set_transient( 'ezcache_https_2_support', [ 'has_support' => $supports ], DAY_IN_SECONDS ); } return isset( $supports['has_support'] ) ? $supports['has_support'] : false; } /** * Get the trnaslations required for the javascript frontend * * @return array */ protected function getJsTraslations() { return [ 'select_all' => __( 'Select All', 'ezcache' ), 'select_none' => __( 'Select None', 'ezcache' ), 'ezcache' => __( 'ezCache', 'ezcache' ), 'enabled' => __( 'Enabled', 'ezcache' ), 'disabled' => __( 'Disabled', 'ezcache' ), 'run_speed_test' => __( 'Run a Speed Test', 'ezcache' ), 'save_settings' => __( 'Save Settings', 'ezcache' ), 'settings_saved' => __( 'Settings updated.', 'ezcache' ), 'error_saving_settings' => __( 'Could not save settings.', 'ezcache' ), 'clear_cache' => __( 'Clear Cache', 'ezcache' ), 'cache_cleared' => __( 'Cache has been cleared.', 'ezcache' ), 'documentation' => __( 'Documentation', 'ezcache' ), 'knowledgebase' => __( 'Knowledgebase', 'ezcache' ), 'settings' => __( 'Settings', 'ezcache' ), 'advanced_settings' => __( 'Advanced Settings', 'ezcache' ), 'stats' => __( 'Statistics', 'ezcache' ), 'license' => __( 'License', 'ezcache' ), 'recommended' => __( 'Recommended', 'ezcache' ), 'basic_settings' => __( 'Basic Settings', 'ezcache' ), 'no_cache_known_users' => __( 'Don\'t cache pages for known users', 'ezcache' ), 'no_cache_known_users_description' => __( 'This disables cache for logged in users or visitors who left comments on posts.', 'ezcache' ), 'cache_expiry' => __( 'Cache Expiry', 'ezcache' ), 'cache_lifetime' => __( 'Cache Timeout', 'ezcache' ), 'cache_lifetime_description' => __( 'How long to keep the cached data, the recommended and effective starting point is one day.', 'ezcache' ), 'cache_expiry_interval' => __( 'Check for stale cache every', 'ezcache' ), 'cache_expiry_interval_description' => __( 'Automatically check for stale cache files and delete them at a set interval.', 'ezcache' ), 'interval' => __( 'Interval', 'ezcache' ), 'every' => __( 'Every', 'ezcache' ), 'seconds' => __( 'Seconds', 'ezcache' ), 'cache_schedule_type_time' => __( 'At Time', 'ezcache' ), 'cache_schedule_interval' => __( 'Interval', 'ezcache' ), 'weekly' => __( 'Weekly', 'ezcache' ), 'daily' => __( 'Daily', 'ezcache' ), 'twicedaily' => __( 'Twice Daily', 'ezcache' ), 'hourly' => __( 'Hourly', 'ezcache' ), 'at' => __( 'At', 'ezcache' ), 'cache_bypass' => __( 'Cache Bypass', 'ezcache' ), 'no_cache_query_params' => __( 'Don\'t cache pages where the URLs contain parameters in the query string', 'ezcache' ), 'no_cache_query_params_description' => __( 'Don\'t save cache when the URL contains query string parameters, such as ?page_id=15 at the end of the URL.', 'ezcache' ), 'separate_mobile_cache' => __( 'Separate cache for mobile devices', 'ezcache' ), 'separate_mobile_cache_description' => __( 'Save separate cache files for mobile browsers and a separate file for desktop browsers, you should only enable this option if your theme is not responsive and you use a theme or a plugin that produces a separate mobile version of the website.', 'ezcache' ), 'cache_clear_on_post_edit' => __( 'Clear cache when a post or page is published or updated', 'ezcache' ), 'cache_clear_on_post_edit_description' => __( 'Make sure your visitors read the latest posts by clearing the cache when you update or publish a post.', 'ezcache' ), 'bypass_cache_title' => __( 'Disable caching for the following pages', 'ezcache' ), 'bypass_cache_single' => __( 'Single Posts', 'ezcache' ), 'bypass_cache_pages' => __( 'Pages', 'ezcache' ), 'bypass_cache_frontpage' => __( 'Front Page', 'ezcache' ), 'bypass_cache_home' => __( 'Home', 'ezcache' ), 'bypass_cache_archives' => __( 'Archives', 'ezcache' ), 'bypass_cache_tag' => __( 'Tags', 'ezcache' ), 'bypass_cache_category' => __( 'Categories', 'ezcache' ), 'bypass_cache_feed' => __( 'Feeds', 'ezcache' ), 'bypass_cache_search' => __( 'Search Results', 'ezcache' ), 'bypass_cache_author' => __( 'Author Pages', 'ezcache' ), 'rejected_uri' => __( 'Links (URLs) which will never get cached', 'ezcache' ), 'rejected_uri_description' => __( 'Do not serve cached content if the URL matches any link in the following list', 'ezcache' ), 'rejected_uri_wildcard' => __( 'The domain part of the URL will be stripped automatically. Use * wildcard character to match multiple characters at this position (eg. /product/*).', 'ezcache' ), 'rejected_user_agent' => __( 'User Agents which will never receive cached data', 'ezcache' ), 'rejected_user_agent_description' => __( 'Do not serve cached content to the following useragents', 'ezcache' ), 'rejected_cookies' => __( 'Cookies which will prevent pages from getting cached', 'ezcache' ), 'rejected_cookies_description' => __( 'Specify the cookies that when set in the visitor\'s browser, should prevent a page from getting cached (one per line)', 'ezcache' ), 'rejected_cookies_placeholder' => _x( 'wordpress_logged_in_', 'rejected cookies example', 'ezcache' ), 'n_minutes' => __( '%s Minutes', 'ezcache' ), 'n_hours' => __( '%s Hours', 'ezcache' ), 'n_days' => __( '%s Days', 'ezcache' ), 'never_expire' => __( 'Never Expire', 'ezcache' ), 'cache_disabled' => __( 'WP_CACHE is disabled in your wp-config.php, caching will not work.', 'ezcache' ), 'adv_cache_not_exists' => __( 'advanced-cache.php is missing from your wp-content folder, caching will not work.', 'ezcache' ), 'plugin_badly_installed' => __( 'Plugin is not installed properly, please reinstall, caching will not work.', 'ezcache' ), 'desktop' => _x( 'Desktop', 'statistics block title', 'ezcache' ), 'mobile' => _x( 'Mobile', 'statistics block title', 'ezcache' ), 'expired' => _x( 'Expire Cache', 'statistics block title', 'ezcache' ), 'javascript' => _x( 'JavaScript Files', 'statistics block title', 'ezcache' ), 'css' => _x( 'CSS Files', 'statistics block title', 'ezcache' ), 'webp_images' => _x( 'WebP Images', 'statistics block title', 'ezcache' ), 'cache_usage' => __( 'ezCache Cache Usage', 'ezcache' ), 'webp_stats_description' => __( 'Images optimized with WebP.', 'ezcache' ), 'cache_bypass_settings' => _x( 'Cache Bypass', 'settings block title', 'ezcache' ), 'cache_settings' => _x( 'Caching', 'settings block title', 'ezcache' ), 'performance_settings' => _x( 'Performance', 'settings block title', 'ezcache' ), 'cache_expiry_settings' => _x( 'Cache Expiration', 'settings block title', 'ezcache' ), 'optimize_google_fonts' => __( 'Optimize Google fonts', 'ezcache' ), 'optimize_google_fonts_description' => __( 'Combine multiple Google Fonts declerations into one.', 'ezcache' ), 'minify_html' => __( 'Minify HTML', 'ezcache' ), 'minify_html_description' => __( 'Minify the cached HTML to make cached files smaller.', 'ezcache' ), 'minify_inline_js' => __( 'Minify Inline JavaScript', 'ezcache' ), 'minify_inline_js_description' => __( 'Include JavaScript embedded in the HTML in the minification process.', 'ezcache' ), 'minify_inline_css' => __( 'Minify Inline CSS', 'ezcache' ), 'minify_inline_css_description' => __( 'Include CSS embedded in the HTML in the minification process.', 'ezcache' ), 'minify_js' => __( 'Minify JavaScript', 'ezcache' ), 'minify_js_description' => __( 'Minify JavaScript files to reduce their size.', 'ezcache' ), 'minify_html_comments' => __( 'Remove HTML comments', 'ezcache' ), 'minify_html_comments_description' => __( 'Remove embeded comments from minified HTML.', 'ezcache' ), 'combine_head_js' => __( 'Combine JavaScript in Head', 'ezcache' ), 'combine_head_js_description' => __( 'Combine multiple JavaScript files found in the head section of the HTML into one file.', 'ezcache' ), 'combine_body_js' => __( 'Combine JavaScript in Body', 'ezcache' ), 'combine_body_js_description' => __( 'Combine multiple JavaScript files found in the body section of the HTML into one file.', 'ezcache' ), 'minify_css' => __( 'Minify CSS', 'ezcache' ), 'minify_css_description' => __( 'Minify CSS files to reduce their size.', 'ezcache' ), 'combine_css' => __( 'Combine CSS', 'ezcache' ), 'combine_css_description' => __( 'Combine multiple CSS files into one to reduce HTTP requests.', 'ezcache' ), 'disable_wp_emoji' => __( 'Disable WordPress Emoji', 'ezcache' ), 'disable_wp_emoji_description' => __( 'Remove extra code related to Emoji from WordPress which was added recently to support Emoji in an older browsers.', 'ezcache' ), 'not_recommended_https2' => __( 'Your server supports HTTP/2 which benefits from having this option kept disabled', 'ezcache' ), 'enable_webp_support' => __( 'Optimize Images With WebP', 'ezcache' ), 'enable_webp_support_description' => __( 'WebP is a modern image format that provides superior lossless and lossy compression for images on the web. WebP lossless images are 26% smaller in size compared to PNGs, and 25-34% smaller than comparable JPEG images.', 'ezcache' ), 'requries_premium_license' => __( 'Requires a premium license', 'ezcache' ), 'rejected_user_agent_placeholder' => _x( 'Googlebot', 'user agent example', 'ezcache' ), 'rejected_uri_placeholder' => _x( '/products/*', 'rejected uri example', 'ezcache' ), 'css_stats_description' => __( 'Optimized and cached CSS files.', 'ezcache' ), 'javascript_stats_description' => __( 'Optimized and cached JavaScript files.', 'ezcache' ), 'expired_stats_description' => __( 'Cache data that has expired and waiting to be cleaned up.', 'ezcache' ), 'mobile_stats_description' => __( 'Cache data for pages viewed from mobile devices.', 'ezcache' ), 'desktop_stats_description' => __( 'Cache data for pages viewed from desktop computers.', 'ezcache' ), 'general_advanced_settings' => __( 'General', 'ezcache' ), 'license_key' => __( 'License Key', 'ezcache' ), 'license_key_description' => __( 'ezCache pro license will allow you to use the WebP image optimization without limits.', 'ezcache' ), 'deactivate_license' => __( 'Deactivate License', 'ezcache' ), 'activate_license' => __( 'Activate License', 'ezcache' ), 'license_valid' => __( 'License is valid', 'ezcache' ), 'license_invalid' => __( 'License is invalid', 'ezcache' ), 'license_expires_at' => __( 'License expires at %s', 'ezcache' ), 'unknown' => __( 'Unknown', 'ezcache' ), 'license_status' => __( 'Status', 'ezcache' ), 'license_details' => __( 'License Details', 'ezcache' ), 'license_type' => __( 'License Type', 'ezcache' ), 'trial_license' => _x( 'Trial', 'license type', 'ezcache' ), 'regular_license' => _x( 'Pro', 'license type', 'ezcache' ), 'expires_in' => __( 'Expires In', 'ezcache' ), 'expires_at' => __( 'Expires At', 'ezcache' ), 'uses_left' => __( 'Convertions Left', 'ezcache' ), 'trial_not_started' => __( '%s days after first usage', 'ezcache' ), 'purchase_license' => __( 'Get a Pro License', 'ezcache' ), 'license_expired' => __( 'Expired', 'ezcache' ), 'no_expiry_while_upress_client' => __( 'Will not expire while hosted on uPress', 'ezcache' ), 'upress_ad' => __( 'uPress Premium WordPress Hosting', 'ezcache' ), 'upress_domain' => __( 'www.upress.io', 'ezcache' ), 'upress_ad_link' => __( 'https://www.upress.io/?utm_source=wordpress&utm_medium=cpc&utm_campaign=ezcache', 'ezcache' ), 'speed_test_url' => __( 'https://speedom.net/?url=%s&location=US-NY&utm_source=wordpress&utm_medium=cpc&utm_campaign=ezcache', 'ezcache' ), 'ezcache_docs_link' => __( 'https://ezcache.app/documentation?utm_source=wordpress&utm_medium=cpc&utm_campaign=ezcache', 'ezcache' ), 'ezcache_knowledgebase_link' => __( 'https://ezcache.app/knowledgebase?utm_source=wordpress&utm_medium=cpc&utm_campaign=ezcache', 'ezcache' ), 'ezcache_pricing_link' => __( 'https://ezcache.app/pricing?utm_source=wordpress&utm_medium=cpc&utm_campaign=ezcache', 'ezcache' ), ]; } /** * Show cache status admin notices when needed */ function maybe_show_advanced_cache_notice() { $webp_queue = get_site_option( 'ezcache_convert_images_to_webp_reprocess_queue' ); if ( ! $webp_queue ) { $webp_queue = []; } $count_pending = array_reduce( $webp_queue, function ( $count, $images ) { return $count + count( $images ); }, 0 ); if ( $count_pending > 0 ) { echo '

' . esc_html__( 'ezCache', 'ezcache' ) . ': ' . sprintf( esc_html__( 'WebP Processing is currently running, %d images remaining.', 'ezcache' ), $count_pending ) . '

'; } if ( isset( $_SESSION['EZCACHE_REPAIRED'] ) ) { unset( $_SESSION['EZCACHE_REPAIRED'] ); echo '

' . esc_html__( 'ezCache installation repaired.', 'ezcache' ) . '

'; return; } if ( ! get_site_option( 'ezcache_first_run', false ) ) { update_site_option( 'ezcache_first_run', 1 ); return; } $status = $this->plugin->ezcache->get_status(); $messages = []; if ( ! $status['cache_enabled'] ) { $messages[] = __( 'WP_CACHE is disabled in your wp-config.php', 'ezcache' ); } if ( ! $status['adv_cache_exists'] ) { $messages[] = __( 'advanced-cache.php is missing from your wp-content folder', 'ezcache' ); } if ( $status['adv_cache_exists'] && ! $status['correct_cache_exists'] ) { $messages[] = __( 'Invalid advanced-cache.php file detected', 'ezcache' ); } if ( ! $status['webp_table_exists'] ) { $messages[] = __( 'WebP images database table is missing or corrupt', 'ezcache' ); } if ( ! count( $messages ) ) { return; } $referer = rawurlencode( wp_unslash( remove_query_arg( 'fl_builder', $_SERVER['REQUEST_URI'] ) ) ); echo '

'; esc_html_e( 'ezCache detected the following configuration problems:', 'ezcache' ); echo '
'; echo implode( ', ', $messages ); echo '
'; echo '' . esc_html__( 'Repair ezCache Installation', 'ezcache' ) . ''; echo '

'; } function admin_clear_cache() { if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'wpb-clear-cache' ) ) { wp_nonce_ays( 'wpb-clear-cache' ); } $this->plugin->ezcache->clear_cache(); wp_redirect( wp_get_referer() ); exit; } /** * Repaire the plugin installation when POST variable is set */ function admin_repair_installation() { if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'wpb-repair-install' ) ) { wp_nonce_ays( 'wpb-repair-install' ); } $this->plugin->activation_hook(); $_SESSION['EZCACHE_REPAIRED'] = true; wp_redirect( wp_get_referer() ); exit; } }