PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/www/wp-content/object-cache.php

https://gitlab.com/Blueprint-Marketing/vip-quickstart
PHP | 402 lines | 299 code | 87 blank | 16 comment | 53 complexity | 86cf2223709f9daadfe3e71e247c3cf3 MD5 | raw file
  1. <?php
  2. /*
  3. Plugin Name: Memcached
  4. Description: Memcached backend for the WP Object Cache.
  5. Version: 2.0.2
  6. Plugin URI: http://wordpress.org/extend/plugins/memcached/
  7. Author: Ryan Boren, Denis de Bernardy, Matt Martz
  8. Install this file to wp-content/object-cache.php
  9. */
  10. // Users with setups where multiple installs share a common wp-config.php or $table_prefix
  11. // can use this to guarantee uniqueness for the keys generated by this object cache
  12. if ( !defined( 'WP_CACHE_KEY_SALT' ) )
  13. define( 'WP_CACHE_KEY_SALT', '' );
  14. function wp_cache_add($key, $data, $group = '', $expire = 0) {
  15. global $wp_object_cache;
  16. return $wp_object_cache->add($key, $data, $group, $expire);
  17. }
  18. function wp_cache_incr($key, $n = 1, $group = '') {
  19. global $wp_object_cache;
  20. return $wp_object_cache->incr($key, $n, $group);
  21. }
  22. function wp_cache_decr($key, $n = 1, $group = '') {
  23. global $wp_object_cache;
  24. return $wp_object_cache->decr($key, $n, $group);
  25. }
  26. function wp_cache_close() {
  27. global $wp_object_cache;
  28. return $wp_object_cache->close();
  29. }
  30. function wp_cache_delete($key, $group = '') {
  31. global $wp_object_cache;
  32. return $wp_object_cache->delete($key, $group);
  33. }
  34. function wp_cache_flush() {
  35. global $wp_object_cache;
  36. return $wp_object_cache->flush();
  37. }
  38. function wp_cache_get($key, $group = '', $force = false) {
  39. global $wp_object_cache;
  40. return $wp_object_cache->get($key, $group, $force);
  41. }
  42. function wp_cache_init() {
  43. global $wp_object_cache;
  44. $wp_object_cache = new WP_Object_Cache();
  45. }
  46. function wp_cache_replace($key, $data, $group = '', $expire = 0) {
  47. global $wp_object_cache;
  48. return $wp_object_cache->replace($key, $data, $group, $expire);
  49. }
  50. function wp_cache_set($key, $data, $group = '', $expire = 0) {
  51. global $wp_object_cache;
  52. if ( defined('WP_INSTALLING') == false )
  53. return $wp_object_cache->set($key, $data, $group, $expire);
  54. else
  55. return $wp_object_cache->delete($key, $group);
  56. }
  57. function wp_cache_add_global_groups( $groups ) {
  58. global $wp_object_cache;
  59. $wp_object_cache->add_global_groups($groups);
  60. }
  61. function wp_cache_add_non_persistent_groups( $groups ) {
  62. global $wp_object_cache;
  63. $wp_object_cache->add_non_persistent_groups($groups);
  64. }
  65. class WP_Object_Cache {
  66. var $global_groups = array();
  67. var $no_mc_groups = array();
  68. var $cache = array();
  69. var $mc = array();
  70. var $stats = array();
  71. var $group_ops = array();
  72. var $cache_enabled = true;
  73. var $default_expiration = 0;
  74. var $debug = false;
  75. function add($id, $data, $group = 'default', $expire = 0) {
  76. $key = $this->key($id, $group);
  77. if ( is_object( $data ) )
  78. $data = clone $data;
  79. if ( in_array($group, $this->no_mc_groups) ) {
  80. $this->cache[$key] = $data;
  81. return true;
  82. } elseif ( isset($this->cache[$key]) && $this->cache[$key] !== false ) {
  83. return false;
  84. }
  85. $mc =& $this->get_mc($group);
  86. $expire = ($expire == 0) ? $this->default_expiration : $expire;
  87. $result = $mc->add($key, $data, false, $expire);
  88. if ( false !== $result ) {
  89. @ ++$this->stats['add'];
  90. $this->group_ops[$group][] = "add $id";
  91. $this->cache[$key] = $data;
  92. }
  93. return $result;
  94. }
  95. function add_global_groups($groups) {
  96. if ( ! is_array($groups) )
  97. $groups = (array) $groups;
  98. $this->global_groups = array_merge($this->global_groups, $groups);
  99. $this->global_groups = array_unique($this->global_groups);
  100. }
  101. function add_non_persistent_groups($groups) {
  102. if ( ! is_array($groups) )
  103. $groups = (array) $groups;
  104. $this->no_mc_groups = array_merge($this->no_mc_groups, $groups);
  105. $this->no_mc_groups = array_unique($this->no_mc_groups);
  106. }
  107. function incr($id, $n = 1, $group = 'default' ) {
  108. $key = $this->key($id, $group);
  109. $mc =& $this->get_mc($group);
  110. $this->cache[ $key ] = $mc->increment( $key, $n );
  111. return $this->cache[ $key ];
  112. }
  113. function decr($id, $n = 1, $group = 'default' ) {
  114. $key = $this->key($id, $group);
  115. $mc =& $this->get_mc($group);
  116. $this->cache[ $key ] = $mc->decrement( $key, $n );
  117. return $this->cache[ $key ];
  118. }
  119. function close() {
  120. foreach ( $this->mc as $bucket => $mc )
  121. $mc->close();
  122. }
  123. function delete($id, $group = 'default') {
  124. $key = $this->key($id, $group);
  125. if ( in_array($group, $this->no_mc_groups) ) {
  126. unset($this->cache[$key]);
  127. return true;
  128. }
  129. $mc =& $this->get_mc($group);
  130. $result = $mc->delete($key);
  131. @ ++$this->stats['delete'];
  132. $this->group_ops[$group][] = "delete $id";
  133. if ( false !== $result )
  134. unset($this->cache[$key]);
  135. return $result;
  136. }
  137. function flush() {
  138. $is_multisite = ( function_exists( 'is_site_admin' ) || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) );
  139. // Abort object cache flushing if on multisite (really, WordPress.com) when not running unit tests
  140. if ( $is_multisite && ! ( defined( 'WP_TESTS_MULTISITE' ) && WP_TESTS_MULTISITE ) ) {
  141. return false;
  142. }
  143. $ret = true;
  144. foreach ( array_keys($this->mc) as $group )
  145. $ret &= $this->mc[$group]->flush();
  146. return $ret;
  147. }
  148. function get($id, $group = 'default', $force = false) {
  149. $key = $this->key($id, $group);
  150. $mc =& $this->get_mc($group);
  151. if ( isset($this->cache[$key]) && ( !$force || in_array($group, $this->no_mc_groups) ) ) {
  152. if ( is_object( $this->cache[$key] ) )
  153. $value = clone $this->cache[$key];
  154. else
  155. $value = $this->cache[$key];
  156. } else if ( in_array($group, $this->no_mc_groups) ) {
  157. $this->cache[$key] = $value = false;
  158. } else {
  159. $value = $mc->get($key);
  160. if ( NULL === $value )
  161. $value = false;
  162. $this->cache[$key] = $value;
  163. }
  164. @ ++$this->stats['get'];
  165. $this->group_ops[$group][] = "get $id";
  166. if ( 'checkthedatabaseplease' === $value ) {
  167. unset( $this->cache[$key] );
  168. $value = false;
  169. }
  170. return $value;
  171. }
  172. function get_multi( $groups ) {
  173. /*
  174. format: $get['group-name'] = array( 'key1', 'key2' );
  175. */
  176. $return = array();
  177. foreach ( $groups as $group => $ids ) {
  178. $mc =& $this->get_mc($group);
  179. foreach ( $ids as $id ) {
  180. $key = $this->key($id, $group);
  181. if ( isset($this->cache[$key]) ) {
  182. if ( is_object( $this->cache[$key] ) )
  183. $return[$key] = clone $this->cache[$key];
  184. else
  185. $return[$key] = $this->cache[$key];
  186. continue;
  187. } else if ( in_array($group, $this->no_mc_groups) ) {
  188. $return[$key] = false;
  189. continue;
  190. } else {
  191. $return[$key] = $mc->get($key);
  192. }
  193. }
  194. if ( $to_get ) {
  195. $vals = $mc->get_multi( $to_get );
  196. $return = array_merge( $return, $vals );
  197. }
  198. }
  199. @ ++$this->stats['get_multi'];
  200. $this->group_ops[$group][] = "get_multi $id";
  201. $this->cache = array_merge( $this->cache, $return );
  202. return $return;
  203. }
  204. function key($key, $group) {
  205. if ( empty($group) )
  206. $group = 'default';
  207. if ( false !== array_search($group, $this->global_groups) )
  208. $prefix = $this->global_prefix;
  209. else
  210. $prefix = $this->blog_prefix;
  211. return preg_replace('/\s+/', '', WP_CACHE_KEY_SALT . "$prefix$group:$key");
  212. }
  213. function replace($id, $data, $group = 'default', $expire = 0) {
  214. $key = $this->key($id, $group);
  215. $expire = ($expire == 0) ? $this->default_expiration : $expire;
  216. $mc =& $this->get_mc($group);
  217. if ( is_object( $data ) )
  218. $data = clone $data;
  219. $result = $mc->replace($key, $data, false, $expire);
  220. if ( false !== $result )
  221. $this->cache[$key] = $data;
  222. return $result;
  223. }
  224. function set($id, $data, $group = 'default', $expire = 0) {
  225. $key = $this->key($id, $group);
  226. if ( isset($this->cache[$key]) && ('checkthedatabaseplease' === $this->cache[$key]) )
  227. return false;
  228. if ( is_object($data) )
  229. $data = clone $data;
  230. $this->cache[$key] = $data;
  231. if ( in_array($group, $this->no_mc_groups) )
  232. return true;
  233. $expire = ($expire == 0) ? $this->default_expiration : $expire;
  234. $mc =& $this->get_mc($group);
  235. $result = $mc->set($key, $data, false, $expire);
  236. return $result;
  237. }
  238. function colorize_debug_line($line) {
  239. $colors = array(
  240. 'get' => 'green',
  241. 'set' => 'purple',
  242. 'add' => 'blue',
  243. 'delete' => 'red');
  244. $cmd = substr($line, 0, strpos($line, ' '));
  245. $cmd2 = "<span style='color:{$colors[$cmd]}'>$cmd</span>";
  246. return $cmd2 . substr($line, strlen($cmd)) . "\n";
  247. }
  248. function stats() {
  249. echo "<p>\n";
  250. foreach ( $this->stats as $stat => $n ) {
  251. echo "<strong>$stat</strong> $n";
  252. echo "<br/>\n";
  253. }
  254. echo "</p>\n";
  255. echo "<h3>Memcached:</h3>";
  256. foreach ( $this->group_ops as $group => $ops ) {
  257. if ( !isset($_GET['debug_queries']) && 500 < count($ops) ) {
  258. $ops = array_slice( $ops, 0, 500 );
  259. echo "<big>Too many to show! <a href='" . esc_url( add_query_arg( 'debug_queries', 'true' ) ) . "'>Show them anyway</a>.</big>\n";
  260. }
  261. echo "<h4>$group commands</h4>";
  262. echo "<pre>\n";
  263. $lines = array();
  264. foreach ( $ops as $op ) {
  265. $lines[] = $this->colorize_debug_line($op);
  266. }
  267. print_r($lines);
  268. echo "</pre>\n";
  269. }
  270. if ( $this->debug )
  271. var_dump($this->memcache_debug);
  272. }
  273. function &get_mc($group) {
  274. if ( isset($this->mc[$group]) )
  275. return $this->mc[$group];
  276. return $this->mc['default'];
  277. }
  278. function failure_callback($host, $port) {
  279. //error_log("Connection failure for $host:$port\n", 3, '/tmp/memcached.txt');
  280. }
  281. function __construct() {
  282. global $memcached_servers;
  283. if ( isset($memcached_servers) )
  284. $buckets = $memcached_servers;
  285. else
  286. $buckets = array('127.0.0.1:11211');
  287. reset($buckets);
  288. if ( is_int( key($buckets) ) )
  289. $buckets = array('default' => $buckets);
  290. foreach ( $buckets as $bucket => $servers) {
  291. $this->mc[$bucket] = new Memcache();
  292. foreach ( $servers as $server ) {
  293. list ( $node, $port ) = explode(':', $server);
  294. if ( !$port )
  295. $port = ini_get('memcache.default_port');
  296. $port = intval($port);
  297. if ( !$port )
  298. $port = 11211;
  299. $this->mc[$bucket]->addServer($node, $port, true, 1, 1, 15, true, array($this, 'failure_callback'));
  300. $this->mc[$bucket]->setCompressThreshold(20000, 0.2);
  301. }
  302. }
  303. global $blog_id, $table_prefix;
  304. $this->global_prefix = '';
  305. $this->blog_prefix = '';
  306. if ( function_exists( 'is_multisite' ) ) {
  307. $this->global_prefix = ( is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE') ) ? '' : $table_prefix;
  308. $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ) . ':';
  309. }
  310. $this->cache_hits =& $this->stats['get'];
  311. $this->cache_misses =& $this->stats['add'];
  312. }
  313. }
  314. ?>