Merge pull request #23895 from colemanw/searchKitManaged
[civicrm-core.git] / CRM / Core / BAO / WordReplacement.php
CommitLineData
d83a3991 1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
d83a3991 5 | |
bc77d7c0
TO
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 |
d83a3991 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
d83a3991 11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
d83a3991 16 */
17
18/**
d09edf64 19 * Class CRM_Core_BAO_WordReplacement.
d83a3991 20 */
ee44263e 21class CRM_Core_BAO_WordReplacement extends CRM_Core_DAO_WordReplacement implements \Civi\Core\HookInterface {
d83a3991 22
d83a3991 23 /**
4f940304 24 * Retrieve DB object and copy to defaults array.
d83a3991 25 *
6a0b768e 26 * @param array $params
4f940304 27 * Array of criteria values.
6a0b768e 28 * @param array $defaults
4f940304 29 * Array to be populated with found values.
d83a3991 30 *
4f940304
CW
31 * @return self|null
32 * The DAO object, if found.
33 *
34 * @deprecated
d83a3991 35 */
4f940304
CW
36 public static function retrieve($params, &$defaults) {
37 return self::commonRetrieve(self::class, $params, $defaults);
d83a3991 38 }
39
d83a3991 40 /**
700dda89 41 * Deprecated update function.
d83a3991 42 *
700dda89 43 * @deprecated
c490a46a 44 * @param array $params
100fef9d 45 * @param int $id
72b3a70c 46 * @return array
d83a3991 47 */
00be9182 48 public static function edit(&$params, &$id) {
700dda89 49 CRM_Core_Error::deprecatedWarning('APIv4');
d83a3991 50 $wordReplacement = new CRM_Core_DAO_WordReplacement();
51 $wordReplacement->id = $id;
52 $wordReplacement->copyValues($params);
53 $wordReplacement->save();
63b71ea8
TO
54 if (!isset($params['options']) || CRM_Utils_Array::value('wp-rebuild', $params['options'], TRUE)) {
55 self::rebuild();
56 }
d83a3991 57 return $wordReplacement;
58 }
59
60 /**
700dda89 61 * Deprecated create function.
d83a3991 62 *
700dda89 63 * @deprecated
c490a46a 64 * @param array $params
72b3a70c 65 * @return array
d83a3991 66 */
00be9182 67 public static function create($params) {
22e263ad 68 if (array_key_exists("domain_id", $params) === FALSE) {
6cf5bb6f
DL
69 $params["domain_id"] = CRM_Core_Config::domainID();
70 }
d83a3991 71 $wordReplacement = new CRM_Core_DAO_WordReplacement();
72 $wordReplacement->copyValues($params);
73 $wordReplacement->save();
63b71ea8
TO
74 if (!isset($params['options']) || CRM_Utils_Array::value('wp-rebuild', $params['options'], TRUE)) {
75 self::rebuild();
76 }
d83a3991 77 return $wordReplacement;
78 }
6cf5bb6f 79
d83a3991 80 /**
de6cd515 81 * Deprecated delete function
d83a3991 82 *
de6cd515 83 * @deprecated
6a0b768e 84 * @param int $id
de6cd515 85 * @return CRM_Core_DAO_WordReplacement
d83a3991 86 */
00be9182 87 public static function del($id) {
de6cd515
CW
88 return static::deleteRecord(['id' => $id]);
89 }
90
91 /**
92 * Callback for hook_civicrm_post().
93 * @param \Civi\Core\Event\PostEvent $event
94 */
95 public static function self_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) {
96 if ($event->action === 'delete') {
63b71ea8
TO
97 self::rebuild();
98 }
de6cd515
CW
99 }
100
101 /**
102 * Efficient function to write multiple records then rebuild at the end
103 *
104 * @param array[] $records
105 * @return CRM_Core_DAO_WordReplacement[]
106 * @throws CRM_Core_Exception
107 */
108 public static function writeRecords(array $records): array {
109 $records = parent::writeRecords($records);
110 self::rebuild();
111 return $records;
d83a3991 112 }
d83a3991 113
f01484bc 114 /**
d09edf64 115 * Get all word-replacements in the form of an array.
f01484bc 116 *
6a0b768e
TO
117 * @param int $id
118 * Domain ID.
d09edf64 119 *
f01484bc
TO
120 * @return array
121 * @see civicrm_domain.locale_custom_strings
122 */
123 public static function getAllAsConfigArray($id) {
6cf5bb6f
DL
124 $query = "
125SELECT find_word,replace_word,is_active,match_type
126FROM civicrm_word_replacement
127WHERE domain_id = %1
128";
be2fb01f 129 $params = [1 => [$id, 'Integer']];
6cf5bb6f
DL
130
131 $dao = CRM_Core_DAO::executeQuery($query, $params);
132
be2fb01f 133 $overrides = [];
6cf5bb6f 134
d83a3991 135 while ($dao->fetch()) {
2aa397bc 136 if ($dao->is_active == 1) {
a36ecdd0
E
137 $overrides['enabled'][$dao->match_type][$dao->find_word] = $dao->replace_word;
138 }
139 else {
140 $overrides['disabled'][$dao->match_type][$dao->find_word] = $dao->replace_word;
675605a7 141 }
d83a3991 142 }
d83a3991 143 $config = CRM_Core_Config::singleton();
d83a3991 144
234d8f09
TO
145 // So. Weird. Some bizarre/probably-broken multi-lingual thing where
146 // data isn't really stored in civicrm_word_replacements. Probably
147 // shouldn't exist.
148 $stringOverride = self::_getLocaleCustomStrings($id);
149 $stringOverride[$config->lcMessages] = $overrides;
d83a3991 150
f01484bc
TO
151 return $stringOverride;
152 }
d83a3991 153
f01484bc 154 /**
d09edf64
EM
155 * Rebuild.
156 *
157 * @param bool $clearCaches
158 *
159 * @return bool
f01484bc 160 */
00be9182 161 public static function rebuild($clearCaches = TRUE) {
f01484bc 162 $id = CRM_Core_Config::domainID();
234d8f09 163 self::_setLocaleCustomStrings($id, self::getAllAsConfigArray($id));
f01484bc 164
234d8f09
TO
165 // Partially mitigate the inefficiency introduced in CRM-13187 by doing this conditionally
166 if ($clearCaches) {
167 // Reset navigation
168 CRM_Core_BAO_Navigation::resetNavigation();
169 // Clear js localization
170 CRM_Core_Resources::singleton()->flushStrings()->resetCacheCode();
d83a3991 171 }
f01484bc 172
234d8f09 173 return TRUE;
d83a3991 174 }
0f65e834
TO
175
176 /**
d09edf64
EM
177 * Get word replacements for the api.
178 *
b37b9bef
JV
179 * Get all the word-replacements stored in config-arrays for the
180 * configured language, and convert them to params for the
181 * WordReplacement.create API.
0f65e834
TO
182 *
183 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
184 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
185 * step behaves consistently even as the BAO evolves in future versions.
186 * However, if there's a bug in here prior to 4.4.0, we should apply the
d09edf64 187 * bug-fix in both places.
0f65e834 188 *
6a0b768e
TO
189 * @param bool $rebuildEach
190 * Whether to perform rebuild after each individual API call.
d09edf64 191 *
a6c01b45
CW
192 * @return array
193 * Each item is $params for WordReplacement.create
0f65e834
TO
194 * @see CRM_Core_BAO_WordReplacement::convertConfigArraysToAPIParams
195 */
00be9182 196 public static function getConfigArraysAsAPIParams($rebuildEach) {
be2fb01f 197 $settingsResult = civicrm_api3('Setting', 'get', [
b37b9bef 198 'return' => 'lcMessages',
be2fb01f 199 ]);
d6ef088f
JV
200 $returnValues = CRM_Utils_Array::first($settingsResult['values']);
201 $lang = $returnValues['lcMessages'];
b37b9bef 202
be2fb01f 203 $wordReplacementCreateParams = [];
0f65e834 204 // get all domains
be2fb01f
CW
205 $result = civicrm_api3('domain', 'get', [
206 'return' => ['locale_custom_strings'],
207 ]);
0f65e834
TO
208 if (!empty($result["values"])) {
209 foreach ($result["values"] as $value) {
be2fb01f 210 $params = [];
0f65e834 211 $params["domain_id"] = $value["id"];
be2fb01f 212 $params["options"] = ['wp-rebuild' => $rebuildEach];
d09edf64 213 // Unserialize word match string.
f24846d5 214 $localeCustomArray = CRM_Utils_String::unserialize($value["locale_custom_strings"]);
0f65e834 215 if (!empty($localeCustomArray)) {
be2fb01f 216 $wordMatchArray = [];
b37b9bef
JV
217 // Only return the replacement strings of the current language,
218 // otherwise some replacements will be duplicated, which will
219 // lead to undesired results, like CRM-19683.
220 $localCustomData = $localeCustomArray[$lang];
221 // Traverse status array "enabled" "disabled"
222 foreach ($localCustomData as $status => $matchTypes) {
63d76404 223 $params["is_active"] = $status == "enabled";
b37b9bef
JV
224 // Traverse Match Type array "wildcardMatch" "exactMatch"
225 foreach ($matchTypes as $matchType => $words) {
226 $params["match_type"] = $matchType;
227 foreach ($words as $word => $replace) {
228 $params["find_word"] = $word;
229 $params["replace_word"] = $replace;
230 $wordReplacementCreateParams[] = $params;
a36ecdd0
E
231 }
232 }
0f65e834
TO
233 }
234 }
235 }
236 }
237 return $wordReplacementCreateParams;
238 }
239
240 /**
d09edf64
EM
241 * Rebuild word replacements.
242 *
0f65e834
TO
243 * Get all the word-replacements stored in config-arrays
244 * and write them out as records in civicrm_word_replacement.
245 *
246 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
247 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
248 * step behaves consistently even as the BAO evolves in future versions.
249 * However, if there's a bug in here prior to 4.4.0, we should apply the
d09edf64 250 * bug-fix in both places.
0f65e834
TO
251 */
252 public static function rebuildWordReplacementTable() {
be2fb01f
CW
253 civicrm_api3('word_replacement', 'replace', [
254 'options' => ['match' => ['domain_id', 'find_word']],
0f65e834 255 'values' => self::getConfigArraysAsAPIParams(FALSE),
be2fb01f 256 ]);
0f65e834
TO
257 CRM_Core_BAO_WordReplacement::rebuild();
258 }
96025800 259
234d8f09
TO
260 /**
261 * Get WordReplacements for a locale.
262 *
263 * @param string $locale
ad37ac8e 264 * @param int $domainId
265 *
234d8f09
TO
266 * @return array
267 * List of word replacements (enabled/disabled) for the given locale.
268 */
269 public static function getLocaleCustomStrings($locale, $domainId = NULL) {
270 if ($domainId === NULL) {
271 $domainId = CRM_Core_Config::domainID();
272 }
273
274 return CRM_Utils_Array::value($locale, self::_getLocaleCustomStrings($domainId));
275 }
276
ad37ac8e 277 /**
278 * Get custom locale strings.
279 *
280 * @param int $domainId
281 *
282 * @return array|mixed
283 */
234d8f09
TO
284 private static function _getLocaleCustomStrings($domainId) {
285 // TODO: Would it be worthwhile using memcache here?
be2fb01f
CW
286 $domain = CRM_Core_DAO::executeQuery('SELECT locale_custom_strings FROM civicrm_domain WHERE id = %1', [
287 1 => [$domainId, 'Integer'],
288 ]);
234d8f09 289 while ($domain->fetch()) {
f24846d5 290 return empty($domain->locale_custom_strings) ? [] : CRM_Utils_String::unserialize($domain->locale_custom_strings);
234d8f09
TO
291 }
292 }
293
ad37ac8e 294 /**
295 * Set locale strings.
296 *
297 * @param string $locale
298 * @param array $values
299 * @param int $domainId
300 */
234d8f09
TO
301 public static function setLocaleCustomStrings($locale, $values, $domainId = NULL) {
302 if ($domainId === NULL) {
303 $domainId = CRM_Core_Config::domainID();
304 }
305
306 $lcs = self::_getLocaleCustomStrings($domainId);
307 $lcs[$locale] = $values;
308
309 self::_setLocaleCustomStrings($domainId, $lcs);
310 }
311
312 /**
ad37ac8e 313 * Set locale strings.
314 *
315 * @param int $domainId
316 * @param string $lcs
234d8f09
TO
317 */
318 private static function _setLocaleCustomStrings($domainId, $lcs) {
be2fb01f
CW
319 CRM_Core_DAO::executeQuery("UPDATE civicrm_domain SET locale_custom_strings = %1 WHERE id = %2", [
320 1 => [serialize($lcs), 'String'],
321 2 => [$domainId, 'Integer'],
322 ]);
234d8f09
TO
323 }
324
d83a3991 325}