Merge pull request #12141 from seamuslee001/file_perms_fix
[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 $moveStatus .= ts('Database cache tables cleared.') . '<br />';
264
265 $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
266 'Boolean',
267 CRM_Core_DAO::$_nullArray,
268 FALSE,
269 FALSE,
270 'REQUEST'
271 );
272 if ($config->userSystem->is_drupal &&
273 $resetSessionTable
274 ) {
275 db_query("DELETE FROM {sessions} WHERE 1");
276 $moveStatus .= ts('Drupal session table cleared.') . '<br />';
277 }
278 else {
279 $session = CRM_Core_Session::singleton();
280 $session->reset(2);
281 $moveStatus .= ts('Session has been reset.') . '<br />';
282 }
283
284 return $moveStatus;
285 }
286
287 /**
288 * Takes a componentName and enables it in the config.
289 * Primarily used during unit testing
290 *
291 * @param string $componentName
292 * Name of the component to be enabled, needs to be valid.
293 *
294 * @return bool
295 * true if valid component name and enabling succeeds, else false
296 */
297 public static function enableComponent($componentName) {
298 $config = CRM_Core_Config::singleton();
299 if (in_array($componentName, $config->enableComponents)) {
300 // component is already enabled
301 return TRUE;
302 }
303
304 // return if component does not exist
305 if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
306 return FALSE;
307 }
308
309 // get enabled-components from DB and add to the list
310 $enabledComponents = Civi::settings()->get('enable_components');
311 $enabledComponents[] = $componentName;
312
313 self::setEnabledComponents($enabledComponents);
314
315 return TRUE;
316 }
317
318 /**
319 * Disable specified component.
320 *
321 * @param string $componentName
322 *
323 * @return bool
324 */
325 public static function disableComponent($componentName) {
326 $config = CRM_Core_Config::singleton();
327 if (!in_array($componentName, $config->enableComponents) ||
328 !array_key_exists($componentName, CRM_Core_Component::getComponents())
329 ) {
330 // Post-condition is satisfied.
331 return TRUE;
332 }
333
334 // get enabled-components from DB and add to the list
335 $enabledComponents = Civi::settings()->get('enable_components');
336 $enabledComponents = array_diff($enabledComponents, array($componentName));
337
338 self::setEnabledComponents($enabledComponents);
339
340 return TRUE;
341 }
342
343 /**
344 * Set enabled components.
345 *
346 * @param array $enabledComponents
347 */
348 public static function setEnabledComponents($enabledComponents) {
349 // fix the config object. update db.
350 Civi::settings()->set('enable_components', $enabledComponents);
351
352 // also force reset of component array
353 CRM_Core_Component::getEnabledComponents(TRUE);
354 }
355
356 /**
357 * @return array
358 */
359 public static function skipVars() {
360 return array(
361 'dsn',
362 'templateCompileDir',
363 'userFrameworkDSN',
364 'userFramework',
365 'userFrameworkBaseURL',
366 'userFrameworkClass',
367 'userHookClass',
368 'userPermissionClass',
369 'userPermissionTemp',
370 'userFrameworkURLVar',
371 'userFrameworkVersion',
372 'newBaseURL',
373 'newBaseDir',
374 'newSiteName',
375 'configAndLogDir',
376 'qfKey',
377 'gettextResourceDir',
378 'cleanURL',
379 'entryURL',
380 'locale_custom_strings',
381 'localeCustomStrings',
382 'autocompleteContactSearch',
383 'autocompleteContactReference',
384 'checksumTimeout',
385 'checksum_timeout',
386 );
387 }
388
389 /**
390 * @param array $params
391 * @return array
392 */
393 public static function filterSkipVars($params) {
394 $skipVars = self::skipVars();
395 foreach ($skipVars as $var) {
396 unset($params[$var]);
397 }
398 foreach (array_keys($params) as $key) {
399 if (preg_match('/^_qf_/', $key)) {
400 unset($params[$key]);
401 }
402 }
403 return $params;
404 }
405
406 /**
407 * @return array
408 */
409 private static function getUrlSettings() {
410 return array(
411 'userFrameworkResourceURL',
412 'imageUploadURL',
413 'customCSSURL',
414 'extensionsURL',
415 );
416 }
417
418 /**
419 * @return array
420 */
421 private static function getPathSettings() {
422 return array(
423 'uploadDir',
424 'imageUploadDir',
425 'customFileUploadDir',
426 'customTemplateDir',
427 'customPHPPathDir',
428 'extensionsDir',
429 );
430 }
431
432 }