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