import v1.0.0-RC4 | 2009-05-20

This commit is contained in:
2019-07-17 22:08:50 +02:00
commit b484e522e8
2459 changed files with 1038434 additions and 0 deletions

259
libs/Zend/Feed/Abstract.php Normal file
View File

@ -0,0 +1,259 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 12507 2008-11-10 16:29:09Z matthew $
*/
/**
* @see Zend_Feed_Element
*/
require_once 'Zend/Feed/Element.php';
/**
* The Zend_Feed_Abstract class is an abstract class representing feeds.
*
* Zend_Feed_Abstract implements two core PHP 5 interfaces: ArrayAccess and
* Iterator. In both cases the collection being treated as an array is
* considered to be the entry collection, such that iterating over the
* feed takes you through each of the feed.s entries.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator
{
/**
* Current index on the collection of feed entries for the
* Iterator implementation.
*
* @var integer
*/
protected $_entryIndex = 0;
/**
* Cache of feed entries.
*
* @var array
*/
protected $_entries;
/**
* Feed constructor
*
* The Zend_Feed_Abstract constructor takes the URI of a feed or a
* feed represented as a string and loads it as XML.
*
* @param string $uri The full URI of the feed to load, or NULL if not retrieved via HTTP or as an array.
* @param string $string The feed as a string, or NULL if retrieved via HTTP or as an array.
* @param Zend_Feed_Builder_Interface $builder The feed as a builder instance or NULL if retrieved as a string or via HTTP.
* @return void
* @throws Zend_Feed_Exception If loading the feed failed.
*/
public function __construct($uri = null, $string = null, Zend_Feed_Builder_Interface $builder = null)
{
if ($uri !== null) {
// Retrieve the feed via HTTP
$client = Zend_Feed::getHttpClient();
$client->setUri($uri);
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
$this->_element = $response->getBody();
$this->__wakeup();
} elseif ($string !== null) {
// Retrieve the feed from $string
$this->_element = $string;
$this->__wakeup();
} else {
// Generate the feed from the array
$header = $builder->getHeader();
$this->_element = new DOMDocument('1.0', $header['charset']);
$root = $this->_mapFeedHeaders($header);
$this->_mapFeedEntries($root, $builder->getEntries());
$this->_element = $root;
$this->_buildEntryCache();
}
}
/**
* Load the feed as an XML DOMDocument object
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
@ini_set('track_errors', 1);
$doc = new DOMDocument;
$status = @$doc->loadXML($this->_element);
@ini_restore('track_errors');
if (!$status) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
$this->_element = $doc;
}
/**
* Prepare for serialiation
*
* @return array
*/
public function __sleep()
{
$this->_element = $this->saveXML();
return array('_element');
}
/**
* Cache the individual feed elements so they don't need to be
* searched for on every operation.
*
* @return void
*/
protected function _buildEntryCache()
{
$this->_entries = array();
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $this->_entryElementName) {
$this->_entries[] = $child;
}
}
}
/**
* Get the number of entries in this feed object.
*
* @return integer Entry count.
*/
public function count()
{
return count($this->_entries);
}
/**
* Required by the Iterator interface.
*
* @return void
*/
public function rewind()
{
$this->_entryIndex = 0;
}
/**
* Required by the Iterator interface.
*
* @return mixed The current row, or null if no rows.
*/
public function current()
{
return new $this->_entryClassName(
null,
$this->_entries[$this->_entryIndex]);
}
/**
* Required by the Iterator interface.
*
* @return mixed The current row number (starts at 0), or NULL if no rows
*/
public function key()
{
return $this->_entryIndex;
}
/**
* Required by the Iterator interface.
*
* @return mixed The next row, or null if no more rows.
*/
public function next()
{
++$this->_entryIndex;
}
/**
* Required by the Iterator interface.
*
* @return boolean Whether the iteration is valid
*/
public function valid()
{
return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
abstract protected function _mapFeedHeaders($array);
/**
* Generate the entries of the feed when working in write mode
*
* @param DOMElement $root the root node to use
* @param array $array the data to use
* @return DOMElement root node
*/
abstract protected function _mapFeedEntries(DOMElement $root, $array);
/**
* Send feed to a http client with the correct header
*
* @throws Zend_Feed_Exception if headers have already been sent
* @return void
*/
abstract public function send();
}

390
libs/Zend/Feed/Atom.php Normal file
View File

