original_string: protected function resolveRelativeUrl($relative_url_uri_query_fragment, $base_url = '')
      {
          $relative_url_uri_query_fragment = (string) $relative_url_uri_query_fragment;
          $base_url                        = (string) $base_url;
  
          if (!$base_url) {
              $base_url = $this->currentUrl();
          } // Auto-detects current URL/location.
  
          $relative_parts         = $this->mustParseUrl($relative_url_uri_query_fragment, null, 0);
          $relative_parts['path'] = $this->nUrlPathSeps($relative_parts['path'], true);
          $base_parts             = $parts             = $this->mustParseUrl($base_url);
  
          if ($relative_parts['host']) {
              if (!$relative_parts['scheme']) {
                  $relative_parts['scheme'] = $base_parts['scheme'];
              }
              return $this->mustUnparseUrl($relative_parts);
          }
          if (!$base_parts['host']) {
              throw new \Exception(sprintf('Unable to parse (missing base host name): `%1$s`.', $base_url));
          }
          if (isset($relative_parts['path'][0])) {
              if (mb_strpos($relative_parts['path'], '/') === 0) {
                  $parts['path'] = ''; // Reduce to nothing if relative is absolute.
              } else {
                  $parts['path'] = preg_replace('/\/[^\/]*$/u', '', $parts['path']).'/'; // Reduce to nearest `/`.
              }
              // Replace `/./` and `/foo/../` with `/` (resolve relatives).
              for ($_i = 1, $parts['path'] = $parts['path'].$relative_parts['path']; $_i > 0;) {
                  $parts['path'] = preg_replace(['/\/\.\//u', '/\/(?!\.\.)[^\/]+\/\.\.\//u'], '/', $parts['path'], -1, $_i);
              } // unset($_i); // Just a little housekeeping.
  
              // We can ditch any unresolvable `../` patterns now.
              // For instance, if there were too many `../../../../../` back references.
              $parts['path'] = str_replace('../', '', $parts['path']);
  
              $parts['query'] = $relative_parts['query'];
              // Use relative query.
          } elseif (isset($relative_parts['query'][0])) {
              $parts['query'] = $relative_parts['query'];
          } // Relative query string supersedes base.
  
          $parts['fragment'] = $relative_parts['fragment']; // Always changes.
  
          return $this->mustUnparseUrl($parts); // Resolved now.
      }
code: protected function resolveRelativeUrl($relative_url_uri_query_fragment, $base_url = '')
      {
          $relative_url_uri_query_fragment = (string) $relative_url_uri_query_fragment;
          $base_url                        = (string) $base_url;
  
          if (!$base_url) {
              $base_url = $this->currentUrl();
          } // Auto-detects current URL/location.
  
          $relative_parts         = $this->mustParseUrl($relative_url_uri_query_fragment, null, 0);
          $relative_parts['path'] = $this->nUrlPathSeps($relative_parts['path'], true);
          $base_parts             = $parts             = $this->mustParseUrl($base_url);
  
          if ($relative_parts['host']) {
              if (!$relative_parts['scheme']) {
                  $relative_parts['scheme'] = $base_parts['scheme'];
              }
              return $this->mustUnparseUrl($relative_parts);
          }
          if (!$base_parts['host']) {
              throw new \Exception(sprintf('Unable to parse (missing base host name): `%1$s`.', $base_url));
          }
          if (isset($relative_parts['path'][0])) {
              if (mb_strpos($relative_parts['path'], '/') === 0) {
                  $parts['path'] = ''; // Reduce to nothing if relative is absolute.
              } else {
                  $parts['path'] = preg_replace('/\/[^\/]*$/u', '', $parts['path']).'/'; // Reduce to nearest `/`.
              }
              // Replace `/./` and `/foo/../` with `/` (resolve relatives).
              for ($_i = 1, $parts['path'] = $parts['path'].$relative_parts['path']; $_i > 0;) {
                  $parts['path'] = preg_replace(['/\/\.\//u', '/\/(?!\.\.)[^\/]+\/\.\.\//u'], '/', $parts['path'], -1, $_i);
              } // unset($_i); // Just a little housekeeping.
  
              // We can ditch any unresolvable `../` patterns now.
              // For instance, if there were too many `../../../../../` back references.
              $parts['path'] = str_replace('../', '', $parts['path']);
  
              $parts['query'] = $relative_parts['query'];
              // Use relative query.
          } elseif (isset($relative_parts['query'][0])) {
              $parts['query'] = $relative_parts['query'];
          } // Relative query string supersedes base.
  
          $parts['fragment'] = $relative_parts['fragment']; // Always changes.
  
          return $this->mustUnparseUrl($parts); // Resolved now.
      }
