Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2010-06-23 07:45:36 +0400
committermatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2010-06-23 07:45:36 +0400
commit7e1b5d6b762340cbff1bb928d15815980c7649a7 (patch)
treee07da179b9e1372866d2349777bd1cc6b4c9e8cf /libs/Zend/Feed
parent999f46479294713104c962bfe7469e9b6e7a4bbf (diff)
parentc98ea06f2cccec81c6ccce49162a583494e44d91 (diff)
Diffstat (limited to 'libs/Zend/Feed')
-rw-r--r--libs/Zend/Feed/Abstract.php18
-rw-r--r--libs/Zend/Feed/Atom.php18
-rw-r--r--libs/Zend/Feed/Builder.php28
-rw-r--r--libs/Zend/Feed/Builder/Entry.php10
-rw-r--r--libs/Zend/Feed/Builder/Exception.php8
-rw-r--r--libs/Zend/Feed/Builder/Header.php32
-rw-r--r--libs/Zend/Feed/Builder/Header/Itunes.php26
-rw-r--r--libs/Zend/Feed/Builder/Interface.php6
-rw-r--r--libs/Zend/Feed/Element.php40
-rw-r--r--libs/Zend/Feed/Entry/Abstract.php18
-rw-r--r--libs/Zend/Feed/Entry/Atom.php32
-rw-r--r--libs/Zend/Feed/Entry/Rss.php10
-rw-r--r--libs/Zend/Feed/Exception.php8
-rw-r--r--libs/Zend/Feed/Pubsubhubbub.php152
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/CallbackAbstract.php307
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/CallbackInterface.php68
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Exception.php33
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/HttpResponse.php233
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php64
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Model/Subscription.php131
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php64
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Publisher.php417
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Subscriber.php856
-rw-r--r--libs/Zend/Feed/Pubsubhubbub/Subscriber/Callback.php328
-rw-r--r--libs/Zend/Feed/Reader.php173
-rw-r--r--libs/Zend/Feed/Reader/Collection.php33
-rw-r--r--libs/Zend/Feed/Reader/Collection/Author.php51
-rw-r--r--libs/Zend/Feed/Reader/Collection/Category.php57
-rw-r--r--libs/Zend/Feed/Reader/Collection/CollectionAbstract.php41
-rw-r--r--libs/Zend/Feed/Reader/Entry/Atom.php61
-rw-r--r--libs/Zend/Feed/Reader/Entry/Rss.php172
-rw-r--r--libs/Zend/Feed/Reader/EntryAbstract.php28
-rw-r--r--libs/Zend/Feed/Reader/EntryInterface.php13
-rw-r--r--libs/Zend/Feed/Reader/Extension/Atom/Entry.php291
-rw-r--r--libs/Zend/Feed/Reader/Extension/Atom/Feed.php210
-rw-r--r--libs/Zend/Feed/Reader/Extension/Content/Entry.php17
-rw-r--r--libs/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php10
-rw-r--r--libs/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php10
-rw-r--r--libs/Zend/Feed/Reader/Extension/DublinCore/Entry.php66
-rw-r--r--libs/Zend/Feed/Reader/Extension/DublinCore/Feed.php72
-rw-r--r--libs/Zend/Feed/Reader/Extension/EntryAbstract.php23
-rw-r--r--libs/Zend/Feed/Reader/Extension/FeedAbstract.php43
-rw-r--r--libs/Zend/Feed/Reader/Extension/Podcast/Entry.php10
-rw-r--r--libs/Zend/Feed/Reader/Extension/Podcast/Feed.php8
-rw-r--r--libs/Zend/Feed/Reader/Extension/Slash/Entry.php12
-rw-r--r--libs/Zend/Feed/Reader/Extension/Syndication/Feed.php22
-rw-r--r--libs/Zend/Feed/Reader/Extension/Thread/Entry.php12
-rw-r--r--libs/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php12
-rw-r--r--libs/Zend/Feed/Reader/Feed/Atom.php100
-rw-r--r--libs/Zend/Feed/Reader/Feed/Atom/Source.php102
-rw-r--r--libs/Zend/Feed/Reader/Feed/Rss.php298
-rw-r--r--libs/Zend/Feed/Reader/FeedAbstract.php83
-rw-r--r--libs/Zend/Feed/Reader/FeedInterface.php13
-rw-r--r--libs/Zend/Feed/Reader/FeedSet.php148
-rw-r--r--libs/Zend/Feed/Rss.php28
-rw-r--r--libs/Zend/Feed/Writer.php267
-rw-r--r--libs/Zend/Feed/Writer/Deleted.php202
-rw-r--r--libs/Zend/Feed/Writer/Entry.php761
-rw-r--r--libs/Zend/Feed/Writer/Exception/InvalidMethodException.php41
-rw-r--r--libs/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php123
-rw-r--r--libs/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php92
-rw-r--r--libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php96
-rw-r--r--libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php96
-rw-r--r--libs/Zend/Feed/Writer/Extension/ITunes/Entry.php242
-rw-r--r--libs/Zend/Feed/Writer/Extension/ITunes/Feed.php361
-rw-r--r--libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php216
-rw-r--r--libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php320
-rw-r--r--libs/Zend/Feed/Writer/Extension/RendererAbstract.php179
-rw-r--r--libs/Zend/Feed/Writer/Extension/RendererInterface.php59
-rw-r--r--libs/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php91
-rw-r--r--libs/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php145
-rw-r--r--libs/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php96
-rw-r--r--libs/Zend/Feed/Writer/Feed.php281
-rw-r--r--libs/Zend/Feed/Writer/Feed/FeedAbstract.php805
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Entry/Atom.php410
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php121
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Entry/Rss.php346
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Feed/Atom.php130
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php427
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php110
-rw-r--r--libs/Zend/Feed/Writer/Renderer/Feed/Rss.php505
-rw-r--r--libs/Zend/Feed/Writer/Renderer/RendererAbstract.php250
-rw-r--r--libs/Zend/Feed/Writer/Renderer/RendererInterface.php111
-rw-r--r--libs/Zend/Feed/Writer/Source.php33
84 files changed, 11391 insertions, 651 deletions
diff --git a/libs/Zend/Feed/Abstract.php b/libs/Zend/Feed/Abstract.php
index ce59dc0793..8cd77dee7c 100644
--- a/libs/Zend/Feed/Abstract.php
+++ b/libs/Zend/Feed/Abstract.php
@@ -15,16 +15,16 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 18293 2009-09-18 22:16:07Z padraic $
+ * @version $Id: Abstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Element
*/
-require_once 'Zend/Feed/Element.php';
+// require_once 'Zend/Feed/Element.php';
/**
@@ -37,7 +37,7 @@ require_once 'Zend/Feed/Element.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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, Countable
@@ -77,10 +77,10 @@ abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator,
$client->setUri($uri);
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
- /**
+ /**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
$this->_element = $response->getBody();
@@ -123,11 +123,11 @@ abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator,
$php_errormsg = '(error message not available)';
}
}
-
- /**
+
+ /**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
diff --git a/libs/Zend/Feed/Atom.php b/libs/Zend/Feed/Atom.php
index db0055c5c2..8a723f862d 100644
--- a/libs/Zend/Feed/Atom.php
+++ b/libs/Zend/Feed/Atom.php
@@ -15,21 +15,21 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Atom.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Atom.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Abstract
*/
-require_once 'Zend/Feed/Abstract.php';
+// require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Atom
*/
-require_once 'Zend/Feed/Entry/Atom.php';
+// require_once 'Zend/Feed/Entry/Atom.php';
/**
@@ -44,7 +44,7 @@ require_once 'Zend/Feed/Entry/Atom.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -89,10 +89,10 @@ class Zend_Feed_Atom extends Zend_Feed_Abstract
// 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';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> or <' . $this->_entryElementName
. '> element found, cannot parse feed.');
}
@@ -376,10 +376,10 @@ class Zend_Feed_Atom extends Zend_Feed_Abstract
public function send()
{
if (headers_sent()) {
- /**
+ /**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send ATOM because headers have already been sent.');
}
diff --git a/libs/Zend/Feed/Builder.php b/libs/Zend/Feed/Builder.php
index a0adbb1643..a9517ce5be 100644
--- a/libs/Zend/Feed/Builder.php
+++ b/libs/Zend/Feed/Builder.php
@@ -15,26 +15,26 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Builder.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Builder.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Builder_Interface
*/
-require_once 'Zend/Feed/Builder/Interface.php';
+// require_once 'Zend/Feed/Builder/Interface.php';
/**
* @see Zend_Feed_Builder_Header
*/
-require_once 'Zend/Feed/Builder/Header.php';
+// require_once 'Zend/Feed/Builder/Header.php';
/**
* @see Zend_Feed_Builder_Entry
*/
-require_once 'Zend/Feed/Builder/Entry.php';
+// require_once 'Zend/Feed/Builder/Entry.php';
/**
@@ -44,7 +44,7 @@ require_once 'Zend/Feed/Builder/Entry.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -212,7 +212,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
* @throws Zend_Feed_Builder_Exception
* @return void
*/
- private function _createHeader(array $data)
+ protected function _createHeader(array $data)
{
$mandatories = array('title', 'link', 'charset');
foreach ($mandatories as $mandatory) {
@@ -220,7 +220,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
@@ -268,7 +268,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your cloud");
}
}
@@ -282,7 +282,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your textInput");
}
}
@@ -340,7 +340,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
* @throws Zend_Feed_Builder_Exception
* @return void
*/
- private function _createEntries(array $data)
+ protected function _createEntries(array $data)
{
foreach ($data as $row) {
$mandatories = array('title', 'link', 'description');
@@ -349,7 +349,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
@@ -379,7 +379,7 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key of source property is missing");
}
}
@@ -395,4 +395,4 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
$this->_entries[] = $entry;
}
}
-} \ No newline at end of file
+}
diff --git a/libs/Zend/Feed/Builder/Entry.php b/libs/Zend/Feed/Builder/Entry.php
index e428928717..6e7edc67b0 100644
--- a/libs/Zend/Feed/Builder/Entry.php
+++ b/libs/Zend/Feed/Builder/Entry.php
@@ -15,9 +15,9 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
@@ -29,7 +29,7 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -224,7 +224,7 @@ class Zend_Feed_Builder_Entry extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define the name of the category");
}
@@ -263,7 +263,7 @@ class Zend_Feed_Builder_Entry extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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'] : '';
diff --git a/libs/Zend/Feed/Builder/Exception.php b/libs/Zend/Feed/Builder/Exception.php
index b213ceb42b..9037cc891a 100644
--- a/libs/Zend/Feed/Builder/Exception.php
+++ b/libs/Zend/Feed/Builder/Exception.php
@@ -15,16 +15,16 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Exception.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Exception
*/
-require_once 'Zend/Feed/Exception.php';
+// require_once 'Zend/Feed/Exception.php';
/**
@@ -32,7 +32,7 @@ require_once 'Zend/Feed/Exception.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
diff --git a/libs/Zend/Feed/Builder/Header.php b/libs/Zend/Feed/Builder/Header.php
index a234377a15..51a57953f2 100644
--- a/libs/Zend/Feed/Builder/Header.php
+++ b/libs/Zend/Feed/Builder/Header.php
@@ -15,20 +15,20 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Header.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Header.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Builder_Header_Itunes
*/
-require_once 'Zend/Feed/Builder/Header/Itunes.php';
+// require_once 'Zend/Feed/Builder/Header/Itunes.php';
/**
* @see Zend_Uri
*/
-require_once 'Zend/Uri.php';
+// require_once 'Zend/Uri.php';
/**
@@ -39,7 +39,7 @@ require_once 'Zend/Uri.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -172,13 +172,13 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Validate_EmailAddress
*/
- require_once 'Zend/Validate/EmailAddress.php';
+ // require_once 'Zend/Validate/EmailAddress.php';
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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);
@@ -246,13 +246,13 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Validate_EmailAddress
*/
- require_once 'Zend/Validate/EmailAddress.php';
+ // require_once 'Zend/Validate/EmailAddress.php';
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($webmaster)) {
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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);
@@ -272,13 +272,13 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Validate_Int
*/
- require_once 'Zend/Validate/Int.php';
+ // require_once 'Zend/Validate/Int.php';
$validate = new Zend_Validate_Int();
if (!$validate->isValid($ttl)) {
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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);
@@ -317,7 +317,7 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception('Passed parameter is not a valid HTTP URI');
}
if (!$uri->getPort()) {
@@ -362,7 +362,7 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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) {
@@ -370,7 +370,7 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$hour has te be between 0 and 23");
}
}
@@ -392,7 +392,7 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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');
@@ -401,7 +401,7 @@ class Zend_Feed_Builder_Header extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$day is not a valid day");
}
}
diff --git a/libs/Zend/Feed/Builder/Header/Itunes.php b/libs/Zend/Feed/Builder/Header/Itunes.php
index cbb443bbae..9445460c07 100644
--- a/libs/Zend/Feed/Builder/Header/Itunes.php
+++ b/libs/Zend/Feed/Builder/Header/Itunes.php
@@ -15,9 +15,9 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Itunes.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Itunes.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
@@ -28,7 +28,7 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -66,14 +66,14 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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';
+ // 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) {
@@ -81,7 +81,7 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set the main category (category #$i)");
}
}
@@ -112,16 +112,16 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject
public function setOwner($name = '', $email = '')
{
if (!empty($email)) {
- /**
- * @see Zend_Validate_EmailAddress
- */
- require_once 'Zend/Validate/EmailAddress.php';
+ /**
+ * @see Zend_Validate_EmailAddress
+ */
+ // require_once 'Zend/Validate/EmailAddress.php';
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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");
}
}
@@ -182,7 +182,7 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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);
@@ -203,7 +203,7 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject
/**
* @see Zend_Feed_Builder_Exception
*/
- require_once 'Zend/Feed/Builder/Exception.php';
+ // 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);
diff --git a/libs/Zend/Feed/Builder/Interface.php b/libs/Zend/Feed/Builder/Interface.php
index a3cce7e018..9dce55f815 100644
--- a/libs/Zend/Feed/Builder/Interface.php
+++ b/libs/Zend/Feed/Builder/Interface.php
@@ -15,9 +15,9 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Interface.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Interface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
@@ -29,7 +29,7 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Feed_Builder_Interface
diff --git a/libs/Zend/Feed/Element.php b/libs/Zend/Feed/Element.php
index 2f0337d54f..b7a8e632f2 100644
--- a/libs/Zend/Feed/Element.php
+++ b/libs/Zend/Feed/Element.php
@@ -15,9 +15,9 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Element.php 18568 2009-10-16 11:59:55Z sgehrig $
+ * @version $Id: Element.php 20104 2010-01-06 21:26:01Z matthew $
*/
@@ -26,7 +26,7 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -38,6 +38,11 @@ class Zend_Feed_Element implements ArrayAccess
protected $_element;
/**
+ * @var string Character encoding to utilize
+ */
+ protected $_encoding = 'UTF-8';
+
+ /**
* @var Zend_Feed_Element
*/
protected $_parentElement;
@@ -148,6 +153,27 @@ class Zend_Feed_Element implements ArrayAccess
return $this->_element->ownerDocument->saveXML($this->_element);
}
+ /**
+ * Get encoding
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Set encoding
+ *
+ * @param string $value Encoding to use
+ * @return Zend_Feed_Element
+ */
+ public function setEncoding($value)
+ {
+ $this->_encoding = (string) $value;
+ return $this;
+ }
/**
* Map variable access onto the underlying entry representation.
@@ -205,18 +231,18 @@ class Zend_Feed_Element implements ArrayAccess
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
$node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns),
- $var, htmlspecialchars($val, ENT_NOQUOTES, 'UTF-8'));
+ $var, htmlspecialchars($val, ENT_NOQUOTES, $this->getEncoding()));
$this->_element->appendChild($node);
} else {
$node = $this->_element->ownerDocument->createElement($var,
- htmlspecialchars($val, ENT_NOQUOTES, 'UTF-8'));
+ htmlspecialchars($val, ENT_NOQUOTES, $this->getEncoding()));
$this->_element->appendChild($node);
}
} elseif (count($nodes) > 1) {
- /**
+ /**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot set the value of multiple tags simultaneously.');
} else {
$nodes[0]->nodeValue = $val;
diff --git a/libs/Zend/Feed/Entry/Abstract.php b/libs/Zend/Feed/Entry/Abstract.php
index ba82f1fca1..60c10cc89a 100644
--- a/libs/Zend/Feed/Entry/Abstract.php
+++ b/libs/Zend/Feed/Entry/Abstract.php
@@ -15,21 +15,21 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Abstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed
*/
-require_once 'Zend/Feed.php';
+// require_once 'Zend/Feed.php';
/**
* @see Zend_Feed_Element
*/
-require_once 'Zend/Feed/Element.php';
+// require_once 'Zend/Feed/Element.php';
/**
@@ -38,7 +38,7 @@ require_once 'Zend/Feed/Element.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -93,19 +93,19 @@ abstract class Zend_Feed_Entry_Abstract extends Zend_Feed_Element
}
}
- /**
+ /**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // 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';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <' . $this->_rootElement . '> element found, cannot parse feed.');
}
} else {
diff --git a/libs/Zend/Feed/Entry/Atom.php b/libs/Zend/Feed/Entry/Atom.php
index 7cbfce2c0e..01a17232eb 100644
--- a/libs/Zend/Feed/Entry/Atom.php
+++ b/libs/Zend/Feed/Entry/Atom.php
@@ -15,16 +15,16 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Atom.php 18184 2009-09-17 18:26:40Z padraic $
+ * @version $Id: Atom.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
-require_once 'Zend/Feed/Entry/Abstract.php';
+// require_once 'Zend/Feed/Entry/Abstract.php';
/**
@@ -32,15 +32,15 @@ require_once 'Zend/Feed/Entry/Abstract.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
{
- /**
- * Content-Type
- */
- const CONTENT_TYPE = 'application/atom+xml';
+ /**
+ * Content-Type
+ */
+ const CONTENT_TYPE = 'application/atom+xml';
/**
* Root XML element for Atom entries.
@@ -79,7 +79,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot delete entry; no link rel="edit" is present.');
}
@@ -107,7 +107,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Expected response code 2xx, got $httpStatus");
}
} while (true);
@@ -144,7 +144,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot edit entry; no link rel="edit" is present.');
}
@@ -164,7 +164,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 200, got ' . $response->getStatus());
}
} else {
@@ -172,7 +172,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('PostURI must be specified to save new entries.');
}
$client = Zend_Feed::getHttpClient();
@@ -185,7 +185,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 201, got '
. $response->getStatus());
}
@@ -210,7 +210,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('XML cannot be parsed: ' . $php_errormsg);
}
@@ -219,7 +219,7 @@ class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> element found in server response:'
. "\n\n" . $client->responseBody);
}
diff --git a/libs/Zend/Feed/Entry/Rss.php b/libs/Zend/Feed/Entry/Rss.php
index 464601b5e7..a03fe8052e 100644
--- a/libs/Zend/Feed/Entry/Rss.php
+++ b/libs/Zend/Feed/Entry/Rss.php
@@ -15,16 +15,16 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Rss.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Rss.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
-require_once 'Zend/Feed/Entry/Abstract.php';
+// require_once 'Zend/Feed/Entry/Abstract.php';
/**
@@ -32,7 +32,7 @@ require_once 'Zend/Feed/Entry/Abstract.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -98,7 +98,7 @@ class Zend_Feed_Entry_Rss extends Zend_Feed_Entry_Abstract
return parent::__isset($var);
}
}
-
+
/**
* Overwrites parent::_call method to enable read access
* to content:encoded element.
diff --git a/libs/Zend/Feed/Exception.php b/libs/Zend/Feed/Exception.php
index c77bb35495..1142c88a00 100644
--- a/libs/Zend/Feed/Exception.php
+++ b/libs/Zend/Feed/Exception.php
@@ -15,16 +15,16 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 16205 2009-06-21 19:08:45Z thomas $
+ * @version $Id: Exception.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Exception
*/
-require_once 'Zend/Exception.php';
+// require_once 'Zend/Exception.php';
/**
@@ -34,7 +34,7 @@ require_once 'Zend/Exception.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
diff --git a/libs/Zend/Feed/Pubsubhubbub.php b/libs/Zend/Feed/Pubsubhubbub.php
new file mode 100644
index 0000000000..eeffd74218
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub.php
@@ -0,0 +1,152 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Http_Client
+ */
+// require_once 'Zend/Http/Client.php';
+
+/**
+ * @see Zend_Uri
+ */
+// require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Version
+ */
+// require_once 'Zend/Version.php';
+
+/**
+ * @see Zend_Feed_Reader
+ */
+// require_once 'Zend/Feed/Reader.php';
+
+/**
+ * @see Zend_Feed_Abstract
+ */
+// require_once 'Zend/Feed/Abstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub
+{
+ /**
+ * Verification Modes
+ */
+ const VERIFICATION_MODE_SYNC = 'sync';
+ const VERIFICATION_MODE_ASYNC = 'async';
+
+ /**
+ * Subscription States
+ */
+ const SUBSCRIPTION_VERIFIED = 'verified';
+ const SUBSCRIPTION_NOTVERIFIED = 'not_verified';
+ const SUBSCRIPTION_TODELETE = 'to_delete';
+
+ /**
+ * Singleton instance if required of the HTTP client
+ *
+ * @var Zend_Http_Client
+ */
+ protected static $httpClient = null;
+
+ /**
+ * Simple utility function which imports any feed URL and
+ * determines the existence of Hub Server endpoints. This works
+ * best if directly given an instance of Zend_Feed_Reader_Atom|Rss
+ * to leverage off.
+ *
+ * @param Zend_Feed_Reader_FeedAbstract|Zend_Feed_Abstract|string $source
+ * @return array
+ */
+ public static function detectHubs($source)
+ {
+ if (is_string($source)) {
+ $feed = Zend_Feed_Reader::import($source);
+ } elseif (is_object($source) && $source instanceof Zend_Feed_Reader_FeedAbstract) {
+ $feed = $source;
+ } elseif (is_object($source) && $source instanceof Zend_Feed_Abstract) {
+ $feed = Zend_Feed_Reader::importFeed($source);
+ } else {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('The source parameter was'
+ . ' invalid, i.e. not a URL string or an instance of type'
+ . ' Zend_Feed_Reader_FeedAbstract or Zend_Feed_Abstract');
+ }
+ return $feed->getHubs();
+ }
+
+ /**
+ * Allows the external environment to make Zend_Oauth use a specific
+ * Client instance.
+ *
+ * @param Zend_Http_Client $httpClient
+ * @return void
+ */
+ public static function setHttpClient(Zend_Http_Client $httpClient)
+ {
+ self::$httpClient = $httpClient;
+ }
+
+ /**
+ * Return the singleton instance of the HTTP Client. Note that
+ * the instance is reset and cleared of previous parameters GET/POST.
+ * Headers are NOT reset but handled by this component if applicable.
+ *
+ * @return Zend_Http_Client
+ */
+ public static function getHttpClient()
+ {
+ if (!isset(self::$httpClient)):
+ self::$httpClient = new Zend_Http_Client;
+ else:
+ self::$httpClient->resetParameters();
+ endif;
+ return self::$httpClient;
+ }
+
+ /**
+ * Simple mechanism to delete the entire singleton HTTP Client instance
+ * which forces an new instantiation for subsequent requests.
+ *
+ * @return void
+ */
+ public static function clearHttpClient()
+ {
+ self::$httpClient = null;
+ }
+
+ /**
+ * RFC 3986 safe url encoding method
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function urlencode($string)
+ {
+ $rawencoded = rawurlencode($string);
+ $rfcencoded = str_replace('%7E', '~', $rawencoded);
+ return $rfcencoded;
+ }
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/CallbackAbstract.php b/libs/Zend/Feed/Pubsubhubbub/CallbackAbstract.php
new file mode 100644
index 0000000000..2fae31b831
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/CallbackAbstract.php
@@ -0,0 +1,307 @@
+<?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_Pubsubhubbub
+ * @subpackage Callback
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Pubsubhubbub_CallbackInterface
+ */
+// require_once 'Zend/Feed/Pubsubhubbub/CallbackInterface.php';
+
+/**
+ * @see Zend_Feed_Pubsubhubbub_HttpResponse
+ */
+// require_once 'Zend/Feed/Pubsubhubbub/HttpResponse.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @subpackage Callback
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Feed_Pubsubhubbub_CallbackAbstract
+ implements Zend_Feed_Pubsubhubbub_CallbackInterface
+{
+ /**
+ * An instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
+ * to background save any verification tokens associated with a subscription
+ * or other.
+ *
+ * @var Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+ */
+ protected $_storage = null;
+
+ /**
+ * An instance of a class handling Http Responses. This is implemented in
+ * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
+ * (i.e. not inherited from) Zend_Controller_Response_Http.
+ *
+ * @var Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
+ */
+ protected $_httpResponse = null;
+
+ /**
+ * The number of Subscribers for which any updates are on behalf of.
+ *
+ * @var int
+ */
+ protected $_subscriberCount = 1;
+
+ /**
+ * Constructor; accepts an array or Zend_Config instance to preset
+ * options for the Subscriber without calling all supported setter
+ * methods in turn.
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ */
+ public function __construct($config = null)
+ {
+ if (!is_null($config)) {
+ $this->setConfig($config);
+ }
+ }
+
+ /**
+ * Process any injected configuration options
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
+ */
+ public function setConfig($config)
+ {
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+ } elseif (!is_array($config)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Array or Zend_Config object'
+ . 'expected, got ' . gettype($config));
+ }
+ if (array_key_exists('storage', $config)) {
+ $this->setStorage($config['storage']);
+ }
+ return $this;
+ }
+
+ /**
+ * Send the response, including all headers.
+ * If you wish to handle this via Zend_Controller, use the getter methods
+ * to retrieve any data needed to be set on your HTTP Response object, or
+ * simply give this object the HTTP Response instance to work with for you!
+ *
+ * @return void
+ */
+ public function sendResponse()
+ {
+ $this->getHttpResponse()->sendResponse();
+ }
+
+ /**
+ * Sets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
+ * to background save any verification tokens associated with a subscription
+ * or other.
+ *
+ * @param Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage
+ * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
+ */
+ public function setStorage(Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage)
+ {
+ $this->_storage = $storage;
+ return $this;
+ }
+
+ /**
+ * Gets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
+ * to background save any verification tokens associated with a subscription
+ * or other.
+ *
+ * @return Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+ */
+ public function getStorage()
+ {
+ if ($this->_storage === null) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('No storage object has been'
+ . ' set that subclasses Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface');
+ }
+ return $this->_storage;
+ }
+
+ /**
+ * An instance of a class handling Http Responses. This is implemented in
+ * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
+ * (i.e. not inherited from) Zend_Controller_Response_Http.
+ *
+ * @param Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http $httpResponse
+ * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
+ */
+ public function setHttpResponse($httpResponse)
+ {
+ if (!is_object($httpResponse)
+ || (!$httpResponse instanceof Zend_Feed_Pubsubhubbub_HttpResponse
+ && !$httpResponse instanceof Zend_Controller_Response_Http)
+ ) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('HTTP Response object must'
+ . ' implement one of Zend_Feed_Pubsubhubbub_HttpResponse or'
+ . ' Zend_Controller_Response_Http');
+ }
+ $this->_httpResponse = $httpResponse;
+ return $this;
+ }
+
+ /**
+ * An instance of a class handling Http Responses. This is implemented in
+ * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
+ * (i.e. not inherited from) Zend_Controller_Response_Http.
+ *
+ * @return Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
+ */
+ public function getHttpResponse()
+ {
+ if ($this->_httpResponse === null) {
+ $this->_httpResponse = new Zend_Feed_Pubsubhubbub_HttpResponse;
+ }
+ return $this->_httpResponse;
+ }
+
+ /**
+ * Sets the number of Subscribers for which any updates are on behalf of.
+ * In other words, is this class serving one or more subscribers? How many?
+ * Defaults to 1 if left unchanged.
+ *
+ * @param string|int $count
+ * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
+ */
+ public function setSubscriberCount($count)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Subscriber count must be'
+ . ' greater than zero');
+ }
+ $this->_subscriberCount = $count;
+ return $this;
+ }
+
+ /**
+ * Gets the number of Subscribers for which any updates are on behalf of.
+ * In other words, is this class serving one or more subscribers? How many?
+ *
+ * @return int
+ */
+ public function getSubscriberCount()
+ {
+ return $this->_subscriberCount;
+ }
+
+ /**
+ * Attempt to detect the callback URL (specifically the path forward)
+ */
+ protected function _detectCallbackUrl()
+ {
+ $callbackUrl = '';
+ if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
+ $callbackUrl = $_SERVER['HTTP_X_REWRITE_URL'];
+ } elseif (isset($_SERVER['REQUEST_URI'])) {
+ $callbackUrl = $_SERVER['REQUEST_URI'];
+ $scheme = 'http';
+ if ($_SERVER['HTTPS'] == 'on') {
+ $scheme = 'https';
+ }
+ $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
+ if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
+ $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
+ }
+ } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
+ $callbackUrl= $_SERVER['ORIG_PATH_INFO'];
+ if (!empty($_SERVER['QUERY_STRING'])) {
+ $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
+ }
+ }
+ return $callbackUrl;
+ }
+
+ /**
+ * Get the HTTP host
+ *
+ * @return string
+ */
+ protected function _getHttpHost()
+ {
+ if (!empty($_SERVER['HTTP_HOST'])) {
+ return $_SERVER['HTTP_HOST'];
+ }
+ $scheme = 'http';
+ if ($_SERVER['HTTPS'] == 'on') {
+ $scheme = 'https';
+ }
+ $name = $_SERVER['SERVER_NAME'];
+ $port = $_SERVER['SERVER_PORT'];
+ if (($scheme == 'http' && $port == 80)
+ || ($scheme == 'https' && $port == 443)
+ ) {
+ return $name;
+ } else {
+ return $name . ':' . $port;
+ }
+ }
+
+ /**
+ * Retrieve a Header value from either $_SERVER or Apache
+ *
+ * @param string $header
+ */
+ protected function _getHeader($header)
+ {
+ $temp = strtoupper(str_replace('-', '_', $header));
+ if (!empty($_SERVER[$temp])) {
+ return $_SERVER[$temp];
+ }
+ $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
+ if (!empty($_SERVER[$temp])) {
+ return $_SERVER[$temp];
+ }
+ if (function_exists('apache_request_headers')) {
+ $headers = apache_request_headers();
+ if (!empty($headers[$header])) {
+ return $headers[$header];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the raw body of the request
+ *
+ * @return string|false Raw body, or false if not present
+ */
+ protected function _getRawBody()
+ {
+ $body = file_get_contents('php://input');
+ if (strlen(trim($body)) == 0 && isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
+ $body = $GLOBALS['HTTP_RAW_POST_DATA'];
+ }
+ if (strlen(trim($body)) > 0) {
+ return $body;
+ }
+ return false;
+ }
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/CallbackInterface.php b/libs/Zend/Feed/Pubsubhubbub/CallbackInterface.php
new file mode 100644
index 0000000000..ce30a6bb23
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/CallbackInterface.php
@@ -0,0 +1,68 @@
+<?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_Pubsubhubbub
+ * @subpackage Callback
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @subpackage Callback
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Feed_Pubsubhubbub_CallbackInterface
+{
+ /**
+ * Handle any callback from a Hub Server responding to a subscription or
+ * unsubscription request. This should be the Hub Server confirming the
+ * the request prior to taking action on it.
+ *
+ * @param array $httpData GET/POST data if available and not in $_GET/POST
+ * @param bool $sendResponseNow Whether to send response now or when asked
+ */
+ public function handle(array $httpData = null, $sendResponseNow = false);
+
+ /**
+ * Send the response, including all headers.
+ * If you wish to handle this via Zend_Controller, use the getter methods
+ * to retrieve any data needed to be set on your HTTP Response object, or
+ * simply give this object the HTTP Response instance to work with for you!
+ *
+ * @return void
+ */
+ public function sendResponse();
+
+ /**
+ * An instance of a class handling Http Responses. This is implemented in
+ * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
+ * (i.e. not inherited from) Zend_Controller_Response_Http.
+ *
+ * @param Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http $httpResponse
+ */
+ public function setHttpResponse($httpResponse);
+
+ /**
+ * An instance of a class handling Http Responses. This is implemented in
+ * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
+ * (i.e. not inherited from) Zend_Controller_Response_Http.
+ *
+ * @return Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
+ */
+ public function getHttpResponse();
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Exception.php b/libs/Zend/Feed/Pubsubhubbub/Exception.php
new file mode 100644
index 0000000000..5bc562c94e
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Exception.php
@@ -0,0 +1,33 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Exception
+ */
+// require_once 'Zend/Exception.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Exception extends Zend_Exception
+{}
diff --git a/libs/Zend/Feed/Pubsubhubbub/HttpResponse.php b/libs/Zend/Feed/Pubsubhubbub/HttpResponse.php
new file mode 100644
index 0000000000..e44f0eb86a
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/HttpResponse.php
@@ -0,0 +1,233 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Pubsubhubbub
+ */
+// require_once 'Zend/Feed/Pubsubhubbub.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_HttpResponse
+{
+ /**
+ * The body of any response to the current callback request
+ *
+ * @var string
+ */
+ protected $_body = '';
+
+ /**
+ * Array of headers. Each header is an array with keys 'name' and 'value'
+ *
+ * @var array
+ */
+ protected $_headers = array();
+
+ /**
+ * HTTP response code to use in headers
+ *
+ * @var int
+ */
+ protected $_httpResponseCode = 200;
+
+ /**
+ * Send the response, including all headers
+ *
+ * @return void
+ */
+ public function sendResponse()
+ {
+ $this->sendHeaders();
+ echo $this->getBody();
+ }
+
+ /**
+ * Send all headers
+ *
+ * Sends any headers specified. If an {@link setHttpResponseCode() HTTP response code}
+ * has been specified, it is sent with the first header.
+ *
+ * @return void
+ */
+ public function sendHeaders()
+ {
+ if (count($this->_headers) || (200 != $this->_httpResponseCode)) {
+ $this->canSendHeaders(true);
+ } elseif (200 == $this->_httpResponseCode) {
+ return;
+ }
+ $httpCodeSent = false;
+ foreach ($this->_headers as $header) {
+ if (!$httpCodeSent && $this->_httpResponseCode) {
+ header($header['name'] . ': ' . $header['value'], $header['replace'], $this->_httpResponseCode);
+ $httpCodeSent = true;
+ } else {
+ header($header['name'] . ': ' . $header['value'], $header['replace']);
+ }
+ }
+ if (!$httpCodeSent) {
+ header('HTTP/1.1 ' . $this->_httpResponseCode);
+ $httpCodeSent = true;
+ }
+ }
+
+ /**
+ * Set a header
+ *
+ * If $replace is true, replaces any headers already defined with that
+ * $name.
+ *
+ * @param string $name
+ * @param string $value
+ * @param boolean $replace
+ * @return Zend_Feed_Pubsubhubbub_HttpResponse
+ */
+ public function setHeader($name, $value, $replace = false)
+ {
+ $name = $this->_normalizeHeader($name);
+ $value = (string) $value;
+ if ($replace) {
+ foreach ($this->_headers as $key => $header) {
+ if ($name == $header['name']) {
+ unset($this->_headers[$key]);
+ }
+ }
+ }
+ $this->_headers[] = array(
+ 'name' => $name,
+ 'value' => $value,
+ 'replace' => $replace,
+ );
+
+ return $this;
+ }
+
+ /**
+ * Check if a specific Header is set and return its value
+ *
+ * @param string $name
+ * @return string|null
+ */
+ public function getHeader($name)
+ {
+ $name = $this->_normalizeHeader($name);
+ foreach ($this->_headers as $header) {
+ if ($header['name'] == $name) {
+ return $header['value'];
+ }
+ }
+ }
+
+ /**
+ * Return array of headers; see {@link $_headers} for format
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->_headers;
+ }
+
+ /**
+ * Can we send headers?
+ *
+ * @param boolean $throw Whether or not to throw an exception if headers have been sent; defaults to false
+ * @return boolean
+ * @throws Zend_Feed_Pubsubhubbub_Exception
+ */
+ public function canSendHeaders($throw = false)
+ {
+ $ok = headers_sent($file, $line);
+ if ($ok && $throw) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Cannot send headers; headers already sent in ' . $file . ', line ' . $line);
+ }
+ return !$ok;
+ }
+
+ /**
+ * Set HTTP response code to use with headers
+ *
+ * @param int $code
+ * @return Zend_Feed_Pubsubhubbub_HttpResponse
+ */
+ public function setHttpResponseCode($code)
+ {
+ if (!is_int($code) || (100 > $code) || (599 < $code)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid HTTP response'
+ . ' code:' . $code);
+ }
+ $this->_httpResponseCode = $code;
+ return $this;
+ }
+
+ /**
+ * Retrieve HTTP response code
+ *
+ * @return int
+ */
+ public function getHttpResponseCode()
+ {
+ return $this->_httpResponseCode;
+ }
+
+ /**
+ * Set body content
+ *
+ * @param string $content
+ * @return Zend_Feed_Pubsubhubbub_HttpResponse
+ */
+ public function setBody($content)
+ {
+ $this->_body = (string) $content;
+ $this->setHeader('content-length', strlen($content));
+ return $this;
+ }
+
+ /**
+ * Return the body content
+ *
+ * @return string
+ */
+ public function getBody()
+ {
+ return $this->_body;
+ }
+
+ /**
+ * Normalizes a header name to X-Capitalized-Names
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function _normalizeHeader($name)
+ {
+ $filtered = str_replace(array('-', '_'), ' ', (string) $name);
+ $filtered = ucwords(strtolower($filtered));
+ $filtered = str_replace(' ', '-', $filtered);
+ return $filtered;
+ }
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php b/libs/Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php
new file mode 100644
index 0000000000..eab4b56322
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php
@@ -0,0 +1,64 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** @see Zend_Db_Table */
+// require_once 'Zend/Db/Table.php';
+
+/**
+ * @see Zend_Registry
+ * Seems to fix the file not being included by Zend_Db_Table...
+ */
+// require_once 'Zend/Registry.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Model_ModelAbstract
+{
+ /**
+ * Zend_Db_Table instance to host database methods
+ *
+ * @var Zend_Db_Table
+ */
+ protected $_db = null;
+
+ /**
+ * Constructor
+ *
+ * @param array $data
+ * @param Zend_Db_Table_Abstract $tableGateway
+ * @return void
+ */
+ public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
+ {
+ if (is_null($tableGateway)) {
+ $parts = explode('_', get_class($this));
+ $table = strtolower(array_pop($parts));
+ $this->_db = new Zend_Db_Table($table);
+ } else {
+ $this->_db = $tableGateway;
+ }
+ }
+
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Model/Subscription.php b/libs/Zend/Feed/Pubsubhubbub/Model/Subscription.php
new file mode 100644
index 0000000000..ea971b4f77
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Model/Subscription.php
@@ -0,0 +1,131 @@
+<?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_Pubsubhubbub
+ * @subpackage Entity
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/** @see Zend_Feed_Pubsubhubbub_Model_ModelAbstract */
+// require_once 'Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php';
+
+/** @see Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface */
+// require_once 'Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @subpackage Entity
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Model_Subscription
+ extends Zend_Feed_Pubsubhubbub_Model_ModelAbstract
+ implements Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+{
+
+ /**
+ * Save subscription to RDMBS
+ *
+ * @param array $data
+ * @return bool
+ */
+ public function setSubscription(array $data)
+ {
+ if (!isset($data['id'])) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception(
+ 'ID must be set before attempting a save'
+ );
+ }
+ $result = $this->_db->find($data['id']);
+ if ($result) {
+ $data['created_time'] = $result->current()->created_time;
+ $now = new Zend_Date;
+ if ($data['lease_seconds']) {
+ $data['expiration_time'] = $now->add($data['lease_seconds'], Zend_Date::SECOND)
+ ->get('yyyy-MM-dd HH:mm:ss');
+ }
+ $this->_db->update(
+ $data,
+ $this->_db->getAdapter()->quoteInto('id = ?', $data['id'])
+ );
+ return false;
+ }
+
+ $this->_db->insert($data);
+ return true;
+ }
+
+ /**
+ * Get subscription by ID/key
+ *
+ * @param string $key
+ * @return array
+ */
+ public function getSubscription($key)
+ {
+ if (empty($key) || !is_string($key)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "key"'
+ .' of "' . $key . '" must be a non-empty string');
+ }
+ $result = $this->_db->find($key);
+ if ($result) {
+ return (array) $result->current();
+ }
+ return false;
+ }
+
+ /**
+ * Determine if a subscription matching the key exists
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasSubscription($key)
+ {
+ if (empty($key) || !is_string($key)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "key"'
+ .' of "' . $key . '" must be a non-empty string');
+ }
+ $result = $this->_db->find($key);
+ if ($result) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Delete a subscription
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function deleteSubscription($key)
+ {
+ $result = $this->_db->find($key);
+ if ($result) {
+ $this->_db->delete(
+ $this->_db->getAdapter()->quoteInto('id = ?', $key)
+ );
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php b/libs/Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php
new file mode 100644
index 0000000000..f8a6e6a3e3
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php
@@ -0,0 +1,64 @@
+<?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_Pubsubhubbub
+ * @subpackage Entity
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @subpackage Entity
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+{
+
+ /**
+ * Save subscription to RDMBS
+ *
+ * @param array $data The key must be stored here as a $data['id'] entry
+ * @return bool
+ */
+ public function setSubscription(array $data);
+
+ /**
+ * Get subscription by ID/key
+ *
+ * @param string $key
+ * @return array
+ */
+ public function getSubscription($key);
+
+ /**
+ * Determine if a subscription matching the key exists
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasSubscription($key);
+
+ /**
+ * Delete a subscription
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function deleteSubscription($key);
+
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Publisher.php b/libs/Zend/Feed/Pubsubhubbub/Publisher.php
new file mode 100644
index 0000000000..dfc388beca
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Publisher.php
@@ -0,0 +1,417 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Pubsubhubbub
+ */
+// require_once 'Zend/Feed/Pubsubhubbub.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Publisher
+{
+ /**
+ * An array of URLs for all Hub Servers used by the Publisher, and to
+ * which all topic update notifications will be sent.
+ *
+ * @var array
+ */
+ protected $_hubUrls = array();
+
+ /**
+ * An array of topic (Atom or RSS feed) URLs which have been updated and
+ * whose updated status will be notified to all Hub Servers.
+ *
+ * @var array
+ */
+ protected $_updatedTopicUrls = array();
+
+ /**
+ * An array of any errors including keys for 'response', 'hubUrl'.
+ * The response is the actual Zend_Http_Response object.
+ *
+ * @var array
+ */
+ protected $_errors = array();
+
+ /**
+ * An array of topic (Atom or RSS feed) URLs which have been updated and
+ * whose updated status will be notified to all Hub Servers.
+ *
+ * @var array
+ */
+ protected $_parameters = array();
+
+ /**
+ * Constructor; accepts an array or Zend_Config instance to preset
+ * options for the Publisher without calling all supported setter
+ * methods in turn.
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ * @return void
+ */
+ public function __construct($config = null)
+ {
+ if (!is_null($config)) {
+ $this->setConfig($config);
+ }
+ }
+
+ /**
+ * Process any injected configuration options
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function setConfig($config)
+ {
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+ } elseif (!is_array($config)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Array or Zend_Config object'
+ . 'expected, got ' . gettype($config));
+ }
+ if (array_key_exists('hubUrls', $config)) {
+ $this->addHubUrls($config['hubUrls']);
+ }
+ if (array_key_exists('updatedTopicUrls', $config)) {
+ $this->addUpdatedTopicUrls($config['updatedTopicUrls']);
+ }
+ if (array_key_exists('parameters', $config)) {
+ $this->setParameters($config['parameters']);
+ }
+ return $this;
+ }
+
+ /**
+ * Add a Hub Server URL supported by Publisher
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function addHubUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ .' of "' . $url . '" must be a non-empty string and a valid'
+ .'URL');
+ }
+ $this->_hubUrls[] = $url;
+ return $this;
+ }
+
+ /**
+ * Add an array of Hub Server URLs supported by Publisher
+ *
+ * @param array $urls
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function addHubUrls(array $urls)
+ {
+ foreach ($urls as $url) {
+ $this->addHubUrl($url);
+ }
+ return $this;
+ }
+
+ /**
+ * Remove a Hub Server URL
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function removeHubUrl($url)
+ {
+ if (!in_array($url, $this->getHubUrls())) {
+ return $this;
+ }
+ $key = array_search($url, $this->_hubUrls);
+ unset($this->_hubUrls[$key]);
+ return $this;
+ }
+
+ /**
+ * Return an array of unique Hub Server URLs currently available
+ *
+ * @return array
+ */
+ public function getHubUrls()
+ {
+ $this->_hubUrls = array_unique($this->_hubUrls);
+ return $this->_hubUrls;
+ }
+
+ /**
+ * Add a URL to a topic (Atom or RSS feed) which has been updated
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function addUpdatedTopicUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ .' of "' . $url . '" must be a non-empty string and a valid'
+ .'URL');
+ }
+ $this->_updatedTopicUrls[] = $url;
+ return $this;
+ }
+
+ /**
+ * Add an array of Topic URLs which have been updated
+ *
+ * @param array $urls
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function addUpdatedTopicUrls(array $urls)
+ {
+ foreach ($urls as $url) {
+ $this->addUpdatedTopicUrl($url);
+ }
+ return $this;
+ }
+
+ /**
+ * Remove an updated topic URL
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function removeUpdatedTopicUrl($url)
+ {
+ if (!in_array($url, $this->getUpdatedTopicUrls())) {
+ return $this;
+ }
+ $key = array_search($url, $this->_updatedTopicUrls);
+ unset($this->_updatedTopicUrls[$key]);
+ return $this;
+ }
+
+ /**
+ * Return an array of unique updated topic URLs currently available
+ *
+ * @return array
+ */
+ public function getUpdatedTopicUrls()
+ {
+ $this->_updatedTopicUrls = array_unique($this->_updatedTopicUrls);
+ return $this->_updatedTopicUrls;
+ }
+
+ /**
+ * Notifies a single Hub Server URL of changes
+ *
+ * @param string $url The Hub Server's URL
+ * @return void
+ * @throws Zend_Feed_Pubsubhubbub_Exception Thrown on failure
+ */
+ public function notifyHub($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ .' of "' . $url . '" must be a non-empty string and a valid'
+ .'URL');
+ }
+ $client = $this->_getHttpClient();
+ $client->setUri($url);
+ $response = $client->request();
+ if ($response->getStatus() !== 204) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Notification to Hub Server '
+ . 'at "' . $url . '" appears to have failed with a status code of "'
+ . $response->getStatus() . '" and message "'
+ . $response->getMessage() . '"');
+ }
+ }
+
+ /**
+ * Notifies all Hub Server URLs of changes
+ *
+ * If a Hub notification fails, certain data will be retained in an
+ * an array retrieved using getErrors(), if a failure occurs for any Hubs
+ * the isSuccess() check will return FALSE. This method is designed not
+ * to needlessly fail with an Exception/Error unless from Zend_Http_Client.
+ *
+ * @return void
+ * @throws Zend_Feed_Pubsubhubbub_Exception Thrown if no hubs attached
+ */
+ public function notifyAll()
+ {
+ $client = $this->_getHttpClient();
+ $hubs = $this->getHubUrls();
+ if (empty($hubs)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('No Hub Server URLs'
+ . ' have been set so no notifcations can be sent');
+ }
+ $this->_errors = array();
+ foreach ($hubs as $url) {
+ $client->setUri($url);
+ $response = $client->request();
+ if ($response->getStatus() !== 204) {
+ $this->_errors[] = array(
+ 'response' => $response,
+ 'hubUrl' => $url
+ );
+ }
+ }
+ }
+
+ /**
+ * Add an optional parameter to the update notification requests
+ *
+ * @param string $name
+ * @param string|null $value
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function setParameter($name, $value = null)
+ {
+ if (is_array($name)) {
+ $this->setParameters($name);
+ return $this;
+ }
+ if (empty($name) || !is_string($name)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "name"'
+ .' of "' . $name . '" must be a non-empty string');
+ }
+ if ($value === null) {
+ $this->removeParameter($name);
+ return $this;
+ }
+ if (empty($value) || (!is_string($value) && !is_null($value))) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "value"'
+ .' of "' . $value . '" must be a non-empty string');
+ }
+ $this->_parameters[$name] = $value;
+ return $this;
+ }
+
+ /**
+ * Add an optional parameter to the update notification requests
+ *
+ * @param array $parameters
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function setParameters(array $parameters)
+ {
+ foreach ($parameters as $name => $value) {
+ $this->setParameter($name, $value);
+ }
+ return $this;
+ }
+
+ /**
+ * Remove an optional parameter for the notification requests
+ *
+ * @param string $name
+ * @return Zend_Feed_Pubsubhubbub_Publisher
+ */
+ public function removeParameter($name)
+ {
+ if (empty($name) || !is_string($name)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "name"'
+ .' of "' . $name . '" must be a non-empty string');
+ }
+ if (array_key_exists($name, $this->_parameters)) {
+ unset($this->_parameters[$name]);
+ }
+ return $this;
+ }
+
+ /**
+ * Return an array of optional parameters for notification requests
+ *
+ * @return array
+ */
+ public function getParameters()
+ {
+ return $this->_parameters;
+ }
+
+ /**
+ * Returns a boolean indicator of whether the notifications to Hub
+ * Servers were ALL successful. If even one failed, FALSE is returned.
+ *
+ * @return bool
+ */
+ public function isSuccess()
+ {
+ if (count($this->_errors) > 0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return an array of errors met from any failures, including keys:
+ * 'response' => the Zend_Http_Response object from the failure
+ * 'hubUrl' => the URL of the Hub Server whose notification failed
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->_errors;
+ }
+
+ /**
+ * Get a basic prepared HTTP client for use
+ *
+ * @return Zend_Http_Client
+ */
+ protected function _getHttpClient()
+ {
+ $client = Zend_Feed_Pubsubhubbub::getHttpClient();
+ $client->setMethod(Zend_Http_Client::POST);
+ $client->setConfig(array(
+ 'useragent' => 'Zend_Feed_Pubsubhubbub_Publisher/' . Zend_Version::VERSION,
+ ));
+ $params = array();
+ $params[] = 'hub.mode=publish';
+ $topics = $this->getUpdatedTopicUrls();
+ if (empty($topics)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('No updated topic URLs'
+ . ' have been set');
+ }
+ foreach ($topics as $topicUrl) {
+ $params[] = 'hub.url=' . urlencode($topicUrl);
+ }
+ $optParams = $this->getParameters();
+ foreach ($optParams as $name => $value) {
+ $params[] = urlencode($name) . '=' . urlencode($value);
+ }
+ $paramString = implode('&', $params);
+ $client->setRawData($paramString);
+ return $client;
+ }
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Subscriber.php b/libs/Zend/Feed/Pubsubhubbub/Subscriber.php
new file mode 100644
index 0000000000..9921bce594
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Subscriber.php
@@ -0,0 +1,856 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Pubsubhubbub
+ */
+// require_once 'Zend/Feed/Pubsubhubbub.php';
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Date.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Subscriber
+{
+ /**
+ * An array of URLs for all Hub Servers to subscribe/unsubscribe.
+ *
+ * @var array
+ */
+ protected $_hubUrls = array();
+
+ /**
+ * An array of optional parameters to be included in any
+ * (un)subscribe requests.
+ *
+ * @var array
+ */
+ protected $_parameters = array();
+
+ /**
+ * The URL of the topic (Rss or Atom feed) which is the subject of
+ * our current intent to subscribe to/unsubscribe from updates from
+ * the currently configured Hub Servers.
+ *
+ * @var string
+ */
+ protected $_topicUrl = '';
+
+ /**
+ * The URL Hub Servers must use when communicating with this Subscriber
+ *
+ * @var string
+ */
+ protected $_callbackUrl = '';
+
+ /**
+ * The number of seconds for which the subscriber would like to have the
+ * subscription active. Defaults to null, i.e. not sent, to setup a
+ * permanent subscription if possible.
+ *
+ * @var int
+ */
+ protected $_leaseSeconds = null;
+
+ /**
+ * The preferred verification mode (sync or async). By default, this
+ * Subscriber prefers synchronous verification, but is considered
+ * desireable to support asynchronous verification if possible.
+ *
+ * Zend_Feed_Pubsubhubbub_Subscriber will always send both modes, whose
+ * order of occurance in the parameter list determines this preference.
+ *
+ * @var string
+ */
+ protected $_preferredVerificationMode
+ = Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC;
+
+ /**
+ * An array of any errors including keys for 'response', 'hubUrl'.
+ * The response is the actual Zend_Http_Response object.
+ *
+ * @var array
+ */
+ protected $_errors = array();
+
+ /**
+ * An array of Hub Server URLs for Hubs operating at this time in
+ * asynchronous verification mode.
+ *
+ * @var array
+ */
+ protected $_asyncHubs = array();
+
+ /**
+ * An instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used to background
+ * save any verification tokens associated with a subscription or other.
+ *
+ * @var Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+ */
+ protected $_storage = null;
+
+ /**
+ * An array of authentication credentials for HTTP Basic Authentication
+ * if required by specific Hubs. The array is indexed by Hub Endpoint URI
+ * and the value is a simple array of the username and password to apply.
+ *
+ * @var array
+ */
+ protected $_authentications = array();
+
+ /**
+ * Tells the Subscriber to append any subscription identifier to the path
+ * of the base Callback URL. E.g. an identifier "subkey1" would be added
+ * to the callback URL "http://www.example.com/callback" to create a subscription
+ * specific Callback URL of "http://www.example.com/callback/subkey1".
+ *
+ * This is required for all Hubs using the Pubsubhubbub 0.1 Specification.
+ * It should be manually intercepted and passed to the Callback class using
+ * Zend_Feed_Pubsubhubbub_Subscriber_Callback::setSubscriptionKey(). Will
+ * require a route in the form "callback/:subkey" to allow the parameter be
+ * retrieved from an action using the Zend_Controller_Action::_getParam()
+ * method.
+ *
+ * @var string
+ */
+ protected $_usePathParameter = false;
+
+ /**
+ * Constructor; accepts an array or Zend_Config instance to preset
+ * options for the Subscriber without calling all supported setter
+ * methods in turn.
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ * @return void
+ */
+ public function __construct($config = null)
+ {
+ if (!is_null($config)) {
+ $this->setConfig($config);
+ }
+ }
+
+ /**
+ * Process any injected configuration options
+ *
+ * @param array|Zend_Config $options Options array or Zend_Config instance
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setConfig($config)
+ {
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+ } elseif (!is_array($config)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Array or Zend_Config object'
+ . ' expected, got ' . gettype($config));
+ }
+ if (array_key_exists('hubUrls', $config)) {
+ $this->addHubUrls($config['hubUrls']);
+ }
+ if (array_key_exists('callbackUrl', $config)) {
+ $this->setCallbackUrl($config['callbackUrl']);
+ }
+ if (array_key_exists('topicUrl', $config)) {
+ $this->setTopicUrl($config['topicUrl']);
+ }
+ if (array_key_exists('storage', $config)) {
+ $this->setStorage($config['storage']);
+ }
+ if (array_key_exists('leaseSeconds', $config)) {
+ $this->setLeaseSeconds($config['leaseSeconds']);
+ }
+ if (array_key_exists('parameters', $config)) {
+ $this->setParameters($config['parameters']);
+ }
+ if (array_key_exists('authentications', $config)) {
+ $this->addAuthentications($config['authentications']);
+ }
+ if (array_key_exists('usePathParameter', $config)) {
+ $this->usePathParameter($config['usePathParameter']);
+ }
+ if (array_key_exists('preferredVerificationMode', $config)) {
+ $this->setPreferredVerificationMode(
+ $config['preferredVerificationMode']
+ );
+ }
+ return $this;
+ }
+
+ /**
+ * Set the topic URL (RSS or Atom feed) to which the intended (un)subscribe
+ * event will relate
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setTopicUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ .' of "' . $url . '" must be a non-empty string and a valid'
+ .' URL');
+ }
+ $this->_topicUrl = $url;
+ return $this;
+ }
+
+ /**
+ * Set the topic URL (RSS or Atom feed) to which the intended (un)subscribe
+ * event will relate
+ *
+ * @return string
+ */
+ public function getTopicUrl()
+ {
+ if (empty($this->_topicUrl)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('A valid Topic (RSS or Atom'
+ . ' feed) URL MUST be set before attempting any operation');
+ }
+ return $this->_topicUrl;
+ }
+
+ /**
+ * Set the number of seconds for which any subscription will remain valid
+ *
+ * @param int $seconds
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setLeaseSeconds($seconds)
+ {
+ $seconds = intval($seconds);
+ if ($seconds <= 0) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Expected lease seconds'
+ . ' must be an integer greater than zero');
+ }
+ $this->_leaseSeconds = $seconds;
+ return $this;
+ }
+
+ /**
+ * Get the number of lease seconds on subscriptions
+ *
+ * @return int
+ */
+ public function getLeaseSeconds()
+ {
+ return $this->_leaseSeconds;
+ }
+
+ /**
+ * Set the callback URL to be used by Hub Servers when communicating with
+ * this Subscriber
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setCallbackUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ . ' of "' . $url . '" must be a non-empty string and a valid'
+ . ' URL');
+ }
+ $this->_callbackUrl = $url;
+ return $this;
+ }
+
+ /**
+ * Get the callback URL to be used by Hub Servers when communicating with
+ * this Subscriber
+ *
+ * @return string
+ */
+ public function getCallbackUrl()
+ {
+ if (empty($this->_callbackUrl)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('A valid Callback URL MUST be'
+ . ' set before attempting any operation');
+ }
+ return $this->_callbackUrl;
+ }
+
+ /**
+ * Set preferred verification mode (sync or async). By default, this
+ * Subscriber prefers synchronous verification, but does support
+ * asynchronous if that's the Hub Server's utilised mode.
+ *
+ * Zend_Feed_Pubsubhubbub_Subscriber will always send both modes, whose
+ * order of occurance in the parameter list determines this preference.
+ *
+ * @param string $mode Should be 'sync' or 'async'
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setPreferredVerificationMode($mode)
+ {
+ if ($mode !== Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC
+ && $mode !== Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_ASYNC) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid preferred'
+ . ' mode specified: "' . $mode . '" but should be one of'
+ . ' Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC or'
+ . ' Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_ASYNC');
+ }
+ $this->_preferredVerificationMode = $mode;
+ return $this;
+ }
+
+ /**
+ * Get preferred verification mode (sync or async).
+ *
+ * @return string
+ */
+ public function getPreferredVerificationMode()
+ {
+ return $this->_preferredVerificationMode;
+ }
+
+ /**
+ * Add a Hub Server URL supported by Publisher
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function addHubUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ . ' of "' . $url . '" must be a non-empty string and a valid'
+ . ' URL');
+ }
+ $this->_hubUrls[] = $url;
+ return $this;
+ }
+
+ /**
+ * Add an array of Hub Server URLs supported by Publisher
+ *
+ * @param array $urls
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function addHubUrls(array $urls)
+ {
+ foreach ($urls as $url) {
+ $this->addHubUrl($url);
+ }
+ return $this;
+ }
+
+ /**
+ * Remove a Hub Server URL
+ *
+ * @param string $url
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function removeHubUrl($url)
+ {
+ if (!in_array($url, $this->getHubUrls())) {
+ return $this;
+ }
+ $key = array_search($url, $this->_hubUrls);
+ unset($this->_hubUrls[$key]);
+ return $this;
+ }
+
+ /**
+ * Return an array of unique Hub Server URLs currently available
+ *
+ * @return array
+ */
+ public function getHubUrls()
+ {
+ $this->_hubUrls = array_unique($this->_hubUrls);
+ return $this->_hubUrls;
+ }
+
+ /**
+ * Add authentication credentials for a given URL
+ *
+ * @param string $url
+ * @param array $authentication
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function addAuthentication($url, array $authentication)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "url"'
+ . ' of "' . $url . '" must be a non-empty string and a valid'
+ . ' URL');
+ }
+ $this->_authentications[$url] = $authentication;
+ return $this;
+ }
+
+ /**
+ * Add authentication credentials for hub URLs
+ *
+ * @param array $authentications
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function addAuthentications(array $authentications)
+ {
+ foreach ($authentications as $url => $authentication) {
+ $this->addAuthentication($url, $authentication);
+ }
+ return $this;
+ }
+
+ /**
+ * Get all hub URL authentication credentials
+ *
+ * @return array
+ */
+ public function getAuthentications()
+ {
+ return $this->_authentications;
+ }
+
+ /**
+ * Set flag indicating whether or not to use a path parameter
+ *
+ * @param bool $bool
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function usePathParameter($bool = true)
+ {
+ $this->_usePathParameter = $bool;
+ return $this;
+ }
+
+ /**
+ * Add an optional parameter to the (un)subscribe requests
+ *
+ * @param string $name
+ * @param string|null $value
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setParameter($name, $value = null)
+ {
+ if (is_array($name)) {
+ $this->setParameters($name);
+ return $this;
+ }
+ if (empty($name) || !is_string($name)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "name"'
+ . ' of "' . $name . '" must be a non-empty string');
+ }
+ if ($value === null) {
+ $this->removeParameter($name);
+ return $this;
+ }
+ if (empty($value) || (!is_string($value) && !is_null($value))) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "value"'
+ . ' of "' . $value . '" must be a non-empty string');
+ }
+ $this->_parameters[$name] = $value;
+ return $this;
+ }
+
+ /**
+ * Add an optional parameter to the (un)subscribe requests
+ *
+ * @param string $name
+ * @param string|null $value
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setParameters(array $parameters)
+ {
+ foreach ($parameters as $name => $value) {
+ $this->setParameter($name, $value);
+ }
+ return $this;
+ }
+
+ /**
+ * Remove an optional parameter for the (un)subscribe requests
+ *
+ * @param string $name
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function removeParameter($name)
+ {
+ if (empty($name) || !is_string($name)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid parameter "name"'
+ . ' of "' . $name . '" must be a non-empty string');
+ }
+ if (array_key_exists($name, $this->_parameters)) {
+ unset($this->_parameters[$name]);
+ }
+ return $this;
+ }
+
+ /**
+ * Return an array of optional parameters for (un)subscribe requests
+ *
+ * @return array
+ */
+ public function getParameters()
+ {
+ return $this->_parameters;
+ }
+
+ /**
+ * Sets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used to background
+ * save any verification tokens associated with a subscription or other.
+ *
+ * @param Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage
+ * @return Zend_Feed_Pubsubhubbub_Subscriber
+ */
+ public function setStorage(Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage)
+ {
+ $this->_storage = $storage;
+ return $this;
+ }
+
+ /**
+ * Gets an instance of Zend_Feed_Pubsubhubbub_Storage_StorageInterface used
+ * to background save any verification tokens associated with a subscription
+ * or other.
+ *
+ * @return Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
+ */
+ public function getStorage()
+ {
+ if ($this->_storage === null) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('No storage vehicle '
+ . 'has been set.');
+ }
+ return $this->_storage;
+ }
+
+ /**
+ * Subscribe to one or more Hub Servers using the stored Hub URLs
+ * for the given Topic URL (RSS or Atom feed)
+ *
+ * @return void
+ */
+ public function subscribeAll()
+ {
+ return $this->_doRequest('subscribe');
+ }
+
+ /**
+ * Unsubscribe from one or more Hub Servers using the stored Hub URLs
+ * for the given Topic URL (RSS or Atom feed)
+ *
+ * @return void
+ */
+ public function unsubscribeAll()
+ {
+ return $this->_doRequest('unsubscribe');
+ }
+
+ /**
+ * Returns a boolean indicator of whether the notifications to Hub
+ * Servers were ALL successful. If even one failed, FALSE is returned.
+ *
+ * @return bool
+ */
+ public function isSuccess()
+ {
+ if (count($this->_errors) > 0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return an array of errors met from any failures, including keys:
+ * 'response' => the Zend_Http_Response object from the failure
+ * 'hubUrl' => the URL of the Hub Server whose notification failed
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->_errors;
+ }
+
+ /**
+ * Return an array of Hub Server URLs who returned a response indicating
+ * operation in Asynchronous Verification Mode, i.e. they will not confirm
+ * any (un)subscription immediately but at a later time (Hubs may be
+ * doing this as a batch process when load balancing)
+ *
+ * @return array
+ */
+ public function getAsyncHubs()
+ {
+ return $this->_asyncHubs;
+ }
+
+ /**
+ * Executes an (un)subscribe request
+ *
+ * @param string $mode
+ * @return void
+ */
+ protected function _doRequest($mode)
+ {
+ $client = $this->_getHttpClient();
+ $hubs = $this->getHubUrls();
+ if (empty($hubs)) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('No Hub Server URLs'
+ . ' have been set so no subscriptions can be attempted');
+ }
+ $this->_errors = array();
+ $this->_asyncHubs = array();
+ foreach ($hubs as $url) {
+ if (array_key_exists($url, $this->_authentications)) {
+ $auth = $this->_authentications[$url];
+ $client->setAuth($auth[0], $auth[1]);
+ }
+ $client->setUri($url);
+ $client->setRawData($this->_getRequestParameters($url, $mode));
+ $response = $client->request();
+ if ($response->getStatus() !== 204
+ && $response->getStatus() !== 202
+ ) {
+ $this->_errors[] = array(
+ 'response' => $response,
+ 'hubUrl' => $url,
+ );
+ /**
+ * At first I thought it was needed, but the backend storage will
+ * allow tracking async without any user interference. It's left
+ * here in case the user is interested in knowing what Hubs
+ * are using async verification modes so they may update Models and
+ * move these to asynchronous processes.
+ */
+ } elseif ($response->getStatus() == 202) {
+ $this->_asyncHubs[] = array(
+ 'response' => $response,
+ 'hubUrl' => $url,
+ );
+ }
+ }
+ }
+
+ /**
+ * Get a basic prepared HTTP client for use
+ *
+ * @param string $mode Must be "subscribe" or "unsubscribe"
+ * @return Zend_Http_Client
+ */
+ protected function _getHttpClient()
+ {
+ $client = Zend_Feed_Pubsubhubbub::getHttpClient();
+ $client->setMethod(Zend_Http_Client::POST);
+ $client->setConfig(array('useragent' => 'Zend_Feed_Pubsubhubbub_Subscriber/'
+ . Zend_Version::VERSION));
+ return $client;
+ }
+
+ /**
+ * Return a list of standard protocol/optional parameters for addition to
+ * client's POST body that are specific to the current Hub Server URL
+ *
+ * @param string $hubUrl
+ * @param mode $hubUrl
+ * @return string
+ */
+ protected function _getRequestParameters($hubUrl, $mode)
+ {
+ if (!in_array($mode, array('subscribe', 'unsubscribe'))) {
+ // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
+ throw new Zend_Feed_Pubsubhubbub_Exception('Invalid mode specified: "'
+ . $mode . '" which should have been "subscribe" or "unsubscribe"');
+ }
+
+ $params = array(
+ 'hub.mode' => $mode,
+ 'hub.topic' => $this->getTopicUrl(),
+ );
+
+ if ($this->getPreferredVerificationMode()
+ == Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC
+ ) {
+ $vmodes = array(
+ Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC,
+ Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_ASYNC,
+ );
+ } else {
+ $vmodes = array(
+ Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_ASYNC,
+ Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_SYNC,
+ );
+ }
+ $params['hub.verify'] = array();
+ foreach($vmodes as $vmode) {
+ $params['hub.verify'][] = $vmode;
+ }
+
+ /**
+ * Establish a persistent verify_token and attach key to callback
+ * URL's path/querystring
+ */
+ $key = $this->_generateSubscriptionKey($params, $hubUrl);
+ $token = $this->_generateVerifyToken();
+ $params['hub.verify_token'] = $token;
+
+ // Note: query string only usable with PuSH 0.2 Hubs
+ if (!$this->_usePathParameter) {
+ $params['hub.callback'] = $this->getCallbackUrl()
+ . '?xhub.subscription=' . Zend_Feed_Pubsubhubbub::urlencode($key);
+ } else {
+ $params['hub.callback'] = rtrim($this->getCallbackUrl(), '/')
+ . '/' . Zend_Feed_Pubsubhubbub::urlencode($key);
+ }
+ if ($mode == 'subscribe' && !is_null($this->getLeaseSeconds())) {
+ $params['hub.lease_seconds'] = $this->getLeaseSeconds();
+ }
+
+ // hub.secret not currently supported
+ $optParams = $this->getParameters();
+ foreach ($optParams as $name => $value) {
+ $params[$name] = $value;
+ }
+
+ // store subscription to storage
+ $now = new Zend_Date;
+ $expires = null;
+ if (isset($params['hub.lease_seconds'])) {
+ $expires = $now->add($params['hub.lease_seconds'], Zend_Date::SECOND)
+ ->get('yyyy-MM-dd HH:mm:ss');
+ }
+ $data = array(
+ 'id' => $key,
+ 'topic_url' => $params['hub.topic'],
+ 'hub_url' => $hubUrl,
+ 'created_time' => $now->get('yyyy-MM-dd HH:mm:ss'),
+ 'lease_seconds' => $expires,
+ 'verify_token' => hash('sha256', $params['hub.verify_token']),
+ 'secret' => null,
+ 'expiration_time' => $expires,
+ 'subscription_state' => Zend_Feed_Pubsubhubbub::SUBSCRIPTION_NOTVERIFIED,
+ );
+ $this->getStorage()->setSubscription($data);
+
+ return $this->_toByteValueOrderedString(
+ $this->_urlEncode($params)
+ );
+ }
+
+ /**
+ * Simple helper to generate a verification token used in (un)subscribe
+ * requests to a Hub Server. Follows no particular method, which means
+ * it might be improved/changed in future.
+ *
+ * @param string $hubUrl The Hub Server URL for which this token will apply
+ * @return string
+ */
+ protected function _generateVerifyToken()
+ {
+ if (!empty($this->_testStaticToken)) {
+ return $this->_testStaticToken;
+ }
+ return uniqid(rand(), true) . time();
+ }
+
+ /**
+ * Simple helper to generate a verification token used in (un)subscribe
+ * requests to a Hub Server.
+ *
+ * @param string $hubUrl The Hub Server URL for which this token will apply
+ * @return string
+ */
+ protected function _generateSubscriptionKey(array $params, $hubUrl)
+ {
+ $keyBase = $params['hub.topic'] . $hubUrl;
+ $key = md5($keyBase);
+ return $key;
+ }
+
+ /**
+ * URL Encode an array of parameters
+ *
+ * @param array $params
+ * @return array
+ */
+ protected function _urlEncode(array $params)
+ {
+ $encoded = array();
+ foreach ($params as $key => $value) {
+ if (is_array($value)) {
+ $ekey = Zend_Feed_Pubsubhubbub::urlencode($key);
+ $encoded[$ekey] = array();
+ foreach ($value as $duplicateKey) {
+ $encoded[$ekey][]
+ = Zend_Feed_Pubsubhubbub::urlencode($duplicateKey);
+ }
+ } else {
+ $encoded[Zend_Feed_Pubsubhubbub::urlencode($key)]
+ = Zend_Feed_Pubsubhubbub::urlencode($value);
+ }
+ }
+ return $encoded;
+ }
+
+ /**
+ * Order outgoing parameters
+ *
+ * @param array $params
+ * @return array
+ */
+ protected function _toByteValueOrderedString(array $params)
+ {
+ $return = array();
+ uksort($params, 'strnatcmp');
+ foreach ($params as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $keyduplicate) {
+ $return[] = $key . '=' . $keyduplicate;
+ }
+ } else {
+ $return[] = $key . '=' . $value;
+ }
+ }
+ return implode('&', $return);
+ }
+
+ /**
+ * This is STRICTLY for testing purposes only...
+ */
+ protected $_testStaticToken = null;
+
+ final public function setTestStaticToken($token)
+ {
+ $this->_testStaticToken = (string) $token;
+ }
+}
diff --git a/libs/Zend/Feed/Pubsubhubbub/Subscriber/Callback.php b/libs/Zend/Feed/Pubsubhubbub/Subscriber/Callback.php
new file mode 100644
index 0000000000..1f42375839
--- /dev/null
+++ b/libs/Zend/Feed/Pubsubhubbub/Subscriber/Callback.php
@@ -0,0 +1,328 @@
+<?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_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Pubsubhubbub
+ */
+// require_once 'Zend/Feed/Pubsubhubbub.php';
+
+/**
+ * @see Zend_Feed_Pubsubhubbub
+ */
+// require_once 'Zend/Feed/Pubsubhubbub/CallbackAbstract.php';
+
+/**
+ * @see Zend_Feed_Reader
+ */
+// require_once 'Zend/Feed/Reader.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Pubsubhubbub
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Pubsubhubbub_Subscriber_Callback
+ extends Zend_Feed_Pubsubhubbub_CallbackAbstract
+{
+ /**
+ * Contains the content of any feeds sent as updates to the Callback URL
+ *
+ * @var string
+ */
+ protected $_feedUpdate = null;
+
+ /**
+ * Holds a manually set subscription key (i.e. identifies a unique
+ * subscription) which is typical when it is not passed in the query string
+ * but is part of the Callback URL path, requiring manual retrieval e.g.
+ * using a route and the Zend_Controller_Action::_getParam() method.
+ *
+ * @var string
+ */
+ protected $_subscriptionKey = null;
+
+ /**
+ * After verification, this is set to the verified subscription's data.
+ *
+ * @var array
+ */
+ protected $_currentSubscriptionData = null;
+
+ /**
+ * Set a subscription key to use for the current callback request manually.
+ * Required if usePathParameter is enabled for the Subscriber.
+ *
+ * @param string $key
+ * @return Zend_Feed_Pubsubhubbub_Subscriber_Callback
+ */
+ public function setSubscriptionKey($key)
+ {
+ $this->_subscriptionKey = $key;
+ return $this;
+ }
+
+ /**
+ * Handle any callback from a Hub Server responding to a subscription or
+ * unsubscription request. This should be the Hub Server confirming the
+ * the request prior to taking action on it.
+ *
+ * @param array $httpGetData GET data if available and not in $_GET
+ * @param bool $sendResponseNow Whether to send response now or when asked
+ * @return void
+ */
+ public function handle(array $httpGetData = null, $sendResponseNow = false)
+ {
+ if ($httpGetData === null) {
+ $httpGetData = $_GET;
+ }
+
+ /**
+ * Handle any feed updates (sorry for the mess :P)
+ *
+ * This DOES NOT attempt to process a feed update. Feed updates
+ * SHOULD be validated/processed by an asynchronous process so as
+ * to avoid holding up responses to the Hub.
+ */
+ if (strtolower($_SERVER['REQUEST_METHOD']) == 'post'
+ && $this->_hasValidVerifyToken(null, false)
+ && ($this->_getHeader('Content-Type') == 'application/atom+xml'
+ || $this->_getHeader('Content-Type') == 'application/rss+xml'
+ || $this->_getHeader('Content-Type') == 'application/xml'
+ || $this->_getHeader('Content-Type') == 'text/xml'
+ || $this->_getHeader('Content-Type') == 'application/rdf+xml')
+ ) {
+ $this->setFeedUpdate($this->_getRawBody());
+ $this->getHttpResponse()
+ ->setHeader('X-Hub-On-Behalf-Of', $this->getSubscriberCount());
+ /**
+ * Handle any (un)subscribe confirmation requests
+ */
+ } elseif ($this->isValidHubVerification($httpGetData)) {
+ $data = $this->_currentSubscriptionData;
+ $this->getHttpResponse()->setBody($httpGetData['hub_challenge']);
+ $data['subscription_state'] = Zend_Feed_Pubsubhubbub::SUBSCRIPTION_VERIFIED;
+ if (isset($httpGetData['hub_lease_seconds'])) {
+ $data['lease_seconds'] = $httpGetData['hub_lease_seconds'];
+ }
+ $this->getStorage()->setSubscription($data);
+ /**
+ * Hey, C'mon! We tried everything else!
+ */
+ } else {
+ $this->getHttpResponse()->setHttpResponseCode(404);
+ }
+ if ($sendResponseNow) {
+ $this->sendResponse();
+ }
+ }
+
+ /**
+ * Checks validity of the request simply by making a quick pass and
+ * confirming the presence of all REQUIRED parameters.
+ *
+ * @param array $httpGetData
+ * @return bool
+ */
+ public function isValidHubVerification(array $httpGetData)
+ {
+ /**
+ * As per the specification, the hub.verify_token is OPTIONAL. This
+ * implementation of Pubsubhubbub considers it REQUIRED and will
+ * always send a hub.verify_token parameter to be echoed back
+ * by the Hub Server. Therefore, its absence is considered invalid.
+ */
+ if (strtolower($_SERVER['REQUEST_METHOD']) !== 'get') {
+ return false;
+ }
+ $required = array(
+ 'hub_mode',
+ 'hub_topic',
+ 'hub_challenge',
+ 'hub_verify_token',
+ );
+ foreach ($required as $key) {
+ if (!array_key_exists($key, $httpGetData)) {
+ return false;
+ }
+ }
+ if ($httpGetData['hub_mode'] !== 'subscribe'
+ && $httpGetData['hub_mode'] !== 'unsubscribe'
+ ) {
+ return false;
+ }
+ if ($httpGetData['hub_mode'] == 'subscribe'
+ && !array_key_exists('hub_lease_seconds', $httpGetData)
+ ) {
+ return false;
+ }
+ if (!Zend_Uri::check($httpGetData['hub_topic'])) {
+ return false;
+ }
+
+ /**
+ * Attempt to retrieve any Verification Token Key attached to Callback
+ * URL's path by our Subscriber implementation
+ */
+ if (!$this->_hasValidVerifyToken($httpGetData)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sets a newly received feed (Atom/RSS) sent by a Hub as an update to a
+ * Topic we've subscribed to.
+ *
+ * @param string $feed
+ * @return Zend_Feed_Pubsubhubbub_Subscriber_Callback
+ */
+ public function setFeedUpdate($feed)
+ {
+ $this->_feedUpdate = $feed;
+ return $this;
+ }
+
+ /**
+ * Check if any newly received feed (Atom/RSS) update was received
+ *
+ * @return bool
+ */
+ public function hasFeedUpdate()
+ {
+ if (is_null($this->_feedUpdate)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Gets a newly received feed (Atom/RSS) sent by a Hub as an update to a
+ * Topic we've subscribed to.
+ *
+ * @return string
+ */
+ public function getFeedUpdate()
+ {
+ return $this->_feedUpdate;
+ }
+
+ /**
+ * Check for a valid verify_token. By default attempts to compare values
+ * with that sent from Hub, otherwise merely ascertains its existence.
+ *
+ * @param array $httpGetData
+ * @param bool $checkValue
+ * @return bool
+ */
+ protected function _hasValidVerifyToken(array $httpGetData = null, $checkValue = true)
+ {
+ $verifyTokenKey = $this->_detectVerifyTokenKey($httpGetData);
+ if (empty($verifyTokenKey)) {
+ return false;
+ }
+ $verifyTokenExists = $this->getStorage()->hasSubscription($verifyTokenKey);
+ if (!$verifyTokenExists) {
+ return false;
+ }
+ if ($checkValue) {
+ $data = $this->getStorage()->getSubscription($verifyTokenKey);
+ $verifyToken = $data['verify_token'];
+ if ($verifyToken !== hash('sha256', $httpGetData['hub_verify_token'])) {
+ return false;
+ }
+ $this->_currentSubscriptionData = $data;
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Attempt to detect the verification token key. This would be passed in
+ * the Callback URL (which we are handling with this class!) as a URI
+ * path part (the last part by convention).
+ *
+ * @param null|array $httpGetData
+ * @return false|string
+ */
+ protected function _detectVerifyTokenKey(array $httpGetData = null)
+ {
+ /**
+ * Available when sub keys encoding in Callback URL path
+ */
+ if (isset($this->_subscriptionKey)) {
+ return $this->_subscriptionKey;
+ }
+
+ /**
+ * Available only if allowed by PuSH 0.2 Hubs
+ */
+ if (is_array($httpGetData)
+ && isset($httpGetData['xhub_subscription'])
+ ) {
+ return $httpGetData['xhub_subscription'];
+ }
+
+ /**
+ * Available (possibly) if corrupted in transit and not part of $_GET
+ */
+ $params = $this->_parseQueryString();
+ if (isset($params['xhub.subscription'])) {
+ return rawurldecode($params['xhub.subscription']);
+ }
+
+ return false;
+ }
+
+ /**
+ * Build an array of Query String parameters.
+ * This bypasses $_GET which munges parameter names and cannot accept
+ * multiple parameters with the same key.
+ *
+ * @return array|void
+ */
+ protected function _parseQueryString()
+ {
+ $params = array();
+ $queryString = '';
+ if (isset($_SERVER['QUERY_STRING'])) {
+ $queryString = $_SERVER['QUERY_STRING'];
+ }
+ if (empty($queryString)) {
+ return array();
+ }
+ $parts = explode('&', $queryString);
+ foreach ($parts as $kvpair) {
+ $pair = explode('=', $kvpair);
+ $key = rawurldecode($pair[0]);
+ $value = rawurldecode($pair[1]);
+ if (isset($params[$key])) {
+ if (is_array($params[$key])) {
+ $params[$key][] = $value;
+ } else {
+ $params[$key] = array($params[$key], $value);
+ }
+ } else {
+ $params[$key] = $value;
+ }
+ }
+ return $params;
+ }
+}
diff --git a/libs/Zend/Feed/Reader.php b/libs/Zend/Feed/Reader.php
index ced12cf7c7..26bf661cdf 100644
--- a/libs/Zend/Feed/Reader.php
+++ b/libs/Zend/Feed/Reader.php
@@ -14,49 +14,55 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Reader.php 17391 2009-08-05 11:27:52Z padraic $
+ * @version $Id: Reader.php 22093 2010-05-04 12:55:06Z padraic $
*/
/**
* @see Zend_Feed
*/
-require_once 'Zend/Feed.php';
+// require_once 'Zend/Feed.php';
/**
* @see Zend_Feed_Reader_Feed_Rss
*/
-require_once 'Zend/Feed/Reader/Feed/Rss.php';
+// require_once 'Zend/Feed/Reader/Feed/Rss.php';
/**
* @see Zend_Feed_Reader_Feed_Atom
*/
-require_once 'Zend/Feed/Reader/Feed/Atom.php';
+// require_once 'Zend/Feed/Reader/Feed/Atom.php';
+
+/**
+ * @see Zend_Feed_Reader_FeedSet
+ */
+// require_once 'Zend/Feed/Reader/FeedSet.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader
{
- /**
- * Namespace constants
- */
- const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#';
+ /**
+ * Namespace constants
+ */
+ const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#';
const NAMESPACE_ATOM_10 = 'http://www.w3.org/2005/Atom';
const NAMESPACE_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
const NAMESPACE_RSS_090 = 'http://my.netscape.com/rdf/simple/0.9/';
const NAMESPACE_RSS_10 = 'http://purl.org/rss/1.0/';
/**
- * Feed type constants
- */
- const TYPE_ANY = 'any';
- const TYPE_ATOM_03 = 'atom-03';
+ * Feed type constants
+ */
+ const TYPE_ANY = 'any';
+ const TYPE_ATOM_03 = 'atom-03';
const TYPE_ATOM_10 = 'atom-10';
+ const TYPE_ATOM_10_ENTRY = 'atom-10-entry';
const TYPE_ATOM_ANY = 'atom';
const TYPE_RSS_090 = 'rss-090';
const TYPE_RSS_091 = 'rss-091';
@@ -161,7 +167,7 @@ class Zend_Feed_Reader
/**
* @see Zend_Http_Client
*/
- require_once 'Zend/Http/Client.php';
+ // require_once 'Zend/Http/Client.php';
self::$_httpClient = new Zend_Http_Client();
}
@@ -208,13 +214,13 @@ class Zend_Feed_Reader
}
/**
- * Import a feed by providing a URL
- *
- * @param string $url The URL to the feed
+ * Import a feed by providing a URL
+ *
+ * @param string $url The URL to the feed
* @param string $etag OPTIONAL Last received ETag for this resource
* @param string $lastModified OPTIONAL Last-Modified value for this resource
- * @return Zend_Feed_Reader_Feed_Interface
- */
+ * @return Zend_Feed_Reader_FeedInterface
+ */
public static function import($uri, $etag = null, $lastModified = null)
{
$cache = self::getCache();
@@ -245,7 +251,7 @@ class Zend_Feed_Reader
}
$response = $client->request('GET');
if ($response->getStatus() !== 200 && $response->getStatus() !== 304) {
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
if ($response->getStatus() == 304) {
@@ -268,7 +274,7 @@ class Zend_Feed_Reader
}
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
$responseXml = $response->getBody();
@@ -277,10 +283,12 @@ class Zend_Feed_Reader
} else {
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
- return self::importString($response->getBody());
+ $reader = self::importString($response->getBody());
+ $reader->setOriginalSourceUri($uri);
+ return $reader;
}
}
@@ -288,8 +296,8 @@ class Zend_Feed_Reader
* Import a feed by providing a Zend_Feed_Abstract object
*
* @param Zend_Feed_Abstract $feed A fully instantiated Zend_Feed object
- * @return Zend_Feed_Reader_Feed_Interface
- */
+ * @return Zend_Feed_Reader_FeedInterface
+ */
public static function importFeed(Zend_Feed_Abstract $feed)
{
$dom = $feed->getDOM()->ownerDocument;
@@ -298,7 +306,7 @@ class Zend_Feed_Reader
if (substr($type, 0, 3) == 'rss') {
$reader = new Zend_Feed_Reader_Feed_Rss($dom, $type);
} else {
- $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
+ $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
}
return $reader;
@@ -308,7 +316,7 @@ class Zend_Feed_Reader
* Import a feed froma string
*
* @param string $string
- * @return Zend_Feed_Reader_Feed_Interface
+ * @return Zend_Feed_Reader_FeedInterface
*/
public static function importString($string)
{
@@ -321,12 +329,12 @@ class Zend_Feed_Reader
// Build error message
$error = libxml_get_last_error();
if ($error && $error->message) {
- $errormsg = "DOMDocument cannot parse XML: {$error->message}";
+ $errormsg = "DOMDocument cannot parse XML: {$error->message}";
} else {
- $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity";
+ $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity";
}
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception($errormsg);
}
@@ -336,8 +344,14 @@ class Zend_Feed_Reader
if (substr($type, 0, 3) == 'rss') {
$reader = new Zend_Feed_Reader_Feed_Rss($dom, $type);
+ } elseif (substr($type, 8, 5) == 'entry') {
+ $reader = new Zend_Feed_Reader_Entry_Atom($dom->documentElement, 0, Zend_Feed_Reader::TYPE_ATOM_10);
+ } elseif (substr($type, 0, 4) == 'atom') {
+ $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
} else {
- $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('The URI used does not point to a '
+ . 'valid Atom, RSS or RDF feed that Zend_Feed_Reader can parse.');
}
return $reader;
}
@@ -358,7 +372,7 @@ class Zend_Feed_Reader
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("File could not be loaded: $php_errormsg");
}
return self::importString($feed);
@@ -374,62 +388,48 @@ class Zend_Feed_Reader
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus());
}
$responseHtml = $response->getBody();
- @ini_set('track_errors', 1);
+ $libxml_errflag = libxml_use_internal_errors(true);
$dom = new DOMDocument;
- $status = @$dom->loadHTML($responseHtml);
- @ini_restore('track_errors');
+ $status = $dom->loadHTML($responseHtml);
+ libxml_use_internal_errors($libxml_errflag);
if (!$status) {
- 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)';
- }
+ // Build error message
+ $error = libxml_get_last_error();
+ if ($error && $error->message) {
+ $errormsg = "DOMDocument cannot parse HTML: {$error->message}";
+ } else {
+ $errormsg = "DOMDocument cannot parse HTML: Please check the XML document's validity";
}
- require_once 'Zend/Feed/Exception.php';
- throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
+
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception($errormsg);
}
- $feedLinks = new stdClass;
+ $feedSet = new Zend_Feed_Reader_FeedSet;
$links = $dom->getElementsByTagName('link');
- foreach ($links as $link) {
- if (strtolower($link->getAttribute('rel')) !== 'alternate'
- || !$link->getAttribute('type') || !$link->getAttribute('href')) {
- continue;
- }
- if (!isset($feedLinks->rss) && $link->getAttribute('type') == 'application/rss+xml') {
- $feedLinks->rss = $link->getAttribute('href');
- } elseif(!isset($feedLinks->atom) && $link->getAttribute('type') == 'application/atom+xml') {
- $feedLinks->atom = $link->getAttribute('href');
- } elseif(!isset($feedLinks->rdf) && $link->getAttribute('type') == 'application/rdf+xml') {
- $feedLinks->rdf = $link->getAttribute('href');
- }
- if (isset($feedLinks->rss) && isset($feedLinks->atom) && isset($feedLinks->rdf)) {
- break;
- }
- }
- return $feedLinks;
+ $feedSet->addLinks($links, $uri);
+ return $feedSet;
}
/**
* Detect the feed type of the provided feed
*
- * @param Zend_Feed_Abstract $feed A fully instantiated Zend_Feed object
+ * @param Zend_Feed_Abstract|DOMDocument|string $feed
* @return string
*/
- public static function detectType($feed)
+ public static function detectType($feed, $specOnly = false)
{
if ($feed instanceof Zend_Feed_Reader_FeedInterface) {
$dom = $feed->getDomDocument();
- } elseif($feed instanceof DomDocument) {
+ } elseif($feed instanceof DOMDocument) {
$dom = $feed;
} elseif(is_string($feed) && !empty($feed)) {
@ini_set('track_errors', 1);
$dom = new DOMDocument;
- $status = @$doc->loadXML($string);
+ $status = @$dom->loadXML($feed);
@ini_restore('track_errors');
if (!$status) {
if (!isset($php_errormsg)) {
@@ -439,12 +439,13 @@ class Zend_Feed_Reader
$php_errormsg = '(error message not available)';
}
}
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
} else {
- require_once 'Zend/Feed/Exception.php';
- throw new Zend_Feed_Exception('Invalid object/scalar provided: must be of type Zend_Feed_Reader_FeedInterface, DomDocument or string');
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid object/scalar provided: must'
+ . ' be of type Zend_Feed_Reader_FeedInterface, DomDocument or string');
}
$xpath = new DOMXPath($dom);
@@ -509,6 +510,14 @@ class Zend_Feed_Reader
if ($xpath->query('//atom:feed')->length) {
return self::TYPE_ATOM_10;
}
+
+ if ($xpath->query('//atom:entry')->length) {
+ if ($specOnly == true) {
+ return self::TYPE_ATOM_10;
+ } else {
+ return self::TYPE_ATOM_10_ENTRY;
+ }
+ }
$xpath->registerNamespace('atom', self::NAMESPACE_ATOM_03);
@@ -537,7 +546,7 @@ class Zend_Feed_Reader
public static function getPluginLoader()
{
if (!isset(self::$_pluginLoader)) {
- require_once 'Zend/Loader/PluginLoader.php';
+ // require_once 'Zend/Loader/PluginLoader.php';
self::$_pluginLoader = new Zend_Loader_PluginLoader(array(
'Zend_Feed_Reader_Extension_' => 'Zend/Feed/Reader/Extension/',
));
@@ -607,7 +616,7 @@ class Zend_Feed_Reader
if (!self::getPluginLoader()->isLoaded($feedName)
&& !self::getPluginLoader()->isLoaded($entryName)
) {
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Could not load extension: ' . $name
. 'using Plugin Loader. Check prefix paths are configured and extension exists.');
}
@@ -689,4 +698,24 @@ class Zend_Feed_Reader
self::registerExtension('Thread');
self::registerExtension('Podcast');
}
+
+ /**
+ * Utility method to apply array_unique operation to a multidimensional
+ * array.
+ *
+ * @param array
+ * @return array
+ */
+ public static function arrayUnique(array $array)
+ {
+ foreach ($array as &$value) {
+ $value = serialize($value);
+ }
+ $array = array_unique($array);
+ foreach ($array as &$value) {
+ $value = unserialize($value);
+ }
+ return $array;
+ }
+
}
diff --git a/libs/Zend/Feed/Reader/Collection.php b/libs/Zend/Feed/Reader/Collection.php
new file mode 100644
index 0000000000..fba2b52b52
--- /dev/null
+++ b/libs/Zend/Feed/Reader/Collection.php
@@ -0,0 +1,33 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Reader_Collection extends ArrayObject
+{
+
+
+
+}
diff --git a/libs/Zend/Feed/Reader/Collection/Author.php b/libs/Zend/Feed/Reader/Collection/Author.php
new file mode 100644
index 0000000000..6a039974b6
--- /dev/null
+++ b/libs/Zend/Feed/Reader/Collection/Author.php
@@ -0,0 +1,51 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Author.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Feed_Reader_Collection_CollectionAbstract
+ */
+// require_once 'Zend/Feed/Reader/Collection/CollectionAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Reader_Collection_Author
+extends Zend_Feed_Reader_Collection_CollectionAbstract
+{
+
+ /**
+ * Return a simple array of the most relevant slice of
+ * the author values, i.e. all author names.
+ *
+ * @return array
+ */
+ public function getValues() {
+ $authors = array();
+ foreach ($this->getIterator() as $element) {
+ $authors[] = $element['name'];
+ }
+ return array_unique($authors);
+ }
+
+}
diff --git a/libs/Zend/Feed/Reader/Collection/Category.php b/libs/Zend/Feed/Reader/Collection/Category.php
new file mode 100644
index 0000000000..2587c13268
--- /dev/null
+++ b/libs/Zend/Feed/Reader/Collection/Category.php
@@ -0,0 +1,57 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Category.php 20954 2010-02-06 17:56:27Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Reader_Collection_CollectionAbstract
+ */
+// require_once 'Zend/Feed/Reader/Collection/CollectionAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Reader_Collection_Category
+extends Zend_Feed_Reader_Collection_CollectionAbstract
+{
+
+ /**
+ * Return a simple array of the most relevant slice of
+ * the collection values. For example, feed categories contain
+ * the category name, domain/URI, and other data. This method would
+ * merely return the most useful data - i.e. the category names.
+ *
+ * @return array
+ */
+ public function getValues() {
+ $categories = array();
+ foreach ($this->getIterator() as $element) {
+ if (isset($element['label']) && !empty($element['label'])) {
+ $categories[] = $element['label'];
+ } else {
+ $categories[] = $element['term'];
+ }
+ }
+ return array_unique($categories);
+ }
+
+}
diff --git a/libs/Zend/Feed/Reader/Collection/CollectionAbstract.php b/libs/Zend/Feed/Reader/Collection/CollectionAbstract.php
new file mode 100644
index 0000000000..7b6dbd0317
--- /dev/null
+++ b/libs/Zend/Feed/Reader/Collection/CollectionAbstract.php
@@ -0,0 +1,41 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: CollectionAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Feed_Reader_Collection_CollectionAbstract extends ArrayObject
+{
+
+ /**
+ * Return a simple array of the most relevant slice of
+ * the collection values. For example, feed categories contain
+ * the category name, domain/URI, and other data. This method would
+ * merely return the most useful data - i.e. the category names.
+ *
+ * @return array
+ */
+ public abstract function getValues();
+
+}
diff --git a/libs/Zend/Feed/Reader/Entry/Atom.php b/libs/Zend/Feed/Reader/Entry/Atom.php
index b788cd2533..77289b411b 100644
--- a/libs/Zend/Feed/Reader/Entry/Atom.php
+++ b/libs/Zend/Feed/Reader/Entry/Atom.php
@@ -14,35 +14,35 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Atom.php 16966 2009-07-22 15:22:18Z padraic $
+ * @version $Id: Atom.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_EntryInterface
*/
-require_once 'Zend/Feed/Reader/EntryInterface.php';
+// require_once 'Zend/Feed/Reader/EntryInterface.php';
/**
* @see Zend_Feed_Reader_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/EntryAbstract.php';
/**
* @see Zend_Feed_Reader_Extension_Atom_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/Atom/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/Atom/Entry.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Entry_Atom extends Zend_Feed_Reader_EntryAbstract implements Zend_Feed_Reader_EntryInterface
@@ -74,9 +74,12 @@ class Zend_Feed_Reader_Entry_Atom extends Zend_Feed_Reader_EntryAbstract impleme
$threadClass = Zend_Feed_Reader::getPluginLoader()->getClassName('Thread_Entry');
$this->_extensions['Thread_Entry'] = new $threadClass($entry, $entryKey, $type);
+
+ $threadClass = Zend_Feed_Reader::getPluginLoader()->getClassName('DublinCore_Entry');
+ $this->_extensions['DublinCore_Entry'] = new $threadClass($entry, $entryKey, $type);
}
- /**
+ /**
* Get the specified author
*
* @param int $index
@@ -295,7 +298,7 @@ class Zend_Feed_Reader_Entry_Atom extends Zend_Feed_Reader_EntryAbstract impleme
return $this->_data['commentcount'];
}
- $commentcount = $this->getExtension('Thread')>getCommentCount();
+ $commentcount = $this->getExtension('Thread')->getCommentCount();
if (!$commentcount) {
$commentcount = $this->getExtension('Atom')->getCommentCount();
@@ -341,6 +344,46 @@ class Zend_Feed_Reader_Entry_Atom extends Zend_Feed_Reader_EntryAbstract impleme
return $this->_data['commentfeedlink'];
}
+
+ /**
+ * Get category data as a Zend_Feed_Reader_Collection_Category object
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ $categoryCollection = $this->getExtension('Atom')->getCategories();
+
+ if (count($categoryCollection) == 0) {
+ $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
+
+ /**
+ * Get source feed metadata from the entry
+ *
+ * @return Zend_Feed_Reader_Feed_Atom_Source|null
+ */
+ public function getSource()
+ {
+ if (array_key_exists('source', $this->_data)) {
+ return $this->_data['source'];
+ }
+
+ $source = $this->getExtension('Atom')->getSource();
+
+ $this->_data['source'] = $source;
+
+ return $this->_data['source'];
+ }
/**
* Set the XPath query (incl. on all Extensions)
diff --git a/libs/Zend/Feed/Reader/Entry/Rss.php b/libs/Zend/Feed/Reader/Entry/Rss.php
index b91990a665..21a30a98fc 100644
--- a/libs/Zend/Feed/Reader/Entry/Rss.php
+++ b/libs/Zend/Feed/Reader/Entry/Rss.php
@@ -14,65 +14,70 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Rss.php 18367 2009-09-22 14:55:59Z padraic $
+ * @version $Id: Rss.php 22301 2010-05-26 10:15:13Z padraic $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_EntryInterface
*/
-require_once 'Zend/Feed/Reader/EntryInterface.php';
+// require_once 'Zend/Feed/Reader/EntryInterface.php';
/**
* @see Zend_Feed_Reader_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/EntryAbstract.php';
/**
* @see Zend_Feed_Reader_Extension_DublinCore_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/DublinCore/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/DublinCore/Entry.php';
/**
* @see Zend_Feed_Reader_Extension_Content_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/Content/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/Content/Entry.php';
/**
* @see Zend_Feed_Reader_Extension_Atom_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/Atom/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/Atom/Entry.php';
/**
* @see Zend_Feed_Reader_Extension_WellformedWeb_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php';
/**
* @see Zend_Feed_Reader_Extension_Slash_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/Slash/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/Slash/Entry.php';
/**
* @see Zend_Feed_Reader_Extension_Thread_Entry
*/
-require_once 'Zend/Feed/Reader/Extension/Thread/Entry.php';
+// require_once 'Zend/Feed/Reader/Extension/Thread/Entry.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Feed_Reader_Collection_Category
+ */
+// require_once 'Zend/Feed/Reader/Collection/Category.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implements Zend_Feed_Reader_EntryInterface
@@ -154,45 +159,50 @@ class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implemen
if (array_key_exists('authors', $this->_data)) {
return $this->_data['authors'];
}
-
+
$authors = array();
- // @todo: create a list from all potential sources rather than from alternatives
- if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
- $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
- $list = $this->_xpath->evaluate($this->_xpathQueryRss.'//author');
- } else {
- $list = $this->_xpath->evaluate($this->_xpathQueryRdf.'//rss:author');
- }
- if (!$list->length) {
- if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
- $list = $this->_xpath->query('//author');
- } else {
- $list = $this->_xpath->query('//rss:author');
+ $authors_dc = $this->getExtension('DublinCore')->getAuthors();
+ if (!empty($authors_dc)) {
+ foreach ($authors_dc as $author) {
+ $authors[] = array(
+ 'name' => $author['name']
+ );
}
}
-
+
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10
+ && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $list = $this->_xpath->query($this->_xpathQueryRss . '//author');
+ } else {
+ $list = $this->_xpath->query($this->_xpathQueryRdf . '//rss:author');
+ }
if ($list->length) {
foreach ($list as $author) {
- if ($this->getType() == Zend_Feed_Reader::TYPE_RSS_20
- && preg_match("/\(([^\)]+)\)/", $author->nodeValue, $matches, PREG_OFFSET_CAPTURE)
- ) {
- // source name from RSS 2.0 <author>
- // format "joe@example.com (Joe Bloggs)"
- $authors[] = $matches[1][0];
- } else {
- $authors[] = $author->nodeValue;
- }
+ $string = trim($author->nodeValue);
+ $email = null;
+ $name = null;
+ $data = array();
+ // Pretty rough parsing - but it's a catchall
+ if (preg_match("/^.*@[^ ]*/", $string, $matches)) {
+ $data['email'] = trim($matches[0]);
+ if (preg_match("/\((.*)\)$/", $string, $matches)) {
+ $data['name'] = $matches[1];
+ }
+ $authors[] = $data;
+ }
}
-
- $authors = array_unique($authors);
}
- if (empty($authors)) {
- $authors = $this->getExtension('DublinCore')->getAuthors();
+ if (count($authors) == 0) {
+ $authors = $this->getExtension('Atom')->getAuthors();
+ } else {
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
}
- if (empty($authors)) {
- $authors = $this->getExtension('Atom')->getAuthors();
+ if (count($authors) == 0) {
+ $authors = null;
}
$this->_data['authors'] = $authors;
@@ -255,21 +265,27 @@ class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implemen
) {
$dateModified = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/pubDate)');
if ($dateModified) {
- $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822,
- Zend_Date::RFC_2822, Zend_Date::DATES);
- $date = new Zend_Date;
- foreach ($dateStandards as $standard) {
- try {
- $date->set($dateModified, $standard);
- break;
- } catch (Zend_Date_Exception $e) {
- if ($standard == Zend_Date::DATES) {
- require_once 'Zend/Feed/Exception.php';
- throw new Zend_Feed_Exception(
- 'Could not load date due to unrecognised'
- .' format (should follow RFC 822 or 2822):'
- . $e->getMessage()
- );
+ $dateModifiedParsed = strtotime($dateModified);
+ if ($dateModifiedParsed) {
+ $date = new Zend_Date($dateModifiedParsed);
+ } else {
+ $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822,
+ Zend_Date::RFC_2822, Zend_Date::DATES);
+ $date = new Zend_Date;
+ foreach ($dateStandards as $standard) {
+ try {
+ $date->set($dateModified, $standard);
+ break;
+ } catch (Zend_Date_Exception $e) {
+ if ($standard == Zend_Date::DATES) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception(
+ 'Could not load date due to unrecognised'
+ .' format (should follow RFC 822 or 2822):'
+ . $e->getMessage(),
+ 0, $e
+ );
+ }
}
}
}
@@ -324,8 +340,6 @@ class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implemen
if (!$description) {
$description = null;
- } else {
- $description = html_entity_decode($description, ENT_QUOTES, $this->getEncoding());
}
$this->_data['description'] = $description;
@@ -458,6 +472,46 @@ class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implemen
return $this->_data['links'];
}
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
+ $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $list = $this->_xpath->query($this->_xpathQueryRss.'//category');
+ } else {
+ $list = $this->_xpath->query($this->_xpathQueryRdf.'//rss:category');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->nodeValue,
+ 'scheme' => $category->getAttribute('domain'),
+ 'label' => $category->nodeValue,
+ );
+ }
+ } else {
+ $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+ }
+
+ if (count($categoryCollection) == 0) {
+ $categoryCollection = $this->getExtension('Atom')->getCategories();
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
/**
* Get a permalink to the entry
diff --git a/libs/Zend/Feed/Reader/EntryAbstract.php b/libs/Zend/Feed/Reader/EntryAbstract.php
index 153149ebcc..f73e1d1e8e 100644
--- a/libs/Zend/Feed/Reader/EntryAbstract.php
+++ b/libs/Zend/Feed/Reader/EntryAbstract.php
@@ -14,15 +14,15 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: EntryAbstract.php 16966 2009-07-22 15:22:18Z padraic $
+ * @version $Id: EntryAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Reader_EntryAbstract
@@ -118,6 +118,9 @@ abstract class Zend_Feed_Reader_EntryAbstract
public function getEncoding()
{
$assumed = $this->getDomDocument()->encoding;
+ if (empty($assumed)) {
+ $assumed = 'UTF-8';
+ }
return $assumed;
}
@@ -134,7 +137,7 @@ abstract class Zend_Feed_Reader_EntryAbstract
return $dom->saveXml();
}
- /**
+ /**
* Get the entry type
*
* @return string
@@ -151,10 +154,13 @@ abstract class Zend_Feed_Reader_EntryAbstract
*/
public function getXpath()
{
+ if (!$this->_xpath) {
+ $this->setXpath(new DOMXPath($this->getDomDocument()));
+ }
return $this->_xpath;
}
- /**
+ /**
* Set the XPath query
*
* @param DOMXPath $xpath
@@ -167,16 +173,6 @@ abstract class Zend_Feed_Reader_EntryAbstract
}
/**
- * Serialize the entry to an array
- *
- * @return array
- */
- public function toArray()
- {
- return $this->_data;
- }
-
- /**
* Get registered extensions
*
* @return array
@@ -215,7 +211,7 @@ abstract class Zend_Feed_Reader_EntryAbstract
return call_user_func_array(array($extension, $method), $args);
}
}
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Method: ' . $method
. 'does not exist and could not be located on a registered Extension');
}
diff --git a/libs/Zend/Feed/Reader/EntryInterface.php b/libs/Zend/Feed/Reader/EntryInterface.php
index dafbe293dd..392a533a30 100644
--- a/libs/Zend/Feed/Reader/EntryInterface.php
+++ b/libs/Zend/Feed/Reader/EntryInterface.php
@@ -14,15 +14,15 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: EntryInterface.php 16953 2009-07-22 11:57:25Z padraic $
+ * @version $Id: EntryInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Feed_Reader_EntryInterface
@@ -133,4 +133,11 @@ interface Zend_Feed_Reader_EntryInterface
* @return string
*/
public function getCommentFeedLink();
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories();
}
diff --git a/libs/Zend/Feed/Reader/Extension/Atom/Entry.php b/libs/Zend/Feed/Reader/Extension/Atom/Entry.php
index f442115801..1efa197787 100644
--- a/libs/Zend/Feed/Reader/Extension/Atom/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/Atom/Entry.php
@@ -14,41 +14,51 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 18655 2009-10-20 14:17:39Z padraic $
+ * @version $Id: Entry.php 22301 2010-05-26 10:15:13Z padraic $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
/**
* @see Zend_Uri
*/
-require_once 'Zend/Uri.php';
+// require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Feed_Reader_Collection_Category
+ */
+// require_once 'Zend/Feed/Reader/Collection/Category.php';
+
+/**
+ * @see Zend_Feed_Reader_Feed_Atom_Source
+ */
+// require_once 'Zend/Feed/Reader/Feed/Atom/Source.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Extension_Atom_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
- /**
+ /**
* Get the specified author
*
* @param int $index
@@ -76,33 +86,34 @@ class Zend_Feed_Reader_Extension_Atom_Entry
return $this->_data['authors'];
}
- $authors = $this->_xpath->query(
- $this->getXpathPrefix() . '//atom:author' . '|'
- . $this->getXpathPrefix(). '//atom:contributor'
- );
+ $authors = array();
+ $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom:author');
- if (!$authors->length) {
- $authors = $this->_xpath->query(
- '//atom:author' . '|' . '//atom:contributor'
- );
+ if (!$list->length) {
+ /**
+ * TODO: Limit query to feed level els only!
+ */
+ $list = $this->getXpath()->query('//atom:author');
}
- $people = array();
-
- if ($authors->length) {
- foreach ($authors as $author) {
+ if ($list->length) {
+ foreach ($list as $author) {
$author = $this->_getAuthor($author);
-
if (!empty($author)) {
- $people[] = $author;
+ $authors[] = $author;
}
}
}
- $people = array_unique($people);
-
- $this->_data['authors'] = $people;
+ if (count($authors) == 0) {
+ $authors = null;
+ } else {
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
+ }
+ $this->_data['authors'] = $authors;
return $this->_data['authors'];
}
@@ -116,21 +127,65 @@ class Zend_Feed_Reader_Extension_Atom_Entry
if (array_key_exists('content', $this->_data)) {
return $this->_data['content'];
}
-
- $content = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:content)');
-
- if ($content) {
- $content = html_entity_decode($content, ENT_QUOTES, $this->getEncoding());
+
+ $content = null;
+
+ $el = $this->getXpath()->query($this->getXpathPrefix() . '/atom:content');
+ if($el->length > 0) {
+ $el = $el->item(0);
+ $type = $el->getAttribute('type');
+ switch ($type) {
+ case '':
+ case 'text':
+ case 'text/plain':
+ case 'html':
+ case 'text/html':
+ $content = $el->nodeValue;
+ break;
+ case 'xhtml':
+ $this->getXpath()->registerNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
+ $xhtml = $this->getXpath()->query(
+ $this->getXpathPrefix() . '/atom:content/xhtml:div'
+ )->item(0);
+ //$xhtml->setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
+ $d = new DOMDocument('1.0', $this->getEncoding());
+ $xhtmls = $d->importNode($xhtml, true);
+ $d->appendChild($xhtmls);
+ $content = $this->_collectXhtml(
+ $d->saveXML(),
+ $d->lookupPrefix('http://www.w3.org/1999/xhtml')
+ );
+ break;
+ }
}
+
+ //var_dump($content); exit;
if (!$content) {
$content = $this->getDescription();
}
- $this->_data['content'] = $content;
+ $this->_data['content'] = trim($content);
return $this->_data['content'];
}
+
+ /**
+ * Parse out XHTML to remove the namespacing
+ */
+ protected function _collectXhtml($xhtml, $prefix)
+ {
+ if (!empty($prefix)) $prefix = $prefix . ':';
+ $matches = array(
+ "/<\?xml[^<]*>[^<]*<" . $prefix . "div[^<]*/",
+ "/<\/" . $prefix . "div>\s*$/"
+ );
+ $xhtml = preg_replace($matches, '', $xhtml);
+ if (!empty($prefix)) {
+ $xhtml = preg_replace("/(<[\/]?)" . $prefix . "([a-zA-Z]+)/", '$1$2', $xhtml);
+ }
+ return $xhtml;
+ }
/**
* Get the entry creation date
@@ -145,10 +200,10 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$date = null;
- if ($this->getType() === Zend_Feed_Reader::TYPE_ATOM_03) {
- $dateCreated = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:created)');
+ if ($this->_getAtomType() === Zend_Feed_Reader::TYPE_ATOM_03) {
+ $dateCreated = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:created)');
} else {
- $dateCreated = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:published)');
+ $dateCreated = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:published)');
}
if ($dateCreated) {
@@ -174,10 +229,10 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$date = null;
- if ($this->getType() === Zend_Feed_Reader::TYPE_ATOM_03) {
- $dateModified = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:modified)');
+ if ($this->_getAtomType() === Zend_Feed_Reader::TYPE_ATOM_03) {
+ $dateModified = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:modified)');
} else {
- $dateModified = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:updated)');
+ $dateModified = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:updated)');
}
if ($dateModified) {
@@ -201,12 +256,10 @@ class Zend_Feed_Reader_Extension_Atom_Entry
return $this->_data['description'];
}
- $description = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:summary)');
+ $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:summary)');
if (!$description) {
$description = null;
- } else {
- $description = html_entity_decode($description, ENT_QUOTES, $this->getEncoding());
}
$this->_data['description'] = $description;
@@ -227,7 +280,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$enclosure = null;
- $nodeList = $this->_xpath->query($this->getXpathPrefix() . '/atom:link[@rel="enclosure"]');
+ $nodeList = $this->getXpath()->query($this->getXpathPrefix() . '/atom:link[@rel="enclosure"]');
if ($nodeList->length > 0) {
$enclosure = new stdClass();
@@ -252,7 +305,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
return $this->_data['id'];
}
- $id = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:id)');
+ $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:id)');
if (!$id) {
if ($this->getPermalink()) {
@@ -268,7 +321,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
return $this->_data['id'];
}
-
+
/**
* Get the base URI of the feed (if set).
*
@@ -279,19 +332,19 @@ class Zend_Feed_Reader_Extension_Atom_Entry
if (array_key_exists('baseUrl', $this->_data)) {
return $this->_data['baseUrl'];
}
-
- $baseUrl = $this->_xpath->evaluate('string('
+
+ $baseUrl = $this->getXpath()->evaluate('string('
. $this->getXpathPrefix() . '/@xml:base[1]'
. ')');
-
+
if (!$baseUrl) {
- $baseUrl = $this->_xpath->evaluate('string(//@xml:base[1])');
+ $baseUrl = $this->getXpath()->evaluate('string(//@xml:base[1])');
}
if (!$baseUrl) {
$baseUrl = null;
}
-
+
$this->_data['baseUrl'] = $baseUrl;
return $this->_data['baseUrl'];
@@ -329,7 +382,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$links = array();
- $list = $this->_xpath->query(
+ $list = $this->getXpath()->query(
$this->getXpathPrefix() . '//atom:link[@rel="alternate"]/@href' . '|' .
$this->getXpathPrefix() . '//atom:link[not(@rel)]/@href'
);
@@ -366,12 +419,10 @@ class Zend_Feed_Reader_Extension_Atom_Entry
return $this->_data['title'];
}
- $title = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:title)');
+ $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:title)');
if (!$title) {
$title = null;
- } else {
- $title = html_entity_decode($title, ENT_QUOTES, $this->getEncoding());
}
$this->_data['title'] = $title;
@@ -392,8 +443,8 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$count = null;
- $this->_xpath->registerNamespace('thread10', 'http://purl.org/syndication/thread/1.0');
- $list = $this->_xpath->query(
+ $this->getXpath()->registerNamespace('thread10', 'http://purl.org/syndication/thread/1.0');
+ $list = $this->getXpath()->query(
$this->getXpathPrefix() . '//atom:link[@rel="replies"]/@thread10:count'
);
@@ -419,7 +470,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$link = null;
- $list = $this->_xpath->query(
+ $list = $this->getXpath()->query(
$this->getXpathPrefix() . '//atom:link[@rel="replies" and @type="text/html"]/@href'
);
@@ -446,7 +497,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
$link = null;
- $list = $this->_xpath->query(
+ $list = $this->getXpath()->query(
$this->getXpathPrefix() . '//atom:link[@rel="replies" and @type="application/'.$type.'+xml"]/@href'
);
@@ -461,6 +512,72 @@ class Zend_Feed_Reader_Extension_Atom_Entry
}
/**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ if ($this->_getAtomType() == Zend_Feed_Reader::TYPE_ATOM_10) {
+ $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom:category');
+ } else {
+ /**
+ * Since Atom 0.3 did not support categories, it would have used the
+ * Dublin Core extension. However there is a small possibility Atom 0.3
+ * may have been retrofittied to use Atom 1.0 instead.
+ */
+ $this->getXpath()->registerNamespace('atom10', Zend_Feed_Reader::NAMESPACE_ATOM_10);
+ $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom10:category');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->getAttribute('term'),
+ 'scheme' => $category->getAttribute('scheme'),
+ 'label' => $category->getAttribute('label')
+ );
+ }
+ } else {
+ return new Zend_Feed_Reader_Collection_Category;
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
+
+ /**
+ * Get source feed metadata from the entry
+ *
+ * @return Zend_Feed_Reader_Feed_Atom_Source|null
+ */
+ public function getSource()
+ {
+ if (array_key_exists('source', $this->_data)) {
+ return $this->_data['source'];
+ }
+
+ $source = null;
+ // TODO: Investigate why _getAtomType() fails here. Is it even needed?
+ if ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10) {
+ $list = $this->getXpath()->query($this->getXpathPrefix() . '/atom:source[1]');
+ if ($list->length) {
+ $element = $list->item(0);
+ $source = new Zend_Feed_Reader_Feed_Atom_Source($element, $this->getXpathPrefix());
+ }
+ }
+
+ $this->_data['source'] = $source;
+ return $this->_data['source'];
+ }
+
+ /**
* Attempt to absolutise the URI, i.e. if a relative URI apply the
* xml:base value as a prefix to turn into an absolute URI.
*/
@@ -485,35 +602,28 @@ class Zend_Feed_Reader_Extension_Atom_Entry
*/
protected function _getAuthor(DOMElement $element)
{
- $email = null;
- $name = null;
- $uri = null;
+ $author = array();
$emailNode = $element->getElementsByTagName('email');
$nameNode = $element->getElementsByTagName('name');
$uriNode = $element->getElementsByTagName('uri');
-
- if ($emailNode->length) {
- $email = $emailNode->item(0)->nodeValue;
+
+ if ($emailNode->length && strlen($emailNode->item(0)->nodeValue) > 0) {
+ $author['email'] = $emailNode->item(0)->nodeValue;
}
- if ($nameNode->length) {
- $name = $nameNode->item(0)->nodeValue;
+ if ($nameNode->length && strlen($nameNode->item(0)->nodeValue) > 0) {
+ $author['name'] = $nameNode->item(0)->nodeValue;
}
- if ($uriNode->length) {
- $uri = $uriNode->item(0)->nodeValue;
+ if ($uriNode->length && strlen($uriNode->item(0)->nodeValue) > 0) {
+ $author['uri'] = $uriNode->item(0)->nodeValue;
}
- if (!empty($email)) {
- return $email . (empty($name) ? '' : ' (' . $name . ')');
- } else if (!empty($name)) {
- return $name;
- } else if (!empty($uri)) {
- return $uri;
+ if (empty($author)) {
+ return null;
}
-
- return null;
+ return $author;
}
/**
@@ -521,18 +631,12 @@ class Zend_Feed_Reader_Extension_Atom_Entry
*/
protected function _registerNamespaces()
{
- if ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10
- || $this->getType() == Zend_Feed_Reader::TYPE_ATOM_03
- ) {
- return; // pre-registered at Feed level
- }
- $atomDetected = $this->_getAtomType();
- switch ($atomDetected) {
+ switch ($this->_getAtomType()) {
case Zend_Feed_Reader::TYPE_ATOM_03:
- $this->_xpath->registerNamespace('atom', Zend_Feed_Reader::NAMESPACE_ATOM_03);
+ $this->getXpath()->registerNamespace('atom', Zend_Feed_Reader::NAMESPACE_ATOM_03);
break;
default:
- $this->_xpath->registerNamespace('atom', Zend_Feed_Reader::NAMESPACE_ATOM_10);
+ $this->getXpath()->registerNamespace('atom', Zend_Feed_Reader::NAMESPACE_ATOM_10);
break;
}
}
@@ -542,17 +646,16 @@ class Zend_Feed_Reader_Extension_Atom_Entry
*/
protected function _getAtomType()
{
- $nslist = $this->getDomDocument()->documentElement->attributes;
- if (!$nslist->length) {
- return null;
- }
- foreach ($nslist as $ns) {
- if ($ns->value == Zend_Feed_Reader::NAMESPACE_ATOM_10) {
- return Zend_Feed_Reader::TYPE_ATOM_10;
- }
- if ($ns->value == Zend_Feed_Reader::NAMESPACE_ATOM_03) {
- return Zend_Feed_Reader::TYPE_ATOM_03;
- }
+ $dom = $this->getDomDocument();
+ $prefixAtom03 = $dom->lookupPrefix(Zend_Feed_Reader::NAMESPACE_ATOM_03);
+ $prefixAtom10 = $dom->lookupPrefix(Zend_Feed_Reader::NAMESPACE_ATOM_10);
+ if ($dom->isDefaultNamespace(Zend_Feed_Reader::NAMESPACE_ATOM_03)
+ || !empty($prefixAtom03)) {
+ return Zend_Feed_Reader::TYPE_ATOM_03;
+ }
+ if ($dom->isDefaultNamespace(Zend_Feed_Reader::NAMESPACE_ATOM_10)
+ || !empty($prefixAtom10)) {
+ return Zend_Feed_Reader::TYPE_ATOM_10;
}
}
}
diff --git a/libs/Zend/Feed/Reader/Extension/Atom/Feed.php b/libs/Zend/Feed/Reader/Extension/Atom/Feed.php
index 4b1de87ed8..3e0e2079c5 100644
--- a/libs/Zend/Feed/Reader/Extension/Atom/Feed.php
+++ b/libs/Zend/Feed/Reader/Extension/Atom/Feed.php
@@ -14,33 +14,38 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Feed.php 18655 2009-10-20 14:17:39Z padraic $
+ * @version $Id: Feed.php 22301 2010-05-26 10:15:13Z padraic $
*/
/**
* @see Zend_Feed_Reader_Extension_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
/**
* @see Zend_Uri
*/
-require_once 'Zend/Uri.php';
+// require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Feed_Reader_Collection_Author
+ */
+// require_once 'Zend/Feed/Reader/Collection/Author.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_Atom_Feed
+class Zend_Feed_Reader_Extension_Atom_Feed
extends Zend_Feed_Reader_Extension_FeedAbstract
{
/**
@@ -71,38 +76,28 @@ class Zend_Feed_Reader_Extension_Atom_Feed
return $this->_data['authors'];
}
- $authors = $this->_xpath->query('//atom:author');
- $contributors = $this->_xpath->query('//atom:contributor');
+ $list = $this->_xpath->query('//atom:author');
- $people = array();
+ $authors = array();
- if ($authors->length) {
- foreach ($authors as $author) {
+ if ($list->length) {
+ foreach ($list as $author) {
$author = $this->_getAuthor($author);
-
if (!empty($author)) {
- $people[] = $author;
- }
- }
- }
-
- if ($contributors->length) {
- foreach ($contributors as $contributor) {
- $contributor = $this->_getAuthor($contributor);
-
- if (!empty($contributor)) {
- $people[] = $contributor;
+ $authors[] = $author;
}
}
}
- if (empty($people)) {
- $people = null;
+ if (count($authors) == 0) {
+ $authors = null;
} else {
- $people = array_unique($people);
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
}
- $this->_data['authors'] = $people;
+ $this->_data['authors'] = $authors;
return $this->_data['authors'];
}
@@ -236,8 +231,6 @@ class Zend_Feed_Reader_Extension_Atom_Feed
if (!$generator) {
$generator = null;
- } else {
- $generator = html_entity_decode($generator, ENT_QUOTES, $this->getEncoding());
}
$this->_data['generator'] = $generator;
@@ -245,7 +238,7 @@ class Zend_Feed_Reader_Extension_Atom_Feed
return $this->_data['generator'];
}
- /**
+ /**
* Get the feed ID
*
* @return string|null
@@ -298,7 +291,31 @@ class Zend_Feed_Reader_Extension_Atom_Feed
return $this->_data['language'];
}
-
+
+ /**
+ * Get the feed image
+ *
+ * @return array|null
+ */
+ public function getImage()
+ {
+ if (array_key_exists('image', $this->_data)) {
+ return $this->_data['image'];
+ }
+
+ $imageUrl = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:logo)');
+
+ if (!$imageUrl) {
+ $image = null;
+ } else {
+ $image = array('uri'=>$imageUrl);
+ }
+
+ $this->_data['image'] = $image;
+
+ return $this->_data['image'];
+ }
+
/**
* Get the base URI of the feed (if set).
*
@@ -332,12 +349,12 @@ class Zend_Feed_Reader_Extension_Atom_Feed
}
$link = null;
-
+
$list = $this->_xpath->query(
$this->getXpathPrefix() . '/atom:link[@rel="alternate"]/@href' . '|' .
$this->getXpathPrefix() . '/atom:link[not(@rel)]/@href'
);
-
+
if ($list->length) {
$link = $list->item(0)->nodeValue;
$link = $this->_absolutiseUri($link);
@@ -369,6 +386,34 @@ class Zend_Feed_Reader_Extension_Atom_Feed
}
/**
+ * Get an array of any supported Pusubhubbub endpoints
+ *
+ * @return array|null
+ */
+ public function getHubs()
+ {
+ if (array_key_exists('hubs', $this->_data)) {
+ return $this->_data['hubs'];
+ }
+ $hubs = array();
+
+ $list = $this->_xpath->query($this->getXpathPrefix()
+ . '//atom:link[@rel="hub"]/@href');
+
+ if ($list->length) {
+ foreach ($list as $uri) {
+ $hubs[] = $this->_absolutiseUri($uri->nodeValue);
+ }
+ } else {
+ $hubs = null;
+ }
+
+ $this->_data['hubs'] = $hubs;
+
+ return $this->_data['hubs'];
+ }
+
+ /**
* Get the feed title
*
* @return string|null
@@ -389,8 +434,49 @@ class Zend_Feed_Reader_Extension_Atom_Feed
return $this->_data['title'];
}
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
- /**
+ if ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10) {
+ $list = $this->_xpath->query($this->getXpathPrefix() . '/atom:category');
+ } else {
+ /**
+ * Since Atom 0.3 did not support categories, it would have used the
+ * Dublin Core extension. However there is a small possibility Atom 0.3
+ * may have been retrofittied to use Atom 1.0 instead.
+ */
+ $this->_xpath->registerNamespace('atom10', Zend_Feed_Reader::NAMESPACE_ATOM_10);
+ $list = $this->_xpath->query($this->getXpathPrefix() . '/atom10:category');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->getAttribute('term'),
+ 'scheme' => $category->getAttribute('scheme'),
+ 'label' => $category->getAttribute('label')
+ );
+ }
+ } else {
+ return new Zend_Feed_Reader_Collection_Category;
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
+
+ /**
* Get an author entry in RSS format
*
* @param DOMElement $element
@@ -398,37 +484,30 @@ class Zend_Feed_Reader_Extension_Atom_Feed
*/
protected function _getAuthor(DOMElement $element)
{
- $email = null;
- $name = null;
- $uri = null;
+ $author = array();
$emailNode = $element->getElementsByTagName('email');
$nameNode = $element->getElementsByTagName('name');
$uriNode = $element->getElementsByTagName('uri');
-
- if ($emailNode->length) {
- $email = $emailNode->item(0)->nodeValue;
+
+ if ($emailNode->length && strlen($emailNode->item(0)->nodeValue) > 0) {
+ $author['email'] = $emailNode->item(0)->nodeValue;
}
- if ($nameNode->length) {
- $name = $nameNode->item(0)->nodeValue;
+ if ($nameNode->length && strlen($nameNode->item(0)->nodeValue) > 0) {
+ $author['name'] = $nameNode->item(0)->nodeValue;
}
- if ($uriNode->length) {
- $uri = $uriNode->item(0)->nodeValue;
+ if ($uriNode->length && strlen($uriNode->item(0)->nodeValue) > 0) {
+ $author['uri'] = $uriNode->item(0)->nodeValue;
}
- if (!empty($email)) {
- return $email . (empty($name) ? '' : ' (' . $name . ')');
- } else if (!empty($name)) {
- return $name;
- } else if (!empty($uri)) {
- return $uri;
+ if (empty($author)) {
+ return null;
}
-
- return null;
+ return $author;
}
-
+
/**
* Attempt to absolutise the URI, i.e. if a relative URI apply the
* xml:base value as a prefix to turn into an absolute URI.
@@ -451,7 +530,7 @@ class Zend_Feed_Reader_Extension_Atom_Feed
*/
protected function _registerNamespaces()
{
- if ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10
+ if ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10
|| $this->getType() == Zend_Feed_Reader::TYPE_ATOM_03
) {
return; // pre-registered at Feed level
@@ -472,17 +551,16 @@ class Zend_Feed_Reader_Extension_Atom_Feed
*/
protected function _getAtomType()
{
- $nslist = $this->getDomDocument()->documentElement->attributes;
- if (!$nslist->length) {
- return null;
- }
- foreach ($nslist as $ns) {
- if ($ns->value == Zend_Feed_Reader::NAMESPACE_ATOM_10) {
- return Zend_Feed_Reader::TYPE_ATOM_10;
- }
- if ($ns->value == Zend_Feed_Reader::NAMESPACE_ATOM_03) {
- return Zend_Feed_Reader::TYPE_ATOM_03;
- }
+ $dom = $this->getDomDocument();
+ $prefixAtom03 = $dom->lookupPrefix(Zend_Feed_Reader::NAMESPACE_ATOM_03);
+ $prefixAtom10 = $dom->lookupPrefix(Zend_Feed_Reader::NAMESPACE_ATOM_10);
+ if ($dom->isDefaultNamespace(Zend_Feed_Reader::NAMESPACE_ATOM_10)
+ || !empty($prefixAtom10)) {
+ return Zend_Feed_Reader::TYPE_ATOM_10;
+ }
+ if ($dom->isDefaultNamespace(Zend_Feed_Reader::NAMESPACE_ATOM_03)
+ || !empty($prefixAtom03)) {
+ return Zend_Feed_Reader::TYPE_ATOM_03;
}
}
}
diff --git a/libs/Zend/Feed/Reader/Extension/Content/Entry.php b/libs/Zend/Feed/Reader/Extension/Content/Entry.php
index 7145281ecb..ca10f24a3b 100644
--- a/libs/Zend/Feed/Reader/Extension/Content/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/Content/Entry.php
@@ -14,43 +14,40 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Entry.php 22301 2010-05-26 10:15:13Z padraic $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Entry_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_Content_Entry
+class Zend_Feed_Reader_Extension_Content_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
public function getContent()
{
- if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10
&& $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090
) {
$content = $this->_xpath->evaluate('string('.$this->getXpathPrefix().'/content:encoded)');
} else {
$content = $this->_xpath->evaluate('string('.$this->getXpathPrefix().'/content:encoded)');
}
- if ($content) {
- $content = html_entity_decode($content, ENT_QUOTES, $this->getEncoding());
- }
return $content;
}
diff --git a/libs/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php b/libs/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
index b9830089d3..5e78db10ab 100644
--- a/libs/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
@@ -14,25 +14,25 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @see Zend_Feed_Reader_Extension_CreativeCommons_Feed
*/
-require_once 'Zend/Feed/Reader/Extension/CreativeCommons/Feed.php';
+// require_once 'Zend/Feed/Reader/Extension/CreativeCommons/Feed.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Extension_CreativeCommons_Entry extends Zend_Feed_Reader_Extension_EntryAbstract
diff --git a/libs/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php b/libs/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
index c3d0cd2d42..3d29c6911f 100644
--- a/libs/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
+++ b/libs/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
@@ -14,23 +14,23 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Feed.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_CreativeCommons_Feed
+class Zend_Feed_Reader_Extension_CreativeCommons_Feed
extends Zend_Feed_Reader_Extension_FeedAbstract
{
/**
diff --git a/libs/Zend/Feed/Reader/Extension/DublinCore/Entry.php b/libs/Zend/Feed/Reader/Extension/DublinCore/Entry.php
index 522e2c1498..4ad104b6ff 100644
--- a/libs/Zend/Feed/Reader/Extension/DublinCore/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/DublinCore/Entry.php
@@ -14,33 +14,33 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16711 2009-07-14 16:10:54Z matthew $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_DublinCore_Entry
+class Zend_Feed_Reader_Extension_DublinCore_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
/**
@@ -87,22 +87,56 @@ class Zend_Feed_Reader_Extension_DublinCore_Entry
if ($list->length) {
foreach ($list as $author) {
- if ($this->getType() == Zend_Feed_Reader::TYPE_RSS_20
- && preg_match("/\(([^\)]+)\)/", $author->nodeValue, $matches, PREG_OFFSET_CAPTURE)
- ) {
- $authors[] = $matches[1][0];
- } else {
- $authors[] = $author->nodeValue;
- }
+ $authors[] = array(
+ 'name' => $author->nodeValue
+ );
}
-
- $authors = array_unique($authors);
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
+ } else {
+ $authors = null;
}
$this->_data['authors'] = $authors;
return $this->_data['authors'];
}
+
+ /**
+ * Get categories (subjects under DC)
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ $list = $this->_xpath->evaluate($this->getXpathPrefix() . '//dc11:subject');
+
+ if (!$list->length) {
+ $list = $this->_xpath->evaluate($this->getXpathPrefix() . '//dc10:subject');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->nodeValue,
+ 'scheme' => null,
+ 'label' => $category->nodeValue,
+ );
+ }
+ } else {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+ return $this->_data['categories'];
+ }
+
/**
* Get the entry content
diff --git a/libs/Zend/Feed/Reader/Extension/DublinCore/Feed.php b/libs/Zend/Feed/Reader/Extension/DublinCore/Feed.php
index 68078578b2..4e4bcf4888 100644
--- a/libs/Zend/Feed/Reader/Extension/DublinCore/Feed.php
+++ b/libs/Zend/Feed/Reader/Extension/DublinCore/Feed.php
@@ -14,31 +14,36 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Feed.php 16711 2009-07-14 16:10:54Z matthew $
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Feed_Reader_Collection_Author
+ */
+// require_once 'Zend/Feed/Reader/Collection/Author.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_DublinCore_Feed
+class Zend_Feed_Reader_Extension_DublinCore_Feed
extends Zend_Feed_Reader_Extension_FeedAbstract
{
- /**
+ /**
* Get a single author
*
* @param int $index
@@ -79,13 +84,18 @@ class Zend_Feed_Reader_Extension_DublinCore_Feed
$list = $this->_xpath->query('//dc10:publisher');
}
}
-
- foreach ($list as $authorObj) {
- $authors[] = $authorObj->nodeValue;
- }
-
- if (!empty($authors)) {
- $authors = array_unique($authors);
+
+ if ($list->length) {
+ foreach ($list as $author) {
+ $authors[] = array(
+ 'name' => $author->nodeValue
+ );
+ }
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
+ } else {
+ $authors = null;
}
$this->_data['authors'] = $authors;
@@ -251,6 +261,40 @@ class Zend_Feed_Reader_Extension_DublinCore_Feed
return $this->_data['date'];
}
+
+ /**
+ * Get categories (subjects under DC)
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ $list = $this->_xpath->evaluate($this->getXpathPrefix() . '//dc11:subject');
+
+ if (!$list->length) {
+ $list = $this->_xpath->evaluate($this->getXpathPrefix() . '//dc10:subject');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->nodeValue,
+ 'scheme' => null,
+ 'label' => $category->nodeValue,
+ );
+ }
+ } else {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+ return $this->_data['categories'];
+ }
/**
* Register the default namespaces for the current feed format
diff --git a/libs/Zend/Feed/Reader/Extension/EntryAbstract.php b/libs/Zend/Feed/Reader/Extension/EntryAbstract.php
index 68ae193cf7..299c1bfbaf 100644
--- a/libs/Zend/Feed/Reader/Extension/EntryAbstract.php
+++ b/libs/Zend/Feed/Reader/Extension/EntryAbstract.php
@@ -14,15 +14,15 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: EntryAbstract.php 16711 2009-07-14 16:10:54Z matthew $
+ * @version $Id: EntryAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Reader_Extension_EntryAbstract
@@ -86,14 +86,14 @@ abstract class Zend_Feed_Reader_Extension_EntryAbstract
if (!is_null($type)) {
$this->_data['type'] = $type;
} else {
- $this->_data['type'] = Zend_Feed_Reader::detectType($feed);
+ $this->_data['type'] = Zend_Feed_Reader::detectType($entry->ownerDocument, true);
}
// set the XPath query prefix for the entry being queried
- if ($this->getType() == Zend_Feed_Reader::TYPE_RSS_10
+ if ($this->getType() == Zend_Feed_Reader::TYPE_RSS_10
|| $this->getType() == Zend_Feed_Reader::TYPE_RSS_090
) {
$this->setXpathPrefix('//rss:item[' . ($this->_entryKey+1) . ']');
- } elseif ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10
+ } elseif ($this->getType() == Zend_Feed_Reader::TYPE_ATOM_10
|| $this->getType() == Zend_Feed_Reader::TYPE_ATOM_03
) {
$this->setXpathPrefix('//atom:entry[' . ($this->_entryKey+1) . ']');
@@ -123,7 +123,7 @@ abstract class Zend_Feed_Reader_Extension_EntryAbstract
return $assumed;
}
- /**
+ /**
* Get the entry type
*
* @return string
@@ -153,6 +153,9 @@ abstract class Zend_Feed_Reader_Extension_EntryAbstract
*/
public function getXpath()
{
+ if (!$this->_xpath) {
+ $this->setXpath(new DOMXPath($this->getDomDocument()));
+ }
return $this->_xpath;
}
@@ -178,8 +181,8 @@ abstract class Zend_Feed_Reader_Extension_EntryAbstract
/**
* Set the XPath prefix
- *
- * @param string $prefix
+ *
+ * @param string $prefix
* @return Zend_Feed_Reader_Extension_EntryAbstract
*/
public function setXpathPrefix($prefix)
@@ -190,7 +193,7 @@ abstract class Zend_Feed_Reader_Extension_EntryAbstract
/**
* Register XML namespaces
- *
+ *
* @return void
*/
protected abstract function _registerNamespaces();
diff --git a/libs/Zend/Feed/Reader/Extension/FeedAbstract.php b/libs/Zend/Feed/Reader/Extension/FeedAbstract.php
index 973dd81197..23d97d3f7a 100644
--- a/libs/Zend/Feed/Reader/Extension/FeedAbstract.php
+++ b/libs/Zend/Feed/Reader/Extension/FeedAbstract.php
@@ -14,36 +14,36 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: FeedAbstract.php 16711 2009-07-14 16:10:54Z matthew $
+ * @version $Id: FeedAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Entry_Atom
*/
-require_once 'Zend/Feed/Reader/Entry/Atom.php';
+// require_once 'Zend/Feed/Reader/Entry/Atom.php';
/**
* @see Zend_Feed_Reader_Entry_Rss
*/
-require_once 'Zend/Feed/Reader/Entry/Rss.php';
+// require_once 'Zend/Feed/Reader/Entry/Rss.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Reader_Extension_FeedAbstract
{
- /**
+ /**
* Parsed feed data
*
* @var array
@@ -139,10 +139,33 @@ abstract class Zend_Feed_Reader_Extension_FeedAbstract
return $this->_data;
}
- /**
+ /**
+ * Set the XPath query
+ *
+ * @param DOMXPath $xpath
+ * @return Zend_Feed_Reader_Extension_EntryAbstract
+ */
+ public function setXpath(DOMXPath $xpath)
+ {
+ $this->_xpath = $xpath;
+ $this->_registerNamespaces();
+ return $this;
+ }
+
+ /**
+ * Get the DOMXPath object
+ *
+ * @return string
+ */
+ public function getXpath()
+ {
+ return $this->_xpath;
+ }
+
+ /**
* Get the XPath prefix
- *
- * @return string
+ *
+ * @return string
*/
public function getXpathPrefix()
{
diff --git a/libs/Zend/Feed/Reader/Extension/Podcast/Entry.php b/libs/Zend/Feed/Reader/Extension/Podcast/Entry.php
index 7af2285421..bbe340ce63 100644
--- a/libs/Zend/Feed/Reader/Extension/Podcast/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/Podcast/Entry.php
@@ -14,25 +14,25 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16792 2009-07-17 02:52:37Z norm2782 $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Extension_Podcast_Entry extends Zend_Feed_Reader_Extension_EntryAbstract
diff --git a/libs/Zend/Feed/Reader/Extension/Podcast/Feed.php b/libs/Zend/Feed/Reader/Extension/Podcast/Feed.php
index b213d34590..c4ea180f7c 100644
--- a/libs/Zend/Feed/Reader/Extension/Podcast/Feed.php
+++ b/libs/Zend/Feed/Reader/Extension/Podcast/Feed.php
@@ -14,20 +14,20 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Feed.php 16792 2009-07-17 02:52:37Z norm2782 $
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Extension_Podcast_Feed extends Zend_Feed_Reader_Extension_FeedAbstract
diff --git a/libs/Zend/Feed/Reader/Extension/Slash/Entry.php b/libs/Zend/Feed/Reader/Extension/Slash/Entry.php
index b2aa12457b..222c0e1062 100644
--- a/libs/Zend/Feed/Reader/Extension/Slash/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/Slash/Entry.php
@@ -14,28 +14,28 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_Slash_Entry
+class Zend_Feed_Reader_Extension_Slash_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
/**
diff --git a/libs/Zend/Feed/Reader/Extension/Syndication/Feed.php b/libs/Zend/Feed/Reader/Extension/Syndication/Feed.php
index bd205bcf61..5b383cfedb 100644
--- a/libs/Zend/Feed/Reader/Extension/Syndication/Feed.php
+++ b/libs/Zend/Feed/Reader/Extension/Syndication/Feed.php
@@ -14,25 +14,25 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Feed.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_Syndication_Feed
+class Zend_Feed_Reader_Extension_Syndication_Feed
extends Zend_Feed_Reader_Extension_FeedAbstract
{
/**
@@ -57,7 +57,7 @@ class Zend_Feed_Reader_Extension_Syndication_Feed
case 'yearly':
return $period;
default:
- throw new Zend_Feed_Exception("Feed specified invalid update period: '$period'."
+ throw new Zend_Feed_Exception("Feed specified invalid update period: '$period'."
. " Must be one of hourly, daily, weekly or yearly"
);
}
@@ -100,13 +100,13 @@ class Zend_Feed_Reader_Extension_Syndication_Feed
switch ($period)
{
//intentional fall through
- case 'yearly':
+ case 'yearly':
$ticks *= 52; //TODO: fix generalisation, how?
- case 'weekly':
+ case 'weekly':
$ticks *= 7;
- case 'daily':
+ case 'daily':
$ticks *= 24;
- case 'hourly':
+ case 'hourly':
$ticks *= 3600;
break;
default: //Never arrive here, exception thrown in getPeriod()
diff --git a/libs/Zend/Feed/Reader/Extension/Thread/Entry.php b/libs/Zend/Feed/Reader/Extension/Thread/Entry.php
index c8b632726c..e8a4bde92f 100644
--- a/libs/Zend/Feed/Reader/Extension/Thread/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/Thread/Entry.php
@@ -14,28 +14,28 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_Thread_Entry
+class Zend_Feed_Reader_Extension_Thread_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
/**
* Get the "in-reply-to" value
- *
+ *
* @return string
*/
public function getInReplyTo()
diff --git a/libs/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php b/libs/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
index 8c96f6e316..fe47448338 100644
--- a/libs/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
+++ b/libs/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
@@ -14,28 +14,28 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Entry.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_Feed_Reader_Extension_EntryAbstract
*/
-require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
+// require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-class Zend_Feed_Reader_Extension_WellFormedWeb_Entry
+class Zend_Feed_Reader_Extension_WellFormedWeb_Entry
extends Zend_Feed_Reader_Extension_EntryAbstract
{
/**
diff --git a/libs/Zend/Feed/Reader/Feed/Atom.php b/libs/Zend/Feed/Reader/Feed/Atom.php
index 0256e36122..8199355995 100644
--- a/libs/Zend/Feed/Reader/Feed/Atom.php
+++ b/libs/Zend/Feed/Reader/Feed/Atom.php
@@ -14,25 +14,25 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Atom.php 18655 2009-10-20 14:17:39Z padraic $
+ * @version $Id: Atom.php 22108 2010-05-05 13:44:11Z padraic $
*/
/**
* @see Zend_Feed_Reader_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/FeedAbstract.php';
/**
* @see Zend_Feed_Reader_Extension_Atom_Feed
*/
-require_once 'Zend/Feed/Reader/Extension/Atom/Feed.php';
+// require_once 'Zend/Feed/Reader/Extension/Atom/Feed.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
@@ -41,15 +41,16 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
/**
* Constructor
*
- * @param Zend_Feed_Abstract $feed
+ * @param DOMDocument $dom
* @param string $type
- * @param string $xpath
*/
- public function __construct(DomDocument $dom, $type = null)
+ public function __construct(DOMDocument $dom, $type = null)
{
parent::__construct($dom, $type);
$atomClass = Zend_Feed_Reader::getPluginLoader()->getClassName('Atom_Feed');
$this->_extensions['Atom_Feed'] = new $atomClass($dom, $this->_data['type'], $this->_xpath);
+ $atomClass = Zend_Feed_Reader::getPluginLoader()->getClassName('DublinCore_Feed');
+ $this->_extensions['DublinCore_Feed'] = new $atomClass($dom, $this->_data['type'], $this->_xpath);
foreach ($this->_extensions as $extension) {
$extension->setXpathPrefix('/atom:feed');
}
@@ -83,9 +84,9 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
return $this->_data['authors'];
}
- $people = $this->getExtension('Atom')->getAuthors();
+ $authors = $this->getExtension('Atom')->getAuthors();
- $this->_data['authors'] = $people;
+ $this->_data['authors'] = $authors;
return $this->_data['authors'];
}
@@ -157,6 +158,16 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
}
/**
+ * Get the feed lastBuild date. This is not implemented in Atom.
+ *
+ * @return string|null
+ */
+ public function getLastBuildDate()
+ {
+ return null;
+ }
+
+ /**
* Get the feed description
*
* @return string|null
@@ -196,7 +207,7 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
return $this->_data['generator'];
}
- /**
+ /**
* Get the feed ID
*
* @return string|null
@@ -239,7 +250,7 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
return $this->_data['language'];
}
-
+
/**
* Get a link to the source website
*
@@ -277,6 +288,24 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
}
/**
+ * Get feed image data
+ *
+ * @return array|null
+ */
+ public function getImage()
+ {
+ if (array_key_exists('image', $this->_data)) {
+ return $this->_data['image'];
+ }
+
+ $link = $this->getExtension('Atom')->getImage();
+
+ $this->_data['image'] = $link;
+
+ return $this->_data['image'];
+ }
+
+ /**
* Get a link to the feed's XML Url
*
* @return string|null
@@ -289,6 +318,10 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
$link = $this->getExtension('Atom')->getFeedLink();
+ if (is_null($link) || empty($link)) {
+ $link = $this->getOriginalSourceUri();
+ }
+
$this->_data['feedlink'] = $link;
return $this->_data['feedlink'];
@@ -312,9 +345,50 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
return $this->_data['title'];
}
- /**
+ /**
+ * Get an array of any supported Pusubhubbub endpoints
+ *
+ * @return array|null
+ */
+ public function getHubs()
+ {
+ if (array_key_exists('hubs', $this->_data)) {
+ return $this->_data['hubs'];
+ }
+
+ $hubs = $this->getExtension('Atom')->getHubs();
+
+ $this->_data['hubs'] = $hubs;
+
+ return $this->_data['hubs'];
+ }
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ $categoryCollection = $this->getExtension('Atom')->getCategories();
+
+ if (count($categoryCollection) == 0) {
+ $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
+
+ /**
* Read all entries to the internal entries array
*
+ * @return void
*/
protected function _indexEntries()
{
diff --git a/libs/Zend/Feed/Reader/Feed/Atom/Source.php b/libs/Zend/Feed/Reader/Feed/Atom/Source.php
new file mode 100644
index 0000000000..bdd972f93e
--- /dev/null
+++ b/libs/Zend/Feed/Reader/Feed/Atom/Source.php
@@ -0,0 +1,102 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 19165 2009-11-21 16:46:40Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Reader_Feed_Atom
+ */
+// require_once 'Zend/Feed/Reader/Feed/Atom.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Reader_Feed_Atom_Source extends Zend_Feed_Reader_Feed_Atom
+{
+
+ /**
+ * Constructor: Create a Source object which is largely just a normal
+ * Zend_Feed_Reader_FeedAbstract object only designed to retrieve feed level
+ * metadata from an Atom entry's source element.
+ *
+ * @param DOMElement $source
+ * @param string $xpathPrefix Passed from parent Entry object
+ * @param string $type Nearly always Atom 1.0
+ */
+ public function __construct(DOMElement $source, $xpathPrefix, $type = Zend_Feed_Reader::TYPE_ATOM_10)
+ {
+ $this->_domDocument = $source->ownerDocument;
+ $this->_xpath = new DOMXPath($this->_domDocument);
+ $this->_data['type'] = $type;
+ $this->_registerNamespaces();
+ $this->_loadExtensions();
+
+ $atomClass = Zend_Feed_Reader::getPluginLoader()->getClassName('Atom_Feed');
+ $this->_extensions['Atom_Feed'] = new $atomClass($this->_domDocument, $this->_data['type'], $this->_xpath);
+ $atomClass = Zend_Feed_Reader::getPluginLoader()->getClassName('DublinCore_Feed');
+ $this->_extensions['DublinCore_Feed'] = new $atomClass($this->_domDocument, $this->_data['type'], $this->_xpath);
+ foreach ($this->_extensions as $extension) {
+ $extension->setXpathPrefix(rtrim($xpathPrefix, '/') . '/atom:source');
+ }
+ }
+
+ /**
+ * Since this is not an Entry carrier but a vehicle for Feed metadata, any
+ * applicable Entry methods are stubbed out and do nothing.
+ */
+
+ /**
+ * @return void
+ */
+ public function count() {}
+
+ /**
+ * @return void
+ */
+ public function current() {}
+
+ /**
+ * @return void
+ */
+ public function key() {}
+
+ /**
+ * @return void
+ */
+ public function next() {}
+
+ /**
+ * @return void
+ */
+ public function rewind() {}
+
+ /**
+ * @return void
+ */
+ public function valid() {}
+
+ /**
+ * @return void
+ */
+ protected function _indexEntries() {}
+
+}
diff --git a/libs/Zend/Feed/Reader/Feed/Rss.php b/libs/Zend/Feed/Reader/Feed/Rss.php
index 2dc2ec86f4..bff78c3455 100644
--- a/libs/Zend/Feed/Reader/Feed/Rss.php
+++ b/libs/Zend/Feed/Reader/Feed/Rss.php
@@ -14,35 +14,40 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Rss.php 18367 2009-09-22 14:55:59Z padraic $
+ * @version $Id: Rss.php 22301 2010-05-26 10:15:13Z padraic $
*/
/**
* @see Zend_Feed_Reader_FeedAbstract
*/
-require_once 'Zend/Feed/Reader/FeedAbstract.php';
+// require_once 'Zend/Feed/Reader/FeedAbstract.php';
/**
* @see Zend_feed_Reader_Extension_Atom_Feed
*/
-require_once 'Zend/Feed/Reader/Extension/Atom/Feed.php';
+// require_once 'Zend/Feed/Reader/Extension/Atom/Feed.php';
/**
* @see Zend_Feed_Reader_Extension_DublinCore_Feed
*/
-require_once 'Zend/Feed/Reader/Extension/DublinCore/Feed.php';
+// require_once 'Zend/Feed/Reader/Extension/DublinCore/Feed.php';
/**
* @see Zend_Date
*/
-require_once 'Zend/Date.php';
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Feed_Reader_Collection_Author
+ */
+// require_once 'Zend/Feed/Reader/Collection/Author.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
@@ -51,9 +56,8 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
/**
* Constructor
*
- * @param Zend_Feed_Abstract $feed
+ * @param DOMDocument $dom
* @param string $type
- * @param string $xpath
*/
public function __construct(DomDocument $dom, $type = null)
{
@@ -74,7 +78,7 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
}
}
- /**
+ /**
* Get a single author
*
* @param int $index
@@ -101,33 +105,54 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
if (array_key_exists('authors', $this->_data)) {
return $this->_data['authors'];
}
-
+
$authors = array();
-
- if (empty($authors)) {
- $authors = $this->getExtension('DublinCore')->getAuthors();
- }
-
- if (empty($authors)) {
- if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
- $list = $this->_xpath->query('//author');
- } else {
- $list = $this->_xpath->query('//rss:author');
+ $authors_dc = $this->getExtension('DublinCore')->getAuthors();
+ if (!empty($authors_dc)) {
+ foreach ($authors_dc as $author) {
+ $authors[] = array(
+ 'name' => $author['name']
+ );
}
+ }
- foreach ($list as $authorObj) {
- $authors[] = $authorObj->nodeValue;
+ /**
+ * Technically RSS doesn't specific author element use at the feed level
+ * but it's supported on a "just in case" basis.
+ */
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10
+ && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $list = $this->_xpath->query('//author');
+ } else {
+ $list = $this->_xpath->query('//rss:author');
+ }
+ if ($list->length) {
+ foreach ($list as $author) {
+ $string = trim($author->nodeValue);
+ $email = null;
+ $name = null;
+ $data = array();
+ // Pretty rough parsing - but it's a catchall
+ if (preg_match("/^.*@[^ ]*/", $string, $matches)) {
+ $data['email'] = trim($matches[0]);
+ if (preg_match("/\((.*)\)$/", $string, $matches)) {
+ $data['name'] = $matches[1];
+ }
+ $authors[] = $data;
+ }
}
}
- if (empty($authors)) {
+ if (count($authors) == 0) {
$authors = $this->getExtension('Atom')->getAuthors();
+ } else {
+ $authors = new Zend_Feed_Reader_Collection_Author(
+ Zend_Feed_Reader::arrayUnique($authors)
+ );
}
- if (empty($authors)) {
+ if (count($authors) == 0) {
$authors = null;
- } else {
- $authors = array_unique($authors);
}
$this->_data['authors'] = $authors;
@@ -170,7 +195,7 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
return $this->_data['copyright'];
}
- /**
+ /**
* Get the feed creation date
*
* @return string|null
@@ -201,21 +226,27 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
$dateModified = $this->_xpath->evaluate('string(/rss/channel/lastBuildDate)');
}
if ($dateModified) {
- $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822,
- Zend_Date::RFC_2822, Zend_Date::DATES);
- $date = new Zend_Date;
- foreach ($dateStandards as $standard) {
- try {
- $date->set($dateModified, $standard);
- break;
- } catch (Zend_Date_Exception $e) {
- if ($standard == Zend_Date::DATES) {
- require_once 'Zend/Feed/Exception.php';
- throw new Zend_Feed_Exception(
- 'Could not load date due to unrecognised'
- .' format (should follow RFC 822 or 2822):'
- . $e->getMessage()
- );
+ $dateModifiedParsed = strtotime($dateModified);
+ if ($dateModifiedParsed) {
+ $date = new Zend_Date($dateModifiedParsed);
+ } else {
+ $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822,
+ Zend_Date::RFC_2822, Zend_Date::DATES);
+ $date = new Zend_Date;
+ foreach ($dateStandards as $standard) {
+ try {
+ $date->set($dateModified, $standard);
+ break;
+ } catch (Zend_Date_Exception $e) {
+ if ($standard == Zend_Date::DATES) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception(
+ 'Could not load date due to unrecognised'
+ .' format (should follow RFC 822 or 2822):'
+ . $e->getMessage(),
+ 0, $e
+ );
+ }
}
}
}
@@ -240,6 +271,60 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
}
/**
+ * Get the feed lastBuild date
+ *
+ * @return Zend_Date
+ */
+ public function getLastBuildDate()
+ {
+ if (array_key_exists('lastBuildDate', $this->_data)) {
+ return $this->_data['lastBuildDate'];
+ }
+
+ $lastBuildDate = null;
+ $date = null;
+
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
+ $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $lastBuildDate = $this->_xpath->evaluate('string(/rss/channel/lastBuildDate)');
+ if ($lastBuildDate) {
+ $lastBuildDateParsed = strtotime($lastBuildDate);
+ if ($lastBuildDateParsed) {
+ $date = new Zend_Date($lastBuildDateParsed);
+ } else {
+ $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822,
+ Zend_Date::RFC_2822, Zend_Date::DATES);
+ $date = new Zend_Date;
+ foreach ($dateStandards as $standard) {
+ try {
+ $date->set($lastBuildDate, $standard);
+ break;
+ } catch (Zend_Date_Exception $e) {
+ if ($standard == Zend_Date::DATES) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception(
+ 'Could not load date due to unrecognised'
+ .' format (should follow RFC 822 or 2822):'
+ . $e->getMessage(),
+ 0, $e
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!$date) {
+ $date = null;
+ }
+
+ $this->_data['lastBuildDate'] = $date;
+
+ return $this->_data['lastBuildDate'];
+ }
+
+ /**
* Get the feed description
*
* @return string|null
@@ -318,6 +403,60 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
}
/**
+ * Get the feed image data
+ *
+ * @return array|null
+ */
+ public function getImage()
+ {
+ if (array_key_exists('image', $this->_data)) {
+ return $this->_data['image'];
+ }
+
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
+ $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $list = $this->_xpath->query('/rss/channel/image');
+ $prefix = '/rss/channel/image[1]';
+ } else {
+ $list = $this->_xpath->query('/rdf:RDF/rss:channel/rss:image');
+ $prefix = '/rdf:RDF/rss:channel/rss:image[1]';
+ }
+ if ($list->length > 0) {
+ $image = array();
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/url)');
+ if ($value) {
+ $image['uri'] = $value;
+ }
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/link)');
+ if ($value) {
+ $image['link'] = $value;
+ }
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/title)');
+ if ($value) {
+ $image['title'] = $value;
+ }
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/height)');
+ if ($value) {
+ $image['height'] = $value;
+ }
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/width)');
+ if ($value) {
+ $image['width'] = $value;
+ }
+ $value = $this->_xpath->evaluate('string(' . $prefix . '/description)');
+ if ($value) {
+ $image['description'] = $value;
+ }
+ } else {
+ $image = null;
+ }
+
+ $this->_data['image'] = $image;
+
+ return $this->_data['image'];
+ }
+
+ /**
* Get the feed language
*
* @return string|null
@@ -404,8 +543,8 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
$link = $this->getExtension('Atom')->getFeedLink();
- if (!$link) {
- $link = null;
+ if (is_null($link) || empty($link)) {
+ $link = $this->getOriginalSourceUri();
}
$this->_data['feedlink'] = $link;
@@ -438,9 +577,6 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
} else {
$generator = $this->_xpath->evaluate('string(/rdf:RDF/rss:channel/atom:generator)');
}
- if ($generator) {
- $generator = html_entity_decode($generator, ENT_QUOTES, $this->getEncoding());
- }
}
if (empty($generator)) {
@@ -493,7 +629,71 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
return $this->_data['title'];
}
- /**
+ /**
+ * Get an array of any supported Pusubhubbub endpoints
+ *
+ * @return array|null
+ */
+ public function getHubs()
+ {
+ if (array_key_exists('hubs', $this->_data)) {
+ return $this->_data['hubs'];
+ }
+
+ $hubs = $this->getExtension('Atom')->getHubs();
+
+ if (empty($hubs)) {
+ $hubs = null;
+ } else {
+ $hubs = array_unique($hubs);
+ }
+
+ $this->_data['hubs'] = $hubs;
+
+ return $this->_data['hubs'];
+ }
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories()
+ {
+ if (array_key_exists('categories', $this->_data)) {
+ return $this->_data['categories'];
+ }
+
+ if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
+ $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+ $list = $this->_xpath->query('/rss/channel//category');
+ } else {
+ $list = $this->_xpath->query('/rdf:RDF/rss:channel//rss:category');
+ }
+
+ if ($list->length) {
+ $categoryCollection = new Zend_Feed_Reader_Collection_Category;
+ foreach ($list as $category) {
+ $categoryCollection[] = array(
+ 'term' => $category->nodeValue,
+ 'scheme' => $category->getAttribute('domain'),
+ 'label' => $category->nodeValue,
+ );
+ }
+ } else {
+ $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+ }
+
+ if (count($categoryCollection) == 0) {
+ $categoryCollection = $this->getExtension('Atom')->getCategories();
+ }
+
+ $this->_data['categories'] = $categoryCollection;
+
+ return $this->_data['categories'];
+ }
+
+ /**
* Read all entries to the internal entries array
*
*/
diff --git a/libs/Zend/Feed/Reader/FeedAbstract.php b/libs/Zend/Feed/Reader/FeedAbstract.php
index 1e8da71726..bda9f23b46 100644
--- a/libs/Zend/Feed/Reader/FeedAbstract.php
+++ b/libs/Zend/Feed/Reader/FeedAbstract.php
@@ -14,41 +14,30 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: FeedAbstract.php 16966 2009-07-22 15:22:18Z padraic $
+ * @version $Id: FeedAbstract.php 22093 2010-05-04 12:55:06Z padraic $
*/
/**
* @see Zend_Feed_Reader
*/
-require_once 'Zend/Feed/Reader.php';
-
-/**
- * @see Zend_Feed_Reader_Entry_Atom
- */
-require_once 'Zend/Feed/Reader/Entry/Atom.php';
-
-
-/**
- * @see Zend_Feed_Reader_Entry_Rss
- */
-require_once 'Zend/Feed/Reader/Entry/Rss.php';
+// require_once 'Zend/Feed/Reader.php';
/**
* @see Zend_feed_Reader_FeedInterface
*/
-require_once 'Zend/Feed/Reader/FeedInterface.php';
+// require_once 'Zend/Feed/Reader/FeedInterface.php';
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInterface
{
- /**
+ /**
* Parsed feed data
*
* @var array
@@ -83,9 +72,21 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
*/
protected $_xpath = null;
+ /**
+ * Array of loaded extensions
+ *
+ * @var array
+ */
protected $_extensions = array();
/**
+ * Original Source URI (set if imported from a URI)
+ *
+ * @var string
+ */
+ protected $_originalSourceUri = null;
+
+ /**
* Constructor
*
* @param DomDocument The DOM object for the feed's XML
@@ -106,7 +107,30 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
$this->_loadExtensions();
}
- /**
+ /**
+ * Set an original source URI for the feed being parsed. This value
+ * is returned from getFeedLink() method if the feed does not carry
+ * a self-referencing URI.
+ *
+ * @param string $uri
+ */
+ public function setOriginalSourceUri($uri)
+ {
+ $this->_originalSourceUri = $uri;
+ }
+
+ /**
+ * Get an original source URI for the feed being parsed. Returns null if
+ * unset or the feed was not imported from a URI.
+ *
+ * @return string|null
+ */
+ public function getOriginalSourceUri()
+ {
+ return $this->_originalSourceUri;
+ }
+
+ /**
* Get the number of feed entries.
* Required by the Iterator interface.
*
@@ -117,10 +141,10 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
return count($this->_entries);
}
- /**
+ /**
* Return the current entry
*
- * @return Zend_Feed_Reader_Entry_Interface
+ * @return Zend_Feed_Reader_EntryInterface
*/
public function current()
{
@@ -153,6 +177,9 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
public function getEncoding()
{
$assumed = $this->getDomDocument()->encoding;
+ if (empty($assumed)) {
+ $assumed = 'UTF-8';
+ }
return $assumed;
}
@@ -196,7 +223,7 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
return $this->_data['type'];
}
- /**
+ /**
* Return the current feed key
*
* @return unknown
@@ -206,7 +233,7 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
return $this->_entriesKey;
}
- /**
+ /**
* Move the feed pointer forward
*
*/
@@ -225,16 +252,6 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
}
/**
- * Return the feed as an array
- *
- * @return array
- */
- public function toArray() // untested
- {
- return $this->_data;
- }
-
- /**
* Check to see if the iterator is still valid
*
* @return boolean
@@ -256,7 +273,7 @@ abstract class Zend_Feed_Reader_FeedAbstract implements Zend_Feed_Reader_FeedInt
return call_user_func_array(array($extension, $method), $args);
}
}
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Method: ' . $method
. 'does not exist and could not be located on a registered Extension');
}
diff --git a/libs/Zend/Feed/Reader/FeedInterface.php b/libs/Zend/Feed/Reader/FeedInterface.php
index 3278f3ea75..35060bafce 100644
--- a/libs/Zend/Feed/Reader/FeedInterface.php
+++ b/libs/Zend/Feed/Reader/FeedInterface.php
@@ -14,15 +14,15 @@
*
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: FeedInterface.php 16953 2009-07-22 11:57:25Z padraic $
+ * @version $Id: FeedInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @category Zend
* @package Zend_Feed_Reader
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Feed_Reader_FeedInterface extends Iterator, Countable
@@ -111,5 +111,12 @@ interface Zend_Feed_Reader_FeedInterface extends Iterator, Countable
* @return string|null
*/
public function getTitle();
+
+ /**
+ * Get all categories
+ *
+ * @return Zend_Feed_Reader_Collection_Category
+ */
+ public function getCategories();
}
diff --git a/libs/Zend/Feed/Reader/FeedSet.php b/libs/Zend/Feed/Reader/FeedSet.php
new file mode 100644
index 0000000000..57ccbf6056
--- /dev/null
+++ b/libs/Zend/Feed/Reader/FeedSet.php
@@ -0,0 +1,148 @@
+<?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_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: FeedSet.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Feed_Reader
+ */
+// require_once 'Zend/Feed/Reader.php';
+
+/**
+ * @see Zend_Uri
+ */
+// require_once 'Zend/Uri.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Reader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Reader_FeedSet extends ArrayObject
+{
+
+ public $rss = null;
+
+ public $rdf = null;
+
+ public $atom = null;
+
+ /**
+ * Import a DOMNodeList from any document containing a set of links
+ * for alternate versions of a document, which will normally refer to
+ * RSS/RDF/Atom feeds for the current document.
+ *
+ * All such links are stored internally, however the first instance of
+ * each RSS, RDF or Atom type has its URI stored as a public property
+ * as a shortcut where the use case is simply to get a quick feed ref.
+ *
+ * Note that feeds are not loaded at this point, but will be lazy
+ * loaded automatically when each links 'feed' array key is accessed.
+ *
+ * @param DOMNodeList $links
+ * @param string $uri
+ * @return void
+ */
+ public function addLinks(DOMNodeList $links, $uri)
+ {
+ foreach ($links as $link) {
+ if (strtolower($link->getAttribute('rel')) !== 'alternate'
+ || !$link->getAttribute('type') || !$link->getAttribute('href')) {
+ continue;
+ }
+ if (!isset($this->rss) && $link->getAttribute('type') == 'application/rss+xml') {
+ $this->rss = $this->_absolutiseUri(trim($link->getAttribute('href')), $uri);
+ } elseif(!isset($this->atom) && $link->getAttribute('type') == 'application/atom+xml') {
+ $this->atom = $this->_absolutiseUri(trim($link->getAttribute('href')), $uri);
+ } elseif(!isset($this->rdf) && $link->getAttribute('type') == 'application/rdf+xml') {
+ $this->rdf = $this->_absolutiseUri(trim($link->getAttribute('href')), $uri);
+ }
+ $this[] = new self(array(
+ 'rel' => 'alternate',
+ 'type' => $link->getAttribute('type'),
+ 'href' => $this->_absolutiseUri(trim($link->getAttribute('href')), $uri),
+ ));
+ }
+ }
+
+ /**
+ * Attempt to turn a relative URI into an absolute URI
+ */
+ protected function _absolutiseUri($link, $uri = null)
+ {
+ if (!Zend_Uri::check($link)) {
+ if (!is_null($uri)) {
+ $uri = Zend_Uri::factory($uri);
+
+ if ($link[0] !== '/') {
+ $link = $uri->getPath() . '/' . $link;
+ }
+
+ $link = $uri->getScheme() . '://' . $uri->getHost() . '/' . $this->_canonicalizePath($link);
+ if (!Zend_Uri::check($link)) {
+ $link = null;
+ }
+ }
+ }
+ return $link;
+ }
+
+ /**
+ * Canonicalize relative path
+ */
+ protected function _canonicalizePath($path)
+ {
+ $parts = array_filter(explode('/', $path));
+ $absolutes = array();
+ foreach ($parts as $part) {
+ if ('.' == $part) {
+ continue;
+ }
+ if ('..' == $part) {
+ array_pop($absolutes);
+ } else {
+ $absolutes[] = $part;
+ }
+ }
+ return implode('/', $absolutes);
+ }
+
+ /**
+ * Supports lazy loading of feeds using Zend_Feed_Reader::import() but
+ * delegates any other operations to the parent class.
+ *
+ * @param string $offset
+ * @return mixed
+ * @uses Zend_Feed_Reader
+ */
+ public function offsetGet($offset)
+ {
+ if ($offset == 'feed' && !$this->offsetExists('feed')) {
+ if (!$this->offsetExists('href')) {
+ return null;
+ }
+ $feed = Zend_Feed_Reader::import($this->offsetGet('href'));
+ $this->offsetSet('feed', $feed);
+ return $feed;
+ }
+ return parent::offsetGet($offset);
+ }
+
+}
diff --git a/libs/Zend/Feed/Rss.php b/libs/Zend/Feed/Rss.php
index 351dcdf2e5..19eaa8ec19 100644
--- a/libs/Zend/Feed/Rss.php
+++ b/libs/Zend/Feed/Rss.php
@@ -15,21 +15,21 @@
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Rss.php 18266 2009-09-18 18:32:30Z padraic $
+ * @version $Id: Rss.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Feed_Abstract
*/
-require_once 'Zend/Feed/Abstract.php';
+// require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Rss
*/
-require_once 'Zend/Feed/Entry/Rss.php';
+// require_once 'Zend/Feed/Entry/Rss.php';
/**
@@ -43,7 +43,7 @@ require_once 'Zend/Feed/Entry/Rss.php';
*
* @category Zend
* @package Zend_Feed
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2010 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
@@ -82,7 +82,7 @@ class Zend_Feed_Rss extends Zend_Feed_Abstract
// Find the base channel element and create an alias to it.
$rdfTags = $this->_element->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'RDF');
if ($rdfTags->length != 0) {
- $this->_element = $rdfTags->item(0);
+ $this->_element = $rdfTags->item(0);
} else {
$this->_element = $this->_element->getElementsByTagName('channel')->item(0);
}
@@ -90,7 +90,7 @@ class Zend_Feed_Rss extends Zend_Feed_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <channel> element found, cannot parse channel.');
}
@@ -282,11 +282,12 @@ class Zend_Feed_Rss extends Zend_Feed_Abstract
$author = '';
$email = '';
if (isset($array->itunes->owner)) {
- if (isset($array->itunes->owner['name'])) {
- $author = $array->itunes->owner['name'];
+ $itunesOwner = $array->itunes->owner;
+ if (isset($itunesOwner['name'])) {
+ $author = $itunesOwner['name'];
}
- if (isset($array->itunes->owner['email'])) {
- $email = $array->itunes->owner['email'];
+ if (isset($itunesOwner['email'])) {
+ $email = $itunesOwner['email'];
}
}
if (empty($author) && isset($array->author)) {
@@ -411,6 +412,9 @@ class Zend_Feed_Rss extends Zend_Feed_Abstract
if (isset($dataentry->guid)) {
$guid = $this->_element->createElement('guid', $dataentry->guid);
+ if (!Zend_Uri::check($dataentry->guid)) {
+ $guid->setAttribute('isPermaLink', 'false');
+ }
$item->appendChild($guid);
}
@@ -514,7 +518,7 @@ class Zend_Feed_Rss extends Zend_Feed_Abstract
/**
* @see Zend_Feed_Exception
*/
- require_once 'Zend/Feed/Exception.php';
+ // require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send RSS because headers have already been sent.');
}
diff --git a/libs/Zend/Feed/Writer.php b/libs/Zend/Feed/Writer.php
new file mode 100644
index 0000000000..1a40f63cd9
--- /dev/null
+++ b/libs/Zend/Feed/Writer.php
@@ -0,0 +1,267 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Writer.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer
+{
+ /**
+ * Namespace constants
+ */
+ const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#';
+ const NAMESPACE_ATOM_10 = 'http://www.w3.org/2005/Atom';
+ const NAMESPACE_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+ const NAMESPACE_RSS_090 = 'http://my.netscape.com/rdf/simple/0.9/';
+ const NAMESPACE_RSS_10 = 'http://purl.org/rss/1.0/';
+
+ /**
+ * Feed type constants
+ */
+ const TYPE_ANY = 'any';
+ const TYPE_ATOM_03 = 'atom-03';
+ const TYPE_ATOM_10 = 'atom-10';
+ const TYPE_ATOM_ANY = 'atom';
+ const TYPE_RSS_090 = 'rss-090';
+ const TYPE_RSS_091 = 'rss-091';
+ const TYPE_RSS_091_NETSCAPE = 'rss-091n';
+ const TYPE_RSS_091_USERLAND = 'rss-091u';
+ const TYPE_RSS_092 = 'rss-092';
+ const TYPE_RSS_093 = 'rss-093';
+ const TYPE_RSS_094 = 'rss-094';
+ const TYPE_RSS_10 = 'rss-10';
+ const TYPE_RSS_20 = 'rss-20';
+ const TYPE_RSS_ANY = 'rss';
+
+ /**
+ * PluginLoader instance used by component
+ *
+ * @var Zend_Loader_PluginLoader_Interface
+ */
+ protected static $_pluginLoader = null;
+
+ /**
+ * Path on which to search for Extension classes
+ *
+ * @var array
+ */
+ protected static $_prefixPaths = array();
+
+ /**
+ * Array of registered extensions by class postfix (after the base class
+ * name) across four categories - data containers and renderers for entry
+ * and feed levels.
+ *
+ * @var array
+ */
+ protected static $_extensions = array(
+ 'entry' => array(),
+ 'feed' => array(),
+ 'entryRenderer' => array(),
+ 'feedRenderer' => array(),
+ );
+
+ /**
+ * Set plugin loader for use with Extensions
+ *
+ * @param Zend_Loader_PluginLoader_Interface
+ */
+ public static function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader)
+ {
+ self::$_pluginLoader = $loader;
+ }
+
+ /**
+ * Get plugin loader for use with Extensions
+ *
+ * @return Zend_Loader_PluginLoader_Interface
+ */
+ public static function getPluginLoader()
+ {
+ if (!isset(self::$_pluginLoader)) {
+ // require_once 'Zend/Loader/PluginLoader.php';
+ self::$_pluginLoader = new Zend_Loader_PluginLoader(array(
+ 'Zend_Feed_Writer_Extension_' => 'Zend/Feed/Writer/Extension/',
+ ));
+ }
+ return self::$_pluginLoader;
+ }
+
+ /**
+ * Add prefix path for loading Extensions
+ *
+ * @param string $prefix
+ * @param string $path
+ * @return void
+ */
+ public static function addPrefixPath($prefix, $path)
+ {
+ $prefix = rtrim($prefix, '_');
+ $path = rtrim($path, DIRECTORY_SEPARATOR);
+ self::getPluginLoader()->addPrefixPath($prefix, $path);
+ }
+
+ /**
+ * Add multiple Extension prefix paths at once
+ *
+ * @param array $spec
+ * @return void
+ */
+ public static function addPrefixPaths(array $spec)
+ {
+ if (isset($spec['prefix']) && isset($spec['path'])) {
+ self::addPrefixPath($spec['prefix'], $spec['path']);
+ }
+ foreach ($spec as $prefixPath) {
+ if (isset($prefixPath['prefix']) && isset($prefixPath['path'])) {
+ self::addPrefixPath($prefixPath['prefix'], $prefixPath['path']);
+ }
+ }
+ }
+
+ /**
+ * Register an Extension by name
+ *
+ * @param string $name
+ * @return void
+ * @throws Zend_Feed_Exception if unable to resolve Extension class
+ */
+ public static function registerExtension($name)
+ {
+ $feedName = $name . '_Feed';
+ $entryName = $name . '_Entry';
+ $feedRendererName = $name . '_Renderer_Feed';
+ $entryRendererName = $name . '_Renderer_Entry';
+ if (self::isRegistered($name)) {
+ if (self::getPluginLoader()->isLoaded($feedName)
+ || self::getPluginLoader()->isLoaded($entryName)
+ || self::getPluginLoader()->isLoaded($feedRendererName)
+ || self::getPluginLoader()->isLoaded($entryRendererName)
+ ) {
+ return;
+ }
+ }
+ try {
+ self::getPluginLoader()->load($feedName);
+ self::$_extensions['feed'][] = $feedName;
+ } catch (Zend_Loader_PluginLoader_Exception $e) {
+ }
+ try {
+ self::getPluginLoader()->load($entryName);
+ self::$_extensions['entry'][] = $entryName;
+ } catch (Zend_Loader_PluginLoader_Exception $e) {
+ }
+ try {
+ self::getPluginLoader()->load($feedRendererName);
+ self::$_extensions['feedRenderer'][] = $feedRendererName;
+ } catch (Zend_Loader_PluginLoader_Exception $e) {
+ }
+ try {
+ self::getPluginLoader()->load($entryRendererName);
+ self::$_extensions['entryRenderer'][] = $entryRendererName;
+ } catch (Zend_Loader_PluginLoader_Exception $e) {
+ }
+ if (!self::getPluginLoader()->isLoaded($feedName)
+ && !self::getPluginLoader()->isLoaded($entryName)
+ && !self::getPluginLoader()->isLoaded($feedRendererName)
+ && !self::getPluginLoader()->isLoaded($entryRendererName)
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Could not load extension: ' . $name
+ . 'using Plugin Loader. Check prefix paths are configured and extension exists.');
+ }
+ }
+
+ /**
+ * Is a given named Extension registered?
+ *
+ * @param string $extensionName
+ * @return boolean
+ */
+ public static function isRegistered($extensionName)
+ {
+ $feedName = $extensionName . '_Feed';
+ $entryName = $extensionName . '_Entry';
+ $feedRendererName = $extensionName . '_Renderer_Feed';
+ $entryRendererName = $extensionName . '_Renderer_Entry';
+ if (in_array($feedName, self::$_extensions['feed'])
+ || in_array($entryName, self::$_extensions['entry'])
+ || in_array($feedRendererName, self::$_extensions['feedRenderer'])
+ || in_array($entryRendererName, self::$_extensions['entryRenderer'])
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get a list of extensions
+ *
+ * @return array
+ */
+ public static function getExtensions()
+ {
+ return self::$_extensions;
+ }
+
+ /**
+ * Reset class state to defaults
+ *
+ * @return void
+ */
+ public static function reset()
+ {
+ self::$_pluginLoader = null;
+ self::$_prefixPaths = array();
+ self::$_extensions = array(
+ 'entry' => array(),
+ 'feed' => array(),
+ 'entryRenderer' => array(),
+ 'feedRenderer' => array(),
+ );
+ }
+
+ /**
+ * Register core (default) extensions
+ *
+ * @return void
+ */
+ public static function registerCoreExtensions()
+ {
+ self::registerExtension('DublinCore');
+ self::registerExtension('Content');
+ self::registerExtension('Atom');
+ self::registerExtension('Slash');
+ self::registerExtension('WellFormedWeb');
+ self::registerExtension('Threading');
+ self::registerExtension('ITunes');
+ }
+
+ public static function lcfirst($str)
+ {
+ $str[0] = strtolower($str[0]);
+ return $str;
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Deleted.php b/libs/Zend/Feed/Writer/Deleted.php
new file mode 100644
index 0000000000..19bb56b49e
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Deleted.php
@@ -0,0 +1,202 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+// require_once 'Zend/Feed/Writer/Feed/FeedAbstract.php';
+
+ /**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Deleted
+{
+
+ /**
+ * Internal array containing all data associated with this entry or item.
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Holds the value "atom" or "rss" depending on the feed type set when
+ * when last exported.
+ *
+ * @var string
+ */
+ protected $_type = null;
+
+ /**
+ * Set the feed character encoding
+ *
+ * @return string|null
+ */
+ public function setEncoding($encoding)
+ {
+ if (empty($encoding) || !is_string($encoding)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['encoding'] = $encoding;
+ }
+
+ /**
+ * Get the feed character encoding
+ *
+ * @return string|null
+ */
+ public function getEncoding()
+ {
+ if (!array_key_exists('encoding', $this->_data)) {
+ return 'UTF-8';
+ }
+ return $this->_data['encoding'];
+ }
+
+ /**
+ * Unset a specific data point
+ *
+ * @param string $name
+ */
+ public function remove($name)
+ {
+ if (isset($this->_data[$name])) {
+ unset($this->_data[$name]);
+ }
+ }
+
+ /**
+ * Set the current feed type being exported to "rss" or "atom". This allows
+ * other objects to gracefully choose whether to execute or not, depending
+ * on their appropriateness for the current type, e.g. renderers.
+ *
+ * @param string $type
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+ }
+
+ /**
+ * Retrieve the current or last feed type exported.
+ *
+ * @return string Value will be "rss" or "atom"
+ */
+ public function getType()
+ {
+ return $this->_type;
+ }
+
+ public function setReference($reference)
+ {
+ if (empty($reference) || !is_string($reference)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: reference must be a non-empty string');
+ }
+ $this->_data['reference'] = $reference;
+ }
+
+ public function getReference()
+ {
+ if (!array_key_exists('reference', $this->_data)) {
+ return null;
+ }
+ return $this->_data['reference'];
+ }
+
+ public function setWhen($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['when'] = $zdate;
+ }
+
+ public function getWhen()
+ {
+ if (!array_key_exists('when', $this->_data)) {
+ return null;
+ }
+ return $this->_data['when'];
+ }
+
+ public function setBy(array $by)
+ {
+ $author = array();
+ if (!array_key_exists('name', $by)
+ || empty($by['name'])
+ || !is_string($by['name'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: author array must include a "name" key with a non-empty string value');
+ }
+ $author['name'] = $by['name'];
+ if (isset($by['email'])) {
+ if (empty($by['email']) || !is_string($by['email'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "email" array value must be a non-empty string');
+ }
+ $author['email'] = $by['email'];
+ }
+ if (isset($by['uri'])) {
+ if (empty($by['uri'])
+ || !is_string($by['uri'])
+ || !Zend_Uri::check($by['uri'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI');
+ }
+ $author['uri'] = $by['uri'];
+ }
+ $this->_data['by'] = $author;
+ }
+
+ public function getBy()
+ {
+ if (!array_key_exists('by', $this->_data)) {
+ return null;
+ }
+ return $this->_data['by'];
+ }
+
+ public function setComment($comment)
+ {
+ $this->_data['comment'] = $comment;
+ }
+
+ public function getComment()
+ {
+ if (!array_key_exists('comment', $this->_data)) {
+ return null;
+ }
+ return $this->_data['comment'];
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Entry.php b/libs/Zend/Feed/Writer/Entry.php
new file mode 100644
index 0000000000..01d290e6fb
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Entry.php
@@ -0,0 +1,761 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 22065 2010-04-30 14:04:57Z padraic $
+ */
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Uri.php';
+
+// require_once 'Zend/Feed/Writer/Source.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Entry
+{
+
+ /**
+ * Internal array containing all data associated with this entry or item.
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Registered extensions
+ *
+ * @var array
+ */
+ protected $_extensions = array();
+
+ /**
+ * Holds the value "atom" or "rss" depending on the feed type set when
+ * when last exported.
+ *
+ * @var string
+ */
+ protected $_type = null;
+
+ /**
+ * Constructor: Primarily triggers the registration of core extensions and
+ * loads those appropriate to this data container.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ Zend_Feed_Writer::registerCoreExtensions();
+ $this->_loadExtensions();
+ }
+
+ /**
+ * Set a single author
+ *
+ * @param int $index
+ * @return string|null
+ */
+ public function addAuthor($name, $email = null, $uri = null)
+ {
+ $author = array();
+ if (is_array($name)) {
+ if (!array_key_exists('name', $name)
+ || empty($name['name'])
+ || !is_string($name['name'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: author array must include a "name" key with a non-empty string value');
+ }
+ $author['name'] = $name['name'];
+ if (isset($name['email'])) {
+ if (empty($name['email']) || !is_string($name['email'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "email" array value must be a non-empty string');
+ }
+ $author['email'] = $name['email'];
+ }
+ if (isset($name['uri'])) {
+ if (empty($name['uri'])
+ || !is_string($name['uri'])
+ || !Zend_Uri::check($name['uri'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI');
+ }
+ $author['uri'] = $name['uri'];
+ }
+ /**
+ * @deprecated
+ * Array notation (above) is preferred and will be the sole supported input from ZF 2.0
+ */
+ } else {
+ if (empty($name['name']) || !is_string($name['name'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "name" must be a non-empty string value');
+ }
+ $author['name'] = $name;
+ if (isset($email)) {
+ if (empty($email) || !is_string($email)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "email" value must be a non-empty string');
+ }
+ $author['email'] = $email;
+ }
+ if (isset($uri)) {
+ if (empty($uri) || !is_string($uri) || !Zend_Uri::check($uri)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" value must be a non-empty string and valid URI/IRI');
+ }
+ $author['uri'] = $uri;
+ }
+ }
+ $this->_data['authors'][] = $author;
+ }
+
+ /**
+ * Set an array with feed authors
+ *
+ * @return array
+ */
+ public function addAuthors(array $authors)
+ {
+ foreach($authors as $author) {
+ $this->addAuthor($author);
+ }
+ }
+
+ /**
+ * Set the feed character encoding
+ *
+ * @return string|null
+ */
+ public function setEncoding($encoding)
+ {
+ if (empty($encoding) || !is_string($encoding)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['encoding'] = $encoding;
+ }
+
+ /**
+ * Get the feed character encoding
+ *
+ * @return string|null
+ */
+ public function getEncoding()
+ {
+ if (!array_key_exists('encoding', $this->_data)) {
+ return 'UTF-8';
+ }
+ return $this->_data['encoding'];
+ }
+
+ /**
+ * Set the copyright entry
+ *
+ * @return string|null
+ */
+ public function setCopyright($copyright)
+ {
+ if (empty($copyright) || !is_string($copyright)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['copyright'] = $copyright;
+ }
+
+ /**
+ * Set the entry's content
+ *
+ * @return string|null
+ */
+ public function setContent($content)
+ {
+ if (empty($content) || !is_string($content)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['content'] = $content;
+ }
+
+ /**
+ * Set the feed creation date
+ *
+ * @return string|null
+ */
+ public function setDateCreated($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['dateCreated'] = $zdate;
+ }
+
+ /**
+ * Set the feed modification date
+ *
+ * @return string|null
+ */
+ public function setDateModified($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['dateModified'] = $zdate;
+ }
+
+ /**
+ * Set the feed description
+ *
+ * @return string|null
+ */
+ public function setDescription($description)
+ {
+ if (empty($description) || !is_string($description)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['description'] = $description;
+ }
+
+ /**
+ * Set the feed ID
+ *
+ * @return string|null
+ */
+ public function setId($id)
+ {
+ if (empty($id) || !is_string($id)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['id'] = $id;
+ }
+
+ /**
+ * Set a link to the HTML source of this entry
+ *
+ * @return string|null
+ */
+ public function setLink($link)
+ {
+ if (empty($link) || !is_string($link) || !Zend_Uri::check($link)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['link'] = $link;
+ }
+
+ /**
+ * Set the number of comments associated with this entry
+ *
+ * @return string|null
+ */
+ public function setCommentCount($count)
+ {
+ if (empty($count) || !is_numeric($count) || (int) $count < 0) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "count" must be a non-empty integer number');
+ }
+ $this->_data['commentCount'] = (int) $count;
+ }
+
+ /**
+ * Set a link to a HTML page containing comments associated with this entry
+ *
+ * @return string|null
+ */
+ public function setCommentLink($link)
+ {
+ if (empty($link) || !is_string($link) || !Zend_Uri::check($link)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "link" must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['commentLink'] = $link;
+ }
+
+ /**
+ * Set a link to an XML feed for any comments associated with this entry
+ *
+ * @return string|null
+ */
+ public function setCommentFeedLink(array $link)
+ {
+ if (!isset($link['uri']) || !is_string($link['uri']) || !Zend_Uri::check($link['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "link" must be a non-empty string and valid URI/IRI');
+ }
+ if (!isset($link['type']) || !in_array($link['type'], array('atom', 'rss', 'rdf'))) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "type" must be one'
+ . ' of "atom", "rss" or "rdf"');
+ }
+ if (!isset($this->_data['commentFeedLinks'])) {
+ $this->_data['commentFeedLinks'] = array();
+ }
+ $this->_data['commentFeedLinks'][] = $link;
+ }
+
+ /**
+ * Set a links to an XML feed for any comments associated with this entry.
+ * Each link is an array with keys "uri" and "type", where type is one of:
+ * "atom", "rss" or "rdf".
+ *
+ * @return string|null
+ */
+ public function setCommentFeedLinks(array $links)
+ {
+ foreach ($links as $link) {
+ $this->setCommentFeedLink($link);
+ }
+ }
+
+ /**
+ * Set the feed title
+ *
+ * @return string|null
+ */
+ public function setTitle($title)
+ {
+ if (empty($title) || !is_string($title)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['title'] = $title;
+ }
+
+ /**
+ * Get an array with feed authors
+ *
+ * @return array
+ */
+ public function getAuthors()
+ {
+ if (!array_key_exists('authors', $this->_data)) {
+ return null;
+ }
+ return $this->_data['authors'];
+ }
+
+ /**
+ * Get the entry content
+ *
+ * @return string
+ */
+ public function getContent()
+ {
+ if (!array_key_exists('content', $this->_data)) {
+ return null;
+ }
+ return $this->_data['content'];
+ }
+
+ /**
+ * Get the entry copyright information
+ *
+ * @return string
+ */
+ public function getCopyright()
+ {
+ if (!array_key_exists('copyright', $this->_data)) {
+ return null;
+ }
+ return $this->_data['copyright'];
+ }
+
+ /**
+ * Get the entry creation date
+ *
+ * @return string
+ */
+ public function getDateCreated()
+ {
+ if (!array_key_exists('dateCreated', $this->_data)) {
+ return null;
+ }
+ return $this->_data['dateCreated'];
+ }
+
+ /**
+ * Get the entry modification date
+ *
+ * @return string
+ */
+ public function getDateModified()
+ {
+ if (!array_key_exists('dateModified', $this->_data)) {
+ return null;
+ }
+ return $this->_data['dateModified'];
+ }
+
+ /**
+ * Get the entry description
+ *
+ * @return string
+ */
+ public function getDescription()
+ {
+ if (!array_key_exists('description', $this->_data)) {
+ return null;
+ }
+ return $this->_data['description'];
+ }
+
+ /**
+ * Get the entry ID
+ *
+ * @return string
+ */
+ public function getId()
+ {
+ if (!array_key_exists('id', $this->_data)) {
+ return null;
+ }
+ return $this->_data['id'];
+ }
+
+ /**
+ * Get a link to the HTML source
+ *
+ * @return string|null
+ */
+ public function getLink()
+ {
+ if (!array_key_exists('link', $this->_data)) {
+ return null;
+ }
+ return $this->_data['link'];
+ }
+
+
+ /**
+ * Get all links
+ *
+ * @return array
+ */
+ public function getLinks()
+ {
+ if (!array_key_exists('links', $this->_data)) {
+ return null;
+ }
+ return $this->_data['links'];
+ }
+
+ /**
+ * Get the entry title
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ if (!array_key_exists('title', $this->_data)) {
+ return null;
+ }
+ return $this->_data['title'];
+ }
+
+ /**
+ * Get the number of comments/replies for current entry
+ *
+ * @return integer
+ */
+ public function getCommentCount()
+ {
+ if (!array_key_exists('commentCount', $this->_data)) {
+ return null;
+ }
+ return $this->_data['commentCount'];
+ }
+
+ /**
+ * Returns a URI pointing to the HTML page where comments can be made on this entry
+ *
+ * @return string
+ */
+ public function getCommentLink()
+ {
+ if (!array_key_exists('commentLink', $this->_data)) {
+ return null;
+ }
+ return $this->_data['commentLink'];
+ }
+
+ /**
+ * Returns an array of URIs pointing to a feed of all comments for this entry
+ * where the array keys indicate the feed type (atom, rss or rdf).
+ *
+ * @return string
+ */
+ public function getCommentFeedLinks()
+ {
+ if (!array_key_exists('commentFeedLinks', $this->_data)) {
+ return null;
+ }
+ return $this->_data['commentFeedLinks'];
+ }
+
+ /**
+ * Add a entry category
+ *
+ * @param string $category
+ */
+ public function addCategory(array $category)
+ {
+ if (!isset($category['term'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Each category must be an array and '
+ . 'contain at least a "term" element containing the machine '
+ . ' readable category name');
+ }
+ if (isset($category['scheme'])) {
+ if (empty($category['scheme'])
+ || !is_string($category['scheme'])
+ || !Zend_Uri::check($category['scheme'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('The Atom scheme or RSS domain of'
+ . ' a category must be a valid URI');
+ }
+ }
+ if (!isset($this->_data['categories'])) {
+ $this->_data['categories'] = array();
+ }
+ $this->_data['categories'][] = $category;
+ }
+
+ /**
+ * Set an array of entry categories
+ *
+ * @param array $categories
+ */
+ public function addCategories(array $categories)
+ {
+ foreach ($categories as $category) {
+ $this->addCategory($category);
+ }
+ }
+
+ /**
+ * Get the entry categories
+ *
+ * @return string|null
+ */
+ public function getCategories()
+ {
+ if (!array_key_exists('categories', $this->_data)) {
+ return null;
+ }
+ return $this->_data['categories'];
+ }
+
+ /**
+ * Adds an enclosure to the entry. The array parameter may contain the
+ * keys 'uri', 'type' and 'length'. Only 'uri' is required for Atom, though the
+ * others must also be provided or RSS rendering (where they are required)
+ * will throw an Exception.
+ *
+ * @param array $enclosures
+ */
+ public function setEnclosure(array $enclosure)
+ {
+ if (!isset($enclosure['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Enclosure "uri" is not set');
+ }
+ if (!Zend_Uri::check($enclosure['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Enclosure "uri" is not a valid URI/IRI');
+ }
+ $this->_data['enclosure'] = $enclosure;
+ }
+
+ /**
+ * Retrieve an array of all enclosures to be added to entry.
+ *
+ * @return array
+ */
+ public function getEnclosure()
+ {
+ if (!array_key_exists('enclosure', $this->_data)) {
+ return null;
+ }
+ return $this->_data['enclosure'];
+ }
+
+ /**
+ * Unset a specific data point
+ *
+ * @param string $name
+ */
+ public function remove($name)
+ {
+ if (isset($this->_data[$name])) {
+ unset($this->_data[$name]);
+ }
+ }
+
+ /**
+ * Get registered extensions
+ *
+ * @return array
+ */
+ public function getExtensions()
+ {
+ return $this->_extensions;
+ }
+
+ /**
+ * Return an Extension object with the matching name (postfixed with _Entry)
+ *
+ * @param string $name
+ * @return object
+ */
+ public function getExtension($name)
+ {
+ if (array_key_exists($name . '_Entry', $this->_extensions)) {
+ return $this->_extensions[$name . '_Entry'];
+ }
+ return null;
+ }
+
+ /**
+ * Set the current feed type being exported to "rss" or "atom". This allows
+ * other objects to gracefully choose whether to execute or not, depending
+ * on their appropriateness for the current type, e.g. renderers.
+ *
+ * @param string $type
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+ }
+
+ /**
+ * Retrieve the current or last feed type exported.
+ *
+ * @return string Value will be "rss" or "atom"
+ */
+ public function getType()
+ {
+ return $this->_type;
+ }
+
+ /**
+ * Method overloading: call given method on first extension implementing it
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ * @throws Zend_Feed_Exception if no extensions implements the method
+ */
+ public function __call($method, $args)
+ {
+ foreach ($this->_extensions as $extension) {
+ try {
+ return call_user_func_array(array($extension, $method), $args);
+ } catch (Zend_Feed_Writer_Exception_InvalidMethodException $e) {
+ }
+ }
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Method: ' . $method
+ . ' does not exist and could not be located on a registered Extension');
+ }
+
+ /**
+ * Creates a new Zend_Feed_Writer_Source data container for use. This is NOT
+ * added to the current feed automatically, but is necessary to create a
+ * container with some initial values preset based on the current feed data.
+ *
+ * @return Zend_Feed_Writer_Source
+ */
+ public function createSource()
+ {
+ $source = new Zend_Feed_Writer_Source;
+ if ($this->getEncoding()) {
+ $source->setEncoding($this->getEncoding());
+ }
+ $source->setType($this->getType());
+ return $source;
+ }
+
+ /**
+ * Appends a Zend_Feed_Writer_Entry object representing a new entry/item
+ * the feed data container's internal group of entries.
+ *
+ * @param Zend_Feed_Writer_Source $source
+ */
+ public function setSource(Zend_Feed_Writer_Source $source)
+ {
+ $this->_data['source'] = $source;
+ }
+
+ /**
+ * @return Zend_Feed_Writer_Source
+ */
+ public function getSource()
+ {
+ if (isset($this->_data['source'])) {
+ return $this->_data['source'];
+ }
+ return null;
+ }
+
+ /**
+ * Load extensions from Zend_Feed_Writer
+ *
+ * @return void
+ */
+ protected function _loadExtensions()
+ {
+ $all = Zend_Feed_Writer::getExtensions();
+ $exts = $all['entry'];
+ foreach ($exts as $ext) {
+ $className = Zend_Feed_Writer::getPluginLoader()->getClassName($ext);
+ $this->_extensions[$ext] = new $className();
+ $this->_extensions[$ext]->setEncoding($this->getEncoding());
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Exception/InvalidMethodException.php b/libs/Zend/Feed/Writer/Exception/InvalidMethodException.php
new file mode 100644
index 0000000000..4510f12b68
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Exception/InvalidMethodException.php
@@ -0,0 +1,41 @@
+<?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-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: InvalidMethodException.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+
+/**
+ * @see Zend_Feed_Exception
+ */
+// require_once 'Zend/Feed/Exception.php';
+
+
+/**
+ * Feed exceptions
+ *
+ * Class to represent exceptions that occur during Feed operations.
+ *
+ * @category Zend
+ * @package Zend_Feed
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Exception_InvalidMethodException extends Zend_Exception
+{}
diff --git a/libs/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php b/libs/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php
new file mode 100644
index 0000000000..588a57af66
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php
@@ -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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_Atom_Renderer_Feed
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render feed
+ *
+ * @return void
+ */
+ public function render()
+ {
+ /**
+ * RSS 2.0 only. Used mainly to include Atom links and
+ * Pubsubhubbub Hub endpoint URIs under the Atom namespace
+ */
+ if (strtolower($this->getType()) == 'atom') {
+ return;
+ }
+ $this->_setFeedLinks($this->_dom, $this->_base);
+ $this->_setHubs($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append namespaces to root element of feed
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:atom',
+ 'http://www.w3.org/2005/Atom');
+ }
+
+ /**
+ * Set feed link elements
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
+ {
+ $flinks = $this->getDataContainer()->getFeedLinks();
+ if(!$flinks || empty($flinks)) {
+ return;
+ }
+ foreach ($flinks as $type => $href) {
+ $mime = 'application/' . strtolower($type) . '+xml';
+ $flink = $dom->createElement('atom:link');
+ $root->appendChild($flink);
+ $flink->setAttribute('rel', 'self');
+ $flink->setAttribute('type', $mime);
+ $flink->setAttribute('href', $href);
+ }
+ $this->_called = true;
+ }
+
+ /**
+ * Set PuSH hubs
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setHubs(DOMDocument $dom, DOMElement $root)
+ {
+ $hubs = $this->getDataContainer()->getHubs();
+ if (!$hubs || empty($hubs)) {
+ return;
+ }
+ foreach ($hubs as $hubUrl) {
+ $hub = $dom->createElement('atom:link');
+ $hub->setAttribute('rel', 'hub');
+ $hub->setAttribute('href', $hubUrl);
+ $root->appendChild($hub);
+ }
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php
new file mode 100644
index 0000000000..0036c6325e
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php
@@ -0,0 +1,92 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_Content_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'atom') {
+ return;
+ }
+ $this->_setContent($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append namespaces to root element
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:content',
+ 'http://purl.org/rss/1.0/modules/content/');
+ }
+
+ /**
+ * Set entry content
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setContent(DOMDocument $dom, DOMElement $root)
+ {
+ $content = $this->getDataContainer()->getContent();
+ if (!$content) {
+ return;
+ }
+ $element = $dom->createElement('content:encoded');
+ $root->appendChild($element);
+ $cdata = $dom->createCDATASection($content);
+ $element->appendChild($cdata);
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php
new file mode 100644
index 0000000000..c433ea3a6c
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php
@@ -0,0 +1,96 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_DublinCore_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'atom') {
+ return;
+ }
+ $this->_setAuthors($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append namespaces to entry
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:dc',
+ 'http://purl.org/dc/elements/1.1/');
+ }
+
+ /**
+ * Set entry author elements
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->getDataContainer()->getAuthors();
+ if (!$authors || empty($authors)) {
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('dc:creator');
+ if (array_key_exists('name', $data)) {
+ $text = $dom->createTextNode($data['name']);
+ $author->appendChild($text);
+ $root->appendChild($author);
+ }
+ }
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php b/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php
new file mode 100644
index 0000000000..e1a0105019
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php
@@ -0,0 +1,96 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_DublinCore_Renderer_Feed
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render feed
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'atom') {
+ return;
+ }
+ $this->_setAuthors($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append namespaces to feed element
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:dc',
+ 'http://purl.org/dc/elements/1.1/');
+ }
+
+ /**
+ * Set feed authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->getDataContainer()->getAuthors();
+ if (!$authors || empty($authors)) {
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('dc:creator');
+ if (array_key_exists('name', $data)) {
+ $text = $dom->createTextNode($data['name']);
+ $author->appendChild($text);
+ $root->appendChild($author);
+ }
+ }
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/ITunes/Entry.php b/libs/Zend/Feed/Writer/Extension/ITunes/Entry.php
new file mode 100644
index 0000000000..1d7fbc5070
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/ITunes/Entry.php
@@ -0,0 +1,242 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_ITunes_Entry
+{
+ /**
+ * Array of Feed data for rendering by Extension's renderers
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Encoding of all text values
+ *
+ * @var string
+ */
+ protected $_encoding = 'UTF-8';
+
+ /**
+ * Set feed encoding
+ *
+ * @param string $enc
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setEncoding($enc)
+ {
+ $this->_encoding = $enc;
+ return $this;
+ }
+
+ /**
+ * Get feed encoding
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Set a block value of "yes" or "no". You may also set an empty string.
+ *
+ * @param string
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesBlock($value)
+ {
+ if (!ctype_alpha($value) && strlen($value) > 0) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "block" may only'
+ . ' contain alphabetic characters');
+ }
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "block" may only'
+ . ' contain a maximum of 255 characters');
+ }
+ $this->_data['block'] = $value;
+ }
+
+ /**
+ * Add authors to itunes entry
+ *
+ * @param array $values
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function addItunesAuthors(array $values)
+ {
+ foreach ($values as $value) {
+ $this->addItunesAuthor($value);
+ }
+ return $this;
+ }
+
+ /**
+ * Add author to itunes entry
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function addItunesAuthor($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "author" may only'
+ . ' contain a maximum of 255 characters each');
+ }
+ if (!isset($this->_data['authors'])) {
+ $this->_data['authors'] = array();
+ }
+ $this->_data['authors'][] = $value;
+ return $this;
+ }
+
+ /**
+ * Set duration
+ *
+ * @param int $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesDuration($value)
+ {
+ $value = (string) $value;
+ if (!ctype_digit($value)
+ && !preg_match("/^\d+:[0-5]{1}[0-9]{1}$/", $value)
+ && !preg_match("/^\d+:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/", $value)
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "duration" may only'
+ . ' be of a specified [[HH:]MM:]SS format');
+ }
+ $this->_data['duration'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set "explicit" flag
+ *
+ * @param bool $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesExplicit($value)
+ {
+ if (!in_array($value, array('yes','no','clean'))) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "explicit" may only'
+ . ' be one of "yes", "no" or "clean"');
+ }
+ $this->_data['explicit'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set keywords
+ *
+ * @param array $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesKeywords(array $value)
+ {
+ if (count($value) > 12) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "keywords" may only'
+ . ' contain a maximum of 12 terms');
+ }
+ $concat = implode(',', $value);
+ if (iconv_strlen($concat, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "keywords" may only'
+ . ' have a concatenated length of 255 chars where terms are delimited'
+ . ' by a comma');
+ }
+ $this->_data['keywords'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set subtitle
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesSubtitle($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "subtitle" may only'
+ . ' contain a maximum of 255 characters');
+ }
+ $this->_data['subtitle'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set summary
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Entry
+ */
+ public function setItunesSummary($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 4000) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "summary" may only'
+ . ' contain a maximum of 4000 characters');
+ }
+ $this->_data['summary'] = $value;
+ return $this;
+ }
+
+ /**
+ * Overloading to itunes specific setters
+ *
+ * @param string $method
+ * @param array $params
+ * @return mixed
+ */
+ public function __call($method, array $params)
+ {
+ $point = Zend_Feed_Writer::lcfirst(substr($method, 9));
+ if (!method_exists($this, 'setItunes' . ucfirst($point))
+ && !method_exists($this, 'addItunes' . ucfirst($point))
+ ) {
+ // require_once 'Zend/Feed/Writer/Exception/InvalidMethodException.php';
+ throw new Zend_Feed_Writer_Exception_InvalidMethodException(
+ 'invalid method: ' . $method
+ );
+ }
+ if (!array_key_exists($point, $this->_data)
+ || empty($this->_data[$point])
+ ) {
+ return null;
+ }
+ return $this->_data[$point];
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/ITunes/Feed.php b/libs/Zend/Feed/Writer/Extension/ITunes/Feed.php
new file mode 100644
index 0000000000..caf0440a03
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/ITunes/Feed.php
@@ -0,0 +1,361 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_ITunes_Feed
+{
+ /**
+ * Array of Feed data for rendering by Extension's renderers
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Encoding of all text values
+ *
+ * @var string
+ */
+ protected $_encoding = 'UTF-8';
+
+ /**
+ * Set feed encoding
+ *
+ * @param string $enc
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setEncoding($enc)
+ {
+ $this->_encoding = $enc;
+ return $this;
+ }
+
+ /**
+ * Get feed encoding
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Set a block value of "yes" or "no". You may also set an empty string.
+ *
+ * @param string
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesBlock($value)
+ {
+ if (!ctype_alpha($value) && strlen($value) > 0) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "block" may only'
+ . ' contain alphabetic characters');
+ }
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "block" may only'
+ . ' contain a maximum of 255 characters');
+ }
+ $this->_data['block'] = $value;
+ return $this;
+ }
+
+ /**
+ * Add feed authors
+ *
+ * @param array $values
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function addItunesAuthors(array $values)
+ {
+ foreach ($values as $value) {
+ $this->addItunesAuthor($value);
+ }
+ return $this;
+ }
+
+ /**
+ * Add feed author
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function addItunesAuthor($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "author" may only'
+ . ' contain a maximum of 255 characters each');
+ }
+ if (!isset($this->_data['authors'])) {
+ $this->_data['authors'] = array();
+ }
+ $this->_data['authors'][] = $value;
+ return $this;
+ }
+
+ /**
+ * Set feed categories
+ *
+ * @param array $values
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesCategories(array $values)
+ {
+ if (!isset($this->_data['categories'])) {
+ $this->_data['categories'] = array();
+ }
+ foreach ($values as $key=>$value) {
+ if (!is_array($value)) {
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "category" may only'
+ . ' contain a maximum of 255 characters each');
+ }
+ $this->_data['categories'][] = $value;
+ } else {
+ if (iconv_strlen($key, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "category" may only'
+ . ' contain a maximum of 255 characters each');
+ }
+ $this->_data['categories'][$key] = array();
+ foreach ($value as $val) {
+ if (iconv_strlen($val, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "category" may only'
+ . ' contain a maximum of 255 characters each');
+ }
+ $this->_data['categories'][$key][] = $val;
+ }
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Set feed image (icon)
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesImage($value)
+ {
+ if (!Zend_Uri::check($value)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "image" may only'
+ . ' be a valid URI/IRI');
+ }
+ if (!in_array(substr($value, -3), array('jpg','png'))) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "image" may only'
+ . ' use file extension "jpg" or "png" which must be the last three'
+ . ' characters of the URI (i.e. no query string or fragment)');
+ }
+ $this->_data['image'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set feed cumulative duration
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesDuration($value)
+ {
+ $value = (string) $value;
+ if (!ctype_digit($value)
+ && !preg_match("/^\d+:[0-5]{1}[0-9]{1}$/", $value)
+ && !preg_match("/^\d+:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/", $value)
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "duration" may only'
+ . ' be of a specified [[HH:]MM:]SS format');
+ }
+ $this->_data['duration'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set "explicit" flag
+ *
+ * @param bool $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesExplicit($value)
+ {
+ if (!in_array($value, array('yes','no','clean'))) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "explicit" may only'
+ . ' be one of "yes", "no" or "clean"');
+ }
+ $this->_data['explicit'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set feed keywords
+ *
+ * @param array $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesKeywords(array $value)
+ {
+ if (count($value) > 12) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "keywords" may only'
+ . ' contain a maximum of 12 terms');
+ }
+ $concat = implode(',', $value);
+ if (iconv_strlen($concat, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "keywords" may only'
+ . ' have a concatenated length of 255 chars where terms are delimited'
+ . ' by a comma');
+ }
+ $this->_data['keywords'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set new feed URL
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesNewFeedUrl($value)
+ {
+ if (!Zend_Uri::check($value)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "newFeedUrl" may only'
+ . ' be a valid URI/IRI');
+ }
+ $this->_data['newFeedUrl'] = $value;
+ return $this;
+ }
+
+ /**
+ * Add feed owners
+ *
+ * @param array $values
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function addItunesOwners(array $values)
+ {
+ foreach ($values as $value) {
+ $this->addItunesOwner($value);
+ }
+ return $this;
+ }
+
+ /**
+ * Add feed owner
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function addItunesOwner(array $value)
+ {
+ if (!isset($value['name']) || !isset($value['email'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "owner" must'
+ . ' be an array containing keys "name" and "email"');
+ }
+ if (iconv_strlen($value['name'], $this->getEncoding()) > 255
+ || iconv_strlen($value['email'], $this->getEncoding()) > 255
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: any "owner" may only'
+ . ' contain a maximum of 255 characters each for "name" and "email"');
+ }
+ if (!isset($this->_data['owners'])) {
+ $this->_data['owners'] = array();
+ }
+ $this->_data['owners'][] = $value;
+ return $this;
+ }
+
+ /**
+ * Set feed subtitle
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesSubtitle($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 255) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "subtitle" may only'
+ . ' contain a maximum of 255 characters');
+ }
+ $this->_data['subtitle'] = $value;
+ return $this;
+ }
+
+ /**
+ * Set feed summary
+ *
+ * @param string $value
+ * @return Zend_Feed_Writer_Extension_ITunes_Feed
+ */
+ public function setItunesSummary($value)
+ {
+ if (iconv_strlen($value, $this->getEncoding()) > 4000) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('invalid parameter: "summary" may only'
+ . ' contain a maximum of 4000 characters');
+ }
+ $this->_data['summary'] = $value;
+ return $this;
+ }
+
+ /**
+ * Overloading: proxy to internal setters
+ *
+ * @param string $method
+ * @param array $params
+ * @return mixed
+ */
+ public function __call($method, array $params)
+ {
+ $point = Zend_Feed_Writer::lcfirst(substr($method, 9));
+ if (!method_exists($this, 'setItunes' . ucfirst($point))
+ && !method_exists($this, 'addItunes' . ucfirst($point))
+ ) {
+ // require_once 'Zend/Feed/Writer/Exception/InvalidMethodException.php';
+ throw new Zend_Feed_Writer_Exception_InvalidMethodException(
+ 'invalid method: ' . $method
+ );
+ }
+ if (!array_key_exists($point, $this->_data) || empty($this->_data[$point])) {
+ return null;
+ }
+ return $this->_data[$point];
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php
new file mode 100644
index 0000000000..046cb546fb
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php
@@ -0,0 +1,216 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_ITunes_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ $this->_setAuthors($this->_dom, $this->_base);
+ $this->_setBlock($this->_dom, $this->_base);
+ $this->_setDuration($this->_dom, $this->_base);
+ $this->_setExplicit($this->_dom, $this->_base);
+ $this->_setKeywords($this->_dom, $this->_base);
+ $this->_setSubtitle($this->_dom, $this->_base);
+ $this->_setSummary($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append namespaces to entry root
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:itunes',
+ 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+ }
+
+ /**
+ * Set entry authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->getDataContainer()->getItunesAuthors();
+ if (!$authors || empty($authors)) {
+ return;
+ }
+ foreach ($authors as $author) {
+ $el = $dom->createElement('itunes:author');
+ $text = $dom->createTextNode($author);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+ }
+
+ /**
+ * Set itunes block
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setBlock(DOMDocument $dom, DOMElement $root)
+ {
+ $block = $this->getDataContainer()->getItunesBlock();
+ if (is_null($block)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:block');
+ $text = $dom->createTextNode($block);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set entry duration
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDuration(DOMDocument $dom, DOMElement $root)
+ {
+ $duration = $this->getDataContainer()->getItunesDuration();
+ if (!$duration) {
+ return;
+ }
+ $el = $dom->createElement('itunes:duration');
+ $text = $dom->createTextNode($duration);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set explicit flag
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setExplicit(DOMDocument $dom, DOMElement $root)
+ {
+ $explicit = $this->getDataContainer()->getItunesExplicit();
+ if (is_null($explicit)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:explicit');
+ $text = $dom->createTextNode($explicit);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set entry keywords
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setKeywords(DOMDocument $dom, DOMElement $root)
+ {
+ $keywords = $this->getDataContainer()->getItunesKeywords();
+ if (!$keywords || empty($keywords)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:keywords');
+ $text = $dom->createTextNode(implode(',', $keywords));
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set entry subtitle
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setSubtitle(DOMDocument $dom, DOMElement $root)
+ {
+ $subtitle = $this->getDataContainer()->getItunesSubtitle();
+ if (!$subtitle) {
+ return;
+ }
+ $el = $dom->createElement('itunes:subtitle');
+ $text = $dom->createTextNode($subtitle);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set entry summary
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setSummary(DOMDocument $dom, DOMElement $root)
+ {
+ $summary = $this->getDataContainer()->getItunesSummary();
+ if (!$summary) {
+ return;
+ }
+ $el = $dom->createElement('itunes:summary');
+ $text = $dom->createTextNode($summary);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php b/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php
new file mode 100644
index 0000000000..192d19ec42
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php
@@ -0,0 +1,320 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_ITunes_Renderer_Feed
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render feed
+ *
+ * @return void
+ */
+ public function render()
+ {
+ $this->_setAuthors($this->_dom, $this->_base);
+ $this->_setBlock($this->_dom, $this->_base);
+ $this->_setCategories($this->_dom, $this->_base);
+ $this->_setImage($this->_dom, $this->_base);
+ $this->_setDuration($this->_dom, $this->_base);
+ $this->_setExplicit($this->_dom, $this->_base);
+ $this->_setKeywords($this->_dom, $this->_base);
+ $this->_setNewFeedUrl($this->_dom, $this->_base);
+ $this->_setOwners($this->_dom, $this->_base);
+ $this->_setSubtitle($this->_dom, $this->_base);
+ $this->_setSummary($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append feed namespaces
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:itunes',
+ 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+ }
+
+ /**
+ * Set feed authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->getDataContainer()->getItunesAuthors();
+ if (!$authors || empty($authors)) {
+ return;
+ }
+ foreach ($authors as $author) {
+ $el = $dom->createElement('itunes:author');
+ $text = $dom->createTextNode($author);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ }
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed itunes block
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setBlock(DOMDocument $dom, DOMElement $root)
+ {
+ $block = $this->getDataContainer()->getItunesBlock();
+ if (is_null($block)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:block');
+ $text = $dom->createTextNode($block);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed categories
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCategories(DOMDocument $dom, DOMElement $root)
+ {
+ $cats = $this->getDataContainer()->getItunesCategories();
+ if (!$cats || empty($cats)) {
+ return;
+ }
+ foreach ($cats as $key=>$cat) {
+ if (!is_array($cat)) {
+ $el = $dom->createElement('itunes:category');
+ $el->setAttribute('text', $cat);
+ $root->appendChild($el);
+ } else {
+ $el = $dom->createElement('itunes:category');
+ $el->setAttribute('text', $key);
+ $root->appendChild($el);
+ foreach ($cat as $subcat) {
+ $el2 = $dom->createElement('itunes:category');
+ $el2->setAttribute('text', $subcat);
+ $el->appendChild($el2);
+ }
+ }
+ }
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed image (icon)
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setImage(DOMDocument $dom, DOMElement $root)
+ {
+ $image = $this->getDataContainer()->getItunesImage();
+ if (!$image) {
+ return;
+ }
+ $el = $dom->createElement('itunes:image');
+ $el->setAttribute('href', $image);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed cumulative duration
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDuration(DOMDocument $dom, DOMElement $root)
+ {
+ $duration = $this->getDataContainer()->getItunesDuration();
+ if (!$duration) {
+ return;
+ }
+ $el = $dom->createElement('itunes:duration');
+ $text = $dom->createTextNode($duration);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set explicit flag
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setExplicit(DOMDocument $dom, DOMElement $root)
+ {
+ $explicit = $this->getDataContainer()->getItunesExplicit();
+ if (is_null($explicit)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:explicit');
+ $text = $dom->createTextNode($explicit);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed keywords
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setKeywords(DOMDocument $dom, DOMElement $root)
+ {
+ $keywords = $this->getDataContainer()->getItunesKeywords();
+ if (!$keywords || empty($keywords)) {
+ return;
+ }
+ $el = $dom->createElement('itunes:keywords');
+ $text = $dom->createTextNode(implode(',', $keywords));
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed's new URL
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setNewFeedUrl(DOMDocument $dom, DOMElement $root)
+ {
+ $url = $this->getDataContainer()->getItunesNewFeedUrl();
+ if (!$url) {
+ return;
+ }
+ $el = $dom->createElement('itunes:new-feed-url');
+ $text = $dom->createTextNode($url);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed owners
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setOwners(DOMDocument $dom, DOMElement $root)
+ {
+ $owners = $this->getDataContainer()->getItunesOwners();
+ if (!$owners || empty($owners)) {
+ return;
+ }
+ foreach ($owners as $owner) {
+ $el = $dom->createElement('itunes:owner');
+ $name = $dom->createElement('itunes:name');
+ $text = $dom->createTextNode($owner['name']);
+ $name->appendChild($text);
+ $email = $dom->createElement('itunes:email');
+ $text = $dom->createTextNode($owner['email']);
+ $email->appendChild($text);
+ $root->appendChild($el);
+ $el->appendChild($name);
+ $el->appendChild($email);
+ }
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed subtitle
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setSubtitle(DOMDocument $dom, DOMElement $root)
+ {
+ $subtitle = $this->getDataContainer()->getItunesSubtitle();
+ if (!$subtitle) {
+ return;
+ }
+ $el = $dom->createElement('itunes:subtitle');
+ $text = $dom->createTextNode($subtitle);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+
+ /**
+ * Set feed summary
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setSummary(DOMDocument $dom, DOMElement $root)
+ {
+ $summary = $this->getDataContainer()->getItunesSummary();
+ if (!$summary) {
+ return;
+ }
+ $el = $dom->createElement('itunes:summary');
+ $text = $dom->createTextNode($summary);
+ $el->appendChild($text);
+ $root->appendChild($el);
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/RendererAbstract.php b/libs/Zend/Feed/Writer/Extension/RendererAbstract.php
new file mode 100644
index 0000000000..b381be3657
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/RendererAbstract.php
@@ -0,0 +1,179 @@
+<?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 padraic dot brady at yahoo dot com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed_Writer_Entry_Rss
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererInterface
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererInterface.php';
+
+ /**
+ * @category Zend
+ * @package Zend_Feed_Writer_Entry_Rss
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Feed_Writer_Extension_RendererAbstract
+ implements Zend_Feed_Writer_Extension_RendererInterface
+{
+ /**
+ * @var DOMDocument
+ */
+ protected $_dom = null;
+
+ /**
+ * @var mixed
+ */
+ protected $_entry = null;
+
+ /**
+ * @var DOMElement
+ */
+ protected $_base = null;
+
+ /**
+ * @var mixed
+ */
+ protected $_container = null;
+
+ /**
+ * @var string
+ */
+ protected $_type = null;
+
+ /**
+ * @var DOMElement
+ */
+ protected $_rootElement = null;
+
+ /**
+ * Encoding of all text values
+ *
+ * @var string
+ */
+ protected $_encoding = 'UTF-8';
+
+ /**
+ * Constructor
+ *
+ * @param mixed $container
+ * @return void
+ */
+ public function __construct($container)
+ {
+ $this->_container = $container;
+ }
+
+ /**
+ * Set feed encoding
+ *
+ * @param string $enc
+ * @return Zend_Feed_Writer_Extension_RendererAbstract
+ */
+ public function setEncoding($enc)
+ {
+ $this->_encoding = $enc;
+ return $this;
+ }
+
+ /**
+ * Get feed encoding
+ *
+ * @return void
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Set DOMDocument and DOMElement on which to operate
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $base
+ * @return Zend_Feed_Writer_Extension_RendererAbstract
+ */
+ public function setDomDocument(DOMDocument $dom, DOMElement $base)
+ {
+ $this->_dom = $dom;
+ $this->_base = $base;
+ return $this;
+ }
+
+ /**
+ * Get data container being rendered
+ *
+ * @return mixed
+ */
+ public function getDataContainer()
+ {
+ return $this->_container;
+ }
+
+ /**
+ * Set feed type
+ *
+ * @param string $type
+ * @return Zend_Feed_Writer_Extension_RendererAbstract
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+ return $this;
+ }
+
+ /**
+ * Get feedtype
+ *
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->_type;
+ }
+
+ /**
+ * Set root element of document
+ *
+ * @param DOMElement $root
+ * @return Zend_Feed_Writer_Extension_RendererAbstract
+ */
+ public function setRootElement(DOMElement $root)
+ {
+ $this->_rootElement = $root;
+ return $this;
+ }
+
+ /**
+ * Get root element
+ *
+ * @return DOMElement
+ */
+ public function getRootElement()
+ {
+ return $this->_rootElement;
+ }
+
+ /**
+ * Append namespaces to feed
+ *
+ * @return void
+ */
+ abstract protected function _appendNamespaces();
+}
diff --git a/libs/Zend/Feed/Writer/Extension/RendererInterface.php b/libs/Zend/Feed/Writer/Extension/RendererInterface.php
new file mode 100644
index 0000000000..e9c9014176
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/RendererInterface.php
@@ -0,0 +1,59 @@
+<?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 padraic dot brady at yahoo dot com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Feed_Writer_Extension_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param mixed $container
+ * @return void
+ */
+ public function __construct($container);
+
+ /**
+ * Set DOMDocument and DOMElement on which to operate
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $base
+ * @return void
+ */
+ public function setDomDocument(DOMDocument $dom, DOMElement $base);
+
+ /**
+ * Render
+ *
+ * @return void
+ */
+ public function render();
+
+ /**
+ * Retrieve container
+ *
+ * @return mixed
+ */
+ public function getDataContainer();
+}
diff --git a/libs/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php
new file mode 100644
index 0000000000..2814775551
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php
@@ -0,0 +1,91 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_Slash_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'atom') {
+ return; // RSS 2.0 only
+ }
+ $this->_setCommentCount($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append entry namespaces
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:slash',
+ 'http://purl.org/rss/1.0/modules/slash/');
+ }
+
+ /**
+ * Set entry comment count
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentCount(DOMDocument $dom, DOMElement $root)
+ {
+ $count = $this->getDataContainer()->getCommentCount();
+ if (!$count) {
+ $count = 0;
+ }
+ $tcount = $this->_dom->createElement('slash:comments');
+ $tcount->nodeValue = $count;
+ $root->appendChild($tcount);
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php
new file mode 100644
index 0000000000..69e731d4ba
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php
@@ -0,0 +1,145 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_Threading_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'rss') {
+ return; // Atom 1.0 only
+ }
+ $this->_setCommentLink($this->_dom, $this->_base);
+ $this->_setCommentFeedLinks($this->_dom, $this->_base);
+ $this->_setCommentCount($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append entry namespaces
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:thr',
+ 'http://purl.org/syndication/thread/1.0');
+ }
+
+ /**
+ * Set comment link
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentLink(DOMDocument $dom, DOMElement $root)
+ {
+ $link = $this->getDataContainer()->getCommentLink();
+ if (!$link) {
+ return;
+ }
+ $clink = $this->_dom->createElement('link');
+ $clink->setAttribute('rel', 'replies');
+ $clink->setAttribute('type', 'text/html');
+ $clink->setAttribute('href', $link);
+ $count = $this->getDataContainer()->getCommentCount();
+ if (!is_null($count)) {
+ $clink->setAttribute('thr:count', $count);
+ }
+ $root->appendChild($clink);
+ $this->_called = true;
+ }
+
+ /**
+ * Set comment feed links
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentFeedLinks(DOMDocument $dom, DOMElement $root)
+ {
+ $links = $this->getDataContainer()->getCommentFeedLinks();
+ if (!$links || empty($links)) {
+ return;
+ }
+ foreach ($links as $link) {
+ $flink = $this->_dom->createElement('link');
+ $flink->setAttribute('rel', 'replies');
+ $flink->setAttribute('type', 'application/'. $link['type'] .'+xml');
+ $flink->setAttribute('href', $link['uri']);
+ $count = $this->getDataContainer()->getCommentCount();
+ if (!is_null($count)) {
+ $flink->setAttribute('thr:count', $count);
+ }
+ $root->appendChild($flink);
+ $this->_called = true;
+ }
+ }
+
+ /**
+ * Set entry comment count
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentCount(DOMDocument $dom, DOMElement $root)
+ {
+ $count = $this->getDataContainer()->getCommentCount();
+ if (is_null($count)) {
+ return;
+ }
+ $tcount = $this->_dom->createElement('thr:total');
+ $tcount->nodeValue = $count;
+ $root->appendChild($tcount);
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php b/libs/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php
new file mode 100644
index 0000000000..c57244ae4b
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php
@@ -0,0 +1,96 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Entry.php 20326 2010-01-16 00:20:43Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Extension_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Extension_WellFormedWeb_Renderer_Entry
+ extends Zend_Feed_Writer_Extension_RendererAbstract
+{
+
+ /**
+ * Set to TRUE if a rendering method actually renders something. This
+ * is used to prevent premature appending of a XML namespace declaration
+ * until an element which requires it is actually appended.
+ *
+ * @var bool
+ */
+ protected $_called = false;
+
+ /**
+ * Render entry
+ *
+ * @return void
+ */
+ public function render()
+ {
+ if (strtolower($this->getType()) == 'atom') {
+ return; // RSS 2.0 only
+ }
+ $this->_setCommentFeedLinks($this->_dom, $this->_base);
+ if ($this->_called) {
+ $this->_appendNamespaces();
+ }
+ }
+
+ /**
+ * Append entry namespaces
+ *
+ * @return void
+ */
+ protected function _appendNamespaces()
+ {
+ $this->getRootElement()->setAttribute('xmlns:wfw',
+ 'http://wellformedweb.org/CommentAPI/');
+ }
+
+ /**
+ * Set entry comment feed links
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentFeedLinks(DOMDocument $dom, DOMElement $root)
+ {
+ $links = $this->getDataContainer()->getCommentFeedLinks();
+ if (!$links || empty($links)) {
+ return;
+ }
+ foreach ($links as $link) {
+ if ($link['type'] == 'rss') {
+ $flink = $this->_dom->createElement('wfw:commentRss');
+ $text = $dom->createTextNode($link['uri']);
+ $flink->appendChild($text);
+ $root->appendChild($flink);
+ }
+ }
+ $this->_called = true;
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Feed.php b/libs/Zend/Feed/Writer/Feed.php
new file mode 100644
index 0000000000..724caed1a2
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Feed.php
@@ -0,0 +1,281 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20519 2010-01-22 14:06:24Z padraic $
+ */
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Feed_Writer
+ */
+// require_once 'Zend/Feed/Writer.php';
+
+/**
+ * @see Zend_Feed_Writer_Entry
+ */
+// require_once 'Zend/Feed/Writer/Entry.php';
+
+/**
+ * @see Zend_Feed_Writer_Deleted
+ */
+// require_once 'Zend/Feed/Writer/Deleted.php';
+
+/**
+ * @see Zend_Feed_Writer_Renderer_Feed_Atom
+ */
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Atom.php';
+
+/**
+ * @see Zend_Feed_Writer_Renderer_Feed_Rss
+ */
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Rss.php';
+
+// require_once 'Zend/Feed/Writer/Feed/FeedAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Feed extends Zend_Feed_Writer_Feed_FeedAbstract
+implements Iterator, Countable
+{
+
+ /**
+ * Contains all entry objects
+ *
+ * @var array
+ */
+ protected $_entries = array();
+
+ /**
+ * A pointer for the iterator to keep track of the entries array
+ *
+ * @var int
+ */
+ protected $_entriesKey = 0;
+
+ /**
+ * Creates a new Zend_Feed_Writer_Entry data container for use. This is NOT
+ * added to the current feed automatically, but is necessary to create a
+ * container with some initial values preset based on the current feed data.
+ *
+ * @return Zend_Feed_Writer_Entry
+ */
+ public function createEntry()
+ {
+ $entry = new Zend_Feed_Writer_Entry;
+ if ($this->getEncoding()) {
+ $entry->setEncoding($this->getEncoding());
+ }
+ $entry->setType($this->getType());
+ return $entry;
+ }
+
+ /**
+ * Appends a Zend_Feed_Writer_Deleted object representing a new entry tombstone
+ * to the feed data container's internal group of entries.
+ *
+ * @param Zend_Feed_Writer_Deleted $entry
+ */
+ public function addTombstone(Zend_Feed_Writer_Deleted $deleted)
+ {
+ $this->_entries[] = $deleted;
+ }
+
+ /**
+ * Creates a new Zend_Feed_Writer_Deleted data container for use. This is NOT
+ * added to the current feed automatically, but is necessary to create a
+ * container with some initial values preset based on the current feed data.
+ *
+ * @return Zend_Feed_Writer_Deleted
+ */
+ public function createTombstone()
+ {
+ $deleted = new Zend_Feed_Writer_Deleted;
+ if ($this->getEncoding()) {
+ $deleted->setEncoding($this->getEncoding());
+ }
+ $deleted->setType($this->getType());
+ return $deleted;
+ }
+
+ /**
+ * Appends a Zend_Feed_Writer_Entry object representing a new entry/item
+ * the feed data container's internal group of entries.
+ *
+ * @param Zend_Feed_Writer_Entry $entry
+ */
+ public function addEntry(Zend_Feed_Writer_Entry $entry)
+ {
+ $this->_entries[] = $entry;
+ }
+
+ /**
+ * Removes a specific indexed entry from the internal queue. Entries must be
+ * added to a feed container in order to be indexed.
+ *
+ * @param int $index
+ */
+ public function removeEntry($index)
+ {
+ if (isset($this->_entries[$index])) {
+ unset($this->_entries[$index]);
+ }
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Undefined index: ' . $index . '. Entry does not exist.');
+ }
+
+ /**
+ * Retrieve a specific indexed entry from the internal queue. Entries must be
+ * added to a feed container in order to be indexed.
+ *
+ * @param int $index
+ */
+ public function getEntry($index = 0)
+ {
+ if (isset($this->_entries[$index])) {
+ return $this->_entries[$index];
+ }
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Undefined index: ' . $index . '. Entry does not exist.');
+ }
+
+ /**
+ * Orders all indexed entries by date, thus offering date ordered readable
+ * content where a parser (or Homo Sapien) ignores the generic rule that
+ * XML element order is irrelevant and has no intrinsic meaning.
+ *
+ * Using this method will alter the original indexation.
+ *
+ * @return void
+ */
+ public function orderByDate()
+ {
+ /**
+ * Could do with some improvement for performance perhaps
+ */
+ $timestamp = time();
+ $entries = array();
+ foreach ($this->_entries as $entry) {
+ if ($entry->getDateModified()) {
+ $timestamp = (int) $entry->getDateModified()->get(Zend_Date::TIMESTAMP);
+ } elseif ($entry->getDateCreated()) {
+ $timestamp = (int) $entry->getDateCreated()->get(Zend_Date::TIMESTAMP);
+ }
+ $entries[$timestamp] = $entry;
+ }
+ krsort($entries, SORT_NUMERIC);
+ $this->_entries = array_values($entries);
+ }
+
+ /**
+ * Get the number of feed entries.
+ * Required by the Iterator interface.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->_entries);
+ }
+
+ /**
+ * Return the current entry
+ *
+ * @return Zend_Feed_Reader_Entry_Interface
+ */
+ public function current()
+ {
+ return $this->_entries[$this->key()];
+ }
+
+ /**
+ * Return the current feed key
+ *
+ * @return unknown
+ */
+ public function key()
+ {
+ return $this->_entriesKey;
+ }
+
+ /**
+ * Move the feed pointer forward
+ *
+ * @return void
+ */
+ public function next()
+ {
+ ++$this->_entriesKey;
+ }
+
+ /**
+ * Reset the pointer in the feed object
+ *
+ * @return void
+ */
+ public function rewind()
+ {
+ $this->_entriesKey = 0;
+ }
+
+ /**
+ * Check to see if the iterator is still valid
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return 0 <= $this->_entriesKey && $this->_entriesKey < $this->count();
+ }
+
+ /**
+ * Attempt to build and return the feed resulting from the data set
+ *
+ * @param $type The feed type "rss" or "atom" to export as
+ * @return string
+ */
+ public function export($type, $ignoreExceptions = false)
+ {
+ $this->setType(strtolower($type));
+ $type = ucfirst($this->getType());
+ if ($type !== 'Rss' && $type !== 'Atom') {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid feed type specified: ' . $type . '.'
+ . ' Should be one of "rss" or "atom".');
+ }
+ $renderClass = 'Zend_Feed_Writer_Renderer_Feed_' . $type;
+ $renderer = new $renderClass($this);
+ if ($ignoreExceptions) {
+ $renderer->ignoreExceptions();
+ }
+ return $renderer->render()->saveXml();
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Feed/FeedAbstract.php b/libs/Zend/Feed/Writer/Feed/FeedAbstract.php
new file mode 100644
index 0000000000..bc2a0fa06f
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Feed/FeedAbstract.php
@@ -0,0 +1,805 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Date.php';
+
+/**
+ * @see Zend_Date
+ */
+// require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Feed_Writer
+ */
+// require_once 'Zend/Feed/Writer.php';
+
+/**
+ * @see Zend_Feed_Writer_Entry
+ */
+// require_once 'Zend/Feed/Writer/Entry.php';
+
+/**
+ * @see Zend_Feed_Writer_Renderer_Feed_Atom
+ */
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Atom.php';
+
+/**
+ * @see Zend_Feed_Writer_Renderer_Feed_Rss
+ */
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Rss.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Feed_FeedAbstract
+{
+ /**
+ * Contains all Feed level date to append in feed output
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Holds the value "atom" or "rss" depending on the feed type set when
+ * when last exported.
+ *
+ * @var string
+ */
+ protected $_type = null;
+
+ /**
+ * Constructor: Primarily triggers the registration of core extensions and
+ * loads those appropriate to this data container.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ Zend_Feed_Writer::registerCoreExtensions();
+ $this->_loadExtensions();
+ }
+
+ /**
+ * Set a single author
+ *
+ * @param int $index
+ * @return string|null
+ */
+ public function addAuthor($name, $email = null, $uri = null)
+ {
+ $author = array();
+ if (is_array($name)) {
+ if (!array_key_exists('name', $name) || empty($name['name']) || !is_string($name['name'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: author array must include a "name" key with a non-empty string value');
+ }
+ $author['name'] = $name['name'];
+ if (isset($name['email'])) {
+ if (empty($name['email']) || !is_string($name['email'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "email" array value must be a non-empty string');
+ }
+ $author['email'] = $name['email'];
+ }
+ if (isset($name['uri'])) {
+ if (empty($name['uri']) || !is_string($name['uri']) || !Zend_Uri::check($name['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI');
+ }
+ $author['uri'] = $name['uri'];
+ }
+ } else {
+ if (empty($name['name']) || !is_string($name['name'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "name" must be a non-empty string value');
+ }
+ $author['name'] = $name;
+ if (isset($email)) {
+ if (empty($email) || !is_string($email)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "email" value must be a non-empty string');
+ }
+ $author['email'] = $email;
+ }
+ if (isset($uri)) {
+ if (empty($uri) || !is_string($uri) || !Zend_Uri::check($uri)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" value must be a non-empty string and valid URI/IRI');
+ }
+ $author['uri'] = $uri;
+ }
+ }
+ $this->_data['authors'][] = $author;
+ }
+
+ /**
+ * Set an array with feed authors
+ *
+ * @return array
+ */
+ public function addAuthors(array $authors)
+ {
+ foreach($authors as $author) {
+ $this->addAuthor($author);
+ }
+ }
+
+ /**
+ * Set the copyright entry
+ *
+ * @return string|null
+ */
+ public function setCopyright($copyright)
+ {
+ if (empty($copyright) || !is_string($copyright)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['copyright'] = $copyright;
+ }
+
+ /**
+ * Set the feed creation date
+ *
+ * @param null|integer|Zend_Date
+ */
+ public function setDateCreated($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['dateCreated'] = $zdate;
+ }
+
+ /**
+ * Set the feed modification date
+ *
+ * @param null|integer|Zend_Date
+ */
+ public function setDateModified($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['dateModified'] = $zdate;
+ }
+
+ /**
+ * Set the feed last-build date. Ignored for Atom 1.0.
+ *
+ * @param null|integer|Zend_Date
+ */
+ public function setLastBuildDate($date = null)
+ {
+ $zdate = null;
+ if (is_null($date)) {
+ $zdate = new Zend_Date;
+ } elseif (ctype_digit($date) && strlen($date) == 10) {
+ $zdate = new Zend_Date($date, Zend_Date::TIMESTAMP);
+ } elseif ($date instanceof Zend_Date) {
+ $zdate = $date;
+ } else {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid Zend_Date object or UNIX Timestamp passed as parameter');
+ }
+ $this->_data['lastBuildDate'] = $zdate;
+ }
+
+ /**
+ * Set the feed description
+ *
+ * @return string|null
+ */
+ public function setDescription($description)
+ {
+ if (empty($description) || !is_string($description)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['description'] = $description;
+ }
+
+ /**
+ * Set the feed generator entry
+ *
+ * @return string|null
+ */
+ public function setGenerator($name, $version = null, $uri = null)
+ {
+ if (is_array($name)) {
+ $data = $name;
+ if (empty($data['name']) || !is_string($data['name'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "name" must be a non-empty string');
+ }
+ $generator = array('name' => $data['name']);
+ if (isset($data['version'])) {
+ if (empty($data['version']) || !is_string($data['version'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "version" must be a non-empty string');
+ }
+ $generator['version'] = $data['version'];
+ }
+ if (isset($data['uri'])) {
+ if (empty($data['uri']) || !is_string($data['uri']) || !Zend_Uri::check($data['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" must be a non-empty string and a valid URI/IRI');
+ }
+ $generator['uri'] = $data['uri'];
+ }
+ } else {
+ if (empty($name) || !is_string($name)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "name" must be a non-empty string');
+ }
+ $generator = array('name' => $name);
+ if (isset($version)) {
+ if (empty($version) || !is_string($version)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "version" must be a non-empty string');
+ }
+ $generator['version'] = $version;
+ }
+ if (isset($uri)) {
+ if (empty($uri) || !is_string($uri) || !Zend_Uri::check($uri)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "uri" must be a non-empty string and a valid URI/IRI');
+ }
+ $generator['uri'] = $uri;
+ }
+ }
+ $this->_data['generator'] = $generator;
+ }
+
+ /**
+ * Set the feed ID - URI or URN (via PCRE pattern) supported
+ *
+ * @param string $id
+ */
+ public function setId($id)
+ {
+ if ((empty($id) || !is_string($id) || !Zend_Uri::check($id)) &&
+ !preg_match("#^urn:[a-zA-Z0-9][a-zA-Z0-9\-]{1,31}:([a-zA-Z0-9\(\)\+\,\.\:\=\@\;\$\_\!\*\-]|%[0-9a-fA-F]{2})*#", $id)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['id'] = $id;
+ }
+
+ /**
+ * Set a feed image (URI at minimum). Parameter is a single array with the
+ * required key 'uri'. When rendering as RSS, the required keys are 'uri',
+ * 'title' and 'link'. RSS also specifies three optional parameters 'width',
+ * 'height' and 'description'. Only 'uri' is required and used for Atom rendering.
+ *
+ * @param array $data
+ */
+ public function setImage(array $data)
+ {
+ if (empty($data['uri']) || !is_string($data['uri'])
+ || !Zend_Uri::check($data['uri'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter \'uri\''
+ . ' must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['image'] = $data;
+ }
+
+ /**
+ * Set the feed language
+ *
+ * @return string|null
+ */
+ public function setLanguage($language)
+ {
+ if (empty($language) || !is_string($language)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['language'] = $language;
+ }
+
+ /**
+ * Set a link to the HTML source
+ *
+ * @param string $link
+ */
+ public function setLink($link)
+ {
+ if (empty($link) || !is_string($link) || !Zend_Uri::check($link)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['link'] = $link;
+ }
+
+ /**
+ * Set a link to an XML feed for any feed type/version
+ *
+ * @return string|null
+ */
+ public function setFeedLink($link, $type)
+ {
+ if (empty($link) || !is_string($link) || !Zend_Uri::check($link)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "link"" must be a non-empty string and valid URI/IRI');
+ }
+ if (!in_array(strtolower($type), array('rss', 'rdf', 'atom'))) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "type"; You must declare the type of feed the link points to, i.e. RSS, RDF or Atom');
+ }
+ $this->_data['feedLinks'][strtolower($type)] = $link;
+ }
+
+ /**
+ * Set the feed title
+ *
+ * @return string|null
+ */
+ public function setTitle($title)
+ {
+ if (empty($title) || !is_string($title)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['title'] = $title;
+ }
+
+ /**
+ * Set the feed character encoding
+ *
+ * @param string $encoding
+ */
+ public function setEncoding($encoding)
+ {
+ if (empty($encoding) || !is_string($encoding)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: parameter must be a non-empty string');
+ }
+ $this->_data['encoding'] = $encoding;
+ }
+
+ /**
+ * Set the feed's base URL
+ *
+ * @param string $url
+ */
+ public function setBaseUrl($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "url" array value'
+ . ' must be a non-empty string and valid URI/IRI');
+ }
+ $this->_data['baseUrl'] = $url;
+ }
+
+ /**
+ * Add a Pubsubhubbub hub endpoint URL
+ *
+ * @param string $url
+ */
+ public function addHub($url)
+ {
+ if (empty($url) || !is_string($url) || !Zend_Uri::check($url)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: "url" array value'
+ . ' must be a non-empty string and valid URI/IRI');
+ }
+ if (!isset($this->_data['hubs'])) {
+ $this->_data['hubs'] = array();
+ }
+ $this->_data['hubs'][] = $url;
+ }
+
+ /**
+ * Add Pubsubhubbub hub endpoint URLs
+ *
+ * @param array $urls
+ */
+ public function addHubs(array $urls)
+ {
+ foreach ($urls as $url) {
+ $this->addHub($url);
+ }
+ }
+
+ /**
+ * Add a feed category
+ *
+ * @param string $category
+ */
+ public function addCategory(array $category)
+ {
+ if (!isset($category['term'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Each category must be an array and '
+ . 'contain at least a "term" element containing the machine '
+ . ' readable category name');
+ }
+ if (isset($category['scheme'])) {
+ if (empty($category['scheme'])
+ || !is_string($category['scheme'])
+ || !Zend_Uri::check($category['scheme'])
+ ) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('The Atom scheme or RSS domain of'
+ . ' a category must be a valid URI');
+ }
+ }
+ if (!isset($this->_data['categories'])) {
+ $this->_data['categories'] = array();
+ }
+ $this->_data['categories'][] = $category;
+ }
+
+ /**
+ * Set an array of feed categories
+ *
+ * @param array $categories
+ */
+ public function addCategories(array $categories)
+ {
+ foreach ($categories as $category) {
+ $this->addCategory($category);
+ }
+ }
+
+ /**
+ * Get a single author
+ *
+ * @param int $index
+ * @return string|null
+ */
+ public function getAuthor($index = 0)
+ {
+ if (isset($this->_data['authors'][$index])) {
+ return $this->_data['authors'][$index];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get an array with feed authors
+ *
+ * @return array
+ */
+ public function getAuthors()
+ {
+ if (!array_key_exists('authors', $this->_data)) {
+ return null;
+ }
+ return $this->_data['authors'];
+ }
+
+ /**
+ * Get the copyright entry
+ *
+ * @return string|null
+ */
+ public function getCopyright()
+ {
+ if (!array_key_exists('copyright', $this->_data)) {
+ return null;
+ }
+ return $this->_data['copyright'];
+ }
+
+ /**
+ * Get the feed creation date
+ *
+ * @return string|null
+ */
+ public function getDateCreated()
+ {
+ if (!array_key_exists('dateCreated', $this->_data)) {
+ return null;
+ }
+ return $this->_data['dateCreated'];
+ }
+
+ /**
+ * Get the feed modification date
+ *
+ * @return string|null
+ */
+ public function getDateModified()
+ {
+ if (!array_key_exists('dateModified', $this->_data)) {
+ return null;
+ }
+ return $this->_data['dateModified'];
+ }
+
+ /**
+ * Get the feed last-build date
+ *
+ * @return string|null
+ */
+ public function getLastBuildDate()
+ {
+ if (!array_key_exists('lastBuildDate', $this->_data)) {
+ return null;
+ }
+ return $this->_data['lastBuildDate'];
+ }
+
+ /**
+ * Get the feed description
+ *
+ * @return string|null
+ */
+ public function getDescription()
+ {
+ if (!array_key_exists('description', $this->_data)) {
+ return null;
+ }
+ return $this->_data['description'];
+ }
+
+ /**
+ * Get the feed generator entry
+ *
+ * @return string|null
+ */
+ public function getGenerator()
+ {
+ if (!array_key_exists('generator', $this->_data)) {
+ return null;
+ }
+ return $this->_data['generator'];
+ }
+
+ /**
+ * Get the feed ID
+ *
+ * @return string|null
+ */
+ public function getId()
+ {
+ if (!array_key_exists('id', $this->_data)) {
+ return null;
+ }
+ return $this->_data['id'];
+ }
+
+ /**
+ * Get the feed image URI
+ *
+ * @return array
+ */
+ public function getImage()
+ {
+ if (!array_key_exists('image', $this->_data)) {
+ return null;
+ }
+ return $this->_data['image'];
+ }
+
+ /**
+ * Get the feed language
+ *
+ * @return string|null
+ */
+ public function getLanguage()
+ {
+ if (!array_key_exists('language', $this->_data)) {
+ return null;
+ }
+ return $this->_data['language'];
+ }
+
+ /**
+ * Get a link to the HTML source
+ *
+ * @return string|null
+ */
+ public function getLink()
+ {
+ if (!array_key_exists('link', $this->_data)) {
+ return null;
+ }
+ return $this->_data['link'];
+ }
+
+ /**
+ * Get a link to the XML feed
+ *
+ * @return string|null
+ */
+ public function getFeedLinks()
+ {
+ if (!array_key_exists('feedLinks', $this->_data)) {
+ return null;
+ }
+ return $this->_data['feedLinks'];
+ }
+
+ /**
+ * Get the feed title
+ *
+ * @return string|null
+ */
+ public function getTitle()
+ {
+ if (!array_key_exists('title', $this->_data)) {
+ return null;
+ }
+ return $this->_data['title'];
+ }
+
+ /**
+ * Get the feed character encoding
+ *
+ * @return string|null
+ */
+ public function getEncoding()
+ {
+ if (!array_key_exists('encoding', $this->_data)) {
+ return 'UTF-8';
+ }
+ return $this->_data['encoding'];
+ }
+
+ /**
+ * Get the feed's base url
+ *
+ * @return string|null
+ */
+ public function getBaseUrl()
+ {
+ if (!array_key_exists('baseUrl', $this->_data)) {
+ return null;
+ }
+ return $this->_data['baseUrl'];
+ }
+
+ /**
+ * Get the URLs used as Pubsubhubbub hubs endpoints
+ *
+ * @return string|null
+ */
+ public function getHubs()
+ {
+ if (!array_key_exists('hubs', $this->_data)) {
+ return null;
+ }
+ return $this->_data['hubs'];
+ }
+
+ /**
+ * Get the feed categories
+ *
+ * @return string|null
+ */
+ public function getCategories()
+ {
+ if (!array_key_exists('categories', $this->_data)) {
+ return null;
+ }
+ return $this->_data['categories'];
+ }
+
+ /**
+ * Resets the instance and deletes all data
+ *
+ * @return void
+ */
+ public function reset()
+ {
+ $this->_data = array();
+ }
+
+ /**
+ * Set the current feed type being exported to "rss" or "atom". This allows
+ * other objects to gracefully choose whether to execute or not, depending
+ * on their appropriateness for the current type, e.g. renderers.
+ *
+ * @param string $type
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+ }
+
+ /**
+ * Retrieve the current or last feed type exported.
+ *
+ * @return string Value will be "rss" or "atom"
+ */
+ public function getType()
+ {
+ return $this->_type;
+ }
+
+ /**
+ * Unset a specific data point
+ *
+ * @param string $name
+ */
+ public function remove($name)
+ {
+ if (isset($this->_data[$name])) {
+ unset($this->_data[$name]);
+ }
+ }
+
+ /**
+ * Method overloading: call given method on first extension implementing it
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ * @throws Zend_Feed_Exception if no extensions implements the method
+ */
+ public function __call($method, $args)
+ {
+ foreach ($this->_extensions as $extension) {
+ try {
+ return call_user_func_array(array($extension, $method), $args);
+ } catch (Zend_Feed_Writer_Exception_InvalidMethodException $e) {
+ }
+ }
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Method: ' . $method
+ . ' does not exist and could not be located on a registered Extension');
+ }
+
+ /**
+ * Load extensions from Zend_Feed_Writer
+ *
+ * @return void
+ */
+ protected function _loadExtensions()
+ {
+ $all = Zend_Feed_Writer::getExtensions();
+ $exts = $all['feed'];
+ foreach ($exts as $ext) {
+ $className = Zend_Feed_Writer::getPluginLoader()->getClassName($ext);
+ $this->_extensions[$ext] = new $className();
+ $this->_extensions[$ext]->setEncoding($this->getEncoding());
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Entry/Atom.php b/libs/Zend/Feed/Writer/Renderer/Entry/Atom.php
new file mode 100644
index 0000000000..76095e89f0
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Entry/Atom.php
@@ -0,0 +1,410 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 22065 2010-04-30 14:04:57Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Renderer_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Atom/Source.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Entry_Atom
+ extends Zend_Feed_Writer_Renderer_RendererAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Entry $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Entry $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render atom entry
+ *
+ * @return Zend_Feed_Writer_Renderer_Entry_Atom
+ */
+ public function render()
+ {
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $entry = $this->_dom->createElementNS(Zend_Feed_Writer::NAMESPACE_ATOM_10, 'entry');
+ $this->_dom->appendChild($entry);
+
+ $this->_setSource($this->_dom, $entry);
+ $this->_setTitle($this->_dom, $entry);
+ $this->_setDescription($this->_dom, $entry);
+ $this->_setDateCreated($this->_dom, $entry);
+ $this->_setDateModified($this->_dom, $entry);
+ $this->_setLink($this->_dom, $entry);
+ $this->_setId($this->_dom, $entry);
+ $this->_setAuthors($this->_dom, $entry);
+ $this->_setEnclosure($this->_dom, $entry);
+ $this->_setContent($this->_dom, $entry);
+ $this->_setCategories($this->_dom, $entry);
+
+ foreach ($this->_extensions as $ext) {
+ $ext->setType($this->getType());
+ $ext->setRootElement($this->getRootElement());
+ $ext->setDomDocument($this->getDomDocument(), $entry);
+ $ext->render();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set entry title
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setTitle(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getTitle()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 entry elements MUST contain exactly one'
+ . ' atom:title element but a title has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $title = $dom->createElement('title');
+ $root->appendChild($title);
+ $title->setAttribute('type', 'html');
+ $cdata = $dom->createCDATASection($this->getDataContainer()->getTitle());
+ $title->appendChild($cdata);
+ }
+
+ /**
+ * Set entry description
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDescription(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDescription()) {
+ return; // unless src content or base64
+ }
+ $subtitle = $dom->createElement('summary');
+ $root->appendChild($subtitle);
+ $subtitle->setAttribute('type', 'html');
+ $cdata = $dom->createCDATASection(
+ $this->getDataContainer()->getDescription()
+ );
+ $subtitle->appendChild($cdata);
+ }
+
+ /**
+ * Set date entry was modified
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateModified()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 entry elements MUST contain exactly one'
+ . ' atom:updated element but a modification date has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ $updated = $dom->createElement('updated');
+ $root->appendChild($updated);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getDateModified()->get(Zend_Date::ISO_8601)
+ );
+ $updated->appendChild($text);
+ }
+
+ /**
+ * Set date entry was created
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+ {
+ if (!$this->getDataContainer()->getDateCreated()) {
+ return;
+ }
+ $el = $dom->createElement('published');
+ $root->appendChild($el);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getDateCreated()->get(Zend_Date::ISO_8601)
+ );
+ $el->appendChild($text);
+ }
+
+ /**
+ * Set entry authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->_container->getAuthors();
+ if ((!$authors || empty($authors))) {
+ /**
+ * This will actually trigger an Exception at the feed level if
+ * a feed level author is not set.
+ */
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('author');
+ $name = $this->_dom->createElement('name');
+ $author->appendChild($name);
+ $root->appendChild($author);
+ $text = $dom->createTextNode($data['name']);
+ $name->appendChild($text);
+ if (array_key_exists('email', $data)) {
+ $email = $this->_dom->createElement('email');
+ $author->appendChild($email);
+ $text = $dom->createTextNode($data['email']);
+ $email->appendChild($text);
+ }
+ if (array_key_exists('uri', $data)) {
+ $uri = $this->_dom->createElement('uri');
+ $author->appendChild($uri);
+ $text = $dom->createTextNode($data['uri']);
+ $uri->appendChild($text);
+ }
+ }
+ }
+
+ /**
+ * Set entry enclosure
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setEnclosure(DOMDocument $dom, DOMElement $root)
+ {
+ $data = $this->_container->getEnclosure();
+ if ((!$data || empty($data))) {
+ return;
+ }
+ $enclosure = $this->_dom->createElement('link');
+ $enclosure->setAttribute('rel', 'enclosure');
+ if (isset($data['type'])) {
+ $enclosure->setAttribute('type', $data['type']);
+ }
+ if (isset($data['length'])) {
+ $enclosure->setAttribute('length', $data['length']);
+ }
+ $enclosure->setAttribute('href', $data['uri']);
+ $root->appendChild($enclosure);
+ }
+
+ protected function _setLink(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getLink()) {
+ return;
+ }
+ $link = $dom->createElement('link');
+ $root->appendChild($link);
+ $link->setAttribute('rel', 'alternate');
+ $link->setAttribute('type', 'text/html');
+ $link->setAttribute('href', $this->getDataContainer()->getLink());
+ }
+
+ /**
+ * Set entry identifier
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setId(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getId()
+ && !$this->getDataContainer()->getLink()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 entry elements MUST contain exactly one '
+ . 'atom:id element, or as an alternative, we can use the same '
+ . 'value as atom:link however neither a suitable link nor an '
+ . 'id have been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ if (!$this->getDataContainer()->getId()) {
+ $this->getDataContainer()->setId(
+ $this->getDataContainer()->getLink());
+ }
+ if (!Zend_Uri::check($this->getDataContainer()->getId()) &&
+ !preg_match("#^urn:[a-zA-Z0-9][a-zA-Z0-9\-]{1,31}:([a-zA-Z0-9\(\)\+\,\.\:\=\@\;\$\_\!\*\-]|%[0-9a-fA-F]{2})*#", $this->getDataContainer()->getId())) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Atom 1.0 IDs must be a valid URI/IRI');
+ }
+ $id = $dom->createElement('id');
+ $root->appendChild($id);
+ $text = $dom->createTextNode($this->getDataContainer()->getId());
+ $id->appendChild($text);
+ }
+
+ /**
+ * Set entry content
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setContent(DOMDocument $dom, DOMElement $root)
+ {
+ $content = $this->getDataContainer()->getContent();
+ if (!$content && !$this->getDataContainer()->getLink()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 entry elements MUST contain exactly one '
+ . 'atom:content element, or as an alternative, at least one link '
+ . 'with a rel attribute of "alternate" to indicate an alternate '
+ . 'method to consume the content.';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ if (!$content) {
+ return;
+ }
+ $element = $dom->createElement('content');
+ $element->setAttribute('type', 'xhtml');
+ $xhtmlElement = $this->_loadXhtml($content);
+ $xhtml = $dom->importNode($xhtmlElement, true);
+ $element->appendChild($xhtml);
+ $root->appendChild($element);
+ }
+
+ /**
+ * Load a HTML string and attempt to normalise to XML
+ */
+ protected function _loadXhtml($content)
+ {
+ $xhtml = '';
+ if (class_exists('tidy', false)) {
+ $tidy = new tidy;
+ $config = array(
+ 'output-xhtml' => true,
+ 'show-body-only' => true,
+ 'quote-nbsp' => false
+ );
+ $encoding = str_replace('-', '', $this->getEncoding());
+ $tidy->parseString($content, $config, $encoding);
+ $tidy->cleanRepair();
+ $xhtml = (string) $tidy;
+ } else {
+ $xhtml = $content;
+ }
+ $xhtml = preg_replace(array(
+ "/(<[\/]?)([a-zA-Z]+)/"
+ ), '$1xhtml:$2', $xhtml);
+ $dom = new DOMDocument('1.0', $this->getEncoding());
+ $dom->loadXML('<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">'
+ . $xhtml . '</xhtml:div>');
+ return $dom->documentElement;
+ }
+
+ /**
+ * Set entry cateories
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCategories(DOMDocument $dom, DOMElement $root)
+ {
+ $categories = $this->getDataContainer()->getCategories();
+ if (!$categories) {
+ return;
+ }
+ foreach ($categories as $cat) {
+ $category = $dom->createElement('category');
+ $category->setAttribute('term', $cat['term']);
+ if (isset($cat['label'])) {
+ $category->setAttribute('label', $cat['label']);
+ } else {
+ $category->setAttribute('label', $cat['term']);
+ }
+ if (isset($cat['scheme'])) {
+ $category->setAttribute('scheme', $cat['scheme']);
+ }
+ $root->appendChild($category);
+ }
+ }
+
+ /**
+ * Append Source element (Atom 1.0 Feed Metadata)
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setSource(DOMDocument $dom, DOMElement $root)
+ {
+ $source = $this->getDataContainer()->getSource();
+ if (!$source) {
+ return;
+ }
+ $renderer = new Zend_Feed_Writer_Renderer_Feed_Atom_Source($source);
+ $renderer->setType($this->getType());
+ $element = $renderer->render()->getElement();
+ $imported = $dom->importNode($element, true);
+ $root->appendChild($imported);
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php b/libs/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php
new file mode 100644
index 0000000000..fb75262935
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php
@@ -0,0 +1,121 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 20506 2010-01-21 22:19:05Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Renderer_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Entry_Atom_Deleted
+ extends Zend_Feed_Writer_Renderer_RendererAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Deleted $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Deleted $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render atom entry
+ *
+ * @return Zend_Feed_Writer_Renderer_Entry_Atom
+ */
+ public function render()
+ {
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $entry = $this->_dom->createElement('at:deleted-entry');
+ $this->_dom->appendChild($entry);
+
+ $entry->setAttribute('ref', $this->_container->getReference());
+ $entry->setAttribute('when', $this->_container->getWhen()->get(Zend_Date::ISO_8601));
+
+ $this->_setBy($this->_dom, $entry);
+ $this->_setComment($this->_dom, $entry);
+
+ return $this;
+ }
+
+ /**
+ * Set tombstone comment
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setComment(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getComment()) {
+ return;
+ }
+ $c = $dom->createElement('at:comment');
+ $root->appendChild($c);
+ $c->setAttribute('type', 'html');
+ $cdata = $dom->createCDATASection($this->getDataContainer()->getComment());
+ $c->appendChild($cdata);
+ }
+
+ /**
+ * Set entry authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setBy(DOMDocument $dom, DOMElement $root)
+ {
+ $data = $this->_container->getBy();
+ if ((!$data || empty($data))) {
+ return;
+ }
+ $author = $this->_dom->createElement('at:by');
+ $name = $this->_dom->createElement('name');
+ $author->appendChild($name);
+ $root->appendChild($author);
+ $text = $dom->createTextNode($data['name']);
+ $name->appendChild($text);
+ if (array_key_exists('email', $data)) {
+ $email = $this->_dom->createElement('email');
+ $author->appendChild($email);
+ $text = $dom->createTextNode($data['email']);
+ $email->appendChild($text);
+ }
+ if (array_key_exists('uri', $data)) {
+ $uri = $this->_dom->createElement('uri');
+ $author->appendChild($uri);
+ $text = $dom->createTextNode($data['uri']);
+ $uri->appendChild($text);
+ }
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Entry/Rss.php b/libs/Zend/Feed/Writer/Renderer/Entry/Rss.php
new file mode 100644
index 0000000000..74e80f5707
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Entry/Rss.php
@@ -0,0 +1,346 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Rss.php 22065 2010-04-30 14:04:57Z padraic $
+ */
+
+/**
+ * @see Zend_Feed_Writer_Renderer_RendererAbstract
+ */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Entry_Rss
+ extends Zend_Feed_Writer_Renderer_RendererAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Entry $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Entry $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render RSS entry
+ *
+ * @return Zend_Feed_Writer_Renderer_Entry_Rss
+ */
+ public function render()
+ {
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $this->_dom->substituteEntities = false;
+ $entry = $this->_dom->createElement('item');
+ $this->_dom->appendChild($entry);
+
+ $this->_setTitle($this->_dom, $entry);
+ $this->_setDescription($this->_dom, $entry);
+ $this->_setDateCreated($this->_dom, $entry);
+ $this->_setDateModified($this->_dom, $entry);
+ $this->_setLink($this->_dom, $entry);
+ $this->_setId($this->_dom, $entry);
+ $this->_setAuthors($this->_dom, $entry);
+ $this->_setEnclosure($this->_dom, $entry);
+ $this->_setCommentLink($this->_dom, $entry);
+ $this->_setCategories($this->_dom, $entry);
+ foreach ($this->_extensions as $ext) {
+ $ext->setType($this->getType());
+ $ext->setRootElement($this->getRootElement());
+ $ext->setDomDocument($this->getDomDocument(), $entry);
+ $ext->render();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set entry title
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setTitle(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDescription()
+ && !$this->getDataContainer()->getTitle()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 entry elements SHOULD contain exactly one'
+ . ' title element but a title has not been set. In addition, there'
+ . ' is no description as required in the absence of a title.';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $title = $dom->createElement('title');
+ $root->appendChild($title);
+ $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+ $title->appendChild($text);
+ }
+
+ /**
+ * Set entry description
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDescription(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDescription()
+ && !$this->getDataContainer()->getTitle()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 entry elements SHOULD contain exactly one'
+ . ' description element but a description has not been set. In'
+ . ' addition, there is no title element as required in the absence'
+ . ' of a description.';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ if (!$this->getDataContainer()->getDescription()) {
+ return;
+ }
+ $subtitle = $dom->createElement('description');
+ $root->appendChild($subtitle);
+ $text = $dom->createCDATASection($this->getDataContainer()->getDescription());
+ $subtitle->appendChild($text);
+ }
+
+ /**
+ * Set date entry was last modified
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateModified()) {
+ return;
+ }
+
+ $updated = $dom->createElement('pubDate');
+ $root->appendChild($updated);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getDateModified()->get(Zend_Date::RSS)
+ );
+ $updated->appendChild($text);
+ }
+
+ /**
+ * Set date entry was created
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+ {
+ if (!$this->getDataContainer()->getDateCreated()) {
+ return;
+ }
+ if (!$this->getDataContainer()->getDateModified()) {
+ $this->getDataContainer()->setDateModified(
+ $this->getDataContainer()->getDateCreated()
+ );
+ }
+ }
+
+ /**
+ * Set entry authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->_container->getAuthors();
+ if ((!$authors || empty($authors))) {
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('author');
+ $name = $data['name'];
+ if (array_key_exists('email', $data)) {
+ $name = $data['email'] . ' (' . $data['name'] . ')';
+ }
+ $text = $dom->createTextNode($name);
+ $author->appendChild($text);
+ $root->appendChild($author);
+ }
+ }
+
+ /**
+ * Set entry enclosure
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setEnclosure(DOMDocument $dom, DOMElement $root)
+ {
+ $data = $this->_container->getEnclosure();
+ if ((!$data || empty($data))) {
+ return;
+ }
+ if (!isset($data['type'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ $exception = new Zend_Feed_Exception('Enclosure "type" is not set');
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ if (!isset($data['length'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ $exception = new Zend_Feed_Exception('Enclosure "length" is not set');
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ if (isset($data['length']) && (int) $data['length'] <= 0) {
+ // require_once 'Zend/Feed/Exception.php';
+ $exception = new Zend_Feed_Exception('Enclosure "length" must be an integer'
+ . ' indicating the content\'s length in bytes');
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $enclosure = $this->_dom->createElement('enclosure');
+ $enclosure->setAttribute('type', $data['type']);
+ $enclosure->setAttribute('length', $data['length']);
+ $enclosure->setAttribute('url', $data['uri']);
+ $root->appendChild($enclosure);
+ }
+
+ /**
+ * Set link to entry
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLink(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getLink()) {
+ return;
+ }
+ $link = $dom->createElement('link');
+ $root->appendChild($link);
+ $text = $dom->createTextNode($this->getDataContainer()->getLink());
+ $link->appendChild($text);
+ }
+
+ /**
+ * Set entry identifier
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setId(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getId()
+ && !$this->getDataContainer()->getLink()) {
+ return;
+ }
+
+ $id = $dom->createElement('guid');
+ $root->appendChild($id);
+ if (!$this->getDataContainer()->getId()) {
+ $this->getDataContainer()->setId(
+ $this->getDataContainer()->getLink());
+ }
+ $text = $dom->createTextNode($this->getDataContainer()->getId());
+ $id->appendChild($text);
+ if (!Zend_Uri::check($this->getDataContainer()->getId())) {
+ $id->setAttribute('isPermaLink', 'false');
+ }
+ }
+
+ /**
+ * Set link to entry comments
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCommentLink(DOMDocument $dom, DOMElement $root)
+ {
+ $link = $this->getDataContainer()->getCommentLink();
+ if (!$link) {
+ return;
+ }
+ $clink = $this->_dom->createElement('comments');
+ $text = $dom->createTextNode($link);
+ $clink->appendChild($text);
+ $root->appendChild($clink);
+ }
+
+ /**
+ * Set entry categories
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCategories(DOMDocument $dom, DOMElement $root)
+ {
+ $categories = $this->getDataContainer()->getCategories();
+ if (!$categories) {
+ return;
+ }
+ foreach ($categories as $cat) {
+ $category = $dom->createElement('category');
+ if (isset($cat['scheme'])) {
+ $category->setAttribute('domain', $cat['scheme']);
+ }
+ $text = $dom->createCDATASection($cat['term']);
+ $category->appendChild($text);
+ $root->appendChild($category);
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Feed/Atom.php b/libs/Zend/Feed/Writer/Renderer/Feed/Atom.php
new file mode 100644
index 0000000000..2c88dd4298
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Feed/Atom.php
@@ -0,0 +1,130 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 22098 2010-05-04 18:03:29Z padraic $
+ */
+
+/** @see Zend_Feed_Writer_Feed */
+// require_once 'Zend/Feed/Writer/Feed.php';
+
+/** @see Zend_Version */
+// require_once 'Zend/Version.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererInterface */
+// require_once 'Zend/Feed/Writer/Renderer/RendererInterface.php';
+
+/** @see Zend_Feed_Writer_Renderer_Entry_Atom */
+// require_once 'Zend/Feed/Writer/Renderer/Entry/Atom.php';
+
+/** @see Zend_Feed_Writer_Renderer_Entry_Atom_Deleted */
+// require_once 'Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererAbstract */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Feed_Atom
+ extends Zend_Feed_Writer_Renderer_Feed_Atom_AtomAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Feed $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Feed $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render Atom feed
+ *
+ * @return Zend_Feed_Writer_Renderer_Feed_Atom
+ */
+ public function render()
+ {
+ if (!$this->_container->getEncoding()) {
+ $this->_container->setEncoding('UTF-8');
+ }
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $root = $this->_dom->createElementNS(
+ Zend_Feed_Writer::NAMESPACE_ATOM_10, 'feed'
+ );
+ $this->setRootElement($root);
+ $this->_dom->appendChild($root);
+ $this->_setLanguage($this->_dom, $root);
+ $this->_setBaseUrl($this->_dom, $root);
+ $this->_setTitle($this->_dom, $root);
+ $this->_setDescription($this->_dom, $root);
+ $this->_setImage($this->_dom, $root);
+ $this->_setDateCreated($this->_dom, $root);
+ $this->_setDateModified($this->_dom, $root);
+ $this->_setGenerator($this->_dom, $root);
+ $this->_setLink($this->_dom, $root);
+ $this->_setFeedLinks($this->_dom, $root);
+ $this->_setId($this->_dom, $root);
+ $this->_setAuthors($this->_dom, $root);
+ $this->_setCopyright($this->_dom, $root);
+ $this->_setCategories($this->_dom, $root);
+ $this->_setHubs($this->_dom, $root);
+
+ foreach ($this->_extensions as $ext) {
+ $ext->setType($this->getType());
+ $ext->setRootElement($this->getRootElement());
+ $ext->setDomDocument($this->getDomDocument(), $root);
+ $ext->render();
+ }
+
+ foreach ($this->_container as $entry) {
+ if ($this->getDataContainer()->getEncoding()) {
+ $entry->setEncoding($this->getDataContainer()->getEncoding());
+ }
+ if ($entry instanceof Zend_Feed_Writer_Entry) {
+ $renderer = new Zend_Feed_Writer_Renderer_Entry_Atom($entry);
+ } else {
+ if (!$this->_dom->documentElement->hasAttribute('xmlns:at')) {
+ $this->_dom->documentElement->setAttribute(
+ 'xmlns:at', 'http://purl.org/atompub/tombstones/1.0'
+ );
+ }
+ $renderer = new Zend_Feed_Writer_Renderer_Entry_Atom_Deleted($entry);
+ }
+ if ($this->_ignoreExceptions === true) {
+ $renderer->ignoreExceptions();
+ }
+ $renderer->setType($this->getType());
+ $renderer->setRootElement($this->_dom->documentElement);
+ $renderer->render();
+ $element = $renderer->getElement();
+ $imported = $this->_dom->importNode($element, true);
+ $root->appendChild($imported);
+ }
+ return $this;
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php b/libs/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php
new file mode 100644
index 0000000000..254516e5b5
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php
@@ -0,0 +1,427 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/** @see Zend_Feed_Writer_Feed */
+// require_once 'Zend/Feed/Writer/Feed.php';
+
+/** @see Zend_Version */
+// require_once 'Zend/Version.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererInterface */
+// require_once 'Zend/Feed/Writer/Renderer/RendererInterface.php';
+
+/** @see Zend_Feed_Writer_Renderer_Entry_Atom */
+// require_once 'Zend/Feed/Writer/Renderer/Entry/Atom.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererAbstract */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Feed_Atom_AtomAbstract
+ extends Zend_Feed_Writer_Renderer_RendererAbstract
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Feed $container
+ * @return void
+ */
+ public function __construct ($container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Set feed language
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLanguage(DOMDocument $dom, DOMElement $root)
+ {
+ if ($this->getDataContainer()->getLanguage()) {
+ $root->setAttribute('xml:lang', $this->getDataContainer()
+ ->getLanguage());
+ }
+ }
+
+ /**
+ * Set feed title
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setTitle(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getTitle()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 feed elements MUST contain exactly one'
+ . ' atom:title element but a title has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ $title = $dom->createElement('title');
+ $root->appendChild($title);
+ $title->setAttribute('type', 'text');
+ $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+ $title->appendChild($text);
+ }
+
+ /**
+ * Set feed description
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDescription(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDescription()) {
+ return;
+ }
+ $subtitle = $dom->createElement('subtitle');
+ $root->appendChild($subtitle);
+ $subtitle->setAttribute('type', 'text');
+ $text = $dom->createTextNode($this->getDataContainer()->getDescription());
+ $subtitle->appendChild($text);
+ }
+
+ /**
+ * Set date feed was last modified
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateModified()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 feed elements MUST contain exactly one'
+ . ' atom:updated element but a modification date has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ $updated = $dom->createElement('updated');
+ $root->appendChild($updated);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getDateModified()->get(Zend_Date::ISO_8601)
+ );
+ $updated->appendChild($text);
+ }
+
+ /**
+ * Set feed generator string
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getGenerator()) {
+ $this->getDataContainer()->setGenerator('Zend_Feed_Writer',
+ Zend_Version::VERSION, 'http://framework.zend.com');
+ }
+
+ $gdata = $this->getDataContainer()->getGenerator();
+ $generator = $dom->createElement('generator');
+ $root->appendChild($generator);
+ $text = $dom->createTextNode($gdata['name']);
+ $generator->appendChild($text);
+ if (array_key_exists('uri', $gdata)) {
+ $generator->setAttribute('uri', $gdata['uri']);
+ }
+ if (array_key_exists('version', $gdata)) {
+ $generator->setAttribute('version', $gdata['version']);
+ }
+ }
+
+ /**
+ * Set link to feed
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLink(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getLink()) {
+ return;
+ }
+ $link = $dom->createElement('link');
+ $root->appendChild($link);
+ $link->setAttribute('rel', 'alternate');
+ $link->setAttribute('type', 'text/html');
+ $link->setAttribute('href', $this->getDataContainer()->getLink());
+ }
+
+ /**
+ * Set feed links
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
+ {
+ $flinks = $this->getDataContainer()->getFeedLinks();
+ if(!$flinks || !array_key_exists('atom', $flinks)) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 feed elements SHOULD contain one atom:link '
+ . 'element with a rel attribute value of "self". This is the '
+ . 'preferred URI for retrieving Atom Feed Documents representing '
+ . 'this Atom feed but a feed link has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ foreach ($flinks as $type => $href) {
+ $mime = 'application/' . strtolower($type) . '+xml';
+ $flink = $dom->createElement('link');
+ $root->appendChild($flink);
+ $flink->setAttribute('rel', 'self');
+ $flink->setAttribute('type', $mime);
+ $flink->setAttribute('href', $href);
+ }
+ }
+
+ /**
+ * Set feed authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->_container->getAuthors();
+ if (!$authors || empty($authors)) {
+ /**
+ * Technically we should defer an exception until we can check
+ * that all entries contain an author. If any entry is missing
+ * an author, then a missing feed author element is invalid
+ */
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('author');
+ $name = $this->_dom->createElement('name');
+ $author->appendChild($name);
+ $root->appendChild($author);
+ $text = $dom->createTextNode($data['name']);
+ $name->appendChild($text);
+ if (array_key_exists('email', $data)) {
+ $email = $this->_dom->createElement('email');
+ $author->appendChild($email);
+ $text = $dom->createTextNode($data['email']);
+ $email->appendChild($text);
+ }
+ if (array_key_exists('uri', $data)) {
+ $uri = $this->_dom->createElement('uri');
+ $author->appendChild($uri);
+ $text = $dom->createTextNode($data['uri']);
+ $uri->appendChild($text);
+ }
+ }
+ }
+
+ /**
+ * Set feed identifier
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setId(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getId()
+ && !$this->getDataContainer()->getLink()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Atom 1.0 feed elements MUST contain exactly one '
+ . 'atom:id element, or as an alternative, we can use the same '
+ . 'value as atom:link however neither a suitable link nor an '
+ . 'id have been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ if (!$this->getDataContainer()->getId()) {
+ $this->getDataContainer()->setId(
+ $this->getDataContainer()->getLink());
+ }
+ $id = $dom->createElement('id');
+ $root->appendChild($id);
+ $text = $dom->createTextNode($this->getDataContainer()->getId());
+ $id->appendChild($text);
+ }
+
+ /**
+ * Set feed copyright
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCopyright(DOMDocument $dom, DOMElement $root)
+ {
+ $copyright = $this->getDataContainer()->getCopyright();
+ if (!$copyright) {
+ return;
+ }
+ $copy = $dom->createElement('rights');
+ $root->appendChild($copy);
+ $text = $dom->createTextNode($copyright);
+ $copy->appendChild($text);
+ }
+
+ /**
+ * Set feed level logo (image)
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setImage(DOMDocument $dom, DOMElement $root)
+ {
+ $image = $this->getDataContainer()->getImage();
+ if (!$image) {
+ return;
+ }
+ $img = $dom->createElement('logo');
+ $root->appendChild($img);
+ $text = $dom->createTextNode($image['uri']);
+ $img->appendChild($text);
+ }
+
+ /**
+ * Set date feed was created
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateCreated()) {
+ return;
+ }
+ if(!$this->getDataContainer()->getDateModified()) {
+ $this->getDataContainer()->setDateModified(
+ $this->getDataContainer()->getDateCreated()
+ );
+ }
+ }
+
+ /**
+ * Set base URL to feed links
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setBaseUrl(DOMDocument $dom, DOMElement $root)
+ {
+ $baseUrl = $this->getDataContainer()->getBaseUrl();
+ if (!$baseUrl) {
+ return;
+ }
+ $root->setAttribute('xml:base', $baseUrl);
+ }
+
+ /**
+ * Set hubs to which this feed pushes
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setHubs(DOMDocument $dom, DOMElement $root)
+ {
+ $hubs = $this->getDataContainer()->getHubs();
+ if (!$hubs) {
+ return;
+ }
+ foreach ($hubs as $hubUrl) {
+ $hub = $dom->createElement('link');
+ $hub->setAttribute('rel', 'hub');
+ $hub->setAttribute('href', $hubUrl);
+ $root->appendChild($hub);
+ }
+ }
+
+ /**
+ * Set feed cateories
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCategories(DOMDocument $dom, DOMElement $root)
+ {
+ $categories = $this->getDataContainer()->getCategories();
+ if (!$categories) {
+ return;
+ }
+ foreach ($categories as $cat) {
+ $category = $dom->createElement('category');
+ $category->setAttribute('term', $cat['term']);
+ if (isset($cat['label'])) {
+ $category->setAttribute('label', $cat['label']);
+ } else {
+ $category->setAttribute('label', $cat['term']);
+ }
+ if (isset($cat['scheme'])) {
+ $category->setAttribute('scheme', $cat['scheme']);
+ }
+ $root->appendChild($category);
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php b/libs/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php
new file mode 100644
index 0000000000..125fed1eaf
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php
@@ -0,0 +1,110 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Atom.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+// require_once 'Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Feed_Atom_Source
+ extends Zend_Feed_Writer_Renderer_Feed_Atom_AtomAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Feed_Source $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Source $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render Atom Feed Metadata (Source element)
+ *
+ * @return Zend_Feed_Writer_Renderer_Feed_Atom
+ */
+ public function render()
+ {
+ if (!$this->_container->getEncoding()) {
+ $this->_container->setEncoding('UTF-8');
+ }
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $root = $this->_dom->createElement('source');
+ $this->setRootElement($root);
+ $this->_dom->appendChild($root);
+ $this->_setLanguage($this->_dom, $root);
+ $this->_setBaseUrl($this->_dom, $root);
+ $this->_setTitle($this->_dom, $root);
+ $this->_setDescription($this->_dom, $root);
+ $this->_setDateCreated($this->_dom, $root);
+ $this->_setDateModified($this->_dom, $root);
+ $this->_setGenerator($this->_dom, $root);
+ $this->_setLink($this->_dom, $root);
+ $this->_setFeedLinks($this->_dom, $root);
+ $this->_setId($this->_dom, $root);
+ $this->_setAuthors($this->_dom, $root);
+ $this->_setCopyright($this->_dom, $root);
+ $this->_setCategories($this->_dom, $root);
+
+ foreach ($this->_extensions as $ext) {
+ $ext->setType($this->getType());
+ $ext->setRootElement($this->getRootElement());
+ $ext->setDomDocument($this->getDomDocument(), $root);
+ $ext->render();
+ }
+ return $this;
+ }
+
+ /**
+ * Set feed generator string
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getGenerator()) {
+ return;
+ }
+
+ $gdata = $this->getDataContainer()->getGenerator();
+ $generator = $dom->createElement('generator');
+ $root->appendChild($generator);
+ $text = $dom->createTextNode($gdata['name']);
+ $generator->appendChild($text);
+ if (array_key_exists('uri', $gdata)) {
+ $generator->setAttribute('uri', $gdata['uri']);
+ }
+ if (array_key_exists('version', $gdata)) {
+ $generator->setAttribute('version', $gdata['version']);
+ }
+ }
+
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/Feed/Rss.php b/libs/Zend/Feed/Writer/Renderer/Feed/Rss.php
new file mode 100644
index 0000000000..07b94e7b86
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/Feed/Rss.php
@@ -0,0 +1,505 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Rss.php 22108 2010-05-05 13:44:11Z padraic $
+ */
+
+/** @see Zend_Feed_Writer_Feed */
+// require_once 'Zend/Feed/Writer/Feed.php';
+
+/** @see Zend_Version */
+// require_once 'Zend/Version.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererInterface */
+// require_once 'Zend/Feed/Writer/Renderer/RendererInterface.php';
+
+/** @see Zend_Feed_Writer_Renderer_Entry_Rss */
+// require_once 'Zend/Feed/Writer/Renderer/Entry/Rss.php';
+
+/** @see Zend_Feed_Writer_Renderer_RendererAbstract */
+// require_once 'Zend/Feed/Writer/Renderer/RendererAbstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_Feed_Rss
+ extends Zend_Feed_Writer_Renderer_RendererAbstract
+ implements Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Constructor
+ *
+ * @param Zend_Feed_Writer_Feed $container
+ * @return void
+ */
+ public function __construct (Zend_Feed_Writer_Feed $container)
+ {
+ parent::__construct($container);
+ }
+
+ /**
+ * Render RSS feed
+ *
+ * @return Zend_Feed_Writer_Renderer_Feed_Rss
+ */
+ public function render()
+ {
+ if (!$this->_container->getEncoding()) {
+ $this->_container->setEncoding('UTF-8');
+ }
+ $this->_dom = new DOMDocument('1.0', $this->_container->getEncoding());
+ $this->_dom->formatOutput = true;
+ $this->_dom->substituteEntities = false;
+ $rss = $this->_dom->createElement('rss');
+ $this->setRootElement($rss);
+ $rss->setAttribute('version', '2.0');
+
+ $channel = $this->_dom->createElement('channel');
+ $rss->appendChild($channel);
+ $this->_dom->appendChild($rss);
+ $this->_setLanguage($this->_dom, $channel);
+ $this->_setBaseUrl($this->_dom, $channel);
+ $this->_setTitle($this->_dom, $channel);
+ $this->_setDescription($this->_dom, $channel);
+ $this->_setImage($this->_dom, $channel);
+ $this->_setDateCreated($this->_dom, $channel);
+ $this->_setDateModified($this->_dom, $channel);
+ $this->_setLastBuildDate($this->_dom, $channel);
+ $this->_setGenerator($this->_dom, $channel);
+ $this->_setLink($this->_dom, $channel);
+ $this->_setAuthors($this->_dom, $channel);
+ $this->_setCopyright($this->_dom, $channel);
+ $this->_setCategories($this->_dom, $channel);
+
+ foreach ($this->_extensions as $ext) {
+ $ext->setType($this->getType());
+ $ext->setRootElement($this->getRootElement());
+ $ext->setDomDocument($this->getDomDocument(), $channel);
+ $ext->render();
+ }
+
+ foreach ($this->_container as $entry) {
+ if ($this->getDataContainer()->getEncoding()) {
+ $entry->setEncoding($this->getDataContainer()->getEncoding());
+ }
+ if ($entry instanceof Zend_Feed_Writer_Entry) {
+ $renderer = new Zend_Feed_Writer_Renderer_Entry_Rss($entry);
+ } else {
+ continue;
+ }
+ if ($this->_ignoreExceptions === true) {
+ $renderer->ignoreExceptions();
+ }
+ $renderer->setType($this->getType());
+ $renderer->setRootElement($this->_dom->documentElement);
+ $renderer->render();
+ $element = $renderer->getElement();
+ $imported = $this->_dom->importNode($element, true);
+ $channel->appendChild($imported);
+ }
+ return $this;
+ }
+
+ /**
+ * Set feed language
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLanguage(DOMDocument $dom, DOMElement $root)
+ {
+ $lang = $this->getDataContainer()->getLanguage();
+ if (!$lang) {
+ return;
+ }
+ $language = $dom->createElement('language');
+ $root->appendChild($language);
+ $language->nodeValue = $lang;
+ }
+
+ /**
+ * Set feed title
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setTitle(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getTitle()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 feed elements MUST contain exactly one'
+ . ' title element but a title has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+
+ $title = $dom->createElement('title');
+ $root->appendChild($title);
+ $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+ $title->appendChild($text);
+ }
+
+ /**
+ * Set feed description
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDescription(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDescription()) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 feed elements MUST contain exactly one'
+ . ' description element but one has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $subtitle = $dom->createElement('description');
+ $root->appendChild($subtitle);
+ $text = $dom->createTextNode($this->getDataContainer()->getDescription());
+ $subtitle->appendChild($text);
+ }
+
+ /**
+ * Set date feed was last modified
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateModified()) {
+ return;
+ }
+
+ $updated = $dom->createElement('pubDate');
+ $root->appendChild($updated);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getDateModified()->get(Zend_Date::RSS)
+ );
+ $updated->appendChild($text);
+ }
+
+ /**
+ * Set feed generator string
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getGenerator()) {
+ $this->getDataContainer()->setGenerator('Zend_Feed_Writer',
+ Zend_Version::VERSION, 'http://framework.zend.com');
+ }
+
+ $gdata = $this->getDataContainer()->getGenerator();
+ $generator = $dom->createElement('generator');
+ $root->appendChild($generator);
+ $name = $gdata['name'];
+ if (array_key_exists('version', $gdata)) {
+ $name .= ' ' . $gdata['version'];
+ }
+ if (array_key_exists('uri', $gdata)) {
+ $name .= ' (' . $gdata['uri'] . ')';
+ }
+ $text = $dom->createTextNode($name);
+ $generator->appendChild($text);
+ }
+
+ /**
+ * Set link to feed
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLink(DOMDocument $dom, DOMElement $root)
+ {
+ $value = $this->getDataContainer()->getLink();
+ if(!$value) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 feed elements MUST contain exactly one'
+ . ' link element but one has not been set';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $link = $dom->createElement('link');
+ $root->appendChild($link);
+ $text = $dom->createTextNode($value);
+ $link->appendChild($text);
+ if (!Zend_Uri::check($value)) {
+ $link->setAttribute('isPermaLink', 'false');
+ }
+ }
+
+ /**
+ * Set feed authors
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+ {
+ $authors = $this->getDataContainer()->getAuthors();
+ if (!$authors || empty($authors)) {
+ return;
+ }
+ foreach ($authors as $data) {
+ $author = $this->_dom->createElement('author');
+ $name = $data['name'];
+ if (array_key_exists('email', $data)) {
+ $name = $data['email'] . ' (' . $data['name'] . ')';
+ }
+ $text = $dom->createTextNode($name);
+ $author->appendChild($text);
+ $root->appendChild($author);
+ }
+ }
+
+ /**
+ * Set feed copyright
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCopyright(DOMDocument $dom, DOMElement $root)
+ {
+ $copyright = $this->getDataContainer()->getCopyright();
+ if (!$copyright) {
+ return;
+ }
+ $copy = $dom->createElement('copyright');
+ $root->appendChild($copy);
+ $text = $dom->createTextNode($copyright);
+ $copy->appendChild($text);
+ }
+
+ /**
+ * Set feed channel image
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setImage(DOMDocument $dom, DOMElement $root)
+ {
+ $image = $this->getDataContainer()->getImage();
+ if (!$image) {
+ return;
+ }
+ if (!isset($image['title']) || empty($image['title'])
+ || !is_string($image['title'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'RSS 2.0 feed images must include a title';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ if (empty($image['link']) || !is_string($image['link'])
+ || !Zend_Uri::check($image['link'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Invalid parameter: parameter \'link\''
+ . ' must be a non-empty string and valid URI/IRI';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $img = $dom->createElement('image');
+ $root->appendChild($img);
+ $url = $dom->createElement('url');
+ $text = $dom->createTextNode($image['uri']);
+ $url->appendChild($text);
+ $title = $dom->createElement('title');
+ $text = $dom->createTextNode($image['title']);
+ $title->appendChild($text);
+ $link = $dom->createElement('link');
+ $text = $dom->createTextNode($image['link']);
+ $link->appendChild($text);
+ $img->appendChild($url);
+ $img->appendChild($title);
+ $img->appendChild($link);
+ if (isset($image['height'])) {
+ if (!ctype_digit((string) $image['height']) || $image['height'] > 400) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Invalid parameter: parameter \'height\''
+ . ' must be an integer not exceeding 400';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $height = $dom->createElement('height');
+ $text = $dom->createTextNode($image['height']);
+ $height->appendChild($text);
+ $img->appendChild($height);
+ }
+ if (isset($image['width'])) {
+ if (!ctype_digit((string) $image['width']) || $image['width'] > 144) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Invalid parameter: parameter \'width\''
+ . ' must be an integer not exceeding 144';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $width = $dom->createElement('width');
+ $text = $dom->createTextNode($image['width']);
+ $width->appendChild($text);
+ $img->appendChild($width);
+ }
+ if (isset($image['description'])) {
+ if (empty($image['description']) || !is_string($image['description'])) {
+ // require_once 'Zend/Feed/Exception.php';
+ $message = 'Invalid parameter: parameter \'description\''
+ . ' must be a non-empty string';
+ $exception = new Zend_Feed_Exception($message);
+ if (!$this->_ignoreExceptions) {
+ throw $exception;
+ } else {
+ $this->_exceptions[] = $exception;
+ return;
+ }
+ }
+ $desc = $dom->createElement('description');
+ $text = $dom->createTextNode($image['description']);
+ $desc->appendChild($text);
+ $img->appendChild($desc);
+ }
+ }
+
+ /**
+ * Set date feed was created
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getDateCreated()) {
+ return;
+ }
+ if(!$this->getDataContainer()->getDateModified()) {
+ $this->getDataContainer()->setDateModified(
+ $this->getDataContainer()->getDateCreated()
+ );
+ }
+ }
+
+ /**
+ * Set date feed last build date
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setLastBuildDate(DOMDocument $dom, DOMElement $root)
+ {
+ if(!$this->getDataContainer()->getLastBuildDate()) {
+ return;
+ }
+
+ $lastBuildDate = $dom->createElement('lastBuildDate');
+ $root->appendChild($lastBuildDate);
+ $text = $dom->createTextNode(
+ $this->getDataContainer()->getLastBuildDate()->get(Zend_Date::RSS)
+ );
+ $lastBuildDate->appendChild($text);
+ }
+
+ /**
+ * Set base URL to feed links
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setBaseUrl(DOMDocument $dom, DOMElement $root)
+ {
+ $baseUrl = $this->getDataContainer()->getBaseUrl();
+ if (!$baseUrl) {
+ return;
+ }
+ $root->setAttribute('xml:base', $baseUrl);
+ }
+
+ /**
+ * Set feed categories
+ *
+ * @param DOMDocument $dom
+ * @param DOMElement $root
+ * @return void
+ */
+ protected function _setCategories(DOMDocument $dom, DOMElement $root)
+ {
+ $categories = $this->getDataContainer()->getCategories();
+ if (!$categories) {
+ return;
+ }
+ foreach ($categories as $cat) {
+ $category = $dom->createElement('category');
+ if (isset($cat['scheme'])) {
+ $category->setAttribute('domain', $cat['scheme']);
+ }
+ $text = $dom->createTextNode($cat['term']);
+ $category->appendChild($text);
+ $root->appendChild($category);
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/RendererAbstract.php b/libs/Zend/Feed/Writer/Renderer/RendererAbstract.php
new file mode 100644
index 0000000000..b3457ed643
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/RendererAbstract.php
@@ -0,0 +1,250 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: RendererAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/** @see Zend_Feed_Writer */
+// require_once 'Zend/Feed/Writer.php';
+
+/** @see Zend_Version */
+// require_once 'Zend/Version.php';
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Renderer_RendererAbstract
+{
+ /**
+ * Extensions
+ * @var array
+ */
+ protected $_extensions = array();
+
+ /**
+ * @var mixed
+ */
+ protected $_container = null;
+
+ /**
+ * @var DOMDocument
+ */
+ protected $_dom = null;
+
+ /**
+ * @var bool
+ */
+ protected $_ignoreExceptions = false;
+
+ /**
+ * @var array
+ */
+ protected $_exceptions = array();
+
+ /**
+ * Encoding of all text values
+ *
+ * @var string
+ */
+ protected $_encoding = 'UTF-8';
+
+ /**
+ * Holds the value "atom" or "rss" depending on the feed type set when
+ * when last exported.
+ *
+ * @var string
+ */
+ protected $_type = null;
+
+ /**
+ * @var DOMElement
+ */
+ protected $_rootElement = null;
+
+ /**
+ * Constructor
+ *
+ * @param mixed $container
+ * @return void
+ */
+ public function __construct($container)
+ {
+ $this->_container = $container;
+ $this->setType($container->getType());
+ $this->_loadExtensions();
+ }
+
+ /**
+ * Save XML to string
+ *
+ * @return string
+ */
+ public function saveXml()
+ {
+ return $this->getDomDocument()->saveXml();
+ }
+
+ /**
+ * Get DOM document
+ *
+ * @return DOMDocument
+ */
+ public function getDomDocument()
+ {
+ return $this->_dom;
+ }
+
+ /**
+ * Get document element from DOM
+ *
+ * @return DOMElement
+ */
+ public function getElement()
+ {
+ return $this->getDomDocument()->documentElement;
+ }
+
+ /**
+ * Get data container of items being rendered
+ *
+ * @return mixed
+ */
+ public function getDataContainer()
+ {
+ return $this->_container;
+ }
+
+ /**
+ * Set feed encoding
+ *
+ * @param string $enc
+ * @return Zend_Feed_Writer_Renderer_RendererAbstract
+ */
+ public function setEncoding($enc)
+ {
+ $this->_encoding = $enc;
+ return $this;
+ }
+
+ /**
+ * Get feed encoding
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Indicate whether or not to ignore exceptions
+ *
+ * @param bool $bool
+ * @return Zend_Feed_Writer_Renderer_RendererAbstract
+ */
+ public function ignoreExceptions($bool = true)
+ {
+ if (!is_bool($bool)) {
+ // require_once 'Zend/Feed/Exception.php';
+ throw new Zend_Feed_Exception('Invalid parameter: $bool. Should be TRUE or FALSE (defaults to TRUE if null)');
+ }
+ $this->_ignoreExceptions = $bool;
+ return $this;
+ }
+
+ /**
+ * Get exception list
+ *
+ * @return array
+ */
+ public function getExceptions()
+ {
+ return $this->_exceptions;
+ }
+
+ /**
+ * Set the current feed type being exported to "rss" or "atom". This allows
+ * other objects to gracefully choose whether to execute or not, depending
+ * on their appropriateness for the current type, e.g. renderers.
+ *
+ * @param string $type
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+ }
+
+ /**
+ * Retrieve the current or last feed type exported.
+ *
+ * @return string Value will be "rss" or "atom"
+ */
+ public function getType()
+ {
+ return $this->_type;
+ }
+
+ /**
+ * Sets the absolute root element for the XML feed being generated. This
+ * helps simplify the appending of namespace declarations, but also ensures
+ * namespaces are added to the root element - not scattered across the entire
+ * XML file - may assist namespace unsafe parsers and looks pretty ;).
+ *
+ * @param DOMElement $root
+ */
+ public function setRootElement(DOMElement $root)
+ {
+ $this->_rootElement = $root;
+ }
+
+ /**
+ * Retrieve the absolute root element for the XML feed being generated.
+ *
+ * @return DOMElement
+ */
+ public function getRootElement()
+ {
+ return $this->_rootElement;
+ }
+
+ /**
+ * Load extensions from Zend_Feed_Writer
+ *
+ * @return void
+ */
+ protected function _loadExtensions()
+ {
+ Zend_Feed_Writer::registerCoreExtensions();
+ $all = Zend_Feed_Writer::getExtensions();
+ if (stripos(get_class($this), 'entry')) {
+ $exts = $all['entryRenderer'];
+ } else {
+ $exts = $all['feedRenderer'];
+ }
+ foreach ($exts as $extension) {
+ $className = Zend_Feed_Writer::getPluginLoader()->getClassName($extension);
+ $this->_extensions[$extension] = new $className(
+ $this->getDataContainer()
+ );
+ $this->_extensions[$extension]->setEncoding($this->getEncoding());
+ }
+ }
+}
diff --git a/libs/Zend/Feed/Writer/Renderer/RendererInterface.php b/libs/Zend/Feed/Writer/Renderer/RendererInterface.php
new file mode 100644
index 0000000000..89b4294416
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Renderer/RendererInterface.php
@@ -0,0 +1,111 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: RendererInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Feed_Writer_Renderer_RendererInterface
+{
+ /**
+ * Render feed/entry
+ *
+ * @return void
+ */
+ public function render();
+
+ /**
+ * Save feed and/or entry to XML and return string
+ *
+ * @return string
+ */
+ public function saveXml();
+
+ /**
+ * Get DOM document
+ *
+ * @return DOMDocument
+ */
+ public function getDomDocument();
+
+ /**
+ * Get document element from DOM
+ *
+ * @return DOMElement
+ */
+ public function getElement();
+
+ /**
+ * Get data container containing feed items
+ *
+ * @return mixed
+ */
+ public function getDataContainer();
+
+ /**
+ * Should exceptions be ignored?
+ *
+ * @return mixed
+ */
+ public function ignoreExceptions();
+
+ /**
+ * Get list of thrown exceptions
+ *
+ * @return array
+ */
+ public function getExceptions();
+
+ /**
+ * Set the current feed type being exported to "rss" or "atom". This allows
+ * other objects to gracefully choose whether to execute or not, depending
+ * on their appropriateness for the current type, e.g. renderers.
+ *
+ * @param string $type
+ */
+ public function setType($type);
+
+ /**
+ * Retrieve the current or last feed type exported.
+ *
+ * @return string Value will be "rss" or "atom"
+ */
+ public function getType();
+
+ /**
+ * Sets the absolute root element for the XML feed being generated. This
+ * helps simplify the appending of namespace declarations, but also ensures
+ * namespaces are added to the root element - not scattered across the entire
+ * XML file - may assist namespace unsafe parsers and looks pretty ;).
+ *
+ * @param DOMElement $root
+ */
+ public function setRootElement(DOMElement $root);
+
+ /**
+ * Retrieve the absolute root element for the XML feed being generated.
+ *
+ * @return DOMElement
+ */
+ public function getRootElement();
+}
diff --git a/libs/Zend/Feed/Writer/Source.php b/libs/Zend/Feed/Writer/Source.php
new file mode 100644
index 0000000000..3861fc77fc
--- /dev/null
+++ b/libs/Zend/Feed/Writer/Source.php
@@ -0,0 +1,33 @@
+<?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_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Feed.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+// require_once 'Zend/Feed/Writer/Feed/FeedAbstract.php';
+
+ /**
+ * @category Zend
+ * @package Zend_Feed_Writer
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Feed_Writer_Source extends Zend_Feed_Writer_Feed_FeedAbstract
+{
+
+}