Merge pull request #22992 from eileenmcnaughton/billingnot
[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) {
5d2065af
CW
312 $enabledComponents = Civi::settings()->get('enable_components');
313 if (in_array($componentName, $enabledComponents)) {
6a488035
TO
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
3124edb3 324 $enabledComponents[] = $componentName;
b086633a
TO
325 self::setEnabledComponents($enabledComponents);
326
327 return TRUE;
328 }
329
5d2065af
CW
330 /**
331 * Ensure all components are enabled
332 * @throws CRM_Core_Exception
333 */
334 public static function enableAllComponents() {
335 $allComponents = array_keys(CRM_Core_Component::getComponents());
336 if (Civi::settings()->get('enable_components') != $allComponents) {
337 self::setEnabledComponents($allComponents);
338 }
339 }
340
b896fa44
EM
341 /**
342 * Disable specified component.
343 *
344 * @param string $componentName
345 *
346 * @return bool
347 */
00be9182 348 public static function disableComponent($componentName) {
b086633a 349 $config = CRM_Core_Config::singleton();
4c235182
EM
350 if (!in_array($componentName, $config->enableComponents) ||
351 !array_key_exists($componentName, CRM_Core_Component::getComponents())
352 ) {
b896fa44 353 // Post-condition is satisfied.
b086633a
TO
354 return TRUE;
355 }
356
357 // get enabled-components from DB and add to the list
84fb7424 358 $enabledComponents = Civi::settings()->get('enable_components');
be2fb01f 359 $enabledComponents = array_diff($enabledComponents, [$componentName]);
b086633a
TO
360
361 self::setEnabledComponents($enabledComponents);
362
363 return TRUE;
364 }
365
b896fa44
EM
366 /**
367 * Set enabled components.
368 *
369 * @param array $enabledComponents
370 */
b086633a 371 public static function setEnabledComponents($enabledComponents) {
2f255668 372 // The on_change trigger on this setting will trigger a cache flush
edbcbd96 373 Civi::settings()->set('enable_components', $enabledComponents);
6a488035
TO
374 }
375
b5c2afd0
EM
376 /**
377 * @return array
378 */
00be9182 379 public static function skipVars() {
be2fb01f 380 return [
4c235182
EM
381 'dsn',
382 'templateCompileDir',
6a488035
TO
383 'userFrameworkDSN',
384 'userFramework',
4c235182
EM
385 'userFrameworkBaseURL',
386 'userFrameworkClass',
387 'userHookClass',
388 'userPermissionClass',
59735506 389 'userPermissionTemp',
4c235182
EM
390 'userFrameworkURLVar',
391 'userFrameworkVersion',
392 'newBaseURL',
393 'newBaseDir',
394 'newSiteName',
395 'configAndLogDir',
396 'qfKey',
397 'gettextResourceDir',
398 'cleanURL',
7e0c769c 399 'entryURL',
4c235182
EM
400 'locale_custom_strings',
401 'localeCustomStrings',
6a488035
TO
402 'autocompleteContactSearch',
403 'autocompleteContactReference',
404 'checksumTimeout',
92a8de72 405 'checksum_timeout',
be2fb01f 406 ];
6a488035 407 }
96025800 408
7e0c769c
TO
409 /**
410 * @param array $params
411 * @return array
412 */
413 public static function filterSkipVars($params) {
414 $skipVars = self::skipVars();
415 foreach ($skipVars as $var) {
416 unset($params[$var]);
417 }
418 foreach (array_keys($params) as $key) {
419 if (preg_match('/^_qf_/', $key)) {
420 unset($params[$key]);
421 }
422 }
423 return $params;
424 }
425
4f240ac1
TO
426 /**
427 * @return array
428 */
429 private static function getUrlSettings() {
be2fb01f 430 return [
4f240ac1
TO
431 'userFrameworkResourceURL',
432 'imageUploadURL',
433 'customCSSURL',
434 'extensionsURL',
be2fb01f 435 ];
4f240ac1
TO
436 }
437
438 /**
439 * @return array
440 */
441 private static function getPathSettings() {
be2fb01f 442 return [
4f240ac1
TO
443 'uploadDir',
444 'imageUploadDir',
445 'customFileUploadDir',
446 'customTemplateDir',
447 'customPHPPathDir',
448 'extensionsDir',
be2fb01f 449 ];
4f240ac1
TO
450 }
451
6a488035 452}