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