/** * Resolve a base URI with a relative URI and return a new URI. * * @param UriInterface $base Base URI * @param null|string|UriInterface $rel Relative URI * * @throws \InvalidArgumentException * * @return UriInterface */ public static function resolve(UriInterface $base, $rel = null) { if ($rel === null || $rel === '') { return $base; } if (!$rel instanceof UriInterface) { $rel = new self($rel); } // Return the relative uri as-is if it has a scheme. if ($rel->getScheme()) { return $rel->withPath(static::removeDotSegments($rel->getPath())); } $relParts = ['scheme' => $rel->getScheme(), 'authority' => $rel->getAuthority(), 'path' => $rel->getPath(), 'query' => $rel->getQuery(), 'fragment' => $rel->getFragment()]; $parts = ['scheme' => $base->getScheme(), 'authority' => $base->getAuthority(), 'path' => $base->getPath(), 'query' => $base->getQuery(), 'fragment' => $base->getFragment()]; if (!empty($relParts['path'])) { if (strpos($relParts['path'], '/') === 0) { $parts['path'] = self::removeDotSegments($relParts['path']); $parts['query'] = $relParts['query']; $parts['fragment'] = $relParts['fragment']; } else { $mergedPath = substr($parts['path'], 0, strrpos($parts['path'], '/') + 1); $parts['path'] = self::removeDotSegments($mergedPath . $relParts['path']); $parts['query'] = $relParts['query']; $parts['fragment'] = $relParts['fragment']; } } elseif (!empty($relParts['query'])) { $parts['query'] = $relParts['query']; } elseif ($relParts['fragment'] !== null) { $parts['fragment'] = $relParts['fragment']; } return new self(static::createUriString($parts['scheme'], $parts['authority'], $parts['path'], $parts['query'], $parts['fragment'])); }
/** * Returns an Net_URL2 instance representing an absolute URL relative to * this URL. * * @param Net_URL2|string $reference relative URL * * @throws Exception * @return $this */ public function resolve($reference) { if (!$reference instanceof Net_URL2) { $reference = new self($reference); } if (!$reference->_isFragmentOnly() && !$this->isAbsolute()) { throw new Exception('Base-URL must be absolute if reference is not fragment-only'); } // A non-strict parser may ignore a scheme in the reference if it is // identical to the base URI's scheme. if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) { $reference->_scheme = false; } $target = new self(''); if ($reference->_scheme !== false) { $target->_scheme = $reference->_scheme; $target->setAuthority($reference->getAuthority()); $target->_path = self::removeDotSegments($reference->_path); $target->_query = $reference->_query; } else { $authority = $reference->getAuthority(); if ($authority !== false) { $target->setAuthority($authority); $target->_path = self::removeDotSegments($reference->_path); $target->_query = $reference->_query; } else { if ($reference->_path == '') { $target->_path = $this->_path; if ($reference->_query !== false) { $target->_query = $reference->_query; } else { $target->_query = $this->_query; } } else { if (substr($reference->_path, 0, 1) == '/') { $target->_path = self::removeDotSegments($reference->_path); } else { // Merge paths (RFC 3986, section 5.2.3) if ($this->_host !== false && $this->_path == '') { $target->_path = '/' . $reference->_path; } else { $i = strrpos($this->_path, '/'); if ($i !== false) { $target->_path = substr($this->_path, 0, $i + 1); } $target->_path .= $reference->_path; } $target->_path = self::removeDotSegments($target->_path); } $target->_query = $reference->_query; } $target->setAuthority($this->getAuthority()); } $target->_scheme = $this->_scheme; } $target->_fragment = $reference->_fragment; return $target; }
/** * Resolve a base URI with a relative URI and return a new URI. * * @param UriInterface $base Base URI * @param string|UriInterface $rel Relative URI * * @return UriInterface * @link http://tools.ietf.org/html/rfc3986#section-5.2 */ public static function resolve(UriInterface $base, $rel) { if (!$rel instanceof UriInterface) { $rel = new self($rel); } if ((string) $rel === '') { // we can simply return the same base URI instance for this same-document reference return $base; } if ($rel->getScheme() != '') { return $rel->withPath(self::removeDotSegments($rel->getPath())); } if ($rel->getAuthority() != '') { $targetAuthority = $rel->getAuthority(); $targetPath = self::removeDotSegments($rel->getPath()); $targetQuery = $rel->getQuery(); } else { $targetAuthority = $base->getAuthority(); if ($rel->getPath() === '') { $targetPath = $base->getPath(); $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery(); } else { if ($rel->getPath()[0] === '/') { $targetPath = $rel->getPath(); } else { if ($targetAuthority != '' && $base->getPath() === '') { $targetPath = '/' . $rel->getPath(); } else { $lastSlashPos = strrpos($base->getPath(), '/'); if ($lastSlashPos === false) { $targetPath = $rel->getPath(); } else { $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath(); } } } $targetPath = self::removeDotSegments($targetPath); $targetQuery = $rel->getQuery(); } } return new self(self::createUriString($base->getScheme(), $targetAuthority, $targetPath, $targetQuery, $rel->getFragment())); }