123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- <?php
- /**
- * RSS and Atom feed helper.
- *
- * @package KO7
- * @category Helpers
- *
- * @copyright (c) 2007-2016 Kohana Team
- * @copyright (c) since 2016 Koseven Team
- * @license https://koseven.dev/LICENSE
- */
- class KO7_Feed {
- /**
- * Parses a remote feed into an array.
- *
- * @param string $feed remote feed URL
- * @param integer $limit item limit to fetch
- * @return array
- */
- public static function parse($feed, $limit = 0)
- {
- // Check if SimpleXML is installed
- if ( ! function_exists('simplexml_load_file'))
- throw new KO7_Exception('SimpleXML must be installed!');
- // Make limit an integer
- $limit = (int) $limit;
- // Disable error reporting while opening the feed
- $error_level = error_reporting(0);
- // Allow loading by filename or raw XML string
- if (Valid::url($feed))
- {
- // Use native Request client to get remote contents
- $response = Request::factory($feed)->execute();
- $feed = $response->body();
- }
- elseif (is_file($feed))
- {
- // Get file contents
- $feed = file_get_contents($feed);
- }
- // Load the feed
- $feed = simplexml_load_string($feed, 'SimpleXMLElement', LIBXML_NOCDATA);
- // Restore error reporting
- error_reporting($error_level);
- // Feed could not be loaded
- if ($feed === FALSE)
- return [];
- $namespaces = $feed->getNamespaces(TRUE);
- // Detect the feed type. RSS 1.0/2.0 and Atom 1.0 are supported.
- $feed = isset($feed->channel) ? $feed->xpath('//item') : $feed->entry;
- $i = 0;
- $items = [];
- foreach ($feed as $item)
- {
- if ($limit > 0 AND $i++ === $limit)
- break;
- $item_fields = (array) $item;
- // get namespaced tags
- foreach ($namespaces as $ns)
- {
- $item_fields += (array) $item->children($ns);
- }
- $items[] = $item_fields;
- }
- return $items;
- }
- /**
- * Creates a feed from the given parameters.
- *
- * @param array $info feed information
- * @param array $items items to add to the feed
- * @param string $encoding define which encoding to use
- * @return string
- */
- public static function create($info, $items, $encoding = 'UTF-8')
- {
- $info += ['title' => 'Generated Feed', 'link' => '', 'generator' => 'KO7PHP'];
- $feed = '<?xml version="1.0" encoding="'.$encoding.'"?><rss version="2.0"><channel></channel></rss>';
- $feed = simplexml_load_string($feed);
- foreach ($info as $name => $value)
- {
- if ($name === 'image')
- {
- // Create an image element
- $image = $feed->channel->addChild('image');
- if ( ! isset($value['link'], $value['url'], $value['title']))
- {
- throw new KO7_Exception('Feed images require a link, url, and title');
- }
- if (strpos($value['link'], '://') === FALSE)
- {
- // Convert URIs to URLs
- $value['link'] = URL::site($value['link'], 'http');
- }
- if (strpos($value['url'], '://') === FALSE)
- {
- // Convert URIs to URLs
- $value['url'] = URL::site($value['url'], 'http');
- }
- // Create the image elements
- $image->addChild('link', $value['link']);
- $image->addChild('url', $value['url']);
- $image->addChild('title', $value['title']);
- }
- else
- {
- if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value)))
- {
- // Convert timestamps to RFC 822 formatted dates
- $value = date('r', $value);
- }
- elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE)
- {
- // Convert URIs to URLs
- $value = URL::site($value, 'http');
- }
- // Add the info to the channel
- $feed->channel->addChild($name, $value);
- }
- }
- foreach ($items as $item)
- {
- // Add the item to the channel
- $row = $feed->channel->addChild('item');
- foreach ($item as $name => $value)
- {
- if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value)))
- {
- // Convert timestamps to RFC 822 formatted dates
- $value = date('r', $value);
- }
- elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE)
- {
- // Convert URIs to URLs
- $value = URL::site($value, 'http');
- }
- // Add the info to the row
- $row->addChild($name, $value);
- }
- }
- if (function_exists('dom_import_simplexml'))
- {
- // Convert the feed object to a DOM object
- $feed = dom_import_simplexml($feed)->ownerDocument;
- // DOM generates more readable XML
- $feed->formatOutput = TRUE;
- // Export the document as XML
- $feed = $feed->saveXML();
- }
- else
- {
- // Export the document as XML
- $feed = $feed->asXML();
- }
- return $feed;
- }
- }
|