ConfigSetting.php 12.8 KB
Newer Older
totten's avatar
totten committed
1
2
3
<?php
/*
 +--------------------------------------------------------------------+
totten's avatar
totten committed
4
 | CiviCRM version 5                                                  |
totten's avatar
totten committed
5
 +--------------------------------------------------------------------+
Seamus Lee's avatar
Seamus Lee committed
6
 | Copyright CiviCRM LLC (c) 2004-2019                                |
totten's avatar
totten committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 +--------------------------------------------------------------------+
 | This file is a part of CiviCRM.                                    |
 |                                                                    |
 | CiviCRM is free software; you can copy, modify, and distribute it  |
 | under the terms of the GNU Affero General Public License           |
 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
 |                                                                    |
 | CiviCRM is distributed in the hope that it will be useful, but     |
 | WITHOUT ANY WARRANTY; without even the implied warranty of         |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 | See the GNU Affero General Public License for more details.        |
 |                                                                    |
 | You should have received a copy of the GNU Affero General Public   |
 | License and the CiviCRM Licensing Exception along                  |
 | with this program; if not, contact CiviCRM LLC                     |
 | at info[AT]civicrm[DOT]org. If you have questions about the        |
 | GNU Affero General Public License or the licensing of CiviCRM,     |
 | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
 +--------------------------------------------------------------------+
26
 */
totten's avatar
totten committed
27
28
29
30
31

/**
 *
 *
 * @package CRM
Seamus Lee's avatar
Seamus Lee committed
32
 * @copyright CiviCRM LLC (c) 2004-2019
totten's avatar
totten committed
33
34
35
 */

/**
eileenmcnaugton's avatar
eileenmcnaugton committed
36
 * File contains functions used in civicrm configuration.
totten's avatar
totten committed
37
38
39
40
 */
class CRM_Core_BAO_ConfigSetting {

  /**
colemanw's avatar
colemanw committed
41
   * Create civicrm settings. This is the same as add but it clears the cache and
lobo's avatar
lobo committed
42
   * reloads the config object
totten's avatar
totten committed
43
   *
44
45
   * @param array $params
   *   Associated array of civicrm variables.
totten's avatar
totten committed
46
   */
47
  public static function create($params) {
totten's avatar
totten committed
48
49
50
    self::add($params);
    $cache = CRM_Utils_Cache::singleton();
    $cache->delete('CRM_Core_Config');
eileen's avatar
eileen committed
51
    $cache->delete('CRM_Core_Config' . CRM_Core_Config::domainID());
totten's avatar
totten committed
52
53
54
55
    $config = CRM_Core_Config::singleton(TRUE, TRUE);
  }

  /**
56
   * Add civicrm settings.
totten's avatar
totten committed
57
   *
58
59
   * @param array $params
   *   Associated array of civicrm variables.
totten's avatar
totten committed
60
   */
61
  public static function add(&$params) {
totten's avatar
totten committed
62
63
64
65
    $domain = new CRM_Core_DAO_Domain();
    $domain->id = CRM_Core_Config::domainID();
    $domain->find(TRUE);
    if ($domain->config_backend) {
66
      $params = array_merge(unserialize($domain->config_backend), $params);
totten's avatar
totten committed
67
68
    }

69
    $params = CRM_Core_BAO_ConfigSetting::filterSkipVars($params);
totten's avatar
totten committed
70
71
72
73
74
75
76
77
78
79
80
81
82

    // also skip all Dir Params, we dont need to store those in the DB!
    foreach ($params as $name => $val) {
      if (substr($name, -3) == 'Dir') {
        unset($params[$name]);
      }
    }

    $domain->config_backend = serialize($params);
    $domain->save();
  }

