Merge pull request #17008 from ivan-compucorp/CPS-70-fix-radio-value
[civicrm-core.git] / CRM / Core / BAO / ConfigSetting.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 */
18
19 /**
20 * File contains functions used in civicrm configuration.
21 */
22 class CRM_Core_BAO_ConfigSetting {
23
24 /**
25 * Create civicrm settings. This is the same as add but it clears the cache and
26 * reloads the config object
27 *
28 * @param array $params
29 * Associated array of civicrm variables.
30 */
31 public static function create($params) {
32 self::add($params);
33 $cache = CRM_Utils_Cache::singleton();
34 $cache->delete('CRM_Core_Config');
35 $cache->delete('CRM_Core_Config' . CRM_Core_Config::domainID());
36 $config = CRM_Core_Config::singleton(TRUE, TRUE);
37 }
38
39 /**
40 * Add civicrm settings.
41 *
42 * @param array $params
43 * Associated array of civicrm variables.
44 * @deprecated
45 * This method was historically used to access civicrm_domain.config_backend.
46 * However, that has been fully replaced by the settings system since v4.7.
47 */
48 public static function add(&$params) {
49 $domain = new CRM_Core_DAO_Domain();
50 $domain->id = CRM_Core_Config::domainID();
51 $domain->find(TRUE);
52 if ($domain->config_backend) {
53 $params = array_merge(unserialize($domain->config_backend), $params);
54 }
55
56 $params = CRM_Core_BAO_ConfigSetting::filterSkipVars($params);
57
58 // also skip all Dir Params, we dont need to store those in the DB!
59 foreach ($params as $name => $val) {
60 if (substr($name, -3) == 'Dir') {
61 unset($params[$name]);
62 }
63 }
64
65 $domain->config_backend = serialize($params);
66 $domain->save();
67 }
68
69 /**
70 * Retrieve the settings values from db.
71 *
72 * @param $defaults
73 *
74 * @return array
75 * @deprecated
76 * This method was historically used to access civicrm_domain.config_backend.
77 * However, that has been fully replaced by the settings system since v4.7.
78 */
79 public static function retrieve(&$defaults) {
80 $domain = new CRM_Core_DAO_Domain();
81 $isUpgrade = CRM_Core_Config::isUpgradeMode();
82
83 //we are initializing config, really can't use, CRM-7863
84 $urlVar = 'q';
85 if (defined('CIVICRM_UF') && CIVICRM_UF == 'Joomla') {
86 $urlVar = 'task';
87 }
88
89 $hasBackend = CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_domain', 'config_backend');
90 if ($isUpgrade && $hasBackend) {
91 $domain->selectAdd('config_backend');
92 }
93 else {
94 $domain->selectAdd('locales');
95 }
96
97 $domain->id = CRM_Core_Config::domainID();
98 $domain->find(TRUE);
99 if ($hasBackend && $domain->config_backend) {
100 // This whole branch can probably be removed; the transitional loading
101 // is in SettingBag::loadValues(). Moreover, since 4.7.alpha1 dropped
102 // the column, anyone calling ::retrieve() has likely not gotten any data.
103 $defaults = unserialize($domain->config_backend);
104 if ($defaults === FALSE || !is_array($defaults)) {
105 $defaults = [];
106 return FALSE;
107 }
108
109 $skipVars = self::skipVars();
110 foreach ($skipVars as $skip) {
111 if (array_key_exists($skip, $defaults)) {
112 unset($defaults[$skip]);
113 }
114 }
115 }
116 if (!$isUpgrade) {
117 CRM_Core_BAO_ConfigSetting::applyLocale(Civi::settings($domain->id), $domain->locales);
118 }
119 }
120
121 /**
122 * Evaluate locale preferences and activate a chosen locale by
123 * updating session+global variables.
124 *
125 * @param \Civi\Core\SettingsBag $settings
126 * @param string $activatedLocales
127 * Imploded list of locales which are supported in the DB.
128 */
129 public static function applyLocale($settings, $activatedLocales) {
130 // are we in a multi-language setup?
131 $multiLang = (bool) $activatedLocales;
132
133 // set the current language
134 $chosenLocale = NULL;
135
136 $session = CRM_Core_Session::singleton();
137
138 $permittedLanguages = CRM_Core_I18n::uiLanguages(TRUE);
139
140 // The locale to be used can come from various places:
141 // - the request (url)
142 // - the session
143 // - civicrm_uf_match
144 // - inherited from the CMS
145 // Only look at this if there is actually a choice of permitted languages
146 if (count($permittedLanguages) >= 2) {
147 $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
148 if (in_array($requestLocale, $permittedLanguages)) {
149 $chosenLocale = $requestLocale;
150
151 //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache.
152 // Ed: This doesn't sound good.
153 // Civi::cache('navigation')->flush();
154 }
155 else {
156 $requestLocale = NULL;
157 }
158
159 if (!$requestLocale) {
160 $sessionLocale = $session->get('lcMessages');
161 if (in_array($sessionLocale, $permittedLanguages)) {
162 $chosenLocale = $sessionLocale;
163 }
164 else {
165 $sessionLocale = NULL;
166 }
167 }
168
169 if ($requestLocale) {
170 $ufm = new CRM_Core_DAO_UFMatch();
171 $ufm->contact_id = $session->get('userID');
172 if ($ufm->find(TRUE)) {
173 $ufm->language = $chosenLocale;
174 $ufm->save();
175 }
176 $session->set('lcMessages', $chosenLocale);
177 }
178
179 if (!$chosenLocale and $session->get('userID')) {
180 $ufm = new CRM_Core_DAO_UFMatch();
181 $ufm->contact_id = $session->get('userID');
182 if ($ufm->find(TRUE) &&
183 in_array($ufm->language, $permittedLanguages)
184 ) {
185 $chosenLocale = $ufm->language;
186 }
187 $session->set('lcMessages', $chosenLocale);
188 }
189 }
190 global $dbLocale;
191
192 // try to inherit the language from the hosting CMS
193 // If the language is specified in the session (ie. via lcMessages) we still allow it to be overridden.
194 if ($settings->get('inheritLocale') && empty($sessionLocale)) {
195 // FIXME: On multilanguage installs, CRM_Utils_System::getUFLocale() in many cases returns nothing if $dbLocale is not set
196 $lcMessages = $settings->get('lcMessages');
197 $dbLocale = $multiLang && $lcMessages ? "_{$lcMessages}" : '';
198 $chosenLocale = CRM_Utils_System::getUFLocale();
199 if ($activatedLocales and !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
200 $chosenLocale = NULL;
201 }
202 }
203
204 if (empty($chosenLocale)) {
205 //CRM-11993 - if a single-lang site, use default
206 $chosenLocale = $settings->get('lcMessages');
207 }
208
209 // set suffix for table names - use views if more than one language
210 $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
211
212 // FIXME: an ugly hack to fix CRM-4041
213 global $tsLocale;
214 $tsLocale = $chosenLocale;
215
216 // FIXME: as bad aplace as any to fix CRM-5428
217 // (to be moved to a sane location along with the above)
218 if (function_exists('mb_internal_encoding')) {
219 mb_internal_encoding('UTF-8');
220 }
221 }
222
223 /**
224 * @param array $defaultValues
225 *
226 * @return string
227 * @throws Exception
228 */
229 public static function doSiteMove($defaultValues = []) {
230 $moveStatus = ts('Beginning site move process...') . '<br />';
231 $settings = Civi::settings();
232
233 foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
234 $value = $settings->get($key);
235 if ($value && $value != $settings->getDefault($key)) {
236 if ($settings->getMandatory($key) === NULL) {
237 $settings->revert($key);
238 $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", [
239 1 => $key,
240 ]);
241 $moveStatus .= '<br />';
242 }
243 else {
244 $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", [
245 1 => $key,
246 ]);
247 $moveStatus .= '<br />';
248 }
249 }
250 }
251
252 $config = CRM_Core_Config::singleton();
253
254 // clear the template_c and upload directory also
255 $config->cleanup(3, TRUE);
256 $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';
257
258 // clear all caches
259 CRM_Core_Config::clearDBCache();
260 Civi::cache('session')->clear();
261 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
262
263 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
264 'Boolean',
265 CRM_Core_DAO::$_nullArray,
266 FALSE,
267 FALSE
268 );
269 if ($config->userSystem->is_drupal &&
270 $resetSessionTable
271 ) {
272 db_query("DELETE FROM {sessions} WHERE 1");
273 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
274 }
275 else {
276 $session = CRM_Core_Session::singleton();
277 $session->reset(2);
278 $moveStatus .= ts('Session has been reset.') . '<br />';
279 }
280
281 return $moveStatus;
282 }
283
284 /**
285 * Takes a componentName and enables it in the config.
286 * Primarily used during unit testing
287 *
288 * @param string $componentName
289 * Name of the component to be enabled, needs to be valid.
290 *
291 * @return bool
292 * true if valid component name and enabling succeeds, else false
293 */
294 public static function enableComponent($componentName) {
295 $config = CRM_Core_Config::singleton();
296 if (in_array($componentName, $config->enableComponents)) {
297 // component is already enabled
298 return TRUE;
299 }
300
301 // return if component does not exist
302 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
303 return FALSE;
304 }
305
306 // get enabled-components from DB and add to the list
307 $enabledComponents = Civi::settings()->get('enable_components');
308 $enabledComponents[] = $componentName;
309
310 self::setEnabledComponents($enabledComponents);
311
312 return TRUE;
313 }
314
315 /**
316 * Disable specified component.
317 *
318 * @param string $componentName
319 *
320 * @return bool
321 */
322 public static function disableComponent($componentName) {
323 $config = CRM_Core_Config::singleton();
324 if (!in_array($componentName, $config->enableComponents) ||
325 !array_key_exists($componentName, CRM_Core_Component::getComponents())
326 ) {
327 // Post-condition is satisfied.
328 return TRUE;
329 }
330
331 // get enabled-components from DB and add to the list
332 $enabledComponents = Civi::settings()->get('enable_components');
333 $enabledComponents = array_diff($enabledComponents, [$componentName]);
334
335 self::setEnabledComponents($enabledComponents);
336
337 return TRUE;
338 }
339
340 /**
341 * Set enabled components.
342 *
343 * @param array $enabledComponents
344 */
345 public static function setEnabledComponents($enabledComponents) {
346 // fix the config object. update db.
347 Civi::settings()->set('enable_components', $enabledComponents);
348
349 // also force reset of component array
350 CRM_Core_Component::getEnabledComponents(TRUE);
351 }
352
353 /**
354 * @return array
355 */
356 public static function skipVars() {
357 return [
358 'dsn',
359 'templateCompileDir',
360 'userFrameworkDSN',
361 'userFramework',
362 'userFrameworkBaseURL',
363 'userFrameworkClass',
364 'userHookClass',
365 'userPermissionClass',
366 'userPermissionTemp',
367 'userFrameworkURLVar',
368 'userFrameworkVersion',
369 'newBaseURL',
370 'newBaseDir',
371 'newSiteName',
372 'configAndLogDir',
373 'qfKey',
374 'gettextResourceDir',
375 'cleanURL',
376 'entryURL',
377 'locale_custom_strings',
378 'localeCustomStrings',
379 'autocompleteContactSearch',
380 'autocompleteContactReference',
381 'checksumTimeout',
382 'checksum_timeout',
383 ];
384 }
385
386 /**
387 * @param array $params
388 * @return array
389 */
390 public static function filterSkipVars($params) {
391 $skipVars = self::skipVars();
392 foreach ($skipVars as $var) {
393 unset($params[$var]);
394 }
395 foreach (array_keys($params) as $key) {
396 if (preg_match('/^_qf_/', $key)) {
397 unset($params[$key]);
398 }
399 }
400 return $params;
401 }
402
403 /**
404 * @return array
405 */
406 private static function getUrlSettings() {
407 return [
408 'userFrameworkResourceURL',
409 'imageUploadURL',
410 'customCSSURL',
411 'extensionsURL',
412 ];
413 }
414
415 /**
416 * @return array
417 */
418 private static function getPathSettings() {
419 return [
420 'uploadDir',
421 'imageUploadDir',
422 'customFileUploadDir',
423 'customTemplateDir',
424 'customPHPPathDir',
425 'extensionsDir',
426 ];
427 }
428
429 }