diff --git a/wp-content/plugins/w3-total-cache/Cache.php b/wp-content/plugins/w3-total-cache/Cache.php index 65d5b7d9..87d72da7 100644 --- a/wp-content/plugins/w3-total-cache/Cache.php +++ b/wp-content/plugins/w3-total-cache/Cache.php @@ -1,4 +1,10 @@ available() ) { - $instances[$instance_key] = new Cache_Base( $config ); + if ( ! isset( $instances[ $instance_key ] ) || ! $instances[ $instance_key ]->available() ) { + $instances[ $instance_key ] = new Cache_Base( $config ); } } - return $instances[$instance_key]; + return $instances[ $instance_key ]; } /** * Returns caching engine name * - * @param unknown $engine - * @param unknown $module + * @param string $engine Engine key code. + * @param string $module Module. * * @return string */ - static public function engine_name( $engine, $module = '' ) { + public static function engine_name( $engine, $module = '' ) { switch ( $engine ) { - case 'memcached': - if ( class_exists( 'Memcached' ) ) - $engine_name = 'memcached'; - else - $engine_name = 'memcache'; + case 'memcached': + if ( class_exists( 'Memcached' ) ) { + $engine_name = 'Memcached'; + } else { + $engine_name = 'Memcache'; + } + break; - break; + case 'nginx_memcached': + $engine_name = 'Nginx + Memcached'; + break; - case 'nginx_memcached': - $engine_name = 'nginx + memcached'; - break; + case 'apc': + $engine_name = 'APC'; + break; - case 'apc': - $engine_name = 'apc'; - break; + case 'eaccelerator': + $engine_name = 'EAccelerator'; + break; - case 'eaccelerator': - $engine_name = 'eaccelerator'; - break; + case 'redis': + $engine_name = 'Redis'; + break; - case 'redis': - $engine_name = 'redis'; - break; + case 'xcache': + $engine_name = 'XCache'; + break; - case 'xcache': - $engine_name = 'xcache'; - break; + case 'wincache': + $engine_name = 'WinCache'; + break; - case 'wincache': - $engine_name = 'wincache'; - break; + case 'file': + if ( 'pgcache' === $module ) { + $engine_name = 'Disk: Basic'; + } else { + $engine_name = 'Disk'; + } + break; - case 'file': - if ( $module == 'pgcache' ) - $engine_name = 'disk: basic'; - else - $engine_name = 'disk'; - break; + case 'file_generic': + $engine_name = 'Disk: Enhanced'; + break; - case 'file_generic': - $engine_name = 'disk: enhanced'; - break; + case 'ftp': + $engine_name = 'Self-hosted / file transfer protocol upload'; + break; - case 'ftp': - $engine_name = 'self-hosted / file transfer protocol upload'; - break; + case 's3': + $engine_name = 'Amazon Simple Storage Service (S3)'; + break; - case 's3': - $engine_name = 'amazon simple storage service (s3)'; - break; + case 's3_compatible': + $engine_name = 'S3 compatible'; + break; - case 's3_compatible': - $engine_name = 's3 compatible'; - break; + case 'cf': + $engine_name = 'Amazon Cloudfront'; + break; - case 'cf': - $engine_name = 'amazon cloudfront'; - break; + case 'google_drive': + $engine_name = 'Google Drive'; + break; - case 'google_drive': - $engine_name = 'google drive'; - break; + case 'highwinds': + $engine_name = 'Highwinds'; + break; - case 'highwinds': - $engine_name = 'highwinds'; - break; + case 'cf2': + $engine_name = 'Amazon Cloudfront'; + break; - case 'cf2': - $engine_name = 'amazon cloudfront'; - break; + case 'rscf': + $engine_name = 'Rackspace Cloud Files'; + break; - case 'rscf': - $engine_name = 'rackspace cloud files'; - break; + case 'azure': + $engine_name = 'Microsoft Azure Storage'; + break; - case 'azure': - $engine_name = 'microsoft azure storage'; - break; + case 'edgecast': + $engine_name = 'Media Template ProCDN / EdgeCast'; + break; - case 'edgecast': - $engine_name = 'media template procdn / edgecast'; - break; + case 'att': + $engine_name = 'AT&T'; + break; - case 'att': - $engine_name = 'at&t'; - break; + case 'rackspace_cdn': + $engine_name = 'Rackspace'; + break; - case 'rackspace_cdn': - $engine_name = 'rackspace'; - break; + case 'stackpath2': + $engine_name = 'StackPath'; + break; - case 'stackpath2': - $engine_name = 'stackpath'; - break; + case 'bunnycdn': + $engine_name = 'Bunny CDN'; + break; - default: - $engine_name = $engine; - break; + case '': + $engine_name = __( 'None', 'w3-total-cache' ); + break; + + default: + $engine_name = $engine; + break; } return $engine_name; } - } diff --git a/wp-content/plugins/w3-total-cache/CacheFlush.php b/wp-content/plugins/w3-total-cache/CacheFlush.php index 80930b32..d78f86fd 100644 --- a/wp-content/plugins/w3-total-cache/CacheFlush.php +++ b/wp-content/plugins/w3-total-cache/CacheFlush.php @@ -92,11 +92,14 @@ class CacheFlush { } /** - * Purge CDN mirror cache + * Purge CDN mirror cache. + * + * @param array $extras Extra configuration. */ - function cdn_purge_all( $extras = array() ) { - if ( $this->_config->get_boolean( 'cdn.enabled' ) ) + public function cdn_purge_all( $extras = array() ) { + if ( $this->_config->get_boolean( 'cdn.enabled' ) || $this->_config->get_boolean( 'cdnfsd.enabled' ) ) { return $this->_executor->cdn_purge_all( $extras ); + } return false; } diff --git a/wp-content/plugins/w3-total-cache/CacheGroups_Plugin_Admin_View.php b/wp-content/plugins/w3-total-cache/CacheGroups_Plugin_Admin_View.php index 1cd03412..bf946be9 100644 --- a/wp-content/plugins/w3-total-cache/CacheGroups_Plugin_Admin_View.php +++ b/wp-content/plugins/w3-total-cache/CacheGroups_Plugin_Admin_View.php @@ -122,7 +122,7 @@ if ( ! defined( 'W3TC' ) ) { - + - + @@ -310,7 +310,7 @@ if ( ! defined( 'W3TC' ) ) { - + '', + 'storage_api_key' => '', + 'stream_api_key' => '', + 'pull_zone_id' => null, + 'domain' => '', + ), + $config + ); + + parent::__construct( $config ); + } + + /** + * Purge remote files. + * + * @since X.X.X + * + * @param array $files Local and remote file paths. + * @param array $results Results. + * @return bool + */ + public function purge( $files, &$results ) { + if ( empty( $this->_config['account_api_key'] ) ) { + $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, \__( 'Missing account API key.', 'w3-total-cache' ) ); + + return false; + } + + if ( empty( $this->_config['cdn_hostname'] ) ) { + $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, \__( 'Missing CDN hostname.', 'w3-total-cache' ) ); + + return false; + } + + $url_prefixes = $this->url_prefixes(); + $api = new Cdn_BunnyCdn_Api( $this->_config ); + $results = array(); + + try { + $items = array(); + + foreach ( $files as $file ) { + foreach ( $url_prefixes as $prefix ) { + $items[] = array( + 'url' => $prefix . '/' . $file['remote_path'], + 'recursive' => true, + ); + } + } + + $api->purge( array( 'items' => $items ) ); + + $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_OK, 'OK' ); + } catch ( \Exception $e ) { + $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, \__( 'Could not purge pull zone items: ', 'w3-total-cache' ) . $e->getMessage() ); + } + + return ! $this->_is_error( $results ); + } + + /** + * Purge CDN completely. + * + * @since X.X.X + * + * @param array $results Results. + * @return bool + */ + public function purge_all( &$results ) { + if ( empty( $this->_config['account_api_key'] ) ) { + $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Missing account API key.', 'w3-total-cache' ) ); + + return false; + } + + // Purge active pull zones: CDN & CDNFSD. + $active_zone_ids = array(); + $config = Dispatcher::config(); + $cdn_zone_id = $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ); + $cdnfsd_zone_id = $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); + + if ( $config->get_boolean( 'cdn.enabled' ) && 'bunnycdn' === $config->get_string( 'cdn.engine' ) && $cdn_zone_id ) { + $active_ids[] = $cdn_zone_id; + } + + if ( $config->get_boolean( 'cdnfsd.enabled' ) && 'bunnycdn' === $config->get_string( 'cdnfsd.engine' ) && $cdnfsd_zone_id ) { + $active_ids[] = $cdnfsd_zone_id; + } + + if ( empty( $active_ids ) ) { + $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Missing pull zone id.', 'w3-total-cache' ) ); + + return false; + } + + $results = array(); + + foreach ( $active_ids as $id ) { + $api = new Cdn_BunnyCdn_Api( array_merge( $this->_config, array( 'pull_zone_id' => $id ) ) ); + + try { + $api->purge_pull_zone(); + $results[] = $this->_get_result( '', '' ); // W3TC_CDN_RESULT_OK. + } catch ( \Exception $e ) { + $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, \__( 'Could not purge pull zone', 'w3-total-cache' ) . '; ' . $e->getMessage() ); + } + } + + return ! $this->_is_error( $results ); + } + + /** + * Get URL prefixes. + * + * If set to "auto", then add URLs for both "http" and "https". + * + * @since X.X.X + * + * @return array + */ + private function url_prefixes() { + $url_prefixes = array(); + + if ( 'auto' === $this->_config['ssl'] || 'enabled' === $this->_config['ssl'] ) { + $url_prefixes[] = 'https://' . $this->_config['cdn_hostname']; + } + if ( 'auto' === $this->_config['ssl'] || 'enabled' !== $this->_config['ssl'] ) { + $url_prefixes[] = 'http://' . $this->_config['cdn_hostname']; + } + + return $url_prefixes; + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_AdminActions.php b/wp-content/plugins/w3-total-cache/Cdn_AdminActions.php index 268a3ad6..b33ea7f4 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_AdminActions.php +++ b/wp-content/plugins/w3-total-cache/Cdn_AdminActions.php @@ -413,6 +413,7 @@ class Cdn_AdminActions { $engine == 'stackpath2' || $engine == 'rackspace_cdn' || $engine == 'rscf' || + 'bunnycdn' === $engine || $engine == 's3_compatible' ) { // those use already stored w3tc config $w3_cdn = Dispatcher::component( 'Cdn_Core' )->get_cdn(); @@ -462,46 +463,69 @@ class Cdn_AdminActions { $container_id = ''; switch ( $engine ) { - case 's3': - case 'cf': - case 'cf2': - case 'azure': - $w3_cdn = CdnEngine::instance( $engine, $config ); + case 's3': + case 'cf': + case 'cf2': + case 'azure': + $w3_cdn = CdnEngine::instance( $engine, $config ); - @set_time_limit( $this->_config->get_integer( 'timelimit.cdn_upload' ) ); + @set_time_limit( $this->_config->get_integer( 'timelimit.cdn_upload' ) ); - $result = false; - try { - $container_id = $w3_cdn->create_container(); - $result = true; - $error = __( 'Created successfully.', 'w3-total-cache' ); - } catch ( \Exception $ex ) { - $error = sprintf( __( 'Error: %s', 'w3-total-cache' ), - $ex->getMessage() ); - } + $result = false; - break; - default: - $result = false; - $error = __( 'Incorrect type.', 'w3-total-cache' ); + try { + $container_id = $w3_cdn->create_container(); + $result = true; + $error = __( 'Created successfully.', 'w3-total-cache' ); + } catch ( \Exception $ex ) { + $error = sprintf( + __( 'Error: %s', 'w3-total-cache' ), + $ex->getMessage() + ); + } + + break; + + default: + $result = false; + $error = __( 'Incorrect type.', 'w3-total-cache' ); } $response = array( - 'result' => $result, - 'error' => $error, - 'container_id' => $container_id + 'result' => $result, + 'error' => $error, + 'container_id' => $container_id, ); echo json_encode( $response ); } + /** + * Redirect to the Bunny CDN signup page. + * + * @since X.X.X + * + * @return void + */ + public function w3tc_cdn_bunnycdn_signup() { + try { + $state = Dispatcher::config_state(); + $state->set( 'track.bunnycdn_signup', time() ); + $state->save(); + } catch ( \Exception $ex ) {} // phpcs:ignore + Util_Environment::redirect( W3TC_BUNNYCDN_SIGNUP_URL ); + } - + /** + * Test CDN URL. + * + * @param string $url URL. + */ private function test_cdn_url( $url ) { $response = wp_remote_get( $url ); - if ( is_wp_error( $response ) ) + if ( is_wp_error( $response ) ) { return false; - else { + } else { $code = wp_remote_retrieve_response_code( $response ); return 200 == $code; } diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Api.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Api.php new file mode 100644 index 00000000..7fc0304e --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Api.php @@ -0,0 +1,552 @@ + 15, // BypassPermaCache. + 'TriggerMatchingType' => 0, // MatchAny. + 'Enabled' => true, + 'Triggers' => array( + array( + 'Type' => 3, // UrlExtension. + 'PatternMatchingType' => 0, // MatchAny. + 'PatternMatches' => array( '.zip' ), + ), + ), + 'Description' => 'Bypass PermaCache for ZIP files', + ), + array( + 'ActionType' => 3, // OverrideCacheTime. + 'TriggerMatchingType' => 0, // MatchAny. + 'ActionParameter1' => '0', + 'ActionParameter2' => '', + 'Enabled' => true, + 'Triggers' => array( + array( + 'Type' => 1, // RequestHeader. + 'PatternMatchingType' => 0, // MatchAny. + 'PatternMatches' => array( + '*wordpress_logged_in_*', + '*wordpress_sec_*', + ), + 'Parameter1' => 'Cookie', + ), + ), + 'Description' => 'Override Cache Time if logged into WordPress', + ), + array( + 'ActionType' => 15, // BypassPermaCache. + 'TriggerMatchingType' => 0, // MatchAny. + 'Enabled' => true, + 'Triggers' => array( + array( + 'Type' => 1, // RequestHeader. + 'PatternMatchingType' => 0, // MatchAny. + 'PatternMatches' => array( + '*wordpress_logged_in_*', + '*wordpress_sec_*', + ), + 'Parameter1' => 'Cookie', + ), + ), + 'Description' => 'Bypass PermaCache if logged into WordPress', + ), + array( + 'ActionType' => 16, // OverrideBrowserCacheTime. + 'TriggerMatchingType' => 0, // MatchAny. + 'ActionParameter1' => '0', + 'Enabled' => true, + 'Triggers' => array( + array( + 'Type' => 1, // RequestHeader. + 'PatternMatchingType' => 0, // MatchAny. + 'PatternMatches' => array( + '*wordpress_logged_in_*', + '*wordpress_sec_*', + ), + 'Parameter1' => 'Cookie', + ), + ), + 'Description' => 'Override Browser Cache Time if logged into WordPress', + ), + ); + + /** + * Constructor. + * + * @since X.X.X + * + * @param array $config Configuration. + */ + public function __construct( array $config ) { + $this->account_api_key = ! empty( $config['account_api_key'] ) ? $config['account_api_key'] : ''; + $this->storage_api_key = ! empty( $config['storage_api_key'] ) ? $config['storage_api_key'] : ''; + $this->stream_api_key = ! empty( $config['stream_api_key'] ) ? $config['stream_api_key'] : ''; + $this->pull_zone_id = ! empty( $config['pull_zone_id'] ) ? $config['pull_zone_id'] : ''; + } + + /** + * Increase http request timeout to 60 seconds. + * + * @since X.X.X + * + * @param int $time Timeout in seconds. + */ + public function filter_timeout_time( $time ) { + return 600; + } + + /** + * Don't check certificate, some users have limited CA list + * + * @since X.X.X + * + * @param bool $verify Always false. + */ + public function https_ssl_verify( $verify = false ) { + return false; + } + + /** + * List pull zones. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_index + * + * @return array + */ + public function list_pull_zones() { + $this->api_type = 'account'; + + return $this->wp_remote_get( \esc_url( 'https://api.bunny.net/pullzone' ) ); + } + + /** + * Get pull zone details by pull zone id. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_index2 + * + * @param int $id Pull zone id. + * @return array + */ + public function get_pull_zone( $id ) { + $this->api_type = 'account'; + + return $this->wp_remote_get( + \esc_url( 'https://api.bunny.net/pullzone/id' . $id ) + ); + } + + /** + * Add a pull zone. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_add + * + * @param array $data { + * Data used to create the pull zone. + * + * @type string $Name The name/hostname for the pull zone where the files will be accessible; only letters, numbers, and dashes. + * @type string $OriginUrl Origin URL or IP (with optional port number). + * @type string $OriginHostHeader Optional: The host HTTP header that will be sent to the origin. If empty, hostname will be automatically extracted from the Origin URL. + * @type bool $AddHostHeader Optional: If enabled, the original host header of the request will be forwarded to the origin server. This should be disabled in most cases. + * } + * + * @return array + * @throws \Exception Exception. + */ + public function add_pull_zone( array $data ) { + $this->api_type = 'account'; + + if ( empty( $data['Name'] ) || ! \is_string( $data['Name'] ) ) { // A Name string is required, which is used for the CDN hostname. + throw new \Exception( \esc_html__( 'A pull zone name (string) is required.', 'w3-total-cache' ) ); + } + + if ( \preg_match( '[^\w\d-]', $data['Name'] ) ) { // Only letters, numbers, and dashes are allowed in the Name. + throw new \Exception( \esc_html__( 'A pull zone name (string) is required.', 'w3-total-cache' ) ); + } + + return $this->wp_remote_post( + 'https://api.bunny.net/pullzone', + $data + ); + } + + /** + * Update a pull zone. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_updatepullzone + * + * @param int $id Optional pull zone ID. Can be specified in the constructor configuration array parameter. + * @param array $data Data used to update the pull zone. + * @return array + * @throws \Exception Exception. + */ + public function update_pull_zone( $id, array $data ) { + $this->api_type = 'account'; + $id = empty( $this->pull_zone_id ) ? $id : $this->pull_zone_id; + + if ( empty( $id ) || ! \is_int( $id ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + return $this->wp_remote_post( + 'https://api.bunny.net/pullzone/' . $id, + $data + ); + } + + /** + * Delete a pull zone. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_delete + * + * @param int $id Optional pull zone ID. Can be specified in the constructor configuration array parameter. + * @return array + * @throws \Exception Exception. + */ + public function delete_pull_zone( $id ) { + $this->api_type = 'account'; + $id = empty( $this->pull_zone_id ) ? $id : $this->pull_zone_id; + + if ( empty( $id ) || ! \is_int( $id ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + return $this->wp_remote_post( + \esc_url( 'https://api.bunny.net/pullzone/' . $id ), + array(), + array( 'method' => 'DELETE' ) + ); + } + + /** + * Add a custom hostname to a pull zone. + * + * @since X.X.X + * + * @link https://docs.bunny.net/reference/pullzonepublic_addhostname + * + * @param string $hostname Custom hostname. + * @param int $pull_zone_id Optional pull zone ID. Can be specified in the constructor configuration array parameter. + * @return void + * @throws \Exception Exception. + */ + public function add_custom_hostname( $hostname, $pull_zone_id = null ) { + $this->api_type = 'account'; + $pull_zone_id = empty( $this->pull_zone_id ) ? $pull_zone_id : $this->pull_zone_id; + + if ( empty( $pull_zone_id ) || ! \is_int( $pull_zone_id ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + if ( empty( $hostname ) || ! \filter_var( $hostname, FILTER_VALIDATE_DOMAIN ) ) { + throw new \Exception( \esc_html__( 'Invalid hostname', 'w3-total-cache' ) . ' "' . \esc_html( $hostname ) . '".' ); + } + + $this->wp_remote_post( + \esc_url( 'https://api.bunny.net/pullzone/' . $pull_zone_id . '/addHostname' ), + array( 'Hostname' => $hostname ) + ); + } + + /** + * Get the default edge rules. + * + * @since X.X.X + * @static + * + * @return array + */ + public static function get_default_edge_rules() { + return self::$default_edge_rules; + } + + /** + * Add/Update Edge Rule. + * + * @since X.X.X + * + * @param array $data Data. + * @param int $pull_zone_id Optional pull zone ID. Can be specified in the constructor configuration array parameter. + * @return void + * @throws \Exception Exception. + */ + public function add_edge_rule( array $data, $pull_zone_id = null ) { + $this->api_type = 'account'; + $pull_zone_id = empty( $this->pull_zone_id ) ? $pull_zone_id : $this->pull_zone_id; + + if ( empty( $pull_zone_id ) || ! \is_int( $pull_zone_id ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + if ( ! isset( $data['ActionType'] ) || ! \is_int( $data['ActionType'] ) || $data['ActionType'] < 0 ) { + throw new \Exception( \esc_html__( 'Invalid parameter "ActionType".', 'w3-total-cache' ) ); + } + + if ( ! isset( $data['TriggerMatchingType'] ) || ! \is_int( $data['TriggerMatchingType'] ) || $data['TriggerMatchingType'] < 0 ) { + throw new \Exception( \esc_html__( 'Invalid parameter "TriggerMatchingType".', 'w3-total-cache' ) ); + } + + if ( ! isset( $data['Enabled'] ) || ! \is_bool( $data['Enabled'] ) ) { + throw new \Exception( \esc_html__( 'Missing parameter "Enabled".', 'w3-total-cache' ) ); + } + + if ( empty( $data['Triggers'] ) ) { + throw new \Exception( \esc_html__( 'Missing parameter "Triggers".', 'w3-total-cache' ) ); + } + + $this->wp_remote_post( + \esc_url( 'https://api.bunny.net/pullzone/' . $pull_zone_id . '/edgerules/addOrUpdate' ), + $data + ); + } + + /** + * Purge. + * + * @since X.X.X + * + * @param array $data Data for the POST request. + * @return array + */ + public function purge( array $data ) { + $this->api_type = 'account'; + + return $this->wp_remote_get( + \esc_url( 'https://api.bunny.net/purge' ), + $data + ); + } + + /** + * Purge an entire pull zone. + * + * @since X.X.X + * + * @param int $pull_zone_id Optional pull zone ID. Can be specified in the constructor configuration array parameter. + * @return void + * @throws \Exception Exception. + */ + public function purge_pull_zone( $pull_zone_id = null ) { + $this->api_type = 'account'; + $pull_zone_id = empty( $this->pull_zone_id ) ? $pull_zone_id : $this->pull_zone_id; + + if ( empty( $pull_zone_id ) || ! \is_int( $pull_zone_id ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + $this->wp_remote_post( \esc_url( 'https://api.bunny.net/pullzone/' . $pull_zone_id . '/purgeCache' ) ); + } + + /** + * Get the API key by API type. + * + * API type can be passed or the class property will be used. + * + * @since X.X.X + * + * @param string $type API type: One of "account", "storage", "stream" (optional). + * @return string|null + * @throws \Exception Exception. + */ + private function get_api_key( $type = null ) { + if ( empty( $type ) ) { + $type = $this->api_type; + } + + if ( ! \in_array( $type, array( 'account', 'storage', 'stream' ), true ) ) { + throw new \Exception( \esc_html__( 'Invalid API type; must be one of "account", "storage", "stream".', 'w3-total-cache' ) ); + } + + if ( empty( $this->{$type . '_api_key'} ) ) { + throw new \Exception( \esc_html__( 'API key value is empty.', 'w3-total-cache' ) ); + } + + return $this->{$type . '_api_key'}; + } + + /** + * Decode response from a wp_remote_* call. + * + * @since X.X.X + * + * @param array|WP_Error $result Result. + * @return array + * @throws \Exception Exception. + */ + private function decode_response( $result ) { + if ( \is_wp_error( $result ) ) { + throw new \Exception( \esc_html__( 'Failed to reach API endpoint', 'w3-total-cache' ) ); + } + + $response_body = @\json_decode( $result['body'], true ); + + // Throw an exception if the response code/status is not ok. + if ( ! \in_array( $result['response']['code'], array( 200, 201, 204 ), true ) ) { + $message = isset( $response_body['Message'] ) ? $response_body['Message'] : $result['body']; + + throw new \Exception( + \esc_html( \__( 'Response code ', 'w3-total-cache' ) . $result['response']['code'] . ': ' . $message ) + ); + } + + return \is_array( $response_body ) ? $response_body : array(); + } + + /** + * Remote GET request. + * + * @since X.X.X + * + * @link https://developer.wordpress.org/reference/functions/wp_remote_get/ + * @link https://developer.wordpress.org/reference/classes/wp_http/request/ + * + * @param string $url URL address. + * @param array $data Query string data for the GET request. + * @return array + */ + private function wp_remote_get( $url, array $data = array() ) { + $api_key = $this->get_api_key(); + + \add_filter( 'http_request_timeout', array( $this, 'filter_timeout_time' ) ); + \add_filter( 'https_ssl_verify', array( $this, 'https_ssl_verify' ) ); + + $result = \wp_remote_get( + $url . ( empty( $data ) ? '' : '?' . \http_build_query( $data ) ), + array( + 'headers' => array( + 'AccessKey' => $api_key, + 'Accept' => 'application/json', + ), + ) + ); + + \remove_filter( 'https_ssl_verify', array( $this, 'https_ssl_verify' ) ); + \remove_filter( 'http_request_timeout', array( $this, 'filter_timeout_time' ) ); + + return self::decode_response( $result ); + } + + /** + * Remote POST request. + * + * @since X.X.X + * + * @link https://developer.wordpress.org/reference/functions/wp_remote_post/ + * @link https://developer.wordpress.org/reference/classes/wp_http/request/ + * + * @param string $url URL address. + * @param array $data Optional data for the POSt request. + * @param array $args Optional additional arguments for the wp_remote_port call. + * @return string + */ + private function wp_remote_post( $url, array $data = array(), array $args = array() ) { + $api_key = $this->get_api_key(); + + \add_filter( 'http_request_timeout', array( $this, 'filter_timeout_time' ) ); + \add_filter( 'https_ssl_verify', array( $this, 'https_ssl_verify' ) ); + + $result = \wp_remote_post( + $url, + \array_merge( + array( + 'headers' => array( + 'AccessKey' => $api_key, + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ), + 'body' => empty( $data ) ? null : \json_encode( $data ), + ), + $args + ) + ); + + \remove_filter( 'https_ssl_verify', array( $this, 'https_ssl_verify' ) ); + \remove_filter( 'http_request_timeout', array( $this, 'filter_timeout_time' ) ); + + return self::decode_response( $result ); + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page.php new file mode 100644 index 00000000..95aadc39 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page.php @@ -0,0 +1,204 @@ +get_boolean( 'cdn.enabled' ); + $cdn_engine = $config->get_string( 'cdn.engine' ); + $cdn_zone_id = $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ); + $cdnfsd_enabled = $config->get_boolean( 'cdnfsd.enabled' ); + $cdnfsd_engine = $config->get_string( 'cdnfsd.engine' ); + $cdnfsd_zone_id = $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + + return ( $account_api_key && + ( + ( $cdn_enabled && 'bunnycdn' === $cdn_engine && $cdn_zone_id ) || + ( $cdnfsd_enabled && 'bunnycdn' === $cdnfsd_engine && $cdnfsd_zone_id ) + ) + ); + } + + /** + * Add Dashboard actions. + * + * @since X.X.X + * @static + * + * @see self::in_active() + * + * @param array $actions Actions. + * @return array + */ + public static function w3tc_dashboard_actions( array $actions ) { + if ( self::is_active() ) { + $modules = Dispatcher::component( 'ModuleStatus' ); + $can_empty_memcache = $modules->can_empty_memcache(); + $can_empty_opcode = $modules->can_empty_opcode(); + $can_empty_file = $modules->can_empty_file(); + $can_empty_varnish = $modules->can_empty_varnish(); + + $actions[] = sprintf( + '', + esc_attr__( 'Empty All Caches Except Bunny CDN', 'w3-total-cache' ), + ( ! $can_empty_memcache && ! $can_empty_opcode && ! $can_empty_file && ! $can_empty_varnish ) ? ' disabled="disabled"' : '' + ); + } + + return $actions; + } + + /** + * Enqueue scripts. + * + * Called from plugin-admin. + * + * @since X.X.X + * @static + * + * @return void + */ + public static function admin_print_scripts_w3tc_cdn() { + $config = Dispatcher::config(); + $is_authorized = ! empty( $config->get_string( 'cdn.bunnycdn.account_api_key' ) ) && + ( $config->get_string( 'cdn.bunnycdn.pull_zone_id' ) || $config->get_string( 'cdnfsd.bunnycdn.pull_zone_id' ) ); + + \wp_register_script( + 'w3tc_cdn_bunnycdn', + \plugins_url( 'Cdn_BunnyCdn_Page_View.js', W3TC_FILE ), + array( 'jquery' ), + W3TC_VERSION + ); + + \wp_localize_script( + 'w3tc_cdn_bunnycdn', + 'W3TC_Bunnycdn', + array( + 'is_authorized' => $is_authorized, + 'lang' => array( + 'empty_url' => \esc_html__( 'No URL specified', 'w3-total-cache' ), + 'success_purging' => \esc_html__( 'Successfully purged URL', 'w3-total-cache' ), + 'error_purging' => \esc_html__( 'Error purging URL', 'w3-total-cache' ), + 'error_ajax' => \esc_html__( 'Error with AJAX', 'w3-total-cache' ), + ), + ) + ); + + \wp_enqueue_script( 'w3tc_cdn_bunnycdn' ); + } + + /** + * CDN settings. + * + * @since X.X.X + * @static + * + * @return void + */ + public static function w3tc_settings_cdn_boxarea_configuration() { + $config = Dispatcher::config(); + + include W3TC_DIR . '/Cdn_BunnyCdn_Page_View.php'; + } + + /** + * Display purge URLs page. + * + * @since X.X.X + * @static + */ + public static function w3tc_purge_urls_box() { + $config = Dispatcher::config(); + + include W3TC_DIR . '/Cdn_BunnyCdn_Page_View_Purge_Urls.php'; + } + + /** + * W3TC AJAX: Purge a URL. + * + * Purging a URL will remove the file from the CDN cache and re-download it from your origin server. + * Please enter the exact CDN URL of each individual file. + * You can also purge folders or wildcard files using * inside of the URL path. + * Wildcard values are not supported if using Perma-Cache. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_purge_url() { + $url = Util_Request::get_string( 'url' ); + + // Check if URL starts with "http", starts with a valid protocol, and passes a URL validation check. + if ( 0 !== \strpos( $url, 'http' ) || ! \preg_match( '~^http(s?)://(.+)~i', $url ) || ! \filter_var( $url, FILTER_VALIDATE_URL ) ) { + \wp_send_json_error( + array( 'error_message' => \esc_html__( 'Invalid URL', 'w3-total-cache' ) ), + 400 + ); + } + + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to delete pull zone. + try { + $api->purge( + array( + 'url' => \esc_url( $url, array( 'http', 'https' ) ), + 'async' => true, + ) + ); + } catch ( \Exception $ex ) { + \wp_send_json_error( array( 'error_message' => $ex->getMessage() ), 422 ); + } + + \wp_send_json_success(); + } + + /** + * Flush all caches except Bunny CDN. + * + * @since X.X.X + */ + public function w3tc_bunnycdn_flush_all_except_bunnycdn() { + Dispatcher::component( 'CacheFlush' )->flush_all( array( 'bunnycdn' => 'skip' ) ); + Util_Admin::redirect( array( 'w3tc_note' => 'flush_all' ), true ); + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.js b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.js new file mode 100644 index 00000000..4dde97aa --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.js @@ -0,0 +1,249 @@ +/** + * File: Cdn_BunnyCdn_Page_View.js + * + * @since X.X.X + * @package W3TC + * + * @global W3TC_Bunnycdn Localization array for info and language. + */ + +jQuery(function($) { + /** + * Resize the popup modal. + * + * @param object o W3tc_Lightbox object. + */ + function w3tc_bunnycdn_resize(o) { + o.options.height = $('.w3tc_cdn_bunnycdn_form').height(); + o.resize(); + } + + // Add event handlers. + $('body') + // Load the authorization form. + .on('click', '.w3tc_cdn_bunnycdn_authorize', function() { + W3tc_Lightbox.open({ + id:'w3tc-overlay', + close: '', + width: 800, + height: 300, + url: ajaxurl + + '?action=w3tc_ajax&_wpnonce=' + + w3tc_nonce + + '&w3tc_action=cdn_bunnycdn_intro', + callback: w3tc_bunnycdn_resize + }); + }) + + // Sanitize the account API key input value. + .on('change', '#w3tc-account-api-key', function() { + var $this = $(this); + + $this.val($.trim($this.val().replace(/[^a-z0-9-]/g, ''))); + }) + + // Load the pull zone selection form. + .on('click', '.w3tc_cdn_bunnycdn_list_pull_zones', function() { + var url = ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce + + '&w3tc_action=cdn_bunnycdn_list_pull_zones'; + + W3tc_Lightbox.load_form(url, '.w3tc_cdn_bunnycdn_form', w3tc_bunnycdn_resize); + }) + + // Enable/disable (readonly) add pull zone form fields based on selection. + .on('change', '#w3tc-pull-zone-id', function() { + var $selected_option = $(this).find(':selected'), + $origin = $('#w3tc-origin-url'), + $name = $('#w3tc-pull-zone-name'), + $hostnames = $('#w3tc-custom-hostnames'); + + if ($(this).find(':selected').val() === '') { + // Enable the add pull zone fields with suggested or entered values. + $origin.val($origin.data('suggested')).prop('readonly', false); + $name.val($name.data('suggested')).prop('readonly', false); + $hostnames.val($hostnames.data('suggested')).prop('readonly', false); + } else { + // Disable the add pull zone fields and change values using the selected option. + $origin.prop('readonly', true).val($selected_option.data('origin')); + $name.prop('readonly', true).val($selected_option.data('name')); + $hostnames.prop('readonly', true).val($selected_option.data('custom-hostnames')); + } + + // Update the hidden input field for the selected pull zone id from the select option value. + $('[name="pull_zone_id"]').val($selected_option.val()); + + // Update the hidden input field for the selected pull zone CDN hostname from the select option value. + $('[name="cdn_hostname"]').val($selected_option.data('cdn-hostname')); + }) + + // Sanitize the origin URL/IP input value. + .on('change', '#w3tc-origin-url', function() { + var $this = $(this); + + $this.val($.trim($this.val().toLowerCase().replace(/[^a-z0-9\.:\/-]/g, ''))); + }) + + // Sanitize the pull zone name input value. + .on('change', '#w3tc-pull-zone-name', function() { + var $this = $(this); + + $this.val($.trim($this.val().toLowerCase().replace(/[^a-z0-9-]/g, ''))); + }) + + // Sanitize the CDN hostname input value. + .on('change', '#w3tc_bunnycdn_hostname', function() { + var $this = $(this); + + $this.val($.trim($this.val().toLowerCase().replace(/(^https?:|:.+$|[^a-z0-9\.-])/g, ''))); + }) + + // Configure pull zone. + .on('click', '.w3tc_cdn_bunnycdn_configure_pull_zone', function() { + var url = ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce + + '&w3tc_action=cdn_bunnycdn_configure_pull_zone'; + + W3tc_Lightbox.load_form(url, '.w3tc_cdn_bunnycdn_form', w3tc_bunnycdn_resize); + }) + + // Close the popup success modal. + .on('click', '.w3tc_cdn_bunnycdn_done', function() { + window.location = window.location + '&'; + }) + + // Load the deauthorize form. + .on('click', '.w3tc_cdn_bunnycdn_deauthorization', function() { + W3tc_Lightbox.open({ + id:'w3tc-overlay', + close: '', + width: 800, + height: 300, + url: ajaxurl + + '?action=w3tc_ajax&_wpnonce=' + + w3tc_nonce + + '&w3tc_action=cdn_bunnycdn_deauthorization', + callback: w3tc_bunnycdn_resize + }); + }) + + // Deauthorize and optionally delete the pull zone. + .on('click', '.w3tc_cdn_bunnycdn_deauthorize', function() { + var url = ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce + + '&w3tc_action=cdn_bunnycdn_deauthorize'; + + W3tc_Lightbox.load_form(url, '.w3tc_cdn_bunnycdn_form', w3tc_bunnycdn_resize); + }) + + // Sanitize the purge URL list. + .on('focusout', '#w3tc-purge-urls', function () { + // Abort if Bunny CDN is not authorized. + if (! W3TC_Bunnycdn.is_authorized) { + return; + } + + // Declare vars. + var $this = $(this), + $button = $('.w3tc_cdn_bunnycdn_purge_urls'); + + // Strip whitespace, newlines, and invalid characters. + $this.val( $this.val().replace(/^(\s)*(\r\n|\n|\r)/gm, '') ); + $this.val($.trim($this.val().replace(/[^a-z0-9\.:\/\r\n*-]/g, ''))); + + // Enable the purge button. + $button.prop('disabled', false); + }) + + // Purge URLs. + .on('click', '.w3tc_cdn_bunnycdn_purge_urls', function() { + // Abort if Bunny CDN is not authorized. + if (! W3TC_Bunnycdn.is_authorized) { + return; + } + + // Declare vars. + var urls_processed = 0, + list = $('#w3tc-purge-urls').val().split("\n").filter((v) => v != ''), + $messages = $('#w3tc-purge-messages'), + $this = $(this); + + // Disable the button clicked and show a spinner. + $this + .prop('disabled', true) + .closest('p').addClass('lightbox-loader'); + + // Clear the messages div. + $messages.empty(); + + // Abort if nothing was submitted. + if (list.length < 1) { + $('
', { + class: 'error', + text: W3TC_Bunnycdn.lang.empty_url + '.' + }).appendTo($messages); + + $this.closest('p').removeClass('lightbox-loader'); + + return; + } + + list.forEach(function(url, index, array) { + $.ajax({ + method: 'POST', + url: ajaxurl, + data: { + _wpnonce: w3tc_nonce[0], + action: 'w3tc_ajax', + w3tc_action: 'cdn_bunnycdn_purge_url', + url: url + } + }) + .done(function(response) { + // Possible success. + if (typeof response.success !== 'undefined') { + if (response.success) { + // Successful. + $('
', { + class: 'updated', + text: W3TC_Bunnycdn.lang.success_purging + ' "' + url + '".' + }).appendTo($messages); + } else { + // Unsucessful. + $('
', { + class: 'error', + text: W3TC_Bunnycdn.lang.error_purging + ' "' + url + '"; ' + response.data.error_message + '.' + }).appendTo($messages); + } + } else { + // Unknown error. + $('
', { + class: 'error', + text: W3TC_Bunnycdn.lang.error_ajax + '.' + }).appendTo($messages); + } + }) + .fail(function(response) { + // Failure; received a non-2xx/3xx HTTP status code. + if (typeof response.responseJSON !== 'undefined' && 'data' in response.responseJSON && 'error_message' in response.responseJSON.data) { + // An error message was passed in the response data. + $('
', { + class: 'error', + text: W3TC_Bunnycdn.lang.error_purging + ' "' + url + '"; ' + response.responseJSON.data.error_message + '.' + }).appendTo($messages); + } else { + // Unknown error. + $('
', { + class: 'error', + text: W3TC_Bunnycdn.lang.error_ajax + '.' + }).appendTo($messages); + } + }) + .complete(function() { + urls_processed++; + + // When requests are all complete, then remove the spinner. + if (urls_processed === array.length) { + $this.closest('p').removeClass('lightbox-loader'); + } + }); + }); + }); +}); diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.php new file mode 100644 index 00000000..2487789f --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View.php @@ -0,0 +1,130 @@ +get_string( 'cdn.bunnycdn.account_api_key' ); +$is_authorized = ! empty( $account_api_key ) && $config->get_string( 'cdn.bunnycdn.pull_zone_id' ); +$is_unavailable = ! empty( $account_api_key ) && $config->get_string( 'cdnfsd.bunnycdn.pull_zone_id' ); // CDN is unavailable if CDN FSD is authorized for Bunny CDN. + +?> + + + + + + + + + + + + + + + + + + + + +
+ + + + + + /> + +
+

+ +

+
+ + +
+ get_string( 'cdn.bunnycdn.name' ) ); ?> +
+ + + get_string( 'cdn.bunnycdn.origin_url' ) ); ?> +
+ + + +

