oc_vc_path = __DIR__; $this->oc_vc_uri = plugins_url( '', __FILE__ ); $this->vc_path = dirname( $this->oc_vc_path ); $this->onecom_vcache_dir_url = plugin_dir_url( __FILE__ ); $this->logger = new Onecom_Logger(); $this->blog_url = get_option( 'home' ); $this->purge_id = $this->oc_json_get_option( 'onecom_vcache_info', 'vcache_purge_id' ); if ( is_multisite() ) { $this->cdn_url = rtrim( 'https://usercontent.one/wp/' . str_replace( array( self::HTTPS, self::HTTP ), '', network_site_url() ), '/' ); } else { $this->cdn_url = 'https://usercontent.one/wp/' . str_replace( array( self::HTTPS, self::HTTP ), '', $this->blog_url ); } $this->clusterAdjustments(); /** * This commented becuase performance cache is available to all now. * and Enable disable settings works with activation/deactivation hooks, no need to do it on each page load * @todo - to be deleted after a while if all works well */ add_action( 'admin_init', array( $this, 'runAdminSettings' ), 1 ); add_action( 'admin_menu', array( $this, 'remove_parent_page' ), 100 ); add_action( 'admin_menu', array( $this, 'add_menu_item' ) ); add_action( 'admin_init', array( $this, 'options_page_fields' ) ); add_action( 'plugins_loaded', array( $this, 'filter_purge_settings' ), 1 ); add_action( 'admin_head', array( $this, 'vcaching_reset_dev_mode' ), 10 ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_resources' ) ); add_action( 'admin_head', array( $this, 'onecom_vcache_icon_css' ) ); add_action( 'wp_ajax_oc_set_vc_state', array( $this, 'oc_set_vc_state_cb' ) ); // add_action( 'wp_ajax_oc_set_vc_ttl', array( $this, 'oc_set_vc_ttl_cb' ) ); // add_action( 'wp_ajax_oc_set_cdn_state', array( $this, 'oc_cdn_state_cb' ) ); // add_action( 'wp_ajax_oc_set_dev_mode', array( $this, 'oc_set_dev_mode_cb' ) ); // add_action( 'wp_ajax_oc_exclude_cdn_mode', array( $this, 'oc_exclude_cdn_mode_cb' ) ); // add_action( 'wp_ajax_oc_update_cdn_data', array( $this, 'oc_update_cdn_data_cb' ) ); add_action( 'wp_ajax_oc_activate_wp_rocket', array( $this, 'oc_activate_wp_rocket' ) ); add_action( 'wp_ajax_on_reload_plugin_activate', array( $this, 'on_reload_plugin_activate_check' ) ); add_action( 'wp_ajax_activate_onclick_wp_plugin', array( $this, 'onclick_plugin_activate' ) ); add_action( 'wp_ajax_check_addon_purchase_status', array( $this, 'check_addon_purchase_status' ) ); add_action( 'wp_ajax_check_addon_purchase_status_onload', array( $this, 'on_reload_addon_status_check' ) ); add_action( 'template_redirect', array( $this, 'oc_cdn_rewrites' ) ); add_action( 'upgrader_process_complete', array( $this, 'oc_upgrade_housekeeping' ), 10, 2 ); add_action( 'plugins_loaded', array( $this, 'oc_update_headers_htaccess' ) ); add_action( 'switch_theme', array( $this, 'purge_theme_cache' ) ); add_action( 'onecom_purge_cdn', array( $this, 'oc_purge_cdn_cache' ) ); add_action( 'wp_ajax_oc_handle_cdn_settings', array( $this, 'oc_handle_cdn_settings_cb' ) ); // remove purge requests from Oclick demo importer add_filter( 'vcaching_events', array( $this, 'vcaching_events_cb' ) ); //intercept the list of urls, replace multiple urls with a single generic url add_filter( 'vcaching_purge_urls', array( $this, 'vcaching_purge_urls_cb' ) ); add_action( 'wp_ajax_purge_cache', array( $this,'handle_purge_cache_request' )); register_activation_hook( $this->vc_path . DIRECTORY_SEPARATOR . 'vcaching.php', array( $this, 'onActivatePlugin' ) ); register_deactivation_hook( $this->vc_path . DIRECTORY_SEPARATOR . 'vcaching.php', array( $this, 'onDeactivatePlugin' ) ); $exclude_cache = new OnecomExcludeCache(); } /** * Function to run admin settings * */ public function runAdminSettings() { if ( 'false' !== $this->state ) { return; } // Following removes admin bar purge link, so commented // add_action( 'admin_bar_menu', array( $this, 'remove_toolbar_node' ), 999 ); add_filter( 'post_row_actions', array( $this, 'remove_post_row_actions' ), 10, 2 ); add_filter( 'page_row_actions', array( $this, 'remove_page_row_actions' ), 10, 2 ); } /** * Function will execute after plugin activated * **/ public function onActivatePlugin() { // Enable/Disable Cache/CDN on activation based on eligibility $cdn_enabled = update_site_option( self::OPTIONCDN, 'true', 'no' ); self::setDefaultSettings(); } /** * Function will execute after plugin deactivated * */ public function onDeactivatePlugin() { $on_deactivate = true; self::disableDefaultSettings( $on_deactivate ); self::purgeAll(); } /** * Function to make some checks to ensure best usage **/ private function runChecklist() { $this->oc_upgrade_housekeeping( 'activate' ); // If not exist, then return if ( ! in_array( 'vcaching/vcaching.php', (array) get_site_option( 'active_plugins' ), true ) ) { return true; } $this->logger->wp_api_sendlog( 'already_exists', self::PLUGINNAME, self::PLUGINNAME . 'DefaultWP Caching plugin already exists.', self::PLUGINVERSION ); add_action( 'admin_notices', array( $this, 'duplicateWarning' ) ); return false; } /** * Function to disable vcache promo/notice * */ private function disablePromoNotice() { $local_promo = get_site_option( 'onecom_local_promo' ); if ( isset( $local_promo['xpromo'] ) && '18-jul-2018' === $local_promo['xpromo'] ) { $local_promo['show'] = false; update_site_option( 'onecom_local_promo', $local_promo, 'no' ); } } /* * Show Admin notice */ public function duplicateWarning() { $screen = get_current_screen(); $warn_screens = array( 'toplevel_page_onecom-vcache-plugin', 'one-com_page_onecom-vcache-plugin', 'plugins', 'options-general', 'dashboard', ); if ( ! in_array( $screen->id, $warn_screens, true ) ) { return; } $class = 'notice notice-warning is-dismissible'; $dect_link = add_query_arg( array( 'disable-old-varnish' => 1, '_wpnonce' => wp_create_nonce( 'disable-old-varnish' ), ) ); $dect_link = wp_nonce_url( $dect_link, 'plugin-deactivation' ); $message = __( 'To get the best out of One.com Performance Cache, kindly deactivate the existing "Varnish Caching" plugin.  ', 'vcaching' ); $message .= sprintf( "%s", ( $dect_link ), __( 'Deactivate' ) ); printf( '

%2$s

', esc_attr( $class ), $message ); } /* Function to convert boolean to string * * */ private function booleanCast( $value ) { if ( ! is_string( $value ) ) { $value = ( 1 === $value || true === $value ) ? 'true' : 'false'; } if ( '1' === $value ) { $value = 'true'; } if ( '0' === $value ) { $value = 'false'; } return $value; } /** * Function to set default settings for one.com * **/ private function setDefaultSettings() { // Enable by default $enable = $this->booleanCast( self::DEFAULTENABLE ); $enabled = update_site_option( self::DEFAULTPREFIX . 'enable', $enable, 'no' ); $check = get_site_option( self::DEFAULTPREFIX . 'enable', $enable ); if ( ! ( 'true' === $check || true === $check || 1 === $check ) ) { return; } // Update the cookie name if (! get_site_option(self::DEFAULTPREFIX . 'cookie')) { $name = bin2hex(random_bytes(16)); // changed from sha1(md5(uniqid())) to fix SAST update_site_option(self::DEFAULTPREFIX . 'cookie', $name, 'no'); } // Set default TTL $ttl = self::DEFAULTTTL; $ttl_unit = self::DEFAULTTTLUNIT; if ( ! get_site_option( self::DEFAULTPREFIX . 'ttl' ) && ! is_bool( get_site_option( self::DEFAULTPREFIX . 'ttl' ) ) && get_site_option( self::DEFAULTPREFIX . 'ttl' ) !== 0 ) { update_site_option( self::DEFAULTPREFIX . 'ttl', $ttl, 'no' ); update_site_option( self::DEFAULTPREFIX . 'ttl_unit', $ttl_unit, 'no' ); } elseif ( ! get_site_option( self::DEFAULTPREFIX . 'ttl' ) && is_bool( get_site_option( self::DEFAULTPREFIX . 'ttl' ) ) ) { update_site_option( self::DEFAULTPREFIX . 'ttl', $ttl, 'no' ); update_site_option( self::DEFAULTPREFIX . 'ttl_unit', $ttl_unit, 'no' ); } if ( ! get_site_option( self::DEFAULTPREFIX . 'homepage_ttl' ) && ! is_bool( get_site_option( self::DEFAULTPREFIX . 'homepage_ttl' ) ) && get_site_option( self::DEFAULTPREFIX . 'homepage_ttl' ) !== 0 ) { update_site_option( self::DEFAULTPREFIX . 'homepage_ttl', $ttl, 'no' ); update_site_option( self::DEFAULTPREFIX . 'ttl_unit', $ttl_unit, 'no' ); } elseif ( ! get_site_option( self::DEFAULTPREFIX . 'homepage_ttl' ) && is_bool( get_site_option( self::DEFAULTPREFIX . 'homepage_ttl' ) ) ) { update_site_option( self::DEFAULTPREFIX . 'homepage_ttl', $ttl, 'no' ); update_site_option( self::DEFAULTPREFIX . 'ttl_unit', $ttl_unit, 'no' ); } // Set default varnish IP $ip = getHostByName( getHostName() ); update_site_option( self::DEFAULTPREFIX . 'ips', $ip, 'no' ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { update_site_option( self::DEFAULTPREFIX . 'debug', true, 'no' ); } // Deactivate the old varnish caching plugin on user's consent. if ( isset( $_REQUEST['disable-old-varnish'] ) && 1 === $_REQUEST['disable-old-varnish'] ) { deactivate_plugins( '/vcaching/vcaching.php' ); self::runAdminSettings(); add_action( 'admin_bar_menu', array( $this, 'remove_toolbar_node' ), 999 ); } // Check and notify if varnish plugin already active. if ( in_array( 'vcaching/vcaching.php', (array) get_site_option( 'active_plugins' ), true ) ) { add_action( 'admin_notices', array( $this, 'duplicateWarning' ) ); } } /** * Function to disable varnish plugin **/ private function disableDefaultSettings( $on_deactivate = false ) { self::purgeAll(); delete_option( self::DEFAULTPREFIX . 'ttl' ); delete_option( self::DEFAULTPREFIX . 'homepage_ttl' ); delete_option( self::DEFAULTPREFIX . 'ttl_unit' ); delete_option( 'onecom_vcache_info' ); } /** * Remove current menu item * */ public function remove_parent_page() { remove_menu_page( 'vcaching-plugin' ); } /** * Add menu item * */ public function add_menu_item() { if ( parent::check_if_purgeable() ) { global $onecom_generic_menu_position; $position = ( function_exists( 'onecom_get_free_menu_position' ) && ! empty( $onecom_generic_menu_position ) ) ? onecom_get_free_menu_position( $onecom_generic_menu_position ) : null; add_menu_page( __( 'Performance Cache', 'vcaching' ), __( 'Performance Cache ', 'vcaching' ), 'manage_options', self::PLUGINNAME . '-plugin', array( $this, 'settings_page' ), 'dashicons-dashboard', $position ); } } /** * Function to show settings page * */ public static function cache_settings_page() { require_once plugin_dir_path( __FILE__ ) . '/templates/cache-settings.php'; } public static function cdn_settings_page() { require_once plugin_dir_path( __FILE__ ) . '/templates/cdn-settings.php'; } public static function wp_rocket_page() { require_once plugin_dir_path( __FILE__ ) . '/templates/wp-rocket.php'; } /** * Function to customize options fields * */ public function options_page_fields() { add_settings_section( self::DEFAULTPREFIX . 'oc_options', null, null, self::DEFAULTPREFIX . 'oc_options' ); add_settings_field( self::DEFAULTPREFIX . 'ttl', __( 'Cache TTL', 'vcaching' ) . '' . __( 'The time that website data is stored in the Varnish cache. After the TTL expires the data will be updated, 0 means no caching.', 'vcaching' ) . '', array( $this, self::DEFAULTPREFIX . 'ttl_callback' ), self::DEFAULTPREFIX . 'oc_options', self::DEFAULTPREFIX . 'oc_options' ); if ( isset( $_POST['option_page'] ) && self::DEFAULTPREFIX . 'oc_options' === $_POST['option_page'] ) { register_setting( self::DEFAULTPREFIX . 'oc_options', self::DEFAULTPREFIX . 'enable' ); register_setting( self::DEFAULTPREFIX . 'oc_options', self::DEFAULTPREFIX . 'ttl' ); $ttl = $_POST[ self::DEFAULTPREFIX . 'ttl' ]; $is_update = update_site_option( self::DEFAULTPREFIX . 'homepage_ttl', $ttl, 'no' ); //overriding homepage TTL } self::disablePromoNotice(); } /** * Function enqueue resources * */ public function enqueue_resources( $hook ) { $pages = array( 'toplevel_page_onecom-vcache-plugin', 'one-com_page_onecom-vcache-plugin', '_page_onecom-vcache-plugin', 'one-com_page_onecom-cdn', '_page_onecom-wp-rocket', 'one-com_page_onecom-wp-rocket' ); if ( ! in_array( $hook, $pages, true ) ) { return; } if ( SCRIPT_DEBUG || SCRIPT_DEBUG === 'true' ) { $folder = ''; $extenstion = ''; } else { $folder = 'min-'; $extenstion = '.min'; } wp_register_style( self::PLUGINNAME, $this->oc_vc_uri . '/assets/' . $folder . 'css/style' . $extenstion . '.css', null, self::PLUGINVERSION, 'all' ); wp_enqueue_style( 'onecss', $this->oc_vc_uri . '/assets/min-css/one.min.css', null, self::PLUGINVERSION, 'all' ); wp_register_script( self::PLUGINNAME, $this->oc_vc_uri . '/assets/' . $folder . 'js/scripts' . $extenstion . '.js', array( 'jquery' ), self::PLUGINVERSION, 'all' ); wp_enqueue_style( self::PLUGINNAME ); wp_enqueue_script( self::PLUGINNAME ); if( 'toplevel_page_onecom-vcache-plugin' === $hook || 'one-com_page_onecom-vcache-plugin' === $hook) { wp_enqueue_script( 'cache-admin-form', plugins_url('/assets/js/blocks/oc-cache-settings.js', __FILE__), ['wp-element'], self::PLUGINVERSION, true ); } if( 'one-com_page_onecom-cdn' === $hook ) { wp_enqueue_script( 'cdn-admin-form' , plugins_url( '/assets/js/blocks/oc-cdn-settings.js' , __FILE__ ) , [ 'wp-element' ] , self::PLUGINVERSION , true ); } $varnish_caching_ttl = get_site_option( 'varnish_caching_ttl' ); $varnish_caching_ttl_unit = get_site_option( 'varnish_caching_ttl_unit' ); $varnish_caching = get_site_option( 'varnish_caching_enable' ); if ( 'minutes' === $varnish_caching_ttl_unit ) { $vc_ttl_as_unit = $varnish_caching_ttl / 60; } elseif ( 'hours' === $varnish_caching_ttl_unit ) { $vc_ttl_as_unit = $varnish_caching_ttl / 3600; } elseif ( 'days' === $varnish_caching_ttl_unit ) { $vc_ttl_as_unit = $varnish_caching_ttl / 86400; } else { $vc_ttl_as_unit = $varnish_caching_ttl; } wp_localize_script('cache-admin-form', 'vcacheSettings', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('vcaching'), 'vc_ttl' => $vc_ttl_as_unit, 'vc_ttl_unit' => $varnish_caching_ttl_unit, 'vc_status' => $varnish_caching, 'cache_ttl' => __( 'Cache TTL' , 'vcaching' ), 'frequency_ttl' => __( 'Frequency' , 'vcaching' ), 'clearCacheMessage' => array( 'success' => __('Your cache was cleared.', 'vcaching'), 'failure' => __('Couldn’t clear your cache. Please try again and contact our support if the issue persists.', 'vcaching'), ), 'settingsSaveMessage' => array( 'success' => __('Your changes were saved.', 'vcaching'), 'failure' => __('Couldn’t save your changes. Please try again and contact our support if the issue persists.', 'vcaching'), ), 'ttlValidationMsg' => __('TTL value must be at least 1 second.','vcaching'), 'frequency_options' => [ 'seconds' => __('Seconds', 'vcaching'), 'minutes' => __('Minutes', 'vcaching'), 'hours' => __('Hours', 'vcaching'), 'days' => __('Days', 'vcaching'), ], 'LblActive' => __('Active', 'vcaching'), 'LblInactive' => __('Inactive', 'vcaching'), 'TooltipMessage' => __('The time your website data will be stored in the Varnish cache. Our default value is 30 days. When the TTL expires, the cached content will be refreshed.', 'vcaching'), 'Ttlplaceholder' =>__('Enter Cache TTL','vcaching'), 'ClearCache' =>__('Clear Cache now','vcaching'), 'clearingCache' =>__('Clearing cache','vcaching'), 'labelSave' => __('Save', 'vcaching'), 'labelSaving' => __('Saving', 'vcaching'), 'imageDIR' => $this->onecom_vcache_dir_url, ]); $cdn_enabled = get_site_option( 'oc_cdn_enabled' ); $dev_mode_duration = parent::oc_json_get_option( 'onecom_vcache_info', 'dev_mode_duration' ); $oc_dev_mode_status = parent::oc_json_get_option( 'onecom_vcache_info', 'oc_dev_mode_enabled' ); $oc_exclude_cdn_data = parent::oc_json_get_option( 'onecom_vcache_info', 'oc_exclude_cdn_data' ); $oc_exclude_cdn_status = parent::oc_json_get_option( 'onecom_vcache_info', 'oc_exclude_cdn_enabled' ); wp_localize_script('cdn-admin-form', 'CdnSettings', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('vcaching'), 'clearCacheMessage' => array( 'success' => __('Your CDN cache was cleared.', 'vcaching'), 'failure' => __('Couldn’t clear your CDN cache. Please try again and contact our support if the issue persists.', 'vcaching'), ), 'settingsSaveMessage' => array( 'success' => __('Your changes were saved.', 'vcaching'), 'failure' => __('Couldn’t save your changes. Please try again and contact our support if the issue persists.', 'vcaching'), ), 'CdnStatus' => $cdn_enabled, 'devModeDuration' => $dev_mode_duration, 'devModeStatus' => $oc_dev_mode_status, 'excludeCdnData' => $oc_exclude_cdn_data, 'excludeCdnStatus' => $oc_exclude_cdn_status, 'lblActive' => __('Active', 'vcaching'), 'lblInactive' => __('Inactive', 'vcaching'), 'excludeTitle' => __('Exclude items from CDN' , 'vcaching'), 'excludeDescription' => __('Enter file names (myfile.jpg), file extensions (.jpg) or paths (wp-content/uploads/2025/file.jpg) that shouldn’t be delivered through CDN. Enter one item per line.' , 'vcaching'), 'excludeValidationMsg' => __('Enter what you want to exclude.' , 'vcaching'), 'excludeCdnMsg' => __('Enter one item per line' , 'vcaching'), 'CdnTitle' => __('CDN settings' , 'vcaching'), 'clearCache' => __('Clear CDN cache' , 'vcaching'), 'clearingCache' => __('Clearing CDN cache' , 'vcaching'), 'excludeValidationMsg' => __('Enter what you want to exclude.' , 'vcaching'), 'devModeTitle' => __('Activate development mode', 'vcaching'), 'devModeDescription' => __('Specify when development mode should get deactivated again (hours). Note that CDN is inactive for logged-in users while development mode is active.', 'vcaching'), 'mwpDisabledHeading' => __('This is a Managed WP feature', 'vcaching'), 'mwpDisabledMessage' => __('Upgrade now to get access to development mode and exclude CDN feature.', 'vcaching'), 'isMWP' => $this->oc_premium(), 'labelSave' => __('Save', 'vcaching'), 'labelSaving' => __('Saving', 'vcaching'), 'labelExclude' => __('Items to exclude', 'vcaching'), 'upgradeBtn' => __('Upgrade now', 'vcaching'), 'imageDIR' => $this->onecom_vcache_dir_url, ]); } /* Function to enqueue style tag in admin head * */ public function onecom_vcache_icon_css() { echo ""; return; } /* Function to show inline promo on premium cdn switches */ public function mwp_promo($cuJourneyEvent = '') { ob_start(); ?>
$_SERVER['SERVER_NAME'], 'X-VC-Purge-Method' => $purgemethod, 'X-VC-Purge-Host' => $_SERVER['SERVER_NAME'], ); $response = wp_remote_request( $purgeme, array( 'method' => 'PURGE', 'headers' => $headers, 'sslverify' => false, ) ); if ( $response instanceof WP_Error ) { error_log( 'Cannot purge: ' . $purgeme ); } } /** * Function to change purge settings * */ public function filter_purge_settings() { add_filter( 'ocvc_purge_notices', array( $this, 'ocvc_purge_notices_callback' ), 10, 2 ); add_filter( 'ocvc_purge_url', array( $this, 'ocvc_purge_url_callback' ), 1, 3 ); add_filter( 'ocvc_purge_headers', array( $this, 'ocvc_purge_headers_callback' ), 1, 2 ); add_filter( 'ocvc_permalink_notice', array( $this, 'ocvc_permalink_notice_callback' ) ); add_filter( 'vcaching_purge_urls', array( $this, 'vcaching_purge_urls_callback' ), 10, 2 ); add_action( 'admin_notices', array( $this, 'oc_vc_notice' ) ); add_action( 'network_admin_notices', array( $this, 'oc_vc_notice' ) ); } /** * Function to filter the purge request response * * @param object $response //request response object * @param string $url // url trying to purge */ public function ocvc_purge_notices_callback( $response, $url ) { $response = wp_remote_retrieve_body( $response ); $find = array( /* translators: %s is the URL of the resource being purged */ '404 Key not found' => sprintf( __( 'It seems that %s is already purged. There is no resource in the cache to purge.', 'vcaching' ), $url ), /* translators: %s is the URL of the resource that was purged */ 'Error 200 Purged' => sprintf( __( '%s is purged successfully.', 'vcaching' ), $url ), ); foreach ( $find as $key => $message ) { if ( strpos( $response, $key ) !== false ) { array_push( $this->messages, $message ); } } } /** * Function to add notice * */ public function oc_vc_notice() { if ( empty( $this->messages ) && empty( $_SESSION['ocvcaching_purge_note'] ) ) { return; } ?>
Permalinks Options Page to configure them.', 'vcaching' ); return '

' . $message . '

'; } /** * Function to to remove menu item from admin menu bar * */ public function remove_toolbar_node( $wp_admin_bar ) { // replace 'updraft_admin_node' with your node id $wp_admin_bar->remove_node( 'purge-all-varnish-cache' ); } /** * Function to to remove purge cache from post * */ public function remove_post_row_actions( $actions, $post ) { if ( isset( $actions['vcaching_purge_post'] ) ) { unset( $actions['vcaching_purge_post'] ); } return $actions; } /** * Function to to remove purge cache from page * */ public function remove_page_row_actions( $actions, $post ) { if ( isset( $actions['vcaching_purge_page'] ) ) { unset( $actions['vcaching_purge_page'] ); } return $actions; } /** * Function to set purge single post/page URL * * @param array $array_urls // array of urls * @param number $post_id //POST ID */ public function vcaching_purge_urls_callback( $array_urls, $post_id ) { $url = get_permalink( $post_id ); array_unshift( $array_urls, $url ); return $array_urls; } /** * Function vcaching_events_cb * Callback function for vcaching_events WP filter * This function checks if the registered events are to be returned, judging from request payload. * e.g. the events are nulled for request actions like "heartbeat" and "ocdi_import_demo_data" * @param $events, an array of events on which caching is hooked. * @return array */ public function vcaching_events_cb( $events ) { $no_post_action = ! isset( $_REQUEST['action'] ); $action_not_watched = isset( $_REQUEST['action'] ) && ( 'ocdi_import_demo_data' === $_REQUEST['action'] || 'heartbeat' === $_REQUEST['action'] ); if ( $no_post_action || $action_not_watched ) { return array(); } else { return $events; } } /** * Function vcaching_purge_urls_cb * Callback function for vcaching_purge_urls WP filters * This function removes all the urls that are to be purged and returns single url that purges entire cache. * @param $urls, an array of urls that were originally to be purged. * @return array */ public function vcaching_purge_urls_cb( $urls ) { $site_url = trailingslashit( get_site_url() ); $purge_url = $site_url . '.*'; $urls = array( $purge_url ); return $urls; } /** * Function vcaching_reset_dev_mode * This function deletes/reset development mode data on admin init * ** if development mode expire time passed */ public function vcaching_reset_dev_mode() { $cdn_dev_enabled = $this->oc_json_get_option( 'onecom_vcache_info', 'oc_dev_mode_enabled' ); $dev_expire_time = $this->oc_json_get_option( 'onecom_vcache_info', 'dev_expire_time' ); if ( 'true' === $cdn_dev_enabled && 'false' !== $dev_expire_time && $dev_expire_time < time() ) { // if development mode exists and expired, reset it $this->oc_json_delete_option( 'onecom_vcache_info', 'oc_dev_mode_enabled' ); $this->oc_json_delete_option( 'onecom_vcache_info', 'dev_expire_time' ); $this->oc_json_delete_option( 'onecom_vcache_info', 'dev_mode_duration' ); return true; } else { return false; } } /** * Function oc_set_vc_state_cb() * Enable/disable vcaching. Used as AJAX callback * @since v0.1.24 * @param null * @return null */ public function oc_set_vc_state_cb() { if ( ! isset( $_POST['oc_csrf'] ) && ! wp_verify_nonce( 'one_vcache_nonce' ) ) { return false; } $state = intval( $_POST['vc_state'] ) === 0 ? 'false' : 'true'; // check eligibility if Performance Cache is being enabled. If it is being disabled, allow to continue if ( 'true' === $state ) { $event_action = 'enable'; $res = $this->oc_check_pc_activation( $state ); if ( 'success' !== $res['status'] ) { wp_send_json( $res ); return false; } } else { $event_action = 'disable'; } if ( get_site_option( self::DEFAULTPREFIX . 'enable' ) === $state ) { $result_status = true; } else { $result_status = update_site_option( self::DEFAULTPREFIX . 'enable', $state, 'no' ); } $result_ttl = $this->oc_set_vc_ttl_cb( false ); $response = array(); if ( $result_ttl && $result_status ) { $response = array( 'status' => 'success', 'message' => __( 'Performance cache settings updated' ), ); ( class_exists( 'OCPushStats' ) ? \OCPushStats::push_stats_performance_cache( "$event_action", 'setting', 'cache', 'performance_cache' ) : '' ); } else { $response = array( 'status' => 'error', 'message' => __( 'Something went wrong!' ), ); } wp_send_json( $response ); } public function oc_set_vc_ttl_cb( $echo_oc ) { if ( wp_doing_ajax() && ! isset( $_POST['oc_csrf'] ) && ! wp_verify_nonce( 'one_vcache_nonce' ) ) { return false; } if ( '' === $echo_oc ) { $echo_oc = true; } $ttl_value = intval( trim( $_POST['vc_ttl'] ) ); $ttl = 0 === $ttl_value ? 2592000 : $ttl_value; $ttl_unit = trim( $_POST['vc_ttl_unit'] ); $ttl_unit = empty( $ttl_unit ) ? 'days' : $ttl_unit; // Convert into seconds except default value if ( 2592000 !== $ttl && 'minutes' === $ttl_unit ) { $ttl = $ttl * 60; } elseif ( 2592000 !== $ttl && 'hours' === $ttl_unit ) { $ttl = $ttl * 3600; } elseif ( 2592000 !== $ttl && 'days' === $ttl_unit ) { $ttl = $ttl * 86400; } if ( ( get_site_option( 'varnish_caching_ttl' ) === (string)$ttl ) && ( get_site_option( 'varnish_caching_homepage_ttl' ) === (string)$ttl ) && ( get_site_option( 'varnish_caching_ttl_unit' ) === (string)$ttl_unit ) ) { $result = true; } else { $result = update_site_option( 'varnish_caching_ttl', $ttl, 'no' ); update_site_option( 'varnish_caching_homepage_ttl', $ttl, 'no' ); update_site_option( 'varnish_caching_ttl_unit', $ttl_unit, 'no' ); ( class_exists( 'OCPushStats' ) ? \OCPushStats::push_stats_performance_cache( 'update', 'setting', 'ttl', 'performance_cache' ) : '' ); } $response = array(); if ( $result ) { $response = array( 'status' => 'success', 'message' => __( 'TTL updated' ), ); } else { $response = array( 'status' => 'error', 'message' => __( 'Something went wrong!' ), ); } if ( $echo_oc ) { wp_send_json( $response ); } else { return $result; } } /** * Activate a plugin */ public function oc_activate_wp_rocket() { $activation_status = is_null( activate_plugin( self::WP_ROCKET_PATH ) ); wp_send_json( array( 'status' => $activation_status ) ); } /** * Plugin activates on the button click * @return void */ public function onclick_plugin_activate() { $addon_slug = $_POST['addon_slug']; $transient_key = "{$addon_slug}_activation_button_clicked_at"; set_site_transient( $transient_key, current_time( 'timestamp' ), self::EXPIRATION_TIME_IN_MINUTES * MINUTE_IN_SECONDS ); $this->activate_wp_plugin( $addon_slug ); } /** * Addon status check on the button click * @return void */ public function check_addon_purchase_status() { $addon_slug = $_POST['addon_slug']; $transient_key = "{$addon_slug}_select_button_clicked_at"; set_site_transient( $transient_key, current_time( 'timestamp' ), self::EXPIRATION_TIME_IN_MINUTES * MINUTE_IN_SECONDS ); $this->addon_status_check( $addon_slug ); } /** * Check plugin activation on reload * @return void */ public function on_reload_addon_status_check() { $addon_slug = $_POST['addon_slug']; $this->addon_status_check( $addon_slug ); } /** * Check plugin activation on reload * @return void */ public function on_reload_plugin_activate_check() { $addon_slug = $_POST['addon_slug']; $this->activate_wp_plugin( $addon_slug ); } public function check_addon_purchase_response($getAddonStatus){ if (is_array($getAddonStatus) && array_key_exists('success', $getAddonStatus) && $getAddonStatus['success']) { if (array_key_exists('data', $getAddonStatus) && array_key_exists('source', $getAddonStatus['data']) && $getAddonStatus['data']['source'] === 'PURCHASED' && array_key_exists('product', $getAddonStatus['data']) && $getAddonStatus['data']['product'] === 'WP_ROCKET') { return true; } else { return false; } } else { error_log("Error fetching addon status from features endpoint: " . (is_array($getAddonStatus) && array_key_exists('error', $getAddonStatus) ? $getAddonStatus['error'] : 'Unknown error')); return false; } } /** * onclick and reload check * Addon purchase status */ public function addon_status_check($addon_slug) { $start_time_key = "{$addon_slug}_purchase_button_start_at"; $btn_transient_key = "{$addon_slug}_select_button_clicked_at"; $timeout_limit = self::EXPIRATION_TIME_IN_MINUTES * MINUTE_IN_SECONDS; $current_time = current_time('timestamp'); $plugin_slug = self::WR_SLUG; // Ensure the activation button was clicked if ( ! get_site_transient($btn_transient_key) ) { wp_send_json(['status' => 'normal_reload']); } // Common success response $send_success = function() use ($addon_slug) { error_log("Addon purchased successfully from WP-admin: {$addon_slug}"); $this->clear_addon_status_queue($addon_slug); //set status for activation plugin $this->set_transient_for_addon_activation($addon_slug); //addon purchased, now set transient for activation plugin wp_send_json([ 'status' => 'addon_purchased' ]); }; // If the plugin is already active, respond immediately if (is_plugin_active($plugin_slug)) { error_log("Plugin already active: {$plugin_slug}, skipping purchase check"); wp_send_json([ 'status' => 'already_plugin_active' ]); } $start_time = get_site_transient($start_time_key); // Case 1: First time select click attempt if (!$start_time) { set_site_transient($start_time_key, $current_time, $timeout_limit); wp_send_json(['status' => 'added_in_queue']); } //get addon purchase status, force refresh feature endpoint //call feature endpoint to get latest addon status $getAddonStatus = $this->oc_wp_rocket_addon_info(true); $addon_purchased = $this->check_addon_purchase_response($getAddonStatus); if ($addon_purchased) { $send_success(); } $elapsed_time = $current_time - (int) $start_time; $time_left = $timeout_limit - $elapsed_time; // Case 2: Stop polling early if less than 30 seconds left if ($time_left <= 30) { if ($addon_purchased) { $send_success(); } error_log("Polling stopped early (time left: {$time_left}s) for {$addon_slug}"); $this->clear_addon_status_queue($addon_slug); wp_send_json(['status' => 'expired_queue']); } // Case 3: Queue expired after timeout if ($elapsed_time >= $timeout_limit) { if ($addon_purchased) { $send_success(); } error_log("Addon not purchased and timed out: {$plugin_slug}"); $this->clear_addon_status_queue($addon_slug); wp_send_json(['status' => 'expired_queue']); } // Case 3: Queue still in progress error_log("Addon purchase in progress: {$plugin_slug}"); wp_send_json(['status' => 'already_in_queue']); } /** * onclick and reload check * Activate a plugin */ public function activate_wp_plugin($addon_slug) { $start_time_key = "{$addon_slug}_activation_start_at"; $btn_transient_key = "{$addon_slug}_activation_button_clicked_at"; $plugin_slug = self::WR_SLUG; $admin_url = admin_url('options-general.php?page=wprocket'); $plugin_btn_text = __('Go to WP Rocket plugin', 'vcaching'); $timeout_limit = self::EXPIRATION_TIME_IN_MINUTES * MINUTE_IN_SECONDS; $current_time = current_time('timestamp'); // Ensure the activation button was clicked if ( ! get_site_transient($btn_transient_key) ) { wp_send_json(['status' => 'normal_reload']); } // Common success response $send_success = function() use ($addon_slug, $plugin_slug, $admin_url, $plugin_btn_text) { error_log("Plugin activated successfully from WP-admin: {$plugin_slug}"); $this->clear_activation_queue($addon_slug); wp_send_json([ 'status' => 'activated', 'url' => $admin_url, 'btn_text' => $plugin_btn_text, ]); }; // If the plugin is already active, respond immediately if (is_plugin_active($plugin_slug)) { $send_success(); } $start_time = get_site_transient($start_time_key); // Case 1: First time activation attempt if (!$start_time) { set_site_transient($start_time_key, $current_time, $timeout_limit); if ($this->is_wp_rocket_installed()) { $result = activate_plugin($plugin_slug); if (is_wp_error($result)) { error_log("Plugin activation failed from WP-admin: {$plugin_slug}"); $this->clear_activation_queue($addon_slug); wp_send_json_error([ 'status' => 'activation_failed', 'message' => $result->get_error_message(), ]); } $send_success(); } // If not active, trigger provisioner if (!is_plugin_active($plugin_slug)) { $status = $this->call_wp_api_provisioner($addon_slug); error_log('PP status: ' . $status); wp_send_json(['status' => $status]); } } // Case 2: Existing queue, check timeout if (($current_time - (int) $start_time) >= $timeout_limit) { if (is_plugin_active($plugin_slug)) { $send_success(); } error_log("Plugin not activated and timed out: {$plugin_slug}"); $this->clear_activation_queue($addon_slug); wp_send_json(['status' => 'expired_queue']); } // Case 3: Queue still in progress error_log("Plugin activation in progress: {$plugin_slug}"); wp_send_json(['status' => 'already_in_queue']); } public function set_transient_for_addon_activation($addon_slug) { $activation_start_at = "{$addon_slug}_activation_start_at"; $activation_button_clicked_at = "{$addon_slug}_activation_button_clicked_at"; $pp_activation_start_at = "$addon_slug-pp-activation-start-at"; $timeout_limit = self::EXPIRATION_TIME_IN_MINUTES * MINUTE_IN_SECONDS; $current_time = current_time('timestamp'); set_site_transient( $activation_start_at, $current_time, $timeout_limit ); set_site_transient( $activation_button_clicked_at, $current_time, $timeout_limit ); set_site_transient( $pp_activation_start_at, $current_time, $timeout_limit ); } public function clear_activation_queue($addon_slug) { delete_site_transient( "{$addon_slug}_activation_start_at" ); delete_site_transient( "{$addon_slug}_activation_button_clicked_at" ); delete_site_transient( "$addon_slug-pp-activation-start-at" ); //clear cache if ( function_exists( 'wp_cache_flush' ) ) { wp_cache_flush(); } } public function clear_addon_status_queue($addon_slug) { delete_site_transient( "{$addon_slug}_purchase_button_start_at" ); delete_site_transient( "{$addon_slug}_select_button_clicked_at" ); //clear cache if ( function_exists( 'wp_cache_flush' ) ) { wp_cache_flush(); } } public function get_marketplace_prices(array $addons = array(), $force = false){ $countryCode = $this->get_cu_country_code(); $addons_param = rawurlencode(implode(', ', $addons)); // check transient $wp_marketplace_price = get_site_transient( 'onecom_marketplace_prices' ); if ( ! empty( $wp_marketplace_price ) && false === $force ) { error_log('Using transient marketplace prices'); return $wp_marketplace_price; } $curl_url = self::WR_MARKETPLACE_PRICES_API . '?addons=' . $addons_param . '&countryCode=' . rawurlencode($countryCode); $domain = isset( $_SERVER['ONECOM_DOMAIN_NAME'] ) ? $_SERVER['ONECOM_DOMAIN_NAME'] : false; $totp = function_exists('oc_generate_totp') ? oc_generate_totp() : ''; // Build headers similar to oc_wp_rocket_addon_info $http_header = array( 'Cache-Control: no-cache', ); if($domain){ $http_header[] = 'X-Onecom-Client-Domain: ' . $domain; } if($totp){ $http_header[] = 'X-TOTP: ' . $totp; } if ( function_exists('is_cluster_domain') && is_cluster_domain() ) { if(defined('OC_CLUSTER_ID')){ $http_header[] = 'X-ONECOM-CLUSTER-ID: ' . OC_CLUSTER_ID; } if(isset($_SERVER['HTTP_X_GROUPONE_WEBCONFIG_NAME'])){ $http_header[] = 'X-ONECOM-WEBCONFIG-NAME: ' . $_SERVER['HTTP_X_GROUPONE_WEBCONFIG_NAME']; } } $curl = curl_init(); curl_setopt_array( $curl, array( CURLOPT_URL => $curl_url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => $http_header ) ); $response = curl_exec( $curl ); $err = curl_error( $curl ); curl_close( $curl ); // Handle curl error if ( $err ) { return array( 'data' => null, 'error' => __( 'Some error occurred, please reload the page and try again.', 'validator' ), 'success' => false, ); } $response_arr = json_decode($response, true); if(!is_array($response_arr)){ return array( 'data' => null, 'error' => __( 'Invalid response from marketplace prices API.', 'vcaching' ), 'success' => false, ); } //set transient for next calls and return the latest response set_site_transient( 'onecom_marketplace_prices', $response_arr, 12 * HOUR_IN_SECONDS ); return $response_arr; } public function get_wpr_price(array $addons = array('WP_ROCKET')){ // Fetch prices from marketplace API for the requested addons and aggregate all valid ones. $api_resp = $this->get_marketplace_prices($addons); if (is_array($api_resp) && isset($api_resp['success']) && $api_resp['success'] && isset($api_resp['data']['prices']) && is_array($api_resp['data']['prices'])) { // Build an index of prices by addon for an easier lookup $prices_by_addon = array(); foreach ($api_resp['data']['prices'] as $price_entry) { if (!isset($price_entry['addon'])) { continue; } $prices_by_addon[$price_entry['addon']] = $price_entry; } $result = array('success' => true); $found_any = false; // Respect the order of requested addons. Collect all valid ones. foreach ($addons as $addon_name) { if (!isset($prices_by_addon[$addon_name])) { continue; } $price_entry = $prices_by_addon[$addon_name]; // Only include if a result is a valid array if (isset($price_entry['result']) && is_array($price_entry['result'])) { $r = $price_entry['result']; $result[$addon_name] = $r; $found_any = true; } } if ($found_any) { return $result; } } // If we reach here, no valid pricing available for requested addons; return error with success false as per requirement. return array( 'success' => false, 'error' => __( 'Requested addon price not available at the moment. Please try again later.', 'vcaching' ), ); } public function get_cu_country_code(){ $default = 'US'; $status = $this->oc_wp_rocket_addon_info(); $country_code = $default; if(is_array($status) && isset($status['data']) && is_array($status['data']) && !empty($status['data']['country'])) { $country_code = $status['data']['country']; } error_log("Country code use for addon price: $country_code"); return $country_code; } public function call_wp_api_provisioner($addon_slug) { if (empty($addon_slug)) { return; } //skip provisioner call if addon not subscribed if(!$this->is_wp_rocket_addon_purchased()){ error_log('addon_not_subscribed, skipping WP API Provisioner call: ' . $addon_slug); return 'addon_not_subscribed'; } error_log("Request plugin activation from wp-admin: $addon_slug"); //Just add the below key in onboarding also for sync $pp_start_at = "$addon_slug-pp-activation-start-at"; $start_time = get_site_transient( $pp_start_at ); if($start_time){ error_log("The provisioning request has already been sent; skipping the re-request: " . $addon_slug); return 'already_in_queue'; } error_log("Calling WP API Provisioner for plugin:" . $addon_slug); if (is_cluster_domain()) { $url = MIDDLEWARE_URL . '/plugin-provisioner/cluster'; } else { $url = onecom_query_check(MIDDLEWARE_URL . '/plugin-provisioner'); } add_filter('http_request_args', 'oc_add_http_headers', 10, 2); wp_remote_post( $url, array( 'body' => json_encode(array( 'subdomain' => OCPushStats::get_subdomain(), 'domain' => OCPushStats::get_domain(), 'addon_slug' => $addon_slug )) ) ); remove_filter('http_request_args', 'oc_add_http_headers'); // Push installed plugins with activation status ( class_exists( 'OCPUSHSTATS' ) ? \OCPushStats::push_stats_event_themes_and_plugins( 'plugin_install', 'blog', 'plugin_selector', "wpapi_provisoner" ) : '' ); return 'added_to_queue'; } /** * Section 3: Pricing + Features * @return void */ public function wp_rocket_pricing_table() { $wpr_features = [ __('Page and browser caching', 'vcaching'), __('GZIP compression', 'vcaching'), __('Cross-Origin support for web fonts', 'vcaching'), __('Detection and support of various third-party plugins, themes', 'vcaching'), __('Combination of inline and 3rd party scripts', 'vcaching'), __('WooCommerce Refresh Cart Fragments Cache', 'vcaching'), __('Optimise Google Fonts files', 'vcaching'), __('Optimise database and emojis', 'vcaching'), ]; //The default params will be WP_ROCKET $wpr_price = $this->get_wpr_price(); $addon_key = 'WP_ROCKET'; $has_price = (is_array($wpr_price) && isset($wpr_price['success']) && $wpr_price['success'] && isset($wpr_price[$addon_key]) && is_array($wpr_price[$addon_key])); $priceInclVat = $has_price ? $wpr_price[$addon_key]['fullPriceInclVat'] : ''; $currencySymbol = $has_price ? $wpr_price[$addon_key]['currency'] : ''; ?>

is_wp_rocket_addon_purchased()){?> is_wp_rocket_active() && $this->is_wp_rocket_addon_purchased()){ ?>

$wpr_feature) : ?>

