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