  /**
83
   * Retrieve the settings values from db.
totten's avatar
totten committed
84
   *
Eileen McNaughton's avatar
Eileen McNaughton committed
85
86
   * @param $defaults
   *
87
   * @return array
totten's avatar
totten committed
88
   */
89
  public static function retrieve(&$defaults) {
totten's avatar
totten committed
90
    $domain = new CRM_Core_DAO_Domain();
91
    $isUpgrade = CRM_Core_Config::isUpgradeMode();
totten's avatar
totten committed
92
93
94
95
96
97
98

    //we are initializing config, really can't use, CRM-7863
    $urlVar = 'q';
    if (defined('CIVICRM_UF') && CIVICRM_UF == 'Joomla') {
      $urlVar = 'task';
    }

colemanw's avatar
colemanw committed
99
    if ($isUpgrade && CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_domain', 'config_backend')) {
totten's avatar
totten committed
100
101
      $domain->selectAdd('config_backend');
    }
jitendrapurohit's avatar
jitendrapurohit committed
102
103
104
    else {
      $domain->selectAdd('locales');
    }
totten's avatar
totten committed
105
106
107
108
109
110

    $domain->id = CRM_Core_Config::domainID();
    $domain->find(TRUE);
    if ($domain->config_backend) {
      $defaults = unserialize($domain->config_backend);
      if ($defaults === FALSE || !is_array($defaults)) {
111
        $defaults = [];
Kurund Jalmi's avatar
Kurund Jalmi committed
112
        return FALSE;
totten's avatar
totten committed
113
114
115
116
117
118
119
120
      }

      $skipVars = self::skipVars();
      foreach ($skipVars as $skip) {
        if (array_key_exists($skip, $defaults)) {
          unset($defaults[$skip]);
        }
      }
jitendrapurohit's avatar
jitendrapurohit committed
121
122
123
    }
    if (!$isUpgrade) {
      CRM_Core_BAO_ConfigSetting::applyLocale(Civi::settings($domain->id), $domain->locales);
124
125
    }
  }
totten's avatar
totten committed
126

127
128
129
130
131
132
133
134
135
136
137
  /**
   * Evaluate locale preferences and activate a chosen locale by
   * updating session+global variables.
   *
   * @param \Civi\Core\SettingsBag $settings
   * @param string $activatedLocales
   *   Imploded list of locales which are supported in the DB.
   */
  public static function applyLocale($settings, $activatedLocales) {
    // are we in a multi-language setup?
    $multiLang = $activatedLocales ? TRUE : FALSE;
totten's avatar
totten committed
138

139
140
    // set the current language
    $chosenLocale = NULL;
totten's avatar
totten committed
141

142
    $session = CRM_Core_Session::singleton();
totten's avatar
totten committed
143

144
145
146
147
148
149
150
151
152
    $permittedLanguages = CRM_Core_I18n::uiLanguages(TRUE);

    // The locale to be used can come from various places:
    // - the request (url)
    // - the session
    // - civicrm_uf_match
    // - inherited from the CMS
    // Only look at this if there is actually a choice of permitted languages
    if (count($permittedLanguages) >= 2) {
153
      $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
154
      if (in_array($requestLocale, $permittedLanguages)) {
155
        $chosenLocale = $requestLocale;
totten's avatar
totten committed
156

157
158
        //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache.
        // Ed: This doesn't sound good.
159
        // Civi::cache('navigation')->flush();
160
161
162
163
      }
      else {
        $requestLocale = NULL;
      }
totten's avatar
totten committed
164

165
166
      if (!$requestLocale) {
        $sessionLocale = $session->get('lcMessages');
167
        if (in_array($sessionLocale, $permittedLanguages)) {
168
169
170
171
          $chosenLocale = $sessionLocale;
        }
        else {
          $sessionLocale = NULL;
totten's avatar
totten committed
172
        }
173
      }
totten's avatar
totten committed
174

175
176
177
178
179
180
      if ($requestLocale) {
        $ufm = new CRM_Core_DAO_UFMatch();
        $ufm->contact_id = $session->get('userID');
        if ($ufm->find(TRUE)) {
          $ufm->language = $chosenLocale;
          $ufm->save();
totten's avatar
totten committed
181
        }
182
        $session->set('lcMessages', $chosenLocale);
totten's avatar
totten committed
183
      }
184
185
186
187
188

      if (!$chosenLocale and $session->get('userID')) {
        $ufm = new CRM_Core_DAO_UFMatch();
        $ufm->contact_id = $session->get('userID');
        if ($ufm->find(TRUE) &&
189
          in_array($ufm->language, $permittedLanguages)
Eileen McNaughton's avatar
Eileen McNaughton committed
190
        ) {
191
          $chosenLocale = $ufm->language;
totten's avatar
totten committed
192
        }
193
        $session->set('lcMessages', $chosenLocale);
totten's avatar
totten committed
194
      }
195
196
197
198
199
200
    }
    global $dbLocale;

    // try to inherit the language from the hosting CMS
    if ($settings->get('inheritLocale')) {
      // FIXME: On multilanguage installs, CRM_Utils_System::getUFLocale() in many cases returns nothing if $dbLocale is not set
201
202
      $lcMessages = $settings->get('lcMessages');
      $dbLocale = $multiLang && $lcMessages ? "_{$lcMessages}" : '';
203
204
205
      $chosenLocale = CRM_Utils_System::getUFLocale();
      if ($activatedLocales and !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
        $chosenLocale = NULL;
206
      }
207
    }
totten's avatar
totten committed
208

209
210
211
212
    if (empty($chosenLocale)) {
      //CRM-11993 - if a single-lang site, use default
      $chosenLocale = $settings->get('lcMessages');
    }
totten's avatar
totten committed
213

214
    // set suffix for table names - use views if more than one language
215
    $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
totten's avatar
totten committed
216

217
218
219
220
221
222
223
224
    // FIXME: an ugly hack to fix CRM-4041
    global $tsLocale;
    $tsLocale = $chosenLocale;

    // FIXME: as bad aplace as any to fix CRM-5428
    // (to be moved to a sane location along with the above)
    if (function_exists('mb_internal_encoding')) {
      mb_internal_encoding('UTF-8');
totten's avatar
totten committed
225
226
227
    }
  }

228
229
230
231
232
233
  /**
   * @param array $defaultValues
   *
   * @return string
   * @throws Exception
   */
234
  public static function doSiteMove($defaultValues = []) {
totten's avatar
totten committed
235
    $moveStatus = ts('Beginning site move process...') . '<br />';
236
237
238
239
240
241
242
    $settings = Civi::settings();

    foreach (array_merge(self::getPathSettings(), self::getUrlSettings()) as $key) {
      $value = $settings->get($key);
      if ($value && $value != $settings->getDefault($key)) {
        if ($settings->getMandatory($key) === NULL) {
          $settings->revert($key);
243
          $moveStatus .= ts("WARNING: The setting (%1) has been reverted.", [
244
            1 => $key,
245
          ]);
246
          $moveStatus .= '<br />';
totten's avatar
totten committed
247
        }
248
        else {
249
          $moveStatus .= ts("WARNING: The setting (%1) is overridden and could not be reverted.", [
250
            1 => $key,
251
          ]);
252
          $moveStatus .= '<br />';
totten's avatar
totten committed
253
254
255
256
257
258
259
260
261
262
263
264
        }
      }
    }

    $config = CRM_Core_Config::singleton();

    // clear the template_c and upload directory also
    $config->cleanup(3, TRUE);
    $moveStatus .= ts('Template cache and upload directory have been cleared.') . '<br />';

    // clear all caches
    CRM_Core_Config::clearDBCache();
265
    Civi::cache('session')->clear();
totten's avatar
totten committed
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
    $moveStatus .= ts('Database cache tables cleared.') . '<br />';

    $resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
      'Boolean',
      CRM_Core_DAO::$_nullArray,
      FALSE,
      FALSE,
      'REQUEST'
    );
    if ($config->userSystem->is_drupal &&
      $resetSessionTable
    ) {
      db_query("DELETE FROM {sessions} WHERE 1");
      $moveStatus .= ts('Drupal session table cleared.') . '<br />';
    }
    else {
      $session = CRM_Core_Session::singleton();
      $session->reset(2);
      $moveStatus .= ts('Session has been reset.') . '<br />';
    }

