Allow rerouting CRM_Core_BAO_Cache::{set,get}Item(s) to PSR-16 drivers
[civicrm-core.git] / CRM / Core / BAO / Cache / Psr16.php
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 */
89 public static function &getItem($group, $path, $componentID = NULL) {
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 }
98 $value = self::getGroup($group)->get(CRM_Core_BAO_Cache::cleanKey($path));
99 return $value;
100 }
101
102 /**
103 * Retrieve all items in a group.
104 *
105 * @param string $group
106 * (required) The group name of the item.
107 * @param int $componentID
108 * The optional component ID (so componenets can share the same name space).
109 *
110 * @throws CRM_Core_Exception
111 */
112 public static function &getItems($group, $componentID = NULL) {
113 // Based on grepping universe, this function is not currently used.
114 // Moreover, it's hard to implement in PSR-16. (We'd have to extend the
115 // interface.) Let's wait and see if anyone actually needs this...
116 throw new \CRM_Core_Exception('Not implemented: CRM_Core_BAO_Cache_Psr16::getItems');
117 }
118
119 /**
120 * Store an item in the DB cache.
121 *
122 * @param object $data
123 * (required) A reference to the data that will be serialized and stored.
124 * @param string $group
125 * (required) The group name of the item.
126 * @param string $path
127 * (required) The path under which this item is stored.
128 * @param int $componentID
129 * The optional component ID (so componenets can share the same name space).
130 */
131 public static function setItem(&$data, $group, $path, $componentID = NULL) {
132 // TODO: Generate a general deprecation notice.
133
134 if ($componentID) {
135 Civi::log()
136 ->warning('setItem({group},{path},...) uses unsupported componentID. Consider migrating explicitly to PSR-16.', [
137 'group' => $group,
138 'path' => $path,
139 ]);
140 }
141 self::getGroup($group)
142 ->set(CRM_Core_BAO_Cache::cleanKey($path), $data, self::TTL);
143 }
144
145 /**
146 * Delete all the cache elements that belong to a group OR delete the entire cache if group is not specified.
147 *
148 * @param string $group
149 * The group name of the entries to be deleted.
150 * @param string $path
151 * Path of the item that needs to be deleted.
152 */
153 public static function deleteGroup($group = NULL, $path = NULL) {
154 // FIXME: Generate a general deprecation notice.
155
156 if ($path) {
157 self::getGroup($group)->delete(CRM_Core_BAO_Cache::cleanKey($path));
158 }
159 else {
160 self::getGroup($group)->clear();
161 }
162 }
163
164 /**
165 * Cleanup any caches that we've mapped.
166 *
167 * Traditional SQL-backed caches are cleared as a matter of course during a
168 * system flush (by way of "TRUNCATE TABLE civicrm_cache"). This provides
169 * a spot where the adapter can
170 */
171 public static function clearDBCache() {
172 foreach (self::getLegacyGroups() as $groupName) {
173 $group = self::getGroup($groupName);
174 $group->clear();
175 }
176 }
177
178 /**
179 * Get a list of known cache-groups
180 *
181 * @return array
182 */
183 public static function getLegacyGroups() {
184 return [
185 // Core
186 'CiviCRM Search PrevNextCache',
187 'contact fields',
188 'navigation',
189 'contact groups',
190 'custom data',
191
192 // Universe
193 'dashboard', // be.chiro.civi.atomfeeds
194 'lineitem-editor', // biz.jmaconsulting.lineitemedit
195 'HRCore_Info', // civihr/uk.co.compucorp.civicrm.hrcore
196 'CiviCRM setting Spec', // nz.co.fuzion.entitysetting
197 'descendant groups for an org', // org.civicrm.multisite
198 ];
199 }
200
201 }