Merge pull request #17742 from MiyaNoctem/dev-core-1854-fix-resetting-overridden...
[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 */
181 if ($settings->get('inheritLocale') && empty($chosenLocale)) {
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
CW
207
208 // Always assign the chosen locale to the session.
209 $session->set('lcMessages', $chosenLocale);
210
b72b5fc0 211 }
2cbb2113
CW
212 else {
213
214 // CRM-11993 - Use default when it's a single-language install.
215 $chosenLocale = $defaultLocale;
6a488035 216
b72b5fc0 217 }
6a488035 218
2cbb2113
CW
219 /*
220 * Set suffix for table names in multi-language installs.
221 * Use views if more than one language.
222 */
5da9acde 223 $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
6a488035 224
2cbb2113 225 // FIXME: an ugly hack to fix CRM-4041.
b72b5fc0
TO
226 $tsLocale = $chosenLocale;
227
2cbb2113
CW
228 /*
229 * FIXME: as bad a place as any to fix CRM-5428.
230 * (to be moved to a sane location along with the above)
231 */
b72b5fc0
TO
232 if (function_exists('mb_internal_encoding')) {
233 mb_internal_encoding('UTF-8');
6a488035 234 }
2cbb2113 235
6a488035
TO
236 }
237
b5c2afd0
EM
238 /**
239 * @param array $defaultValues
240 *
241 * @return string
242 * @throws Exception
243 */
be2fb01f 244 public static function doSiteMove($defaultValues = []) {
6a488035 245 $moveStatus = ts('Beginning site move process...') . '<br />';
4f240ac1
TO
246 $settings = Civi::settings();
247
248 foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
249 $value = $settings->get($key);
250 if ($value && $value != $settings->getDefault($key)) {
251 if ($settings->getMandatory($key) === NULL) {
252 $settings->revert($key);
be2fb01f 253 $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", [
4f240ac1 254 1 => $key,
be2fb01f 255 ]);
4f240ac1 256 $moveStatus .= '<br />';
6a488035 257 }
4f240ac1 258 else {
be2fb01f 259 $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", [
4f240ac1 260 1 => $key,
be2fb01f 261 ]);
4f240ac1 262 $moveStatus .= '<br />';
6a488035
TO
263 }
264 }
265 }
266
6a488035
TO
267 $config = CRM_Core_Config::singleton();
268
269 // clear the template_c and upload directory also
270 $config->cleanup(3, TRUE);
271 $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';
272
273 // clear all caches
274 CRM_Core_Config::clearDBCache();
0a12cd4a 275 Civi::cache('session')->clear();
6a488035
TO
276 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
277
278 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
279 'Boolean',
280 CRM_Core_DAO::$_nullArray,
281 FALSE,
f7ad2038 282 FALSE
6a488035
TO
283 );
284 if ($config->userSystem->is_drupal &&
285 $resetSessionTable
286 ) {
287 db_query("DELETE FROM {sessions} WHERE 1");
288 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
289 }
290 else {
291 $session = CRM_Core_Session::singleton();
292 $session->reset(2);
293 $moveStatus .= ts('Session has been reset.') . '<br />';
294 }
295
296 return $moveStatus;
297 }
298
299 /**
fe482240 300 * Takes a componentName and enables it in the config.
6a488035
TO
301 * Primarily used during unit testing
302 *
6a0b768e
TO
303 * @param string $componentName
304 * Name of the component to be enabled, needs to be valid.
6a488035 305 *
608e6658 306 * @return bool
a6c01b45 307 * true if valid component name and enabling succeeds, else false
6a488035 308 */
00be9182 309 public static function enableComponent($componentName) {
6a488035
TO
310 $config = CRM_Core_Config::singleton();
311 if (in_array($componentName, $config->enableComponents)) {
312 // component is already enabled
313 return TRUE;
314 }
6a488035
TO
315
316 // return if component does not exist
b086633a 317 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
6a488035
TO
318 return FALSE;
319 }
320
3124edb3 321 // get enabled-components from DB and add to the list
84fb7424 322 $enabledComponents = Civi::settings()->get('enable_components');
3124edb3 323 $enabledComponents[] = $componentName;
6a488035 324
b086633a
TO
325 self::setEnabledComponents($enabledComponents);
326
327 return TRUE;
328 }
329
b896fa44
EM
330 /**
331 * Disable specified component.
332 *
333 * @param string $componentName
334 *
335 * @return bool
336 */
00be9182 337 public static function disableComponent($componentName) {
b086633a 338 $config = CRM_Core_Config::singleton();
4c235182
EM
339 if (!in_array($componentName, $config->enableComponents) ||
340 !array_key_exists($componentName, CRM_Core_Component::getComponents())
341 ) {
b896fa44 342 // Post-condition is satisfied.
b086633a
TO
343 return TRUE;
344 }
345
346 // get enabled-components from DB and add to the list
84fb7424 347 $enabledComponents = Civi::settings()->get('enable_components');
be2fb01f 348 $enabledComponents = array_diff($enabledComponents, [$componentName]);
b086633a
TO
349
350 self::setEnabledComponents($enabledComponents);
351
352 return TRUE;
353 }
354
b896fa44
EM
355 /**
356 * Set enabled components.
357 *
358 * @param array $enabledComponents
359 */
b086633a 360 public static function setEnabledComponents($enabledComponents) {
edbcbd96
TO
361 // fix the config object. update db.
362 Civi::settings()->set('enable_components', $enabledComponents);
6a488035
TO
363
364 // also force reset of component array
365 CRM_Core_Component::getEnabledComponents(TRUE);
6a488035
TO
366 }
367
b5c2afd0
EM
368 /**
369 * @return array
370 */
00be9182 371 public static function skipVars() {
be2fb01f 372 return [
4c235182
EM
373 'dsn',
374 'templateCompileDir',
6a488035
TO
375 'userFrameworkDSN',
376 'userFramework',
4c235182
EM
377 'userFrameworkBaseURL',
378 'userFrameworkClass',
379 'userHookClass',
380 'userPermissionClass',
59735506 381 'userPermissionTemp',
4c235182
EM
382 'userFrameworkURLVar',
383 'userFrameworkVersion',
384 'newBaseURL',
385 'newBaseDir',
386 'newSiteName',
387 'configAndLogDir',
388 'qfKey',
389 'gettextResourceDir',
390 'cleanURL',
7e0c769c 391 'entryURL',
4c235182
EM
392 'locale_custom_strings',
393 'localeCustomStrings',
6a488035
TO
394 'autocompleteContactSearch',
395 'autocompleteContactReference',
396 'checksumTimeout',
92a8de72 397 'checksum_timeout',
be2fb01f 398 ];
6a488035 399 }
96025800 400
7e0c769c
TO
401 /**
402 * @param array $params
403 * @return array
404 */
405 public static function filterSkipVars($params) {
406 $skipVars = self::skipVars();
407 foreach ($skipVars as $var) {
408 unset($params[$var]);
409 }
410 foreach (array_keys($params) as $key) {
411 if (preg_match('/^_qf_/', $key)) {
412 unset($params[$key]);
413 }
414 }
415 return $params;
416 }
417
4f240ac1
TO
418 /**
419 * @return array
420 */
421 private static function getUrlSettings() {
be2fb01f 422 return [
4f240ac1
TO
423 'userFrameworkResourceURL',
424 'imageUploadURL',
425 'customCSSURL',
426 'extensionsURL',
be2fb01f 427 ];
4f240ac1
TO
428 }
429
430 /**
431 * @return array
432 */
433 private static function getPathSettings() {
be2fb01f 434 return [
4f240ac1
TO
435 'uploadDir',
436 'imageUploadDir',
437 'customFileUploadDir',
438 'customTemplateDir',
439 'customPHPPathDir',
440 'extensionsDir',
be2fb01f 441 ];
4f240ac1
TO
442 }
443
6a488035 444}