+ ', + '' + ), + array( + 'acronym' => array( + 'title' => array(), + ), + ) + ); + ?> +

+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View_Purge_Urls.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View_Purge_Urls.php new file mode 100644 index 00000000..3fdcf47e --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Page_View_Purge_Urls.php @@ -0,0 +1,63 @@ +get_string( 'cdn.bunnycdn.account_api_key' ); +$is_authorized = ! empty( $account_api_key ) && + ( $config->get_string( 'cdn.bunnycdn.pull_zone_id' ) || $config->get_string( 'cdnfsd.bunnycdn.pull_zone_id' ) ); +$placeholder = \esc_url( \home_url() . '/about-us' ) . "\r\n" . \esc_url( \home_url() . '/css/*' ); + +?> + + + + + +
+ + + +

+

+ /> +

+

', + 'Bunny CDN', + '

' + ), + array( + 'div' => array( + 'class' => array(), + ), + 'p' => array(), + ) + ); + else : + ?> +
+

+ +
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup.php new file mode 100644 index 00000000..38d0277a --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup.php @@ -0,0 +1,279 @@ +get_string( 'cdn.bunnycdn.account_api_key' ); + + // Ask for an account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + ) + ); + } + + /** + * W3TC AJAX: List pull zones. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_list_pull_zones() { + $account_api_key = Util_Request::get_string( 'account_api_key' ); + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to retrieve pull zones. + try { + $pull_zones = $api->list_pull_zones(); + } catch ( \Exception $ex ) { + // Reauthorize: Ask for a new account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + 'error_message' => \esc_html( \__( 'Cannot list pull zones', 'w3-total-cache' ) . '; ' . $ex->getMessage() ), + ) + ); + } + + // Save the account API key, if added or changed. + $config = Dispatcher::config(); + + if ( $config->get_string( 'cdn.bunnycdn.account_api_key' ) !== $account_api_key ) { + $config->set( 'cdn.bunnycdn.account_api_key', $account_api_key ); + $config->save(); + } + + // Print the view. + $server_ip = ! empty( $_SERVER['SERVER_ADDR'] ) && \filter_var( \wp_unslash( $_SERVER['SERVER_ADDR'] ), FILTER_VALIDATE_IP ) ? + \filter_var( \wp_unslash( $_SERVER['SERVER_ADDR'] ), FILTER_SANITIZE_URL ) : null; + + $details = array( + 'pull_zones' => $pull_zones, + 'suggested_origin_url' => \home_url(), // Suggested origin URL or IP. + 'suggested_zone_name' => \substr( \str_replace( '.', '-', \parse_url( \home_url(), PHP_URL_HOST ) ), 0, 60 ), // Suggested pull zone name. + 'pull_zone_id' => $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ), + ); + + include W3TC_DIR . '/Cdn_BunnyCdn_Popup_View_Pull_Zones.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Configure pull zone. + * + * @since X.X.X + * + * @see Cdn_BunnyCdn_Api::get_default_edge_rules() + */ + public function w3tc_ajax_cdn_bunnycdn_configure_pull_zone() { + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + $pull_zone_id = Util_Request::get_integer( 'pull_zone_id' ); + $origin_url = Util_Request::get_string( 'origin_url' ); // Origin URL or IP. + $name = Util_Request::get_string( 'name' ); // Pull zone name. + $cdn_hostname = Util_Request::get_string( 'cdn_hostname' ); // Pull zone CDN hostname (system). + + // If not selecting a pull zone. then create a new one. + if ( empty( $pull_zone_id ) ) { + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to create a new pull zone. + try { + $response = $api->add_pull_zone( + array( + 'Name' => $name, // The name/hostname for the pull zone where the files will be accessible; only letters, numbers, and dashes. + 'OriginUrl' => $origin_url, // Origin URL or IP (with optional port number). + 'CacheErrorResponses' => true, // If enabled, bunny.net will temporarily cache error responses (304+ HTTP status codes) from your servers for 5 seconds to prevent DDoS attacks on your origin. If disabled, error responses will be set to no-cache. + 'DisableCookies' => false, // Determines if the Pull Zone should automatically remove cookies from the responses. + 'EnableTLS1' => false, // TLS 1.0 was deprecated in 2018. + 'EnableTLS1_1' => false, // TLS 1.1 was EOL's on March 31,2020. + 'ErrorPageWhitelabel' => true, // Any bunny.net branding will be removed from the error page and replaced with a generic term. + 'OriginHostHeader' => \parse_url( \home_url(), PHP_URL_HOST ), // Sets the host header that will be sent to the origin. + 'UseStaleWhileUpdating' => true, // Serve stale content while updating. If Stale While Updating is enabled, cache will not be refreshed if the origin responds with a non-cacheable resource. + 'UseStaleWhileOffline' => true, // Serve stale content if the origin is offline. + ) + ); + + $pull_zone_id = (int) $response['Id']; + $name = $response['Name']; + $cdn_hostname = $response['Hostnames'][0]['Value']; + } catch ( \Exception $ex ) { + // Reauthorize: Ask for a new account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + 'error_message' => \esc_html( \__( 'Cannot select or add a pull zone', 'w3-total-cache' ) . '; ' . $ex->getMessage() ), + ) + ); + } + + // Initialize an error messages array. + $error_messages = array(); + + // Add Edge Rules. + foreach ( Cdn_BunnyCdn_Api::get_default_edge_rules() as $edge_rule ) { + try { + $api->add_edge_rule( $edge_rule, $pull_zone_id ); + } catch ( \Exception $ex ) { + $error_messages[] = sprintf( + // translators: 1: Edge Rule description/name. + \__( 'Could not add Edge Rule "%1$s".', 'w3-total-cache' ) . '; ', + \esc_html( $edge_rule['Description'] ) + ) . $ex->getMessage(); + } + } + + // Convert error messages array to a string. + $error_messages = \implode( "\r\n", $error_messages ); + } + + // Save configuration. + $config->set( 'cdn.bunnycdn.pull_zone_id', $pull_zone_id ); + $config->set( 'cdn.bunnycdn.name', $name ); + $config->set( 'cdn.bunnycdn.origin_url', $origin_url ); + $config->set( 'cdn.bunnycdn.cdn_hostname', $cdn_hostname ); + $config->save(); + + // Print success view. + include W3TC_DIR . '/Cdn_BunnyCdn_Popup_View_Configured.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Deauthorization form. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_deauthorization() { + $config = Dispatcher::config(); + $origin_url = $config->get_string( 'cdn.bunnycdn.origin_url' ); // Origin URL or IP. + $name = $config->get_string( 'cdn.bunnycdn.name' ); // Pull zone name. + $cdn_hostname = $config->get_string( 'cdn.bunnycdn.cdn_hostname' ); // Pull zone CDN hostname. + $cdn_pull_zone_id = $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ); // CDN pull zone id. + $cdnfsd_pull_zone_id = $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); // CDN FSD pull zone id. + + // Present details and ask to deauthorize and optionally delete the pull zone. + include W3TC_DIR . '/Cdn_BunnyCdn_Popup_View_Deauthorize.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Deauthorize. + * + * Deauthorize and optionally delete the pull zone. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_deauthorize() { + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + $cdn_pull_zone_id = $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ); // CDN pull zone id. + $cdnfsd_pull_zone_id = $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); // CDN FSD pull zone id. + $delete_pull_zone = Util_Request::get_string( 'delete_pull_zone' ); + + // Delete pull zone, if requested. + if ( 'yes' === $delete_pull_zone ) { + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to delete pull zone. + try { + $api->delete_pull_zone( $cdn_pull_zone_id ); + } catch ( \Exception $ex ) { + $delete_error_message = $ex->getMessage(); + } + + // If the same pull zone is used for FSD, then deauthorize that too. + if ( ! empty( $cdn_pull_zone_id ) && $cdn_pull_zone_id === $cdnfsd_pull_zone_id ) { + $config->set( 'cdnfsd.bunnycdn.pull_zone_id', null ); + $config->set( 'cdnfsd.bunnycdn.name', null ); + $config->set( 'cdnfsd.bunnycdn.origin_url', null ); + $config->set( 'cdnfsd.bunnycdn.cdn_hostname', null ); + } + } + + $config->set( 'cdn.bunnycdn.pull_zone_id', null ); + $config->set( 'cdn.bunnycdn.name', null ); + $config->set( 'cdn.bunnycdn.origin_url', null ); + $config->set( 'cdn.bunnycdn.cdn_hostname', null ); + $config->save(); + + // Print success view. + include W3TC_DIR . '/Cdn_BunnyCdn_Popup_View_Deauthorized.php'; + \wp_die(); + } + + /** + * Render intro. + * + * @since X.X.X + * @access private + * + * @param array $details { + * Details for the modal. + * + * @type string $account_api_key Account API key. + * @type string $error_message Error message (optional). + * } + */ + private function render_intro( array $details ) { + include W3TC_DIR . '/Cdn_BunnyCdn_Popup_View_Intro.php'; + \wp_die(); + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Configured.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Configured.php new file mode 100644 index 00000000..f6fc06d1 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Configured.php @@ -0,0 +1,33 @@ + + +
+ +
+ +
+
+ + +
+ .
+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorize.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorize.php new file mode 100644 index 00000000..e8885eb9 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorize.php @@ -0,0 +1,62 @@ + +
+ +
+ + + + + + + + + + + + + + + + + + +
:
:
:
: + Delete the pull zone + +

+ +

+ +
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorized.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorized.php new file mode 100644 index 00000000..cf7e580b --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Deauthorized.php @@ -0,0 +1,49 @@ + +
+ +
+ +
+ +
+ + +
+

.

+
+ +
+

.

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Intro.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Intro.php new file mode 100644 index 00000000..9a674f1f --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Intro.php @@ -0,0 +1,54 @@ + +
+ +
+ +
+ +
+ + + + + + +
: + +

+ + , + +

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Pull_Zones.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Pull_Zones.php new file mode 100644 index 00000000..dad1e1c0 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Popup_View_Pull_Zones.php @@ -0,0 +1,137 @@ + +
+ + +
+ + + + + + + + + + + + + +
: + + data-suggested="" /> +

+ +

+
: + + data-suggested="" /> +

+ +

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget.php new file mode 100644 index 00000000..b8fe80bb --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget.php @@ -0,0 +1,75 @@ +
', + array( $o, 'widget_form' ), + Util_Ui::admin_url( 'admin.php?page=w3tc_cdn' ), + 'normal' + ); + } + + /** + * Print widget form. + * + * @since X.X.X + * + * return void + */ + public function widget_form() { + $c = Dispatcher::config(); + $authorized = $c->get_string( 'cdn.engine' ) === 'bunnycdn' && + ( ! empty( $c->get_integer( 'cdn.bunnycdn.pull_zone_id' ) ) || ! empty( $c->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ) ) ); + + if ( $authorized ) { + include __DIR__ . DIRECTORY_SEPARATOR . 'Cdn_BunnyCdn_Widget_View_Authorized.php'; + } else { + include __DIR__ . DIRECTORY_SEPARATOR . 'Cdn_BunnyCdn_Widget_View_Unauthorized.php'; + } + } + + /** + * Enqueue styles. + * + * @since X.X.X + * + * @return void + */ + public function admin_print_styles() { + wp_enqueue_style( 'w3tc-widget' ); + + wp_enqueue_style( + 'w3tc-bunnycdn-widget', + plugins_url( 'Cdn_BunnyCdn_Widget_View.css', W3TC_FILE ), + array(), + W3TC_VERSION + ); + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View.css b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View.css new file mode 100644 index 00000000..73502596 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View.css @@ -0,0 +1,89 @@ +.w3tc-widget-bunnycdn-logo { + width: 150px; + height: 50px; + background: url('pub/img/w3tc_bunnycdn_logo.svg') 0 8px no-repeat; + float: left; +} + +.w3tc_bunnycdn_h4 { + text-align: center; +} + +.w3tc_bunnycdn_summary_h4 { + text-align: center; + color: #8F8F8F; + text-align: left; + margin: 0; +} + +.w3tc_bunnycdn_summary { + border-bottom: 1px solid #d2d2d2; + padding-left: 10px; + padding-right: 10px; +} + +.w3tc_bunnycdn_wrapper { + margin-left: -10px; + margin-right: -10px; +} + +.w3tc_bunnycdn_ul li { + margin-bottom: 3px; + padding: 0; +} + +.w3tc_bunnycdn_summary_col1 { + display: block; + font-weight: bold; + width: 90px; + float:left; +} + +.w3tc_bunnycdn_summary_col2 { + display: block; + font-weight: bold; + width: 80px; + float:left; +} + +.w3tc_bunnycdn_tools { + margin-top:15px; + padding-left: 10px; + padding-right: 10px; +} + +.w3tc_bunnycdn_tools li { + display:inline-block; + margin-right:10px; +} + +.w3tc_bunnycdn_chart { + clear: both; + padding-left: 10px; + padding-right: 10px; +} + +.w3tc_bunnycdn_chart p { + color:#8F8F8F; + margin:0; +} + +.w3tc_bunnycdn_wrapper .button-secondary { + margin-bottom: 3px; +} + +.w3tc_bunnycdn_signup_h4 { + text-align: left; + margin-bottom: 0; + padding-bottom: 0; +} + +.w3tc_bunnycdn_signup p { + margin-top: 4px; + padding-top: 0; + +} + +.w3tc_bunnycdn_signup p span.desc { + color:#8F8F8F; +} diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Authorized.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Authorized.php new file mode 100644 index 00000000..dba03499 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Authorized.php @@ -0,0 +1,59 @@ + + +
+
+
+

+ ' . \__( 'CDN', 'w3-total-cache' ) . '' + ) + ); + ?> +

+
+
+
    +
  • +
+

+ + +

+

+ ' . \__( 'CDN', 'w3-total-cache' ) . '' + ) + ); + ?> +