@ -0,0 +1,390 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Atom.php 11654 2008-10-03 16:03:35Z yoshida@zend.co.jp $
*/
/**
* @see Zend_Feed_Abstract
*/
require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Atom
*/
require_once 'Zend/Feed/Entry/Atom.php';
/**
* Atom feed class
*
* The Zend_Feed_Atom class is a concrete subclass of the general
* Zend_Feed_Abstract class, tailored for representing an Atom
* feed. It shares all of the same methods with its abstract
* parent. The distinction is made in the format of data that
* Zend_Feed_Atom expects, and as a further pointer for users as to
* what kind of feed object they have been passed.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Atom extends Zend_Feed_Abstract
{
/**
* The classname for individual feed elements.
*
* @var string
*/
protected $_entryClassName = 'Zend_Feed_Entry_Atom';
/**
* The element name for individual feed elements (Atom <entry>
* elements).
*
* @var string
*/
protected $_entryElementName = 'entry';
/**
* The default namespace for Atom feeds.
*
* @var string
*/
protected $_defaultNamespace = 'atom';
/**
* Override Zend_Feed_Abstract to set up the $_element and $_entries aliases.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
parent::__wakeup();
// Find the base feed element and create an alias to it.
$element = $this->_element->getElementsByTagName('feed')->item(0);
if (!$element) {
// Try to find a single <entry> instead.
$element = $this->_element->getElementsByTagName($this->_entryElementName)->item(0);
if (!$element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> or <' . $this->_entryElementName
. '> element found, cannot parse feed.');
}
$doc = new DOMDocument($this->_element->version,
$this->_element->actualEncoding);
$feed = $doc->appendChild($doc->createElement('feed'));
$feed->appendChild($doc->importNode($element, true));
$element = $feed;
}
$this->_element = $element;
// Find the entries and save a pointer to them for speed and
// simplicity.
$this->_buildEntryCache();
}
/**
* Easy access to <link> tags keyed by "rel" attributes.
*
* If $elt->link() is called with no arguments, we will attempt to
* return the value of the <link> tag(s) like all other
* method-syntax attribute access. If an argument is passed to
* link(), however, then we will return the "href" value of the
* first <link> tag that has a "rel" attribute matching $rel:
*
* $elt->link(): returns the value of the link tag.
* $elt->link('self'): returns the href from the first <link rel="self"> in the entry.
*
* @param string $rel The "rel" attribute to look for.
* @return mixed
*/
public function link($rel = null)
{
if ($rel === null) {
return parent::__call('link', null);
}
// index link tags by their "rel" attribute.
$links = parent::__get('link');
if (!is_array($links)) {
if ($links instanceof Zend_Feed_Element) {
$links = array($links);
} else {
return $links;
}
}
foreach ($links as $link) {
if (empty($link['rel'])) {
continue;
}
if ($rel == $link['rel']) {
return $link['href'];
}
}
return null;
}
/**
* Make accessing some individual elements of the feed easier.
*
* Special accessors 'entry' and 'entries' are provided so that if
* you wish to iterate over an Atom feed's entries, you can do so
* using foreach ($feed->entries as $entry) or foreach
* ($feed->entry as $entry).
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'entry':
// fall through to the next case
case 'entries':
return $this;
default:
return parent::__get($var);
}
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
protected function _mapFeedHeaders($array)
{
$feed = $this->_element->createElement('feed');
$feed->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$id = $this->_element->createElement('id', $array->link);
$feed->appendChild($id);
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($array->title));
$feed->appendChild($title);
if (isset($array->author)) {
$author = $this->_element->createElement('author');
$name = $this->_element->createElement('name', $array->author);
$author->appendChild($name);
if (isset($array->email)) {
$email = $this->_element->createElement('email', $array->email);
$author->appendChild($email);
}
$feed->appendChild($author);
}
$updated = isset($array->lastUpdate) ? $array->lastUpdate : time();
$updated = $this->_element->createElement('updated', date(DATE_ATOM, $updated));
$feed->appendChild($updated);
if (isset($array->published)) {
$published = $this->_element->createElement('published', date(DATE_ATOM, $array->published));
$feed->appendChild($published);
}
$link = $this->_element->createElement('link');
$link->setAttribute('rel', 'self');
$link->setAttribute('href', $array->link);
if (isset($array->language)) {
$link->setAttribute('hreflang', $array->language);
}
$feed->appendChild($link);
if (isset($array->description)) {
$subtitle = $this->_element->createElement('subtitle');
$subtitle->appendChild($this->_element->createCDATASection($array->description));
$feed->appendChild($subtitle);
}
if (isset($array->copyright)) {
$copyright = $this->_element->createElement('rights', $array->copyright);
$feed->appendChild($copyright);
}
if (isset($array->image)) {
$image = $this->_element->createElement('logo', $array->image);
$feed->appendChild($image);
}
$generator = !empty($array->generator) ? $array->generator : 'Zend_Feed';
$generator = $this->_element->createElement('generator', $generator);
$feed->appendChild($generator);
return $feed;
}
/**
* Generate the entries of the feed when working in write mode
*
* The following nodes are constructed for each feed entry
* <entry>
* <id>url to feed entry</id>
* <title>entry title</title>
* <updated>last update</updated>
* <link rel="alternate" href="url to feed entry" />
* <summary>short text</summary>
* <content>long version, can contain html</content>
* </entry>
*
* @param array $array the data to use
* @param DOMElement $root the root node to use
* @return void
*/
protected function _mapFeedEntries(DOMElement $root, $array)
{
foreach ($array as $dataentry) {
$entry = $this->_element->createElement('entry');
$id = $this->_element->createElement('id', isset($dataentry->guid) ? $dataentry->guid : $dataentry->link);
$entry->appendChild($id);
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($dataentry->title));
$entry->appendChild($title);
$updated = isset($dataentry->lastUpdate) ? $dataentry->lastUpdate : time();
$updated = $this->_element->createElement('updated', date(DATE_ATOM, $updated));
$entry->appendChild($updated);
$link = $this->_element->createElement('link');
$link->setAttribute('rel', 'alternate');
$link->setAttribute('href', $dataentry->link);
$entry->appendChild($link);
$summary = $this->_element->createElement('summary');
$summary->appendChild($this->_element->createCDATASection($dataentry->description));
$entry->appendChild($summary);
if (isset($dataentry->content)) {
$content = $this->_element->createElement('content');
$content->setAttribute('type', 'html');
$content->appendChild($this->_element->createCDATASection($dataentry->content));
$entry->appendChild($content);
}
if (isset($dataentry->category)) {
foreach ($dataentry->category as $category) {
$node = $this->_element->createElement('category');
$node->setAttribute('term', $category['term']);
if (isset($category['scheme'])) {
$node->setAttribute('scheme', $category['scheme']);
}
$entry->appendChild($node);
}
}
if (isset($dataentry->source)) {
$source = $this->_element->createElement('source');
$title = $this->_element->createElement('title', $dataentry->source['title']);
$source->appendChild($title);
$link = $this->_element->createElement('link', $dataentry->source['title']);
$link->setAttribute('rel', 'alternate');
$link->setAttribute('href', $dataentry->source['url']);
$source->appendChild($link);
}
if (isset($dataentry->enclosure)) {
foreach ($dataentry->enclosure as $enclosure) {
$node = $this->_element->createElement('link');
$node->setAttribute('rel', 'enclosure');
$node->setAttribute('href', $enclosure['url']);
if (isset($enclosure['type'])) {
$node->setAttribute('type', $enclosure['type']);
}
if (isset($enclosure['length'])) {
$node->setAttribute('length', $enclosure['length']);
}
$entry->appendChild($node);
}
}
if (isset($dataentry->comments)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:comment',
$dataentry->comments);
$entry->appendChild($comments);
}
if (isset($dataentry->commentRss)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:commentRss',
$dataentry->commentRss);
$entry->appendChild($comments);
}
$root->appendChild($entry);
}
}
/**
* Override Zend_Feed_Element to allow formated feeds
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$doc->appendChild($doc->importNode($this->_element, true));
$doc->formatOutput = true;
return $doc->saveXML();
}
/**
* Send feed to a http client with the correct header
*
* @return void
* @throws Zend_Feed_Exception if headers have already been sent
*/
public function send()
{
if (headers_sent()) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send ATOM because headers have already been sent.');
}
header('Content-Type: application/atom+xml; charset=' . $this->_element->ownerDocument->actualEncoding);
echo $this->saveXML();
}
}

395
libs/Zend/Feed/Builder.php Normal file
View File

