Merge pull request #16156 from civicrm/5.21
[civicrm-core.git] / CRM / Utils / Cache / APCcache.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17 class CRM_Utils_Cache_APCcache implements CRM_Utils_Cache_Interface {
18
19 // TODO Consider native implementation.
20 use CRM_Utils_Cache_NaiveMultipleTrait;
21 // TODO Native implementation
22 use CRM_Utils_Cache_NaiveHasTrait;
23
24 const DEFAULT_TIMEOUT = 3600;
25 const DEFAULT_PREFIX = '';
26
27 /**
28 * The default timeout to use.
29 *
30 * @var int
31 */
32 protected $_timeout = self::DEFAULT_TIMEOUT;
33
34 /**
35 * The prefix prepended to cache keys.
36 *
37 * If we are using the same memcache instance for multiple CiviCRM
38 * installs, we must have a unique prefix for each install to prevent
39 * the keys from clobbering each other.
40 *
41 * @var string
42 */
43 protected $_prefix = self::DEFAULT_PREFIX;
44
45 /**
46 * Constructor.
47 *
48 * @param array $config
49 * An array of configuration params.
50 *
51 * @return \CRM_Utils_Cache_APCcache
52 */
53 public function __construct(&$config) {
54 if (isset($config['timeout'])) {
55 $this->_timeout = intval($config['timeout']);
56 }
57 if (isset($config['prefix'])) {
58 $this->_prefix = $config['prefix'];
59 }
60 }
61
62 /**
63 * @param $key
64 * @param $value
65 * @param null|int|\DateInterval $ttl
66 *
67 * @return bool
68 */
69 public function set($key, $value, $ttl = NULL) {
70 CRM_Utils_Cache::assertValidKey($key);
71 if (is_int($ttl) && $ttl <= 0) {
72 return $this->delete($key);
73 }
74
75 $ttl = CRM_Utils_Date::convertCacheTtl($ttl, $this->_timeout);
76 $expires = time() + $ttl;
77 if (!apc_store($this->_prefix . $key, ['e' => $expires, 'v' => $value], $ttl)) {
78 return FALSE;
79 }
80 return TRUE;
81 }
82
83 /**
84 * @param $key
85 * @param mixed $default
86 *
87 * @return mixed
88 */
89 public function get($key, $default = NULL) {
90 CRM_Utils_Cache::assertValidKey($key);
91 $result = apc_fetch($this->_prefix . $key, $success);
92 if ($success && isset($result['e']) && $result['e'] > time()) {
93 return $this->reobjectify($result['v']);
94 }
95 return $default;
96 }
97
98 /**
99 * @param $key
100 *
101 * @return bool|string[]
102 */
103 public function delete($key) {
104 CRM_Utils_Cache::assertValidKey($key);
105 apc_delete($this->_prefix . $key);
106 return TRUE;
107 }
108
109 public function flush() {
110 $allinfo = apc_cache_info('user');
111 $keys = $allinfo['cache_list'];
112 // Our keys follows this pattern: ([A-Za-z0-9_]+)?CRM_[A-Za-z0-9_]+
113 $prefix = $this->_prefix;
114 // Get prefix length
115 $lp = strlen($prefix);
116
117 foreach ($keys as $key) {
118 $name = $key['info'];
119 if ($prefix == substr($name, 0, $lp)) {
120 // Ours?
121 apc_delete($name);
122 }
123 }
124 return TRUE;
125 }
126
127 public function clear() {
128 return $this->flush();
129 }
130
131 private function reobjectify($value) {
132 return is_object($value) ? unserialize(serialize($value)) : $value;
133 }
134
135 }