PluginProbe ʕ •ᴥ•ʔ
WP Super Cache / 0.8.1
WP Super Cache v0.8.1
3.1.1 trunk 0.1 0.2 0.3 0.3.1 0.4 0.5 0.5.1 0.5.2 0.5.3 0.6.2 0.6.3 0.6.4 0.6.5 0.6.6 0.6.7 0.6.8 0.7 0.7.1 0.8 0.8.1 0.8.2 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 0.8.8 0.8.9 0.9 0.9.1 0.9.2 0.9.3 0.9.3.1 0.9.4 0.9.4.1 0.9.4.2 0.9.4.3 0.9.5 0.9.6 0.9.6.1 0.9.7 0.9.8 0.9.9 0.9.9.1 0.9.9.2 0.9.9.3 0.9.9.4 0.9.9.5 0.9.9.6 0.9.9.7 0.9.9.8 0.9.9.9 1.0 1.0.1 1.1 1.1.1 1.10.0 1.11.0 1.12.0 1.12.1 1.12.2 1.12.3 1.12.4 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.7.1 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8 1.9 1.9.1 1.9.2 1.9.3 1.9.4 2.0.0 2.0.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0
wp-super-cache / wp-cache.php
wp-super-cache Last commit date
plugins 17 years ago Changelog.txt 17 years ago readme.txt 17 years ago wp-cache-base.php 18 years ago wp-cache-config-sample.php 17 years ago wp-cache-phase1.php 17 years ago wp-cache-phase2.php 17 years ago wp-cache.php 17 years ago
wp-cache.php
1216 lines
1 <?php
2 /*
3 Plugin Name: WP Super Cache
4 Plugin URI: http://ocaoimh.ie/wp-super-cache/
5 Description: Very fast caching module for WordPress. Once activated, you must <a href="options-general.php?page=wpsupercache">enable the cache</a>. Based on WP-Cache by <a href="http://mnm.uib.es/gallir/">Ricardo Galli Granada</a>.
6 Version: 0.8.1
7 Author: Donncha O Caoimh
8 Author URI: http://ocaoimh.ie/
9 */
10 /* Copyright 2005-2006 Ricardo Galli Granada (email : gallir@uib.es)
11 Some code copyright 2007-2008 Donncha O Caoimh (http://ocaoimh.ie/)
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28 // Pre-2.6 compatibility
29 if( !defined('WP_CONTENT_URL') )
30 define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content');
31 if( !defined('WP_CONTENT_DIR') )
32 define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
33
34 $wp_cache_config_file = WP_CONTENT_DIR . '/wp-cache-config.php';
35
36 if( !@include($wp_cache_config_file) ) {
37 get_wpcachehome();
38 $wp_cache_config_file_sample = WPCACHEHOME . 'wp-cache-config-sample.php';
39 @include($wp_cache_config_file_sample);
40 } else {
41 get_wpcachehome();
42 }
43
44 $wp_cache_config_file_sample = WPCACHEHOME . 'wp-cache-config-sample.php';
45 $wp_cache_link = WP_CONTENT_DIR . '/advanced-cache.php';
46 $wp_cache_file = WPCACHEHOME . 'wp-cache-phase1.php';
47
48 include(WPCACHEHOME . 'wp-cache-base.php');
49
50
51 // from legolas558 d0t users dot sf dot net at http://www.php.net/is_writable
52 function is_writeable_ACLSafe($path) {
53
54 // PHP's is_writable does not work with Win32 NTFS
55
56 if ($path{strlen($path)-1}=='/') // recursively return a temporary file path
57 return is_writeable_ACLSafe($path.uniqid(mt_rand()).'.tmp');
58 else if (is_dir($path))
59 return is_writeable_ACLSafe($path.'/'.uniqid(mt_rand()).'.tmp');
60 // check tmp file for read/write capabilities
61 $rm = file_exists($path);
62 $f = @fopen($path, 'a');
63 if ($f===false)
64 return false;
65 fclose($f);
66 if (!$rm)
67 unlink($path);
68 return true;
69 }
70
71 function get_wpcachehome() {
72 if( defined( 'WPCACHEHOME' ) == false ) {
73 if( is_file( dirname(__FILE__) . '/wp-cache-config-sample.php' ) ) {
74 define( 'WPCACHEHOME', trailingslashit( dirname(__FILE__) ) );
75 } elseif( is_file( dirname(__FILE__) . '/wp-super-cache/wp-cache-config-sample.php' ) ) {
76 define( 'WPCACHEHOME', dirname(__FILE__) . '/wp-super-cache/' );
77 } else {
78 die( 'Please create ' . WP_CONTENT_DIR . '/wp-cache-config.php from wp-super-cache/wp-cache-config-sample.php' );
79 }
80 }
81 }
82
83 function wpsupercache_deactivate() {
84 global $wp_cache_config_file, $wp_cache_link, $cache_path;
85 $files = array( $wp_cache_config_file, $wp_cache_link );
86 foreach( $files as $file ) {
87 if( file_exists( $file ) )
88 unlink( $file );
89 }
90 if( !function_exists( 'prune_super_cache' ) )
91 include_once( 'wp-cache-phase2.php' );
92 prune_super_cache ($cache_path, true);
93 @unlink( $cache_path . '.htaccess' );
94 @unlink( $cache_path . 'meta' );
95 @unlink( $cache_path . 'supercache' );
96 }
97 register_deactivation_hook( __FILE__, 'wpsupercache_deactivate' );
98
99 function wp_cache_add_pages() {
100 if( function_exists( 'is_site_admin' ) ) {
101 if( is_site_admin() ) {
102 add_submenu_page('wpmu-admin.php', __('WP Super Cache'), __('WP Super Cache'), 'manage_options', 'wpsupercache', 'wp_cache_manager');
103 add_options_page('WP Super Cache', 'WP Super Cache', 'manage_options', 'wpsupercache', 'wp_cache_manager');
104 }
105 } else {
106 add_options_page('WP Super Cache', 'WP Super Cache', 'manage_options', 'wpsupercache', 'wp_cache_manager');
107 }
108 }
109 add_action('admin_menu', 'wp_cache_add_pages');
110
111 function wp_cache_manager() {
112 global $wp_cache_config_file, $valid_nonce, $supercachedir, $cache_path, $cache_enabled, $cache_compression, $super_cache_enabled, $wp_cache_hello_world, $wp_cache_clear_on_post_edit;
113
114 if( function_exists( 'is_site_admin' ) )
115 if( !is_site_admin() )
116 return;
117
118 $supercachedir = $cache_path . 'supercache/' . preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"]);
119 if( get_option( 'gzipcompression' ) == 1 )
120 update_option( 'gzipcompression', 0 );
121 $valid_nonce = wp_verify_nonce($_REQUEST['_wpnonce'], 'wp-cache');
122 /* http://www.netlobo.com/div_hiding.html */
123 ?>
124 <script type='text/javascript'>
125 <!--
126 function toggleLayer( whichLayer ) {
127 var elem, vis;
128 if( document.getElementById ) // this is the way the standards work
129 elem = document.getElementById( whichLayer );
130 else if( document.all ) // this is the way old msie versions work
131 elem = document.all[whichLayer];
132 else if( document.layers ) // this is the way nn4 works
133 elem = document.layers[whichLayer];
134 vis = elem.style;
135 // if the style.display value is blank we try to figure it out here
136 if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
137 vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
138 vis.display = (vis.display==''||vis.display=='block')?'none':'block';
139 }
140 // -->
141 </script>
142 <style type="text/css">
143 /* Taken from http://sw-guide.de/wordpress/plugins/simple-trackback-validation/ */
144 .wrap h3 { color: black; background-color: #e5f3ff; padding: 4px 8px; }
145 </style>
146 <?php
147 echo '<div class="wrap">';
148 echo "<h2>WP Super Cache Manager</h2>\n";
149 if( ini_get( 'safe_mode' ) ) {
150 ?><h3>Warning! PHP safe mode enabled!</h3>
151 <p>You may experience problems running this plugin because SAFE MODE is enabled. <?php
152 if( !ini_get( 'safe_mode_gid' ) ) {
153 ?>Your server is set up to check the owner of PHP scripts before allowing them to read and write files.</p><p>You or an administrator may be able to make it work by changing the group owner of the plugin scripts to match that of the web server user. The group owner of the <?php echo WP_CONTENT_DIR; ?>/cache/ directory must also be changed. See the <a href='http://php.net/features.safe-mode'>safe mode manual page</a> for further details.</p><?php
154 } else {
155 ?>You or an administrator must disable this. See the <a href='http://php.net/features.safe-mode'>safe mode manual page</a> for further details. This cannot be disabled in a .htaccess file unfortunately. It must be done in the php.ini config file.</p><?php
156 }
157 }
158 if(isset($_REQUEST['wp_restore_config']) && $valid_nonce) {
159 unlink($wp_cache_config_file);
160 echo '<strong>Configuration file changed, some values might be wrong. Load the page again from the "Options" menu to reset them.</strong>';
161 }
162
163 if ( !wp_cache_check_link() ||
164 !wp_cache_verify_config_file() ||
165 !wp_cache_verify_cache_dir() ) {
166 echo "<br>Cannot continue... fix previous problems and retry.<br />";
167 echo "</div>\n";
168 return;
169 }
170
171 if (!wp_cache_check_global_config()) {
172 echo "</div>\n";
173 return;
174 }
175
176 if( $cache_enabled == true && $super_cache_enabled == true && !got_mod_rewrite() ) {
177 ?><h4 style='color: #a00'>Mod rewrite may not be installed!</h4>
178 <p>It appears that mod_rewrite is not installed. Sometimes this check isn't 100% reliable, especially if you are not using Apache. Please verify that the mod_rewrite module is loaded. It is required for serving Super Cache static files. You will still be able to use WP-Cache.</p><?php
179 }
180
181 if( !is_writeable_ACLSafe($wp_cache_config_file) ) {
182 define( "SUBMITDISABLED", 'disabled style="color: #aaa" ' );
183 ?><h4 style='text-align:center; color: #a00'>Read Only Mode. Configuration cannot be changed. <a href="javascript:toggleLayer('readonlywarning');" title="Why your configuration may not be changed">Why</a></h4>
184 <div id='readonlywarning' style='border: 1px solid #aaa; margin: 2px; padding: 2px; display: none;'>
185 <p>The WP Super Cache configuration file is <code><?php echo WP_CONTENT_DIR; ?>/wp-cache-config.php</code> and cannot be modified. The file <?php echo WP_CONTENT_DIR; ?>/wp-cache-config.php must be writeable by the webserver to make any changes.<br />
186 A simple way of doing that is by changing the permissions temporarily using the CHMOD command or through your ftp client. Make sure it's globally writeable and it should be fine.<br />
187 Writeable: <code>chmod 666 <?php echo WP_CONTENT_DIR; ?>/wp-cache-config.php</code><br />
188 Readonly: <code>chmod 644 <?php echo WP_CONTENT_DIR; ?>/wp-cache-config.php</code></p>
189 </div><?php
190 } else {
191 define( "SUBMITDISABLED", ' ' );
192 }
193
194 // Server could be running as the owner of the wp-content directory. Therefore, if it's
195 // writable, issue a warning only if the permissions aren't 755.
196 if( is_writeable_ACLSafe( WP_CONTENT_DIR . '/' ) ) {
197 $wp_content_stat = stat(WP_CONTENT_DIR . '/');
198 $wp_content_mode = ($wp_content_stat['mode'] & 0777);
199 if( $wp_content_mode != 0755 ) {
200 ?><h4 style='text-align:center; color: #a00'>Warning! <?php echo WP_CONTENT_DIR; ?> is writeable!</h4>
201 <p>You should change the permissions on <?php echo WP_CONTENT_DIR; ?> and make it more restrictive. Use your ftp client, or the following command to fix things:<br /><code>chmod 755 <?php echo WP_CONTENT_DIR; ?>/</code></p><?php
202 }
203 }
204
205 if ( $valid_nonce ) {
206 if( isset( $_POST[ 'wp_cache_status' ] ) ) {
207 switch( $_POST[ 'wp_cache_status' ] ) {
208 case 'all':
209 wp_cache_enable();
210 break;
211 case 'none':
212 wp_cache_disable();
213 break;
214 case 'wpcache':
215 wp_cache_enable();
216 wp_super_cache_disable();
217 break;
218 }
219 if( isset( $_POST[ 'wp_cache_hello_world' ] ) ) {
220 $wp_cache_hello_world = (int)$_POST[ 'wp_cache_hello_world' ];
221 } else {
222 $wp_cache_hello_world = 0;
223 }
224 wp_cache_replace_line('^ *\$wp_cache_hello_world', '$wp_cache_hello_world = ' . (int)$wp_cache_hello_world . ";", $wp_cache_config_file);
225 }
226 if( isset( $_POST[ 'cache_compression' ] ) && $_POST[ 'cache_compression' ] != $cache_compression ) {
227 $cache_compression_changed = true;
228 $cache_compression = intval( $_POST[ 'cache_compression' ] );
229 wp_cache_replace_line('^ *\$cache_compression', "\$cache_compression = " . $cache_compression . ";", $wp_cache_config_file);
230 if( function_exists( 'prune_super_cache' ) )
231 prune_super_cache ($cache_path, true);
232 delete_option( 'super_cache_meta' );
233 }
234 if( isset( $_POST[ 'wp_cache_clear_on_post_edit' ] ) && $_POST[ 'wp_cache_clear_on_post_edit' ] != $wp_cache_clear_on_post_edit ) {
235 $wp_cache_clear_on_post_edit = intval( $_POST[ 'wp_cache_clear_on_post_edit' ] );
236 wp_cache_replace_line('^ *\$wp_cache_clear_on_post_edit', "\$wp_cache_clear_on_post_edit = " . $wp_cache_clear_on_post_edit . ";", $wp_cache_config_file);
237 }
238 }
239
240 ?><fieldset class="options">
241 <h3>WP Super Cache Status</h3><?php
242 echo '<form name="wp_manager" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
243 ?>
244 <label><input type='radio' name='wp_cache_status' value='all' <?php if( $cache_enabled == true && $super_cache_enabled == true ) { echo 'checked=checked'; } ?>> <strong>ON</strong> (WP Cache and Super Cache enabled)</label><br />
245 <label><input type='radio' name='wp_cache_status' value='wpcache' <?php if( $cache_enabled == true && $super_cache_enabled == false ) { echo 'checked=checked'; } ?>> <strong>HALF ON</strong> (Super Cache Disabled, only legacy WP-Cache caching.)</label><br />
246 <label><input type='radio' name='wp_cache_status' value='none' <?php if( $cache_enabled == false ) { echo 'checked=checked'; } ?>> <strong>OFF</strong> (WP Cache and Super Cache disabled)</label><br />
247 <p><label><input type='checkbox' name='wp_cache_hello_world' <?php if( $wp_cache_hello_world ) echo "checked"; ?> value='1'> Proudly tell the world your server is Digg proof! (places a message in your blog's footer)</label></p>
248 <p><label><input type='checkbox' name='wp_cache_clear_on_post_edit' <?php if( $wp_cache_clear_on_post_edit ) echo "checked"; ?> value='1'> Clear all cache files when a post or page is edited. (This may significantly slow down saving of posts.)</label></p>
249 <p>Note: if uninstalling this plugin, make sure the directory <em><?php echo WP_CONTENT_DIR; ?></em> is writeable by the webserver so the files <em>advanced-cache.php</em> and <em>cache-config.php</em> can be deleted automatically. (Making sure those files are writeable too is probably a good idea!)</p>
250 <?php
251 echo "<div><input type='submit' " . SUBMITDISABLED . " value='Update Status &raquo;' /></div>";
252 wp_nonce_field('wp-cache');
253 ?>
254 </form>
255 </fieldset>
256 <?php
257
258 wsc_mod_rewrite();
259
260 wp_cache_edit_max_time();
261
262 echo '<br /><a name="files"></a><fieldset class="options"><h3>Accepted filenames, rejected URIs</h3>';
263 wp_cache_edit_rejected();
264 echo "<br />\n";
265 wp_cache_edit_accepted();
266 echo '</fieldset>';
267
268 wp_cache_edit_rejected_ua();
269
270 wp_cache_files();
271
272 wp_lock_down();
273
274 wp_cache_restore();
275
276 ob_start();
277 if( defined( 'WP_CACHE' ) ) {
278 if( function_exists( 'do_cacheaction' ) ) {
279 do_cacheaction( 'cache_admin_page' );
280 }
281 }
282 $out = ob_get_contents();
283 ob_end_clean();
284 if( SUBMITDISABLED == ' ' && $out != '' ) {
285 echo '<fieldset class="options"><h3>Cache Plugins</h3>';
286 echo $out;
287 echo '</fieldset>';
288 }
289
290 echo "</div>\n";
291 }
292
293 function wsc_mod_rewrite() {
294 global $super_cache_enabled, $cache_compression, $cache_compression_changed, $valid_nonce, $cache_path;
295 if( $super_cache_enabled == false )
296 return;
297 ?>
298 <br /><fieldset class="options">
299 <h3>Super Cache Compression</h3>
300 <form name="wp_manager" action="<?php echo $_SERVER["REQUEST_URI"]; ?>" method="post">
301 <label><input type="radio" name="cache_compression" value="1" <?php if( $cache_compression ) { echo "checked=checked"; } ?>> Enabled</label>
302 <label><input type="radio" name="cache_compression" value="0" <?php if( !$cache_compression ) { echo "checked=checked"; } ?>> Disabled</label>
303 <p>Compression is disabled by default because some hosts have problems with compressed files. Switching this on and off clears the cache.</p>
304 <?php
305 if( isset( $cache_compression_changed ) && isset( $_POST[ 'cache_compression' ] ) && !$cache_compression ) {
306 ?><p><strong>Super Cache compression is now disabled.</strong></p> <?php
307 } elseif( isset( $cache_compression_changed ) && isset( $_POST[ 'cache_compression' ] ) && $cache_compression ) {
308 ?><p><strong>Super Cache compression is now enabled.</strong></p><?php
309 }
310 echo '<div><input ' . SUBMITDISABLED . 'type="submit" value="Update Compression &raquo;" /></div>';
311 wp_nonce_field('wp-cache');
312 echo "</form>\n";
313 ?></fieldset><br />
314
315 <a name="modrewrite"></a><fieldset class="options">
316 <h3>Mod Rewrite Rules</h3><?php
317 $home_path = get_home_path();
318 $home_root = parse_url(get_bloginfo('url'));
319 $home_root = trailingslashit($home_root['path']);
320 $inst_root = parse_url(get_bloginfo('wpurl'));
321 $inst_root = trailingslashit($inst_root['path']);
322 $wprules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WordPress' ) );
323 $wprules = str_replace( "RewriteEngine On\n", '', $wprules );
324 $wprules = str_replace( "RewriteBase $home_root\n", '', $wprules );
325 $scrules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WPSuperCache' ) );
326
327 if( substr( get_option( 'permalink_structure' ), -1 ) == '/' ) {
328 $condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*[^/]$";
329 $condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*//.*$";
330 }
331 $condition_rules[] = "RewriteCond %{REQUEST_METHOD} !=POST";
332 $condition_rules[] = "RewriteCond %{QUERY_STRING} !.*=.*";
333 $condition_rules[] = "RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress|wp-postpass_).*$";
334 $condition_rules = apply_filters( 'supercacherewriteconditions', $condition_rules );
335
336 $rules = "<IfModule mod_rewrite.c>\n";
337 $rules .= "RewriteEngine On\n";
338 $rules .= "RewriteBase $home_root\n"; // props Chris Messina
339 $charset = get_option('blog_charset') == '' ? 'UTF-8' : get_option('blog_charset');
340 $rules .= "AddDefaultCharset {$charset}\n";
341 $rules .= "CONDITION_RULES";
342 $rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n";
343 $rules .= "RewriteCond %{DOCUMENT_ROOT}{$inst_root}wp-content/cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html.gz -f\n";
344 $rules .= "RewriteRule ^(.*) {$inst_root}wp-content/cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html.gz [L]\n\n";
345
346 $rules .= "CONDITION_RULES";
347 $rules .= "RewriteCond %{DOCUMENT_ROOT}{$inst_root}wp-content/cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html -f\n";
348 $rules .= "RewriteRule ^(.*) {$inst_root}wp-content/cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html [L]\n";
349 $rules .= "</IfModule>\n";
350 $rules = apply_filters( 'supercacherewriterules', $rules );
351
352 $rules = str_replace( "CONDITION_RULES", implode( "\n", $condition_rules ) . "\n", $rules );
353
354 $dohtaccess = true;
355 if( function_exists( 'is_site_admin' ) ) {
356 echo "<h4 style='color: #a00'>WordPress MU Detected</h4><p>Unfortunately the rewrite rules cannot be updated automatically when running WordPress MU. Please open your .htaccess and add the following mod_rewrite rules above any other rules in that file.</p>";
357 } elseif( !$wprules || $wprules == '' ) {
358 echo "<h4 style='color: #a00'>Mod Rewrite rules cannot be updated!</h4>";
359 echo "<p>You must have <strong>BEGIN</strong> and <strong>END</strong> markers in {$home_path}.htaccess for the auto update to work. They look like this and surround the main WordPress mod_rewrite rules:
360 <blockquote><code><em># BEGIN WordPress</em><br /> RewriteCond %{REQUEST_FILENAME} !-f<br /> RewriteCond %{REQUEST_FILENAME} !-d<br /> RewriteRule . /index.php [L]<br /> <em># END WordPress</em></code></blockquote>
361 Refresh this page when you have updated your .htaccess file.";
362 echo "</fieldset></div>";
363 return;
364 } elseif( strpos( $wprules, 'wordpressuser' ) ) { // Need to clear out old mod_rewrite rules
365 echo "<p><strong>Thank you for upgrading.</strong> The mod_rewrite rules changed since you last installed this plugin. Unfortunately you must remove the old supercache rules before the new ones are updated. Refresh this page when you have edited your .htaccess file. If you wish to manually upgrade, change the following line: <blockquote><code>RewriteCond %{HTTP_COOKIE} !^.*wordpressuser.*\$</code></blockquote> so it looks like this: <blockquote><code>RewriteCond %{HTTP:Cookie} !^.*wordpress.*\$</code></blockquote> The only changes are 'HTTP_COOKIE' becomes 'HTTP:Cookie' and 'wordpressuser' becomes 'wordpress'. This is a WordPress 2.5 change but it's backwards compatible with older versions if you're brave enough to use them.</p>";
366 echo "</fieldset></div>";
367 return;
368 } elseif( $scrules != '' && strpos( $scrules, '%{REQUEST_URI} !^.*[^/]$' ) === false && substr( get_option( 'permalink_structure' ), -1 ) == '/' ) { // permalink structure has a trailing slash, need slash check in rules.
369 echo "<div style='padding: 2px; background: #ff0'><h4>Trailing slash check required.</h4><p>It looks like your blog has URLs that end with a '/'. Unfortunately since you installed this plugin a duplicate content bug has been found where URLs not ending in a '/' end serve the same content as those with the '/' and do not redirect to the proper URL.<br />";
370 echo "To fix, you must edit your .htaccess file and add these two rules to the two groups of Super Cache rules:</p>";
371 echo "<blockquote><code>RewriteCond %{REQUEST_URI} !^.*[^/]$<br />RewriteCond %{REQUEST_URI} !^.*//.*$<br /></code></blockquote>";
372 echo "<p>You can see where the rules go and examine the complete rules by clicking the 'View mod_rewrite rules' link below.</p></div>";
373 $dohtaccess = false;
374 } elseif( strpos( $scrules, 'supercache' ) || strpos( $wprules, 'supercache' ) ) { // only write the rules once
375 $dohtaccess = false;
376 }
377 if( $dohtaccess && !$_POST[ 'updatehtaccess' ] ) {
378 if( !is_writeable_ACLSafe( $home_path . ".htaccess" ) ) {
379 echo "<div style='padding: 2px; background: #ff0'><h4>Cannot update .htaccess</h4><p>The file <code>{$home_path}.htaccess</code> cannot be modified by the web server. Please correct this using the chmod command or your ftp client.</p><p>Refresh this page when the file permissions have been modified.</p><p>Alternatively, you can edit your <code>{$home_path}.htaccess</code> file manually and add the following code (before any WordPress rules):</p>";
380 echo "<p><pre># BEGIN WPSuperCache\n" . wp_specialchars( $rules ) . "# END WPSuperCache</pre></p></div>";
381 } else {
382 echo "<div style='padding: 2px; background: #ff0'><p>To serve static html files your server must have the correct mod_rewrite rules added to a file called <code>{$home_path}.htaccess</code><br /> This can be done automatically by clicking the <em>'Update mod_rewrite rules &raquo;'</em> button or you can edit the file yourself and add the following rules. Make sure they appear before any existing WordPress rules.";
383 echo "<pre># BEGIN WPSuperCache\n" . wp_specialchars( $rules ) . "# END WPSuperCache</pre></p>";
384 echo '<form name="updatehtaccess" action="'. $_SERVER["REQUEST_URI"] . '#modrewrite" method="post">';
385 echo '<input type="hidden" name="updatehtaccess" value="1" />';
386 echo '<div><input type="submit" ' . SUBMITDISABLED . 'id="updatehtaccess" value="Update mod_rewrite rules &raquo;" /></div>';
387 wp_nonce_field('wp-cache');
388 echo "</form></div>\n";
389 }
390 } elseif( $dohtaccess && $valid_nonce && $_POST[ 'updatehtaccess' ] ) {
391 wpsc_remove_marker( $home_path.'.htaccess', 'WordPress' ); // remove original WP rules so SuperCache rules go on top
392 echo "<div style='padding: 2px; background: #ff0'>";
393 if( insert_with_markers( $home_path.'.htaccess', 'WPSuperCache', explode( "\n", $rules ) ) && insert_with_markers( $home_path.'.htaccess', 'WordPress', explode( "\n", $wprules ) ) ) {
394 echo "<h4>Mod Rewrite rules updated!</h4>";
395 echo "<p><strong>{$home_path}.htaccess has been updated with the necessary mod_rewrite rules. Please verify they are correct. They should look like this:</strong></p>\n";
396 } else {
397 echo "<h4>Mod Rewrite rules must be updated!</h4>";
398 echo "<p><strong> Your {$home_path}.htaccess is not writable by the webserver and must be updated with the necessary mod_rewrite rules. The new rules go above the regular WordPress rules as shown in the code below:</strong></p>\n";
399 }
400 echo "<p><pre>" . wp_specialchars( $rules ) . "</pre></p>\n</div>";
401 } else {
402 ?>
403 <p>WP Super Cache mod rewrite rules were detected in your <?php echo $home_path ?>.htaccess file. Click the following link to see the lines added to that file. If you have upgraded the plugin make sure these rules match. <a href="javascript:toggleLayer('rewriterules');" title="See your mod_rewrite rules">View mod_rewrite rules</a>
404 <div id='rewriterules' style='display: none;'>
405 <?php echo "<p><pre># BEGIN WPSuperCache\n" . wp_specialchars( $rules ) . "# END WPSuperCache</pre></p>\n"; ?>
406 </div>
407 <?php
408 }
409 // http://allmybrain.com/2007/11/08/making-wp-super-cache-gzip-compression-work/
410 if( !is_file( $cache_path . '.htaccess' ) ) {
411 $gziprules = "<IfModule mod_mime.c>\n AddEncoding x-gzip .gz\n AddType text/html .gz\n</IfModule>\n";
412 $gziprules .= "<IfModule mod_deflate.c>\n SetEnvIfNoCase Request_URI \.gz$ no-gzip\n</IfModule>\n";
413 $gziprules .= "<IfModule mod_headers.c>\n Header set Cache-Control 'max-age=300, must-revalidate'\n</IfModule>\n";
414 $gziprules .= "<IfModule mod_expires.c>\n ExpiresActive On\n ExpiresByType text/html A300\n</IfModule>\n";
415 $gziprules = insert_with_markers( $cache_path . '.htaccess', 'supercache', explode( "\n", $gziprules ) );
416 echo "<h4>Gzip encoding rules in {$cache_path}.htaccess created.</h4>";
417 }
418
419 ?></fieldset><?php
420 }
421
422 function wp_cache_restore() {
423 echo '<br /><fieldset class="options"><h3>Configuration messed up?</h3>';
424 echo '<form name="wp_restore" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
425 echo '<input type="hidden" name="wp_restore_config" />';
426 echo '<div><input type="submit" ' . SUBMITDISABLED . 'id="deletepost" value="Restore default configuration &raquo;" /></div>';
427 wp_nonce_field('wp-cache');
428 echo "</form>\n";
429 echo '</fieldset>';
430
431 }
432
433 function comment_form_lockdown_message() {
434 ?><p><?php _e( "Comment moderation is enabled. Your comment may take some time to appear." ); ?></p><?php
435 }
436 if( defined( 'WPLOCKDOWN' ) && constant( 'WPLOCKDOWN' ) )
437 add_action( 'comment_form', 'comment_form_lockdown_message' );
438
439 function wp_lock_down() {
440 global $wpdb, $cache_path, $wp_cache_config_file, $valid_nonce, $cached_direct_pages, $cache_enabled, $super_cache_enabled;
441
442 if(isset($_POST['wp_lock_down']) && $valid_nonce) {
443 $wp_lock_down = $_POST['wp_lock_down'] == '1' ? '1' : '0';
444 wp_cache_replace_line('^.*WPLOCKDOWN', "define( 'WPLOCKDOWN', '$wp_lock_down' );", $wp_cache_config_file);
445 if( $wp_lock_down == '0' && function_exists( 'prune_super_cache' ) )
446 prune_super_cache( $cache_path, true ); // clear the cache after lockdown
447
448 }
449 if( !isset( $wp_lock_down ) ) {
450 if( defined( 'WPLOCKDOWN' ) ) {
451 $wp_lock_down = constant( 'WPLOCKDOWN' );
452 } else {
453 $wp_lock_down = '0';
454 }
455 }
456 ?><br /><br /><fieldset class="options">
457 <h3>Lock Down: <span style='color: #f00'><?php echo $wp_lock_down == '0' ? 'disabled' : 'enabled'; ?></span> (advanced use only)</h3>
458 <p>Prepare your server for an expected spike in traffic by enabling the lock down. When this is enabled, new comments on a post will not refresh the cached static files.</p>
459 <p>Developers: Make your plugin lock down compatible by checking the 'WPLOCKDOWN' constant. The following code will make sure your plugin respects the WPLOCKDOWN setting.
460 <blockquote><code>if( defined( 'WPLOCKDOWN' ) && constant( 'WPLOCKDOWN' ) ) { <br />
461 &nbsp;&nbsp;&nbsp;&nbsp;echo "Sorry. My blog is locked down. Updates will appear shortly";<br />
462 }</code></blockquote>
463 <?php
464 if( $wp_lock_down == '1' ) {
465 ?><strong>WordPress is locked down. Super Cache static files will not be deleted when new comments are made.</strong><?php
466 } else {
467 ?><strong>WordPress is not locked down. New comments will refresh Super Cache static files as normal.</strong><?php
468 }
469 $new_lockdown = $wp_lock_down == '1' ? '0' : '1';
470 $new_lockdown_desc = $wp_lock_down == '1' ? 'Disable' : 'Enable';
471 echo '<form name="wp_lock_down" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
472 echo "<input type='hidden' name='wp_lock_down' value='{$new_lockdown}' />";
473 echo "<div><input type='submit' " . SUBMITDISABLED . " value='{$new_lockdown_desc} Lock Down &raquo;' /></div>";
474 wp_nonce_field('wp-cache');
475 echo "</form>\n";
476
477 ?></fieldset><br /><?php
478 if( $cache_enabled == true && $super_cache_enabled == true ) {
479 ?><fieldset class="options">
480 <h3>Directly Cached Files (advanced use only)</h3><?php
481
482 $out = '';
483 if( $valid_nonce && is_array( $_POST[ 'direct_pages' ] ) && !empty( $_POST[ 'direct_pages' ] ) ) {
484 $expiredfiles = array_diff( $cached_direct_pages, $_POST[ 'direct_pages' ] );
485 unset( $cached_direct_pages );
486 foreach( $_POST[ 'direct_pages' ] as $page ) {
487 $page = $wpdb->escape( $page );
488 if( $page != '' ) {
489 $cached_direct_pages[] = $page;
490 $out .= "'$page', ";
491 }
492 }
493 if( $out == '' ) {
494 $out = "'', ";
495 }
496 }
497 if( $valid_nonce && $_POST[ 'new_direct_page' ] && '' != $_POST[ 'new_direct_page' ] ) {
498 $page = str_replace( get_option( 'siteurl' ), '', $_POST[ 'new_direct_page' ] );
499 if( substr( $page, 0, 1 ) != '/' )
500 $page = '/' . $page;
501 $page = $wpdb->escape( $page );
502 if( in_array( $page, $cached_direct_pages ) == false ) {
503 $cached_direct_pages[] = $page;
504 $out .= "'$page', ";
505 }
506 }
507
508 if( $out != '' ) {
509 $out = substr( $out, 0, -2 );
510 $out = '$cached_direct_pages = array( ' . $out . ' );';
511 wp_cache_replace_line('^ *\$cached_direct_pages', "$out", $wp_cache_config_file);
512 prune_super_cache( $cache_path, true );
513 }
514
515 if( !empty( $expiredfiles ) ) {
516 foreach( $expiredfiles as $file ) {
517 if( $file != '' ) {
518 $firstfolder = explode( '/', $file );
519 $firstfolder = ABSPATH . $firstfolder[1];
520 $file = ABSPATH . $file;
521 @unlink( trailingslashit( $file ) . 'index.html' );
522 @unlink( trailingslashit( $file ) . 'index.html.gz' );
523 RecursiveFolderDelete( trailingslashit( $firstfolder ) );
524 }
525 }
526 }
527
528 if( $valid_nonce && $_POST[ 'deletepage' ] ) {
529 $page = preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', str_replace( '..', '', $_POST['deletepage']) );
530 $pagefile = ABSPATH . $page . 'index.html';
531 $firstfolder = explode( '/', $page );
532 $firstfolder = ABSPATH . $firstfolder[1];
533 $page = ABSPATH . $page;
534 if( is_file( $pagefile ) && is_writeable_ACLSafe( $pagefile ) && is_writeable_ACLSafe( $firstfolder ) ) {
535 @unlink( $pagefile );
536 @unlink( $pagefile . '.gz' );
537 RecursiveFolderDelete( $firstfolder );
538 echo "<strong>$pagefile removed!</strong><br />";
539 prune_super_cache( $cache_path, true );
540 }
541 }
542
543 $readonly = '';
544 if( !is_writeable_ACLSafe( ABSPATH ) ) {
545 $readonly = 'READONLY';
546 ?><p><strong style='color: #a00'>WARNING! You must make <?php echo ABSPATH ?> writable to enable this feature. As this is a security risk please make it readonly after your page is generated.</strong></p><?php
547 } else {
548 ?><p><strong style='color: #a00'>WARNING! <?php echo ABSPATH ?> is writable. Please make it readonly after your page is generated as this is a security risk.</strong></p><?php
549 }
550 echo '<form name="direct_page" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
551 if( is_array( $cached_direct_pages ) ) {
552 $out = '';
553 foreach( $cached_direct_pages as $page ) {
554 if( $page == '' )
555 continue;
556 $generated = '';
557 if( is_file( ABSPATH . $page . '/index.html' ) )
558 $generated = '<input type="Submit" name="deletepage" value="' . $page . '">';
559 $out .= "<tr><td><input type='text' $readonly name='direct_pages[]' size='30' value='$page' /></td><td>$generated</td></tr>";
560 }
561 if( $out != '' ) {
562 ?><table><tr><th>Existing direct page</th><th>Delete cached file</th></tr><?php
563 echo "$out</table>";
564 }
565 }
566 if( $readonly != 'READONLY' )
567 echo "Add direct page: <input type='text' $readonly name='new_direct_page' size='30' value='' /><br />";
568
569 echo "<p>Directly cached files are files created directly off " . ABSPATH . " where your blog lives. This feature is only useful if you are expecting a major Digg or Slashdot level of traffic to one post or page.</p>";
570 if( $readonly != 'READONLY' ) {
571 echo "<p>For example: to cache <em>'" . trailingslashit( get_option( 'siteurl' ) ) . "about/'</em>, you would enter '" . trailingslashit( get_option( 'siteurl' ) ) . "about/' or '/about/'. The cached file will be generated the next time an anonymous user visits that page.</p>";
572 echo "<p>Make the textbox blank to remove it from the list of direct pages and delete the cached file.</p>";
573 }
574
575 wp_nonce_field('wp-cache');
576 if( $readonly != 'READONLY' )
577 echo "<div><input type='submit' ' . SUBMITDISABLED . 'value='Update direct pages &raquo;' /></div>";
578 echo "</form>\n";
579 ?></fieldset><?php
580 } // if $super_cache_enabled
581 }
582
583 function RecursiveFolderDelete ( $folderPath ) { // from http://www.php.net/manual/en/function.rmdir.php
584 if( trailingslashit( constant( 'ABSPATH' ) ) == trailingslashit( $folderPath ) )
585 return false;
586 if ( @is_dir ( $folderPath ) ) {
587 $dh = @opendir($folderPath);
588 while (false !== ($value = @readdir($dh))) {
589 if ( $value != "." && $value != ".." ) {
590 $value = $folderPath . "/" . $value;
591 if ( @is_dir ( $value ) ) {
592 RecursiveFolderDelete ( $value );
593 }
594 }
595 }
596 return @rmdir ( $folderPath );
597 } else {
598 return FALSE;
599 }
600 }
601
602 function wp_cache_edit_max_time () {
603 global $cache_max_time, $wp_cache_config_file, $valid_nonce, $cache_enabled, $super_cache_enabled, $wp_cache_gc;
604
605 if( !isset( $cache_max_time ) )
606 $cache_max_time = 3600;
607
608 if(isset($_POST['wp_max_time']) && $valid_nonce) {
609 $max_time = (int)$_POST['wp_max_time'];
610 if ($max_time > 0) {
611 $cache_max_time = $max_time;
612 wp_cache_replace_line('^ *\$cache_max_time', "\$cache_max_time = $cache_max_time;", $wp_cache_config_file);
613 }
614 }
615 if(isset($_POST['wp_cache_gc']) && $valid_nonce) {
616 $wp_cache_gc = (int)$_POST['wp_cache_gc'];
617 wp_cache_replace_line('^ *\$wp_cache_gc', "\$wp_cache_gc = $wp_cache_gc;", $wp_cache_config_file);
618 }
619 ?><br /><fieldset class="options">
620 <h3>Expiry Time and Garbage Collection</h3><?php
621 echo '<form name="wp_edit_max_time" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
622 echo '<label for="wp_max_time">Expire time:</label> ';
623 echo "<input type=\"text\" size=6 name=\"wp_max_time\" value=\"$cache_max_time\" /> seconds<br />";
624 if( !isset( $wp_cache_gc ) )
625 $wp_cache_gc = 1000;
626 echo "<h4>Garbage Collection</h4><p>How often should expired files be deleted? Once every:</p>";
627 echo "<ul><li><input type='radio' name='wp_cache_gc' value='1000'" . ( $wp_cache_gc == 1000 ? ' checked=checked' : '' ) . " /> 1000 requests</li>\n";
628 echo "<li><input type='radio' name='wp_cache_gc' value='2000'" . ( $wp_cache_gc == 2000 ? ' checked=checked' : '' ) . " /> 2000 requests</li>\n";
629 echo "<li><input type='radio' name='wp_cache_gc' value='5000'" . ( $wp_cache_gc == 5000 ? ' checked=checked' : '' ) . " /> 5000 requests</li></ul>\n";
630 echo "<p>Checking for and deleting expired files is expensive, but it's expensive leaving them there too. On a very busy site you can leave this fairly high. Experiment with different values and visit this page to see how many expired files remain at different times during the day.</p><p>Simple rule of thumb: divide your number of daily page views by 5 and pick the closest number above.</p>";
631 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="Change expiration &raquo;" /></div>';
632 wp_nonce_field('wp-cache');
633 echo "</form>\n";
634 ?></fieldset><?php
635 }
636
637 function wp_cache_sanitize_value($text, & $array) {
638 $text = wp_specialchars(strip_tags($text));
639 $array = preg_split("/[\s,]+/", chop($text));
640 $text = var_export($array, true);
641 $text = preg_replace('/[\s]+/', ' ', $text);
642 return $text;
643 }
644
645 // from tehjosh at gamingg dot net http://uk2.php.net/manual/en/function.apache-request-headers.php#73964
646 // fixed bug in second substr()
647 if( !function_exists('apache_request_headers') ) {
648 function apache_request_headers() {
649 $headers = array();
650 foreach(array_keys($_SERVER) as $skey) {
651 if(substr($skey, 0, 5) == "HTTP_") {
652 $headername = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($skey, 5)))));
653 $headers[$headername] = $_SERVER[$skey];
654 }
655 }
656 return $headers;
657 }
658 }
659
660 function wp_cache_edit_rejected_ua() {
661 global $cache_rejected_user_agent, $wp_cache_config_file, $valid_nonce;
662
663 if (!function_exists('apache_request_headers')) return;
664
665 if(isset($_REQUEST['wp_rejected_user_agent']) && $valid_nonce) {
666 $text = wp_cache_sanitize_value($_REQUEST['wp_rejected_user_agent'], $cache_rejected_user_agent);
667 wp_cache_replace_line('^ *\$cache_rejected_user_agent', "\$cache_rejected_user_agent = $text;", $wp_cache_config_file);
668 }
669
670
671 echo '<br /><a name="user-agents"></a><fieldset class="options"><h3>Rejected User Agents</h3>';
672 echo "<p>Strings in the HTTP 'User Agent' header that prevent WP-Cache from
673 caching bot, spiders, and crawlers' requests.
674 Note that cached files are still sent to these request if they already exists.</p>\n";
675 echo '<form name="wp_edit_rejected_user_agent" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
676 echo '<label for="wp_rejected_user_agent"><h4>Rejected UA strings</h4></label>';
677 echo '<textarea name="wp_rejected_user_agent" cols="40" rows="4" style="width: 50%; font-size: 12px;" class="code">';
678 foreach ($cache_rejected_user_agent as $ua) {
679 echo wp_specialchars($ua) . "\n";
680 }
681 echo '</textarea> ';
682 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="Save UA strings &raquo;" /></div>';
683 wp_nonce_field('wp-cache');
684 echo '</form>';
685 echo "</fieldset>\n";
686 }
687
688
689 function wp_cache_edit_rejected() {
690 global $cache_acceptable_files, $cache_rejected_uri, $wp_cache_config_file, $valid_nonce;
691
692 if(isset($_REQUEST['wp_rejected_uri']) && $valid_nonce) {
693 $text = wp_cache_sanitize_value($_REQUEST['wp_rejected_uri'], $cache_rejected_uri);
694 wp_cache_replace_line('^ *\$cache_rejected_uri', "\$cache_rejected_uri = $text;", $wp_cache_config_file);
695 }
696
697
698 echo '<form name="wp_edit_rejected" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
699 echo '<label for="wp_rejected_uri"><h4>Rejected URIs</h4></label>';
700 echo "<p>Add here strings (not a filename) that forces a page not to be cached. For example, if your URLs include year and you dont want to cache last year posts, it's enough to specify the year, i.e. '/2004/'. WP-Cache will search if that string is part of the URI and if so, it will not cache that page.</p>\n";
701 echo '<textarea name="wp_rejected_uri" cols="40" rows="4" style="width: 50%; font-size: 12px;" class="code">';
702 foreach ($cache_rejected_uri as $file) {
703 echo wp_specialchars($file) . "\n";
704 }
705 echo '</textarea> ';
706 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="Save strings &raquo;" /></div>';
707 wp_nonce_field('wp-cache');
708 echo "</form>\n";
709 }
710
711 function wp_cache_edit_accepted() {
712 global $cache_acceptable_files, $cache_rejected_uri, $wp_cache_config_file, $valid_nonce;
713
714 if(isset($_REQUEST['wp_accepted_files']) && $valid_nonce) {
715 $text = wp_cache_sanitize_value($_REQUEST['wp_accepted_files'], $cache_acceptable_files);
716 wp_cache_replace_line('^ *\$cache_acceptable_files', "\$cache_acceptable_files = $text;", $wp_cache_config_file);
717 }
718
719
720 echo '<br clear="all" /><form name="wp_edit_accepted" action="'. $_SERVER["REQUEST_URI"] . '" method="post">';
721 echo '<h4>Accepted files</h4>';
722 echo "<p>Add here those filenames that can be cached, even if they match one of the rejected substring specified above.</p>\n";
723 echo '<textarea name="wp_accepted_files" cols="40" rows="8" style="width: 50%; font-size: 12px;" class="code">';
724 foreach ($cache_acceptable_files as $file) {
725 echo wp_specialchars($file) . "\n";
726 }
727 echo '</textarea> ';
728 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="Save files &raquo;" /></div>';
729 wp_nonce_field('wp-cache');
730 echo "</form>\n";
731 }
732
733 function wp_cache_enable() {
734 global $wp_cache_config_file, $cache_enabled, $supercachedir;
735
736 if(get_option('gzipcompression')) {
737 echo "<b>Error: GZIP compression is enabled, disable it if you want to enable wp-cache.</b><br /><br />";
738 return false;
739 }
740 if( wp_cache_replace_line('^ *\$cache_enabled', '$cache_enabled = true;', $wp_cache_config_file) ) {
741 $cache_enabled = true;
742 }
743 wp_super_cache_enable();
744 }
745
746 function wp_cache_disable() {
747 global $cache_path, $wp_cache_config_file, $cache_enabled, $supercachedir, $cache_path;
748
749 if (wp_cache_replace_line('^ *\$cache_enabled', '$cache_enabled = false;', $wp_cache_config_file)) {
750 $cache_enabled = false;
751 }
752 wp_super_cache_disable();
753 sleep( 1 ); // allow existing processes to write to the supercachedir and then delete it
754 if (function_exists ('prune_super_cache') && is_dir( $supercachedir ) ) {
755 prune_super_cache( $cache_path, true );
756 }
757 }
758 function wp_super_cache_enable() {
759 global $supercachedir, $wp_cache_config_file, $super_cache_enabled;
760
761 if( is_dir( $supercachedir . ".disabled" ) )
762 rename( $supercachedir . ".disabled", $supercachedir );
763 wp_cache_replace_line('^ *\$super_cache_enabled', '$super_cache_enabled = true;', $wp_cache_config_file);
764 $super_cache_enabled = true;
765 }
766
767 function wp_super_cache_disable() {
768 global $supercachedir, $wp_cache_config_file, $super_cache_enabled;
769
770 wp_cache_replace_line('^ *\$super_cache_enabled', '$super_cache_enabled = false;', $wp_cache_config_file);
771 if( is_dir( $supercachedir ) )
772 rename( $supercachedir, $supercachedir . ".disabled" );
773 $super_cache_enabled = false;
774 }
775
776 function wp_cache_is_enabled() {
777 global $wp_cache_config_file;
778
779 if(get_option('gzipcompression')) {
780 echo "<b>Warning</b>: GZIP compression is enabled in Wordpress, wp-cache will be bypassed until you disable gzip compression.<br />";
781 return false;
782 }
783 $lines = file($wp_cache_config_file);
784 foreach($lines as $line) {
785 if (preg_match('/^ *\$cache_enabled *= *true *;/', $line))
786 return true;
787 }
788 return false;
789 }
790
791
792 function wp_cache_replace_line($old, $new, $my_file) {
793 if (!is_writeable_ACLSafe($my_file)) {
794 echo "Error: file $my_file is not writable.<br />\n";
795 return false;
796 }
797 $found = false;
798 $lines = file($my_file);
799 foreach($lines as $line) {
800 if ( preg_match("/$old/", $line)) {
801 $found = true;
802 break;
803 }
804 }
805 if ($found) {
806 $fd = fopen($my_file, 'w');
807 foreach($lines as $line) {
808 if ( !preg_match("/$old/", $line))
809 fputs($fd, $line);
810 else {
811 fputs($fd, "$new //Added by WP-Cache Manager\n");
812 }
813 }
814 fclose($fd);
815 return true;
816 }
817 $fd = fopen($my_file, 'w');
818 $done = false;
819 foreach($lines as $line) {
820 if ( $done || !preg_match('/^define|\$|\?>/', $line))
821 fputs($fd, $line);
822 else {
823 fputs($fd, "$new //Added by WP-Cache Manager\n");
824 fputs($fd, $line);
825 $done = true;
826 }
827 }
828 fclose($fd);
829 return true;
830 /*
831 copy($my_file, $my_file . "-prev");
832 rename($my_file . '-new', $my_file);
833 */
834 }
835
836 function wp_cache_verify_cache_dir() {
837 global $cache_path;
838
839 $dir = dirname($cache_path);
840 if ( !file_exists($cache_path) ) {
841 if ( !is_writeable_ACLSafe( $dir ) || !($dir = mkdir( $cache_path ) ) ) {
842 echo "<b>Error:</b> Your cache directory (<b>$cache_path</b>) did not exist and couldn't be created by the web server. <br /> Check $dir permissions.";
843 return false;
844 }
845 }
846 if ( !is_writeable_ACLSafe($cache_path)) {
847 echo "<b>Error:</b> Your cache directory (<b>$cache_path</b>) or <b>$dir</b> need to be writable for this plugin to work. <br /> Double-check it.";
848 return false;
849 }
850
851 if ( '/' != substr($cache_path, -1)) {
852 $cache_path .= '/';
853 }
854
855 @mkdir( $cache_path . 'meta' );
856
857 return true;
858 }
859
860 function wp_cache_verify_config_file() {
861 global $wp_cache_config_file, $wp_cache_config_file_sample, $sem_id, $cache_path;
862
863 $new = false;
864 $dir = dirname($wp_cache_config_file);
865
866 if ( file_exists($wp_cache_config_file) ) {
867 $lines = join( ' ', file( $wp_cache_config_file ) );
868 if( strpos( $lines, 'WPCACHEHOME' ) === false ) {
869 if( is_writeable_ACLSafe( $wp_cache_config_file ) ) {
870 @unlink( $wp_cache_config_file );
871 } else {
872 echo "<b>Error:</b> Your WP-Cache config file (<b>$wp_cache_config_file</b>) is out of date and not writable by the Web server.<br />Please delete it and refresh this page.";
873 return false;
874 }
875 }
876 } elseif( !is_writeable_ACLSafe($dir)) {
877 echo "<b>Error:</b> Configuration file missing and " . WP_CONTENT_DIR . " directory (<b>$dir</b>) is not writable by the Web server.<br />Check its permissions.";
878 return false;
879 }
880
881 if ( !file_exists($wp_cache_config_file) ) {
882 if ( !file_exists($wp_cache_config_file_sample) ) {
883 echo "<b>Error:</b> Sample WP-Cache config file (<b>$wp_cache_config_file_sample</b>) does not exist.<br />Verify you installation.";
884 return false;
885 }
886 copy($wp_cache_config_file_sample, $wp_cache_config_file);
887 if( is_file( dirname(__FILE__) . '/wp-cache-config-sample.php' ) ) {
888 wp_cache_replace_line('WPCACHEHOME', "define( 'WPCACHEHOME', ABSPATH . " . str_replace( '\\', '/', str_replace( ABSPATH, ' "', dirname(__FILE__) ) ) . "/\" );", $wp_cache_config_file);
889 } elseif( is_file( dirname(__FILE__) . '/wp-super-cache/wp-cache-config-sample.php' ) ) {
890 wp_cache_replace_line('WPCACHEHOME', "define( 'WPCACHEHOME', ABSPATH . " . str_replace( '\\', '/', str_replace( ABSPATH, ' "', dirname(__FILE__) ) ) . "/wp-super-cache/\" );", $wp_cache_config_file);
891 }
892 $new = true;
893 }
894 if( $sem_id == 5419 && $cache_path != '' ) {
895 $sem_id = crc32( $_SERVER[ 'HTTP_HOST' ] . $cache_path ) & 0x7fffffff;
896 wp_cache_replace_line('sem_id', '$sem_id = ' . $sem_id . ';', $wp_cache_config_file);
897 }
898 require($wp_cache_config_file);
899 return true;
900 }
901
902 function wp_cache_check_link() {
903 global $wp_cache_link, $wp_cache_file;
904
905 if( file_exists($wp_cache_link) ) {
906 if( strpos( join( "\n", file( $wp_cache_link ) ), 'WPCACHEHOME' ) ) {
907 // read the file and verify it's a super-cache file and not the wp-cache one.
908 return true;
909 } else {
910 // remove the old version
911 @unlink($wp_cache_link);
912 }
913 }
914
915 $ret = true;
916 if ( basename(@readlink($wp_cache_link)) != basename($wp_cache_file)) {
917 @unlink($wp_cache_link);
918 if( function_exists( 'symlink' ) ) {
919 if( !@symlink ($wp_cache_file, $wp_cache_link) ) {
920 $ret = false;
921 }
922 } elseif( !@copy( $wp_cache_file, $wp_cache_link ) ) {
923 $ret = false;
924 }
925 if( !$ret ) {
926 echo "<code>advanced-cache.php</code> does not exist<br />";
927 echo "Create it by executing: <br /><code>ln -s $wp_cache_file $wp_cache_link</code><br /> in your server<br />";
928 echo "Or by copying $wp_cache_file to $wp_cache_link.<br />";
929 return false;
930 }
931 }
932 return true;
933 }
934
935 function wp_cache_check_global_config() {
936
937 if ( file_exists( ABSPATH . 'wp-config.php') ) {
938 $global = ABSPATH . 'wp-config.php';
939 } else {
940 $global = dirname(ABSPATH) . '/wp-config.php';
941 }
942
943 $lines = file($global);
944 foreach($lines as $line) {
945 if (preg_match('/^ *define *\( *\'WP_CACHE\' *, *true *\) *;/', $line)) {
946 return true;
947 }
948 }
949 $line = 'define(\'WP_CACHE\', true);';
950 if (!is_writeable_ACLSafe($global) || !wp_cache_replace_line('define *\( *\'WP_CACHE\'', $line, $global) ) {
951 echo "<b>Error: WP_CACHE is not enabled</b> in your <code>wp-config.php</code> file and I couldn't modified it.<br />";
952 echo "Edit <code>$global</code> and add the following line: <br /><code>define('WP_CACHE', true);</code><br />Otherwise, <b>WP-Cache will not be executed</b> by Wordpress core. <br />";
953 return false;
954 }
955 return true;
956 }
957
958 function wp_cache_files() {
959 global $cache_path, $file_prefix, $cache_max_time, $valid_nonce, $supercachedir, $cache_enabled, $super_cache_enabled;
960
961 if ( '/' != substr($cache_path, -1)) {
962 $cache_path .= '/';
963 }
964
965 if ( $valid_nonce ) {
966 if(isset($_REQUEST['wp_delete_cache'])) {
967 wp_cache_clean_cache($file_prefix);
968 }
969 if(isset($_REQUEST['wp_delete_cache_file'])) {
970 wp_cache_clean_cache($_REQUEST['wp_delete_cache_file']);
971 }
972 if(isset($_REQUEST['wp_delete_expired'])) {
973 wp_cache_clean_expired($file_prefix);
974 }
975 }
976 if(isset($_REQUEST['wp_list_cache'])) {
977 $list_files = true;
978 $list_mess = "Update list";
979 } else
980 $list_mess = "List files";
981
982 echo '<br /><a name="list"></a><fieldset class="options"><h3>Cache Contents</h3>';
983 /*
984 echo '<form name="wp_cache_content_list" action="'. $_SERVER["REQUEST_URI"] . '#list" method="post">';
985 echo '<input type="hidden" name="wp_list_cache" />';
986 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="'.$list_mess.' &raquo;" /></div>';
987 echo "</form>\n";
988 */
989
990 $list_files = false; // it doesn't list supercached files, and removing single pages is buggy
991 $count = 0;
992 $expired = 0;
993 $now = time();
994 if ( ($handle = @opendir( $cache_path . 'meta/' )) ) {
995 if ($list_files) echo "<table cellspacing=\"0\" cellpadding=\"5\">";
996 while ( false !== ($file = readdir($handle))) {
997 if ( preg_match("/^$file_prefix.*\.meta/", $file) ) {
998 $this_expired = false;
999 $content_file = preg_replace("/meta$/", "html", $file);
1000 $mtime = filemtime($cache_path . 'meta/' . $file);
1001 if ( ! ($fsize = @filesize($cache_path.$content_file)) )
1002 continue; // .meta does not exists
1003 $fsize = intval($fsize/1024);
1004 $age = $now - $mtime;
1005 if ( $age > $cache_max_time) {
1006 $expired++;
1007 $this_expired = true;
1008 }
1009 $count++;
1010 if ($list_files) {
1011 $meta = new CacheMeta;
1012 $meta = unserialize(file_get_contents($cache_path . 'meta/' . $file));
1013 echo $flip ? '<tr style="background: #EAEAEA;">' : '<tr>';
1014 $flip = !$flip;
1015 echo '<td><a href="http://' . $meta->uri . '" target="_blank" >';
1016 echo $meta->uri . "</a></td>";
1017 if ($this_expired) echo "<td><span style='color:red'>$age secs</span></td>";
1018 else echo "<td>$age secs</td>";
1019 echo "<td>$fsize KB</td>";
1020 echo '<td><form name="wp_delete_cache_file" action="'. $_SERVER["REQUEST_URI"] . '#list" method="post">';
1021 echo '<input type="hidden" name="wp_list_cache" />';
1022 echo '<input type="hidden" name="wp_delete_cache_file" value="'.preg_replace("/^(.*)\.meta$/", "$1", $file).'" />';
1023 echo '<div><input id="deletepost" ' . SUBMITDISABLED . 'type="submit" value="Remove" /></div>';
1024 wp_nonce_field('wp-cache');
1025 echo "</form></td></tr>\n";
1026 }
1027 }
1028 }
1029 closedir($handle);
1030 if ($list_files) echo "</table>";
1031 }
1032 if( $cache_enabled == true && $super_cache_enabled == true ) {
1033 $now = time();
1034 $sizes = array( 'expired' => 0, 'cached' => 0, 'ts' => 0 );
1035
1036 if (is_dir($supercachedir)) {
1037 $entries = glob($supercachedir. '/*');
1038 foreach( (array) $entries as $entry) {
1039 if ($entry != '.' && $entry != '..') {
1040 $sizes = wpsc_dirsize( $entry, $sizes );
1041 }
1042 }
1043 } else {
1044 if(is_file($supercachedir) && filemtime( $supercachedir ) + $cache_max_time <= $now )
1045 $sizes[ 'expired' ] ++;
1046 }
1047 $sizes[ 'ts' ] = time();
1048 }
1049
1050 echo "<p><h4>WP-Cache</h4></p>";
1051 echo "<ul><li>$count cached pages</li>";
1052 echo "<li>$expired expired pages</li></ul>";
1053 if( $cache_enabled == true && $super_cache_enabled == true ) {
1054 echo "<p><h4>WP-Super-Cache</h4></p>";
1055 echo "<ul><li>" . intval($sizes['cached']/2) . " cached pages</li>";
1056 $age = intval(($now - $sizes['ts'])/60);
1057 echo "<li>" . intval($sizes['expired']/2) . " expired pages.</li></ul>";
1058 }
1059
1060 echo '<form name="wp_cache_content_expired" action="'. $_SERVER["REQUEST_URI"] . '#list" method="post">';
1061 echo '<input type="hidden" name="wp_delete_expired" />';
1062 echo '<div><input type="submit" ' . SUBMITDISABLED . 'value="Delete expired &raquo;" /></div>';
1063 wp_nonce_field('wp-cache');
1064 echo "</form>\n";
1065
1066
1067 echo '<form name="wp_cache_content_delete" action="'. $_SERVER["REQUEST_URI"] . '#list" method="post">';
1068 echo '<input type="hidden" name="wp_delete_cache" />';
1069 echo '<div><input id="deletepost" type="submit" ' . SUBMITDISABLED . 'value="Delete cache &raquo;" /></div>';
1070 wp_nonce_field('wp-cache');
1071 echo "</form>\n";
1072
1073 echo '</fieldset>';
1074 }
1075
1076 function delete_cache_dashboard() {
1077 echo "<li><a href='" . wp_nonce_url( 'options-general.php?page=wpsupercache&wp_delete_cache=1#list', 'wp-cache' ) . "' target='_blank' title='Delete Super Cache cached files (opens in new window)'>Delete Cache</a></li>";
1078 }
1079 add_action( 'dashmenu', 'delete_cache_dashboard' );
1080
1081 function wpsc_dirsize($directory, $sizes) {
1082 global $cache_max_time;
1083 $now = time();
1084
1085 if (is_dir($directory)) {
1086 $entries = glob($directory. '/*');
1087 if( is_array( $entries ) && !empty( $entries ) ) foreach ($entries as $entry) {
1088 if ($entry != '.' && $entry != '..') {
1089 $sizes = wpsc_dirsize($entry, $sizes);
1090 }
1091 }
1092 } else {
1093 if(is_file($directory) ) {
1094 if( filemtime( $directory ) + $cache_max_time <= $now ) {
1095 $sizes[ 'expired' ]+=1;
1096 } else {
1097 $sizes[ 'cached' ]+=1;
1098 }
1099 }
1100 }
1101 return $sizes;
1102 }
1103
1104
1105 function wp_cache_clean_cache($file_prefix) {
1106 global $cache_path, $supercachedir;
1107
1108 // If phase2 was compiled, use its function to avoid race-conditions
1109 if(function_exists('wp_cache_phase2_clean_cache')) {
1110 if (function_exists ('prune_super_cache')) {
1111 if( is_dir( $supercachedir ) ) {
1112 prune_super_cache( $supercachedir, true );
1113 } elseif( is_dir( $supercachedir . '.disabled' ) ) {
1114 prune_super_cache( $supercachedir . '.disabled', true );
1115 }
1116 prune_super_cache( $cache_path, true );
1117 $_POST[ 'super_cache_stats' ] = 1; // regenerate super cache stats;
1118 }
1119 return wp_cache_phase2_clean_cache($file_prefix);
1120 }
1121
1122 $expr = "/^$file_prefix/";
1123 if ( ($handle = opendir( $cache_path )) ) {
1124 while ( false !== ($file = readdir($handle))) {
1125 if ( preg_match($expr, $file) ) {
1126 unlink($cache_path . $file);
1127 unlink($cache_path . 'meta/' . str_replace( '.html', '.term', $file ) );
1128 }
1129 }
1130 closedir($handle);
1131 }
1132 }
1133
1134 function wp_cache_clean_expired($file_prefix) {
1135 global $cache_path, $cache_max_time;
1136
1137 // If phase2 was compiled, use its function to avoid race-conditions
1138 if(function_exists('wp_cache_phase2_clean_expired')) {
1139 if (function_exists ('prune_super_cache')) {
1140 $dir = $cache_path . 'supercache/' . preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"]);
1141 if( is_dir( $dir ) ) {
1142 prune_super_cache( $dir );
1143 } elseif( is_dir( $dir . '.disabled' ) ) {
1144 prune_super_cache( $dir . '.disabled' );
1145 }
1146 $_POST[ 'super_cache_stats' ] = 1; // regenerate super cache stats;
1147 }
1148 return wp_cache_phase2_clean_expired($file_prefix);
1149 }
1150
1151 $expr = "/^$file_prefix/";
1152 $now = time();
1153 if ( ($handle = opendir( $cache_path )) ) {
1154 while ( false !== ($file = readdir($handle))) {
1155 if ( preg_match($expr, $file) &&
1156 (filemtime($cache_path . $file) + $cache_max_time) <= $now) {
1157 unlink($cache_path . $file);
1158 unlink($cache_path . 'meta/' . str_replace( '.html', '.term', $file ) );
1159 }
1160 }
1161 closedir($handle);
1162 }
1163 }
1164
1165 function wpsc_remove_marker( $filename, $marker ) {
1166 if (!file_exists( $filename ) || is_writeable_ACLSafe( $filename ) ) {
1167 if (!file_exists( $filename ) ) {
1168 return '';
1169 } else {
1170 $markerdata = explode( "\n", implode( '', file( $filename ) ) );
1171 }
1172
1173 $f = fopen( $filename, 'w' );
1174 $foundit = false;
1175 if ( $markerdata ) {
1176 $state = true;
1177 foreach ( $markerdata as $n => $markerline ) {
1178 if (strpos($markerline, '# BEGIN ' . $marker) !== false)
1179 $state = false;
1180 if ( $state ) {
1181 if ( $n + 1 < count( $markerdata ) )
1182 fwrite( $f, "{$markerline}\n" );
1183 else
1184 fwrite( $f, "{$markerline}" );
1185 }
1186 if (strpos($markerline, '# END ' . $marker) !== false) {
1187 $state = true;
1188 }
1189 }
1190 }
1191 return true;
1192 } else {
1193 return false;
1194 }
1195 }
1196
1197 function wp_super_cache_footer() {
1198 ?><p id='supercache'><?php bloginfo('name'); ?> is Digg proof thanks to caching by <a href="http://ocaoimh.ie/wp-super-cache/">WP Super Cache</a>!</p><?php
1199 }
1200 if( isset( $wp_cache_hello_world ) && $wp_cache_hello_world )
1201 add_action( 'wp_footer', 'wp_super_cache_footer' );
1202
1203 if( get_option( 'gzipcompression' ) )
1204 update_option( 'gzipcompression', 0 );
1205
1206 // Catch 404 requests. Themes that use query_posts() destroy $wp_query->is_404
1207 function wp_cache_catch_404() {
1208 global $wp_cache_404;
1209 $wp_cache_404 = false;
1210 if( is_404() )
1211 $wp_cache_404 = true;
1212 }
1213 add_action( 'template_redirect', 'wp_cache_catch_404' );
1214
1215 ?>
1216