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