Current File : /home/k/a/r/karenpetzb/www/items/category/Feed.tar
Entry/Atom.php000060400000022604150716071160007262 0ustar00<?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;
    }

}
Entry/Rss.php000060400000007014150716071160007127 0ustar00<?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);
        }
    }
}
Entry/Abstract.php000060400000010007150716071160010117 0ustar00<?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);
    }

}
Builder.php000060400000043001150716071160006641 0ustar00<?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;
        }
    }
}Builder/Header.php000060400000027261150716071160010043 0ustar00<?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;
    }
}
Builder/Exception.php000060400000002177150716071160010610 0ustar00<?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
{
}
Builder/Interface.php000060400000003057150716071160010550 0ustar00<?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();
}
Builder/Header/Itunes.php000060400000017532150716071160011312 0ustar00<?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);
        }
    }

}Builder/Entry.php000060400000016704150716071160007754 0ustar00<?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;
    }
}
Element.php000060400000026342150716071160006655 0ustar00<?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);
        }
    }

}
Atom.php000060400000032714150716071160006164 0ustar00<?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();
    }
}
Abstract.php000060400000016211150716071160007021 0ustar00<?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();
}
Rss.php000060400000045254150716071160006036 0ustar00<?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();
    }

}
Exception.php000060400000002235150716071160007215 0ustar00<?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
{}