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