Merge pull request #8494 from kcristiano/CRM-18221
[civicrm-core.git] / CRM / Core / BAO / ConfigSetting.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2016
33 */
34
35 /**
36 * File contains functions used in civicrm configuration.
37 */
38 class CRM_Core_BAO_ConfigSetting {
39
40 /**
41 * Create civicrm settings. This is the same as add but it clears the cache and
42 * reloads the config object
43 *
44 * @param array $params
45 * Associated array of civicrm variables.
46 */
47 public static function create($params) {
48 self::add($params);
49 $cache = CRM_Utils_Cache::singleton();
50 $cache->delete('CRM_Core_Config');
51 $cache->delete('CRM_Core_Config' . CRM_Core_Config::domainID());
52 $config = CRM_Core_Config::singleton(TRUE, TRUE);
53 }
54
55 /**
56 * Add civicrm settings.
57 *
58 * @param array $params
59 * Associated array of civicrm variables.
60 */
61 public static function add(&$params) {
62 $domain = new CRM_Core_DAO_Domain();
63 $domain->id = CRM_Core_Config::domainID();
64 $domain->find(TRUE);
65 if ($domain->config_backend) {
66 $params = array_merge(unserialize($domain->config_backend), $params);
67 }
68
69 $params = CRM_Core_BAO_ConfigSetting::filterSkipVars($params);
70
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
78 $domain->config_backend = serialize($params);
79 $domain->save();
80 }
81
82 /**
83 * Retrieve the settings values from db.
84 *
85 * @param $defaults
86 *
87 * @return array
88 */
89 public static function retrieve(&$defaults) {
90 $domain = new CRM_Core_DAO_Domain();
91 $isUpgrade = CRM_Core_Config::isUpgradeMode();
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
99 if ($isUpgrade && CRM_Core_DAO::checkFieldExists('civicrm_domain', 'config_backend')) {
100 $domain->selectAdd('config_backend');
101 }
102 else {
103 $domain->selectAdd('locales');
104 }
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();
112 return FALSE;
113 }
114
115 $skipVars = self::skipVars();
116 foreach ($skipVars as $skip) {
117 if (array_key_exists($skip, $defaults)) {
118 unset($defaults[$skip]);
119 }
120 }
121 }
122 if (!$isUpgrade) {
123 CRM_Core_BAO_ConfigSetting::applyLocale(Civi::settings($domain->id), $domain->locales);
124 }
125 }
126
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.
134 */
135 public static function applyLocale($settings, $activatedLocales) {
136 // are we in a multi-language setup?
137 $multiLang = $activatedLocales ? TRUE : FALSE;
138
139 // set the current language
140 $chosenLocale = NULL;
141
142 $session = CRM_Core_Session::singleton();
143
144 // on multi-lang sites based on request and civicrm_uf_match
145 if ($multiLang) {
146 $languageLimit = array();
147 if (is_array($settings->get('languageLimit'))) {
148 $languageLimit = $settings->get('languageLimit');
149 }
150
151 $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
152 if (in_array($requestLocale, array_keys($languageLimit))) {
153 $chosenLocale = $requestLocale;
154
155 //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache.
156 // Ed: This doesn't sound good.
157 CRM_Core_BAO_Cache::deleteGroup('navigation');
158 }
159 else {
160 $requestLocale = NULL;
161 }
162
163 if (!$requestLocale) {
164 $sessionLocale = $session->get('lcMessages');
165 if (in_array($sessionLocale, array_keys($languageLimit))) {
166 $chosenLocale = $sessionLocale;
167 }
168 else {
169 $sessionLocale = NULL;
170 }
171 }
172
173 if ($requestLocale) {
174 $ufm = new CRM_Core_DAO_UFMatch();
175 $ufm->contact_id = $session->get('userID');
176 if ($ufm->find(TRUE)) {
177 $ufm->language = $chosenLocale;
178 $ufm->save();
179 }
180 $session->set('lcMessages', $chosenLocale);
181 }
182
183 if (!$chosenLocale and $session->get('userID')) {
184 $ufm = new CRM_Core_DAO_UFMatch();
185 $ufm->contact_id = $session->get('userID');
186 if ($ufm->find(TRUE) &&
187 in_array($ufm->language, array_keys($languageLimit))
188 ) {
189 $chosenLocale = $ufm->language;
190 }
191 $session->set('lcMessages', $chosenLocale);
192 }
193 }
194 global $dbLocale;
195
196 // try to inherit the language from the hosting CMS
197 if ($settings->get('inheritLocale')) {
198 // FIXME: On multilanguage installs, CRM_Utils_System::getUFLocale() in many cases returns nothing if $dbLocale is not set
199 $dbLocale = $multiLang ? ("_" . $settings->get('lcMessages')) : '';
200 $chosenLocale = CRM_Utils_System::getUFLocale();
201 if ($activatedLocales and !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
202 $chosenLocale = NULL;
203 }
204 }
205
206 if (empty($chosenLocale)) {
207 //CRM-11993 - if a single-lang site, use default
208 $chosenLocale = $settings->get('lcMessages');
209 }
210
211 // set suffix for table names - use views if more than one language
212 $dbLocale = $multiLang ? "_{$chosenLocale}" : '';
213
214 // FIXME: an ugly hack to fix CRM-4041
215 global $tsLocale;
216 $tsLocale = $chosenLocale;
217
218 // FIXME: as bad aplace as any to fix CRM-5428
219 // (to be moved to a sane location along with the above)
220 if (function_exists('mb_internal_encoding')) {
221 mb_internal_encoding('UTF-8');
222 }
223 }
224
225 /**
226 * @param array $defaultValues
227 *
228 * @return string
229 * @throws Exception
230 */
231 public static function doSiteMove($defaultValues = array()) {
232 $moveStatus = ts('Beginning site move process...') . '<br />';
233 $settings = Civi::settings();
234
235 foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
236 $value = $settings->get($key);
237 if ($value && $value != $settings->getDefault($key)) {
238 if ($settings->getMandatory($key) === NULL) {
239 $settings->revert($key);
240 $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", array(
241 1 => $key,
242 ));
243 $moveStatus .= '<br />';
244 }
245 else {
246 $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", array(
247 1 => $key,
248 ));
249 $moveStatus .= '<br />';
250 }
251 }
252 }
253
254 $config = CRM_Core_Config::singleton();
255
256 // clear the template_c and upload directory also
257 $config->cleanup(3, TRUE);
258 $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';
259
260 // clear all caches
261 CRM_Core_Config::clearDBCache();
262 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
263
264 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
265 'Boolean',
266 CRM_Core_DAO::$_nullArray,
267 FALSE,
268 FALSE,
269 'REQUEST'
270 );
271 if ($config->userSystem->is_drupal &&
272 $resetSessionTable
273 ) {
274 db_query("DELETE FROM {sessions} WHERE 1");
275 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
276 }
277 else {
278 $session = CRM_Core_Session::singleton();
279 $session->reset(2);
280 $moveStatus .= ts('Session has been reset.') . '<br />';
281 }
282
283 return $moveStatus;
284 }
285
286 /**
287 * Takes a componentName and enables it in the config.
288 * Primarily used during unit testing
289 *
290 * @param string $componentName
291 * Name of the component to be enabled, needs to be valid.
292 *
293 * @return bool
294 * true if valid component name and enabling succeeds, else false
295 */
296 public static function enableComponent($componentName) {
297 $config = CRM_Core_Config::singleton();
298 if (in_array($componentName, $config->enableComponents)) {
299 // component is already enabled
300 return TRUE;
301 }
302
303 // return if component does not exist
304 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
305 return FALSE;
306 }
307
308 // get enabled-components from DB and add to the list
309 $enabledComponents = Civi::settings()->get('enable_components');
310 $enabledComponents[] = $componentName;
311
312 self::setEnabledComponents($enabledComponents);
313
314 return TRUE;
315 }
316
317 /**
318 * Disable specified component.
319 *
320 * @param string $componentName
321 *
322 * @return bool
323 */
324 public static function disableComponent($componentName) {
325 $config = CRM_Core_Config::singleton();
326 if (!in_array($componentName, $config->enableComponents) ||
327 !array_key_exists($componentName, CRM_Core_Component::getComponents())
328 ) {
329 // Post-condition is satisfied.
330 return TRUE;
331 }
332
333 // get enabled-components from DB and add to the list
334 $enabledComponents = Civi::settings()->get('enable_components');
335 $enabledComponents = array_diff($enabledComponents, array($componentName));
336
337 self::setEnabledComponents($enabledComponents);
338
339 return TRUE;
340 }
341
342 /**
343 * Set enabled components.
344 *
345 * @param array $enabledComponents
346 */
347 public static function setEnabledComponents($enabledComponents) {
348 // fix the config object. update db.
349 Civi::settings()->set('enable_components', $enabledComponents);
350
351 // also force reset of component array
352 CRM_Core_Component::getEnabledComponents(TRUE);
353 }
354
355 /**
356 * @return array
357 */
358 public static function skipVars() {
359 return array(
360 'dsn',
361 'templateCompileDir',
362 'userFrameworkDSN',
363 'userFramework',
364 'userFrameworkBaseURL',
365 'userFrameworkClass',
366 'userHookClass',
367 'userPermissionClass',
368 'userPermissionTemp',
369 'userFrameworkURLVar',
370 'userFrameworkVersion',
371 'newBaseURL',
372 'newBaseDir',
373 'newSiteName',
374 'configAndLogDir',
375 'qfKey',
376 'gettextResourceDir',
377 'cleanURL',
378 'entryURL',
379 'locale_custom_strings',
380 'localeCustomStrings',
381 'autocompleteContactSearch',
382 'autocompleteContactReference',
383 'checksumTimeout',
384 'checksum_timeout',
385 );
386 }
387
388 /**
389 * @param array $params
390 * @return array
391 */
392 public static function filterSkipVars($params) {
393 $skipVars = self::skipVars();
394 foreach ($skipVars as $var) {
395 unset($params[$var]);
396 }
397 foreach (array_keys($params) as $key) {
398 if (preg_match('/^_qf_/', $key)) {
399 unset($params[$key]);
400 }
401 }
402 return $params;
403 }
404
405 /**
406 * @return array
407 */
408 private static function getUrlSettings() {
409 return array(
410 'userFrameworkResourceURL',
411 'imageUploadURL',
412 'customCSSURL',
413 'extensionsURL',
414 );
415 }
416
417 /**
418 * @return array
419 */
420 private static function getPathSettings() {
421 return array(
422 'uploadDir',
423 'imageUploadDir',
424 'customFileUploadDir',
425 'customTemplateDir',
426 'customPHPPathDir',
427 'extensionsDir',
428 );
429 }
430
431 }