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