Merge pull request #16671 from eileenmcnaughton/acl
[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
TO
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.
b72b5fc0
TO
128 */
129 public static function applyLocale($settings, $activatedLocales) {
130 // are we in a multi-language setup?
131 $multiLang = $activatedLocales ? TRUE : FALSE;
6a488035 132
b72b5fc0
TO
133 // set the current language
134 $chosenLocale = NULL;
6a488035 135
b72b5fc0 136 $session = CRM_Core_Session::singleton();
6a488035 137
921ed8ae
AS
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) {
b72b5fc0 147 $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
921ed8ae 148 if (in_array($requestLocale, $permittedLanguages)) {
b72b5fc0 149 $chosenLocale = $requestLocale;
6a488035 150
b72b5fc0
TO
151 //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache.
152 // Ed: This doesn't sound good.
96689db3 153 // Civi::cache('navigation')->flush();
b72b5fc0
TO
154 }
155 else {
156 $requestLocale = NULL;
157 }
6a488035 158
b72b5fc0
TO
159 if (!$requestLocale) {
160 $sessionLocale = $session->get('lcMessages');
921ed8ae 161 if (in_array($sessionLocale, $permittedLanguages)) {
b72b5fc0
TO
162 $chosenLocale = $sessionLocale;
163 }
164 else {
165 $sessionLocale = NULL;
6a488035 166 }
b72b5fc0 167 }
6a488035 168
b72b5fc0
TO
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();
6a488035 175 }
b72b5fc0 176 $session->set('lcMessages', $chosenLocale);
6a488035 177 }
b72b5fc0
TO
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) &&
921ed8ae 183 in_array($ufm->language, $permittedLanguages)
4c235182 184 ) {
b72b5fc0 185 $chosenLocale = $ufm->language;
6a488035 186 }
b72b5fc0 187 $session->set('lcMessages', $chosenLocale);
6a488035 188 }
b72b5fc0
TO
189 }
190 global $dbLocale;
191
192 // try to inherit the language from the hosting CMS
193 if ($settings->get('inheritLocale')) {
194 // FIXME: On multilanguage installs, CRM_Utils_System::getUFLocale() in many cases returns nothing if $dbLocale is not set
5da9acde
CG
195 $lcMessages = $settings->get('lcMessages');
196 $dbLocale = $multiLang && $lcMessages ? "_{$lcMessages}" : '';
b72b5fc0
TO
197 $chosenLocale = CRM_Utils_System::getUFLocale();
198 if ($activatedLocales and !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
199 $chosenLocale = NULL;
5b6ed484 200 }
b72b5fc0 201 }
6a488035 202
b72b5fc0
TO
203 if (empty($chosenLocale)) {
204 //CRM-11993 - if a single-lang site, use default
205 $chosenLocale = $settings->get('lcMessages');
206 }
6a488035 207
b72b5fc0 208 // set suffix for table names - use views if more than one language
5da9acde 209 $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
6a488035 210
b72b5fc0
TO
211 // FIXME: an ugly hack to fix CRM-4041
212 global $tsLocale;
213 $tsLocale = $chosenLocale;
214
215 // FIXME: as bad aplace as any to fix CRM-5428
216 // (to be moved to a sane location along with the above)
217 if (function_exists('mb_internal_encoding')) {
218 mb_internal_encoding('UTF-8');
6a488035 219 }
6a488035
TO
220 }
221
b5c2afd0
EM
222 /**
223 * @param array $defaultValues
224 *
225 * @return string
226 * @throws Exception
227 */
be2fb01f 228 public static function doSiteMove($defaultValues = []) {
6a488035 229 $moveStatus = ts('Beginning site move process...') . '<br />';
4f240ac1
TO
230 $settings = Civi::settings();
231
232 foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
233 $value = $settings->get($key);
234 if ($value && $value != $settings->getDefault($key)) {
235 if ($settings->getMandatory($key) === NULL) {
236 $settings->revert($key);
be2fb01f 237 $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", [
4f240ac1 238 1 => $key,
be2fb01f 239 ]);
4f240ac1 240 $moveStatus .= '<br />';
6a488035 241 }
4f240ac1 242 else {
be2fb01f 243 $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", [
4f240ac1 244 1 => $key,
be2fb01f 245 ]);
4f240ac1 246 $moveStatus .= '<br />';
6a488035
TO
247 }
248 }
249 }
250
6a488035
TO
251 $config = CRM_Core_Config::singleton();
252
253 // clear the template_c and upload directory also
254 $config->cleanup(3, TRUE);
255 $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';
256
257 // clear all caches
258 CRM_Core_Config::clearDBCache();
0a12cd4a 259 Civi::cache('session')->clear();
6a488035
TO
260 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
261
262 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
263 'Boolean',
264 CRM_Core_DAO::$_nullArray,
265 FALSE,
f7ad2038 266 FALSE
6a488035
TO
267 );
268 if ($config->userSystem->is_drupal &&
269 $resetSessionTable
270 ) {
271 db_query("DELETE FROM {sessions} WHERE 1");
272 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
273 }
274 else {
275 $session = CRM_Core_Session::singleton();
276 $session->reset(2);
277 $moveStatus .= ts('Session has been reset.') . '<br />';
278 }
279
280 return $moveStatus;
281 }
282
283 /**
fe482240 284 * Takes a componentName and enables it in the config.
6a488035
TO
285 * Primarily used during unit testing
286 *
6a0b768e
TO
287 * @param string $componentName
288 * Name of the component to be enabled, needs to be valid.
6a488035 289 *
608e6658 290 * @return bool
a6c01b45 291 * true if valid component name and enabling succeeds, else false
6a488035 292 */
00be9182 293 public static function enableComponent($componentName) {
6a488035
TO
294 $config = CRM_Core_Config::singleton();
295 if (in_array($componentName, $config->enableComponents)) {
296 // component is already enabled
297 return TRUE;
298 }
6a488035
TO
299
300 // return if component does not exist
b086633a 301 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
6a488035
TO
302 return FALSE;
303 }
304
3124edb3 305 // get enabled-components from DB and add to the list
84fb7424 306 $enabledComponents = Civi::settings()->get('enable_components');
3124edb3 307 $enabledComponents[] = $componentName;
6a488035 308
b086633a
TO
309 self::setEnabledComponents($enabledComponents);
310
311 return TRUE;
312 }
313
b896fa44
EM
314 /**
315 * Disable specified component.
316 *
317 * @param string $componentName
318 *
319 * @return bool
320 */
00be9182 321 public static function disableComponent($componentName) {
b086633a 322 $config = CRM_Core_Config::singleton();
4c235182
EM
323 if (!in_array($componentName, $config->enableComponents) ||
324 !array_key_exists($componentName, CRM_Core_Component::getComponents())
325 ) {
b896fa44 326 // Post-condition is satisfied.
b086633a
TO
327 return TRUE;
328 }
329
330 // get enabled-components from DB and add to the list
84fb7424 331 $enabledComponents = Civi::settings()->get('enable_components');
be2fb01f 332 $enabledComponents = array_diff($enabledComponents, [$componentName]);
b086633a
TO
333
334 self::setEnabledComponents($enabledComponents);
335
336 return TRUE;
337 }
338
b896fa44
EM
339 /**
340 * Set enabled components.
341 *
342 * @param array $enabledComponents
343 */
b086633a 344 public static function setEnabledComponents($enabledComponents) {
edbcbd96
TO
345 // fix the config object. update db.
346 Civi::settings()->set('enable_components', $enabledComponents);
6a488035
TO
347
348 // also force reset of component array
349 CRM_Core_Component::getEnabledComponents(TRUE);
6a488035
TO
350 }
351
b5c2afd0
EM
352 /**
353 * @return array
354 */
00be9182 355 public static function skipVars() {
be2fb01f 356 return [
4c235182
EM
357 'dsn',
358 'templateCompileDir',
6a488035
TO
359 'userFrameworkDSN',
360 'userFramework',
4c235182
EM
361 'userFrameworkBaseURL',
362 'userFrameworkClass',
363 'userHookClass',
364 'userPermissionClass',
59735506 365 'userPermissionTemp',
4c235182
EM
366 'userFrameworkURLVar',
367 'userFrameworkVersion',
368 'newBaseURL',
369 'newBaseDir',
370 'newSiteName',
371 'configAndLogDir',
372 'qfKey',
373 'gettextResourceDir',
374 'cleanURL',
7e0c769c 375 'entryURL',
4c235182
EM
376 'locale_custom_strings',
377 'localeCustomStrings',
6a488035
TO
378 'autocompleteContactSearch',
379 'autocompleteContactReference',
380 'checksumTimeout',
92a8de72 381 'checksum_timeout',
be2fb01f 382 ];
6a488035 383 }
96025800 384
7e0c769c
TO
385 /**
386 * @param array $params
387 * @return array
388 */
389 public static function filterSkipVars($params) {
390 $skipVars = self::skipVars();
391 foreach ($skipVars as $var) {
392 unset($params[$var]);
393 }
394 foreach (array_keys($params) as $key) {
395 if (preg_match('/^_qf_/', $key)) {
396 unset($params[$key]);
397 }
398 }
399 return $params;
400 }
401
4f240ac1
TO
402 /**
403 * @return array
404 */
405 private static function getUrlSettings() {
be2fb01f 406 return [
4f240ac1
TO
407 'userFrameworkResourceURL',
408 'imageUploadURL',
409 'customCSSURL',
410 'extensionsURL',
be2fb01f 411 ];
4f240ac1
TO
412 }
413
414 /**
415 * @return array
416 */
417 private static function getPathSettings() {
be2fb01f 418 return [
4f240ac1
TO
419 'uploadDir',
420 'imageUploadDir',
421 'customFileUploadDir',
422 'customTemplateDir',
423 'customPHPPathDir',
424 'extensionsDir',
be2fb01f 425 ];
4f240ac1
TO
426 }
427
6a488035 428}