diff options
Diffstat (limited to 'classes/feeditem')
-rwxr-xr-x | classes/feeditem/atom.php | 57 | ||||
-rwxr-xr-x | classes/feeditem/common.php | 50 | ||||
-rwxr-xr-x | classes/feeditem/rss.php | 41 |
3 files changed, 108 insertions, 40 deletions
diff --git a/classes/feeditem/atom.php b/classes/feeditem/atom.php index 51358f36c..cac6d8c54 100755 --- a/classes/feeditem/atom.php +++ b/classes/feeditem/atom.php @@ -2,7 +2,7 @@ class FeedItem_Atom extends FeedItem_Common { const NS_XML = "http://www.w3.org/XML/1998/namespace"; - function get_id() { + function get_id(): string { $id = $this->elem->getElementsByTagName("id")->item(0); if ($id) { @@ -12,6 +12,9 @@ class FeedItem_Atom extends FeedItem_Common { } } + /** + * @return int|false a timestamp on success, false otherwise + */ function get_date() { $updated = $this->elem->getElementsByTagName("updated")->item(0); @@ -30,10 +33,13 @@ class FeedItem_Atom extends FeedItem_Common { if ($date) { return strtotime($date->nodeValue); } + + // consistent with strtotime failing to parse + return false; } - function get_link() { + function get_link(): string { $links = $this->elem->getElementsByTagName("link"); foreach ($links as $link) { @@ -44,24 +50,27 @@ class FeedItem_Atom extends FeedItem_Common { $base = $this->xpath->evaluate("string(ancestor-or-self::*[@xml:base][1]/@xml:base)", $link); if ($base) - return rewrite_relative_url($base, clean(trim($link->getAttribute("href")))); + return UrlHelper::rewrite_relative($base, clean(trim($link->getAttribute("href")))); else return clean(trim($link->getAttribute("href"))); - } } + + return ''; } - function get_title() { + function get_title(): string { $title = $this->elem->getElementsByTagName("title")->item(0); - - if ($title) { - return clean(trim($title->nodeValue)); - } + return $title ? clean(trim($title->nodeValue)) : ''; } - /** $base is optional (returns $content if $base is null), $content is an HTML string */ - private function rewrite_content_to_base($base, $content) { + /** + * @param string|null $base optional (returns $content if $base is null) + * @param string $content an HTML string + * + * @return string the rewritten XML or original $content + */ + private function rewrite_content_to_base(?string $base = null, ?string $content = '') { if (!empty($base) && !empty($content)) { @@ -81,14 +90,17 @@ class FeedItem_Atom extends FeedItem_Common { } } - return $tmpdoc->saveXML(); + // Fall back to $content if saveXML somehow fails (i.e. returns false) + $modified_content = $tmpdoc->saveXML(); + return $modified_content !== false ? $modified_content : $content; } } return $content; } - function get_content() { + function get_content(): string { + /** @var DOMElement|null */ $content = $this->elem->getElementsByTagName("content")->item(0); if ($content) { @@ -108,10 +120,13 @@ class FeedItem_Atom extends FeedItem_Common { return $this->rewrite_content_to_base($base, $this->subtree_or_text($content)); } + + return ''; } // TODO: duplicate code should be merged with get_content() - function get_description() { + function get_description(): string { + /** @var DOMElement|null */ $content = $this->elem->getElementsByTagName("summary")->item(0); if ($content) { @@ -132,9 +147,13 @@ class FeedItem_Atom extends FeedItem_Common { return $this->rewrite_content_to_base($base, $this->subtree_or_text($content)); } + return ''; } - function get_categories() { + /** + * @return array<int, string> + */ + function get_categories(): array { $categories = $this->elem->getElementsByTagName("category"); $cats = []; @@ -152,7 +171,10 @@ class FeedItem_Atom extends FeedItem_Common { return $this->normalize_categories($cats); } - function get_enclosures() { + /** + * @return array<int, FeedEnclosure> + */ + function get_enclosures(): array { $links = $this->elem->getElementsByTagName("link"); $encs = []; @@ -182,7 +204,7 @@ class FeedItem_Atom extends FeedItem_Common { return $encs; } - function get_language() { + function get_language(): string { $lang = $this->elem->getAttributeNS(self::NS_XML, "lang"); if (!empty($lang)) { @@ -195,5 +217,6 @@ class FeedItem_Atom extends FeedItem_Common { } } } + return ''; } } diff --git a/classes/feeditem/common.php b/classes/feeditem/common.php index 18afeaa94..6a9be8aca 100755 --- a/classes/feeditem/common.php +++ b/classes/feeditem/common.php @@ -1,16 +1,20 @@ <?php abstract class FeedItem_Common extends FeedItem { + /** @var DOMElement */ protected $elem; - protected $xpath; + + /** @var DOMDocument */ protected $doc; - function __construct($elem, $doc, $xpath) { + /** @var DOMXPath */ + protected $xpath; + + function __construct(DOMElement $elem, DOMDocument $doc, DOMXPath $xpath) { $this->elem = $elem; $this->xpath = $xpath; $this->doc = $doc; try { - $source = $elem->getElementsByTagName("source")->item(0); // we don't need <source> element @@ -21,11 +25,12 @@ abstract class FeedItem_Common extends FeedItem { } } - function get_element() { + function get_element(): DOMElement { return $this->elem; } - function get_author() { + function get_author(): string { + /** @var DOMElement|null */ $author = $this->elem->getElementsByTagName("author")->item(0); if ($author) { @@ -51,7 +56,7 @@ abstract class FeedItem_Common extends FeedItem { return implode(", ", $authors); } - function get_comments_url() { + function get_comments_url(): string { //RSS only. Use a query here to avoid namespace clashes (e.g. with slash). //might give a wrong result if a default namespace was declared (possible with XPath 2.0) $com_url = $this->xpath->query("comments", $this->elem)->item(0); @@ -65,20 +70,28 @@ abstract class FeedItem_Common extends FeedItem { if ($com_url) return clean($com_url->nodeValue); + + return ''; } - function get_comments_count() { + function get_comments_count(): int { //also query for ATE stuff here $query = "slash:comments|thread:total|atom:link[@rel='replies']/@thread:count"; $comments = $this->xpath->query($query, $this->elem)->item(0); - if ($comments) { - return clean($comments->nodeValue); + if ($comments && is_numeric($comments->nodeValue)) { + return (int) clean($comments->nodeValue); } + + return 0; } - // this is common for both Atom and RSS types and deals with various media: elements - function get_enclosures() { + /** + * this is common for both Atom and RSS types and deals with various 'media:' elements + * + * @return array<int, FeedEnclosure> + */ + function get_enclosures(): array { $encs = []; $enclosures = $this->xpath->query("media:content", $this->elem); @@ -108,6 +121,7 @@ abstract class FeedItem_Common extends FeedItem { foreach ($enclosures as $enclosure) { $enc = new FeedEnclosure(); + /** @var DOMElement|null */ $content = $this->xpath->query("media:content", $enclosure)->item(0); if ($content) { @@ -150,11 +164,14 @@ abstract class FeedItem_Common extends FeedItem { return $encs; } - function count_children($node) { + function count_children(DOMElement $node): int { return $node->getElementsByTagName("*")->length; } - function subtree_or_text($node) { + /** + * @return false|string false on failure, otherwise string contents + */ + function subtree_or_text(DOMElement $node) { if ($this->count_children($node) == 0) { return $node->nodeValue; } else { @@ -162,7 +179,12 @@ abstract class FeedItem_Common extends FeedItem { } } - static function normalize_categories($cats) { + /** + * @param array<int, string> $cats + * + * @return array<int, string> + */ + static function normalize_categories(array $cats): array { $tmp = []; diff --git a/classes/feeditem/rss.php b/classes/feeditem/rss.php index 1f7953c51..7017d04e9 100755 --- a/classes/feeditem/rss.php +++ b/classes/feeditem/rss.php @@ -1,6 +1,6 @@ <?php class FeedItem_RSS extends FeedItem_Common { - function get_id() { + function get_id(): string { $id = $this->elem->getElementsByTagName("guid")->item(0); if ($id) { @@ -10,6 +10,9 @@ class FeedItem_RSS extends FeedItem_Common { } } + /** + * @return int|false a timestamp on success, false otherwise + */ function get_date() { $pubDate = $this->elem->getElementsByTagName("pubDate")->item(0); @@ -22,9 +25,12 @@ class FeedItem_RSS extends FeedItem_Common { if ($date) { return strtotime($date->nodeValue); } + + // consistent with strtotime failing to parse + return false; } - function get_link() { + function get_link(): string { $links = $this->xpath->query("atom:link", $this->elem); foreach ($links as $link) { @@ -37,6 +43,7 @@ class FeedItem_RSS extends FeedItem_Common { } } + /** @var DOMElement|null */ $link = $this->elem->getElementsByTagName("guid")->item(0); if ($link && $link->hasAttributes() && $link->getAttribute("isPermaLink") == "true") { @@ -48,9 +55,11 @@ class FeedItem_RSS extends FeedItem_Common { if ($link) { return clean(trim($link->nodeValue)); } + + return ''; } - function get_title() { + function get_title(): string { $title = $this->xpath->query("title", $this->elem)->item(0); if ($title) { @@ -64,10 +73,15 @@ class FeedItem_RSS extends FeedItem_Common { if ($title) { return clean(trim($title->nodeValue)); } + + return ''; } - function get_content() { + function get_content(): string { + /** @var DOMElement|null */ $contentA = $this->xpath->query("content:encoded", $this->elem)->item(0); + + /** @var DOMElement|null */ $contentB = $this->elem->getElementsByTagName("description")->item(0); if ($contentA && !$contentB) { @@ -85,17 +99,24 @@ class FeedItem_RSS extends FeedItem_Common { return mb_strlen($resultA) > mb_strlen($resultB) ? $resultA : $resultB; } + + return ''; } - function get_description() { + function get_description(): string { $summary = $this->elem->getElementsByTagName("description")->item(0); if ($summary) { return $summary->nodeValue; } + + return ''; } - function get_categories() { + /** + * @return array<int, string> + */ + function get_categories(): array { $categories = $this->elem->getElementsByTagName("category"); $cats = []; @@ -112,7 +133,10 @@ class FeedItem_RSS extends FeedItem_Common { return $this->normalize_categories($cats); } - function get_enclosures() { + /** + * @return array<int, FeedEnclosure> + */ + function get_enclosures(): array { $enclosures = $this->elem->getElementsByTagName("enclosure"); $encs = array(); @@ -134,7 +158,7 @@ class FeedItem_RSS extends FeedItem_Common { return $encs; } - function get_language() { + function get_language(): string { $languages = $this->doc->getElementsByTagName('language'); if (count($languages) == 0) { @@ -143,5 +167,4 @@ class FeedItem_RSS extends FeedItem_Common { return clean($languages[0]->textContent); } - } |