PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-super-cache/tags/0.3/wp-cache-phase2.php

https://github.com/brandonburke/WordPress-Plugin-Baseline
PHP | 454 lines | 361 code | 52 blank | 41 comment | 111 complexity | 2de8464fa072196e079b3d0ff1504703 MD5 | raw file
  1. <?php
  2. /** Diable here because PHP4.3 does not make the global
  3. Serious bug?
  4. $mutex_filename = 'wp_cache_mutex.lock';
  5. $new_cache = false;
  6. */
  7. function wp_cache_phase2() {
  8. global $cache_filename, $cache_acceptable_files, $wp_cache_meta_object;
  9. global $wp_cache_gzip_encoding;
  10. wp_cache_mutex_init();
  11. if(function_exists('add_action')) {
  12. // Post ID is received
  13. add_action('publish_post', 'wp_cache_post_change', 0);
  14. add_action('edit_post', 'wp_cache_post_change', 0);
  15. add_action('delete_post', 'wp_cache_post_change', 0);
  16. add_action('publish_phone', 'wp_cache_post_change', 0);
  17. // Coment ID is received
  18. add_action('trackback_post', 'wp_cache_get_postid_from_comment', 0);
  19. add_action('pingback_post', 'wp_cache_get_postid_from_comment', 0);
  20. add_action('comment_post', 'wp_cache_get_postid_from_comment', 0);
  21. add_action('edit_comment', 'wp_cache_get_postid_from_comment', 0);
  22. add_action('wp_set_comment_status', 'wp_cache_get_postid_from_comment', 0);
  23. // No post_id is available
  24. add_action('delete_comment', 'wp_cache_no_postid', 0);
  25. add_action('switch_theme', 'wp_cache_no_postid', 0);
  26. do_cacheaction( 'add_cacheaction' );
  27. }
  28. if( $_SERVER["REQUEST_METHOD"] == 'POST' || get_option('gzipcompression'))
  29. return;
  30. $script = basename($_SERVER['PHP_SELF']);
  31. if (!in_array($script, $cache_acceptable_files) &&
  32. wp_cache_is_rejected($_SERVER["REQUEST_URI"]))
  33. return;
  34. if (wp_cache_user_agent_is_rejected()) return;
  35. $wp_cache_meta_object = new CacheMeta;
  36. ob_start('wp_cache_ob_callback');
  37. register_shutdown_function('wp_cache_shutdown_callback');
  38. }
  39. function wp_cache_get_response_headers() {
  40. if(function_exists('apache_response_headers')) {
  41. flush();
  42. $headers = apache_response_headers();
  43. } else if(function_exists('headers_list')) {
  44. $headers = array();
  45. foreach(headers_list() as $hdr) {
  46. list($header_name, $header_value) = explode(': ', $hdr, 2);
  47. $headers[$header_name] = $header_value;
  48. }
  49. } else
  50. $headers = null;
  51. return $headers;
  52. }
  53. function wp_cache_is_rejected($uri) {
  54. global $cache_rejected_uri;
  55. if (strstr($uri, '/wp-admin/'))
  56. return true; //we don't allow cacheing wp-admin for security
  57. foreach ($cache_rejected_uri as $expr) {
  58. if (strlen($expr) > 0 && substr( $uri, 1, strlen($expr) ) == $expr && strpos( $uri, '.php' ) )
  59. return true;
  60. }
  61. return false;
  62. }
  63. function wp_cache_user_agent_is_rejected() {
  64. global $cache_rejected_user_agent;
  65. if (!function_exists('apache_request_headers')) return false;
  66. $headers = apache_request_headers();
  67. if (!isset($headers["User-Agent"])) return false;
  68. foreach ($cache_rejected_user_agent as $expr) {
  69. if (strlen($expr) > 0 && stristr($headers["User-Agent"], $expr))
  70. return true;
  71. }
  72. return false;
  73. }
  74. function wp_cache_mutex_init() {
  75. global $use_flock, $mutex, $cache_path, $mutex_filename, $sem_id;
  76. if(!is_bool($use_flock)) {
  77. if(function_exists('sem_get'))
  78. $use_flock = false;
  79. else
  80. $use_flock = true;
  81. }
  82. if ($use_flock)
  83. $mutex = fopen($cache_path . $mutex_filename, 'w');
  84. else
  85. $mutex = sem_get($sem_id, 1, 0644 | IPC_CREAT, 1);
  86. }
  87. function wp_cache_writers_entry() {
  88. global $use_flock, $mutex, $cache_path, $mutex_filename;
  89. if ($use_flock)
  90. flock($mutex, LOCK_EX);
  91. else
  92. sem_acquire($mutex);
  93. }
  94. function wp_cache_writers_exit() {
  95. global $use_flock, $mutex, $cache_path, $mutex_filename;
  96. if ($use_flock)
  97. flock($mutex, LOCK_UN);
  98. else
  99. sem_release($mutex);
  100. }
  101. function wp_cache_ob_callback($buffer) {
  102. global $cache_path, $cache_filename, $meta_file, $wp_start_time, $supercachedir;
  103. global $new_cache, $wp_cache_meta_object, $file_expired, $blog_id, $cache_compression;
  104. global $wp_cache_gzip_encoding, $super_cache_enabled;
  105. /* Mode paranoic, check for closing tags
  106. * we avoid caching incomplete files */
  107. if (is_404() || !preg_match('/(<\/html>|<\/rss>|<\/feed>)/i',$buffer) ) {
  108. $new_cache = false;
  109. return $buffer;
  110. }
  111. $duration = wp_cache_microtime_diff($wp_start_time, microtime());
  112. $duration = sprintf("%0.3f", $duration);
  113. $buffer .= "\n<!-- Dynamic Page Served (once) in $duration seconds -->\n";
  114. wp_cache_writers_entry();
  115. $mtime = @filemtime($cache_path . $cache_filename);
  116. /* Return if:
  117. the file didn't exist before but it does exist now (another connection created)
  118. OR
  119. the file was expired and its mtime is less than 5 seconds
  120. */
  121. if( !((!$file_expired && $mtime) || ($mtime && $file_expired && (time() - $mtime) < 5)) ) {
  122. $dir = strtolower(preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"])).preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', str_replace( '..', '', $_SERVER['REQUEST_URI']) ); // To avoid XSS attacs
  123. $dir = trailingslashit( $cache_path . 'supercache/' . $dir );
  124. $supercachedir = $cache_path . 'supercache/' . preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"]);
  125. if( $super_cache_enabled == true && is_dir( substr( $supercachedir, 0, -1 ) . '.disabled' ) ) {
  126. $super_cache_enabled = false;
  127. }
  128. $fr = @fopen($cache_path . $cache_filename, 'w');
  129. if (!$fr)
  130. $buffer = "Couldn't write to: " . $cache_path . $cache_filename . "\n";
  131. if( $super_cache_enabled ) {
  132. if( is_dir( $dir ) == false )
  133. @mkpath( $dir );
  134. $user_info = wp_cache_get_cookies_values();
  135. $do_cache = apply_filters( 'do_createsupercache', $user_info );
  136. if( $user_info == '' || $do_cache === true ) {
  137. if( !is_feed() ) { // don't super cache feeds
  138. $fr2 = @fopen("{$dir}index.html", 'w');
  139. if( $cache_compression )
  140. $gz = @gzopen("{$dir}index.html.gz", 'w3');
  141. }
  142. }
  143. }
  144. if (preg_match('/<!--mclude|<!--mfunc/', $buffer)) { //Dynamic content
  145. $store = preg_replace('|<!--mclude (.*?)-->(.*?)<!--/mclude-->|is',
  146. "<!--mclude-->\n<?php include_once('" . ABSPATH . "$1'); ?>\n<!--/mclude-->", $buffer);
  147. $store = preg_replace('|<!--mfunc (.*?)-->(.*?)<!--/mfunc-->|is',
  148. "<!--mfunc-->\n<?php $1 ;?>\n<!--/mfunc-->", $store);
  149. $wp_cache_meta_object->dynamic = true;
  150. /* Clean function calls in tag */
  151. $buffer = preg_replace('|<!--mclude (.*?)-->|is', '<!--mclude-->', $buffer);
  152. $buffer = preg_replace('|<!--mfunc (.*?)-->|is', '<!--mfunc-->', $buffer);
  153. fputs($fr, $store);
  154. if( $fr2 )
  155. fputs($fr2, $store . '<!-- super cache -->' );
  156. if( $gz )
  157. gzwrite($gz, $store . '<!-- super cache gz -->' );
  158. } else {
  159. $log = "<!-- Cached page served by WP-Cache -->\n";
  160. if ($wp_cache_gzip_encoding) {
  161. $log .= "<!-- Compression = " . $wp_cache_gzip_encoding ." -->";
  162. $gzdata = gzencode($buffer . $log, 3, FORCE_GZIP);
  163. $gzsize = strlen($gzdata);
  164. array_push($wp_cache_meta_object->headers, 'Content-Encoding: ' . $wp_cache_gzip_encoding);
  165. array_push($wp_cache_meta_object->headers, 'Vary: Accept-Encoding');
  166. array_push($wp_cache_meta_object->headers, 'Content-Length: ' . strlen($gzdata));
  167. // Return uncompressed data & store compressed for later use
  168. fputs($fr, $gzdata);
  169. }else{ // no compression
  170. fputs($fr, $buffer.$log);
  171. }
  172. if( $fr2 )
  173. fputs($fr2, $buffer . '<!-- super cache -->' );
  174. if( $gz )
  175. gzwrite($gz, $buffer . '<!-- super cache gz -->' );
  176. }
  177. $new_cache = true;
  178. fclose($fr);
  179. if( $fr2 )
  180. fclose($fr2);
  181. if( $gz )
  182. fclose($gz);
  183. }
  184. wp_cache_writers_exit();
  185. return $buffer;
  186. }
  187. function wp_cache_phase2_clean_cache($file_prefix) {
  188. global $cache_path;
  189. wp_cache_writers_entry();
  190. if ( ($handle = opendir( $cache_path )) ) {
  191. while ( false !== ($file = readdir($handle))) {
  192. if ( preg_match("/^$file_prefix/", $file) ) {
  193. unlink($cache_path . $file);
  194. }
  195. }
  196. closedir($handle);
  197. }
  198. wp_cache_writers_exit();
  199. }
  200. function prune_super_cache($directory, $force = false) {
  201. global $super_cache_max_time, $cache_path;
  202. if( !isset( $super_cache_max_time ) )
  203. $super_cache_max_time = 21600;
  204. $now = time();
  205. if (is_dir($directory)) {
  206. $entries = glob($directory. '/*');
  207. foreach ($entries as $entry) {
  208. if ($entry != '.' && $entry != '..') {
  209. prune_super_cache($entry, $force);
  210. if( $force || is_dir( $entry ) && @filemtime( $entry ) + $super_cache_max_time <= $now ) {
  211. if( $entry != $cache_path . '/meta' )
  212. @rmdir( $entry );
  213. }
  214. }
  215. }
  216. } else {
  217. if( $force || is_file($directory) && filemtime( $directory ) + $super_cache_max_time <= $now )
  218. unlink($directory);
  219. }
  220. }
  221. function wp_cache_phase2_clean_expired($file_prefix) {
  222. global $cache_path, $cache_max_time;
  223. clearstatcache();
  224. wp_cache_writers_entry();
  225. $now = time();
  226. if ( ($handle = opendir( $cache_path )) ) {
  227. while ( false !== ($file = readdir($handle))) {
  228. if ( preg_match("/^$file_prefix/", $file) &&
  229. (filemtime($cache_path . $file) + $cache_max_time) <= $now ) {
  230. @unlink($cache_path . $file);
  231. @unlink($cache_path . 'meta/' . str_replace( '.html', '.meta', $file ) );
  232. continue;
  233. }
  234. if($file != '.' && $file != '..') {
  235. if ( is_dir( $cache_path . $file ) == false && (filemtime($cache_path . $file) + $cache_max_time) <= $now ) {
  236. @unlink($cache_path . $file);
  237. } elseif( is_dir( $cache_path . $file ) ) {
  238. prune_super_cache( $cache_path . $file );
  239. }
  240. }
  241. }
  242. closedir($handle);
  243. }
  244. wp_cache_writers_exit();
  245. }
  246. function wp_cache_shutdown_callback() {
  247. global $cache_path, $cache_max_time, $file_expired, $file_prefix, $meta_file, $new_cache;
  248. global $wp_cache_meta_object, $known_headers, $blog_id;
  249. $wp_cache_meta_object->uri = $_SERVER["SERVER_NAME"].preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER['REQUEST_URI']); // To avoid XSS attacs
  250. $wp_cache_meta_object->blog_id=$blog_id;
  251. $wp_cache_meta_object->post = wp_cache_post_id();
  252. $response = wp_cache_get_response_headers();
  253. foreach ($known_headers as $key) {
  254. if(isset($response{$key})) {
  255. array_push($wp_cache_meta_object->headers, "$key: " . $response{$key});
  256. }
  257. }
  258. /* Not used because it gives problems with some
  259. * PHP installations
  260. if (!$response{'Content-Length'}) {
  261. // WP does not set content size
  262. $content_size = ob_get_length();
  263. @header("Content-Length: $content_size");
  264. array_push($wp_cache_meta_object->headers, "Content-Length: $content_size");
  265. }
  266. */
  267. if (!$response{'Last-Modified'}) {
  268. $value = gmdate('D, d M Y H:i:s') . ' GMT';
  269. /* Dont send this the first time */
  270. /* @header('Last-Modified: ' . $value); */
  271. array_push($wp_cache_meta_object->headers, "Last-Modified: $value");
  272. }
  273. if (!$response{'Content-Type'} && !$response{'Content-type'}) {
  274. // On some systems, headers set by PHP can't be fetched from
  275. // the output buffer. This is a last ditch effort to set the
  276. // correct Content-Type header for feeds, if we didn't see
  277. // it in the response headers already. -- dougal
  278. if (is_feed()) {
  279. $type = get_query_var('feed');
  280. $type = str_replace('/','',$type);
  281. switch ($type) {
  282. case 'atom':
  283. $value = "application/atom+xml";
  284. break;
  285. case 'rdf':
  286. $value = "application/rdf+xml";
  287. break;
  288. case 'rss':
  289. case 'rss2':
  290. default:
  291. $value = "application/rss+xml";
  292. }
  293. } else { // not a feed
  294. $value = 'text/html';
  295. }
  296. $value .= "; charset=\"" . get_settings('blog_charset') . "\"";
  297. @header("Content-Type: $value");
  298. array_push($wp_cache_meta_object->headers, "Content-Type: $value");
  299. }
  300. ob_end_flush();
  301. if ($new_cache) {
  302. $serial = serialize($wp_cache_meta_object);
  303. wp_cache_writers_entry();
  304. $fr = fopen($cache_path . 'meta/' . $meta_file, 'w');
  305. if( !$fr )
  306. @mkdir( $cache_path . 'meta/' );
  307. $fr = fopen($cache_path . 'meta/' . $meta_file, 'w');
  308. fputs($fr, $serial);
  309. fclose($fr);
  310. wp_cache_writers_exit();
  311. }
  312. if ($file_expired == false) {
  313. return;
  314. }
  315. // we delete expired files
  316. flush(); //Ensure we send data to the client
  317. wp_cache_phase2_clean_expired($file_prefix);
  318. }
  319. function wp_cache_no_postid($id) {
  320. return wp_cache_post_change(wp_cache_post_id());
  321. }
  322. function wp_cache_get_postid_from_comment($comment_id) {
  323. $comment = get_commentdata($comment_id, 1, true);
  324. $postid = $comment['comment_post_ID'];
  325. // Do nothing if comment is not moderated
  326. // http://ocaoimh.ie/2006/12/05/caching-wordpress-with-wp-cache-in-a-spam-filled-world
  327. if( !preg_match('/wp-admin\//', $_SERVER['REQUEST_URI']) && $comment['comment_approved'] == 'spam' ) // changed from 1 to "spam"
  328. return $post_id;
  329. // We must check it up again due to WP bugs calling two different actions
  330. // for delete, for example both wp_set_comment_status and delete_comment
  331. // are called when deleting a comment
  332. if ($postid > 0)
  333. return wp_cache_post_change($postid);
  334. else
  335. return wp_cache_post_change(wp_cache_post_id());
  336. }
  337. function wp_cache_post_change($post_id) {
  338. global $file_prefix;
  339. global $cache_path;
  340. global $blog_id;
  341. global $blogcacheid;
  342. static $last_processed = -1;
  343. // Avoid cleaning twice the same pages
  344. if ($post_id == $last_processed) return $post_id;
  345. $last_processed = $post_id;
  346. $permalink = trailingslashit( str_replace( get_option( 'siteurl' ), '', post_permalink( $post_id ) ) );
  347. $siteurl = str_replace( 'http://', '', get_option( 'siteurl' ) );
  348. $dir = $cache_path . 'supercache/' . strtolower(preg_replace('/:.*$/', '', $siteurl ) );
  349. $files_to_delete = array( $dir . '/index.html', $dir . '/feed/index.html', $dir . $permalink . 'index.html', $dir . $permalink . 'feed/index.html' );
  350. foreach( $files_to_delete as $cache_file ) {
  351. @unlink( $cache_file );
  352. @unlink( $cache_file . '.gz' );
  353. }
  354. $meta = new CacheMeta;
  355. $matches = array();
  356. wp_cache_writers_entry();
  357. if ( ($handle = opendir( $cache_path . 'meta/' )) ) {
  358. while ( false !== ($file = readdir($handle))) {
  359. if ( preg_match("/^({$file_prefix}{$blogcacheid}.*)\.meta/", $file, $matches) ) {
  360. $meta_pathname = $cache_path . 'meta/' . $file;
  361. $content_pathname = $cache_path . $matches[1] . ".html";
  362. $meta = unserialize(@file_get_contents($meta_pathname));
  363. if ($post_id > 0 && $meta) {
  364. if ($meta->blog_id == $blog_id && (!$meta->post || $meta->post == $post_id) ) {
  365. unlink($meta_pathname);
  366. unlink($content_pathname);
  367. }
  368. } elseif ($meta->blog_id == $blog_id) {
  369. unlink($meta_pathname);
  370. unlink($content_pathname);
  371. }
  372. }
  373. }
  374. closedir($handle);
  375. }
  376. wp_cache_writers_exit();
  377. return $post_id;
  378. }
  379. function wp_cache_microtime_diff($a, $b) {
  380. list($a_dec, $a_sec) = explode(' ', $a);
  381. list($b_dec, $b_sec) = explode(' ', $b);
  382. return $b_sec - $a_sec + $b_dec - $a_dec;
  383. }
  384. function wp_cache_post_id() {
  385. global $posts, $comment_post_ID, $post_ID;
  386. // We try hard all options. More frequent first.
  387. if ($post_ID > 0 ) return $post_ID;
  388. if ($comment_post_ID > 0 ) return $comment_post_ID;
  389. if (is_single() || is_page()) return $posts[0]->ID;
  390. if ($_GET['p'] > 0) return $_GET['p'];
  391. if ($_POST['p'] > 0) return $_POST['p'];
  392. return 0;
  393. }
  394. if( !function_exists( 'mkpath' ) ) {
  395. function mkpath($path) {
  396. if(@mkdir($path, 0777) or file_exists($path)) return true;
  397. return (mkpath(dirname($path)) and mkdir($path, 0777));
  398. }
  399. }
  400. ?>