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