]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-17091 Adding part of GoogleData API from the Zend Framework, in order to support...
authornicolasconnault <nicolasconnault>
Fri, 31 Oct 2008 15:33:45 +0000 (15:33 +0000)
committernicolasconnault <nicolasconnault>
Fri, 31 Oct 2008 15:33:45 +0000 (15:33 +0000)
140 files changed:
lib/zend/Zend/Exception.php [new file with mode: 0644]
lib/zend/Zend/Gdata.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/AuthException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/BadMethodCallException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Base.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/BaseMediaSource.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/CaptchaRequiredException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Entry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Exception.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Author.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Category.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Content.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Contributor.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Control.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Draft.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Element.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Email.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Generator.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Icon.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Id.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Link.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Logo.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Name.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Person.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Published.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Rights.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Source.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Subtitle.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Summary.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Text.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Title.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Updated.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Extension/Uri.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Feed.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/FeedEntryParent.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/FeedSourceParent.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/HttpException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/IOException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/InvalidArgumentException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/LoggingHttpClientAdapterSocket.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/MediaEntry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/MediaFileSource.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/MediaSource.php [new file with mode: 0644]
lib/zend/Zend/Gdata/App/Util.php [new file with mode: 0644]
lib/zend/Zend/Gdata/AuthSub.php [new file with mode: 0644]
lib/zend/Zend/Gdata/ClientLogin.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Docs.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Docs/DocumentListEntry.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Docs/DocumentListFeed.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Docs/Query.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Entry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/AttendeeStatus.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/AttendeeType.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Comments.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/EntryLink.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/EventStatus.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/ExtendedProperty.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/FeedLink.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/OpenSearchItemsPerPage.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/OriginalEvent.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Rating.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Recurrence.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/RecurrenceException.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Reminder.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Transparency.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Visibility.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/When.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Where.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Extension/Who.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Feed.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/Entry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/Extension/BaseAttribute.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/Feed.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/ItemEntry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/ItemFeed.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/ItemQuery.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/Query.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/SnippetEntry.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/SnippetFeed.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Gbase/SnippetQuery.php [new file with mode: 0644]
lib/zend/Zend/Gdata/HttpClient.php [new file with mode: 0644]
lib/zend/Zend/Gdata/Media.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Entry.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaCategory.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaContent.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaCopyright.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaCredit.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaDescription.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaGroup.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaHash.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaKeywords.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaPlayer.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaRating.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaRestriction.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaText.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaThumbnail.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Extension/MediaTitle.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Media/Feed.php [new file with mode: 0755]
lib/zend/Zend/Gdata/Query.php [new file with mode: 0644]
lib/zend/Zend/Http/Client.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Adapter/Exception.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Adapter/Interface.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Adapter/Proxy.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Adapter/Socket.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Adapter/Test.php [new file with mode: 0644]
lib/zend/Zend/Http/Client/Exception.php [new file with mode: 0644]
lib/zend/Zend/Http/Exception.php [new file with mode: 0644]
lib/zend/Zend/Http/Response.php [new file with mode: 0644]
lib/zend/Zend/Loader.php [new file with mode: 0644]
lib/zend/Zend/Mime.php [new file with mode: 0644]
lib/zend/Zend/Mime/Decode.php [new file with mode: 0644]
lib/zend/Zend/Mime/Exception.php [new file with mode: 0644]
lib/zend/Zend/Mime/Message.php [new file with mode: 0644]
lib/zend/Zend/Mime/Part.php [new file with mode: 0644]
lib/zend/Zend/Registry.php [new file with mode: 0644]
lib/zend/Zend/Uri.php [new file with mode: 0644]
lib/zend/Zend/Uri/Exception.php [new file with mode: 0644]
lib/zend/Zend/Uri/Http.php [new file with mode: 0644]
lib/zend/Zend/Validate/Abstract.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/At.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Ch.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/De.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Fi.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Hu.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Interface.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Li.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/No.php [new file with mode: 0644]
lib/zend/Zend/Validate/Hostname/Se.php [new file with mode: 0644]
lib/zend/Zend/Validate/Interface.php [new file with mode: 0644]
lib/zend/Zend/Validate/Ip.php [new file with mode: 0644]
lib/zend/Zend/Version.php [new file with mode: 0644]
portfolio/type/gdata/lib.php [new file with mode: 0755]
portfolio/type/gdata/version.php [new file with mode: 0755]

diff --git a/lib/zend/Zend/Exception.php b/lib/zend/Zend/Exception.php
new file mode 100644 (file)
index 0000000..599d8a0
--- /dev/null
@@ -0,0 +1,30 @@
+<?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
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * @category   Zend
+ * @package    Zend
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Exception extends Exception
+{}
+
diff --git a/lib/zend/Zend/Gdata.php b/lib/zend/Zend/Gdata.php
new file mode 100644 (file)
index 0000000..9e63f88
--- /dev/null
@@ -0,0 +1,207 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_App
+ */
+require_once 'Zend/Gdata/App.php';
+
+/**
+ * Provides functionality to interact with Google data APIs
+ * Subclasses exist to implement service-specific features
+ *
+ * As the Google data API protocol is based upon the Atom Publishing Protocol
+ * (APP), GData functionality extends the appropriate Zend_Gdata_App classes
+ *
+ * @link http://code.google.com/apis/gdata/overview.html
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata extends Zend_Gdata_App
+{
+
+    /**
+     * Service name for use with Google's authentication mechanisms
+     *
+     * @var string
+     */
+    const AUTH_SERVICE_NAME = 'xapi';
+
+    /**
+     * Default URI to which to POST.
+     *
+     * @var string
+     */
+    protected $_defaultPostUri = null;
+
+    /**
+     * Packages to search for classes when using magic __call method, in order.
+     *
+     * @var array
+     */
+    protected $_registeredPackages = array(
+            'Zend_Gdata_Kind',
+            'Zend_Gdata_Extension',
+            'Zend_Gdata',
+            'Zend_Gdata_App_Extension',
+            'Zend_Gdata_App');
+
+    /**
+     * Namespaces used for GData data
+     *
+     * @var array
+     */
+    public static $namespaces = array(
+        'openSearch' => 'http://a9.com/-/spec/opensearchrss/1.0/',
+        'rss' => 'http://blogs.law.harvard.edu/tech/rss',
+        'gd' => 'http://schemas.google.com/g/2005');
+
+    /**
+     * Client object used to communicate
+     *
+     * @var Zend_Gdata_HttpClient
+     */
+    protected $_httpClient;
+
+    /**
+     * Client object used to communicate in static context
+     *
+     * @var Zend_Gdata_HttpClient
+     */
+    protected static $_staticHttpClient = null;
+
+    /**
+     * Create Gdata object
+     *
+     * @param Zend_Http_Client $client
+     * @param string $applicationId The identity of the app in the form of Company-AppName-Version
+     */
+    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        parent::__construct($client, $applicationId);
+    }
+
+    /**
+     * Imports a feed located at $uri.
+     *
+     * @param  string $uri
+     * @param  Zend_Http_Client $client The client used for communication
+     * @param  string $className The class which is used as the return type
+     * @throws Zend_Gdata_App_Exception
+     * @return Zend_Gdata_App_Feed
+     */
+    public static function import($uri, $client = null, $className='Zend_Gdata_Feed')
+    {
+        $app = new Zend_Gdata($client);
+        $requestData = $app->decodeRequest('GET', $uri);
+        $response = $app->performHttpRequest($requestData['method'], $requestData['url']);
+
+        $feedContent = $response->getBody();
+        $feed = self::importString($feedContent, $className);
+        if ($client != null) {
+            $feed->setHttpClient($client);
+        }
+        return $feed;
+    }
+
+    /**
+     * Retreive feed object
+     *
+     * @param mixed $location The location as string or Zend_Gdata_Query
+     * @param string $className The class type to use for returning the feed
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     * @return Zend_Gdata_Feed
+     */
+    public function getFeed($location, $className='Zend_Gdata_Feed')
+    {
+        if (is_string($location)) {
+            $uri = $location;
+        } elseif ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'You must specify the location as either a string URI ' .
+                    'or a child of Zend_Gdata_Query');
+        }
+        return parent::getFeed($uri, $className);
+    }
+
+    /**
+     * Retreive entry object
+     *
+     * @param mixed $location The location as string or Zend_Gdata_Query
+     * @return Zend_Gdata_Feed
+     */
+    public function getEntry($location, $className='Zend_Gdata_Entry')
+    {
+        if (is_string($location)) {
+            $uri = $location;
+        } elseif ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'You must specify the location as either a string URI ' .
+                    'or a child of Zend_Gdata_Query');
+        }
+        return parent::getEntry($uri, $className);
+    }
+
+    /**
+     * Performs a HTTP request using the specified method.
+     * 
+     * Overrides the definition in the parent (Zend_Gdata_App)
+     * and uses the Zend_Gdata_HttpClient functionality
+     * to filter the HTTP requests and responses.
+     *  
+     * @param string $method The HTTP method for the request -
+     *                       'GET', 'POST', 'PUT', 'DELETE'
+     * @param string $url The URL to which this request is being performed,
+     *                    or null if found in $data
+     * @param array $headers An associative array of HTTP headers
+     *                       for this request
+     * @param string $body The body of the HTTP request
+     * @param string $contentType The value for the content type of the
+     *                            request body
+     * @param int $remainingRedirects Number of redirects to follow
+     *                                if requests results in one
+     * @return Zend_Http_Response The response object
+     */
+    public function performHttpRequest($method, $url, $headers = array(), $body = null, $contentType = null, $remainingRedirects = null)
+    {
+        if ($this->_httpClient instanceof Zend_Gdata_HttpClient) {
+            $filterResult = $this->_httpClient->filterHttpRequest($method, $url, $headers, $body, $contentType);
+            $method = $filterResult['method'];
+            $url = $filterResult['url'];
+            $body = $filterResult['body'];
+            $headers = $filterResult['headers'];
+            $contentType = $filterResult['contentType'];
+            return $this->_httpClient->filterHttpResponse(parent::performHttpRequest($method, $url, $headers, $body, $contentType, $remainingRedirects));
+        } else {
+            return parent::performHttpRequest($method, $url, $headers, $body, $contentType, $remainingRedirects);
+        }
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App.php b/lib/zend/Zend/Gdata/App.php
new file mode 100644 (file)
index 0000000..9d826c4
--- /dev/null
@@ -0,0 +1,804 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_Feed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+/**
+ * Zend_Gdata_Http_Client
+ */
+require_once 'Zend/Http/Client.php';
+
+/**
+ * Zend_Version
+ */
+require_once 'Zend/Version.php';
+
+/**
+ * Zend_Gdata_App_MediaSource
+ */
+require_once 'Zend/Gdata/App/MediaSource.php';
+
+/**
+ * Provides Atom Publishing Protocol (APP) functionality.  This class and all
+ * other components of Zend_Gdata_App are designed to work independently from
+ * other Zend_Gdata components in order to interact with generic APP services.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App
+{
+
+    /**
+     * Client object used to communicate
+     *
+     * @var Zend_Http_Client
+     */
+    protected $_httpClient;
+
+    /**
+     * Client object used to communicate in static context
+     *
+     * @var Zend_Http_Client
+     */
+    protected static $_staticHttpClient = null;
+
+    /**
+     * Override HTTP PUT and DELETE request methods?
+     *
+     * @var boolean
+     */
+    protected static $_httpMethodOverride = false;
+
+    /**
+     * Enable gzipped responses?
+     *
+     * @var boolean
+     */
+    protected static $_gzipEnabled = false;
+
+    /**
+     * Use verbose exception messages.  In the case of HTTP errors,
+     * use the body of the HTTP response in the exception message.
+     *
+     * @var boolean
+     */
+    protected static $_verboseExceptionMessages = true;
+
+    /**
+     * Default URI to which to POST.
+     *
+     * @var string
+     */
+    protected $_defaultPostUri = null;
+
+    /**
+     * Packages to search for classes when using magic __call method, in order.
+     *
+     * @var array
+     */
+    protected $_registeredPackages = array(
+            'Zend_Gdata_App_Extension',
+            'Zend_Gdata_App');
+
+    /**
+     * Maximum number of redirects to follow during HTTP operations
+     *
+     * @var int
+     */
+    protected static $_maxRedirects = 5;
+
+    /**
+     * Create Gdata object
+     *
+     * @param Zend_Http_Client $client
+     * @param string $applicationId
+     */
+    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        $this->setHttpClient($client, $applicationId);
+    }
+
+    /**
+     * Adds a Zend Framework package to the $_registeredPackages array.
+     * This array is searched when using the magic __call method below
+     * to instantiante new objects.
+     *
+     * @param string $name The name of the package (eg Zend_Gdata_App)
+     * @return void
+     */
+    public function registerPackage($name)
+    {
+        array_unshift($this->_registeredPackages, $name);
+    }
+
+    /**
+     * Retreive feed object
+     *
+     * @param string $uri The uri from which to retrieve the feed
+     * @param string $className The class which is used as the return type
+     * @return Zend_Gdata_App_Feed
+     */
+    public function getFeed($uri, $className='Zend_Gdata_App_Feed')
+    {
+        return $this->importUrl($uri, $className);
+    }
+
+    /**
+     * Retreive entry object
+     *
+     * @param string $uri
+     * @param string $className The class which is used as the return type
+     * @return Zend_Gdata_App_Entry
+     */
+    public function getEntry($uri, $className='Zend_Gdata_App_Entry')
+    {
+        return $this->importUrl($uri, $className);
+    }
+
+    /**
+     * Get the Zend_Http_Client object used for communication
+     *
+     * @return Zend_Http_Client
+     */
+    public function getHttpClient()
+    {
+        return $this->_httpClient;
+    }
+
+    /**
+     * Set the Zend_Http_Client object used for communication
+     *
+     * @param Zend_Http_Client $client The client to use for communication
+     * @throws Zend_Gdata_App_HttpException
+     * @return Zend_Gdata_App Provides a fluent interface
+     */
+    public function setHttpClient($client, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        if ($client === null) {
+            $client = new Zend_Http_Client();
+        }
+        if (!$client instanceof Zend_Http_Client) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException('Argument is not an instance of Zend_Http_Client.');
+        }
+        $userAgent = $applicationId . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
+        $client->setHeaders('User-Agent', $userAgent);
+        $client->setConfig(array(
+            'strictredirects' => true
+            )
+        );
+        $this->_httpClient = $client;
+        Zend_Gdata::setStaticHttpClient($client);
+        return $this;
+    }
+
+
+    /**
+     * Set the static HTTP client instance
+     *
+     * Sets the static HTTP client object to use for retrieving the feed.
+     *
+     * @param  Zend_Http_Client $httpClient
+     * @return void
+     */
+    public static function setStaticHttpClient(Zend_Http_Client $httpClient)
+    {
+        self::$_staticHttpClient = $httpClient;
+    }
+
+
+    /**
+     * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used.
+     *
+     * @return Zend_Http_Client
+     */
+    public static function getStaticHttpClient()
+    {
+        if (!self::$_staticHttpClient instanceof Zend_Http_Client) {
+            $client = new Zend_Http_Client();
+            $userAgent = 'Zend_Framework_Gdata/' . Zend_Version::VERSION;
+            $client->setHeaders('User-Agent', $userAgent);
+            $client->setConfig(array(
+                'strictredirects' => true
+                )
+            );
+            self::$_staticHttpClient = $client;
+        }
+        return self::$_staticHttpClient;
+    }
+
+    /**
+     * Toggle using POST instead of PUT and DELETE HTTP methods
+     *
+     * Some feed implementations do not accept PUT and DELETE HTTP
+     * methods, or they can't be used because of proxies or other
+     * measures. This allows turning on using POST where PUT and
+     * DELETE would normally be used; in addition, an
+     * X-Method-Override header will be sent with a value of PUT or
+     * DELETE as appropriate.
+     *
+     * @param  boolean $override Whether to override PUT and DELETE with POST.
+     * @return void
+     */
+    public static function setHttpMethodOverride($override = true)
+    {
+        self::$_httpMethodOverride = $override;
+    }
+
+    /**
+     * Get the HTTP override state
+     *
+     * @return boolean
+     */
+    public static function getHttpMethodOverride()
+    {
+        return self::$_httpMethodOverride;
+    }
+
+    /**
+     * Toggle requesting gzip encoded responses
+     *
+     * @param  boolean $enabled Whether or not to enable gzipped responses
+     * @return void
+     */
+    public static function setGzipEnabled($enabled = false)
+    {
+        if ($enabled && !function_exists('gzinflate')) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'You cannot enable gzipped responses if the zlib module ' .
+                    'is not enabled in your PHP installation.');
+        
+        }
+        self::$_gzipEnabled = $enabled;
+    }
+
+    /**
+     * Get the HTTP override state
+     *
+     * @return boolean
+     */
+    public static function getGzipEnabled()
+    {
+        return self::$_gzipEnabled;
+    }
+
+    /**
+     * Get whether to use verbose exception messages
+     *
+     * In the case of HTTP errors,  use the body of the HTTP response 
+     * in the exception message.
+     *
+     * @return boolean
+     */
+    public static function getVerboseExceptionMessages()
+    {
+        return self::$_verboseExceptionMessages;
+    }
+
+    /**
+     * Set whether to use verbose exception messages
+     *
+     * In the case of HTTP errors, use the body of the HTTP response 
+     * in the exception message.
+     *
+     * @param boolean $verbose Whether to use verbose exception messages
+     */
+    public static function setVerboseExceptionMessages($verbose)
+    {
+        self::$_verboseExceptionMessages = $verbose;
+    }
+
+    /**
+     * Set the maximum number of redirects to follow during HTTP operations
+     *
+     * @param int $maxRedirects Maximum number of redirects to follow
+     * @return void
+     */
+    public static function setMaxRedirects($maxRedirects)
+    {
+        self::$_maxRedirects = $maxRedirects;
+    }
+
+    /**
+     * Get the maximum number of redirects to follow during HTTP operations
+     *
+     * @return int Maximum number of redirects to follow
+     */
+    public static function getMaxRedirects()
+    {
+        return self::$_maxRedirects;
+    }
+
+    /**
+     * Provides pre-processing for HTTP requests to APP services.  
+     *
+     * 1. Checks the $data element and, if it's an entry, extracts the XML, 
+     *    multipart data, edit link (PUT,DELETE), etc.
+     * 2. If $data is a string, sets the default content-type  header as 
+     *    'application/atom+xml' if it's not already been set.
+     * 3. Adds a x-http-method override header and changes the HTTP method 
+     *    to 'POST' if necessary as per getHttpMethodOverride()
+     *
+     * @param string $method The HTTP method for the request - 'GET', 'POST', 
+     *                       'PUT', 'DELETE'
+     * @param string $url The URL to which this request is being performed, 
+     *                    or null if found in $data
+     * @param array $headers An associative array of HTTP headers for this 
+     *                       request
+     * @param mixed $data The Zend_Gdata_App_Entry or XML for the  
+     *                    body of the request
+     * @param string $contentTypeOverride The override value for the 
+     *                                    content type of the request body
+     * @return array An associative array containing the determined 
+     *               'method', 'url', 'data', 'headers', 'contentType'
+     */
+    public function prepareRequest($method, $url = null, $headers = array(), $data = null, $contentTypeOverride = null)
+    {
+        $rawData = null;
+        $finalContentType = null;
+        if ($url == null) {
+            $url = $this->_defaultPostUri;
+        }
+
+        if (is_string($data)) {
+            $rawData = $data;
+            if ($contentTypeOverride === null) {
+                $finalContentType = 'application/atom+xml';
+            }
+        } elseif ($data instanceof Zend_Gdata_App_MediaEntry) {
+            $rawData = $data->encode();
+            if ($data->getMediaSource() !== null) {
+                $finalContentType = 'multipart/related; boundary="' . $data->getBoundary() . '"';
+                $headers['MIME-version'] = '1.0'; 
+                $headers['Slug'] = $data->getMediaSource()->getSlug();
+            } else {
+                $finalContentType = 'application/atom+xml';
+            }
+            if ($method == 'PUT' || $method == 'DELETE') {
+                $editLink = $data->getEditLink();
+                if ($editLink != null) {
+                    $url = $editLink->getHref();
+                }
+            }
+        } elseif ($data instanceof Zend_Gdata_App_Entry) {
+            $rawData = $data->saveXML();
+            $finalContentType = 'application/atom+xml';
+            if ($method == 'PUT' || $method == 'DELETE') {
+                $editLink = $data->getEditLink();
+                if ($editLink != null) {
+                    $url = $editLink->getHref();
+                }
+            }
+        } elseif ($data instanceof Zend_Gdata_App_MediaSource) {
+            $rawData = $data->encode();
+            if ($data->getSlug() !== null) {
+                $headers['Slug'] = $data->getSlug();
+            }
+            $finalContentType = $data->getContentType();
+        }
+        if ($method == 'DELETE') {
+            $rawData = null;
+        }
+        if ($method != 'POST' && $method != 'GET' && Zend_Gdata_App::getHttpMethodOverride()) {
+            $headers['x-http-method-override'] = $method;
+            $method = 'POST';
+        } else {
+            $headers['x-http-method-override'] = null;
+        }
+
+        if ($contentTypeOverride != null) {
+            $finalContentType = $contentTypeOverride;
+        }
+
+        return array('method' => $method, 'url' => $url, 'data' => $rawData, 'headers' => $headers, 'contentType' => $finalContentType);
+    }
+
+    /**
+     * Performs a HTTP request using the specified method
+     *
+     * @param string $method The HTTP method for the request - 'GET', 'POST', 
+     *                       'PUT', 'DELETE'
+     * @param string $url The URL to which this request is being performed
+     * @param array $headers An associative array of HTTP headers 
+     *                       for this request
+     * @param string $body The body of the HTTP request
+     * @param string $contentType The value for the content type 
+     *                                of the request body
+     * @param int $remainingRedirects Number of redirects to follow if request
+     *                              s results in one
+     * @return Zend_Http_Response The response object
+     */
+    public function performHttpRequest($method, $url, $headers = null, $body = null, $contentType = null, $remainingRedirects = null)
+    {
+        require_once 'Zend/Http/Client/Exception.php';
+        if ($remainingRedirects === null) {
+            $remainingRedirects = self::getMaxRedirects();
+        }
+        if ($headers === null) {
+            $headers = array();
+        }
+        // check the overridden method
+        if (($method == 'POST' || $method == 'PUT') && $body === null && $headers['x-http-method-override'] != 'DELETE') {
+                require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+                throw new Zend_Gdata_App_InvalidArgumentException(
+                        'You must specify the data to post as either a ' . 
+                        'string or a child of Zend_Gdata_App_Entry');
+        }
+        if ($url === null) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException('You must specify an URI to which to post.');
+        }
+        $headers['Content-Type'] = $contentType;
+        if (Zend_Gdata_App::getGzipEnabled()) {
+            // some services require the word 'gzip' to be in the user-agent header
+            // in addition to the accept-encoding header
+            if (strpos($this->_httpClient->getHeader('User-Agent'), 'gzip') === false) {
+                $headers['User-Agent'] = $this->_httpClient->getHeader('User-Agent') . ' (gzip)';
+            }
+            $headers['Accept-encoding'] = 'gzip, deflate';
+        } else {
+            $headers['Accept-encoding'] = 'identity';
+        }
+
+        // Make sure the HTTP client object is 'clean' before making a request
+        // In addition to standard headers to reset via resetParameters(), 
+        // also reset the Slug header
+        $this->_httpClient->resetParameters();
+        $this->_httpClient->setHeaders('Slug', null);
+
+        // Set the params for the new request to be performed
+        $this->_httpClient->setHeaders($headers);
+        $this->_httpClient->setUri($url);
+        $this->_httpClient->setConfig(array('maxredirects' => 0));
+        $this->_httpClient->setRawData($body, $contentType);
+        try {
+            $response = $this->_httpClient->request($method);
+        } catch (Zend_Http_Client_Exception $e) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
+        }
+        if ($response->isRedirect()) {
+            if ($remainingRedirects > 0) {
+                $newUrl = $response->getHeader('Location');
+                $response = $this->performHttpRequest($method, $newUrl, $headers, $body, $contentType, $remainingRedirects);
+            } else {
+                require_once 'Zend/Gdata/App/HttpException.php';
+                throw new Zend_Gdata_App_HttpException(
+                        'Number of redirects exceeds maximum', null, $response);
+            }
+        }
+        if (!$response->isSuccessful()) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            $exceptionMessage = 'Expected response code 200, got ' . $response->getStatus();
+            if (self::getVerboseExceptionMessages()) {
+                $exceptionMessage .= "\n" . $response->getBody();
+            }
+            $exception = new Zend_Gdata_App_HttpException($exceptionMessage);
+            $exception->setResponse($response);
+            throw $exception;
+        }
+        return $response;
+    }
+
+    /**
+     * Imports a feed located at $uri.
+     *
+     * @param  string $uri
+     * @param  Zend_Http_Client $client The client used for communication
+     * @param  string $className The class which is used as the return type
+     * @throws Zend_Gdata_App_Exception
+     * @return Zend_Gdata_App_Feed
+     */
+    public static function import($uri, $client = null, $className='Zend_Gdata_App_Feed')
+    {
+        $app = new Zend_Gdata_App($client);
+        $requestData = $app->prepareRequest('GET', $uri);
+        $response = $app->performHttpRequest($requestData['method'], $requestData['url']);
+
+        $feedContent = $response->getBody();
+        $feed = self::importString($feedContent, $className);
+        if ($client != null) {
+            $feed->setHttpClient($client);
+        }
+        return $feed;
+    }
+
+    /**
+     * Imports the specified URL (non-statically).
+     *
+     * @param  string $url The URL to import
+     * @param  string $className The class which is used as the return type
+     * @throws Zend_Gdata_App_Exception
+     * @return Zend_Gdata_App_Feed
+     */
+    public function importUrl($url, $className='Zend_Gdata_App_Feed')
+    {
+        $response = $this->get($url);
+        
+        $feedContent = $response->getBody();
+        $feed = self::importString($feedContent, $className);
+        if ($this->getHttpClient() != null) {
+            $feed->setHttpClient($this->getHttpClient());
+        }   
+        return $feed;
+    }   
+
+
+    /**
+     * Imports a feed represented by $string.
+     *
+     * @param  string $string
+     * @param  string $className The class which is used as the return type
+     * @throws Zend_Gdata_App_Exception
+     * @return Zend_Gdata_App_Feed
+     */
+    public static function importString($string, $className='Zend_Gdata_App_Feed')
+    {
+        // Load the feed as an XML DOMDocument object
+        @ini_set('track_errors', 1);
+        $doc = new DOMDocument();
+        $success = @$doc->loadXML($string);
+        @ini_restore('track_errors');
+
+        if (!$success) {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg");
+        }
+        $feed = new $className($string);
+        $feed->setHttpClient(self::getstaticHttpClient());
+        return $feed;
+    }
+
+
+    /**
+     * Imports a feed from a file located at $filename.
+     *
+     * @param  string $filename
+     * @param  string $className The class which is used as the return type
+     * @param  string $useIncludePath Whether the include_path should be searched
+     * @throws Zend_Gdata_App_Exception
+     * @return Zend_Gdata_Feed
+     */
+    public static function importFile($filename,
+            $className='Zend_Gdata_App_Feed', $useIncludePath = false)
+    {
+        @ini_set('track_errors', 1);
+        $feed = @file_get_contents($filename, $useIncludePath);
+        @ini_restore('track_errors');
+        if ($feed === false) {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception("File could not be loaded: $php_errormsg");
+        }
+        return self::importString($feed, $className);
+    }
+
+    /**
+     * GET a uri using client object
+     *
+     * @param  string $uri
+     * @throws Zend_Gdata_App_HttpException
+     * @return Zend_Http_Response
+     */
+    public function get($uri)
+    {
+        $requestData = $this->prepareRequest('GET', $uri);
+        return $this->performHttpRequest($requestData['method'], $requestData['url']);
+    }
+
+    /**
+     * POST data with client object
+     *
+     * @param mixed $data The Zend_Gdata_App_Entry or XML to post
+     * @param string $uri POST URI
+     * @param array $headers Additional HTTP headers to insert.
+     * @param string $contentType Content-type of the data
+     * @param array $extraHaders Extra headers to add to the request
+     * @return Zend_Http_Response
+     * @throws Zend_Gdata_App_Exception
+     * @throws Zend_Gdata_App_HttpException
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     */
+    public function post($data, $uri = null, $remainingRedirects = null,
+            $contentType = null, $extraHeaders = null)
+    {
+        $requestData = $this->prepareRequest('POST', $uri, $extraHeaders, 
+                                             $data, $contentType);
+        return $this->performHttpRequest(
+                $requestData['method'], $requestData['url'], 
+                $requestData['headers'], $requestData['data'], 
+                $requestData['contentType']);
+    }
+
+    /**
+     * PUT data with client object
+     *
+     * @param mixed $data The Zend_Gdata_App_Entry or XML to post
+     * @param string $uri PUT URI
+     * @param array $headers Additional HTTP headers to insert.
+     * @param string $contentType Content-type of the data
+     * @param array $extraHaders Extra headers to add to the request
+     * @return Zend_Http_Response
+     * @throws Zend_Gdata_App_Exception
+     * @throws Zend_Gdata_App_HttpException
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     */
+    public function put($data, $uri = null, $remainingRedirects = null,
+            $contentType = null, $extraHeaders = null)
+    {
+        $requestData = $this->prepareRequest('PUT', $uri, $extraHeaders, $data, $contentType);
+        return $this->performHttpRequest(
+                $requestData['method'], $requestData['url'], 
+                $requestData['headers'], $requestData['data'], 
+                $requestData['contentType']);
+    }
+
+    /**
+     * DELETE entry with client object
+     *
+     * @param mixed $data The Zend_Gdata_App_Entry or URL to delete
+     * @return void
+     * @throws Zend_Gdata_App_Exception
+     * @throws Zend_Gdata_App_HttpException
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     */
+    public function delete($data, $remainingRedirects = null)
+    {
+        if (is_string($data)) {
+            $requestData = $this->prepareRequest('DELETE', $data);
+        } else {
+            $requestData = $this->prepareRequest('DELETE', null, null, $data); 
+        }
+        return $this->performHttpRequest($requestData['method'], $requestData['url'], 
+                                         $requestData['headers'], '', $requestData['contentType'], 
+                                         $remainingRedirects);
+    }
+
+    /**
+     * Inserts an entry to a given URI and returns the response as a fully formed Entry.
+     * @param mixed  $data The Zend_Gdata_App_Entry or XML to post
+     * @param string $uri POST URI
+     * @param string $className The class of entry to be returned.
+     * @return Zend_Gdata_App_Entry The entry returned by the service after insertion.
+     */
+    public function insertEntry($data, $uri, $className='Zend_Gdata_App_Entry')
+    {
+        $response = $this->post($data, $uri);
+
+        $returnEntry = new $className($response->getBody());
+        $returnEntry->setHttpClient(self::getstaticHttpClient());
+        return $returnEntry;
+    }
+
+    /**
+     * Update an entry
+     *
+     * @param mixed $data Zend_Gdata_App_Entry or XML (w/ID and link rel='edit')
+     * @return Zend_Gdata_App_Entry The entry returned from the server
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function updateEntry($data, $uri = null, $className = null)
+    {
+        if ($className === null && $data instanceof Zend_Gdata_App_Entry) {
+            $className = get_class($data);
+        } elseif ($className === null) {
+            $className = 'Zend_Gdata_App_Entry';
+        }
+        
+        $response = $this->put($data, $uri);
+        $returnEntry = new $className($response->getBody());
+        $returnEntry->setHttpClient(self::getstaticHttpClient());
+        return $returnEntry;
+    }
+
+    /**
+     * Provides a magic factory method to instantiate new objects with
+     * shorter syntax than would otherwise be required by the Zend Framework
+     * naming conventions.  For instance, to construct a new
+     * Zend_Gdata_Calendar_Extension_Color, a developer simply needs to do
+     * $gCal->newColor().  For this magic constructor, packages are searched
+     * in the same order as which they appear in the $_registeredPackages
+     * array
+     *
+     * @param string $method The method name being called
+     * @param array $args The arguments passed to the call
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function __call($method, $args)
+    {
+        if (preg_match('/^new(\w+)/', $method, $matches)) {
+            $class = $matches[1];
+            $foundClassName = null;
+            foreach ($this->_registeredPackages as $name) {
+                 try {
+                     @Zend_Loader::loadClass("${name}_${class}");
+                     $foundClassName = "${name}_${class}";
+                     break;
+                 } catch (Zend_Exception $e) {
+                     // package wasn't here- continue searching
+                 }
+            }
+            if ($foundClassName != null) {
+                $reflectionObj = new ReflectionClass($foundClassName);
+                return $reflectionObj->newInstanceArgs($args);
+            } else {
+                require_once 'Zend/Gdata/App/Exception.php';
+                throw new Zend_Gdata_App_Exception(
+                        "Unable to find '${class}' in registered packages");
+            }
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception("No such method ${method}");
+        }
+    }
+
+    /**
+     * Retrieve all entries for a feed, iterating through pages as necessary.
+     * Be aware that calling this function on a large dataset will take a 
+     * significant amount of time to complete. In some cases this may cause 
+     * execution to timeout without proper precautions in place.
+     *
+     * @param $feed The feed to iterate through.
+     * @return mixed A new feed of the same type as the one originally 
+     *          passed in, containing all relevent entries.
+     */
+    public function retrieveAllEntriesForFeed($feed) {
+        $feedClass = get_class($feed);
+        $reflectionObj = new ReflectionClass($feedClass);
+        $result = $reflectionObj->newInstance();
+        do {
+            foreach ($feed as $entry) {
+                $result->addEntry($entry);
+            }
+            
+            $next = $feed->getLink('next');
+            if ($next !== null) {
+                $feed = $this->getFeed($next->href, $feedClass);
+            } else {
+                $feed = null;
+            }
+        }
+        while ($feed != null);
+        return $result;
+    }
+
+    /**
+     * This method enables logging of requests by changing the
+     * Zend_Http_Client_Adapter used for performing the requests.
+     * NOTE: This will not work if you have customized the adapter
+     * already to use a proxy server or other interface.
+     * 
+     * @param $logfile The logfile to use when logging the requests
+     */
+    public function enableRequestDebugLogging($logfile) 
+    {
+        $this->_httpClient->setConfig(array(
+            'adapter' => 'Zend_Gdata_App_LoggingHttpClientAdapterSocket',
+            'logfile' => $logfile
+            ));
+    }
+}
diff --git a/lib/zend/Zend/Gdata/App/AuthException.php b/lib/zend/Zend/Gdata/App/AuthException.php
new file mode 100644 (file)
index 0000000..ac19d52
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @subpackage Zend_Gdata_App
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Exception
+ */
+require_once 'Zend/Gdata/App/Exception.php';
+
+/**
+ * Gdata exceptions
+ *
+ * Class to represent exceptions that occur during Gdata operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @subpackage Zend_Gdata_App
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_AuthException extends Zend_Gdata_App_Exception
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/BadMethodCallException.php b/lib/zend/Zend/Gdata/App/BadMethodCallException.php
new file mode 100644 (file)
index 0000000..8aa9792
--- /dev/null
@@ -0,0 +1,39 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_App_Exception
+ */
+require_once 'Zend/Gdata/App/Exception.php';
+
+/**
+ * Gdata APP exceptions
+ *
+ * Class to represent exceptions that occur during Gdata APP operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_BadMethodCallException extends Zend_Gdata_App_Exception
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/Base.php b/lib/zend/Zend/Gdata/App/Base.php
new file mode 100644 (file)
index 0000000..2eb1eb8
--- /dev/null
@@ -0,0 +1,459 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Abstract class for all XML elements
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_Base
+{
+
+    /**
+     * @var string The XML element name, including prefix if desired
+     */
+    protected $_rootElement = null;
+
+    /**
+     * @var string The XML namespace prefix
+     */
+    protected $_rootNamespace = 'atom';
+
+    /**
+     * @var string The XML namespace URI - takes precedence over lookup up the
+     * corresponding URI for $_rootNamespace
+     */
+    protected $_rootNamespaceURI = null;
+
+    /**
+     * @var array Leftover elements which were not handled
+     */
+    protected $_extensionElements = array();
+
+    /**
+     * @var array Leftover attributes which were not handled
+     */
+    protected $_extensionAttributes = array();
+
+    /**
+     * @var string XML child text node content
+     */
+    protected $_text = null;
+
+    /**
+     * @var array
+     */
+    protected $_namespaces = array(
+        'atom'       => 'http://www.w3.org/2005/Atom',
+        'app'       => 'http://purl.org/atom/app#'
+    );
+
+    public function __construct()
+    {
+    }
+
+    /**
+     * Returns the child text node of this element
+     * This represents any raw text contained within the XML element
+     *
+     * @return string Child text node
+     */
+    public function getText($trim = true)
+    {
+        if ($trim) {
+            return trim($this->_text);
+        } else {
+            return $this->_text;
+        }
+    }
+
+    /**
+     * Sets the child text node of this element
+     * This represents any raw text contained within the XML element
+     *
+     * @param string $value Child text node
+     * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
+     */
+    public function setText($value)
+    {
+        $this->_text = $value;
+        return $this;
+    }
+
+    /**
+     * Returns an array of all elements not matched to data model classes
+     * during the parsing of the XML
+     *
+     * @return array All elements not matched to data model classes during parsing
+     */
+    public function getExtensionElements()
+    {
+        return $this->_extensionElements;
+    }
+
+    /**
+     * Sets an array of all elements not matched to data model classes
+     * during the parsing of the XML.  This method can be used to add arbitrary
+     * child XML elements to any data model class.
+     *
+     * @param array $value All extension elements
+     * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
+     */
+    public function setExtensionElements($value)
+    {
+        $this->_extensionElements = $value;
+        return $this;
+    }
+
+    /**
+     * Returns an array of all extension attributes not transformed into data
+     * model properties during parsing of the XML.  Each element of the array 
+     * is a hashed array of the format: 
+     *     array('namespaceUri' => string, 'name' => string, 'value' => string);
+     *
+     * @return array All extension attributes
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_extensionAttributes;
+    }
+
+    /**
+     * Sets an array of all extension attributes not transformed into data
+     * model properties during parsing of the XML.  Each element of the array 
+     * is a hashed array of the format: 
+     *     array('namespaceUri' => string, 'name' => string, 'value' => string);
+     * This can be used to add arbitrary attributes to any data model element
+     *
+     * @param array $value All extension attributes
+     * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
+     */
+    public function setExtensionAttributes($value)
+    {
+        $this->_extensionAttributes = $value;
+        return $this;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        if (is_null($doc)) {
+            $doc = new DOMDocument('1.0', 'utf-8');
+        }
+        if ($this->_rootNamespaceURI != null) {
+            $element = $doc->createElementNS($this->_rootNamespaceURI, $this->_rootElement);
+        } elseif ($this->_rootNamespace !== null) {
+            if (strpos($this->_rootElement, ':') === false) {
+                $elementName = $this->_rootNamespace . ':' . $this->_rootElement;
+            } else {
+                $elementName = $this->_rootElement;
+            }
+            $element = $doc->createElementNS($this->lookupNamespace($this->_rootNamespace), $elementName);
+        } else {
+            $element = $doc->createElement($this->_rootElement);
+        }
+        if ($this->_text != null) {
+            $element->appendChild($element->ownerDocument->createTextNode($this->_text));
+        }
+        foreach ($this->_extensionElements as $extensionElement) {
+            $element->appendChild($extensionElement->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_extensionAttributes as $attribute) {
+            $element->setAttribute($attribute['name'], $attribute['value']);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a child DOMNode, tries to determine how to map the data into
+     * object instance members.  If no mapping is defined, Extension_Element
+     * objects are created and stored in an array.
+     *
+     * @param DOMNode $child The DOMNode needed to be handled
+     */
+    protected function takeChildFromDOM($child)
+    {
+        if ($child->nodeType == XML_TEXT_NODE) {
+            $this->_text = $child->nodeValue;
+        } else {
+            $extensionElement = new Zend_Gdata_App_Extension_Element();
+            $extensionElement->transferFromDOM($child);
+            $this->_extensionElements[] = $extensionElement;
+        }
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        $arrayIndex = ($attribute->namespaceURI != '')?(
+                $attribute->namespaceURI . ':' . $attribute->name):
+                $attribute->name;
+        $this->_extensionAttributes[$arrayIndex] =
+                array('namespaceUri' => $attribute->namespaceURI,
+                      'name' => $attribute->localName,
+                      'value' => $attribute->nodeValue);
+    }
+
+    /**
+     * Transfers each child and attribute into member variables.
+     * This is called when XML is received over the wire and the data
+     * model needs to be built to represent this XML.
+     *
+     * @param DOMNode $node The DOMNode that represents this object's data
+     */
+    public function transferFromDOM($node)
+    {
+        foreach ($node->childNodes as $child) {
+            $this->takeChildFromDOM($child);
+        }
+        foreach ($node->attributes as $attribute) {
+            $this->takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Parses the provided XML text and generates data model classes for
+     * each know element by turning the XML text into a DOM tree and calling
+     * transferFromDOM($element).  The first data model element with the same
+     * name as $this->_rootElement is used and the child elements are
+     * recursively parsed.
+     *
+     * @param string $xml The XML text to parse
+     */
+    public function transferFromXML($xml)
+    {
+        if ($xml) {
+            // Load the feed as an XML DOMDocument object
+            @ini_set('track_errors', 1);
+            $doc = new DOMDocument();
+            $success = @$doc->loadXML($xml);
+            @ini_restore('track_errors');
+            if (!$success) {
+                require_once 'Zend/Gdata/App/Exception.php';
+                throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg");
+            }
+            $element = $doc->getElementsByTagName($this->_rootElement)->item(0);
+            if (!$element) {
+                require_once 'Zend/Gdata/App/Exception.php';
+                throw new Zend_Gdata_App_Exception('No root <' . $this->_rootElement . '> element');
+            }
+            $this->transferFromDOM($element);
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception('XML passed to transferFromXML cannot be null');
+        }
+    }
+
+    /**
+     * Converts this element and all children into XML text using getDOM()
+     *
+     * @return string XML content
+     */
+    public function saveXML()
+    {
+        $element = $this->getDOM();
+        return $element->ownerDocument->saveXML($element);
+    }
+
+    /**
+     * Alias for saveXML() returns XML content for this element and all
+     * children
+     *
+     * @return string XML content
+     */
+    public function getXML()
+    {
+        return $this->saveXML();
+    }
+    
+    /**
+     * Alias for saveXML()
+     *
+     * Can be overridden by children to provide more complex representations
+     * of entries.
+     *
+     * @return string Encoded string content
+     */
+    public function encode()
+    {
+        return $this->saveXML();
+    }
+
+    /**
+     * Get the full version of a namespace prefix
+     *
+     * Looks up a prefix (atom:, etc.) in the list of registered
+     * namespaces and returns the full namespace URI if
+     * available. Returns the prefix, unmodified, if it's not
+     * registered.
+     *
+     * @return string
+     */
+    public function lookupNamespace($prefix)
+    {
+        return isset($this->_namespaces[$prefix]) ?
+            $this->_namespaces[$prefix] :
+            $prefix;
+    }
+
+
+    /**
+     * Add a namespace and prefix to the registered list
+     *
+     * Takes a prefix and a full namespace URI and adds them to the
+     * list of registered namespaces for use by
+     * $this->lookupNamespace().
+     *
+     * @param  string $prefix The namespace prefix
+     * @param  string $namespaceUri The full namespace URI
+     * @return void
+     */
+    public function registerNamespace($prefix, $namespaceUri)
+    {
+        $this->_namespaces[$prefix] = $namespaceUri;
+    }
+
+    /**
+     * Magic getter to allow acces like $entry->foo to call $entry->getFoo()
+     * Alternatively, if no getFoo() is defined, but a $_foo protected variable
+     * is defined, this is returned.
+     *
+     * TODO Remove ability to bypass getFoo() methods??
+     *
+     * @param string $name The variable name sought
+     */
+    public function __get($name)
+    {
+        $method = 'get'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method));
+        } else if (property_exists($this, "_${name}")) {
+            return $this->{'_' . $name};
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . ' does not exist');
+        }
+    }
+
+    /**
+     * Magic setter to allow acces like $entry->foo='bar' to call
+     * $entry->setFoo('bar') automatically.
+     *
+     * Alternatively, if no setFoo() is defined, but a $_foo protected variable
+     * is defined, this is returned.
+     *
+     * TODO Remove ability to bypass getFoo() methods??
+     *
+     * @param string $name
+     * @param string $value
+     */
+    public function __set($name, $val)
+    {
+        $method = 'set'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method), $val);
+        } else if (isset($this->{'_' . $name}) || is_null($this->{'_' . $name})) {
+            $this->{'_' . $name} = $val;
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . '  does not exist');
+        }
+    }
+
+    /**
+     * Magic __isset method
+     *
+     * @param string $name
+     */
+    public function __isset($name)
+    {
+        $rc = new ReflectionClass(get_class($this));
+        $privName = '_' . $name;
+        if (!($rc->hasProperty($privName))) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . ' does not exist');
+        } else {
+            if (isset($this->{$privName})) {
+                if (is_array($this->{$privName})) {
+                    if (count($this->{$privName}) > 0) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    return true;
+                }
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Magic __unset method
+     *
+     * @param string $name
+     */
+    public function __unset($name)
+    {
+        if (isset($this->{'_' . $name})) {
+            if (is_array($this->{'_' . $name})) {
+                $this->{'_' . $name} = array();
+            } else {
+                $this->{'_' . $name} = null;
+            }
+        }
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     *
+     * @return string The text representation of this object
+     */
+    public function __toString()
+    {
+        return $this->getText();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/BaseMediaSource.php b/lib/zend/Zend/Gdata/App/BaseMediaSource.php
new file mode 100644 (file)
index 0000000..772f589
--- /dev/null
@@ -0,0 +1,176 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_MediaSource
+ */
+require_once 'Zend/Gdata/App/MediaSource.php';
+
+/**
+ * Concrete class to use a file handle as an attachment within a MediaEntry.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_BaseMediaSource implements Zend_Gdata_App_MediaSource
+{
+
+    /**
+     * The content type for the attached file (example image/png)
+     *
+     * @var string
+     */
+    protected $_contentType = null;
+
+    /**
+     * The slug header value representing the attached file title, or null if
+     * no slug should be used.  The slug header is only necessary in some cases,
+     * usually when a multipart upload is not being performed.
+     *
+     * @var string
+     */
+    protected $_slug = null;
+    
+    /** 
+     * The content type for the attached file (example image/png)
+     *
+     * @return string The content type
+     */
+    public function getContentType()
+    {
+        return $this->_contentType;
+    }
+
+    /** 
+     * Set the content type for the file attached (example image/png)
+     *
+     * @param string $value The content type
+     * @return Zend_Gdata_App_MediaFileSource Provides a fluent interface
+     */
+    public function setContentType($value)
+    {
+        $this->_contentType = $value;
+        return $this;
+    }
+
+    /**
+     * Returns the Slug header value.  Used by some services to determine the 
+     * title for the uploaded file.  Returns null if no slug should be used.
+     *
+     * @return string
+     */
+    public function getSlug(){
+        return $this->_slug;
+    }
+
+    /**
+     * Sets the Slug header value.  Used by some services to determine the 
+     * title for the uploaded file.  A null value indicates no slug header.
+     *
+     * @var string The slug value
+     * @return Zend_Gdata_App_MediaSource Provides a fluent interface
+     */
+    public function setSlug($value){
+        $this->_slug = $value;
+        return $this;
+    }
+
+
+    /**
+     * Magic getter to allow acces like $source->foo to call $source->getFoo()
+     * Alternatively, if no getFoo() is defined, but a $_foo protected variable
+     * is defined, this is returned.
+     *
+     * TODO Remove ability to bypass getFoo() methods??
+     *
+     * @param string $name The variable name sought
+     */
+    public function __get($name)
+    {
+        $method = 'get'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method));
+        } else if (property_exists($this, "_${name}")) {
+            return $this->{'_' . $name};
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . ' does not exist');
+        }
+    }
+
+    /**
+     * Magic setter to allow acces like $source->foo='bar' to call
+     * $source->setFoo('bar') automatically.
+     *
+     * Alternatively, if no setFoo() is defined, but a $_foo protected variable
+     * is defined, this is returned.
+     *
+     * @param string $name
+     * @param string $value
+     */
+    public function __set($name, $val)
+    {
+        $method = 'set'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method), $val);
+        } else if (isset($this->{'_' . $name}) || is_null($this->{'_' . $name})) {
+            $this->{'_' . $name} = $val;
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . '  does not exist');
+        }
+    }
+
+    /**
+     * Magic __isset method
+     *
+     * @param string $name
+     */
+    public function __isset($name)
+    {
+        $rc = new ReflectionClass(get_class($this));
+        $privName = '_' . $name;
+        if (!($rc->hasProperty($privName))) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Property ' . $name . ' does not exist');
+        } else {
+            if (isset($this->{$privName})) {
+                if (is_array($this->{$privName})) {
+                    if (count($this->{$privName}) > 0) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    return true;
+                }
+            } else {
+                return false;
+            }
+        }
+    }
+    
+}
diff --git a/lib/zend/Zend/Gdata/App/CaptchaRequiredException.php b/lib/zend/Zend/Gdata/App/CaptchaRequiredException.php
new file mode 100644 (file)
index 0000000..02b8147
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_CaptchaRequiredException
+ */
+require_once 'Zend/Gdata/App/AuthException.php';
+
+/**
+ * Gdata exceptions
+ *
+ * Class to represent an exception that occurs during the use of ClientLogin.
+ * This particular exception happens when a CAPTCHA challenge is issued. This
+ * challenge is a visual puzzle presented to the user to prove that they are
+ * not an automated system.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_CaptchaRequiredException extends Zend_Gdata_App_AuthException
+{
+    /**
+     * The Google Accounts URL prefix.
+     */
+    const ACCOUNTS_URL = 'https://www.google.com/accounts/';
+    
+    /**
+     * The token identifier from the server.
+     * 
+     * @var string
+     */
+    private $captchaToken;
+    
+    /**
+     * The URL of the CAPTCHA image.
+     * 
+     * @var string
+     */
+    private $captchaUrl;
+    
+    /**
+     * Constructs the exception to handle a CAPTCHA required response.
+     * 
+     * @param string $captchaToken The CAPTCHA token ID provided by the server.
+     * @param string $captchaUrl The URL to the CAPTCHA challenge image.
+     */
+    public function __construct($captchaToken, $captchaUrl) {
+        $this->captchaToken = $captchaToken;
+        $this->captchaUrl = Zend_Gdata_App_CaptchaRequiredException::ACCOUNTS_URL . $captchaUrl;
+        parent::__construct('CAPTCHA challenge issued by server');
+    }
+    
+    /**
+     * Retrieves the token identifier as provided by the server.
+     * 
+     * @return string
+     */
+    public function getCaptchaToken() {
+        return $this->captchaToken;
+    }
+    
+    /**
+     * Retrieves the URL CAPTCHA image as provided by the server.
+     * 
+     * @return string
+     */
+    public function getCaptchaUrl() {
+        return $this->captchaUrl;
+    }
+    
+}
diff --git a/lib/zend/Zend/Gdata/App/Entry.php b/lib/zend/Zend/Gdata/App/Entry.php
new file mode 100644 (file)
index 0000000..2fe1740
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_FeedEntryParent
+ */
+require_once 'Zend/Gdata/App/FeedEntryParent.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Content
+ */
+require_once 'Zend/Gdata/App/Extension/Content.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Published
+ */
+require_once 'Zend/Gdata/App/Extension/Published.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Source
+ */
+require_once 'Zend/Gdata/App/Extension/Source.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Summary
+ */
+require_once 'Zend/Gdata/App/Extension/Summary.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Control
+ */
+require_once 'Zend/Gdata/App/Extension/Control.php';
+
+/**
+ * Concrete class for working with Atom entries.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Entry extends Zend_Gdata_App_FeedEntryParent
+{
+
+    /**
+     * Root XML element for Atom entries.
+     *
+     * @var string
+     */
+    protected $_rootElement = 'entry';
+
+    /**
+     * Class name for each entry in this feed*
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_App_Entry';
+
+    /**
+     * atom:content element
+     *
+     * @var Zend_Gdata_App_Extension_Content
+     */
+    protected $_content = null;
+
+    /**
+     * atom:published element
+     *
+     * @var Zend_Gdata_App_Extension_Published
+     */
+    protected $_published = null;
+
+    /**
+     * atom:source element
+     *
+     * @var Zend_Gdata_App_Extension_Source
+     */
+    protected $_source = null;
+
+    /**
+     * atom:summary element
+     *
+     * @var Zend_Gdata_App_Extension_Summary
+     */
+    protected $_summary = null;
+
+    /**
+     * app:control element
+     *
+     * @var Zend_Gdata_App_Extension_Control
+     */
+    protected $_control = null;
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_content != null) {
+            $element->appendChild($this->_content->getDOM($element->ownerDocument));
+        }
+        if ($this->_published != null) {
+            $element->appendChild($this->_published->getDOM($element->ownerDocument));
+        }
+        if ($this->_source != null) {
+            $element->appendChild($this->_source->getDOM($element->ownerDocument));
+        }
+        if ($this->_summary != null) {
+            $element->appendChild($this->_summary->getDOM($element->ownerDocument));
+        }
+        if ($this->_control != null) {
+            $element->appendChild($this->_control->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('atom') . ':' . 'content':
+            $content = new Zend_Gdata_App_Extension_Content();
+            $content->transferFromDOM($child);
+            $this->_content = $content;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'published':
+            $published = new Zend_Gdata_App_Extension_Published();
+            $published->transferFromDOM($child);
+            $this->_published = $published;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'source':
+            $source = new Zend_Gdata_App_Extension_Source();
+            $source->transferFromDOM($child);
+            $this->_source = $source;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'summary':
+            $summary = new Zend_Gdata_App_Extension_Summary();
+            $summary->transferFromDOM($child);
+            $this->_summary = $summary;
+            break;
+        case $this->lookupNamespace('app') . ':' . 'control':
+            $control = new Zend_Gdata_App_Extension_Control();
+            $control->transferFromDOM($child);
+            $this->_control = $control;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * Uploads changes in this entry to the server using Zend_Gdata_App
+     *
+     * @return Zend_Gdata_App_Entry The updated entry
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function save()
+    {
+        $service = new Zend_Gdata_App($this->getHttpClient());
+        return $service->updateEntry($this);
+    }
+
+    /**
+     * Deletes this entry to the server using the referenced
+     * Zend_Http_Client to do a HTTP DELETE to the edit link stored in this
+     * entry's link collection.
+     *
+     * @return void
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function delete()
+    {
+        $service = new Zend_Gdata_App($this->getHttpClient());
+        $service->delete($this);
+    }
+
+    /**
+     * Gets the value of the atom:content element
+     *
+     * @return Zend_Gdata_App_Extension_Content
+     */
+    public function getContent()
+    {
+        return $this->_content;
+    }
+
+    /**
+     * Sets the value of the atom:content element
+     *
+     * @param Zend_Gdata_App_Extension_Content $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setContent($value)
+    {
+        $this->_content = $value;
+        return $this;
+    }
+
+    /**
+     * Sets the value of the atom:published element
+     * This represents the publishing date for an entry
+     *
+     * @return Zend_Gdata_App_Extension_Published
+     */
+    public function getPublished()
+    {
+        return $this->_published;
+    }
+
+    /**
+     * Sets the value of the atom:published element
+     * This represents the publishing date for an entry
+     *
+     * @param Zend_Gdata_App_Extension_Published $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setPublished($value)
+    {
+        $this->_published = $value;
+        return $this;
+    }
+
+    /**
+     * Gets the value of the atom:source element
+     *
+     * @return Zend_Gdata_App_Extension_Source
+     */
+    public function getSource()
+    {
+        return $this->_source;
+    }
+
+    /**
+     * Sets the value of the atom:source element
+     *
+     * @param Zend_Gdata_App_Extension_Source $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setSource($value)
+    {
+        $this->_source = $value;
+        return $this;
+    }
+
+    /**
+     * Gets the value of the atom:summary element
+     * This represents a textual summary of this entry's content
+     *
+     * @return Zend_Gdata_App_Extension_Summary
+     */
+    public function getSummary()
+    {
+        return $this->_summary;
+    }
+
+    /**
+     * Sets the value of the atom:summary element
+     * This represents a textual summary of this entry's content
+     *
+     * @param Zend_Gdata_App_Extension_Summary $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setSummary($value)
+    {
+        $this->_summary = $value;
+        return $this;
+    }
+
+    /**
+     * Gets the value of the app:control element
+     *
+     * @return Zend_Gdata_App_Extension_Control
+     */
+    public function getControl()
+    {
+        return $this->_control;
+    }
+
+    /**
+     * Sets the value of the app:control element
+     *
+     * @param Zend_Gdata_App_Extension_Control $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setControl($value)
+    {
+        $this->_control = $value;
+        return $this;
+    }
+}
diff --git a/lib/zend/Zend/Gdata/App/Exception.php b/lib/zend/Zend/Gdata/App/Exception.php
new file mode 100644 (file)
index 0000000..01f3591
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+/**
+ * Gdata App exceptions
+ *
+ * Class to represent exceptions that occur during Gdata App operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Exception extends Zend_Exception
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension.php b/lib/zend/Zend/Gdata/App/Extension.php
new file mode 100644 (file)
index 0000000..ae8bc99
--- /dev/null
@@ -0,0 +1,37 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Base
+ */
+require_once 'Zend/Gdata/App/Base.php';
+
+/**
+ * Gdata App extensions
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_Extension extends Zend_Gdata_App_Base
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Author.php b/lib/zend/Zend/Gdata/App/Extension/Author.php
new file mode 100644 (file)
index 0000000..846a906
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension/Person.php';
+
+/**
+ * Represents the atom:author element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Author extends Zend_Gdata_App_Extension_Person
+{
+
+    protected $_rootElement = 'author';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Category.php b/lib/zend/Zend/Gdata/App/Extension/Category.php
new file mode 100644 (file)
index 0000000..5bbbab0
--- /dev/null
@@ -0,0 +1,139 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:category element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Category extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'category';
+    protected $_term = null;
+    protected $_scheme = null;
+    protected $_label = null;
+
+    public function __construct($term = null, $scheme = null, $label=null)
+    {
+        parent::__construct();
+        $this->_term = $term;
+        $this->_scheme = $scheme;
+        $this->_label = $label;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_term != null) {
+            $element->setAttribute('term', $this->_term);
+        }
+        if ($this->_scheme != null) {
+            $element->setAttribute('scheme', $this->_scheme);
+        }
+        if ($this->_label != null) {
+            $element->setAttribute('label', $this->_label);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'term':
+            $this->_term = $attribute->nodeValue;
+            break;
+        case 'scheme':
+            $this->_scheme = $attribute->nodeValue;
+            break;
+        case 'label':
+            $this->_label = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Term
+     */
+    public function getTerm()
+    {
+        return $this->_term;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Term $value
+     * @return Zend_Gdata_App_Extension_Category Provides a fluent interface
+     */
+    public function setTerm($value)
+    {
+        $this->_term = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Scheme
+     */
+    public function getScheme()
+    {
+        return $this->_scheme;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Scheme $value
+     * @return Zend_Gdata_App_Extension_Category Provides a fluent interface
+     */
+    public function setScheme($value)
+    {
+        $this->_scheme = $value;
+        return $this;
+    }
+
+    /**
+
+    /**
+     * @return Zend_Gdata_App_Extension_Label
+     */
+    public function getLabel()
+    {
+        return $this->_label;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Label $value
+     * @return Zend_Gdata_App_Extension_Category Provides a fluent interface
+     */
+    public function setLabel($value)
+    {
+        $this->_label = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Content.php b/lib/zend/Zend/Gdata/App/Extension/Content.php
new file mode 100644 (file)
index 0000000..e42dbf7
--- /dev/null
@@ -0,0 +1,85 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Text
+ */
+require_once 'Zend/Gdata/App/Extension/Text.php';
+
+/**
+ * Represents the atom:content element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Content extends Zend_Gdata_App_Extension_Text
+{
+
+    protected $_rootElement = 'content';
+    protected $_src = null;
+
+    public function __construct($text = null, $type = 'text', $src = null)
+    {
+        parent::__construct($text, $type);
+        $this->_src = $src;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_src != null) {
+            $element->setAttribute('src', $this->_src);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'src':
+            $this->_src = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Src
+     */
+    public function getSrc()
+    {
+        return $this->_src;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Src $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setSrc($value)
+    {
+        $this->_src = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Contributor.php b/lib/zend/Zend/Gdata/App/Extension/Contributor.php
new file mode 100644 (file)
index 0000000..9c219dc
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension/Person.php';
+
+/**
+ * Represents the atom:contributor element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Contributor extends Zend_Gdata_App_Extension_Person
+{
+
+    protected $_rootElement = 'contributor';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Control.php b/lib/zend/Zend/Gdata/App/Extension/Control.php
new file mode 100644 (file)
index 0000000..90c4202
--- /dev/null
@@ -0,0 +1,95 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Draft
+ */
+require_once 'Zend/Gdata/App/Extension/Draft.php';
+
+/**
+ * Represents the app:control element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Control extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootNamespace = 'app';
+    protected $_rootElement = 'control';
+    protected $_draft = null;
+
+    public function __construct($draft = null)
+    {
+        parent::__construct();
+        $this->_draft = $draft;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_draft != null) {
+            $element->appendChild($this->_draft->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('app') . ':' . 'draft':
+            $draft = new Zend_Gdata_App_Extension_Draft();
+            $draft->transferFromDOM($child);
+            $this->_draft = $draft;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Draft
+     */
+    public function getDraft()
+    {
+        return $this->_draft;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Draft $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setDraft($value)
+    {
+        $this->_draft = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Draft.php b/lib/zend/Zend/Gdata/App/Extension/Draft.php
new file mode 100644 (file)
index 0000000..c002bff
--- /dev/null
@@ -0,0 +1,47 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the app:draft element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Draft extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootNamespace = 'app';
+    protected $_rootElement = 'draft';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Element.php b/lib/zend/Zend/Gdata/App/Extension/Element.php
new file mode 100644 (file)
index 0000000..b936124
--- /dev/null
@@ -0,0 +1,55 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Class that represents elements which were not handled by other parsing
+ * code in the library.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Element extends Zend_Gdata_App_Extension
+{
+
+    public function __construct($rootElement=null, $rootNamespace=null, $rootNamespaceURI=null, $text=null){
+        parent::__construct();
+        $this->_rootElement = $rootElement;
+        $this->_rootNamespace = $rootNamespace;
+        $this->_rootNamespaceURI = $rootNamespaceURI;
+        $this->_text = $text;
+    }
+
+    public function transferFromDOM($node)
+    {
+        parent::transferFromDOM($node);
+        $this->_rootNamespace = null;
+        $this->_rootNamespaceURI = $node->namespaceURI;
+        $this->_rootElement = $node->localName;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Email.php b/lib/zend/Zend/Gdata/App/Extension/Email.php
new file mode 100644 (file)
index 0000000..953679d
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:email element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Email extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'email';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Generator.php b/lib/zend/Zend/Gdata/App/Extension/Generator.php
new file mode 100644 (file)
index 0000000..b8d1549
--- /dev/null
@@ -0,0 +1,112 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:generator element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Generator extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'generator';
+    protected $_uri = null;
+    protected $_version = null;
+
+    public function __construct($text = null, $uri = null, $version = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+        $this->_uri = $uri;
+        $this->_version = $version;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_uri != null) {
+            $element->setAttribute('uri', $this->_uri);
+        }
+        if ($this->_version != null) {
+            $element->setAttribute('version', $this->_version);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'uri':
+            $this->_uri = $attribute->nodeValue;
+            break;
+        case 'version':
+            $this->_version= $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Uri
+     */
+    public function getUri()
+    {
+        return $this->_uri;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Uri $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setUri($value)
+    {
+        $this->_uri = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Version
+     */
+    public function getVersion()
+    {
+        return $this->_version;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Version $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setVersion($value)
+    {
+        $this->_version = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Icon.php b/lib/zend/Zend/Gdata/App/Extension/Icon.php
new file mode 100644 (file)
index 0000000..44324b7
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:icon element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Icon extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'icon';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Id.php b/lib/zend/Zend/Gdata/App/Extension/Id.php
new file mode 100644 (file)
index 0000000..446489c
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:id element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Id extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'id';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Link.php b/lib/zend/Zend/Gdata/App/Extension/Link.php
new file mode 100644 (file)
index 0000000..829e614
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model for representing an atom:link element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Link extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'link';
+    protected $_href = null;
+    protected $_rel = null;
+    protected $_type = null;
+    protected $_hrefLang = null;
+    protected $_title = null;
+    protected $_length = null;
+
+    public function __construct($href = null, $rel = null, $type = null,
+            $hrefLang = null, $title = null, $length = null)
+    {
+        parent::__construct();
+        $this->_href = $href;
+        $this->_rel = $rel;
+        $this->_type = $type;
+        $this->_hrefLang = $hrefLang;
+        $this->_title = $title;
+        $this->_length = $length;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_href != null) {
+            $element->setAttribute('href', $this->_href);
+        }
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        if ($this->_hrefLang != null) {
+            $element->setAttribute('hreflang', $this->_hrefLang);
+        }
+        if ($this->_title != null) {
+            $element->setAttribute('title', $this->_title);
+        }
+        if ($this->_length != null) {
+            $element->setAttribute('length', $this->_length);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'href':
+            $this->_href = $attribute->nodeValue;
+            break;
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        case 'hreflang':
+            $this->_hrefLang = $attribute->nodeValue;
+            break;
+        case 'title':
+            $this->_title = $attribute->nodeValue;
+            break;
+        case 'length':
+            $this->_length = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Href
+     */
+    public function getHref()
+    {
+        return $this->_href;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Href $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setHref($value)
+    {
+        $this->_href = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Rel
+     */
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Rel $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Type
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Type $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_HrefLang
+     */
+    public function getHrefLang()
+    {
+        return $this->_hrefLang;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_HrefLang $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setHrefLang($value)
+    {
+        $this->_hrefLang = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Title
+     */
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Title $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setTitle($value)
+    {
+        $this->_title = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Length
+     */
+    public function getLength()
+    {
+        return $this->_length;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Length $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setLength($value)
+    {
+        $this->_length = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Logo.php b/lib/zend/Zend/Gdata/App/Extension/Logo.php
new file mode 100644 (file)
index 0000000..9d19e59
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:logo element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Logo extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'logo';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Name.php b/lib/zend/Zend/Gdata/App/Extension/Name.php
new file mode 100644 (file)
index 0000000..c726072
--- /dev/null
@@ -0,0 +1,45 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:name element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Name extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'name';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Person.php b/lib/zend/Zend/Gdata/App/Extension/Person.php
new file mode 100644 (file)
index 0000000..294125d
--- /dev/null
@@ -0,0 +1,160 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Name
+ */
+require_once 'Zend/Gdata/App/Extension/Name.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Email
+ */
+require_once 'Zend/Gdata/App/Extension/Email.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Uri
+ */
+require_once 'Zend/Gdata/App/Extension/Uri.php';
+
+/**
+ * Base class for people (currently used by atom:author, atom:contributor)
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_Extension_Person extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = null;
+    protected $_name = null;
+    protected $_email = null;
+    protected $_uri = null;
+
+    public function __construct($name = null, $email = null, $uri = null)
+    {
+        parent::__construct();
+        $this->_name = $name;
+        $this->_email = $email;
+        $this->_uri = $uri;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_name != null) {
+            $element->appendChild($this->_name->getDOM($element->ownerDocument));
+        }
+        if ($this->_email != null) {
+            $element->appendChild($this->_email->getDOM($element->ownerDocument));
+        }
+        if ($this->_uri != null) {
+            $element->appendChild($this->_uri->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('atom') . ':' . 'name':
+            $name = new Zend_Gdata_App_Extension_Name();
+            $name->transferFromDOM($child);
+            $this->_name = $name;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'email':
+            $email = new Zend_Gdata_App_Extension_Email();
+            $email->transferFromDOM($child);
+            $this->_email = $email;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'uri':
+            $uri = new Zend_Gdata_App_Extension_Uri();
+            $uri->transferFromDOM($child);
+            $this->_uri = $uri;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Name
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Name $value
+     * @return Zend_Gdata_App_Entry Provides a fluent interface
+     */
+    public function setName($value)
+    {
+        $this->_name = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Email
+     */
+    public function getEmail()
+    {
+        return $this->_email;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Email $value
+     * @return Zend_Gdata_App_Extension_Person Provides a fluent interface
+     */
+    public function setEmail($value)
+    {
+        $this->_email = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Uri
+     */
+    public function getUri()
+    {
+        return $this->_uri;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Uri $value
+     * @return Zend_Gdata_App_Extension_Person Provides a fluent interface
+     */
+    public function setUri($value)
+    {
+        $this->_uri = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Published.php b/lib/zend/Zend/Gdata/App/Extension/Published.php
new file mode 100644 (file)
index 0000000..7072538
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:published element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Published extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'published';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Rights.php b/lib/zend/Zend/Gdata/App/Extension/Rights.php
new file mode 100644 (file)
index 0000000..a050d5d
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Text
+ */
+require_once 'Zend/Gdata/App/Extension/Text.php';
+
+/**
+ * Represents the atom:rights element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Rights extends Zend_Gdata_App_Extension_Text
+{
+
+    protected $_rootElement = 'rights';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Source.php b/lib/zend/Zend/Gdata/App/Extension/Source.php
new file mode 100644 (file)
index 0000000..5df072f
--- /dev/null
@@ -0,0 +1,43 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Entry
+ */
+require_once 'Zend/Gdata/App/Entry.php';
+
+/**
+ * @see Zend_Gdata_App_FeedSourceParent
+ */
+require_once 'Zend/Gdata/App/FeedSourceParent.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Source extends Zend_Gdata_App_FeedSourceParent
+{
+
+    protected $_rootElement = 'source';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Subtitle.php b/lib/zend/Zend/Gdata/App/Extension/Subtitle.php
new file mode 100644 (file)
index 0000000..f82d5b6
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Text
+ */
+require_once 'Zend/Gdata/App/Extension/Text.php';
+
+/**
+ * Represents the atom:subtitle element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Subtitle extends Zend_Gdata_App_Extension_Text
+{
+
+    protected $_rootElement = 'subtitle';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Summary.php b/lib/zend/Zend/Gdata/App/Extension/Summary.php
new file mode 100644 (file)
index 0000000..7b61eb2
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Text
+ */
+require_once 'Zend/Gdata/App/Extension/Text.php';
+
+/**
+ * Represents the atom:summary element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Summary extends Zend_Gdata_App_Extension_Text
+{
+
+    protected $_rootElement = 'summary';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Text.php b/lib/zend/Zend/Gdata/App/Extension/Text.php
new file mode 100644 (file)
index 0000000..3780665
--- /dev/null
@@ -0,0 +1,87 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Abstract class for data models that require only text and type-- such as:
+ * title, summary, etc.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_Extension_Text extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = null;
+    protected $_type = 'text';
+
+    public function __construct($text = null, $type = 'text')
+    {
+        parent::__construct();
+        $this->_text = $text;
+        $this->_type = $type;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /*
+     * @return Zend_Gdata_App_Extension_Type
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /*
+     * @param string $value
+     * @return Zend_Gdata_App_Extension_Text Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Title.php b/lib/zend/Zend/Gdata/App/Extension/Title.php
new file mode 100644 (file)
index 0000000..de0856b
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Text
+ */
+require_once 'Zend/Gdata/App/Extension/Text.php';
+
+/**
+ * Represents the atom:title element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Title extends Zend_Gdata_App_Extension_Text
+{
+
+    protected $_rootElement = 'title';
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Updated.php b/lib/zend/Zend/Gdata/App/Extension/Updated.php
new file mode 100644 (file)
index 0000000..f081d2b
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:updated element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Updated extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'updated';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Extension/Uri.php b/lib/zend/Zend/Gdata/App/Extension/Uri.php
new file mode 100644 (file)
index 0000000..03a0d32
--- /dev/null
@@ -0,0 +1,46 @@
+<?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 uri
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the atom:uri element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Extension_Uri extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootElement = 'uri';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/Feed.php b/lib/zend/Zend/Gdata/App/Feed.php
new file mode 100644 (file)
index 0000000..4e2900c
--- /dev/null
@@ -0,0 +1,264 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Entry
+ */
+require_once 'Zend/Gdata/App/Entry.php';
+
+/**
+ * @see Zend_Gdata_App_FeedSourceParent
+ */
+require_once 'Zend/Gdata/App/FeedSourceParent.php';
+
+/**
+ * Atom feed class
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Feed extends Zend_Gdata_App_FeedSourceParent
+        implements Iterator, ArrayAccess
+{
+
+    /**
+     * The root xml element of this data element
+     *
+     * @var string
+     */
+    protected $_rootElement = 'feed';
+
+    /**
+     * Cache of feed entries.
+     *
+     * @var array
+     */
+    protected $_entry = array();
+
+    /**
+     * Current location in $_entry array
+     *
+     * @var int
+     */
+    protected $_entryIndex = 0;
+
+    /**
+     * Make accessing some individual elements of the feed easier.
+     *
+     * Special accessors 'entry' and 'entries' are provided so that if
+     * you wish to iterate over an Atom feed's entries, you can do so
+     * using foreach ($feed->entries as $entry) or foreach
+     * ($feed->entry as $entry).
+     *
+     * @param  string $var The property to get.
+     * @return mixed
+     */
+    public function __get($var)
+    {
+        switch ($var) {
+            case 'entries':
+                return $this;
+            default:
+                return parent::__get($var);
+        }
+    }
+
+    /**
+     * Retrieves the DOM model representing this object and all children
+     *
+     * @param DOMDocument $doc
+     * @return DOMElement
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        foreach ($this->_entry as $entry) {
+            $element->appendChild($entry->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them in the $_entry array based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('atom') . ':' . 'entry':
+            $newEntry = new $this->_entryClassName($child);
+            $newEntry->setHttpClient($this->getHttpClient());
+            $this->_entry[] = $newEntry;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * Get the number of entries in this feed object.
+     *
+     * @return integer Entry count.
+     */
+    public function count()
+    {
+        return count($this->_entry);
+    }
+
+    /**
+     * Required by the Iterator interface.
+     *
+     * @return void
+     */
+    public function rewind()
+    {
+        $this->_entryIndex = 0;
+    }
+
+    /**
+     * Required by the Iterator interface.
+     *
+     * @return mixed The current row, or null if no rows.
+     */
+    public function current()
+    {
+        return $this->_entry[$this->_entryIndex];
+    }
+
+    /**
+     * Required by the Iterator interface.
+     *
+     * @return mixed The current row number (starts at 0), or NULL if no rows
+     */
+    public function key()
+    {
+        return $this->_entryIndex;
+    }
+
+    /**
+     * Required by the Iterator interface.
+     *
+     * @return mixed The next row, or null if no more rows.
+     */
+    public function next()
+    {
+        ++$this->_entryIndex;
+    }
+
+    /**
+     * Required by the Iterator interface.
+     *
+     * @return boolean Whether the iteration is valid
+     */
+    public function valid()
+    {
+        return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
+    }
+
+    /**
+     * Gets the array of atom:entry elements contained within this
+     * atom:feed representation
+     *
+     * @return array Zend_Gdata_App_Entry array
+     */
+    public function getEntry()
+    {
+        return $this->_entry;
+    }
+
+    /**
+     * Sets the array of atom:entry elements contained within this
+     * atom:feed representation
+     *
+     * @param array $value The array of Zend_Gdata_App_Entry elements
+     * @return Zend_Gdata_App_Feed Provides a fluent interface
+     */
+    public function setEntry($value)
+    {
+        $this->_entry = $value;
+        return $this;
+    }
+
+    /**
+     * Adds an entry representation to the array of entries
+     * contained within this feed
+     *
+     * @param Zend_Gdata_App_Entry An individual entry to add.
+     * @return Zend_Gdata_App_Feed Provides a fluent interface
+     */
+    public function addEntry($value)
+    {
+        $this->_entry[] = $value;
+        return $this;
+    }
+
+    /**
+     * Required by the ArrayAccess interface
+     *
+     * @param int $key The index to set
+     * @param Zend_Gdata_App_Entry $value The value to set
+     * @return void
+     */
+    public function offsetSet($key, $value) {
+        $this->_entry[$key] = $value;
+    }
+
+    /**
+     * Required by the ArrayAccess interface
+     *
+     * @param int $key The index to get
+     * @param Zend_Gdata_App_Entry $value The value to set
+     */
+    public function offsetGet($key) {
+        if (array_key_exists($key, $this->_entry)) {
+            return $this->_entry[$key];
+        }
+    }
+
+    /**
+     * Required by the ArrayAccess interface
+     *
+     * @param int $key The index to set
+     * @param Zend_Gdata_App_Entry $value The value to set
+     */
+    public function offsetUnset($key) {
+        if (array_key_exists($key, $this->_entry)) {
+            unset($this->_entry[$key]);
+        }
+    }
+
+    /**
+     * Required by the ArrayAccess interface
+     *
+     * @param int $key The index to check for existence
+     * @return boolean
+     */
+    public function offsetExists($offset) {
+        return (array_key_exists($key, $this->_entry));
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/FeedEntryParent.php b/lib/zend/Zend/Gdata/App/FeedEntryParent.php
new file mode 100644 (file)
index 0000000..64ce5c5
--- /dev/null
@@ -0,0 +1,525 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Element
+*/
+require_once 'Zend/Gdata/App/Extension/Element.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Author
+*/
+require_once 'Zend/Gdata/App/Extension/Author.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Category
+*/
+require_once 'Zend/Gdata/App/Extension/Category.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Contributor
+*/
+require_once 'Zend/Gdata/App/Extension/Contributor.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Id
+ */
+require_once 'Zend/Gdata/App/Extension/Id.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Link
+ */
+require_once 'Zend/Gdata/App/Extension/Link.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Rights
+ */
+require_once 'Zend/Gdata/App/Extension/Rights.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Title
+ */
+require_once 'Zend/Gdata/App/Extension/Title.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Updated
+ */
+require_once 'Zend/Gdata/App/Extension/Updated.php';
+
+/**
+ * Zend_Version
+ */
+require_once 'Zend/Version.php';
+
+/**
+ * Abstract class for common functionality in entries and feeds
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_FeedEntryParent extends Zend_Gdata_App_Base
+{
+
+    /**
+     * HTTP client object to use for retrieving feeds
+     *
+     * @var Zend_Http_Client
+     */
+    protected $_httpClient = null;
+
+    protected $_author = array();
+    protected $_category = array();
+    protected $_contributor = array();
+    protected $_id = null;
+    protected $_link = array();
+    protected $_rights = null;
+    protected $_title = null;
+    protected $_updated = null;
+
+    /**
+     * Constructs a Feed or Entry
+     */
+    public function __construct($element = null)
+    {
+        if (!($element instanceof DOMElement)) {
+            if ($element) {
+                // Load the feed as an XML DOMDocument object
+                @ini_set('track_errors', 1);
+                $doc = new DOMDocument();
+                $success = @$doc->loadXML($element);
+                @ini_restore('track_errors');
+                if (!$success) {
+                    require_once 'Zend/Gdata/App/Exception.php';
+                    throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg");
+                }
+                $element = $doc->getElementsByTagName($this->_rootElement)->item(0);
+                if (!$element) {
+                    require_once 'Zend/Gdata/App/Exception.php';
+                    throw new Zend_Gdata_App_Exception('No root <' . $this->_rootElement . '> element found, cannot parse feed.');
+                }
+                $this->transferFromDOM($element);
+            }
+        } else {
+            $this->transferFromDOM($element);
+        }
+    }
+
+    /**
+     * Set the HTTP client instance
+     *
+     * Sets the HTTP client object to use for retrieving the feed.
+     *
+     * @param  Zend_Http_Client $httpClient
+     * @return Zend_Gdata_App_Feed Provides a fluent interface
+     */
+    public function setHttpClient(Zend_Http_Client $httpClient)
+    {
+        $this->_httpClient = $httpClient;
+        return $this;
+    }
+
+
+    /**
+     * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used.
+     *
+     * @return Zend_Http_Client_Abstract
+     */
+    public function getHttpClient()
+    {
+        if (!$this->_httpClient instanceof Zend_Http_Client) {
+            /**
+             * @see Zend_Http_Client
+             */
+            require_once 'Zend/Http/Client.php';
+            $this->_httpClient = new Zend_Http_Client();
+            $useragent = 'Zend_Framework_Gdata/' . Zend_Version::VERSION;
+            $this->_httpClient->setConfig(array(
+                'strictredirects' => true,
+                 'useragent' => $useragent
+                )
+            );
+        }
+        return $this->_httpClient;
+    }
+
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        foreach ($this->_author as $author) {
+            $element->appendChild($author->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_category as $category) {
+            $element->appendChild($category->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_contributor as $contributor) {
+            $element->appendChild($contributor->getDOM($element->ownerDocument));
+        }
+        if ($this->_id != null) {
+            $element->appendChild($this->_id->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_link as $link) {
+            $element->appendChild($link->getDOM($element->ownerDocument));
+        }
+        if ($this->_rights != null) {
+            $element->appendChild($this->_rights->getDOM($element->ownerDocument));
+        }
+        if ($this->_title != null) {
+            $element->appendChild($this->_title->getDOM($element->ownerDocument));
+        }
+        if ($this->_updated != null) {
+            $element->appendChild($this->_updated->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('atom') . ':' . 'author':
+            $author = new Zend_Gdata_App_Extension_Author();
+            $author->transferFromDOM($child);
+            $this->_author[] = $author;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'category':
+            $category = new Zend_Gdata_App_Extension_Category();
+            $category->transferFromDOM($child);
+            $this->_category[] = $category;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'contributor':
+            $contributor = new Zend_Gdata_App_Extension_Contributor();
+            $contributor->transferFromDOM($child);
+            $this->_contributor[] = $contributor;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'id':
+            $id = new Zend_Gdata_App_Extension_Id();
+            $id->transferFromDOM($child);
+            $this->_id = $id;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'link':
+            $link = new Zend_Gdata_App_Extension_Link();
+            $link->transferFromDOM($child);
+            $this->_link[] = $link;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'rights':
+            $rights = new Zend_Gdata_App_Extension_Rights();
+            $rights->transferFromDOM($child);
+            $this->_rights = $rights;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'title':
+            $title = new Zend_Gdata_App_Extension_Title();
+            $title->transferFromDOM($child);
+            $this->_title = $title;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'updated':
+            $updated = new Zend_Gdata_App_Extension_Updated();
+            $updated->transferFromDOM($child);
+            $this->_updated = $updated;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Author
+     */
+    public function getAuthor()
+    {
+        return $this->_author;
+    }
+
+    /**
+     * Sets the list of the authors of this feed/entry.  In an atom feed, each
+     * author is represented by an atom:author element
+     *
+     * @param array $value
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setAuthor($value)
+    {
+        $this->_author = $value;
+        return $this;
+    }
+
+    /**
+     * Returns the array of categories that classify this feed/entry.  Each
+     * category is represented in an atom feed by an atom:category element.
+     *
+     * @return array Array of Zend_Gdata_App_Extension_Category
+     */
+    public function getCategory()
+    {
+        return $this->_category;
+    }
+
+    /**
+     * Sets the array of categories that classify this feed/entry.  Each
+     * category is represented in an atom feed by an atom:category element.
+     *
+     * @param array $value Array of Zend_Gdata_App_Extension_Category
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setCategory($value)
+    {
+        $this->_category = $value;
+        return $this;
+    }
+
+    /**
+     * Returns the array of contributors to this feed/entry.  Each contributor
+     * is represented in an atom feed by an atom:contributor XML element
+     *
+     * @return array An array of Zend_Gdata_App_Extension_Contributor
+     */
+    public function getContributor()
+    {
+        return $this->_contributor;
+    }
+
+    /**
+     * Sets the array of contributors to this feed/entry.  Each contributor
+     * is represented in an atom feed by an atom:contributor XML element
+     *
+     * @param array $value
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setContributor($value)
+    {
+        $this->_contributor = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Id
+     */
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Id $value
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setId($value)
+    {
+        $this->_id = $value;
+        return $this;
+    }
+
+    /**
+     * Given a particular 'rel' value, this method returns a matching
+     * Zend_Gdata_App_Extension_Link element.  If the 'rel' value 
+     * is not provided, the full array of Zend_Gdata_App_Extension_Link 
+     * elements is returned.  In an atom feed, each link is represented
+     * by an atom:link element.  The 'rel' value passed to this function
+     * is the atom:link/@rel attribute.  Example rel values include 'self',
+     * 'edit', and 'alternate'.
+     *
+     * @param string $rel The rel value of the link to be found.  If null,
+     *     the array of Zend_Gdata_App_Extension_link elements is returned
+     * @return mixed Either a single Zend_Gdata_App_Extension_link element,
+     *     an array of the same or null is returned depending on the rel value
+     *     supplied as the argument to this function
+     */
+    public function getLink($rel = null)
+    {
+        if ($rel == null) {
+            return $this->_link;
+        } else {
+            foreach ($this->_link as $link) {
+                if ($link->rel == $rel) {
+                    return $link;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Returns the Zend_Gdata_App_Extension_Link element which represents
+     * the URL used to edit this resource.  This link is in the atom feed/entry
+     * as an atom:link with a rel attribute value of 'edit'.  
+     *
+     * @return Zend_Gdata_App_Extension_Link The link, or null if not found
+     */
+    public function getEditLink()
+    {
+        return $this->getLink('edit');
+    }
+
+    /**
+     * Returns the Zend_Gdata_App_Extension_Link element which represents
+     * the URL used to retrieve the next chunk of results when paging through
+     * a feed.  This link is in the atom feed as an atom:link with a 
+     * rel attribute value of 'next'.  
+     *
+     * @return Zend_Gdata_App_Extension_Link The link, or null if not found
+     */
+    public function getNextLink()
+    {
+        return $this->getLink('next');
+    }
+
+    /**
+     * Returns the Zend_Gdata_App_Extension_Link element which represents
+     * the URL used to retrieve the previous chunk of results when paging 
+     * through a feed.  This link is in the atom feed as an atom:link with a 
+     * rel attribute value of 'previous'.  
+     *
+     * @return Zend_Gdata_App_Extension_Link The link, or null if not found
+     */
+    public function getPreviousLink()
+    {
+        return $this->getLink('previous');
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Link
+     */
+    public function getLicenseLink()
+    {
+        return $this->getLink('license');
+    }
+
+    /**
+     * Returns the Zend_Gdata_App_Extension_Link element which represents
+     * the URL used to retrieve the entry or feed represented by this object
+     * This link is in the atom feed/entry as an atom:link with a 
+     * rel attribute value of 'self'.  
+     *
+     * @return Zend_Gdata_App_Extension_Link The link, or null if not found
+     */
+    public function getSelfLink()
+    {
+        return $this->getLink('self');
+    }
+
+    /**
+     * Returns the Zend_Gdata_App_Extension_Link element which represents
+     * the URL for an alternate view of the data represented by this feed or
+     * entry.  This alternate view is commonly a user-facing webpage, blog 
+     * post, etc.  The MIME type for the data at the URL is available from the
+     * returned Zend_Gdata_App_Extension_Link element. 
+     * This link is in the atom feed/entry as an atom:link with a 
+     * rel attribute value of 'self'.  
+     *
+     * @return Zend_Gdata_App_Extension_Link The link, or null if not found
+     */
+    public function getAlternateLink()
+    {
+        return $this->getLink('alternate');
+    }
+
+    /**
+     * @param array $value The array of Zend_Gdata_App_Extension_Link elements
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setLink($value)
+    {
+        $this->_link = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_AppExtension_Rights
+     */
+    public function getRights()
+    {
+        return $this->_rights;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Rights $value
+     * @return Zend_Gdata_App_FeedEntryParent Provides a fluent interface
+     */
+    public function setRights($value)
+    {
+        $this->_rights = $value;
+        return $this;
+    }
+
+    /**
+     * Returns the title of this feed or entry.  The title is an extremely
+     * short textual representation of this resource and is found as
+     * an atom:title element in a feed or entry
+     *
+     * @return Zend_Gdata_App_Extension_Title
+     */
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    /**
+     * Returns a string representation of the title of this feed or entry.  
+     * The title is an extremely short textual representation of this 
+     * resource and is found as an atom:title element in a feed or entry
+     *
+     * @return string
+     */
+    public function getTitleValue()
+    {
+        if (($titleObj = $this->getTitle()) != null) {
+            return $titleObj->getText();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the title of this feed or entry.  The title is an extremely
+     * short textual representation of this resource and is found as
+     * an atom:title element in a feed or entry
+     *
+     * @param Zend_Gdata_App_Extension_Title $value
+     * @return Zend_Gdata_App_Feed_Entry_Parent Provides a fluent interface
+     */
+    public function setTitle($value)
+    {
+        $this->_title = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_App_Extension_Updated
+     */
+    public function getUpdated()
+    {
+        return $this->_updated;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Updated $value
+     * @return Zend_Gdata_App_Feed_Entry_Parent Provides a fluent interface
+     */
+    public function setUpdated($value)
+    {
+        $this->_updated = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/FeedSourceParent.php b/lib/zend/Zend/Gdata/App/FeedSourceParent.php
new file mode 100644 (file)
index 0000000..d4e52a8
--- /dev/null
@@ -0,0 +1,245 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Entry
+ */
+require_once 'Zend/Gdata/App/Entry.php';
+
+/**
+ * @see Zend_Gdata_App_FeedSourceParent
+ */
+require_once 'Zend/Gdata/App/FeedEntryParent.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Generator
+ */
+require_once 'Zend/Gdata/App/Extension/Generator.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Icon
+ */
+require_once 'Zend/Gdata/App/Extension/Icon.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Logo
+ */
+require_once 'Zend/Gdata/App/Extension/Logo.php';
+
+/**
+ * @see Zend_Gdata_App_Extension_Subtitle
+ */
+require_once 'Zend/Gdata/App/Extension/Subtitle.php';
+
+/**
+ * Atom feed class
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Gdata_App_FeedSourceParent extends Zend_Gdata_App_FeedEntryParent
+{
+
+    /**
+     * The classname for individual feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_App_Entry';
+
+    /**
+     * Root XML element for Atom entries.
+     *
+     * @var string
+     */
+    protected $_rootElement = null;
+
+    protected $_generator = null;
+    protected $_icon = null;
+    protected $_logo = null;
+    protected $_subtitle = null;
+
+    /**
+     * Set the HTTP client instance
+     *
+     * Sets the HTTP client object to use for retrieving the feed.
+     *
+     * @param  Zend_Http_Client $httpClient
+     * @return Zend_Gdata_App_FeedSourceParent Provides a fluent interface
+     */
+    public function setHttpClient(Zend_Http_Client $httpClient)
+    {
+        $this->_httpClient = $httpClient;
+        foreach ($this->_entry as $entry) {
+            $entry->setHttpClient($httpClient);
+        }
+        return $this;
+    }
+
+    /**
+     * Make accessing some individual elements of the feed easier.
+     *
+     * Special accessors 'entry' and 'entries' are provided so that if
+     * you wish to iterate over an Atom feed's entries, you can do so
+     * using foreach ($feed->entries as $entry) or foreach
+     * ($feed->entry as $entry).
+     *
+     * @param  string $var The property to access.
+     * @return mixed
+     */
+    public function __get($var)
+    {
+        switch ($var) {
+            default:
+                return parent::__get($var);
+        }
+    }
+
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_generator != null) {
+            $element->appendChild($this->_generator->getDOM($element->ownerDocument));
+        }
+        if ($this->_icon != null) {
+            $element->appendChild($this->_icon->getDOM($element->ownerDocument));
+        }
+        if ($this->_logo != null) {
+            $element->appendChild($this->_logo->getDOM($element->ownerDocument));
+        }
+        if ($this->_subtitle != null) {
+            $element->appendChild($this->_subtitle->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them in the $_entry array based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('atom') . ':' . 'generator':
+            $generator = new Zend_Gdata_App_Extension_Generator();
+            $generator->transferFromDOM($child);
+            $this->_generator = $generator;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'icon':
+            $icon = new Zend_Gdata_App_Extension_Icon();
+            $icon->transferFromDOM($child);
+            $this->_icon = $icon;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'logo':
+            $logo = new Zend_Gdata_App_Extension_Logo();
+            $logo->transferFromDOM($child);
+            $this->_logo = $logo;
+            break;
+        case $this->lookupNamespace('atom') . ':' . 'subtitle':
+            $subtitle = new Zend_Gdata_App_Extension_Subtitle();
+            $subtitle->transferFromDOM($child);
+            $this->_subtitle = $subtitle;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * @return Zend_Gdata_AppExtension_Generator
+     */
+    public function getGenerator()
+    {
+        return $this->_generator;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Generator $value
+     * @return Zend_Gdata_App_FeedSourceParent Provides a fluent interface
+     */
+    public function setGenerator($value)
+    {
+        $this->_generator = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_AppExtension_Icon
+     */
+    public function getIcon()
+    {
+        return $this->_icon;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Icon $value
+     * @return Zend_Gdata_App_FeedSourceParent Provides a fluent interface
+     */
+    public function setIcon($value)
+    {
+        $this->_icon = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_AppExtension_logo
+     */
+    public function getlogo()
+    {
+        return $this->_logo;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_logo $value
+     * @return Zend_Gdata_App_FeedSourceParent Provides a fluent interface
+     */
+    public function setlogo($value)
+    {
+        $this->_logo = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_AppExtension_Subtitle
+     */
+    public function getSubtitle()
+    {
+        return $this->_subtitle;
+    }
+
+    /**
+     * @param Zend_Gdata_App_Extension_Subtitle $value
+     * @return Zend_Gdata_App_FeedSourceParent Provides a fluent interface
+     */
+    public function setSubtitle($value)
+    {
+        $this->_subtitle = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/HttpException.php b/lib/zend/Zend/Gdata/App/HttpException.php
new file mode 100644 (file)
index 0000000..c585e46
--- /dev/null
@@ -0,0 +1,118 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_App_Exception
+ */
+require_once 'Zend/Gdata/App/Exception.php';
+
+/**
+ * Zend_Http_Client_Exception
+ */
+require_once 'Zend/Http/Client/Exception.php';
+
+/**
+ * Gdata exceptions
+ *
+ * Class to represent exceptions that occur during Gdata operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_HttpException extends Zend_Gdata_App_Exception
+{
+
+    protected $_httpClientException = null;
+    protected $_response = null;
+
+    /**
+     * Create a new Zend_Gdata_App_HttpException
+     *
+     * @param  string $message Optionally set a message
+     * @param Zend_Http_Client_Exception Optionally pass in a Zend_Http_Client_Exception
+     * @param Zend_Http_Response Optionally pass in a Zend_Http_Response
+     */
+    public function __construct($message = null, $e = null, $response = null)
+    {
+        $this->_httpClientException = $e;
+        $this->_response = $response;
+        parent::__construct($message);
+    }
+
+    /**
+     * Get the Zend_Http_Client_Exception.
+     *
+     * @return Zend_Http_Client_Exception
+     */
+    public function getHttpClientException()
+    {
+        return $this->_httpClientException;
+    }
+
+    /**
+     * Set the Zend_Http_Client_Exception.
+     *
+     * @param Zend_Http_Client_Exception $value
+     */
+    public function setHttpClientException($value)
+    {
+        $this->_httpClientException = $value;
+        return $this;
+    }
+
+    /**
+     * Set the Zend_Http_Response.
+     *
+     * @param Zend_Http_Response $response
+     */
+    public function setResponse($response)
+    {
+        $this->_response = $response;
+        return $this;
+    }
+
+    /**
+     * Get the Zend_Http_Response.
+     *
+     * @return Zend_Http_Response
+     */
+    public function getResponse()
+    {
+        return $this->_response;
+    }
+
+    /**
+     * Get the body of the Zend_Http_Response
+     *
+     * @return string
+     */
+    public function getRawResponseBody()
+    {
+        if ($this->getResponse()) {
+            $response = $this->getResponse();
+            return $response->getRawBody();
+        }
+        return null;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/IOException.php b/lib/zend/Zend/Gdata/App/IOException.php
new file mode 100644 (file)
index 0000000..d78aa53
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Zend_Gdata_App_Exception
+ */
+require_once 'Zend/Gdata/App/Exception.php';
+
+/**
+ * Gdata App IO exceptions.
+ *
+ * Class to represent IO exceptions that occur during Gdata App operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_IOException extends Zend_Gdata_App_Exception
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/InvalidArgumentException.php b/lib/zend/Zend/Gdata/App/InvalidArgumentException.php
new file mode 100644 (file)
index 0000000..562c66c
--- /dev/null
@@ -0,0 +1,39 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_App_Exception
+ */
+require_once 'Zend/Gdata/App/Exception.php';
+
+/**
+ * Gdata exceptions
+ *
+ * Class to represent exceptions that occur during Gdata operations.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_InvalidArgumentException extends Zend_Gdata_App_Exception
+{
+}
diff --git a/lib/zend/Zend/Gdata/App/LoggingHttpClientAdapterSocket.php b/lib/zend/Zend/Gdata/App/LoggingHttpClientAdapterSocket.php
new file mode 100644 (file)
index 0000000..9abe313
--- /dev/null
@@ -0,0 +1,116 @@
+<?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_Http
+ * @subpackage Client_Adapter
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Http/Client/Adapter/Socket.php';
+
+/**
+ * Overrides the traditional socket-based adapter class for Zend_Http_Client to 
+ * enable logging of requests.  All requests are logged to a location specified
+ * in the config as $config['logfile'].  Requests and responses are logged after
+ * they are sent and received/processed, thus an error could prevent logging.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @subpackage App
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_LoggingHttpClientAdapterSocket extends Zend_Http_Client_Adapter_Socket
+{
+
+    /**
+     * The file handle for writing logs
+     *
+     * @var resource|null
+     */
+    protected $log_handle = null;
+
+    /**
+     * Log the given message to the log file.  The log file is configured
+     * as the config param 'logfile'.  This method opens the file for
+     * writing if necessary.
+     *
+     * @param string $message The message to log
+     */
+    protected function log($message)
+    {
+        if ($this->log_handle == null) {
+            $this->log_handle = fopen($this->config['logfile'], 'a');
+        }
+        fwrite($this->log_handle, $message);
+    }
+
+    /**
+     * Connect to the remote server
+     *
+     * @param string  $host
+     * @param int     $port
+     * @param boolean $secure
+     * @param int     $timeout
+     */
+    public function connect($host, $port = 80, $secure = false)
+    {
+        $this->log("Connecting to: ${host}:${port}");
+        return parent::connect($host, $port, $secure);
+    }
+
+    /**
+     * Send request to the remote server
+     *
+     * @param string        $method
+     * @param Zend_Uri_Http $uri
+     * @param string        $http_ver
+     * @param array         $headers
+     * @param string        $body
+     * @return string Request as string
+     */
+    public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+    {
+        $request = parent::write($method, $uri, $http_ver, $headers, $body);
+        $this->log("\n\n" . $request);
+        return $request;
+    }
+
+    /**
+     * Read response from server
+     *
+     * @return string
+     */
+    public function read()
+    {
+        $response = parent::read();
+        $this->log("${response}\n\n");
+        return $response;
+    }
+
+    /**
+     * Close the connection to the server
+     *
+     */
+    public function close()
+    {
+        $this->log("Closing socket\n\n");
+        parent::close();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/MediaEntry.php b/lib/zend/Zend/Gdata/App/MediaEntry.php
new file mode 100644 (file)
index 0000000..fe57438
--- /dev/null
@@ -0,0 +1,160 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Entry
+ */
+require_once 'Zend/Gdata/App/Entry.php';
+
+/**
+ * @see Zend_Gdata_App_MediaSource
+ */
+require_once 'Zend/Gdata/App/MediaSource.php';
+
+/**
+ * @see Zend_Mime
+ */
+require_once 'Zend/Mime.php';
+
+/**
+ * @see Zend_Mime_Message
+ */
+require_once 'Zend/Mime/Message.php';
+
+
+/**
+ * Concrete class for working with Atom entries containing multi-part data.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_MediaEntry extends Zend_Gdata_App_Entry
+{
+    /**
+     * The attached MediaSource/file
+     *
+     * @var Zend_Gdata_App_MediaSource 
+     */
+    protected $_mediaSource = null;
+
+    /**
+     * The Zend_Mime object used to generate the boundary
+     *
+     * @var Zend_Mime 
+     */
+    protected $_mime = null;
+   
+    /**
+     * Constructs a new MediaEntry, representing XML data and optional
+     * file to upload
+     *
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null, $mediaSource = null)
+    {
+        parent::__construct($element);
+        $this->_mime = new Zend_Mime();
+        $this->_mediaSource = $mediaSource;
+    }
+    /**
+     * Return the Zend_Mime object associated with this MediaEntry.  This
+     * object is used to generate the media boundaries.
+     * 
+     * @return Zend_Mime The Zend_Mime object associated with this MediaEntry.
+     */
+    public function getMime()
+    {
+        return $this->_mime;
+    }
+    
+    /**
+     * Return the MIME multipart representation of this MediaEntry.
+     *
+     * @return string The MIME multipart representation of this MediaEntry
+     */
+    public function encode()
+    {
+        $xmlData = $this->saveXML();
+        if ($this->getMediaSource() === null) {
+            // No attachment, just send XML for entry
+            return $xmlData;
+        } else {
+            $mimeMessage = new Zend_Mime_Message();
+            $mimeMessage->setMime($this->_mime);
+           
+            $xmlPart = new Zend_Mime_Part($xmlData);
+            $xmlPart->type = 'application/atom+xml';
+            $xmlPart->encoding = null;
+            $mimeMessage->addPart($xmlPart);
+            
+            $binaryPart = new Zend_Mime_Part($this->getMediaSource()->encode());
+            $binaryPart->type = $this->getMediaSource()->getContentType();
+            $binaryPart->encoding = null;
+            $mimeMessage->addPart($binaryPart);
+
+            return $mimeMessage->generateMessage();
+        }
+    }
+   
+    /**
+     * Return the MediaSource object representing the file attached to this
+     * MediaEntry.
+     *
+     * @return Zend_Gdata_App_MediaSource The attached MediaSource/file
+     */
+    public function getMediaSource()
+    {
+        return $this->_mediaSource;
+    }
+
+    /**
+     * Set the MediaSource object (file) for this MediaEntry
+     *
+     * @param Zend_Gdata_App_MediaSource $value The attached MediaSource/file
+     * @return Zend_Gdata_App_MediaEntry Provides a fluent interface
+     */
+    public function setMediaSource($value)
+    {
+        if ($value instanceof Zend_Gdata_App_MediaSource) {
+            $this->_mediaSource = $value;
+        } else {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'You must specify the media data as a class that conforms to Zend_Gdata_App_MediaSource.');
+        }
+        return $this;
+    }
+    
+    /**
+     * Return the boundary used in the MIME multipart message
+     *
+     * @return string The boundary used in the MIME multipart message 
+     */
+    public function getBoundary()
+    {
+        return $this->_mime->boundary();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/App/MediaFileSource.php b/lib/zend/Zend/Gdata/App/MediaFileSource.php
new file mode 100644 (file)
index 0000000..2970d76
--- /dev/null
@@ -0,0 +1,143 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_MediaData
+ */
+require_once 'Zend/Gdata/App/BaseMediaSource.php';
+
+/**
+ * Concrete class to use a file handle as an attachment within a MediaEntry.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_MediaFileSource extends Zend_Gdata_App_BaseMediaSource
+{
+    /**
+     * The filename which is represented
+     *
+     * @var string 
+     */
+    protected $_filename = null;
+
+    /**
+     * The content type for the file attached (example image/png)
+     *
+     * @var string
+     */
+    protected $_contentType = null;
+    
+    /**
+     * Create a new Zend_Gdata_App_MediaFileSource object.
+     *
+     * @param string $filename The name of the file to read from.
+     */
+    public function __construct($filename)
+    {
+        $this->setFilename($filename);
+    }
+    
+    /**
+     * Return the MIME multipart representation of this MediaEntry.
+     *
+     * @return string
+     * @throws Zend_Gdata_App_IOException
+     */
+    public function encode()
+    {
+        if ($this->getFilename() !== null && 
+            is_readable($this->getFilename())) {
+
+            // Retrieves the file, using the include path
+            $fileHandle = fopen($this->getFilename(), 'r', true);
+            $result = fread($fileHandle, filesize($this->getFilename()));
+            if ($result === false) {
+                require_once 'Zend/Gdata/App/IOException.php';
+                throw new Zend_Gdata_App_IOException("Error reading file - " .
+                        $this->getFilename() . '. Read failed.');
+            }
+            fclose($fileHandle);
+            return $result;
+        } else {
+            require_once 'Zend/Gdata/App/IOException.php';
+            throw new Zend_Gdata_App_IOException("Error reading file - " . 
+                    $this->getFilename() . '. File is not readable.');
+        }
+    }
+    
+    /**
+     * Get the filename associated with this reader.
+     *
+     * @return string
+     */
+    public function getFilename()
+    {
+        return $this->_filename;
+    }
+
+    /**
+     * Set the filename which is to be read.
+     * 
+     * @param string $value The desired file handle.
+     * @return Zend_Gdata_App_MediaFileSource Provides a fluent interface.
+     */
+    public function setFilename($value)
+    {
+        $this->_filename = $value;
+        return $this;
+    }
+   
+    /** 
+     * The content type for the file attached (example image/png)
+     *
+     * @return string The content type
+     */
+    public function getContentType()
+    {
+        return $this->_contentType;
+    }
+
+    /** 
+     * Set the content type for the file attached (example image/png)
+     *
+     * @param string $value The content type
+     * @return Zend_Gdata_App_MediaFileSource Provides a fluent interface
+     */
+    public function setContentType($value)
+    {
+        $this->_contentType = $value;
+        return $this;
+    }
+    
+    /**
+     * Alias for getFilename().
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getFilename();
+    }
+    
+}
diff --git a/lib/zend/Zend/Gdata/App/MediaSource.php b/lib/zend/Zend/Gdata/App/MediaSource.php
new file mode 100644 (file)
index 0000000..c92e15a
--- /dev/null
@@ -0,0 +1,70 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Interface for defining data that can be encoded and sent over the network.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+interface Zend_Gdata_App_MediaSource
+{
+    /**
+     * Return a byte stream representation of this object.
+     *
+     * @return string
+     */
+    public function encode();
+
+    /** 
+     * Set the content type for the file attached (example image/png)
+     *
+     * @param string $value The content type
+     * @return Zend_Gdata_App_MediaFileSource Provides a fluent interface
+     */
+    public function setContentType($value);
+
+    /** 
+     * The content type for the file attached (example image/png)
+     *
+     * @return string The content type
+     */
+    public function getContentType();
+
+    /**
+     * Sets the Slug header value.  Used by some services to determine the 
+     * title for the uploaded file.  A null value indicates no slug header.
+     *
+     * @var string The slug value
+     * @return Zend_Gdata_App_MediaSource Provides a fluent interface
+     */
+    public function setSlug($value);
+
+    /**
+     * Returns the Slug header value.  Used by some services to determine the 
+     * title for the uploaded file.  Returns null if no slug should be used.
+     *
+     * @return string The slug value
+     */
+    public function getSlug();
+}
diff --git a/lib/zend/Zend/Gdata/App/Util.php b/lib/zend/Zend/Gdata/App/Util.php
new file mode 100644 (file)
index 0000000..074fdc0
--- /dev/null
@@ -0,0 +1,60 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Utility class for static functions needed by Zend_Gdata_App
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_App_Util
+{
+
+    /**
+     *  Convert timestamp into RFC 3339 date string.
+     *  2005-04-19T15:30:00
+     *
+     * @param int $timestamp
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     */
+    public static function formatTimestamp($timestamp)
+    {
+        $rfc3339 = '/^(\d{4})\-?(\d{2})\-?(\d{2})((T|t)(\d{2})\:?(\d{2})' .
+                   '\:?(\d{2})(\.\d{1,})?((Z|z)|([\+\-])(\d{2})\:?(\d{2})))?$/';
+
+        if (ctype_digit($timestamp)) {
+            return gmdate('Y-m-d\TH:i:sP', $timestamp);
+        } elseif (preg_match($rfc3339, $timestamp) > 0) {
+            // timestamp is already properly formatted
+            return $timestamp;
+        } else {
+            $ts = strtotime($timestamp);
+            if ($ts === false) {
+                require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+                throw new Zend_Gdata_App_InvalidArgumentException("Invalid timestamp: $timestamp.");
+            }
+            return date('Y-m-d\TH:i:s', $ts);
+        }
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/AuthSub.php b/lib/zend/Zend/Gdata/AuthSub.php
new file mode 100644 (file)
index 0000000..4cc1d9a
--- /dev/null
@@ -0,0 +1,222 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_HttpClient
+ */
+require_once 'Zend/Gdata/HttpClient.php';
+
+/**
+ * Zend_Version
+ */
+require_once 'Zend/Version.php';
+
+/**
+ * Wrapper around Zend_Http_Client to facilitate Google's "Account Authentication
+ * Proxy for Web-Based Applications".
+ *
+ * @see http://code.google.com/apis/accounts/AuthForWebApps.html
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_AuthSub
+{
+
+    const AUTHSUB_REQUEST_URI      = 'https://www.google.com/accounts/AuthSubRequest';
+
+    const AUTHSUB_SESSION_TOKEN_URI = 'https://www.google.com/accounts/AuthSubSessionToken';
+
+    const AUTHSUB_REVOKE_TOKEN_URI  = 'https://www.google.com/accounts/AuthSubRevokeToken';
+
+    const AUTHSUB_TOKEN_INFO_URI    = 'https://www.google.com/accounts/AuthSubTokenInfo';
+
+     /**
+      * Creates a URI to request a single-use AuthSub token.
+      *
+      * @param string $next (required) URL identifying the service to be 
+      *                     accessed.
+      *  The resulting token will enable access to the specified service only.
+      *  Some services may limit scope further, such as read-only access.
+      * @param string $scope (required) URL identifying the service to be 
+      *                      accessed.  The resulting token will enable 
+      *                      access to the specified service only.
+      *                      Some services may limit scope further, such 
+      *                      as read-only access.
+      * @param int $secure (optional) Boolean flag indicating whether the 
+      *                    authentication transaction should issue a secure 
+      *                    token (1) or a non-secure token (0). Secure tokens
+      *                    are available to registered applications only.
+      * @param int $session (optional) Boolean flag indicating whether 
+      *                     the one-time-use  token may be exchanged for 
+      *                     a session token (1) or not (0).
+      * @param string $request_uri (optional) URI to which to direct the 
+      *                            authentication request.
+      */
+     public static function getAuthSubTokenUri($next, $scope, $secure=0, $session=0, 
+                                               $request_uri = self::AUTHSUB_REQUEST_URI)
+     {
+         $querystring = '?next=' . urlencode($next)
+             . '&scope=' . urldecode($scope)
+             . '&secure=' . urlencode($secure)
+             . '&session=' . urlencode($session);
+         return $request_uri . $querystring;
+     }
+
+
+    /**
+     * Upgrades a single use token to a session token
+     *
+     * @param string $token The single use token which is to be upgraded
+     * @param Zend_Http_Client $client (optional) HTTP client to use to 
+     *                                 make the request
+     * @param string $request_uri (optional) URI to which to direct 
+     *                            the session token upgrade
+     * @return string The upgraded token value
+     * @throws Zend_Gdata_App_AuthException
+     * @throws Zend_Gdata_App_HttpException
+     */
+    public static function getAuthSubSessionToken(
+            $token, $client = null, 
+            $request_uri = self::AUTHSUB_SESSION_TOKEN_URI)
+    {
+        $client = self::getHttpClient($token, $client);
+   
+        if ($client instanceof Zend_Gdata_HttpClient) { 
+            $filterResult = $client->filterHttpRequest('GET', $request_uri);
+            $url = $filterResult['url'];
+            $headers = $filterResult['headers'];
+            $client->setHeaders($headers);
+            $client->setUri($url);
+        } else {
+            $client->setUri($request_uri);
+        }
+
+        try {
+            $response = $client->request('GET');
+        } catch (Zend_Http_Client_Exception $e) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
+        }
+
+        // Parse Google's response
+        if ($response->isSuccessful()) {
+            $goog_resp = array();
+            foreach (explode("\n", $response->getBody()) as $l) {
+                $l = chop($l);
+                if ($l) {
+                    list($key, $val) = explode('=', chop($l), 2);
+                    $goog_resp[$key] = $val;
+                }
+            }
+            return $goog_resp['Token'];
+        } else {
+            require_once 'Zend/Gdata/App/AuthException.php';
+            throw new Zend_Gdata_App_AuthException(
+                    'Token upgrade failed. Reason: ' . $response->getBody());
+        }
+    }
+
+    /**
+     * Revoke a token
+     *
+     * @param string $token The token to revoke
+     * @param Zend_Http_Client $client (optional) HTTP client to use to make the request
+     * @param string $request_uri (optional) URI to which to direct the revokation request
+     * @return boolean Whether the revokation was successful
+     * @throws Zend_Gdata_App_HttpException
+     */
+    public static function AuthSubRevokeToken($token, $client = null,
+                                              $request_uri = self::AUTHSUB_REVOKE_TOKEN_URI)
+    {
+        $client = self::getHttpClient($token, $client);
+        $client->setUri($request_uri);
+        ob_start();
+        try {
+            $response = $client->request('GET');
+        } catch (Zend_Http_Client_Exception $e) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
+        }
+        ob_end_clean();
+        // Parse Google's response
+        if ($response->isSuccessful()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * get token information
+     *
+     * @param string $token The token to retrieve information about
+     * @param Zend_Http_Client $client (optional) HTTP client to use to 
+     *                                 make the request
+     * @param string $request_uri (optional) URI to which to direct 
+     *                            the information request
+     */
+    public static function getAuthSubTokenInfo(
+            $token, $client = null, $request_uri = self::AUTHSUB_TOKEN_INFO_URI)
+    {
+        $client = self::getHttpClient($token, $client);
+        $client->setUri($request_uri);
+        ob_start();
+        try {
+            $response = $client->request('GET');
+        } catch (Zend_Http_Client_Exception $e) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
+        }
+        ob_end_clean();
+        return $response->getBody();
+    }
+
+    /**
+     * Retrieve a HTTP client object with AuthSub credentials attached
+     * as the Authorization header
+     *
+     * @param string $token The token to retrieve information about
+     * @param Zend_Gdata_HttpClient $client (optional) HTTP client to use to make the request
+     */
+    public static function getHttpClient($token, $client = null)
+    {
+        if ($client == null) {
+            $client = new Zend_Gdata_HttpClient();
+        }
+        if (!$client instanceof Zend_Http_Client) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException('Client is not an instance of Zend_Http_Client.');
+        }
+        $useragent = 'Zend_Framework_Gdata/' . Zend_Version::VERSION;
+        $client->setConfig(array(
+                'strictredirects' => true,
+                'useragent' => $useragent
+            )
+        );
+        $client->setAuthSubToken($token);
+        return $client;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/ClientLogin.php b/lib/zend/Zend/Gdata/ClientLogin.php
new file mode 100644 (file)
index 0000000..18c4358
--- /dev/null
@@ -0,0 +1,180 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_HttpClient
+ */
+require_once 'Zend/Gdata/HttpClient.php';
+
+/**
+ * Zend_Version
+ */
+require_once 'Zend/Version.php';
+
+/**
+ * Class to facilitate Google's "Account Authentication
+ * for Installed Applications" also known as "ClientLogin".
+ * @see http://code.google.com/apis/accounts/AuthForInstalledApps.html
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_ClientLogin
+{
+
+    /**
+     * The Google client login URI
+     *
+     */
+    const CLIENTLOGIN_URI = 'https://www.google.com/accounts/ClientLogin';
+
+    /**
+     * The default 'source' parameter to send to Google
+     *
+     */
+    const DEFAULT_SOURCE = 'Zend-ZendFramework';
+
+    /**
+     * Set Google authentication credentials.
+     * Must be done before trying to do any Google Data operations that
+     * require authentication.
+     * For example, viewing private data, or posting or deleting entries.
+     *
+     * @param string $email
+     * @param string $password
+     * @param string $service
+     * @param Zend_Gdata_HttpClient $client
+     * @param string $source
+     * @param string $loginToken The token identifier as provided by the server.
+     * @param string $loginCaptcha The user's response to the CAPTCHA challenge.
+     * @param string $accountType An optional string to identify whether the
+     * account to be authenticated is a google or a hosted account. Defaults to 
+     * 'HOSTED_OR_GOOGLE'. See: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request
+     * @throws Zend_Gdata_App_AuthException
+     * @throws Zend_Gdata_App_HttpException
+     * @throws Zend_Gdata_App_CaptchaRequiredException
+     * @return Zend_Gdata_HttpClient
+     */
+    public static function getHttpClient($email, $password, $service = 'xapi',
+        $client = null,
+        $source = self::DEFAULT_SOURCE,
+        $loginToken = null,
+        $loginCaptcha = null,
+        $loginUri = self::CLIENTLOGIN_URI,
+        $accountType = 'HOSTED_OR_GOOGLE')
+    {
+        if (! ($email && $password)) {
+            require_once 'Zend/Gdata/App/AuthException.php';
+            throw new Zend_Gdata_App_AuthException(
+                   'Please set your Google credentials before trying to ' .
+                   'authenticate');
+        }
+
+        if ($client == null) {
+            $client = new Zend_Gdata_HttpClient();
+        }
+        if (!$client instanceof Zend_Http_Client) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException(
+                    'Client is not an instance of Zend_Http_Client.');
+        }
+
+        // Build the HTTP client for authentication
+        $client->setUri($loginUri);
+        $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
+        $client->setConfig(array(
+                'maxredirects'    => 0,
+                'strictredirects' => true,
+                'useragent' => $useragent
+            )
+        );
+        $client->setParameterPost('accountType', $accountType);
+        $client->setParameterPost('Email', (string) $email);
+        $client->setParameterPost('Passwd', (string) $password);
+        $client->setParameterPost('service', (string) $service);
+        $client->setParameterPost('source', (string) $source);
+        if ($loginToken || $loginCaptcha) {
+            if($loginToken && $loginCaptcha) {
+                $client->setParameterPost('logintoken', (string) $loginToken);
+                $client->setParameterPost('logincaptcha', 
+                        (string) $loginCaptcha);
+            }
+            else {
+                require_once 'Zend/Gdata/App/AuthException.php';
+                throw new Zend_Gdata_App_AuthException(
+                    'Please provide both a token ID and a user\'s response ' .
+                    'to the CAPTCHA challenge.');
+            }
+        }
+
+        // Send the authentication request
+        // For some reason Google's server causes an SSL error. We use the
+        // output buffer to supress an error from being shown. Ugly - but works!
+        ob_start();
+        try {
+            $response = $client->request('POST');
+        } catch (Zend_Http_Client_Exception $e) {
+            require_once 'Zend/Gdata/App/HttpException.php';
+            throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
+        }
+        ob_end_clean();
+
+        // Parse Google's response
+        $goog_resp = array();
+        foreach (explode("\n", $response->getBody()) as $l) {
+            $l = chop($l);
+            if ($l) {
+                list($key, $val) = explode('=', chop($l), 2);
+                $goog_resp[$key] = $val;
+            }
+        }
+
+        if ($response->getStatus() == 200) {
+            $client = new Zend_Gdata_HttpClient();
+            $client->setClientLoginToken($goog_resp['Auth']);
+            $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
+            $client->setConfig(array(
+                    'strictredirects' => true,
+                    'useragent' => $useragent
+                )
+            );
+            return $client;
+
+        } elseif ($response->getStatus() == 403) {
+            // Check if the server asked for a CAPTCHA
+            if (array_key_exists('Error', $goog_resp) &&
+                $goog_resp['Error'] == 'CaptchaRequired') {
+                require_once 'Zend/Gdata/App/CaptchaRequiredException.php';
+                throw new Zend_Gdata_App_CaptchaRequiredException(
+                    $goog_resp['CaptchaToken'], $goog_resp['CaptchaUrl']);
+            }
+            else {
+                require_once 'Zend/Gdata/App/AuthException.php';
+                throw new Zend_Gdata_App_AuthException('Authentication with Google failed. Reason: ' .
+                    (isset($goog_resp['Error']) ? $goog_resp['Error'] : 'Unspecified.'));
+            }
+        }
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Docs.php b/lib/zend/Zend/Gdata/Docs.php
new file mode 100755 (executable)
index 0000000..cd63e8d
--- /dev/null
@@ -0,0 +1,254 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata
+ */
+require_once 'Zend/Gdata.php';
+
+/**
+ * @see Zend_Gdata_Docs_DocumentListFeed
+ */
+require_once 'Zend/Gdata/Docs/DocumentListFeed.php';
+
+/**
+ * @see Zend_Gdata_Docs_DocumentListEntry
+ */
+require_once 'Zend/Gdata/Docs/DocumentListEntry.php';
+
+/**
+ * Service class for interacting with the Google Document List data API
+ * @link http://code.google.com/apis/documents/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Docs extends Zend_Gdata
+{
+
+    const DOCUMENTS_LIST_FEED_URI = 'http://docs.google.com/feeds/documents/private/full';
+    const AUTH_SERVICE_NAME = 'writely';
+
+    protected $_defaultPostUri = self::DOCUMENTS_LIST_FEED_URI;
+
+    private static $SUPPORTED_FILETYPES = array(
+      'CSV'=>'text/csv',
+      'DOC'=>'application/msword',
+      'ODS'=>'application/vnd.oasis.opendocument.spreadsheet',
+      'ODT'=>'application/vnd.oasis.opendocument.text',
+      'RTF'=>'application/rtf',
+      'SXW'=>'application/vnd.sun.xml.writer',
+      'TXT'=>'text/plain',
+      'XLS'=>'application/vnd.ms-excel');
+
+    /**
+     * Create Gdata_Docs object
+     *
+     * @param Zend_Http_Client $client (optional) The HTTP client to use when
+     *          when communicating with the Google servers.
+     * @param string $applicationId The identity of the app in the form of Company-AppName-Version
+     */
+    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        $this->registerPackage('Zend_Gdata_Docs');
+        parent::__construct($client, $applicationId);
+        $this->_httpClient->setParameterPost('service', self::AUTH_SERVICE_NAME);
+    }
+
+    /**
+     * Looks up the mime type based on the file name extension. For example,
+     * calling this method with 'csv' would return 
+     * 'text/comma-separated-values'. The Mime type is sent as a header in 
+     * the upload HTTP POST request.
+     *
+     * @param string $fileExtension 
+     * @return string The mime type to be sent to the server to tell it how the
+     *          multipart mime data should be interpreted.
+     */
+    public static function lookupMimeType($fileExtension) {
+      return self::$SUPPORTED_FILETYPES[strtoupper($fileExtension)];
+    }
+
+    /**
+     * Retreive feed object containing entries for the user's documents.
+     *
+     * @param mixed $location The location for the feed, as a URL or Query
+     * @return Zend_Gdata_Docs_DocumentListFeed
+     */
+    public function getDocumentListFeed($location = null)
+    {
+        if ($location === null) {
+            $uri = self::DOCUMENTS_LIST_FEED_URI;
+        } else if ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            $uri = $location;
+        }
+        return parent::getFeed($uri, 'Zend_Gdata_Docs_DocumentListFeed');
+    }
+
+    /**
+     * Retreive entry object representing a single document.
+     *
+     * @param mixed $location The location for the entry, as a URL or Query
+     * @return Zend_Gdata_Docs_DocumentListEntry
+     */
+    public function getDocumentListEntry($location = null)
+    {
+        if ($location === null) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Location must not be null');
+        } else if ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            $uri = $location;
+        }
+        return parent::getEntry($uri, 'Zend_Gdata_Docs_DocumentListEntry');
+    }
+
+    /**
+     * Retreive entry object representing a single document.
+     *
+     * This method builds the URL where this item is stored using the type
+     * and the id of the document.
+     * @param string $docId The URL key for the document. Examples: 
+     *     dcmg89gw_62hfjj8m, pKq0CzjiF3YmGd0AIlHKqeg
+     * @param string $docType The type of the document as used in the Google
+     *     Document List URLs. Examples: document, spreadsheet, presentation
+     * @return Zend_Gdata_Docs_DocumentListEntry
+     */
+    public function getDoc($docId, $docType) {
+        $location = 'http://docs.google.com/feeds/documents/private/full/' . 
+            $docType . '%3A' . $docId;
+        return $this->getDocumentListEntry($location);
+    }
+
+    /**
+     * Retreive entry object for the desired word processing document.
+     *
+     * @param string $id The URL id for the document. Example: 
+     *     dcmg89gw_62hfjj8m
+     */
+    public function getDocument($id) {
+      return $this->getDoc($id, 'document');
+    }
+    
+    /**
+     * Retreive entry object for the desired spreadsheet.
+     *
+     * @param string $id The URL id for the document. Example: 
+     *     pKq0CzjiF3YmGd0AIlHKqeg
+     */
+    public function getSpreadsheet($id) {
+      return $this->getDoc($id, 'spreadsheet');
+    }
+    
+    /**
+     * Retreive entry object for the desired presentation.
+     *
+     * @param string $id The URL id for the document. Example: 
+     *     dcmg89gw_21gtrjcn
+     */
+    public function getPresentation($id) {
+      return $this->getDoc($id, 'presentation');
+    }
+
+    /**
+     * Upload a local file to create a new Google Document entry. 
+     *
+     * @param string $fileLocation The full or relative path of the file to
+     *         be uploaded.
+     * @param string $title The name that this document should have on the 
+     *         server. If set, the title is used as the slug header in the
+     *         POST request. If no title is provided, the location of the 
+     *         file will be used as the slug header in the request. If no 
+     *         mimeType is provided, this method attempts to determine the
+     *         mime type based on the slugHeader by looking for .doc, 
+     *         .csv, .txt, etc. at the end of the file name.
+     *         Example value: 'test.doc'.
+     * @param string $mimeType Describes the type of data which is being sent
+     *         to the server. This must be one of the accepted mime types 
+     *         which are enumerated in SUPPORTED_FILETYPES.
+     * @param string $uri (optional) The URL to which the upload should be 
+     *         made.
+     *         Example: 'http://docs.google.com/feeds/documents/private/full'.
+     * @return Zend_Gdata_Docs_DocumentListEntry The entry for the newly 
+     *         created Google Document.
+     */
+    public function uploadFile($fileLocation, $title=null, $mimeType=null, 
+                               $uri=null)
+    {
+        // Set the URI to which the file will be uploaded.
+        if ($uri === null) {
+            $uri = $this->_defaultPostUri;
+        }
+        
+        // Create the media source which describes the file.
+        $fs = $this->newMediaFileSource($fileLocation);
+        if ($title !== null) {
+            $slugHeader = $title;
+        } else {
+            $slugHeader = $fileLocation;
+        }
+        
+        // Set the slug header to tell the Google Documents server what the 
+        // title of the document should be and what the file extension was 
+        // for the original file.
+        $fs->setSlug($slugHeader);
+
+        // Set the mime type of the data.
+        if ($mimeType === null) {
+          $slugHeader =  $fs->getSlug();
+          $filenameParts = explode('.', $slugHeader);
+          $fileExtension = end($filenameParts);
+          $mimeType = self::lookupMimeType($fileExtension);
+        }
+        
+        // Set the mime type for the upload request.
+        $fs->setContentType($mimeType);
+        
+        // Send the data to the server.
+        return $this->insertDocument($fs, $uri);
+    }
+
+    /**
+     * Inserts an entry to a given URI and returns the response as an Entry.
+     *
+     * @param mixed  $data The Zend_Gdata_Docs_DocumentListEntry or media 
+     *         source to post. If it is a DocumentListEntry, the mediaSource
+     *         should already have been set. If $data is a mediaSource, it 
+     *         should have the correct slug header and mime type.
+     * @param string $uri POST URI
+     * @param string $className (optional) The class of entry to be returned. 
+     *         The default is a 'Zend_Gdata_Docs_DocumentListEntry'.
+     * @return Zend_Gdata_Docs_DocumentListEntry The entry returned by the 
+     *     service after insertion.
+     */
+    public function insertDocument($data, $uri, 
+        $className='Zend_Gdata_Docs_DocumentListEntry')
+    {
+        return $this->insertEntry($data, $uri, $className);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Docs/DocumentListEntry.php b/lib/zend/Zend/Gdata/Docs/DocumentListEntry.php
new file mode 100755 (executable)
index 0000000..d483e3f
--- /dev/null
@@ -0,0 +1,53 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_EntryAtom
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * Represents a Documents List entry in the Documents List data API meta feed
+ * of a user's documents.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Docs_DocumentListEntry extends Zend_Gdata_Entry
+{
+
+    /**
+     * Create a new instance of an entry representing a document.
+     *
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Docs::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Docs/DocumentListFeed.php b/lib/zend/Zend/Gdata/Docs/DocumentListFeed.php
new file mode 100755 (executable)
index 0000000..974588d
--- /dev/null
@@ -0,0 +1,67 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Feed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+
+/**
+ * Data model for a Google Documents List feed of documents
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Docs_DocumentListFeed extends Zend_Gdata_Feed
+{
+
+    /**
+     * The classname for individual feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Docs_DocumentListEntry';
+
+    /**
+     * The classname for the feed.
+     *
+     * @var string
+     */
+    protected $_feedClassName = 'Zend_Gdata_Docs_DocumentListFeed';
+
+    /**
+     * Create a new instance of a feed for a list of documents.
+     *
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Docs::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Docs/Query.php b/lib/zend/Zend/Gdata/Docs/Query.php
new file mode 100755 (executable)
index 0000000..3d6d9fd
--- /dev/null
@@ -0,0 +1,219 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_Query
+ */
+require_once('Zend/Gdata/Query.php');
+
+/**
+ * Assists in constructing queries for Google Document List documents
+ *
+ * @link http://code.google.com/apis/gdata/spreadsheets/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Docs_Query extends Zend_Gdata_Query
+{
+
+    /**
+     * The base URL for retrieving a document list
+     *
+     * @var string
+     */
+    const DOCUMENTS_LIST_FEED_URI = 'http://docs.google.com/feeds/documents';
+
+    /**
+     * The generic base URL used by some inherited methods
+     *
+     * @var string
+     */
+    protected $_defaultFeedUri = self::DOCUMENTS_LIST_FEED_URI;
+
+    /**
+     * The visibility to be used when querying for the feed. A request for a 
+     * feed with private visbility requires the user to be authenricated. 
+     * Private is the only avilable visibility for the documents list.
+     *
+     * @var string
+     */
+    protected $_visibility = 'private';
+
+    /**
+     * The projection determines how much detail should be given in the
+     * result of the query. Full is the only valid projection for the
+     * documents list.
+     *
+     * @var string
+     */
+    protected $_projection = 'full';
+
+    /**
+     * Constructs a new instance of a Zend_Gdata_Docs_Query object.
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Sets the projection for this query. Common values for projection 
+     * include 'full'.
+     *
+     * @param string $value
+     * @return Zend_Gdata_Docs_Query Provides a fluent interface
+     */
+    public function setProjection($value)
+    {
+        $this->_projection = $value;
+        return $this;
+    }
+
+    /**
+     * Sets the visibility for this query. Common values for visibility
+     * include 'private'.
+     *
+     * @return Zend_Gdata_Docs_Query Provides a fluent interface
+     */
+    public function setVisibility($value)
+    {
+        $this->_visibility = $value;
+        return $this;
+    }
+
+    /**
+     * Gets the projection for this query.
+     *
+     * @return string projection
+     */
+    public function getProjection()
+    {
+        return $this->_projection;
+    }
+
+    /**
+     * Gets the visibility for this query.
+     *
+     * @return string visibility
+     */
+    public function getVisibility()
+    {
+        return $this->_visibility;
+    }
+
+    /**
+     * Sets the title attribute for this query. The title parameter is used
+     * to restrict the results to documents whose titles either contain or 
+     * completely match the title.
+     *
+     * @param string $value
+     * @return Zend_Gdata_Docs_Query Provides a fluent interface
+     */
+    public function setTitle($value)
+    {
+        if ($value !== null) {
+            $this->_params['title'] = $value;
+        } else {
+            unset($this->_params['title']);
+        }
+        return $this;
+    }
+
+    /**
+     * Gets the title attribute for this query.
+     *
+     * @return string title
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->_params)) {
+            return $this->_params['title'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the title-exact attribute for this query.
+     * If title-exact is set to true, the title query parameter will be used
+     * in an exact match. Only documents with a title identical to the
+     * title parameter will be returned.
+     *
+     * @param boolean $value Use either true or false
+     * @return Zend_Gdata_Docs_Query Provides a fluent interface
+     */
+    public function setTitleExact($value)
+    {
+        if ($value) {
+            $this->_params['title-exact'] = $value;
+        } else {
+            unset($this->_params['title-exact']);
+        }
+        return $this;
+    }
+
+    /**
+     * Gets the title-exact attribute for this query.
+     *
+     * @return string title-exact
+     */
+    public function getTitleExact()
+    {
+        if (array_key_exists('title-exact', $this->_params)) {
+            return $this->_params['title-exact'];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Gets the full query URL for this query.
+     *
+     * @return string url
+     */
+    public function getQueryUrl()
+    {
+        $uri = $this->_defaultFeedUri;
+
+        if ($this->_visibility !== null) {
+            $uri .= '/' . $this->_visibility;
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception(
+                'A visibility must be provided for cell queries.');
+        }
+
+        if ($this->_projection !== null) {
+            $uri .= '/' . $this->_projection;
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception(
+                'A projection must be provided for cell queries.');
+        }
+
+        $uri .= $this->getQueryString();
+        return $uri;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Entry.php b/lib/zend/Zend/Gdata/Entry.php
new file mode 100644 (file)
index 0000000..ee53467
--- /dev/null
@@ -0,0 +1,48 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_MediaEntry
+ */
+require_once 'Zend/Gdata/App/MediaEntry.php';
+
+/**
+ * Represents the GData flavor of an Atom entry
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Entry extends Zend_Gdata_App_MediaEntry
+{
+
+    protected $_entryClassName = 'Zend_Gdata_Entry';
+
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension.php b/lib/zend/Zend/Gdata/Extension.php
new file mode 100644 (file)
index 0000000..fdeb173
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents a GData extension
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension extends Zend_Gdata_App_Extension
+{
+
+    protected $_rootNamespace = 'gd';
+
+    public function __construct()
+    {
+        /* NOTE: namespaces must be registered before calling parent */
+        $this->registerNamespace('openSearch',
+                'http://a9.com/-/spec/opensearchrss/1.0/');
+        $this->registerNamespace('rss',
+                'http://blogs.law.harvard.edu/tech/rss');
+        $this->registerNamespace('gd',
+                'http://schemas.google.com/g/2005');
+        parent::__construct();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/AttendeeStatus.php b/lib/zend/Zend/Gdata/Extension/AttendeeStatus.php
new file mode 100644 (file)
index 0000000..8617ddf
--- /dev/null
@@ -0,0 +1,120 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent an attendee's status (gd:attendeeStatus)
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_AttendeeStatus extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'attendeeStatus';
+    protected $_value = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_AttendeeStatus object.
+     * @param string $value (optional) Visibility value as URI.
+     */
+    public function __construct($value = null)
+    {
+        parent::__construct();
+        $this->_value = $value;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_value !== null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Get the value for this element's Value attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Set the value for this element's Value attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Visibility The element being modified.
+     */
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     */
+    public function __toString()
+    {
+        return $this->getValue();
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Extension/AttendeeType.php b/lib/zend/Zend/Gdata/Extension/AttendeeType.php
new file mode 100644 (file)
index 0000000..7c6b6a0
--- /dev/null
@@ -0,0 +1,120 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent an attendee's type (gd:attendeeType)
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_AttendeeType extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'attendeeType';
+    protected $_value = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_AttendeeType object.
+     * @param string $value (optional) This entry's 'value' attribute.
+     */
+    public function __construct($value = null)
+    {
+        parent::__construct();
+    $this->_value = $value;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_value != null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Get the value for this element's Value attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Set the value for this element's Value attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Visibility The element being modified.
+     */
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     */
+    public function __toString()
+    {
+        return $this->getValue();
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Extension/Comments.php b/lib/zend/Zend/Gdata/Extension/Comments.php
new file mode 100644 (file)
index 0000000..69ed62c
--- /dev/null
@@ -0,0 +1,114 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Extension_FeedLink
+ */
+require_once 'Zend/Gdata/Extension/FeedLink.php';
+
+/**
+ * Represents the gd:comments element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Comments extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'comments';
+    protected $_rel = null;
+    protected $_feedLink = null;
+
+    public function __construct($rel = null, $feedLink = null)
+    {
+        parent::__construct();
+        $this->_rel = $rel;
+        $this->_feedLink = $feedLink;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_feedLink != null) {
+            $element->appendChild($this->_feedLink->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('gd') . ':' . 'feedLink';
+                $feedLink = new Zend_Gdata_Extension_FeedLink();
+                $feedLink->transferFromDOM($child);
+                $this->_feedLink = $feedLink;
+                break;
+            default:
+                parent::takeChildFromDOM($child);
+                break;
+        }
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    public function getFeedLink()
+    {
+        return $this->_feedLink;
+    }
+
+    public function setFeedLink($value)
+    {
+        $this->_feedLink = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/EntryLink.php b/lib/zend/Zend/Gdata/Extension/EntryLink.php
new file mode 100644 (file)
index 0000000..c00291f
--- /dev/null
@@ -0,0 +1,164 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Entry
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * Represents the gd:entryLink element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_EntryLink extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'entryLink';
+    protected $_href = null;
+    protected $_readOnly = null;
+    protected $_rel = null;
+    protected $_entry = null;
+
+    public function __construct($href = null, $rel = null,
+            $readOnly = null, $entry = null)
+    {
+        parent::__construct();
+        $this->_href = $href;
+        $this->_readOnly = $readOnly;
+        $this->_rel = $rel;
+        $this->_entry = $entry;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_href != null) {
+            $element->setAttribute('href', $this->_href);
+        }
+        if ($this->_readOnly != null) {
+            $element->setAttribute('readOnly', ($this->_readOnly ? "true" : "false"));
+        }
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_entry != null) {
+            $element->appendChild($this->_entry->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('atom') . ':' . 'entry';
+                $entry = new Zend_Gdata_Entry();
+                $entry->transferFromDOM($child);
+                $this->_entry = $entry;
+                break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'href':
+            $this->_href = $attribute->nodeValue;
+            break;
+        case 'readOnly':
+            if ($attribute->nodeValue == "true") {
+                $this->_readOnly = true;
+            }
+            else if ($attribute->nodeValue == "false") {
+                $this->_readOnly = false;
+            }
+            else {
+                throw new Zend_Gdata_App_InvalidArgumentException("Expected 'true' or 'false' for gCal:selected#value.");
+            }
+            break;
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getHref()
+    {
+        return $this->_href;
+    }
+
+    public function setHref($value)
+    {
+        $this->_href = $value;
+        return $this;
+    }
+
+    public function getReadOnly()
+    {
+        return $this->_readOnly;
+    }
+
+    public function setReadOnly($value)
+    {
+        $this->_readOnly = $value;
+        return $this;
+    }
+
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    public function getEntry()
+    {
+        return $this->_entry;
+    }
+
+    public function setEntry($value)
+    {
+        $this->_entry = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/EventStatus.php b/lib/zend/Zend/Gdata/Extension/EventStatus.php
new file mode 100644 (file)
index 0000000..579efc2
--- /dev/null
@@ -0,0 +1,98 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the gd:eventStatus element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_EventStatus extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'eventStatus';
+    protected $_value = null;
+
+    public function __construct($value = null)
+    {
+        parent::__construct();
+        $this->_value = $value;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_value != null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Get the value for this element's Value attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Set the value for this element's Value attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Visibility The element being modified.
+     */
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     */
+    public function __toString()
+    {
+        return $this->getValue();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/ExtendedProperty.php b/lib/zend/Zend/Gdata/Extension/ExtendedProperty.php
new file mode 100644 (file)
index 0000000..05fa95c
--- /dev/null
@@ -0,0 +1,103 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model for gd:extendedProperty element, used by some GData
+ * services to implement arbitrary name/value pair storage
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_ExtendedProperty extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'extendedProperty';
+    protected $_name = null;
+    protected $_value = null;
+
+    public function __construct($name = null, $value = null)
+    {
+        parent::__construct();
+        $this->_name = $name;
+        $this->_value = $value;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_name != null) {
+            $element->setAttribute('name', $this->_name);
+        }
+        if ($this->_value != null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'name':
+            $this->_name = $attribute->nodeValue;
+            break;
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    public function __toString()
+    {
+        return $this->getName() . '=' . $this->getValue();
+    }
+
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    public function setName($value)
+    {
+        $this->_name = $value;
+        return $this;
+    }
+
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/FeedLink.php b/lib/zend/Zend/Gdata/Extension/FeedLink.php
new file mode 100644 (file)
index 0000000..b307f41
--- /dev/null
@@ -0,0 +1,172 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Feed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+/**
+ * Represents the gd:feedLink element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_FeedLink extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'feedLink';
+    protected $_countHint = null;
+    protected $_href = null;
+    protected $_readOnly = null;
+    protected $_rel = null;
+    protected $_feed = null;
+
+    public function __construct($href = null, $rel = null,
+            $countHint = null, $readOnly = null, $feed = null)
+    {
+        parent::__construct();
+        $this->_countHint = $countHint;
+        $this->_href = $href;
+        $this->_readOnly = $readOnly;
+        $this->_rel = $rel;
+        $this->_feed = $feed;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_countHint != null) {
+            $element->setAttribute('countHint', $this->_countHint);
+        }
+        if ($this->_href != null) {
+            $element->setAttribute('href', $this->_href);
+        }
+        if ($this->_readOnly != null) {
+            $element->setAttribute('readOnly', ($this->_readOnly ? "true" : "false"));
+        }
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_feed != null) {
+            $element->appendChild($this->_feed->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('atom') . ':' . 'feed';
+                $feed = new Zend_Gdata_Feed();
+                $feed->transferFromDOM($child);
+                $this->_feed = $feed;
+                break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'countHint':
+            $this->_countHint = $attribute->nodeValue;
+            break;
+        case 'href':
+            $this->_href = $attribute->nodeValue;
+            break;
+        case 'readOnly':
+            if ($attribute->nodeValue == "true") {
+                $this->_readOnly = true;
+            }
+            else if ($attribute->nodeValue == "false") {
+                $this->_readOnly = false;
+            }
+            else {
+                throw new Zend_Gdata_App_InvalidArgumentException("Expected 'true' or 'false' for gCal:selected#value.");
+            }
+            break;
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getHref()
+    {
+        return $this->_href;
+    }
+
+    public function setHref($value)
+    {
+        $this->_href = $value;
+        return $this;
+    }
+
+    public function getReadOnly()
+    {
+        return $this->_readOnly;
+    }
+
+    public function setReadOnly($value)
+    {
+        $this->_readOnly = $value;
+        return $this;
+    }
+
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    public function getFeed()
+    {
+        return $this->_feed;
+    }
+
+    public function setFeed($value)
+    {
+        $this->_feed = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/OpenSearchItemsPerPage.php b/lib/zend/Zend/Gdata/Extension/OpenSearchItemsPerPage.php
new file mode 100644 (file)
index 0000000..443cb1f
--- /dev/null
@@ -0,0 +1,47 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the openSearch:itemsPerPage element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_OpenSearchItemsPerPage extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'itemsPerPage';
+    protected $_rootNamespace = 'openSearch';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php b/lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php
new file mode 100644 (file)
index 0000000..249bd03
--- /dev/null
@@ -0,0 +1,47 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the openSeach:startIndex element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_OpenSearchStartIndex extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'startIndex';
+    protected $_rootNamespace = 'openSearch';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php b/lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php
new file mode 100644 (file)
index 0000000..fb88012
--- /dev/null
@@ -0,0 +1,47 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the openSearch:totalResults element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_OpenSearchTotalResults extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'totalResults';
+    protected $_rootNamespace = 'openSearch';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/OriginalEvent.php b/lib/zend/Zend/Gdata/Extension/OriginalEvent.php
new file mode 100644 (file)
index 0000000..bea57ac
--- /dev/null
@@ -0,0 +1,139 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Feed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+/**
+ * @see Zend_Gdata_When
+ */
+require_once 'Zend/Gdata/Extension/When.php';
+
+/**
+ * Represents the gd:originalEvent element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_OriginalEvent extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'originalEvent';
+    protected $_id = null;
+    protected $_href = null;
+    protected $_when = null;
+
+    public function __construct($id = null, $href = null, $when = null)
+    {
+        parent::__construct();
+        $this->_id = $id;
+        $this->_href = $href;
+        $this->_when = $when;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_id != null) {
+            $element->setAttribute('id', $this->_id);
+        }
+        if ($this->_href != null) {
+            $element->setAttribute('href', $this->_href);
+        }
+        if ($this->_when != null) {
+            $element->appendChild($this->_when->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'id':
+            $this->_id = $attribute->nodeValue;
+            break;
+        case 'href':
+            $this->_href = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('gd') . ':' . 'when';
+                $when = new Zend_Gdata_Extension_When();
+                $when->transferFromDOM($child);
+                $this->_when = $when;
+                break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function setId($value)
+    {
+        $this->_id = $value;
+        return $this;
+    }
+
+    public function getHref()
+    {
+        return $this->_href;
+    }
+
+    public function setHref($value)
+    {
+        $this->_href = $value;
+        return $this;
+    }
+
+    public function getWhen()
+    {
+        return $this->_when;
+    }
+
+    public function setWhen($value)
+    {
+        $this->_when = $value;
+        return $this;
+    }
+
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/Rating.php b/lib/zend/Zend/Gdata/Extension/Rating.php
new file mode 100644 (file)
index 0000000..2e86725
--- /dev/null
@@ -0,0 +1,142 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Implements the gd:rating element
+ * 
+ * TODO: Add comments for these methods
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Rating extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'rating';
+    protected $_min = null;
+    protected $_max = null;
+    protected $_numRaters = null;
+    protected $_average = null;
+
+    public function __construct($average = null, $min = null, 
+            $max = null, $numRaters = null)
+    {
+        parent::__construct();
+        $this->_average = $average;
+        $this->_min = $min; 
+        $this->_max = $max;
+        $this->_numRaters = $numRaters;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_min != null) {
+            $element->setAttribute('min', $this->_min);
+        }
+        if ($this->_max != null) {
+            $element->setAttribute('max', $this->_max);
+        }
+        if ($this->_numRaters != null) {
+            $element->setAttribute('numRaters', $this->_numRaters);
+        }
+        if ($this->_average != null) {
+            $element->setAttribute('average', $this->_average);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+            case 'min':
+                $this->_min = $attribute->nodeValue;
+                break;
+            case 'max':
+                $this->_max = $attribute->nodeValue;
+                break;
+            case 'numRaters':
+                $this->_numRaters = $attribute->nodeValue;
+                break;
+            case 'average':
+                $this->_average = $attribute->nodeValue;
+                break;
+            default:
+                parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    public function __toString() 
+    {   
+        return $this->_average;
+    }
+
+    public function getMin()
+    {
+        return $this->_min;
+    }
+
+    public function setMin($value)
+    {
+        $this->_min = $value;
+        return $this;
+    }
+
+    public function getNumRaters()
+    {
+        return $this->_numRaters;
+    }
+
+    public function setNumRaters($value)
+    {
+        $this->_numRaters = $value;
+        return $this;
+    }
+    public function getAverage()
+    {
+        return $this->_average;
+    }
+
+    public function setAverage($value)
+    {
+        $this->_average = $value;
+        return $this;
+    }
+
+    public function getMax()
+    {
+        return $this->_max;
+    }
+
+    public function setMax($value)
+    {
+        $this->_max = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/Recurrence.php b/lib/zend/Zend/Gdata/Extension/Recurrence.php
new file mode 100644 (file)
index 0000000..4bb7760
--- /dev/null
@@ -0,0 +1,46 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the gd:recurrence element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Recurrence extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'recurrence';
+
+    public function __construct($text = null)
+    {
+        parent::__construct();
+        $this->_text = $text;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/RecurrenceException.php b/lib/zend/Zend/Gdata/Extension/RecurrenceException.php
new file mode 100644 (file)
index 0000000..0d9d939
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent an entry's recurrenceException
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_RecurrenceException extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'recurrenceException';
+    protected $_specialized = null;
+    protected $_entryLink = null;
+    protected $_originalEvent = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_RecurrenceException object.
+     * @param bool $specialized (optional) Whether this is a specialized exception or not.
+     * @param Zend_Gdata_EntryLink (optional) An Event entry with details about the exception.
+     * @param Zend_Gdata_OriginalEvent (optional) The origianl recurrent event this is an exeption to.
+     */
+    public function __construct($specialized = null, $entryLink = null,
+            $originalEvent = null)
+    {
+        parent::__construct();
+        $this->_specialized = $specialized;
+        $this->_entryLink = $entryLink;
+        $this->_originalEvent = $originalEvent;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_specialized != null) {
+            $element->setAttribute('specialized', ($this->_specialized ? "true" : "false"));
+        }
+        if ($this->_entryLink != null) {
+            $element->appendChild($this->_entryLink->getDOM($element->ownerDocument));
+        }
+        if ($this->_originalEvent != null) {
+            $element->appendChild($this->_originalEvent->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'specialized':
+            if ($attribute->nodeValue == "true") {
+                $this->_specialized = true;
+            }
+            else if ($attribute->nodeValue == "false") {
+                $this->_specialized = false;
+            }
+            else {
+                throw new Zend_Gdata_App_InvalidArgumentException("Expected 'true' or 'false' for gCal:selected#value.");
+            }
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them as members of this entry based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('gd') . ':' . 'entryLink':
+            $entryLink = new Zend_Gdata_Extension_EntryLink();
+            $entryLink->transferFromDOM($child);
+            $this->_entryLink = $entryLink;
+            break;
+        case $this->lookupNamespace('gd') . ':' . 'originalEvent':
+            $originalEvent = new Zend_Gdata_Extension_OriginalEvent();
+            $originalEvent->transferFromDOM($child);
+            $this->_originalEvent = $originalEvent;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * Get the value for this element's Specialized attribute.
+     *
+     * @return bool The requested attribute.
+     */
+    public function getSpecialized()
+    {
+        return $this->_specialized;
+    }
+
+    /**
+     * Set the value for this element's Specialized attribute.
+     *
+     * @param bool $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_RecurrenceException The element being modified.
+     */
+    public function setSpecialized($value)
+    {
+        $this->_specialized = $value;
+        return $this;
+    }
+
+    /**
+     * Get the value for this element's EntryLink attribute.
+     *
+     * @return Zend_Gdata_Extension_EntryLink The requested attribute.
+     */
+    public function getEntryLink()
+    {
+        return $this->_entryLink;
+    }
+
+    /**
+     * Set the value for this element's EntryLink attribute.
+     *
+     * @param Zend_Gdata_Extension_EntryLink $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_RecurrenceException The element being modified.
+     */
+    public function setEntryLink($value)
+    {
+        $this->_entryLink = $value;
+        return $this;
+    }
+
+    /**
+     * Get the value for this element's Specialized attribute.
+     *
+     * @return Zend_Gdata_Extension_OriginalEvent The requested attribute.
+     */
+    public function getOriginalEvent()
+    {
+        return $this->_originalEvent;
+    }
+
+    /**
+     * Set the value for this element's Specialized attribute.
+     *
+     * @param Zend_Gdata_Extension_OriginalEvent $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_RecurrenceException The element being modified.
+     */
+    public function setOriginalEvent($value)
+    {
+        $this->_originalEvent = $value;
+        return $this;
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Extension/Reminder.php b/lib/zend/Zend/Gdata/Extension/Reminder.php
new file mode 100644 (file)
index 0000000..50639d6
--- /dev/null
@@ -0,0 +1,168 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Implements the gd:reminder element used to set/retrieve notifications
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Reminder extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'reminder';
+    protected $_absoluteTime = null;
+    protected $_method = null;
+    protected $_days = null;
+    protected $_hours = null;
+    protected $_minutes = null;
+
+    public function __construct($absoluteTime = null, $method = null, $days = null,
+            $hours = null, $minutes = null)
+    {
+        parent::__construct();
+        $this->_absoluteTime = $absoluteTime;
+        $this->_method = $method;
+        $this->_days = $days;
+        $this->_hours = $hours;
+        $this->_minutes = $minutes;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_absoluteTime != null) {
+            $element->setAttribute('absoluteTime', $this->_absoluteTime);
+        }
+        if ($this->_method != null) {
+            $element->setAttribute('method', $this->_method);
+        }
+        if ($this->_days != null) {
+            $element->setAttribute('days', $this->_days);
+        }
+        if ($this->_hours != null) {
+            $element->setAttribute('hours', $this->_hours);
+        }
+        if ($this->_minutes != null) {
+            $element->setAttribute('minutes', $this->_minutes);
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+            case 'absoluteTime':
+                $this->_absoluteTime = $attribute->nodeValue;
+                break;
+            case 'method':
+                $this->_method = $attribute->nodeValue;
+                break;
+            case 'days':
+                $this->_days = $attribute->nodeValue;
+                break;
+            case 'hours':
+                $this->_hours = $attribute->nodeValue;
+                break;
+            case 'minutes':
+                $this->_minutes = $attribute->nodeValue;
+                break;
+            default:
+                parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    public function __toString()
+    {
+        $s;
+        if ($absoluteTime)
+            $s = "at" . $absoluteTime;
+        else if ($days)
+            $s = "in" . $days . "days";
+        else if ($hours)
+            $s = "in" . $hours . "hours";
+        else if ($minutes)
+            $s = "in" . $minutes . "minutes";
+        return $method . $s;
+    }
+
+    public function getAbsoluteTime()
+    {
+        return $this->_absoluteTime;
+    }
+
+    public function setAbsoluteTime($value)
+    {
+        $this->_absoluteTime = $value;
+        return $this;
+    }
+
+    public function getDays()
+    {
+        return $this->_days;
+    }
+
+    public function setDays($value)
+    {
+        $this->_days = $value;
+        return $this;
+    }
+    public function getHours()
+    {
+        return $this->_hours;
+    }
+
+    public function setHours($value)
+    {
+        $this->_hours = $value;
+        return $this;
+    }
+
+    public function getMinutes()
+    {
+        return $this->_minutes;
+    }
+
+    public function setMinutes($value)
+    {
+        $this->_minutes = $value;
+        return $this;
+    }
+
+    public function getMethod()
+    {
+        return $this->_method;
+    }
+
+    public function setMethod($value)
+    {
+        $this->_method = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/Transparency.php b/lib/zend/Zend/Gdata/Extension/Transparency.php
new file mode 100644 (file)
index 0000000..8cf1c7b
--- /dev/null
@@ -0,0 +1,120 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent an entry's transparency
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Transparency extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'transparency';
+    protected $_value = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_Transparency object.
+     * @param bool $value (optional) Transparency value as URI
+     */
+    public function __construct($value = null)
+    {
+        parent::__construct();
+    $this->_value = $value;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_value != null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Get the value for this element's Value attribute.
+     *
+     * @return bool The requested attribute.
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Set the value for this element's Value attribute.
+     *
+     * @param bool $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Transparency The element being modified.
+     */
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     */
+    public function __toString()
+    {
+        return $this->getValue();
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Extension/Visibility.php b/lib/zend/Zend/Gdata/Extension/Visibility.php
new file mode 100644 (file)
index 0000000..9a0c0a7
--- /dev/null
@@ -0,0 +1,120 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent an entry's visibility
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Visibility extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'visibility';
+    protected $_value = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_Visibility object.
+     * @param bool $value (optional) Visibility value as URI.
+     */
+    public function __construct($value = null)
+    {
+        parent::__construct();
+    $this->_value = $value;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_value != null) {
+            $element->setAttribute('value', $this->_value);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'value':
+            $this->_value = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Get the value for this element's Value attribute.
+     *
+     * @return bool The requested attribute.
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Set the value for this element's Value attribute.
+     *
+     * @param bool $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Visibility The element being modified.
+     */
+    public function setValue($value)
+    {
+        $this->_value = $value;
+        return $this;
+    }
+
+    /**
+     * Magic toString method allows using this directly via echo
+     * Works best in PHP >= 4.2.0
+     */
+    public function __toString()
+    {
+        return $this->getValue();
+    }
+
+}
+
diff --git a/lib/zend/Zend/Gdata/Extension/When.php b/lib/zend/Zend/Gdata/Extension/When.php
new file mode 100644 (file)
index 0000000..d61825a
--- /dev/null
@@ -0,0 +1,166 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Extension_Reminder
+ */
+require_once 'Zend/Gdata/Extension/Reminder.php';
+
+/**
+ * Represents the gd:when element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_When extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'when';
+    protected $_reminders = array();
+    protected $_startTime = null;
+    protected $_valueString = null;
+    protected $_endTime = null;
+
+    public function __construct($startTime = null, $endTime = null,
+            $valueString = null, $reminders = null)
+    {
+        parent::__construct();
+        $this->_startTime = $startTime;
+        $this->_endTime = $endTime;
+        $this->_valueString = $valueString;
+        $this->_reminders = $reminders;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_startTime != null) {
+            $element->setAttribute('startTime', $this->_startTime);
+        }
+        if ($this->_endTime != null) {
+            $element->setAttribute('endTime', $this->_endTime);
+        }
+        if ($this->_valueString != null) {
+            $element->setAttribute('valueString', $this->_valueString);
+        }
+        if ($this->_reminders != null) {
+            foreach ($this->_reminders as $reminder) {
+                $element->appendChild(
+                        $reminder->getDOM($element->ownerDocument));
+            }
+        }
+        return $element;
+    }
+
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('gd') . ':' . 'reminder';
+                $reminder = new Zend_Gdata_Extension_Reminder();
+                $reminder->transferFromDOM($child);
+                $this->_reminders[] = $reminder;
+                break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+            case 'startTime':
+                $this->_startTime = $attribute->nodeValue;
+                break;
+            case 'endTime':
+                $this->_endTime = $attribute->nodeValue;
+                break;
+            case 'valueString':
+                $this->_valueString = $attribute->nodeValue;
+                break;
+            default:
+                parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    public function __toString()
+    {
+        if ($valueString)
+            return $valueString;
+        else {
+            return 'Starts: ' . $this->getStartTime() . ' ' .
+                   'Ends: ' .  $this->getEndTime();
+        }
+    }
+
+    public function getStartTime()
+    {
+        return $this->_startTime;
+    }
+
+    public function setStartTime($value)
+    {
+        $this->_startTime = $value;
+        return $this;
+    }
+
+    public function getEndTime()
+    {
+        return $this->_endTime;
+    }
+
+    public function setEndTime($value)
+    {
+        $this->_endTime = $value;
+        return $this;
+    }
+
+    public function getValueString()
+    {
+        return $this->_valueString;
+    }
+
+    public function setValueString($value)
+    {
+        $this->_valueString = $value;
+        return $this;
+    }
+
+    public function getReminders()
+    {
+        return $this->_reminders;
+    }
+
+    public function setReminders($value)
+    {
+        $this->_reminders = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/Where.php b/lib/zend/Zend/Gdata/Extension/Where.php
new file mode 100644 (file)
index 0000000..a675c22
--- /dev/null
@@ -0,0 +1,163 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Data model class to represent a location (gd:where element)
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Where extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'where';
+    protected $_label = null;
+    protected $_rel = null;
+    protected $_valueString = null;
+    protected $_entryLink = null;
+
+    public function __construct($valueString = null, $label = null, $rel = null, $entryLink = null)
+    {
+        parent::__construct();
+        $this->_valueString = $valueString;
+        $this->_label = $label;
+        $this->_rel = $rel;
+        $this->_entryLink = $entryLink;
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_label != null) {
+            $element->setAttribute('label', $this->_label);
+        }
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_valueString != null) {
+            $element->setAttribute('valueString', $this->_valueString);
+        }
+        if ($this->entryLink != null) {
+            $element->appendChild($this->_entryLink->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'label':
+            $this->_label = $attribute->nodeValue;
+            break;
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        case 'valueString':
+            $this->_valueString = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them in the $_entry array based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('gd') . ':' . 'entryLink':
+            $entryLink = new Zend_Gdata_Extension_EntryLink();
+            $entryLink->transferFromDOM($child);
+            $this->_entryLink = $entryLink;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    public function __toString()
+    {
+        if ($this->_valueString != null) {
+            return $this->_valueString;
+        }
+        else {
+            return parent::__toString();
+        }
+    }
+
+    public function getLabel()
+    {
+        return $this->_label;
+    }
+
+    public function setLabel($value)
+    {
+        $this->_label = $value;
+        return $this;
+    }
+
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    public function getValueString()
+    {
+        return $this->_valueString;
+    }
+
+    public function setValueString($value)
+    {
+        $this->_valueString = $value;
+        return $this;
+    }
+
+    public function getEntryLink()
+    {
+        return $this->_entryLink;
+    }
+
+    public function setEntryLink($value)
+    {
+        $this->_entryLink = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Extension/Who.php b/lib/zend/Zend/Gdata/Extension/Who.php
new file mode 100644 (file)
index 0000000..5793097
--- /dev/null
@@ -0,0 +1,291 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Extension_AttendeeStatus
+ */
+require_once 'Zend/Gdata/Extension/AttendeeStatus.php';
+
+/**
+ * @see Zend_Gdata_Extension_AttendeeType
+ */
+require_once 'Zend/Gdata/Extension/AttendeeType.php';
+
+/**
+ * Data model class to represent a participant
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Extension_Who extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'who';
+    protected $_email = null;
+    protected $_rel = null;
+    protected $_valueString = null;
+    protected $_attendeeStatus = null;
+    protected $_attendeeType = null;
+    protected $_entryLink = null;
+
+    /**
+     * Constructs a new Zend_Gdata_Extension_Who object.
+     * @param string $email (optional) Email address.
+     * @param string $rel (optional) Relationship description.
+     * @param string $valueString (optional) Simple string describing this person.
+     * @param Zend_Gdata_Extension_AttendeeStatus $attendeeStatus (optional) The status of the attendee.
+     * @param Zend_Gdata_Extension_AttendeeType $attendeeType (optional) The type of the attendee.
+     * @param string $entryLink URL pointing to an associated entry (Contact kind) describing this person.
+     */
+    public function __construct($email = null, $rel = null, $valueString = null,
+        $attendeeStatus = null, $attendeeType = null, $entryLink = null)
+    {
+        parent::__construct();
+        $this->_email = $email;
+        $this->_rel = $rel;
+        $this->_valueString = $valueString;
+        $this->_attendeeStatus = $attendeeStatus;
+        $this->_attendeeType = $attendeeType;
+        $this->_entryLink = $entryLink;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_email != null) {
+            $element->setAttribute('email', $this->_email);
+        }
+        if ($this->_rel != null) {
+            $element->setAttribute('rel', $this->_rel);
+        }
+        if ($this->_valueString != null) {
+            $element->setAttribute('valueString', $this->_valueString);
+        }
+        if ($this->_attendeeStatus != null) {
+            $element->appendChild($this->_attendeeStatus->getDOM($element->ownerDocument));
+        }
+        if ($this->_attendeeType != null) {
+            $element->appendChild($this->_attendeeType->getDOM($element->ownerDocument));
+        }
+        if ($this->_entryLink != null) {
+            $element->appendChild($this->_entryLink->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'email':
+            $this->_email = $attribute->nodeValue;
+            break;
+        case 'rel':
+            $this->_rel = $attribute->nodeValue;
+            break;
+        case 'valueString':
+            $this->_valueString = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them as members of this entry based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('gd') . ':' . 'attendeeStatus':
+            $attendeeStatus = new Zend_Gdata_Extension_AttendeeStatus();
+            $attendeeStatus->transferFromDOM($child);
+            $this->_attendeeStatus = $attendeeStatus;
+            break;
+        case $this->lookupNamespace('gd') . ':' . 'attendeeType':
+            $attendeeType = new Zend_Gdata_Extension_AttendeeType();
+            $attendeeType->transferFromDOM($child);
+            $this->_attendeeType = $attendeeType;
+            break;
+        case $this->lookupNamespace('gd') . ':' . 'entryLink':
+            $entryLink = new Zend_Gdata_Extension_EntryLink();
+            $entryLink->transferFromDOM($child);
+            $this->_entryLink = $entryLink;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * Retrieves a human readable string describing this attribute's value.
+     *
+     * @return string The attribute value.
+     */
+    public function __toString()
+    {
+        if ($this->_valueString != null) {
+            return $this->_valueString;
+        }
+        else {
+            return parent::__toString();
+        }
+    }
+
+    /**
+     * Get the value for this element's ValueString attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getValueString()
+    {
+        return $this->_valueString;
+    }
+
+    /**
+     * Set the value for this element's ValueString attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Who The element being modified.
+     */
+    public function setValueString($value)
+    {
+        $this->_valueString = $value;
+        return $this;
+    }
+
+    /**
+     * Get the value for this element's Email attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getEmail()
+    {
+        return $this->_email;
+    }
+
+    /**
+     * Set the value for this element's Email attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Who The element being modified.
+     */
+    public function setEmail($value)
+    {
+        $this->_email = $value;
+        return $this;
+    }
+
+    /**
+     * Get the value for this element's Rel attribute.
+     *
+     * @return string The requested attribute.
+     */
+    public function getRel()
+    {
+        return $this->_rel;
+    }
+
+    /**
+     * Set the value for this element's Rel attribute.
+     *
+     * @param string $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Who The element being modified.
+     */
+    public function setRel($value)
+    {
+        $this->_rel = $value;
+        return $this;
+    }
+
+    /**
+     * Get this entry's AttendeeStatus element.
+     *
+     * @return Zend_Gdata_Extension_AttendeeStatus The requested entry.
+     */
+    public function getAttendeeStatus()
+    {
+        return $this->_attendeeStatus;
+    }
+
+    /**
+     * Set the child's AttendeeStatus element.
+     *
+     * @param Zend_Gdata_Extension_AttendeeStatus $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Who The element being modified.
+     */
+    public function setAttendeeStatus($value)
+    {
+        $this->_attendeeStatus = $value;
+        return $this;
+    }
+
+    /**
+     * Get this entry's AttendeeType element.
+     *
+     * @return Zend_Gdata_Extension_AttendeeType The requested entry.
+     */
+    public function getAttendeeType()
+    {
+        return $this->_attendeeType;
+    }
+
+    /**
+     * Set the child's AttendeeType element.
+     *
+     * @param Zend_Gdata_Extension_AttendeeType $value The desired value for this attribute.
+     * @return Zend_Gdata_Extension_Who The element being modified.
+     */
+    public function setAttendeeType($value)
+    {
+        $this->_attendeeType = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Feed.php b/lib/zend/Zend/Gdata/Feed.php
new file mode 100644 (file)
index 0000000..25764ec
--- /dev/null
@@ -0,0 +1,167 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Feed
+ */
+require_once 'Zend/Gdata/App/Feed.php';
+
+/**
+ * @see Zend_Gdata_Entry
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * @see Zend_Gdata_Extension_OpenSearchTotalResults
+ */
+require_once 'Zend/Gdata/Extension/OpenSearchTotalResults.php';
+
+/**
+ * @see Zend_Gdata_Extension_OpenSearchStartIndex
+ */
+require_once 'Zend/Gdata/Extension/OpenSearchStartIndex.php';
+
+/**
+ * @see Zend_Gdata_Extension_OpenSearchItemsPerPage
+ */
+require_once 'Zend/Gdata/Extension/OpenSearchItemsPerPage.php';
+
+/**
+ * The GData flavor of an Atom Feed
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Feed extends Zend_Gdata_App_Feed
+{
+
+    /**
+     * The classname for individual feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Entry';
+
+    /**
+     * The openSearch:totalResults element
+     *
+     * @var string
+     */
+    protected $_totalResults = null;
+
+    /**
+     * The openSearch:startIndex element
+     *
+     * @var string
+     */
+    protected $_startIndex = null;
+
+    /**
+     * The openSearch:itemsPerPage element
+     *
+     * @var string
+     */
+    protected $_itemsPerPage = null;
+
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_totalResults != null) {
+            $element->appendChild($this->_totalResults->getDOM($element->ownerDocument));
+        }
+        if ($this->_startIndex != null) {
+            $element->appendChild($this->_startIndex->getDOM($element->ownerDocument));
+        }
+        if ($this->_itemsPerPage != null) {
+            $element->appendChild($this->_itemsPerPage->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them in the $_entry array based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('openSearch') . ':' . 'totalResults':
+            $totalResults = new Zend_Gdata_Extension_OpenSearchTotalResults();
+            $totalResults->transferFromDOM($child);
+            $this->_totalResults = $totalResults;
+            break;
+        case $this->lookupNamespace('openSearch') . ':' . 'startIndex':
+            $startIndex = new Zend_Gdata_Extension_OpenSearchStartIndex();
+            $startIndex->transferFromDOM($child);
+            $this->_startIndex = $startIndex;
+            break;
+        case $this->lookupNamespace('openSearch') . ':' . 'itemsPerPage':
+            $itemsPerPage = new Zend_Gdata_Extension_OpenSearchItemsPerPage();
+            $itemsPerPage->transferFromDOM($child);
+            $this->_itemsPerPage = $itemsPerPage;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    function setTotalResults($value) {
+        $this->_totalResults = $value;
+        return $this;
+    }
+
+    function getTotalResults() {
+        return $this->_totalResults;
+    }
+
+    function setStartIndex($value) {
+        $this->_startIndex = $value;
+        return $this;
+    }
+
+    function getStartIndex() {
+        return $this->_startIndex;
+    }
+
+    function setItemsPerPage($value) {
+        $this->_itemsPerPage = $value;
+        return $this;
+    }
+
+    function getItemsPerPage() {
+        return $this->_itemsPerPage;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase.php b/lib/zend/Zend/Gdata/Gbase.php
new file mode 100644 (file)
index 0000000..bdfc8d3
--- /dev/null
@@ -0,0 +1,200 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata
+ */
+require_once 'Zend/Gdata.php';
+
+/**
+ * @see Zend_Gdata_Gbase_ItemFeed
+ */
+require_once 'Zend/Gdata/Gbase/ItemFeed.php';
+
+/**
+ * @see Zend_Gdata_Gbase_ItemEntry
+ */
+require_once 'Zend/Gdata/Gbase/ItemEntry.php';
+
+/**
+ * @see Zend_Gdata_Gbase_SnippetEntry
+ */
+require_once 'Zend/Gdata/Gbase/SnippetEntry.php';
+
+/**
+ * @see Zend_Gdata_Gbase_SnippetFeed
+ */
+require_once 'Zend/Gdata/Gbase/SnippetFeed.php';
+
+/**
+ * Service class for interacting with the Google Base data API
+ *
+ * @link http://code.google.com/apis/base
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase extends Zend_Gdata
+{
+
+    /**
+     * Path to the customer items feeds on the Google Base server.
+     */
+    const GBASE_ITEM_FEED_URI = 'http://www.google.com/base/feeds/items';
+
+    /**
+     * Path to the snippets feeds on the Google Base server.
+     */
+    const GBASE_SNIPPET_FEED_URI = 'http://www.google.com/base/feeds/snippets';
+
+    /**
+     * Authentication service name for Google Base
+     */
+    const AUTH_SERVICE_NAME = 'gbase';
+
+    /**
+     * The default URI for POST methods
+     *
+     * @var string
+     */    
+    protected $_defaultPostUri = self::GBASE_ITEM_FEED_URI;
+
+    public static $namespaces = array(
+            'g' => 'http://base.google.com/ns/1.0',
+            'batch' => 'http://schemas.google.com/gdata/batch');
+
+    /**
+     * Create Zend_Gdata_Gbase object
+     *
+     * @param Zend_Http_Client $client (optional) The HTTP client to use when
+     *          when communicating with the Google Apps servers.
+     * @param string $applicationId The identity of the app in the form of Company-AppName-Version
+     */
+    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        $this->registerPackage('Zend_Gdata_Gbase');
+        $this->registerPackage('Zend_Gdata_Gbase_Extension');
+        parent::__construct($client, $applicationId);
+        $this->_httpClient->setParameterPost('service', self::AUTH_SERVICE_NAME);
+    }
+
+    /**
+     * Retreive feed object
+     *
+     * @param mixed $location The location for the feed, as a URL or Query
+     * @return Zend_Gdata_Gbase_ItemFeed
+     */
+    public function getGbaseItemFeed($location = null)
+    {
+        if ($location === null) {
+            $uri = self::GBASE_ITEM_FEED_URI;
+        } else if ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            $uri = $location;
+        }
+        return parent::getFeed($uri, 'Zend_Gdata_Gbase_ItemFeed');
+    }
+
+    /**
+     * Retreive entry object
+     *
+     * @param mixed $location The location for the feed, as a URL or Query
+     * @return Zend_Gdata_Gbase_ItemEntry
+     */
+    public function getGbaseItemEntry($location = null)
+    {
+        if ($location === null) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'Location must not be null');
+        } else if ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            $uri = $location;
+        }
+        return parent::getEntry($uri, 'Zend_Gdata_Gbase_ItemEntry');
+    }
+
+    /**
+     * Insert an entry
+     *
+     * @param Zend_Gdata_Gbase_ItemEntry $entry The Base entry to upload
+     * @param boolean $dryRun Flag for the 'dry-run' parameter
+     * @return Zend_Gdata_Gbase_ItemFeed
+     */
+    public function insertGbaseItem($entry, $dryRun = false)
+    {
+        if ($dryRun == false) {
+            $uri = $this->_defaultPostUri;
+        } else {
+            $uri = $this->_defaultPostUri . '?dry-run=true';
+        }
+        $newitem = $this->insertEntry($entry, $uri, 'Zend_Gdata_Gbase_ItemEntry');
+        return $newitem;
+    }
+
+    /**
+     * Update an entry
+     *
+     * @param Zend_Gdata_Gbase_ItemEntry $entry The Base entry to be updated
+     * @param boolean $dryRun Flag for the 'dry-run' parameter
+     * @return Zend_Gdata_Gbase_ItemEntry
+     */
+    public function updateGbaseItem($entry, $dryRun = false)
+    {
+        $returnedEntry = $entry->save($dryRun);
+        return $returnedEntry;
+    }
+
+    /**
+     * Delete an entry
+     *
+     * @param Zend_Gdata_Gbase_ItemEntry $entry The Base entry to remove
+     * @param boolean $dryRun Flag for the 'dry-run' parameter
+     * @return Zend_Gdata_Gbase_ItemFeed
+     */
+    public function deleteGbaseItem($entry, $dryRun = false)
+    {
+        $entry->delete($dryRun);
+        return $this;
+    }
+
+    /**
+     * Retrieve feed object
+     *
+     * @param mixed $location The location for the feed, as a URL or Query
+     * @return Zend_Gdata_Gbase_SnippetFeed
+     */
+    public function getGbaseSnippetFeed($location = null)
+    {
+        if ($location === null) {
+            $uri = self::GBASE_SNIPPET_FEED_URI;
+        } else if ($location instanceof Zend_Gdata_Query) {
+            $uri = $location->getQueryUrl();
+        } else {
+            $uri = $location;
+        }
+        return parent::getFeed($uri, 'Zend_Gdata_Gbase_SnippetFeed');
+    }
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/Entry.php b/lib/zend/Zend/Gdata/Gbase/Entry.php
new file mode 100644 (file)
index 0000000..41492a0
--- /dev/null
@@ -0,0 +1,150 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Entry
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * @see Zend_Gdata_Gbase_Extension_BaseAttribute
+ */
+require_once 'Zend/Gdata/Gbase/Extension/BaseAttribute.php';
+
+/**
+ * Base class for working with Google Base entries.
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_Entry extends Zend_Gdata_Entry
+{
+
+    /**
+     * Name of the base class for Google Base entries
+     *
+     * var @string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Gbase_Entry';
+
+    /**
+     * Google Base attribute elements in the 'g' namespace
+     *
+     * @var array
+     */
+    protected $_baseAttributes = array();
+
+    /**
+     * Constructs a new Zend_Gdata_Gbase_ItemEntry object.
+     * @param DOMElement $element (optional) The DOMElement on which to base this object.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Gbase::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     *          child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        foreach ($this->_baseAttributes as $baseAttribute) {
+            $element->appendChild($baseAttribute->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them as members of this entry based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+
+        if (strstr($absoluteNodeName, $this->lookupNamespace('g') . ':')) {
+            $baseAttribute = new Zend_Gdata_Gbase_Extension_BaseAttribute();
+            $baseAttribute->transferFromDOM($child);
+            $this->_baseAttributes[] = $baseAttribute;
+        } else {
+            parent::takeChildFromDOM($child);
+        }
+    }
+
+    /**
+     * Get the value of the itme_type
+     *
+     * @return Zend_Gdata_Gbase_Extension_ItemType The requested object.
+     */
+    public function getItemType()
+    {
+        $itemType = $this->getGbaseAttribute('item_type');
+        if (is_object($itemType[0])) {
+          return $itemType[0];
+        } else {
+          return null;
+        }
+    }
+
+    /** 
+     * Return all the Base attributes
+     * @return Zend_Gdata_Gbase_Extension_BaseAttribute
+     */
+    public function getGbaseAttributes() {
+        return $this->_baseAttributes;
+    }
+
+    /** 
+     * Return an array of Base attributes that match the given attribute name
+     *
+     * @param string $name The name of the Base attribute to look for
+     * @return array $matches Array that contains the matching list of Base attributes
+     */
+    public function getGbaseAttribute($name) 
+    {
+        $matches = array();
+        for ($i = 0; $i < count($this->_baseAttributes); $i++) {
+            $baseAttribute = $this->_baseAttributes[$i];
+            if ($baseAttribute->rootElement == $name && 
+                $baseAttribute->rootNamespaceURI == $this->lookupNamespace('g')) {
+                $matches[] = &$this->_baseAttributes[$i];
+            }
+        }
+        return $matches;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/Extension/BaseAttribute.php b/lib/zend/Zend/Gdata/Gbase/Extension/BaseAttribute.php
new file mode 100644 (file)
index 0000000..51ef299
--- /dev/null
@@ -0,0 +1,115 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension_Element
+ */
+require_once 'Zend/Gdata/App/Extension/Element.php';
+
+/**
+ * Concrete class for working with ItemType elements.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_Extension_BaseAttribute extends Zend_Gdata_App_Extension_Element
+{
+
+    /**
+     * Namespace for Google Base elements
+     *
+     * var @string
+     */
+    protected $_rootNamespace = 'g';
+    
+    /**
+     * Create a new instance.
+     * 
+     * @param string $name (optional) The name of the Base attribute
+     * @param string $text (optional) The text value of the Base attribute
+     * @param string $text (optional) The type of the Base attribute
+     */
+    public function __construct($name = null, $text = null, $type = null)
+    {
+        foreach (Zend_Gdata_Gbase::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        } 
+        if ($type !== null) {
+          $attr = array('name' => 'type', 'value' => $type);
+          $typeAttr = array('type' => $attr);
+          $this->setExtensionAttributes($typeAttr);
+        }
+        parent::__construct($name, 
+                            $this->_rootNamespace, 
+                            $this->lookupNamespace($this->_rootNamespace), 
+                            $text);
+    }
+
+    /**
+     * Get the name of the attribute
+     *
+     * @return attribute name The requested object.
+     */
+    public function getName() {
+      return $this->_rootElement;
+    }
+
+    /**
+     * Get the type of the attribute
+     *
+     * @return attribute type The requested object.
+     */
+    public function getType() {
+      $typeAttr = $this->getExtensionAttributes();
+      return $typeAttr['type']['value'];
+    }
+
+    /**
+     * Set the 'name' of the Base attribute object:
+     *     &lt;g:[$name] type='[$type]'&gt;[$value]&lt;/g:[$name]&gt;      
+     *
+     * @param Zend_Gdata_App_Extension_Element $attribute The attribute object
+     * @param string $name The name of the Base attribute
+     * @return Zend_Gdata_Extension_ItemEntry Provides a fluent interface
+     */
+    public function setName($name) {
+      $this->_rootElement = $name;
+      return $this;
+    }
+
+    /**
+     * Set the 'type' of the Base attribute object:
+     *     &lt;g:[$name] type='[$type]'&gt;[$value]&lt;/g:[$name]&gt;      
+     *
+     * @param Zend_Gdata_App_Extension_Element $attribute The attribute object
+     * @param string $type The type of the Base attribute
+     * @return Zend_Gdata_Extension_ItemEntry Provides a fluent interface
+     */
+    public function setType($type) {
+      $attr = array('name' => 'type', 'value' => $type);
+      $typeAttr = array('type' => $attr);
+      $this->setExtensionAttributes($typeAttr);
+      return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/Feed.php b/lib/zend/Zend/Gdata/Gbase/Feed.php
new file mode 100644 (file)
index 0000000..bcb753a
--- /dev/null
@@ -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 license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Feed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+/**
+ * Base class for the Google Base Feed
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_Feed extends Zend_Gdata_Feed
+{
+    /**
+     * The classname for the feed.
+     *
+     * @var string
+     */
+    protected $_feedClassName = 'Zend_Gdata_Gbase_Feed';
+
+    /**
+     * Create a new instance.
+     * 
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Gbase::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/ItemEntry.php b/lib/zend/Zend/Gdata/Gbase/ItemEntry.php
new file mode 100644 (file)
index 0000000..7961de4
--- /dev/null
@@ -0,0 +1,147 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Gbase_Entry
+ */
+require_once 'Zend/Gdata/Gbase/Entry.php';
+
+/**
+ * Concrete class for working with Item entries.
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_ItemEntry extends Zend_Gdata_Gbase_Entry
+{
+    /**
+     * The classname for individual item entry elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Gbase_ItemEntry';
+
+    /**
+     * Set the value of the itme_type
+     *
+     * @param Zend_Gdata_Gbase_Extension_ItemType $value The desired value for the item_type 
+     * @return Zend_Gdata_Gbase_ItemEntry Provides a fluent interface
+     */
+    public function setItemType($value)
+    {
+        $this->addGbaseAttribute('item_type', $value, 'text');
+        return $this;
+    }
+
+    /**
+     * Adds a custom attribute to the entry in the following format:
+     * &lt;g:[$name] type='[$type]'&gt;[$value]&lt;/g:[$name]&gt;      
+     *
+     * @param string $name The name of the attribute
+     * @param string $value The text value of the attribute
+     * @param string $type (optional) The type of the attribute.
+     *          e.g.: 'text', 'number', 'floatUnit'
+     * @return Zend_Gdata_Gbase_ItemEntry Provides a fluent interface
+     */
+    public function addGbaseAttribute($name, $text, $type = null) {
+        $newBaseAttribute =  new Zend_Gdata_Gbase_Extension_BaseAttribute($name, $text, $type);
+        $this->_baseAttributes[] = $newBaseAttribute;
+        return $this;
+    }
+
+    /**
+     * Removes a Base attribute from the current list of Base attributes
+     * 
+     * @param Zend_Gdata_Gbase_Extension_BaseAttribute $baseAttribute The attribute to be removed
+     * @return Zend_Gdata_Gbase_ItemEntry Provides a fluent interface
+     */
+    public function removeGbaseAttribute($baseAttribute) {
+        $baseAttributes = $this->_baseAttributes;
+        for ($i = 0; $i < count($this->_baseAttributes); $i++) {
+            if ($this->_baseAttributes[$i] == $baseAttribute) {
+                array_splice($baseAttributes, $i, 1);
+                break;
+            }
+        }
+        $this->_baseAttributes = $baseAttributes;
+        return $this;
+    }
+
+    /**
+     * Uploads changes in this entry to the server using Zend_Gdata_App
+     *
+     * @param boolean $dryRun Whether the transaction is dry run or not
+     * @return Zend_Gdata_App_Entry The updated entry
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function save($dryRun = false)
+    {
+        $uri = null;
+
+        if ($dryRun == true) {
+            $editLink = $this->getEditLink();
+            if ($editLink !== null) {
+                $uri = $editLink->getHref() . '?dry-run=true';
+            }
+            if ($uri === null) {
+                require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+                throw new Zend_Gdata_App_InvalidArgumentException('You must specify an URI which needs deleted.');
+            }
+            $service = new Zend_Gdata_App($this->getHttpClient());
+            return $service->updateEntry($this, $uri);
+        } else {
+            parent::save();
+        }
+    }
+
+    /**
+     * Deletes this entry to the server using the referenced
+     * Zend_Http_Client to do a HTTP DELETE to the edit link stored in this
+     * entry's link collection.
+     *
+     * @param boolean $dyrRun Whether the transaction is dry run or not
+     * @return void
+     * @throws Zend_Gdata_App_Exception
+     */
+    public function delete($dryRun = false)
+    {
+        $uri = null;
+
+        if ($dryRun == true) {
+            $editLink = $this->getEditLink();
+            if ($editLink !== null) {
+                $uri = $editLink->getHref() . '?dry-run=true';
+            }
+            if ($uri === null) {
+                require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+                throw new Zend_Gdata_App_InvalidArgumentException('You must specify an URI which needs deleted.');
+            }
+            parent::delete($uri);
+        } else {
+            parent::delete();
+        }
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/ItemFeed.php b/lib/zend/Zend/Gdata/Gbase/ItemFeed.php
new file mode 100644 (file)
index 0000000..eea296d
--- /dev/null
@@ -0,0 +1,45 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Gbase_Feed
+ */
+require_once 'Zend/Gdata/Gbase/Feed.php';
+
+/**
+ * Represents the Google Base Customer Items Feed
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_ItemFeed extends Zend_Gdata_Feed
+{
+    /**
+     * The classname for individual item feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Gbase_ItemEntry';
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/ItemQuery.php b/lib/zend/Zend/Gdata/Gbase/ItemQuery.php
new file mode 100644 (file)
index 0000000..ba3dee3
--- /dev/null
@@ -0,0 +1,98 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Query
+ */
+require_once('Zend/Gdata/Query.php');
+
+/**
+ * @see Zend_Gdata_Gbase_Query
+ */
+require_once('Zend/Gdata/Gbase/Query.php');
+
+
+/**
+ * Assists in constructing queries for Google Base Customer Items Feed
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_ItemQuery extends Zend_Gdata_Gbase_Query
+{
+    /**
+     * Path to the customer items feeds on the Google Base server.
+     */
+    const GBASE_ITEM_FEED_URI = 'http://www.google.com/base/feeds/items';
+
+    /**
+     * The default URI for POST methods
+     *
+     * @var string
+     */    
+    protected $_defaultFeedUri = self::GBASE_ITEM_FEED_URI;
+
+    /**
+     * The id of an item
+     *
+     * @var string
+     */    
+    protected $_id = null;
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setId($value)
+    {
+        $this->_id = $value;
+        return $this;
+    }
+
+    /*
+     * @return string id
+     */
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    /**
+     * Returns the query URL generated by this query instance.
+     * 
+     * @return string The query URL for this instance.
+     */
+    public function getQueryUrl()
+    {
+        $uri = $this->_defaultFeedUri;
+        if ($this->getId() !== null) {
+            $uri .= '/' . $this->getId();
+        } else {
+            $uri .= $this->getQueryString();
+        }
+        return $uri;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/Query.php b/lib/zend/Zend/Gdata/Gbase/Query.php
new file mode 100644 (file)
index 0000000..1b22eb3
--- /dev/null
@@ -0,0 +1,265 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Query
+ */
+require_once('Zend/Gdata/Query.php');
+
+/**
+ * Assists in constructing queries for Google Base
+ *
+ * @link http://code.google.com/apis/base
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_Query extends Zend_Gdata_Query
+{
+
+    /**
+     * Path to the customer items feeds on the Google Base server.
+     */
+    const GBASE_ITEM_FEED_URI = 'http://www.google.com/base/feeds/items';
+
+    /**
+     * Path to the snippets feeds on the Google Base server.
+     */
+    const GBASE_SNIPPET_FEED_URI = 'http://www.google.com/base/feeds/snippets';
+
+    /**
+     * The default URI for POST methods
+     *
+     * @var string
+     */    
+    protected $_defaultFeedUri = self::GBASE_ITEM_FEED_URI;
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_Query Provides a fluent interface
+     */
+    public function setKey($value)
+    {
+        if ($value !== null) {
+            $this->_params['key'] = $value;
+        } else {
+            unset($this->_params['key']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setBq($value)
+    {
+        if ($value !== null) {
+            $this->_params['bq'] = $value;
+        } else {
+            unset($this->_params['bq']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setRefine($value)
+    {
+        if ($value !== null) {
+            $this->_params['refine'] = $value;
+        } else {
+            unset($this->_params['refine']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setContent($value)
+    {
+        if ($value !== null) {
+            $this->_params['content'] = $value;
+        } else {
+            unset($this->_params['content']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setOrderBy($value)
+    {
+        if ($value !== null) {
+            $this->_params['orderby'] = $value;
+        } else {
+            unset($this->_params['orderby']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setSortOrder($value)
+    {
+        if ($value !== null) {
+            $this->_params['sortorder'] = $value;
+        } else {
+            unset($this->_params['sortorder']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setCrowdBy($value)
+    {
+        if ($value !== null) {
+            $this->_params['crowdby'] = $value;
+        } else {
+            unset($this->_params['crowdby']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Gbase_ItemQuery Provides a fluent interface
+     */
+    public function setAdjust($value)
+    {
+        if ($value !== null) {
+            $this->_params['adjust'] = $value;
+        } else {
+            unset($this->_params['adjust']);
+        }
+        return $this;
+    }
+
+    /**
+     * @return string key
+     */
+    public function getKey()
+    {
+        if (array_key_exists('key', $this->_params)) {
+            return $this->_params['key'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string bq
+     */
+    public function getBq()
+    {
+        if (array_key_exists('bq', $this->_params)) {
+            return $this->_params['bq'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string refine
+     */
+    public function getRefine()
+    {
+        if (array_key_exists('refine', $this->_params)) {
+            return $this->_params['refine'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string content
+     */
+    public function getContent()
+    {
+        if (array_key_exists('content', $this->_params)) {
+            return $this->_params['content'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string orderby
+     */
+    public function getOrderBy()
+    {
+        if (array_key_exists('orderby', $this->_params)) {
+            return $this->_params['orderby'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string sortorder
+     */
+    public function getSortOrder()
+    {
+        if (array_key_exists('sortorder', $this->_params)) {
+            return $this->_params['sortorder'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string crowdby
+     */
+    public function getCrowdBy()
+    {
+        if (array_key_exists('crowdby', $this->_params)) {
+            return $this->_params['crowdby'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string adjust
+     */
+    public function getAdjust()
+    {
+        if (array_key_exists('adjust', $this->_params)) {
+            return $this->_params['adjust'];
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/SnippetEntry.php b/lib/zend/Zend/Gdata/Gbase/SnippetEntry.php
new file mode 100644 (file)
index 0000000..22b81b9
--- /dev/null
@@ -0,0 +1,45 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Gbase_Entry
+ */
+require_once 'Zend/Gdata/Gbase/Entry.php';
+
+/**
+ * Concrete class for working with Snippet entries.
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_SnippetEntry extends Zend_Gdata_Gbase_Entry
+{
+    /**
+     * The classname for individual snippet entry elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Gbase_SnippetEntry';
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/SnippetFeed.php b/lib/zend/Zend/Gdata/Gbase/SnippetFeed.php
new file mode 100644 (file)
index 0000000..34f0272
--- /dev/null
@@ -0,0 +1,45 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Gbase_Feed
+ */
+require_once 'Zend/Gdata/Gbase/Feed.php';
+
+/**
+ * Represents the Google Base Snippets Feed
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_SnippetFeed extends Zend_Gdata_Feed
+{
+    /**
+     * The classname for individual snippet feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Gbase_SnippetEntry';
+}
diff --git a/lib/zend/Zend/Gdata/Gbase/SnippetQuery.php b/lib/zend/Zend/Gdata/Gbase/SnippetQuery.php
new file mode 100644 (file)
index 0000000..251f3cd
--- /dev/null
@@ -0,0 +1,71 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_Query
+ */
+require_once('Zend/Gdata/Query.php');
+
+/**
+ * Zend_Gdata_Gbase_Query
+ */
+require_once('Zend/Gdata/Gbase/Query.php');
+
+/**
+ * Assists in constructing queries for Google Base Snippets Feed
+ *
+ * @link http://code.google.com/apis/base/
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Gbase_SnippetQuery extends Zend_Gdata_Gbase_Query
+{
+    /**
+     * Path to the snippets feeds on the Google Base server.
+     */
+    const BASE_SNIPPET_FEED_URI = 'http://www.google.com/base/feeds/snippets';
+
+    /**
+     * The default URI for POST methods
+     *
+     * @var string
+     */    
+    protected $_defaultFeedUri = self::BASE_SNIPPET_FEED_URI;
+
+    /**
+     * Returns the query URL generated by this query instance.
+     * 
+     * @return string The query URL for this instance.
+     */
+    public function getQueryUrl()
+    {
+        $uri = $this->_defaultFeedUri;
+        if ($this->getCategory() !== null) {
+            $uri .= '/-/' . $this->getCategory();
+        }
+        $uri .= $this->getQueryString();
+        return $uri;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/HttpClient.php b/lib/zend/Zend/Gdata/HttpClient.php
new file mode 100644 (file)
index 0000000..bf5a76e
--- /dev/null
@@ -0,0 +1,245 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+/**
+ * Zend_Http_Client
+ */
+require_once 'Zend/Http/Client.php';
+
+/**
+ * Gdata Http Client object.
+ *
+ * Class to extend the generic Zend Http Client with the ability to perform
+ * secure AuthSub requests
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_HttpClient extends Zend_Http_Client
+{
+
+    /**
+     * OpenSSL private key resource id
+     * This key is used for AuthSub authentication.  If this value is set,
+     * it is assuemd that secure AuthSub is desired.
+     *
+     * @var resource 
+     */
+    private $_authSubPrivateKeyId = null;
+
+    /**
+     * Token for AuthSub authentication.  
+     * If this token is set, AuthSub authentication is used.
+     *
+     * @var string
+     */
+    private $_authSubToken = null;
+
+    /**
+     * Token for ClientLogin authentication.  
+     * If only this token is set, ClientLogin authentication is used.
+     *
+     * @var string
+     */
+    private $_clientLoginToken = null;
+
+    /**
+     * Token for ClientLogin authentication.
+     * If this token is set, and the AuthSub key is not set,
+     * ClientLogin authentication is used
+     *
+     * @var string
+     */
+    private $_clientLoginKey = null;
+
+    /**
+     * Sets the PEM formatted private key, as read from a file.
+     *
+     * This method reads the file and then calls setAuthSubPrivateKey()
+     * with the file contents.
+     *
+     * @param string $file The location of the file containing the PEM key
+     * @param string $passphrase The optional private key passphrase
+     * @param bool $useIncludePath Whether to search the include_path 
+     *                             for the file
+     * @return void
+     */
+    public function setAuthSubPrivateKeyFile($file, $passphrase = null, 
+                                             $useIncludePath = false) {
+        $fp = fopen($file, "r", $useIncludePath);
+        $key = '';
+        while (!feof($fp)) {
+            $key .= fread($fp, 8192);
+        }
+        $this->setAuthSubPrivateKey($key, $passphrase);
+        fclose($fp);
+    }
+
+    /**
+     * Sets the PEM formatted private key to be used for secure AuthSub auth.
+     *
+     * In order to call this method, openssl must be enabled in your PHP
+     * installation.  Otherwise, a Zend_Gdata_App_InvalidArgumentException
+     * will be thrown.
+     *
+     * @param string $key The private key
+     * @param string $passphrase The optional private key passphrase
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     * @return Zend_Gdata_HttpClient Provides a fluent interface
+     */
+    public function setAuthSubPrivateKey($key, $passphrase = null) {
+        if ($key != null && !function_exists('openssl_pkey_get_private')) {
+            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
+            throw new Zend_Gdata_App_InvalidArgumentException(
+                    'You cannot enable secure AuthSub if the openssl module ' .
+                    'is not enabled in your PHP installation.');
+        }
+        $this->_authSubPrivateKeyId = openssl_pkey_get_private(
+                $key, $passphrase);
+        return $this;
+    }
+
+    /**
+     * Gets the openssl private key id
+     *
+     * @return string The private key
+     */
+    public function getAuthSubPrivateKeyId() {
+        return $this->_authSubPrivateKeyId;
+    }
+    
+    /**
+     * Gets the AuthSub token used for authentication
+     *
+     * @return string The token
+     */
+    public function getAuthSubToken() {
+        return $this->_authSubToken;
+    }
+
+    /**
+     * Sets the AuthSub token used for authentication
+     *
+     * @param string $token The token 
+     * @return Zend_Gdata_HttpClient Provides a fluent interface
+     */
+    public function setAuthSubToken($token) {
+        $this->_authSubToken = $token;
+        return $this;
+    }
+
+    /**
+     * Gets the ClientLogin token used for authentication
+     *
+     * @return string The token 
+     */
+    public function getClientLoginToken() {
+        return $this->_clientLoginToken;
+    }
+
+    /**
+     * Sets the ClientLogin token used for authentication
+     *
+     * @param string $token The token 
+     * @return Zend_Gdata_HttpClient Provides a fluent interface
+     */
+    public function setClientLoginToken($token) {
+        $this->_clientLoginToken = $token;
+        return $this;
+    }
+
+    /**
+     * Filters the HTTP requests being sent to add the Authorization header.
+     *
+     * If both AuthSub and ClientLogin tokens are set,
+     * AuthSub takes precedence.  If an AuthSub key is set, then
+     * secure AuthSub authentication is used, and the request is signed.
+     * Requests must be signed only with the private key corresponding to the
+     * public key registered with Google.  If an AuthSub key is set, but
+     * openssl support is not enabled in the PHP installation, an exception is
+     * thrown.
+     *
+     * @param string $method The HTTP method
+     * @param string $url The URL
+     * @param array $headers An associate array of headers to be 
+     *                       sent with the request or null
+     * @param string $body The body of the request or null
+     * @param string $contentType The MIME content type of the body or null
+     * @throws Zend_Gdata_App_Exception if there was a signing failure
+     * @return array The processed values in an associative array, 
+     *               using the same names as the params
+     */
+    public function filterHttpRequest($method, $url, $headers = array(), $body = null, $contentType = null) {
+        if ($this->getAuthSubToken() != null) {
+            // AuthSub authentication
+            if ($this->getAuthSubPrivateKeyId() != null) {
+                // secure AuthSub
+                $time = time();
+                $nonce = mt_rand(0, 999999999);
+                $dataToSign = $method . ' ' . $url . ' ' . $time . ' ' . $nonce;
+
+                // compute signature
+                $pKeyId = $this->getAuthSubPrivateKeyId();
+                $signSuccess = openssl_sign($dataToSign, $signature, $pKeyId, 
+                                            OPENSSL_ALGO_SHA1);
+                if (!$signSuccess) {
+                    require_once 'Zend/Gdata/App/Exception.php';
+                    throw new Zend_Gdata_App_Exception(
+                            'openssl_signing failure - returned false');
+                }
+                // encode signature
+                $encodedSignature = base64_encode($signature);
+
+                // final header
+                $headers['authorization'] = 'AuthSub token="' . $this->getAuthSubToken() . '" ' .
+                                            'data="' . $dataToSign . '" ' .
+                                            'sig="' . $encodedSignature . '" ' .
+                                            'sigalg="rsa-sha1"';
+            } else {
+                // AuthSub without secure tokens
+                $headers['authorization'] = 'AuthSub token="' . $this->getAuthSubToken() . '"';
+            }
+        } elseif ($this->getClientLoginToken() != null) {
+            $headers['authorization'] = 'GoogleLogin auth=' . $this->getClientLoginToken();
+        }
+        return array('method' => $method, 'url' => $url, 'body' => $body, 'headers' => $headers, 'contentType' => $contentType);
+    }
+
+    /**
+     * Method for filtering the HTTP response, though no filtering is
+     * currently done.
+     *
+     * @param Zend_Http_Response $response The response object to filter
+     * @return Zend_Http_Response The filterd response object
+     */
+    public function filterHttpResponse($response) {
+        return $response;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media.php b/lib/zend/Zend/Gdata/Media.php
new file mode 100755 (executable)
index 0000000..f271f9b
--- /dev/null
@@ -0,0 +1,56 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata
+ */
+require_once 'Zend/Gdata.php';
+
+/**
+ * Service class for interacting with the services which use the media extensions
+ * @link http://code.google.com/apis/gdata/calendar.html
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media extends Zend_Gdata
+{
+
+    public static $namespaces = array(
+            'media' => 'http://search.yahoo.com/mrss/');
+
+    /**
+     * Create Gdata_Media object
+     *
+     * @param Zend_Http_Client $client (optional) The HTTP client to use when
+     *          when communicating with the Google Apps servers.
+     * @param string $applicationId The identity of the app in the form of Company-AppName-Version
+     */
+    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
+    {
+        $this->registerPackage('Zend_Gdata_Media');
+        $this->registerPackage('Zend_Gdata_Media_Extension');
+        parent::__construct($client, $applicationId);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Entry.php b/lib/zend/Zend/Gdata/Media/Entry.php
new file mode 100755 (executable)
index 0000000..cb462ae
--- /dev/null
@@ -0,0 +1,133 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Entry
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * @see Zend_Gdata_Media
+ */
+require_once 'Zend/Gdata/Media.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaGroup
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaGroup.php';
+
+/**
+ * Represents the GData flavor of an Atom entry
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Entry extends Zend_Gdata_Entry
+{
+
+    protected $_entryClassName = 'Zend_Gdata_Media_Entry';
+
+    /**
+     * media:group element
+     *
+     * @var Zend_Gdata_Media_Extension_MediaGroup
+     */
+    protected $_mediaGroup = null;
+
+    /**
+     * Create a new instance.
+     * 
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri); 
+        }
+        parent::__construct($element);
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     *          child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_mediaGroup != null) {
+            $element->appendChild($this->_mediaGroup->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them as members of this entry based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;    
+        switch ($absoluteNodeName) {
+        case $this->lookupNamespace('media') . ':' . 'group':
+            $mediaGroup = new Zend_Gdata_Media_Extension_MediaGroup();
+            $mediaGroup->transferFromDOM($child);
+            $this->_mediaGroup = $mediaGroup;
+            break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * Returns the entry's mediaGroup object.
+     *
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+    */
+    public function getMediaGroup()
+    {
+        return $this->_mediaGroup;
+    }
+
+    /**
+     * Sets the entry's mediaGroup object.
+     *
+     * @param Zend_Gdata_Media_Extension_MediaGroup $mediaGroup
+     * @return Zend_Gdata_Media_Entry Provides a fluent interface
+     */
+    public function setMediaGroup($mediaGroup)
+    {
+        $this->_mediaGroup = $mediaGroup;
+        return $this;
+    }
+
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaCategory.php b/lib/zend/Zend/Gdata/Media/Extension/MediaCategory.php
new file mode 100755 (executable)
index 0000000..352d31f
--- /dev/null
@@ -0,0 +1,147 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:category element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaCategory extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'category'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_scheme = null;
+    protected $_label = null;
+
+    /**
+     * Creates an individual MediaCategory object.
+     * 
+     * @param string $text      Indication of the type and content of the media
+     * @param string $scheme    URI that identifies the categorization scheme
+     * @param string $label     Human-readable label to be displayed in applications
+     */ 
+    public function __construct($text = null, $scheme = null, $label = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_scheme = $scheme;
+        $this->_label = $label;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_scheme != null) {
+            $element->setAttribute('scheme', $this->_scheme);
+        }
+        if ($this->_label != null) {
+            $element->setAttribute('label', $this->_label);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'scheme':
+            $this->_scheme = $attribute->nodeValue;
+            break;
+        case 'label':
+            $this->_label = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Returns the URI that identifies the categorization scheme
+     * Optional.
+     *
+     * @return string URI that identifies the categorization scheme
+     */
+    public function getScheme()
+    {
+        return $this->_scheme;
+    }
+
+    /**
+     * @param string $value     URI that identifies the categorization scheme
+     * @return Zend_Gdata_Media_Extension_MediaCategory Provides a fluent interface
+     */
+    public function setScheme($value)
+    {
+        $this->_scheme = $value;
+        return $this;
+    }
+
+    /**
+     * @return string Human-readable label to be displayed in applications
+     */
+    public function getLabel()
+    {
+        return $this->_label;
+    }
+
+    /**
+     * @param string $value     Human-readable label to be displayed in applications
+     * @return Zend_Gdata_Media_Extension_MediaCategory Provides a fluent interface
+     */
+    public function setLabel($value)
+    {
+        $this->_label = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaContent.php b/lib/zend/Zend/Gdata/Media/Extension/MediaContent.php
new file mode 100755 (executable)
index 0000000..66b18b6
--- /dev/null
@@ -0,0 +1,521 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * Represents the media:content element of Media RSS.
+ * Represents media objects.  Multiple media objects representing
+ * the same content can be represented using a 
+ * media:group (Zend_Gdata_Media_Extension_MediaGroup) element.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaContent extends Zend_Gdata_Extension
+{
+    protected $_rootElement = 'content';
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_url = null;
+
+    /**
+     * @var int 
+     */
+    protected $_fileSize = null;
+
+    /**
+     * @var string
+     */
+    protected $_type = null;
+
+    /**
+     * @var string
+     */
+    protected $_medium = null;
+
+    /**
+     * @var string
+     */
+    protected $_isDefault = null;
+
+    /**
+     * @var string
+     */
+    protected $_expression = null;
+
+    /**
+     * @var int
+     */ 
+    protected $_bitrate = null;
+
+    /**
+     * @var int
+     */
+    protected $_framerate = null;
+
+    /**
+     * @var int
+     */
+    protected $_samplingrate = null;
+
+    /**
+     * @var int
+     */
+    protected $_channels = null;
+
+    /**
+     * @var int
+     */
+    protected $_duration = null;
+
+    /**
+     * @var int
+     */
+    protected $_height = null;
+
+    /**
+     * @var int
+     */
+    protected $_width = null;
+
+    /**
+     * @var string
+     */
+    protected $_lang = null;
+
+    /**
+     * Creates an individual MediaContent object.
+     */
+    public function __construct($url = null, $fileSize = null, $type = null,
+            $medium = null, $isDefault = null, $expression = null, 
+            $bitrate = null, $framerate = null, $samplingrate = null, 
+            $channels = null, $duration = null, $height = null, $width = null,
+            $lang = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_url = $url;
+        $this->_fileSize = $fileSize;
+        $this->_type = $type;
+        $this->_medium = $medium;
+        $this->_isDefault = $isDefault;
+        $this->_expression = $expression;
+        $this->_bitrate = $bitrate;
+        $this->_framerate = $framerate;
+        $this->_samplingrate = $samplingrate;
+        $this->_channels = $channels;
+        $this->_duration = $duration;
+        $this->_height = $height;
+        $this->_width = $width;
+        $this->_lang = $lang;
+    }
+
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_url != null) {
+            $element->setAttribute('url', $this->_url);
+        }
+        if ($this->_fileSize != null) {
+            $element->setAttribute('fileSize', $this->_fileSize);
+        }
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        if ($this->_medium != null) {
+            $element->setAttribute('medium', $this->_medium);
+        }
+        if ($this->_isDefault != null) {
+            $element->setAttribute('isDefault', $this->_isDefault);
+        }
+        if ($this->_expression != null) {
+            $element->setAttribute('expression', $this->_expression);
+        }
+        if ($this->_bitrate != null) {
+            $element->setAttribute('bitrate', $this->_bitrate);
+        }
+        if ($this->_framerate != null) {
+            $element->setAttribute('framerate', $this->_framerate);
+        }
+        if ($this->_samplingrate != null) {
+            $element->setAttribute('samplingrate', $this->_samplingrate);
+        }
+        if ($this->_channels != null) {
+            $element->setAttribute('channels', $this->_channels);
+        }
+        if ($this->_duration != null) {
+            $element->setAttribute('duration', $this->_duration);
+        }
+        if ($this->_height != null) {
+            $element->setAttribute('height', $this->_height);
+        }
+        if ($this->_width != null) {
+            $element->setAttribute('width', $this->_width);
+        }
+        if ($this->_lang != null) {
+            $element->setAttribute('lang', $this->_lang);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+            case 'url':
+                $this->_url = $attribute->nodeValue;
+                break;
+            case 'fileSize':
+                $this->_fileSize = $attribute->nodeValue;
+                break;
+            case 'type':
+                $this->_type = $attribute->nodeValue;
+                break;
+            case 'medium':
+                $this->_medium = $attribute->nodeValue;
+                break;
+            case 'isDefault':
+                $this->_isDefault = $attribute->nodeValue;
+                break;
+            case 'expression':
+                $this->_expression = $attribute->nodeValue;
+                break;
+            case 'bitrate':
+                $this->_bitrate = $attribute->nodeValue;
+                break;
+            case 'framerate':
+                $this->_framerate = $attribute->nodeValue;
+                break;
+            case 'samplingrate':
+                $this->_samplingrate = $attribute->nodeValue;
+                break;
+            case 'channels':
+                $this->_channels = $attribute->nodeValue;
+                break;
+            case 'duration':
+                $this->_duration = $attribute->nodeValue;
+                break;
+            case 'height':
+                $this->_height = $attribute->nodeValue;
+                break;
+            case 'width':
+                $this->_width = $attribute->nodeValue;
+                break;
+            case 'lang':
+                $this->_lang = $attribute->nodeValue;
+                break;
+            default:
+                parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * Returns the URL representing this MediaContent object
+     *
+     * @return string   The URL representing this MediaContent object.
+     */ 
+    public function __toString() 
+    {
+        return $this->getUrl();
+    }
+
+    /**
+     * @return string   The direct URL to the media object
+     */
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    /**
+     * @param string $value     The direct URL to the media object
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setUrl($value)
+    {
+        $this->_url = $value;
+        return $this;
+    }
+
+    /**
+     * @return int  The size of the media in bytes
+     */
+    public function getFileSize()
+    {
+        return $this->_fileSize;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setFileSize($value)
+    {
+        $this->_fileSize = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMedium()
+    {
+        return $this->_medium;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setMedium($value)
+    {
+        $this->_medium = $value;
+        return $this;
+    }
+
+    /**
+     * @return bool
+     */
+    public function getIsDefault()
+    {
+        return $this->_isDefault;
+    }
+
+    /**
+     * @param bool $value
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setIsDefault($value)
+    {
+        $this->_isDefault = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+
+    /**
+     * @param string
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setExpression($value)
+    {
+        $this->_expression = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getBitrate()
+    {
+        return $this->_bitrate;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setBitrate($value)
+    {
+        $this->_bitrate = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFramerate()
+    {
+        return $this->_framerate;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setFramerate($value)
+    {
+        $this->_framerate = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getSamplingrate()
+    {
+        return $this->_samplingrate;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setSamplingrate($value)
+    {
+        $this->_samplingrate = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getChannels()
+    {
+        return $this->_channels;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setChannels($value)
+    {
+        $this->_channels = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getDuration()
+    {
+        return $this->_duration;
+    }
+
+    /**
+     *
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setDuration($value)
+    {
+        $this->_duration = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getHeight()
+    {
+        return $this->_height;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setHeight($value)
+    {
+        $this->_height = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getWidth()
+    {
+        return $this->_width;
+    }
+
+    /**
+     * @param int
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setWidth($value)
+    {
+        $this->_width = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLang()
+    {
+        return $this->_lang;
+    }
+
+    /**
+     * @param string
+     * @return Zend_Gdata_Media_Extension_MediaContent  Provides a fluent interface
+     */
+    public function setLang($value)
+    {
+        $this->_lang = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaCopyright.php b/lib/zend/Zend/Gdata/Media/Extension/MediaCopyright.php
new file mode 100755 (executable)
index 0000000..05504c4
--- /dev/null
@@ -0,0 +1,115 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:copyright element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaCopyright extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'copyright'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_url = null;
+
+    /**
+     * @param string $text
+     * @param string $url 
+     */
+    public function __construct($text = null, $url = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_url = $url;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.   
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties. 
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_url != null) {
+            $element->setAttribute('url', $this->_url);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'url':
+            $this->_url = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaCopyright Provides a fluent interface
+     */
+    public function setUrl($value)
+    {
+        $this->_url = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaCredit.php b/lib/zend/Zend/Gdata/Media/Extension/MediaCredit.php
new file mode 100755 (executable)
index 0000000..bf76545
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:credit element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaCredit extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'credit'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_role = null;
+
+    /**
+     * @var string
+     */
+    protected $_scheme = null;
+
+    /**
+     * Creates an individual MediaCredit object.
+     *
+     * @param string $text
+     * @param string $role
+     * @param string $scheme
+     */
+    public function __construct($text = null, $role = null,  $scheme = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_role = $role;
+        $this->_scheme = $scheme;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_role != null) {
+            $element->setAttribute('role', $this->_role);
+        }
+        if ($this->_scheme != null) {
+            $element->setAttribute('scheme', $this->_scheme);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'role':
+            $this->_role = $attribute->nodeValue;
+            break;
+        case 'scheme':
+            $this->_scheme = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getRole()
+    {
+        return $this->_role;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaCredit Provides a fluent interface
+     */
+    public function setRole($value)
+    {
+        $this->_role = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getScheme()
+    {
+        return $this->_scheme;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaCredit Provides a fluent interface
+     */
+    public function setScheme($value)
+    {
+        $this->_scheme = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaDescription.php b/lib/zend/Zend/Gdata/Media/Extension/MediaDescription.php
new file mode 100755 (executable)
index 0000000..020388b
--- /dev/null
@@ -0,0 +1,115 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:description element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaDescription extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'description'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_type = null;
+
+    /**
+     * @param string $text
+     * @param string $type
+     */
+    public function __construct($text = null, $type = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_type = $type;
+        $this->_text = $text;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaDescription Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaGroup.php b/lib/zend/Zend/Gdata/Media/Extension/MediaGroup.php
new file mode 100755 (executable)
index 0000000..ce5bcd9
--- /dev/null
@@ -0,0 +1,565 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_Extension
+ */
+require_once 'Zend/Gdata/Extension.php';
+
+/**
+ * @see Zend_Gdata_Entry
+ */
+require_once 'Zend/Gdata/Entry.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaContent
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaContent.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaCategory
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaCategory.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaCopyright
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaCopyright.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaCredit
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaCredit.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaDescription
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaDescription.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaHash
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaHash.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaKeywords
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaKeywords.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaPlayer
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaPlayer.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaRating
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaRating.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaRestriction
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaRestriction.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaText
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaText.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaThumbnail
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaThumbnail.php';
+
+/**
+ * @see Zend_Gdata_Media_Extension_MediaTitle
+ */
+require_once 'Zend/Gdata/Media/Extension/MediaTitle.php';
+
+
+/**
+ * This class represents the media:group element of Media RSS.
+ * It allows the grouping of media:content elements that are 
+ * different representations of the same content.  When it exists,
+ * it is a child of an Entry (Atom) or Item (RSS).
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaGroup extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'group';
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var array
+     */
+    protected $_content = array(); 
+
+    /**
+     * @var array
+     */
+    protected $_category = array(); 
+
+    /**
+     * @var Zend_Gdata_Media_Extension_MediaCopyright
+     */
+    protected $_copyright = null; 
+
+    /**
+     * @var array
+     */
+    protected $_credit = array(); 
+
+    /**
+     * @var Zend_Gdata_Media_Extension_MediaDescription
+     */
+    protected $_description = null; 
+
+    /**
+     * @var array
+     */
+    protected $_hash = array(); 
+
+    /**
+     * @var Zend_Gdata_Media_Extension_MediaKeywords
+     */
+    protected $_keywords = null; 
+
+    /**
+     * @var array
+     */
+    protected $_player = array(); 
+
+    /**
+     * @var array
+     */
+    protected $_rating = array(); 
+
+    /**
+     * @var array
+     */
+    protected $_restriction = array(); 
+
+    /**
+     * @var array
+     */
+    protected $_mediaText = array(); 
+
+    /**
+     * @var array
+     */
+    protected $_thumbnail = array(); 
+
+    /**
+     * @var string
+     */
+    protected $_title = null; 
+
+    /**
+     * Creates an individual MediaGroup object.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.   
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties. 
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        foreach ($this->_content as $content) {
+            $element->appendChild($content->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_category as $category) {
+            $element->appendChild($category->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_credit as $credit) {
+            $element->appendChild($credit->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_player as $player) {
+            $element->appendChild($player->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_rating as $rating) {
+            $element->appendChild($rating->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_restriction as $restriction) {
+            $element->appendChild($restriction->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_mediaText as $text) {
+            $element->appendChild($text->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_thumbnail as $thumbnail) {
+            $element->appendChild($thumbnail->getDOM($element->ownerDocument));
+        }
+        if ($this->_copyright != null) {
+            $element->appendChild(
+                    $this->_copyright->getDOM($element->ownerDocument));
+        }
+        if ($this->_description != null) {
+            $element->appendChild(
+                    $this->_description->getDOM($element->ownerDocument));
+        }
+        foreach ($this->_hash as $hash) {
+            $element->appendChild($hash->getDOM($element->ownerDocument));
+        }
+        if ($this->_keywords != null) {
+            $element->appendChild(
+                    $this->_keywords->getDOM($element->ownerDocument));
+        }
+        if ($this->_title != null) {
+            $element->appendChild(
+                    $this->_title->getDOM($element->ownerDocument));
+        }
+        return $element;
+    }
+
+    /**
+     * Creates individual Entry objects of the appropriate type and
+     * stores them in the $_entry array based upon DOM data.
+     *
+     * @param DOMNode $child The DOMNode to process
+     */
+    protected function takeChildFromDOM($child)
+    {
+        $absoluteNodeName = $child->namespaceURI . ':' . $child->localName;
+        switch ($absoluteNodeName) {
+            case $this->lookupNamespace('media') . ':' . 'content'; 
+                $content = new Zend_Gdata_Media_Extension_MediaContent();
+                $content->transferFromDOM($child);
+                $this->_content[] = $content;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'category'; 
+                $category = new Zend_Gdata_Media_Extension_MediaCategory();
+                $category->transferFromDOM($child);
+                $this->_category[] = $category;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'copyright'; 
+                $copyright = new Zend_Gdata_Media_Extension_MediaCopyright();
+                $copyright->transferFromDOM($child);
+                $this->_copyright = $copyright;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'credit'; 
+                $credit = new Zend_Gdata_Media_Extension_MediaCredit();
+                $credit->transferFromDOM($child);
+                $this->_credit[] = $credit;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'description'; 
+                $description = new Zend_Gdata_Media_Extension_MediaDescription();
+                $description->transferFromDOM($child);
+                $this->_description = $description;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'hash'; 
+                $hash = new Zend_Gdata_Media_Extension_MediaHash();
+                $hash->transferFromDOM($child);
+                $this->_hash[] = $hash;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'keywords'; 
+                $keywords = new Zend_Gdata_Media_Extension_MediaKeywords();
+                $keywords->transferFromDOM($child);
+                $this->_keywords = $keywords;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'player'; 
+                $player = new Zend_Gdata_Media_Extension_MediaPlayer();
+                $player->transferFromDOM($child);
+                $this->_player[] = $player;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'rating'; 
+                $rating = new Zend_Gdata_Media_Extension_MediaRating();
+                $rating->transferFromDOM($child);
+                $this->_rating[] = $rating;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'restriction'; 
+                $restriction = new Zend_Gdata_Media_Extension_MediaRestriction();
+                $restriction->transferFromDOM($child);
+                $this->_restriction[] = $restriction;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'text'; 
+                $text = new Zend_Gdata_Media_Extension_MediaText();
+                $text->transferFromDOM($child);
+                $this->_mediaText[] = $text;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'thumbnail'; 
+                $thumbnail = new Zend_Gdata_Media_Extension_MediaThumbnail();
+                $thumbnail->transferFromDOM($child);
+                $this->_thumbnail[] = $thumbnail;
+                break;
+            case $this->lookupNamespace('media') . ':' . 'title'; 
+                $title = new Zend_Gdata_Media_Extension_MediaTitle();
+                $title->transferFromDOM($child);
+                $this->_title = $title;
+                break;
+        default:
+            parent::takeChildFromDOM($child);
+            break;
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getContent()
+    {
+        return $this->_content;
+    }
+
+    /**
+     * @param array $value
+     * @return Zend_Gdata_Media_MediaGroup Provides a fluent interface
+     */
+    public function setContent($value)
+    {
+        $this->_content = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getCategory()
+    {
+        return $this->_category;
+    }
+
+    /**
+     * @param array $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setCategory($value)
+    {
+        $this->_category = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_Media_Extension_MediaCopyright
+     */
+    public function getCopyright()
+    {
+        return $this->_copyright;
+    }
+
+    /**
+     * @param Zend_Gdata_Media_Extension_MediaCopyright $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setCopyright($value)
+    {
+        $this->_copyright = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getCredit()
+    {
+        return $this->_credit;
+    }
+
+    /**
+     * @param array $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setCredit($value)
+    {
+        $this->_credit = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_Media_Extension_MediaTitle
+     */ 
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    /**
+     * @param Zend_Gdata_Media_Extension_MediaTitle $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */ 
+    public function setTitle($value)
+    {
+        $this->_title = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_Media_Extension_MediaDescription
+     */
+    public function getDescription()
+    {
+        return $this->_description;
+    }
+
+    /**
+     * @param Zend_Gdata_Media_Extension_MediaDescription $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setDescription($value)
+    {
+        $this->_description = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getHash()
+    {
+        return $this->_hash;
+    }
+
+    /**
+     * @param array $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setHash($value)
+    {
+        $this->_hash = $value;
+        return $this;
+    }
+
+    /**
+     * @return Zend_Gdata_Media_Extension_MediaKeywords
+     */
+    public function getKeywords()
+    {
+        return $this->_keywords;
+    }
+
+    /**
+     * @param array $value
+     * @return Zend_Gdata_Media_Extension_MediaGroup Provides a fluent interface
+     */
+    public function setKeywords($value)
+    {
+        $this->_keywords = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getPlayer()
+    {
+        return $this->_player;
+    }
+
+    /**
+     * @param array
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setPlayer($value)
+    {
+        $this->_player = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getRating()
+    {
+        return $this->_rating;
+    }
+
+    /**
+     * @param array
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setRating($value)
+    {
+        $this->_rating = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getRestriction()
+    {
+        return $this->_restriction;
+    }
+
+    /**
+     * @param array
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setRestriction($value)
+    {
+        $this->_restriction = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getThumbnail()
+    {
+        return $this->_thumbnail;
+    }
+
+    /**
+     * @param array
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setThumbnail($value)
+    {
+        $this->_thumbnail = $value;
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getMediaText()
+    {
+        return $this->_mediaText;
+    }
+
+    /**
+     * @param array
+     * @return Zend_Gdata_Media_Extension_MediaGroup
+     */
+    public function setMediaText($value)
+    {
+        $this->_mediaText = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaHash.php b/lib/zend/Zend/Gdata/Media/Extension/MediaHash.php
new file mode 100755 (executable)
index 0000000..bbd58be
--- /dev/null
@@ -0,0 +1,114 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:hash element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaHash extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'hash'; 
+    protected $_rootNamespace = 'media';
+    protected $_algo = null;
+
+    /**
+     * Constructs a new MediaHash element
+     *
+     * @param string $text 
+     * @param string $algo
+     */
+    public function __construct($text = null, $algo = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_algo = $algo;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_algo != null) {
+            $element->setAttribute('algo', $this->_algo);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     * @throws Zend_Gdata_App_InvalidArgumentException
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'algo':
+            $this->_algo = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string The algo
+     */
+    public function getAlgo()
+    {
+        return $this->_algo;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaHash Provides a fluent interface
+     */
+    public function setAlgo($value)
+    {
+        $this->_algo = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaKeywords.php b/lib/zend/Zend/Gdata/Media/Extension/MediaKeywords.php
new file mode 100755 (executable)
index 0000000..7b734bf
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:keywords element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaKeywords extends Zend_Gdata_Extension
+{
+    protected $_rootElement = 'keywords';
+    protected $_rootNamespace = 'media';
+
+    /**
+     * Constructs a new MediaKeywords element
+     */
+    public function __construct()
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaPlayer.php b/lib/zend/Zend/Gdata/Media/Extension/MediaPlayer.php
new file mode 100755 (executable)
index 0000000..de208f8
--- /dev/null
@@ -0,0 +1,177 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:player element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaPlayer extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'player'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_url = null;
+
+    /**
+     * @var int
+     */
+    protected $_width = null;
+
+    /**
+     * @var int 
+     */
+    protected $_height = null;
+
+    /**
+     * Constructs a new MediaPlayer element
+     *
+     * @param string $url 
+     * @param int $width
+     * @param int $height
+     */
+    public function __construct($url = null, $width = null, $height = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_url = $url;
+        $this->_width = $width;
+        $this->_height = $height;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_url != null) {
+            $element->setAttribute('url', $this->_url);
+        }
+        if ($this->_width != null) {
+            $element->setAttribute('width', $this->_width);
+        }
+        if ($this->_height != null) {
+            $element->setAttribute('height', $this->_height);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'url':
+            $this->_url = $attribute->nodeValue;
+            break;
+        case 'width':
+            $this->_width = $attribute->nodeValue;
+            break;
+        case 'height':
+            $this->_height = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaPlayer Provides a fluent interface
+     */
+    public function setUrl($value)
+    {
+        $this->_url = $value;
+        return $this;
+    }
+
+    /**
+     * @return int 
+     */
+    public function getWidth()
+    {
+        return $this->_width;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Media_Extension_MediaPlayer Provides a fluent interface
+     */
+    public function setWidth($value)
+    {
+        $this->_width = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getHeight()
+    {
+        return $this->_height;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Media_Extension_MediaPlayer Provides a fluent interface
+     */
+    public function setHeight($value)
+    {
+        $this->_height = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaRating.php b/lib/zend/Zend/Gdata/Media/Extension/MediaRating.php
new file mode 100755 (executable)
index 0000000..6f4048a
--- /dev/null
@@ -0,0 +1,117 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:rating element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaRating extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'rating'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_scheme = null;
+
+    /**
+     * Constructs a new MediaRating element
+     *
+     * @param string $text
+     * @param string $scheme
+     */
+    public function __construct($text = null, $scheme = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_scheme = $scheme;
+        $this->_text = $text;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_scheme != null) {
+            $element->setAttribute('scheme', $this->_scheme);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'scheme':
+            $this->_scheme = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getScheme()
+    {
+        return $this->_scheme;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaRating Provides a fluent interface
+     */
+    public function setScheme($value)
+    {
+        $this->_scheme = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaRestriction.php b/lib/zend/Zend/Gdata/Media/Extension/MediaRestriction.php
new file mode 100755 (executable)
index 0000000..76df5e8
--- /dev/null
@@ -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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:restriction element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaRestriction extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'restriction';
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_relationship = null;
+
+    /**
+     * @var string
+     */
+    protected $_type = null;
+
+    /**
+     * Constructs a new MediaRestriction element
+     *
+     * @param string $text
+     * @param string $relationship
+     * @param string $type
+     */
+    public function __construct($text = null, $relationship = null,  $type = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_relationship = $relationship;
+        $this->_type = $type;
+    }
+
+    /**
+     * Retrieves a DOMElement which corresponds to this element and all
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_relationship != null) {
+            $element->setAttribute('relationship', $this->_relationship);
+        }
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'relationship':
+            $this->_relationship = $attribute->nodeValue;
+            break;
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getRelationship()
+    {
+        return $this->_relationship;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaRestriction Provides a fluent interface
+     */
+    public function setRelationship($value)
+    {
+        $this->_relationship = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaRestriction Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaText.php b/lib/zend/Zend/Gdata/Media/Extension/MediaText.php
new file mode 100755 (executable)
index 0000000..b1b4262
--- /dev/null
@@ -0,0 +1,210 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:text element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaText extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'text'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_type = null;
+
+    /**
+     * @var string
+     */
+    protected $_lang = null;
+
+    /**
+     * @var string
+     */
+    protected $_start = null;
+
+    /**
+     * @var string
+     */
+    protected $_end = null;
+
+    /**
+     * Constructs a new MediaText element
+     *
+     * @param $text string
+     * @param $type string
+     * @param $lang string
+     * @param $start string
+     * @param $end string
+     */
+    public function __construct($text = null, $type = null, $lang = null,
+            $start = null, $end = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_text = $text;
+        $this->_type = $type;
+        $this->_lang = $lang;
+        $this->_start = $start;
+        $this->_end = $end;
+    }
+
+    /** 
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        if ($this->_lang != null) {
+            $element->setAttribute('lang', $this->_lang);
+        }
+        if ($this->_start != null) {
+            $element->setAttribute('start', $this->_start);
+        }
+        if ($this->_end != null) {
+            $element->setAttribute('end', $this->_end);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */ 
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        case 'lang':
+            $this->_lang = $attribute->nodeValue;
+            break;
+        case 'start':
+            $this->_start = $attribute->nodeValue;
+            break;
+        case 'end':
+            $this->_end = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaText Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLang()
+    {
+        return $this->_lang;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaText Provides a fluent interface
+     */
+    public function setLang($value)
+    {
+        $this->_lang = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStart()
+    {
+        return $this->_start;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaText Provides a fluent interface
+     */
+    public function setStart($value)
+    {
+        $this->_start = $value;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getEnd()
+    {
+        return $this->_end;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaText Provides a fluent interface
+     */
+    public function setEnd($value)
+    {
+        $this->_end = $value;
+        return $this;
+    }
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaThumbnail.php b/lib/zend/Zend/Gdata/Media/Extension/MediaThumbnail.php
new file mode 100755 (executable)
index 0000000..b650102
--- /dev/null
@@ -0,0 +1,209 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:thumbnail element
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaThumbnail extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'thumbnail'; 
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_url = null;
+
+    /**
+     * @var int
+     */
+    protected $_width = null;
+
+    /**
+     * @var int
+     */
+    protected $_height = null;
+
+    /**
+     * @var string
+     */
+    protected $_time = null;
+
+    /**
+     * Constructs a new MediaThumbnail element
+     *
+     * @param string $url
+     * @param int $width
+     * @param int $height
+     * @param string $time
+     */
+    public function __construct($url = null, $width = null, $height = null,
+            $time = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_url = $url;
+        $this->_width = $width;
+        $this->_height = $height;
+        $this->_time = $time ;
+    }
+
+    /** 
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_url != null) {
+            $element->setAttribute('url', $this->_url);
+        }
+        if ($this->_width != null) {
+            $element->setAttribute('width', $this->_width);
+        }
+        if ($this->_height != null) {
+            $element->setAttribute('height', $this->_height);
+        }
+        if ($this->_time != null) {
+            $element->setAttribute('time', $this->_time);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */ 
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'url':
+            $this->_url = $attribute->nodeValue;
+            break;
+        case 'width':
+            $this->_width = $attribute->nodeValue;
+            break;
+        case 'height':
+            $this->_height = $attribute->nodeValue;
+            break;
+        case 'time':
+            $this->_time = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaThumbnail Provides a fluent interface
+     */
+    public function setUrl($value)
+    {
+        $this->_url = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getWidth()
+    {
+        return $this->_width;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Media_Extension_MediaThumbnail Provides a fluent interface
+     */
+    public function setWidth($value)
+    {
+        $this->_width = $value;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getHeight()
+    {
+        return $this->_height;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Media_Extension_MediaThumbnail Provides a fluent interface
+     */
+    public function setHeight($value)
+    {
+        $this->_height = $value;
+        return $this;
+    }
+
+    /**
+     * @return string 
+     */
+    public function getTime()
+    {
+        return $this->_time;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaThumbnail Provides a fluent interface
+     */
+    public function setTime($value)
+    {
+        $this->_time = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Extension/MediaTitle.php b/lib/zend/Zend/Gdata/Media/Extension/MediaTitle.php
new file mode 100755 (executable)
index 0000000..06bf6f6
--- /dev/null
@@ -0,0 +1,117 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_App_Extension
+ */
+require_once 'Zend/Gdata/App/Extension.php';
+
+/**
+ * Represents the media:title element in MediaRSS
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Extension_MediaTitle extends Zend_Gdata_Extension
+{
+
+    protected $_rootElement = 'title';
+    protected $_rootNamespace = 'media';
+
+    /**
+     * @var string
+     */
+    protected $_type = null;
+
+    /**
+     * Constructs a MediaTitle element
+     *
+     * @param string $text
+     * @param string $type
+     */
+    public function __construct($text = null, $type = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct();
+        $this->_type = $type;
+        $this->_text = $text;
+    }
+
+    /** 
+     * Retrieves a DOMElement which corresponds to this element and all 
+     * child properties.  This is used to build an entry back into a DOM
+     * and eventually XML text for sending to the server upon updates, or
+     * for application storage/persistence.  
+     *
+     * @param DOMDocument $doc The DOMDocument used to construct DOMElements
+     * @return DOMElement The DOMElement representing this element and all 
+     * child properties.
+     */
+    public function getDOM($doc = null)
+    {
+        $element = parent::getDOM($doc);
+        if ($this->_type != null) {
+            $element->setAttribute('type', $this->_type);
+        }
+        return $element;
+    }
+
+    /**
+     * Given a DOMNode representing an attribute, tries to map the data into
+     * instance members.  If no mapping is defined, the name and value are 
+     * stored in an array.
+     *
+     * @param DOMNode $attribute The DOMNode attribute needed to be handled
+     */ 
+    protected function takeAttributeFromDOM($attribute)
+    {
+        switch ($attribute->localName) {
+        case 'type':
+            $this->_type = $attribute->nodeValue;
+            break;
+        default:
+            parent::takeAttributeFromDOM($attribute);
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Media_Extension_MediaTitle Provides a fluent interface
+     */
+    public function setType($value)
+    {
+        $this->_type = $value;
+        return $this;
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Media/Feed.php b/lib/zend/Zend/Gdata/Media/Feed.php
new file mode 100755 (executable)
index 0000000..518fb30
--- /dev/null
@@ -0,0 +1,69 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Gdata_eed
+ */
+require_once 'Zend/Gdata/Feed.php';
+
+/**
+ * @see Zend_Gdata_Media
+ */
+require_once 'Zend/Gdata/Media.php';
+
+/**
+ * @see Zend_Gdata_Media_Entry
+ */
+require_once 'Zend/Gdata/Media/Entry.php';
+
+/**
+ * The GData flavor of an Atom Feed with media support
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Media_Feed extends Zend_Gdata_Feed
+{
+
+    /**
+     * The classname for individual feed elements.
+     *
+     * @var string
+     */
+    protected $_entryClassName = 'Zend_Gdata_Media_Entry';
+
+    /**
+     * Create a new instance.
+     * 
+     * @param DOMElement $element (optional) DOMElement from which this
+     *          object should be constructed.
+     */
+    public function __construct($element = null)
+    {
+        foreach (Zend_Gdata_Media::$namespaces as $nsPrefix => $nsUri) {
+            $this->registerNamespace($nsPrefix, $nsUri);
+        }
+        parent::__construct($element);
+    }
+
+}
diff --git a/lib/zend/Zend/Gdata/Query.php b/lib/zend/Zend/Gdata/Query.php
new file mode 100644 (file)
index 0000000..3e97762
--- /dev/null
@@ -0,0 +1,415 @@
+<?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_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Gdata_App_Util
+ */
+require_once 'Zend/Gdata/App/Util.php';
+
+/**
+ * Provides a mechanism to build a query URL for GData services.
+ * Queries are not defined for APP, but are provided by GData services
+ * as an extension.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_Query
+{
+
+    /**
+     * Query parameters.
+     *
+     * @var array
+     */
+    protected $_params = array();
+
+    /**
+     * Default URL
+     *
+     * @var string
+     */
+    protected $_defaultFeedUri = null;
+
+    /**
+     * Base URL
+     * TODO: Add setters and getters
+     *
+     * @var string
+     */
+    protected $_url = null;
+
+    /**
+     * Category for the query
+     *
+     * @var string
+     */
+    protected $_category = null;
+
+    /**
+     * Create Gdata_Query object
+     */
+    public function __construct($url = null)
+    {
+        $this->_url = $url;
+    }
+
+    /**
+     * @return string querystring
+     */
+    public function getQueryString()
+    {
+        $queryArray = array();
+        foreach ($this->_params as $name => $value) {
+            if (substr($name, 0, 1) == '_') {
+                continue;
+            }
+            $queryArray[] = urlencode($name) . '=' . urlencode($value);
+        }
+        if (count($queryArray) > 0) {
+            return '?' . implode('&', $queryArray);
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     *
+     */
+    public function resetParameters()
+    {
+        $this->_params = array();
+    }
+
+    /**
+     * @return string url
+     */
+    public function getQueryUrl()
+    {
+        if ($this->_url == null) {
+            $url = $this->_defaultFeedUri;
+        } else {
+            $url = $this->_url;
+        }
+        if ($this->getCategory() !== null) {
+            $url .= '/-/' . $this->getCategory();
+        }
+        $url .= $this->getQueryString();
+        return $url;
+    }
+
+    /**
+     * @param string $name
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setParam($name, $value)
+    {
+        $this->_params[$name] = $value;
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     */
+    public function getParam($name)
+    {
+        return $this->_params[$name];
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setAlt($value)
+    {
+        if ($value != null) {
+            $this->_params['alt'] = $value;
+        } else {
+            unset($this->_params['alt']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setMaxResults($value)
+    {
+        if ($value != null) {
+            $this->_params['max-results'] = $value;
+        } else {
+            unset($this->_params['max-results']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setQuery($value)
+    {
+        if ($value != null) {
+            $this->_params['q'] = $value;
+        } else {
+            unset($this->_params['q']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param int $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setStartIndex($value)
+    {
+        if ($value != null) {
+            $this->_params['start-index'] = $value;
+        } else {
+            unset($this->_params['start-index']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setUpdatedMax($value)
+    {
+        if ($value != null) {
+            $this->_params['updated-max'] = Zend_Gdata_App_Util::formatTimestamp($value);
+        } else {
+            unset($this->_params['updated-max']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setUpdatedMin($value)
+    {
+        if ($value != null) {
+            $this->_params['updated-min'] = Zend_Gdata_App_Util::formatTimestamp($value);
+        } else {
+            unset($this->_params['updated-min']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setPublishedMax($value)
+    {
+        if ($value !== null) {
+            $this->_params['published-max'] = Zend_Gdata_App_Util::formatTimestamp($value);
+        } else {
+            unset($this->_params['published-max']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setPublishedMin($value)
+    {
+        if ($value != null) {
+            $this->_params['published-min'] = Zend_Gdata_App_Util::formatTimestamp($value);
+        } else {
+            unset($this->_params['published-min']);
+        }
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setAuthor($value)
+    {
+        if ($value != null) {
+            $this->_params['author'] = $value;
+        } else {
+            unset($this->_params['author']);
+        }
+        return $this;
+    }
+
+    /**
+     * @return string rss or atom
+     */
+    public function getAlt()
+    {
+        if (array_key_exists('alt', $this->_params)) {
+            return $this->_params['alt'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return int maxResults
+     */
+    public function getMaxResults()
+    {
+        if (array_key_exists('max-results', $this->_params)) {
+            return intval($this->_params['max-results']);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string query
+     */
+    public function getQuery()
+    {
+        if (array_key_exists('q', $this->_params)) {
+            return $this->_params['q'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return int startIndex
+     */
+    public function getStartIndex()
+    {
+        if (array_key_exists('start-index', $this->_params)) {
+            return intval($this->_params['start-index']);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string updatedMax
+     */
+    public function getUpdatedMax()
+    {
+        if (array_key_exists('updated-max', $this->_params)) {
+            return $this->_params['updated-max'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string updatedMin
+     */
+    public function getUpdatedMin()
+    {
+        if (array_key_exists('updated-min', $this->_params)) {
+            return $this->_params['updated-min'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string publishedMax
+     */
+    public function getPublishedMax()
+    {
+        if (array_key_exists('published-max', $this->_params)) {
+            return $this->_params['published-max'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string publishedMin
+     */
+    public function getPublishedMin()
+    {
+        if (array_key_exists('published-min', $this->_params)) {
+            return $this->_params['published-min'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return string author
+     */
+    public function getAuthor()
+    {
+        if (array_key_exists('author', $this->_params)) {
+            return $this->_params['author'];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @param string $value
+     * @return Zend_Gdata_Query Provides a fluent interface
+     */
+    public function setCategory($value)
+    {
+        $this->_category = $value;
+        return $this;
+    }
+
+    /*
+     * @return string id
+     */
+    public function getCategory()
+    {
+        return $this->_category;
+    }
+
+
+    public function __get($name)
+    {
+        $method = 'get'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method));
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception('Property ' . $name . '  does not exist');
+        }
+    }
+
+    public function __set($name, $val)
+    {
+        $method = 'set'.ucfirst($name);
+        if (method_exists($this, $method)) {
+            return call_user_func(array(&$this, $method), $val);
+        } else {
+            require_once 'Zend/Gdata/App/Exception.php';
+            throw new Zend_Gdata_App_Exception('Property ' . $name . '  does not exist');
+        }
+    }
+
+}
diff --git a/lib/zend/Zend/Http/Client.php b/lib/zend/Zend/Http/Client.php
new file mode 100644 (file)
index 0000000..d0df942
--- /dev/null
@@ -0,0 +1,1194 @@
+<?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_Http
+ * @subpackage Client
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+
+/**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+
+/**
+ * @see Zend_Http_Client_Adapter_Interface
+ */
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+
+/**
+ * @see Zend_Http_Response
+ */
+require_once 'Zend/Http/Response.php';
+
+/**
+ * Zend_Http_Client is an implemetation of an HTTP client in PHP. The client
+ * supports basic features like sending different HTTP requests and handling
+ * redirections, as well as more advanced features like proxy settings, HTTP
+ * authentication and cookie persistance (using a Zend_Http_CookieJar object)
+ *
+ * @todo Implement proxy settings
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client
+ * @throws     Zend_Http_Client_Exception
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client
+{
+    /**
+     * HTTP request methods
+     */
+    const GET     = 'GET';
+    const POST    = 'POST';
+    const PUT     = 'PUT';
+    const HEAD    = 'HEAD';
+    const DELETE  = 'DELETE';
+    const TRACE   = 'TRACE';
+    const OPTIONS = 'OPTIONS';
+    const CONNECT = 'CONNECT';
+
+    /**
+     * Supported HTTP Authentication methods
+     */
+    const AUTH_BASIC = 'basic';
+    //const AUTH_DIGEST = 'digest'; <-- not implemented yet
+
+    /**
+     * HTTP protocol versions
+     */
+    const HTTP_1 = '1.1';
+    const HTTP_0 = '1.0';
+
+    /**
+     * Content attributes
+     */
+    const CONTENT_TYPE   = 'Content-Type';
+    const CONTENT_LENGTH = 'Content-Length';
+
+    /**
+     * POST data encoding methods
+     */
+    const ENC_URLENCODED = 'application/x-www-form-urlencoded';
+    const ENC_FORMDATA   = 'multipart/form-data';
+
+    /**
+     * Configuration array, set using the constructor or using ::setConfig()
+     *
+     * @var array
+     */
+    protected $config = array(
+        'maxredirects'    => 5,
+        'strictredirects' => false,
+        'useragent'       => 'Zend_Http_Client',
+        'timeout'         => 10,
+        'adapter'         => 'Zend_Http_Client_Adapter_Socket',
+        'httpversion'     => self::HTTP_1,
+        'keepalive'       => false,
+        'storeresponse'   => true,
+        'strict'          => true
+    );
+
+    /**
+     * The adapter used to preform the actual connection to the server
+     *
+     * @var Zend_Http_Client_Adapter_Interface
+     */
+    protected $adapter = null;
+
+    /**
+     * Request URI
+     *
+     * @var Zend_Uri_Http
+     */
+    protected $uri;
+
+    /**
+     * Associative array of request headers
+     *
+     * @var array
+     */
+    protected $headers = array();
+
+    /**
+     * HTTP request method
+     *
+     * @var string
+     */
+    protected $method = self::GET;
+
+    /**
+     * Associative array of GET parameters
+     *
+     * @var array
+     */
+    protected $paramsGet = array();
+
+    /**
+     * Assiciative array of POST parameters
+     *
+     * @var array
+     */
+    protected $paramsPost = array();
+
+    /**
+     * Request body content type (for POST requests)
+     *
+     * @var string
+     */
+    protected $enctype = null;
+
+    /**
+     * The raw post data to send. Could be set by setRawData($data, $enctype).
+     *
+     * @var string
+     */
+    protected $raw_post_data = null;
+
+    /**
+     * HTTP Authentication settings
+     *
+     * Expected to be an associative array with this structure:
+     * $this->auth = array('user' => 'username', 'password' => 'password', 'type' => 'basic')
+     * Where 'type' should be one of the supported authentication types (see the AUTH_*
+     * constants), for example 'basic' or 'digest'.
+     *
+     * If null, no authentication will be used.
+     *
+     * @var array|null
+     */
+    protected $auth;
+
+    /**
+     * File upload arrays (used in POST requests)
+     *
+     * An associative array, where each element is of the format:
+     *   'name' => array('filename.txt', 'text/plain', 'This is the actual file contents')
+     *
+     * @var array
+     */
+    protected $files = array();
+
+    /**
+     * The client's cookie jar
+     *
+     * @var Zend_Http_CookieJar
+     */
+    protected $cookiejar = null;
+
+    /**
+     * The last HTTP request sent by the client, as string
+     *
+     * @var string
+     */
+    protected $last_request = null;
+
+    /**
+     * The last HTTP response received by the client
+     *
+     * @var Zend_Http_Response
+     */
+    protected $last_response = null;
+
+    /**
+     * Redirection counter
+     *
+     * @var int
+     */
+    protected $redirectCounter = 0;
+
+    /**
+     * Fileinfo magic database resource
+     * 
+     * This varaiable is populated the first time _detectFileMimeType is called
+     * and is then reused on every call to this method
+     *
+     * @var resource
+     */
+    static protected $_fileInfoDb = null;
+    
+    /**
+     * Contructor method. Will create a new HTTP client. Accepts the target
+     * URL and optionally configuration array.
+     *
+     * @param Zend_Uri_Http|string $uri
+     * @param array $config Configuration key-value pairs.
+     */
+    public function __construct($uri = null, $config = null)
+    {
+        if ($uri !== null) $this->setUri($uri);
+        if ($config !== null) $this->setConfig($config);
+    }
+
+    /**
+     * Set the URI for the next request
+     *
+     * @param  Zend_Uri_Http|string $uri
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setUri($uri)
+    {
+        if (is_string($uri)) {
+            $uri = Zend_Uri::factory($uri);
+        }
+
+        if (!$uri instanceof Zend_Uri_Http) {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception('Passed parameter is not a valid HTTP URI.');
+        }
+
+        // We have no ports, set the defaults
+        if (! $uri->getPort()) {
+            $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80));
+        }
+
+        $this->uri = $uri;
+
+        return $this;
+    }
+
+    /**
+     * Get the URI for the next request
+     *
+     * @param boolean $as_string If true, will return the URI as a string
+     * @return Zend_Uri_Http|string
+     */
+    public function getUri($as_string = false)
+    {
+        if ($as_string && $this->uri instanceof Zend_Uri_Http) {
+            return $this->uri->__toString();
+        } else {
+            return $this->uri;
+        }
+    }
+
+    /**
+     * Set configuration parameters for this HTTP client
+     *
+     * @param array $config
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setConfig($config = array())
+    {
+        if (! is_array($config)) {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception('Expected array parameter, given ' . gettype($config));
+        }
+
+        foreach ($config as $k => $v)
+            $this->config[strtolower($k)] = $v;
+
+        return $this;
+    }
+
+    /**
+     * Set the next request's method
+     *
+     * Validated the passed method and sets it. If we have files set for
+     * POST requests, and the new method is not POST, the files are silently
+     * dropped.
+     *
+     * @param string $method
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setMethod($method = self::GET)
+    {
+        $regex = '/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/';
+        if (! preg_match($regex, $method)) {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception("'{$method}' is not a valid HTTP request method.");
+        }
+
+        if ($method == self::POST && $this->enctype === null)
+            $this->setEncType(self::ENC_URLENCODED);
+
+        $this->method = $method;
+
+        return $this;
+    }
+
+    /**
+     * Set one or more request headers
+     *
+     * This function can be used in several ways to set the client's request
+     * headers:
+     * 1. By providing two parameters: $name as the header to set (eg. 'Host')
+     *    and $value as it's value (eg. 'www.example.com').
+     * 2. By providing a single header string as the only parameter
+     *    eg. 'Host: www.example.com'
+     * 3. By providing an array of headers as the first parameter
+     *    eg. array('host' => 'www.example.com', 'x-foo: bar'). In This case
+     *    the function will call itself recursively for each array item.
+     *
+     * @param string|array $name Header name, full header string ('Header: value')
+     *     or an array of headers
+     * @param mixed $value Header value or null
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setHeaders($name, $value = null)
+    {
+        // If we got an array, go recusive!
+        if (is_array($name)) {
+            foreach ($name as $k => $v) {
+                if (is_string($k)) {
+                    $this->setHeaders($k, $v);
+                } else {
+                    $this->setHeaders($v, null);
+                }
+            }
+        } else {
+            // Check if $name needs to be split
+            if ($value === null && (strpos($name, ':') > 0))
+                list($name, $value) = explode(':', $name, 2);
+
+            // Make sure the name is valid if we are in strict mode
+            if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("{$name} is not a valid HTTP header name");
+            }
+            
+            $normalized_name = strtolower($name);
+
+            // If $value is null or false, unset the header
+            if ($value === null || $value === false) {
+                unset($this->headers[$normalized_name]);
+
+            // Else, set the header
+            } else {
+                // Header names are storred lowercase internally.
+                if (is_string($value)) $value = trim($value);
+                $this->headers[$normalized_name] = array($name, $value);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get the value of a specific header
+     *
+     * Note that if the header has more than one value, an array
+     * will be returned.
+     *
+     * @param string $key
+     * @return string|array|null The header value or null if it is not set
+     */
+    public function getHeader($key)
+    {
+        $key = strtolower($key);
+        if (isset($this->headers[$key])) {
+            return $this->headers[$key][1];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Set a GET parameter for the request. Wrapper around _setParameter
+     *
+     * @param string|array $name
+     * @param string $value
+     * @return Zend_Http_Client
+     */
+    public function setParameterGet($name, $value = null)
+    {
+        if (is_array($name)) {
+            foreach ($name as $k => $v)
+                $this->_setParameter('GET', $k, $v);
+        } else {
+            $this->_setParameter('GET', $name, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set a POST parameter for the request. Wrapper around _setParameter
+     *
+     * @param string|array $name
+     * @param string $value
+     * @return Zend_Http_Client
+     */
+    public function setParameterPost($name, $value = null)
+    {
+        if (is_array($name)) {
+            foreach ($name as $k => $v)
+                $this->_setParameter('POST', $k, $v);
+        } else {
+            $this->_setParameter('POST', $name, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set a GET or POST parameter - used by SetParameterGet and SetParameterPost
+     *
+     * @param string $type GET or POST
+     * @param string $name
+     * @param string $value
+     * @return null
+     */
+    protected function _setParameter($type, $name, $value)
+    {
+        $parray = array();
+        $type = strtolower($type);
+        switch ($type) {
+            case 'get':
+                $parray = &$this->paramsGet;
+                break;
+            case 'post':
+                $parray = &$this->paramsPost;
+                break;
+        }
+
+        if ($value === null) {
+            if (isset($parray[$name])) unset($parray[$name]);
+        } else {
+            $parray[$name] = $value;
+        }
+    }
+
+    /**
+     * Get the number of redirections done on the last request
+     *
+     * @return int
+     */
+    public function getRedirectionsCount()
+    {
+        return $this->redirectCounter;
+    }
+
+    /**
+     * Set HTTP authentication parameters
+     *
+     * $type should be one of the supported types - see the self::AUTH_*
+     * constants.
+     *
+     * To enable authentication:
+     * <code>
+     * $this->setAuth('shahar', 'secret', Zend_Http_Client::AUTH_BASIC);
+     * </code>
+     *
+     * To disable authentication:
+     * <code>
+     * $this->setAuth(false);
+     * </code>
+     *
+     * @see http://www.faqs.org/rfcs/rfc2617.html
+     * @param string|false $user User name or false disable authentication
+     * @param string $password Password
+     * @param string $type Authentication type
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setAuth($user, $password = '', $type = self::AUTH_BASIC)
+    {
+        // If we got false or null, disable authentication
+        if ($user === false || $user === null) {
+            $this->auth = null;
+
+        // Else, set up authentication
+        } else {
+            // Check we got a proper authentication type
+            if (! defined('self::AUTH_' . strtoupper($type))) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("Invalid or not supported authentication type: '$type'");
+            }
+
+            $this->auth = array(
+                'user' => (string) $user,
+                'password' => (string) $password,
+                'type' => $type
+            );
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the HTTP client's cookie jar.
+     *
+     * A cookie jar is an object that holds and maintains cookies across HTTP requests
+     * and responses.
+     *
+     * @param Zend_Http_CookieJar|boolean $cookiejar Existing cookiejar object, true to create a new one, false to disable
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setCookieJar($cookiejar = true)
+    {
+        if (! class_exists('Zend_Http_CookieJar'))
+            require_once 'Zend/Http/CookieJar.php';
+
+        if ($cookiejar instanceof Zend_Http_CookieJar) {
+            $this->cookiejar = $cookiejar;
+        } elseif ($cookiejar === true) {
+            $this->cookiejar = new Zend_Http_CookieJar();
+        } elseif (! $cookiejar) {
+            $this->cookiejar = null;
+        } else {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception('Invalid parameter type passed as CookieJar');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Return the current cookie jar or null if none.
+     *
+     * @return Zend_Http_CookieJar|null
+     */
+    public function getCookieJar()
+    {
+        return $this->cookiejar;
+    }
+
+    /**
+     * Add a cookie to the request. If the client has no Cookie Jar, the cookies
+     * will be added directly to the headers array as "Cookie" headers.
+     *
+     * @param Zend_Http_Cookie|string $cookie
+     * @param string|null $value If "cookie" is a string, this is the cookie value.
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setCookie($cookie, $value = null)
+    {
+        if (! class_exists('Zend_Http_Cookie'))
+            require_once 'Zend/Http/Cookie.php';
+
+        if (is_array($cookie)) {
+            foreach ($cookie as $c => $v) {
+                if (is_string($c)) {
+                    $this->setCookie($c, $v);
+                } else {
+                    $this->setCookie($v);
+                }
+            }
+
+            return $this;
+        }
+
+        if ($value !== null) $value = urlencode($value);
+
+        if (isset($this->cookiejar)) {
+            if ($cookie instanceof Zend_Http_Cookie) {
+                $this->cookiejar->addCookie($cookie);
+            } elseif (is_string($cookie) && $value !== null) {
+                $cookie = Zend_Http_Cookie::fromString("{$cookie}={$value}", $this->uri);
+                $this->cookiejar->addCookie($cookie);
+            }
+        } else {
+            if ($cookie instanceof Zend_Http_Cookie) {
+                $name = $cookie->getName();
+                $value = $cookie->getValue();
+                $cookie = $name;
+            }
+
+            if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})");
+            }
+
+            $value = addslashes($value);
+
+            if (! isset($this->headers['cookie'])) $this->headers['cookie'] = array('Cookie', '');
+            $this->headers['cookie'][1] .= $cookie . '=' . $value . '; ';
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set a file to upload (using a POST request)
+     *
+     * Can be used in two ways:
+     *
+     * 1. $data is null (default): $filename is treated as the name if a local file which
+     *    will be read and sent. Will try to guess the content type using mime_content_type().
+     * 2. $data is set - $filename is sent as the file name, but $data is sent as the file
+     *    contents and no file is read from the file system. In this case, you need to
+     *    manually set the Content-Type ($ctype) or it will default to
+     *    application/octet-stream.
+     *
+     * @param string $filename Name of file to upload, or name to save as
+     * @param string $formname Name of form element to send as
+     * @param string $data Data to send (if null, $filename is read and sent)
+     * @param string $ctype Content type to use (if $data is set and $ctype is
+     *     null, will be application/octet-stream)
+     * @return Zend_Http_Client
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setFileUpload($filename, $formname, $data = null, $ctype = null)
+    {
+        if ($data === null) {
+            if (($data = @file_get_contents($filename)) === false) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("Unable to read file '{$filename}' for upload");
+            }
+
+            if (! $ctype) $ctype = $this->_detectFileMimeType($filename);
+        }
+
+        // Force enctype to multipart/form-data
+        $this->setEncType(self::ENC_FORMDATA);
+
+        $this->files[$formname] = array(basename($filename), $ctype, $data);
+
+        return $this;
+    }
+
+    /**
+     * Set the encoding type for POST data
+     *
+     * @param string $enctype
+     * @return Zend_Http_Client
+     */
+    public function setEncType($enctype = self::ENC_URLENCODED)
+    {
+        $this->enctype = $enctype;
+
+        return $this;
+    }
+
+    /**
+     * Set the raw (already encoded) POST data.
+     *
+     * This function is here for two reasons:
+     * 1. For advanced user who would like to set their own data, already encoded
+     * 2. For backwards compatibilty: If someone uses the old post($data) method.
+     *    this method will be used to set the encoded data.
+     *
+     * @param string $data
+     * @param string $enctype
+     * @return Zend_Http_Client
+     */
+    public function setRawData($data, $enctype = null)
+    {
+        $this->raw_post_data = $data;
+        $this->setEncType($enctype);
+
+        return $this;
+    }
+
+    /**
+     * Clear all GET and POST parameters
+     *
+     * Should be used to reset the request parameters if the client is
+     * used for several concurrent requests.
+     *
+     * @return Zend_Http_Client
+     */
+    public function resetParameters()
+    {
+        // Reset parameter data
+        $this->paramsGet     = array();
+        $this->paramsPost    = array();
+        $this->files         = array();
+        $this->raw_post_data = null;
+
+        // Clear outdated headers
+        if (isset($this->headers[strtolower(self::CONTENT_TYPE)]))
+            unset($this->headers[strtolower(self::CONTENT_TYPE)]);
+        if (isset($this->headers[strtolower(self::CONTENT_LENGTH)]))
+            unset($this->headers[strtolower(self::CONTENT_LENGTH)]);
+
+        return $this;
+    }
+
+    /**
+     * Get the last HTTP request as string
+     *
+     * @return string
+     */
+    public function getLastRequest()
+    {
+        return $this->last_request;
+    }
+
+    /**
+     * Get the last HTTP response received by this client
+     *
+     * If $config['storeresponse'] is set to false, or no response was
+     * stored yet, will return null
+     *
+     * @return Zend_Http_Response or null if none
+     */
+    public function getLastResponse()
+    {
+        return $this->last_response;
+    }
+
+    /**
+     * Load the connection adapter
+     *
+     * While this method is not called more than one for a client, it is
+     * seperated from ->request() to preserve logic and readability
+     *
+     * @param Zend_Http_Client_Adapter_Interface|string $adapter
+     * @return null
+     * @throws Zend_Http_Client_Exception
+     */
+    public function setAdapter($adapter)
+    {
+        if (is_string($adapter)) {
+            try {
+                Zend_Loader::loadClass($adapter);
+            } catch (Zend_Exception $e) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("Unable to load adapter '$adapter': {$e->getMessage()}");
+            }
+
+            $adapter = new $adapter;
+        }
+
+        if (! $adapter instanceof Zend_Http_Client_Adapter_Interface) {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception('Passed adapter is not a HTTP connection adapter');
+        }
+
+        $this->adapter = $adapter;
+        $config = $this->config;
+        unset($config['adapter']);
+        $this->adapter->setConfig($config);
+    }
+
+    /**
+     * Send the HTTP request and return an HTTP response object
+     *
+     * @param string $method
+     * @return Zend_Http_Response
+     * @throws Zend_Http_Client_Exception
+     */
+    public function request($method = null)
+    {
+        if (! $this->uri instanceof Zend_Uri_Http) {
+            /** @see Zend_Http_Client_Exception */
+            require_once 'Zend/Http/Client/Exception.php';
+            throw new Zend_Http_Client_Exception('No valid URI has been passed to the client');
+        }
+
+        if ($method) $this->setMethod($method);
+        $this->redirectCounter = 0;
+        $response = null;
+
+        // Make sure the adapter is loaded
+        if ($this->adapter == null) $this->setAdapter($this->config['adapter']);
+
+        // Send the first request. If redirected, continue.
+        do {
+            // Clone the URI and add the additional GET parameters to it
+            $uri = clone $this->uri;
+            if (! empty($this->paramsGet)) {
+                $query = $uri->getQuery();
+                   if (! empty($query)) $query .= '&';
+                $query .= http_build_query($this->paramsGet, null, '&');
+
+                $uri->setQuery($query);
+            }
+
+            $body = $this->_prepareBody();
+            $headers = $this->_prepareHeaders();
+
+            // Open the connection, send the request and read the response
+            $this->adapter->connect($uri->getHost(), $uri->getPort(),
+                ($uri->getScheme() == 'https' ? true : false));
+
+            $this->last_request = $this->adapter->write($this->method,
+                $uri, $this->config['httpversion'], $headers, $body);
+
+            $response = $this->adapter->read();
+            if (! $response) {
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception('Unable to read response, or response is empty');
+            }
+
+            $response = Zend_Http_Response::fromString($response);
+            if ($this->config['storeresponse']) $this->last_response = $response;
+
+            // Load cookies into cookie jar
+            if (isset($this->cookiejar)) $this->cookiejar->addCookiesFromResponse($response, $uri);
+
+            // If we got redirected, look for the Location header
+            if ($response->isRedirect() && ($location = $response->getHeader('location'))) {
+
+                // Check whether we send the exact same request again, or drop the parameters
+                // and send a GET request
+                if ($response->getStatus() == 303 ||
+                   ((! $this->config['strictredirects']) && ($response->getStatus() == 302 ||
+                       $response->getStatus() == 301))) {
+
+                    $this->resetParameters();
+                    $this->setMethod(self::GET);
+                }
+
+                // If we got a well formed absolute URI
+                if (Zend_Uri_Http::check($location)) {
+                    $this->setHeaders('host', null);
+                    $this->setUri($location);
+
+                } else {
+
+                    // Split into path and query and set the query
+                    if (strpos($location, '?') !== false) {
+                        list($location, $query) = explode('?', $location, 2);
+                    } else {
+                        $query = '';
+                    }
+                    $this->uri->setQuery($query);
+
+                    // Else, if we got just an absolute path, set it
+                    if(strpos($location, '/') === 0) {
+                        $this->uri->setPath($location);
+
+                        // Else, assume we have a relative path
+                    } else {
+                        // Get the current path directory, removing any trailing slashes
+                        $path = $this->uri->getPath();
+                        $path = rtrim(substr($path, 0, strrpos($path, '/')), "/");
+                        $this->uri->setPath($path . '/' . $location);
+                    }
+                }
+                ++$this->redirectCounter;
+
+            } else {
+                // If we didn't get any location, stop redirecting
+                break;
+            }
+
+        } while ($this->redirectCounter < $this->config['maxredirects']);
+
+        return $response;
+    }
+
+    /**
+     * Prepare the request headers
+     *
+     * @return array
+     */
+    protected function _prepareHeaders()
+    {
+        $headers = array();
+
+        // Set the host header
+        if (! isset($this->headers['host'])) {
+            $host = $this->uri->getHost();
+
+            // If the port is not default, add it
+            if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) ||
+                  ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) {
+                $host .= ':' . $this->uri->getPort();
+            }
+
+            $headers[] = "Host: {$host}";
+        }
+
+        // Set the connection header
+        if (! isset($this->headers['connection'])) {
+            if (! $this->config['keepalive']) $headers[] = "Connection: close";
+        }
+
+        // Set the Accept-encoding header if not set - depending on whether
+        // zlib is available or not.
+        if (! isset($this->headers['accept-encoding'])) {
+               if (function_exists('gzinflate')) {
+                       $headers[] = 'Accept-encoding: gzip, deflate';
+               } else {
+                       $headers[] = 'Accept-encoding: identity';
+               }
+        }
+        
+        // Set the Content-Type header
+        if ($this->method == self::POST &&
+           (! isset($this->headers[strtolower(self::CONTENT_TYPE)]) && isset($this->enctype))) {
+
+            $headers[] = self::CONTENT_TYPE . ': ' . $this->enctype;
+        }
+        
+        // Set the user agent header
+        if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) {
+            $headers[] = "User-Agent: {$this->config['useragent']}";
+        }
+
+        // Set HTTP authentication if needed
+        if (is_array($this->auth)) {
+            $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']);
+            $headers[] = "Authorization: {$auth}";
+        }
+
+        // Load cookies from cookie jar
+        if (isset($this->cookiejar)) {
+            $cookstr = $this->cookiejar->getMatchingCookies($this->uri,
+                true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT);
+
+            if ($cookstr) $headers[] = "Cookie: {$cookstr}";
+        }
+
+        // Add all other user defined headers
+        foreach ($this->headers as $header) {
+               list($name, $value) = $header;
+            if (is_array($value))
+                $value = implode(', ', $value);
+
+            $headers[] = "$name: $value";
+        }
+
+        return $headers;
+    }
+
+    /**
+     * Prepare the request body (for POST and PUT requests)
+     *
+     * @return string
+     * @throws Zend_Http_Client_Exception
+     */
+    protected function _prepareBody()
+    {
+        // According to RFC2616, a TRACE request should not have a body.
+        if ($this->method == self::TRACE) {
+            return '';
+        }
+
+        // If we have raw_post_data set, just use it as the body.
+        if (isset($this->raw_post_data)) {
+            $this->setHeaders(self::CONTENT_LENGTH, strlen($this->raw_post_data));
+            return $this->raw_post_data;
+        }
+
+        $body = '';
+
+        // If we have files to upload, force enctype to multipart/form-data
+        if (count ($this->files) > 0) $this->setEncType(self::ENC_FORMDATA);
+
+        // If we have POST parameters or files, encode and add them to the body
+        if (count($this->paramsPost) > 0 || count($this->files) > 0) {
+            switch($this->enctype) {
+                case self::ENC_FORMDATA:
+                    // Encode body as multipart/form-data
+                    $boundary = '---ZENDHTTPCLIENT-' . md5(microtime());
+                    $this->setHeaders(self::CONTENT_TYPE, self::ENC_FORMDATA . "; boundary={$boundary}");
+
+                    // Get POST parameters and encode them
+                    $params = $this->_getParametersRecursive($this->paramsPost);
+                    foreach ($params as $pp) {
+                        $body .= self::encodeFormData($boundary, $pp[0], $pp[1]);
+                    }
+
+                    // Encode files
+                    foreach ($this->files as $name => $file) {
+                        $fhead = array(self::CONTENT_TYPE => $file[1]);
+                        $body .= self::encodeFormData($boundary, $name, $file[2], $file[0], $fhead);
+                    }
+
+                    $body .= "--{$boundary}--\r\n";
+                    break;
+
+                case self::ENC_URLENCODED:
+                    // Encode body as application/x-www-form-urlencoded
+                    $this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED);
+                    $body = http_build_query($this->paramsPost, '', '&');
+                    break;
+
+                default:
+                    /** @see Zend_Http_Client_Exception */
+                    require_once 'Zend/Http/Client/Exception.php';
+                    throw new Zend_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." .
+                        " Please use Zend_Http_Client::setRawData to send this kind of content.");
+                    break;
+            }
+        }
+        
+        // Set the Content-Length if we have a body or if request is POST/PUT
+        if ($body || $this->method == self::POST || $this->method == self::PUT) {
+            $this->setHeaders(self::CONTENT_LENGTH, strlen($body));
+        }
+
+        return $body;
+    }
+
+    /**
+     * Helper method that gets a possibly multi-level parameters array (get or
+     * post) and flattens it.
+     *
+     * The method returns an array of (key, value) pairs (because keys are not
+     * necessarily unique. If one of the parameters in as array, it will also
+     * add a [] suffix to the key.
+     *
+     * @param array $parray The parameters array
+     * @param bool $urlencode Whether to urlencode the name and value
+     * @return array
+     */
+    protected function _getParametersRecursive($parray, $urlencode = false)
+    {
+        if (! is_array($parray)) return $parray;
+        $parameters = array();
+
+        foreach ($parray as $name => $value) {
+            if ($urlencode) $name = urlencode($name);
+
+            // If $value is an array, iterate over it
+            if (is_array($value)) {
+                $name .= ($urlencode ? '%5B%5D' : '[]');
+                foreach ($value as $subval) {
+                    if ($urlencode) $subval = urlencode($subval);
+                    $parameters[] = array($name, $subval);
+                }
+            } else {
+                if ($urlencode) $value = urlencode($value);
+                $parameters[] = array($name, $value);
+            }
+        }
+
+        return $parameters;
+    }
+    
+    /**
+     * Attempt to detect the MIME type of a file using available extensions
+     * 
+     * This method will try to detect the MIME type of a file. If the fileinfo
+     * extension is available, it will be used. If not, the mime_magic 
+     * extension which is deprected but is still available in many PHP setups
+     * will be tried. 
+     * 
+     * If neither extension is available, the default application/octet-stream
+     * MIME type will be returned
+     *
+     * @param  string $file File path
+     * @return string       MIME type
+     */
+    protected function _detectFileMimeType($file)
+    {
+        $type = null;
+        
+        // First try with fileinfo functions
+        if (function_exists('finfo_open')) {
+            if (self::$_fileInfoDb === null) {
+                self::$_fileInfoDb = @finfo_open(FILEINFO_MIME);
+            }
+            
+            if (self::$_fileInfoDb) { 
+                $type = finfo_file(self::$_fileInfoDb, $file);
+            }
+            
+        } elseif (function_exists('mime_content_type')) {
+            $type = mime_content_type($file);
+        }
+        
+        // Fallback to the default application/octet-stream
+        if (! $type) {
+            $type = 'application/octet-stream';
+        }
+        
+        return $type;
+    }
+
+    /**
+     * Encode data to a multipart/form-data part suitable for a POST request.
+     *
+     * @param string $boundary
+     * @param string $name
+     * @param mixed $value
+     * @param string $filename
+     * @param array $headers Associative array of optional headers @example ("Content-Transfer-Encoding" => "binary")
+     * @return string
+     */
+    public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) {
+        $ret = "--{$boundary}\r\n" .
+            'Content-Disposition: form-data; name="' . $name .'"';
+
+        if ($filename) $ret .= '; filename="' . $filename . '"';
+        $ret .= "\r\n";
+
+        foreach ($headers as $hname => $hvalue) {
+            $ret .= "{$hname}: {$hvalue}\r\n";
+        }
+        $ret .= "\r\n";
+
+        $ret .= "{$value}\r\n";
+
+        return $ret;
+    }
+
+    /**
+     * Create a HTTP authentication "Authorization:" header according to the
+     * specified user, password and authentication method.
+     *
+     * @see http://www.faqs.org/rfcs/rfc2617.html
+     * @param string $user
+     * @param string $password
+     * @param string $type
+     * @return string
+     * @throws Zend_Http_Client_Exception
+     */
+    public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC)
+    {
+        $authHeader = null;
+
+        switch ($type) {
+            case self::AUTH_BASIC:
+                // In basic authentication, the user name cannot contain ":"
+                if (strpos($user, ':') !== false) {
+                    /** @see Zend_Http_Client_Exception */
+                    require_once 'Zend/Http/Client/Exception.php';
+                    throw new Zend_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication");
+                }
+
+                $authHeader = 'Basic ' . base64_encode($user . ':' . $password);
+                break;
+
+            //case self::AUTH_DIGEST:
+                /**
+                 * @todo Implement digest authentication
+                 */
+            //    break;
+
+            default:
+                /** @see Zend_Http_Client_Exception */
+                require_once 'Zend/Http/Client/Exception.php';
+                throw new Zend_Http_Client_Exception("Not a supported HTTP authentication type: '$type'");
+        }
+
+        return $authHeader;
+    }
+}
diff --git a/lib/zend/Zend/Http/Client/Adapter/Exception.php b/lib/zend/Zend/Http/Client/Adapter/Exception.php
new file mode 100644 (file)
index 0000000..89eb95b
--- /dev/null
@@ -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_Http
+ * @subpackage Client_Adapter_Exception
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Http/Client/Exception.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client_Adapter_Exception extends Zend_Http_Client_Exception
+{}
diff --git a/lib/zend/Zend/Http/Client/Adapter/Interface.php b/lib/zend/Zend/Http/Client/Adapter/Interface.php
new file mode 100644 (file)
index 0000000..e9ddf55
--- /dev/null
@@ -0,0 +1,78 @@
+<?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_Http
+ * @subpackage Client_Adapter
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * An interface description for Zend_Http_Client_Adapter classes.
+ *
+ * These classes are used as connectors for Zend_Http_Client, performing the
+ * tasks of connecting, writing, reading and closing connection to the server.
+ *
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+interface Zend_Http_Client_Adapter_Interface
+{
+    /**
+     * Set the configuration array for the adapter
+     *
+     * @param array $config
+     */
+    public function setConfig($config = array());
+
+    /**
+     * Connect to the remote server
+     *
+     * @param string  $host
+     * @param int     $port
+     * @param boolean $secure
+     */
+    public function connect($host, $port = 80, $secure = false);
+
+    /**
+     * Send request to the remote server
+     *
+     * @param string        $method
+     * @param Zend_Uri_Http $url
+     * @param string        $http_ver
+     * @param array         $headers
+     * @param string        $body
+     * @return string Request as text
+     */
+    public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '');
+
+    /**
+     * Read response from server
+     *
+     * @return string
+     */
+    public function read();
+
+    /**
+     * Close the connection to the server
+     *
+     */
+    public function close();
+}
diff --git a/lib/zend/Zend/Http/Client/Adapter/Proxy.php b/lib/zend/Zend/Http/Client/Adapter/Proxy.php
new file mode 100644 (file)
index 0000000..7ddbe5a
--- /dev/null
@@ -0,0 +1,269 @@
+<?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_Http
+ * @subpackage Client_Adapter
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Client.php';
+require_once 'Zend/Http/Client/Adapter/Socket.php';
+
+/**
+ * HTTP Proxy-supporting Zend_Http_Client adapter class, based on the default
+ * socket based adapter.
+ *
+ * Should be used if proxy HTTP access is required. If no proxy is set, will
+ * fall back to Zend_Http_Client_Adapter_Socket behavior. Just like the
+ * default Socket adapter, this adapter does not require any special extensions
+ * installed.
+ *
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket
+{
+    /**
+     * Parameters array
+     *
+     * @var array
+     */
+    protected $config = array(
+        'ssltransport'  => 'ssl',
+        'proxy_host'    => '',
+        'proxy_port'    => 8080,
+        'proxy_user'    => '',
+        'proxy_pass'    => '',
+        'proxy_auth'    => Zend_Http_Client::AUTH_BASIC,
+        'persistent'    => false
+    );
+
+    /**
+     * Whether HTTPS CONNECT was already negotiated with the proxy or not
+     *
+     * @var boolean
+     */
+    protected $negotiated = false;
+    
+    /**
+     * Connect to the remote server
+     *
+     * Will try to connect to the proxy server. If no proxy was set, will
+     * fall back to the target server (behave like regular Socket adapter)
+     *
+     * @param string  $host
+     * @param int     $port
+     * @param boolean $secure
+     * @param int     $timeout
+     */
+    public function connect($host, $port = 80, $secure = false)
+    {
+        // If no proxy is set, fall back to Socket adapter
+        if (! $this->config['proxy_host']) return parent::connect($host, $port, $secure);
+
+        // Go through a proxy - the connection is actually to the proxy server
+        $host = $this->config['proxy_host'];
+        $port = $this->config['proxy_port'];
+
+        // If we are connected to the wrong proxy, disconnect first
+        if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
+            if (is_resource($this->socket)) $this->close();
+        }
+
+        // Now, if we are not connected, connect
+        if (! is_resource($this->socket) || ! $this->config['keepalive']) {
+            $this->socket = @fsockopen($host, $port, $errno, $errstr, (int) $this->config['timeout']);
+            if (! $this->socket) {
+                $this->close();
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+                throw new Zend_Http_Client_Adapter_Exception(
+                    'Unable to Connect to proxy server ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
+            }
+
+            // Set the stream timeout
+            if (!stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+                throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
+            }
+
+            // Update connected_to
+            $this->connected_to = array($host, $port);
+        }
+    }
+
+    /**
+     * Send request to the proxy server
+     *
+     * @param string        $method
+     * @param Zend_Uri_Http $uri
+     * @param string        $http_ver
+     * @param array         $headers
+     * @param string        $body
+     * @return string Request as string
+     */
+    public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+    {
+        // If no proxy is set, fall back to default Socket adapter
+        if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
+
+        // Make sure we're properly connected
+        if (! $this->socket) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected");
+        }
+
+        $host = $this->config['proxy_host'];
+        $port = $this->config['proxy_port'];
+
+        if ($this->connected_to[0] != $host || $this->connected_to[1] != $port) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server");
+        }
+
+        // Add Proxy-Authorization header
+        if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) {
+            $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader(
+                $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
+            );
+        }
+                
+        // if we are proxying HTTPS, preform CONNECT handshake with the proxy
+        if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
+            $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
+            $this->negotiated = true;
+        }
+        
+        // Save request method for later
+        $this->method = $method;
+
+        // Build request headers
+        $request = "{$method} {$uri->__toString()} HTTP/{$http_ver}\r\n";
+
+        // Add all headers to the request string
+        foreach ($headers as $k => $v) {
+            if (is_string($k)) $v = "$k: $v";
+            $request .= "$v\r\n";
+        }
+
+        // Add the request body
+        $request .= "\r\n" . $body;
+
+        // Send the request
+        if (! @fwrite($this->socket, $request)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
+        }
+
+        return $request;
+    }
+
+    /**
+     * Preform handshaking with HTTPS proxy using CONNECT method
+     *
+     * @param string  $host
+     * @param integer $port
+     * @param string  $http_ver
+     * @param array   $headers
+     */
+    protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array())
+    {
+       $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . 
+                  "Host: " . $this->config['proxy_host'] . "\r\n";
+
+       // Add the user-agent header
+       if (isset($this->config['useragent'])) {
+               $request .= "User-agent: " . $this->config['useragent'] . "\r\n";
+       }
+       
+       // If the proxy-authorization header is set, send it to proxy but remove
+       // it from headers sent to target host
+       if (isset($headers['proxy-authorization'])) {
+           $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
+           unset($headers['proxy-authorization']);
+       }
+       
+        $request .= "\r\n";
+
+        // Send the request
+        if (! @fwrite($this->socket, $request)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
+        }
+
+        // Read response headers only
+        $response = '';
+        $gotStatus = false;
+        while ($line = @fgets($this->socket)) {
+            $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
+            if ($gotStatus) {
+                $response .= $line;
+                if (!chop($line)) break;
+            }
+        }
+        
+        // Check that the response from the proxy is 200
+        if (Zend_Http_Response::extractCode($response) != 200) {
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+               throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response);
+        }
+        
+        // If all is good, switch socket to secure mode. We have to fall back
+        // through the different modes 
+        $modes = array(
+            STREAM_CRYPTO_METHOD_TLS_CLIENT, 
+            STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+            STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+            STREAM_CRYPTO_METHOD_SSLv2_CLIENT 
+        );
+        
+        $success = false; 
+        foreach($modes as $mode) {
+            $success = stream_socket_enable_crypto($this->socket, true, $mode);
+               if ($success) break;
+        }
+        
+        if (! $success) {
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+                throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" . 
+                    " HTTPS server through proxy: could not negotiate secure connection.");
+        }
+    }
+    
+    /**
+     * Close the connection to the server
+     *
+     */
+    public function close()
+    {
+        parent::close();
+        $this->negotiated = false;
+    }
+    
+    /**
+     * Destructor: make sure the socket is disconnected
+     *
+     */
+    public function __destruct()
+    {
+        if ($this->socket) $this->close();
+    }
+}
diff --git a/lib/zend/Zend/Http/Client/Adapter/Socket.php b/lib/zend/Zend/Http/Client/Adapter/Socket.php
new file mode 100644 (file)
index 0000000..544fbeb
--- /dev/null
@@ -0,0 +1,337 @@
+<?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_Http
+ * @subpackage Client_Adapter
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+/**
+ * A sockets based (stream_socket_client) adapter class for Zend_Http_Client. Can be used
+ * on almost every PHP environment, and does not require any special extensions.
+ *
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client_Adapter_Socket implements Zend_Http_Client_Adapter_Interface
+{
+    /**
+     * The socket for server connection
+     *
+     * @var resource|null
+     */
+    protected $socket = null;
+
+    /**
+     * What host/port are we connected to?
+     *
+     * @var array
+     */
+    protected $connected_to = array(null, null);
+
+    /**
+     * Parameters array
+     *
+     * @var array
+     */
+    protected $config = array(
+        'persistent'    => false,
+        'ssltransport'  => 'ssl',
+        'sslcert'       => null,
+        'sslpassphrase' => null
+    );
+
+    /**
+     * Request method - will be set by write() and might be used by read()
+     *
+     * @var string
+     */
+    protected $method = null;
+
+    /**
+     * Adapter constructor, currently empty. Config is set using setConfig()
+     *
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Set the configuration array for the adapter
+     *
+     * @param array $config
+     */
+    public function setConfig($config = array())
+    {
+        if (! is_array($config)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception(
+                '$config expects an array, ' . gettype($config) . ' recieved.');
+        }
+
+        foreach ($config as $k => $v) {
+            $this->config[strtolower($k)] = $v;
+        }
+    }
+
+    /**
+     * Connect to the remote server
+     *
+     * @param string  $host
+     * @param int     $port
+     * @param boolean $secure
+     * @param int     $timeout
+     */
+    public function connect($host, $port = 80, $secure = false)
+    {
+        // If the URI should be accessed via SSL, prepend the Hostname with ssl://
+        $host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
+
+        // If we are connected to the wrong host, disconnect first
+        if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
+            if (is_resource($this->socket)) $this->close();
+        }
+
+        // Now, if we are not connected, connect
+        if (! is_resource($this->socket) || ! $this->config['keepalive']) {
+            $context = stream_context_create();
+            if ($secure) {
+                if ($this->config['sslcert'] !== null) {
+                    if (! stream_context_set_option($context, 'ssl', 'local_cert',
+                                                    $this->config['sslcert'])) {
+                        require_once 'Zend/Http/Client/Adapter/Exception.php';
+                        throw new Zend_Http_Client_Adapter_Exception('Unable to set sslcert option');
+                    }
+                }
+                if ($this->config['sslpassphrase'] !== null) {
+                    if (! stream_context_set_option($context, 'ssl', 'passphrase',
+                                                    $this->config['sslpassphrase'])) {
+                        require_once 'Zend/Http/Client/Adapter/Exception.php';
+                        throw new Zend_Http_Client_Adapter_Exception('Unable to set sslpassphrase option');
+                    }
+                }
+            }
+
+            $flags = STREAM_CLIENT_CONNECT;
+            if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT;
+            
+            $this->socket = @stream_socket_client($host . ':' . $port,
+                                                  $errno,
+                                                  $errstr,
+                                                  (int) $this->config['timeout'],
+                                                  $flags,
+                                                  $context);
+            if (! $this->socket) {
+                $this->close();
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+                throw new Zend_Http_Client_Adapter_Exception(
+                    'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
+            }
+
+            // Set the stream timeout
+            if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
+                require_once 'Zend/Http/Client/Adapter/Exception.php';
+                throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
+            }
+
+            // Update connected_to
+            $this->connected_to = array($host, $port);
+        }
+    }
+
+    /**
+     * Send request to the remote server
+     *
+     * @param string        $method
+     * @param Zend_Uri_Http $uri
+     * @param string        $http_ver
+     * @param array         $headers
+     * @param string        $body
+     * @return string Request as string
+     */
+    public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+    {
+        // Make sure we're properly connected
+        if (! $this->socket) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are not connected');
+        }
+
+        $host = $uri->getHost();
+        $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
+        if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are connected to the wrong host');
+        }
+
+        // Save request method for later
+        $this->method = $method;
+
+        // Build request headers
+        $path = $uri->getPath();
+        if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
+        $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
+        foreach ($headers as $k => $v) {
+            if (is_string($k)) $v = ucfirst($k) . ": $v";
+            $request .= "$v\r\n";
+        }
+
+        // Add the request body
+        $request .= "\r\n" . $body;
+
+        // Send the request
+        if (! @fwrite($this->socket, $request)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception('Error writing request to server');
+        }
+
+        return $request;
+    }
+
+    /**
+     * Read response from server
+     *
+     * @return string
+     */
+    public function read()
+    {
+        // First, read headers only
+        $response = '';
+        $gotStatus = false;
+        while (($line = @fgets($this->socket)) !== false) {
+            $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
+            if ($gotStatus) {
+                $response .= $line;
+                if (rtrim($line) === '') break;
+            }
+        }
+
+        $statusCode = Zend_Http_Response::extractCode($response);
+         
+        // Handle 100 and 101 responses internally by restarting the read again
+        if ($statusCode == 100 || $statusCode == 101) return $this->read();
+
+        /**
+         * Responses to HEAD requests and 204 or 304 responses are not expected
+         * to have a body - stop reading here
+         */
+        if ($statusCode == 304 || $statusCode == 204 || 
+            $this->method == Zend_Http_Client::HEAD) return $response;
+
+        // Check headers to see what kind of connection / transfer encoding we have
+        $headers = Zend_Http_Response::extractHeaders($response);
+
+        // If we got a 'transfer-encoding: chunked' header
+        if (isset($headers['transfer-encoding'])) {
+            if ($headers['transfer-encoding'] == 'chunked') {
+                do {
+                    $chunk = '';
+                    $line = @fgets($this->socket);
+                    $chunk .= $line;
+
+                    $hexchunksize = ltrim(chop($line), '0');
+                    $hexchunksize = strlen($hexchunksize) ? strtolower($hexchunksize) : 0;
+
+                    $chunksize = hexdec(chop($line));
+                    if (dechex($chunksize) != $hexchunksize) {
+                        @fclose($this->socket);
+                        require_once 'Zend/Http/Client/Adapter/Exception.php';
+                        throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' .
+                            $hexchunksize . '" unable to read chunked body');
+                    }
+
+                    $left_to_read = $chunksize;
+                    while ($left_to_read > 0) {
+                        $line = @fread($this->socket, $left_to_read);
+                        $chunk .= $line;
+                        $left_to_read -= strlen($line);
+                        
+                        // Break if the connection ended prematurely
+                        if (feof($this->socket)) break;
+                    }
+
+                    $chunk .= @fgets($this->socket);
+                    $response .= $chunk;
+                } while ($chunksize > 0);
+                
+            } else {
+                throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' .
+                    $headers['transfer-encoding'] . '" transfer encoding');
+            }
+            
+        // Else, if we got the content-length header, read this number of bytes
+        } elseif (isset($headers['content-length'])) {
+            $left_to_read = $headers['content-length'];
+            $chunk = '';
+            while ($left_to_read > 0) {
+                $chunk = @fread($this->socket, $left_to_read);
+                $left_to_read -= strlen($chunk);
+                $response .= $chunk;
+                
+                // Break if the connection ended prematurely
+                if (feof($this->socket)) break;
+            }
+                    
+        // Fallback: just read the response until EOF
+        } else {
+            while (($buff = @fread($this->socket, 8192)) !== false) {
+                $response .= $buff;
+                if (feof($this->socket)) break;
+            }
+
+            $this->close();
+        }
+        
+        // Close the connection if requested to do so by the server
+        if (isset($headers['connection']) && $headers['connection'] == 'close') {
+            $this->close();
+        }
+
+        return $response;
+    }
+
+    /**
+     * Close the connection to the server
+     *
+     */
+    public function close()
+    {
+        if (is_resource($this->socket)) @fclose($this->socket);
+        $this->socket = null;
+        $this->connected_to = array(null, null);
+    }
+
+    /**
+     * Destructor: make sure the socket is disconnected 
+     * 
+     * If we are in persistent TCP mode, will not close the connection
+     *
+     */
+    public function __destruct()
+    {
+        if (! $this->config['persistent']) {
+            if ($this->socket) $this->close();
+        }
+    }
+}
diff --git a/lib/zend/Zend/Http/Client/Adapter/Test.php b/lib/zend/Zend/Http/Client/Adapter/Test.php
new file mode 100644 (file)
index 0000000..aad25f2
--- /dev/null
@@ -0,0 +1,193 @@
+<?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_Http
+ * @subpackage Client_Adapter
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Response.php';
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+/**
+ * A testing-purposes adapter.
+ *
+ * Should be used to test all components that rely on Zend_Http_Client,
+ * without actually performing an HTTP request. You should instantiate this
+ * object manually, and then set it as the client's adapter. Then, you can
+ * set the expected response using the setResponse() method.
+ *
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client_Adapter_Test implements Zend_Http_Client_Adapter_Interface
+{
+    /**
+     * Parameters array
+     *
+     * @var array
+     */
+    protected $config = array();
+
+    /**
+     * Buffer of responses to be returned by the read() method.  Can be
+     * set using setResponse() and addResponse().
+     *
+     * @var array
+     */
+    protected $responses = array("HTTP/1.1 400 Bad Request\r\n\r\n");
+
+    /**
+     * Current position in the response buffer
+     *
+     * @var integer
+     */
+    protected $responseIndex = 0;
+
+    /**
+     * Adapter constructor, currently empty. Config is set using setConfig()
+     *
+     */
+    public function __construct()
+    { }
+
+    /**
+     * Set the configuration array for the adapter
+     *
+     * @param array $config
+     */
+    public function setConfig($config = array())
+    {
+        if (! is_array($config)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception(
+                '$config expects an array, ' . gettype($config) . ' recieved.');
+        }
+
+        foreach ($config as $k => $v) {
+            $this->config[strtolower($k)] = $v;
+        }
+    }
+
+    /**
+     * Connect to the remote server
+     *
+     * @param string  $host
+     * @param int     $port
+     * @param boolean $secure
+     * @param int     $timeout
+     */
+    public function connect($host, $port = 80, $secure = false)
+    { }
+
+    /**
+     * Send request to the remote server
+     *
+     * @param string        $method
+     * @param Zend_Uri_Http $uri
+     * @param string        $http_ver
+     * @param array         $headers
+     * @param string        $body
+     * @return string Request as string
+     */
+    public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+    {
+        $host = $uri->getHost();
+            $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host);
+
+        // Build request headers
+        $path = $uri->getPath();
+        if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
+        $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
+        foreach ($headers as $k => $v) {
+            if (is_string($k)) $v = ucfirst($k) . ": $v";
+            $request .= "$v\r\n";
+        }
+
+        // Add the request body
+        $request .= "\r\n" . $body;
+
+        // Do nothing - just return the request as string
+
+        return $request;
+    }
+
+    /**
+     * Return the response set in $this->setResponse()
+     *
+     * @return string
+     */
+    public function read()
+    {
+        if ($this->responseIndex >= count($this->responses)) {
+            $this->responseIndex = 0;
+        }
+        return $this->responses[$this->responseIndex++];
+    }
+
+    /**
+     * Close the connection (dummy)
+     *
+     */
+    public function close()
+    { }
+
+    /**
+     * Set the HTTP response(s) to be returned by this adapter
+     *
+     * @param Zend_Http_Response|array|string $response
+     */
+    public function setResponse($response)
+    {
+        if ($response instanceof Zend_Http_Response) {
+            $response = $response->asString();
+        }
+
+        $this->responses = (array)$response;
+        $this->responseIndex = 0;
+    }
+
+    /**
+     * Add another response to the response buffer.
+     *
+     * @param string $response
+     */
+    public function addResponse($response)
+    {
+        $this->responses[] = $response;
+    }
+
+    /**
+     * Sets the position of the response buffer.  Selects which
+     * response will be returned on the next call to read().
+     *
+     * @param integer $index
+     */
+    public function setResponseIndex($index)
+    {
+        if ($index < 0 || $index >= count($this->responses)) {
+            require_once 'Zend/Http/Client/Adapter/Exception.php';
+            throw new Zend_Http_Client_Adapter_Exception(
+                'Index out of range of response buffer size');
+        }
+        $this->responseIndex = $index;
+    }
+}
diff --git a/lib/zend/Zend/Http/Client/Exception.php b/lib/zend/Zend/Http/Client/Exception.php
new file mode 100644 (file)
index 0000000..3573057
--- /dev/null
@@ -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_Http
+ * @subpackage Client_Exception
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Http/Exception.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Client_Exception extends Zend_Http_Exception
+{}
diff --git a/lib/zend/Zend/Http/Exception.php b/lib/zend/Zend/Http/Exception.php
new file mode 100644 (file)
index 0000000..585ae85
--- /dev/null
@@ -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_Http
+ * @subpackage Exception
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Exception.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Http
+ * @subpackage Client
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Exception extends Zend_Exception
+{}
diff --git a/lib/zend/Zend/Http/Response.php b/lib/zend/Zend/Http/Response.php
new file mode 100644 (file)
index 0000000..17c0261
--- /dev/null
@@ -0,0 +1,625 @@
+<?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_Http
+ * @subpackage Response
+ * @version    $Id$
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Http_Response represents an HTTP 1.0 / 1.1 response message. It
+ * includes easy access to all the response's different elemts, as well as some
+ * convenience methods for parsing and validating HTTP responses.
+ *
+ * @package    Zend_Http
+ * @subpackage Response
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Http_Response
+{
+    /**
+     * List of all known HTTP response codes - used by responseCodeAsText() to
+     * translate numeric codes to messages.
+     *
+     * @var array
+     */
+    protected static $messages = array(
+        // Informational 1xx
+        100 => 'Continue',
+        101 => 'Switching Protocols',
+
+        // Success 2xx
+        200 => 'OK',
+        201 => 'Created',
+        202 => 'Accepted',
+        203 => 'Non-Authoritative Information',
+        204 => 'No Content',
+        205 => 'Reset Content',
+        206 => 'Partial Content',
+
+        // Redirection 3xx
+        300 => 'Multiple Choices',
+        301 => 'Moved Permanently',
+        302 => 'Found',  // 1.1
+        303 => 'See Other',
+        304 => 'Not Modified',
+        305 => 'Use Proxy',
+        // 306 is deprecated but reserved
+        307 => 'Temporary Redirect',
+
+        // Client Error 4xx
+        400 => 'Bad Request',
+        401 => 'Unauthorized',
+        402 => 'Payment Required',
+        403 => 'Forbidden',
+        404 => 'Not Found',
+        405 => 'Method Not Allowed',
+        406 => 'Not Acceptable',
+        407 => 'Proxy Authentication Required',
+        408 => 'Request Timeout',
+        409 => 'Conflict',
+        410 => 'Gone',
+        411 => 'Length Required',
+        412 => 'Precondition Failed',
+        413 => 'Request Entity Too Large',
+        414 => 'Request-URI Too Long',
+        415 => 'Unsupported Media Type',
+        416 => 'Requested Range Not Satisfiable',
+        417 => 'Expectation Failed',
+
+        // Server Error 5xx
+        500 => 'Internal Server Error',
+        501 => 'Not Implemented',
+        502 => 'Bad Gateway',
+        503 => 'Service Unavailable',
+        504 => 'Gateway Timeout',
+        505 => 'HTTP Version Not Supported',
+        509 => 'Bandwidth Limit Exceeded'
+    );
+
+    /**
+     * The HTTP version (1.0, 1.1)
+     *
+     * @var string
+     */
+    protected $version;
+
+    /**
+     * The HTTP response code
+     *
+     * @var int
+     */
+    protected $code;
+
+    /**
+     * The HTTP response code as string
+     * (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500)
+     *
+     * @var string
+     */
+    protected $message;
+
+    /**
+     * The HTTP response headers array
+     *
+     * @var array
+     */
+    protected $headers = array();
+
+    /**
+     * The HTTP response body
+     *
+     * @var string
+     */
+    protected $body;
+
+    /**
+     * HTTP response constructor
+     *
+     * In most cases, you would use Zend_Http_Response::fromString to parse an HTTP
+     * response string and create a new Zend_Http_Response object.
+     *
+     * NOTE: The constructor no longer accepts nulls or empty values for the code and
+     * headers and will throw an exception if the passed values do not form a valid HTTP
+     * responses.
+     *
+     * If no message is passed, the message will be guessed according to the response code.
+     *
+     * @param int $code Response code (200, 404, ...)
+     * @param array $headers Headers array
+     * @param string $body Response body
+     * @param string $version HTTP version
+     * @param string $message Response code as text
+     * @throws Zend_Http_Exception
+     */
+    public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
+    {
+        // Make sure the response code is valid and set it
+        if (self::responseCodeAsText($code) === null) {
+            require_once 'Zend/Http/Exception.php';
+            throw new Zend_Http_Exception("{$code} is not a valid HTTP response code");
+        }
+
+        $this->code = $code;
+
+        // Make sure we got valid headers and set them
+        if (! is_array($headers)) {
+            require_once 'Zend/Http/Exception.php';
+            throw new Zend_Http_Exception('No valid headers were passed');
+       }
+
+        foreach ($headers as $name => $value) {
+            if (is_int($name))
+                list($name, $value) = explode(": ", $value, 1);
+
+            $this->headers[ucwords(strtolower($name))] = $value;
+        }
+
+        // Set the body
+        $this->body = $body;
+
+        // Set the HTTP version
+        if (! preg_match('|^\d\.\d$|', $version)) {
+            require_once 'Zend/Http/Exception.php';
+            throw new Zend_Http_Exception("Invalid HTTP response version: $version");
+        }
+
+        $this->version = $version;
+
+        // If we got the response message, set it. Else, set it according to
+        // the response code
+        if (is_string($message)) {
+            $this->message = $message;
+        } else {
+            $this->message = self::responseCodeAsText($code);
+        }
+    }
+
+    /**
+     * Check whether the response is an error
+     *
+     * @return boolean
+     */
+    public function isError()
+    {
+        $restype = floor($this->code / 100);
+        if ($restype == 4 || $restype == 5) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check whether the response in successful
+     *
+     * @return boolean
+     */
+    public function isSuccessful()
+    {
+        $restype = floor($this->code / 100);
+        if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ???
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check whether the response is a redirection
+     *
+     * @return boolean
+     */
+    public function isRedirect()
+    {
+        $restype = floor($this->code / 100);
+        if ($restype == 3) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the response body as string
+     *
+     * This method returns the body of the HTTP response (the content), as it
+     * should be in it's readable version - that is, after decoding it (if it
+     * was decoded), deflating it (if it was gzip compressed), etc.
+     *
+     * If you want to get the raw body (as transfered on wire) use
+     * $this->getRawBody() instead.
+     *
+     * @return string
+     */
+    public function getBody()
+    {
+        $body = '';
+
+        // Decode the body if it was transfer-encoded
+        switch ($this->getHeader('transfer-encoding')) {
+
+            // Handle chunked body
+            case 'chunked':
+                $body = self::decodeChunkedBody($this->body);
+                break;
+
+            // No transfer encoding, or unknown encoding extension:
+            // return body as is
+            default:
+                $body = $this->body;
+                break;
+        }
+
+        // Decode any content-encoding (gzip or deflate) if needed
+        switch (strtolower($this->getHeader('content-encoding'))) {
+
+            // Handle gzip encoding
+            case 'gzip':
+                $body = self::decodeGzip($body);
+                break;
+
+            // Handle deflate encoding
+            case 'deflate':
+                $body = self::decodeDeflate($body);
+                break;
+
+            default:
+                break;
+        }
+
+        return $body;
+    }
+
+    /**
+     * Get the raw response body (as transfered "on wire") as string
+     *
+     * If the body is encoded (with Transfer-Encoding, not content-encoding -
+     * IE "chunked" body), gzip compressed, etc. it will not be decoded.
+     *
+     * @return string
+     */
+    public function getRawBody()
+    {
+        return $this->body;
+    }
+
+    /**
+     * Get the HTTP version of the response
+     *
+     * @return string
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * Get the HTTP response status code
+     *
+     * @return int
+     */
+    public function getStatus()
+    {
+        return $this->code;
+    }
+
+    /**
+     * Return a message describing the HTTP response code
+     * (Eg. "OK", "Not Found", "Moved Permanently")
+     *
+     * @return string
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * Get the response headers
+     *
+     * @return array
+     */
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+
+    /**
+     * Get a specific header as string, or null if it is not set
+     *
+     * @param string$header
+     * @return string|array|null
+     */
+    public function getHeader($header)
+    {
+        $header = ucwords(strtolower($header));
+        if (! is_string($header) || ! isset($this->headers[$header])) return null;
+
+        return $this->headers[$header];
+    }
+
+    /**
+     * Get all headers as string
+     *
+     * @param boolean $status_line Whether to return the first status line (IE "HTTP 200 OK")
+     * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+     * @return string
+     */
+    public function getHeadersAsString($status_line = true, $br = "\n")
+    {
+        $str = '';
+
+        if ($status_line) {
+            $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}";
+        }
+
+        // Iterate over the headers and stringify them
+        foreach ($this->headers as $name => $value)
+        {
+            if (is_string($value))
+                $str .= "{$name}: {$value}{$br}";
+
+            elseif (is_array($value)) {
+                foreach ($value as $subval) {
+                    $str .= "{$name}: {$subval}{$br}";
+                }
+            }
+        }
+
+        return $str;
+    }
+
+    /**
+     * Get the entire response as string
+     *
+     * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+     * @return string
+     */
+    public function asString($br = "\n")
+    {
+        return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody();
+    }
+
+    /**
+     * A convenience function that returns a text representation of
+     * HTTP response codes. Returns 'Unknown' for unknown codes.
+     * Returns array of all codes, if $code is not specified.
+     *
+     * Conforms to HTTP/1.1 as defined in RFC 2616 (except for 'Unknown')
+     * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 for reference
+     *
+     * @param int $code HTTP response code
+     * @param boolean $http11 Use HTTP version 1.1
+     * @return string
+     */
+    public static function responseCodeAsText($code = null, $http11 = true)
+    {
+        $messages = self::$messages;
+        if (! $http11) $messages[302] = 'Moved Temporarily';
+
+        if ($code === null) {
+            return $messages;
+        } elseif (isset($messages[$code])) {
+            return $messages[$code];
+        } else {
+            return 'Unknown';
+        }
+    }
+
+    /**
+     * Extract the response code from a response string
+     *
+     * @param string $response_str
+     * @return int
+     */
+    public static function extractCode($response_str)
+    {
+        preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
+
+        if (isset($m[1])) {
+            return (int) $m[1];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Extract the HTTP message from a response
+     *
+     * @param string $response_str
+     * @return string
+     */
+    public static function extractMessage($response_str)
+    {
+        preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
+
+        if (isset($m[1])) {
+            return $m[1];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Extract the HTTP version from a response
+     *
+     * @param string $response_str
+     * @return string
+     */
+    public static function extractVersion($response_str)
+    {
+        preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
+
+        if (isset($m[1])) {
+            return $m[1];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Extract the headers from a response string
+     *
+     * @param string $response_str
+     * @return array
+     */
+    public static function extractHeaders($response_str)
+    {
+        $headers = array();
+        
+        // First, split body and headers
+        $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
+        if (! $parts[0]) return $headers;
+        
+        // Split headers part to lines
+        $lines = explode("\n", $parts[0]);
+        unset($parts);
+        $last_header = null;
+
+        foreach($lines as $line) {
+            $line = trim($line, "\r\n");
+            if ($line == "") break;
+
+            if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) {
+                unset($last_header);
+                $h_name = strtolower($m[1]);
+                $h_value = $m[2];
+
+                if (isset($headers[$h_name])) {
+                    if (! is_array($headers[$h_name])) {
+                        $headers[$h_name] = array($headers[$h_name]);
+                    }
+
+                    $headers[$h_name][] = $h_value;
+                } else {
+                    $headers[$h_name] = $h_value;
+                }
+                $last_header = $h_name;
+            } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
+                if (is_array($headers[$last_header])) {
+                    end($headers[$last_header]);
+                    $last_header_key = key($headers[$last_header]);
+                    $headers[$last_header][$last_header_key] .= $m[1];
+                } else {
+                    $headers[$last_header] .= $m[1];
+                }
+            }
+        }
+
+        return $headers;
+    }
+
+    /**
+     * Extract the body from a response string
+     *
+     * @param string $response_str
+     * @return string
+     */
+    public static function extractBody($response_str)
+    {
+        $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
+        if (isset($parts[1])) { 
+               return $parts[1];
+        } else {
+               return '';
+        }
+    }
+
+    /**
+     * Decode a "chunked" transfer-encoded body and return the decoded text
+     *
+     * @param string $body
+     * @return string
+     */
+    public static function decodeChunkedBody($body)
+    {
+        $decBody = '';
+        
+        while (trim($body)) {
+            if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
+                require_once 'Zend/Http/Exception.php';
+                throw new Zend_Http_Exception("Error parsing body - doesn't seem to be a chunked message");
+            }
+
+            $length = hexdec(trim($m[1]));
+            $cut = strlen($m[0]);
+
+            $decBody .= substr($body, $cut, $length);
+            $body = substr($body, $cut + $length + 2);
+        }
+
+        return $decBody;
+    }
+
+    /**
+     * Decode a gzip encoded message (when Content-encoding = gzip)
+     *
+     * Currently requires PHP with zlib support
+     *
+     * @param string $body
+     * @return string
+     */
+    public static function decodeGzip($body)
+    {
+        if (! function_exists('gzinflate')) {
+            require_once 'Zend/Http/Exception.php';
+            throw new Zend_Http_Exception('Unable to decode gzipped response ' . 
+                'body: perhaps the zlib extension is not loaded?'); 
+        }
+
+        return gzinflate(substr($body, 10));
+    }
+
+    /**
+     * Decode a zlib deflated message (when Content-encoding = deflate)
+     *
+     * Currently requires PHP with zlib support
+     *
+     * @param string $body
+     * @return string
+     */
+    public static function decodeDeflate($body)
+    {
+        if (! function_exists('gzuncompress')) {
+            require_once 'Zend/Http/Exception.php';
+            throw new Zend_Http_Exception('Unable to decode deflated response ' . 
+                'body: perhaps the zlib extension is not loaded?'); 
+        }
+
+       return gzuncompress($body);
+    }
+
+    /**
+     * Create a new Zend_Http_Response object from a string
+     *
+     * @param string $response_str
+     * @return Zend_Http_Response
+     */
+    public static function fromString($response_str)
+    {
+        $code    = self::extractCode($response_str);
+        $headers = self::extractHeaders($response_str);
+        $body    = self::extractBody($response_str);
+        $version = self::extractVersion($response_str);
+        $message = self::extractMessage($response_str);
+
+        return new Zend_Http_Response($code, $headers, $body, $version, $message);
+    }
+}
diff --git a/lib/zend/Zend/Loader.php b/lib/zend/Zend/Loader.php
new file mode 100644 (file)
index 0000000..9e70813
--- /dev/null
@@ -0,0 +1,258 @@
+<?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_Loader
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Static methods for loading classes and files.
+ *
+ * @category   Zend
+ * @package    Zend_Loader
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Loader
+{
+    /**
+     * Loads a class from a PHP file.  The filename must be formatted
+     * as "$class.php".
+     *
+     * If $dirs is a string or an array, it will search the directories
+     * in the order supplied, and attempt to load the first matching file.
+     *
+     * If $dirs is null, it will split the class name at underscores to
+     * generate a path hierarchy (e.g., "Zend_Example_Class" will map
+     * to "Zend/Example/Class.php").
+     *
+     * If the file was not found in the $dirs, or if no $dirs were specified,
+     * it will attempt to load it from PHP's include_path.
+     *
+     * @param string $class      - The full class name of a Zend component.
+     * @param string|array $dirs - OPTIONAL Either a path or an array of paths
+     *                             to search.
+     * @return void
+     * @throws Zend_Exception
+     */
+    public static function loadClass($class, $dirs = null)
+    {
+        if (class_exists($class, false) || interface_exists($class, false)) {
+            return;
+        }
+
+        if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Directory argument must be a string or an array');
+        }
+
+        // autodiscover the path from the class name
+        $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
+        if (!empty($dirs)) {
+            // use the autodiscovered path
+            $dirPath = dirname($file);
+            if (is_string($dirs)) {
+                $dirs = explode(PATH_SEPARATOR, $dirs);
+            }
+            foreach ($dirs as $key => $dir) {
+                if ($dir == '.') {
+                    $dirs[$key] = $dirPath;
+                } else {
+                    $dir = rtrim($dir, '\\/');
+                    $dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;
+                }
+            }
+            $file = basename($file);
+            self::loadFile($file, $dirs, true);
+        } else {
+            self::_securityCheck($file);
+            include_once $file;
+        }
+
+        if (!class_exists($class, false) && !interface_exists($class, false)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file");
+        }
+    }
+
+    /**
+     * Loads a PHP file.  This is a wrapper for PHP's include() function.
+     *
+     * $filename must be the complete filename, including any
+     * extension such as ".php".  Note that a security check is performed that
+     * does not permit extended characters in the filename.  This method is
+     * intended for loading Zend Framework files.
+     *
+     * If $dirs is a string or an array, it will search the directories
+     * in the order supplied, and attempt to load the first matching file.
+     *
+     * If the file was not found in the $dirs, or if no $dirs were specified,
+     * it will attempt to load it from PHP's include_path.
+     *
+     * If $once is TRUE, it will use include_once() instead of include().
+     *
+     * @param  string        $filename
+     * @param  string|array  $dirs - OPTIONAL either a path or array of paths
+     *                       to search.
+     * @param  boolean       $once
+     * @return boolean
+     * @throws Zend_Exception
+     */
+    public static function loadFile($filename, $dirs = null, $once = false)
+    {
+        self::_securityCheck($filename);
+
+        /**
+         * Search in provided directories, as well as include_path
+         */
+        $incPath = false;
+        if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
+            if (is_array($dirs)) {
+                $dirs = implode(PATH_SEPARATOR, $dirs);
+            }
+            $incPath = get_include_path();
+            set_include_path($dirs . PATH_SEPARATOR . $incPath);
+        }
+
+        /**
+         * Try finding for the plain filename in the include_path.
+         */
+        if ($once) {
+            include_once $filename;
+        } else {
+            include $filename;
+        }
+
+        /**
+         * If searching in directories, reset include_path
+         */
+        if ($incPath) {
+            set_include_path($incPath);
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns TRUE if the $filename is readable, or FALSE otherwise.
+     * This function uses the PHP include_path, where PHP's is_readable()
+     * does not.
+     *
+     * @param string   $filename
+     * @return boolean
+     */
+    public static function isReadable($filename)
+    {
+        if (!$fh = @fopen($filename, 'r', true)) {
+            return false;
+        }
+        @fclose($fh);
+        return true;
+    }
+
+    /**
+     * spl_autoload() suitable implementation for supporting class autoloading.
+     *
+     * Attach to spl_autoload() using the following:
+     * <code>
+     * spl_autoload_register(array('Zend_Loader', 'autoload'));
+     * </code>
+     *
+     * @param string $class
+     * @return string|false Class name on success; false on failure
+     */
+    public static function autoload($class)
+    {
+        try {
+            self::loadClass($class);
+            return $class;
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+
+    /**
+     * Register {@link autoload()} with spl_autoload()
+     *
+     * @param string $class (optional)
+     * @param boolean $enabled (optional)
+     * @return void
+     * @throws Zend_Exception if spl_autoload() is not found
+     * or if the specified class does not have an autoload() method.
+     */
+    public static function registerAutoload($class = 'Zend_Loader', $enabled = true)
+    {
+        if (!function_exists('spl_autoload_register')) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('spl_autoload does not exist in this PHP installation');
+        }
+
+        self::loadClass($class);
+        $methods = get_class_methods($class);
+        if (!in_array('autoload', (array) $methods)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception("The class \"$class\" does not have an autoload() method");
+        }
+
+        if ($enabled === true) {
+            spl_autoload_register(array($class, 'autoload'));
+        } else {
+            spl_autoload_unregister(array($class, 'autoload'));
+        }
+    }
+
+    /**
+     * Ensure that filename does not contain exploits
+     *
+     * @param  string $filename
+     * @return void
+     * @throws Zend_Exception
+     */
+    protected static function _securityCheck($filename)
+    {
+        /**
+         * Security check
+         */
+        if (preg_match('/[^a-z0-9\\/\\\\_.-]/i', $filename)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Security check: Illegal character in filename');
+        }
+    }
+
+    /**
+     * Attempt to include() the file.
+     *
+     * include() is not prefixed with the @ operator because if
+     * the file is loaded and contains a parse error, execution
+     * will halt silently and this is difficult to debug.
+     *
+     * Always set display_errors = Off on production servers!
+     *
+     * @param  string  $filespec
+     * @param  boolean $once
+     * @return boolean
+     * @deprecated Since 1.5.0; use loadFile() instead
+     */
+    protected static function _includeFile($filespec, $once = false)
+    {
+        if ($once) {
+            return include_once $filespec;
+        } else {
+            return include $filespec ;
+        }
+    }
+}
diff --git a/lib/zend/Zend/Mime.php b/lib/zend/Zend/Mime.php
new file mode 100644 (file)
index 0000000..499ff21
--- /dev/null
@@ -0,0 +1,252 @@
+<?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_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Support class for MultiPart Mime Messages
+ *
+ * @category   Zend
+ * @package    Zend_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mime
+{
+    const TYPE_OCTETSTREAM = 'application/octet-stream';
+    const TYPE_TEXT = 'text/plain';
+    const TYPE_HTML = 'text/html';
+    const ENCODING_7BIT = '7bit';
+    const ENCODING_8BIT = '8bit';
+    const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
+    const ENCODING_BASE64 = 'base64';
+    const DISPOSITION_ATTACHMENT = 'attachment';
+    const DISPOSITION_INLINE = 'inline';
+    const LINELENGTH = 74;
+    const LINEEND = "\n";
+    const MULTIPART_ALTERNATIVE = 'multipart/alternative';
+    const MULTIPART_MIXED = 'multipart/mixed';
+    const MULTIPART_RELATED = 'multipart/related';
+
+    protected $_boundary;
+    protected static $makeUnique = 0;
+
+    // lookup-Tables for QuotedPrintable
+    public static $qpKeys = array(
+        "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07",
+        "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F",
+        "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17",
+        "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
+        "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86",
+        "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E",
+        "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96",
+        "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E",
+        "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6",
+        "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE",
+        "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6",
+        "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE",
+        "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6",
+        "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE",
+        "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6",
+        "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE",
+        "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6",
+        "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE",
+        "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6",
+        "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE",
+        "\xFF"
+        );
+
+    public static $qpReplaceValues = array(
+        "=00","=01","=02","=03","=04","=05","=06","=07",
+        "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F",
+        "=10","=11","=12","=13","=14","=15","=16","=17",
+        "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F",
+        "=7F","=80","=81","=82","=83","=84","=85","=86",
+        "=87","=88","=89","=8A","=8B","=8C","=8D","=8E",
+        "=8F","=90","=91","=92","=93","=94","=95","=96",
+        "=97","=98","=99","=9A","=9B","=9C","=9D","=9E",
+        "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6",
+        "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE",
+        "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6",
+        "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE",
+        "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6",
+        "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE",
+        "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6",
+        "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE",
+        "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6",
+        "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE",
+        "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6",
+        "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE",
+        "=FF"
+        );
+
+    public static $qpKeysString =
+         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
+
+    /**
+     * Check if the given string is "printable"
+     *
+     * Checks that a string contains no unprintable characters. If this returns
+     * false, encode the string for secure delivery.
+     *
+     * @param string $str
+     * @return boolean
+     */
+    public static function isPrintable($str)
+    {
+        return (strcspn($str, self::$qpKeysString) == strlen($str));
+    }
+
+    /**
+     * Encode a given string with the QUOTED_PRINTABLE mechanism
+     *
+     * @param string $str
+     * @param int $lineLength Defaults to {@link LINELENGTH}
+     * @param int $lineEnd Defaults to {@link LINEEND}
+     * @return string
+     */
+    public static function encodeQuotedPrintable($str,
+        $lineLength = self::LINELENGTH,
+        $lineEnd = self::LINEEND)
+    {
+        $out = '';
+        $str = str_replace('=', '=3D', $str);
+        $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
+        $str = rtrim($str);
+
+        // Split encoded text into separate lines
+        while ($str) {
+            $ptr = strlen($str);
+            if ($ptr > $lineLength) {
+                $ptr = $lineLength;
+            }
+
+            // Ensure we are not splitting across an encoded character
+            $pos = strrpos(substr($str, 0, $ptr), '=');
+            if ($pos !== false && $pos >= $ptr - 2) {
+                $ptr = $pos;
+            }
+
+            // Check if there is a space at the end of the line and rewind
+            if ($ptr > 0 && $str[$ptr - 1] == ' ') {
+                --$ptr;
+            }
+
+            // Add string and continue
+            $out .= substr($str, 0, $ptr) . '=' . $lineEnd;
+            $str = substr($str, $ptr);
+        }
+
+        $out = rtrim($out, $lineEnd);
+        $out = rtrim($out, '=');
+        return $out;
+    }
+
+    /**
+     * Encode a given string in base64 encoding and break lines
+     * according to the maximum linelength.
+     *
+     * @param string $str
+     * @param int $lineLength Defaults to {@link LINELENGTH}
+     * @param int $lineEnd Defaults to {@link LINEEND}
+     * @return string
+     */
+    public static function encodeBase64($str,
+        $lineLength = self::LINELENGTH,
+        $lineEnd = self::LINEEND)
+    {
+        return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param null|string $boundary
+     * @access public
+     * @return void
+     */
+    public function __construct($boundary = null)
+    {
+        // This string needs to be somewhat unique
+        if ($boundary === null) {
+            $this->_boundary = '=_' . md5(microtime(1) . self::$makeUnique++);
+        } else {
+            $this->_boundary = $boundary;
+        }
+    }
+
+    /**
+     * Encode the given string with the given encoding.
+     *
+     * @param string $str
+     * @param string $encoding
+     * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+     * @return string
+     */
+    public static function encode($str, $encoding, $EOL = self::LINEEND)
+    {
+        switch ($encoding) {
+            case self::ENCODING_BASE64:
+                return self::encodeBase64($str, self::LINELENGTH, $EOL);
+
+            case self::ENCODING_QUOTEDPRINTABLE:
+                return self::encodeQuotedPrintable($str, self::LINELENGTH, $EOL);
+
+            default:
+                /**
+                 * @todo 7Bit and 8Bit is currently handled the same way.
+                 */
+                return $str;
+        }
+    }
+
+    /**
+     * Return a MIME boundary
+     *
+     * @access public
+     * @return string
+     */
+    public function boundary()
+    {
+        return $this->_boundary;
+    }
+
+    /**
+     * Return a MIME boundary line
+     *
+     * @param mixed $EOL Defaults to {@link LINEEND}
+     * @access public
+     * @return string
+     */
+    public function boundaryLine($EOL = self::LINEEND)
+    {
+        return $EOL . '--' . $this->_boundary . $EOL;
+    }
+
+    /**
+     * Return MIME ending
+     *
+     * @access public
+     * @return string
+     */
+    public function mimeEnd($EOL = self::LINEEND)
+    {
+        return $EOL . '--' . $this->_boundary . '--' . $EOL;
+    }
+}
diff --git a/lib/zend/Zend/Mime/Decode.php b/lib/zend/Zend/Mime/Decode.php
new file mode 100644 (file)
index 0000000..0d0dda8
--- /dev/null
@@ -0,0 +1,243 @@
+<?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_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Mime
+ */
+require_once 'Zend/Mime.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mime_Decode
+{
+    /**
+     * Explode MIME multipart string into seperate parts
+     *
+     * Parts consist of the header and the body of each MIME part.
+     *
+     * @param  string $body     raw body of message
+     * @param  string $boundary boundary as found in content-type
+     * @return array parts with content of each part, empty if no parts found
+     * @throws Zend_Exception
+     */
+    public static function splitMime($body, $boundary)
+    {
+        // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
+        $body = str_replace("\r", '', $body);
+
+        $start = 0;
+        $res = array();
+        // find every mime part limiter and cut out the
+        // string before it.
+        // the part before the first boundary string is discarded:
+        $p = strpos($body, '--' . $boundary . "\n", $start);
+        if ($p === false) {
+            // no parts found!
+            return array();
+        }
+
+        // position after first boundary line
+        $start = $p + 3 + strlen($boundary);
+
+        while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
+            $res[] = substr($body, $start, $p-$start);
+            $start = $p + 3 + strlen($boundary);
+        }
+
+        // no more parts, find end boundary
+        $p = strpos($body, '--' . $boundary . '--', $start);
+        if ($p===false) {
+            throw new Zend_Exception('Not a valid Mime Message: End Missing');
+        }
+
+        // the remaining part also needs to be parsed:
+        $res[] = substr($body, $start, $p-$start);
+        return $res;
+    }
+
+    /**
+     * decodes a mime encoded String and returns a
+     * struct of parts with header and body
+     *
+     * @param  string $message  raw message content
+     * @param  string $boundary boundary as found in content-type
+     * @param  string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+     * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found
+     * @throws Zend_Exception
+     */
+    public static function splitMessageStruct($message, $boundary, $EOL = Zend_Mime::LINEEND)
+    {
+        $parts = self::splitMime($message, $boundary);
+        if (count($parts) <= 0) {
+            return null;
+        }
+        $result = array();
+        foreach ($parts as $part) {
+            self::splitMessage($part, $headers, $body, $EOL);
+            $result[] = array('header' => $headers,
+                              'body'   => $body    );
+        }
+        return $result;
+    }
+
+    /**
+     * split a message in header and body part, if no header or an
+     * invalid header is found $headers is empty
+     *
+     * The charset of the returned headers depend on your iconv settings.
+     *
+     * @param  string $message raw message with header and optional content
+     * @param  array  $headers output param, array with headers as array(name => value)
+     * @param  string $body    output param, content of message
+     * @param  string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+     * @return null
+     */
+    public static function splitMessage($message, &$headers, &$body, $EOL = Zend_Mime::LINEEND)
+    {
+        // check for valid header at first line
+        $firstline = strtok($message, "\n");
+        if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
+            $headers = array();
+            // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
+            $body = str_replace(array("\r", "\n"), array('', $EOL), $message);
+            return;
+        }
+
+        // find an empty line between headers and body
+        // default is set new line
+        if (strpos($message, $EOL . $EOL)) {
+            list($headers, $body) = explode($EOL . $EOL, $message, 2);
+        // next is the standard new line
+        } else if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
+            list($headers, $body) = explode("\r\n\r\n", $message, 2);
+        // next is the other "standard" new line
+        } else if ($EOL != "\n" && strpos($message, "\n\n")) {
+            list($headers, $body) = explode("\n\n", $message, 2);
+        // at last resort find anything that looks like a new line
+        } else {
+            @list($headers, $body) = @preg_split("%([\r\n]+)\\1%U", $message, 2);
+        }
+
+        $headers = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
+
+        if ($headers === false ) {
+               // an error occurs during the decoding
+               return;
+        }
+
+        // normalize header names
+        foreach ($headers as $name => $header) {
+            $lower = strtolower($name);
+            if ($lower == $name) {
+                continue;
+            }
+            unset($headers[$name]);
+            if (!isset($headers[$lower])) {
+                $headers[$lower] = $header;
+                continue;
+            }
+            if (is_array($headers[$lower])) {
+                $headers[$lower][] = $header;
+                continue;
+            }
+            $headers[$lower] = array($headers[$lower], $header);
+        }
+    }
+
+    /**
+     * split a content type in its different parts
+     *
+     * @param  string $type       content-type
+     * @param  string $wantedPart the wanted part, else an array with all parts is returned
+     * @return string|array wanted part or all parts as array('type' => content-type, partname => value)
+     */
+    public static function splitContentType($type, $wantedPart = null)
+    {
+        return self::splitHeaderField($type, $wantedPart, 'type');
+    }
+
+    /**
+     * split a header field like content type in its different parts
+     *
+     * @param  string $type       header field
+     * @param  string $wantedPart the wanted part, else an array with all parts is returned
+     * @param  string $firstName  key name for the first part
+     * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
+     * @throws Zend_Exception
+     */
+    public static function splitHeaderField($field, $wantedPart = null, $firstName = 0)
+    {
+       $wantedPart = strtolower($wantedPart);
+       $firstName = strtolower($firstName);
+
+        // special case - a bit optimized
+        if ($firstName === $wantedPart) {
+            $field = strtok($field, ';');
+            return $field[0] == '"' ? substr($field, 1, -1) : $field;
+        }
+
+        $field = $firstName . '=' . $field;
+        if (!preg_match_all('%([^=\s]+)\s*=("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
+            throw new Zend_Exception('not a valid header field');
+        }
+
+        if ($wantedPart) {
+            foreach ($matches[1] as $key => $name) {
+                if (strcasecmp($name, $wantedPart)) {
+                    continue;
+                }
+                if ($matches[2][$key][0] != '"') {
+                    return $matches[2][$key];
+                }
+                return substr($matches[2][$key], 1, -1);
+            }
+            return null;
+        }
+
+        $split = array();
+        foreach ($matches[1] as $key => $name) {
+               $name = strtolower($name);
+            if ($matches[2][$key][0] == '"') {
+                $split[$name] = substr($matches[2][$key], 1, -1);
+            } else {
+                $split[$name] = $matches[2][$key];
+            }
+        }
+
+        return $split;
+    }
+
+    /**
+     * decode a quoted printable encoded string
+     *
+     * The charset of the returned string depends on your iconv settings.
+     *
+     * @param  string encoded string
+     * @return string decoded string
+     */
+    public static function decodeQuotedPrintable($string)
+    {
+        return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
+    }
+}
diff --git a/lib/zend/Zend/Mime/Exception.php b/lib/zend/Zend/Mime/Exception.php
new file mode 100644 (file)
index 0000000..2c22e9b
--- /dev/null
@@ -0,0 +1,36 @@
+<?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_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mime_Exception extends Zend_Exception
+{}
+
diff --git a/lib/zend/Zend/Mime/Message.php b/lib/zend/Zend/Mime/Message.php
new file mode 100644 (file)
index 0000000..febde66
--- /dev/null
@@ -0,0 +1,286 @@
+<?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_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+
+/**
+ * Zend_Mime
+ */
+require_once 'Zend/Mime.php';
+
+/**
+ * Zend_Mime_Part
+ */
+require_once 'Zend/Mime/Part.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mime_Message
+{
+
+    protected $_parts = array();
+    protected $_mime = null;
+
+    /**
+     * Returns the list of all Zend_Mime_Parts in the message
+     *
+     * @return array of Zend_Mime_Part
+     */
+    public function getParts()
+    {
+        return $this->_parts;
+    }
+
+    /**
+     * Sets the given array of Zend_Mime_Parts as the array for the message
+     *
+     * @param array $parts
+     */
+    public function setParts($parts)
+    {
+        $this->_parts = $parts;
+    }
+
+    /**
+     * Append a new Zend_Mime_Part to the current message
+     *
+     * @param Zend_Mime_Part $part
+     */
+    public function addPart(Zend_Mime_Part $part)
+    {
+        /**
+         * @todo check for duplicate object handle
+         */
+        $this->_parts[] = $part;
+    }
+
+    /**
+     * Check if message needs to be sent as multipart
+     * MIME message or if it has only one part.
+     *
+     * @return boolean
+     */
+    public function isMultiPart()
+    {
+        return (count($this->_parts) > 1);
+    }
+
+    /**
+     * Set Zend_Mime object for the message
+     *
+     * This can be used to set the boundary specifically or to use a subclass of
+     * Zend_Mime for generating the boundary.
+     *
+     * @param Zend_Mime $mime
+     */
+    public function setMime(Zend_Mime $mime)
+    {
+        $this->_mime = $mime;
+    }
+
+    /**
+     * Returns the Zend_Mime object in use by the message
+     *
+     * If the object was not present, it is created and returned. Can be used to
+     * determine the boundary used in this message.
+     *
+     * @return Zend_Mime
+     */
+    public function getMime()
+    {
+        if ($this->_mime === null) {
+            $this->_mime = new Zend_Mime();
+        }
+
+        return $this->_mime;
+    }
+
+    /**
+     * Generate MIME-compliant message from the current configuration
+     *
+     * This can be a multipart message if more than one MIME part was added. If
+     * only one part is present, the content of this part is returned. If no
+     * part had been added, an empty string is returned.
+     *
+     * Parts are seperated by the mime boundary as defined in Zend_Mime. If
+     * {@link setMime()} has been called before this method, the Zend_Mime
+     * object set by this call will be used. Otherwise, a new Zend_Mime object
+     * is generated and used.
+     *
+     * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+     * @return string
+     */
+    public function generateMessage($EOL = Zend_Mime::LINEEND)
+    {
+        if (! $this->isMultiPart()) {
+            $body = array_shift($this->_parts);
+            $body = $body->getContent($EOL);
+        } else {
+            $mime = $this->getMime();
+
+            $boundaryLine = $mime->boundaryLine($EOL);
+            $body = 'This is a message in Mime Format.  If you see this, '
+                  . "your mail reader does not support this format." . $EOL;
+
+            foreach (array_keys($this->_parts) as $p) {
+                $body .= $boundaryLine
+                       . $this->getPartHeaders($p, $EOL)
+                       . $EOL
+                       . $this->getPartContent($p, $EOL);
+            }
+
+            $body .= $mime->mimeEnd($EOL);
+        }
+
+        return trim($body);
+    }
+
+    /**
+     * Get the headers of a given part as an array
+     *
+     * @param int $partnum
+     * @return array
+     */
+    public function getPartHeadersArray($partnum)
+    {
+        return $this->_parts[$partnum]->getHeadersArray();
+    }
+
+    /**
+     * Get the headers of a given part as a string
+     *
+     * @param int $partnum
+     * @return string
+     */
+    public function getPartHeaders($partnum, $EOL = Zend_Mime::LINEEND)
+    {
+        return $this->_parts[$partnum]->getHeaders($EOL);
+    }
+
+    /**
+     * Get the (encoded) content of a given part as a string
+     *
+     * @param int $partnum
+     * @return string
+     */
+    public function getPartContent($partnum, $EOL = Zend_Mime::LINEEND)
+    {
+        return $this->_parts[$partnum]->getContent($EOL);
+    }
+
+    /**
+     * Explode MIME multipart string into seperate parts
+     *
+     * Parts consist of the header and the body of each MIME part.
+     *
+     * @param string $body
+     * @param string $boundary
+     * @return array
+     */
+    protected static function _disassembleMime($body, $boundary)
+    {
+        $start = 0;
+        $res = array();
+        // find every mime part limiter and cut out the
+        // string before it.
+        // the part before the first boundary string is discarded:
+        $p = strpos($body, '--'.$boundary."\n", $start);
+        if ($p === false) {
+            // no parts found!
+            return array();
+        }
+
+        // position after first boundary line
+        $start = $p + 3 + strlen($boundary);
+
+        while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
+            $res[] = substr($body, $start, $p-$start);
+            $start = $p + 3 + strlen($boundary);
+        }
+
+        // no more parts, find end boundary
+        $p = strpos($body, '--' . $boundary . '--', $start);
+        if ($p===false) {
+            throw new Zend_Exception('Not a valid Mime Message: End Missing');
+        }
+
+        // the remaining part also needs to be parsed:
+        $res[] = substr($body, $start, $p-$start);
+        return $res;
+    }
+
+    /**
+     * Decodes a MIME encoded string and returns a Zend_Mime_Message object with
+     * all the MIME parts set according to the given string
+     *
+     * @param string $message
+     * @param string $boundary
+     * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+     * @return Zend_Mime_Message
+     */
+    public static function createFromMessage($message, $boundary, $EOL = Zend_Mime::LINEEND)
+    {
+        require_once 'Zend/Mime/Decode.php';
+        $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL);
+
+        $res = new self();
+        foreach ($parts as $part) {
+            // now we build a new MimePart for the current Message Part:
+            $newPart = new Zend_Mime_Part($part);
+            foreach ($part['header'] as $key => $value) {
+                /**
+                 * @todo check for characterset and filename
+                 */
+                // list($key, $value) = $header;
+                switch(strtolower($key)) {
+                    case 'content-type':
+                        $newPart->type = $value;
+                        break;
+                    case 'content-transfer-encoding':
+                        $newPart->encoding = $value;
+                        break;
+                    case 'content-id':
+                        $newPart->id = trim($value,'<>');
+                        break;
+                    case 'content-disposition':
+                        $newPart->disposition = $value;
+                        break;
+                    case 'content-description':
+                        $newPart->description = $value;
+                        break;
+                    case 'content-location':
+                        $newPart->location = $value;
+                        break;
+                    case 'content-language':
+                        $newPart->language = $value;
+                        break;
+                    default:
+                        throw new Zend_Exception('Unknown header ignored for MimePart:' . $key);
+                }
+            }
+            $res->addPart($newPart);
+        }
+        return $res;
+    }
+}
diff --git a/lib/zend/Zend/Mime/Part.php b/lib/zend/Zend/Mime/Part.php
new file mode 100644 (file)
index 0000000..4149533
--- /dev/null
@@ -0,0 +1,218 @@
+<?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_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * Zend_Mime
+ */
+require_once 'Zend/Mime.php';
+
+/**
+ * Zend_Mime_Exception
+ */
+require_once 'Zend/Mime/Exception.php';
+
+/**
+ * Class representing a MIME part.
+ *
+ * @category   Zend
+ * @package    Zend_Mime
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mime_Part {
+
+    public $type = Zend_Mime::TYPE_OCTETSTREAM;
+    public $encoding = Zend_Mime::ENCODING_8BIT;
+    public $id;
+    public $disposition;
+    public $filename;
+    public $description;
+    public $charset;
+    public $boundary;
+    public $location;
+    public $language;
+    protected $_content;
+    protected $_isStream = false;
+
+
+    /**
+     * create a new Mime Part.
+     * The (unencoded) content of the Part as passed
+     * as a string or stream
+     *
+     * @param mixed $content  String or Stream containing the content
+     */
+    public function __construct($content)
+    {
+        $this->_content = $content;
+        if (is_resource($content)) {
+            $this->_isStream = true;
+        }
+    }
+
+    /**
+     * @todo setters/getters
+     * @todo error checking for setting $type
+     * @todo error checking for setting $encoding
+     */
+
+    /**
+     * check if this part can be read as a stream.
+     * if true, getEncodedStream can be called, otherwise
+     * only getContent can be used to fetch the encoded
+     * content of the part
+     *
+     * @return bool
+     */
+    public function isStream()
+    {
+      return $this->_isStream;
+    }
+
+    /**
+     * if this was created with a stream, return a filtered stream for
+     * reading the content. very useful for large file attachments.
+     *
+     * @return stream
+     * @throws Zend_Mime_Exception if not a stream or unable to append filter
+     */
+    public function getEncodedStream()
+    {
+        if (!$this->_isStream) {
+            throw new Zend_Mime_Exception('Attempt to get a stream from a string part');
+        }
+
+        //stream_filter_remove(); // ??? is that right?
+        switch ($this->encoding) {
+            case Zend_Mime::ENCODING_QUOTEDPRINTABLE:
+                $filter = stream_filter_append(
+                    $this->_content,
+                    'convert.quoted-printable-encode',
+                    STREAM_FILTER_READ,
+                    array(
+                        'line-length'      => 76,
+                        'line-break-chars' => Zend_Mime::LINEEND
+                    )
+                );
+                if (!is_resource($filter)) {
+                    throw new Zend_Mime_Exception('Failed to append quoted-printable filter');
+                }
+                break;
+            case Zend_Mime::ENCODING_BASE64:
+                $filter = stream_filter_append(
+                    $this->_content,
+                    'convert.base64-encode',
+                    STREAM_FILTER_READ,
+                    array(
+                        'line-length'      => 76,
+                        'line-break-chars' => Zend_Mime::LINEEND
+                    )
+                );
+                if (!is_resource($filter)) {
+                    throw new Zend_Mime_Exception('Failed to append base64 filter');
+                }
+                break;
+            default:
+        }
+        return $this->_content;
+    }
+
+    /**
+     * Get the Content of the current Mime Part in the given encoding.
+     *
+     * @return String
+     */
+    public function getContent($EOL = Zend_Mime::LINEEND)
+    {
+        if ($this->_isStream) {
+            return stream_get_contents($this->getEncodedStream());
+        } else {
+            return Zend_Mime::encode($this->_content, $this->encoding, $EOL);
+        }
+    }
+
+    /**
+     * Create and return the array of headers for this MIME part
+     *
+     * @access public
+     * @return array
+     */
+    public function getHeadersArray($EOL = Zend_Mime::LINEEND)
+    {
+        $headers = array();
+
+        $contentType = $this->type;
+        if ($this->charset) {
+            $contentType .= '; charset="' . $this->charset . '"';
+        }
+
+        if ($this->boundary) {
+            $contentType .= ';' . $EOL
+                          . " boundary=\"" . $this->boundary . '"';
+        }
+
+        $headers[] = array('Content-Type', $contentType);
+
+        if ($this->encoding) {
+            $headers[] = array('Content-Transfer-Encoding', $this->encoding);
+        }
+
+        if ($this->id) {
+            $headers[]  = array('Content-ID', '<' . $this->id . '>');
+        }
+
+        if ($this->disposition) {
+            $disposition = $this->disposition;
+            if ($this->filename) {
+                $disposition .= '; filename="' . $this->filename . '"';
+            }
+            $headers[] = array('Content-Disposition', $disposition);
+        }
+
+        if ($this->description) {
+            $headers[] = array('Content-Description', $this->description);
+        }
+        
+        if ($this->location) {
+            $headers[] = array('Content-Location', $this->location);
+        }
+        
+        if ($this->language){
+            $headers[] = array('Content-Language', $this->language);
+        }
+
+        return $headers;
+    }
+
+    /**
+     * Return the headers for this part as a string
+     *
+     * @return String
+     */
+    public function getHeaders($EOL = Zend_Mime::LINEEND)
+    {
+        $res = '';
+        foreach ($this->getHeadersArray($EOL) as $header) {
+            $res .= $header[0] . ': ' . $header[1] . $EOL;
+        }
+
+        return $res;
+    }
+}
diff --git a/lib/zend/Zend/Registry.php b/lib/zend/Zend/Registry.php
new file mode 100644 (file)
index 0000000..11bba27
--- /dev/null
@@ -0,0 +1,195 @@
+<?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_Registry
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Generic storage class helps to manage global data.
+ *
+ * @category   Zend
+ * @package    Zend_Registry
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Registry extends ArrayObject
+{
+    /**
+     * Class name of the singleton registry object.
+     * @var string
+     */
+    private static $_registryClassName = 'Zend_Registry';
+
+    /**
+     * Registry object provides storage for shared objects.
+     * @var Zend_Registry
+     */
+    private static $_registry = null;
+
+    /**
+     * Retrieves the default registry instance.
+     *
+     * @return Zend_Registry
+     */
+    public static function getInstance()
+    {
+        if (self::$_registry === null) {
+            self::init();
+        }
+
+        return self::$_registry;
+    }
+
+    /**
+     * Set the default registry instance to a specified instance.
+     *
+     * @param Zend_Registry $registry An object instance of type Zend_Registry,
+     *   or a subclass.
+     * @return void
+     * @throws Zend_Exception if registry is already initialized.
+     */
+    public static function setInstance(Zend_Registry $registry)
+    {
+        if (self::$_registry !== null) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Registry is already initialized');
+        }
+
+        self::setClassName(get_class($registry));
+        self::$_registry = $registry;
+    }
+
+    /**
+     * Initialize the default registry instance.
+     *
+     * @return void
+     */
+    protected static function init()
+    {
+        self::setInstance(new self::$_registryClassName());
+    }
+
+    /**
+     * Set the class name to use for the default registry instance.
+     * Does not affect the currently initialized instance, it only applies
+     * for the next time you instantiate.
+     *
+     * @param string $registryClassName
+     * @return void
+     * @throws Zend_Exception if the registry is initialized or if the
+     *   class name is not valid.
+     */
+    public static function setClassName($registryClassName = 'Zend_Registry')
+    {
+        if (self::$_registry !== null) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Registry is already initialized');
+        }
+
+        if (!is_string($registryClassName)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception("Argument is not a class name");
+        }
+
+        /**
+         * @see Zend_Loader
+         */
+        require_once 'Zend/Loader.php';
+        Zend_Loader::loadClass($registryClassName);
+
+        self::$_registryClassName = $registryClassName;
+    }
+
+    /**
+     * Unset the default registry instance.
+     * Primarily used in tearDown() in unit tests.
+     * @returns void
+     */
+    public static function _unsetInstance()
+    {
+        self::$_registry = null;
+    }
+
+    /**
+     * getter method, basically same as offsetGet().
+     *
+     * This method can be called from an object of type Zend_Registry, or it
+     * can be called statically.  In the latter case, it uses the default
+     * static instance stored in the class.
+     *
+     * @param string $index - get the value associated with $index
+     * @return mixed
+     * @throws Zend_Exception if no entry is registerd for $index.
+     */
+    public static function get($index)
+    {
+        $instance = self::getInstance();
+
+        if (!$instance->offsetExists($index)) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception("No entry is registered for key '$index'");
+        }
+
+        return $instance->offsetGet($index);
+    }
+
+    /**
+     * setter method, basically same as offsetSet().
+     *
+     * This method can be called from an object of type Zend_Registry, or it
+     * can be called statically.  In the latter case, it uses the default
+     * static instance stored in the class.
+     *
+     * @param string $index The location in the ArrayObject in which to store
+     *   the value.
+     * @param mixed $value The object to store in the ArrayObject.
+     * @return void
+     */
+    public static function set($index, $value)
+    {
+        $instance = self::getInstance();
+        $instance->offsetSet($index, $value);
+    }
+
+    /**
+     * Returns TRUE if the $index is a named value in the registry,
+     * or FALSE if $index was not found in the registry.
+     *
+     * @param  string $index
+     * @return boolean
+     */
+    public static function isRegistered($index)
+    {
+        if (self::$_registry === null) {
+            return false;
+        }
+        return self::$_registry->offsetExists($index);
+    }
+
+    /**
+     * @param string $index
+     * @returns mixed
+     *
+     * Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960).
+     */
+    public function offsetExists($index)
+    {
+        return array_key_exists($index, $this);
+    }
+
+}
diff --git a/lib/zend/Zend/Uri.php b/lib/zend/Zend/Uri.php
new file mode 100644 (file)
index 0000000..9230068
--- /dev/null
@@ -0,0 +1,164 @@
+<?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_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * Abstract class for all Zend_Uri handlers
+ *
+ * @category  Zend
+ * @package   Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Uri
+{
+    /**
+     * Scheme of this URI (http, ftp, etc.)
+     *
+     * @var string
+     */
+    protected $_scheme = '';
+
+    /**
+     * Return a string representation of this URI.
+     *
+     * @see    getUri()
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getUri();
+    }
+
+    /**
+     * Convenience function, checks that a $uri string is well-formed
+     * by validating it but not returning an object.  Returns TRUE if
+     * $uri is a well-formed URI, or FALSE otherwise.
+     *
+     * @param  string $uri The URI to check
+     * @return boolean
+     */
+    public static function check($uri)
+    {
+        try {
+            $uri = self::factory($uri);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        return $uri->valid();
+    }
+
+    /**
+     * Create a new Zend_Uri object for a URI.  If building a new URI, then $uri should contain
+     * only the scheme (http, ftp, etc).  Otherwise, supply $uri with the complete URI.
+     *
+     * @param  string $uri The URI form which a Zend_Uri instance is created
+     * @throws Zend_Uri_Exception When an empty string was supplied for the scheme
+     * @throws Zend_Uri_Exception When an illegal scheme is supplied
+     * @throws Zend_Uri_Exception When the scheme is not supported
+     * @return Zend_Uri
+     * @link   http://www.faqs.org/rfcs/rfc2396.html
+     */
+    public static function factory($uri = 'http')
+    {
+        // Separate the scheme from the scheme-specific parts
+        $uri            = explode(':', $uri, 2);
+        $scheme         = strtolower($uri[0]);
+        $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
+
+        if (strlen($scheme) === 0) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('An empty string was supplied for the scheme');
+        }
+
+        // Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
+        if (ctype_alnum($scheme) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
+        }
+
+        /**
+         * Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the
+         * scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown.
+         */
+        switch ($scheme) {
+            case 'http':
+                // Break intentionally omitted
+            case 'https':
+                $className = 'Zend_Uri_Http';
+                break;
+
+            case 'mailto':
+                // TODO
+            default:
+                require_once 'Zend/Uri/Exception.php';
+                throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported");
+                break;
+        }
+
+        Zend_Loader::loadClass($className);
+        $schemeHandler = new $className($scheme, $schemeSpecific);
+
+        return $schemeHandler;
+    }
+
+    /**
+     * Get the URI's scheme
+     *
+     * @return string|false Scheme or false if no scheme is set.
+     */
+    public function getScheme()
+    {
+        if (empty($this->_scheme) === false) {
+            return $this->_scheme;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Zend_Uri and its subclasses cannot be instantiated directly.
+     * Use Zend_Uri::factory() to return a new Zend_Uri object.
+     *
+     * @param string $scheme         The scheme of the URI
+     * @param string $schemeSpecific The scheme-specific part of the URI
+     */
+    abstract protected function __construct($scheme, $schemeSpecific = '');
+
+    /**
+     * Return a string representation of this URI.
+     *
+     * @return string
+     */
+    abstract public function getUri();
+
+    /**
+     * Returns TRUE if this URI is valid, or FALSE otherwise.
+     *
+     * @return boolean
+     */
+    abstract public function valid();
+}
diff --git a/lib/zend/Zend/Uri/Exception.php b/lib/zend/Zend/Uri/Exception.php
new file mode 100644 (file)
index 0000000..fe9a271
--- /dev/null
@@ -0,0 +1,37 @@
+<?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_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+/**
+ * Exceptions for Zend_Uri
+ *
+ * @category  Zend
+ * @package   Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Uri_Exception extends Zend_Exception
+{
+}
diff --git a/lib/zend/Zend/Uri/Http.php b/lib/zend/Zend/Uri/Http.php
new file mode 100644 (file)
index 0000000..3c9b918
--- /dev/null
@@ -0,0 +1,703 @@
+<?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_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Validate_Hostname
+ */
+require_once 'Zend/Validate/Hostname.php';
+
+/**
+ * HTTP(S) URI handler
+ *
+ * @category  Zend
+ * @package   Zend_Uri
+ * @uses      Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Uri_Http extends Zend_Uri
+{
+    /**
+     * HTTP username
+     *
+     * @var string
+     */
+    protected $_username = '';
+
+    /**
+     * HTTP password
+     *
+     * @var string
+     */
+    protected $_password = '';
+
+    /**
+     * HTTP host
+     *
+     * @var string
+     */
+    protected $_host = '';
+
+    /**
+     * HTTP post
+     *
+     * @var string
+     */
+    protected $_port = '';
+
+    /**
+     * HTTP part
+     *
+     * @var string
+     */
+    protected $_path = '';
+
+    /**
+     * HTTP query
+     *
+     * @var string
+     */
+    protected $_query = '';
+
+    /**
+     * HTTP fragment
+     *
+     * @var string
+     */
+    protected $_fragment = '';
+
+    /**
+     * Regular expression grammar rules for validation; values added by constructor
+     *
+     * @var array
+     */
+    protected $_regex = array();
+
+    /**
+     * Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI
+     * (e.g., example.com/path/to/resource?query=param#fragment)
+     *
+     * @param  string $scheme         The scheme of the URI
+     * @param  string $schemeSpecific The scheme-specific part of the URI
+     * @throws Zend_Uri_Exception When the URI is not valid
+     */
+    protected function __construct($scheme, $schemeSpecific = '')
+    {
+        // Set the scheme
+        $this->_scheme = $scheme;
+
+        // Set up grammar rules for validation via regular expressions. These
+        // are to be used with slash-delimited regular expression strings.
+        $this->_regex['alphanum']   = '[^\W_]';
+        $this->_regex['escaped']    = '(?:%[\da-fA-F]{2})';
+        $this->_regex['mark']       = '[-_.!~*\'()\[\]]';
+        $this->_regex['reserved']   = '[;\/?:@&=+$,]';
+        $this->_regex['unreserved'] = '(?:' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . ')';
+        $this->_regex['segment']    = '(?:(?:' . $this->_regex['unreserved'] . '|' . $this->_regex['escaped']
+                                    . '|[:@&=+$,;])*)';
+        $this->_regex['path']       = '(?:\/' . $this->_regex['segment'] . '?)+';
+        $this->_regex['uric']       = '(?:' . $this->_regex['reserved'] . '|' . $this->_regex['unreserved'] . '|'
+                                    . $this->_regex['escaped'] . ')';
+        // If no scheme-specific part was supplied, the user intends to create
+        // a new URI with this object.  No further parsing is required.
+        if (strlen($schemeSpecific) === 0) {
+            return;
+        }
+
+        // Parse the scheme-specific URI parts into the instance variables.
+        $this->_parseUri($schemeSpecific);
+
+        // Validate the URI
+        if ($this->valid() === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Invalid URI supplied');
+        }
+    }
+
+    /**
+     * Creates a Zend_Uri_Http from the given string
+     *
+     * @param  string $uri String to create URI from, must start with
+     *                     'http://' or 'https://'
+     * @throws InvalidArgumentException  When the given $uri is not a string or
+     *                                   does not start with http:// or https://
+     * @throws Zend_Uri_Exception        When the given $uri is invalid
+     * @return Zend_Uri_Http
+     */
+    public static function fromString($uri)
+    {
+        if (is_string($uri) === false) {
+            throw new InvalidArgumentException('$uri is not a string');
+        }
+
+        $uri            = explode(':', $uri, 2);
+        $scheme         = strtolower($uri[0]);
+        $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
+
+        if (in_array($scheme, array('http', 'https')) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Invalid scheme: '$scheme'");
+        }
+
+        $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific);
+        return $schemeHandler;
+    }
+
+    /**
+     * Parse the scheme-specific portion of the URI and place its parts into instance variables.
+     *
+     * @param  string $schemeSpecific The scheme-specific portion to parse
+     * @throws Zend_Uri_Exception When scheme-specific decoposition fails
+     * @throws Zend_Uri_Exception When authority decomposition fails
+     * @return void
+     */
+    protected function _parseUri($schemeSpecific)
+    {
+        // High-level decomposition parser
+        $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~';
+        $status  = @preg_match($pattern, $schemeSpecific, $matches);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed');
+        }
+
+        // Failed decomposition; no further processing needed
+        if ($status === false) {
+            return;
+        }
+
+        // Save URI components that need no further decomposition
+        $this->_path     = isset($matches[4]) === true ? $matches[4] : '';
+        $this->_query    = isset($matches[6]) === true ? $matches[6] : '';
+        $this->_fragment = isset($matches[8]) === true ? $matches[8] : '';
+
+        // Additional decomposition to get username, password, host, and port
+        $combo   = isset($matches[3]) === true ? $matches[3] : '';
+        $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~';
+        $status  = @preg_match($pattern, $combo, $matches);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: authority decomposition failed');
+        }
+
+        // Failed decomposition; no further processing needed
+        if ($status === false) {
+            return;
+        }
+
+        // Save remaining URI components
+        $this->_username = isset($matches[2]) === true ? $matches[2] : '';
+        $this->_password = isset($matches[4]) === true ? $matches[4] : '';
+        $this->_host     = isset($matches[5]) === true ? $matches[5] : '';
+        $this->_port     = isset($matches[7]) === true ? $matches[7] : '';
+
+    }
+
+    /**
+     * Returns a URI based on current values of the instance variables. If any
+     * part of the URI does not pass validation, then an exception is thrown.
+     *
+     * @throws Zend_Uri_Exception When one or more parts of the URI are invalid
+     * @return string
+     */
+    public function getUri()
+    {
+        if ($this->valid() === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('One or more parts of the URI are invalid');
+        }
+
+        $password = strlen($this->_password) > 0 ? ":$this->_password" : '';
+        $auth     = strlen($this->_username) > 0 ? "$this->_username$password@" : '';
+        $port     = strlen($this->_port) > 0 ? ":$this->_port" : '';
+        $query    = strlen($this->_query) > 0 ? "?$this->_query" : '';
+        $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : '';
+
+        return $this->_scheme
+             . '://'
+             . $auth
+             . $this->_host
+             . $port
+             . $this->_path
+             . $query
+             . $fragment;
+    }
+
+    /**
+     * Validate the current URI from the instance variables. Returns true if and only if all
+     * parts pass validation.
+     *
+     * @return boolean
+     */
+    public function valid()
+    {
+        // Return true if and only if all parts of the URI have passed validation
+        return $this->validateUsername()
+           and $this->validatePassword()
+           and $this->validateHost()
+           and $this->validatePort()
+           and $this->validatePath()
+           and $this->validateQuery()
+           and $this->validateFragment();
+    }
+
+    /**
+     * Returns the username portion of the URL, or FALSE if none.
+     *
+     * @return string
+     */
+    public function getUsername()
+    {
+        return strlen($this->_username) > 0 ? $this->_username : false;
+    }
+
+    /**
+     * Returns true if and only if the username passes validation. If no username is passed,
+     * then the username contained in the instance variable is used.
+     *
+     * @param  string $username The HTTP username
+     * @throws Zend_Uri_Exception When username validation fails
+     * @return boolean
+     * @link   http://www.faqs.org/rfcs/rfc2396.html
+     */
+    public function validateUsername($username = null)
+    {
+        if ($username === null) {
+            $username = $this->_username;
+        }
+
+        // If the username is empty, then it is considered valid
+        if (strlen($username) === 0) {
+            return true;
+        }
+
+        // Check the username against the allowed values
+        $status = @preg_match('/^(' . $this->_regex['alphanum']  . '|' . $this->_regex['mark'] . '|'
+                            . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $username);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: username validation failed');
+        }
+
+        return $status === 1;
+    }
+
+    /**
+     * Sets the username for the current URI, and returns the old username
+     *
+     * @param  string $username The HTTP username
+     * @throws Zend_Uri_Exception When $username is not a valid HTTP username
+     * @return string
+     */
+    public function setUsername($username)
+    {
+        if ($this->validateUsername($username) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username");
+        }
+
+        $oldUsername     = $this->_username;
+        $this->_username = $username;
+
+        return $oldUsername;
+    }
+
+    /**
+     * Returns the password portion of the URL, or FALSE if none.
+     *
+     * @return string
+     */
+    public function getPassword()
+    {
+        return strlen($this->_password) > 0 ? $this->_password : false;
+    }
+
+    /**
+     * Returns true if and only if the password passes validation. If no password is passed,
+     * then the password contained in the instance variable is used.
+     *
+     * @param  string $password The HTTP password
+     * @throws Zend_Uri_Exception When password validation fails
+     * @return boolean
+     * @link   http://www.faqs.org/rfcs/rfc2396.html
+     */
+    public function validatePassword($password = null)
+    {
+        if ($password === null) {
+            $password = $this->_password;
+        }
+
+        // If the password is empty, then it is considered valid
+        if (strlen($password) === 0) {
+            return true;
+        }
+
+        // If the password is nonempty, but there is no username, then it is considered invalid
+        if (strlen($password) > 0 and strlen($this->_username) === 0) {
+            return false;
+        }
+
+        // Check the password against the allowed values
+        $status = @preg_match('/^(' . $this->_regex['alphanum']  . '|' . $this->_regex['mark'] . '|'
+                             . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $password);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: password validation failed.');
+        }
+
+        return $status == 1;
+    }
+
+    /**
+     * Sets the password for the current URI, and returns the old password
+     *
+     * @param  string $password The HTTP password
+     * @throws Zend_Uri_Exception When $password is not a valid HTTP password
+     * @return string
+     */
+    public function setPassword($password)
+    {
+        if ($this->validatePassword($password) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password.");
+        }
+
+        $oldPassword     = $this->_password;
+        $this->_password = $password;
+
+        return $oldPassword;
+    }
+
+    /**
+     * Returns the domain or host IP portion of the URL, or FALSE if none.
+     *
+     * @return string
+     */
+    public function getHost()
+    {
+        return strlen($this->_host) > 0 ? $this->_host : false;
+    }
+
+    /**
+     * Returns true if and only if the host string passes validation. If no host is passed,
+     * then the host contained in the instance variable is used.
+     *
+     * @param  string $host The HTTP host
+     * @return boolean
+     * @uses   Zend_Filter
+     */
+    public function validateHost($host = null)
+    {
+        if ($host === null) {
+            $host = $this->_host;
+        }
+
+        // If the host is empty, then it is considered invalid
+        if (strlen($host) === 0) {
+            return false;
+        }
+
+        // Check the host against the allowed values; delegated to Zend_Filter.
+        $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
+
+        return $validate->isValid($host);
+    }
+
+    /**
+     * Sets the host for the current URI, and returns the old host
+     *
+     * @param  string $host The HTTP host
+     * @throws Zend_Uri_Exception When $host is nota valid HTTP host
+     * @return string
+     */
+    public function setHost($host)
+    {
+        if ($this->validateHost($host) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host");
+        }
+
+        $oldHost     = $this->_host;
+        $this->_host = $host;
+
+        return $oldHost;
+    }
+
+    /**
+     * Returns the TCP port, or FALSE if none.
+     *
+     * @return string
+     */
+    public function getPort()
+    {
+        return strlen($this->_port) > 0 ? $this->_port : false;
+    }
+
+    /**
+     * Returns true if and only if the TCP port string passes validation. If no port is passed,
+     * then the port contained in the instance variable is used.
+     *
+     * @param  string $port The HTTP port
+     * @return boolean
+     */
+    public function validatePort($port = null)
+    {
+        if ($port === null) {
+            $port = $this->_port;
+        }
+
+        // If the port is empty, then it is considered valid
+        if (strlen($port) === 0) {
+            return true;
+        }
+
+        // Check the port against the allowed values
+        return ctype_digit((string) $port) and 1 <= $port and $port <= 65535;
+    }
+
+    /**
+     * Sets the port for the current URI, and returns the old port
+     *
+     * @param  string $port The HTTP port
+     * @throws Zend_Uri_Exception When $port is not a valid HTTP port
+     * @return string
+     */
+    public function setPort($port)
+    {
+        if ($this->validatePort($port) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port.");
+        }
+
+        $oldPort     = $this->_port;
+        $this->_port = $port;
+
+        return $oldPort;
+    }
+
+    /**
+     * Returns the path and filename portion of the URL, or FALSE if none.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return strlen($this->_path) > 0 ? $this->_path : '/';
+    }
+
+    /**
+     * Returns true if and only if the path string passes validation. If no path is passed,
+     * then the path contained in the instance variable is used.
+     *
+     * @param  string $path The HTTP path
+     * @throws Zend_Uri_Exception When path validation fails
+     * @return boolean
+     */
+    public function validatePath($path = null)
+    {
+        if ($path === null) {
+            $path = $this->_path;
+        }
+
+        // If the path is empty, then it is considered valid
+        if (strlen($path) === 0) {
+            return true;
+        }
+
+        // Determine whether the path is well-formed
+        $pattern = '/^' . $this->_regex['path'] . '$/';
+        $status  = @preg_match($pattern, $path);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: path validation failed');
+        }
+
+        return (boolean) $status;
+    }
+
+    /**
+     * Sets the path for the current URI, and returns the old path
+     *
+     * @param  string $path The HTTP path
+     * @throws Zend_Uri_Exception When $path is not a valid HTTP path
+     * @return string
+     */
+    public function setPath($path)
+    {
+        if ($this->validatePath($path) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path");
+        }
+
+        $oldPath     = $this->_path;
+        $this->_path = $path;
+
+        return $oldPath;
+    }
+
+    /**
+     * Returns the query portion of the URL (after ?), or FALSE if none.
+     *
+     * @return string
+     */
+    public function getQuery()
+    {
+        return strlen($this->_query) > 0 ? $this->_query : false;
+    }
+
+    /**
+     * Returns true if and only if the query string passes validation. If no query is passed,
+     * then the query string contained in the instance variable is used.
+     *
+     * @param  string $query The query to validate
+     * @throws Zend_Uri_Exception When query validation fails
+     * @return boolean
+     * @link   http://www.faqs.org/rfcs/rfc2396.html
+     */
+    public function validateQuery($query = null)
+    {
+        if ($query === null) {
+            $query = $this->_query;
+        }
+
+        // If query is empty, it is considered to be valid
+        if (strlen($query) === 0) {
+            return true;
+        }
+
+        // Determine whether the query is well-formed
+        $pattern = '/^' . $this->_regex['uric'] . '*$/';
+        $status  = @preg_match($pattern, $query);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: query validation failed');
+        }
+
+        return $status == 1;
+    }
+
+    /**
+     * Set the query string for the current URI, and return the old query
+     * string This method accepts both strings and arrays.
+     *
+     * @param  string|array $query The query string or array
+     * @throws Zend_Uri_Exception When $query is not a valid query string
+     * @return string              Old query string
+     */
+    public function setQuery($query)
+    {
+        $oldQuery = $this->_query;
+
+        // If query is empty, set an empty string
+        if (empty($query) === true) {
+            $this->_query = '';
+            return $oldQuery;
+        }
+
+        // If query is an array, make a string out of it
+        if (is_array($query) === true) {
+            $query = http_build_query($query, '', '&');
+        } else {
+            // If it is a string, make sure it is valid. If not parse and encode it
+            $query = (string) $query;
+            if ($this->validateQuery($query) === false) {
+                parse_str($query, $queryArray);
+                $query = http_build_query($queryArray, '', '&');
+            }
+        }
+
+        // Make sure the query is valid, and set it
+        if ($this->validateQuery($query) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("'$query' is not a valid query string");
+        }
+
+        $this->_query = $query;
+
+        return $oldQuery;
+    }
+
+    /**
+     * Returns the fragment portion of the URL (after #), or FALSE if none.
+     *
+     * @return string|false
+     */
+    public function getFragment()
+    {
+        return strlen($this->_fragment) > 0 ? $this->_fragment : false;
+    }
+
+    /**
+     * Returns true if and only if the fragment passes validation. If no fragment is passed,
+     * then the fragment contained in the instance variable is used.
+     *
+     * @param  string $fragment Fragment of an URI
+     * @throws Zend_Uri_Exception When fragment validation fails
+     * @return boolean
+     * @link   http://www.faqs.org/rfcs/rfc2396.html
+     */
+    public function validateFragment($fragment = null)
+    {
+        if ($fragment === null) {
+            $fragment = $this->_fragment;
+        }
+
+        // If fragment is empty, it is considered to be valid
+        if (strlen($fragment) === 0) {
+            return true;
+        }
+
+        // Determine whether the fragment is well-formed
+        $pattern = '/^' . $this->_regex['uric'] . '*$/';
+        $status  = @preg_match($pattern, $fragment);
+        if ($status === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception('Internal error: fragment validation failed');
+        }
+
+        return (boolean) $status;
+    }
+
+    /**
+     * Sets the fragment for the current URI, and returns the old fragment
+     *
+     * @param  string $fragment Fragment of the current URI
+     * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment
+     * @return string
+     */
+    public function setFragment($fragment)
+    {
+        if ($this->validateFragment($fragment) === false) {
+            require_once 'Zend/Uri/Exception.php';
+            throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment");
+        }
+
+        $oldFragment     = $this->_fragment;
+        $this->_fragment = $fragment;
+
+        return $oldFragment;
+    }
+}
diff --git a/lib/zend/Zend/Validate/Abstract.php b/lib/zend/Zend/Validate/Abstract.php
new file mode 100644 (file)
index 0000000..3125510
--- /dev/null
@@ -0,0 +1,348 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Interface
+ */
+require_once 'Zend/Validate/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Validate_Abstract implements Zend_Validate_Interface
+{
+    /**
+     * The value to be validated
+     *
+     * @var mixed
+     */
+    protected $_value;
+
+    /**
+     * Additional variables available for validation failure messages
+     *
+     * @var array
+     */
+    protected $_messageVariables = array();
+
+    /**
+     * Validation failure message template definitions
+     *
+     * @var array
+     */
+    protected $_messageTemplates = array();
+
+    /**
+     * Array of validation failure messages
+     *
+     * @var array
+     */
+    protected $_messages = array();
+
+    /**
+     * Flag indidcating whether or not value should be obfuscated in error 
+     * messages
+     * @var bool
+     */
+    protected $_obscureValue = false;
+
+    /**
+     * Array of validation failure message codes
+     *
+     * @var array
+     * @deprecated Since 1.5.0
+     */
+    protected $_errors = array();
+
+    /**
+     * Translation object
+     * @var Zend_Translate
+     */
+    protected $_translator;
+
+    /**
+     * Default translation object for all validate objects
+     * @var Zend_Translate
+     */
+    protected static $_defaultTranslator;
+
+    /**
+     * Returns array of validation failure messages
+     *
+     * @return array
+     */
+    public function getMessages()
+    {
+        return $this->_messages;
+    }
+
+    /**
+     * Returns an array of the names of variables that are used in constructing validation failure messages
+     *
+     * @return array
+     */
+    public function getMessageVariables()
+    {
+        return array_keys($this->_messageVariables);
+    }
+
+    /**
+     * Sets the validation failure message template for a particular key
+     *
+     * @param  string $messageString
+     * @param  string $messageKey     OPTIONAL
+     * @return Zend_Validate_Abstract Provides a fluent interface
+     * @throws Zend_Validate_Exception
+     */
+    public function setMessage($messageString, $messageKey = null)
+    {
+        if ($messageKey === null) {
+            $keys = array_keys($this->_messageTemplates);
+            $messageKey = current($keys);
+        }
+        if (!isset($this->_messageTemplates[$messageKey])) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("No message template exists for key '$messageKey'");
+        }
+        $this->_messageTemplates[$messageKey] = $messageString;
+        return $this;
+    }
+
+    /**
+     * Sets validation failure message templates given as an array, where the array keys are the message keys,
+     * and the array values are the message template strings.
+     *
+     * @param  array $messages
+     * @return Zend_Validate_Abstract
+     */
+    public function setMessages(array $messages)
+    {
+        foreach ($messages as $key => $message) {
+            $this->setMessage($message, $key);
+        }
+        return $this;
+    }
+
+    /**
+     * Magic function returns the value of the requested property, if and only if it is the value or a
+     * message variable.
+     *
+     * @param  string $property
+     * @return mixed
+     * @throws Zend_Validate_Exception
+     */
+    public function __get($property)
+    {
+        if ($property == 'value') {
+            return $this->_value;
+        }
+        if (array_key_exists($property, $this->_messageVariables)) {
+            return $this->{$this->_messageVariables[$property]};
+        }
+        /**
+         * @see Zend_Validate_Exception
+         */
+        require_once 'Zend/Validate/Exception.php';
+        throw new Zend_Validate_Exception("No property exists by the name '$property'");
+    }
+
+    /**
+     * Constructs and returns a validation failure message with the given message key and value.
+     *
+     * Returns null if and only if $messageKey does not correspond to an existing template.
+     *
+     * If a translator is available and a translation exists for $messageKey, 
+     * the translation will be used.
+     *
+     * @param  string $messageKey
+     * @param  string $value
+     * @return string
+     */
+    protected function _createMessage($messageKey, $value)
+    {
+        if (!isset($this->_messageTemplates[$messageKey])) {
+            return null;
+        }
+
+        $message = $this->_messageTemplates[$messageKey];
+
+        if (null !== ($translator = $this->getTranslator())) {
+            if ($translator->isTranslated($message)) {
+                $message = $translator->translate($message);
+            } elseif ($translator->isTranslated($messageKey)) {
+                $message = $translator->translate($messageKey);
+            }
+        }
+
+        if ($this->getObscureValue()) {
+            $value = str_repeat('*', strlen($value));
+        }
+
+        $message = str_replace('%value%', (string) $value, $message);
+        foreach ($this->_messageVariables as $ident => $property) {
+            $message = str_replace("%$ident%", $this->$property, $message);
+        }
+        return $message;
+    }
+
+    /**
+     * @param  string $messageKey OPTIONAL
+     * @param  string $value      OPTIONAL
+     * @return void
+     */
+    protected function _error($messageKey = null, $value = null)
+    {
+        if ($messageKey === null) {
+            $keys = array_keys($this->_messageTemplates);
+            $messageKey = current($keys);
+        }
+        if ($value === null) {
+            $value = $this->_value;
+        }
+        $this->_errors[]              = $messageKey;
+        $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value);
+    }
+
+    /**
+     * Sets the value to be validated and clears the messages and errors arrays
+     *
+     * @param  mixed $value
+     * @return void
+     */
+    protected function _setValue($value)
+    {
+        $this->_value    = $value;
+        $this->_messages = array();
+        $this->_errors   = array();
+    }
+
+    /**
+     * Returns array of validation failure message codes
+     *
+     * @return array
+     * @deprecated Since 1.5.0
+     */
+    public function getErrors()
+    {
+        return $this->_errors;
+    }
+
+    /**
+     * Set flag indicating whether or not value should be obfuscated in messages
+     * 
+     * @param  bool $flag 
+     * @return Zend_Validate_Abstract
+     */
+    public function setObscureValue($flag)
+    {
+        $this->_obscureValue = (bool) $flag;
+        return $this;
+    }
+
+    /**
+     * Retrieve flag indicating whether or not value should be obfuscated in 
+     * messages
+     * 
+     * @return bool
+     */
+    public function getObscureValue()
+    {
+        return $this->_obscureValue;
+    }
+
+    /**
+     * Set translation object
+     * 
+     * @param  Zend_Translate|Zend_Translate_Adapter|null $translator 
+     * @return Zend_Validate_Abstract
+     */
+    public function setTranslator($translator = null)
+    {
+        if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
+            $this->_translator = $translator;
+        } elseif ($translator instanceof Zend_Translate) {
+            $this->_translator = $translator->getAdapter();
+        } else {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception('Invalid translator specified');
+        }
+        return $this;
+    }
+
+    /**
+     * Return translation object
+     * 
+     * @return Zend_Translate_Adapter|null
+     */
+    public function getTranslator()
+    {
+        if (null === $this->_translator) {
+            return self::getDefaultTranslator();
+        }
+
+        return $this->_translator;
+    }
+
+    /**
+     * Set default translation object for all validate objects
+     * 
+     * @param  Zend_Translate|Zend_Translate_Adapter|null $translator 
+     * @return void
+     */
+    public static function setDefaultTranslator($translator = null)
+    {
+        if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
+            self::$_defaultTranslator = $translator;
+        } elseif ($translator instanceof Zend_Translate) {
+            self::$_defaultTranslator = $translator->getAdapter();
+        } else {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception('Invalid translator specified');
+        }
+    }
+
+    /**
+     * Get default translation object for all validate objects
+     * 
+     * @return Zend_Translate_Adapter|null
+     */
+    public static function getDefaultTranslator()
+    {
+        if (null === self::$_defaultTranslator) {
+            require_once 'Zend/Registry.php';
+            if (Zend_Registry::isRegistered('Zend_Translate')) {
+                $translator = Zend_Registry::get('Zend_Translate');
+                if ($translator instanceof Zend_Translate_Adapter) {
+                    return $translator;
+                } elseif ($translator instanceof Zend_Translate) {
+                    return $translator->getAdapter();
+                }
+            }
+        }
+        return self::$_defaultTranslator;
+    }
+}
diff --git a/lib/zend/Zend/Validate/Hostname.php b/lib/zend/Zend/Validate/Hostname.php
new file mode 100644 (file)
index 0000000..2f6468e
--- /dev/null
@@ -0,0 +1,444 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * @see Zend_Validate_Ip
+ */
+require_once 'Zend/Validate/Ip.php';
+
+/**
+ * Please note there are two standalone test scripts for testing IDN characters due to problems
+ * with file encoding.
+ *
+ * The first is tests/Zend/Validate/HostnameTestStandalone.php which is designed to be run on
+ * the command line.
+ *
+ * The second is tests/Zend/Validate/HostnameTestForm.php which is designed to be run via HTML
+ * to allow users to test entering UTF-8 characters in a form.
+ *
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname extends Zend_Validate_Abstract
+{
+
+    const IP_ADDRESS_NOT_ALLOWED  = 'hostnameIpAddressNotAllowed';
+    const UNKNOWN_TLD             = 'hostnameUnknownTld';
+    const INVALID_DASH            = 'hostnameDashCharacter';
+    const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema';
+    const UNDECIPHERABLE_TLD      = 'hostnameUndecipherableTld';
+    const INVALID_HOSTNAME        = 'hostnameInvalidHostname';
+    const INVALID_LOCAL_NAME      = 'hostnameInvalidLocalName';
+    const LOCAL_NAME_NOT_ALLOWED  = 'hostnameLocalNameNotAllowed';
+
+    /**
+     * @var array
+     */
+    protected $_messageTemplates = array(
+        self::IP_ADDRESS_NOT_ALLOWED  => "'%value%' appears to be an IP address, but IP addresses are not allowed",
+        self::UNKNOWN_TLD             => "'%value%' appears to be a DNS hostname but cannot match TLD against known list",
+        self::INVALID_DASH            => "'%value%' appears to be a DNS hostname but contains a dash (-) in an invalid position",
+        self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'",
+        self::UNDECIPHERABLE_TLD      => "'%value%' appears to be a DNS hostname but cannot extract TLD part",
+        self::INVALID_HOSTNAME        => "'%value%' does not match the expected structure for a DNS hostname",
+        self::INVALID_LOCAL_NAME      => "'%value%' does not appear to be a valid local network name",
+        self::LOCAL_NAME_NOT_ALLOWED  => "'%value%' appears to be a local network name but local network names are not allowed"
+    );
+
+    /**
+     * @var array
+     */
+    protected $_messageVariables = array(
+        'tld' => '_tld'
+    );
+
+    /**
+     * Allows Internet domain names (e.g., example.com)
+     */
+    const ALLOW_DNS   = 1;
+
+    /**
+     * Allows IP addresses
+     */
+    const ALLOW_IP    = 2;
+
+    /**
+     * Allows local network names (e.g., localhost, www.localdomain)
+     */
+    const ALLOW_LOCAL = 4;
+
+    /**
+     * Allows all types of hostnames
+     */
+    const ALLOW_ALL   = 7;
+
+    /**
+     * Whether IDN domains are validated
+     *
+     * @var boolean
+     */
+    private $_validateIdn = true;
+
+    /**
+     * Whether TLDs are validated against a known list
+     *
+     * @var boolean
+     */
+    private $_validateTld = true;
+
+    /**
+     * Bit field of ALLOW constants; determines which types of hostnames are allowed
+     *
+     * @var integer
+     */
+    protected $_allow;
+
+    /**
+     * Bit field of CHECK constants; determines what additional hostname checks to make
+     *
+     * @var unknown_type
+     */
+    // protected $_check;
+
+    /**
+     * Array of valid top-level-domains
+     *
+     * @var array
+     * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt  List of all TLDs by domain
+     */
+    protected $_validTlds = array(
+        'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao',
+        'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb',
+        'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo',
+        'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd',
+        'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop',
+        'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do',
+        'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj',
+        'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh',
+        'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',
+        'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il',
+        'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm',
+        'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw',
+        'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu',
+        'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm',
+        'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv',
+        'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng',
+        'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
+        'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt',
+        'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd',
+        'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr',
+        'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj',
+        'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw',
+        'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've',
+        'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm',
+        'zw'
+        );
+
+    /**
+     * @var string
+     */
+    protected $_tld;
+
+    /**
+     * Sets validator options
+     *
+     * @param integer          $allow       OPTIONAL Set what types of hostname to allow (default ALLOW_DNS)
+     * @param boolean          $validateIdn OPTIONAL Set whether IDN domains are validated (default true)
+     * @param boolean          $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true)
+     * @param Zend_Validate_Ip $ipValidator OPTIONAL
+     * @return void
+     * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm  Technical Specifications for ccTLDs
+     */
+    public function __construct($allow = self::ALLOW_DNS, $validateIdn = true, $validateTld = true, Zend_Validate_Ip $ipValidator = null)
+    {
+        // Set allow options
+        $this->setAllow($allow);
+
+        // Set validation options
+        $this->_validateIdn = $validateIdn;
+        $this->_validateTld = $validateTld;
+
+        $this->setIpValidator($ipValidator);
+    }
+
+    /**
+     * @param Zend_Validate_Ip $ipValidator OPTIONAL
+     * @return void;
+     */
+    public function setIpValidator(Zend_Validate_Ip $ipValidator = null)
+    {
+        if ($ipValidator === null) {
+            $ipValidator = new Zend_Validate_Ip();
+        }
+        $this->_ipValidator = $ipValidator;
+    }
+
+    /**
+     * Returns the allow option
+     *
+     * @return integer
+     */
+    public function getAllow()
+    {
+        return $this->_allow;
+    }
+
+    /**
+     * Sets the allow option
+     *
+     * @param  integer $allow
+     * @return Zend_Validate_Hostname Provides a fluent interface
+     */
+    public function setAllow($allow)
+    {
+        $this->_allow = $allow;
+        return $this;
+    }
+
+    /**
+     * Set whether IDN domains are validated
+     *
+     * This only applies when DNS hostnames are validated
+     *
+     * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them
+     */
+    public function setValidateIdn ($allowed)
+    {
+        $this->_validateIdn = (bool) $allowed;
+    }
+
+    /**
+     * Set whether the TLD element of a hostname is validated
+     *
+     * This only applies when DNS hostnames are validated
+     *
+     * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them
+     */
+    public function setValidateTld ($allowed)
+    {
+        $this->_validateTld = (bool) $allowed;
+    }
+
+    /**
+     * Sets the check option
+     *
+     * @param  integer $check
+     * @return Zend_Validate_Hostname Provides a fluent interface
+     */
+    /*
+    public function setCheck($check)
+    {
+        $this->_check = $check;
+        return $this;
+    }
+     */
+
+    /**
+     * Defined by Zend_Validate_Interface
+     *
+     * Returns true if and only if the $value is a valid hostname with respect to the current allow option
+     *
+     * @param  string $value
+     * @throws Zend_Validate_Exception if a fatal error occurs for validation process
+     * @return boolean
+     */
+    public function isValid($value)
+    {
+        $valueString = (string) $value;
+
+        $this->_setValue($valueString);
+
+        // Check input against IP address schema
+        if ($this->_ipValidator->setTranslator($this->getTranslator())->isValid($valueString)) {
+            if (!($this->_allow & self::ALLOW_IP)) {
+                $this->_error(self::IP_ADDRESS_NOT_ALLOWED);
+                return false;
+            } else{
+                return true;
+            }
+        }
+
+        // Check input against DNS hostname schema
+        $domainParts = explode('.', $valueString);
+        if ((count($domainParts) > 1) && (strlen($valueString) >= 4) && (strlen($valueString) <= 254)) {
+            $status = false;
+
+            do {
+                // First check TLD
+                if (preg_match('/([a-z]{2,10})$/i', end($domainParts), $matches)) {
+
+                    reset($domainParts);
+
+                    // Hostname characters are: *(label dot)(label dot label); max 254 chars
+                    // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
+                    // id-prefix: alpha / digit
+                    // ldh: alpha / digit / dash
+
+                    // Match TLD against known list
+                    $this->_tld = strtolower($matches[1]);
+                    if ($this->_validateTld) {
+                        if (!in_array($this->_tld, $this->_validTlds)) {
+                            $this->_error(self::UNKNOWN_TLD);
+                            $status = false;
+                            break;
+                        }
+                    }
+
+                    /**
+                     * Match against IDN hostnames
+                     * @see Zend_Validate_Hostname_Interface
+                     */
+                    $labelChars = 'a-z0-9';
+                    $utf8 = false;
+                    $classFile = 'Zend/Validate/Hostname/' . ucfirst($this->_tld) . '.php';
+                    if ($this->_validateIdn) {
+                        if (Zend_Loader::isReadable($classFile)) {
+
+                            // Load additional characters
+                            $className = 'Zend_Validate_Hostname_' . ucfirst($this->_tld);
+                            Zend_Loader::loadClass($className);
+                            $labelChars .= call_user_func(array($className, 'getCharacters'));
+                            $utf8 = true;
+                        }
+                    }
+
+                    // Keep label regex short to avoid issues with long patterns when matching IDN hostnames
+                    $regexLabel = '/^[' . $labelChars . '\x2d]{1,63}$/i';
+                    if ($utf8) {
+                        $regexLabel .= 'u';
+                    }
+
+                    // Check each hostname part
+                    $valid = true;
+                    foreach ($domainParts as $domainPart) {
+
+                        // Check dash (-) does not start, end or appear in 3rd and 4th positions
+                        if (strpos($domainPart, '-') === 0 ||
+                        (strlen($domainPart) > 2 && strpos($domainPart, '-', 2) == 2 && strpos($domainPart, '-', 3) == 3) ||
+                        strrpos($domainPart, '-') === strlen($domainPart) - 1) {
+
+                            $this->_error(self::INVALID_DASH);
+                            $status = false;
+                            break 2;
+                        }
+
+                        // Check each domain part
+                        $status = @preg_match($regexLabel, $domainPart);
+                        if ($status === false) {
+                            /**
+                             * Regex error
+                             * @see Zend_Validate_Exception
+                             */
+                            require_once 'Zend/Validate/Exception.php';
+                            throw new Zend_Validate_Exception('Internal error: DNS validation failed');
+                        } elseif ($status === 0) {
+                            $valid = false;
+                        }
+                    }
+
+                    // If all labels didn't match, the hostname is invalid
+                    if (!$valid) {
+                        $this->_error(self::INVALID_HOSTNAME_SCHEMA);
+                        $status = false;
+                    }
+
+                } else {
+                    // Hostname not long enough
+                    $this->_error(self::UNDECIPHERABLE_TLD);
+                    $status = false;
+                }
+            } while (false);
+
+            // If the input passes as an Internet domain name, and domain names are allowed, then the hostname
+            // passes validation
+            if ($status && ($this->_allow & self::ALLOW_DNS)) {
+                return true;
+            }
+        } else {
+            $this->_error(self::INVALID_HOSTNAME);
+        }
+
+        // Check input against local network name schema; last chance to pass validation
+        $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
+        $status = @preg_match($regexLocal, $valueString);
+        if (false === $status) {
+            /**
+             * Regex error
+             * @see Zend_Validate_Exception
+             */
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception('Internal error: local network name validation failed');
+        }
+
+        // If the input passes as a local network name, and local network names are allowed, then the
+        // hostname passes validation
+        $allowLocal = $this->_allow & self::ALLOW_LOCAL;
+        if ($status && $allowLocal) {
+            return true;
+        }
+
+        // If the input does not pass as a local network name, add a message
+        if (!$status) {
+            $this->_error(self::INVALID_LOCAL_NAME);
+        }
+
+        // If local network names are not allowed, add a message
+        if ($status && !$allowLocal) {
+            $this->_error(self::LOCAL_NAME_NOT_ALLOWED);
+        }
+
+        return false;
+    }
+
+    /**
+     * Throws an exception if a regex for $type does not exist
+     *
+     * @param  string $type
+     * @throws Zend_Validate_Exception
+     * @return Zend_Validate_Hostname Provides a fluent interface
+     */
+    /*
+    protected function _checkRegexType($type)
+    {
+        if (!isset($this->_regex[$type])) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("'$type' must be one of ('" . implode(', ', array_keys($this->_regex))
+                                            . "')");
+        }
+        return $this;
+    }
+     */
+
+}
diff --git a/lib/zend/Zend/Validate/Hostname/At.php b/lib/zend/Zend/Validate/Hostname/At.php
new file mode 100644 (file)
index 0000000..c1e1f00
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_At implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.nic.at/en/service/technical_information/idn/charset_converter/ Austria (.AT)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}\x{0161}\x{017E}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/Ch.php b/lib/zend/Zend/Validate/Hostname/Ch.php
new file mode 100644 (file)
index 0000000..464e867
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_Ch implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Switzerland (.CH)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/De.php b/lib/zend/Zend/Validate/Hostname/De.php
new file mode 100644 (file)
index 0000000..0b7c1e3
--- /dev/null
@@ -0,0 +1,58 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_De implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.denic.de/en/domains/idns/liste.html Germany (.DE) alllowed characters
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return  '\x{00E1}\x{00E0}\x{0103}\x{00E2}\x{00E5}\x{00E4}\x{00E3}\x{0105}\x{0101}\x{00E6}\x{0107}' .
+                '\x{0109}\x{010D}\x{010B}\x{00E7}\x{010F}\x{0111}\x{00E9}\x{00E8}\x{0115}\x{00EA}\x{011B}' .
+                '\x{00EB}\x{0117}\x{0119}\x{0113}\x{011F}\x{011D}\x{0121}\x{0123}\x{0125}\x{0127}\x{00ED}' .
+                '\x{00EC}\x{012D}\x{00EE}\x{00EF}\x{0129}\x{012F}\x{012B}\x{0131}\x{0135}\x{0137}\x{013A}' .
+                '\x{013E}\x{013C}\x{0142}\x{0144}\x{0148}\x{00F1}\x{0146}\x{014B}\x{00F3}\x{00F2}\x{014F}' .
+                '\x{00F4}\x{00F6}\x{0151}\x{00F5}\x{00F8}\x{014D}\x{0153}\x{0138}\x{0155}\x{0159}\x{0157}' .
+                '\x{015B}\x{015D}\x{0161}\x{015F}\x{0165}\x{0163}\x{0167}\x{00FA}\x{00F9}\x{016D}\x{00FB}' .
+                '\x{016F}\x{00FC}\x{0171}\x{0169}\x{0173}\x{016B}\x{0175}\x{00FD}\x{0177}\x{00FF}\x{017A}' .
+                '\x{017E}\x{017C}\x{00F0}\x{00FE}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/Fi.php b/lib/zend/Zend/Validate/Hostname/Fi.php
new file mode 100644 (file)
index 0000000..4f16a4a
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_Fi implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html Finland (.FI)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00E5}\x{00E4}\x{00F6}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/Hu.php b/lib/zend/Zend/Validate/Hostname/Hu.php
new file mode 100644 (file)
index 0000000..381c74d
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_Hu implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.domain.hu/domain/English/szabalyzat.html Hungary (.HU)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00E1}\x{00E9}\x{00ED}\x{00F3}\x{00F6}\x{0151}\x{00FA}\x{00FC}\x{0171}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/Interface.php b/lib/zend/Zend/Validate/Hostname/Interface.php
new file mode 100644 (file)
index 0000000..ab925be
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+interface Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * UTF-8 characters should be written as four character hex codes \x{XXXX}
+     * For example é (lowercase e with acute) is represented by the hex code \x{00E9}
+     *
+     * You only need to include lower-case equivalents of characters since the hostname
+     * check is case-insensitive
+     *
+     * Please document the supported TLDs in the documentation file at:
+     * manual/en/module_specs/Zend_Validate-Hostname.xml
+     *
+     * @see http://en.wikipedia.org/wiki/Internationalized_domain_name
+     * @see http://www.iana.org/cctld/ Country-Code Top-Level Domains (TLDs)
+     * @see http://www.columbia.edu/kermit/utf8-t1.html UTF-8 characters
+     * @return string
+     */
+    static function getCharacters();
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/Li.php b/lib/zend/Zend/Validate/Hostname/Li.php
new file mode 100644 (file)
index 0000000..5bf8b48
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_Li implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Liechtenstein (.LI)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Hostname/No.php b/lib/zend/Zend/Validate/Hostname/No.php
new file mode 100644 (file)
index 0000000..65c3098
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_No implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html Norway (.NO)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return  '\x00E1\x00E0\x00E4\x010D\x00E7\x0111\x00E9\x00E8\x00EA\x\x014B' .
+                '\x0144\x00F1\x00F3\x00F2\x00F4\x00F6\x0161\x0167\x00FC\x017E\x00E6' .
+                '\x00F8\x00E5';
+    }
+
+}
diff --git a/lib/zend/Zend/Validate/Hostname/Se.php b/lib/zend/Zend/Validate/Hostname/Se.php
new file mode 100644 (file)
index 0000000..1febf5f
--- /dev/null
@@ -0,0 +1,50 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Hostname_Se implements Zend_Validate_Hostname_Interface
+{
+
+    /**
+     * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+     *
+     * @see http://www.iis.se/english/IDN_campaignsite.shtml?lang=en Sweden (.SE)
+     * @return string
+     */
+    static function getCharacters()
+    {
+        return '\x{00E5}\x{00E4}\x{00F6}\x{00FC}\x{00E9}';
+    }
+
+}
\ No newline at end of file
diff --git a/lib/zend/Zend/Validate/Interface.php b/lib/zend/Zend/Validate/Interface.php
new file mode 100644 (file)
index 0000000..40db340
--- /dev/null
@@ -0,0 +1,71 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+interface Zend_Validate_Interface
+{
+    /**
+     * Returns true if and only if $value meets the validation requirements
+     *
+     * If $value fails validation, then this method returns false, and
+     * getMessages() will return an array of messages that explain why the
+     * validation failed.
+     *
+     * @param  mixed $value
+     * @return boolean
+     * @throws Zend_Valid_Exception If validation of $value is impossible
+     */
+    public function isValid($value);
+
+    /**
+     * Returns an array of messages that explain why the most recent isValid()
+     * call returned false. The array keys are validation failure message identifiers,
+     * and the array values are the corresponding human-readable message strings.
+     *
+     * If isValid() was never called or if the most recent isValid() call
+     * returned true, then this method returns an empty array.
+     *
+     * @return array
+     */
+    public function getMessages();
+
+    /**
+     * Returns an array of message codes that explain why a previous isValid() call
+     * returned false.
+     *
+     * If isValid() was never called or if the most recent isValid() call
+     * returned true, then this method returns an empty array.
+     *
+     * This is now the same as calling array_keys() on the return value from getMessages().
+     *
+     * @return array
+     * @deprecated Since 1.5.0
+     */
+    public function getErrors();
+
+}
diff --git a/lib/zend/Zend/Validate/Ip.php b/lib/zend/Zend/Validate/Ip.php
new file mode 100644 (file)
index 0000000..926934b
--- /dev/null
@@ -0,0 +1,70 @@
+<?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_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_Ip extends Zend_Validate_Abstract
+{
+
+    const NOT_IP_ADDRESS = 'notIpAddress';
+
+    /**
+     * @var array
+     */
+    protected $_messageTemplates = array(
+        self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address"
+    );
+
+    /**
+     * Defined by Zend_Validate_Interface
+     *
+     * Returns true if and only if $value is a valid IP address
+     *
+     * @param  mixed $value
+     * @return boolean
+     */
+    public function isValid($value)
+    {
+        $valueString = (string) $value;
+
+        $this->_setValue($valueString);
+
+        if (ip2long($valueString) === false) {
+            $this->_error();
+            return false;
+        }
+
+        return true;
+    }
+
+}
diff --git a/lib/zend/Zend/Version.php b/lib/zend/Zend/Version.php
new file mode 100644 (file)
index 0000000..1a10730
--- /dev/null
@@ -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_Version
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Class to store and retrieve the version of Zend Framework.
+ *
+ * @category   Zend
+ * @package    Zend_Version
+ * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+final class Zend_Version
+{
+    /**
+     * Zend Framework version identification - see compareVersion()
+     */
+    const VERSION = '1.6.2';
+
+    /**
+     * Compare the specified Zend Framework version string $version
+     * with the current Zend_Version::VERSION of the Zend Framework.
+     *
+     * @param  string  $version  A version string (e.g. "0.7.1").
+     * @return boolean           -1 if the $version is older,
+     *                           0 if they are the same,
+     *                           and +1 if $version is newer.
+     *
+     */
+    public static function compareVersion($version)
+    {
+        return version_compare($version, self::VERSION);
+    }
+}
diff --git a/portfolio/type/gdata/lib.php b/portfolio/type/gdata/lib.php
new file mode 100755 (executable)
index 0000000..99f6d80
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+require_once($CFG->libdir.'/filelib.php');
+require_once 'Zend/Loader.php';
+Zend_Loader::loadClass('Zend_Gdata');
+Zend_Loader::loadClass('Zend_Gdata_AuthSub');
+Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
+Zend_Loader::loadClass('Zend_Gdata_Docs');
+Zend_Loader::loadClass('Zend_Http_Client_Adapter_Socket');
+
+class portfolio_plugin_gdata extends portfolio_plugin_push_base {
+    public $client;
+    public $gdata;
+    public $listfeed;
+    public $token;
+    public $docID;
+
+    public static function get_name() {
+        return get_string('pluginname', 'portfolio_gdata');
+    }
+
+    public function prepare_package() {
+
+    }
+
+    public function send_package() {
+        global $CFG;
+
+        foreach ($this->exporter->get_tempfiles() as $file) {
+            // @TODO get max size from gdata
+            $filesize = $file->get_filesize();
+
+            // TODO upload method
+            $tempfilepath = $CFG->dataroot.'/temp/'.$file->get_pathnamehash();
+            $file->copy_content_to($tempfilepath);
+
+            $title = $file->get_filename();
+
+            if ($this->get_export_config('title')) {
+                $title = $this->get_export_config('title');
+            }
+
+            $return = $this->gdata->uploadFile($tempfilepath, $title, $file->get_mimetype());
+
+            unlink($tempfilepath);
+
+            if (method_exists($return, 'getContent')) {
+                $feed_src = $return->getContent()->getSrc();
+                if (preg_match('|.*docID=([a-z0-9A-Z_]+)|', $feed_src, $matches)) {
+                    $this->docID = $matches[1];
+                }
+
+            } else {
+                throw new portfolio_plugin_exception('uploadfailed', 'portfolio_gdata', 'Upload not yet implemented');
+            }
+        }
+    }
+
+    public static function allows_multiple() {
+        return false;
+    }
+
+    public function get_continue_url() {
+        $idparam = '';
+        if (!empty($this->docID)) {
+            $idparam = "/Doc?id=".$this->docID;
+        }
+        return "http://docs.google.com".$idparam;
+    }
+
+    public function expected_time($callertime) {
+        return $callertime;
+    }
+
+    public static function get_allowed_config() {
+        return array();
+    }
+
+    public static function has_admin_config() {
+        return false;
+    }
+
+    public function admin_config_form(&$mform) {
+
+    }
+
+    public function has_export_config() {
+        return true;
+    }
+
+    public function get_allowed_user_config() {
+        return array('authtoken');
+    }
+
+    public function steal_control($stage) {
+        global $CFG;
+        if ($stage != PORTFOLIO_STAGE_CONFIG) {
+            return false;
+        }
+        if ($this->token) {
+            return false;
+        }
+
+        $token = $this->get_user_config('authtoken', $this->get('user')->id);
+
+        if (!empty($token)) {
+            $this->token = $token;
+            $this->client = Zend_Gdata_AuthSub::getHttpClient($token);
+            $this->gdata = new Zend_Gdata_Docs($this->client);
+            $this->feed = $this->gdata->getDocumentListFeed();
+            return false;
+        }
+
+        $scope = 'http://docs.google.com/feeds/documents';
+        $secure = false;
+        $session = true;
+
+        return Zend_Gdata_AuthSub::getAuthSubTokenUri($CFG->wwwroot.'/portfolio/add.php?postcontrol=1', $scope, $secure, $session);
+    }
+
+    public function post_control($stage, $params) {
+        if ($stage != PORTFOLIO_STAGE_CONFIG) {
+            return;
+        }
+        if (!array_key_exists('token', $params) || empty($params['token'])) {
+            throw new portfolio_plugin_exception('noauthtoken', 'portfolio_gdata');
+        }
+
+        $this->set_user_config(array('authtoken' => Zend_Gdata_AuthSub::getAuthSubSessionToken($params['token'])), $this->get('user')->id);
+    }
+
+    public function export_config_form(&$mform) {
+        $mform->addElement('text', 'plugin_title', get_string('title', 'portfolio_gdata'));
+    }
+
+    public function get_allowed_export_config() {
+        return array('title');
+    }
+
+    public function get_export_summary() {
+        return array(get_string('title', 'portfolio_gdata') => $this->get_export_config('title'));
+    }
+}
diff --git a/portfolio/type/gdata/version.php b/portfolio/type/gdata/version.php
new file mode 100755 (executable)
index 0000000..1a00826
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$plugin->version  = 2008072500;
+$plugin->requires = 2008072500;
+$plugin->cron     = 0;
+
+?>