You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ch...@apache.org on 2008/05/08 01:48:22 UTC
svn commit: r654331 [2/6] - in /incubator/shindig/trunk/php: ./
src/common/Zend/ src/common/Zend/Feed/ src/common/Zend/Feed/Builder/
src/common/Zend/Feed/Builder/Header/ src/common/Zend/Feed/Entry/
src/common/Zend/Http/ src/common/Zend/Http/Client/ src...
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Header/Itunes.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Header/Itunes.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Header/Itunes.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Header/Itunes.php Wed May 7 16:48:15 2008
@@ -0,0 +1,285 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Itunes.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * ITunes rss extension
+ *
+ * Classes used to describe the itunes channel extension
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Builder_Header_Itunes extends ArrayObject
+{
+ /**
+ * Constructor
+ *
+ * @param array $categories Categories columns and in iTunes Music Store Browse
+ * @return void
+ */
+ public function __construct(array $categories)
+ {
+ $this->setCategories($categories);
+ }
+
+ /**
+ * Sets the categories column and in iTunes Music Store Browse
+ * $categories must conform to the following format:
+ * <code>
+ * array(array('main' => 'main category',
+ * 'sub' => 'sub category' // optionnal
+ * ),
+ * // up to 3 rows
+ * )
+ * </code>
+ *
+ * @param array $categories
+ * @return Zend_Feed_Builder_Header_Itunes
+ * @throws Zend_Feed_Builder_Exception
+ */
+ public function setCategories(array $categories)
+ {
+ $nb = count($categories);
+ if (0 === $nb) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set at least one itunes category");
+ }
+ if ($nb > 3) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set at most three itunes categories");
+ }
+ foreach ($categories as $i => $category) {
+ if (empty($category['main'])) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set the main category (category #$i)");
+ }
+ }
+ $this->offsetSet('category', $categories);
+ return $this;
+ }
+
+ /**
+ * Sets the artist value, default to the feed's author value
+ *
+ * @param string $author
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setAuthor($author)
+ {
+ $this->offsetSet('author', $author);
+ return $this;
+ }
+
+ /**
+ * Sets the owner of the postcast
+ *
+ * @param string $name default to the feed's author value
+ * @param string $email default to the feed's email value
+ * @return Zend_Feed_Builder_Header_Itunes
+ * @throws Zend_Feed_Builder_Exception
+ */
+ public function setOwner($name = '', $email = '')
+ {
+ if (!empty($email)) {
+ Zend_Loader::loadClass('Zend_Validate_EmailAddress');
+ $validate = new Zend_Validate_EmailAddress();
+ if (!$validate->isValid($email)) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the itunes owner's email property");
+ }
+ }
+ $this->offsetSet('owner', array('name' => $name, 'email' => $email));
+ return $this;
+ }
+
+ /**
+ * Sets the album/podcast art picture
+ * Default to the feed's image value
+ *
+ * @param string $image
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setImage($image)
+ {
+ $this->offsetSet('image', $image);
+ return $this;
+ }
+
+ /**
+ * Sets the short description of the podcast
+ * Default to the feed's description
+ *
+ * @param string $subtitle
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setSubtitle($subtitle)
+ {
+ $this->offsetSet('subtitle', $subtitle);
+ return $this;
+ }
+
+ /**
+ * Sets the longer description of the podcast
+ * Default to the feed's description
+ *
+ * @param string $summary
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setSummary($summary)
+ {
+ $this->offsetSet('summary', $summary);
+ return $this;
+ }
+
+ /**
+ * Prevent a feed from appearing
+ *
+ * @param string $block can be 'yes' or 'no'
+ * @return Zend_Feed_Builder_Header_Itunes
+ * @throws Zend_Feed_Builder_Exception
+ */
+ public function setBlock($block)
+ {
+ $block = strtolower($block);
+ if (!in_array($block, array('yes', 'no'))) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set yes or no to the itunes block property");
+ }
+ $this->offsetSet('block', $block);
+ return $this;
+ }
+
+ /**
+ * Configuration of the parental advisory graphic
+ *
+ * @param string $explicit can be 'yes', 'no' or 'clean'
+ * @return Zend_Feed_Builder_Header_Itunes
+ * @throws Zend_Feed_Builder_Exception
+ */
+ public function setExplicit($explicit)
+ {
+ $explicit = strtolower($explicit);
+ if (!in_array($explicit, array('yes', 'no', 'clean'))) {
+ /**
+ * @see Zend_Feed_Builder_Exception
+ */
+ require_once 'Zend/Feed/Builder/Exception.php';
+ throw new Zend_Feed_Builder_Exception("you have to set yes, no or clean to the itunes explicit property");
+ }
+ $this->offsetSet('explicit', $explicit);
+ return $this;
+ }
+
+ /**
+ * Sets a comma separated list of 12 keywords maximum
+ *
+ * @param string $keywords
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setKeywords($keywords)
+ {
+ $this->offsetSet('keywords', $keywords);
+ return $this;
+ }
+
+ /**
+ * Sets the new feed URL location
+ *
+ * @param string $url
+ * @return Zend_Feed_Builder_Header_Itunes
+ */
+ public function setNewFeedUrl($url)
+ {
+ $this->offsetSet('new_feed_url', $url);
+ return $this;
+ }
+
+ /**
+ * Read only properties accessor
+ *
+ * @param string $name property to read
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ if (!$this->offsetExists($name)) {
+ return NULL;
+ }
+
+ return $this->offsetGet($name);
+ }
+
+ /**
+ * Write properties accessor
+ *
+ * @param string $name name of the property to set
+ * @param mixed $value value to set
+ * @return void
+ */
+ public function __set($name, $value)
+ {
+ $this->offsetSet($name, $value);
+ }
+
+ /**
+ * Isset accessor
+ *
+ * @param string $key
+ * @return boolean
+ */
+ public function __isset($key)
+ {
+ return $this->offsetExists($key);
+ }
+
+ /**
+ * Unset accessor
+ *
+ * @param string $key
+ * @return void
+ */
+ public function __unset($key)
+ {
+ if ($this->offsetExists($key)) {
+ $this->offsetUnset($key);
+ }
+ }
+
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Interface.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Interface.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Interface.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Builder/Interface.php Wed May 7 16:48:15 2008
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * Input feed data interface
+ *
+ * Classes implementing this interface can be passe to Zend_Feed::importBuilder
+ * as an input data source for the Zend_Feed construction
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Feed_Builder_Interface
+{
+ /**
+ * Returns an instance of Zend_Feed_Builder_Header
+ * describing the header of the feed
+ *
+ * @return Zend_Feed_Builder_Header
+ */
+ public function getHeader();
+
+ /**
+ * Returns an array of Zend_Feed_Builder_Entry instances
+ * describing the entries of the feed
+ *
+ * @return array of Zend_Feed_Builder_Entry
+ */
+ public function getEntries();
+}
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Element.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Element.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Element.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Element.php Wed May 7 16:48:15 2008
@@ -0,0 +1,408 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Element.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * Wraps a DOMElement allowing for SimpleXML-like access to attributes.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Element implements ArrayAccess
+{
+
+ /**
+ * @var DOMElement
+ */
+ protected $_element;
+
+ /**
+ * @var Zend_Feed_Element
+ */
+ protected $_parentElement;
+
+ /**
+ * @var boolean
+ */
+ protected $_appended = true;
+
+
+ /**
+ * Zend_Feed_Element constructor.
+ *
+ * @param DOMElement $element The DOM element we're encapsulating.
+ * @return void
+ */
+ public function __construct($element = null)
+ {
+ $this->_element = $element;
+ }
+
+
+ /**
+ * Get a DOM representation of the element
+ *
+ * Returns the underlying DOM object, which can then be
+ * manipulated with full DOM methods.
+ *
+ * @return DOMDocument
+ */
+ public function getDOM()
+ {
+ return $this->_element;
+ }
+
+
+ /**
+ * Update the object from a DOM element
+ *
+ * Take a DOMElement object, which may be originally from a call
+ * to getDOM() or may be custom created, and use it as the
+ * DOM tree for this Zend_Feed_Element.
+ *
+ * @param DOMElement $element
+ * @return void
+ */
+ public function setDOM(DOMElement $element)
+ {
+ $this->_element = $this->_element->ownerDocument->importNode($element, true);
+ }
+
+ /**
+ * Set the parent element of this object to another
+ * Zend_Feed_Element.
+ *
+ * @param Zend_Feed_Element $element
+ * @return void
+ */
+ public function setParent(Zend_Feed_Element $element)
+ {
+ $this->_parentElement = $element;
+ $this->_appended = false;
+ }
+
+
+ /**
+ * Appends this element to its parent if necessary.
+ *
+ * @return void
+ */
+ protected function ensureAppended()
+ {
+ if (!$this->_appended) {
+ $this->_parentElement->getDOM()->appendChild($this->_element);
+ $this->_appended = true;
+ $this->_parentElement->ensureAppended();
+ }
+ }
+
+
+ /**
+ * Get an XML string representation of this element
+ *
+ * Returns a string of this element's XML, including the XML
+ * prologue.
+ *
+ * @return string
+ */
+ public function saveXml()
+ {
+ // Return a complete document including XML prologue.
+ $doc = new DOMDocument($this->_element->ownerDocument->version,
+ $this->_element->ownerDocument->actualEncoding);
+ $doc->appendChild($doc->importNode($this->_element, true));
+ return $doc->saveXML();
+ }
+
+
+ /**
+ * Get the XML for only this element
+ *
+ * Returns a string of this element's XML without prologue.
+ *
+ * @return string
+ */
+ public function saveXmlFragment()
+ {
+ return $this->_element->ownerDocument->saveXML($this->_element);
+ }
+
+
+ /**
+ * Map variable access onto the underlying entry representation.
+ *
+ * Get-style access returns a Zend_Feed_Element representing the
+ * child element accessed. To get string values, use method syntax
+ * with the __call() overriding.
+ *
+ * @param string $var The property to access.
+ * @return mixed
+ */
+ public function __get($var)
+ {
+ $nodes = $this->_children($var);
+ $length = count($nodes);
+
+ if ($length == 1) {
+ return new Zend_Feed_Element($nodes[0]);
+ } elseif ($length > 1) {
+ return array_map(create_function('$e', 'return new Zend_Feed_Element($e);'), $nodes);
+ } else {
+ // When creating anonymous nodes for __set chaining, don't
+ // call appendChild() on them. Instead we pass the current
+ // element to them as an extra reference; the child is
+ // then responsible for appending itself when it is
+ // actually set. This way "if ($foo->bar)" doesn't create
+ // a phantom "bar" element in our tree.
+ if (strpos($var, ':') !== false) {
+ list($ns, $elt) = explode(':', $var, 2);
+ $node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $elt);
+ } else {
+ $node = $this->_element->ownerDocument->createElement($var);
+ }
+ $node = new self($node);
+ $node->setParent($this);
+ return $node;
+ }
+ }
+
+
+ /**
+ * Map variable sets onto the underlying entry representation.
+ *
+ * @param string $var The property to change.
+ * @param string $val The property's new value.
+ * @return void
+ * @throws Zend_Feed_Exception
+ */
+ public function __set($var, $val)
+ {
+ $this->ensureAppended();
+
+ $nodes = $this->_children($var);
+ if (!$nodes) {
+ if (strpos($var, ':') !== false) {
+ list($ns, $elt) = explode(':', $var, 2);
+ $node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $var, $val);
+ $this->_element->appendChild($node);
+ } else {
+ $node = $this->_element->ownerDocument->createElement($var, $val);
+ $this->_element->appendChild($node);
+ }
+ } elseif (count($nodes) > 1) {
+ /**
+ * @see Zend_Feed_Exception
+ */
+ require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Cannot set the value of multiple tags simultaneously.');
+ } else {
+ $nodes[0]->nodeValue = $val;
+ }
+ }
+
+
+ /**
+ * Map isset calls onto the underlying entry representation.
+ *
+ * @param string $var
+ * @return boolean
+ */
+ public function __isset($var)
+ {
+ // Look for access of the form {ns:var}. We don't use
+ // _children() here because we can break out of the loop
+ // immediately once we find something.
+ if (strpos($var, ':') !== false) {
+ list($ns, $elt) = explode(':', $var, 2);
+ foreach ($this->_element->childNodes as $child) {
+ if ($child->localName == $elt && $child->prefix == $ns) {
+ return true;
+ }
+ }
+ } else {
+ foreach ($this->_element->childNodes as $child) {
+ if ($child->localName == $var) {
+ return true;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Get the value of an element with method syntax.
+ *
+ * Map method calls to get the string value of the requested
+ * element. If there are multiple elements that match, this will
+ * return an array of those objects.
+ *
+ * @param string $var The element to get the string value of.
+ * @param mixed $unused This parameter is not used.
+ * @return mixed The node's value, null, or an array of nodes.
+ */
+ public function __call($var, $unused)
+ {
+ $nodes = $this->_children($var);
+
+ if (!$nodes) {
+ return null;
+ } elseif (count($nodes) > 1) {
+ return $nodes;
+ } else {
+ return $nodes[0]->nodeValue;
+ }
+ }
+
+
+ /**
+ * Remove all children matching $var.
+ *
+ * @param string $var
+ * @return void
+ */
+ public function __unset($var)
+ {
+ $nodes = $this->_children($var);
+ foreach ($nodes as $node) {
+ $parent = $node->parentNode;
+ $parent->removeChild($node);
+ }
+ }
+
+
+ /**
+ * Returns the nodeValue of this element when this object is used
+ * in a string context.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->_element->nodeValue;
+ }
+
+
+ /**
+ * Finds children with tagnames matching $var
+ *
+ * Similar to SimpleXML's children() method.
+ *
+ * @param string $var Tagname to match, can be either namespace:tagName or just tagName.
+ * @return array
+ */
+ protected function _children($var)
+ {
+ $found = array();
+
+ // Look for access of the form {ns:var}.
+ if (strpos($var, ':') !== false) {
+ list($ns, $elt) = explode(':', $var, 2);
+ foreach ($this->_element->childNodes as $child) {
+ if ($child->localName == $elt && $child->prefix == $ns) {
+ $found[] = $child;
+ }
+ }
+ } else {
+ foreach ($this->_element->childNodes as $child) {
+ if ($child->localName == $var) {
+ $found[] = $child;
+ }
+ }
+ }
+
+ return $found;
+ }
+
+
+ /**
+ * Required by the ArrayAccess interface.
+ *
+ * @param string $offset
+ * @return boolean
+ */
+ public function offsetExists($offset)
+ {
+ if (strpos($offset, ':') !== false) {
+ list($ns, $attr) = explode(':', $offset, 2);
+ return $this->_element->hasAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
+ } else {
+ return $this->_element->hasAttribute($offset);
+ }
+ }
+
+
+ /**
+ * Required by the ArrayAccess interface.
+ *
+ * @param string $offset
+ * @return string
+ */
+ public function offsetGet($offset)
+ {
+ if (strpos($offset, ':') !== false) {
+ list($ns, $attr) = explode(':', $offset, 2);
+ return $this->_element->getAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
+ } else {
+ return $this->_element->getAttribute($offset);
+ }
+ }
+
+
+ /**
+ * Required by the ArrayAccess interface.
+ *
+ * @param string $offset
+ * @param string $value
+ * @return string
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->ensureAppended();
+
+ if (strpos($offset, ':') !== false) {
+ list($ns, $attr) = explode(':', $offset, 2);
+ return $this->_element->setAttributeNS(Zend_Feed::lookupNamespace($ns), $attr, $value);
+ } else {
+ return $this->_element->setAttribute($offset, $value);
+ }
+ }
+
+
+ /**
+ * Required by the ArrayAccess interface.
+ *
+ * @param string $offset
+ * @return boolean
+ */
+ public function offsetUnset($offset)
+ {
+ if (strpos($offset, ':') !== false) {
+ list($ns, $attr) = explode(':', $offset, 2);
+ return $this->_element->removeAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
+ } else {
+ return $this->_element->removeAttribute($offset);
+ }
+ }
+
+}
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Abstract.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Abstract.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Abstract.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Abstract.php Wed May 7 16:48:15 2008
@@ -0,0 +1,123 @@
+<?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 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @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 = @DOMDocument::loadXML($element);
+ @ini_restore('track_errors');
+
+ if (!$doc) {
+ // 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);
+ }
+
+}
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Atom.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Atom.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Atom.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Atom.php Wed May 7 16:48:15 2008
@@ -0,0 +1,273 @@
+<?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 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 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 = @DOMDocument::loadXML($response->getBody());
+ @ini_restore('track_errors');
+
+ if (!$newEntry) {
+ // 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;
+ }
+
+}
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Rss.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Rss.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Rss.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Entry/Rss.php Wed May 7 16:48:15 2008
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Rss.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Feed_Entry_Abstract
+ */
+require_once 'Zend/Feed/Entry/Abstract.php';
+
+
+/**
+ * Concrete class for working with RSS items.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Entry_Rss extends Zend_Feed_Entry_Abstract
+{
+ /**
+ * Root XML element for RSS items.
+ *
+ * @var string
+ */
+ protected $_rootElement = 'item';
+
+ /**
+ * Overwrites parent::_get method to enable read access
+ * to content:encoded element.
+ *
+ * @param string $var The property to access.
+ * @return mixed
+ */
+ public function __get($var)
+ {
+ switch ($var) {
+ case 'content':
+ $prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
+ return parent::__get("$prefix:encoded");
+ default:
+ return parent::__get($var);
+ }
+ }
+
+ /**
+ * Overwrites parent::_set method to enable write access
+ * to content:encoded element.
+ *
+ * @param string $var The property to change.
+ * @param string $val The property's new value.
+ * @return void
+ */
+ public function __set($var, $value)
+ {
+ switch ($var) {
+ case 'content':
+ parent::__set('content:encoded', $value);
+ break;
+ default:
+ parent::__set($var, $value);
+ }
+ }
+
+ /**
+ * Overwrites parent::_isset method to enable access
+ * to content:encoded element.
+ *
+ * @param string $var
+ * @return boolean
+ */
+ public function __isset($var)
+ {
+ switch ($var) {
+ case 'content':
+ // don't use other callback to prevent invalid returned value
+ return $this->content() !== null;
+ default:
+ return parent::__isset($var);
+ }
+ }
+
+ /**
+ * Overwrites parent::_call method to enable read access
+ * to content:encoded element.
+ * Please note that method-style write access is not currently supported
+ * by parent method, consequently this method doesn't as well.
+ *
+ * @param string $var The element to get the string value of.
+ * @param mixed $unused This parameter is not used.
+ * @return mixed The node's value, null, or an array of nodes.
+ */
+ public function __call($var, $unused)
+ {
+ switch ($var) {
+ case 'content':
+ $prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
+ return parent::__call("$prefix:encoded", $unused);
+ default:
+ return parent::__call($var, $unused);
+ }
+ }
+}
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Exception.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Exception.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Exception.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Exception.php Wed May 7 16:48:15 2008
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+
+/**
+ * Feed exceptions
+ *
+ * Class to represent exceptions that occur during Feed operations.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Exception extends Zend_Exception
+{}
+
Added: incubator/shindig/trunk/php/src/common/Zend/Feed/Rss.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Zend/Feed/Rss.php?rev=654331&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/Zend/Feed/Rss.php (added)
+++ incubator/shindig/trunk/php/src/common/Zend/Feed/Rss.php Wed May 7 16:48:15 2008
@@ -0,0 +1,504 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Rss.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @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();
+ }
+
+}