diff options
Diffstat (limited to 'lib/FeedItem.php')
-rw-r--r-- | lib/FeedItem.php | 516 |
1 files changed, 121 insertions, 395 deletions
diff --git a/lib/FeedItem.php b/lib/FeedItem.php index 3d1b4509..4915c1b9 100644 --- a/lib/FeedItem.php +++ b/lib/FeedItem.php @@ -1,129 +1,90 @@ <?php -/** - * This file is part of RSS-Bridge, a PHP project capable of generating RSS and - * Atom feeds for websites that don't have one. - * - * For the full license information, please view the UNLICENSE file distributed - * with this source code. - * - * @package Core - * @license http://unlicense.org/ UNLICENSE - * @link https://github.com/rss-bridge/rss-bridge - */ - -/** - * Represents a simple feed item for transformation into various feed formats. - * - * This class represents a feed item. A feed item is an entity that can be - * transformed into various feed formats. It holds a set of pre-defined - * properties: - * - * - **URI**: URI to the full article (i.e. "https://...") - * - **Title**: The title - * - **Timestamp**: A timestamp of when the item was first released - * - **Author**: Name of the author - * - **Content**: Body of the feed, as text or HTML - * - **Enclosures**: A list of links to media objects (images, videos, etc...) - * - **Categories**: A list of category names or tags to categorize the item - * - * _Note_: A feed item can have any number of additional parameters, all of which - * may or may not be transformed to the selected output format. - * - * _Remarks_: This class supports legacy items via {@see FeedItem::__construct()} - * (i.e. `$feedItem = \FeedItem($item);`). Support for legacy items may be removed - * in future versions of RSS-Bridge. - */ class FeedItem { - /** @var string|null URI to the full article */ - protected $uri = null; - - /** @var string|null Title of the item */ - protected $title = null; - - /** @var int|null Timestamp of when the item was first released */ - protected $timestamp = null; - - /** @var string|null Name of the author */ - protected $author = null; - - /** @var string|null Body of the feed */ - protected $content = null; - - /** @var array List of links to media objects */ - protected $enclosures = []; - - /** @var array List of category names or tags */ - protected $categories = []; - - /** @var string Unique ID for the current item */ - protected $uid = null; + protected ?string $uri = null; + protected ?string $title = null; + protected ?int $timestamp = null; + protected ?string $author = null; + protected ?string $content = null; + protected array $enclosures = []; + protected array $categories = []; + protected ?string $uid = null; + protected array $misc = []; + + public function __construct() + { + } - /** @var array Associative list of additional parameters */ - protected $misc = []; // Custom parameters + public static function fromArray(array $itemArray): self + { + $item = new self(); + foreach ($itemArray as $key => $value) { + $item->__set($key, $value); + } + return $item; + } - /** - * Create object from legacy item. - * - * The provided array must be an associative array of key-value-pairs, where - * keys may correspond to any of the properties of this class. - * - * Example use: - * - * ```PHP - * <?php - * $item = array(); - * - * $item['uri'] = 'https://www.github.com/rss-bridge/rss-bridge/'; - * $item['title'] = 'Title'; - * $item['timestamp'] = strtotime('now'); - * $item['author'] = 'Unknown author'; - * $item['content'] = 'Hello World!'; - * $item['enclosures'] = array('https://github.com/favicon.ico'); - * $item['categories'] = array('php', 'rss-bridge', 'awesome'); - * - * $feedItem = new \FeedItem($item); - * - * ``` - * - * The result of the code above is the same as the code below: - * - * ```PHP - * <?php - * $feedItem = \FeedItem(); - * - * $feedItem->uri = 'https://www.github.com/rss-bridge/rss-bridge/'; - * $feedItem->title = 'Title'; - * $feedItem->timestamp = strtotime('now'); - * $feedItem->autor = 'Unknown author'; - * $feedItem->content = 'Hello World!'; - * $feedItem->enclosures = array('https://github.com/favicon.ico'); - * $feedItem->categories = array('php', 'rss-bridge', 'awesome'); - * ``` - * - * @param array $item (optional) A legacy item (empty: no legacy support). - * @return object A new object of this class - */ - public function __construct($item = []) + public function __set($name, $value) { - if (!is_array($item)) { - Debug::log('Item must be an array!'); + switch ($name) { + case 'uri': + $this->setURI($value); + break; + case 'title': + $this->setTitle($value); + break; + case 'timestamp': + $this->setTimestamp($value); + break; + case 'author': + $this->setAuthor($value); + break; + case 'content': + $this->setContent($value); + break; + case 'enclosures': + $this->setEnclosures($value); + break; + case 'categories': + $this->setCategories($value); + break; + case 'uid': + $this->setUid($value); + break; + default: + $this->addMisc($name, $value); } + } - foreach ($item as $key => $value) { - $this->__set($key, $value); + public function __get($name) + { + switch ($name) { + case 'uri': + return $this->getURI(); + case 'title': + return $this->getTitle(); + case 'timestamp': + return $this->getTimestamp(); + case 'author': + return $this->getAuthor(); + case 'content': + return $this->getContent(); + case 'enclosures': + return $this->getEnclosures(); + case 'categories': + return $this->getCategories(); + case 'uid': + return $this->getUid(); + default: + if (array_key_exists($name, $this->misc)) { + return $this->misc[$name]; + } + return null; } } - /** - * Get current URI. - * - * Use {@see FeedItem::setURI()} to set the URI. - * - * @return string|null The URI or null if it hasn't been set. - */ - public function getURI() + public function getURI(): ?string { return $this->uri; } @@ -138,8 +99,7 @@ class FeedItem * _Remarks_: Uses the attribute "href" or "src" if the provided URI is an * object of simple_html_dom_node. * - * @param object|string $uri URI to the full article. - * @return self + * @param simple_html_dom_node|object|string $uri URI to the full article. */ public function setURI($uri) { @@ -156,325 +116,174 @@ class FeedItem } if (!is_string($uri)) { Debug::log(sprintf('Expected $uri to be string but got %s', gettype($uri))); - return $this; + return; } $uri = trim($uri); // Intentionally doing a weak url validation here because FILTER_VALIDATE_URL is too strict if (!preg_match('#^https?://#i', $uri)) { Debug::log(sprintf('Not a valid url: "%s"', $uri)); - return $this; + return; } $this->uri = $uri; - return $this; } - /** - * Get current title. - * - * Use {@see FeedItem::setTitle()} to set the title. - * - * @return string|null The current title or null if it hasn't been set. - */ - public function getTitle() + public function getTitle(): ?string { return $this->title; } - /** - * Set title. - * - * Use {@see FeedItem::getTitle()} to get the title. - * - * _Note_: Removes whitespace from beginning and end of the title. - * - * @param string $title The title - * @return self - */ public function setTitle($title) { - $this->title = null; // Clear previous data - + $this->title = null; if (!is_string($title)) { Debug::log('Title must be a string!'); } else { $this->title = truncate(trim($title)); } - - return $this; } - /** - * Get current timestamp. - * - * Use {@see FeedItem::setTimestamp()} to set the timestamp. - * - * @return int|null The current timestamp or null if it hasn't been set. - */ - public function getTimestamp() + public function getTimestamp(): ?int { return $this->timestamp; } - /** - * Set timestamp of first release. - * - * _Note_: The timestamp should represent the number of seconds since - * January 1 1970 00:00:00 GMT (Unix time). - * - * _Remarks_: If the provided timestamp is a string (not numeric), this - * function automatically attempts to parse the string using - * [strtotime](http://php.net/manual/en/function.strtotime.php) - * - * @link http://php.net/manual/en/function.strtotime.php strtotime (PHP) - * @link https://en.wikipedia.org/wiki/Unix_time Unix time (Wikipedia) - * - * @param string|int $timestamp A timestamp of when the item was first released - * @return self - */ public function setTimestamp($timestamp) { - $this->timestamp = null; // Clear previous data - + $this->timestamp = null; if ( !is_numeric($timestamp) && !$timestamp = strtotime($timestamp) ) { Debug::log('Unable to parse timestamp!'); } - if ($timestamp <= 0) { Debug::log('Timestamp must be greater than zero!'); } else { $this->timestamp = $timestamp; } - - return $this; } - /** - * Get the current author name. - * - * Use {@see FeedItem::setAuthor()} to set the author. - * - * @return string|null The author or null if it hasn't been set. - */ - public function getAuthor() + public function getAuthor(): ?string { return $this->author; } - /** - * Set the author name. - * - * Use {@see FeedItem::getAuthor()} to get the author. - * - * @param string $author The author name. - * @return self - */ public function setAuthor($author) { - $this->author = null; // Clear previous data - + $this->author = null; if (!is_string($author)) { Debug::log('Author must be a string!'); } else { $this->author = $author; } - return $this; } - /** - * Get item content. - * - * Use {@see FeedItem::setContent()} to set the item content. - * - * @return string|null The item content or null if it hasn't been set. - */ - public function getContent() + public function getContent(): ?string { return $this->content; } /** - * Set item content. - * - * Note: This function casts objects of type simple_html_dom and - * simple_html_dom_node to string. - * - * Use {@see FeedItem::getContent()} to get the current item content. - * * @param string|object $content The item content as text or simple_html_dom object. - * @return self */ public function setContent($content) { - $this->content = null; // Clear previous data - + $this->content = null; if ( $content instanceof simple_html_dom || $content instanceof simple_html_dom_node ) { - $content = (string)$content; + $content = (string) $content; } - if (is_string($content)) { $this->content = $content; } else { Debug::log(sprintf('Feed content must be a string but got %s', gettype($content))); } - - return $this; } - /** - * Get item enclosures. - * - * Use {@see FeedItem::setEnclosures()} to set feed enclosures. - * - * @return array Enclosures as array of enclosure URIs. - */ - public function getEnclosures() + public function getEnclosures(): array { return $this->enclosures; } - /** - * Set item enclosures. - * - * Use {@see FeedItem::getEnclosures()} to get the current item enclosures. - * - * @param array $enclosures Array of enclosures, where each element links to - * one enclosure. - * @return self - */ public function setEnclosures($enclosures) { $this->enclosures = []; - if (is_array($enclosures)) { - foreach ($enclosures as $enclosure) { - if ( - !filter_var( - $enclosure, - FILTER_VALIDATE_URL, - FILTER_FLAG_PATH_REQUIRED - ) - ) { - Debug::log('Each enclosure must contain a scheme, host and path!'); - } elseif (!in_array($enclosure, $this->enclosures)) { - $this->enclosures[] = $enclosure; - } - } - } else { + if (!is_array($enclosures)) { Debug::log('Enclosures must be an array!'); + return; + } + foreach ($enclosures as $enclosure) { + if ( + !filter_var( + $enclosure, + FILTER_VALIDATE_URL, + FILTER_FLAG_PATH_REQUIRED + ) + ) { + Debug::log('Each enclosure must contain a scheme, host and path!'); + } elseif (!in_array($enclosure, $this->enclosures)) { + $this->enclosures[] = $enclosure; + } } - - return $this; } - /** - * Get item categories. - * - * Use {@see FeedItem::setCategories()} to set item categories. - * - * @param array The item categories. - */ - public function getCategories() + public function getCategories(): array { return $this->categories; } - /** - * Set item categories. - * - * Use {@see FeedItem::getCategories()} to get the current item categories. - * - * @param array $categories Array of categories, where each element defines - * a single category name. - * @return self - */ public function setCategories($categories) { $this->categories = []; - if (is_array($categories)) { - foreach ($categories as $category) { - if (!is_string($category)) { - Debug::log('Category must be a string!'); - } else { - $this->categories[] = $category; - } - } - } else { + if (!is_array($categories)) { Debug::log('Categories must be an array!'); + return; + } + foreach ($categories as $category) { + if (is_string($category)) { + $this->categories[] = $category; + } else { + Debug::log('Category must be a string!'); + } } - - return $this; } - /** - * Get unique id - * - * Use {@see FeedItem::setUid()} to set the unique id. - * - * @param string The unique id. - */ - public function getUid() + public function getUid(): ?string { return $this->uid; } - /** - * Set unique id. - * - * Use {@see FeedItem::getUid()} to get the unique id. - * - * @param string $uid A string that uniquely identifies the current item - * @return self - */ public function setUid($uid) { - $this->uid = null; // Clear previous data - + $this->uid = null; if (!is_string($uid)) { Debug::log('Unique id must be a string!'); } elseif (preg_match('/^[a-f0-9]{40}$/', $uid)) { - // keep id if it already is a SHA-1 hash + // keep id if it already is SHA-1 hash $this->uid = $uid; } else { $this->uid = sha1($uid); } - - return $this; } - /** - * Add miscellaneous elements to the item. - * - * @param string $key Name of the element. - * @param mixed $value Value of the element. - * @return self - */ - public function addMisc($key, $value) + public function addMisc($name, $value) { - if (!is_string($key)) { + if (!is_string($name)) { Debug::log('Key must be a string!'); - } elseif (in_array($key, get_object_vars($this))) { + } elseif (in_array($name, get_object_vars($this))) { Debug::log('Key must be unique!'); } else { - $this->misc[$key] = $value; + $this->misc[$name] = $value; } - return $this; } - /** - * Transform current object to array - * - * @return array - */ - public function toArray() + public function toArray(): array { return array_merge( [ @@ -490,87 +299,4 @@ class FeedItem $this->misc ); } - - /** - * Set item property - * - * Allows simple assignment to parameters. This method is slower, but easier - * to implement in some cases: - * - * ```PHP - * $item = new \FeedItem(); - * $item->content = 'Hello World!'; - * $item->my_id = 42; - * ``` - * - * @param string $name Property name - * @param mixed $value Property value - */ - public function __set($name, $value) - { - switch ($name) { - case 'uri': - $this->setURI($value); - break; - case 'title': - $this->setTitle($value); - break; - case 'timestamp': - $this->setTimestamp($value); - break; - case 'author': - $this->setAuthor($value); - break; - case 'content': - $this->setContent($value); - break; - case 'enclosures': - $this->setEnclosures($value); - break; - case 'categories': - $this->setCategories($value); - break; - case 'uid': - $this->setUid($value); - break; - default: - $this->addMisc($name, $value); - } - } - - /** - * Get item property - * - * Allows simple assignment to parameters. This method is slower, but easier - * to implement in some cases. - * - * @param string $name Property name - * @return mixed Property value - */ - public function __get($name) - { - switch ($name) { - case 'uri': - return $this->getURI(); - case 'title': - return $this->getTitle(); - case 'timestamp': - return $this->getTimestamp(); - case 'author': - return $this->getAuthor(); - case 'content': - return $this->getContent(); - case 'enclosures': - return $this->getEnclosures(); - case 'categories': - return $this->getCategories(); - case 'uid': - return $this->getUid(); - default: - if (array_key_exists($name, $this->misc)) { - return $this->misc[$name]; - } - return null; - } - } } |