+ + + +
+
+
diff --git a/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Unauthorized.php b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Unauthorized.php new file mode 100644 index 00000000..eac68395 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdn_BunnyCdn_Widget_View_Unauthorized.php @@ -0,0 +1,79 @@ + + + diff --git a/wp-content/plugins/w3-total-cache/Cdn_Core.php b/wp-content/plugins/w3-total-cache/Cdn_Core.php index e71344e2..fc95f117 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_Core.php +++ b/wp-content/plugins/w3-total-cache/Cdn_Core.php @@ -1,106 +1,122 @@ _config = Dispatcher::config(); $this->debug = $this->_config->get_boolean( 'cdn.debug' ); } /** - * Adds file to queue + * Adds file to queue. * - * @param string $local_path - * @param string $remote_path - * @param integer $command - * @param string $last_error - * @return integer + * @param string $local_path Local path. + * @param string $remote_path Remote path. + * @param int $command Command number. + * @param string $last_error Last error. + * @return int */ - function queue_add( $local_path, $remote_path, $command, $last_error ) { + public function queue_add( $local_path, $remote_path, $command, $last_error ) { global $wpdb; $table = $wpdb->base_prefix . W3TC_CDN_TABLE_QUEUE; - $rows = $wpdb->get_results( $wpdb->prepare( - 'SELECT id, command '. - "FROM $table " . - 'WHERE local_path = %s AND remote_path = %s', - $local_path, $remote_path ) ); + $rows = $wpdb->get_results( + $wpdb->prepare( + 'SELECT id, command FROM ' . $table . ' WHERE local_path = %s AND remote_path = %s', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $local_path, + $remote_path + ) + ); $already_exists = false; + foreach ( $rows as $row ) { - if ( $row->command != $command ) - $wpdb->query( $wpdb->prepare( - "DELETE FROM $table " . - 'WHERE id = %d', $row->id ) ); - else + if ( $row->command != $command ) { + $wpdb->query( + $wpdb->prepare( + 'DELETE FROM ' . $table . ' WHERE id = %d', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $row->id + ) + ); + } else { $already_exists = true; + } } - if ( $already_exists ) + if ( $already_exists ) { return true; + } - // insert if not yet there - return $wpdb->query( $wpdb->prepare( - "INSERT INTO $table " . - '(local_path, remote_path, command, last_error, date) ' . - 'VALUES (%s, %s, %d, %s, NOW())', - $local_path, $remote_path, $command, $last_error ) ); + // Insert if not yet there. + return $wpdb->query( + $wpdb->prepare( + 'INSERT INTO ' . $table . ' (local_path, remote_path, command, last_error, date) VALUES (%s, %s, %d, %s, NOW())', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $local_path, + $remote_path, + $command, + $last_error + ) + ); } /** - * Returns array of array('local_path' => '', 'remote_path' => '') for specified file + * Returns array of array('local_path' => '', 'remote_path' => '') for specified file. * - * @param string $file + * @param string $file File. * @return array */ - function get_files_for_upload( $file ) { - $files = array(); + public function get_files_for_upload( $file ) { + $files = array(); $upload_info = Util_Http::upload_info(); if ( $upload_info ) { - $file = $this->normalize_attachment_file( $file ); - - $local_file = $upload_info['basedir'] . '/' . $file; - - $parsed = parse_url( rtrim( $upload_info['baseurl'], '/' ) . - '/' . $file ); - $local_uri = $parsed['path']; - $remote_uri = $this->uri_to_cdn_uri( $local_uri ); + $file = $this->normalize_attachment_file( $file ); + $local_file = $upload_info['basedir'] . '/' . $file; + $parsed = parse_url( rtrim( $upload_info['baseurl'], '/' ) . '/' . $file ); + $local_uri = $parsed['path']; + $remote_uri = $this->uri_to_cdn_uri( $local_uri ); $remote_file = ltrim( $remote_uri, '/' ); - - $files[] = $this->build_file_descriptor( $local_file, $remote_file ); + $files[] = $this->build_file_descriptor( $local_file, $remote_file ); } return $files; } /** - * Returns array of files from sizes array + * Returns array of files from sizes array. * - * @param string $attached_file - * @param array $sizes + * @param string $attached_file Attached file. + * @param array $sizes Sizes. * @return array */ - function _get_sizes_files( $attached_file, $sizes ) { - $files = array(); + public function _get_sizes_files( $attached_file, $sizes ) { + $files = array(); $base_dir = Util_File::dirname( $attached_file ); foreach ( (array) $sizes as $size ) { @@ -119,12 +135,12 @@ class Cdn_Core { } /** - * Returns attachment files by metadata + * Returns attachment files by metadata. * - * @param array $metadata + * @param array $metadata Metadata. * @return array */ - function get_metadata_files( $metadata ) { + public function get_metadata_files( $metadata ) { $files = array(); if ( isset( $metadata['file'] ) && isset( $metadata['sizes'] ) ) { @@ -135,25 +151,21 @@ class Cdn_Core { } /** - * Returns attachment files by attachment ID + * Returns attachment files by attachment id. * - * @param integer $attachment_id + * @param int $attachment_id Attachment id. * @return array */ - function get_attachment_files( $attachment_id ) { + public function get_attachment_files( $attachment_id ) { $files = array(); - /** - * Get attached file - */ + // Get attached file. $attached_file = get_post_meta( $attachment_id, '_wp_attached_file', true ); - if ( $attached_file != '' ) { + if ( ! empty( $attached_file ) ) { $files = array_merge( $files, $this->get_files_for_upload( $attached_file ) ); - /** - * Get backup sizes files - */ + // Get backup sizes files. $attachment_backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ); if ( is_array( $attachment_backup_sizes ) ) { @@ -161,9 +173,7 @@ class Cdn_Core { } } - /** - * Get files from metadata - */ + // Get files from metadata. $attachment_metadata = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); if ( is_array( $attachment_metadata ) ) { @@ -174,20 +184,20 @@ class Cdn_Core { } /** - * Uploads files to CDN + * Uploads files to CDN. * - * @param array $files - * @param boolean $queue_failed - * @param array $results - * @return boolean + * @param array $files Files. + * @param bool $queue_failed Is queue failed. + * @param array $results Results. + * @param int $timeout_time Timeout time. + * @return bool */ - function upload( $files, $queue_failed, &$results, $timeout_time = NULL ) { + public function upload( $files, $queue_failed, &$results, $timeout_time = null ) { if ( $this->debug ) { - Util_Debug::log( 'cdn', 'upload: ' . - json_encode( $files, JSON_PRETTY_PRINT ) ); + Util_Debug::log( 'cdn', 'upload: ' . json_encode( $files, JSON_PRETTY_PRINT ) ); } - $cdn = $this->get_cdn(); + $cdn = $this->get_cdn(); $force_rewrite = $this->_config->get_boolean( 'cdn.force.rewrite' ); @set_time_limit( $this->_config->get_integer( 'timelimit.cdn_upload' ) ); @@ -195,9 +205,9 @@ class Cdn_Core { $engine = $this->_config->get_string( 'cdn.engine' ); $return = $cdn->upload( $files, $results, $force_rewrite, $timeout_time ); - if ( !$return && $queue_failed ) { + if ( ! $return && $queue_failed ) { foreach ( $results as $result ) { - if ( $result['result'] != W3TC_CDN_RESULT_OK ) { + if ( W3TC_CDN_RESULT_OK !== $result['result'] ) { $this->queue_add( $result['local_path'], $result['remote_path'], W3TC_CDN_COMMAND_UPLOAD, $result['error'] ); } } @@ -207,27 +217,26 @@ class Cdn_Core { } /** - * Deletes files frrom CDN + * Deletes files from CDN. * - * @param array $files - * @param boolean $queue_failed - * @param array $results - * @return boolean + * @param array $files Files. + * @param bool $queue_failed Is queue failed. + * @param array $results Results. + * @return bool */ - function delete( $files, $queue_failed, &$results ) { + public function delete( $files, $queue_failed, &$results ) { $cdn = $this->get_cdn(); @set_time_limit( $this->_config->get_integer( 'timelimit.cdn_delete' ) ); $return = $cdn->delete( $files, $results ); if ( $this->debug ) { - Util_Debug::log( 'cdn', 'delete: ' . - json_encode( $files, JSON_PRETTY_PRINT ) ); + Util_Debug::log( 'cdn', 'delete: ' . json_encode( $files, JSON_PRETTY_PRINT ) ); } - if ( !$return && $queue_failed ) { + if ( ! $return && $queue_failed ) { foreach ( $results as $result ) { - if ( $result['result'] != W3TC_CDN_RESULT_OK ) { + if ( W3TC_CDN_RESULT_OK !== $result['result'] ) { $this->queue_add( $result['local_path'], $result['remote_path'], W3TC_CDN_COMMAND_DELETE, $result['error'] ); } } @@ -237,21 +246,19 @@ class Cdn_Core { } /** - * Purges files from CDN + * Purges files from CDN. * - * @param array $files consisting of array('local_path'=>'', 'remote_path'=>'') - * @param boolean $queue_failed - * @param array $results - * @return boolean + * @param array $files Files; consisting of array( 'local_path'=>'', 'remote_path'=>'' ). + * @param array $results Results. + * @return bool */ - function purge( $files, &$results ) { + public function purge( $files, &$results ) { if ( $this->debug ) { - Util_Debug::log( 'cdn', 'purge: ' . - json_encode( $files, JSON_PRETTY_PRINT ) ); + Util_Debug::log( 'cdn', 'purge: ' . json_encode( $files, JSON_PRETTY_PRINT ) ); } /** - * Purge varnish servers before mirror purging + * Purge varnish servers before mirror purging. */ if ( Cdn_Util::is_engine_mirror( $this->_config->get_string( 'cdn.engine' ) ) && $this->_config->get_boolean( 'varnish.enabled' ) ) { $varnish = Dispatcher::component( 'Varnish_Flush' ); @@ -263,7 +270,7 @@ class Cdn_Core { } /** - * Purge CDN + * Purge CDN. */ $cdn = $this->get_cdn(); @@ -271,9 +278,9 @@ class Cdn_Core { $return = $cdn->purge( $files, $results ); - if ( !$return ) { + if ( ! $return ) { foreach ( $results as $result ) { - if ( $result['result'] != W3TC_CDN_RESULT_OK ) { + if ( W3TC_CDN_RESULT_OK !== $result['result'] ) { $this->queue_add( $result['local_path'], $result['remote_path'], W3TC_CDN_COMMAND_PURGE, $result['error'] ); } } @@ -283,31 +290,28 @@ class Cdn_Core { } /** - * Purge CDN completely + * Purge CDN completely. * - * @param unknown $results + * @param unknown $results Results of the purge. * @return mixed */ - function purge_all( &$results ) { - /** - * Purge CDN - */ + public function purge_all( &$results ) { $cdn = $this->get_cdn(); @set_time_limit( $this->_config->get_integer( 'timelimit.cdn_purge' ) ); - $return = $cdn->purge_all( $results ); - return $return; + return $cdn->purge_all( $results ); } /** * Queues file upload. - * Links wp_cron call to do that by the end of request processing * - * @param string $url + * Links wp_cron call to do that by the end of request processing. + * + * @param string $url Url. * @return void */ - function queue_upload_url( $url ) { + public function queue_upload_url( $url ) { $docroot_filename = Util_Environment::url_to_docroot_filename( $url ); if ( is_null( $docroot_filename ) ) { return; @@ -315,24 +319,23 @@ class Cdn_Core { $filename = Util_Environment::docroot_to_full_filename( $docroot_filename ); - $a = parse_url( $url ); - $uri = $a['path']; + $a = \parse_url( $url ); + $remote_filename = $this->uri_to_cdn_uri( $a['path'] ); - $remote_file_name = $this->uri_to_cdn_uri( $uri ); - $this->queue_add( $filename, $remote_file_name, - W3TC_CDN_COMMAND_UPLOAD, 'Pending' ); + $this->queue_add( $filename, $remote_filename, W3TC_CDN_COMMAND_UPLOAD, 'Pending' ); } /** - * Normalizes attachment file + * Normalizes attachment file. * - * @param string $file + * @param string $file Filename. * @return string */ - function normalize_attachment_file( $file ) { + public function normalize_attachment_file( $file ) { $upload_info = Util_Http::upload_info(); + if ( $upload_info ) { - $file = ltrim( str_replace( $upload_info['basedir'], '', $file ), '/\\' ); + $file = ltrim( str_replace( $upload_info['basedir'], '', $file ), '/\\' ); $matches = null; if ( preg_match( '~(\d{4}/\d{2}/)?[^/]+$~', $file, $matches ) ) { @@ -344,267 +347,259 @@ class Cdn_Core { } /** - * Returns CDN object + * Returns CDN object. */ - function get_cdn() { + public function get_cdn() { static $cdn = null; if ( is_null( $cdn ) ) { - $c = $this->_config; - $engine = $c->get_string( 'cdn.engine' ); + $c = $this->_config; + $engine = $c->get_string( 'cdn.engine' ); $compression = ( $c->get_boolean( 'browsercache.enabled' ) && $c->get_boolean( 'browsercache.html.compression' ) ); switch ( $engine ) { - case 'akamai': - $engine_config = array( - 'username' => $c->get_string( 'cdn.akamai.username' ), - 'password' => $c->get_string( 'cdn.akamai.password' ), - 'zone' => $c->get_string( 'cdn.akamai.zone' ), - 'domain' => $c->get_array( 'cdn.akamai.domain' ), - 'ssl' => $c->get_string( 'cdn.akamai.ssl' ), - 'email_notification' => $c->get_array( 'cdn.akamai.email_notification' ), - 'compression' => false - ); - break; - - case 'att': - $engine_config = array( - 'account' => $c->get_string( 'cdn.att.account' ), - 'token' => $c->get_string( 'cdn.att.token' ), - 'domain' => $c->get_array( 'cdn.att.domain' ), - 'ssl' => $c->get_string( 'cdn.att.ssl' ), - 'compression' => false - ); - break; - - case 'azure': - $engine_config = array( - 'user' => $c->get_string( 'cdn.azure.user' ), - 'key' => $c->get_string( 'cdn.azure.key' ), - 'container' => $c->get_string( 'cdn.azure.container' ), - 'cname' => $c->get_array( 'cdn.azure.cname' ), - 'ssl' => $c->get_string( 'cdn.azure.ssl' ), - 'compression' => false - ); - break; - - case 'cf': - $engine_config = array( - 'key' => $c->get_string( 'cdn.cf.key' ), - 'secret' => $c->get_string( 'cdn.cf.secret' ), - 'bucket' => $c->get_string( 'cdn.cf.bucket' ), - 'bucket_location' => $c->get_string( 'cdn.cf.bucket.location' ), - 'id' => $c->get_string( 'cdn.cf.id' ), - 'cname' => $c->get_array( 'cdn.cf.cname' ), - 'ssl' => $c->get_string( 'cdn.cf.ssl' ), - 'public_objects' => $c->get_string( 'cdn.cf.public_objects' ), - 'compression' => $compression - ); - break; - - case 'cf2': - $engine_config = array( - 'key' => $c->get_string( 'cdn.cf2.key' ), - 'secret' => $c->get_string( 'cdn.cf2.secret' ), - 'id' => $c->get_string( 'cdn.cf2.id' ), - 'cname' => $c->get_array( 'cdn.cf2.cname' ), - 'ssl' => $c->get_string( 'cdn.cf2.ssl' ), - 'compression' => false - ); - break; - - case 'cotendo': - $engine_config = array( - 'username' => $c->get_string( 'cdn.cotendo.username' ), - 'password' => $c->get_string( 'cdn.cotendo.password' ), - 'zones' => $c->get_array( 'cdn.cotendo.zones' ), - 'domain' => $c->get_array( 'cdn.cotendo.domain' ), - 'ssl' => $c->get_string( 'cdn.cotendo.ssl' ), - 'compression' => false - ); - break; - - case 'edgecast': - $engine_config = array( - 'account' => $c->get_string( 'cdn.edgecast.account' ), - 'token' => $c->get_string( 'cdn.edgecast.token' ), - 'domain' => $c->get_array( 'cdn.edgecast.domain' ), - 'ssl' => $c->get_string( 'cdn.edgecast.ssl' ), - 'compression' => false - ); - break; - - case 'ftp': - $engine_config = array( - 'host' => $c->get_string( 'cdn.ftp.host' ), - 'type' => $c->get_string( 'cdn.ftp.type' ), - 'user' => $c->get_string( 'cdn.ftp.user' ), - 'pass' => $c->get_string( 'cdn.ftp.pass' ), - 'path' => $c->get_string( 'cdn.ftp.path' ), - 'pasv' => $c->get_boolean( 'cdn.ftp.pasv' ), - 'domain' => $c->get_array( 'cdn.ftp.domain' ), - 'ssl' => $c->get_string( 'cdn.ftp.ssl' ), - 'compression' => false, - 'docroot' => Util_Environment::document_root() - ); - break; - - case 'google_drive': - $state = Dispatcher::config_state(); - - $engine_config = array( - 'client_id' => - $c->get_string( 'cdn.google_drive.client_id' ), - 'access_token' => - $state->get_string( 'cdn.google_drive.access_token' ), - 'refresh_token' => - $c->get_string( 'cdn.google_drive.refresh_token' ), - 'root_url' => - $c->get_string( 'cdn.google_drive.folder.url' ), - 'root_folder_id' => - $c->get_string( 'cdn.google_drive.folder.id' ), - 'new_access_token_callback' => array( - $this, - 'on_google_drive_new_access_token' - ) - ); - break; - - case 'highwinds': - $state = Dispatcher::config_state(); - - $engine_config = array( - 'domains' => - $c->get_array( 'cdn.highwinds.host.domains' ), - 'ssl' => - $c->get_string( 'cdn.highwinds.ssl' ), - 'api_token' => - $c->get_string( 'cdn.highwinds.api_token' ), - 'account_hash' => - $c->get_string( 'cdn.highwinds.account_hash' ), - 'host_hash_code' => - $c->get_string( 'cdn.highwinds.host.hash_code' ) - ); - break; - - case 'limelight': - $engine_config = array( - 'short_name' => $c->get_string( 'cdn.limelight.short_name' ), - 'username' => $c->get_string( 'cdn.limelight.username' ), - 'api_key' => $c->get_string( 'cdn.limelight.api_key' ), - 'domains' => $c->get_array( 'cdn.limelight.host.domains' ), - 'debug' => $c->get_string( 'cdn.debug' ) + case 'akamai': + $engine_config = array( + 'username' => $c->get_string( 'cdn.akamai.username' ), + 'password' => $c->get_string( 'cdn.akamai.password' ), + 'zone' => $c->get_string( 'cdn.akamai.zone' ), + 'domain' => $c->get_array( 'cdn.akamai.domain' ), + 'ssl' => $c->get_string( 'cdn.akamai.ssl' ), + 'email_notification' => $c->get_array( 'cdn.akamai.email_notification' ), + 'compression' => false, ); - break; + break; - case 'mirror': - $engine_config = array( - 'domain' => $c->get_array( 'cdn.mirror.domain' ), - 'ssl' => $c->get_string( 'cdn.mirror.ssl' ), - 'compression' => false - ); - break; + case 'att': + $engine_config = array( + 'account' => $c->get_string( 'cdn.att.account' ), + 'token' => $c->get_string( 'cdn.att.token' ), + 'domain' => $c->get_array( 'cdn.att.domain' ), + 'ssl' => $c->get_string( 'cdn.att.ssl' ), + 'compression' => false, + ); + break; - case 'rackspace_cdn': - $state = Dispatcher::config_state(); + case 'azure': + $engine_config = array( + 'user' => $c->get_string( 'cdn.azure.user' ), + 'key' => $c->get_string( 'cdn.azure.key' ), + 'container' => $c->get_string( 'cdn.azure.container' ), + 'cname' => $c->get_array( 'cdn.azure.cname' ), + 'ssl' => $c->get_string( 'cdn.azure.ssl' ), + 'compression' => false, + ); + break; - $engine_config = array( - 'user_name' => $c->get_string( 'cdn.rackspace_cdn.user_name' ), - 'api_key' => $c->get_string( 'cdn.rackspace_cdn.api_key' ), - 'region' => $c->get_string( 'cdn.rackspace_cdn.region' ), - 'service_access_url' => $c->get_string( 'cdn.rackspace_cdn.service.access_url' ), - 'service_id' => $c->get_string( 'cdn.rackspace_cdn.service.id' ), - 'service_protocol' => $c->get_string( 'cdn.rackspace_cdn.service.protocol' ), - 'domains' => $c->get_array( 'cdn.rackspace_cdn.domains' ), - 'access_state' => - $state->get_string( 'cdn.rackspace_cdn.access_state' ), - 'new_access_state_callback' => array( - $this, - 'on_rackspace_cdn_new_access_state' - ) + case 'cf': + $engine_config = array( + 'key' => $c->get_string( 'cdn.cf.key' ), + 'secret' => $c->get_string( 'cdn.cf.secret' ), + 'bucket' => $c->get_string( 'cdn.cf.bucket' ), + 'bucket_location' => $c->get_string( 'cdn.cf.bucket.location' ), + 'id' => $c->get_string( 'cdn.cf.id' ), + 'cname' => $c->get_array( 'cdn.cf.cname' ), + 'ssl' => $c->get_string( 'cdn.cf.ssl' ), + 'public_objects' => $c->get_string( 'cdn.cf.public_objects' ), + 'compression' => $compression, + ); + break; - ); - break; - case 'rscf': - $state = Dispatcher::config_state(); + case 'cf2': + $engine_config = array( + 'key' => $c->get_string( 'cdn.cf2.key' ), + 'secret' => $c->get_string( 'cdn.cf2.secret' ), + 'id' => $c->get_string( 'cdn.cf2.id' ), + 'cname' => $c->get_array( 'cdn.cf2.cname' ), + 'ssl' => $c->get_string( 'cdn.cf2.ssl' ), + 'compression' => false, + ); + break; - $engine_config = array( - 'user_name' => $c->get_string( 'cdn.rscf.user' ), - 'api_key' => $c->get_string( 'cdn.rscf.key' ), - 'region' => $c->get_string( 'cdn.rscf.location' ), - 'container' => $c->get_string( 'cdn.rscf.container' ), - 'cname' => $c->get_array( 'cdn.rscf.cname' ), - 'ssl' => $c->get_string( 'cdn.rscf.ssl' ), - 'compression' => false, - 'access_state' => - $state->get_string( 'cdn.rackspace_cf.access_state' ), - 'new_access_state_callback' => array( - $this, - 'on_rackspace_cf_new_access_state' - ) + case 'cotendo': + $engine_config = array( + 'username' => $c->get_string( 'cdn.cotendo.username' ), + 'password' => $c->get_string( 'cdn.cotendo.password' ), + 'zones' => $c->get_array( 'cdn.cotendo.zones' ), + 'domain' => $c->get_array( 'cdn.cotendo.domain' ), + 'ssl' => $c->get_string( 'cdn.cotendo.ssl' ), + 'compression' => false, + ); + break; - ); - break; + case 'edgecast': + $engine_config = array( + 'account' => $c->get_string( 'cdn.edgecast.account' ), + 'token' => $c->get_string( 'cdn.edgecast.token' ), + 'domain' => $c->get_array( 'cdn.edgecast.domain' ), + 'ssl' => $c->get_string( 'cdn.edgecast.ssl' ), + 'compression' => false, + ); + break; - case 's3': - $engine_config = array( - 'key' => $c->get_string( 'cdn.s3.key' ), - 'secret' => $c->get_string( 'cdn.s3.secret' ), - 'bucket' => $c->get_string( 'cdn.s3.bucket' ), - 'bucket_location' => $c->get_string( 'cdn.s3.bucket.location' ), - 'cname' => $c->get_array( 'cdn.s3.cname' ), - 'ssl' => $c->get_string( 'cdn.s3.ssl' ), - 'public_objects' => $c->get_string( 'cdn.s3.public_objects' ), - 'compression' => $compression - ); - break; + case 'ftp': + $engine_config = array( + 'host' => $c->get_string( 'cdn.ftp.host' ), + 'type' => $c->get_string( 'cdn.ftp.type' ), + 'user' => $c->get_string( 'cdn.ftp.user' ), + 'pass' => $c->get_string( 'cdn.ftp.pass' ), + 'path' => $c->get_string( 'cdn.ftp.path' ), + 'pasv' => $c->get_boolean( 'cdn.ftp.pasv' ), + 'domain' => $c->get_array( 'cdn.ftp.domain' ), + 'ssl' => $c->get_string( 'cdn.ftp.ssl' ), + 'compression' => false, + 'docroot' => Util_Environment::document_root(), + ); + break; - case 's3_compatible': - $engine_config = array( - 'key' => $c->get_string( 'cdn.s3.key' ), - 'secret' => $c->get_string( 'cdn.s3.secret' ), - 'bucket' => $c->get_string( 'cdn.s3.bucket' ), - 'cname' => $c->get_array( 'cdn.s3.cname' ), - 'ssl' => $c->get_string( 'cdn.s3.ssl' ), - 'compression' => $compression, - 'api_host' => $c->get_string( 'cdn.s3_compatible.api_host' ) - ); - break; + case 'google_drive': + $state = Dispatcher::config_state(); - case 'stackpath': - $engine_config = array( - 'authorization_key' => $c->get_string( 'cdn.stackpath.authorization_key' ), - 'zone_id' => $c->get_integer( 'cdn.stackpath.zone_id' ), - 'domain' => $c->get_array( 'cdn.stackpath.domain' ), - 'ssl' => $c->get_string( 'cdn.stackpath.ssl' ), - 'compression' => false - ); - break; + $engine_config = array( + 'client_id' => $c->get_string( 'cdn.google_drive.client_id' ), + 'access_token' => $state->get_string( 'cdn.google_drive.access_token' ), + 'refresh_token' => $c->get_string( 'cdn.google_drive.refresh_token' ), + 'root_url' => $c->get_string( 'cdn.google_drive.folder.url' ), + 'root_folder_id' => $c->get_string( 'cdn.google_drive.folder.id' ), + 'new_access_token_callback' => array( $this, 'on_google_drive_new_access_token' ), + ); + break; + + case 'highwinds': + $state = Dispatcher::config_state(); + + $engine_config = array( + 'domains' => $c->get_array( 'cdn.highwinds.host.domains' ), + 'ssl' => $c->get_string( 'cdn.highwinds.ssl' ), + 'api_token' => $c->get_string( 'cdn.highwinds.api_token' ), + 'account_hash' => $c->get_string( 'cdn.highwinds.account_hash' ), + 'host_hash_code' => $c->get_string( 'cdn.highwinds.host.hash_code' ), + ); + break; + + case 'limelight': + $engine_config = array( + 'short_name' => $c->get_string( 'cdn.limelight.short_name' ), + 'username' => $c->get_string( 'cdn.limelight.username' ), + 'api_key' => $c->get_string( 'cdn.limelight.api_key' ), + 'domains' => $c->get_array( 'cdn.limelight.host.domains' ), + 'debug' => $c->get_string( 'cdn.debug' ), + ); + break; + + case 'mirror': + $engine_config = array( + 'domain' => $c->get_array( 'cdn.mirror.domain' ), + 'ssl' => $c->get_string( 'cdn.mirror.ssl' ), + 'compression' => false, + ); + break; + + case 'rackspace_cdn': + $state = Dispatcher::config_state(); + + $engine_config = array( + 'user_name' => $c->get_string( 'cdn.rackspace_cdn.user_name' ), + 'api_key' => $c->get_string( 'cdn.rackspace_cdn.api_key' ), + 'region' => $c->get_string( 'cdn.rackspace_cdn.region' ), + 'service_access_url' => $c->get_string( 'cdn.rackspace_cdn.service.access_url' ), + 'service_id' => $c->get_string( 'cdn.rackspace_cdn.service.id' ), + 'service_protocol' => $c->get_string( 'cdn.rackspace_cdn.service.protocol' ), + 'domains' => $c->get_array( 'cdn.rackspace_cdn.domains' ), + 'access_state' => $state->get_string( 'cdn.rackspace_cdn.access_state' ), + 'new_access_state_callback' => array( $this, 'on_rackspace_cdn_new_access_state' ), + + ); + break; + case 'rscf': + $state = Dispatcher::config_state(); + + $engine_config = array( + 'user_name' => $c->get_string( 'cdn.rscf.user' ), + 'api_key' => $c->get_string( 'cdn.rscf.key' ), + 'region' => $c->get_string( 'cdn.rscf.location' ), + 'container' => $c->get_string( 'cdn.rscf.container' ), + 'cname' => $c->get_array( 'cdn.rscf.cname' ), + 'ssl' => $c->get_string( 'cdn.rscf.ssl' ), + 'compression' => false, + 'access_state' => $state->get_string( 'cdn.rackspace_cf.access_state' ), + 'new_access_state_callback' => array( $this, 'on_rackspace_cf_new_access_state' ), + + ); + break; + + case 's3': + $engine_config = array( + 'key' => $c->get_string( 'cdn.s3.key' ), + 'secret' => $c->get_string( 'cdn.s3.secret' ), + 'bucket' => $c->get_string( 'cdn.s3.bucket' ), + 'bucket_location' => $c->get_string( 'cdn.s3.bucket.location' ), + 'cname' => $c->get_array( 'cdn.s3.cname' ), + 'ssl' => $c->get_string( 'cdn.s3.ssl' ), + 'public_objects' => $c->get_string( 'cdn.s3.public_objects' ), + 'compression' => $compression, + ); + break; + + case 's3_compatible': + $engine_config = array( + 'key' => $c->get_string( 'cdn.s3.key' ), + 'secret' => $c->get_string( 'cdn.s3.secret' ), + 'bucket' => $c->get_string( 'cdn.s3.bucket' ), + 'cname' => $c->get_array( 'cdn.s3.cname' ), + 'ssl' => $c->get_string( 'cdn.s3.ssl' ), + 'compression' => $compression, + 'api_host' => $c->get_string( 'cdn.s3_compatible.api_host' ), + ); + break; + + case 'stackpath': + $engine_config = array( + 'authorization_key' => $c->get_string( 'cdn.stackpath.authorization_key' ), + 'zone_id' => $c->get_integer( 'cdn.stackpath.zone_id' ), + 'domain' => $c->get_array( 'cdn.stackpath.domain' ), + 'ssl' => $c->get_string( 'cdn.stackpath.ssl' ), + 'compression' => false, + ); + break; case 'stackpath2': $state = Dispatcher::config_state(); $engine_config = array( - 'client_id' => $c->get_string( 'cdn.stackpath2.client_id' ), - 'client_secret' => $c->get_string( 'cdn.stackpath2.client_secret' ), - 'stack_id' => $c->get_string( 'cdn.stackpath2.stack_id' ), - 'site_root_domain' => $c->get_string( 'cdn.stackpath2.site_root_domain' ), - 'domain' => $c->get_array( 'cdn.stackpath2.domain' ), - 'ssl' => $c->get_string( 'cdn.stackpath2.ssl' ), - 'access_token' => $state->get_string( 'cdn.stackpath2.access_token' ), - 'on_new_access_token' => array( - $this, - 'on_stackpath2_new_access_token' - ) + 'client_id' => $c->get_string( 'cdn.stackpath2.client_id' ), + 'client_secret' => $c->get_string( 'cdn.stackpath2.client_secret' ), + 'stack_id' => $c->get_string( 'cdn.stackpath2.stack_id' ), + 'site_root_domain' => $c->get_string( 'cdn.stackpath2.site_root_domain' ), + 'domain' => $c->get_array( 'cdn.stackpath2.domain' ), + 'ssl' => $c->get_string( 'cdn.stackpath2.ssl' ), + 'access_token' => $state->get_string( 'cdn.stackpath2.access_token' ), + 'on_new_access_token' => array( $this, 'on_stackpath2_new_access_token' ), ); break; + case 'bunnycdn': + $engine_config = array( + 'account_api_key' => $c->get_string( 'cdn.bunnycdn.account_api_key' ), + 'storage_api_key' => $c->get_string( 'cdn.bunnycdn.storage_api_key' ), + 'stream_api_key' => $c->get_string( 'cdn.bunnycdn.stream_api_key' ), + 'pull_zone_id' => $c->get_integer( 'cdn.bunnycdn.pull_zone_id' ), + 'domain' => $c->get_string( 'cdn.bunnycdn.cdn_hostname' ), + ); + break; + + default: + $engine_config = array(); + break; } - $engine_config = array_merge( $engine_config, array( - 'debug' => $c->get_boolean( 'cdn.debug' ), - 'headers' => apply_filters( 'w3tc_cdn_config_headers', array() ) - ) ); + $engine_config = array_merge( + $engine_config, + array( + 'debug' => $c->get_boolean( 'cdn.debug' ), + 'headers' => apply_filters( 'w3tc_cdn_config_headers', array() ), + ) + ); $cdn = CdnEngine::instance( $engine, $engine_config ); } @@ -613,7 +608,9 @@ class Cdn_Core { } /** - * Called when new access token is issued by cdnengine + * Called when a new access token is issued by cdnengine. + * + * @param string $access_token Access token. */ public function on_google_drive_new_access_token( $access_token ) { $state = Dispatcher::config_state(); @@ -622,7 +619,9 @@ class Cdn_Core { } /** - * Called when new access state is issued by cdnengine + * Called when a new access state is issued by cdnengine + * + * @param string $access_state Access state. */ public function on_rackspace_cdn_new_access_state( $access_state ) { $state = Dispatcher::config_state(); @@ -631,7 +630,9 @@ class Cdn_Core { } /** - * Called when new access state is issued by cdnengine + * Called when a new access state is issued by cdnengine + * + * @param string $access_state Access state. */ public function on_rackspace_cf_new_access_state( $access_state ) { $state = Dispatcher::config_state(); @@ -639,6 +640,11 @@ class Cdn_Core { $state->save(); } + /** + * Called when a new access token is issued by cdnengine. + * + * @param string $access_token Access token. + */ public function on_stackpath2_new_access_token( $access_token ) { $state = Dispatcher::config_state(); $state->set( 'cdn.stackpath2.access_token', $access_token ); @@ -646,73 +652,69 @@ class Cdn_Core { } /** - * Convert relative file which is relative to ABSPATH (wp folder on disc) to path uri + * Convert relative file which is relative to ABSPATH (wp folder on disc) to path uri. * - * @param unknown $file + * @param string $file Filename. * @return string */ - function docroot_filename_to_uri( $file ) { + public function docroot_filename_to_uri( $file ) { $file = ltrim( $file, '/' ); - // Translate multisite subsite uploads paths - $file = str_replace( basename( WP_CONTENT_DIR ) . '/blogs.dir/' . - Util_Environment::blog_id() . '/', '', $file ); - return $file; + // Translate multisite subsite uploads paths. + return str_replace( basename( WP_CONTENT_DIR ) . '/blogs.dir/' . Util_Environment::blog_id() . '/', '', $file ); } /** - * Convert a relative path (relative to ABSPATH (wp folder on disc) into a absolute path + * Convert a relative path (relative to ABSPATH (wp folder on disc) into a absolute path. * - * @param unknown $file + * @param string $file Filename. * @return string */ - function docroot_filename_to_absolute_path( $file ) { - if ( is_file( $file ) ) + public function docroot_filename_to_absolute_path( $file ) { + if ( is_file( $file ) ) { return $file; + } - if ( DIRECTORY_SEPARATOR != '/' ) + if ( DIRECTORY_SEPARATOR != '/' ) { $file = str_replace( '/', DIRECTORY_SEPARATOR, $file ); + } - return rtrim( Util_Environment::document_root(), '/\\' ) . - DIRECTORY_SEPARATOR . ltrim( $file, '/\\' ); + return rtrim( Util_Environment::document_root(), '/\\' ) . DIRECTORY_SEPARATOR . ltrim( $file, '/\\' ); } /** - * Convert local uri path to CDN type specific path + * Convert local uri path to CDN type specific path. * - * @param unknown $local_uri_path + * @param string $local_uri Local URI. * @return string */ - function uri_to_cdn_uri( $local_uri ) { - $local_uri = ltrim( $local_uri, '/' ); + public function uri_to_cdn_uri( $local_uri ) { + $local_uri = ltrim( $local_uri, '/' ); $remote_uri = $local_uri; - if ( Util_Environment::is_wpmu() && defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) + if ( Util_Environment::is_wpmu() && defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) { $remote_uri = str_replace( site_url(), '', $local_uri ); + } $engine = $this->_config->get_string( 'cdn.engine' ); if ( Cdn_Util::is_engine_mirror( $engine ) ) { if ( Util_Environment::is_wpmu() && strpos( $local_uri, 'files' ) === 0 ) { $upload_dir = Util_Environment::wp_upload_dir(); - $remote_uri = $this->abspath_to_relative_path( - dirname( $upload_dir['basedir'] ) ) . '/' . $local_uri; + $remote_uri = $this->abspath_to_relative_path( dirname( $upload_dir['basedir'] ) ) . '/' . $local_uri; } - } - elseif ( Util_Environment::is_wpmu() && - !Util_Environment::is_wpmu_subdomain() && + } elseif ( Util_Environment::is_wpmu() && + ! Util_Environment::is_wpmu_subdomain() && Util_Environment::is_using_master_config() && Cdn_Util::is_engine_push( $engine ) ) { - // in common config mode files are uploaded for network home url - // so mirror will not contain /subblog/ path in uri - // - // since upload process is not blog-specific and - // wp-content/plugins/../*.jpg files are common - $home = trim( home_url( '', 'relative' ), '/' ) . '/'; + /** + * In common config mode files are uploaded for network home url so mirror will not contain /subblog/ path in uri. + * Since upload process is not blog-specific and wp-content/plugins/../*.jpg files are common. + */ + $home = trim( home_url( '', 'relative' ), '/' ) . '/'; $network_home = trim( network_home_url( '', 'relative' ), '/' ) . '/'; - if ( $home != $network_home && - substr( $local_uri, 0, strlen( $home ) ) == $home ) { + if ( $home !== $network_home && substr( $local_uri, 0, strlen( $home ) ) === $home ) { $remote_uri = $network_home . substr( $local_uri, strlen( $home ) ); } } @@ -721,79 +723,63 @@ class Cdn_Core { } /** - * Need to pass full URL and it's URI - * URI passed to prevent redundant parsing, normally it's available for caller + * Need to pass full URL and it's URI. + * URI passed to prevent redundant parsing, normally it's available for caller. + * + * @param string $url URL. + * @param string $path Path. + * @return string|null **/ - function url_to_cdn_url( $url, $path ) { - $cdn = $this->get_cdn(); + public function url_to_cdn_url( $url, $path ) { + $cdn = $this->get_cdn(); $remote_path = $this->uri_to_cdn_uri( $path ); - $new_url = $cdn->format_url( $remote_path ); - if ( !$new_url ) { + $new_url = $cdn->format_url( $remote_path ); + + if ( ! $new_url ) { return null; } - $is_engine_mirror = Cdn_Util::is_engine_mirror( - $this->_config->get_string( 'cdn.engine' ) ); - $new_url = apply_filters( 'w3tc_cdn_url', $new_url, $url, - $is_engine_mirror ); + $is_engine_mirror = Cdn_Util::is_engine_mirror( $this->_config->get_string( 'cdn.engine' ) ); + $new_url = apply_filters( 'w3tc_cdn_url', $new_url, $url, $is_engine_mirror ); + return $new_url; } /** - * Returns the sitepath for multisite subfolder or subdomain path for multisite subdomain + * Takes an absolute path and converts to a relative path to root. * - * @return string - */ - private function _get_multisite_url_identifier() { - if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) { - $parsedUrl = parse_url( site_url() ); - return $parsedUrl['host']; - } elseif ( Util_Environment::is_wpmu_subdomain() ) { - $parsedUrl = parse_url( Util_Environment::home_domain_root_url() ); - $urlparts = explode( '.', $parsedUrl['host'] ); - - if ( sizeof( $urlparts ) > 2 ) { - $subdomain = array_shift( $urlparts ); - return trim( $subdomain, '/' ); - } - } - return trim( Util_Environment::site_url_uri(), '/' ); - } - - /** - * Taks an absolute path and converts to a relative path to root - * - * @param unknown $path + * @param string $path Path. * @return mixed */ - function abspath_to_relative_path( $path ) { + public function abspath_to_relative_path( $path ) { return str_replace( Util_Environment::document_root(), '', $path ); } /** - * Takes a root relative path and converts to a full uri + * Takes a root relative path and converts to a full URI. * - * @param unknown $path + * @param string $path Path. * @return string */ - function relative_path_to_url( $path ) { - $cdnuri = $this->docroot_filename_to_uri( ltrim( $path, "/" ) ); - return rtrim( Util_Environment::home_domain_root_url(), "/" ) . '/' . $cdnuri; + public function relative_path_to_url( $path ) { + return rtrim( Util_Environment::home_domain_root_url(), '/' ) . '/' . + $this->docroot_filename_to_uri( ltrim( $path, '/' ) ); } /** - * Constructs a CDN file descriptor + * Constructs a CDN file descriptor. * - * @param unknown $local_path - * @param unknown $remote_path + * @param string $local_path Local path. + * @param string $remote_path Remote path. * @return array */ - function build_file_descriptor( $local_path, $remote_path ) { - $file = array( 'local_path' => $local_path, - 'remote_path' => $remote_path, - 'original_url' => $this->relative_path_to_url( $local_path ) ); + public function build_file_descriptor( $local_path, $remote_path ) { + $file = array( + 'local_path' => $local_path, + 'remote_path' => $remote_path, + 'original_url' => $this->relative_path_to_url( $local_path ), + ); - $file = apply_filters( 'w3tc_build_cdn_file_array', $file ); - return $file; + return apply_filters( 'w3tc_build_cdn_file_array', $file ); } } diff --git a/wp-content/plugins/w3-total-cache/Cdn_GeneralPage_View.php b/wp-content/plugins/w3-total-cache/Cdn_GeneralPage_View.php index 76c091f3..7e3e82b8 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_GeneralPage_View.php +++ b/wp-content/plugins/w3-total-cache/Cdn_GeneralPage_View.php @@ -7,9 +7,7 @@ namespace W3TC; -if ( ! defined( 'W3TC' ) ) { - die(); -} +defined( 'W3TC' ) || die; Util_Ui::postbox_header_tabs( wp_kses( @@ -29,12 +27,12 @@ Util_Ui::postbox_header_tabs( ) ), esc_html__( - 'Content Delivery Network (CDN) is a powerful feature that can significantly enhance the performance of - your WordPress website. By leveraging a distributed network of servers located worldwide, a CDN helps - deliver your website\'s static files, such as images, CSS, and JavaScript, to visitors more efficiently. - This reduces the latency and improves the loading speed of your website, resulting in a faster and - smoother browsing experience for your users. With W3 Total Cache\'s CDN integration, you can easily - configure and connect your website to a CDN service of your choice, unleashing the full potential of + 'Content Delivery Network (CDN) is a powerful feature that can significantly enhance the performance of + your WordPress website. By leveraging a distributed network of servers located worldwide, a CDN helps + deliver your website\'s static files, such as images, CSS, and JavaScript, to visitors more efficiently. + This reduces the latency and improves the loading speed of your website, resulting in a faster and + smoother browsing experience for your users. With W3 Total Cache\'s CDN integration, you can easily + configure and connect your website to a CDN service of your choice, unleashing the full potential of your WordPress site\'s speed optimization.', 'w3-total-cache' ), @@ -50,6 +48,32 @@ Util_Ui::config_overloading_button( ?>

', + '', + '', + '' + ), + array( + 'acronym' => array( + 'title' => array(), + ), + 'a' => array( + 'href' => array(), + 'target' => array(), + ), + ) + ); + } + $config = Dispatcher::config(); $cdn_engine = $config->get_string( 'cdn.engine' ); $cdnfsd_engine = $config->get_string( 'cdnfsd.engine' ); @@ -61,16 +85,16 @@ Util_Ui::config_overloading_button(

+ ?>

+ ?>

', diff --git a/wp-content/plugins/w3-total-cache/Cdn_Page.php b/wp-content/plugins/w3-total-cache/Cdn_Page.php index d6427b63..71c66fc3 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_Page.php +++ b/wp-content/plugins/w3-total-cache/Cdn_Page.php @@ -1,11 +1,18 @@ get_string( 'cdn.engine' ); - - $cdn_enabled = $config->get_boolean( 'cdn.enabled' ); - $cdn_mirror = Cdn_Util::is_engine_mirror( $cdn_engine ); + public function view() { + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + $cdn_engine = $config->get_string( 'cdn.engine' ); + $cdn_enabled = $config->get_boolean( 'cdn.enabled' ); + $is_cdn_authorized = ! empty( $account_api_key ) && ! empty( $config->get_string( 'cdn.bunnycdn.pull_zone_id' ) ); + $cdnfsd_engine = $config->get_string( 'cdnfsd.engine' ); + $cdnfsd_enabled = $config->get_boolean( 'cdnfsd.enabled' ); + $is_cdnfsd_authorized = ! empty( $account_api_key ) && ! empty( $config->get_string( 'cdnfsd.bunnycdn.pull_zone_id' ) ); + $cdn_mirror = Cdn_Util::is_engine_mirror( $cdn_engine ); $cdn_mirror_purge_all = Cdn_Util::can_purge_all( $cdn_engine ); - $cdn_common = Dispatcher::component( 'Cdn_Core' ); - - $cdn = $cdn_common->get_cdn(); - $cdn_supports_header = $cdn->headers_support() == W3TC_CDN_HEADER_MIRRORING; - $minify_enabled = ( + $cdn_common = Dispatcher::component( 'Cdn_Core' ); + $cdn = $cdn_common->get_cdn(); + $cdn_supports_header = $cdn->headers_support() == W3TC_CDN_HEADER_MIRRORING; + $minify_enabled = ( $config->get_boolean( 'minify.enabled' ) && Util_Rule::can_check_rules() && $config->get_boolean( 'minify.rewrite' ) && - ( !$config->get_boolean( 'minify.auto' ) || - Cdn_Util::is_engine_mirror( $config->get_string( 'cdn.engine' ) ) ) ); + ( ! $config->get_boolean( 'minify.auto' ) || Cdn_Util::is_engine_mirror( $config->get_string( 'cdn.engine' ) ) ) + ); + $cookie_domain = $this->get_cookie_domain(); + $set_cookie_domain = $this->is_cookie_domain_enabled(); - $cookie_domain = $this->get_cookie_domain(); - $set_cookie_domain = $this->is_cookie_domain_enabled(); - - // Required for Update Media Query String button - $browsercache_enabled = $config->get_boolean( 'browsercache.enabled' ); + // Required for Update Media Query String button. + $browsercache_enabled = $config->get_boolean( 'browsercache.enabled' ); $browsercache_update_media_qs = ( $config->get_boolean( 'browsercache.cssjs.replace' ) || $config->get_boolean( 'browsercache.other.replace' ) ); + include W3TC_INC_DIR . '/options/cdn.php'; } /** - * Returns cookie domain + * Returns cookie domain. * * @return string */ - function get_cookie_domain() { - $site_url = get_option( 'siteurl' ); + public function get_cookie_domain() { + $site_url = get_option( 'siteurl' ); $parse_url = @parse_url( $site_url ); - if ( $parse_url && !empty( $parse_url['host'] ) ) { + if ( $parse_url && ! empty( $parse_url['host'] ) ) { return $parse_url['host']; } @@ -60,11 +70,11 @@ class Cdn_Page extends Base_Page_Settings { } /** - * Checks if COOKIE_DOMAIN is enabled + * Checks if COOKIE_DOMAIN is enabled. * * @return bool */ - function is_cookie_domain_enabled() { + public function is_cookie_domain_enabled() { $cookie_domain = $this->get_cookie_domain(); return defined( 'COOKIE_DOMAIN' ) && COOKIE_DOMAIN == $cookie_domain; diff --git a/wp-content/plugins/w3-total-cache/Cdn_Page_View_Header.php b/wp-content/plugins/w3-total-cache/Cdn_Page_View_Header.php deleted file mode 100644 index ce5679fd..00000000 --- a/wp-content/plugins/w3-total-cache/Cdn_Page_View_Header.php +++ /dev/null @@ -1,30 +0,0 @@ - - - -

- ' . esc_html( Cache::engine_name( $config->get_string( 'cdn.engine' ) ) ) . '', - '' . __( 'enabled', 'w3-total-cache' ) : 'disabled">' . __( 'disabled', 'w3-total-cache' ) ) . '' - ), - array( - 'strong' => array(), - 'span' => array( - 'class' => array(), - ), - ) - ); - ?> -

diff --git a/wp-content/plugins/w3-total-cache/Cdn_Plugin_Admin.php b/wp-content/plugins/w3-total-cache/Cdn_Plugin_Admin.php index 74934528..03f789f2 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_Plugin_Admin.php +++ b/wp-content/plugins/w3-total-cache/Cdn_Plugin_Admin.php @@ -1,244 +1,241 @@ get_string( 'cdn.engine' ); if ( $c->get_boolean( 'cdn.enabled' ) ) { $admin_notes = new Cdn_AdminNotes(); - add_filter( 'w3tc_notes', array( $admin_notes, 'w3tc_notes' ) ); - add_filter( 'w3tc_errors', array( $admin_notes, 'w3tc_errors' ) ); + \add_filter( 'w3tc_notes', array( $admin_notes, 'w3tc_notes' ) ); + \add_filter( 'w3tc_errors', array( $admin_notes, 'w3tc_errors' ) ); - if ( $c->get_boolean( 'cdn.admin.media_library' ) && - $c->get_boolean( 'cdn.uploads.enable' ) ) { - - add_filter( 'wp_get_attachment_url', - array( $this, 'wp_get_attachment_url' ), 0 ); - - add_filter( 'attachment_link', - array( $this, 'wp_get_attachment_url' ), 0 ); + if ( $c->get_boolean( 'cdn.admin.media_library' ) && $c->get_boolean( 'cdn.uploads.enable' ) ) { + \add_filter( 'wp_get_attachment_url', array( $this, 'wp_get_attachment_url' ), 0 ); + \add_filter( 'attachment_link', array( $this, 'wp_get_attachment_url' ), 0 ); } } - - // attach to actions without firing class loading at all without need - if ( $cdn_engine == 'google_drive' ) { - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_GoogleDrive_Page', - 'w3tc_settings_cdn_boxarea_configuration' - ) ); - } elseif ( $cdn_engine == 'highwinds' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_Highwinds_Popup', - 'w3tc_ajax' ) ); - add_action( 'admin_init_w3tc_dashboard', array( - '\W3TC\Cdn_Highwinds_Widget', - 'admin_init_w3tc_dashboard' ) ); - add_action( 'w3tc_ajax_cdn_highwinds_widgetdata', array( - '\W3TC\Cdn_Highwinds_Widget', - 'w3tc_ajax_cdn_highwinds_widgetdata' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_Highwinds_Page', - 'w3tc_settings_cdn_boxarea_configuration' ) ); - } elseif ( $cdn_engine == 'limelight' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_LimeLight_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_LimeLight_Page', - 'w3tc_settings_cdn_boxarea_configuration' - ) ); - } elseif ( $cdn_engine == 'rackspace_cdn' ) { - add_filter( 'w3tc_admin_actions', array( - '\W3TC\Cdn_RackSpaceCdn_Page', - 'w3tc_admin_actions' ) ); - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_RackSpaceCdn_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_RackSpaceCdn_Page', - 'w3tc_settings_cdn_boxarea_configuration' ) ); - } elseif ( $cdn_engine == 'rscf' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_RackSpaceCloudFiles_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_RackSpaceCloudFiles_Page', - 'w3tc_settings_cdn_boxarea_configuration' ) ); - } elseif ( $cdn_engine == 'stackpath' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_StackPath_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_StackPath_Page', - 'w3tc_settings_cdn_boxarea_configuration' - ) ); - add_action( 'admin_init_w3tc_dashboard', array( - '\W3TC\Cdn_StackPath_Widget', - 'admin_init_w3tc_dashboard' ) ); - add_action( 'w3tc_ajax_cdn_stackpath_widgetdata', array( - '\W3TC\Cdn_StackPath_Widget', - 'w3tc_ajax_cdn_stackpath_widgetdata' ) ); - } elseif ( $cdn_engine == 'stackpath2' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdn_StackPath2_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_cdn_boxarea_configuration', array( - '\W3TC\Cdn_StackPath2_Page', - 'w3tc_settings_cdn_boxarea_configuration' - ) ); - add_action( 'admin_init_w3tc_dashboard', array( - '\W3TC\Cdn_StackPath2_Widget', - 'admin_init_w3tc_dashboard' ) ); - add_action( 'w3tc_ajax_cdn_stackpath2_widgetdata', array( - '\W3TC\Cdn_StackPath2_Widget', - 'w3tc_ajax_cdn_stackpath2_widgetdata' ) ); - } else { - // default cdn widget - add_action( 'admin_init_w3tc_dashboard', array( - '\W3TC\Cdn_StackPath2_Widget', - 'admin_init_w3tc_dashboard' ) ); - add_action( 'w3tc_ajax_cdn_stackpath2_widgetdata', array( - '\W3TC\Cdn_StackPath2_Widget', - 'w3tc_ajax_cdn_stackpath2_widgetdata' ) ); + // Attach to actions without firing class loading at all without need. + switch ( $cdn_engine ) { + case 'google_drive': + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_GoogleDrive_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + break; + case 'highwinds': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_Highwinds_Popup', 'w3tc_ajax' ) ); + \add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Cdn_Highwinds_Widget', 'admin_init_w3tc_dashboard' ) ); + \add_action( 'w3tc_ajax_cdn_highwinds_widgetdata', array( '\W3TC\Cdn_Highwinds_Widget', 'w3tc_ajax_cdn_highwinds_widgetdata' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_Highwinds_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + break; + case 'limelight': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_LimeLight_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_LimeLight_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + break; + case 'rackspace_cdn': + \add_filter( 'w3tc_admin_actions', array( '\W3TC\Cdn_RackSpaceCdn_Page', 'w3tc_admin_actions' ) ); + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_RackSpaceCdn_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_RackSpaceCdn_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + break; + case 'rscf': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_RackSpaceCloudFiles_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_RackSpaceCloudFiles_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + break; + case 'stackpath': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_StackPath_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_StackPath_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + \add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Cdn_StackPath_Widget', 'admin_init_w3tc_dashboard' ) ); + \add_action( 'w3tc_ajax_cdn_stackpath_widgetdata', array( '\W3TC\Cdn_StackPath_Widget', 'w3tc_ajax_cdn_stackpath_widgetdata' ) ); + break; + case 'stackpath2': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_StackPath2_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_StackPath2_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + \add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Cdn_StackPath2_Widget', 'admin_init_w3tc_dashboard' ) ); + \add_action( 'w3tc_ajax_cdn_stackpath2_widgetdata', array( '\W3TC\Cdn_StackPath2_Widget', 'w3tc_ajax_cdn_stackpath2_widgetdata' ) ); + break; + case 'bunnycdn': + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_BunnyCdn_Page', 'w3tc_ajax' ) ); + \add_action( 'w3tc_ajax', array( '\W3TC\Cdn_BunnyCdn_Popup', 'w3tc_ajax' ) ); + \add_action( 'w3tc_settings_cdn_boxarea_configuration', array( '\W3TC\Cdn_BunnyCdn_Page', 'w3tc_settings_cdn_boxarea_configuration' ) ); + \add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Cdn_BunnyCdn_Widget', 'admin_init_w3tc_dashboard' ) ); + \add_action( 'w3tc_ajax_cdn_bunnycdn_widgetdata', array( '\W3TC\Cdn_BunnyCdn_Widget', 'w3tc_ajax_cdn_bunnycdn_widgetdata' ) ); + \add_action( 'w3tc_purge_urls_box', array( '\W3TC\Cdn_BunnyCdn_Page', 'w3tc_purge_urls_box' ) ); + // \add_filter( 'w3tc_dashboard_actions', array( '\W3TC\Cdn_BunnyCdn_Page', 'w3tc_dashboard_actions' ) ); // @todo Revisit this item. + break; + default: + \add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Cdn_BunnyCdn_Widget', 'admin_init_w3tc_dashboard' ) ); + \add_action( 'w3tc_ajax_cdn_bunnycdn_widgetdata', array( '\W3TC\Cdn_BunnyCdn_Widget', 'w3tc_ajax_cdn_bunnycdn_widgetdata' ) ); + break; } - add_action( 'w3tc_settings_general_boxarea_cdn', array( - $this, - 'w3tc_settings_general_boxarea_cdn' - ) ); + \add_action( 'w3tc_settings_general_boxarea_cdn', array( $this, 'w3tc_settings_general_boxarea_cdn' ) ); } - - + /** + * CDN settings. + * + * @return void + */ public function w3tc_settings_general_boxarea_cdn() { - $config = Dispatcher::config(); - - $engine_optgroups = array(); - $engine_values = array(); - - $optgroup_pull = count( $engine_optgroups ); - $engine_optgroups[] = __( 'Origin Pull / Mirror:', 'w3-total-cache' ); - - $optgroup_push = count( $engine_optgroups ); - $engine_optgroups[] = __( 'Origin Push:', 'w3-total-cache' ); + $config = Dispatcher::config(); + $engine_optgroups = array(); + $engine_values = array(); + $optgroup_pull = count( $engine_optgroups ); + $engine_optgroups[] = \__( 'Origin Pull / Mirror:', 'w3-total-cache' ); + $optgroup_push = count( $engine_optgroups ); + $engine_optgroups[] = \__( 'Origin Push:', 'w3-total-cache' ); + $engine_values[''] = array( + 'label' => 'Select a provider', + ); $engine_values['akamai'] = array( - 'label' => __( 'Akamai', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Akamai', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['cf2'] = array( - 'label' => __( 'Amazon CloudFront', 'w3-total-cache' ), - 'disabled' => ( !Util_Installed::curl() ? true : null ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Amazon CloudFront', 'w3-total-cache' ), + 'disabled' => ! Util_Installed::curl() ? true : null, + 'optgroup' => $optgroup_pull, ); + $engine_values['att'] = array( - 'label' => __( 'AT&T', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'AT&T', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + + $engine_values['bunnycdn'] = array( + 'label' => \__( 'Bunny CDN (recommended)', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, + ); + $engine_values['cotendo'] = array( - 'label' => __( 'Cotendo (Akamai)', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Cotendo (Akamai)', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['mirror'] = array( - 'label' => __( 'Generic Mirror', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Generic Mirror', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['highwinds'] = array( - 'label' => __( 'Highwinds', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Highwinds', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['limelight'] = array( - 'label' => __( 'LimeLight', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'LimeLight', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['rackspace_cdn'] = array( - 'label' => __( 'RackSpace CDN', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'RackSpace CDN', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['stackpath2'] = array( - 'label' => __( 'StackPath (recommended)', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'StackPath', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['stackpath'] = array( - 'label' => __( 'StackPath SecureCDN (Legacy)', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'StackPath SecureCDN (Legacy)', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['edgecast'] = array( - 'label' => __( 'Verizon Digital Media Services (EdgeCast) / Media Temple ProCDN', 'w3-total-cache' ), - 'optgroup' => $optgroup_pull + 'label' => \__( 'Verizon Digital Media Services (EdgeCast) / Media Temple ProCDN', 'w3-total-cache' ), + 'optgroup' => $optgroup_pull, ); + $engine_values['cf'] = array( - 'disabled' => ( !Util_Installed::curl() ? true : null ), - 'label' => __( 'Amazon CloudFront Over S3', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'disabled' => ! Util_Installed::curl() ? true : null, + 'label' => \__( 'Amazon CloudFront Over S3', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['s3'] = array( - 'disabled' => ( !Util_Installed::curl() ? true : null ), - 'label' => __( 'Amazon Simple Storage Service (S3)', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'disabled' => ! Util_Installed::curl() ? true : null, + 'label' => \__( 'Amazon Simple Storage Service (S3)', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['s3_compatible'] = array( - 'disabled' => ( !Util_Installed::curl() ? true : null ), - 'label' => __( 'Amazon Simple Storage Service (S3) Compatible', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'disabled' => ! Util_Installed::curl() ? true : null, + 'label' => \__( 'Amazon Simple Storage Service (S3) Compatible', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['google_drive'] = array( - 'label' => __( 'Google Drive', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'label' => \__( 'Google Drive', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['azure'] = array( - 'label' => __( 'Microsoft Azure Storage', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'label' => \__( 'Microsoft Azure Storage', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['rscf'] = array( - 'disabled' => ( !Util_Installed::curl() ? true : null ), - 'label' => __( 'Rackspace Cloud Files', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'disabled' => ! Util_Installed::curl() ? true : null, + 'label' => \__( 'Rackspace Cloud Files', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); + $engine_values['ftp'] = array( - 'disabled' => ( !Util_Installed::ftp() ? true : null ), - 'label' => __( 'Self-hosted / File Transfer Protocol Upload', 'w3-total-cache' ), - 'optgroup' => $optgroup_push + 'disabled' => ! Util_Installed::ftp() ? true : null, + 'label' => \__( 'Self-hosted / File Transfer Protocol Upload', 'w3-total-cache' ), + 'optgroup' => $optgroup_push, ); $cdn_enabled = $config->get_boolean( 'cdn.enabled' ); - $cdn_engine = $config->get_string( 'cdn.engine' ); + $cdn_engine = $config->get_string( 'cdn.engine' ); - include W3TC_DIR . '/Cdn_GeneralPage_View.php'; + include W3TC_DIR . '/Cdn_GeneralPage_View.php'; } - - /** - * Adjusts attachment urls to cdn. This is for those who rely on - * wp_get_attachment_url() + * Adjusts attachment urls to cdn. This is for those who rely on wp_get_attachment_url(). * - * @param string $url the local url to modify - * @return string + * @param string $url The local url to modify. + * @return string */ - function wp_get_attachment_url( $url ) { + public function wp_get_attachment_url( $url ) { if ( defined( 'WP_ADMIN' ) ) { $url = trim( $url ); - if ( !empty( $url ) ) { - $parsed = parse_url( $url ); - $uri = ( isset( $parsed['path'] ) ? $parsed['path'] : '/' ) . + if ( ! empty( $url ) ) { + $parsed = \parse_url( $url ); + $uri = ( isset( $parsed['path'] ) ? $parsed['path'] : '/' ) . ( isset( $parsed['query'] ) ? '?' . $parsed['query'] : '' ); - - $wp_upload_dir = wp_upload_dir(); + $wp_upload_dir = \wp_upload_dir(); $upload_base_url = $wp_upload_dir['baseurl']; - if ( substr($url, 0, strlen( $upload_base_url ) ) == $upload_base_url ) { - $common = Dispatcher::component( 'Cdn_Core' ); + if ( \substr( $url, 0, strlen( $upload_base_url ) ) === $upload_base_url ) { + $common = Dispatcher::component( 'Cdn_Core' ); $new_url = $common->url_to_cdn_url( $url, $uri ); - if ( !is_null( $new_url ) ) { + if ( ! is_null( $new_url ) ) { $url = $new_url; } } diff --git a/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Page_View.php b/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Page_View.php index d8d600b6..ccb61058 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Page_View.php +++ b/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Page_View.php @@ -1,9 +1,14 @@ diff --git a/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Popup.php b/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Popup.php index acd3cb84..b08e3d3b 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Popup.php +++ b/wp-content/plugins/w3-total-cache/Cdn_StackPath2_Popup.php @@ -49,7 +49,7 @@ class Cdn_StackPath2_Popup { $api = new Cdn_StackPath2_Api( $api_config ); try { - $r = $r = $api->stacks_list(); + $r = $api->stacks_list(); $stacks = $r['results']; } catch ( \Exception $ex ) { $error_message = 'Can\'t authenticate: ' . $ex->getMessage(); diff --git a/wp-content/plugins/w3-total-cache/Cdn_Util.php b/wp-content/plugins/w3-total-cache/Cdn_Util.php index a7ef8adb..8038a366 100644 --- a/wp-content/plugins/w3-total-cache/Cdn_Util.php +++ b/wp-content/plugins/w3-total-cache/Cdn_Util.php @@ -46,9 +46,10 @@ class Cdn_Util { } /** - * Returns true if CDN engine is mirror + * Returns true if CDN engine is mirror. * * @param string $engine CDN engine. + * @static * * @return bool */ @@ -67,6 +68,7 @@ class Cdn_Util { 'rackspace_cdn', 'stackpath', 'stackpath2', + 'bunnycdn', ), true ); @@ -95,6 +97,7 @@ class Cdn_Util { $engine, array( 'att', + 'bunnycdn', 'cf2', 'cotendo', 'edgecast', diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Engine.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Engine.php new file mode 100644 index 00000000..e039ec8f --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Engine.php @@ -0,0 +1,96 @@ +config = $config; + } + + /** + * Flush URLs. + * + * @since X.X.X + * + * @param array $urls URLs. + * @throws \Exception Exception. + * @return void + */ + public function flush_urls( array $urls ) { + if ( empty( $this->config['account_api_key'] ) ) { + throw new \Exception( esc_html__( 'Account API key not specified.', 'w3-total-cache' ) ); + } + + $api = new Cdn_BunnyCdn_Api( $this->config ); + $items = array(); + + foreach ( $urls as $url ) { + $items[] = array( + 'url' => $url, + 'recursive' => true, + ); + } + + try { + $api->purge( array( 'items' => $items ) ); + } catch ( \Exception $ex ) { + if ( $ex->getMessage() == 'Validation Failure: Purge url must contain one of your hostnames' ) { + throw new \Exception( esc_html__( 'CDN site is not configured correctly: Delivery Domain must match your site domain', 'w3-total-cache' ) ); + } else { + throw $ex; + } + } + } + + /** + * Flushes CDN completely. + * + * @since X.X.X + * + * @throws \Exception Exception. + */ + public function flush_all() { + if ( empty( $this->config['account_api_key'] ) ) { + throw new \Exception( \esc_html__( 'Account API key not specified.', 'w3-total-cache' ) ); + } + + if ( empty( $this->config['pull_zone_id'] ) || ! \is_int( $this->config['pull_zone_id'] ) ) { + throw new \Exception( \esc_html__( 'Invalid pull zone id.', 'w3-total-cache' ) ); + } + + $api = new Cdn_BunnyCdn_Api( $this->config ); + + try { + $r = $api->purge_pull_zone(); + } catch ( \Exception $ex ) { + throw new \Exception( \esc_html( \__( 'Could not purge pull zone', 'w3-total-cache' ) . '; ' . $ex->getMessage() ) ); + } + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Page.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Page.php new file mode 100644 index 00000000..1f6b5193 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Page.php @@ -0,0 +1,41 @@ +get_string( 'cdn.bunnycdn.account_api_key' ); +$is_authorized = $account_api_key && $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); +$is_unavailable = ! empty( $account_api_key ) && $config->get_string( 'cdn.bunnycdn.pull_zone_id' ); // CDN FSD is unavailable if CDN is authorized for Bunny CDN. + +Util_Ui::postbox_header( + esc_html__( 'Configuration: Full-Site Delivery', 'w3-total-cache' ), + '', + 'configuration-fsd' +); + +?> + + + + + + + + + + + + + + + + + + + + +
+ + + + + + /> + +
+

+ +

+
+ + +
+ get_string( 'cdnfsd.bunnycdn.name' ) ); ?> +
+ + + get_string( 'cdnfsd.bunnycdn.origin_url' ) ); ?> +
+ + + get_string( 'cdnfsd.bunnycdn.cdn_hostname' ) ); ?> +

