3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Config handles all the run time configuration changes that the system needs to deal with.
30 * Typically we'll have different values for a user's sandbox, a qa sandbox and a production area.
31 * The default values in general, should reflect production values (minimizes chances of screwing up)
34 * @copyright CiviCRM LLC (c) 2004-2013
39 require_once 'Log.php';
40 require_once 'Mail.php';
42 require_once 'api/api.php';
43 class CRM_Core_Config
extends CRM_Core_Config_Variables
{
45 /// BASE SYSTEM PROPERTIES (CIVICRM.SETTINGS.PHP)
49 * the dsn of the database connection
55 * the name of user framework
58 public $userFramework = 'Drupal';
61 * the name of user framework url variable name
64 public $userFrameworkURLVar = 'q';
67 * the dsn of the database connection for user framework
70 public $userFrameworkDSN = NULL;
73 * The connector module for the CMS/UF
75 * @var CRM_Util_System_{$uf}
77 public $userSystem = NULL;
80 * The root directory where Smarty should store
84 public $templateCompileDir = './templates_c/en_US/';
86 public $configAndLogDir = NULL;
88 // END: BASE SYSTEM PROPERTIES (CIVICRM.SETTINGS.PHP)
91 /// BEGIN HELPER CLASS PROPERTIES
95 * are we initialized and in a proper state
98 public $initialized = 0;
101 * the factory class used to instantiate our DB objects
104 private $DAOFactoryClass = 'CRM_Contact_DAO_Factory';
107 * The handle to the log that we are using
110 private static $_log = NULL;
113 * the handle on the mail handler that we are using
116 private static $_mail = NULL;
119 * We only need one instance of this object. So we use the singleton
120 * pattern and cache the instance in this variable
124 private static $_singleton = NULL;
127 * component registry object (of CRM_Core_Component type)
129 public $componentRegistry = NULL;
132 /// END HELPER CLASS PROPERTIES
136 /// RUNTIME SET CLASS PROPERTIES
140 * to determine wether the call is from cms or civicrm
142 public $inCiviCRM = FALSE;
145 /// END: RUNTIME SET CLASS PROPERTIES
149 * Define recaptcha key
152 public $recaptchaPublicKey;
155 * The constructor. Sets domain id if defined, otherwise assumes
156 * single instance installation.
161 private function __construct() {
165 * Singleton function used to manage this object.
167 * @param $loadFromDB boolean whether to load from the database
168 * @param $force boolean whether to force a reconstruction
173 static function &singleton($loadFromDB = TRUE, $force = FALSE) {
174 if (self
::$_singleton === NULL ||
$force) {
175 // goto a simple error handler
176 $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_CALLBACK
;
177 $GLOBALS['_PEAR_default_error_options'] = array('CRM_Core_Error', 'simpleHandler');
179 // lets ensure we set E_DEPRECATED to minimize errors
181 if (defined('E_DEPRECATED')) {
182 error_reporting(error_reporting() & ~E_DEPRECATED
);
185 // first, attempt to get configuration object from cache
186 $cache = CRM_Utils_Cache
::singleton();
187 self
::$_singleton = $cache->get('CRM_Core_Config');
189 // if not in cache, fire off config construction
190 if (!self
::$_singleton) {
191 self
::$_singleton = new CRM_Core_Config
;
192 self
::$_singleton->_initialize($loadFromDB);
194 //initialize variables. for gencode we cannot load from the
195 //db since the db might not be initialized
197 self
::$_singleton->_initVariables();
199 // retrieve and overwrite stuff from the settings file
200 self
::$_singleton->setCoreVariables();
202 $cache->set('CRM_Core_Config', self
::$_singleton);
205 // we retrieve the object from memcache, so we now initialize the objects
206 self
::$_singleton->_initialize($loadFromDB);
208 // CRM-9803, NYSS-4822
209 // this causes various settings to be reset and hence we should
210 // only use the config object that we retrived from memcache
213 self
::$_singleton->initialized
= 1;
215 if (isset(self
::$_singleton->customPHPPathDir
) &&
216 self
::$_singleton->customPHPPathDir
218 $include_path = self
::$_singleton->customPHPPathDir
. PATH_SEPARATOR
. get_include_path();
219 set_include_path($include_path);
222 // set the callback at the very very end, to avoid an infinite loop
223 // set the error callback
224 CRM_Core_Error
::setCallback();
226 // call the hook so other modules can add to the config
227 // again doing this at the very very end
228 CRM_Utils_Hook
::config(self
::$_singleton);
230 // make sure session is always initialised
231 $session = CRM_Core_Session
::singleton();
233 // for logging purposes, pass the userID to the db
234 $userID = $session->get('userID');
236 CRM_Core_DAO
::executeQuery('SET @civicrm_user_id = %1',
237 array(1 => array($userID, 'Integer'))
241 return self
::$_singleton;
245 private function _setUserFrameworkConfig($userFramework) {
247 $this->userFrameworkClass
= 'CRM_Utils_System_' . $userFramework;
248 $this->userHookClass
= 'CRM_Utils_Hook_' . $userFramework;
249 $userPermissionClass = 'CRM_Core_Permission_' . $userFramework;
250 $this->userPermissionClass
= new $userPermissionClass();
252 $class = $this->userFrameworkClass
;
253 // redundant with _initVariables
254 $userSystem = $this->userSystem
= new $class();
256 if ($userFramework == 'Joomla') {
257 $this->userFrameworkURLVar
= 'task';
260 if (defined('CIVICRM_UF_BASEURL')) {
261 $this->userFrameworkBaseURL
= CRM_Utils_File
::addTrailingSlash(CIVICRM_UF_BASEURL
, '/');
263 //format url for language negotiation, CRM-7803
264 $this->userFrameworkBaseURL
= CRM_Utils_System
::languageNegotiationURL($this->userFrameworkBaseURL
);
266 if (CRM_Utils_System
::isSSL()) {
267 $this->userFrameworkBaseURL
= str_replace('http://', 'https://',
268 $this->userFrameworkBaseURL
273 if (defined('CIVICRM_UF_DSN')) {
274 $this->userFrameworkDSN
= CIVICRM_UF_DSN
;
277 // this is dynamically figured out in the civicrm.settings.php file
278 if (defined('CIVICRM_CLEANURL')) {
279 $this->cleanURL
= CIVICRM_CLEANURL
;
285 $this->userFrameworkVersion
= $userSystem->getVersion();
287 if ($userFramework == 'Joomla') {
289 $dbprefix = $mainframe ?
$mainframe->getCfg('dbprefix') : 'jos_';
290 $this->userFrameworkUsersTableName
= $dbprefix . 'users';
292 elseif ($userFramework == 'WordPress') {
294 $dbprefix = $wpdb ?
$wpdb->prefix
: '';
295 $this->userFrameworkUsersTableName
= $dbprefix . 'users';
300 * Initializes the entire application.
301 * Reads constants defined in civicrm.settings.php and
302 * stores them in config properties.
307 private function _initialize($loadFromDB = TRUE) {
309 // following variables should be set in CiviCRM settings and
310 // as crucial ones, are defined upon initialisation
311 // instead of in CRM_Core_Config_Defaults
312 if (defined('CIVICRM_DSN')) {
313 $this->dsn
= CIVICRM_DSN
;
315 elseif ($loadFromDB) {
316 // bypass when calling from gencode
317 echo 'You need to define CIVICRM_DSN in civicrm.settings.php';
321 if (defined('CIVICRM_TEMPLATE_COMPILEDIR')) {
322 $this->templateCompileDir
= CRM_Utils_File
::addTrailingSlash(CIVICRM_TEMPLATE_COMPILEDIR
);
324 // also make sure we create the config directory within this directory
325 // the below statement will create both the templates directory and the config and log directory
326 $this->configAndLogDir
=
327 CRM_Utils_File
::baseFilePath($this->templateCompileDir
) .
328 'ConfigAndLog' . DIRECTORY_SEPARATOR
;
329 CRM_Utils_File
::createDir($this->configAndLogDir
);
331 // we're automatically prefixing compiled templates directories with country/language code
333 if (!empty($tsLocale)) {
334 $this->templateCompileDir
.= CRM_Utils_File
::addTrailingSlash($tsLocale);
336 elseif (!empty($this->lcMessages
)) {
337 $this->templateCompileDir
.= CRM_Utils_File
::addTrailingSlash($this->lcMessages
);
340 CRM_Utils_File
::createDir($this->templateCompileDir
);
342 elseif ($loadFromDB) {
343 echo 'You need to define CIVICRM_TEMPLATE_COMPILEDIR in civicrm.settings.php';
349 if (defined('CIVICRM_UF')) {
350 $this->userFramework
= CIVICRM_UF
;
351 $this->_setUserFrameworkConfig($this->userFramework
);
354 echo 'You need to define CIVICRM_UF in civicrm.settings.php';
358 // also initialize the logger
359 self
::$_log = Log
::singleton('display');
361 // initialize component registry early to avoid "race"
362 // between CRM_Core_Config and CRM_Core_Component (they
364 $this->componentRegistry
= new CRM_Core_Component();
368 * initialize the DataObject framework
373 private function _initDAO() {
374 CRM_Core_DAO
::init($this->dsn
);
376 $factoryClass = $this->DAOFactoryClass
;
377 require_once str_replace('_', DIRECTORY_SEPARATOR
, $factoryClass) . '.php';
378 CRM_Core_DAO
::setFactory(new $factoryClass());
379 if (CRM_Utils_Constant
::value('CIVICRM_MYSQL_STRICT', CRM_Utils_System
::isDevelopment())) {
380 CRM_Core_DAO
::executeQuery('SET SESSION sql_mode = STRICT_TRANS_TABLES');
385 * returns the singleton logger for the application
392 static public function &getLog() {
393 if (!isset(self
::$_log)) {
394 self
::$_log = Log
::singleton('display');
401 * initialize the config variables
406 private function _initVariables() {
407 // retrieve serialised settings
408 $variables = array();
409 CRM_Core_BAO_ConfigSetting
::retrieve($variables);
411 // if settings are not available, go down the full path
412 if (empty($variables)) {
413 // Step 1. get system variables with their hardcoded defaults
414 $variables = get_object_vars($this);
416 // Step 2. get default values (with settings file overrides if
417 // available - handled in CRM_Core_Config_Defaults)
418 CRM_Core_Config_Defaults
::setValues($variables);
420 // retrieve directory and url preferences also
421 CRM_Core_BAO_Setting
::retrieveDirectoryAndURLPreferences($variables);
423 // add component specific settings
424 $this->componentRegistry
->addConfig($this);
426 // serialise settings
427 $settings = $variables;
428 CRM_Core_BAO_ConfigSetting
::add($settings);
431 $urlArray = array('userFrameworkResourceURL', 'imageUploadURL');
432 $dirArray = array('uploadDir', 'customFileUploadDir');
434 foreach ($variables as $key => $value) {
435 if (in_array($key, $urlArray)) {
436 $value = CRM_Utils_File
::addTrailingSlash($value, '/');
438 elseif (in_array($key, $dirArray)) {
440 $value = CRM_Utils_File
::addTrailingSlash($value);
442 if (empty($value) ||
(CRM_Utils_File
::createDir($value, FALSE) === FALSE)) {
443 // seems like we could not create the directories
444 // settings might have changed, lets suppress a message for now
445 // so we can make some more progress and let the user fix their settings
446 // for now we assign it to a know value
448 $value = $this->templateCompileDir
;
449 $url = CRM_Utils_System
::url('civicrm/admin/setting/path', 'reset=1');
450 CRM_Core_Session
::setStatus(ts('%1 has an incorrect directory path. Please go to the <a href="%2">path setting page</a> and correct it.', array(
453 )), ts('Check Settings'), 'alert');
456 elseif ($key == 'lcMessages') {
457 // reset the templateCompileDir to locale-specific and make sure it exists
458 if (substr($this->templateCompileDir
, -1 * strlen($value) - 1, -1) != $value) {
459 $this->templateCompileDir
.= CRM_Utils_File
::addTrailingSlash($value);
460 CRM_Utils_File
::createDir($this->templateCompileDir
);
464 $this->$key = $value;
467 if ($this->userFrameworkResourceURL
) {
468 // we need to do this here so all blocks also load from an ssl server
469 if (CRM_Utils_System
::isSSL()) {
470 CRM_Utils_System
::mapConfigToSSL();
472 $rrb = parse_url($this->userFrameworkResourceURL
);
473 // dont use absolute path if resources are stored on a different server
475 $this->resourceBase
= $this->userFrameworkResourceURL
;
476 if (isset($_SERVER['HTTP_HOST']) &&
479 $this->resourceBase
= ($rrb['host'] == $_SERVER['HTTP_HOST']) ?
$rrb['path'] : $this->userFrameworkResourceURL
;
483 if (!$this->customFileUploadDir
) {
484 $this->customFileUploadDir
= $this->uploadDir
;
487 if ($this->geoProvider
) {
488 $this->geocodeMethod
= 'CRM_Utils_Geocode_' . $this->geoProvider
;
490 elseif ($this->mapProvider
) {
491 $this->geocodeMethod
= 'CRM_Utils_Geocode_' . $this->mapProvider
;
494 require_once (str_replace('_', DIRECTORY_SEPARATOR
, $this->userFrameworkClass
) . '.php');
495 $class = $this->userFrameworkClass
;
496 // redundant with _setUserFrameworkConfig
497 $this->userSystem
= new $class();
501 * retrieve a mailer to send any mail from the applciation
503 * @param boolean $persist open a persistent smtp connection, should speed up mailings
509 static function &getMailer($persist = FALSE) {
510 if (!isset(self
::$_mail)) {
511 $mailingInfo = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
515 if ($mailingInfo['outBound_option'] == CRM_Mailing_Config
::OUTBOUND_OPTION_REDIRECT_TO_DB ||
516 (defined('CIVICRM_MAILER_SPOOL') && CIVICRM_MAILER_SPOOL
)
518 self
::$_mail = new CRM_Mailing_BAO_Spool();
520 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config
::OUTBOUND_OPTION_SMTP
) {
521 if ($mailingInfo['smtpServer'] == '' ||
!$mailingInfo['smtpServer']) {
522 CRM_Core_Error
::fatal(ts('There is no valid smtp server setting. Click <a href=\'%1\'>Administer CiviCRM >> Global Settings</a> to set the SMTP Server.', array(1 => CRM_Utils_System
::url('civicrm/admin/setting', 'reset=1'))));
525 $params['host'] = $mailingInfo['smtpServer'] ?
$mailingInfo['smtpServer'] : 'localhost';
526 $params['port'] = $mailingInfo['smtpPort'] ?
$mailingInfo['smtpPort'] : 25;
528 if ($mailingInfo['smtpAuth']) {
529 $params['username'] = $mailingInfo['smtpUsername'];
530 $params['password'] = CRM_Utils_Crypt
::decrypt($mailingInfo['smtpPassword']);
531 $params['auth'] = TRUE;
534 $params['auth'] = FALSE;
537 // set the localhost value, CRM-3153
538 $params['localhost'] = CRM_Utils_Array
::value('SERVER_NAME', $_SERVER, 'localhost');
540 // also set the timeout value, lets set it to 30 seconds
542 $params['timeout'] = 30;
545 $params['persist'] = $persist;
547 self
::$_mail = Mail
::factory('smtp', $params);
549 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config
::OUTBOUND_OPTION_SENDMAIL
) {
550 if ($mailingInfo['sendmail_path'] == '' ||
551 !$mailingInfo['sendmail_path']
553 CRM_Core_Error
::fatal(ts('There is no valid sendmail path setting. Click <a href=\'%1\'>Administer CiviCRM >> Global Settings</a> to set the Sendmail Server.', array(1 => CRM_Utils_System
::url('civicrm/admin/setting', 'reset=1'))));
555 $params['sendmail_path'] = $mailingInfo['sendmail_path'];
556 $params['sendmail_args'] = $mailingInfo['sendmail_args'];
558 self
::$_mail = Mail
::factory('sendmail', $params);
560 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config
::OUTBOUND_OPTION_MAIL
) {
562 self
::$_mail = Mail
::factory('mail', $params);
564 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config
::OUTBOUND_OPTION_MOCK
) {
565 self
::$_mail = Mail
::factory('mock', $params);
568 CRM_Core_Session
::setStatus(ts('There is no valid SMTP server Setting Or SendMail path setting. Click <a href=\'%1\'>Administer CiviCRM >> Global Settings</a> to set the OutBound Email.', array(1 => CRM_Utils_System
::url('civicrm/admin/setting', 'reset=1'))), ts('Check Settings'), 'alert');
575 * delete the web server writable directories
577 * @param int $value 1 - clean templates_c, 2 - clean upload, 3 - clean both
583 public function cleanup($value, $rmdir = TRUE) {
584 $value = (int ) $value;
588 CRM_Utils_File
::cleanDir($this->templateCompileDir
, $rmdir);
589 CRM_Utils_File
::createDir($this->templateCompileDir
);
593 CRM_Utils_File
::cleanDir($this->uploadDir
);
594 CRM_Utils_File
::createDir($this->uploadDir
);
595 CRM_Utils_File
::restrictAccess($this->uploadDir
);
600 * verify that the needed parameters are not null in the config
602 * @param CRM_Core_Config (reference ) the system config object
603 * @param array (reference ) the parameters that need a value
609 static function check(&$config, &$required) {
610 foreach ($required as $name) {
611 if (CRM_Utils_System
::isNull($config->$name)) {
619 * reset the serialized array and recompute
623 $query = "UPDATE civicrm_domain SET config_backend = null";
624 CRM_Core_DAO
::executeQuery($query);
628 * one function to get domain ID
630 static function domainID($domainID = NULL, $reset = FALSE) {
635 if ($reset ||
empty($domain)) {
636 $domain = defined('CIVICRM_DOMAIN_ID') ? CIVICRM_DOMAIN_ID
: 1;
643 * do general cleanup of caches, temp directories and temp tables
646 function cleanupCaches($sessionReset = TRUE) {
647 // cleanup templates_c directory
648 $this->cleanup(1, FALSE);
651 self
::clearDBCache();
654 $session = CRM_Core_Session
::singleton();
660 * Do general cleanup of module permissions.
662 function cleanupPermissions() {
663 $module_files = CRM_Extension_System
::singleton()->getMapper()->getActiveModuleFiles();
664 if ($this->userPermissionClass
->isModulePermissionSupported()) {
665 // Can store permissions -- so do it!
666 $this->userPermissionClass
->upgradePermissions(
667 CRM_Core_Permission
::basicPermissions()
670 // Cannot store permissions -- warn if any modules require them
671 $modules_with_perms = array();
672 foreach ($module_files as $module_file) {
673 $perms = $this->userPermissionClass
->getModulePermissions($module_file['prefix']);
674 if (!empty($perms)) {
675 $modules_with_perms[] = $module_file['prefix'];
678 if (!empty($modules_with_perms)) {
679 CRM_Core_Session
::setStatus(
680 ts('Some modules define permissions, but the CMS cannot store them: %1', array(
681 1 => implode(', ', $modules_with_perms),
683 ts('Permission Error'),
691 * Flush information about loaded modules
693 function clearModuleList() {
694 CRM_Extension_System
::singleton()->getCache()->flush();
695 CRM_Utils_Hook
::singleton(TRUE);
696 CRM_Core_PseudoConstant
::getModuleExtensions(TRUE);
697 CRM_Core_Module
::getAll(TRUE);
703 public static function clearDBCache() {
705 'TRUNCATE TABLE civicrm_acl_cache',
706 'TRUNCATE TABLE civicrm_acl_contact_cache',
707 'TRUNCATE TABLE civicrm_cache',
708 'TRUNCATE TABLE civicrm_prevnext_cache',
709 'UPDATE civicrm_group SET cache_date = NULL',
710 'TRUNCATE TABLE civicrm_group_contact_cache',
711 'TRUNCATE TABLE civicrm_menu',
712 'UPDATE civicrm_setting SET value = NULL WHERE name="navigation" AND contact_id IS NOT NULL',
713 'DELETE FROM civicrm_setting WHERE name="modulePaths"', // CRM-10543
716 foreach ($queries as $query) {
717 CRM_Core_DAO
::executeQuery($query);
720 // also delete all the import and export temp tables
721 self
::clearTempTables();
725 * clear leftover temporary tables
727 public static function clearTempTables() {
729 $dao = CRM_Core_DAO
::executeQuery("SELECT DATABASE();");
731 SELECT TABLE_NAME as tableName
732 FROM INFORMATION_SCHEMA.TABLES
733 WHERE TABLE_SCHEMA = %1
734 AND ( TABLE_NAME LIKE 'civicrm_import_job_%'
735 OR TABLE_NAME LIKE 'civicrm_export_temp%'
736 OR TABLE_NAME LIKE 'civicrm_task_action_temp%' )
739 $params = array(1 => array($dao->database(), 'String'));
740 $tableDAO = CRM_Core_DAO
::executeQuery($query, $params);
742 while ($tableDAO->fetch()) {
743 $tables[] = $tableDAO->tableName
;
745 if (!empty($tables)) {
746 $table = implode(',', $tables);
747 // drop leftover temporary tables
748 CRM_Core_DAO
::executeQuery("DROP TABLE $table");
753 * function to check if running in upgrade mode
755 static function isUpgradeMode($path = NULL) {
756 if (defined('CIVICRM_UPGRADE_ACTIVE')) {
761 // note: do not re-initialize config here, since this function is part of
762 // config initialization itself
764 if (defined('CIVICRM_UF') && CIVICRM_UF
== 'Joomla') {
768 $path = CRM_Utils_Array
::value($urlVar, $_GET);
771 if ($path && preg_match('/^civicrm\/upgrade(\/.*)?$/', $path)) {
779 * Wrapper function to allow unit tests to switch user framework on the fly
781 public function setUserFramework($userFramework = NULL) {
782 $this->userFramework
= $userFramework;
783 $this->_setUserFrameworkConfig($userFramework);
786 // end CRM_Core_Config