Chris@0: _loadExtensions(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set a single author Chris@0: * Chris@0: * The following option keys are supported: Chris@0: * 'name' => (string) The name Chris@0: * 'email' => (string) An optional email Chris@0: * 'uri' => (string) An optional and valid URI Chris@0: * Chris@0: * @param array $author Chris@0: * @throws Exception\InvalidArgumentException If any value of $author not follow the format. Chris@0: * @return Entry Chris@0: */ Chris@0: public function addAuthor(array $author) Chris@0: { Chris@0: // Check array values Chris@12: if (! array_key_exists('name', $author) Chris@0: || empty($author['name']) Chris@12: || ! is_string($author['name']) Chris@0: ) { Chris@0: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: author array must include a "name" key with a non-empty string value' Chris@12: ); Chris@0: } Chris@0: Chris@0: if (isset($author['email'])) { Chris@12: if (empty($author['email']) || ! is_string($author['email'])) { Chris@0: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: "email" array value must be a non-empty string' Chris@12: ); Chris@0: } Chris@0: } Chris@0: if (isset($author['uri'])) { Chris@12: if (empty($author['uri']) || ! is_string($author['uri']) || Chris@12: ! Uri::factory($author['uri'])->isValid() Chris@0: ) { Chris@0: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI' Chris@12: ); Chris@0: } Chris@0: } Chris@0: Chris@0: $this->data['authors'][] = $author; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set an array with feed authors Chris@0: * Chris@0: * @see addAuthor Chris@0: * @param array $authors Chris@0: * @return Entry Chris@0: */ Chris@0: public function addAuthors(array $authors) Chris@0: { Chris@0: foreach ($authors as $author) { Chris@0: $this->addAuthor($author); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed character encoding Chris@0: * Chris@0: * @param string $encoding Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setEncoding($encoding) Chris@0: { Chris@12: if (empty($encoding) || ! is_string($encoding)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['encoding'] = $encoding; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the feed character encoding Chris@0: * Chris@0: * @return string|null Chris@0: */ Chris@0: public function getEncoding() Chris@0: { Chris@12: if (! array_key_exists('encoding', $this->data)) { Chris@0: return 'UTF-8'; Chris@0: } Chris@0: return $this->data['encoding']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the copyright entry Chris@0: * Chris@0: * @param string $copyright Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setCopyright($copyright) Chris@0: { Chris@12: if (empty($copyright) || ! is_string($copyright)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['copyright'] = $copyright; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the entry's content Chris@0: * Chris@0: * @param string $content Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setContent($content) Chris@0: { Chris@12: if (empty($content) || ! is_string($content)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['content'] = $content; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed creation date Chris@0: * Chris@17: * @param null|int|DateTimeInterface $date Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setDateCreated($date = null) Chris@0: { Chris@0: if ($date === null) { Chris@0: $date = new DateTime(); Chris@17: } Chris@17: if (is_int($date)) { Chris@0: $date = new DateTime('@' . $date); Chris@17: } Chris@17: if (! $date instanceof DateTimeInterface) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid DateTime object or UNIX Timestamp passed as parameter' Chris@12: ); Chris@0: } Chris@0: $this->data['dateCreated'] = $date; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed modification date Chris@0: * Chris@17: * @param null|int|DateTimeInterface $date Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setDateModified($date = null) Chris@0: { Chris@0: if ($date === null) { Chris@0: $date = new DateTime(); Chris@17: } Chris@17: if (is_int($date)) { Chris@0: $date = new DateTime('@' . $date); Chris@17: } Chris@17: if (! $date instanceof DateTimeInterface) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid DateTime object or UNIX Timestamp passed as parameter' Chris@12: ); Chris@0: } Chris@0: $this->data['dateModified'] = $date; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed description Chris@0: * Chris@0: * @param string $description Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setDescription($description) Chris@0: { Chris@12: if (empty($description) || ! is_string($description)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['description'] = $description; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed ID Chris@0: * Chris@0: * @param string $id Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setId($id) Chris@0: { Chris@12: if (empty($id) || ! is_string($id)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['id'] = $id; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set a link to the HTML source of this entry Chris@0: * Chris@0: * @param string $link Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setLink($link) Chris@0: { Chris@12: if (empty($link) || ! is_string($link) || ! Uri::factory($link)->isValid()) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: parameter must be a non-empty string and valid URI/IRI' Chris@12: ); Chris@0: } Chris@0: $this->data['link'] = $link; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the number of comments associated with this entry Chris@0: * Chris@0: * @param int $count Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setCommentCount($count) Chris@0: { Chris@12: if (! is_numeric($count) || (int) $count != $count || (int) $count < 0) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: "count" must be a positive integer number or zero' Chris@12: ); Chris@0: } Chris@0: $this->data['commentCount'] = (int) $count; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set a link to a HTML page containing comments associated with this entry Chris@0: * Chris@0: * @param string $link Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setCommentLink($link) Chris@0: { Chris@12: if (empty($link) || ! is_string($link) || ! Uri::factory($link)->isValid()) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: "link" must be a non-empty string and valid URI/IRI' Chris@12: ); Chris@0: } Chris@0: $this->data['commentLink'] = $link; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set a link to an XML feed for any comments associated with this entry Chris@0: * Chris@0: * @param array $link Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setCommentFeedLink(array $link) Chris@0: { Chris@12: if (! isset($link['uri']) || ! is_string($link['uri']) || ! Uri::factory($link['uri'])->isValid()) { Chris@12: throw new Exception\InvalidArgumentException( Chris@12: 'Invalid parameter: "link" must be a non-empty string and valid URI/IRI' Chris@12: ); Chris@0: } Chris@12: if (! isset($link['type']) || ! in_array($link['type'], ['atom', 'rss', 'rdf'])) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: "type" must be one' Chris@0: . ' of "atom", "rss" or "rdf"'); Chris@0: } Chris@12: if (! isset($this->data['commentFeedLinks'])) { Chris@0: $this->data['commentFeedLinks'] = []; Chris@0: } Chris@0: $this->data['commentFeedLinks'][] = $link; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set a links to an XML feed for any comments associated with this entry. Chris@0: * Each link is an array with keys "uri" and "type", where type is one of: Chris@0: * "atom", "rss" or "rdf". Chris@0: * Chris@0: * @param array $links Chris@0: * @return Entry Chris@0: */ Chris@0: public function setCommentFeedLinks(array $links) Chris@0: { Chris@0: foreach ($links as $link) { Chris@0: $this->setCommentFeedLink($link); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the feed title Chris@0: * Chris@0: * @param string $title Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setTitle($title) Chris@0: { Chris@16: if ((empty($title) && ! is_numeric($title)) || ! is_string($title)) { Chris@0: throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string'); Chris@0: } Chris@0: $this->data['title'] = $title; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get an array with feed authors Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function getAuthors() Chris@0: { Chris@12: if (! array_key_exists('authors', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['authors']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry content Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getContent() Chris@0: { Chris@12: if (! array_key_exists('content', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['content']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry copyright information Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getCopyright() Chris@0: { Chris@12: if (! array_key_exists('copyright', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['copyright']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry creation date Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getDateCreated() Chris@0: { Chris@12: if (! array_key_exists('dateCreated', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['dateCreated']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry modification date Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getDateModified() Chris@0: { Chris@12: if (! array_key_exists('dateModified', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['dateModified']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry description Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getDescription() Chris@0: { Chris@12: if (! array_key_exists('description', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['description']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry ID Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getId() Chris@0: { Chris@12: if (! array_key_exists('id', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['id']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get a link to the HTML source Chris@0: * Chris@0: * @return string|null Chris@0: */ Chris@0: public function getLink() Chris@0: { Chris@12: if (! array_key_exists('link', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['link']; Chris@0: } Chris@0: Chris@0: Chris@0: /** Chris@0: * Get all links Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function getLinks() Chris@0: { Chris@12: if (! array_key_exists('links', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['links']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry title Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getTitle() Chris@0: { Chris@12: if (! array_key_exists('title', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['title']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the number of comments/replies for current entry Chris@0: * Chris@0: * @return int Chris@0: */ Chris@0: public function getCommentCount() Chris@0: { Chris@12: if (! array_key_exists('commentCount', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['commentCount']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns a URI pointing to the HTML page where comments can be made on this entry Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getCommentLink() Chris@0: { Chris@12: if (! array_key_exists('commentLink', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['commentLink']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns an array of URIs pointing to a feed of all comments for this entry Chris@0: * where the array keys indicate the feed type (atom, rss or rdf). Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getCommentFeedLinks() Chris@0: { Chris@12: if (! array_key_exists('commentFeedLinks', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['commentFeedLinks']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Add an entry category Chris@0: * Chris@0: * @param array $category Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function addCategory(array $category) Chris@0: { Chris@12: if (! isset($category['term'])) { Chris@0: throw new Exception\InvalidArgumentException('Each category must be an array and ' Chris@0: . 'contain at least a "term" element containing the machine ' Chris@0: . ' readable category name'); Chris@0: } Chris@0: if (isset($category['scheme'])) { Chris@0: if (empty($category['scheme']) Chris@12: || ! is_string($category['scheme']) Chris@12: || ! Uri::factory($category['scheme'])->isValid() Chris@0: ) { Chris@0: throw new Exception\InvalidArgumentException('The Atom scheme or RSS domain of' Chris@0: . ' a category must be a valid URI'); Chris@0: } Chris@0: } Chris@12: if (! isset($this->data['categories'])) { Chris@0: $this->data['categories'] = []; Chris@0: } Chris@0: $this->data['categories'][] = $category; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set an array of entry categories Chris@0: * Chris@0: * @param array $categories Chris@0: * @return Entry Chris@0: */ Chris@0: public function addCategories(array $categories) Chris@0: { Chris@0: foreach ($categories as $category) { Chris@0: $this->addCategory($category); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get the entry categories Chris@0: * Chris@0: * @return string|null Chris@0: */ Chris@0: public function getCategories() Chris@0: { Chris@12: if (! array_key_exists('categories', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['categories']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an enclosure to the entry. The array parameter may contain the Chris@0: * keys 'uri', 'type' and 'length'. Only 'uri' is required for Atom, though the Chris@0: * others must also be provided or RSS rendering (where they are required) Chris@0: * will throw an Exception. Chris@0: * Chris@0: * @param array $enclosure Chris@0: * @throws Exception\InvalidArgumentException Chris@0: * @return Entry Chris@0: */ Chris@0: public function setEnclosure(array $enclosure) Chris@0: { Chris@12: if (! isset($enclosure['uri'])) { Chris@0: throw new Exception\InvalidArgumentException('Enclosure "uri" is not set'); Chris@0: } Chris@12: if (! Uri::factory($enclosure['uri'])->isValid()) { Chris@0: throw new Exception\InvalidArgumentException('Enclosure "uri" is not a valid URI/IRI'); Chris@0: } Chris@0: $this->data['enclosure'] = $enclosure; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieve an array of all enclosures to be added to entry. Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function getEnclosure() Chris@0: { Chris@12: if (! array_key_exists('enclosure', $this->data)) { Chris@0: return; Chris@0: } Chris@0: return $this->data['enclosure']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Unset a specific data point Chris@0: * Chris@0: * @param string $name Chris@0: * @return Entry Chris@0: */ Chris@0: public function remove($name) Chris@0: { Chris@0: if (isset($this->data[$name])) { Chris@0: unset($this->data[$name]); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get registered extensions Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function getExtensions() Chris@0: { Chris@0: return $this->extensions; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return an Extension object with the matching name (postfixed with _Entry) Chris@0: * Chris@0: * @param string $name Chris@0: * @return object Chris@0: */ Chris@0: public function getExtension($name) Chris@0: { Chris@0: if (array_key_exists($name . '\\Entry', $this->extensions)) { Chris@0: return $this->extensions[$name . '\\Entry']; Chris@0: } Chris@0: return; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the current feed type being exported to "rss" or "atom". This allows Chris@0: * other objects to gracefully choose whether to execute or not, depending Chris@0: * on their appropriateness for the current type, e.g. renderers. Chris@0: * Chris@0: * @param string $type Chris@0: * @return Entry Chris@0: */ Chris@0: public function setType($type) Chris@0: { Chris@0: $this->type = $type; Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieve the current or last feed type exported. Chris@0: * Chris@0: * @return string Value will be "rss" or "atom" Chris@0: */ Chris@0: public function getType() Chris@0: { Chris@0: return $this->type; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Method overloading: call given method on first extension implementing it Chris@0: * Chris@0: * @param string $method Chris@0: * @param array $args Chris@0: * @return mixed Chris@0: * @throws Exception\BadMethodCallException if no extensions implements the method Chris@0: */ Chris@0: public function __call($method, $args) Chris@0: { Chris@0: foreach ($this->extensions as $extension) { Chris@0: try { Chris@0: return call_user_func_array([$extension, $method], $args); Chris@0: } catch (\BadMethodCallException $e) { Chris@0: } Chris@0: } Chris@0: throw new Exception\BadMethodCallException('Method: ' . $method Chris@0: . ' does not exist and could not be located on a registered Extension'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates a new Zend\Feed\Writer\Source data container for use. This is NOT Chris@0: * added to the current feed automatically, but is necessary to create a Chris@0: * container with some initial values preset based on the current feed data. Chris@0: * Chris@0: * @return Source Chris@0: */ Chris@0: public function createSource() Chris@0: { Chris@0: $source = new Source; Chris@0: if ($this->getEncoding()) { Chris@0: $source->setEncoding($this->getEncoding()); Chris@0: } Chris@0: $source->setType($this->getType()); Chris@0: return $source; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Appends a Zend\Feed\Writer\Entry object representing a new entry/item Chris@0: * the feed data container's internal group of entries. Chris@0: * Chris@0: * @param Source $source Chris@0: * @return Entry Chris@0: */ Chris@0: public function setSource(Source $source) Chris@0: { Chris@0: $this->data['source'] = $source; Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @return Source Chris@0: */ Chris@0: public function getSource() Chris@0: { Chris@0: if (isset($this->data['source'])) { Chris@0: return $this->data['source']; Chris@0: } Chris@0: return; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Load extensions from Zend\Feed\Writer\Writer Chris@0: * Chris@0: * @return void Chris@0: */ Chris@12: // @codingStandardsIgnoreStart Chris@0: protected function _loadExtensions() Chris@0: { Chris@12: // @codingStandardsIgnoreEnd Chris@0: $all = Writer::getExtensions(); Chris@0: $manager = Writer::getExtensionManager(); Chris@0: $exts = $all['entry']; Chris@0: foreach ($exts as $ext) { Chris@0: $this->extensions[$ext] = $manager->get($ext); Chris@0: $this->extensions[$ext]->setEncoding($this->getEncoding()); Chris@0: } Chris@0: } Chris@0: }