Merge pull request #7522 from colemanw/case_api
[civicrm-core.git] / CRM / Core / Config.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 * Config handles all the run time configuration changes that the system needs to deal with.
8eedd10a 30 *
6a488035
TO
31 * Typically we'll have different values for a user's sandbox, a qa sandbox and a production area.
32 * The default values in general, should reflect production values (minimizes chances of screwing up)
33 *
34 * @package CRM
e7112fa7 35 * @copyright CiviCRM LLC (c) 2004-2015
6a488035
TO
36 */
37
38require_once 'Log.php';
39require_once 'Mail.php';
40
41require_once 'api/api.php';
72536736 42
28518c90
EM
43/**
44 * Class CRM_Core_Config
e367c7b0
CW
45 *
46 * @property CRM_Utils_System_Base $userSystem
6b070fc0
CW
47 * @property array $enableComponents
48 * @property array $languageLimit
49 * @property bool $debug
50 * @property bool $doNotResetCache
51 * @property string $maxFileSize
52 * @property string $defaultCurrency
53 * @property string $defaultCurrencySymbol
54 * @property string $lcMessages
55 * @property string $fieldSeparator
56 * @property string $userFramework
57 * @property string $verpSeparator
58 * @property string $dateFormatFull
59 * @property string $resourceBase
60 * @property string $dsn
61 * @property string $customTemplateDir
62 * @property string $defaultContactCountry
63 * @property string $defaultContactStateProvince
64 * @property string $monetaryDecimalPoint
65 * @property string $monetaryThousandSeparator
28518c90 66 */
c0a1f187 67class CRM_Core_Config extends CRM_Core_Config_MagicMerge {
4d66768d 68
6a488035
TO
69 /**
70 * The handle to the log that we are using
71 * @var object
72 */
73 private static $_log = NULL;
74
6a488035
TO
75 /**
76 * We only need one instance of this object. So we use the singleton
77 * pattern and cache the instance in this variable
72536736
AH
78 *
79 * @var CRM_Core_Config
6a488035
TO
80 */
81 private static $_singleton = NULL;
82
6a488035
TO
83 /**
84 * The constructor. Sets domain id if defined, otherwise assumes
85 * single instance installation.
6a488035 86 */
0acb7f15 87 public function __construct() {
c0a1f187 88 parent::__construct();
6a488035
TO
89 }
90
91 /**
92 * Singleton function used to manage this object.
93 *
5a4f6742
CW
94 * @param bool $loadFromDB
95 * whether to load from the database.
96 * @param bool $force
97 * whether to force a reconstruction.
6a488035 98 *
5af8c999 99 * @return CRM_Core_Config
6a488035 100 */
00be9182 101 public static function &singleton($loadFromDB = TRUE, $force = FALSE) {
6a488035 102 if (self::$_singleton === NULL || $force) {
ca32aecc
TO
103 $GLOBALS['civicrm_default_error_scope'] = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'handle'));
104 $errorScope = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'simpleHandler'));
6a488035 105
6a488035
TO
106 if (defined('E_DEPRECATED')) {
107 error_reporting(error_reporting() & ~E_DEPRECATED);
108 }
109
fc50f470 110 self::$_singleton = new CRM_Core_Config();
7f835399
TO
111 \Civi\Core\Container::boot($loadFromDB);
112 if ($loadFromDB && self::$_singleton->dsn) {
c0a1f187
TO
113 $domain = \CRM_Core_BAO_Domain::getDomain();
114 \CRM_Core_BAO_ConfigSetting::applyLocale(\Civi::settings($domain->id), $domain->locales);
6a488035 115
fc50f470 116 unset($errorScope);
6a488035 117
fc50f470
TO
118 CRM_Utils_Hook::config(self::$_singleton);
119 self::$_singleton->authenticate();
23bb9c85 120
fc50f470
TO
121 // Extreme backward compat: $config binds to active domain at moment of setup.
122 self::$_singleton->getSettings();
23bb9c85 123
fc50f470
TO
124 Civi::service('settings_manager')->useDefaults();
125 }
6a488035
TO
126 }
127 return self::$_singleton;
128 }
129
6a488035 130 /**
d09edf64 131 * Returns the singleton logger for the application.
6a488035 132 *
c0a1f187 133 * @deprecated
6a488035 134 * @return object
c0a1f187 135 * @see Civi::log()
6a488035
TO
136 */
137 static public function &getLog() {
138 if (!isset(self::$_log)) {
139 self::$_log = Log::singleton('display');
140 }
141
142 return self::$_log;
143 }
144
6a488035 145 /**
d09edf64 146 * Retrieve a mailer to send any mail from the application.
6a488035 147 *
247eb841
TO
148 * @return Mail
149 * @deprecated
c0a1f187 150 * @see Civi::service()
6a488035 151 */
247eb841 152 public static function getMailer() {
048222df 153 return Civi::service('pear_mail');
72ad6c1b
TO
154 }
155
6a488035 156 /**
d09edf64 157 * Deletes the web server writable directories.
6a488035 158 *
72536736
AH
159 * @param int $value
160 * 1: clean templates_c, 2: clean upload, 3: clean both
161 * @param bool $rmdir
6a488035
TO
162 */
163 public function cleanup($value, $rmdir = TRUE) {
164 $value = (int ) $value;
165
166 if ($value & 1) {
167 // clean templates_c
168 CRM_Utils_File::cleanDir($this->templateCompileDir, $rmdir);
169 CRM_Utils_File::createDir($this->templateCompileDir);
170 }
171 if ($value & 2) {
172 // clean upload dir
173 CRM_Utils_File::cleanDir($this->uploadDir);
174 CRM_Utils_File::createDir($this->uploadDir);
fea6131e
TO
175 }
176
177 // Whether we delete/create or simply preserve directories, we should
178 // certainly make sure the restrictions are enforced.
353ffa53
TO
179 foreach (array(
180 $this->templateCompileDir,
181 $this->uploadDir,
182 $this->configAndLogDir,
8d7a9d07 183 $this->customFileUploadDir,
353ffa53 184 ) as $dir) {
fea6131e
TO
185 if ($dir && is_dir($dir)) {
186 CRM_Utils_File::restrictAccess($dir);
187 }
6a488035
TO
188 }
189 }
190
191 /**
0880a9d0 192 * Verify that the needed parameters are not null in the config.
6a488035 193 *
8d7a9d07
CB
194 * @param CRM_Core_Config $config (reference) the system config object
195 * @param array $required (reference) the parameters that need a value
6a488035 196 *
8d7a9d07 197 * @return bool
6a488035 198 */
00be9182 199 public static function check(&$config, &$required) {
6a488035
TO
200 foreach ($required as $name) {
201 if (CRM_Utils_System::isNull($config->$name)) {
202 return FALSE;
203 }
204 }
205 return TRUE;
206 }
207
208 /**
0880a9d0 209 * Reset the serialized array and recompute.
6a488035
TO
210 * use with care
211 */
00be9182 212 public function reset() {
6a488035
TO
213 $query = "UPDATE civicrm_domain SET config_backend = null";
214 CRM_Core_DAO::executeQuery($query);
215 }
216
546b78fa 217 /**
0880a9d0 218 * This method should initialize auth sources.
546b78fa 219 */
635f0b86
TO
220 public function authenticate() {
221 // make sure session is always initialised
e8f14831 222 $session = CRM_Core_Session::singleton();
635f0b86
TO
223
224 // for logging purposes, pass the userID to the db
225 $userID = $session->get('userID');
226 if ($userID) {
227 CRM_Core_DAO::executeQuery('SET @civicrm_user_id = %1',
228 array(1 => array($userID, 'Integer'))
229 );
230 }
231
e8f14831
DS
232 if ($session->get('userID') && !$session->get('authSrc')) {
233 $session->set('authSrc', CRM_Core_Permission::AUTH_SRC_LOGIN);
234 }
235
236 // checksum source
237 CRM_Contact_BAO_Contact_Permission::initChecksumAuthSrc();
238 }
239
6a488035 240 /**
0880a9d0 241 * One function to get domain ID.
ad37ac8e 242 *
243 * @param int $domainID
244 * @param bool $reset
245 *
246 * @return int|null
6a488035 247 */
00be9182 248 public static function domainID($domainID = NULL, $reset = FALSE) {
6a488035
TO
249 static $domain;
250 if ($domainID) {
251 $domain = $domainID;
252 }
253 if ($reset || empty($domain)) {
254 $domain = defined('CIVICRM_DOMAIN_ID') ? CIVICRM_DOMAIN_ID : 1;
255 }
256
257 return $domain;
258 }
259
260 /**
100fef9d 261 * Do general cleanup of caches, temp directories and temp tables
6a488035 262 * CRM-8739
ea3ddccf 263 *
264 * @param bool $sessionReset
6a488035 265 */
00be9182 266 public function cleanupCaches($sessionReset = TRUE) {
6a488035
TO
267 // cleanup templates_c directory
268 $this->cleanup(1, FALSE);
269
1b50807d 270 // clear all caches
6a488035 271 self::clearDBCache();
1b50807d 272 CRM_Utils_System::flushCache();
6a488035
TO
273
274 if ($sessionReset) {
275 $session = CRM_Core_Session::singleton();
276 $session->reset(2);
277 }
278 }
279
280 /**
281 * Do general cleanup of module permissions.
282 */
00be9182 283 public function cleanupPermissions() {
6a488035 284 $module_files = CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles();
7fccad46
TO
285 if ($this->userPermissionClass->isModulePermissionSupported()) {
286 // Can store permissions -- so do it!
0d8fc497
TO
287 $this->userPermissionClass->upgradePermissions(
288 CRM_Core_Permission::basicPermissions()
289 );
0db6c3e1
TO
290 }
291 else {
7fccad46
TO
292 // Cannot store permissions -- warn if any modules require them
293 $modules_with_perms = array();
294 foreach ($module_files as $module_file) {
295 $perms = $this->userPermissionClass->getModulePermissions($module_file['prefix']);
296 if (!empty($perms)) {
297 $modules_with_perms[] = $module_file['prefix'];
298 }
299 }
300 if (!empty($modules_with_perms)) {
301 CRM_Core_Session::setStatus(
10a5be27 302 ts('Some modules define permissions, but the CMS cannot store them: %1', array(1 => implode(', ', $modules_with_perms))),
7fccad46
TO
303 ts('Permission Error'),
304 'error'
305 );
306 }
6a488035
TO
307 }
308 }
309
310 /**
0880a9d0 311 * Flush information about loaded modules.
6a488035 312 */
00be9182 313 public function clearModuleList() {
6a488035
TO
314 CRM_Extension_System::singleton()->getCache()->flush();
315 CRM_Utils_Hook::singleton(TRUE);
316 CRM_Core_PseudoConstant::getModuleExtensions(TRUE);
317 CRM_Core_Module::getAll(TRUE);
318 }
319
320 /**
0880a9d0 321 * Clear db cache.
6a488035
TO
322 */
323 public static function clearDBCache() {
324 $queries = array(
325 'TRUNCATE TABLE civicrm_acl_cache',
326 'TRUNCATE TABLE civicrm_acl_contact_cache',
327 'TRUNCATE TABLE civicrm_cache',
328 'TRUNCATE TABLE civicrm_prevnext_cache',
329 'UPDATE civicrm_group SET cache_date = NULL',
330 'TRUNCATE TABLE civicrm_group_contact_cache',
331 'TRUNCATE TABLE civicrm_menu',
332 'UPDATE civicrm_setting SET value = NULL WHERE name="navigation" AND contact_id IS NOT NULL',
333 'DELETE FROM civicrm_setting WHERE name="modulePaths"', // CRM-10543
334 );
335
336 foreach ($queries as $query) {
337 CRM_Core_DAO::executeQuery($query);
338 }
339
340 // also delete all the import and export temp tables
341 self::clearTempTables();
342 }
343
344 /**
0880a9d0 345 * Clear leftover temporary tables.
0383ef73
EM
346 *
347 * This is called on upgrade, during tests and site move, from the cron and via clear caches in the UI.
348 *
349 * Currently the UI clear caches does not pass a time interval - which may need review as it does risk
350 * ripping the tables out from underneath a current action. This was considered but
351 * out-of-scope for CRM-16167
352 *
353 * @param string|bool $timeInterval
354 * Optional time interval for mysql date function.g '2 day'. This can be used to prevent
355 * tables created recently from being deleted.
6a488035 356 */
0383ef73
EM
357 public static function clearTempTables($timeInterval = FALSE) {
358
359 $dao = new CRM_Core_DAO();
6a488035 360 $query = "
0383ef73
EM
361 SELECT TABLE_NAME as tableName
362 FROM INFORMATION_SCHEMA.TABLES
363 WHERE TABLE_SCHEMA = %1
364 AND (
365 TABLE_NAME LIKE 'civicrm_import_job_%'
366 OR TABLE_NAME LIKE 'civicrm_export_temp%'
367 OR TABLE_NAME LIKE 'civicrm_task_action_temp%'
368 OR TABLE_NAME LIKE 'civicrm_report_temp%'
369 )
370 ";
371 if ($timeInterval) {
372 $query .= " AND CREATE_TIME < DATE_SUB(NOW(), INTERVAL {$timeInterval})";
373 }
374
375 $tableDAO = CRM_Core_DAO::executeQuery($query, array(1 => array($dao->database(), 'String')));
6a488035
TO
376 $tables = array();
377 while ($tableDAO->fetch()) {
378 $tables[] = $tableDAO->tableName;
379 }
380 if (!empty($tables)) {
381 $table = implode(',', $tables);
382 // drop leftover temporary tables
383 CRM_Core_DAO::executeQuery("DROP TABLE $table");
384 }
385 }
386
387 /**
0880a9d0 388 * Check if running in upgrade mode.
54957108 389 *
390 * @param string $path
391 *
392 * @return bool
6a488035 393 */
00be9182 394 public static function isUpgradeMode($path = NULL) {
6a488035
TO
395 if (defined('CIVICRM_UPGRADE_ACTIVE')) {
396 return TRUE;
397 }
398
399 if (!$path) {
400 // note: do not re-initialize config here, since this function is part of
401 // config initialization itself
402 $urlVar = 'q';
403 if (defined('CIVICRM_UF') && CIVICRM_UF == 'Joomla') {
404 $urlVar = 'task';
405 }
406
407 $path = CRM_Utils_Array::value($urlVar, $_GET);
408 }
409
410 if ($path && preg_match('/^civicrm\/upgrade(\/.*)?$/', $path)) {
411 return TRUE;
412 }
413
414 return FALSE;
415 }
416
9be1374d
EM
417 /**
418 * Is back office credit card processing enabled for this site - ie are there any installed processors that support
fbcb6fba 419 * it?
52767de0
EM
420 * This function is used for determining whether to show the submit credit card link, not for determining which processors to show, hence
421 * it is a config var
9be1374d
EM
422 * @return bool
423 */
00be9182 424 public static function isEnabledBackOfficeCreditCardPayments() {
44b6505d 425 return CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('BackOffice'));
9be1374d 426 }
96025800 427
0acb7f15
TO
428 /**
429 * @deprecated
430 */
431 public function addressSequence() {
432 return CRM_Utils_Address::sequence(Civi::settings()->get('address_format'));
433 }
434
435 /**
436 * @deprecated
437 */
438 public function defaultContactCountry() {
439 return CRM_Core_BAO_Country::defaultContactCountry();
440 }
441
442 /**
443 * @deprecated
444 */
445 public function defaultContactCountryName() {
446 return CRM_Core_BAO_Country::defaultContactCountryName();
447 }
448
449 /**
450 * @deprecated
ea3ddccf 451 *
452 * @param string $defaultCurrency
453 *
454 * @return string
0acb7f15
TO
455 */
456 public function defaultCurrencySymbol($defaultCurrency = NULL) {
457 return CRM_Core_BAO_Country::defaultCurrencySymbol($defaultCurrency);
458 }
459
97b8e6b2 460 /**
461 * Resets the singleton, so that the next call to CRM_Core_Config::singleton()
462 * reloads completely.
463 *
464 * While normally we could call the singleton function with $force = TRUE,
465 * this function addresses a very specific use-case in the CiviCRM installer,
466 * where we cannot yet force a reload, but we want to make sure that the next
467 * call to this object gets a fresh start (ex: to initialize the DAO).
468 */
469 public function free() {
470 self::$_singleton = NULL;
471 }
c8ab0a65 472
6a488035 473}