Merge pull request #15411 from systopia/dev_l10nx
[civicrm-core.git] / CRM / Core / BAO / WordReplacement.php
CommitLineData
d83a3991 1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
d83a3991 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
d83a3991 7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
d83a3991 27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
d83a3991 32 */
33
34/**
d09edf64 35 * Class CRM_Core_BAO_WordReplacement.
d83a3991 36 */
37class CRM_Core_BAO_WordReplacement extends CRM_Core_DAO_WordReplacement {
38
b5c2afd0 39 /**
d09edf64 40 * Class constructor.
b5c2afd0 41 */
00be9182 42 public function __construct() {
d83a3991 43 parent::__construct();
6cf5bb6f 44 }
353ffa53 45
d83a3991 46 /**
d09edf64
EM
47 * Function that must have never worked & should be removed.
48 *
fe482240
EM
49 * Retrieve DB object based on input parameters.
50 *
51 * It also stores all the retrieved values in the default array.
d83a3991 52 *
6a0b768e
TO
53 * @param array $params
54 * (reference ) an assoc array of name/value pairs.
55 * @param array $defaults
56 * (reference ) an assoc array to hold the flattened values.
d83a3991 57 *
ad37ac8e 58 * @return CRM_Core_DAO_WordReplacement
d83a3991 59 */
00be9182 60 public static function retrieve(&$params, &$defaults) {
d83a3991 61 return CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_WordRepalcement', $params, $defaults);
62 }
63
64 /**
d09edf64 65 * Get the domain BAO.
d83a3991 66 *
77b97be7
EM
67 * @param null $reset
68 *
d09edf64 69 * @return null|CRM_Core_BAO_WordReplacement
d83a3991 70 */
00be9182 71 public static function getWordReplacement($reset = NULL) {
d83a3991 72 static $wordReplacement = NULL;
73 if (!$wordReplacement || $reset) {
a36ecdd0 74 $wordReplacement = new CRM_Core_BAO_WordReplacement();
d83a3991 75 $wordReplacement->id = CRM_Core_Config::wordReplacementID();
76 if (!$wordReplacement->find(TRUE)) {
77 CRM_Core_Error::fatal();
78 }
79 }
80 return $wordReplacement;
81 }
82
d83a3991 83 /**
d09edf64 84 * Save the values of a WordReplacement.
d83a3991 85 *
c490a46a 86 * @param array $params
100fef9d 87 * @param int $id
77b97be7 88 *
72b3a70c 89 * @return array
d83a3991 90 */
00be9182 91 public static function edit(&$params, &$id) {
d83a3991 92 $wordReplacement = new CRM_Core_DAO_WordReplacement();
93 $wordReplacement->id = $id;
94 $wordReplacement->copyValues($params);
95 $wordReplacement->save();
63b71ea8
TO
96 if (!isset($params['options']) || CRM_Utils_Array::value('wp-rebuild', $params['options'], TRUE)) {
97 self::rebuild();
98 }
d83a3991 99 return $wordReplacement;
100 }
101
102 /**
d09edf64 103 * Create a new WordReplacement.
d83a3991 104 *
c490a46a 105 * @param array $params
dd244018 106 *
72b3a70c 107 * @return array
d83a3991 108 */
00be9182 109 public static function create($params) {
22e263ad 110 if (array_key_exists("domain_id", $params) === FALSE) {
6cf5bb6f
DL
111 $params["domain_id"] = CRM_Core_Config::domainID();
112 }
d83a3991 113 $wordReplacement = new CRM_Core_DAO_WordReplacement();
114 $wordReplacement->copyValues($params);
115 $wordReplacement->save();
63b71ea8
TO
116 if (!isset($params['options']) || CRM_Utils_Array::value('wp-rebuild', $params['options'], TRUE)) {
117 self::rebuild();
118 }
d83a3991 119 return $wordReplacement;
120 }
6cf5bb6f 121
d83a3991 122 /**
d09edf64 123 * Delete website.
d83a3991 124 *
6a0b768e
TO
125 * @param int $id
126 * WordReplacement id.
d83a3991 127 *
128 * @return object
d83a3991 129 */
00be9182 130 public static function del($id) {
d83a3991 131 $dao = new CRM_Core_DAO_WordReplacement();
132 $dao->id = $id;
133 $dao->delete();
63b71ea8
TO
134 if (!isset($params['options']) || CRM_Utils_Array::value('wp-rebuild', $params['options'], TRUE)) {
135 self::rebuild();
136 }
d83a3991 137 return $dao;
138 }
d83a3991 139
f01484bc 140 /**
d09edf64 141 * Get all word-replacements in the form of an array.
f01484bc 142 *
6a0b768e
TO
143 * @param int $id
144 * Domain ID.
d09edf64 145 *
f01484bc
TO
146 * @return array
147 * @see civicrm_domain.locale_custom_strings
148 */
149 public static function getAllAsConfigArray($id) {
6cf5bb6f
DL
150 $query = "
151SELECT find_word,replace_word,is_active,match_type
152FROM civicrm_word_replacement
153WHERE domain_id = %1
154";
be2fb01f 155 $params = [1 => [$id, 'Integer']];
6cf5bb6f
DL
156
157 $dao = CRM_Core_DAO::executeQuery($query, $params);
158
be2fb01f 159 $overrides = [];
6cf5bb6f 160
d83a3991 161 while ($dao->fetch()) {
2aa397bc 162 if ($dao->is_active == 1) {
a36ecdd0
E
163 $overrides['enabled'][$dao->match_type][$dao->find_word] = $dao->replace_word;
164 }
165 else {
166 $overrides['disabled'][$dao->match_type][$dao->find_word] = $dao->replace_word;
675605a7 167 }
d83a3991 168 }
d83a3991 169 $config = CRM_Core_Config::singleton();
170 $domain = new CRM_Core_DAO_Domain();
171 $domain->find(TRUE);
172
234d8f09
TO
173 // So. Weird. Some bizarre/probably-broken multi-lingual thing where
174 // data isn't really stored in civicrm_word_replacements. Probably
175 // shouldn't exist.
176 $stringOverride = self::_getLocaleCustomStrings($id);
177 $stringOverride[$config->lcMessages] = $overrides;
d83a3991 178
f01484bc
TO
179 return $stringOverride;
180 }
d83a3991 181
f01484bc 182 /**
d09edf64
EM
183 * Rebuild.
184 *
185 * @param bool $clearCaches
186 *
187 * @return bool
f01484bc 188 */
00be9182 189 public static function rebuild($clearCaches = TRUE) {
f01484bc 190 $id = CRM_Core_Config::domainID();
234d8f09 191 self::_setLocaleCustomStrings($id, self::getAllAsConfigArray($id));
f01484bc 192
234d8f09
TO
193 // Partially mitigate the inefficiency introduced in CRM-13187 by doing this conditionally
194 if ($clearCaches) {
195 // Reset navigation
196 CRM_Core_BAO_Navigation::resetNavigation();
197 // Clear js localization
198 CRM_Core_Resources::singleton()->flushStrings()->resetCacheCode();
d83a3991 199 }
f01484bc 200
234d8f09 201 return TRUE;
d83a3991 202 }
0f65e834
TO
203
204 /**
d09edf64
EM
205 * Get word replacements for the api.
206 *
b37b9bef
JV
207 * Get all the word-replacements stored in config-arrays for the
208 * configured language, and convert them to params for the
209 * WordReplacement.create API.
0f65e834
TO
210 *
211 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
212 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
213 * step behaves consistently even as the BAO evolves in future versions.
214 * However, if there's a bug in here prior to 4.4.0, we should apply the
d09edf64 215 * bug-fix in both places.
0f65e834 216 *
6a0b768e
TO
217 * @param bool $rebuildEach
218 * Whether to perform rebuild after each individual API call.
d09edf64 219 *
a6c01b45
CW
220 * @return array
221 * Each item is $params for WordReplacement.create
0f65e834
TO
222 * @see CRM_Core_BAO_WordReplacement::convertConfigArraysToAPIParams
223 */
00be9182 224 public static function getConfigArraysAsAPIParams($rebuildEach) {
be2fb01f 225 $settingsResult = civicrm_api3('Setting', 'get', [
b37b9bef 226 'return' => 'lcMessages',
be2fb01f 227 ]);
d6ef088f
JV
228 $returnValues = CRM_Utils_Array::first($settingsResult['values']);
229 $lang = $returnValues['lcMessages'];
b37b9bef 230
be2fb01f 231 $wordReplacementCreateParams = [];
0f65e834 232 // get all domains
be2fb01f
CW
233 $result = civicrm_api3('domain', 'get', [
234 'return' => ['locale_custom_strings'],
235 ]);
0f65e834
TO
236 if (!empty($result["values"])) {
237 foreach ($result["values"] as $value) {
be2fb01f 238 $params = [];
0f65e834 239 $params["domain_id"] = $value["id"];
be2fb01f 240 $params["options"] = ['wp-rebuild' => $rebuildEach];
d09edf64 241 // Unserialize word match string.
0f65e834
TO
242 $localeCustomArray = unserialize($value["locale_custom_strings"]);
243 if (!empty($localeCustomArray)) {
be2fb01f 244 $wordMatchArray = [];
b37b9bef
JV
245 // Only return the replacement strings of the current language,
246 // otherwise some replacements will be duplicated, which will
247 // lead to undesired results, like CRM-19683.
248 $localCustomData = $localeCustomArray[$lang];
249 // Traverse status array "enabled" "disabled"
250 foreach ($localCustomData as $status => $matchTypes) {
251 $params["is_active"] = ($status == "enabled") ? TRUE : FALSE;
252 // Traverse Match Type array "wildcardMatch" "exactMatch"
253 foreach ($matchTypes as $matchType => $words) {
254 $params["match_type"] = $matchType;
255 foreach ($words as $word => $replace) {
256 $params["find_word"] = $word;
257 $params["replace_word"] = $replace;
258 $wordReplacementCreateParams[] = $params;
a36ecdd0
E
259 }
260 }
0f65e834
TO
261 }
262 }
263 }
264 }
265 return $wordReplacementCreateParams;
266 }
267
268 /**
d09edf64
EM
269 * Rebuild word replacements.
270 *
0f65e834
TO
271 * Get all the word-replacements stored in config-arrays
272 * and write them out as records in civicrm_word_replacement.
273 *
274 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
275 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
276 * step behaves consistently even as the BAO evolves in future versions.
277 * However, if there's a bug in here prior to 4.4.0, we should apply the
d09edf64 278 * bug-fix in both places.
0f65e834
TO
279 */
280 public static function rebuildWordReplacementTable() {
be2fb01f
CW
281 civicrm_api3('word_replacement', 'replace', [
282 'options' => ['match' => ['domain_id', 'find_word']],
0f65e834 283 'values' => self::getConfigArraysAsAPIParams(FALSE),
be2fb01f 284 ]);
0f65e834
TO
285 CRM_Core_BAO_WordReplacement::rebuild();
286 }
96025800 287
234d8f09
TO
288 /**
289 * Get WordReplacements for a locale.
290 *
291 * @param string $locale
ad37ac8e 292 * @param int $domainId
293 *
234d8f09
TO
294 * @return array
295 * List of word replacements (enabled/disabled) for the given locale.
296 */
297 public static function getLocaleCustomStrings($locale, $domainId = NULL) {
298 if ($domainId === NULL) {
299 $domainId = CRM_Core_Config::domainID();
300 }
301
302 return CRM_Utils_Array::value($locale, self::_getLocaleCustomStrings($domainId));
303 }
304
ad37ac8e 305 /**
306 * Get custom locale strings.
307 *
308 * @param int $domainId
309 *
310 * @return array|mixed
311 */
234d8f09
TO
312 private static function _getLocaleCustomStrings($domainId) {
313 // TODO: Would it be worthwhile using memcache here?
be2fb01f
CW
314 $domain = CRM_Core_DAO::executeQuery('SELECT locale_custom_strings FROM civicrm_domain WHERE id = %1', [
315 1 => [$domainId, 'Integer'],
316 ]);
234d8f09 317 while ($domain->fetch()) {
be2fb01f 318 return empty($domain->locale_custom_strings) ? [] : unserialize($domain->locale_custom_strings);
234d8f09
TO
319 }
320 }
321
ad37ac8e 322 /**
323 * Set locale strings.
324 *
325 * @param string $locale
326 * @param array $values
327 * @param int $domainId
328 */
234d8f09
TO
329 public static function setLocaleCustomStrings($locale, $values, $domainId = NULL) {
330 if ($domainId === NULL) {
331 $domainId = CRM_Core_Config::domainID();
332 }
333
334 $lcs = self::_getLocaleCustomStrings($domainId);
335 $lcs[$locale] = $values;
336
337 self::_setLocaleCustomStrings($domainId, $lcs);
338 }
339
340 /**
ad37ac8e 341 * Set locale strings.
342 *
343 * @param int $domainId
344 * @param string $lcs
234d8f09
TO
345 */
346 private static function _setLocaleCustomStrings($domainId, $lcs) {
be2fb01f
CW
347 CRM_Core_DAO::executeQuery("UPDATE civicrm_domain SET locale_custom_strings = %1 WHERE id = %2", [
348 1 => [serialize($lcs), 'String'],
349 2 => [$domainId, 'Integer'],
350 ]);
234d8f09
TO
351 }
352
d83a3991 353}