code_tokens: protected function resolveRelativeUrl ( $ relative_url_uri_query_fragment , $ base_url = '' ) { $ relative_url_uri_query_fragment = ( string ) $ relative_url_uri_query_fragment ; $ base_url = ( string ) $ base_url ; if ( ! $ base_url ) { $ base_url = $ this -> currentUrl ( ) ; } // Auto-detects current URL/location. $ relative_parts = $ this -> mustParseUrl ( $ relative_url_uri_query_fragment , null , 0 ) ; $ relative_parts [ 'path' ] = $ this -> nUrlPathSeps ( $ relative_parts [ 'path' ] , true ) ; $ base_parts = $ parts = $ this -> mustParseUrl ( $ base_url ) ; if ( $ relative_parts [ 'host' ] ) { if ( ! $ relative_parts [ 'scheme' ] ) { $ relative_parts [ 'scheme' ] = $ base_parts [ 'scheme' ] ; } return $ this -> mustUnparseUrl ( $ relative_parts ) ; } if ( ! $ base_parts [ 'host' ] ) { throw new \ Exception ( sprintf ( 'Unable to parse (missing base host name): `%1$s`.' , $ base_url ) ) ; } if ( isset ( $ relative_parts [ 'path' ] [ 0 ] ) ) { if ( mb_strpos ( $ relative_parts [ 'path' ] , '/' ) === 0 ) { $ parts [ 'path' ] = '' ; // Reduce to nothing if relative is absolute. } else { $ parts [ 'path' ] = preg_replace ( '/\/[^\/]*$/u' , '' , $ parts [ 'path' ] ) . '/' ; // Reduce to nearest `/`. } // Replace `/./` and `/foo/../` with `/` (resolve relatives). for ( $ _i = 1 , $ parts [ 'path' ] = $ parts [ 'path' ] . $ relative_parts [ 'path' ] ; $ _i > 0 ; ) { $ parts [ 'path' ] = preg_replace ( [ '/\/\.\//u' , '/\/(?!\.\.)[^\/]+\/\.\.\//u' ] , '/' , $ parts [ 'path' ] , - 1 , $ _i ) ; } // unset($_i); // Just a little housekeeping. // We can ditch any unresolvable `../` patterns now. // For instance, if there were too many `../../../../../` back references. $ parts [ 'path' ] = str_replace ( '../' , '' , $ parts [ 'path' ] ) ; $ parts [ 'query' ] = $ relative_parts [ 'query' ] ; // Use relative query. } elseif ( isset ( $ relative_parts [ 'query' ] [ 0 ] ) ) { $ parts [ 'query' ] = $ relative_parts [ 'query' ] ; } // Relative query string supersedes base. $ parts [ 'fragment' ] = $ relative_parts [ 'fragment' ] ; // Always changes. return $ this -> mustUnparseUrl ( $ parts ) ; // Resolved now. }
docstring: Resolves a relative URL into a full URL from a base.
  
  @since 140417 Initial release.
  
  @param string $relative_url_uri_query_fragment A full URL; or a partial URI;
  or only a query string, or only a fragment. Any of these can be parsed here.
  @param string $base_url                        A base URL. Optional. Defaults to current location.
  This defaults to the current URL. See: {@link current_url()}.
  
  @throws \Exception If unable to parse `$relative_url_uri_query_fragment`.
  @throws \Exception If there is no `$base`, and we're unable to detect current location.
  @throws \Exception If unable to parse `$base` (or if `$base` has no host name).
  
  @return string A full URL; else an exception will be thrown.
docstring_tokens: Resolves a relative URL into a full URL from a base .