Chris@0: getAttribute('rel')) !== 'alternate' Chris@0: || !$link->getAttribute('type') || !$link->getAttribute('href')) { Chris@0: continue; Chris@0: } Chris@0: if (!isset($this->rss) && $link->getAttribute('type') == 'application/rss+xml') { Chris@0: $this->rss = $this->absolutiseUri(trim($link->getAttribute('href')), $uri); Chris@0: } elseif (!isset($this->atom) && $link->getAttribute('type') == 'application/atom+xml') { Chris@0: $this->atom = $this->absolutiseUri(trim($link->getAttribute('href')), $uri); Chris@0: } elseif (!isset($this->rdf) && $link->getAttribute('type') == 'application/rdf+xml') { Chris@0: $this->rdf = $this->absolutiseUri(trim($link->getAttribute('href')), $uri); Chris@0: } Chris@0: $this[] = new static([ Chris@0: 'rel' => 'alternate', Chris@0: 'type' => $link->getAttribute('type'), Chris@0: 'href' => $this->absolutiseUri(trim($link->getAttribute('href')), $uri), Chris@0: ]); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Attempt to turn a relative URI into an absolute URI Chris@0: */ Chris@0: protected function absolutiseUri($link, $uri = null) Chris@0: { Chris@0: $linkUri = Uri::factory($link); Chris@0: if (!$linkUri->isAbsolute() or !$linkUri->isValid()) { Chris@0: if ($uri !== null) { Chris@0: $uri = Uri::factory($uri); Chris@0: Chris@0: if ($link[0] !== '/') { Chris@0: $link = $uri->getPath() . '/' . $link; Chris@0: } Chris@0: Chris@0: $link = sprintf( Chris@0: '%s://%s/%s', Chris@0: ($uri->getScheme() ?: 'http'), Chris@0: $uri->getHost(), Chris@0: $this->canonicalizePath($link) Chris@0: ); Chris@0: Chris@0: if (!Uri::factory($link)->isValid()) { Chris@0: $link = null; Chris@0: } Chris@0: } Chris@0: } Chris@0: return $link; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Canonicalize relative path Chris@0: */ Chris@0: protected function canonicalizePath($path) Chris@0: { Chris@0: $parts = array_filter(explode('/', $path)); Chris@0: $absolutes = []; Chris@0: foreach ($parts as $part) { Chris@0: if ('.' == $part) { Chris@0: continue; Chris@0: } Chris@0: if ('..' == $part) { Chris@0: array_pop($absolutes); Chris@0: } else { Chris@0: $absolutes[] = $part; Chris@0: } Chris@0: } Chris@0: return implode('/', $absolutes); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Supports lazy loading of feeds using Reader::import() but Chris@0: * delegates any other operations to the parent class. Chris@0: * Chris@0: * @param string $offset Chris@0: * @return mixed Chris@0: */ Chris@0: public function offsetGet($offset) Chris@0: { Chris@0: if ($offset == 'feed' && !$this->offsetExists('feed')) { Chris@0: if (!$this->offsetExists('href')) { Chris@0: return; Chris@0: } Chris@0: $feed = Reader::import($this->offsetGet('href')); Chris@0: $this->offsetSet('feed', $feed); Chris@0: return $feed; Chris@0: } Chris@0: return parent::offsetGet($offset); Chris@0: } Chris@0: }