Merge pull request #21965 from civicrm/5.43
[civicrm-core.git] / CRM / Core / BAO / ConfigSetting.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 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 |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
17 */
18
19/**
192d36c5 20 * File contains functions used in civicrm configuration.
6a488035
TO
21 */
22class CRM_Core_BAO_ConfigSetting {
23
24 /**
100fef9d 25 * Create civicrm settings. This is the same as add but it clears the cache and
b597d0b1 26 * reloads the config object
6a488035 27 *
6a0b768e
TO
28 * @param array $params
29 * Associated array of civicrm variables.
6a488035 30 */
00be9182 31 public static function create($params) {
6a488035
TO
32 self::add($params);
33 $cache = CRM_Utils_Cache::singleton();
34 $cache->delete('CRM_Core_Config');
0e04f44e 35 $cache->delete('CRM_Core_Config' . CRM_Core_Config::domainID());
6a488035
TO
36 $config = CRM_Core_Config::singleton(TRUE, TRUE);
37 }
38
39 /**
fe482240 40 * Add civicrm settings.
6a488035 41 *
6a0b768e
TO
42 * @param array $params
43 * Associated array of civicrm variables.
889bb141
TO
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.
6a488035 47 */
00be9182 48 public static function add(&$params) {
6a488035
TO
49 $domain = new CRM_Core_DAO_Domain();
50 $domain->id = CRM_Core_Config::domainID();
51 $domain->find(TRUE);
52 if ($domain->config_backend) {
6e5b5e59 53 $params = array_merge(unserialize($domain->config_backend), $params);
6a488035
TO
54 }
55
7e0c769c 56 $params = CRM_Core_BAO_ConfigSetting::filterSkipVars($params);
6a488035 57
6a488035
TO
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
6a488035
TO
65 $domain->config_backend = serialize($params);
66 $domain->save();
67 }
68
6a488035 69 /**
fe482240 70 * Retrieve the settings values from db.
6a488035 71 *
da6b46f4
EM
72 * @param $defaults
73 *
a6c01b45 74 * @return array
889bb141
TO
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.
6a488035 78 */
00be9182 79 public static function retrieve(&$defaults) {
6a488035 80 $domain = new CRM_Core_DAO_Domain();
747859fe 81 $isUpgrade = CRM_Core_Config::isUpgradeMode();
6a488035
TO
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
889bb141
TO
89 $hasBackend = CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_domain', 'config_backend');
90 if ($isUpgrade && $hasBackend) {
6a488035
TO
91 $domain->selectAdd('config_backend');
92 }
8ef8eacf 93 else {
94 $domain->selectAdd('locales');
95 }
6a488035
TO
96
97 $domain->id = CRM_Core_Config::domainID();
98 $domain->find(TRUE);
889bb141
TO
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.
6a488035
TO
103 $defaults = unserialize($domain->config_backend);
104 if ($defaults === FALSE || !is_array($defaults)) {
be2fb01f 105 $defaults = [];
608e6658 106 return FALSE;
6a488035
TO
107 }
108
109 $skipVars = self::skipVars();
110 foreach ($skipVars as $skip) {
111 if (array_key_exists($skip, $defaults)) {
112 unset($defaults[$skip]);
113 }
114 }
8ef8eacf 115 }
116 if (!$isUpgrade) {
117 CRM_Core_BAO_ConfigSetting::applyLocale(Civi::settings($domain->id), $domain->locales);
b72b5fc0
TO
118 }
119 }
6a488035 120
b72b5fc0 121 /**
2cbb2113
CW
122 * Activate a chosen locale.
123 *
124 * The locale is set by updating the session and global variables.
125 *
126 * When there is a choice of permitted languages (set on the "Administer" ->
127 * "Localisation" -> "Languages, Currency, Locations" screen) the locale to
128 * be applied can come from a variety of sources. The list below is the order
129 * of priority for deciding which of the sources "wins":
130 *
131 * - The request - when the "lcMessages" query variable is present in the URL.
132 * - The session - when the "lcMessages" session variable has been set.
133 * - Inherited from the CMS - when the "inheritLocale" setting is set.
134 * - CiviCRM settings - the fallback when none of the above set the locale.
135 *
136 * Single-language installs skip this and always set the default locale.
b72b5fc0
TO
137 *
138 * @param \Civi\Core\SettingsBag $settings
139 * @param string $activatedLocales
140 * Imploded list of locales which are supported in the DB.
b72b5fc0
TO
141 */
142 public static function applyLocale($settings, $activatedLocales) {
6a488035 143
2cbb2113
CW
144 // Declare access to locale globals.
145 global $dbLocale, $tsLocale;
6a488035 146
2cbb2113 147 // Grab session reference.
b72b5fc0 148 $session = CRM_Core_Session::singleton();
6a488035 149
2cbb2113
CW
150 // Set flag for multi-language setup.
151 $multiLang = (bool) $activatedLocales;
152
153 // Initialise the default and chosen locales.
154 $defaultLocale = $settings->get('lcMessages');
155 $chosenLocale = NULL;
921ed8ae 156
2cbb2113
CW
157 // When there is a choice of permitted languages.
158 $permittedLanguages = CRM_Core_I18n::uiLanguages(TRUE);
921ed8ae 159 if (count($permittedLanguages) >= 2) {
2cbb2113
CW
160
161 // Is the "lcMessages" query variable present in the URL?
b72b5fc0 162 $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
921ed8ae 163 if (in_array($requestLocale, $permittedLanguages)) {
b72b5fc0 164 $chosenLocale = $requestLocale;
b72b5fc0 165 }
6a488035 166
2cbb2113
CW
167 // Check the session if the chosen locale hasn't been set yet.
168 if (empty($chosenLocale)) {
b72b5fc0 169 $sessionLocale = $session->get('lcMessages');
921ed8ae 170 if (in_array($sessionLocale, $permittedLanguages)) {
b72b5fc0
TO
171 $chosenLocale = $sessionLocale;
172 }
b72b5fc0 173 }
6a488035 174
2cbb2113
CW
175 /*
176 * Maybe inherit the language from the CMS.
177 *
178 * If the language is specified via "lcMessages" we skip this, since the
179 * intention of the URL query var is to override all other sources.
180 */
8c9643b3 181 if ($settings->get('inheritLocale')) {
2cbb2113
CW
182
183 /*
184 * FIXME: On multi-language installs, CRM_Utils_System::getUFLocale() in
185 * many cases returns nothing if $dbLocale is not set, so set it to the
186 * default - even if it's overridden later.
187 */
188 $dbLocale = $multiLang && $defaultLocale ? "_{$defaultLocale}" : '';
189
190 // Retrieve locale as reported by CMS.
191 $cmsLocale = CRM_Utils_System::getUFLocale();
192 if (in_array($cmsLocale, $permittedLanguages)) {
193 $chosenLocale = $cmsLocale;
6a488035 194 }
b72b5fc0 195
2cbb2113
CW
196 // Clear chosen locale if not activated in multi-language CiviCRM.
197 if ($activatedLocales && !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
198 $chosenLocale = NULL;
6a488035 199 }
2cbb2113 200
6a488035 201 }
2cbb2113
CW
202
203 // Assign the system default if the chosen locale hasn't been set.
204 if (empty($chosenLocale)) {
205 $chosenLocale = $defaultLocale;
5b6ed484 206 }
2cbb2113 207
b72b5fc0 208 }
2cbb2113
CW
209 else {
210
211 // CRM-11993 - Use default when it's a single-language install.
212 $chosenLocale = $defaultLocale;
6a488035 213
b72b5fc0 214 }
6a488035 215
18436e43
SL
216 if (!$session->isEmpty()) {
217 // Always assign the chosen locale to the session.
218 $session->set('lcMessages', $chosenLocale);
219 }
220
2cbb2113
CW
221 /*
222 * Set suffix for table names in multi-language installs.
223 * Use views if more than one language.
224 */
5da9acde 225 $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
6a488035 226
2cbb2113 227 // FIXME: an ugly hack to fix CRM-4041.
b72b5fc0
TO
228 $tsLocale = $chosenLocale;
229
2cbb2113
CW
230 /*
231 * FIXME: as bad a place as any to fix CRM-5428.
232 * (to be moved to a sane location along with the above)
233 */
b72b5fc0
TO
234 if (function_exists('mb_internal_encoding')) {
235 mb_internal_encoding('UTF-8');
6a488035 236 }
2cbb2113 237
6a488035
TO
238 }
239
b5c2afd0
EM
240 /**
241 * @param array $defaultValues
242 *
243 * @return string
244 * @throws Exception
245 */
be2fb01f 246 public static function doSiteMove($defaultValues = []) {
6a488035 247 $moveStatus = ts('Beginning site move process...') . '<br />';
4f240ac1
TO
248 $settings = Civi::settings();
249
250 foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
251 $value = $settings->get($key);
252 if ($value && $value != $settings->getDefault($key)) {
253 if ($settings->getMandatory($key) === NULL) {
254 $settings->revert($key);
be2fb01f 255 $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", [
4f240ac1 256 1 => $key,
be2fb01f 257 ]);
4f240ac1 258 $moveStatus .= '<br />';
6a488035 259 }
4f240ac1 260 else {
be2fb01f 261 $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", [
4f240ac1 262 1 => $key,
be2fb01f 263 ]);
4f240ac1 264 $moveStatus .= '<br />';
6a488035
TO
265 }
266 }
267 }
268
6a488035
TO
269 $config = CRM_Core_Config::singleton();
270
271 // clear the template_c and upload directory also
272 $config->cleanup(3, TRUE);
273 $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';
274
275 // clear all caches
276 CRM_Core_Config::clearDBCache();
0a12cd4a 277 Civi::cache('session')->clear();
6a488035
TO
278 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
279
280 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
281 'Boolean',
282 CRM_Core_DAO::$_nullArray,
283 FALSE,
f7ad2038 284 FALSE
6a488035
TO
285 );
286 if ($config->userSystem->is_drupal &&
287 $resetSessionTable
288 ) {
289 db_query("DELETE FROM {sessions} WHERE 1");
290 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
291 }
292 else {
293 $session = CRM_Core_Session::singleton();
294 $session->reset(2);
295 $moveStatus .= ts('Session has been reset.') . '<br />';
296 }
297
298 return $moveStatus;
299 }
300
301 /**
fe482240 302 * Takes a componentName and enables it in the config.
6a488035
TO
303 * Primarily used during unit testing
304 *
6a0b768e
TO
305 * @param string $componentName
306 * Name of the component to be enabled, needs to be valid.
6a488035 307 *
608e6658 308 * @return bool
a6c01b45 309 * true if valid component name and enabling succeeds, else false
6a488035 310 */
00be9182 311 public static function enableComponent($componentName) {
6a488035
TO
312 $config = CRM_Core_Config::singleton();
313 if (in_array($componentName, $config->enableComponents)) {
314 // component is already enabled
315 return TRUE;
316 }
6a488035
TO
317
318 // return if component does not exist
b086633a 319 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
6a488035
TO
320 return FALSE;
321 }
322
3124edb3 323 // get enabled-components from DB and add to the list
84fb7424 324 $enabledComponents = Civi::settings()->get('enable_components');
3124edb3 325 $enabledComponents[] = $componentName;
6a488035 326
b086633a
TO
327 self::setEnabledComponents($enabledComponents);
328
329 return TRUE;
330 }
331
b896fa44
EM
332 /**
333 * Disable specified component.
334 *
335 * @param string $componentName
336 *
337 * @return bool
338 */
00be9182 339 public static function disableComponent($componentName) {
b086633a 340 $config = CRM_Core_Config::singleton();
4c235182
EM
341 if (!in_array($componentName, $config->enableComponents) ||
342 !array_key_exists($componentName, CRM_Core_Component::getComponents())
343 ) {
b896fa44 344 // Post-condition is satisfied.
b086633a
TO
345 return TRUE;
346 }
347
348 // get enabled-components from DB and add to the list
84fb7424 349 $enabledComponents = Civi::settings()->get('enable_components');
be2fb01f 350 $enabledComponents = array_diff($enabledComponents, [$componentName]);
b086633a
TO
351
352 self::setEnabledComponents($enabledComponents);
353
354 return TRUE;
355 }
356
b896fa44
EM
357 /**
358 * Set enabled components.
359 *
360 * @param array $enabledComponents
361 */
b086633a 362 public static function setEnabledComponents($enabledComponents) {
2f255668 363 // The on_change trigger on this setting will trigger a cache flush
edbcbd96 364 Civi::settings()->set('enable_components', $enabledComponents);
6a488035
TO
365 }
366
b5c2afd0
EM
367 /**
368 * @return array
369 */
00be9182 370 public static function skipVars() {
be2fb01f 371 return [
4c235182
EM
372 'dsn',
373 'templateCompileDir',
6a488035
TO
374 'userFrameworkDSN',
375 'userFramework',
4c235182
EM
376 'userFrameworkBaseURL',
377 'userFrameworkClass',
378 'userHookClass',
379 'userPermissionClass',
59735506 380 'userPermissionTemp',
4c235182
EM
381 'userFrameworkURLVar',
382 'userFrameworkVersion',
383 'newBaseURL',
384 'newBaseDir',
385 'newSiteName',
386 'configAndLogDir',
387 'qfKey',
388 'gettextResourceDir',
389 'cleanURL',
7e0c769c 390 'entryURL',
4c235182
EM
391 'locale_custom_strings',
392 'localeCustomStrings',
6a488035
TO
393 'autocompleteContactSearch',
394 'autocompleteContactReference',
395 'checksumTimeout',
92a8de72 396 'checksum_timeout',
be2fb01f 397 ];
6a488035 398 }
96025800 399
7e0c769c
TO
400 /**
401 * @param array $params
402 * @return array
403 */
404 public static function filterSkipVars($params) {
405 $skipVars = self::skipVars();
406 foreach ($skipVars as $var) {
407 unset($params[$var]);
408 }
409 foreach (array_keys($params) as $key) {
410 if (preg_match('/^_qf_/', $key)) {
411 unset($params[$key]);
412 }
413 }
414 return $params;
415 }
416
4f240ac1
TO
417 /**
418 * @return array
419 */
420 private static function getUrlSettings() {
be2fb01f 421 return [
4f240ac1
TO
422 'userFrameworkResourceURL',
423 'imageUploadURL',
424 'customCSSURL',
425 'extensionsURL',
be2fb01f 426 ];
4f240ac1
TO
427 }
428
429 /**
430 * @return array
431 */
432 private static function getPathSettings() {
be2fb01f 433 return [
4f240ac1
TO
434 'uploadDir',
435 'imageUploadDir',
436 'customFileUploadDir',
437 'customTemplateDir',
438 'customPHPPathDir',
439 'extensionsDir',
be2fb01f 440 ];
4f240ac1
TO
441 }
442
6a488035 443}