/** * Allow the setting of a URL * * This is here so that RootURLController can change the URL of the request * without us loosing all the other info attached (like headers) * * @param string $url The new URL * @return HTTPRequest The updated request */ public function setUrl($url) { $this->url = $url; // Normalize URL if its relative (strictly speaking), or has leading slashes if (Director::is_relative_url($url) || preg_match('/^\\//', $url)) { $this->url = preg_replace(array('/\\/+/', '/^\\//', '/\\/$/'), array('/', '', ''), $this->url); } if (preg_match('/^(.*)\\.([A-Za-z][A-Za-z0-9]*)$/', $this->url, $matches)) { $this->url = $matches[1]; $this->extension = $matches[2]; } if ($this->url) { $this->dirParts = preg_split('|/+|', $this->url); } else { $this->dirParts = array(); } return $this; }
/** * Will try to include a GET parameter for an existing URL, preserving existing parameters and * fragments. If no URL is given, falls back to $_SERVER['REQUEST_URI']. Uses parse_url() to * dissect the URL, and http_build_query() to reconstruct it with the additional parameter. * Converts any '&' (ampersand) URL parameter separators to the more XHTML compliant '&'. * * CAUTION: If the URL is determined to be relative, it is prepended with Director::absoluteBaseURL(). * This method will always return an absolute URL because Director::makeRelative() can lead to * inconsistent results. * * @param string $varname * @param string $varvalue * @param string $currentURL Relative or absolute URL. * @param string $separator Separator for http_build_query(). * * @return string */ public static function setGetVar($varname, $varvalue, $currentURL = null, $separator = '&') { $uri = $currentURL ? $currentURL : Director::makeRelative($_SERVER['REQUEST_URI']); $isRelative = false; // We need absolute URLs for parse_url() if (Director::is_relative_url($uri)) { $uri = Director::absoluteBaseURL() . $uri; $isRelative = true; } // try to parse uri $parts = parse_url($uri); if (!$parts) { throw new InvalidArgumentException("Can't parse URL: " . $uri); } // Parse params and add new variable $params = array(); if (isset($parts['query'])) { parse_str($parts['query'], $params); } $params[$varname] = $varvalue; // Generate URI segments and formatting $scheme = isset($parts['scheme']) ? $parts['scheme'] : 'http'; $user = isset($parts['user']) && $parts['user'] != '' ? $parts['user'] : ''; if ($user != '') { // format in either user:pass@host.com or user@host.com $user .= isset($parts['pass']) && $parts['pass'] != '' ? ':' . $parts['pass'] . '@' : '@'; } $host = isset($parts['host']) ? $parts['host'] : ''; $port = isset($parts['port']) && $parts['port'] != '' ? ':' . $parts['port'] : ''; $path = isset($parts['path']) && $parts['path'] != '' ? $parts['path'] : ''; // handle URL params which are existing / new $params = $params ? '?' . http_build_query($params, null, $separator) : ''; // keep fragments (anchors) intact. $fragment = isset($parts['fragment']) && $parts['fragment'] != '' ? '#' . $parts['fragment'] : ''; // Recompile URI segments $newUri = $scheme . '://' . $user . $host . $port . $path . $params . $fragment; if ($isRelative) { return Director::makeRelative($newUri); } return $newUri; }
public function testIsRelativeUrl() { $siteUrl = Director::absoluteBaseURL(); $this->assertFalse(Director::is_relative_url('http://test.com')); $this->assertFalse(Director::is_relative_url('https://test.com')); $this->assertFalse(Director::is_relative_url(' https://test.com/testpage ')); $this->assertTrue(Director::is_relative_url('test.com/testpage')); $this->assertFalse(Director::is_relative_url('ftp://test.com')); $this->assertTrue(Director::is_relative_url('/relative')); $this->assertTrue(Director::is_relative_url('relative')); $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com')); $this->assertTrue(Director::is_relative_url('/relative/#=http://test.com')); }