fix_folders($config, $exs); /** * @var W3_Config $config */ if ($config->get_boolean('config.check') || $force_all_checks) { if ($config->get_boolean('minify.enabled') && $config->get_boolean('minify.rewrite')) { $this->rules_core_add($config, $exs); } else { $this->rules_core_remove($exs); } if ((w3_is_apache() || w3_is_litespeed()) && w3_is_network() && !w3_is_subdomain_install()) { if ($config->get_boolean('minify.enabled') && $config->get_boolean('minify.rewrite')) { $this->rules_wpmu_subfolder_add($config, $exs); } else { $this->rules_wpmu_subfolder_remove($exs); } } if ($config->get_boolean('minify.enabled') && $config->get_string('minify.engine') == 'file') { $this->rules_cache_add($config, $exs); } else { $this->rules_cache_remove($exs); } } // if no errors so far - check if rewrite actually works if (count($exs->exceptions()) <= 0 || true) { try { if ($config->get_boolean('minify.enabled') && $config->get_string('minify.engine') == 'file' && $config->get_boolean('minify.debug')) $this->verify_rewrite_working(); } catch (Exception $ex) { $exs->push($ex); } if ($config->get_boolean('minify.enabled')) $this->verify_engine_working($config, $exs); } if (count($exs->exceptions()) > 0) throw $exs; } /** * Fixes environment once event occurs * * @param W3_Config $config * @param string $event * @param null|W3_Config $old_config * @throws SelfTestExceptions */ public function fix_on_event($config, $event, $old_config = null) { // Schedules events if ($config->get_boolean('minify.enabled') && $config->get_string('minify.engine') == 'file') { if ($old_config != null && $config->get_integer('minify.file.gc') != $old_config->get_integer('minify.file.gc')) { $this->unschedule(); } if (!wp_next_scheduled('w3_minify_cleanup')) { wp_schedule_event(time(), 'w3_minify_cleanup', 'w3_minify_cleanup'); } } else { $this->unschedule(); } } /** * Fixes environment after plugin deactivation * @throws SelfTestExceptions */ public function fix_after_deactivation() { $exs = new SelfTestExceptions(); $this->rules_core_remove($exs); $this->rules_wpmu_subfolder_remove($exs); $this->rules_cache_remove($exs); $this->unschedule(); if (count($exs->exceptions()) > 0) throw $exs; } /** * * @param W3_Config $config * @return array */ function get_required_rules($config) { if (!$config->get_boolean('minify.enabled')) return null; $rewrite_rules = array(); if ($config->get_string('minify.engine') == 'file') { $minify_rules_cache_path = w3_get_minify_rules_cache_path(); $rewrite_rules[] = array( 'filename' => $minify_rules_cache_path, 'content' => $this->rules_cache_generate($config) ); } $minify_rules_core_path = w3_get_minify_rules_core_path(); $rewrite_rules[] = array( 'filename' => $minify_rules_core_path, 'content' => $this->rules_core_generate($config), 'last' => true ); return $rewrite_rules; } /** * Fixes folders * @param W3_Config $config * @param SelfTestExceptions $exs **/ private function fix_folders($config, $exs) { // folder that we delete if exists and not writeable if ($config->get_boolean('minify.enabled') && $config->get_string('minify.engine') == 'file') { $dir = W3TC_CACHE_MINIFY_DIR; try{ if (file_exists($dir) && !is_writeable($dir)) w3_wp_delete_folder($dir, '', $_SERVER['REQUEST_URI']); } catch (FilesystemRmdirException $ex) { $exs->push($ex); } } } /** * Minifiers availability error handling * * @param W3_Config $config * @param SelfTestExceptions $exs */ private function verify_engine_working($config, $exs) { $minifiers_errors = array(); if ($config->get_string('minify.js.engine') == 'yuijs') { $path_java = $config->get_string('minify.yuijs.path.java'); $path_jar = $config->get_string('minify.yuijs.path.jar'); if (!file_exists($path_java)) { $minifiers_errors[] = sprintf('YUI Compressor (JS): JAVA executable path was not found. The default minifier JSMin will be used instead.'); } elseif (!file_exists($path_jar)) { $minifiers_errors[] = sprintf('YUI Compressor (JS): JAR file path was not found. The default minifier JSMin will be used instead.'); } } if ($config->get_string('minify.css.engine') == 'yuicss') { $path_java = $config->get_string('minify.yuicss.path.java'); $path_jar = $config->get_string('minify.yuicss.path.jar'); if (!file_exists($path_java)) { $minifiers_errors[] = sprintf('YUI Compressor (CSS): JAVA executable path was not found. The default CSS minifier will be used instead.'); } elseif (!file_exists($path_jar)) { $minifiers_errors[] = sprintf('YUI Compressor (CSS): JAR file path was not found. The default CSS minifier will be used instead.'); } } if ($config->get_string('minify.js.engine') == 'ccjs') { $path_java = $config->get_string('minify.ccjs.path.java'); $path_jar = $config->get_string('minify.ccjs.path.jar'); if (!file_exists($path_java)) { $minifiers_errors[] = sprintf('Closure Compiler: JAVA executable path was not found. The default minifier JSMin will be used instead.'); } elseif (!file_exists($path_jar)) { $minifiers_errors[] = sprintf('Closure Compiler: JAR file path was not found. The default minifier JSMin will be used instead.'); } } if (count($minifiers_errors)) { $minify_error = 'The following minifiers cannot be found or are no longer working:
This message will automatically disappear once the issue is resolved.';
$exs->push(new SelfTestFailedException($minify_error));
}
}
/*
* Checks rewrite
* @throws SelfTestExceptions
**/
private function verify_rewrite_working() {
$url = w3_filename_to_url(w3_cache_blog_dir('minify') . '/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 ' .
$url . '. If handled by ' .
'plugin, it returns "OK" message.
';
$tech_message .= 'The plugin made a request to ' .
$url . ' but received:
' .
$result . '
';
$tech_message .= 'instead of "OK" response.
';
$error = 'W3 Total Cache error:It appears Minify ' .
'URL ' .
'rewriting is not working. ';
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 .= '
Unfortunately minification will ' .
'not function without custom rewrite rules. ' .
'Please ask your server administrator for assistance. ' .
'Also refer to the install page for the rules for your server.';
throw new SelfTestFailedException($error, $tech_message);
}
}
/**
* Perform rewrite test
*
* @param string $url
* @return boolean
*/
private function test_rewrite($url) {
$key = sprintf('w3tc_rewrite_test_%s', substr(md5($url), 0, 16));
$result = get_transient($key);
if ($result === false) {
w3_require_once(W3TC_INC_FUNCTIONS_DIR . '/http.php');
$response = w3_http_get($url);
$result = (!is_wp_error($response) && $response['response']['code'] == 200 && trim($response['body']) == 'OK');
if ($result) {
set_transient($key, $result, 30);
} else {
$key_result = sprintf('w3tc_rewrite_test_result_%s', substr(md5($url), 0, 16));
set_transient($key_result, is_wp_error($response)? $response->get_error_message(): implode(' ', $response['response']), 30);
}
}
return $result;
}
/**
* scheduling stuff
**/
private function unschedule() {
if (wp_next_scheduled('w3_minify_cleanup')) {
wp_clear_scheduled_hook('w3_minify_cleanup');
}
}
/**
* rules core modification
**/
/**
* Writes directives to WP .htaccess
*
* @throws FilesystemOperationException with S/FTP form if it can't get the required filesystem credentials
* @throws FileOperationException
*/
private function rules_core_add($config, $exs) {
w3_add_rules($exs, w3_get_minify_rules_core_path(),
$this->rules_core_generate($config),
W3TC_MARKER_BEGIN_MINIFY_CORE,
W3TC_MARKER_END_MINIFY_CORE,
array(
W3TC_MARKER_BEGIN_PGCACHE_CORE => 0,
W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP => 0,
W3TC_MARKER_BEGIN_WORDPRESS => 0,
W3TC_MARKER_END_BROWSERCACHE_CACHE => strlen(W3TC_MARKER_END_BROWSERCACHE_CACHE) + 1,
W3TC_MARKER_END_PGCACHE_CACHE => strlen(W3TC_MARKER_END_PGCACHE_CACHE) + 1,
W3TC_MARKER_END_MINIFY_CACHE => strlen(W3TC_MARKER_END_MINIFY_CACHE) + 1
)
);
}
/**
* Removes Page Cache core directives
*
* @param SelfTestExceptions $exs
* @throws FilesystemOperationException with S/FTP form if it can't get the required filesystem credentials
* @throws FileOperationException
*/
private function rules_core_remove($exs) {
// no need to remove rules for apache - its in cache .htaccess file
if (!w3_is_nginx())
return;
w3_remove_rules($exs,
w3_get_minify_rules_core_path(),
W3TC_MARKER_BEGIN_MINIFY_CORE ,
W3TC_MARKER_END_MINIFY_CORE);
}
/**
* Generates rules for WP dir
*
* @param W3_Config $config
* @return string
*/
public function rules_core_generate($config) {
switch (true) {
case w3_is_apache():
case w3_is_litespeed():
return $this->rules_core_generate_apache($config);
case w3_is_nginx():
return $this->rules_core_generate_nginx($config);
}
return '';
}
/**
* Generates rules
*
* @param W3_Config $config
* @return string
*/
function rules_core_generate_apache($config) {
$cache_dir = w3_filename_to_uri(W3TC_CACHE_MINIFY_DIR);
$minify_filename = w3_make_relative_path(W3TC_DIR . '/pub/minify.php',
W3TC_CACHE_MINIFY_DIR);
$engine = $config->get_string('minify.engine');
$browsercache = $config->get_boolean('browsercache.enabled');
$compression = ($browsercache && $config->get_boolean('browsercache.cssjs.compression'));
$rules = '';
$rules .= W3TC_MARKER_BEGIN_MINIFY_CORE . "\n";
$rules .= "