constructor_args as $k) { if (isset($args[$k])) $this->$k = stripslashes($args[$k]); } } else { $this->raiseError('non-array first argument passed to constructor (dummy mode: ' . $dummy_run . ')', 'LightPressCache', __LINE__); } $this->validity = (int)$this->validity; $this->gc_probability = (int)$this->gc_probability; $this->track_users = (bool)$this->track_users; if ($dummy_run) return; $this->url_list = explode(' ', $this->url_list); if (!is_dir($this->dir)) { $this->raiseError('cache directory ' . $this->dir . ' not found', 'LightPressCache', __LINE__); $this->active = false; return; } if (!is_writable($this->dir)) { $this->raiseError('cache directory ' . $this->dir . ' not writable', 'LightPressCache', __LINE__); $this->active = false; return; } } function activate() { $this->page_id =& $this->_getId($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']); $this->user_id =& $this->_getUserId(); if (!empty($this->user_id) && !$this->track_users) $this->active = false; } function _getId($uri, $method='GET') { // get the page id if ($method != 'GET' || strpos($uri, '?') !== false) return; if (substr($uri, -1) != '/') $uri = "$uri/"; $found = false; foreach ($this->url_list as $url) { if ($url == $uri || $url == "$uri/") { $found = true; break; } } if ($this->include_or_exclude == 'include') { if (!$found) return; } else { if ($found) return; } return urlencode(preg_replace('/#.*$/', '', $uri)); // thanks to wp-cache for the regexp return ''; } function _getUserId() { // get the user id $user_id = ''; $cookies = array_keys($_COOKIE); sort($cookies); foreach ($cookies as $k) { if ($k == 'lp_identity') $user_id .= $_COOKIE[$k]; else if (strpos($k, 'wordpressuser_') === 0) $user_id .= $_COOKIE[$k]; } if (!empty($user_id)) $user_id = md5($user_id); return $user_id; } function getCache($page_id=null, $user_id=null) { // TODO: return cache-friendly headers, eg Cache-Control: max-age=3600 // together with the page content // have a look at http://www.mnot.net/cache_docs/ for reference if (is_null($page_id)) $page_id = $this->page_id; if (is_null($user_id)) $user_id = $this->user_id; if (is_null($page_id)) return; $filename = $this->dir . DIRECTORY_SEPARATOR . "lpcache_${page_id}_${user_id}"; $file_stat = @stat($filename); if (!$file_stat) return; $mtime =& $file_stat[9]; if (($mtime + $this->validity) < time()) return; if (!($f = @fopen($filename, 'rb'))) return; $data = @fread($f, $file_stat[7]); @fclose($f); if (substr($data, -1) == chr(0)) { return ( substr($data, 0, -1) . '' ); } } function setCache(&$content, $page_id=null, $user_id=null) { if (is_null($page_id)) $page_id = $this->page_id; if (is_null($user_id)) $user_id = $this->user_id; if (is_null($page_id)) return; $filename = $this->dir . DIRECTORY_SEPARATOR . "lpcache_${page_id}_${user_id}"; $dirname = $this->dir . DIRECTORY_SEPARATOR . "lpcache_${page_id}_lock"; if (!$this->_lock($dirname)) return; $f = @fopen($filename, 'wb'); @fwrite($f, $content . '\n" . chr(0)); @fclose($f); $this->_unlock($dirname); $r = rand(0, $this->gc_probability); if ($r == 0) $this->garbageCollect(); } function _lock($dirname) { // we don't care for retries, worst thing that happens is we don't // write the cache file in this request return @mkdir($dirname,0755); } function _unlock($dirname) { @rmdir($dirname); } function clearCache($id=null) { $this->garbageCollect(null, true); } function clearCacheComment($comment_id=null) { if (!is_null($comment_id)) { global $postdata; if (isset($postdata) && isset($postdata->ID)) $this->clearCachePost($postdata->ID); } } function clearCachePost($post_id=null) { if (!is_null($post_id)) { // clear only cache files related to this post id // if we have this it means we are running as an action inside WP $permalink = get_permalink($post_id); $url_tokens = parse_url($permalink); if (isset($url_tokens['path'])) { $page_id = $this->_getId($url_tokens['path']); if (!empty($page_id)) { $this->garbageCollect($page_id, true); $this->garbageCollect($this->_getId($this->base_path), true); } } } } function clearCachePostUri($post_uri) { $page_id = $this->_getId($post_uri); if (!empty($page_id)) $this->garbageCollect($page_id, true); } function garbageCollect($page_id=null, $clean_all=false) { // TODO: grab the list first, then delete so as to interfere less // with new saves if (!is_null($page_id)) $page_id = 'lpcache_' . $page_id . '_'; $dir =& $this->dir; if ($handle = @opendir($dir)) { $valid = $this->_valid; clearstatcache(); while (($file = readdir($handle)) !== false) { if (!substr($file, 0, 9) == 'lp_cache_') continue; if ($page_id && strpos($file, $page_id) !== 0) continue; $file_name = "$dir/$file"; $mtime = @filemtime($file_name); // might have been a lockdir, or garbage collected if ($clean_all || (!$mtime || ($mtime + $this->validity) >= time())) { // old cache or stale lock dir if (@is_dir($file_name)) @rmdir($file_name); else @unlink($file_name); } } closedir($handle); } else { return $this->raiseError( "cannot get directory handle for '$dir'", 'garbageCollect', __LINE__); } } function raiseError($message, $method, $line, $type=E_USER_WARNING) { trigger_error( sprintf("%s.%s() line %d: %s", get_class($this), $method, $line, $message), $type); } } ?>