PHP Cross Reference of WordPress Subversion HEAD |
| [ Index ] [ Classes ] [ Functions ] [ Variables ] [ Constants ] |
[Summary view] [Print] [Text view]
1 <?php 2 function wp_cache_add($key, $data, $flag = '', $expire = 0) { 3 global $wp_object_cache; 4 $data = unserialize(serialize($data)); 5 6 return $wp_object_cache->add($key, $data, $flag, $expire); 7 } 8 9 function wp_cache_close() { 10 global $wp_object_cache; 11 12 if ( ! isset($wp_object_cache) ) 13 return; 14 return $wp_object_cache->save(); 15 } 16 17 function wp_cache_delete($id, $flag = '') { 18 global $wp_object_cache; 19 20 return $wp_object_cache->delete($id, $flag); 21 } 22 23 function wp_cache_flush() { 24 global $wp_object_cache; 25 26 return $wp_object_cache->flush(); 27 } 28 29 function wp_cache_get($id, $flag = '') { 30 global $wp_object_cache; 31 32 return $wp_object_cache->get($id, $flag); 33 } 34 35 function wp_cache_init() { 36 $GLOBALS['wp_object_cache'] =& new WP_Object_Cache(); 37 } 38 39 function wp_cache_replace($key, $data, $flag = '', $expire = 0) { 40 global $wp_object_cache; 41 $data = unserialize(serialize($data)); 42 43 return $wp_object_cache->replace($key, $data, $flag, $expire); 44 } 45 46 function wp_cache_set($key, $data, $flag = '', $expire = 0) { 47 global $wp_object_cache; 48 $data = unserialize(serialize($data)); 49 50 return $wp_object_cache->set($key, $data, $flag, $expire); 51 } 52 53 define('CACHE_SERIAL_HEADER', "<?php\n/*"); 54 define('CACHE_SERIAL_FOOTER', "*/\n?".">"); 55 56 class WP_Object_Cache { 57 var $cache_dir; 58 var $cache_enabled = false; 59 var $expiration_time = 900; 60 var $flock_filename = 'wp_object_cache.lock'; 61 var $mutex; 62 var $cache = array (); 63 var $dirty_objects = array (); 64 var $non_existant_objects = array (); 65 var $global_groups = array ('users', 'userlogins', 'usermeta'); 66 var $non_persistent_groups = array('comment'); 67 var $blog_id; 68 var $cold_cache_hits = 0; 69 var $warm_cache_hits = 0; 70 var $cache_misses = 0; 71 var $secret = ''; 72 73 function acquire_lock() { 74 // Acquire a write lock. 75 $this->mutex = @fopen($this->cache_dir.$this->flock_filename, 'w'); 76 if ( false == $this->mutex) 77 return false; 78 flock($this->mutex, LOCK_EX); 79 return true; 80 } 81 82 function add($id, $data, $group = 'default', $expire = '') { 83 if (empty ($group)) 84 $group = 'default'; 85 86 if (false !== $this->get($id, $group, false)) 87 return false; 88 89 return $this->set($id, $data, $group, $expire); 90 } 91 92 function delete($id, $group = 'default', $force = false) { 93 if (empty ($group)) 94 $group = 'default'; 95 96 if (!$force && false === $this->get($id, $group, false)) 97 return false; 98 99 unset ($this->cache[$group][$id]); 100 $this->non_existant_objects[$group][$id] = true; 101 $this->dirty_objects[$group][] = $id; 102 return true; 103 } 104 105 function flush() { 106 if ( !$this->cache_enabled ) 107 return true; 108 109 if ( ! $this->acquire_lock() ) 110 return false; 111 112 $this->rm_cache_dir(); 113 $this->cache = array (); 114 $this->dirty_objects = array (); 115 $this->non_existant_objects = array (); 116 117 $this->release_lock(); 118 119 return true; 120 } 121 122 function get($id, $group = 'default', $count_hits = true) { 123 if (empty ($group)) 124 $group = 'default'; 125 126 if (isset ($this->cache[$group][$id])) { 127 if ($count_hits) 128 $this->warm_cache_hits += 1; 129 return $this->cache[$group][$id]; 130 } 131 132 if (isset ($this->non_existant_objects[$group][$id])) 133 return false; 134 135 // If caching is not enabled, we have to fall back to pulling from the DB. 136 if (!$this->cache_enabled) { 137 if (!isset ($this->cache[$group])) 138 $this->load_group_from_db($group); 139 140 if (isset ($this->cache[$group][$id])) { 141 $this->cold_cache_hits += 1; 142 return $this->cache[$group][$id]; 143 } 144 145 $this->non_existant_objects[$group][$id] = true; 146 $this->cache_misses += 1; 147 return false; 148 } 149 150 $cache_file = $this->cache_dir.$this->get_group_dir($group)."/".$this->hash($id).'.php'; 151 if (!file_exists($cache_file)) { 152 $this->non_existant_objects[$group][$id] = true; 153 $this->cache_misses += 1; 154 return false; 155 } 156 157 // If the object has expired, remove it from the cache and return false to force 158 // a refresh. 159 $now = time(); 160 if ((filemtime($cache_file) + $this->expiration_time) <= $now) { 161 $this->cache_misses += 1; 162 $this->delete($id, $group, true); 163 return false; 164 } 165 166 $this->cache[$group][$id] = unserialize(base64_decode(substr(@ file_get_contents($cache_file), strlen(CACHE_SERIAL_HEADER), -strlen(CACHE_SERIAL_FOOTER)))); 167 if (false === $this->cache[$group][$id]) 168 $this->cache[$group][$id] = ''; 169 170 $this->cold_cache_hits += 1; 171 return $this->cache[$group][$id]; 172 } 173 174 function get_group_dir($group) { 175 if (false !== array_search($group, $this->global_groups)) 176 return $group; 177 178 return "{$this->blog_id}/$group"; 179 } 180 181 function hash($data) { 182 if ( function_exists('hash_hmac') ) { 183 return hash_hmac('md5', $data, $this->secret); 184 } else { 185 return md5($data . $this->secret); 186 } 187 } 188 189 function load_group_from_db($group) { 190 return; 191 } 192 193 function make_group_dir($group, $perms) { 194 $group_dir = $this->get_group_dir($group); 195 $make_dir = ''; 196 foreach (split('/', $group_dir) as $subdir) { 197 $make_dir .= "$subdir/"; 198 if (!file_exists($this->cache_dir.$make_dir)) { 199 if (! @ mkdir($this->cache_dir.$make_dir)) 200 break; 201 @ chmod($this->cache_dir.$make_dir, $perms); 202 } 203 204 if (!file_exists($this->cache_dir.$make_dir."index.php")) { 205 $file_perms = $perms & 0000666; 206 @ touch($this->cache_dir.$make_dir."index.php"); 207 @ chmod($this->cache_dir.$make_dir."index.php", $file_perms); 208 } 209 } 210 211 return $this->cache_dir."$group_dir/"; 212 } 213 214 function rm_cache_dir() { 215 $dir = $this->cache_dir; 216 $dir = rtrim($dir, DIRECTORY_SEPARATOR); 217 $top_dir = $dir; 218 $stack = array($dir); 219 $index = 0; 220 221 while ($index < count($stack)) { 222 # Get indexed directory from stack 223 $dir = $stack[$index]; 224 225 $dh = @ opendir($dir); 226 if (!$dh) 227 return false; 228 229 while (($file = @ readdir($dh)) !== false) { 230 if ($file == '.' or $file == '..') 231 continue; 232 233 if (@ is_dir($dir . DIRECTORY_SEPARATOR . $file)) 234 $stack[] = $dir . DIRECTORY_SEPARATOR . $file; 235 else if (@ is_file($dir . DIRECTORY_SEPARATOR . $file)) 236 @ unlink($dir . DIRECTORY_SEPARATOR . $file); 237 } 238 239 $index++; 240 } 241 242 $stack = array_reverse($stack); // Last added dirs are deepest 243 foreach($stack as $dir) { 244 if ( $dir != $top_dir) 245 @ rmdir($dir); 246 } 247 248 } 249 250 function release_lock() { 251 // Release write lock. 252 flock($this->mutex, LOCK_UN); 253 fclose($this->mutex); 254 } 255 256 function replace($id, $data, $group = 'default', $expire = '') { 257 if (empty ($group)) 258 $group = 'default'; 259 260 if (false === $this->get($id, $group, false)) 261 return false; 262 263 return $this->set($id, $data, $group, $expire); 264 } 265 266 function set($id, $data, $group = 'default', $expire = '') { 267 if (empty ($group)) 268 $group = 'default'; 269 270 if (NULL === $data) 271 $data = ''; 272 273 $this->cache[$group][$id] = $data; 274 unset ($this->non_existant_objects[$group][$id]); 275 $this->dirty_objects[$group][] = $id; 276 277 return true; 278 } 279 280 function save() { 281 //$this->stats(); 282 283 if (!$this->cache_enabled) 284 return true; 285 286 if (empty ($this->dirty_objects)) 287 return true; 288 289 // Give the new dirs the same perms as wp-content. 290 $stat = stat(ABSPATH.'wp-content'); 291 $dir_perms = $stat['mode'] & 0007777; // Get the permission bits. 292 $file_perms = $dir_perms & 0000666; // Remove execute bits for files. 293 294 // Make the base cache dir. 295 if (!file_exists($this->cache_dir)) { 296 if (! @ mkdir($this->cache_dir)) 297 return false; 298 @ chmod($this->cache_dir, $dir_perms); 299 } 300 301 if (!file_exists($this->cache_dir."index.php")) { 302 @ touch($this->cache_dir."index.php"); 303 @ chmod($this->cache_dir."index.php", $file_perms); 304 } 305 306 if ( ! $this->acquire_lock() ) 307 return false; 308 309 // Loop over dirty objects and save them. 310 $errors = 0; 311 foreach ($this->dirty_objects as $group => $ids) { 312 if ( in_array($group, $this->non_persistent_groups) ) 313 continue; 314 315 $group_dir = $this->make_group_dir($group, $dir_perms); 316 317 $ids = array_unique($ids); 318 foreach ($ids as $id) { 319 $cache_file = $group_dir.$this->hash($id).'.php'; 320 321 // Remove the cache file if the key is not set. 322 if (!isset ($this->cache[$group][$id])) { 323 if (file_exists($cache_file)) 324 @ unlink($cache_file); 325 continue; 326 } 327 328 $temp_file = tempnam($group_dir, 'tmp'); 329 $serial = CACHE_SERIAL_HEADER.base64_encode(serialize($this->cache[$group][$id])).CACHE_SERIAL_FOOTER; 330 $fd = @fopen($temp_file, 'w'); 331 if ( false === $fd ) { 332 $errors++; 333 continue; 334 } 335 fputs($fd, $serial); 336 fclose($fd); 337 if (!@ rename($temp_file, $cache_file)) { 338 if (!@ copy($temp_file, $cache_file)) 339 $errors++; 340 @ unlink($temp_file); 341 } 342 @ chmod($cache_file, $file_perms); 343 } 344 } 345 346 $this->dirty_objects = array(); 347 348 $this->release_lock(); 349 350 if ( $errors ) 351 return false; 352 353 return true; 354 } 355 356 function stats() { 357 echo "<p>"; 358 echo "<strong>Cold Cache Hits:</strong> {$this->cold_cache_hits}<br />"; 359 echo "<strong>Warm Cache Hits:</strong> {$this->warm_cache_hits}<br />"; 360 echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />"; 361 echo "</p>"; 362 363 foreach ($this->cache as $group => $cache) { 364 echo "<p>"; 365 echo "<strong>Group:</strong> $group<br />"; 366 echo "<strong>Cache:</strong>"; 367 echo "<pre>"; 368 print_r($cache); 369 echo "</pre>"; 370 if (isset ($this->dirty_objects[$group])) { 371 echo "<strong>Dirty Objects:</strong>"; 372 echo "<pre>"; 373 print_r(array_unique($this->dirty_objects[$group])); 374 echo "</pre>"; 375 echo "</p>"; 376 } 377 } 378 } 379 380 function WP_Object_Cache() { 381 return $this->__construct(); 382 } 383 384 function __construct() { 385 global $blog_id; 386 387 register_shutdown_function(array(&$this, "__destruct")); 388 389 if (defined('DISABLE_CACHE')) 390 return; 391 392 if ( ! defined('ENABLE_CACHE') ) 393 return; 394 395 // Disable the persistent cache if safe_mode is on. 396 if ( ini_get('safe_mode') && ! defined('ENABLE_CACHE') ) 397 return; 398 399 if (defined('CACHE_PATH')) 400 $this->cache_dir = CACHE_PATH; 401 else 402 // Using the correct separator eliminates some cache flush errors on Windows 403 $this->cache_dir = ABSPATH.'wp-content'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR; 404 405 if (is_writable($this->cache_dir) && is_dir($this->cache_dir)) { 406 $this->cache_enabled = true; 407 } else { 408 if (is_writable(ABSPATH.'wp-content')) { 409 $this->cache_enabled = true; 410 } 411 } 412 413 if (defined('CACHE_EXPIRATION_TIME')) 414 $this->expiration_time = CACHE_EXPIRATION_TIME; 415 416 if ( defined('WP_SECRET') ) 417 $this->secret = WP_SECRET; 418 else 419 $this->secret = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH; 420 421 $this->blog_id = $this->hash($blog_id); 422 } 423 424 function __destruct() { 425 $this->save(); 426 return true; 427 } 428 } 429 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated Thu Dec 6 06:47:08 2007 for RedAlt XRefs | Cross-referenced by PHPXref 0.6 and RedAlt |