Merge pull request #4004 from civicrm/4.4
[civicrm-core.git] / CRM / Core / Config.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
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)
32 *
33 * @package CRM
34 * @copyright CiviCRM LLC (c) 2004-2014
35 * $Id$
36 *
37 */
38
39 require_once 'Log.php';
40 require_once 'Mail.php';
41
42 require_once 'api/api.php';
43
44 /**
45 * Class CRM_Core_Config
46 */
47 class CRM_Core_Config extends CRM_Core_Config_Variables {
48 ///
49 /// BASE SYSTEM PROPERTIES (CIVICRM.SETTINGS.PHP)
50 ///
51
52 /**
53 * the dsn of the database connection
54 *
55 * @var string
56 */
57 public $dsn;
58
59 /**
60 * the name of user framework
61 *
62 * @var string
63 */
64 public $userFramework = 'Drupal';
65
66 /**
67 * the name of user framework url variable name
68 *
69 * @var string
70 */
71 public $userFrameworkURLVar = 'q';
72
73 /**
74 * the dsn of the database connection for user framework
75 *
76 * @var string
77 */
78 public $userFrameworkDSN = NULL;
79
80 /**
81 * The connector module for the CMS/UF
82 * @todo Introduce an interface.
83 *
84 * @var CRM_Utils_System_Base
85 */
86 public $userSystem = NULL;
87
88 /**
89 * @var CRM_Core_Permission_Base
90 */
91 public $userPermissionClass;
92
93 /**
94 * The root directory where Smarty should store compiled files
95 *
96 * @var string
97 */
98 public $templateCompileDir = './templates_c/en_US/';
99
100 /**
101 * @var string
102 */
103 public $configAndLogDir = NULL;
104
105 // END: BASE SYSTEM PROPERTIES (CIVICRM.SETTINGS.PHP)
106
107 ///
108 /// BEGIN HELPER CLASS PROPERTIES
109 ///
110
111 /**
112 * are we initialized and in a proper state
113 *
114 * @var string
115 */
116 public $initialized = 0;
117
118 /**
119 * @var string
120 */
121 public $customPHPPathDir;
122
123 /**
124 * the factory class used to instantiate our DB objects
125 *
126 * @var string
127 */
128 private $DAOFactoryClass = 'CRM_Contact_DAO_Factory';
129
130 /**
131 * The handle to the log that we are using
132 * @var object
133 */
134 private static $_log = NULL;
135
136 /**
137 * the handle on the mail handler that we are using
138 *
139 * @var object
140 */
141 public static $_mail = NULL;
142
143 /**
144 * We only need one instance of this object. So we use the singleton
145 * pattern and cache the instance in this variable
146 *
147 * @var CRM_Core_Config
148 */
149 private static $_singleton = NULL;
150
151 /**
152 * @var CRM_Core_Component
153 */
154 public $componentRegistry = NULL;
155
156 ///
157 /// END HELPER CLASS PROPERTIES
158 ///
159
160 ///
161 /// RUNTIME SET CLASS PROPERTIES
162 ///
163
164 /**
165 * @var bool
166 * TRUE, if the call is CiviCRM.
167 * FALSE, if the call is from the CMS.
168 */
169 public $inCiviCRM = FALSE;
170
171 ///
172 /// END: RUNTIME SET CLASS PROPERTIES
173 ///
174
175 /**
176 * @var string
177 */
178 public $recaptchaPublicKey;
179
180 /**
181 * The constructor. Sets domain id if defined, otherwise assumes
182 * single instance installation.
183 */
184 private function __construct() {
185 }
186
187 /**
188 * Singleton function used to manage this object.
189 *
190 * @param $loadFromDB boolean whether to load from the database
191 * @param $force boolean whether to force a reconstruction
192 *
193 * @return CRM_Core_Config
194 * @static
195 */
196 static function &singleton($loadFromDB = TRUE, $force = FALSE) {
197 if (self::$_singleton === NULL || $force) {
198 // goto a simple error handler
199 $GLOBALS['civicrm_default_error_scope'] = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'handle'));
200 $errorScope = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'simpleHandler'));
201
202 // lets ensure we set E_DEPRECATED to minimize errors
203 // CRM-6327
204 if (defined('E_DEPRECATED')) {
205 error_reporting(error_reporting() & ~E_DEPRECATED);
206 }
207
208 // first, attempt to get configuration object from cache
209 $cache = CRM_Utils_Cache::singleton();
210 self::$_singleton = $cache->get('CRM_Core_Config' . CRM_Core_Config::domainID());
211 // if not in cache, fire off config construction
212 if (!self::$_singleton) {
213 self::$_singleton = new CRM_Core_Config;
214 self::$_singleton->_initialize($loadFromDB);
215
216 //initialize variables. for gencode we cannot load from the
217 //db since the db might not be initialized
218 if ($loadFromDB) {
219 // initialize stuff from the settings file
220 self::$_singleton->setCoreVariables();
221
222 self::$_singleton->_initVariables();
223
224 // I don't think we need to do this twice
225 // however just keeping this commented for now in 4.4
226 // in case we hit any issues - CRM-13064
227 // We can safely delete this once we release 4.4.4
228 // self::$_singleton->setCoreVariables();
229 }
230 $cache->set('CRM_Core_Config' . CRM_Core_Config::domainID(), self::$_singleton);
231 }
232 else {
233 // we retrieve the object from memcache, so we now initialize the objects
234 self::$_singleton->_initialize($loadFromDB);
235
236 // CRM-9803, NYSS-4822
237 // this causes various settings to be reset and hence we should
238 // only use the config object that we retrieved from memcache
239 }
240
241 self::$_singleton->initialized = 1;
242
243 if (isset(self::$_singleton->customPHPPathDir) &&
244 self::$_singleton->customPHPPathDir
245 ) {
246 $include_path = self::$_singleton->customPHPPathDir . PATH_SEPARATOR . get_include_path();
247 set_include_path($include_path);
248 }
249
250 // set the callback at the very very end, to avoid an infinite loop
251 // set the error callback
252 unset($errorScope);
253
254 // call the hook so other modules can add to the config
255 // again doing this at the very very end
256 CRM_Utils_Hook::config(self::$_singleton);
257
258 // make sure session is always initialised
259 $session = CRM_Core_Session::singleton();
260
261 // for logging purposes, pass the userID to the db
262 $userID = $session->get('userID');
263 if ($userID) {
264 CRM_Core_DAO::executeQuery('SET @civicrm_user_id = %1',
265 array(1 => array($userID, 'Integer'))
266 );
267 }
268
269 // initialize authentication source
270 self::$_singleton->initAuthSrc();
271 }
272 return self::$_singleton;
273 }
274
275 /**
276 * @param string $userFramework
277 * One of 'Drupal', 'Joomla', etc.
278 */
279 private function _setUserFrameworkConfig($userFramework) {
280
281 $this->userFrameworkClass = 'CRM_Utils_System_' . $userFramework;
282 $this->userHookClass = 'CRM_Utils_Hook_' . $userFramework;
283 $userPermissionClass = 'CRM_Core_Permission_' . $userFramework;
284 $this->userPermissionClass = new $userPermissionClass();
285
286 $class = $this->userFrameworkClass;
287 // redundant with _initVariables
288 $this->userSystem = new $class();
289
290 if ($userFramework == 'Joomla') {
291 $this->userFrameworkURLVar = 'task';
292 }
293
294 if (defined('CIVICRM_UF_BASEURL')) {
295 $this->userFrameworkBaseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
296
297 //format url for language negotiation, CRM-7803
298 $this->userFrameworkBaseURL = CRM_Utils_System::languageNegotiationURL($this->userFrameworkBaseURL);
299
300 if (CRM_Utils_System::isSSL()) {
301 $this->userFrameworkBaseURL = str_replace('http://', 'https://',
302 $this->userFrameworkBaseURL
303 );
304 }
305 }
306
307 if (defined('CIVICRM_UF_DSN')) {
308 $this->userFrameworkDSN = CIVICRM_UF_DSN;
309 }
310
311 // this is dynamically figured out in the civicrm.settings.php file
312 if (defined('CIVICRM_CLEANURL')) {
313 $this->cleanURL = CIVICRM_CLEANURL;
314 }
315 else {
316 $this->cleanURL = 0;
317 }
318
319 $this->userFrameworkVersion = $this->userSystem->getVersion();
320
321 if ($userFramework == 'Joomla') {
322 /** @var object|null $mainframe */
323 global $mainframe;
324 $dbprefix = $mainframe ? $mainframe->getCfg('dbprefix') : 'jos_';
325 $this->userFrameworkUsersTableName = $dbprefix . 'users';
326 }
327 elseif ($userFramework == 'WordPress') {
328 global $wpdb;
329 $dbprefix = $wpdb ? $wpdb->prefix : '';
330 $this->userFrameworkUsersTableName = $dbprefix . 'users';
331 }
332 }
333
334 /**
335 * Initializes the entire application.
336 * Reads constants defined in civicrm.settings.php and
337 * stores them in config properties.
338 *
339 * @param bool $loadFromDB
340 */
341 private function _initialize($loadFromDB = TRUE) {
342
343 // following variables should be set in CiviCRM settings and
344 // as crucial ones, are defined upon initialisation
345 // instead of in CRM_Core_Config_Defaults
346 if (defined('CIVICRM_DSN')) {
347 $this->dsn = CIVICRM_DSN;
348 }
349 elseif ($loadFromDB) {
350 // bypass when calling from gencode
351 echo 'You need to define CIVICRM_DSN in civicrm.settings.php';
352 exit();
353 }
354
355 if (defined('CIVICRM_TEMPLATE_COMPILEDIR')) {
356 $this->templateCompileDir = CRM_Utils_File::addTrailingSlash(CIVICRM_TEMPLATE_COMPILEDIR);
357
358 // also make sure we create the config directory within this directory
359 // the below statement will create both the templates directory and the config and log directory
360 $this->configAndLogDir =
361 CRM_Utils_File::baseFilePath($this->templateCompileDir) .
362 'ConfigAndLog' . DIRECTORY_SEPARATOR;
363 CRM_Utils_File::createDir($this->configAndLogDir);
364 CRM_Utils_File::restrictAccess($this->configAndLogDir);
365
366 // we're automatically prefixing compiled templates directories with country/language code
367 global $tsLocale;
368 if (!empty($tsLocale)) {
369 $this->templateCompileDir .= CRM_Utils_File::addTrailingSlash($tsLocale);
370 }
371 elseif (!empty($this->lcMessages)) {
372 $this->templateCompileDir .= CRM_Utils_File::addTrailingSlash($this->lcMessages);
373 }
374
375 CRM_Utils_File::createDir($this->templateCompileDir);
376 CRM_Utils_File::restrictAccess($this->templateCompileDir);
377 }
378 elseif ($loadFromDB) {
379 echo 'You need to define CIVICRM_TEMPLATE_COMPILEDIR in civicrm.settings.php';
380 exit();
381 }
382
383 $this->_initDAO();
384
385 if (defined('CIVICRM_UF')) {
386 $this->userFramework = CIVICRM_UF;
387 $this->_setUserFrameworkConfig($this->userFramework);
388 }
389 else {
390 echo 'You need to define CIVICRM_UF in civicrm.settings.php';
391 exit();
392 }
393
394 // also initialize the logger
395 self::$_log = Log::singleton('display');
396
397 // initialize component registry early to avoid "race"
398 // between CRM_Core_Config and CRM_Core_Component (they
399 // are co-dependant)
400 $this->componentRegistry = new CRM_Core_Component();
401 }
402
403 /**
404 * initialize the DataObject framework
405 *
406 * @return void
407 * @access private
408 */
409 private function _initDAO() {
410 CRM_Core_DAO::init($this->dsn);
411
412 $factoryClass = $this->DAOFactoryClass;
413 require_once str_replace('_', DIRECTORY_SEPARATOR, $factoryClass) . '.php';
414 CRM_Core_DAO::setFactory(new $factoryClass());
415 if (CRM_Utils_Constant::value('CIVICRM_MYSQL_STRICT', CRM_Utils_System::isDevelopment())) {
416 CRM_Core_DAO::executeQuery('SET SESSION sql_mode = STRICT_TRANS_TABLES');
417 }
418 }
419
420 /**
421 * returns the singleton logger for the application
422 *
423 * @param
424 * @access private
425 *
426 * @return object
427 */
428 static public function &getLog() {
429 if (!isset(self::$_log)) {
430 self::$_log = Log::singleton('display');
431 }
432
433 return self::$_log;
434 }
435
436 /**
437 * initialize the config variables
438 *
439 * @return void
440 * @access private
441 */
442 private function _initVariables() {
443 // retrieve serialised settings
444 $variables = array();
445 CRM_Core_BAO_ConfigSetting::retrieve($variables);
446
447 // if settings are not available, go down the full path
448 if (empty($variables)) {
449 // Step 1. get system variables with their hardcoded defaults
450 $variables = get_object_vars($this);
451
452 // Step 2. get default values (with settings file overrides if
453 // available - handled in CRM_Core_Config_Defaults)
454 CRM_Core_Config_Defaults::setValues($variables);
455
456 // retrieve directory and url preferences also
457 CRM_Core_BAO_Setting::retrieveDirectoryAndURLPreferences($variables);
458
459 // add component specific settings
460 $this->componentRegistry->addConfig($this);
461
462 // serialise settings
463 $settings = $variables;
464 CRM_Core_BAO_ConfigSetting::add($settings);
465 }
466
467 $urlArray = array('userFrameworkResourceURL', 'imageUploadURL');
468 $dirArray = array('uploadDir', 'customFileUploadDir');
469
470 foreach ($variables as $key => $value) {
471 if (in_array($key, $urlArray)) {
472 $value = CRM_Utils_File::addTrailingSlash($value, '/');
473 }
474 elseif (in_array($key, $dirArray)) {
475 if ($value) {
476 $value = CRM_Utils_File::addTrailingSlash($value);
477 }
478 if (empty($value) || (CRM_Utils_File::createDir($value, FALSE) === FALSE)) {
479 // seems like we could not create the directories
480 // settings might have changed, lets suppress a message for now
481 // so we can make some more progress and let the user fix their settings
482 // for now we assign it to a know value
483 // CRM-4949
484 $value = $this->templateCompileDir;
485 $url = CRM_Utils_System::url('civicrm/admin/setting/path', 'reset=1');
486 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(
487 1 => $key,
488 2 => $url
489 )), ts('Check Settings'), 'alert');
490 }
491 }
492 elseif ($key == 'lcMessages') {
493 // reset the templateCompileDir to locale-specific and make sure it exists
494 if (substr($this->templateCompileDir, -1 * strlen($value) - 1, -1) != $value) {
495 $this->templateCompileDir .= CRM_Utils_File::addTrailingSlash($value);
496 CRM_Utils_File::createDir($this->templateCompileDir);
497 CRM_Utils_File::restrictAccess($this->templateCompileDir);
498 }
499 }
500
501 $this->$key = $value;
502 }
503
504 if ($this->userFrameworkResourceURL) {
505 // we need to do this here so all blocks also load from an ssl server
506 if (CRM_Utils_System::isSSL()) {
507 CRM_Utils_System::mapConfigToSSL();
508 }
509 $rrb = parse_url($this->userFrameworkResourceURL);
510 // don't use absolute path if resources are stored on a different server
511 // CRM-4642
512 $this->resourceBase = $this->userFrameworkResourceURL;
513 if (isset($_SERVER['HTTP_HOST']) &&
514 isset($rrb['host'])
515 ) {
516 $this->resourceBase = ($rrb['host'] == $_SERVER['HTTP_HOST']) ? $rrb['path'] : $this->userFrameworkResourceURL;
517 }
518 }
519
520 if (!$this->customFileUploadDir) {
521 $this->customFileUploadDir = $this->uploadDir;
522 }
523
524 if ($this->geoProvider) {
525 $this->geocodeMethod = 'CRM_Utils_Geocode_' . $this->geoProvider;
526 }
527 elseif ($this->mapProvider) {
528 $this->geocodeMethod = 'CRM_Utils_Geocode_' . $this->mapProvider;
529 }
530
531 require_once (str_replace('_', DIRECTORY_SEPARATOR, $this->userFrameworkClass) . '.php');
532 $class = $this->userFrameworkClass;
533 // redundant with _setUserFrameworkConfig
534 $this->userSystem = new $class();
535 }
536
537 /**
538 * Retrieve a mailer to send any mail from the application
539 *
540 * @param boolean $persist open a persistent smtp connection, should speed up mailings
541 * @access private
542 * @return object
543 */
544 static function &getMailer($persist = FALSE) {
545 if (!isset(self::$_mail)) {
546 $mailingInfo = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
547 'mailing_backend'
548 );
549
550 if ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_REDIRECT_TO_DB ||
551 (defined('CIVICRM_MAILER_SPOOL') && CIVICRM_MAILER_SPOOL)
552 ) {
553 self::$_mail = self::_createMailer('CRM_Mailing_BAO_Spool', array());
554 }
555 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_SMTP) {
556 if ($mailingInfo['smtpServer'] == '' || !$mailingInfo['smtpServer']) {
557 CRM_Core_Error::debug_log_message(ts('There is no valid smtp server setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the SMTP Server.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
558 CRM_Core_Error::fatal(ts('There is no valid smtp server setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the SMTP Server.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
559 }
560
561 $params['host'] = $mailingInfo['smtpServer'] ? $mailingInfo['smtpServer'] : 'localhost';
562 $params['port'] = $mailingInfo['smtpPort'] ? $mailingInfo['smtpPort'] : 25;
563
564 if ($mailingInfo['smtpAuth']) {
565 $params['username'] = $mailingInfo['smtpUsername'];
566 $params['password'] = CRM_Utils_Crypt::decrypt($mailingInfo['smtpPassword']);
567 $params['auth'] = TRUE;
568 }
569 else {
570 $params['auth'] = FALSE;
571 }
572
573 // set the localhost value, CRM-3153
574 $params['localhost'] = CRM_Utils_Array::value('SERVER_NAME', $_SERVER, 'localhost');
575
576 // also set the timeout value, lets set it to 30 seconds
577 // CRM-7510
578 $params['timeout'] = 30;
579
580 // CRM-9349
581 $params['persist'] = $persist;
582
583 self::$_mail = self::_createMailer('smtp', $params);
584 }
585 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_SENDMAIL) {
586 if ($mailingInfo['sendmail_path'] == '' ||
587 !$mailingInfo['sendmail_path']
588 ) {
589 CRM_Core_Error::debug_log_message(ts('There is no valid sendmail path setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the sendmail server.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
590 CRM_Core_Error::fatal(ts('There is no valid sendmail path setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the sendmail server.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
591 }
592 $params['sendmail_path'] = $mailingInfo['sendmail_path'];
593 $params['sendmail_args'] = $mailingInfo['sendmail_args'];
594
595 self::$_mail = self::_createMailer('sendmail', $params);
596 }
597 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_MAIL) {
598 self::$_mail = self::_createMailer('mail', array());
599 }
600 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_MOCK) {
601 self::$_mail = self::_createMailer('mock', array());
602 }
603 elseif ($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_DISABLED) {
604 CRM_Core_Error::debug_log_message(ts('Outbound mail has been disabled. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the OutBound Email.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
605 CRM_Core_Session::setStatus(ts('Outbound mail has been disabled. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the OutBound Email.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
606 }
607 else {
608 CRM_Core_Error::debug_log_message(ts('There is no valid SMTP server Setting Or SendMail path setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the OutBound Email.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
609 CRM_Core_Session::setStatus(ts('There is no valid SMTP server Setting Or sendMail path setting. Click <a href=\'%1\'>Administer >> System Setting >> Outbound Email</a> to set the OutBound Email.', array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))));
610 CRM_Core_Error::debug_var('mailing_info', $mailingInfo);
611 }
612 }
613 return self::$_mail;
614 }
615
616 /**
617 * Create a new instance of a PEAR Mail driver
618 *
619 * @param string $driver 'CRM_Mailing_BAO_Spool' or a name suitable for Mail::factory()
620 * @param array $params
621 * @return Mail (More specifically, a class which implements the "send()" function)
622 */
623 public static function _createMailer($driver, $params) {
624 if ($driver == 'CRM_Mailing_BAO_Spool') {
625 $mailer = new CRM_Mailing_BAO_Spool($params);
626 }
627 else {
628 $mailer = Mail::factory($driver, $params);
629 }
630 CRM_Utils_Hook::alterMail($mailer, $driver, $params);
631 return $mailer;
632 }
633
634 /**
635 * Deletes the web server writable directories
636 *
637 * @param int $value
638 * 1: clean templates_c, 2: clean upload, 3: clean both
639 * @param bool $rmdir
640 */
641 public function cleanup($value, $rmdir = TRUE) {
642 $value = (int ) $value;
643
644 if ($value & 1) {
645 // clean templates_c
646 CRM_Utils_File::cleanDir($this->templateCompileDir, $rmdir);
647 CRM_Utils_File::createDir($this->templateCompileDir);
648 }
649 if ($value & 2) {
650 // clean upload dir
651 CRM_Utils_File::cleanDir($this->uploadDir);
652 CRM_Utils_File::createDir($this->uploadDir);
653 }
654
655 // Whether we delete/create or simply preserve directories, we should
656 // certainly make sure the restrictions are enforced.
657 foreach (array($this->templateCompileDir, $this->uploadDir, $this->configAndLogDir, $this->customFileUploadDir) as $dir) {
658 if ($dir && is_dir($dir)) {
659 CRM_Utils_File::restrictAccess($dir);
660 }
661 }
662 }
663
664 /**
665 * verify that the needed parameters are not null in the config
666 *
667 * @param CRM_Core_Config (reference ) the system config object
668 * @param array (reference ) the parameters that need a value
669 *
670 * @return boolean
671 * @static
672 * @access public
673 */
674 static function check(&$config, &$required) {
675 foreach ($required as $name) {
676 if (CRM_Utils_System::isNull($config->$name)) {
677 return FALSE;
678 }
679 }
680 return TRUE;
681 }
682
683 /**
684 * reset the serialized array and recompute
685 * use with care
686 */
687 function reset() {
688 $query = "UPDATE civicrm_domain SET config_backend = null";
689 CRM_Core_DAO::executeQuery($query);
690 }
691
692 // This method should initialize auth sources
693 function initAuthSrc() {
694 $session = CRM_Core_Session::singleton();
695 if ($session->get('userID') && !$session->get('authSrc')) {
696 $session->set('authSrc', CRM_Core_Permission::AUTH_SRC_LOGIN);
697 }
698
699 // checksum source
700 CRM_Contact_BAO_Contact_Permission::initChecksumAuthSrc();
701 }
702
703 /**
704 * one function to get domain ID
705 */
706 static function domainID($domainID = NULL, $reset = FALSE) {
707 static $domain;
708 if ($domainID) {
709 $domain = $domainID;
710 }
711 if ($reset || empty($domain)) {
712 $domain = defined('CIVICRM_DOMAIN_ID') ? CIVICRM_DOMAIN_ID : 1;
713 }
714
715 return $domain;
716 }
717
718 /**
719 * do general cleanup of caches, temp directories and temp tables
720 * CRM-8739
721 */
722 function cleanupCaches($sessionReset = TRUE) {
723 // cleanup templates_c directory
724 $this->cleanup(1, FALSE);
725
726 // clear db caching
727 self::clearDBCache();
728
729 if ($sessionReset) {
730 $session = CRM_Core_Session::singleton();
731 $session->reset(2);
732 }
733 }
734
735 /**
736 * Do general cleanup of module permissions.
737 */
738 function cleanupPermissions() {
739 $module_files = CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles();
740 if ($this->userPermissionClass->isModulePermissionSupported()) {
741 // Can store permissions -- so do it!
742 $this->userPermissionClass->upgradePermissions(
743 CRM_Core_Permission::basicPermissions()
744 );
745 } else {
746 // Cannot store permissions -- warn if any modules require them
747 $modules_with_perms = array();
748 foreach ($module_files as $module_file) {
749 $perms = $this->userPermissionClass->getModulePermissions($module_file['prefix']);
750 if (!empty($perms)) {
751 $modules_with_perms[] = $module_file['prefix'];
752 }
753 }
754 if (!empty($modules_with_perms)) {
755 CRM_Core_Session::setStatus(
756 ts('Some modules define permissions, but the CMS cannot store them: %1', array(1 => implode(', ', $modules_with_perms))),
757 ts('Permission Error'),
758 'error'
759 );
760 }
761 }
762 }
763
764 /**
765 * Flush information about loaded modules
766 */
767 function clearModuleList() {
768 CRM_Extension_System::singleton()->getCache()->flush();
769 CRM_Utils_Hook::singleton(TRUE);
770 CRM_Core_PseudoConstant::getModuleExtensions(TRUE);
771 CRM_Core_Module::getAll(TRUE);
772 }
773
774 /**
775 * clear db cache
776 */
777 public static function clearDBCache() {
778 $queries = array(
779 'TRUNCATE TABLE civicrm_acl_cache',
780 'TRUNCATE TABLE civicrm_acl_contact_cache',
781 'TRUNCATE TABLE civicrm_cache',
782 'TRUNCATE TABLE civicrm_prevnext_cache',
783 'UPDATE civicrm_group SET cache_date = NULL',
784 'TRUNCATE TABLE civicrm_group_contact_cache',
785 'TRUNCATE TABLE civicrm_menu',
786 'UPDATE civicrm_setting SET value = NULL WHERE name="navigation" AND contact_id IS NOT NULL',
787 'DELETE FROM civicrm_setting WHERE name="modulePaths"', // CRM-10543
788 );
789
790 foreach ($queries as $query) {
791 CRM_Core_DAO::executeQuery($query);
792 }
793
794 // also delete all the import and export temp tables
795 self::clearTempTables();
796 }
797
798 /**
799 * clear leftover temporary tables
800 */
801 public static function clearTempTables() {
802 // CRM-5645
803 $dao = CRM_Core_DAO::executeQuery("SELECT DATABASE();");
804 $query = "
805 SELECT TABLE_NAME as tableName
806 FROM INFORMATION_SCHEMA.TABLES
807 WHERE TABLE_SCHEMA = %1
808 AND
809 ( TABLE_NAME LIKE 'civicrm_import_job_%'
810 OR TABLE_NAME LIKE 'civicrm_export_temp%'
811 OR TABLE_NAME LIKE 'civicrm_task_action_temp%'
812 OR TABLE_NAME LIKE 'civicrm_report_temp%'
813 )
814 ";
815
816 $params = array(1 => array($dao->database(), 'String'));
817 $tableDAO = CRM_Core_DAO::executeQuery($query, $params);
818 $tables = array();
819 while ($tableDAO->fetch()) {
820 $tables[] = $tableDAO->tableName;
821 }
822 if (!empty($tables)) {
823 $table = implode(',', $tables);
824 // drop leftover temporary tables
825 CRM_Core_DAO::executeQuery("DROP TABLE $table");
826 }
827 }
828
829 /**
830 * function to check if running in upgrade mode
831 */
832 static function isUpgradeMode($path = NULL) {
833 if (defined('CIVICRM_UPGRADE_ACTIVE')) {
834 return TRUE;
835 }
836
837 if (!$path) {
838 // note: do not re-initialize config here, since this function is part of
839 // config initialization itself
840 $urlVar = 'q';
841 if (defined('CIVICRM_UF') && CIVICRM_UF == 'Joomla') {
842 $urlVar = 'task';
843 }
844
845 $path = CRM_Utils_Array::value($urlVar, $_GET);
846 }
847
848 if ($path && preg_match('/^civicrm\/upgrade(\/.*)?$/', $path)) {
849 return TRUE;
850 }
851
852 return FALSE;
853 }
854
855 /**
856 * Wrapper function to allow unit tests to switch user framework on the fly
857 */
858 public function setUserFramework($userFramework = NULL) {
859 $this->userFramework = $userFramework;
860 $this->_setUserFrameworkConfig($userFramework);
861 }
862
863 /**
864 * Is back office credit card processing enabled for this site - ie are there any installed processors that support
865 * on-site processing
866 * @return bool
867 */
868 static function isEnabledBackOfficeCreditCardPayments() {
869 // restrict to type=1 (credit card) payment processor payment_types and only include billing mode types 1 and 3
870 $processors = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE,
871 "billing_mode IN ( 1, 3 ) AND payment_type = 1"
872 );
873 if (count($processors) > 0) {
874 return TRUE;
875 }
876 return FALSE;
877 }
878 }
879 // end CRM_Core_Config
880