    return $moveStatus;
  }

  /**
291
   * Takes a componentName and enables it in the config.
totten's avatar
totten committed
292
293
   * Primarily used during unit testing
   *
294
295
   * @param string $componentName
   *   Name of the component to be enabled, needs to be valid.
totten's avatar
totten committed
296
   *
Kurund Jalmi's avatar
Kurund Jalmi committed
297
   * @return bool
298
   *   true if valid component name and enabling succeeds, else false
totten's avatar
totten committed
299
   */
300
  public static function enableComponent($componentName) {
totten's avatar
totten committed
301
302
303
304
305
306
307
    $config = CRM_Core_Config::singleton();
    if (in_array($componentName, $config->enableComponents)) {
      // component is already enabled
      return TRUE;
    }

    // return if component does not exist
308
    if (!array_key_exists($componentName, CRM_Core_Component::getComponents())) {
totten's avatar
totten committed
309
310
311
      return FALSE;
    }

Deepak Srivastava's avatar
Deepak Srivastava committed
312
    // get enabled-components from DB and add to the list
313
    $enabledComponents = Civi::settings()->get('enable_components');
Deepak Srivastava's avatar
Deepak Srivastava committed
314
    $enabledComponents[] = $componentName;
totten's avatar
totten committed
315

316
317
318
319
320
    self::setEnabledComponents($enabledComponents);

    return TRUE;
  }