@ -0,0 +1,395 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Builder.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Builder_Interface
*/
require_once 'Zend/Feed/Builder/Interface.php';
/**
* @see Zend_Feed_Builder_Header
*/
require_once 'Zend/Feed/Builder/Header.php';
/**
* @see Zend_Feed_Builder_Entry
*/
require_once 'Zend/Feed/Builder/Entry.php';
/**
* A simple implementation of Zend_Feed_Builder_Interface.
*
* Users are encouraged to make their own classes to implement Zend_Feed_Builder_Interface
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
{
/**
* The data of the feed
*
* @var $_data array
*/
private $_data;
/**
* Header of the feed
*
* @var $_header Zend_Feed_Builder_Header
*/
private $_header;
/**
* List of the entries of the feed
*
* @var $_entries array
*/
private $_entries = array();
/**
* Constructor. The $data array must conform to the following format:
* <code>
* array(
* 'title' => 'title of the feed', //required
* 'link' => 'canonical url to the feed', //required
* 'lastUpdate' => 'timestamp of the update date', // optional
* 'published' => 'timestamp of the publication date', //optional
* 'charset' => 'charset', // required
* 'description' => 'short description of the feed', //optional
* 'author' => 'author/publisher of the feed', //optional
* 'email' => 'email of the author', //optional
* 'webmaster' => 'email address for person responsible for technical issues' // optional, ignored if atom is used
* 'copyright' => 'copyright notice', //optional
* 'image' => 'url to image', //optional
* 'generator' => 'generator', // optional
* 'language' => 'language the feed is written in', // optional
* 'ttl' => 'how long in minutes a feed can be cached before refreshing', // optional, ignored if atom is used
* 'rating' => 'The PICS rating for the channel.', // optional, ignored if atom is used
* 'cloud' => array(
* 'domain' => 'domain of the cloud, e.g. rpc.sys.com' // required
* 'port' => 'port to connect to' // optional, default to 80
* 'path' => 'path of the cloud, e.g. /RPC2 //required
* 'registerProcedure' => 'procedure to call, e.g. myCloud.rssPleaseNotify' // required
* 'protocol' => 'protocol to use, e.g. soap or xml-rpc' // required
* ), a cloud to be notified of updates // optional, ignored if atom is used
* 'textInput' => array(
* 'title' => 'the label of the Submit button in the text input area' // required,
* 'description' => 'explains the text input area' // required
* 'name' => 'the name of the text object in the text input area' // required
* 'link' => 'the URL of the CGI script that processes text input requests' // required
* ) // a text input box that can be displayed with the feed // optional, ignored if atom is used
* 'skipHours' => array(
* 'hour in 24 format', // e.g 13 (1pm)
* // up to 24 rows whose value is a number between 0 and 23
* ) // Hint telling aggregators which hours they can skip // optional, ignored if atom is used
* 'skipDays ' => array(
* 'a day to skip', // e.g Monday
* // up to 7 rows whose value is a Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday
* ) // Hint telling aggregators which days they can skip // optional, ignored if atom is used
* 'itunes' => array(
* 'author' => 'Artist column' // optional, default to the main author value
* 'owner' => array(
* 'name' => 'name of the owner' // optional, default to main author value
* 'email' => 'email of the owner' // optional, default to main email value
* ) // Owner of the podcast // optional
* 'image' => 'album/podcast art' // optional, default to the main image value
* 'subtitle' => 'short description' // optional, default to the main description value
* 'summary' => 'longer description' // optional, default to the main description value
* 'block' => 'Prevent an episode from appearing (yes|no)' // optional
* 'category' => array(
* array('main' => 'main category', // required
* 'sub' => 'sub category' // optional
* ),
* // up to 3 rows
* ) // 'Category column and in iTunes Music Store Browse' // required
* 'explicit' => 'parental advisory graphic (yes|no|clean)' // optional
* 'keywords' => 'a comma separated list of 12 keywords maximum' // optional
* 'new-feed-url' => 'used to inform iTunes of new feed URL location' // optional
* ) // Itunes extension data // optional, ignored if atom is used
* 'entries' => array(
* array(
* 'title' => 'title of the feed entry', //required
* 'link' => 'url to a feed entry', //required
* 'description' => 'short version of a feed entry', // only text, no html, required
* 'guid' => 'id of the article, if not given link value will used', //optional
* 'content' => 'long version', // can contain html, optional
* 'lastUpdate' => 'timestamp of the publication date', // optional
* 'comments' => 'comments page of the feed entry', // optional
* 'commentRss' => 'the feed url of the associated comments', // optional
* 'source' => array(
* 'title' => 'title of the original source' // required,
* 'url' => 'url of the original source' // required
* ) // original source of the feed entry // optional
* 'category' => array(
* array(
* 'term' => 'first category label' // required,
* 'scheme' => 'url that identifies a categorization scheme' // optional
* ),
* array(
* //data for the second category and so on
* )
* ) // list of the attached categories // optional
* 'enclosure' => array(
* array(
* 'url' => 'url of the linked enclosure' // required
* 'type' => 'mime type of the enclosure' // optional
* 'length' => 'length of the linked content in octets' // optional
* ),
* array(
* //data for the second enclosure and so on
* )
* ) // list of the enclosures of the feed entry // optional
* ),
* array(
* //data for the second entry and so on
* )
* )
* );
* </code>
*
* @param array $data
* @return void
*/
public function __construct(array $data)
{
$this->_data = $data;
$this->_createHeader($data);
if (isset($data['entries'])) {
$this->_createEntries($data['entries']);
}
}
/**
* Returns an instance of Zend_Feed_Builder_Header
* describing the header of the feed
*
* @return Zend_Feed_Builder_Header
*/
public function getHeader()
{
return $this->_header;
}
/**
* Returns an array of Zend_Feed_Builder_Entry instances
* describing the entries of the feed
*
* @return array of Zend_Feed_Builder_Entry
*/
public function getEntries()
{
return $this->_entries;
}
/**
* Create the Zend_Feed_Builder_Header instance
*
* @param array $data
* @throws Zend_Feed_Builder_Exception
* @return void
*/
private function _createHeader(array $data)
{
$mandatories = array('title', 'link', 'charset');
foreach ($mandatories as $mandatory) {
if (!isset($data[$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
$this->_header = new Zend_Feed_Builder_Header($data['title'], $data['link'], $data['charset']);
if (isset($data['lastUpdate'])) {
$this->_header->setLastUpdate($data['lastUpdate']);
}
if (isset($data['published'])) {
$this->_header->setPublishedDate($data['published']);
}
if (isset($data['description'])) {
$this->_header->setDescription($data['description']);
}
if (isset($data['author'])) {
$this->_header->setAuthor($data['author']);
}
if (isset($data['email'])) {
$this->_header->setEmail($data['email']);
}
if (isset($data['webmaster'])) {
$this->_header->setWebmaster($data['webmaster']);
}
if (isset($data['copyright'])) {
$this->_header->setCopyright($data['copyright']);
}
if (isset($data['image'])) {
$this->_header->setImage($data['image']);
}
if (isset($data['generator'])) {
$this->_header->setGenerator($data['generator']);
}
if (isset($data['language'])) {
$this->_header->setLanguage($data['language']);
}
if (isset($data['ttl'])) {
$this->_header->setTtl($data['ttl']);
}
if (isset($data['rating'])) {
$this->_header->setRating($data['rating']);
}
if (isset($data['cloud'])) {
$mandatories = array('domain', 'path', 'registerProcedure', 'protocol');
foreach ($mandatories as $mandatory) {
if (!isset($data['cloud'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your cloud");
}
}
$uri_str = 'http://' . $data['cloud']['domain'] . $data['cloud']['path'];
$this->_header->setCloud($uri_str, $data['cloud']['registerProcedure'], $data['cloud']['protocol']);
}
if (isset($data['textInput'])) {
$mandatories = array('title', 'description', 'name', 'link');
foreach ($mandatories as $mandatory) {
if (!isset($data['textInput'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your textInput");
}
}
$this->_header->setTextInput($data['textInput']['title'],
$data['textInput']['description'],
$data['textInput']['name'],
$data['textInput']['link']);
}
if (isset($data['skipHours'])) {
$this->_header->setSkipHours($data['skipHours']);
}
if (isset($data['skipDays'])) {
$this->_header->setSkipDays($data['skipDays']);
}
if (isset($data['itunes'])) {
$itunes = new Zend_Feed_Builder_Header_Itunes($data['itunes']['category']);
if (isset($data['itunes']['author'])) {
$itunes->setAuthor($data['itunes']['author']);
}
if (isset($data['itunes']['owner'])) {
$name = isset($data['itunes']['owner']['name']) ? $data['itunes']['owner']['name'] : '';
$email = isset($data['itunes']['owner']['email']) ? $data['itunes']['owner']['email'] : '';
$itunes->setOwner($name, $email);
}
if (isset($data['itunes']['image'])) {
$itunes->setImage($data['itunes']['image']);
}
if (isset($data['itunes']['subtitle'])) {
$itunes->setSubtitle($data['itunes']['subtitle']);
}
if (isset($data['itunes']['summary'])) {
$itunes->setSummary($data['itunes']['summary']);
}
if (isset($data['itunes']['block'])) {
$itunes->setBlock($data['itunes']['block']);
}
if (isset($data['itunes']['explicit'])) {
$itunes->setExplicit($data['itunes']['explicit']);
}
if (isset($data['itunes']['keywords'])) {
$itunes->setKeywords($data['itunes']['keywords']);
}
if (isset($data['itunes']['new-feed-url'])) {
$itunes->setNewFeedUrl($data['itunes']['new-feed-url']);
}
$this->_header->setITunes($itunes);
}
}
/**
* Create the array of article entries
*
* @param array $data
* @throws Zend_Feed_Builder_Exception
* @return void
*/
private function _createEntries(array $data)
{
foreach ($data as $row) {
$mandatories = array('title', 'link', 'description');
foreach ($mandatories as $mandatory) {
if (!isset($row[$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
$entry = new Zend_Feed_Builder_Entry($row['title'], $row['link'], $row['description']);
if (isset($row['guid'])) {
$entry->setId($row['guid']);
}
if (isset($row['content'])) {
$entry->setContent($row['content']);
}
if (isset($row['lastUpdate'])) {
$entry->setLastUpdate($row['lastUpdate']);
}
if (isset($row['comments'])) {
$entry->setCommentsUrl($row['comments']);
}
if (isset($row['commentRss'])) {
$entry->setCommentsRssUrl($row['commentRss']);
}
if (isset($row['source'])) {
$mandatories = array('title', 'url');
foreach ($mandatories as $mandatory) {
if (!isset($row['source'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key of source property is missing");
}
}
$entry->setSource($row['source']['title'], $row['source']['url']);
}
if (isset($row['category'])) {
$entry->setCategories($row['category']);
}
if (isset($row['enclosure'])) {
$entry->setEnclosures($row['enclosure']);
}
$this->_entries[] = $entry;
}
}
}

View File

@ -0,0 +1,285 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Entry.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* An entry of a custom build feed
*
* Classes implementing the Zend_Feed_Builder_Interface interface
* uses this class to describe an entry of a feed
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Entry extends ArrayObject
{
/**
* Create a new builder entry
*
* @param string $title
* @param string $link
* @param string $description short version of the entry, no html
* @return void
*/
public function __construct($title, $link, $description)
{
$this->offsetSet('title', $title);
$this->offsetSet('link', $link);
$this->offsetSet('description', $description);
$this->setLastUpdate(time());
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
/**
* Sets the id/guid of the entry
*
* @param string $id
* @return Zend_Feed_Builder_Entry
*/
public function setId($id)
{
$this->offsetSet('guid', $id);
return $this;
}
/**
* Sets the full html content of the entry
*
* @param string $content
* @return Zend_Feed_Builder_Entry
*/
public function setContent($content)
{
$this->offsetSet('content', $content);
return $this;
}
/**
* Timestamp of the update date
*
* @param int $lastUpdate
* @return Zend_Feed_Builder_Entry
*/
public function setLastUpdate($lastUpdate)
{
$this->offsetSet('lastUpdate', $lastUpdate);
return $this;
}
/**
* Sets the url of the commented page associated to the entry
*
* @param string $comments
* @return Zend_Feed_Builder_Entry
*/
public function setCommentsUrl($comments)
{
$this->offsetSet('comments', $comments);
return $this;
}
/**
* Sets the url of the comments feed link
*
* @param string $commentRss
* @return Zend_Feed_Builder_Entry
*/
public function setCommentsRssUrl($commentRss)
{
$this->offsetSet('commentRss', $commentRss);
return $this;
}
/**
* Defines a reference to the original source
*
* @param string $title
* @param string $url
* @return Zend_Feed_Builder_Entry
*/
public function setSource($title, $url)
{
$this->offsetSet('source', array('title' => $title,
'url' => $url));
return $this;
}
/**
* Sets the categories of the entry
* Format of the array:
* <code>
* array(
* array(
* 'term' => 'first category label',
* 'scheme' => 'url that identifies a categorization scheme' // optional
* ),
* // second category and so one
* )
* </code>
*
* @param array $categories
* @return Zend_Feed_Builder_Entry
*/
public function setCategories(array $categories)
{
foreach ($categories as $category) {
$this->addCategory($category);
}
return $this;
}
/**
* Add a category to the entry
*
* @param array $category see Zend_Feed_Builder_Entry::setCategories() for format
* @return Zend_Feed_Builder_Entry
* @throws Zend_Feed_Builder_Exception
*/
public function addCategory(array $category)
{
if (empty($category['term'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define the name of the category");
}
if (!$this->offsetExists('category')) {
$categories = array($category);
} else {
$categories = $this->offsetGet('category');
$categories[] = $category;
}
$this->offsetSet('category', $categories);
return $this;
}
/**
* Sets the enclosures of the entry
* Format of the array:
* <code>
* array(
* array(
* 'url' => 'url of the linked enclosure',
* 'type' => 'mime type of the enclosure' // optional
* 'length' => 'length of the linked content in octets' // optional
* ),
* // second enclosure and so one
* )
* </code>
*
* @param array $enclosures
* @return Zend_Feed_Builder_Entry
* @throws Zend_Feed_Builder_Exception
*/
public function setEnclosures(array $enclosures)
{
foreach ($enclosures as $enclosure) {
if (empty($enclosure['url'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to supply an url for your enclosure");
}
$type = isset($enclosure['type']) ? $enclosure['type'] : '';
$length = isset($enclosure['length']) ? $enclosure['length'] : '';
$this->addEnclosure($enclosure['url'], $type, $length);
}
return $this;
}
/**
* Add an enclosure to the entry
*
* @param string $url
* @param string $type
* @param string $length
* @return Zend_Feed_Builder_Entry
*/
public function addEnclosure($url, $type = '', $length = '')
{
if (!$this->offsetExists('enclosure')) {
$enclosure = array();
} else {
$enclosure = $this->offsetGet('enclosure');
}
$enclosure[] = array('url' => $url,
'type' => $type,
'length' => $length);
$this->offsetSet('enclosure', $enclosure);
return $this;
}
}

View File

@ -0,0 +1,40 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
/**
* Zend_Feed_Builder exception class
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Exception extends Zend_Feed_Exception
{
}

View File

@ -0,0 +1,420 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Header.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
/**
* @see Zend_Feed_Builder_Header_Itunes
*/
require_once 'Zend/Feed/Builder/Header/Itunes.php';
/**
* @see Zend_Uri
*/
require_once 'Zend/Uri.php';
/**
* Header of a custom build feed
*
* Classes implementing the Zend_Feed_Builder_Interface interface
* uses this class to describe the header of a feed
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Header extends ArrayObject
{
/**
* Constructor
*
* @param string $title title of the feed
* @param string $link canonical url of the feed
* @param string $charset charset of the textual data
* @return void
*/
public function __construct($title, $link, $charset = 'utf-8')
{
$this->offsetSet('title', $title);
$this->offsetSet('link', $link);
$this->offsetSet('charset', $charset);
$this->setLastUpdate(time())
->setGenerator('Zend_Feed');
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
/**
* Timestamp of the update date
*
* @param int $lastUpdate
* @return Zend_Feed_Builder_Header
*/
public function setLastUpdate($lastUpdate)
{
$this->offsetSet('lastUpdate', $lastUpdate);
return $this;
}
/**
* Timestamp of the publication date
*
* @param int $published
* @return Zend_Feed_Builder_Header
*/
public function setPublishedDate($published)
{
$this->offsetSet('published', $published);
return $this;
}
/**
* Short description of the feed
*
* @param string $description
* @return Zend_Feed_Builder_Header
*/
public function setDescription($description)
{
$this->offsetSet('description', $description);
return $this;
}
/**
* Sets the author of the feed
*
* @param string $author
* @return Zend_Feed_Builder_Header
*/
public function setAuthor($author)
{
$this->offsetSet('author', $author);
return $this;
}
/**
* Sets the author's email
*
* @param string $email
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setEmail($email)
{
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the email property");
}
$this->offsetSet('email', $email);
return $this;
}
/**
* Sets the copyright notice
*
* @param string $copyright
* @return Zend_Feed_Builder_Header
*/
public function setCopyright($copyright)
{
$this->offsetSet('copyright', $copyright);
return $this;
}
/**
* Sets the image of the feed
*
* @param string $image
* @return Zend_Feed_Builder_Header
*/
public function setImage($image)
{
$this->offsetSet('image', $image);
return $this;
}
/**
* Sets the generator of the feed
*
* @param string $generator
* @return Zend_Feed_Builder_Header
*/
public function setGenerator($generator)
{
$this->offsetSet('generator', $generator);
return $this;
}
/**
* Sets the language of the feed
*
* @param string $language
* @return Zend_Feed_Builder_Header
*/
public function setLanguage($language)
{
$this->offsetSet('language', $language);
return $this;
}
/**
* Email address for person responsible for technical issues
* Ignored if atom is used
*
* @param string $webmaster
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setWebmaster($webmaster)
{
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($webmaster)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the webmaster property");
}
$this->offsetSet('webmaster', $webmaster);
return $this;
}
/**
* How long in minutes a feed can be cached before refreshing
* Ignored if atom is used
*
* @param int $ttl
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setTtl($ttl)
{
Zend_Loader::loadClass('Zend_Validate_Int');
$validate = new Zend_Validate_Int();
if (!$validate->isValid($ttl)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set an integer value to the ttl property");
}
$this->offsetSet('ttl', $ttl);
return $this;
}
/**
* PICS rating for the feed
* Ignored if atom is used
*
* @param string $rating
* @return Zend_Feed_Builder_Header
*/
public function setRating($rating)
{
$this->offsetSet('rating', $rating);
return $this;
}
/**
* Cloud to be notified of updates of the feed
* Ignored if atom is used
*
* @param string|Zend_Uri_Http $uri
* @param string $procedure procedure to call, e.g. myCloud.rssPleaseNotify
* @param string $protocol protocol to use, e.g. soap or xml-rpc
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setCloud($uri, $procedure, $protocol)
{
if (is_string($uri) && Zend_Uri_Http::check($uri)) {
$uri = Zend_Uri::factory($uri);
}
if (!$uri instanceof Zend_Uri_Http) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception('Passed parameter is not a valid HTTP URI');
}
if (!$uri->getPort()) {
$uri->setPort(80);
}
$this->offsetSet('cloud', array('uri' => $uri,
'procedure' => $procedure,
'protocol' => $protocol));
return $this;
}
/**
* A text input box that can be displayed with the feed
* Ignored if atom is used
*
* @param string $title the label of the Submit button in the text input area
* @param string $description explains the text input area
* @param string $name the name of the text object in the text input area
* @param string $link the URL of the CGI script that processes text input requests
* @return Zend_Feed_Builder_Header
*/
public function setTextInput($title, $description, $name, $link)
{
$this->offsetSet('textInput', array('title' => $title,
'description' => $description,
'name' => $name,
'link' => $link));
return $this;
}
/**
* Hint telling aggregators which hours they can skip
* Ignored if atom is used
*
* @param array $hours list of hours in 24 format
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setSkipHours(array $hours)
{
if (count($hours) > 24) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you can not have more than 24 rows in the skipHours property");
}
foreach ($hours as $hour) {
if ($hour < 0 || $hour > 23) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$hour has te be between 0 and 23");
}
}
$this->offsetSet('skipHours', $hours);
return $this;
}
/**
* Hint telling aggregators which days they can skip
* Ignored if atom is used
*
* @param array $days list of days to skip, e.g. Monday
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setSkipDays(array $days)
{
if (count($days) > 7) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you can not have more than 7 days in the skipDays property");
}
$valid = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
foreach ($days as $day) {
if (!in_array(strtolower($day), $valid)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$day is not a valid day");
}
}
$this->offsetSet('skipDays', $days);
return $this;
}
/**
* Sets the iTunes rss extension
*
* @param Zend_Feed_Builder_Header_Itunes $itunes
* @return Zend_Feed_Builder_Header
*/
public function setITunes(Zend_Feed_Builder_Header_Itunes $itunes)
{
$this->offsetSet('itunes', $itunes);
return $this;
}
}

View File

@ -0,0 +1,285 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Itunes.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* ITunes rss extension
*
* Classes used to describe the itunes channel extension
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Header_Itunes extends ArrayObject
{
/**
* Constructor
*
* @param array $categories Categories columns and in iTunes Music Store Browse
* @return void
*/
public function __construct(array $categories)
{
$this->setCategories($categories);
}
/**
* Sets the categories column and in iTunes Music Store Browse
* $categories must conform to the following format:
* <code>
* array(array('main' => 'main category',
* 'sub' => 'sub category' // optionnal
* ),
* // up to 3 rows
* )
* </code>
*
* @param array $categories
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setCategories(array $categories)
{
$nb = count($categories);
if (0 === $nb) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set at least one itunes category");
}
if ($nb > 3) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set at most three itunes categories");
}
foreach ($categories as $i => $category) {
if (empty($category['main'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set the main category (category #$i)");
}
}
$this->offsetSet('category', $categories);
return $this;
}
/**
* Sets the artist value, default to the feed's author value
*
* @param string $author
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setAuthor($author)
{
$this->offsetSet('author', $author);
return $this;
}
/**
* Sets the owner of the postcast
*
* @param string $name default to the feed's author value
* @param string $email default to the feed's email value
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setOwner($name = '', $email = '')
{
if (!empty($email)) {
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the itunes owner's email property");
}
}
$this->offsetSet('owner', array('name' => $name, 'email' => $email));
return $this;
}
/**
* Sets the album/podcast art picture
* Default to the feed's image value
*
* @param string $image
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setImage($image)
{
$this->offsetSet('image', $image);
return $this;
}
/**
* Sets the short description of the podcast
* Default to the feed's description
*
* @param string $subtitle
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setSubtitle($subtitle)
{
$this->offsetSet('subtitle', $subtitle);
return $this;
}
/**
* Sets the longer description of the podcast
* Default to the feed's description
*
* @param string $summary
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setSummary($summary)
{
$this->offsetSet('summary', $summary);
return $this;
}
/**
* Prevent a feed from appearing
*
* @param string $block can be 'yes' or 'no'
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setBlock($block)
{
$block = strtolower($block);
if (!in_array($block, array('yes', 'no'))) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set yes or no to the itunes block property");
}
$this->offsetSet('block', $block);
return $this;
}
/**
* Configuration of the parental advisory graphic
*
* @param string $explicit can be 'yes', 'no' or 'clean'
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setExplicit($explicit)
{
$explicit = strtolower($explicit);
if (!in_array($explicit, array('yes', 'no', 'clean'))) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set yes, no or clean to the itunes explicit property");
}
$this->offsetSet('explicit', $explicit);
return $this;
}
/**
* Sets a comma separated list of 12 keywords maximum
*
* @param string $keywords
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setKeywords($keywords)
{
$this->offsetSet('keywords', $keywords);
return $this;
}
/**
* Sets the new feed URL location
*
* @param string $url
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setNewFeedUrl($url)
{
$this->offsetSet('new_feed_url', $url);
return $this;
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Input feed data interface
*
* Classes implementing this interface can be passe to Zend_Feed::importBuilder
* as an input data source for the Zend_Feed construction
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Feed_Builder_Interface
{
/**
* Returns an instance of Zend_Feed_Builder_Header
* describing the header of the feed
*
* @return Zend_Feed_Builder_Header
*/
public function getHeader();
/**
* Returns an array of Zend_Feed_Builder_Entry instances
* describing the entries of the feed
*
* @return array of Zend_Feed_Builder_Entry
*/
public function getEntries();
}

408
libs/Zend/Feed/Element.php Normal file
View File

@ -0,0 +1,408 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Element.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Wraps a DOMElement allowing for SimpleXML-like access to attributes.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Element implements ArrayAccess
{
/**
* @var DOMElement
*/
protected $_element;
/**
* @var Zend_Feed_Element
*/
protected $_parentElement;
/**
* @var boolean
*/
protected $_appended = true;
/**
* Zend_Feed_Element constructor.
*
* @param DOMElement $element The DOM element we're encapsulating.
* @return void
*/
public function __construct($element = null)
{
$this->_element = $element;
}
/**
* Get a DOM representation of the element
*
* Returns the underlying DOM object, which can then be
* manipulated with full DOM methods.
*
* @return DOMDocument
*/
public function getDOM()
{
return $this->_element;
}
/**
* Update the object from a DOM element
*
* Take a DOMElement object, which may be originally from a call
* to getDOM() or may be custom created, and use it as the
* DOM tree for this Zend_Feed_Element.
*
* @param DOMElement $element
* @return void
*/
public function setDOM(DOMElement $element)
{
$this->_element = $this->_element->ownerDocument->importNode($element, true);
}
/**
* Set the parent element of this object to another
* Zend_Feed_Element.
*
* @param Zend_Feed_Element $element
* @return void
*/
public function setParent(Zend_Feed_Element $element)
{
$this->_parentElement = $element;
$this->_appended = false;
}
/**
* Appends this element to its parent if necessary.
*
* @return void
*/
protected function ensureAppended()
{
if (!$this->_appended) {
$this->_parentElement->getDOM()->appendChild($this->_element);
$this->_appended = true;
$this->_parentElement->ensureAppended();
}
}
/**
* Get an XML string representation of this element
*
* Returns a string of this element's XML, including the XML
* prologue.
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$doc->appendChild($doc->importNode($this->_element, true));
return $doc->saveXML();
}
/**
* Get the XML for only this element
*
* Returns a string of this element's XML without prologue.
*
* @return string
*/
public function saveXmlFragment()
{
return $this->_element->ownerDocument->saveXML($this->_element);
}
/**
* Map variable access onto the underlying entry representation.
*
* Get-style access returns a Zend_Feed_Element representing the
* child element accessed. To get string values, use method syntax
* with the __call() overriding.
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
$nodes = $this->_children($var);
$length = count($nodes);
if ($length == 1) {
return new Zend_Feed_Element($nodes[0]);
} elseif ($length > 1) {
return array_map(create_function('$e', 'return new Zend_Feed_Element($e);'), $nodes);
} else {
// When creating anonymous nodes for __set chaining, don't
// call appendChild() on them. Instead we pass the current
// element to them as an extra reference; the child is
// then responsible for appending itself when it is
// actually set. This way "if ($foo->bar)" doesn't create
// a phantom "bar" element in our tree.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
$node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $elt);
} else {
$node = $this->_element->ownerDocument->createElement($var);
}
$node = new self($node);
$node->setParent($this);
return $node;
}
}
/**
* Map variable sets onto the underlying entry representation.
*
* @param string $var The property to change.
* @param string $val The property's new value.
* @return void
* @throws Zend_Feed_Exception
*/
public function __set($var, $val)
{
$this->ensureAppended();
$nodes = $this->_children($var);
if (!$nodes) {
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
$node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $var, $val);
$this->_element->appendChild($node);
} else {
$node = $this->_element->ownerDocument->createElement($var, $val);
$this->_element->appendChild($node);
}
} elseif (count($nodes) > 1) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot set the value of multiple tags simultaneously.');
} else {
$nodes[0]->nodeValue = $val;
}
}
/**
* Map isset calls onto the underlying entry representation.
*
* @param string $var
* @return boolean
*/
public function __isset($var)
{
// Look for access of the form {ns:var}. We don't use
// _children() here because we can break out of the loop
// immediately once we find something.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $elt && $child->prefix == $ns) {
return true;
}
}
} else {
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $var) {
return true;
}
}
}
}
/**
* Get the value of an element with method syntax.
*
* Map method calls to get the string value of the requested
* element. If there are multiple elements that match, this will
* return an array of those objects.
*
* @param string $var The element to get the string value of.
* @param mixed $unused This parameter is not used.
* @return mixed The node's value, null, or an array of nodes.
*/
public function __call($var, $unused)
{
$nodes = $this->_children($var);
if (!$nodes) {
return null;
} elseif (count($nodes) > 1) {
return $nodes;
} else {
return $nodes[0]->nodeValue;
}
}
/**
* Remove all children matching $var.
*
* @param string $var
* @return void
*/
public function __unset($var)
{
$nodes = $this->_children($var);
foreach ($nodes as $node) {
$parent = $node->parentNode;
$parent->removeChild($node);
}
}
/**
* Returns the nodeValue of this element when this object is used
* in a string context.
*
* @return string
*/
public function __toString()
{
return $this->_element->nodeValue;
}
/**
* Finds children with tagnames matching $var
*
* Similar to SimpleXML's children() method.
*
* @param string $var Tagname to match, can be either namespace:tagName or just tagName.
* @return array
*/
protected function _children($var)
{
$found = array();
// Look for access of the form {ns:var}.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $elt && $child->prefix == $ns) {
$found[] = $child;
}
}
} else {
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $var) {
$found[] = $child;
}
}
}
return $found;
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return boolean
*/
public function offsetExists($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->hasAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->hasAttribute($offset);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return string
*/
public function offsetGet($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->getAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->getAttribute($offset);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @param string $value
* @return string
*/
public function offsetSet($offset, $value)
{
$this->ensureAppended();
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->setAttributeNS(Zend_Feed::lookupNamespace($ns), $attr, $value);
} else {
return $this->_element->setAttribute($offset, $value);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return boolean
*/
public function offsetUnset($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->removeAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->removeAttribute($offset);
}
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 10383 2008-07-24 19:46:15Z matthew $
*/
/**
* @see Zend_Feed
*/
require_once 'Zend/Feed.php';
/**
* @see Zend_Feed_Element
*/
require_once 'Zend/Feed/Element.php';
/**
* Zend_Feed_Entry_Abstract represents a single entry in an Atom or RSS
* feed.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Entry_Abstract extends Zend_Feed_Element
{
/**
* Root XML element for entries. Subclasses must define this to a
* non-null value.
*
* @var string
*/
protected $_rootElement;
/**
* Root namespace for entries. Subclasses may define this to a
* non-null value.
*
* @var string
*/
protected $_rootNamespace = null;
/**
* Zend_Feed_Entry_Abstract constructor
*
* The Zend_Feed_Entry_Abstract constructor takes the URI of the feed the entry
* is part of, and optionally an XML construct (usually a
* SimpleXMLElement, but it can be an XML string or a DOMNode as
* well) that contains the contents of the entry.
*
* @param string $uri
* @param SimpleXMLElement|DOMNode|string $element
* @return void
* @throws Zend_Feed_Exception
*/
public function __construct($uri = null, $element = null)
{
if (!($element instanceof DOMElement)) {
if ($element) {
// Load the feed as an XML DOMDocument object
@ini_set('track_errors', 1);
$doc = new DOMDocument();
$status = @$doc->loadXML($element);
@ini_restore('track_errors');
if (!$status) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
$element = $doc->getElementsByTagName($this->_rootElement)->item(0);
if (!$element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <' . $this->_rootElement . '> element found, cannot parse feed.');
}
} else {
$doc = new DOMDocument('1.0', 'utf-8');
if ($this->_rootNamespace !== null) {
$element = $doc->createElementNS(Zend_Feed::lookupNamespace($this->_rootNamespace), $this->_rootElement);
} else {
$element = $doc->createElement($this->_rootElement);
}
}
}
parent::__construct($element);
}
}

View File

@ -0,0 +1,274 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Atom.php 10383 2008-07-24 19:46:15Z matthew $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
require_once 'Zend/Feed/Entry/Abstract.php';
/**
* Concrete class for working with Atom entries.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
{
/**
* Root XML element for Atom entries.
*
* @var string
*/
protected $_rootElement = 'entry';
/**
* Root namespace for Atom entries.
*
* @var string
*/
protected $_rootNamespace = 'atom';
/**
* Delete an atom entry.
*
* Delete tries to delete this entry from its feed. If the entry
* does not contain a link rel="edit", we throw an error (either
* the entry does not yet exist or this is not an editable
* feed). If we have a link rel="edit", we do the empty-body
* HTTP DELETE to that URI and check for a response of 2xx.
* Usually the response would be 204 No Content, but the Atom
* Publishing Protocol permits it to be 200 OK.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function delete()
{
// Look for link rel="edit" in the entry object.
$deleteUri = $this->link('edit');
if (!$deleteUri) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot delete entry; no link rel="edit" is present.');
}
// DELETE
$client = Zend_Feed::getHttpClient();
do {
$client->setUri($deleteUri);
if (Zend_Feed::getHttpMethodOverride()) {
$client->setHeader('X-HTTP-Method-Override', 'DELETE');
$response = $client->request('POST');
} else {
$response = $client->request('DELETE');
}
$httpStatus = $response->getStatus();
switch ((int) $httpStatus / 100) {
// Success
case 2:
return true;
// Redirect
case 3:
$deleteUri = $response->getHeader('Location');
continue;
// Error
default:
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Expected response code 2xx, got $httpStatus");
}
} while (true);
}
/**
* Save a new or updated Atom entry.
*
* Save is used to either create new entries or to save changes to
* existing ones. If we have a link rel="edit", we are changing
* an existing entry. In this case we re-serialize the entry and
* PUT it to the edit URI, checking for a 200 OK result.
*
* For posting new entries, you must specify the $postUri
* parameter to save() to tell the object where to post itself.
* We use $postUri and POST the serialized entry there, checking
* for a 201 Created response. If the insert is successful, we
* then parse the response from the POST to get any values that
* the server has generated: an id, an updated time, and its new
* link rel="edit".
*
* @param string $postUri Location to POST for creating new entries.
* @return void
* @throws Zend_Feed_Exception
*/
public function save($postUri = null)
{
if ($this->id()) {
// If id is set, look for link rel="edit" in the
// entry object and PUT.
$editUri = $this->link('edit');
if (!$editUri) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot edit entry; no link rel="edit" is present.');
}
$client = Zend_Feed::getHttpClient();
$client->setUri($editUri);
if (Zend_Feed::getHttpMethodOverride()) {
$client->setHeaders(array('X-HTTP-Method-Override: PUT',
'Content-Type: application/atom+xml'));
$client->setRawData($this->saveXML());
$response = $client->request('POST');
} else {
$client->setHeaders('Content-Type', 'application/atom+xml');
$client->setRawData($this->saveXML());
$response = $client->request('PUT');
}
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 200, got ' . $response->getStatus());
}
} else {
if ($postUri === null) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('PostURI must be specified to save new entries.');
}
$client = Zend_Feed::getHttpClient();
$client->setUri($postUri);
$client->setRawData($this->saveXML());
$response = $client->request('POST');
if ($response->getStatus() !== 201) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 201, got '
. $response->getStatus());
}
}
// Update internal properties using $client->responseBody;
@ini_set('track_errors', 1);
$newEntry = new DOMDocument;
$status = @$newEntry->loadXML($response->getBody());
@ini_restore('track_errors');
if (!$status) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('XML cannot be parsed: ' . $php_errormsg);
}
$newEntry = $newEntry->getElementsByTagName($this->_rootElement)->item(0);
if (!$newEntry) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> element found in server response:'
. "\n\n" . $client->responseBody);
}
if ($this->_element->parentNode) {
$oldElement = $this->_element;
$this->_element = $oldElement->ownerDocument->importNode($newEntry, true);
$oldElement->parentNode->replaceChild($this->_element, $oldElement);
} else {
$this->_element = $newEntry;
}
}
/**
* Easy access to <link> tags keyed by "rel" attributes.
*
* If $elt->link() is called with no arguments, we will attempt to
* return the value of the <link> tag(s) like all other
* method-syntax attribute access. If an argument is passed to
* link(), however, then we will return the "href" value of the
* first <link> tag that has a "rel" attribute matching $rel:
*
* $elt->link(): returns the value of the link tag.
* $elt->link('self'): returns the href from the first <link rel="self"> in the entry.
*
* @param string $rel The "rel" attribute to look for.
* @return mixed
*/
public function link($rel = null)
{
if ($rel === null) {
return parent::__call('link', null);
}
// index link tags by their "rel" attribute.
$links = parent::__get('link');
if (!is_array($links)) {
if ($links instanceof Zend_Feed_Element) {
$links = array($links);
} else {
return $links;
}
}
foreach ($links as $link) {
if (empty($link['rel'])) {
continue;
}
if ($rel == $link['rel']) {
return $link['href'];
}
}
return null;
}
}

