* @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Document\Renderer\Feed; use Joomla\CMS\Date\Date; use Joomla\CMS\Document\DocumentRenderer; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * RssRenderer is a feed that implements RSS 2.0 Specification * * @link http://www.rssboard.org/rss-specification * @since 3.5 * * @property-read \Joomla\CMS\Document\FeedDocument $_doc Reference to the Document object that instantiated the renderer */ class RssRenderer extends DocumentRenderer { /** * Renderer mime type * * @var string * @since 3.5 */ protected $_mime = 'application/rss+xml'; /** * Render the feed. * * @param string $name The name of the element to render * @param array $params Array of values * @param string $content Override the output of the renderer * * @return string The output of the script * * @see DocumentRenderer::render() * @since 3.5 */ public function render($name = '', $params = null, $content = null) { $app = Factory::getApplication(); $tz = new \DateTimeZone($app->get('offset')); $data = $this->_doc; // If the last build date from the document isn't a Date object, create one if (!($data->lastBuildDate instanceof Date)) { // Gets and sets timezone offset from site configuration $data->lastBuildDate = Factory::getDate(); $data->lastBuildDate->setTimezone(new \DateTimeZone($app->get('offset'))); } $url = Uri::getInstance()->toString(array('scheme', 'user', 'pass', 'host', 'port')); $syndicationURL = Route::_('&format=feed&type=rss'); $title = $data->getTitle(); if ($app->get('sitename_pagetitles', 0) == 1) { $title = Text::sprintf('JPAGETITLE', $app->get('sitename'), $data->getTitle()); } elseif ($app->get('sitename_pagetitles', 0) == 2) { $title = Text::sprintf('JPAGETITLE', $data->getTitle(), $app->get('sitename')); } $feed_title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); $datalink = $data->getLink(); if (preg_match('/[\x80-\xFF]/', $datalink)) { $datalink = implode('/', array_map('rawurlencode', explode('/', $datalink))); } $feed = "\n"; $feed .= " \n"; $feed .= " " . $feed_title . "\n"; $feed .= " getDescription() . "]]>\n"; $feed .= " " . str_replace(' ', '%20', $url . $datalink) . "\n"; $feed .= " " . htmlspecialchars($data->lastBuildDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "\n"; $feed .= " " . $data->getGenerator() . "\n"; $feed .= " \n"; if ($data->image != null) { $feed .= " \n"; $feed .= " " . $data->image->url . "\n"; $feed .= " " . htmlspecialchars($data->image->title, ENT_COMPAT, 'UTF-8') . "\n"; $feed .= " " . str_replace(' ', '%20', $data->image->link) . "\n"; if ($data->image->width != '') { $feed .= " " . $data->image->width . "\n"; } if ($data->image->height != '') { $feed .= " " . $data->image->height . "\n"; } if ($data->image->description != '') { $feed .= " image->description . "]]>\n"; } $feed .= " \n"; } if ($data->getLanguage() !== '') { $feed .= " " . $data->getLanguage() . "\n"; } if ($data->copyright != '') { $feed .= " " . htmlspecialchars($data->copyright, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->editorEmail != '') { $feed .= " " . htmlspecialchars($data->editorEmail, ENT_COMPAT, 'UTF-8') . ' (' . htmlspecialchars($data->editor, ENT_COMPAT, 'UTF-8') . ")\n"; } if ($data->webmaster != '') { $feed .= " " . htmlspecialchars($data->webmaster, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->pubDate != '') { $pubDate = Factory::getDate($data->pubDate); $pubDate->setTimezone($tz); $feed .= " " . htmlspecialchars($pubDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "\n"; } if (!empty($data->category)) { if (\is_array($data->category)) { foreach ($data->category as $cat) { $feed .= " " . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\n"; } } else { $feed .= " " . htmlspecialchars($data->category, ENT_COMPAT, 'UTF-8') . "\n"; } } if ($data->docs != '') { $feed .= " " . htmlspecialchars($data->docs, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->ttl != '') { $feed .= " " . htmlspecialchars($data->ttl, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->rating != '') { $feed .= " " . htmlspecialchars($data->rating, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->skipHours != '') { $feed .= " " . htmlspecialchars($data->skipHours, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->skipDays != '') { $feed .= " " . htmlspecialchars($data->skipDays, ENT_COMPAT, 'UTF-8') . "\n"; } for ($i = 0, $count = \count($data->items); $i < $count; $i++) { $itemlink = $data->items[$i]->link; if (preg_match('/[\x80-\xFF]/', $itemlink)) { $itemlink = implode('/', array_map('rawurlencode', explode('/', $itemlink))); } if ((strpos($itemlink, 'http://') === false) && (strpos($itemlink, 'https://') === false)) { $itemlink = str_replace(' ', '%20', $url . $itemlink); } $feed .= " \n"; $feed .= " " . htmlspecialchars(strip_tags($data->items[$i]->title), ENT_COMPAT, 'UTF-8') . "\n"; $feed .= " " . str_replace(' ', '%20', $itemlink) . "\n"; if (empty($data->items[$i]->guid)) { $feed .= " " . str_replace(' ', '%20', $itemlink) . "\n"; } else { $feed .= " " . htmlspecialchars($data->items[$i]->guid, ENT_COMPAT, 'UTF-8') . "\n"; } $feed .= " _relToAbs($data->items[$i]->description) . "]]>\n"; if ($data->items[$i]->authorEmail != '') { $feed .= ' ' . htmlspecialchars($data->items[$i]->authorEmail . ' (' . $data->items[$i]->author . ')', ENT_COMPAT, 'UTF-8') . "\n"; } /* * @todo: On hold * if ($data->items[$i]->source!='') * { * $data.= " " . htmlspecialchars($data->items[$i]->source, ENT_COMPAT, 'UTF-8') . "\n"; * } */ if (empty($data->items[$i]->category) === false) { if (\is_array($data->items[$i]->category)) { foreach ($data->items[$i]->category as $cat) { $feed .= " " . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\n"; } } else { $feed .= " " . htmlspecialchars($data->items[$i]->category, ENT_COMPAT, 'UTF-8') . "\n"; } } if ($data->items[$i]->comments != '') { $feed .= " " . htmlspecialchars($data->items[$i]->comments, ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->items[$i]->date != '') { $itemDate = Factory::getDate($data->items[$i]->date); $itemDate->setTimezone($tz); $feed .= " " . htmlspecialchars($itemDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "\n"; } if ($data->items[$i]->enclosure != null) { $feed .= " items[$i]->enclosure->url; $feed .= "\" length=\""; $feed .= $data->items[$i]->enclosure->length; $feed .= "\" type=\""; $feed .= $data->items[$i]->enclosure->type; $feed .= "\"/>\n"; } $feed .= " \n"; } $feed .= " \n"; $feed .= "\n"; return $feed; } }