Ejemplo n.º 1
0
 /**
  * Получить абсолютный URL
  * @param string $href
  * @param string $referrer
  * @return string
  * @throws nc_search_exception
  */
 protected function resolve_link($href, $referrer = null)
 {
     $referrer_parts = $this->parse_utf8_url($referrer);
     // Абсолютная ссылка без указания протокола — неправильно обрабатывается
     // функцией parse_url() до PHP 5.4.7
     if (substr($href, 0, 2) == "//") {
         $scheme = isset($referrer_parts['scheme']) ? $referrer_parts['scheme'] : 'http';
         $href = "{$scheme}:{$href}";
     }
     $href_parts = $this->parse_utf8_url($href);
     if (!is_array($href_parts)) {
         $href_parts = array();
     }
     // $href == "#"
     $result_parts = $href_parts;
     if (!isset($href_parts["host"])) {
         // path with no host name
         if ($referrer == 'http:///') {
             return false;
         }
         if ($referrer == 'http://') {
             return false;
         }
         if (!$referrer_parts || !isset($referrer_parts["host"])) {
             throw new nc_search_exception("Cannot resolve full URL: '{$href}' (no referrer)");
         }
         foreach (array("scheme", "host", "port", "path") as $p) {
             if (isset($referrer_parts[$p]) && !isset($href_parts[$p])) {
                 $result_parts[$p] = $referrer_parts[$p];
             }
         }
         if ($result_parts["path"][0] != "/") {
             // relative path
             $referrer_dir = substr($referrer_parts["path"], -1) == '/' ? $referrer_parts["path"] : dirname($referrer_parts["path"]) . "/";
             $result_parts["path"] = $referrer_dir . $result_parts["path"];
         }
     }
     // end of "path with no host name"
     // "http://mysite.org" → "http://mysite.org/"
     if (!isset($result_parts["path"])) {
         $result_parts["path"] = "/";
     }
     // get rid of "./", "../"
     if (strpos($result_parts["path"], "./") !== false) {
         $path_fragments = array();
         foreach (explode("/", $result_parts["path"]) as $part) {
             if ($part == '.' || $part == '') {
                 continue;
             }
             if ($part == '..') {
                 array_pop($path_fragments);
             } else {
                 $path_fragments[] = $part;
             }
         }
         $path = join("/", $path_fragments);
         if (substr($href_parts["path"], -1) == '/') {
             $path .= "/";
         }
         if ($path[0] != '/') {
             $path = "/{$path}";
         }
         $result_parts["path"] = $path;
     }
     // Производится сортировка параметров для того, чтобы не запрашивать страницу
     // дважды, если в ссылках на неё параметры перечислены в разном порядке, например:
     // /sub/?tag=22&curPos=10 и /sub/?curPos=10&tag=22 будут считаться одной страницей
     // Параметр модуля: IndexerNormalizeLinks
     if (isset($result_parts["query"]) && strpos($result_parts["query"], "&") && nc_search::should('IndexerNormalizeLinks')) {
         $params = explode("&", $result_parts["query"]);
         sort($params);
         $result_parts["query"] = join("&", $params);
     }
     // IDN & non-latin paths
     $result_parts["host"] = nc_search_util::encode_host($result_parts["host"]);
     $result_parts["path"] = nc_search_util::encode_path($result_parts["path"]);
     // MySite.ORG == mysite.org
     $result_parts["host"] = strtolower($result_parts["host"]);
     $full_url = strtolower($result_parts["scheme"]) . "://" . $result_parts["host"] . (isset($result_parts["port"]) ? ":{$result_parts['port']}" : "") . $result_parts["path"] . (isset($result_parts["query"]) ? "?{$result_parts['query']}" : "");
     return $full_url;
 }