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