Eileen McNaughton's avatar
Eileen McNaughton committed
321
322
323
324
325
326
327
  /**
   * Disable specified component.
   *
   * @param string $componentName
   *
   * @return bool
   */
328
  public static function disableComponent($componentName) {
329
    $config = CRM_Core_Config::singleton();
Eileen McNaughton's avatar
Eileen McNaughton committed
330
331
332
    if (!in_array($componentName, $config->enableComponents) ||
      !array_key_exists($componentName, CRM_Core_Component::getComponents())
    ) {
Eileen McNaughton's avatar
Eileen McNaughton committed
333
      // Post-condition is satisfied.
334
335
336
337
      return TRUE;
    }

    // get enabled-components from DB and add to the list
338
    $enabledComponents = Civi::settings()->get('enable_components');
339
    $enabledComponents = array_diff($enabledComponents, [$componentName]);
340
341
342
343
344
345

    self::setEnabledComponents($enabledComponents);

    return TRUE;
  }

Eileen McNaughton's avatar
Eileen McNaughton committed
346
347
348
349
350
  /**
   * Set enabled components.
   *
   * @param array $enabledComponents
   */
351
  public static function setEnabledComponents($enabledComponents) {
352
353
    // fix the config object. update db.
    Civi::settings()->set('enable_components', $enabledComponents);
totten's avatar
totten committed
354
355
356
357
358

    // also force reset of component array
    CRM_Core_Component::getEnabledComponents(TRUE);
  }

359
360
361
  /**
   * @return array
   */
362
  public static function skipVars() {
363
    return [
Eileen McNaughton's avatar
Eileen McNaughton committed
364
365
      'dsn',
      'templateCompileDir',
totten's avatar
totten committed
366
367
      'userFrameworkDSN',
      'userFramework',
Eileen McNaughton's avatar
Eileen McNaughton committed
368
369
370
371
      'userFrameworkBaseURL',
      'userFrameworkClass',
      'userHookClass',
      'userPermissionClass',
372
      'userPermissionTemp',
Eileen McNaughton's avatar
Eileen McNaughton committed
373
374
375
376
377
378
379
380
381
      'userFrameworkURLVar',
      'userFrameworkVersion',
      'newBaseURL',
      'newBaseDir',
      'newSiteName',
      'configAndLogDir',
      'qfKey',
      'gettextResourceDir',
      'cleanURL',
382
      'entryURL',
Eileen McNaughton's avatar
Eileen McNaughton committed
383
384
      'locale_custom_strings',
      'localeCustomStrings',
totten's avatar
totten committed
385
386
387
      'autocompleteContactSearch',
      'autocompleteContactReference',
      'checksumTimeout',
388
      'checksum_timeout',
389
    ];
totten's avatar
totten committed
390
  }
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  /**
   * @param array $params
   * @return array
   */
  public static function filterSkipVars($params) {
    $skipVars = self::skipVars();
    foreach ($skipVars as $var) {
      unset($params[$var]);
    }
    foreach (array_keys($params) as $key) {
      if (preg_match('/^_qf_/', $key)) {
        unset($params[$key]);
      }
    }
    return $params;
  }

409
410
411
412
  /**
   * @return array
   */
  private static function getUrlSettings() {
413
    return [
414
415
416
417
      'userFrameworkResourceURL',
      'imageUploadURL',
      'customCSSURL',
      'extensionsURL',
418
    ];
419
420
421
422
423
424
  }

  /**
   * @return array
   */
  private static function getPathSettings() {
425
    return [
426
427
428
429
430
431
      'uploadDir',
      'imageUploadDir',
      'customFileUploadDir',
      'customTemplateDir',
      'customPHPPathDir',
      'extensionsDir',
432
    ];
433
434
  }

totten's avatar
totten committed
435
}