diff --git a/CRM/Admin/Page/AJAX.php b/CRM/Admin/Page/AJAX.php index 24f4c25f58a7..5b1fdf4f684d 100644 --- a/CRM/Admin/Page/AJAX.php +++ b/CRM/Admin/Page/AJAX.php @@ -48,7 +48,7 @@ public static function getNavigationMenu() { $smarty = CRM_Core_Smarty::singleton(); $smarty->assign('includeEmail', civicrm_api3('setting', 'getvalue', array('name' => 'includeEmailInName', 'group' => 'Search Preferences'))); print $smarty->fetchWith('CRM/common/navigation.js.tpl', array( - 'navigation' => CRM_Core_BAO_Navigation::createNavigation($contactID), + 'navigation' => CRM_Core_BAO_Navigation::createNavigation(), )); } CRM_Utils_System::civiExit(); diff --git a/CRM/Core/BAO/Navigation.php b/CRM/Core/BAO/Navigation.php index c12dc4bcf244..abb6f1801e7d 100644 --- a/CRM/Core/BAO/Navigation.php +++ b/CRM/Core/BAO/Navigation.php @@ -493,22 +493,7 @@ public static function getMenuName(&$value, &$skipMenuItems) { $makeLink = FALSE; if (!empty($url)) { - // Skip processing fully-formed urls - if (substr($url, 0, 4) !== 'http' && $url[0] !== '/' && $url[0] !== '#') { - //CRM-7656 --make sure to separate out url path from url params, - //as we'r going to validate url path across cross-site scripting. - $parsedUrl = parse_url($url); - if (empty($parsedUrl['query'])) { - $parsedUrl['query'] = NULL; - } - if (empty($parsedUrl['fragment'])) { - $parsedUrl['fragment'] = NULL; - } - $url = CRM_Utils_System::url($parsedUrl['path'], $parsedUrl['query'], FALSE, $parsedUrl['fragment'], TRUE); - } - elseif (strpos($url, '&') === FALSE) { - $url = htmlspecialchars($url); - } + $url = self::makeFullyFormedUrl($url); $makeLink = TRUE; } @@ -581,15 +566,10 @@ public static function getMenuName(&$value, &$skipMenuItems) { /** * Create navigation for CiviCRM Admin Menu. * - * @param int $contactID - * Contact id. - * * @return string * returns navigation html */ - public static function createNavigation($contactID) { - $config = CRM_Core_Config::singleton(); - + public static function createNavigation() { $navigation = self::buildNavigation(); if ($navigation) { @@ -603,8 +583,7 @@ public static function createNavigation($contactID) { $homeIcon = ''; self::retrieve($homeParams, $homeNav); if ($homeNav) { - list($path, $q) = explode('?', $homeNav['url']); - $homeURL = CRM_Utils_System::url($path, $q); + $homeURL = self::makeFullyFormedUrl($homeNav['url']); $homeLabel = $homeNav['label']; // CRM-6804 (we need to special-case this as we don’t ts()-tag variables) if ($homeLabel == 'Home') { @@ -630,6 +609,44 @@ public static function createNavigation($contactID) { return $prepandString . $navigation; } + /** + * Turns relative URLs (like civicrm/foo/bar) into fully-formed + * ones (i.e. example.com/wp-admin?q=civicrm/dashboard). + * + * If the URL is already fully-formed, nothing will be done. + * + * @param string $url + * + * @return string + */ + private static function makeFullyFormedUrl($url) { + if (self::isNotFullyFormedUrl($url)) { + //CRM-7656 --make sure to separate out url path from url params, + //as we'r going to validate url path across cross-site scripting. + $path = parse_url($url, PHP_URL_PATH); + $q = parse_url($url, PHP_URL_QUERY); + $fragment = parse_url($url, PHP_URL_FRAGMENT); + return CRM_Utils_System::url($path, $q, FALSE, $fragment); + } + + if (strpos($url, '&') === FALSE) { + return htmlspecialchars($url); + } + + return $url; + } + + /** + * Checks if the given URL is not fully-formed + * + * @param string $url + * + * @return bool + */ + private static function isNotFullyFormedUrl($url) { + return substr($url, 0, 4) !== 'http' && $url[0] !== '/' && $url[0] !== '#'; + } + /** * Reset navigation for all contacts or a specified contact. *