View File

@ -0,0 +1,122 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rss.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
require_once 'Zend/Feed/Entry/Abstract.php';
/**
* Concrete class for working with RSS items.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Entry_Rss extends Zend_Feed_Entry_Abstract
{
/**
* Root XML element for RSS items.
*
* @var string
*/
protected $_rootElement = 'item';
/**
* Overwrites parent::_get method to enable read access
* to content:encoded element.
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'content':
$prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
return parent::__get("$prefix:encoded");
default:
return parent::__get($var);
}
}
/**
* Overwrites parent::_set method to enable write access
* to content:encoded element.
*
* @param string $var The property to change.
* @param string $val The property's new value.
* @return void
*/
public function __set($var, $value)
{
switch ($var) {
case 'content':
parent::__set('content:encoded', $value);
break;
default:
parent::__set($var, $value);
}
}
/**
* Overwrites parent::_isset method to enable access
* to content:encoded element.
*
* @param string $var
* @return boolean
*/
public function __isset($var)
{
switch ($var) {
case 'content':
// don't use other callback to prevent invalid returned value
return $this->content() !== null;
default:
return parent::__isset($var);
}
}
/**
* Overwrites parent::_call method to enable read access
* to content:encoded element.
* Please note that method-style write access is not currently supported
* by parent method, consequently this method doesn't as well.
*
* @param string $var The element to get the string value of.
* @param mixed $unused This parameter is not used.
* @return mixed The node's value, null, or an array of nodes.
*/
public function __call($var, $unused)
{
switch ($var) {
case 'content':
$prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
return parent::__call("$prefix:encoded", $unused);
default:
return parent::__call($var, $unused);
}
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Exception
*/
require_once 'Zend/Exception.php';
/**
* Feed exceptions
*
* Class to represent exceptions that occur during Feed operations.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Exception extends Zend_Exception
{}

504
libs/Zend/Feed/Rss.php Normal file
View File

@ -0,0 +1,504 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rss.php 11654 2008-10-03 16:03:35Z yoshida@zend.co.jp $
*/
/**
* @see Zend_Feed_Abstract
*/
require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Rss
*/
require_once 'Zend/Feed/Entry/Rss.php';
/**
* RSS channel class
*
* The Zend_Feed_Rss class is a concrete subclass of
* Zend_Feed_Abstract meant for representing RSS channels. It does not
* add any methods to its parent, just provides a classname to check
* against with the instanceof operator, and expects to be handling
* RSS-formatted data instead of Atom.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Rss extends Zend_Feed_Abstract
{
/**
* The classname for individual channel elements.
*
* @var string
*/
protected $_entryClassName = 'Zend_Feed_Entry_Rss';
/**
* The element name for individual channel elements (RSS <item>s).
*
* @var string
*/
protected $_entryElementName = 'item';
/**
* The default namespace for RSS channels.
*
* @var string
*/
protected $_defaultNamespace = 'rss';
/**
* Override Zend_Feed_Abstract to set up the $_element and $_entries aliases.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
parent::__wakeup();
// Find the base channel element and create an alias to it.
$this->_element = $this->_element->getElementsByTagName('channel')->item(0);
if (!$this->_element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <channel> element found, cannot parse channel.');
}
// Find the entries and save a pointer to them for speed and
// simplicity.
$this->_buildEntryCache();
}
/**
* Make accessing some individual elements of the channel easier.
*
* Special accessors 'item' and 'items' are provided so that if
* you wish to iterate over an RSS channel's items, you can do so
* using foreach ($channel->items as $item) or foreach
* ($channel->item as $item).
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'item':
// fall through to the next case
case 'items':
return $this;
default:
return parent::__get($var);
}
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
protected function _mapFeedHeaders($array)
{
$channel = $this->_element->createElement('channel');
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($array->title));
$channel->appendChild($title);
$link = $this->_element->createElement('link', $array->link);
$channel->appendChild($link);
$desc = isset($array->description) ? $array->description : '';
$description = $this->_element->createElement('description');
$description->appendChild($this->_element->createCDATASection($desc));
$channel->appendChild($description);
$pubdate = isset($array->lastUpdate) ? $array->lastUpdate : time();
$pubdate = $this->_element->createElement('pubDate', gmdate('r', $pubdate));
$channel->appendChild($pubdate);
if (isset($array->published)) {
$lastBuildDate = $this->_element->createElement('lastBuildDate', gmdate('r', $array->published));
}
$editor = '';
if (!empty($array->email)) {
$editor .= $array->email;
}
if (!empty($array->author)) {
$editor .= ' (' . $array->author . ')';
}
if (!empty($editor)) {
$author = $this->_element->createElement('managingEditor', ltrim($editor));
$channel->appendChild($author);
}
if (isset($array->webmaster)) {
$channel->appendChild($this->_element->createElement('webMaster', $array->webmaster));
}
if (!empty($array->copyright)) {
$copyright = $this->_element->createElement('copyright', $array->copyright);
$channel->appendChild($copyright);
}
if (!empty($array->image)) {
$image = $this->_element->createElement('image');
$url = $this->_element->createElement('url', $array->image);
$image->appendChild($url);
$imagetitle = $this->_element->createElement('title', $array->title);
$image->appendChild($imagetitle);
$imagelink = $this->_element->createElement('link', $array->link);
$image->appendChild($imagelink);
$channel->appendChild($image);
}
$generator = !empty($array->generator) ? $array->generator : 'Zend_Feed';
$generator = $this->_element->createElement('generator', $generator);
$channel->appendChild($generator);
if (!empty($array->language)) {
$language = $this->_element->createElement('language', $array->language);
$channel->appendChild($language);
}
$doc = $this->_element->createElement('docs', 'http://blogs.law.harvard.edu/tech/rss');
$channel->appendChild($doc);
if (isset($array->cloud)) {
$cloud = $this->_element->createElement('cloud');
$cloud->setAttribute('domain', $array->cloud['uri']->getHost());
$cloud->setAttribute('port', $array->cloud['uri']->getPort());
$cloud->setAttribute('path', $array->cloud['uri']->getPath());
$cloud->setAttribute('registerProcedure', $array->cloud['procedure']);
$cloud->setAttribute('protocol', $array->cloud['protocol']);
$channel->appendChild($cloud);
}
if (isset($array->rating)) {
$rating = $this->_element->createElement('rating', $array->rating);
$channel->appendChild($rating);
}
if (isset($array->textInput)) {
$textinput = $this->_element->createElement('textInput');
$textinput->appendChild($this->_element->createElement('title', $array->textInput['title']));
$textinput->appendChild($this->_element->createElement('description', $array->textInput['description']));
$textinput->appendChild($this->_element->createElement('name', $array->textInput['name']));
$textinput->appendChild($this->_element->createElement('link', $array->textInput['link']));
$channel->appendChild($textinput);
}
if (isset($array->skipHours)) {
$skipHours = $this->_element->createElement('skipHours');
foreach ($array->skipHours as $hour) {
$skipHours->appendChild($this->_element->createElement('hour', $hour));
}
$channel->appendChild($skipHours);
}
if (isset($array->skipDays)) {
$skipDays = $this->_element->createElement('skipDays');
foreach ($array->skipDays as $day) {
$skipDays->appendChild($this->_element->createElement('day', $day));
}
$channel->appendChild($skipDays);
}
if (isset($array->itunes)) {
$this->_buildiTunes($channel, $array);
}
return $channel;
}
/**
* Adds the iTunes extensions to a root node
*
* @param DOMElement $root
* @param array $array
* @return void
*/
private function _buildiTunes(DOMElement $root, $array)
{
/* author node */
$author = '';
if (isset($array->itunes->author)) {
$author = $array->itunes->author;
} elseif (isset($array->author)) {
$author = $array->author;
}
if (!empty($author)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:author', $author);
$root->appendChild($node);
}
/* owner node */
$author = '';
$email = '';
if (isset($array->itunes->owner)) {
if (isset($array->itunes->owner['name'])) {
$author = $array->itunes->owner['name'];
}
if (isset($array->itunes->owner['email'])) {
$email = $array->itunes->owner['email'];
}
}
if (empty($author) && isset($array->author)) {
$author = $array->author;
}
if (empty($email) && isset($array->email)) {
$email = $array->email;
}
if (!empty($author) || !empty($email)) {
$owner = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:owner');
if (!empty($author)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:name', $author);
$owner->appendChild($node);
}
if (!empty($email)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:email', $email);
$owner->appendChild($node);
}
$root->appendChild($owner);
}
$image = '';
if (isset($array->itunes->image)) {
$image = $array->itunes->image;
} elseif (isset($array->image)) {
$image = $array->image;
}
if (!empty($image)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:image');
$node->setAttribute('href', $image);
$root->appendChild($node);
}
$subtitle = '';
if (isset($array->itunes->subtitle)) {
$subtitle = $array->itunes->subtitle;
} elseif (isset($array->description)) {
$subtitle = $array->description;
}
if (!empty($subtitle)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:subtitle', $subtitle);
$root->appendChild($node);
}
$summary = '';
if (isset($array->itunes->summary)) {
$summary = $array->itunes->summary;
} elseif (isset($array->description)) {
$summary = $array->description;
}
if (!empty($summary)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:summary', $summary);
$root->appendChild($node);
}
if (isset($array->itunes->block)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:block', $array->itunes->block);
$root->appendChild($node);
}
if (isset($array->itunes->explicit)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:explicit', $array->itunes->explicit);
$root->appendChild($node);
}
if (isset($array->itunes->keywords)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:keywords', $array->itunes->keywords);
$root->appendChild($node);
}
if (isset($array->itunes->new_feed_url)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:new-feed-url', $array->itunes->new_feed_url);
$root->appendChild($node);
}
if (isset($array->itunes->category)) {
foreach ($array->itunes->category as $i => $category) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$node->setAttribute('text', $category['main']);
$root->appendChild($node);
$add_end_category = false;
if (!empty($category['sub'])) {
$add_end_category = true;
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$node->setAttribute('text', $category['sub']);
$root->appendChild($node);
}
if ($i > 0 || $add_end_category) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$root->appendChild($node);
}
}
}
}
/**
* Generate the entries of the feed when working in write mode
*
* The following nodes are constructed for each feed entry
* <item>
* <title>entry title</title>
* <link>url to feed entry</link>
* <guid>url to feed entry</guid>
* <description>short text</description>
* <content:encoded>long version, can contain html</content:encoded>
* </item>
*
* @param DOMElement $root the root node to use
* @param array $array the data to use
* @return void
*/
protected function _mapFeedEntries(DOMElement $root, $array)
{
Zend_Feed::registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
foreach ($array as $dataentry) {
$item = $this->_element->createElement('item');
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($dataentry->title));
$item->appendChild($title);
$link = $this->_element->createElement('link', $dataentry->link);
$item->appendChild($link);
if (isset($dataentry->guid)) {
$guid = $this->_element->createElement('guid', $dataentry->guid);
$item->appendChild($guid);
}
$description = $this->_element->createElement('description');
$description->appendChild($this->_element->createCDATASection($dataentry->description));
$item->appendChild($description);
if (isset($dataentry->content)) {
$content = $this->_element->createElement('content:encoded');
$content->appendChild($this->_element->createCDATASection($dataentry->content));
$item->appendChild($content);
}
$pubdate = isset($dataentry->lastUpdate) ? $dataentry->lastUpdate : time();
$pubdate = $this->_element->createElement('pubDate', gmdate('r', $pubdate));
$item->appendChild($pubdate);
if (isset($dataentry->category)) {
foreach ($dataentry->category as $category) {
$node = $this->_element->createElement('category', $category['term']);
if (isset($category['scheme'])) {
$node->setAttribute('domain', $category['scheme']);
}
$item->appendChild($node);
}
}
if (isset($dataentry->source)) {
$source = $this->_element->createElement('source', $dataentry->source['title']);
$source->setAttribute('url', $dataentry->source['url']);
$item->appendChild($source);
}
if (isset($dataentry->comments)) {
$comments = $this->_element->createElement('comments', $dataentry->comments);
$item->appendChild($comments);
}
if (isset($dataentry->commentRss)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:commentRss',
$dataentry->commentRss);
$item->appendChild($comments);
}
if (isset($dataentry->enclosure)) {
foreach ($dataentry->enclosure as $enclosure) {
$node = $this->_element->createElement('enclosure');
$node->setAttribute('url', $enclosure['url']);
if (isset($enclosure['type'])) {
$node->setAttribute('type', $enclosure['type']);
}
if (isset($enclosure['length'])) {
$node->setAttribute('length', $enclosure['length']);
}
$item->appendChild($node);
}
}
$root->appendChild($item);
}
}
/**
* Override Zend_Feed_Element to include <rss> root node
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$root = $doc->createElement('rss');
// Use rss version 2.0
$root->setAttribute('version', '2.0');
// Content namespace
$root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:content', 'http://purl.org/rss/1.0/modules/content/');
$root->appendChild($doc->importNode($this->_element, true));
// Append root node
$doc->appendChild($root);
// Format output
$doc->formatOutput = true;
return $doc->saveXML();
}
/**
* Send feed to a http client with the correct header
*
* @return void
* @throws Zend_Feed_Exception if headers have already been sent
*/
public function send()
{
if (headers_sent()) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send RSS because headers have already been sent.');
}
header('Content-Type: application/rss+xml; charset=' . $this->_element->ownerDocument->actualEncoding);
echo $this->saveXml();
}
}