Merge pull request #7893 from eileenmcnaughton/CRM-18128
[civicrm-core.git] / CRM / Utils / System.php
index 74a1f8e09239a70f432db966d550ca8c62a07f8e..057545cb89040ad7052d928f1f6f6a225a43f49a 100644 (file)
@@ -250,10 +250,12 @@ class CRM_Utils_System {
    *   outside the site, such as in an RSS feed.
    * @param string $fragment
    *   A fragment identifier (named anchor) to append to the link.
-   *
    * @param bool $htmlize
+   *   Whether to encode special html characters such as &.
    * @param bool $frontend
+   *   This link should be to the CMS front end (applies to WP & Joomla).
    * @param bool $forceBackend
+   *   This link should be to the CMS back end (applies to WP & Joomla).
    *
    * @return string
    *   An HTML string containing a link to the given path.
@@ -269,13 +271,33 @@ class CRM_Utils_System {
   ) {
     $query = self::makeQueryString($query);
 
-    // we have a valid query and it has not yet been transformed
-    if ($htmlize && !empty($query) && strpos($query, '&') === FALSE) {
-      $query = htmlentities($query);
+    // Legacy handling for when the system passes around html escaped strings
+    if (strstr($query, '&')) {
+      $query = html_entity_decode($query);
+    }
+
+    // Extract fragment from path or query if munged together
+    if ($query && strstr($query, '#')) {
+      list($path, $fragment) = explode('#', $query);
+    }
+    if ($path && strstr($path, '#')) {
+      list($path, $fragment) = explode('#', $path);
+    }
+
+    // Extract query from path if munged together
+    if ($path && strstr($path, '?')) {
+      list($path, $extraQuery) = explode('?', $path);
+      $query = $extraQuery . ($query ? "&$query" : '');
     }
 
     $config = CRM_Core_Config::singleton();
-    return $config->userSystem->url($path, $query, $absolute, $fragment, $htmlize, $frontend, $forceBackend);
+    $url = $config->userSystem->url($path, $query, $absolute, $fragment, $frontend, $forceBackend);
+
+    if ($htmlize) {
+      $url = htmlentities($url);
+    }
+
+    return $url;
   }
 
   /**