Permalink
Browse files

FIX: improve Director::makeRelative() to ignore SSL changes.

See http://open.silverstripe.org/ticket/6672. Expanded on initial patch with test coverage. Fixes another one of the commented out cases in the test by picking up URL's which do not include a protocol.
  • Loading branch information...
1 parent 23ed533 commit a67b964267d9666602c0024092b09ea6a78e55f0 @icecaster icecaster committed with wilr Jul 1, 2012
Showing with 49 additions and 26 deletions.
  1. +39 −22 control/Director.php
  2. +10 −4 tests/control/DirectorTest.php
View
61 control/Director.php
@@ -485,27 +485,41 @@ static function setBaseFolder($baseFolder) {
}
/**
- * Turns an absolute URL or folder into one that's relative to the root of the site.
- * This is useful when turning a URL into a filesystem reference, or vice versa.
- *
- * @todo Implement checking across http/https protocols
+ * Turns an absolute URL or folder into one that's relative to the root of
+ * the site. This is useful when turning a URL into a filesystem reference,
+ * or vice versa.
*
* @param string $url Accepts both a URL or a filesystem path
- * @return string Either a relative URL if the checks succeeded, or the original (possibly absolute) URL.
+ * @return string Either a relative URL if the checks succeeded, or the
+ * original (possibly absolute) URL.
*/
- static function makeRelative($url) {
- // Allow for the accidental inclusion of a // in the URL
- $url = preg_replace('#([^:])//#', '\\1/', $url);
- $url = trim($url);
+ public static function makeRelative($url) {
+ // Allow for the accidental inclusion whitespace and // in the URL
+ $url = trim(preg_replace('#([^:])//#', '\\1/', $url));
+
+ $base1 = self::absoluteBaseURL();
+ $baseDomain = substr($base1, strlen(self::protocol()));
// Only bother comparing the URL to the absolute version if $url looks like a URL.
- if(preg_match('/^https?[^:]*:\/\//',$url)) {
- $base1 = self::absoluteBaseURL();
+ if(preg_match('/^https?[^:]*:\/\//',$url,$matches)) {
+ $urlProtocol = $matches[0];
+ $urlWithoutProtocol = substr($url, strlen($urlProtocol));
+
// If we are already looking at baseURL, return '' (substr will return false)
- if($url == $base1) return '';
- else if(substr($url,0,strlen($base1)) == $base1) return substr($url,strlen($base1));
- // Convert http://www.mydomain.com/mysitedir to ''
- else if(substr($base1,-1)=="/" && $url == substr($base1,0,-1)) return "";
+ if($url == $base1) {
+ return '';
+ }
+ else if(substr($url,0,strlen($base1)) == $base1) {
+ return substr($url,strlen($base1));
+ }
+ else if(substr($base1,-1)=="/" && $url == substr($base1,0,-1)) {
+ // Convert http://www.mydomain.com/mysitedir to ''
+ return "";
+ }
+
+ if(substr($urlWithoutProtocol,0,strlen($baseDomain)) == $baseDomain) {
+ return substr($urlWithoutProtocol,strlen($baseDomain));
+ }
}
// test for base folder, e.g. /var/www
@@ -514,8 +528,15 @@ static function makeRelative($url) {
// Test for relative base url, e.g. mywebsite/ if the full URL is http://localhost/mywebsite/
$base3 = self::baseURL();
- if(substr($url,0,strlen($base3)) == $base3) return substr($url,strlen($base3));
-
+ if(substr($url,0,strlen($base3)) == $base3) {
+ return substr($url,strlen($base3));
+ }
+
+ // Test for relative base url, e.g mywebsite/ if the full url is localhost/myswebsite
+ if(substr($url,0,strlen($baseDomain)) == $baseDomain) {
+ return substr($url, strlen($baseDomain));
+ }
+
// Nothing matched, fall back to returning the original URL
return $url;
}
@@ -936,8 +957,4 @@ public static function get_template_global_variables() {
'BaseHref' => 'absoluteBaseURL', //@deprecated 3.0
);
}
-
-}
-
-
-
+}
View
14 tests/control/DirectorTest.php
@@ -122,16 +122,22 @@ public function testIsRelativeUrl() {
public function testMakeRelative() {
$siteUrl = Director::absoluteBaseURL();
$siteUrlNoProtocol = preg_replace('/https?:\/\//', '', $siteUrl);
+
$this->assertEquals(Director::makeRelative("$siteUrl"), '');
- //$this->assertEquals(Director::makeRelative("https://$siteUrlNoProtocol"), '');
+ $this->assertEquals(Director::makeRelative("https://$siteUrlNoProtocol"), '');
+ $this->assertEquals(Director::makeRelative("http://$siteUrlNoProtocol"), '');
+
$this->assertEquals(Director::makeRelative(" $siteUrl/testpage "), 'testpage');
- //$this->assertEquals(Director::makeRelative("$siteUrlNoProtocol/testpage"), 'testpage');
+ $this->assertEquals(Director::makeRelative("$siteUrlNoProtocol/testpage"), 'testpage');
+
$this->assertEquals(Director::makeRelative('ftp://test.com'), 'ftp://test.com');
$this->assertEquals(Director::makeRelative('http://test.com'), 'http://test.com');
- // the below is not a relative URL, test makes no sense
- // $this->assertEquals(Director::makeRelative('/relative'), '/relative');
+
$this->assertEquals(Director::makeRelative('relative'), 'relative');
$this->assertEquals(Director::makeRelative("$siteUrl/?url=http://test.com"), '?url=http://test.com');
+
+ $this->assertEquals("test", Director::makeRelative("https://".$siteUrlNoProtocol."/test"));
+ $this->assertEquals("test", Director::makeRelative("http://".$siteUrlNoProtocol."/test"));
}
/**

0 comments on commit a67b964

Please sign in to comment.