+ ', + '', + '' + ), + array( + 'acronym' => array( + 'title' => array(), + ), + ) + ); + ?> +

+
+ + diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup.php new file mode 100644 index 00000000..5834fab9 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup.php @@ -0,0 +1,297 @@ +get_string( 'cdn.bunnycdn.account_api_key' ); + + // Ask for an account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + ) + ); + } + + /** + * W3TC AJAX: List pull zones. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_fsd_list_pull_zones() { + $account_api_key = Util_Request::get_string( 'account_api_key' ); + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to retrieve pull zones. + try { + $pull_zones = $api->list_pull_zones(); + } catch ( \Exception $ex ) { + // Reauthorize: Ask for a new account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + 'error_message' => \esc_html( \__( 'Cannot list pull zones', 'w3-total-cache' ) . '; ' . $ex->getMessage() ), + ) + ); + } + + // Save the account API key, if added or changed. + $config = Dispatcher::config(); + + if ( $config->get_string( 'cdn.bunnycdn.account_api_key' ) !== $account_api_key ) { + $config->set( 'cdn.bunnycdn.account_api_key', $account_api_key ); + $config->save(); + } + + // Print the view. + $server_ip = ! empty( $_SERVER['SERVER_ADDR'] ) && \filter_var( \wp_unslash( $_SERVER['SERVER_ADDR'] ), FILTER_VALIDATE_IP ) ? + \filter_var( \wp_unslash( $_SERVER['SERVER_ADDR'] ), FILTER_SANITIZE_URL ) : null; + $suggested_origin_url = 'http' . ( \is_ssl() ? 's' : '' ) . '://' . + ( empty( $server_ip ) ? \parse_url( \home_url(), PHP_URL_HOST ) : $server_ip ); + + $details = array( + 'pull_zones' => $pull_zones, + 'suggested_origin_url' => $suggested_origin_url, // Suggested origin URL or IP. + 'suggested_zone_name' => \substr( \str_replace( '.', '-', \parse_url( \home_url(), PHP_URL_HOST ) ), 0, 60 ), // Suggested pull zone name. + 'pull_zone_id' => $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ), + 'suggested_custom_hostname' => \parse_url( \home_url(), PHP_URL_HOST ), // Suggested custom hostname. + ); + + include W3TC_DIR . '/Cdnfsd_BunnyCdn_Popup_View_Pull_Zones.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Configure pull zone. + * + * @since X.X.X + * + * @see Cdn_BunnyCdn_Api::get_default_edge_rules() + */ + public function w3tc_ajax_cdn_bunnycdn_fsd_configure_pull_zone() { + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + $pull_zone_id = Util_Request::get_integer( 'pull_zone_id' ); + $origin_url = Util_Request::get_string( 'origin_url' ); // Origin URL or IP. + $name = Util_Request::get_string( 'name' ); // Pull zone name. + $cdn_hostname = Util_Request::get_string( 'cdn_hostname' ); // Pull zone CDN hostname (system). + $custom_hostnames = explode( ',', Util_Request::get_string( 'custom_hostnames' ) ); + + // If not selecting a pull zone. then create a new one. + if ( empty( $pull_zone_id ) ) { + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to create a new pull zone. + try { + $response = $api->add_pull_zone( + array( + 'Name' => $name, // The name/hostname for the pull zone where the files will be accessible; only letters, numbers, and dashes. + 'OriginUrl' => $origin_url, // Origin URL or IP (with optional port number). + 'AddHostHeader' => true, // Determines if the zone should forward the requested host header to the origin. + 'CacheErrorResponses' => true, // If enabled, bunny.net will temporarily cache error responses (304+ HTTP status codes) from your servers for 5 seconds to prevent DDoS attacks on your origin. If disabled, error responses will be set to no-cache. + 'DisableCookies' => false, // Determines if the Pull Zone should automatically remove cookies from the responses. + 'EnableTLS1' => false, // TLS 1.0 was deprecated in 2018. + 'EnableTLS1_1' => false, // TLS 1.1 was EOL's on March 31,2020. + 'ErrorPageWhitelabel' => true, // Any bunny.net branding will be removed from the error page and replaced with a generic term. + 'UseStaleWhileUpdating' => true, // Serve stale content while updating. If Stale While Updating is enabled, cache will not be refreshed if the origin responds with a non-cacheable resource. + 'UseStaleWhileOffline' => true, // Serve stale content if the origin is offline. + ) + ); + + $pull_zone_id = (int) $response['Id']; + $name = $response['Name']; + $cdn_hostname = $response['Hostnames'][0]['Value']; + } catch ( \Exception $ex ) { + // Reauthorize: Ask for a new account API key. + $this->render_intro( + array( + 'account_api_key' => empty( $account_api_key ) ? null : $account_api_key, + 'error_message' => \esc_html( \__( 'Cannot select or add a pull zone', 'w3-total-cache' ) . '; ' . $ex->getMessage() ), + ) + ); + } + + // Initialize an error messages array. + $error_messages = array(); + + // Add Edge Rules. + foreach ( Cdn_BunnyCdn_Api::get_default_edge_rules() as $edge_rule ) { + try { + $api->add_edge_rule( $edge_rule, $pull_zone_id ); + } catch ( \Exception $ex ) { + $error_messages[] = sprintf( + // translators: 1: Edge Rule description/name. + \__( 'Could not add Edge Rule "%1$s".', 'w3-total-cache' ) . '; ', + \esc_html( $edge_rule['Description'] ) + ) . $ex->getMessage(); + } + } + + // Add custom hostnames, if any. + if ( ! empty( $custom_hostnames ) ) { + + foreach ( $custom_hostnames as $custom_hostname ) { + try { + $api->add_custom_hostname( $custom_hostname, $pull_zone_id ); + } catch ( \Exception $ex ) { + $error_messages[] = sprintf( + // translators: 1: hostname. + \__( 'Could not add custom hostname "%1$s"', 'w3-total-cache' ) . '; ', + \esc_html( $custom_hostname ) + ) . $ex->getMessage(); + } + } + } + + // Convert error messages array to a string. + $error_messages = implode( "\r\n", $error_messages ); + } + + // Save configuration. + $config->set( 'cdnfsd.bunnycdn.pull_zone_id', (int) $pull_zone_id ); + $config->set( 'cdnfsd.bunnycdn.name', $name ); + $config->set( 'cdnfsd.bunnycdn.origin_url', $origin_url ); + $config->set( 'cdnfsd.bunnycdn.cdn_hostname', $cdn_hostname ); + $config->save(); + + // Print success view. + include W3TC_DIR . '/Cdnfsd_BunnyCdn_Popup_View_Configured.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Deauthorization form. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_fsd_deauthorization() { + $config = Dispatcher::config(); + $origin_url = $config->get_string( 'cdnfsd.bunnycdn.origin_url' ); // Origin URL or IP. + $name = $config->get_string( 'cdnfsd.bunnycdn.name' ); // Pull zone name. + $cdn_hostname = $config->get_string( 'cdnfsd.bunnycdn.cdn_hostname' ); // Pull zone CDN hostname. + $cdn_pull_zone_id = $config->get_string( 'cdn.bunnycdn.pull_zone_id' ); // CDN pull zone id. + $cdnfsd_pull_zone_id = $config->get_string( 'cdnfsd.bunnycdn.pull_zone_id' ); // CDN FSD pull zone id. + + // Present details and ask to deauthorize and optionally delete the pull zone. + include W3TC_DIR . '/Cdnfsd_BunnyCdn_Popup_View_Deauthorize.php'; + \wp_die(); + } + + /** + * W3TC AJAX: Deauthorize. + * + * Deauthorize and optionally delete the pull zone. + * + * @since X.X.X + */ + public function w3tc_ajax_cdn_bunnycdn_fsd_deauthorize() { + $config = Dispatcher::config(); + $account_api_key = $config->get_string( 'cdn.bunnycdn.account_api_key' ); + $cdn_pull_zone_id = $config->get_integer( 'cdn.bunnycdn.pull_zone_id' ); // CDN pull zone id. + $cdnfsd_pull_zone_id = $config->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ); // CDN FSD pull zone id. + $delete_pull_zone = Util_Request::get_string( 'delete_pull_zone' ); + + // Delete pull zone, if requested. + if ( 'yes' === $delete_pull_zone ) { + $api = new Cdn_BunnyCdn_Api( array( 'account_api_key' => $account_api_key ) ); + + // Try to delete pull zone. + try { + $api->delete_pull_zone( $cdnfsd_pull_zone_id ); + } catch ( \Exception $ex ) { + $delete_error_message = $ex->getMessage(); + } + + // If the same pull zone is used for CDN Objects, then deauthorize that too. + if ( ! empty( $cdnfsd_pull_zone_id ) && $cdnfsd_pull_zone_id === $cdn_pull_zone_id ) { + $config->set( 'cdn.bunnycdn.pull_zone_id', null ); + $config->set( 'cdn.bunnycdn.name', null ); + $config->set( 'cdn.bunnycdn.origin_url', null ); + $config->set( 'cdn.bunnycdn.cdn_hostname', null ); + } + } + + $config->set( 'cdnfsd.bunnycdn.pull_zone_id', null ); + $config->set( 'cdnfsd.bunnycdn.name', null ); + $config->set( 'cdnfsd.bunnycdn.origin_url', null ); + $config->set( 'cdnfsd.bunnycdn.cdn_hostname', null ); + $config->save(); + + // Print success view. + include W3TC_DIR . '/Cdnfsd_BunnyCdn_Popup_View_Deauthorized.php'; + \wp_die(); + } + + /** + * Render intro. + * + * @since X.X.X + * @access private + * + * @param array $details { + * Details for the modal. + * + * @type string $account_api_key Account API key. + * @type string $error_message Error message (optional). + * } + */ + private function render_intro( array $details ) { + include W3TC_DIR . '/Cdnfsd_BunnyCdn_Popup_View_Intro.php'; + \wp_die(); + } +} diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Configured.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Configured.php new file mode 100644 index 00000000..63183f3a --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Configured.php @@ -0,0 +1,42 @@ + + +
+ +
+ +
+
+ + +
+

