diff --git a/administrator/components/com_actionlogs/helpers/actionlogs.php b/administrator/components/com_actionlogs/helpers/actionlogs.php index 7526b66638dda..b2e138fb073fd 100644 --- a/administrator/components/com_actionlogs/helpers/actionlogs.php +++ b/administrator/components/com_actionlogs/helpers/actionlogs.php @@ -205,7 +205,7 @@ public static function getHumanReadableLogMessage($log, $generateLinks = true) $messageData['type'] = Text::_($messageData['type']); } - $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? 1 : -1; + $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE; foreach ($messageData as $key => $value) { diff --git a/administrator/components/com_messages/models/message.php b/administrator/components/com_messages/models/message.php index 0a9a3ba884b67..c94c2ce0f2b88 100644 --- a/administrator/components/com_messages/models/message.php +++ b/administrator/components/com_messages/models/message.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Router\Route; + /** * Private Message model. * @@ -359,10 +361,10 @@ public function save($data) // Build the email subject and message $app = JFactory::getApplication(); - $linkMode = $app->get('force_ssl', 0) >= 1 ? 1 : -1; + $linkMode = $app->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE; $sitename = $app->get('sitename'); $fromName = $fromUser->get('name'); - $siteURL = JRoute::link('administrator', 'index.php?option=com_messages&view=message&message_id=' . $table->message_id, false, $linkMode); + $siteURL = JRoute::link('administrator', 'index.php?option=com_messages&view=message&message_id=' . $table->message_id, false, $linkMode, true); $subject = html_entity_decode($table->subject, ENT_COMPAT, 'UTF-8'); $message = strip_tags(html_entity_decode($table->message, ENT_COMPAT, 'UTF-8')); diff --git a/administrator/components/com_privacy/models/dashboard.php b/administrator/components/com_privacy/models/dashboard.php index c16b8415eaaeb..533e6562aa1bd 100644 --- a/administrator/components/com_privacy/models/dashboard.php +++ b/administrator/components/com_privacy/models/dashboard.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Router\Route; + /** * Dashboard model class. * @@ -117,7 +119,7 @@ public function getRequestFormPublished() } } - $linkMode = JFactory::getApplication()->get('force_ssl', 0) == 2 ? 1 : -1; + $linkMode = JFactory::getApplication()->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; if (!$menuItem) { diff --git a/administrator/components/com_privacy/models/request.php b/administrator/components/com_privacy/models/request.php index 12cb04702532f..bf3eead939c3e 100644 --- a/administrator/components/com_privacy/models/request.php +++ b/administrator/components/com_privacy/models/request.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Router\Route; + /** * Request item model class. * @@ -311,13 +313,13 @@ public function notifyUserAdminCreatedRequest($id) { $app = JFactory::getApplication(); - $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; $substitutions = array( '[SITENAME]' => $app->get('sitename'), '[URL]' => JUri::root(), - '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode), - '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true), '[TOKEN]' => $token, '\\n' => "\n", ); diff --git a/components/com_privacy/models/request.php b/components/com_privacy/models/request.php index 58736c47035b6..056852de5d451 100644 --- a/components/com_privacy/models/request.php +++ b/components/com_privacy/models/request.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Router\Route; + /** * Request model class. * @@ -125,13 +127,13 @@ public function createRequest($data) { $app = JFactory::getApplication(); - $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; $substitutions = array( '[SITENAME]' => $app->get('sitename'), '[URL]' => JUri::root(), - '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode), - '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true), '[TOKEN]' => $token, '\\n' => "\n", ); diff --git a/components/com_users/models/registration.php b/components/com_users/models/registration.php index 525b5a917ee9d..e308b957931a7 100644 --- a/components/com_users/models/registration.php +++ b/components/com_users/models/registration.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Router\Route; + /** * Registration model class for Users. * @@ -108,14 +110,20 @@ public function activate($token) // Admin activation is on and user is verifying their email if (($userParams->get('useractivation') == 2) && !$user->getParam('activate', 0)) { - $linkMode = $config->get('force_ssl', 0) == 2 ? 1 : -1; + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; // Compile the admin notification mail values. $data = $user->getProperties(); $data['activation'] = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); $user->set('activation', $data['activation']); $data['siteurl'] = JUri::base(); - $data['activate'] = JRoute::link('site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode); + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); $data['fromname'] = $config->get('fromname'); $data['mailfrom'] = $config->get('mailfrom'); @@ -471,9 +479,15 @@ public function register($temp) if ($useractivation == 2) { // Set the link to confirm the user email. - $linkMode = $config->get('force_ssl', 0) == 2 ? 1 : -1; - - $data['activate'] = JRoute::link('site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode); + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); $emailSubject = JText::sprintf( 'COM_USERS_EMAIL_ACCOUNT_DETAILS', @@ -508,9 +522,15 @@ public function register($temp) elseif ($useractivation == 1) { // Set the link to activate the user account. - $linkMode = $config->get('force_ssl', 0) == 2 ? 1 : -1; - - $data['activate'] = JRoute::link('site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode); + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); $emailSubject = JText::sprintf( 'COM_USERS_EMAIL_ACCOUNT_DETAILS', diff --git a/libraries/src/Router/Route.php b/libraries/src/Router/Route.php index 5f2b65e675859..869e5519ae6d8 100644 --- a/libraries/src/Router/Route.php +++ b/libraries/src/Router/Route.php @@ -20,6 +20,27 @@ */ class Route { + /** + * No change, use the protocol currently used. + * + * @since __DEPLOY_VERSION__ + */ + const TLS_IGNORE = 0; + + /** + * Make URI secure using http over TLS (https). + * + * @since __DEPLOY_VERSION__ + */ + const TLS_FORCE = 1; + + /** + * Make URI unsecure using plain http (http). + * + * @since __DEPLOY_VERSION__ + */ + const TLS_DISABLE = 2; + /** * The route object so we don't have to keep fetching it. * @@ -31,29 +52,36 @@ class Route /** * Translates an internal Joomla URL to a humanly readable URL. This method builds links for the current active client. * - * @param string $url Absolute or Relative URI to Joomla resource. - * @param boolean $xhtml Replace & by & for XML compliance. - * @param integer $ssl Secure state for the resolved URI. - * 0: (default) No change, use the protocol currently used in the request - * 1: Make URI secure using global secure site URI. - * 2: Make URI unsecure using the global unsecure site URI. + * @param string $url Absolute or Relative URI to Joomla resource. + * @param boolean $xhtml Replace & by & for XML compliance. + * @param integer $tls Secure state for the resolved URI. Use Route::TLS_* constants + * 0: (default) No change, use the protocol currently used in the request + * 1: Make URI secure using global secure site URI. + * 2: Make URI unsecure using the global unsecure site URI. + * @param boolean $absolute Return an absolute URL * * @return string The translated humanly readable URL. * * @since 1.7.0 */ - public static function _($url, $xhtml = true, $ssl = null) + public static function _($url, $xhtml = true, $tls = self::TLS_IGNORE, $absolute = false) { try { + // @todo Deprecate in 4.0 Before __DEPLOY_VERSION__ this method accepted -1. + if ($tls == -1) + { + $tls = self::TLS_DISABLE; + } + $app = Factory::getApplication(); $client = $app->getName(); - return static::link($client, $url, $xhtml, $ssl); + return static::link($client, $url, $xhtml, $tls, $absolute); } catch (\RuntimeException $e) { - // Before 3.9.0 this method failed silently on router error. This B/C will be removed in Joomla 4.0. + // @deprecated 4.0 Before 3.9.0 this method failed silently on router error. This B/C will be removed in Joomla 4.0. return null; } } @@ -62,13 +90,14 @@ public static function _($url, $xhtml = true, $ssl = null) * Translates an internal Joomla URL to a humanly readable URL. * NOTE: To build link for active client instead of a specific client, you can use JRoute::_() * - * @param string $client The client name for which to build the link. - * @param string $url Absolute or Relative URI to Joomla resource. - * @param boolean $xhtml Replace & by & for XML compliance. - * @param integer $ssl Secure state for the resolved URI. - * 0: (default) No change, use the protocol currently used in the request - * 1: Make URI secure using global secure site URI. - * 2: Make URI unsecure using the global unsecure site URI. + * @param string $client The client name for which to build the link. + * @param string $url Absolute or Relative URI to Joomla resource. + * @param boolean $xhtml Replace & by & for XML compliance. + * @param integer $tls Secure state for the resolved URI. Use Route::TLS_* constants + * 0: (default) No change, use the protocol currently used in the request + * 1: Make URI secure using global secure site URI. + * 2: Make URI unsecure using the global unsecure site URI. + * @param boolean $absolute Return an absolute URL * * @return string The translated humanly readable URL. * @@ -76,7 +105,7 @@ public static function _($url, $xhtml = true, $ssl = null) * * @since 3.9.0 */ - public static function link($client, $url, $xhtml = true, $ssl = null) + public static function link($client, $url, $xhtml = true, $tls = self::TLS_IGNORE, $absolute = false) { // If we cannot process this $url exit early. if (!is_array($url) && (strpos($url, '&') !== 0) && (strpos($url, 'index.php') !== 0)) @@ -109,20 +138,34 @@ public static function link($client, $url, $xhtml = true, $ssl = null) * https and need to set our secure URL to the current request URL, if not, and the scheme is * 'http', then we need to do a quick string manipulation to switch schemes. */ - if ((int) $ssl || $uri->isSsl()) + if ($tls === self::TLS_FORCE) + { + $uri->setScheme('https'); + } + elseif ($tls === self::TLS_DISABLE) + { + $uri->setScheme('http'); + } + + // Set scheme if requested or + if ($absolute || $tls > 0) { - static $host_port; + static $scheme_host_port; + + if (!is_array($scheme_host_port)) + { + $uri2 = Uri::getInstance(); + $scheme_host_port = array($uri2->getScheme(), $uri2->getHost(), $uri2->getPort()); + } - if (!is_array($host_port)) + if (is_null($uri->getScheme())) { - $uri2 = Uri::getInstance(); - $host_port = array($uri2->getHost(), $uri2->getPort()); + $uri->setScheme($scheme_host_port[0]); } - // Determine which scheme we want. - $uri->setScheme(((int) $ssl === 1 || $uri->isSsl()) ? 'https' : 'http'); - $uri->setHost($host_port[0]); - $uri->setPort($host_port[1]); + $uri->setHost($scheme_host_port[1]); + $uri->setPort($scheme_host_port[2]); + $scheme = array_merge($scheme, array('host', 'port', 'scheme')); } diff --git a/plugins/system/privacyconsent/privacyconsent.php b/plugins/system/privacyconsent/privacyconsent.php index a98b6781c696d..9c8f91d925ec0 100644 --- a/plugins/system/privacyconsent/privacyconsent.php +++ b/plugins/system/privacyconsent/privacyconsent.php @@ -11,6 +11,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; use Joomla\Utilities\ArrayHelper; /** @@ -568,7 +569,7 @@ private function remindExpiringConsents() } $app = JFactory::getApplication(); - $linkMode = $app->get('force_ssl', 0) == 2 ? 1 : -1; + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; foreach ($users as $user) { @@ -581,8 +582,8 @@ private function remindExpiringConsents() $substitutions = array( '[SITENAME]' => $app->get('sitename'), '[URL]' => JUri::root(), - '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind&remind_token=' . $token, false, $linkMode), - '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind', false, $linkMode), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind&remind_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=remind', false, $linkMode, true), '[TOKEN]' => $token, '\\n' => "\n", );