From 5a5d4e5830b49f90c4853405bc9f8ee7cfad8885 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Thu, 13 May 2021 09:56:48 -0400 Subject: [PATCH] Add support for scheme and host to be manually specified in $page->url() and $page->httpUrl() methods in $options array argument. This is related to the request in PR #116 --- wire/core/Page.php | 24 +++++++++++++----------- wire/core/PageTraversal.php | 19 ++++++++++++++++--- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/wire/core/Page.php b/wire/core/Page.php index 563745ff..b2a238d9 100644 --- a/wire/core/Page.php +++ b/wire/core/Page.php @@ -3076,6 +3076,9 @@ class Page extends WireData implements \Countable, WireMatchable { * - `data` (array): Array of key=value variables to form a query string. * - `http` (bool): Specify true to make URL include scheme and hostname (default=false). * - `language` (Language): Specify Language object to return URL in that Language. + * - `host` (string): Force hostname to use, i.e. 'world.com' or 'hello.world.com'. The 'http' option is implied. (3.0.178+) + * - `scheme` (string): Like http option, makes URL have scheme+hostname, but you specify scheme here, i.e. 'https' (3.0.178+) + * Note that if you specify scheme of 'https' and $config->noHTTPS is true, the 'http' scheme will still be used. * * You can also specify any of the following for `$options` as shortcuts: * @@ -3217,21 +3220,20 @@ class Page extends WireData implements \Countable, WireMatchable { public function httpUrl($options = array()) { $template = $this->template; if(!$template) return ''; - /** @var Config $config */ - $config = $this->wire('config'); + if(is_array($options)) unset($options['http']); + if($options === true || $options === false) $options = array(); + $url = $this->url($options); + if(strpos($url, '://')) return $url; + $config = $this->wire()->config; $mode = $template->https; if($mode > 0 && $config->noHTTPS) $mode = 0; switch($mode) { - case -1: $protocol = 'http'; break; - case 1: $protocol = 'https'; break; - default: $protocol = $config->https ? 'https' : 'http'; + case -1: $scheme = 'http'; break; + case 1: $scheme = 'https'; break; + default: $scheme = $config->https ? 'https' : 'http'; } - if(is_array($options)) { - unset($options['http']); - } else if(is_bool($options)) { - $options = array(); - } - return "$protocol://" . $config->httpHost . $this->url($options); + $url = "$scheme://$config->httpHost$url"; + return $url; } /** diff --git a/wire/core/PageTraversal.php b/wire/core/PageTraversal.php index 05c1bddf..ee32371f 100644 --- a/wire/core/PageTraversal.php +++ b/wire/core/PageTraversal.php @@ -580,6 +580,8 @@ class PageTraversal { * Specify associative array (in 3.0.155+) to make both keys and values part of the URL segment string. * - `data` (array): Array of key=value variables to form a query string. * - `http` (bool): Specify true to make URL include scheme and hostname (default=false). + * - `scheme` (string): Like the http option, makes URL include scheme and hostname, but you specify scheme with this, i.e. 'https' (3.0.178+) + * - `host` (string): Hostname to force use of, i.e. 'world.com' or 'hello.world.com'. The 'http' option is implied when host specified. (3.0.178+) * - `language` (Language): Specify Language object to return URL in that Language. * * You can also specify any of the following for `$options` as shortcuts: @@ -611,6 +613,8 @@ class PageTraversal { $defaults = array( 'http' => is_bool($options) ? $options : false, + 'scheme' => '', + 'host' => '', 'pageNum' => is_int($options) || (is_string($options) && in_array($options, array('+', '-'))) ? $options : 1, 'data' => array(), 'urlSegmentStr' => is_string($options) ? $options : '', @@ -704,13 +708,22 @@ class PageTraversal { $url .= '?' . $query; } - if($options['http']) { - switch($template->https) { + if($options['scheme']) { + $scheme = strtolower($options['scheme']); + if(strpos($scheme, '://') === false) $scheme .= '://'; + if($scheme === 'https://' && $config->noHTTPS) $scheme = 'http://'; + $host = $options['host'] ? $options['host'] : $config->httpHost; + $url = "$scheme$host$url"; + + } else if($options['http'] || $options['host']) { + $mode = $config->noHTTPS ? -1 : $template->https; + switch($mode) { case -1: $scheme = 'http'; break; case 1: $scheme = 'https'; break; default: $scheme = $config->https ? 'https' : 'http'; } - $url = "$scheme://" . $page->wire('config')->httpHost . $url; + $host = $options['host'] ? $options['host'] : $config->httpHost; + $url = "$scheme://$host$url"; } return $url;