Files
server/usr/share/psa-pear/pear/php/Horde/Feed.php
2026-01-07 20:52:11 +01:00

166 lines
5.2 KiB
PHP

<?php
/**
* Portions Copyright 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* Copyright 2007-2016 Horde LLC (http://www.horde.org/)
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Feed
*/
/**
* @author Chuck Hagenbuch <chuck@horde.org>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Feed
*/
class Horde_Feed
{
/**
* Create a Feed object based on a DOMDocument.
*
* @param DOMDocument $doc The DOMDocument object to import.
*
* @throws Horde_Feed_Exception
*
* @return Horde_Feed_Base The feed object imported from $doc
*/
public static function create(DOMDocument $doc, $uri = null)
{
// Try to find the base feed element or a single <entry> of an
// Atom feed.
if ($feed = $doc->getElementsByTagName('feed')->item(0)) {
// Return an Atom feed.
return new Horde_Feed_Atom($feed, $uri);
} elseif ($entry = $doc->getElementsByTagName('entry')->item(0)) {
// Return an Atom single-entry feed.
$feeddoc = new DOMDocument($doc->version,
$doc->actualEncoding);
$feed = $feeddoc->appendChild($feeddoc->createElement('feed'));
$feed->appendChild($feeddoc->importNode($entry, true));
return new Horde_Feed_Atom($feed, $uri);
}
// Try to find the base feed element of an RSS feed.
if ($channel = $doc->getElementsByTagName('channel')->item(0)) {
// Return an RSS feed.
return new Horde_Feed_Rss($channel, $uri);
}
// Try to find an outline element of an OPML blogroll.
if ($outline = $doc->getElementsByTagName('outline')->item(0)) {
// Return a blogroll feed.
return new Horde_Feed_Blogroll($doc->documentElement, $uri);
}
// $doc does not appear to be a valid feed of the supported
// types.
throw new Horde_Feed_Exception('Invalid or unsupported feed format: '
. substr($doc->saveXML(), 0, 80) . '...');
}
/**
* Reads a feed represented by $string.
*
* @param string $string The XML content of the feed.
* @param string $uri The feed's URI location, if known.
*
* @throws Horde_Feed_Exception
*
* @return Horde_Feed_Base
*/
public static function read($string, $uri = null)
{
// Load the feed as a DOMDocument object.
libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->recover = true;
$loaded = $doc->loadXML($string);
if (!$loaded) {
$loaded = $doc->loadHTML($string);
if (!$loaded) {
self::_exception('DOMDocument cannot parse XML', libxml_get_last_error());
}
}
return self::create($doc);
}
/**
* Read a feed located at $uri
*
* @param string $uri The URI to fetch the feed from.
* @param Horde_Http_Client $httpclient The HTTP client to use.
*
* @throws Horde_Feed_Exception
*
* @return Horde_Feed_Base
*/
public static function readUri($uri, Horde_Http_Client $httpclient = null)
{
if (is_null($httpclient)) {
$httpclient = new Horde_Http_Client();
}
try {
$response = $httpclient->get($uri);
} catch (Horde_Http_Exception $e) {
throw new Horde_Feed_Exception('Error reading feed: ' . $e->getMessage());
}
if ($response->code != 200) {
throw new Horde_Feed_Exception('Unable to read feed, got response code ' . $response->code);
}
$feed = $response->getBody();
return self::read($feed, $uri);
}
/**
* Read a feed from $filename
*
* @param string $filename The location of the feed file on an accessible
* filesystem or through an available stream wrapper.
*
* @throws Horde_Feed_Exception
*
* @return Horde_Feed_Base
*/
public static function readFile($filename)
{
libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->recover = true;
$contents = file_get_contents($filename);
$loaded = $doc->loadXML($contents);
if (!$loaded) {
$loaded = $doc->loadHTML($contents);
if (!$loaded) {
self::_exception('File could not be read or parsed', libxml_get_last_error());
}
}
return self::create($doc);
}
/**
* Builds an exception message from a libXMLError object.
*
* @param string $msg An error message.
* @param libXMLError $error An error object.
*
* @throws Horde_Feed_Exception
*/
protected static function _exception($msg, $error)
{
if ($error) {
$msg .= ': ' . $error->message;
if ($error->file) {
$msg .= sprintf(' in file %s, line %d, column %d',
$error->file, $error->line, $error->column);
}
}
throw new Horde_Feed_Exception($msg);
}
}