Merge pull request #14694 from eileenmcnaughton/cust_field_bulk
[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' => ['*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 return self::getGroup($group)->get(CRM_Utils_Cache::cleanKey($path));
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_Utils_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_Utils_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 $groups = [
184 // Core
185 'contact fields',
186 'navigation',
187 'custom data',
188
189 // Universe
190
191 // be.chiro.civi.atomfeeds
192 'dashboard',
193
194 // biz.jmaconsulting.lineitemedit
195 'lineitem-editor',
196
197 // civihr/uk.co.compucorp.civicrm.hrcore
198 'HRCore_Info',
199
200 ];
201 // Handle Legacy Multisite caching group.
202 $extensions = CRM_Extension_System::singleton()->getManager();
203 $multisiteExtensionStatus = $extensions->getStatus('org.civicrm.multisite');
204 if ($multisiteExtensionStatus == $extensions::STATUS_INSTALLED) {
205 $extension_version = civicrm_api3('Extension', 'get', ['key' => 'org.civicrm.multisite'])['values'][0]['version'];
206 if (version_compare($extension_version, '2.7', '<')) {
207 Civi::log()->warning(
208 'CRM_Core_BAO_Cache_PSR is deprecated for multisite extension, you should upgrade to the latest version to avoid this warning, this code will be removed at the end of 2019',
209 ['civi.tag' => 'deprecated']
210 );
211 $groups[] = 'descendant groups for an org';
212 }
213 }
214 $entitySettingExtensionStatus = $extensions->getStatus('nz.co.fuzion.entitysetting');
215 if ($multisiteExtensionStatus == $extensions::STATUS_INSTALLED) {
216 $extension_version = civicrm_api3('Extension', 'get', ['key' => 'nz.co.fuzion.entitysetting'])['values'][0]['version'];
217 if (version_compare($extension_version, '1.3', '<')) {
218 Civi::log()->warning(
219 'CRM_Core_BAO_Cache_PSR is deprecated for entity setting extension, you should upgrade to the latest version to avoid this warning, this code will be removed at the end of 2019',
220 ['civi.tag' => 'deprecated']
221 );
222 $groups[] = 'CiviCRM setting Spec';
223 }
224 }
225 return $groups;
226 }
227
228 }