CRM-17323 - Store site id in settings
[civicrm-core.git] / CRM / Utils / System.php
index 0bc5170e5902ddbe50a27f2cc7a9ea61619d7460..e78b144882fb2bdc785101965a297c19c0294bed 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
@@ -106,8 +106,8 @@ class CRM_Utils_System {
   public static function getLinksUrl($urlVar, $includeReset = FALSE, $includeForce = TRUE, $skipUFVar = TRUE) {
     // Sort out query string to prevent messy urls
     $querystring = array();
-    $qs          = array();
-    $arrays      = array();
+    $qs = array();
+    $arrays = array();
 
     if (!empty($_SERVER['QUERY_STRING'])) {
       $qs = explode('&', str_replace('&', '&', $_SERVER['QUERY_STRING']));
@@ -182,9 +182,8 @@ class CRM_Utils_System {
    *   (optional) For maintenance mode.
    *
    * @return string
-   *
    */
-  static function theme(
+  public static function theme(
     &$content,
     $print = FALSE,
     $maintenance = FALSE
@@ -230,7 +229,7 @@ class CRM_Utils_System {
    * @return string
    *   An HTML string containing a link to the given path.
    */
-  static function url(
+  public static function url(
     $path = NULL,
     $query = NULL,
     $absolute = FALSE,
@@ -262,7 +261,7 @@ class CRM_Utils_System {
    *
    * @return string
    */
-  static function href(
+  public static function href(
     $text, $path = NULL, $query = NULL, $absolute = TRUE,
     $fragment = NULL, $htmlize = TRUE, $frontend = FALSE, $forceBackend = FALSE
   ) {
@@ -286,7 +285,9 @@ class CRM_Utils_System {
     return $config->userSystem->logout();
   }
 
-  // this is a very drupal specific function for now
+  /**
+   * this is a very drupal specific function for now.
+   */
   public static function updateCategories() {
     $config = CRM_Core_Config::singleton();
     if ($config->userSystem->is_drupal) {
@@ -297,7 +298,8 @@ class CRM_Utils_System {
   /**
    * What menu path are we currently on. Called for the primary tpl
    *
-   * @return string the current menu path
+   * @return string
+   *   the current menu path
    */
   public static function currentPath() {
     $config = CRM_Core_Config::singleton();
@@ -305,12 +307,13 @@ class CRM_Utils_System {
   }
 
   /**
-   * This function is called from a template to compose a url.
+   * called from a template to compose a url.
    *
    * @param array $params
    *   List of parameters.
    *
-   * @return string url
+   * @return string
+   *   url
    */
   public static function crmURL($params) {
     $p = CRM_Utils_Array::value('p', $params);
@@ -334,7 +337,6 @@ class CRM_Utils_System {
    *
    * @param string $title
    * @param string $pageTitle
-   *
    */
   public static function setTitle($title, $pageTitle = NULL) {
     self::$title = $title;
@@ -351,7 +353,6 @@ class CRM_Utils_System {
    *   Refererer should match any str in this array.
    * @param string $default
    *   (optional) The default userContext if no match found.
-   *
    */
   public static function setUserContext($names, $default = NULL) {
     $url = $default;
@@ -381,7 +382,6 @@ class CRM_Utils_System {
    *
    * @return string
    *   The class name of the object.
-   *
    */
   public static function getClassName($object) {
     return get_class($object);
@@ -392,7 +392,6 @@ class CRM_Utils_System {
    *
    * @param string $url
    *   The URL to provide to the browser via the Location header.
-   *
    */
   public static function redirect($url = NULL) {
     if (!$url) {
@@ -427,9 +426,8 @@ class CRM_Utils_System {
    *   (optional) The page title to use for the redirect page.
    * @param string $message
    *   (optional) The message to provide in the body of the redirect page.
-   *
    */
-  static function jsRedirect(
+  public static function jsRedirect(
     $url = NULL,
     $title = NULL,
     $message = NULL
@@ -466,7 +464,6 @@ class CRM_Utils_System {
    * Append an additional breadcrumb tag to the existing breadcrumbs.
    *
    * @param $breadCrumbs
-   *
    */
   public static function appendBreadCrumb($breadCrumbs) {
     $config = CRM_Core_Config::singleton();
@@ -475,7 +472,6 @@ class CRM_Utils_System {
 
   /**
    * Reset an additional breadcrumb tag to the existing breadcrumb.
-   *
    */
   public static function resetBreadCrumb() {
     $config = CRM_Core_Config::singleton();
@@ -486,7 +482,6 @@ class CRM_Utils_System {
    * Append a string to the head of the HTML file.
    *
    * @param string $bc
-   *
    */
   public static function addHTMLHead($bc) {
     $config = CRM_Core_Config::singleton();
@@ -494,7 +489,7 @@ class CRM_Utils_System {
   }
 
   /**
-   * Determine the post URL for a form
+   * Determine the post URL for a form.
    *
    * @param $action
    *   The default action if one is pre-specified.
@@ -509,14 +504,13 @@ class CRM_Utils_System {
 
   /**
    * Rewrite various system URLs to https.
-   *
    */
   public static function mapConfigToSSL() {
     $config = CRM_Core_Config::singleton();
     $config->userFrameworkResourceURL = str_replace('http://', 'https://', $config->userFrameworkResourceURL);
     $config->resourceBase = $config->userFrameworkResourceURL;
 
-    if (! empty($config->extensionsURL)) {
+    if (!empty($config->extensionsURL)) {
       $config->extensionsURL = str_replace('http://', 'https://', $config->extensionsURL);
     }
 
@@ -668,11 +662,17 @@ class CRM_Utils_System {
      * We typically call authenticate only when we need to bootstrap the CMS
      * directly via Civi and hence bypass the normal CMS auth and bootstrap
      * process typically done in CLI and cron scripts. See: CRM-12648
+     *
+     * Q: Can we move this to the userSystem class so that it can be tuned
+     * per-CMS? For example, when dealing with UnitTests UF, there's no
+     * userFrameworkDSN.
      */
     $session = CRM_Core_Session::singleton();
     $session->set('civicrmInitSession', TRUE);
 
-    $dbDrupal = DB::connect($config->userFrameworkDSN);
+    if ($config->userFrameworkDSN) {
+      $dbDrupal = DB::connect($config->userFrameworkDSN);
+    }
     return $config->userSystem->authenticate($name, $password, $loadCMSBootstrap, $realPath);
   }
 
@@ -681,7 +681,6 @@ class CRM_Utils_System {
    *
    * @param string $message
    *   The message to set.
-   *
    */
   public static function setUFMessage($message) {
     $config = CRM_Core_Config::singleton();
@@ -743,17 +742,17 @@ class CRM_Utils_System {
     $s = ob_get_contents();
     ob_end_clean();
 
-    $s        = strip_tags($s, '<h2><th><td>');
-    $s        = preg_replace('/<th[^>]*>([^<]+)<\/th>/', "<info>\\1</info>", $s);
-    $s        = preg_replace('/<td[^>]*>([^<]+)<\/td>/', "<info>\\1</info>", $s);
-    $vTmp     = preg_split('/(<h2>[^<]+<\/h2>)/', $s, -1, PREG_SPLIT_DELIM_CAPTURE);
+    $s = strip_tags($s, '<h2><th><td>');
+    $s = preg_replace('/<th[^>]*>([^<]+)<\/th>/', "<info>\\1</info>", $s);
+    $s = preg_replace('/<td[^>]*>([^<]+)<\/td>/', "<info>\\1</info>", $s);
+    $vTmp = preg_split('/(<h2>[^<]+<\/h2>)/', $s, -1, PREG_SPLIT_DELIM_CAPTURE);
     $vModules = array();
     for ($i = 1; $i < count($vTmp); $i++) {
       if (preg_match('/<h2>([^<]+)<\/h2>/', $vTmp[$i], $vMat)) {
         $vName = trim($vMat[1]);
         $vTmp2 = explode("\n", $vTmp[$i + 1]);
         foreach ($vTmp2 as $vOne) {
-          $vPat  = '<info>([^<]+)<\/info>';
+          $vPat = '<info>([^<]+)<\/info>';
           $vPat3 = "/$vPat\s*$vPat\s*$vPat/";
           $vPat2 = "/$vPat\s*$vPat/";
           // 3cols
@@ -806,7 +805,7 @@ class CRM_Utils_System {
    * @param bool $output
    * @param string $disposition
    */
-  static function download(
+  public static function download(
     $name, $mimeType, &$buffer,
     $ext = NULL,
     $output = TRUE,
@@ -990,8 +989,8 @@ class CRM_Utils_System {
 
     if ($abort) {
       CRM_Core_Error::fatal(ts('This feature requires PHP Version %1 or greater',
-          array(1 => $ver)
-        ));
+        array(1 => $ver)
+      ));
     }
     return FALSE;
   }
@@ -1077,8 +1076,8 @@ class CRM_Utils_System {
           array(dirname(__FILE__), '..', '..', 'xml', 'version.xml')
         );
         if (file_exists($verFile)) {
-          $str     = file_get_contents($verFile);
-          $xmlObj  = simplexml_load_string($str);
+          $str = file_get_contents($verFile);
+          $xmlObj = simplexml_load_string($str);
           $version = (string) $xmlObj->version_no;
         }
       }
@@ -1119,10 +1118,10 @@ class CRM_Utils_System {
         $headers[str_replace(' ',
           '-',
           ucwords(strtolower(str_replace('_',
-                ' ',
-                substr($name, 5)
-              )
-            ))
+              ' ',
+              substr($name, 5)
+            )
+          ))
         )] = $value;
       }
     }
@@ -1158,6 +1157,7 @@ class CRM_Utils_System {
   public static function redirectToSSL($abort = FALSE) {
     $config = CRM_Core_Config::singleton();
     $req_headers = self::getRequestHeaders();
+    // FIXME: Shouldn't the X-Forwarded-Proto check be part of CRM_Utils_System::isSSL()?
     if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'enableSSL') &&
       !self::isSSL() &&
       strtolower(CRM_Utils_Array::value('X_FORWARDED_PROTO', $req_headers)) != 'https'
@@ -1179,7 +1179,7 @@ class CRM_Utils_System {
     }
   }
 
-  /*
+  /**
    * Get logged in user's IP address.
    *
    * Get IP address from HTTP REMOTE_ADDR header. If the CMS is Drupal then use
@@ -1192,11 +1192,6 @@ class CRM_Utils_System {
    * @return string
    *   IP address of logged in user.
    */
-  /**
-   * @param bool $strictIPV4
-   *
-   * @return mixed|string
-   */
   public static function ipAddress($strictIPV4 = TRUE) {
     $address = CRM_Utils_Array::value('REMOTE_ADDR', $_SERVER);
 
@@ -1248,7 +1243,8 @@ class CRM_Utils_System {
   /**
    * Returns wiki (alternate) documentation URL base.
    *
-   * @return string documentation url
+   * @return string
+   *   documentation url
    */
   public static function getWikiBaseURL() {
     // FIXME: move this to configuration at some stage
@@ -1311,13 +1307,13 @@ class CRM_Utils_System {
    * @param array $params
    *   An array of parameters (see CRM_Utils_System::docURL2 method for names)
    *
-   * @return string
+   * @return void|string
    *   URL or link to documentation page, based on provided parameters.
    */
   public static function docURL($params) {
 
     if (!isset($params['page'])) {
-      return;
+      return NULL;
     }
 
     if (CRM_Utils_Array::value('resource', $params) == 'wiki') {
@@ -1353,7 +1349,7 @@ class CRM_Utils_System {
   }
 
   /**
-   * Get the locale set in the hosting CMS
+   * Get the locale set in the hosting CMS.
    *
    * @return string
    *   The used locale or null for none.
@@ -1433,8 +1429,8 @@ class CRM_Utils_System {
       // if db.ver > code.ver, sth really wrong
       if (version_compare($dbVersion, $codeVersion) > 0) {
         $errorMessage = '<p>' . ts('Your database is marked with an unexpected version number: %1. The v%2 codebase may not be compatible with your database state. You will need to determine the correct version corresponding to your current database state. You may want to revert to the codebase you were using until you resolve this problem.',
-          array(1 => $dbVersion, 2 => $codeVersion)
-        ) . '</p>';
+            array(1 => $dbVersion, 2 => $codeVersion)
+          ) . '</p>';
         $errorMessage .= "<p>" . ts('OR if this is a manual install from git, you might want to fix civicrm-version.php file.') . "</p>";
         return FALSE;
       }
@@ -1475,15 +1471,12 @@ class CRM_Utils_System {
     CRM_ACL_BAO_Cache::resetCache();
 
     // reset various static arrays used here
-    CRM_Contact_BAO_Contact::$_importableFields =
-      CRM_Contact_BAO_Contact::$_exportableFields =
-      CRM_Contribute_BAO_Contribution::$_importableFields =
-      CRM_Contribute_BAO_Contribution::$_exportableFields =
-      CRM_Pledge_BAO_Pledge::$_exportableFields =
-      CRM_Contribute_BAO_Query::$_contributionFields =
-      CRM_Core_BAO_CustomField::$_importFields =
-      CRM_Core_BAO_Cache::$_cache =
-      CRM_Core_DAO::$_dbColumnValueCache = NULL;
+    CRM_Contact_BAO_Contact::$_importableFields = CRM_Contact_BAO_Contact::$_exportableFields
+      = CRM_Contribute_BAO_Contribution::$_importableFields
+        = CRM_Contribute_BAO_Contribution::$_exportableFields
+          = CRM_Pledge_BAO_Pledge::$_exportableFields = CRM_Contribute_BAO_Query::$_contributionFields
+            = CRM_Core_BAO_CustomField::$_importFields
+              = CRM_Core_BAO_Cache::$_cache = CRM_Core_DAO::$_dbColumnValueCache = NULL;
 
     CRM_Core_OptionGroup::flushAll();
     CRM_Utils_PseudoConstant::flushAll();
@@ -1548,7 +1541,8 @@ class CRM_Utils_System {
             DIRECTORY_SEPARATOR . 'sites' .
             DIRECTORY_SEPARATOR . 'all' .
             DIRECTORY_SEPARATOR . 'modules'
-          ) === FALSE) {
+          ) === FALSE
+        ) {
           $startPos = strpos($civicrm_root,
             DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR
           );
@@ -1626,7 +1620,8 @@ class CRM_Utils_System {
    *
    * @param string $url
    *
-   * @return string $url, clean url
+   * @return string
+   *   , clean url
    */
   public static function cleanUrl($url) {
     if (!$url) {
@@ -1648,9 +1643,10 @@ class CRM_Utils_System {
    * @param bool $addLanguagePart
    * @param bool $removeLanguagePart
    *
-   * @return string $url, formatted url.
+   * @return string
+   *   , formatted url.
    */
-  static function languageNegotiationURL(
+  public static function languageNegotiationURL(
     $url,
     $addLanguagePart = TRUE,
     $removeLanguagePart = FALSE
@@ -1672,7 +1668,7 @@ class CRM_Utils_System {
    *   (optional) Sent by contribution/event reg/profile pages which uses a id
    *   specific extra file name if present.
    */
-  static function appendTPLFile(
+  public static function appendTPLFile(
     $fileName,
     &$content,
     $overideFileName = NULL
@@ -1761,7 +1757,6 @@ class CRM_Utils_System {
   // getPluginList()
 
   /**
-   *
    */
   public static function executeScheduledJobs() {
     $facility = new CRM_Core_JobManager();
@@ -1783,8 +1778,8 @@ class CRM_Utils_System {
    * @return string|FALSE
    */
   public static function evalUrl($url) {
-    if ($url === FALSE) {
-      return FALSE;
+    if (!$url || strpos($url, '{') === FALSE) {
+      return $url;
     }
     else {
       $config = CRM_Core_Config::singleton();
@@ -1792,18 +1787,31 @@ class CRM_Utils_System {
         '{ver}' => CRM_Utils_System::version(),
         '{uf}' => $config->userFramework,
         '{php}' => phpversion(),
-        '{sid}' => md5('sid_' . (defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : '') . '_' . $config->userFrameworkBaseURL),
+        '{sid}' => self::getSiteID(),
         '{baseUrl}' => $config->userFrameworkBaseURL,
         '{lang}' => $config->lcMessages,
         '{co}' => $config->defaultContactCountry,
       );
-      foreach (array_keys($vars) as $k) {
-        $vars[$k] = urlencode($vars[$k]);
-      }
-      return strtr($url, $vars);
+      return strtr($url, array_map('urlencode', $vars));
     }
   }
 
+  /**
+   * Returns the unique identifier for this site, as used by community messages.
+   *
+   * SiteID will be generated if it is not already stored in the settings table.
+   *
+   * @return string
+   */
+  public static function getSiteID() {
+    $sid = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'site_id');
+    if (!$sid) {
+      $config = CRM_Core_Config::singleton();
+      $sid = md5('sid_' . (defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : '') . '_' . $config->userFrameworkBaseURL);
+      civicrm_api3('Setting', 'create', array('domain_id' => 'all', 'site_id' => $sid));
+    }
+    return $sid;
+  }
 
   /**
    * Determine whether this is a developmental system.
@@ -1834,21 +1842,22 @@ class CRM_Utils_System {
   }
 
   /**
-   * Determine the standard URL for viewing or editing the specified link
+   * Determine the standard URL for viewing or editing the specified link.
    *
    * This function delegates the decision-making to (a) the hook system and
    * (b) the BAO system.
    *
    * @param array $crudLinkSpec
    *   With keys:.
-   *  - action: int, CRM_Core_Action::UPDATE or CRM_Core_Action::VIEW [default: VIEW]
-   *  - entity_table: string, eg "civicrm_contact"
-   *  - entity_id: int
-   * @return array|NULL NULL if unavailable, or an array. array has keys:
-   *  - path: string
-   *  - query: array
-   *  - title: string
-   *  - url: string
+   *   - action: int, CRM_Core_Action::UPDATE or CRM_Core_Action::VIEW [default: VIEW]
+   *   - entity_table: string, eg "civicrm_contact"
+   *   - entity_id: int
+   * @return array|NULL
+   *   NULL if unavailable, or an array. array has keys:
+   *   - path: string
+   *   - query: array
+   *   - title: string
+   *   - url: string
    */
   public static function createDefaultCrudLink($crudLinkSpec) {
     $crudLinkSpec['action'] = CRM_Utils_Array::value('action', $crudLinkSpec, CRM_Core_Action::VIEW);
@@ -1883,4 +1892,5 @@ class CRM_Utils_System {
 
     return NULL;
   }
+
 }