Commit | Line | Data |
---|---|---|
5a302bbc TO |
1 | <?php |
2 | ||
3 | /* | |
4 | +--------------------------------------------------------------------+ | |
5 | | CiviCRM version 5 | | |
6 | +--------------------------------------------------------------------+ | |
7 | | Copyright CiviCRM LLC (c) 2004-2019 | | |
8 | +--------------------------------------------------------------------+ | |
9 | | This file is a part of CiviCRM. | | |
10 | | | | |
11 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
12 | | under the terms of the GNU Affero General Public License | | |
13 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
14 | | | | |
15 | | CiviCRM is distributed in the hope that it will be useful, but | | |
16 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
17 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
18 | | See the GNU Affero General Public License for more details. | | |
19 | | | | |
20 | | You should have received a copy of the GNU Affero General Public | | |
21 | | License and the CiviCRM Licensing Exception along | | |
22 | | with this program; if not, contact CiviCRM LLC | | |
23 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
24 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
25 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
26 | +--------------------------------------------------------------------+ | |
27 | */ | |
28 | ||
29 | /** | |
30 | * Class CRM_Core_BAO_Cache_Psr16 | |
31 | * | |
32 | * This optional adapter to help phase-out CRM_Core_BAO_Cache. | |
33 | * | |
34 | * In effect, it changes the default behavior of legacy cache-consumers | |
35 | * (CRM_Core_BAO_Cache) so that they store in the best-available tier | |
36 | * (Reds/Memcache or SQL or array) rather than being hard-coded to SQL. | |
37 | * | |
38 | * It basically just calls "CRM_Utils_Cache::create()" for each $group and | |
39 | * maps the getItem/setItem to get()/set(). | |
40 | */ | |
41 | class CRM_Core_BAO_Cache_Psr16 { | |
42 | ||
43 | /** | |
44 | * Original BAO behavior did not do expiration. PSR-16 providers have | |
45 | * diverse defaults. To provide some consistency, we'll pick a long(ish) | |
46 | * TTL for everything that goes through the adapter. | |
47 | */ | |
48 | const TTL = 86400; | |
49 | ||
50 | /** | |
51 | * @param string $group | |
52 | * @return CRM_Utils_Cache_Interface | |
53 | */ | |
54 | protected static function getGroup($group) { | |
55 | if (!isset(Civi::$statics[__CLASS__][$group])) { | |
56 | if (!in_array($group, self::getLegacyGroups())) { | |
57 | Civi::log() | |
58 | ->warning('Unrecognized BAO cache group ({group}). This should work generally, but data may not be flushed in some edge-cases. Consider migrating explicitly to PSR-16.', [ | |
59 | 'group' => $group, | |
60 | ]); | |
61 | } | |
62 | ||
63 | $cache = CRM_Utils_Cache::create([ | |
64 | 'name' => "bao_$group", | |
65 | 'type' => array('*memory*', 'SqlGroup', 'ArrayCache'), | |
66 | // We're replacing CRM_Core_BAO_Cache, which traditionally used a front-cache | |
67 | // that was not aware of TTLs. So it seems more consistent/performant to | |
68 | // use 'fast' here. | |
69 | 'withArray' => 'fast', | |
70 | ]); | |
71 | Civi::$statics[__CLASS__][$group] = $cache; | |
72 | } | |
73 | return Civi::$statics[__CLASS__][$group]; | |
74 | } | |
75 | ||
76 | /** | |
77 | * Retrieve an item from the DB cache. | |
78 | * | |
79 | * @param string $group | |
80 | * (required) The group name of the item. | |
81 | * @param string $path | |
82 | * (required) The path under which this item is stored. | |
83 | * @param int $componentID | |
84 | * The optional component ID (so componenets can share the same name space). | |
85 | * | |
86 | * @return object | |
87 | * The data if present in cache, else null | |
88 | */ | |
b5e7d576 | 89 | public static function getItem($group, $path, $componentID = NULL) { |
5a302bbc TO |
90 | // TODO: Generate a general deprecation notice. |
91 | if ($componentID) { | |
92 | Civi::log() | |
93 | ->warning('getItem({group},{path},...) uses unsupported componentID. Consider migrating explicitly to PSR-16.', [ | |
94 | 'group' => $group, | |
95 | 'path' => $path, | |
96 | ]); | |
97 | } | |
b5e7d576 | 98 | return self::getGroup($group)->get(CRM_Core_BAO_Cache::cleanKey($path)); |
5a302bbc TO |
99 | } |
100 | ||
101 | /** | |
102 | * Retrieve all items in a group. | |
103 | * | |
104 | * @param string $group | |
105 | * (required) The group name of the item. | |
106 | * @param int $componentID | |
107 | * The optional component ID (so componenets can share the same name space). | |
108 | * | |
109 | * @throws CRM_Core_Exception | |
110 | */ | |
111 | public static function &getItems($group, $componentID = NULL) { | |
112 | // Based on grepping universe, this function is not currently used. | |
113 | // Moreover, it's hard to implement in PSR-16. (We'd have to extend the | |
114 | // interface.) Let's wait and see if anyone actually needs this... | |
115 | throw new \CRM_Core_Exception('Not implemented: CRM_Core_BAO_Cache_Psr16::getItems'); | |
116 | } | |
117 | ||
118 | /** | |
119 | * Store an item in the DB cache. | |
120 | * | |
121 | * @param object $data | |
122 | * (required) A reference to the data that will be serialized and stored. | |
123 | * @param string $group | |
124 | * (required) The group name of the item. | |
125 | * @param string $path | |
126 | * (required) The path under which this item is stored. | |
127 | * @param int $componentID | |
128 | * The optional component ID (so componenets can share the same name space). | |
129 | */ | |
130 | public static function setItem(&$data, $group, $path, $componentID = NULL) { | |
131 | // TODO: Generate a general deprecation notice. | |
132 | ||
133 | if ($componentID) { | |
134 | Civi::log() | |
135 | ->warning('setItem({group},{path},...) uses unsupported componentID. Consider migrating explicitly to PSR-16.', [ | |
136 | 'group' => $group, | |
137 | 'path' => $path, | |
138 | ]); | |
139 | } | |
140 | self::getGroup($group) | |
141 | ->set(CRM_Core_BAO_Cache::cleanKey($path), $data, self::TTL); | |
142 | } | |
143 | ||
144 | /** | |
145 | * Delete all the cache elements that belong to a group OR delete the entire cache if group is not specified. | |
146 | * | |
147 | * @param string $group | |
148 | * The group name of the entries to be deleted. | |
149 | * @param string $path | |
150 | * Path of the item that needs to be deleted. | |
151 | */ | |
152 | public static function deleteGroup($group = NULL, $path = NULL) { | |
153 | // FIXME: Generate a general deprecation notice. | |
154 | ||
155 | if ($path) { | |
156 | self::getGroup($group)->delete(CRM_Core_BAO_Cache::cleanKey($path)); | |
157 | } | |
158 | else { | |
159 | self::getGroup($group)->clear(); | |
160 | } | |
161 | } | |
162 | ||
163 | /** | |
164 | * Cleanup any caches that we've mapped. | |
165 | * | |
166 | * Traditional SQL-backed caches are cleared as a matter of course during a | |
167 | * system flush (by way of "TRUNCATE TABLE civicrm_cache"). This provides | |
168 | * a spot where the adapter can | |
169 | */ | |
170 | public static function clearDBCache() { | |
171 | foreach (self::getLegacyGroups() as $groupName) { | |
172 | $group = self::getGroup($groupName); | |
173 | $group->clear(); | |
174 | } | |
175 | } | |
176 | ||
177 | /** | |
178 | * Get a list of known cache-groups | |
179 | * | |
180 | * @return array | |
181 | */ | |
182 | public static function getLegacyGroups() { | |
183 | return [ | |
184 | // Core | |
185 | 'CiviCRM Search PrevNextCache', | |
186 | 'contact fields', | |
187 | 'navigation', | |
188 | 'contact groups', | |
189 | 'custom data', | |
190 | ||
191 | // Universe | |
192 | 'dashboard', // be.chiro.civi.atomfeeds | |
193 | 'lineitem-editor', // biz.jmaconsulting.lineitemedit | |
194 | 'HRCore_Info', // civihr/uk.co.compucorp.civicrm.hrcore | |
195 | 'CiviCRM setting Spec', // nz.co.fuzion.entitysetting | |
196 | 'descendant groups for an org', // org.civicrm.multisite | |
197 | ]; | |
198 | } | |
199 | ||
200 | } |