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's avatar
kurund 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's avatar
kurund 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
}