$domain"; echo sprintf( __("You have a WP Rocket subscription for %s, but you still need to activate it for this installation. Activate the plugin to boost your site's performance.", 'vcaching'), $value); ?>

spinner
oc_json_get_option( 'onecom_vcache_info', 'oc_dev_mode_enabled' ); $dev_expire_time = $this->oc_json_get_option( 'onecom_vcache_info', 'dev_expire_time' ); // If development mode is not expired, skip CDN rewrite if ( 'true' === $cdn_dev_enabled && $dev_expire_time > time() && current_user_can( 'administrator' ) ) { return null; } elseif ( 'true' === $cdn_dev_enabled && 'false' !== $dev_expire_time && $dev_expire_time < time() ) { // if development mode exists but expired, reset it $this->oc_json_delete_option( 'onecom_vcache_info', 'oc_dev_mode_enabled' ); $this->oc_json_delete_option( 'onecom_vcache_info', 'dev_expire_time' ); $this->oc_json_delete_option( 'onecom_vcache_info', 'dev_mode_duration' ); } ob_start( array( $this, 'rewrite' ) ); } /** * Function rewrite * Rewrite assets url, replace native ones with the CDN version if the url meets rewrite conditions. * @since v0.1.24 * @param array $html, the html source of the page, provided by ob_start * @return string modified html source */ public function rewrite( $html ) { $url = get_option( 'home' ); if ( is_multisite() ) { $protocols = array( self::HTTPS, self::HTTP ); } else { $protocols = array( self::HTTPS, self::HTTP, '/' ); } $domain_name = str_replace( $protocols, '', $url ); $directories = 'wp-content'; if ( is_multisite() ) { $pattern = "#(?:https://{$domain_name}/{$directories})(\S*\.[0-9a-z]+)\b#m"; } else { $pattern = "/(?:https:\/\/$domain_name\/$directories)(\S*\.[0-9a-z]+)\b/m"; } //Take backup of script schema if class name found in script tag. $result = $this->backupScriptSchemas($html, ['rank-math-schema-pro' ,'rank-math-schema', 'yoast-schema-graph']); $updated_html = preg_replace_callback( $pattern, array( $this, 'rewrite_asset_url' ), $result['html'] ); //Rollback of script schema if class name found in script tag. return $this->restoreScriptSchemas($updated_html, $result['backups']); } /** * Extracts