File manager - Edit - /home/opticamezl/www/newok/Feed.tar
Back
FeedParser.php 0000644 00000017701 15173004413 0007301 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; use Joomla\CMS\Feed\Parser\NamespaceParserInterface; use Joomla\CMS\Filter\InputFilter; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Feed Parser class. * * @since 3.1.4 */ abstract class FeedParser { /** * The feed element name for the entry elements. * * @var string * @since 3.1.4 */ protected $entryElementName = 'entry'; /** * Array of NamespaceParserInterface objects * * @var array * @since 3.1.4 */ protected $namespaces = []; /** * The XMLReader stream object for the feed. * * @var \XMLReader * @since 3.1.4 */ protected $stream; /** * The InputFilter * * @var InputFilter * @since 3.9.25 */ protected $inputFilter; /** * Constructor. * * @param \XMLReader $stream The XMLReader stream object for the feed. * @param InputFilter $inputFilter The InputFilter object to be used * * @since 3.1.4 */ public function __construct(\XMLReader $stream, InputFilter $inputFilter = null) { $this->stream = $stream; $this->inputFilter = $inputFilter ?: InputFilter::getInstance([], [], 1, 1); } /** * Method to parse the feed into a JFeed object. * * @return Feed * * @since 3.1.4 */ public function parse() { $feed = new Feed(); // Detect the feed version. $this->initialise(); // Let's get this party started... do { // Expand the element for processing. $el = new \SimpleXMLElement($this->stream->readOuterXml()); // Get the list of namespaces used within this element. $ns = $el->getNamespaces(true); // Get an array of available namespace objects for the element. $namespaces = []; foreach ($ns as $prefix => $uri) { // Ignore the empty namespace prefix. if (empty($prefix)) { continue; } // Get the necessary namespace objects for the element. $namespace = $this->fetchNamespace($prefix); if ($namespace) { $namespaces[] = $namespace; } } // Process the element. $this->processElement($feed, $el, $namespaces); // Skip over this element's children since it has been processed. $this->moveToClosingElement(); } while ($this->moveToNextElement()); return $feed; } /** * Method to register a namespace handler object. * * @param string $prefix The XML namespace prefix for which to register the namespace object. * @param NamespaceParserInterface $namespace The namespace object to register. * * @return FeedParser * * @since 3.1.4 */ public function registerNamespace($prefix, NamespaceParserInterface $namespace) { $this->namespaces[$prefix] = $namespace; return $this; } /** * Method to initialise the feed for parsing. If child parsers need to detect versions or other * such things this is where you'll want to implement that logic. * * @return void * * @since 3.1.4 */ abstract protected function initialise(); /** * Method to parse a specific feed element. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * @param array $namespaces The array of relevant namespace objects to process for the element. * * @return void * * @since 3.1.4 */ protected function processElement(Feed $feed, \SimpleXMLElement $el, array $namespaces) { // Build the internal method name. $method = 'handle' . ucfirst($el->getName()); // If we are dealing with an item then it is feed entry time. if ($el->getName() == $this->entryElementName) { // Create a new feed entry for the item. $entry = new FeedEntry(); // First call the internal method. $this->processFeedEntry($entry, $el); foreach ($namespaces as $namespace) { if ($namespace instanceof NamespaceParserInterface) { $namespace->processElementForFeedEntry($entry, $el); } } // Add the new entry to the feed. $feed->addEntry($entry); return; } // Otherwise we treat it like any other element. // First call the internal method. if (\is_callable([$this, $method])) { $this->$method($feed, $el); } foreach ($namespaces as $namespace) { if ($namespace instanceof NamespaceParserInterface) { $namespace->processElementForFeed($feed, $el); } } } /** * Method to get a namespace object for a given namespace prefix. * * @param string $prefix The XML prefix for which to fetch the namespace object. * * @return mixed NamespaceParserInterface or false if none exists. * * @since 3.1.4 */ protected function fetchNamespace($prefix) { if (isset($this->namespaces[$prefix])) { return $this->namespaces[$prefix]; } $className = \get_class($this) . ucfirst($prefix); if (class_exists($className)) { $this->namespaces[$prefix] = new $className(); return $this->namespaces[$prefix]; } return false; } /** * Method to move the stream parser to the next XML element node. * * @param string $name The name of the element for which to move the stream forward until is found. * * @return boolean True if the stream parser is on an XML element node. * * @since 3.1.4 */ protected function moveToNextElement($name = null) { // Only keep looking until the end of the stream. while ($this->stream->read()) { // As soon as we get to the next ELEMENT node we are done. if ($this->stream->nodeType == \XMLReader::ELEMENT) { // If we are looking for a specific name make sure we have it. if (isset($name) && ($this->stream->name != $name)) { continue; } return true; } } return false; } /** * Method to move the stream parser to the closing XML node of the current element. * * @return void * * @since 3.1.4 * @throws \RuntimeException If the closing tag cannot be found. */ protected function moveToClosingElement() { // If we are on a self-closing tag then there is nothing to do. if ($this->stream->isEmptyElement) { return; } // Get the name and depth for the current node so that we can match the closing node. $name = $this->stream->name; $depth = $this->stream->depth; // Only keep looking until the end of the stream. while ($this->stream->read()) { // If we have an END_ELEMENT node with the same name and depth as the node we started with we have a bingo. :-) if (($this->stream->name == $name) && ($this->stream->depth == $depth) && ($this->stream->nodeType == \XMLReader::END_ELEMENT)) { return; } } throw new \RuntimeException('Unable to find the closing XML node.'); } } Feed.php 0000644 00000024610 15173004413 0006121 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; use Joomla\CMS\Date\Date; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Class to encapsulate a feed for the Joomla Platform. * * @property FeedPerson $author Person responsible for feed content. * @property array $categories Categories to which the feed belongs. * @property array $contributors People who contributed to the feed content. * @property string $copyright Information about rights, e.g. copyrights, held in and over the feed. * @property string $description A phrase or sentence describing the feed. * @property string $generator A string indicating the program used to generate the feed. * @property FeedLink|null $image FeedLink object containing feed image properties. * @property Date $publishedDate The publication date for the feed content. * @property string $title A human readable title for the feed. * @property Date $updatedDate The last time the content of the feed changed. * @property string $uri Universal, permanent identifier for the feed. * * @since 3.1.4 */ class Feed implements \ArrayAccess, \Countable { /** * @var array The entry properties. * @since 3.1.4 */ protected $properties = [ 'uri' => '', 'title' => '', 'updatedDate' => '', 'description' => '', 'categories' => [], 'contributors' => [], ]; /** * @var array The list of feed entry objects. * @since 3.1.4 */ protected $entries = []; /** * Magic method to return values for feed properties. * * @param string $name The name of the property. * * @return mixed * * @since 3.1.4 */ public function __get($name) { return $this->properties[$name] ?? null; } /** * Magic method to set values for feed properties. * * @param string $name The name of the property. * @param mixed $value The value to set for the property. * * @return void * * @since 3.1.4 */ public function __set($name, $value) { // Ensure that setting a date always sets a Date instance. if ((($name === 'updatedDate') || ($name === 'publishedDate')) && !($value instanceof Date)) { $value = new Date($value); } // Validate that any authors that are set are instances of JFeedPerson or null. if (($name === 'author') && (!($value instanceof FeedPerson) || ($value === null))) { throw new \InvalidArgumentException( sprintf( '%1$s "author" must be an instance of Joomla\\CMS\\Feed\\FeedPerson. %2$s given.', \get_class($this), \gettype($value) === 'object' ? \get_class($value) : \gettype($value) ) ); } // Disallow setting categories or contributors directly. if (\in_array($name, ['categories', 'contributors'])) { throw new \InvalidArgumentException( sprintf( 'Cannot directly set %1$s property "%2$s".', \get_class($this), $name ) ); } $this->properties[$name] = $value; } /** * Method to add a category to the feed object. * * @param string $name The name of the category to add. * @param string $uri The optional URI for the category to add. * * @return Feed * * @since 3.1.4 */ public function addCategory($name, $uri = '') { $this->properties['categories'][$name] = $uri; return $this; } /** * Method to add a contributor to the feed object. * * @param string $name The full name of the person to add. * @param string $email The email address of the person to add. * @param string $uri The optional URI for the person to add. * @param string $type The optional type of person to add. * * @return Feed * * @since 3.1.4 */ public function addContributor($name, $email, $uri = null, $type = null) { $contributor = new FeedPerson($name, $email, $uri, $type); // If the new contributor already exists then there is nothing to do, so just return. foreach ($this->properties['contributors'] as $c) { if ($c == $contributor) { return $this; } } // Add the new contributor. $this->properties['contributors'][] = $contributor; return $this; } /** * Method to add an entry to the feed object. * * @param FeedEntry $entry The entry object to add. * * @return Feed * * @since 3.1.4 */ public function addEntry(FeedEntry $entry) { // If the new entry already exists then there is nothing to do, so just return. foreach ($this->entries as $e) { if ($e == $entry) { return $this; } } // Add the new entry. $this->entries[] = $entry; return $this; } /** * Returns a count of the number of entries in the feed. * * This method is here to implement the Countable interface. * You can call it by doing count($feed) rather than $feed->count(); * * @return integer number of entries in the feed. */ #[\ReturnTypeWillChange] public function count() { return \count($this->entries); } /** * Whether or not an offset exists. This method is executed when using isset() or empty() on * objects implementing ArrayAccess. * * @param mixed $offset An offset to check for. * * @return boolean * * @see ArrayAccess::offsetExists() * @since 3.1.4 */ #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->entries[$offset]); } /** * Returns the value at specified offset. * * @param mixed $offset The offset to retrieve. * * @return mixed The value at the offset. * * @see ArrayAccess::offsetGet() * @since 3.1.4 */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->entries[$offset]; } /** * Assigns a value to the specified offset. * * @param mixed $offset The offset to assign the value to. * @param FeedEntry $value The JFeedEntry to set. * * @return boolean * * @see ArrayAccess::offsetSet() * @since 3.1.4 * @throws \InvalidArgumentException */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!($value instanceof FeedEntry)) { throw new \InvalidArgumentException( sprintf( '%1$s entries must be an instance of Joomla\\CMS\\Feed\\FeedPerson. %2$s given.', \get_class($this), \gettype($value) === 'object' ? \get_class($value) : \gettype($value) ) ); } $this->entries[$offset] = $value; return true; } /** * Unsets an offset. * * @param mixed $offset The offset to unset. * * @return void * * @see ArrayAccess::offsetUnset() * @since 3.1.4 */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->entries[$offset]); } /** * Method to remove a category from the feed object. * * @param string $name The name of the category to remove. * * @return Feed * * @since 3.1.4 */ public function removeCategory($name) { unset($this->properties['categories'][$name]); return $this; } /** * Method to remove a contributor from the feed object. * * @param FeedPerson $contributor The person object to remove. * * @return Feed * * @since 3.1.4 */ public function removeContributor(FeedPerson $contributor) { // If the contributor exists remove it. foreach ($this->properties['contributors'] as $k => $c) { if ($c == $contributor) { unset($this->properties['contributors'][$k]); $this->properties['contributors'] = array_values($this->properties['contributors']); return $this; } } return $this; } /** * Method to remove an entry from the feed object. * * @param FeedEntry $entry The entry object to remove. * * @return Feed * * @since 3.1.4 */ public function removeEntry(FeedEntry $entry) { // If the entry exists remove it. foreach ($this->entries as $k => $e) { if ($e == $entry) { unset($this->entries[$k]); $this->entries = array_values($this->entries); return $this; } } return $this; } /** * Shortcut method to set the author for the feed object. * * @param string $name The full name of the person to set. * @param string $email The email address of the person to set. * @param string $uri The optional URI for the person to set. * @param string $type The optional type of person to set. * * @return Feed * * @since 3.1.4 */ public function setAuthor($name, $email, $uri = null, $type = null) { $author = new FeedPerson($name, $email, $uri, $type); $this->properties['author'] = $author; return $this; } /** * Method to reverse the items if display is set to 'oldest first' * * @return Feed * * @since 3.1.4 */ public function reverseItems() { if (\is_array($this->entries) && !empty($this->entries)) { $this->entries = array_reverse($this->entries); } return $this; } } FeedEntry.php 0000644 00000020252 15173004413 0007141 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; use Joomla\CMS\Date\Date; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Class to encapsulate a feed entry for the Joomla Platform. * * @property FeedPerson $author Person responsible for feed entry content. * @property array $categories Categories to which the feed entry belongs. * @property string $content The content of the feed entry. * @property array $contributors People who contributed to the feed entry content. * @property string $copyright Information about rights, e.g. copyrights, held in and over the feed entry. * @property array $links Links associated with the feed entry. * @property Date $publishedDate The publication date for the feed entry. * @property Feed $source The feed from which the entry is sourced. * @property string $title A human readable title for the feed entry. * @property Date $updatedDate The last time the content of the feed entry changed. * @property string $uri Universal, permanent identifier for the feed entry. * * @since 3.1.4 */ class FeedEntry { /** * @var array The entry properties. * @since 3.1.4 */ protected $properties = [ 'uri' => '', 'title' => '', 'updatedDate' => '', 'content' => '', 'categories' => [], 'contributors' => [], 'links' => [], ]; /** * Magic method to return values for feed entry properties. * * @param string $name The name of the property. * * @return mixed * * @since 3.1.4 */ public function __get($name) { return $this->properties[$name] ?? null; } /** * Magic method to set values for feed properties. * * @param string $name The name of the property. * @param mixed $value The value to set for the property. * * @return void * * @since 3.1.4 */ public function __set($name, $value) { // Ensure that setting a date always sets a Date instance. if ((($name === 'updatedDate') || ($name === 'publishedDate')) && !($value instanceof Date)) { $value = new Date($value); } // Validate that any authors that are set are instances of JFeedPerson or null. if (($name === 'author') && (!($value instanceof FeedPerson) || ($value === null))) { throw new \InvalidArgumentException( sprintf( '%1$s "author" must be an instance of Joomla\\CMS\\Feed\\FeedPerson. %2$s given.', \get_class($this), \gettype($value) === 'object' ? \get_class($value) : \gettype($value) ) ); } // Validate that any sources that are set are instances of JFeed or null. if (($name === 'source') && (!($value instanceof Feed) || ($value === null))) { throw new \InvalidArgumentException( sprintf( '%1$s "source" must be an instance of Joomla\\CMS\\Feed\\Feed. %2$s given.', \get_class($this), \gettype($value) === 'object' ? \get_class($value) : \gettype($value) ) ); } // Disallow setting categories, contributors, or links directly. if (\in_array($name, ['categories', 'contributors', 'links'])) { throw new \InvalidArgumentException( sprintf( 'Cannot directly set %1$s property "%2$s".', \get_class($this), $name ) ); } $this->properties[$name] = $value; } /** * Method to add a category to the feed entry object. * * @param string $name The name of the category to add. * @param string $uri The optional URI for the category to add. * * @return FeedEntry * * @since 3.1.4 */ public function addCategory($name, $uri = '') { $this->properties['categories'][$name] = $uri; return $this; } /** * Method to add a contributor to the feed entry object. * * @param string $name The full name of the person to add. * @param string $email The email address of the person to add. * @param string $uri The optional URI for the person to add. * @param string $type The optional type of person to add. * * @return FeedEntry * * @since 3.1.4 */ public function addContributor($name, $email, $uri = null, $type = null) { $contributor = new FeedPerson($name, $email, $uri, $type); // If the new contributor already exists then there is nothing to do, so just return. foreach ($this->properties['contributors'] as $c) { if ($c == $contributor) { return $this; } } // Add the new contributor. $this->properties['contributors'][] = $contributor; return $this; } /** * Method to add a link to the feed entry object. * * @param FeedLink $link The link object to add. * * @return FeedEntry * * @since 3.1.4 */ public function addLink(FeedLink $link) { // If the new link already exists then there is nothing to do, so just return. foreach ($this->properties['links'] as $l) { if ($l == $link) { return $this; } } // Add the new link. $this->properties['links'][] = $link; return $this; } /** * Method to remove a category from the feed entry object. * * @param string $name The name of the category to remove. * * @return FeedEntry * * @since 3.1.4 */ public function removeCategory($name) { unset($this->properties['categories'][$name]); return $this; } /** * Method to remove a contributor from the feed entry object. * * @param FeedPerson $contributor The person object to remove. * * @return FeedEntry * * @since 3.1.4 */ public function removeContributor(FeedPerson $contributor) { // If the contributor exists remove it. foreach ($this->properties['contributors'] as $k => $c) { if ($c == $contributor) { unset($this->properties['contributors'][$k]); $this->properties['contributors'] = array_values($this->properties['contributors']); return $this; } } return $this; } /** * Method to remove a link from the feed entry object. * * @param FeedLink $link The link object to remove. * * @return FeedEntry * * @since 3.1.4 */ public function removeLink(FeedLink $link) { // If the link exists remove it. foreach ($this->properties['links'] as $k => $l) { if ($l == $link) { unset($this->properties['links'][$k]); $this->properties['links'] = array_values($this->properties['links']); return $this; } } return $this; } /** * Shortcut method to set the author for the feed entry object. * * @param string $name The full name of the person to set. * @param string $email The email address of the person to set. * @param string $uri The optional URI for the person to set. * @param string $type The optional type of person to set. * * @return FeedEntry * * @since 3.1.4 */ public function setAuthor($name, $email, $uri = null, $type = null) { $author = new FeedPerson($name, $email, $uri, $type); $this->properties['author'] = $author; return $this; } } Parser/AtomParser.php 0000644 00000017624 15173004413 0010576 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed\Parser; use Joomla\CMS\Feed\Feed; use Joomla\CMS\Feed\FeedEntry; use Joomla\CMS\Feed\FeedLink; use Joomla\CMS\Feed\FeedParser; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * ATOM Feed Parser class. * * @link http://www.atomenabled.org/developers/syndication/ * @since 3.1.4 */ class AtomParser extends FeedParser { /** * @var string The feed format version. * @since 3.1.4 */ protected $version; /** * Method to handle the `<author>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleAuthor(Feed $feed, \SimpleXMLElement $el) { // Set the author information from the XML element. $feed->setAuthor( $this->inputFilter->clean((string) $el->name, 'html'), filter_var((string) $el->email, FILTER_VALIDATE_EMAIL), filter_var((string) $el->uri, FILTER_VALIDATE_URL) ); } /** * Method to handle the `<contributor>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleContributor(Feed $feed, \SimpleXMLElement $el) { $feed->addContributor( $this->inputFilter->clean((string) $el->name, 'html'), filter_var((string) $el->email, FILTER_VALIDATE_EMAIL), filter_var((string) $el->uri, FILTER_VALIDATE_URL) ); } /** * Method to handle the `<generator>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleGenerator(Feed $feed, \SimpleXMLElement $el) { $feed->generator = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<id>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleId(Feed $feed, \SimpleXMLElement $el) { $feed->uri = (string) $el; } /** * Method to handle the `<link>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleLink(Feed $feed, \SimpleXMLElement $el) { $link = new FeedLink(); $link->uri = (string) $el['href']; $link->language = (string) $el['hreflang']; $link->length = (int) $el['length']; $link->relation = (string) $el['rel']; $link->title = $this->inputFilter->clean((string) $el['title'], 'html'); $link->type = (string) $el['type']; $feed->link = $link; } /** * Method to handle the `<rights>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleRights(Feed $feed, \SimpleXMLElement $el) { $feed->copyright = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<subtitle>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleSubtitle(Feed $feed, \SimpleXMLElement $el) { $feed->description = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<title>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleTitle(Feed $feed, \SimpleXMLElement $el) { $feed->title = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<updated>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleUpdated(Feed $feed, \SimpleXMLElement $el) { $feed->updatedDate = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to initialise the feed for parsing. Here we detect the version and advance the stream * reader so that it is ready to parse feed elements. * * @return void * * @since 3.1.4 */ protected function initialise() { // We are on the first XML Element after the xml doc type declaration $this->version = ($this->stream->getAttribute('version') == '0.3') ? '0.3' : '1.0'; $this->moveToNextElement(); } /** * Method to handle a `<entry>` element for the feed. * * @param FeedEntry $entry The FeedEntry object being built from the parsed feed entry. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function processFeedEntry(FeedEntry $entry, \SimpleXMLElement $el) { $entry->uri = (string) $el->id; $entry->title = $this->inputFilter->clean((string) $el->title, 'html'); $entry->updatedDate = $this->inputFilter->clean((string) $el->updated, 'html'); $entry->content = $this->inputFilter->clean((string) $el->summary, 'html'); if (!$entry->content) { $entry->content = $this->inputFilter->clean((string) $el->content, 'html'); } if (filter_var($entry->uri, FILTER_VALIDATE_URL) === false && !\is_null($el->link) && $el->link) { $link = $el->link; if ($link->count()) { $link = $this->bestLinkForUri($link); } $uri = (string) $link['href']; if ($uri) { $entry->uri = $uri; } } } /** * If there is more than one <link> in the feed entry, find the most appropriate one and return it. * * @param \SimpleXMLElement $links XML node with links from the feed entry. * * @return \SimpleXMLElement */ private function bestLinkForUri(\SimpleXMLElement $links) { $linkPrefs = ['alternate', 'self', '']; foreach ($linkPrefs as $pref) { foreach ($links as $link) { $rel = (string) $link['rel']; if ($rel === $pref) { return $link; } } } return array_shift($links); } } Parser/NamespaceParserInterface.php 0000644 00000002570 15173004413 0013405 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed\Parser; use Joomla\CMS\Feed\Feed; use Joomla\CMS\Feed\FeedEntry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Feed Namespace interface. * * @since 3.1.4 */ interface NamespaceParserInterface { /** * Method to handle an element for the feed given that a certain namespace is present. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeed(Feed $feed, \SimpleXMLElement $el); /** * Method to handle the feed entry element for the feed given that a certain namespace is present. * * @param FeedEntry $entry The FeedEntry object being built from the parsed feed entry. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeedEntry(FeedEntry $entry, \SimpleXMLElement $el); } Parser/Rss/MediaRssParser.php 0000644 00000003041 15173004413 0012140 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed\Parser\Rss; use Joomla\CMS\Feed\Feed; use Joomla\CMS\Feed\FeedEntry; use Joomla\CMS\Feed\Parser\NamespaceParserInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * RSS Feed Parser Namespace handler for MediaRSS. * * @link https://www.rssboard.org/media-rss * @since 3.1.4 */ class MediaRssParser implements NamespaceParserInterface { /** * Method to handle an element for the feed given that the media namespace is present. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeed(Feed $feed, \SimpleXMLElement $el) { } /** * Method to handle the feed entry element for the feed given that the media namespace is present. * * @param FeedEntry $entry The FeedEntry object being built from the parsed feed entry. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeedEntry(FeedEntry $entry, \SimpleXMLElement $el) { } } Parser/Rss/ItunesRssParser.php 0000644 00000003064 15173004413 0012375 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed\Parser\Rss; use Joomla\CMS\Feed\Feed; use Joomla\CMS\Feed\FeedEntry; use Joomla\CMS\Feed\Parser\NamespaceParserInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * RSS Feed Parser Namespace handler for iTunes. * * @link https://itunespartner.apple.com/en/podcasts/overview * @since 3.1.4 */ class ItunesRssParser implements NamespaceParserInterface { /** * Method to handle an element for the feed given that the itunes namespace is present. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeed(Feed $feed, \SimpleXMLElement $el) { } /** * Method to handle the feed entry element for the feed given that the itunes namespace is present. * * @param FeedEntry $entry The FeedEntry object being built from the parsed feed entry. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ public function processElementForFeedEntry(FeedEntry $entry, \SimpleXMLElement $el) { } } Parser/RssParser.php 0000644 00000032763 15173004413 0010446 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed\Parser; use Joomla\CMS\Feed\Feed; use Joomla\CMS\Feed\FeedEntry; use Joomla\CMS\Feed\FeedLink; use Joomla\CMS\Feed\FeedParser; use Joomla\CMS\Feed\FeedPerson; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * RSS Feed Parser class. * * @link http://cyber.law.harvard.edu/rss/rss.html * @since 3.1.4 */ class RssParser extends FeedParser { /** * @var string The feed element name for the entry elements. * @since 3.1.4 */ protected $entryElementName = 'item'; /** * @var string The feed format version. * @since 3.1.4 */ protected $version; /** * Method to handle the `<category>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleCategory(Feed $feed, \SimpleXMLElement $el) { // Get the data from the element. $domain = (string) $el['domain']; $category = $this->inputFilter->clean((string) $el, 'html'); $feed->addCategory($category, $domain); } /** * Method to handle the `<cloud>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleCloud(Feed $feed, \SimpleXMLElement $el) { $cloud = new \stdClass(); $cloud->domain = (string) $el['domain']; $cloud->port = (string) $el['port']; $cloud->path = (string) $el['path']; $cloud->protocol = (string) $el['protocol']; $cloud->registerProcedure = (string) $el['registerProcedure']; $feed->cloud = $cloud; } /** * Method to handle the `<copyright>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleCopyright(Feed $feed, \SimpleXMLElement $el) { $feed->copyright = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<description>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleDescription(Feed $feed, \SimpleXMLElement $el) { $feed->description = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<generator>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleGenerator(Feed $feed, \SimpleXMLElement $el) { $feed->generator = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<image>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleImage(Feed $feed, \SimpleXMLElement $el) { // Create a feed link object for the image. $image = new FeedLink( (string) $el->url, null, 'logo', null, $this->inputFilter->clean((string) $el->title, 'html') ); // Populate extra fields if they exist. $image->link = (string) filter_var($el->link, FILTER_VALIDATE_URL); $image->description = $this->inputFilter->clean((string) $el->description, 'html'); $image->height = (string) $el->height; $image->width = (string) $el->width; $feed->image = $image; } /** * Method to handle the `<language>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleLanguage(Feed $feed, \SimpleXMLElement $el) { $feed->language = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<lastBuildDate>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleLastBuildDate(Feed $feed, \SimpleXMLElement $el) { $feed->updatedDate = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<link>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleLink(Feed $feed, \SimpleXMLElement $el) { $link = new FeedLink(); $link->uri = (string) $el['href']; $feed->link = $link; } /** * Method to handle the `<managingEditor>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleManagingEditor(Feed $feed, \SimpleXMLElement $el) { $feed->author = $this->processPerson((string) $el); } /** * Method to handle the `<skipDays>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleSkipDays(Feed $feed, \SimpleXMLElement $el) { // Initialise the array. $days = []; // Add all of the day values from the feed to the array. foreach ($el->day as $day) { $days[] = (string) $day; } $feed->skipDays = $days; } /** * Method to handle the `<skipHours>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleSkipHours(Feed $feed, \SimpleXMLElement $el) { // Initialise the array. $hours = []; // Add all of the day values from the feed to the array. foreach ($el->hour as $hour) { $hours[] = (int) $hour; } $feed->skipHours = $hours; } /** * Method to handle the `<pubDate>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handlePubDate(Feed $feed, \SimpleXMLElement $el) { $feed->publishedDate = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<title>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleTitle(Feed $feed, \SimpleXMLElement $el) { $feed->title = $this->inputFilter->clean((string) $el, 'html'); } /** * Method to handle the `<ttl>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleTtl(Feed $feed, \SimpleXMLElement $el) { $feed->ttl = (int) $this->inputFilter->clean((string) $el, 'int'); } /** * Method to handle the `<webmaster>` element for the feed. * * @param Feed $feed The Feed object being built from the parsed feed. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function handleWebmaster(Feed $feed, \SimpleXMLElement $el) { // Get the tag contents and split it over the first space. $tmp = (string) $el; $tmp = explode(' ', $tmp, 2); // This is really cheap parsing. Probably need to create a method to do this more robustly. $name = null; if (isset($tmp[1])) { $name = trim( $this->inputFilter->clean($tmp[1], 'html'), ' ()' ); } $email = trim( filter_var((string) $tmp[0], FILTER_VALIDATE_EMAIL) ); $feed->addContributor($name, $email, null, 'webmaster'); } /** * Method to initialise the feed for parsing. Here we detect the version and advance the stream * reader so that it is ready to parse feed elements. * * @return void * * @since 3.1.4 */ protected function initialise() { // We are on the first XML Element after the xml doc type declaration $this->version = $this->stream->getAttribute('version'); // We want to move forward to the first element after the <channel> element. $this->moveToNextElement('channel'); $this->moveToNextElement(); } /** * Method to handle a `<item>` element for the feed. * * @param FeedEntry $entry The FeedEntry object being built from the parsed feed entry. * @param \SimpleXMLElement $el The current XML element object to handle. * * @return void * * @since 3.1.4 */ protected function processFeedEntry(FeedEntry $entry, \SimpleXMLElement $el) { $entry->uri = (string) filter_var($el->link, FILTER_VALIDATE_URL); $entry->title = $this->inputFilter->clean((string) $el->title, 'html'); $entry->publishedDate = $this->inputFilter->clean((string) $el->pubDate, 'html'); $entry->updatedDate = $this->inputFilter->clean((string) $el->pubDate, 'html'); $entry->content = $this->inputFilter->clean((string) $el->description, 'html'); $entry->guid = $this->inputFilter->clean((string) $el->guid, 'html'); $entry->isPermaLink = $entry->guid !== '' && (string) $el->guid['isPermaLink'] !== 'false'; $entry->comments = $this->inputFilter->clean((string) $el->comments, 'html'); // Add the feed entry author if available. $author = $this->inputFilter->clean((string) $el->author, 'html'); if (!empty($author)) { $entry->author = $this->processPerson($author); } // Add any categories to the entry. foreach ($el->category as $category) { $entry->addCategory((string) $category, (string) $category['domain']); } // Add any enclosures to the entry. foreach ($el->enclosure as $enclosure) { $link = new FeedLink( (string) $enclosure['url'], null, (string) $enclosure['type'], null, null, (int) $enclosure['length'] ); $entry->addLink($link); } } /** * Method to parse a string with person data and return a FeedPerson object. * * @param string $data The string to parse for a person. * * @return FeedPerson * * @since 3.1.4 */ protected function processPerson($data) { // Create a new person object. $person = new FeedPerson(); // This is really cheap parsing, but so far good enough. :) $data = explode(' ', $data, 2); if (isset($data[1])) { $person->name = trim( $this->inputFilter->clean($data[1], 'html'), ' ()' ); } // Set the email for the person. $person->email = trim( filter_var((string) $data[0], FILTER_VALIDATE_EMAIL) ); return $person; } } FeedLink.php 0000644 00000005334 15173004413 0006741 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Feed Link class. * * @since 3.1.4 */ class FeedLink { /** * The URI to the linked resource. * * @var string * @since 3.1.4 */ public $uri; /** * The relationship between the feed and the linked resource. * * @var string * @since 3.1.4 */ public $relation; /** * The resource type. * * @var string * @since 3.1.4 */ public $type; /** * The language of the resource found at the given URI. * * @var string * @since 3.1.4 */ public $language; /** * The title of the resource. * * @var string * @since 3.1.4 */ public $title; /** * The length of the resource in bytes. * * @var integer * @since 3.1.4 */ public $length; /** * The link of the image. * * @var integer * @since 4.4.0 */ public $link; /** * The description of the image. * * @var integer * @since 4.4.0 */ public $description; /** * The height of the image. * * @var integer * @since 4.4.0 */ public $height; /** * The width of the image. * * @var integer * @since 4.4.0 */ public $width; /** * Constructor. * * @param string $uri The URI to the linked resource. * @param string $relation The relationship between the feed and the linked resource. * @param string $type The resource type. * @param string $language The language of the resource found at the given URI. * @param string $title The title of the resource. * @param integer $length The length of the resource in bytes. * * @since 3.1.4 * @throws \InvalidArgumentException */ public function __construct($uri = null, $relation = null, $type = null, $language = null, $title = null, $length = null) { $this->uri = $uri; $this->relation = $relation; $this->type = $type; $this->language = $language; $this->title = $title; // Validate the length input. if (isset($length) && !is_numeric($length)) { throw new \InvalidArgumentException('Length must be numeric.'); } $this->length = (int) $length; } } FeedPerson.php 0000644 00000002617 15173004413 0007313 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Feed Person class. * * @since 3.1.4 */ class FeedPerson { /** * The email address of the person. * * @var string * @since 3.1.4 */ public $email; /** * The full name of the person. * * @var string * @since 3.1.4 */ public $name; /** * The type of person. * * @var string * @since 3.1.4 */ public $type; /** * The URI for the person. * * @var string * @since 3.1.4 */ public $uri; /** * Constructor. * * @param string $name The full name of the person. * @param string $email The email address of the person. * @param string $uri The URI for the person. * @param string $type The type of person. * * @since 3.1.4 */ public function __construct($name = null, $email = null, $uri = null, $type = null) { $this->name = $name; $this->email = $email; $this->uri = $uri; $this->type = $type; } } FeedFactory.php 0000644 00000011612 15173004413 0007447 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Feed; use Joomla\CMS\Http\HttpFactory; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Feed factory class. * * @since 3.1.4 */ class FeedFactory { /** * @var array The list of registered parser classes for feeds. * @since 3.1.4 */ protected $parsers = ['rss' => 'Joomla\\CMS\\Feed\\Parser\\RssParser', 'feed' => 'Joomla\\CMS\\Feed\\Parser\\AtomParser']; /** * Method to load a URI into the feed reader for parsing. * * @param string $uri The URI of the feed to load. Idn uris must be passed already converted to punycode. * * @return Feed * * @since 3.1.4 * @throws \InvalidArgumentException * @throws \RuntimeException */ public function getFeed($uri) { // Create the XMLReader object. $reader = new \XMLReader(); // Open the URI within the stream reader. if (!@$reader->open($uri, null, LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_NOWARNING)) { // Retry with JHttpFactory that allow using CURL and Sockets as alternative method when available // Adding a valid user agent string, otherwise some feed-servers returning an error $options = new Registry(); $options->set('userAgent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'); try { $response = HttpFactory::getHttp($options)->get($uri); } catch (\RuntimeException $e) { throw new \RuntimeException('Unable to open the feed.', $e->getCode(), $e); } if ($response->code != 200) { throw new \RuntimeException('Unable to open the feed.'); } // Set the value to the XMLReader parser if (!$reader->XML($response->body, null, LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_NOWARNING)) { throw new \RuntimeException('Unable to parse the feed.'); } } try { // Skip ahead to the root node. while ($reader->read()) { if ($reader->nodeType == \XMLReader::ELEMENT) { break; } } } catch (\Exception $e) { throw new \RuntimeException('Error reading feed.', $e->getCode(), $e); } // Setup the appropriate feed parser for the feed. $parser = $this->_fetchFeedParser($reader->name, $reader); return $parser->parse(); } /** * Method to register a FeedParser class for a given root tag name. * * @param string $tagName The root tag name for which to register the parser class. * @param string $className The FeedParser class name to register for a root tag name. * @param boolean $overwrite True to overwrite the parser class if one is already registered. * * @return FeedFactory * * @since 3.1.4 * @throws \InvalidArgumentException */ public function registerParser($tagName, $className, $overwrite = false) { // Verify that the class exists. if (!class_exists($className)) { throw new \InvalidArgumentException('The feed parser class ' . $className . ' does not exist.'); } // Validate that the tag name is valid. if (!preg_match('/\A(?!XML)[a-z][\w0-9-]*/i', $tagName)) { throw new \InvalidArgumentException('The tag name ' . $tagName . ' is not valid.'); } // Register the given parser class for the tag name if nothing registered or the overwrite flag set. if (empty($this->parsers[$tagName]) || (bool) $overwrite) { $this->parsers[(string) $tagName] = (string) $className; } return $this; } /** * Method to get the registered Parsers * * @return array * * @since 4.0.0 */ public function getParsers() { return $this->parsers; } /** * Method to return a new JFeedParser object based on the registered parsers and a given type. * * @param string $type The name of parser to return. * @param \XMLReader $reader The XMLReader instance for the feed. * * @return FeedParser * * @since 3.1.4 * @throws \LogicException */ private function _fetchFeedParser($type, \XMLReader $reader) { // Look for a registered parser for the feed type. if (empty($this->parsers[$type])) { throw new \LogicException('No registered feed parser for type ' . $type . '.'); } return new $this->parsers[$type]($reader); } } FeedItem.php 0000644 00000005007 15173041043 0006737 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Document\Feed; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Data object representing a feed item * * @since 1.7.0 */ class FeedItem { /** * Title item element * * required * * @var string * @since 1.7.0 */ public $title; /** * Link item element * * required * * @var string * @since 1.7.0 */ public $link; /** * Description item element * * required * * @var string * @since 1.7.0 */ public $description; /** * Author item element * * optional * * @var string * @since 1.7.0 */ public $author; /** * Author email element * * optional * * @var string * @since 1.7.0 */ public $authorEmail; /** * Category element * * optional * * @var array or string * @since 1.7.0 */ public $category; /** * Comments element * * optional * * @var string * @since 1.7.0 */ public $comments; /** * Enclosure element * * @var FeedEnclosure * @since 1.7.0 */ public $enclosure = null; /** * Guid element * * optional * * @var string * @since 1.7.0 */ public $guid; /** * Published date * * optional * * May be in one of the following formats: * * RFC 822: * "Mon, 20 Jan 03 18:05:41 +0400" * "20 Jan 03 18:05:41 +0000" * * ISO 8601: * "2003-01-20T18:05:41+04:00" * * Unix: * 1043082341 * * @var string * @since 1.7.0 */ public $date; /** * Source element * * optional * * @var string * @since 1.7.0 */ public $source; /** * Set the FeedEnclosure for this item * * @param FeedEnclosure $enclosure The FeedEnclosure to add to the feed. * * @return FeedItem instance of $this to allow chaining * * @since 1.7.0 */ public function setEnclosure(FeedEnclosure $enclosure) { $this->enclosure = $enclosure; return $this; } } FeedImage.php 0000644 00000002413 15173041043 0007061 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Document\Feed; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Data object representing a feed image * * @since 1.7.0 */ class FeedImage { /** * Title image attribute * * required * * @var string * @since 1.7.0 */ public $title = ''; /** * URL image attribute * * required * * @var string * @since 1.7.0 */ public $url = ''; /** * Link image attribute * * required * * @var string * @since 1.7.0 */ public $link = ''; /** * Width image attribute * * optional * * @var string * @since 1.7.0 */ public $width; /** * Title feed attribute * * optional * * @var string * @since 1.7.0 */ public $height; /** * Title feed attribute * * optional * * @var string * @since 1.7.0 */ public $description; } FeedEnclosure.php 0000644 00000001570 15173041043 0010001 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Document\Feed; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Data object representing a feed enclosure * * @since 1.7.0 */ class FeedEnclosure { /** * URL enclosure element * * required * * @var string * @since 1.7.0 */ public $url = ''; /** * Length enclosure element * * required * * @var string * @since 1.7.0 */ public $length = ''; /** * Type enclosure element * * required * * @var string * @since 1.7.0 */ public $type = ''; }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings