/** * Updates the plugin from older version. */ function w3_run_legacy_update() { w3_require_once(W3TC_LIB_W3_DIR . '/ConfigWriter.php'); $writer = new W3_ConfigWriter(w3_get_blog_id(), w3_is_preview_mode()); $writer->import_legacy_config_and_save(); // Only remove folders when master blog is running. if (w3_get_blog_id() == 0) { w3_remove_old_folders(); } }
/** * Constructor */ function __construct($master = false) { $preview = w3_is_preview_mode(); if (defined('WP_ADMIN')) { $config_admin = w3_instance('W3_ConfigAdmin'); $preview = $config_admin->get_boolean('previewmode.enabled'); } if ($master) { $this->_blog_id = 0; } else { $this->_blog_id = w3_get_blog_id(); } $this->_preview = $preview; $this->load(); }
/** * @param array $spec options * * 'isPublic': (bool) if true, the Cache-Control header will contain * "public", allowing proxies to cache the content. Otherwise "private" will * be sent, allowing only browser caching. (default false) * * 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers * will be sent with content. This is recommended. * * 'encoding': (string) if set, the header "Vary: Accept-Encoding" will * always be sent and a truncated version of the encoding will be appended * to the ETag. E.g. "pub123456;gz". This will also trigger a more lenient * checking of the client's If-None-Match header, as the encoding portion of * the ETag will be stripped before comparison. * * 'contentHash': (string) if given, only the ETag header can be sent with * content (only HTTP1.1 clients can conditionally GET). The given string * should be short with no quote characters and always change when the * resource changes (recommend md5()). This is not needed/used if * lastModifiedTime is given. * * 'eTag': (string) if given, this will be used as the ETag header rather * than values based on lastModifiedTime or contentHash. Also the encoding * string will not be appended to the given value as described above. * * 'invalidate': (bool) if true, the client cache will be considered invalid * without testing. Effectively this disables conditional GET. * (default false) * * 'maxAge': (int) if given, this will set the Cache-Control max-age in * seconds, and also set the Expires header to the equivalent GMT date. * After the max-age period has passed, the browser will again send a * conditional GET to revalidate its cache. * * @return null */ public function __construct($spec) { if (isset($spec['cacheHeaders']) && is_array($spec['cacheHeaders'])) { $this->_cacheHeaders = $spec['cacheHeaders']; } $scope = $this->_cacheHeaders['cacheheaders_enabled'] && $this->_cacheHeaders['cacheheaders'] != 'no_cache' ? 'public' : 'private'; $maxAge = 0; $this->_headers['Pragma'] = $scope; // backwards compatibility (can be removed later) if (isset($spec['setExpires']) && is_numeric($spec['setExpires']) && !isset($spec['maxAge'])) { $spec['maxAge'] = $spec['setExpires'] - $_SERVER['REQUEST_TIME']; } if (isset($spec['maxAge'])) { $maxAge = $spec['maxAge']; if ($this->_cacheHeaders['expires_enabled'] && $maxAge) { $this->_headers['Expires'] = self::gmtDate($_SERVER['REQUEST_TIME'] + $maxAge); } } $etagAppend = ''; if (isset($spec['encoding'])) { $this->_stripEtag = true; $this->_headers['Vary'] = 'Accept-Encoding'; if ('' !== $spec['encoding']) { if (0 === strpos($spec['encoding'], 'x-')) { $spec['encoding'] = substr($spec['encoding'], 2); } $etagAppend = ';' . substr($spec['encoding'], 0, 2); } } if (isset($spec['lastModifiedTime'])) { $this->_setLastModified($spec['lastModifiedTime']); if (isset($spec['eTag'])) { // Use it $this->_setEtag($spec['eTag'], $scope); } else { // base both headers on time $this->_setEtag($spec['lastModifiedTime'] . $etagAppend, $scope); } } elseif (isset($spec['eTag'])) { // Use it $this->_setEtag($spec['eTag'], $scope); } elseif (isset($spec['contentHash'])) { // Use the hash as the ETag $this->_setEtag($spec['contentHash'] . $etagAppend, $scope); } if ($this->_cacheHeaders['cacheheaders_enabled']) { switch ($this->_cacheHeaders['cacheheaders']) { case 'cache': $this->_headers['Cache-Control'] = 'public'; break; case 'cache_public_maxage': $this->_headers['Cache-Control'] = "max-age={$maxAge}, public"; break; case 'cache_validation': $this->_headers['Cache-Control'] = 'public, must-revalidate, proxy-revalidate'; break; case 'cache_noproxy': $this->_headers['Cache-Control'] = 'public, must-revalidate'; break; case 'cache_maxage': $this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}, must-revalidate, proxy-revalidate"; break; case 'no_cache': $this->_headers['Cache-Control'] = 'max-age=0, private, no-store, no-cache, must-revalidate'; break; } } /** * Disable caching for preview mode */ if (w3_is_preview_mode()) { $this->_headers = array_merge($this->_headers, array('Pragma' => 'private', 'Cache-Control' => 'private')); } // invalidate cache if disabled, otherwise check $this->cacheIsValid = isset($spec['invalidate']) && $spec['invalidate'] ? false : $this->_isCacheValid(); }
/** * Check if we can do modify contents * * @return boolean */ function can_ob() { global $w3_late_init; $enabled = w3_is_preview_mode(); $enabled = $enabled || $this->_config->get_boolean('pgcache.enabled'); $enabled = $enabled || $this->_config->get_boolean('dbcache.enabled'); $enabled = $enabled || $this->_config->get_boolean('objectcache.enabled'); $enabled = $enabled || $this->_config->get_boolean('browsercache.enabled'); $enabled = $enabled || $this->_config->get_boolean('minify.enabled'); $enabled = $enabled || $this->_config->get_boolean('cdn.enabled'); $enabled = $enabled || $this->_config->get_boolean('fragmentcache.enabled'); $enabled = $enabled || w3_is_dbcluster(); $enabled = $enabled && !$w3_late_init; /** * Check if plugin enabled */ if (!$enabled) { return false; } /** * Skip if admin */ if (defined('WP_ADMIN')) { return false; } /** * Skip if doing AJAX */ if (defined('DOING_AJAX')) { return false; } /** * Skip if doing cron */ if (defined('DOING_CRON')) { return false; } /** * Skip if APP request */ if (defined('APP_REQUEST')) { return false; } /** * Skip if XMLRPC request */ if (defined('XMLRPC_REQUEST')) { return false; } /** * Check for WPMU's and WP's 3.0 short init */ if (defined('SHORTINIT') && SHORTINIT) { return false; } /** * Check User Agent */ if (isset($_SERVER['HTTP_USER_AGENT']) && stristr($_SERVER['HTTP_USER_AGENT'], W3TC_POWERED_BY) !== false) { return false; } return true; }
/** * Sends headers * @param boolean $is_404 * @param string $etag * @param integer $time * @param string $compression * @param array $custom_headers * @return boolean */ function _send_headers($is_404, $time, $etag, $compression, $custom_headers = array()) { $exit = false; $headers = array(); $curr_time = time(); $bc_lifetime = $this->_config->get_integer('browsercache.html.lifetime'); $expires = (is_null($time) ? $curr_time : $time) + $bc_lifetime; $max_age = $expires > $curr_time ? $expires - $curr_time : 0; if ($is_404) { /** * Add 404 header */ $headers = array_merge($headers, array('Status' => 'HTTP/1.1 404 Not Found')); } elseif (!is_null($time) && $this->_check_modified_since($time) || $this->_check_match($etag)) { /** * Add 304 header */ $headers = array_merge($headers, array('Status' => 'HTTP/1.1 304 Not Modified')); /** * Don't send content if it isn't modified */ $exit = true; } if ($this->_config->get_boolean('browsercache.enabled')) { if ($this->_config->get_boolean('browsercache.html.last_modified')) { $headers = array_merge($headers, array('Last-Modified' => w3_http_date($time))); } if ($this->_config->get_boolean('browsercache.html.expires')) { $headers = array_merge($headers, array('Expires' => w3_http_date($expires))); } if ($this->_config->get_boolean('browsercache.html.cache.control')) { switch ($this->_config->get_string('browsercache.html.cache.policy')) { case 'cache': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'public')); break; case 'cache_public_maxage': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => sprintf('max-age=%d, public', $max_age))); break; case 'cache_validation': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'public, must-revalidate, proxy-revalidate')); break; case 'cache_noproxy': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'private, must-revalidate')); break; case 'cache_maxage': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => sprintf('max-age=%d, public, must-revalidate, proxy-revalidate', $max_age))); break; case 'no_cache': $headers = array_merge($headers, array('Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, private, no-store, no-cache, must-revalidate')); break; } } if ($this->_config->get_boolean('browsercache.html.etag')) { $headers = array_merge($headers, array('Etag' => $etag)); } if ($this->_config->get_boolean('browsercache.html.w3tc')) { $headers = array_merge($headers, array('X-Powered-By' => W3TC_POWERED_BY)); } } $vary = ''; //compressed && UAG if ($compression && $this->_get_mobile_group()) { $vary = 'Accept-Encoding,User-Agent,Cookie'; $headers = array_merge($headers, array('Content-Encoding' => $compression)); //compressed } elseif ($compression) { $vary = 'Accept-Encoding'; $headers = array_merge($headers, array('Content-Encoding' => $compression)); //uncompressed && UAG } elseif ($this->_get_mobile_group()) { $vary = 'User-Agent,Cookie'; } //Add Cookie to vary if user logged in and not previously set if (!$this->_check_logged_in() && strpos($vary, 'Cookie') === false) { if ($vary) { $vary .= ',Cookie'; } else { $vary = 'Cookie'; } } /** * Add vary header */ if ($vary) { $headers = array_merge($headers, array('Vary' => $vary)); } /** * Add custom headers */ $headers = array_merge($headers, $custom_headers); /** * Disable caching for preview mode */ if (w3_is_preview_mode()) { $headers = array_merge($headers, array('Pragma' => 'private', 'Cache-Control' => 'private')); } /** * Send headers to client */ $result = $this->_headers($headers); if ($exit) { exit; } return $result; }
/** * Returns a preview link with current state * @return string */ function w3tc_get_preview_link() { w3_require_once(W3TC_INC_FUNCTIONS_DIR . '/ui.php'); return w3_is_preview_mode() ? w3_button_link(__('Stop Previewing', 'w3-total-cache'), wp_nonce_url(w3_admin_url('admin.php?page=w3tc_dashboard&w3tc_default_stop_previewing'), 'w3tc'), false) : w3_button_link(__('Preview', 'w3-total-cache'), wp_nonce_url(w3_admin_url('admin.php?page=w3tc_dashboard&w3tc_default_previewing'), 'w3tc'), true); }
private function verify_file_generic_rewrite_working() { $url = w3_get_home_url() . '/w3tc_rewrite_test'; if (!$this->test_rewrite($url)) { $key = sprintf('w3tc_rewrite_test_result_%s', substr(md5($url), 0, 16)); $result = get_transient($key); $home_url = w3_get_home_url(); $tech_message = (w3_is_nginx() ? 'nginx configuration file' : '.htaccess file') . ' contains rules to rewrite url ' . $home_url . '/w3tc_rewrite_test into ' . $home_url . '/?w3tc_rewrite_test which, if handled by ' . 'plugin, return "OK" message.<br/>'; $tech_message .= 'The plugin made a request to ' . $home_url . '/w3tc_rewrite_test but received: <br />' . $result . '<br />'; $tech_message .= 'instead of "OK" response. <br />'; $error = '<strong>W3 Total Cache error:</strong> ' . 'It appears Page Cache ' . '<acronym title="Uniform Resource Locator">URL</acronym> ' . 'rewriting is not working. '; if (w3_is_preview_mode()) { $error .= ' This could be due to using Preview mode. <a href="' . $url . '">Click here</a> to manually verify its working. It should say OK. <br />'; } if (w3_is_nginx()) { $error .= 'Please verify that all configuration files are ' . 'included in the configuration file ' . '(and that you have reloaded / restarted nginx).'; } else { $error .= 'Please verify that the server configuration ' . 'allows .htaccess'; } $error .= '<br />Unfortunately disk enhanced page caching will ' . 'not function without custom rewrite rules. ' . 'Please ask your server administrator for assistance. ' . 'Also refer to <a href="' . admin_url('admin.php?page=w3tc_install') . '">the install page</a> for the rules for your server.'; throw new SelfTestFailedException($error, $tech_message); } }
/** * Sends headers * @param boolean $is_404 * @param string $etag * @param integer $time * @param string $compression * @param array $custom_headers * @return boolean */ function _send_headers($is_404, $time, $etag, $compression, $custom_headers = array()) { $exit = false; $headers = array(); $curr_time = time(); $expires = $time + $this->_lifetime; $max_age = $expires > $curr_time ? $expires - $curr_time : 0; if ($is_404) { /** * Add 404 header */ $headers = array_merge($headers, array('Status' => 'HTTP/1.1 404 Not Found')); } elseif ($this->_check_modified_since($time) || $this->_check_match($etag)) { /** * Add 304 header */ $headers = array_merge($headers, array('Status' => 'HTTP/1.1 304 Not Modified')); /** * Don't send content if it isn't modified */ $exit = true; } /** * Add default headers */ $headers = array_merge($headers, array('Last-Modified' => w3_http_date($time), 'Vary' => 'Cookie')); if ($this->_config->get_boolean('browsercache.enabled')) { if ($this->_config->get_boolean('browsercache.html.expires')) { $headers = array_merge($headers, array('Expires' => w3_http_date($expires))); } if ($this->_config->get_boolean('browsercache.html.cache.control')) { switch ($this->_config->get_string('browsercache.html.cache.policy')) { case 'cache': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'public')); break; case 'cache_validation': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'public, must-revalidate, proxy-revalidate')); break; case 'cache_noproxy': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => 'public, must-revalidate')); break; case 'cache_maxage': $headers = array_merge($headers, array('Pragma' => 'public', 'Cache-Control' => sprintf('max-age=%d, public, must-revalidate, proxy-revalidate', $max_age))); break; case 'no_cache': $headers = array_merge($headers, array('Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, private, no-store, no-cache, must-revalidate')); break; } } if ($this->_config->get_boolean('browsercache.html.etag')) { $headers = array_merge($headers, array('Etag' => $etag)); } if ($this->_config->get_boolean('browsercache.html.w3tc')) { $headers = array_merge($headers, array('X-Powered-By' => W3TC_POWERED_BY)); } } if ($compression) { /** * Add Content-Encoding header */ $headers = array_merge($headers, array('Vary' => 'Accept-Encoding, Cookie', 'Content-Encoding' => $compression)); } /** * Add custom headers */ $headers = array_merge($headers, $custom_headers); /** * Disable caching for preview mode */ if (w3_is_preview_mode()) { $headers = array_merge($headers, array('Pragma' => 'private', 'Cache-Control' => 'private')); } /** * Send headers to client */ $result = $this->_headers($headers); if ($exit) { exit; } return $result; }
/** * Saves config * * @param boolean preview * @return boolean */ function save($preview = null) { if ($preview === null) { $preview = w3_is_preview_mode(); } if ($preview) { return $this->write(W3TC_CONFIG_PREVIEW_PATH); } return $this->write(W3TC_CONFIG_PATH); }