+ +

+

+ +

+

+ + +

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorize.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorize.php new file mode 100644 index 00000000..3986c05d --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorize.php @@ -0,0 +1,62 @@ + +
+ +
+ + + + + + + + + + + + + + + + + + +
:
:
:
: + Delete the pull zone + +

+ +

+ +
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorized.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorized.php new file mode 100644 index 00000000..b385fed7 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Deauthorized.php @@ -0,0 +1,49 @@ + +
+ +
+ +
+ +
+ + +
+

.

+
+ +
+

.

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Intro.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Intro.php new file mode 100644 index 00000000..7eba8452 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Intro.php @@ -0,0 +1,54 @@ + +
+ +
+ +
+ +
+ + + + + + +
: + +

+ + , + +

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Pull_Zones.php b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Pull_Zones.php new file mode 100644 index 00000000..eea4218d --- /dev/null +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_BunnyCdn_Popup_View_Pull_Zones.php @@ -0,0 +1,140 @@ + +
+ + +
+ + + + + + + + + + + + + + + + + +
: + + data-suggested="" /> +

+ +

+
: + + data-suggested="" /> +

+ +

+
: + + data-suggested="" /> +

+ +
+ +

+
+ +

+ +

+ +
+
diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_Core.php b/wp-content/plugins/w3-total-cache/Cdnfsd_Core.php index a286282b..5063524c 100644 --- a/wp-content/plugins/w3-total-cache/Cdnfsd_Core.php +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_Core.php @@ -1,14 +1,23 @@ get_string( 'cdnfsd.engine' ); switch ( $engine ) { - case 'cloudflare': - $engine_object = null; // extension handles everything - break; + case 'cloudflare': + $engine_object = null; // Extension handles everything. + break; case 'transparentcdn': - $engine_object = new Cdnfsd_TransparentCDN_Engine( array( - 'company_id' => $c->get_string( 'cdnfsd.transparentcdn.company_id' ), - 'client_id' => $c->get_string( 'cdnfsd.transparentcdn.client_id' ), - 'client_secret' => $c->get_string( 'cdnfsd.transparentcdn.client_secret' ) - ) ); - break; + $engine_object = new Cdnfsd_TransparentCDN_Engine( + array( + 'company_id' => $c->get_string( 'cdnfsd.transparentcdn.company_id' ), + 'client_id' => $c->get_string( 'cdnfsd.transparentcdn.client_id' ), + 'client_secret' => $c->get_string( 'cdnfsd.transparentcdn.client_secret' ), + ) + ); + break; - case 'cloudfront': - $engine_object = new Cdnfsd_CloudFront_Engine( array( - 'access_key' => $c->get_string( 'cdnfsd.cloudfront.access_key' ), - 'secret_key' => $c->get_string( 'cdnfsd.cloudfront.secret_key' ), - 'distribution_id' => $c->get_string( 'cdnfsd.cloudfront.distribution_id' ) - ) ); - break; + case 'cloudfront': + $engine_object = new Cdnfsd_CloudFront_Engine( + array( + 'access_key' => $c->get_string( 'cdnfsd.cloudfront.access_key' ), + 'secret_key' => $c->get_string( 'cdnfsd.cloudfront.secret_key' ), + 'distribution_id' => $c->get_string( 'cdnfsd.cloudfront.distribution_id' ), + ) + ); + break; - case 'limelight': - $engine_object = new Cdnfsd_LimeLight_Engine( array( - 'short_name' => $c->get_string( 'cdnfsd.limelight.short_name' ), - 'username' => $c->get_string( 'cdnfsd.limelight.username' ), - 'api_key' => $c->get_string( 'cdnfsd.limelight.api_key' ), - 'debug' => $c->get_string( 'cdnfsd.debug' ) - ) ); - break; + case 'limelight': + $engine_object = new Cdnfsd_LimeLight_Engine( + array( + 'short_name' => $c->get_string( 'cdnfsd.limelight.short_name' ), + 'username' => $c->get_string( 'cdnfsd.limelight.username' ), + 'api_key' => $c->get_string( 'cdnfsd.limelight.api_key' ), + 'debug' => $c->get_string( 'cdnfsd.debug' ), + ) + ); + break; - case 'stackpath': - $engine_object = new Cdnfsd_StackPath_Engine( array( - 'api_key' => $c->get_string( 'cdnfsd.stackpath.api_key' ), - 'zone_id' => $c->get_integer( 'cdnfsd.stackpath.zone_id' ) - ) ); - break; + case 'stackpath': + $engine_object = new Cdnfsd_StackPath_Engine( + array( + 'api_key' => $c->get_string( 'cdnfsd.stackpath.api_key' ), + 'zone_id' => $c->get_integer( 'cdnfsd.stackpath.zone_id' ), + ) + ); + break; - case 'stackpath2': - $state = Dispatcher::config_state(); + case 'stackpath2': + $state = Dispatcher::config_state(); - $engine_object = new Cdnfsd_StackPath2_Engine( array( - 'client_id' => $c->get_string( 'cdnfsd.stackpath2.client_id' ), - 'client_secret' => $c->get_string( 'cdnfsd.stackpath2.client_secret' ), - 'stack_id' => $c->get_string( 'cdnfsd.stackpath2.stack_id' ), - 'site_root_domain' => $c->get_string( 'cdnfsd.stackpath2.site_root_domain' ), - 'domain' => $c->get_array( 'cdnfsd.stackpath2.domain' ), - 'ssl' => $c->get_string( 'cdnfsd.stackpath2.ssl' ), - 'access_token' => $state->get_string( 'cdnfsd.stackpath2.access_token' ), - 'on_new_access_token' => array( - $this, - 'on_stackpath2_new_access_token' - ) - ) ); - break; + $engine_object = new Cdnfsd_StackPath2_Engine( + array( + 'client_id' => $c->get_string( 'cdnfsd.stackpath2.client_id' ), + 'client_secret' => $c->get_string( 'cdnfsd.stackpath2.client_secret' ), + 'stack_id' => $c->get_string( 'cdnfsd.stackpath2.stack_id' ), + 'site_root_domain' => $c->get_string( 'cdnfsd.stackpath2.site_root_domain' ), + 'domain' => $c->get_array( 'cdnfsd.stackpath2.domain' ), + 'ssl' => $c->get_string( 'cdnfsd.stackpath2.ssl' ), + 'access_token' => $state->get_string( 'cdnfsd.stackpath2.access_token' ), + 'on_new_access_token' => array( $this, 'on_stackpath2_new_access_token' ), + ) + ); + break; - default: - throw new \Exception( 'unknown engine ' . $engine ); + case 'bunnycdn': + $engine_object = new Cdnfsd_BunnyCdn_Engine( + array( + 'account_api_key' => $c->get_string( 'cdn.bunnycdn.account_api_key' ), + 'pull_zone_id' => $c->get_integer( 'cdnfsd.bunnycdn.pull_zone_id' ), + ), + ); + break; + + default: + throw new \Exception( esc_html( __( 'Unknown engine', 'w3-total-cache' ) . ' ' . $engine ) ); + break; } } return $engine_object; } - + /** + * Save new StackPath access token. + * + * @param string $access_token Access token. + */ public function on_stackpath2_new_access_token( $access_token ) { $state = Dispatcher::config_state(); $state->set( 'cdnfsd.stackpath2.access_token', $access_token ); diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_GeneralPage_View.php b/wp-content/plugins/w3-total-cache/Cdnfsd_GeneralPage_View.php index 699fe1df..9b235ca1 100644 --- a/wp-content/plugins/w3-total-cache/Cdnfsd_GeneralPage_View.php +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_GeneralPage_View.php @@ -7,9 +7,8 @@ namespace W3TC; -if ( ! defined( 'W3TC' ) ) { - die(); -} +defined( 'W3TC' ) || die; + ?>

- -

- ' . Cdnfsd_Util::engine_name( $config->get_string( 'cdnfsd.engine' ) ) . '', - '' . __( 'enabled', 'w3-total-cache' ) : 'disabled">' . __( 'disabled', 'w3-total-cache' ) ) . '' - ), - array( - 'strong' => array(), - 'span' => array( - 'class' => array(), - ), - ) - ); - ?> -

diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_Plugin_Admin.php b/wp-content/plugins/w3-total-cache/Cdnfsd_Plugin_Admin.php index 36f520a0..c6f1dc28 100644 --- a/wp-content/plugins/w3-total-cache/Cdnfsd_Plugin_Admin.php +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_Plugin_Admin.php @@ -1,102 +1,108 @@ get_string( 'cdnfsd.engine' ); - // attach to actions without firing class loading at all without need - if ( $cdnfsd_engine == 'cloudfront' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdnfsd_CloudFront_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_box_cdnfsd', array( - '\W3TC\Cdnfsd_CloudFront_Page', - 'w3tc_settings_box_cdnfsd' ) ); - } elseif ( $cdnfsd_engine == 'limelight' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdnfsd_LimeLight_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_box_cdnfsd', array( - '\W3TC\Cdnfsd_LimeLight_Page', - 'w3tc_settings_box_cdnfsd' ) ); - } elseif ( $cdnfsd_engine == 'stackpath' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdnfsd_StackPath_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_box_cdnfsd', array( - '\W3TC\Cdnfsd_StackPath_Page', - 'w3tc_settings_box_cdnfsd' ) ); - } elseif ( $cdnfsd_engine == 'stackpath2' ) { - add_action( 'w3tc_ajax', array( - '\W3TC\Cdnfsd_StackPath2_Popup', - 'w3tc_ajax' ) ); - add_action( 'w3tc_settings_box_cdnfsd', array( - '\W3TC\Cdnfsd_StackPath2_Page', - 'w3tc_settings_box_cdnfsd' ) ); - } elseif ( 'transparentcdn' === $cdnfsd_engine ){ - add_action( 'init', array( - '\W3TC\Cdnfsd_TransparentCDN_Page', - 'admin_test_api_parameters_transparentcdn' ) ); - add_action( 'w3tc_settings_box_cdnfsd', array( - '\W3TC\Cdnfsd_TransparentCDN_Page', - 'w3tc_settings_box_cdnfsd' ) ); + // Attach to actions without firing class loading at all without need. + switch ( $cdnfsd_engine ) { + case 'cloudfront': + add_action( 'w3tc_ajax', array( '\W3TC\Cdnfsd_CloudFront_Popup', 'w3tc_ajax' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_CloudFront_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + case 'limelight': + add_action( 'w3tc_ajax', array( '\W3TC\Cdnfsd_LimeLight_Popup', 'w3tc_ajax' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_LimeLight_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + case 'stackpath': + add_action( 'w3tc_ajax', array( '\W3TC\Cdnfsd_StackPath_Popup', 'w3tc_ajax' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_StackPath_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + case 'stackpath2': + add_action( 'w3tc_ajax', array( '\W3TC\Cdnfsd_StackPath2_Popup', 'w3tc_ajax' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_StackPath2_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + case 'transparentcdn': + add_action( 'init', array( '\W3TC\Cdnfsd_TransparentCDN_Page', 'admin_test_api_parameters_transparentcdn' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_TransparentCDN_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + case 'bunnycdn': + add_action( 'w3tc_ajax', array( '\W3TC\Cdnfsd_BunnyCdn_Popup', 'w3tc_ajax' ) ); + add_action( 'w3tc_settings_box_cdnfsd', array( '\W3TC\Cdnfsd_BunnyCdn_Page', 'w3tc_settings_box_cdnfsd' ) ); + break; + default: + break; } - add_action( 'w3tc_settings_general_boxarea_cdn_footer', - array( $this, 'w3tc_settings_general_boxarea_cdn_footer' ) ); + add_action( 'w3tc_settings_general_boxarea_cdn_footer', array( $this, 'w3tc_settings_general_boxarea_cdn_footer' ) ); } - - + /** + * Print the general settings page CDN footer. + */ public function w3tc_settings_general_boxarea_cdn_footer() { - $config = Dispatcher::config(); - - $cdnfsd_enabled = $config->get_boolean( 'cdnfsd.enabled' ); - $cdnfsd_engine = $config->get_string( 'cdnfsd.engine' ); - - $is_pro = Util_Environment::is_w3tc_pro( $config ); - + $config = Dispatcher::config(); + $cdnfsd_enabled = $config->get_boolean( 'cdnfsd.enabled' ); + $cdnfsd_engine = $config->get_string( 'cdnfsd.engine' ); + $is_pro = Util_Environment::is_w3tc_pro( $config ); $cdnfsd_engine_values = array(); + $tag = ''; + $cdnfsd_engine_values[''] = array( 'label' => 'Select a provider', ); + + $cdnfsd_engine_values['bunnycdn'] = array( + 'label' => __( 'Bunny CDN (recommended)', 'w3-total-cache' ), + ); + $cdnfsd_engine_values['cloudfront'] = array( 'label' => __( 'Amazon CloudFront', 'w3-total-cache' ), ); + $cdnfsd_engine_values['cloudflare'] = array( 'label' => __( 'CloudFlare (extension not activated)', 'w3-total-cache' ), 'disabled' => true, ); + $cdnfsd_engine_values['limelight'] = array( 'label' => __( 'Limelight', 'w3-total-cache' ), ); + $cdnfsd_engine_values['stackpath'] = array( 'label' => __( 'StackPath SecureCDN (Legacy)', 'w3-total-cache' ), ); + $cdnfsd_engine_values['stackpath2'] = array( - 'label' => __( 'StackPath (recommended)', 'w3-total-cache' ), + 'label' => __( 'StackPath', 'w3-total-cache' ), ); + $cdnfsd_engine_values['transparentcdn'] = array( 'label' => __( 'TransparentCDN', 'w3-total-cache' ), ); - $tag = ''; - if ( $cdnfsd_engine == 'cloudfront' ) { + if ( 'cloudfront' === $cdnfsd_engine ) { $tag = 'https://api.w3-edge.com/v1/redirects/faq/cdn-fsd/cloudfront'; - } elseif ( $cdnfsd_engine == 'stackpath' || $cdnfsd_engine == 'stackpath2' ) { + } elseif ( 'stackpath' === $cdnfsd_engine || 'stackpath2' === $cdnfsd_engine ) { $tag = 'https://api.w3-edge.com/v1/redirects/faq/cdn-fsd/stackpath'; } - if ( empty( $tag ) ) { - $cdnfsd_engine_extra_description = ''; - } else { - $cdnfsd_engine_extra_description = - ' See setup instructions'; - } + $cdnfsd_engine_extra_description = empty( $tag ) ? '' : ' See setup instructions'; - include W3TC_DIR . '/Cdnfsd_GeneralPage_View.php'; + include W3TC_DIR . '/Cdnfsd_GeneralPage_View.php'; } } diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath2_Popup.php b/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath2_Popup.php index 5fc2db0d..f7f07765 100644 --- a/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath2_Popup.php +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath2_Popup.php @@ -50,7 +50,7 @@ class Cdnfsd_StackPath2_Popup { $api = new Cdn_StackPath2_Api( $api_config ); try { - $r = $r = $api->stacks_list(); + $r = $api->stacks_list(); $stacks = $r['results']; } catch ( \Exception $ex ) { $error_message = 'Can\'t authenticate: ' . $ex->getMessage(); diff --git a/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath_Engine.php b/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath_Engine.php index b2a03805..c55bb3b3 100644 --- a/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath_Engine.php +++ b/wp-content/plugins/w3-total-cache/Cdnfsd_StackPath_Engine.php @@ -10,6 +10,7 @@ class Cdnfsd_StackPath_Engine { function __construct( $config = array() ) { +error_log( __METHOD__ . ': ' . print_r( debug_backtrace( 0 ), true ) ); $this->api_key = $config['api_key']; $this->zone_id = $config['zone_id']; } diff --git a/wp-content/plugins/w3-total-cache/ConfigState.php b/wp-content/plugins/w3-total-cache/ConfigState.php index 80a4dc80..a51f5de3 100644 --- a/wp-content/plugins/w3-total-cache/ConfigState.php +++ b/wp-content/plugins/w3-total-cache/ConfigState.php @@ -50,6 +50,7 @@ namespace W3TC; * objectcache.show_note.flush_needed * objectcache.show_note.flush_needed.timestamp - when the note was set * extension..hide_note_suggest_activation + * track.bunnycdn_signup * track.stackpath_signup */ class ConfigState { diff --git a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Api.php b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Api.php index 00c58453..2e7f7350 100644 --- a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Api.php +++ b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Api.php @@ -111,6 +111,11 @@ class Extension_CloudFlare_Api { public function zone_setting_set( $name, $value ) { + // Convert numeric values to the integer type. + if ( is_numeric( $value ) ) { + $value = intval( $value ); + } + return $this->_wp_remote_request( 'PATCH', self::$_root_uri . '/zones/' . $this->_zone_id . '/settings/' . $name, json_encode( array( 'value' => $value ) ) ); @@ -367,4 +372,4 @@ class Extension_CloudFlare_Api { return $headers; } -} \ No newline at end of file +} diff --git a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page.php b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page.php index 5d62d5e0..24ddb2c6 100644 --- a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page.php +++ b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page.php @@ -2,7 +2,7 @@ namespace W3TC; class Extension_CloudFlare_Page { - static public function admin_print_scripts_w3tc_extensions() { + static public function admin_print_scripts_performance_page_w3tc_cdn() { if ( ( isset( $_REQUEST['extension'] ) && Util_Request::get_string( 'extension' ) == 'cloudflare' ) || ( isset( $_REQUEST['page'] ) && diff --git a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page_View.php b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page_View.php index e27005ad..522a83b6 100644 --- a/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page_View.php +++ b/wp-content/plugins/w3-total-cache/Extension_CloudFlare_Page_View.php @@ -588,11 +588,30 @@ if ( ! defined( 'W3TC' ) ) { 'description' => esc_html__( 'Advanced protection from Distributed Denial of Service (DDoS) attacks on your website.', 'w3-total-cache' ), ) ); - self::cloudflare_textbox( + self::cloudflare_selectbox( $settings, array( 'key' => 'max_upload', 'label' => esc_html__( 'Max upload:', 'w3-total-cache' ), + 'values' => array( + '100' => '100 MB', + '125' => '125 MB (Business+)', + '150' => '150 MB (Business+)', + '175' => '175 MB (Business+)', + '200' => '200 MB (Business+)', + '225' => '225 MB (Enterprise)', + '250' => '250 MB (Enterprise)', + '275' => '275 MB (Enterprise)', + '300' => '300 MB (Enterprise)', + '325' => '325 MB (Enterprise)', + '350' => '350 MB (Enterprise)', + '375' => '375 MB (Enterprise)', + '400' => '400 MB (Enterprise)', + '425' => '425 MB (Enterprise)', + '450' => '450 MB (Enterprise)', + '475' => '475 MB (Enterprise)', + '500' => '500 MB (Enterprise)', + ), 'description' => esc_html__( 'Max size of file allowed for uploading', 'w3-total-cache' ), ) ); diff --git a/wp-content/plugins/w3-total-cache/Extensions_Util.php b/wp-content/plugins/w3-total-cache/Extensions_Util.php index bf5b65f3..1d76aeb7 100644 --- a/wp-content/plugins/w3-total-cache/Extensions_Util.php +++ b/wp-content/plugins/w3-total-cache/Extensions_Util.php @@ -111,6 +111,12 @@ class Extensions_Util { $w3_config->set_extension_active_frontend( $extension, true ); } + // Check for Image Service extension status changes. + if ( 'imageservice' === $extension ) { + $w3_config->set( 'extension.imageservice', true ); + } + + // Save the config, unless told not to. try { if ( ! $dont_save_config ) { $w3_config->save(); @@ -150,6 +156,12 @@ class Extensions_Util { $config->set_extension_active_frontend( $extension, false ); + // Check for Image Service extension status changes. + if ( 'imageservice' === $extension ) { + $config->set( 'extension.imageservice', false ); + } + + // Save the config, unless told not to. try { if ( ! $dont_save_config ) { $config->save(); diff --git a/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin.php b/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin.php index 9a8762d0..9b4b3579 100644 --- a/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin.php +++ b/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin.php @@ -57,7 +57,7 @@ class FeatureShowcase_Plugin_Admin { // Check if being redirected. add_filter( 'wp_redirect', - function( $location ) { + function ( $location ) { FeatureShowcase_Plugin_Admin::$wp_redirect_location = $location; return $location; } @@ -83,8 +83,8 @@ class FeatureShowcase_Plugin_Admin { * @see self::get_cards() */ public function load() { - $config = Dispatcher::config(); - $cards = self::get_cards(); + $config = Dispatcher::config(); + $cards_data = self::get_cards(); require W3TC_DIR . '/FeatureShowcase_Plugin_Admin_View.php'; @@ -132,13 +132,15 @@ class FeatureShowcase_Plugin_Admin { global $current_user; $features_seen = (array) get_user_meta( $current_user->ID, 'w3tc_features_seen', true ); - $cards = self::get_cards(); + $cards_data = self::get_cards(); $updated = false; - foreach ( $cards as $id => $card ) { - if ( ! empty( $card['is_new'] ) && ! in_array( $id, $features_seen, true ) ) { - $features_seen[] = $id; - $updated = true; + foreach ( $cards_data as $type => $cards ) { + foreach ( $cards as $id => $card ) { + if ( ! empty( $card['is_new'] ) && ! in_array( $id, $features_seen, true ) ) { + $features_seen[] = $id; + $updated = true; + } } } @@ -177,12 +179,14 @@ class FeatureShowcase_Plugin_Admin { $unseen_count = 0; $features_seen = (array) get_user_meta( $current_user->ID, 'w3tc_features_seen', true ); - $cards = self::get_cards(); + $cards_data = self::get_cards(); // Iterate through the new features and check if already seen. - foreach ( $cards as $id => $card ) { - if ( ! empty( $card['is_new'] ) && ! in_array( $id, $features_seen, true ) ) { - $unseen_count++; + foreach ( $cards_data as $type => $cards ) { + foreach ( $cards as $id => $card ) { + if ( ! empty( $card['is_new'] ) && ! in_array( $id, $features_seen, true ) ) { + $unseen_count++; + } } } @@ -235,273 +239,292 @@ class FeatureShowcase_Plugin_Admin { } return array( - 'defer-scripts' => array( - 'title' => esc_html__( 'Delay Scripts', 'w3-total-cache' ), - 'icon' => 'dashicons-media-code', - 'text' => esc_html__( "Delay the loading of specified internal/external JavaScript sources on your pages separate from Minify.", 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => true, + 'new' => array( + 'preload-requests' => array( + 'title' => esc_html__( 'Preload Requests', 'w3-total-cache' ), + 'icon' => 'dashicons-controls-repeat', + 'text' => esc_html__( 'DNS prefetching, preconnecting, and preloading are essential web optimization techniques that enhance website performance by proactively resolving network-related tasks.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => true, + ), + 'defer-scripts' => array( + 'title' => esc_html__( 'Delay Scripts', 'w3-total-cache' ), + 'icon' => 'dashicons-media-code', + 'text' => esc_html__( 'Delay the loading of specified internal/external JavaScript sources on your pages separate from Minify.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => true, + ), ), - 'pagespeed' => array( - 'title' => esc_html__( 'Google Page Speed', 'w3-total-cache' ), - 'icon' => 'dashicons-analytics', - 'text' => esc_html__( "Adds the ability to analyze the website's homepage and provide a detailed breakdown of performance metrics including potential issues and proposed solutions.", 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => true, - ), - 'lazyload_gmaps' => array( - 'title' => esc_html__( 'Lazy Load Google Maps', 'w3-total-cache' ), - 'icon' => 'dashicons-admin-site', - 'text' => esc_html__( 'Defer loading offscreen Google Maps, making pages load faster.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'cdn_fsd' => array( - 'title' => esc_html__( 'Full Site Delivery via CDN', 'w3-total-cache' ), - 'icon' => 'dashicons-networking', - 'text' => esc_html__( 'Provide the best user experience possible by enhancing by hosting HTML pages and RSS feeds with (supported) CDN\'s high speed global networks.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'render_blocking_css' => array( - 'title' => esc_html__( 'Eliminate Render Blocking CSS', 'w3-total-cache' ), - 'icon' => 'dashicons-table-row-delete', - 'text' => esc_html__( 'Render blocking CSS delays a webpage from being visible in a timely manner. Eliminate this easily with the click of a button in W3 Total Cache Pro.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'extension_framework' => array( - 'title' => esc_html__( 'Extension Framework', 'w3-total-cache' ), - 'icon' => 'dashicons-insert', - 'text' => esc_html__( 'Improve the performance of your Genesis, WPML powered site, and much more. StudioPress\' Genesis Framework is up to 60% faster with W3TC Pro.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'fragment_cache' => array( - 'title' => esc_html__( 'Fragment Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-chart-pie', - 'text' => esc_html__( 'Unlocking the fragment caching module delivers enhanced performance for plugins and themes that use the WordPress Transient API.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'rest_api_cache' => array( - 'title' => esc_html__( 'Rest API Caching', 'w3-total-cache' ), - 'icon' => 'dashicons-embed-generic', - 'text' => esc_html__( 'Save server resources or add scale and performance by caching the WordPress Rest API with W3TC Pro.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'caching_stats' => array( - 'title' => esc_html__( 'Caching Statistics', 'w3-total-cache' ), - 'icon' => 'dashicons-chart-line', - 'text' => esc_html__( 'Analytics for your WordPress and Server cache that allow you to track the size, time and hit/miss ratio of each type of cache, giving you the information needed to gain maximum performance.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'purge_logs' => array( - 'title' => esc_html__( 'Purge Logs', 'w3-total-cache' ), - 'icon' => 'dashicons-search', - 'text' => esc_html__( 'Purge Logs provide information on when your cache has been purged and what triggered it. If you are troubleshooting an issue with your cache being cleared, Purge Logs can tell you why.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => true, - 'is_new' => false, - ), - 'setup_guide' => array( - 'title' => esc_html__( 'Setup Guide Wizard', 'w3-total-cache' ), - 'icon' => 'dashicons-superhero', - 'text' => esc_html__( 'The Setup Guide wizard quickly walks you through configuring W3 Total Cache.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'imageservice' => array( - 'title' => esc_html__( 'WebP Converter', 'w3-total-cache' ), - 'icon' => 'dashicons-embed-photo', - 'text' => esc_html( $imageservice_description ), - 'button' => empty( $imageservice_button_text ) ? '' : - ( '' ), - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'page_cache' => array( - 'title' => esc_html__( 'Page Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-format-aside', - 'text' => esc_html__( 'Page caching decreases the website response time, making pages load faster.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'minify' => array( - 'title' => esc_html__( 'Minify', 'w3-total-cache' ), - 'icon' => 'dashicons-media-text', - 'text' => esc_html__( 'Reduce load time by decreasing the size and number of CSS and JS files.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'lazyload' => array( - 'title' => esc_html__( 'Lazy Load Images', 'w3-total-cache' ), - 'icon' => 'dashicons-format-image', - 'text' => esc_html__( 'Defer loading offscreen images, making pages load faster.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'cdn' => array( - 'title' => esc_html__( 'Content Delivery Network (CDN)', 'w3-total-cache' ), - 'icon' => 'dashicons-format-gallery', - 'text' => esc_html__( 'Host static files with a CDN to reduce page load time.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'opcode_cache' => array( - 'title' => esc_html__( 'Opcode Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-performance', - 'text' => esc_html__( 'Improves PHP performance by storing precompiled script bytecode in shared memory.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'db_cache' => array( - 'title' => esc_html__( 'Database Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-database-view', - 'text' => esc_html__( 'Persistently store data to reduce post, page and feed creation time.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'object_cache' => array( - 'title' => esc_html__( 'Object Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-archive', - 'text' => esc_html__( 'Persistently store objects to reduce execution time for common operations.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'browser_cache' => array( - 'title' => esc_html__( 'Browser Cache', 'w3-total-cache' ), - 'icon' => 'dashicons-welcome-widgets-menus', - 'text' => esc_html__( 'Reduce server load and decrease response time by using the cache available in site visitor\'s web browser.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'extensions' => array( - 'title' => esc_html__( 'Extensions', 'w3-total-cache' ), - 'icon' => 'dashicons-editor-kitchensink', - 'text' => esc_html__( 'Additional features to extend the functionality of W3 Total Cache, such as Accelerated Mobile Pages (AMP) for Minify and support for New Relic.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, - ), - 'cache_groups' => array( - 'title' => esc_html__( 'Cache Groups', 'w3-total-cache' ), - 'icon' => 'dashicons-image-filter', - 'text' => esc_html__( 'Manage cache groups for user agents, referrers, and cookies.', 'w3-total-cache' ), - 'button' => '', - 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', - 'is_premium' => false, - 'is_new' => false, + 'old' => array( + 'lazyload_gmaps' => array( + 'title' => esc_html__( 'Lazy Load Google Maps', 'w3-total-cache' ), + 'icon' => 'dashicons-admin-site', + 'text' => esc_html__( 'Defer loading offscreen Google Maps, making pages load faster.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'cdn_fsd' => array( + 'title' => esc_html__( 'Full Site Delivery via CDN', 'w3-total-cache' ), + 'icon' => 'dashicons-networking', + 'text' => esc_html__( 'Provide the best user experience possible by enhancing by hosting HTML pages and RSS feeds with (supported) CDN\'s high speed global networks.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'render_blocking_css' => array( + 'title' => esc_html__( 'Eliminate Render Blocking CSS', 'w3-total-cache' ), + 'icon' => 'dashicons-table-row-delete', + 'text' => esc_html__( 'Render blocking CSS delays a webpage from being visible in a timely manner. Eliminate this easily with the click of a button in W3 Total Cache Pro.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'extension_framework' => array( + 'title' => esc_html__( 'Extension Framework', 'w3-total-cache' ), + 'icon' => 'dashicons-insert', + 'text' => esc_html__( 'Improve the performance of your Genesis, WPML powered site, and much more. StudioPress\' Genesis Framework is up to 60% faster with W3TC Pro.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'fragment_cache' => array( + 'title' => esc_html__( 'Fragment Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-chart-pie', + 'text' => esc_html__( 'Unlocking the fragment caching module delivers enhanced performance for plugins and themes that use the WordPress Transient API.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'rest_api_cache' => array( + 'title' => esc_html__( 'Rest API Caching', 'w3-total-cache' ), + 'icon' => 'dashicons-embed-generic', + 'text' => esc_html__( 'Save server resources or add scale and performance by caching the WordPress Rest API with W3TC Pro.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'caching_stats' => array( + 'title' => esc_html__( 'Caching Statistics', 'w3-total-cache' ), + 'icon' => 'dashicons-chart-line', + 'text' => esc_html__( 'Analytics for your WordPress and Server cache that allow you to track the size, time and hit/miss ratio of each type of cache, giving you the information needed to gain maximum performance.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'purge_logs' => array( + 'title' => esc_html__( 'Purge Logs', 'w3-total-cache' ), + 'icon' => 'dashicons-search', + 'text' => esc_html__( 'Purge Logs provide information on when your cache has been purged and what triggered it. If you are troubleshooting an issue with your cache being cleared, Purge Logs can tell you why.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => true, + 'is_new' => false, + ), + 'setup_guide' => array( + 'title' => esc_html__( 'Setup Guide Wizard', 'w3-total-cache' ), + 'icon' => 'dashicons-superhero', + 'text' => esc_html__( 'The Setup Guide wizard quickly walks you through configuring W3 Total Cache.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'imageservice' => array( + 'title' => esc_html__( 'WebP Converter', 'w3-total-cache' ), + 'icon' => 'dashicons-embed-photo', + 'text' => esc_html( $imageservice_description ), + 'button' => empty( $imageservice_button_text ) ? '' : + ( '' ), + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'pagespeed' => array( + 'title' => esc_html__( 'Google Page Speed', 'w3-total-cache' ), + 'icon' => 'dashicons-analytics', + 'text' => esc_html__( "Adds the ability to analyze the website's homepage and provide a detailed breakdown of performance metrics including potential issues and proposed solutions.", 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'page_cache' => array( + 'title' => esc_html__( 'Page Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-format-aside', + 'text' => esc_html__( 'Page caching decreases the website response time, making pages load faster.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'minify' => array( + 'title' => esc_html__( 'Minify', 'w3-total-cache' ), + 'icon' => 'dashicons-media-text', + 'text' => esc_html__( 'Reduce load time by decreasing the size and number of CSS and JS files.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'lazyload' => array( + 'title' => esc_html__( 'Lazy Load Images', 'w3-total-cache' ), + 'icon' => 'dashicons-format-image', + 'text' => esc_html__( 'Defer loading offscreen images, making pages load faster.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'cdn' => array( + 'title' => esc_html__( 'Content Delivery Network (CDN)', 'w3-total-cache' ), + 'icon' => 'dashicons-format-gallery', + 'text' => esc_html__( 'Host static files with a CDN to reduce page load time.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'opcode_cache' => array( + 'title' => esc_html__( 'Opcode Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-performance', + 'text' => esc_html__( 'Improves PHP performance by storing precompiled script bytecode in shared memory.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'db_cache' => array( + 'title' => esc_html__( 'Database Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-database-view', + 'text' => esc_html__( 'Persistently store data to reduce post, page and feed creation time.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'object_cache' => array( + 'title' => esc_html__( 'Object Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-archive', + 'text' => esc_html__( 'Persistently store objects to reduce execution time for common operations.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'browser_cache' => array( + 'title' => esc_html__( 'Browser Cache', 'w3-total-cache' ), + 'icon' => 'dashicons-welcome-widgets-menus', + 'text' => esc_html__( 'Reduce server load and decrease response time by using the cache available in site visitor\'s web browser.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'extensions' => array( + 'title' => esc_html__( 'Extensions', 'w3-total-cache' ), + 'icon' => 'dashicons-editor-kitchensink', + 'text' => esc_html__( 'Additional features to extend the functionality of W3 Total Cache, such as Accelerated Mobile Pages (AMP) for Minify and support for New Relic.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), + 'cache_groups' => array( + 'title' => esc_html__( 'Cache Groups', 'w3-total-cache' ), + 'icon' => 'dashicons-image-filter', + 'text' => esc_html__( 'Manage cache groups for user agents, referrers, and cookies.', 'w3-total-cache' ), + 'button' => '', + 'link' => '' . __( 'More info', 'w3-total-cache' ) . '', + 'is_premium' => false, + 'is_new' => false, + ), ), ); } diff --git a/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin_View.php b/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin_View.php index 8a2ab080..6d66ded7 100644 --- a/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin_View.php +++ b/wp-content/plugins/w3-total-cache/FeatureShowcase_Plugin_Admin_View.php @@ -32,44 +32,38 @@ require W3TC_INC_DIR . '/options/common/header.php'; ?>
-
$cards ) { + $class = 'new' === $card_type ? 'w3tc-card-container-new' : 'w3tc-card-container'; -foreach ( $cards as $feature_id => $card ) { - $card_classes = 'w3tc-card'; - $title_classes = 'w3tc-card-title'; - $is_premium = ! empty( $card['is_premium'] ); - $is_new = ! empty( $card['is_new'] ); - - if ( $is_premium ) { - $card_classes .= ' w3tc-card-premium'; - $title_classes .= ' w3tc-card-premium'; - } - - if ( $is_premium && ! $is_pro ) { - $card_classes .= ' w3tc-card-upgrade'; - } - + echo reset( $cards_data ) !== $cards ? '
' : ''; ?> -
+
$card ) { + $card_classes = 'w3tc-card'; + $title_classes = 'w3tc-card-title'; + $is_premium = ! empty( $card['is_premium'] ); + $is_new = ! empty( $card['is_new'] ); + + if ( $is_premium ) { + $card_classes .= ' w3tc-card-premium'; + $title_classes .= ' w3tc-card-premium'; + } + + if ( $is_premium && ! $is_pro ) { + $card_classes .= ' w3tc-card-upgrade'; + } - if ( $is_new ) { ?> -
NEW
- +

- -

- + ' . __( 'PRO FEATURE', 'w3-total-cache' ) . '

'; + } + ?>

@@ -77,21 +71,33 @@ foreach ( $cards as $feature_id => $card ) {
- - ' + . esc_html__( 'Unlock Feature', 'w3-total-cache' ) . ''; } elseif ( ! empty( $card['button'] ) ) { echo $card['button']; } ?>
+ +
+ + + + W3 Total Cache Pro ! + +
+
+ +
-
diff --git a/wp-content/plugins/w3-total-cache/Generic_AdminActions_Default.php b/wp-content/plugins/w3-total-cache/Generic_AdminActions_Default.php index 5633a7bd..b1c16f22 100644 --- a/wp-content/plugins/w3-total-cache/Generic_AdminActions_Default.php +++ b/wp-content/plugins/w3-total-cache/Generic_AdminActions_Default.php @@ -271,6 +271,17 @@ class Generic_AdminActions_Default { $config->set( 'pgcache.enabled', false ); $data['response_errors'][] = 'fancy_permalinks_disabled_pgcache'; } + + /** + * Check for Image Service extension status changes. + */ + if ( $config->get_boolean( 'extension.imageservice' ) !== $this->_config->get_boolean( 'extension.imageservice' ) ) { + if ( $config->get_boolean( 'extension.imageservice' ) ) { + Extensions_Util::activate_extension( 'imageservice', $config ); + } else { + Extensions_Util::deactivate_extension( 'imageservice', $config ); + } + } } /** @@ -558,7 +569,9 @@ class Generic_AdminActions_Default { * * @return bool */ - function enable_cookie_domain() { + public function enable_cookie_domain() { + WP_Filesystem(); + global $wp_filesystem; $config_path = Util_Environment::wp_config_path(); @@ -601,7 +614,9 @@ class Generic_AdminActions_Default { * * @return bool */ - function disable_cookie_domain() { + public function disable_cookie_domain() { + WP_Filesystem(); + global $wp_filesystem; $config_path = Util_Environment::wp_config_path(); diff --git a/wp-content/plugins/w3-total-cache/Generic_AdminActions_Flush.php b/wp-content/plugins/w3-total-cache/Generic_AdminActions_Flush.php index c6b2c9e2..2ec8d5fe 100644 --- a/wp-content/plugins/w3-total-cache/Generic_AdminActions_Flush.php +++ b/wp-content/plugins/w3-total-cache/Generic_AdminActions_Flush.php @@ -17,6 +17,12 @@ class Generic_AdminActions_Flush { */ function w3tc_flush_all() { w3tc_flush_all( array( 'ui_action' => 'flush_button' ) ); + + $state_note = Dispatcher::config_state_note(); + $state_note->set( 'common.show_note.flush_statics_needed', false ); + $state_note->set( 'common.show_note.flush_posts_needed', false ); + $state_note->set( 'common.show_note.plugins_updated', false ); + $this->_redirect_after_flush( 'flush_all' ); } diff --git a/wp-content/plugins/w3-total-cache/Generic_Plugin.php b/wp-content/plugins/w3-total-cache/Generic_Plugin.php index 9f1ed212..ca1b54e6 100644 --- a/wp-content/plugins/w3-total-cache/Generic_Plugin.php +++ b/wp-content/plugins/w3-total-cache/Generic_Plugin.php @@ -254,6 +254,28 @@ class Generic_Plugin { ), ); + // Add menu item to flush all cached except Bunny CDN. + if ( + 0 && // @todo Revisit this item. + Cdn_BunnyCdn_Page::is_active() && ( + $modules->can_empty_memcache() + || $modules->can_empty_opcode() + || $modules->can_empty_file() + || $modules->can_empty_varnish() + ) + ) { + $menu_items['10012.generic'] = array( + 'id' => 'w3tc_flush_all_except_bunnycdn', + 'parent' => 'w3tc', + 'title' => __( 'Purge All Caches Except Bunny CDN', 'w3-total-cache' ), + 'href' => wp_nonce_url( + network_admin_url( 'admin.php?page=w3tc_dashboard&w3tc_bunnycdn_flush_all_except_bunnycdn' ), + 'w3tc' + ), + ); + } + + // Add menu item to flush all cached except Cloudflare. if ( ! empty( $this->_config->get_string( array( 'cloudflare', 'email' ) ) ) && ! empty( $this->_config->get_string( array( 'cloudflare', 'key' ) ) ) @@ -523,6 +545,7 @@ class Generic_Plugin { array( 'swarmify', 'lazyload', + 'deferscripts', 'minify', 'newrelic', 'cdn', diff --git a/wp-content/plugins/w3-total-cache/Generic_Plugin_Admin.php b/wp-content/plugins/w3-total-cache/Generic_Plugin_Admin.php index 6cf042dc..1a03d4ab 100644 --- a/wp-content/plugins/w3-total-cache/Generic_Plugin_Admin.php +++ b/wp-content/plugins/w3-total-cache/Generic_Plugin_Admin.php @@ -171,9 +171,7 @@ class Generic_Plugin_Admin { } /** - * Admin init - * - * @return void + * Admin init. */ public function admin_init() { // Special handling for deactivation link, it's plugins.php file. @@ -181,176 +179,121 @@ class Generic_Plugin_Admin { Util_Activation::deactivate_plugin(); } - // These have been moved here as the admin_print_scripts-{$suffix} hook with translations won't take the user locale setting - // into account if it's called too soon, resulting in JS not loading. - - // Translations are needed as the "prefix" used is based on the menu/page title, which is translated (11+ year old WP bug). + /** + * These have been moved here as the admin_print_scripts-{$suffix} hook with translations won't take the user locale setting + * into account if it's called too soon, resulting in JS not loading. + * + * Translations are needed as the "prefix" used is based on the menu/page title, which is translated (11+ year old WP bug). + */ // Support page. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_support', - array( - '\W3TC\Support_Page', - 'admin_print_scripts_w3tc_support', - ) + array( '\W3TC\Support_Page', 'admin_print_scripts_w3tc_support' ) ); // Minify. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_general', - array( - '\W3TC\Minify_Plugin_Admin', - 'admin_print_scripts_w3tc_general', - ) + array( '\W3TC\Minify_Plugin_Admin', 'admin_print_scripts_w3tc_general' ) ); // PageCache. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_pgcache', - array( - '\W3TC\PgCache_Page', - 'admin_print_scripts_w3tc_pgcache', - ) + array( '\W3TC\PgCache_Page', 'admin_print_scripts_w3tc_pgcache' ) ); // Extensions. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_extensions', - array( - '\W3TC\Extension_CloudFlare_Page', - 'admin_print_scripts_w3tc_extensions', - ) + array( '\W3TC\Extension_CloudFlare_Page', 'admin_print_scripts_performance_page_w3tc_cdn' ) ); // Usage Statistics. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_stats', - array( - '\W3TC\UsageStatistics_Page', - 'admin_print_scripts_w3tc_stats', - ) + array( '\W3TC\UsageStatistics_Page', 'admin_print_scripts_w3tc_stats' ) ); - $c = Dispatcher::config(); - $cdn_engine = $c->get_string( 'cdn.engine' ); - $cdnfsd_engine = $c->get_string( 'cdnfsd.engine' ); + $c = Dispatcher::config(); // CDN. - if ( 'google_drive' === $cdn_engine ) { + switch ( $c->get_string( 'cdn.engine' ) ) { + case 'bunnycdn': + $cdn_class = '\W3TC\Cdn_BunnyCdn_Page'; + break; + case 'google_drive': + $cdn_class = '\W3TC\Cdn_GoogleDrive_Page'; + break; + case 'highwinds': + $cdn_class = '\W3TC\Cdn_Highwinds_Page'; + break; + case 'limelight': + $cdn_class = '\W3TC\Cdn_LimeLight_Page'; + break; + case 'rackspace_cdn': + $cdn_class = '\W3TC\Cdn_RackSpaceCdn_Page'; + break; + case 'rscf': + $cdn_class = '\W3TC\Cdn_RackSpaceCloudFiles_Page'; + break; + case 'stackpath': + $cdn_class = '\W3TC\Cdn_StackPath_Page'; + break; + case 'stackpath2': + $cdn_class = '\W3TC\Cdn_StackPath2_Page'; + break; + default: + break; + } + + if ( ! empty( $cdn_class ) ) { add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_GoogleDrive_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'highwinds' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_Highwinds_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'limelight' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_LimeLight_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'rackspace_cdn' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_RackSpaceCdn_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'rscf' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_RackSpaceCloudFiles_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'stackpath' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_StackPath_Page', - 'admin_print_scripts_w3tc_cdn', - ) - ); - } elseif ( 'stackpath2' === $cdn_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdn_StackPath2_Page', - 'admin_print_scripts_w3tc_cdn', - ) + array( $cdn_class, 'admin_print_scripts_w3tc_cdn' ) ); } // CDNFSD. - if ( 'cloudflare' === $cdnfsd_engine ) { + switch ( $c->get_string( 'cdnfsd.engine' ) ) { + case 'bunnycdn': + $cdnfsd_class = '\W3TC\Cdnfsd_BunnyCdn_Page'; + break; + case 'cloudflare': + $cdnfsd_class = '\W3TC\Extension_CloudFlare_Page'; + break; + case 'cloudfront': + $cdnfsd_class = '\W3TC\Cdnfsd_CloudFront_Page'; + break; + case 'limelight': + $cdnfsd_class = '\W3TC\Cdnfsd_LimeLight_Page'; + break; + case 'stackpath': + $cdnfsd_class = '\W3TC\Cdnfsd_StackPath_Page'; + break; + case 'stackpath2': + $cdnfsd_class = '\W3TC\Cdnfsd_StackPath2_Page'; + break; + default: + break; + } + + if ( ! empty( $cdnfsd_class ) ) { add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Extension_CloudFlare_Page', - 'admin_print_scripts_w3tc_extensions', - ) - ); - } elseif ( 'cloudfront' === $cdnfsd_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdnfsd_CloudFront_Page', - 'admin_print_scripts_performance_page_w3tc_cdn', - ) - ); - } elseif ( 'limelight' === $cdnfsd_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdnfsd_LimeLight_Page', - 'admin_print_scripts_performance_page_w3tc_cdn', - ) - ); - } elseif ( 'stackpath' === $cdnfsd_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdnfsd_StackPath_Page', - 'admin_print_scripts_performance_page_w3tc_cdn', - ) - ); - } elseif ( 'stackpath2' === $cdnfsd_engine ) { - add_action( - 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn', - array( - '\W3TC\Cdnfsd_StackPath2_Page', - 'admin_print_scripts_performance_page_w3tc_cdn', - ) + array( $cdnfsd_class, 'admin_print_scripts_performance_page_w3tc_cdn' ) ); } // PageSpeed page/widget. add_action( 'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_pagespeed', - array( - '\W3TC\PageSpeed_Page', - 'admin_print_scripts_w3tc_pagespeed', - ) + array( '\W3TC\PageSpeed_Page', 'admin_print_scripts_w3tc_pagespeed' ) ); add_action( 'admin_print_scripts-toplevel_page_w3tc_dashboard', - array( - '\W3TC\PageSpeed_Widget', - 'admin_print_scripts_w3tc_pagespeed_widget', - ) + array( '\W3TC\PageSpeed_Widget', 'admin_print_scripts_w3tc_pagespeed_widget' ) ); $page_val = Util_Request::get_string( 'page' ); @@ -380,9 +323,7 @@ class Generic_Plugin_Admin { wp_localize_script( 'w3tc-feature-counter', 'W3TCFeatureShowcaseData', - array( - 'unseenCount' => FeatureShowcase_Plugin_Admin::get_unseen_count(), - ) + array( 'unseenCount' => FeatureShowcase_Plugin_Admin::get_unseen_count() ) ); wp_enqueue_script( 'w3tc-feature-counter' ); @@ -645,6 +586,8 @@ class Generic_Plugin_Admin { 'cdn.flush_manually', Cdn_Util::get_flush_manually_default_override( $this->_config->get_string( 'cdn.engine' ) ) ), + 'cdnfsdEnabled' => $this->_config->get_boolean( 'cdnfsd.enabled' ), + 'cdnfsdEngine' => $this->_config->get_string( 'cdnfsd.engine' ), 'cfWarning' => wp_kses( sprintf( // translators: 1: HTML opening a tag to docs.aws.amazon.com for invalidation payments, 2: HTML closing a tag followed by HTML line break tag, @@ -667,6 +610,10 @@ class Generic_Plugin_Admin { 'br' => array(), ) ), + 'bunnyCdnWarning' => esc_html__( + 'Bunny CDN should only be enabled as either a CDN for objects or full-site delivery, not both at the same time. The CDN settings have been reverted.', + 'w3-total-cache' + ), ) ); } diff --git a/wp-content/plugins/w3-total-cache/ModuleStatus.php b/wp-content/plugins/w3-total-cache/ModuleStatus.php index 528d64b4..3bd85764 100644 --- a/wp-content/plugins/w3-total-cache/ModuleStatus.php +++ b/wp-content/plugins/w3-total-cache/ModuleStatus.php @@ -31,6 +31,7 @@ class ModuleStatus { || $this->is_enabled( 'objectcache' ) || $this->is_enabled( 'browsercache' ) || $this->is_enabled( 'cdn' ) + || $this->is_enabled( 'cdnfsd' ) || $this->is_enabled( 'varnish' ) || $this->is_enabled( 'newrelic' ) || $this->is_enabled( 'fragmentcache' ); diff --git a/wp-content/plugins/w3-total-cache/PageSpeed_Widget.php b/wp-content/plugins/w3-total-cache/PageSpeed_Widget.php index 9aacff34..eda71b59 100644 --- a/wp-content/plugins/w3-total-cache/PageSpeed_Widget.php +++ b/wp-content/plugins/w3-total-cache/PageSpeed_Widget.php @@ -77,7 +77,7 @@ class PageSpeed_Widget { '' . '
' . esc_html__( 'PageSpeed Report', 'w3-total-cache' ) . '
', array( $this, 'widget_pagespeed' ), - Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_page_speed' ), + Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_pagespeed' ), 'normal' ); } diff --git a/wp-content/plugins/w3-total-cache/UserExperience_DeferScripts_Extension.php b/wp-content/plugins/w3-total-cache/UserExperience_DeferScripts_Extension.php index c54f199c..3de33557 100644 --- a/wp-content/plugins/w3-total-cache/UserExperience_DeferScripts_Extension.php +++ b/wp-content/plugins/w3-total-cache/UserExperience_DeferScripts_Extension.php @@ -53,7 +53,7 @@ class UserExperience_DeferScripts_Extension { return; } - Util_Bus::add_ob_callback( 'lazyload', array( $this, 'ob_callback' ) ); + Util_Bus::add_ob_callback( 'deferscripts', array( $this, 'ob_callback' ) ); add_filter( 'w3tc_minify_js_script_tags', array( $this, 'w3tc_minify_js_script_tags' ) ); add_filter( 'w3tc_save_options', array( $this, 'w3tc_save_options' ) ); @@ -289,6 +289,19 @@ class UserExperience_DeferScripts_Extension { return $data; } + + /** + * Gets the enabled status of the extension. + * + * @since 2.5.1 + * + * @return bool + */ + public static function is_enabled() { + $config = Dispatcher::config(); + $extensions_active = $config->get_array( 'extensions.active' ); + return Util_Environment::is_w3tc_pro( $config ) && array_key_exists( 'user-experience-defer-scripts', $extensions_active ); + } } $o = new UserExperience_DeferScripts_Extension(); diff --git a/wp-content/plugins/w3-total-cache/UserExperience_GeneralPage_View.php b/wp-content/plugins/w3-total-cache/UserExperience_GeneralPage_View.php index 6ae6d205..7c38f5e6 100644 --- a/wp-content/plugins/w3-total-cache/UserExperience_GeneralPage_View.php +++ b/wp-content/plugins/w3-total-cache/UserExperience_GeneralPage_View.php @@ -90,10 +90,10 @@ Util_Ui::config_overloading_button( array( 'key' => 'lazyload.configuration_over 'extension_id' => 'user-experience-defer-scripts', 'checkbox_label' => esc_html__( 'Delay Scripts', 'w3-total-cache' ), 'description' => __( - 'Delay the loading of specified interal/external JavaScript sources on your pages separate from Minify. For best results it is recommended to enable the Minify feature to optimize internal sources and to then use the Delay JavaScript feature to handle external sources and/or any internal sources excluded from Minify.', + 'Delay the loading of specified interal/external JavaScript sources on your pages separate from Minify.', 'w3-total-cache' ) . ( - Util_Environment::is_w3tc_pro( $config ) && $config->is_extension_active( 'user-experience-defer-scripts' ) + UserExperience_DeferScripts_Extension::is_enabled() ? wp_kses( sprintf( // translators: 1 opening HTML a tag to W3TC User Experience page, 2 closing HTML a tag. @@ -118,6 +118,39 @@ Util_Ui::config_overloading_button( array( 'key' => 'lazyload.configuration_over ) ); + Util_Ui::config_item_extension_enabled( + array( + 'extension_id' => 'user-experience-preload-requests', + 'checkbox_label' => esc_html__( 'Preload Requests', 'w3-total-cache' ), + 'description' => __( + 'DNS prefetching, preconnecting, and preloading are essential web optimization techniques that enhance website performance by proactively resolving network-related tasks.', + 'w3-total-cache' + ) . ( + UserExperience_Preload_Requests_Extension::is_enabled() + ? wp_kses( + sprintf( + // translators: 1 opening HTML a tag to W3TC User Experience page, 2 closing HTML a tag. + __( + ' Settings can be found on the %1$sUser Experience page%2$s.', + 'w3-total-cache' + ), + '', + '' + ), + array( + 'a' => array( + 'href' => array(), + ), + ) + ) + : '' + ), + 'label_class' => 'w3tc_single_column', + 'pro' => true, + 'disabled' => ! Util_Environment::is_w3tc_pro( $config ) ? true : false, + ) + ); + Util_Ui::config_item_extension_enabled( array( 'extension_id' => 'user-experience-oembed', diff --git a/wp-content/plugins/w3-total-cache/UserExperience_Plugin_Admin.php b/wp-content/plugins/w3-total-cache/UserExperience_Plugin_Admin.php index 977e114e..2eb3e5b6 100644 --- a/wp-content/plugins/w3-total-cache/UserExperience_Plugin_Admin.php +++ b/wp-content/plugins/w3-total-cache/UserExperience_Plugin_Admin.php @@ -46,6 +46,11 @@ class UserExperience_Plugin_Admin { 'extension_id' => 'user-experience-defer-scripts', 'path' => 'w3-total-cache/UserExperience_DeferScripts_Extension.php', ); + $extensions['user-experience-preload-requests'] = array( + 'public' => false, + 'extension_id' => 'user-experience-preload-requests', + 'path' => 'w3-total-cache/UserExperience_Preload_Requests_Extension.php', + ); $extensions['user-experience-emoji'] = array( 'public' => false, 'extension_id' => 'user-experience-emoji', diff --git a/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Extension.php b/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Extension.php new file mode 100644 index 00000000..200efee4 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Extension.php @@ -0,0 +1,203 @@ +config = Dispatcher::config(); + } + + /** + * Runs User Experience DNS Prefetc feature. + * + * @since 2.5.1 + * + * @return void + */ + public function run() { + if ( ! Util_Environment::is_w3tc_pro( $this->config ) ) { + $this->config->set_extension_active_frontend( 'user-experience-preload-requests', false ); + return; + } + + // Applies logic to display page cache flush notice if Preload Requests settings are altered and saved. + add_filter( 'w3tc_save_options', array( $this, 'w3tc_save_options' ) ); + + // Renders the Preload Reqeusts settings metabox on the User Expereince advanced setting page. + add_action( 'w3tc_userexperience_page', array( $this, 'w3tc_userexperience_page' ) ); + + // This filter is documented in Generic_AdminActions_Default.php under the read_request method. + add_filter( 'w3tc_config_key_descriptor', array( $this, 'w3tc_config_key_descriptor' ), 10, 2 ); + + // Applies dns-prefetch, preconnect, and preload headers. + add_action( 'wp_head', array( $this, 'w3tc_preload_requests_headers' ) ); + add_action( 'admin_head', array( $this, 'w3tc_preload_requests_headers' ) ); + } + + /** + * Renders the user experience Preload Requests settings page. + * + * @since 2.5.1 + * + * @return void + */ + public function w3tc_userexperience_page() { + include __DIR__ . '/UserExperience_Preload_Requests_Page_View.php'; + } + + /** + * Specify config key typing for fields that need it. + * + * @since 2.5.1 + * + * @param mixed $descriptor Descriptor. + * @param mixed $key Compound key array. + * + * @return array + */ + public function w3tc_config_key_descriptor( $descriptor, $key ) { + if ( + is_array( $key ) + && in_array( + implode( '.', $key ), + array( + 'user-experience-preload-requests.dns-prefetch', + 'user-experience-preload-requests.preconnect', + 'user-experience-preload-requests.preload-css', + 'user-experience-preload-requests.preload-js', + 'user-experience-preload-requests.preload-fonts', + 'user-experience-preload-requests.preload-images', + 'user-experience-preload-requests.preload-videos', + 'user-experience-preload-requests.preload-audio', + 'user-experience-preload-requests.preload-documents', + ) + ) + ) { + $descriptor = array( 'type' => 'array' ); + } + + return $descriptor; + } + + /** + * Performs actions on save. + * + * @since 2.5.1 + * + * @param array $data Array of save data. + * + * @return array + */ + public function w3tc_save_options( $data ) { + $new_config = $data['new_config']; + $old_config = $data['old_config']; + + $new_includes = $new_config->get_array( array( 'user-experience-preload-requests', 'includes' ) ); + $old_includes = $old_config->get_array( array( 'user-experience-preload-requests', 'includes' ) ); + + if ( $new_includes !== $old_includes && $this->config->get_boolean( 'pgcache.enabled' ) ) { + $state = Dispatcher::config_state(); + $state->set( 'common.show_note.flush_posts_needed', true ); + $state->save(); + } + + return $data; + } + + /** + * Applies the Preload Requests headers for wp_head and admin_head. + * + * @since 2.5.1 + * + * @return void + */ + public function w3tc_preload_requests_headers() { + // Preconnect hints should be printed first so they take priority. If not supported then dns-prefetch will be the fallback. + $preconnect = $this->config->get_array( array( 'user-experience-preload-requests', 'preconnect' ) ); + foreach ( $preconnect as $url ) { + echo ''; + } + + $dns_prefetch = $this->config->get_array( array( 'user-experience-preload-requests', 'dns-prefetch' ) ); + foreach ( $dns_prefetch as $url ) { + echo ''; + } + + $preload_css = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-css' ) ); + foreach ( $preload_css as $url ) { + echo ''; + } + + $preload_js = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-js' ) ); + foreach ( $preload_js as $url ) { + echo ''; + } + + $preload_fonts = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-fonts' ) ); + foreach ( $preload_fonts as $url ) { + echo ''; + } + + $preload_images = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-images' ) ); + foreach ( $preload_images as $url ) { + echo ''; + } + + $preload_videos = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-videos' ) ); + foreach ( $preload_videos as $url ) { + echo ''; + } + + $preload_audio = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-audio' ) ); + foreach ( $preload_audio as $url ) { + echo ''; + } + + $preload_documents = $this->config->get_array( array( 'user-experience-preload-requests', 'preload-documents' ) ); + foreach ( $preload_documents as $url ) { + echo ''; + } + } + + /** + * Gets the enabled status of the extension. + * + * @since 2.5.1 + * + * @return bool + */ + public static function is_enabled() { + $config = Dispatcher::config(); + $extensions_active = $config->get_array( 'extensions.active' ); + return Util_Environment::is_w3tc_pro( $config ) && array_key_exists( 'user-experience-preload-requests', $extensions_active ); + } +} + +$o = new UserExperience_Preload_Requests_Extension(); +$o->run(); diff --git a/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Page_View.php b/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Page_View.php new file mode 100644 index 00000000..a3e70154 --- /dev/null +++ b/wp-content/plugins/w3-total-cache/UserExperience_Preload_Requests_Page_View.php @@ -0,0 +1,102 @@ + + +

+

+

+ + array( 'user-experience-preload-requests', 'dns-prefetch' ), + 'label' => esc_html__( 'DNS Prefetch Domains:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify domains whose DNS should be prefetched by browsers. Include one entry per line, e.g. (https://cdn.domain.com, https://fonts.googleapis.com, https://www.google-ananlytics.com, etc.)', 'w3-total-cache' ), + ) + ); + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preconnect' ), + 'label' => esc_html__( 'Preconnect Domains:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify domains that browsers should preconnect to. Include one entry per line, e.g. (https://cdn.domain.com, https://fonts.googleapis.com, https://www.google-ananlytics.com, etc.)', 'w3-total-cache' ), + ) + ); + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-css' ), + 'label' => esc_html__( 'Preload CSS:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key CSS URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.css, etc.)', 'w3-total-cache' ), + ) + ); + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-js' ), + 'label' => esc_html__( 'Preload JavaScript:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key JavaScript URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.js, etc.)', 'w3-total-cache' ), + ) + ); + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-fonts' ), + 'label' => esc_html__( 'Preload Fonts:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key Font URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.woff, etc.)', 'w3-total-cache' ), + ) + ); + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-images' ), + 'label' => esc_html__( 'Preload Images:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key Image URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.png, etc.)', 'w3-total-cache' ), + ) + ); + + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-videos' ), + 'label' => esc_html__( 'Preload Videos:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key Video URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.mp4, etc.)', 'w3-total-cache' ), + ) + ); + + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-audio' ), + 'label' => esc_html__( 'Prelaod Audio:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key Audio URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.mp3, etc.)', 'w3-total-cache' ), + ) + ); + + Util_Ui::config_item( + array( + 'key' => array( 'user-experience-preload-requests', 'preload-documents' ), + 'label' => esc_html__( 'Preload Documents:', 'w3-total-cache' ), + 'control' => 'textarea', + 'description' => esc_html__( 'Specify key Document URLs that should be preloaded by browsers. Include one entry per line, e.g. (https://example.com/example.pdf, etc.)', 'w3-total-cache' ), + ) + ); + ?> +
+ diff --git a/wp-content/plugins/w3-total-cache/Util_Ui.php b/wp-content/plugins/w3-total-cache/Util_Ui.php index 7e49b4c0..4d56aa34 100644 --- a/wp-content/plugins/w3-total-cache/Util_Ui.php +++ b/wp-content/plugins/w3-total-cache/Util_Ui.php @@ -209,7 +209,7 @@ class Util_Ui { $description = ( ! empty( $description ) ) ? '
' . wp_kses( $description, self::get_allowed_html_for_wp_kses_from_content( $description ) ) . '
' : ''; $basic_settings_tab = ( ! empty( $adv_link ) ) ? '' . esc_html__( 'Basic Settings', 'w3-total-cache' ) . '' : ''; $adv_settings_tab = ( ! empty( $adv_link ) ) ? '' . esc_html__( 'Advanced Settings', 'w3-total-cache' ) . '' : ''; - + $extra_link_tabs = ''; foreach ( $extra_links as $extra_link_text => $extra_link ) { $extra_link_tabs .= '' . esc_html( $extra_link_text ) . ''; @@ -372,8 +372,10 @@ class Util_Ui { if ( $config->getf_boolean( 'objectcache.enabled' ) ) { echo ''; } - if ( $config->get_boolean( 'cdn.enabled' ) ) { - $disable = $config->get_boolean( 'cdn.enabled' ) && Cdn_Util::can_purge_all( $config->get_string( 'cdn.engine' ) ) ? '' : ' disabled="disabled" '; + if ( $config->get_boolean( 'cdn.enabled' ) || $config->get_boolean( 'cdnfsd.enabled' ) ) { + $disable = ( $config->get_boolean( 'cdn.enabled' ) && Cdn_Util::can_purge_all( $config->get_string( 'cdn.engine' ) ) ) || + ( $config->get_boolean( 'cdnfsd.enabled' ) && Cdn_Util::can_purge_all( $config->get_string( 'cdnfsd.engine' ) ) ) ? + '' : ' disabled="disabled" '; echo ''; } if ( $config->is_extension_active_frontend( 'fragmentcache' ) && Util_Environment::is_w3tc_pro( $config ) && ! empty( $config->get_string( array( 'fragmentcache', 'engine' ) ) ) ) { @@ -1443,10 +1445,15 @@ class Util_Ui { } /** - * Returns option name accepted by W3TC as http paramter - * from it's id (full name from config file) + * Returns option name accepted by W3TC as http paramter from its id (full name from config file). + * + * @param mixed $id ID key string/array. + * + * @return string */ public static function config_key_to_http_name( $id ) { + $id = isset( $id ) ? $id : ''; + if ( is_array( $id ) ) { $id = $id[0] . '___' . $id[1]; } @@ -1518,6 +1525,7 @@ class Util_Ui { $config = Dispatcher::config(); $state = Dispatcher::config_state(); $page = Util_Admin::get_current_page(); + $show_purge_link = 'bunnycdn' === $config->get_string( 'cdn.engine' ) || 'bunnycdn' === $config->get_string( 'cdnfsd.engine' ); $licensing_visible = ( ( ! Util_Environment::is_wpmu() || is_network_admin() ) && ! ini_get( 'w3tc.license_key' ) && @@ -1827,7 +1835,15 @@ class Util_Ui { ?>
| - | + get_string( 'cdn.engine' ) ) ) : ?> + | + + get_string( 'cdnfsd.engine' ) ) ) : ?> + | + + + | + |
@@ -1838,14 +1854,18 @@ class Util_Ui { ?>
get_array( 'extensions.active' ); - if ( array_key_exists( 'user-experience-defer-scripts', $extensions_active ) ) { - // If more items are added this will only encompase the Defer Scripts, but if only 1 item show no sub-nav. - ?> - | - - ' . esc_html__( 'Lazy Loading', 'w3-total-cache' ) . '' ); + + if ( UserExperience_DeferScripts_Extension::is_enabled() ) { + $subnav_links[] = '' . esc_html__( 'Delay Scripts', 'w3-total-cache' ) . ''; } + + if ( UserExperience_Preload_Requests_Extension::is_enabled() ) { + $subnav_links[] = '' . esc_html__( 'Preload Requests', 'w3-total-cache' ) . ''; + } + + // If there's only 1 meta box on the page, no need for nav links. + echo count( $subnav_links ) > 1 ? implode( ' | ', $subnav_links ) : ''; ?>
+?>

' . Cache::engine_name( $this->_config->get_string( 'cdn.engine' ) ) . '', - '' . esc_html__( 'enabled', 'w3-total-cache' ) : 'disabled">' . esc_html__( 'disabled', 'w3-total-cache' ) ) . '' + '' . esc_html__( 'enabled', 'w3-total-cache' ) : 'disabled">' . esc_html__( 'disabled', 'w3-total-cache' ) ) . '', + '' . esc_html__( 'authorized', 'w3-total-cache' ) : 'not-authorized">' . esc_html__( 'not authorized', 'w3-total-cache' ) ) . '' + ), + array( + 'strong' => array(), + 'span' => array( + 'class' => array(), + ), + ) + ); + ?> +

+

+ ' . Cache::engine_name( $this->_config->get_string( 'cdnfsd.engine' ) ) . '', + '' . esc_html__( 'enabled', 'w3-total-cache' ) : 'disabled">' . esc_html__( 'disabled', 'w3-total-cache' ) ) . '', + '' . esc_html__( 'authorized', 'w3-total-cache' ) : 'not-authorized">' . esc_html__( 'not authorized', 'w3-total-cache' ) ) . '' ), array( 'strong' => array(), @@ -42,46 +63,89 @@ require W3TC_INC_DIR . '/options/common/header.php'; ?>

- -

- Maximize CDN usage by or - -

-

objects from the CDN' : ''; - $cdn_mirror_purge_button = $cdn_mirror_purge_all ? ( $can_purge ? ' or ' : '' ) . '' : ''; - echo $cdn_purge_button . $cdn_mirror_purge_button; + echo wp_kses( + sprintf( + // translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag. + __( + 'Maximize %1$sCDN%2$s usage by %3$s or %4$s.', + 'w3-total-cache' + ), + '', + '', + '', + '' + ), + array( + 'acronym' => array( + 'title' => array(), + ), + ) + ); ?>

- +

+ objects from the CDN' : + ''; + $cdn_mirror_purge_button = $cdn_mirror_purge_all ? + ( $can_purge ? ' or ' : '' ) . '' : + ''; + + echo wp_kses( + $cdn_purge_button . $cdn_mirror_purge_button, + array( + 'acronym' => array( + 'title' => array(), + ), + 'input' => array( + 'class' => array(), + 'id' => array(), + 'name' => array(), + 'type' => array(), + 'value' => array(), + ), + ) + ); + ?> +

+ ', + '' ), - '', - '' - ), - array( - 'acronym' => array( - 'title' => array(), - ), - ) - ); - ?> - . - Check - - + array( + 'acronym' => array( + 'title' => array(), + ), + ) + ); + ?> + . + Check + + + - - - + + + +

- - - - -
- - + + + + +
+ + + + diff --git a/wp-content/plugins/w3-total-cache/inc/options/cdn/azure.php b/wp-content/plugins/w3-total-cache/inc/options/cdn/azure.php index 3d8e280d..4fef3299 100644 --- a/wp-content/plugins/w3-total-cache/inc/options/cdn/azure.php +++ b/wp-content/plugins/w3-total-cache/inc/options/cdn/azure.php @@ -97,7 +97,7 @@ if ( ! defined( 'W3TC' ) ) { sprintf( // translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag. __( - 'or %1$sCNAME%2$s:', + ' or %1$sCNAME%2$s:', 'w3-total-cache' ), '', diff --git a/wp-content/plugins/w3-total-cache/inc/options/common/footer.php b/wp-content/plugins/w3-total-cache/inc/options/common/footer.php index 9a94c53b..538ac042 100644 --- a/wp-content/plugins/w3-total-cache/inc/options/common/footer.php +++ b/wp-content/plugins/w3-total-cache/inc/options/common/footer.php @@ -70,6 +70,9 @@ do_action( 'w3tc-dashboard-footer' ); + + +
promise()->wait(); } @@ -379,7 +379,7 @@ class ServiceRestProxy extends RestProxy } /** - * Throws ServiceException if the recieved status code is not expected. + * Throws ServiceException if the received status code is not expected. * * @param string $actual The received status code. * @param string $reason The reason phrase. diff --git a/wp-content/plugins/w3-total-cache/lib/Minify/Minify/Cache/File.php b/wp-content/plugins/w3-total-cache/lib/Minify/Minify/Cache/File.php index 2741ce1e..d1e81a2a 100644 --- a/wp-content/plugins/w3-total-cache/lib/Minify/Minify/Cache/File.php +++ b/wp-content/plugins/w3-total-cache/lib/Minify/Minify/Cache/File.php @@ -132,17 +132,19 @@ class Minify_Cache_File { * * @param string $id cache id (e.g. a filename) * - * @return string + * @return string|false */ public function fetch($id) { $path = $this->_path . '/' . $id; $data = @file_get_contents($path . '_meta'); - if ($data) { + if ( ! empty( $data ) ) { $data = @unserialize($data); if (!is_array($data)) $data = array(); + } else { + $data = array(); } if (is_readable($path)) { diff --git a/wp-content/plugins/w3-total-cache/lib/OAuth/W3tcOAuth.php b/wp-content/plugins/w3-total-cache/lib/OAuth/W3tcOAuth.php index 09f2b986..19c0900f 100644 --- a/wp-content/plugins/w3-total-cache/lib/OAuth/W3tcOAuth.php +++ b/wp-content/plugins/w3-total-cache/lib/OAuth/W3tcOAuth.php @@ -589,7 +589,7 @@ class W3tcOAuthUtil { $value = isset($split[1]) ? W3tcOAuthUtil::urldecode_rfc3986($split[1]) : ''; if (isset($parsed_parameters[$parameter])) { - // We have already recieved parameter(s) with this name, so add to the list + // We have already received parameter(s) with this name, so add to the list // of parameters with this name if (is_scalar($parsed_parameters[$parameter])) { diff --git a/wp-content/plugins/w3-total-cache/pub/css/feature-showcase.css b/wp-content/plugins/w3-total-cache/pub/css/feature-showcase.css index 81d1ed95..cc20cc67 100644 --- a/wp-content/plugins/w3-total-cache/pub/css/feature-showcase.css +++ b/wp-content/plugins/w3-total-cache/pub/css/feature-showcase.css @@ -8,18 +8,35 @@ .w3tc-card-container { grid-template-columns: 1fr; } + .w3tc-card-container-new { + grid-template-columns: 1fr; + row-gap: 2em; + } +} + +@media screen and (min-width: 560px) { + .w3tc-card-container-new { + grid-template-columns: repeat(auto-fit, minmax(275px, .4fr)); + grid-gap: 3em 4%; + } } @media screen and (min-width: 900px) { .w3tc-card-container { grid-template-columns: 1fr 1fr 1fr; } + .w3tc-card-container-new { + grid-gap: 3.75em 5%; + } } @media screen and (min-width: 1400px) { .w3tc-card-container { grid-template-columns: 1fr 1fr 1fr 1fr; } + .w3tc-card-container-new { + grid-gap: 6em 7%; + } } .w3tc-page-container { @@ -32,11 +49,55 @@ width: 100%; } +.w3tc-card-container-divider { + border-top-color: #CFCFD0; +} + .w3tc-card-container { display: grid; grid-gap: 2em; } +.w3tc-card-container-new { + display: grid; + justify-content: center; +} + +.w3tc-card-container, +.w3tc-card-container-new { + margin-top: 5em; + margin-bottom: 5em; +} + +.w3tc-card-container-title { + text-align: center; + font-weight: 600 !important; + font-size: 30px !important; + margin: 10px 0 1em !important; + box-shadow: 0 1px 1px -1px #888; + background: #fff; + background-image: none; + background-image: none; + padding: 33px 10px !important; + background-image: linear-gradient( to right, #f9f9f9, #f9f9f9, #f9f9f9, #f0f0f0, #e7f3f3, #56bec1, #16252c); + position: relative; + padding-right: 280px; + border: 1px solid #c3c4c7; +} + +.w3tc-card-container-title::after { + background-image: url("../img/transparent-comet.png"); + background-repeat: no-repeat; + background-position: top right; + background-size: 100% 100%; + content: ""; + width: 251px; + height: 104px; + position: absolute; + top: 0; + right: 0; +} + .w3tc-card { background: #fff; border: 1px solid #ddd; @@ -45,6 +106,11 @@ position: relative; } +.w3tc-card-container-new .w3tc-card { + box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;; + border: none; +} + .w3tc-card-title { height: 2.5em; } @@ -104,61 +170,18 @@ } .w3tc-card-ribbon-new { - height: 75px; - overflow: hidden; - position: absolute; - right: -5px; - top: -5px; - text-align: right; - width: 75px; - z-index: 1; -} - -.w3tc-card-ribbon-new span { - background: #30bec3; - box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 0.5); - color: #fff; - display: block; - font-size: 12px; - font-weight: bold; - line-height: 20px; - position: absolute; - right: -21px; - text-transform: uppercase; text-align: center; - top: 19px; - transform: rotate(45deg); - -webkit-transform: rotate(45deg); - /* Needed for Safari */ - width: 100px; + padding: 7px 5px; + background: #69BCC3; + color: #fff; } -.w3tc-card-ribbon-new span::before { - border-left: 3px solid #30bec3; - border-right: 3px solid transparent; - border-bottom: 3px solid transparent; - border-top: 3px solid #30bec3; - content: ''; - left: 0px; - position: absolute; - top: 100%; - z-index: -1; -} - -.w3tc-card-ribbon-new span::after { - border-right: 3px solid #30bec3; - border-left: 3px solid transparent; - border-bottom: 3px solid transparent; - border-top: 3px solid #30bec3; - content: ''; - position: absolute; - right: 0%; - top: 100%; - z-index: -1; +.w3tc-card-ribbon-new b { + font-weight: 600; } .w3tc-card-footer { - margin: 0 0 10px 10px; + margin: 0 0 20px 10px; } .w3tc-card-footer>div { diff --git a/wp-content/plugins/w3-total-cache/pub/css/options.css b/wp-content/plugins/w3-total-cache/pub/css/options.css index 75742997..877e31bd 100644 --- a/wp-content/plugins/w3-total-cache/pub/css/options.css +++ b/wp-content/plugins/w3-total-cache/pub/css/options.css @@ -60,12 +60,14 @@ display: none; } -.w3tc-enabled { +.w3tc-enabled, +.w3tc-authorized { color: #090; font-weight: 700; } -.w3tc-disabled { +.w3tc-disabled, +.w3tc-not-authorized { color: #f00; font-weight: 700; } diff --git a/wp-content/plugins/w3-total-cache/pub/img/w3tc_bunnycdn_logo.svg b/wp-content/plugins/w3-total-cache/pub/img/w3tc_bunnycdn_logo.svg new file mode 100644 index 00000000..20de43bf --- /dev/null +++ b/wp-content/plugins/w3-total-cache/pub/img/w3tc_bunnycdn_logo.svg @@ -0,0 +1,63 @@ + + + + bunnynet-light + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wp-content/plugins/w3-total-cache/pub/js/lightbox.js b/wp-content/plugins/w3-total-cache/pub/js/lightbox.js index 5af7a6ea..574cda9d 100644 --- a/wp-content/plugins/w3-total-cache/pub/js/lightbox.js +++ b/wp-content/plugins/w3-total-cache/pub/js/lightbox.js @@ -153,7 +153,7 @@ var W3tc_Lightbox = { * adds all controls of the form to the url */ load_form: function(url, form_selector, callback) { - data = {} + data = {}; var v = jQuery(form_selector).find('input').each(function(i) { var name = jQuery(this).attr('name'); var type = jQuery(this).attr('type'); diff --git a/wp-content/plugins/w3-total-cache/pub/js/options.js b/wp-content/plugins/w3-total-cache/pub/js/options.js index 1229a321..708cdf87 100644 --- a/wp-content/plugins/w3-total-cache/pub/js/options.js +++ b/wp-content/plugins/w3-total-cache/pub/js/options.js @@ -317,6 +317,57 @@ function w3tc_csp_reference() { }); } +/** + * Bunny CDN check. + * + * Prevent enabling Bunny CDN ("bunnycdn" engine) for both CDN and CDNFSD. + * + * @since X.X.X + * + * @returns null + */ +function cdn_bunnycdn_check() { + // Prevents JS error for non W3TC pages. + if (typeof w3tcData === 'undefined') { + return; + } + + var $cdn_enabled = jQuery('#cdn__enabled'), + $cdn_engine = jQuery('#cdn__engine'), + $cdnfsd_enabled = jQuery('#cdnfsd__enabled'), + $cdnfsd_engine = jQuery('#cdnfsd__engine'), + cdn_enabled = $cdn_enabled.is(':checked'), + cdn_engine = $cdn_engine.find(':selected').val(), + cdnfsd_enabled = $cdnfsd_enabled.is(':checked'), + cdnfsd_engine = $cdnfsd_engine.find(':selected').val(), + $cdn_inside = jQuery('#cdn .inside'); + + if (cdn_enabled && cdnfsd_enabled && 'bunnycdn' === cdn_engine && cdnfsd_engine === cdn_engine ) { + // Reset to what was last saved. + $cdn_enabled.prop('checked', w3tcData.cdnEnabled); + $cdn_engine.val(w3tcData.cdnEngine).change(); + $cdnfsd_enabled.prop('checked', w3tcData.cdnfsdEnabled); + $cdnfsd_engine.val(w3tcData.cdnfsdEngine).change(); + + // Display a warning. + jQuery('
', { + class: 'notice notice-warning', + id: 'w3tc-bunnycdn-warning', + text: w3tcData.bunnyCdnWarning + }).prependTo($cdn_inside); + } else { + // Remove the warning. + jQuery('#w3tc-bunnycdn-warning').remove(); + } +} + +/** + * Cloudfront CDN check. + * + * When CDN is enabled as "cf" or "cf2", then display a notice about possible charges. + * + * @returns null + */ function cdn_cf_check() { // Prevents JS error for non W3TC pages. if (typeof w3tcData === 'undefined') { @@ -387,8 +438,13 @@ function debounce(func){ }; } +// On document ready. jQuery(function() { - // general page + // Global vars. + var $cdn_enabled = jQuery('#cdn__enabled'), + $cdn_engine = jQuery('#cdn__engine'); + + // General page. jQuery('.w3tc_read_technical_info').on('click', function() { jQuery('.w3tc_technical_info').toggle(); }); @@ -424,10 +480,16 @@ jQuery(function() { }); }); + // Prevent enabling Bunny CDN for both CDN and CDNFSD. + $cdn_enabled.on('click', cdn_bunnycdn_check); + $cdn_engine.on('change', cdn_bunnycdn_check); + jQuery('#cdnfsd__enabled').on('click', cdn_bunnycdn_check); + jQuery('#cdnfsd__engine').on('change', cdn_bunnycdn_check); + // When CDN is enabled as "cf" or "cf2", then display a notice about possible charges. cdn_cf_check(); - jQuery('#cdn__enabled').on('click', cdn_cf_check); - jQuery('#cdn__engine').on('change', cdn_cf_check); + $cdn_enabled.on('click', cdn_cf_check); + $cdn_engine.on('change', cdn_cf_check); /** * CDN page. @@ -435,7 +497,7 @@ jQuery(function() { */ jQuery('[name="cdn__flush_manually"]').on('click', cdn_cf_check); - // pagecache page + // Pagecache page. w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').length); jQuery('#pgcache__reject__logged_roles').on('click', function() { w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').length); @@ -449,7 +511,7 @@ jQuery(function() { jQuery('#pgcache__cache__nginx_handle_xml').attr('checked', this.checked); }); - // browsercache page + // Browsercache page. w3tc_toggle2('browsercache_last_modified', ['browsercache__cssjs__last_modified', 'browsercache__html__last_modified', 'browsercache__other__last_modified' ]); @@ -477,7 +539,7 @@ jQuery(function() { w3tc_security_headers(); - // minify page + // Minify page. w3tc_input_enable('.html_enabled', jQuery('#minify__html__enable:checked').length); w3tc_input_enable('.js_enabled', jQuery('#minify__js__enable:checked').length); w3tc_input_enable('.css_enabled', jQuery('#minify__css__enable:checked').length); @@ -663,7 +725,7 @@ jQuery(function() { return true; }); - // CDN + // CDN. jQuery('.w3tc-tab').on('click', function() { jQuery('.w3tc-tab-content').hide(); jQuery(this.rel).show(); @@ -1126,7 +1188,7 @@ jQuery(function() { }, 'json'); }); - // CDN cnames + // CDN cnames. jQuery('body').on('click', '#cdn_cname_add', function() { jQuery('#cdn_cnames').append('
  • '); w3tc_cdn_cnames_assign(); @@ -1164,7 +1226,7 @@ jQuery(function() { return ret; }); - // add sortable + // Add sortable. if (jQuery.ui && jQuery.ui.sortable) { jQuery('#js_files,#css_files').sortable({ axis: 'y', @@ -1199,7 +1261,7 @@ jQuery(function() { }); } - // show hide rules + // Show hide rules. jQuery('.w3tc-show-rules').on('click', function() { var btn = jQuery(this), rules = btn.parent().find('.w3tc-rules'); @@ -1214,7 +1276,7 @@ jQuery(function() { }); - // show hide missing files + // Show hide missing files. jQuery('.w3tc-show-required-changes').on('click', function() { var btn = jQuery(this), rules = jQuery('.w3tc-required-changes'); @@ -1228,7 +1290,7 @@ jQuery(function() { } }); - // show hide missing files + // Show hide missing files. jQuery('.w3tc-show-ftp-form').on('click', function() { var btn = jQuery(this), rules = jQuery('.w3tc-ftp-form'); @@ -1242,7 +1304,7 @@ jQuery(function() { } }); - // show hide missing files + // Show hide missing files. jQuery('.w3tc-show-technical-info').on('click', function() { var btn = jQuery(this), info = jQuery('.w3tc-technical-info'); @@ -1256,18 +1318,18 @@ jQuery(function() { } }); - // add ignore class to the ftp form elements + // Add ignore class to the ftp form elements. jQuery('#ftp_upload_form').find('input').each(function() { jQuery(this).addClass('w3tc-ignore-change'); }); - // toggle hiddent content + // Toggle hidden content. jQuery('.w3tc_link_more').on('click', function() { var target_class = jQuery(this).metadata().for_class; jQuery('.' + target_class).slideToggle(); }); - // check for unsaved changes + // Check for unsaved changes. jQuery('#w3tc input,#w3tc select,#w3tc textarea').on('change', function() { var ignore = false; jQuery(this).parents().addBack().each(function() { @@ -1284,7 +1346,6 @@ jQuery(function() { jQuery('body').on('click', '.w3tc-button-save', w3tc_beforeupload_unbind); - jQuery('.contextual-help-tabs ul li a').on('click', function() { var id = jQuery(this).attr('aria-controls'); var i = jQuery('#' + id + ' .w3tchelp_content'); @@ -1321,7 +1382,7 @@ jQuery(function() { }); } - // extensions page + // Extensions page. jQuery('.w3tc_extensions_manage_input_checkall').on('click', function(v) { var c = jQuery(this).is(':checked'); @@ -1332,7 +1393,7 @@ jQuery(function() { }); }); - // gopro block + // Go Pro block. jQuery('.w3tc-gopro-more').on('click', function(e) { e.preventDefault(); if (!jQuery(this).data('expanded')) { @@ -1357,13 +1418,13 @@ jQuery(function() { } }); - // Bootstrap dropdown toggle + // Bootstrap dropdown toggle. jQuery('.dropdown-toggle').on('click', function() { jQuery('.dropdown-toggle').not(this).next().hide(); jQuery(this).next().toggle(); }); - // Bootstrap dropdown hide on click away + // Bootstrap dropdown hide on click away. jQuery(document).mouseup(function(e) { var dropdowns = jQuery('.dropdown-toggle'); if (!dropdowns.is(e.target) && dropdowns.has(e.target).length === 0) { @@ -1371,7 +1432,7 @@ jQuery(function() { } }); - // Options menu achor links + // Options menu anchor links. jQuery('#w3tc-top-nav-bar a').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1385,7 +1446,7 @@ jQuery(function() { } }); - // Options menu achor links + // Options menu anchor links. jQuery('#w3tc-options-menu a').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1399,7 +1460,7 @@ jQuery(function() { } }); - // Form control bar buttons + // Form control bar buttons. jQuery('.w3tc_form_bar input').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1413,7 +1474,7 @@ jQuery(function() { } }); - // Footer links + // Footer links. jQuery('#w3tc-footer a').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1427,7 +1488,7 @@ jQuery(function() { } }); - // General settings advanced options links + // General settings advanced options links. jQuery('.advanced-settings a').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1441,7 +1502,7 @@ jQuery(function() { } }); - // Extra links + // Extra links. jQuery('.extra-link a').on('click', function(e) { if (window.w3tc_ga) { w3tc_ga( @@ -1582,13 +1643,13 @@ jQuery(function() { var hash = window.location.hash; if (hash !== "") { - // Start at top of page rather than instantly loading at the anchor point + // Start at top of page rather than instantly loading at the anchor point. window.scrollTo(0, 0); var wpadminbar_height = (jQuery(window).width() > 600 && jQuery('#wpadminbar').length) ? jQuery('#wpadminbar').outerHeight() : 0, nav_bar_height = (jQuery('#w3tc-top-nav-bar').length) ? jQuery('#w3tc-top-nav-bar').outerHeight() : 0, options_menu_height = (jQuery('#w3tc > #w3tc-options-menu').length) ? jQuery('#w3tc > #w3tc-options-menu').outerHeight() : 0, form_bar_height = (jQuery('.w3tc_form_bar').length) ? jQuery('.w3tc_form_bar').outerHeight() : 0; - // Scroll to taget after .5 seconds + // Scroll to taget after .5 seconds. setTimeout( function() { jQuery('html, body').animate({ diff --git a/wp-content/plugins/w3-total-cache/readme.txt b/wp-content/plugins/w3-total-cache/readme.txt index e04a0970..909f2fed 100644 --- a/wp-content/plugins/w3-total-cache/readme.txt +++ b/wp-content/plugins/w3-total-cache/readme.txt @@ -2,8 +2,8 @@ Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto, vmarko, jacobd91 Tags: seo, cache, CDN, pagespeed, caching, performance, compression, optimize, cloudflare, nginx, apache, varnish, redis, aws, amazon web services, s3, cloudfront, azure Requires at least: 5.3 -Tested up to: 6.3 -Stable tag: 2.5.0 +Tested up to: 6.4 +Stable tag: 2.6.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -285,12 +285,28 @@ Please reach out to all of these people and support their projects if you're so == Changelog == += 2.6.1 = +* Fix: WebP Converter extension activation +* Fix: Media Library upload may fail when using Bunny CDN +* Fix: Cloudflare API error when updating certain settings +* Fix: Lazy Loading issue with the Delay Scripts feature enabled +* Update: Allow custom hostname changes for Bunny CDN + += 2.6.0 = +* Feature: Added support for Bunny.Net CDN +* Feature: Preload requests (Pro) +* Fix: Error when changing CDN cookie domain setting +* Fix: Admin notice when flushing cache from the admin bar +* Fix: Error in some Minify cache file operations +* Fix: PHP 8 compatibility +* Update: Delay scripts UI changes + = 2.5.0 = * Feature: Added Delay Scripts (Pro) * Fix: Several PHP 8 warnings * Fix: Fragment Cache extension PHP warnings when no engine was selected * Fix: Fragment Cache engine selection disabled for pro license under certain conditions -* Fix: Added Database Cluster compatiblity for older db.php files +* Fix: Added Database Cluster compatibility for older db.php files * Fix: Fixed one PageSpeed tool metric not outputting data and adjusted a few labels * Fix: Multiple anchor links for PageSpeed block on General Settings page * Fix: Cache Groups validation on save diff --git a/wp-content/plugins/w3-total-cache/vendor/autoload.php b/wp-content/plugins/w3-total-cache/vendor/autoload.php index 467eba84..3800b6ec 100644 --- a/wp-content/plugins/w3-total-cache/vendor/autoload.php +++ b/wp-content/plugins/w3-total-cache/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531::getLoader(); +return ComposerAutoloaderInit0a460180fd05a263e1d1b80239cc4d46::getLoader(); diff --git a/wp-content/plugins/w3-total-cache/vendor/composer/autoload_real.php b/wp-content/plugins/w3-total-cache/vendor/composer/autoload_real.php index 47572752..347a2de3 100644 --- a/wp-content/plugins/w3-total-cache/vendor/composer/autoload_real.php +++ b/wp-content/plugins/w3-total-cache/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531 +class ComposerAutoloaderInit0a460180fd05a263e1d1b80239cc4d46 { private static $loader; @@ -22,15 +22,15 @@ class ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit0a460180fd05a263e1d1b80239cc4d46', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit0a460180fd05a263e1d1b80239cc4d46', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -51,19 +51,19 @@ class ComposerAutoloaderInit81e756b29c31a6c9f87bd8a321bf7531 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire81e756b29c31a6c9f87bd8a321bf7531($fileIdentifier, $file); + composerRequire0a460180fd05a263e1d1b80239cc4d46($fileIdentifier, $file); } return $loader; } } -function composerRequire81e756b29c31a6c9f87bd8a321bf7531($fileIdentifier, $file) +function composerRequire0a460180fd05a263e1d1b80239cc4d46($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/wp-content/plugins/w3-total-cache/vendor/composer/autoload_static.php b/wp-content/plugins/w3-total-cache/vendor/composer/autoload_static.php index 6720a2a2..11e53137 100644 --- a/wp-content/plugins/w3-total-cache/vendor/composer/autoload_static.php +++ b/wp-content/plugins/w3-total-cache/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531 +class ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46 { public static $files = array ( '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', @@ -986,9 +986,9 @@ class ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit81e756b29c31a6c9f87bd8a321bf7531::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit0a460180fd05a263e1d1b80239cc4d46::$classMap; }, null, ClassLoader::class); } diff --git a/wp-content/plugins/w3-total-cache/w3-total-cache-api.php b/wp-content/plugins/w3-total-cache/w3-total-cache-api.php index fd031bbb..1ddfb377 100644 --- a/wp-content/plugins/w3-total-cache/w3-total-cache-api.php +++ b/wp-content/plugins/w3-total-cache/w3-total-cache-api.php @@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) { } define( 'W3TC', true ); -define( 'W3TC_VERSION', '2.5.0' ); +define( 'W3TC_VERSION', '2.6.1' ); define( 'W3TC_POWERED_BY', 'W3 Total Cache' ); define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' ); define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' ); @@ -35,6 +35,9 @@ define( 'W3TC_NEWRELIC_SIGNUP_URL', 'https://api.w3-edge.com/v1/redirects/newrel define( 'W3TC_STACKPATH_AUTHORIZE_URL', 'https://api.w3-edge.com/v1/redirects/stackpath/authorize' ); define( 'W3TC_STACKPATH2_AUTHORIZE_URL', 'https://api.w3-edge.com/v1/redirects/stackpath2/authorize' ); define( 'W3TC_GOOGLE_DRIVE_AUTHORIZE_URL', 'https://api.w3-edge.com/v1/googledrive/authorize' ); +define( 'W3TC_BUNNYCDN_SIGNUP_URL', 'https://api.w3-edge.com/v1/redirects/bunnycdn/signup' ); +define( 'W3TC_BUNNYCDN_SETTINGS_URL', 'https://api.w3-edge.com/v1/redirects/bunnycdn/settings' ); +define( 'W3TC_BUNNYCDN_CDN_URL', 'https://api.w3-edge.com/v1/redirects/bunnycdn/cdn' ); // Image Service rate constants. define( 'W3TC_IMAGE_SERVICE_FREE_HLIMIT', 100 ); diff --git a/wp-content/plugins/w3-total-cache/w3-total-cache.php b/wp-content/plugins/w3-total-cache/w3-total-cache.php index 0b681280..2fb1610f 100644 --- a/wp-content/plugins/w3-total-cache/w3-total-cache.php +++ b/wp-content/plugins/w3-total-cache/w3-total-cache.php @@ -3,7 +3,7 @@ * Plugin Name: W3 Total Cache * Plugin URI: https://www.boldgrid.com/totalcache/ * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress. - * Version: 2.5.0 + * Version: 2.6.1 * Requires at least: 5.3 * Requires PHP: 5.6 * Author: BoldGrid