From 5ab88978b9357553d64dac4c96dc10839888896d Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Fri, 31 Oct 2008 15:33:45 +0000 Subject: [PATCH] MDL-17091 Adding part of GoogleData API from the Zend Framework, in order to support portfolio and repository functions. Also completed basic portfolio plugin. --- lib/zend/Zend/Exception.php | 30 + lib/zend/Zend/Gdata.php | 207 +++ lib/zend/Zend/Gdata/App.php | 804 +++++++++++ lib/zend/Zend/Gdata/App/AuthException.php | 40 + .../Zend/Gdata/App/BadMethodCallException.php | 39 + lib/zend/Zend/Gdata/App/Base.php | 459 +++++++ lib/zend/Zend/Gdata/App/BaseMediaSource.php | 176 +++ .../Gdata/App/CaptchaRequiredException.php | 91 ++ lib/zend/Zend/Gdata/App/Entry.php | 307 +++++ lib/zend/Zend/Gdata/App/Exception.php | 40 + lib/zend/Zend/Gdata/App/Extension.php | 37 + lib/zend/Zend/Gdata/App/Extension/Author.php | 40 + .../Zend/Gdata/App/Extension/Category.php | 139 ++ lib/zend/Zend/Gdata/App/Extension/Content.php | 85 ++ .../Zend/Gdata/App/Extension/Contributor.php | 40 + lib/zend/Zend/Gdata/App/Extension/Control.php | 95 ++ lib/zend/Zend/Gdata/App/Extension/Draft.php | 47 + lib/zend/Zend/Gdata/App/Extension/Element.php | 55 + lib/zend/Zend/Gdata/App/Extension/Email.php | 46 + .../Zend/Gdata/App/Extension/Generator.php | 112 ++ lib/zend/Zend/Gdata/App/Extension/Icon.php | 46 + lib/zend/Zend/Gdata/App/Extension/Id.php | 46 + lib/zend/Zend/Gdata/App/Extension/Link.php | 216 +++ lib/zend/Zend/Gdata/App/Extension/Logo.php | 46 + lib/zend/Zend/Gdata/App/Extension/Name.php | 45 + lib/zend/Zend/Gdata/App/Extension/Person.php | 160 +++ .../Zend/Gdata/App/Extension/Published.php | 46 + lib/zend/Zend/Gdata/App/Extension/Rights.php | 46 + lib/zend/Zend/Gdata/App/Extension/Source.php | 43 + .../Zend/Gdata/App/Extension/Subtitle.php | 40 + lib/zend/Zend/Gdata/App/Extension/Summary.php | 40 + lib/zend/Zend/Gdata/App/Extension/Text.php | 87 ++ lib/zend/Zend/Gdata/App/Extension/Title.php | 40 + lib/zend/Zend/Gdata/App/Extension/Updated.php | 46 + lib/zend/Zend/Gdata/App/Extension/Uri.php | 46 + lib/zend/Zend/Gdata/App/Feed.php | 264 ++++ lib/zend/Zend/Gdata/App/FeedEntryParent.php | 525 ++++++++ lib/zend/Zend/Gdata/App/FeedSourceParent.php | 245 ++++ lib/zend/Zend/Gdata/App/HttpException.php | 118 ++ lib/zend/Zend/Gdata/App/IOException.php | 40 + .../Gdata/App/InvalidArgumentException.php | 39 + .../App/LoggingHttpClientAdapterSocket.php | 116 ++ lib/zend/Zend/Gdata/App/MediaEntry.php | 160 +++ lib/zend/Zend/Gdata/App/MediaFileSource.php | 143 ++ lib/zend/Zend/Gdata/App/MediaSource.php | 70 + lib/zend/Zend/Gdata/App/Util.php | 60 + lib/zend/Zend/Gdata/AuthSub.php | 222 +++ lib/zend/Zend/Gdata/ClientLogin.php | 180 +++ lib/zend/Zend/Gdata/Docs.php | 254 ++++ .../Zend/Gdata/Docs/DocumentListEntry.php | 53 + lib/zend/Zend/Gdata/Docs/DocumentListFeed.php | 67 + lib/zend/Zend/Gdata/Docs/Query.php | 219 +++ lib/zend/Zend/Gdata/Entry.php | 48 + lib/zend/Zend/Gdata/Extension.php | 52 + .../Zend/Gdata/Extension/AttendeeStatus.php | 120 ++ .../Zend/Gdata/Extension/AttendeeType.php | 120 ++ lib/zend/Zend/Gdata/Extension/Comments.php | 114 ++ lib/zend/Zend/Gdata/Extension/EntryLink.php | 164 +++ lib/zend/Zend/Gdata/Extension/EventStatus.php | 98 ++ .../Zend/Gdata/Extension/ExtendedProperty.php | 103 ++ lib/zend/Zend/Gdata/Extension/FeedLink.php | 172 +++ .../Extension/OpenSearchItemsPerPage.php | 47 + .../Gdata/Extension/OpenSearchStartIndex.php | 47 + .../Extension/OpenSearchTotalResults.php | 47 + .../Zend/Gdata/Extension/OriginalEvent.php | 139 ++ lib/zend/Zend/Gdata/Extension/Rating.php | 142 ++ lib/zend/Zend/Gdata/Extension/Recurrence.php | 46 + .../Gdata/Extension/RecurrenceException.php | 202 +++ lib/zend/Zend/Gdata/Extension/Reminder.php | 168 +++ .../Zend/Gdata/Extension/Transparency.php | 120 ++ lib/zend/Zend/Gdata/Extension/Visibility.php | 120 ++ lib/zend/Zend/Gdata/Extension/When.php | 166 +++ lib/zend/Zend/Gdata/Extension/Where.php | 163 +++ lib/zend/Zend/Gdata/Extension/Who.php | 291 ++++ lib/zend/Zend/Gdata/Feed.php | 167 +++ lib/zend/Zend/Gdata/Gbase.php | 200 +++ lib/zend/Zend/Gdata/Gbase/Entry.php | 150 +++ .../Gdata/Gbase/Extension/BaseAttribute.php | 115 ++ lib/zend/Zend/Gdata/Gbase/Feed.php | 59 + lib/zend/Zend/Gdata/Gbase/ItemEntry.php | 147 ++ lib/zend/Zend/Gdata/Gbase/ItemFeed.php | 45 + lib/zend/Zend/Gdata/Gbase/ItemQuery.php | 98 ++ lib/zend/Zend/Gdata/Gbase/Query.php | 265 ++++ lib/zend/Zend/Gdata/Gbase/SnippetEntry.php | 45 + lib/zend/Zend/Gdata/Gbase/SnippetFeed.php | 45 + lib/zend/Zend/Gdata/Gbase/SnippetQuery.php | 71 + lib/zend/Zend/Gdata/HttpClient.php | 245 ++++ lib/zend/Zend/Gdata/Media.php | 56 + lib/zend/Zend/Gdata/Media/Entry.php | 133 ++ .../Gdata/Media/Extension/MediaCategory.php | 147 ++ .../Gdata/Media/Extension/MediaContent.php | 521 +++++++ .../Gdata/Media/Extension/MediaCopyright.php | 115 ++ .../Gdata/Media/Extension/MediaCredit.php | 148 ++ .../Media/Extension/MediaDescription.php | 115 ++ .../Zend/Gdata/Media/Extension/MediaGroup.php | 565 ++++++++ .../Zend/Gdata/Media/Extension/MediaHash.php | 114 ++ .../Gdata/Media/Extension/MediaKeywords.php | 51 + .../Gdata/Media/Extension/MediaPlayer.php | 177 +++ .../Gdata/Media/Extension/MediaRating.php | 117 ++ .../Media/Extension/MediaRestriction.php | 148 ++ .../Zend/Gdata/Media/Extension/MediaText.php | 210 +++ .../Gdata/Media/Extension/MediaThumbnail.php | 209 +++ .../Zend/Gdata/Media/Extension/MediaTitle.php | 117 ++ lib/zend/Zend/Gdata/Media/Feed.php | 69 + lib/zend/Zend/Gdata/Query.php | 415 ++++++ lib/zend/Zend/Http/Client.php | 1194 +++++++++++++++++ .../Zend/Http/Client/Adapter/Exception.php | 33 + .../Zend/Http/Client/Adapter/Interface.php | 78 ++ lib/zend/Zend/Http/Client/Adapter/Proxy.php | 269 ++++ lib/zend/Zend/Http/Client/Adapter/Socket.php | 337 +++++ lib/zend/Zend/Http/Client/Adapter/Test.php | 193 +++ lib/zend/Zend/Http/Client/Exception.php | 33 + lib/zend/Zend/Http/Exception.php | 33 + lib/zend/Zend/Http/Response.php | 625 +++++++++ lib/zend/Zend/Loader.php | 258 ++++ lib/zend/Zend/Mime.php | 252 ++++ lib/zend/Zend/Mime/Decode.php | 243 ++++ lib/zend/Zend/Mime/Exception.php | 36 + lib/zend/Zend/Mime/Message.php | 286 ++++ lib/zend/Zend/Mime/Part.php | 218 +++ lib/zend/Zend/Registry.php | 195 +++ lib/zend/Zend/Uri.php | 164 +++ lib/zend/Zend/Uri/Exception.php | 37 + lib/zend/Zend/Uri/Http.php | 703 ++++++++++ lib/zend/Zend/Validate/Abstract.php | 348 +++++ lib/zend/Zend/Validate/Hostname.php | 444 ++++++ lib/zend/Zend/Validate/Hostname/At.php | 50 + lib/zend/Zend/Validate/Hostname/Ch.php | 50 + lib/zend/Zend/Validate/Hostname/De.php | 58 + lib/zend/Zend/Validate/Hostname/Fi.php | 50 + lib/zend/Zend/Validate/Hostname/Hu.php | 50 + lib/zend/Zend/Validate/Hostname/Interface.php | 52 + lib/zend/Zend/Validate/Hostname/Li.php | 50 + lib/zend/Zend/Validate/Hostname/No.php | 52 + lib/zend/Zend/Validate/Hostname/Se.php | 50 + lib/zend/Zend/Validate/Interface.php | 71 + lib/zend/Zend/Validate/Ip.php | 70 + lib/zend/Zend/Version.php | 51 + portfolio/type/gdata/lib.php | 142 ++ portfolio/type/gdata/version.php | 7 + 140 files changed, 21207 insertions(+) create mode 100644 lib/zend/Zend/Exception.php create mode 100644 lib/zend/Zend/Gdata.php create mode 100644 lib/zend/Zend/Gdata/App.php create mode 100644 lib/zend/Zend/Gdata/App/AuthException.php create mode 100644 lib/zend/Zend/Gdata/App/BadMethodCallException.php create mode 100644 lib/zend/Zend/Gdata/App/Base.php create mode 100644 lib/zend/Zend/Gdata/App/BaseMediaSource.php create mode 100644 lib/zend/Zend/Gdata/App/CaptchaRequiredException.php create mode 100644 lib/zend/Zend/Gdata/App/Entry.php create mode 100644 lib/zend/Zend/Gdata/App/Exception.php create mode 100644 lib/zend/Zend/Gdata/App/Extension.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Author.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Category.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Content.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Contributor.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Control.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Draft.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Element.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Email.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Generator.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Icon.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Id.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Link.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Logo.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Name.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Person.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Published.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Rights.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Source.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Subtitle.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Summary.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Text.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Title.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Updated.php create mode 100644 lib/zend/Zend/Gdata/App/Extension/Uri.php create mode 100644 lib/zend/Zend/Gdata/App/Feed.php create mode 100644 lib/zend/Zend/Gdata/App/FeedEntryParent.php create mode 100644 lib/zend/Zend/Gdata/App/FeedSourceParent.php create mode 100644 lib/zend/Zend/Gdata/App/HttpException.php create mode 100644 lib/zend/Zend/Gdata/App/IOException.php create mode 100644 lib/zend/Zend/Gdata/App/InvalidArgumentException.php create mode 100644 lib/zend/Zend/Gdata/App/LoggingHttpClientAdapterSocket.php create mode 100644 lib/zend/Zend/Gdata/App/MediaEntry.php create mode 100644 lib/zend/Zend/Gdata/App/MediaFileSource.php create mode 100644 lib/zend/Zend/Gdata/App/MediaSource.php create mode 100644 lib/zend/Zend/Gdata/App/Util.php create mode 100644 lib/zend/Zend/Gdata/AuthSub.php create mode 100644 lib/zend/Zend/Gdata/ClientLogin.php create mode 100755 lib/zend/Zend/Gdata/Docs.php create mode 100755 lib/zend/Zend/Gdata/Docs/DocumentListEntry.php create mode 100755 lib/zend/Zend/Gdata/Docs/DocumentListFeed.php create mode 100755 lib/zend/Zend/Gdata/Docs/Query.php create mode 100644 lib/zend/Zend/Gdata/Entry.php create mode 100644 lib/zend/Zend/Gdata/Extension.php create mode 100644 lib/zend/Zend/Gdata/Extension/AttendeeStatus.php create mode 100644 lib/zend/Zend/Gdata/Extension/AttendeeType.php create mode 100644 lib/zend/Zend/Gdata/Extension/Comments.php create mode 100644 lib/zend/Zend/Gdata/Extension/EntryLink.php create mode 100644 lib/zend/Zend/Gdata/Extension/EventStatus.php create mode 100644 lib/zend/Zend/Gdata/Extension/ExtendedProperty.php create mode 100644 lib/zend/Zend/Gdata/Extension/FeedLink.php create mode 100644 lib/zend/Zend/Gdata/Extension/OpenSearchItemsPerPage.php create mode 100644 lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php create mode 100644 lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php create mode 100644 lib/zend/Zend/Gdata/Extension/OriginalEvent.php create mode 100644 lib/zend/Zend/Gdata/Extension/Rating.php create mode 100644 lib/zend/Zend/Gdata/Extension/Recurrence.php create mode 100644 lib/zend/Zend/Gdata/Extension/RecurrenceException.php create mode 100644 lib/zend/Zend/Gdata/Extension/Reminder.php create mode 100644 lib/zend/Zend/Gdata/Extension/Transparency.php create mode 100644 lib/zend/Zend/Gdata/Extension/Visibility.php create mode 100644 lib/zend/Zend/Gdata/Extension/When.php create mode 100644 lib/zend/Zend/Gdata/Extension/Where.php create mode 100644 lib/zend/Zend/Gdata/Extension/Who.php create mode 100644 lib/zend/Zend/Gdata/Feed.php create mode 100644 lib/zend/Zend/Gdata/Gbase.php create mode 100644 lib/zend/Zend/Gdata/Gbase/Entry.php create mode 100644 lib/zend/Zend/Gdata/Gbase/Extension/BaseAttribute.php create mode 100644 lib/zend/Zend/Gdata/Gbase/Feed.php create mode 100644 lib/zend/Zend/Gdata/Gbase/ItemEntry.php create mode 100644 lib/zend/Zend/Gdata/Gbase/ItemFeed.php create mode 100644 lib/zend/Zend/Gdata/Gbase/ItemQuery.php create mode 100644 lib/zend/Zend/Gdata/Gbase/Query.php create mode 100644 lib/zend/Zend/Gdata/Gbase/SnippetEntry.php create mode 100644 lib/zend/Zend/Gdata/Gbase/SnippetFeed.php create mode 100644 lib/zend/Zend/Gdata/Gbase/SnippetQuery.php create mode 100644 lib/zend/Zend/Gdata/HttpClient.php create mode 100755 lib/zend/Zend/Gdata/Media.php create mode 100755 lib/zend/Zend/Gdata/Media/Entry.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaCategory.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaContent.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaCopyright.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaCredit.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaDescription.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaGroup.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaHash.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaKeywords.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaPlayer.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaRating.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaRestriction.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaText.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaThumbnail.php create mode 100755 lib/zend/Zend/Gdata/Media/Extension/MediaTitle.php create mode 100755 lib/zend/Zend/Gdata/Media/Feed.php create mode 100644 lib/zend/Zend/Gdata/Query.php create mode 100644 lib/zend/Zend/Http/Client.php create mode 100644 lib/zend/Zend/Http/Client/Adapter/Exception.php create mode 100644 lib/zend/Zend/Http/Client/Adapter/Interface.php create mode 100644 lib/zend/Zend/Http/Client/Adapter/Proxy.php create mode 100644 lib/zend/Zend/Http/Client/Adapter/Socket.php create mode 100644 lib/zend/Zend/Http/Client/Adapter/Test.php create mode 100644 lib/zend/Zend/Http/Client/Exception.php create mode 100644 lib/zend/Zend/Http/Exception.php create mode 100644 lib/zend/Zend/Http/Response.php create mode 100644 lib/zend/Zend/Loader.php create mode 100644 lib/zend/Zend/Mime.php create mode 100644 lib/zend/Zend/Mime/Decode.php create mode 100644 lib/zend/Zend/Mime/Exception.php create mode 100644 lib/zend/Zend/Mime/Message.php create mode 100644 lib/zend/Zend/Mime/Part.php create mode 100644 lib/zend/Zend/Registry.php create mode 100644 lib/zend/Zend/Uri.php create mode 100644 lib/zend/Zend/Uri/Exception.php create mode 100644 lib/zend/Zend/Uri/Http.php create mode 100644 lib/zend/Zend/Validate/Abstract.php create mode 100644 lib/zend/Zend/Validate/Hostname.php create mode 100644 lib/zend/Zend/Validate/Hostname/At.php create mode 100644 lib/zend/Zend/Validate/Hostname/Ch.php create mode 100644 lib/zend/Zend/Validate/Hostname/De.php create mode 100644 lib/zend/Zend/Validate/Hostname/Fi.php create mode 100644 lib/zend/Zend/Validate/Hostname/Hu.php create mode 100644 lib/zend/Zend/Validate/Hostname/Interface.php create mode 100644 lib/zend/Zend/Validate/Hostname/Li.php create mode 100644 lib/zend/Zend/Validate/Hostname/No.php create mode 100644 lib/zend/Zend/Validate/Hostname/Se.php create mode 100644 lib/zend/Zend/Validate/Interface.php create mode 100644 lib/zend/Zend/Validate/Ip.php create mode 100644 lib/zend/Zend/Version.php create mode 100755 portfolio/type/gdata/lib.php create mode 100755 portfolio/type/gdata/version.php diff --git a/lib/zend/Zend/Exception.php b/lib/zend/Zend/Exception.php new file mode 100644 index 0000000000..599d8a033e --- /dev/null +++ b/lib/zend/Zend/Exception.php @@ -0,0 +1,30 @@ + '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 index 0000000000..9d826c4e18 --- /dev/null +++ b/lib/zend/Zend/Gdata/App.php @@ -0,0 +1,804 @@ +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 index 0000000000..ac19d52aa1 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/AuthException.php @@ -0,0 +1,40 @@ + '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 index 0000000000..772f589cd0 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/BaseMediaSource.php @@ -0,0 +1,176 @@ +_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 index 0000000000..02b8147c75 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/CaptchaRequiredException.php @@ -0,0 +1,91 @@ +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 index 0000000000..2fe1740a91 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Entry.php @@ -0,0 +1,307 @@ +_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 index 0000000000..01f3591f91 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Exception.php @@ -0,0 +1,40 @@ +_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 index 0000000000..e42dbf7d6f --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Content.php @@ -0,0 +1,85 @@ +_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 index 0000000000..9c219dc719 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Contributor.php @@ -0,0 +1,40 @@ +_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 index 0000000000..c002bffefa --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Draft.php @@ -0,0 +1,47 @@ +_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 index 0000000000..b936124756 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Element.php @@ -0,0 +1,55 @@ +_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 index 0000000000..953679d0c1 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Email.php @@ -0,0 +1,46 @@ +_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 index 0000000000..b8d15492b8 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Generator.php @@ -0,0 +1,112 @@ +_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 index 0000000000..44324b7bb8 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Icon.php @@ -0,0 +1,46 @@ +_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 index 0000000000..446489c2e3 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Id.php @@ -0,0 +1,46 @@ +_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 index 0000000000..829e61443c --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Link.php @@ -0,0 +1,216 @@ +_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 index 0000000000..9d19e59df4 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Logo.php @@ -0,0 +1,46 @@ +_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 index 0000000000..c726072790 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Name.php @@ -0,0 +1,45 @@ +_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 index 0000000000..294125d5c0 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Person.php @@ -0,0 +1,160 @@ +_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 index 0000000000..7072538668 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Published.php @@ -0,0 +1,46 @@ +_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 index 0000000000..a050d5da27 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Rights.php @@ -0,0 +1,46 @@ +_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 index 0000000000..5df072fe0e --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Source.php @@ -0,0 +1,43 @@ +_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 index 0000000000..de0856b26a --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Title.php @@ -0,0 +1,40 @@ +_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 index 0000000000..03a0d32c7c --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Extension/Uri.php @@ -0,0 +1,46 @@ +_text = $text; + } + +} diff --git a/lib/zend/Zend/Gdata/App/Feed.php b/lib/zend/Zend/Gdata/App/Feed.php new file mode 100644 index 0000000000..4e2900c392 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/Feed.php @@ -0,0 +1,264 @@ +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 index 0000000000..64ce5c5c34 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/FeedEntryParent.php @@ -0,0 +1,525 @@ +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 index 0000000000..d4e52a89bd --- /dev/null +++ b/lib/zend/Zend/Gdata/App/FeedSourceParent.php @@ -0,0 +1,245 @@ +_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 index 0000000000..c585e46dd9 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/HttpException.php @@ -0,0 +1,118 @@ +_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 index 0000000000..d78aa53951 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/IOException.php @@ -0,0 +1,40 @@ +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 index 0000000000..fe57438e47 --- /dev/null +++ b/lib/zend/Zend/Gdata/App/MediaEntry.php @@ -0,0 +1,160 @@ +_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 index 0000000000..2970d764bb --- /dev/null +++ b/lib/zend/Zend/Gdata/App/MediaFileSource.php @@ -0,0 +1,143 @@ +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 index 0000000000..c92e15a69c --- /dev/null +++ b/lib/zend/Zend/Gdata/App/MediaSource.php @@ -0,0 +1,70 @@ + 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 index 0000000000..4cc1d9abba --- /dev/null +++ b/lib/zend/Zend/Gdata/AuthSub.php @@ -0,0 +1,222 @@ +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 index 0000000000..18c4358db4 --- /dev/null +++ b/lib/zend/Zend/Gdata/ClientLogin.php @@ -0,0 +1,180 @@ +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 index 0000000000..cd63e8df80 --- /dev/null +++ b/lib/zend/Zend/Gdata/Docs.php @@ -0,0 +1,254 @@ +'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 index 0000000000..d483e3f8ac --- /dev/null +++ b/lib/zend/Zend/Gdata/Docs/DocumentListEntry.php @@ -0,0 +1,53 @@ + $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 index 0000000000..974588d528 --- /dev/null +++ b/lib/zend/Zend/Gdata/Docs/DocumentListFeed.php @@ -0,0 +1,67 @@ + $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 index 0000000000..3d6d9fd40a --- /dev/null +++ b/lib/zend/Zend/Gdata/Docs/Query.php @@ -0,0 +1,219 @@ +_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 index 0000000000..ee53467f2a --- /dev/null +++ b/lib/zend/Zend/Gdata/Entry.php @@ -0,0 +1,48 @@ + $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 index 0000000000..fdeb173923 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension.php @@ -0,0 +1,52 @@ +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 index 0000000000..8617ddff98 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/AttendeeStatus.php @@ -0,0 +1,120 @@ +_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 index 0000000000..7c6b6a0e30 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/AttendeeType.php @@ -0,0 +1,120 @@ +_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 index 0000000000..69ed62c03b --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Comments.php @@ -0,0 +1,114 @@ +_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 index 0000000000..c00291fcd1 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/EntryLink.php @@ -0,0 +1,164 @@ +_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 index 0000000000..579efc21eb --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/EventStatus.php @@ -0,0 +1,98 @@ +_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 index 0000000000..05fa95cd0d --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/ExtendedProperty.php @@ -0,0 +1,103 @@ +_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 index 0000000000..b307f41866 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/FeedLink.php @@ -0,0 +1,172 @@ +_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 index 0000000000..443cb1f107 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/OpenSearchItemsPerPage.php @@ -0,0 +1,47 @@ +_text = $text; + } + +} diff --git a/lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php b/lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php new file mode 100644 index 0000000000..249bd037c5 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/OpenSearchStartIndex.php @@ -0,0 +1,47 @@ +_text = $text; + } + +} diff --git a/lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php b/lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php new file mode 100644 index 0000000000..fb88012427 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/OpenSearchTotalResults.php @@ -0,0 +1,47 @@ +_text = $text; + } + +} diff --git a/lib/zend/Zend/Gdata/Extension/OriginalEvent.php b/lib/zend/Zend/Gdata/Extension/OriginalEvent.php new file mode 100644 index 0000000000..bea57acfdd --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/OriginalEvent.php @@ -0,0 +1,139 @@ +_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 index 0000000000..2e86725cfe --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Rating.php @@ -0,0 +1,142 @@ +_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 index 0000000000..4bb7760601 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Recurrence.php @@ -0,0 +1,46 @@ +_text = $text; + } + +} diff --git a/lib/zend/Zend/Gdata/Extension/RecurrenceException.php b/lib/zend/Zend/Gdata/Extension/RecurrenceException.php new file mode 100644 index 0000000000..0d9d93902a --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/RecurrenceException.php @@ -0,0 +1,202 @@ +_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 index 0000000000..50639d6682 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Reminder.php @@ -0,0 +1,168 @@ +_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 index 0000000000..8cf1c7bc2c --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Transparency.php @@ -0,0 +1,120 @@ +_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 index 0000000000..9a0c0a7665 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Visibility.php @@ -0,0 +1,120 @@ +_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 index 0000000000..d61825ad1d --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/When.php @@ -0,0 +1,166 @@ +_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 index 0000000000..a675c22fd4 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Where.php @@ -0,0 +1,163 @@ +_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 index 0000000000..5793097606 --- /dev/null +++ b/lib/zend/Zend/Gdata/Extension/Who.php @@ -0,0 +1,291 @@ +_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 index 0000000000..25764ecf62 --- /dev/null +++ b/lib/zend/Zend/Gdata/Feed.php @@ -0,0 +1,167 @@ + $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 index 0000000000..bdfc8d316a --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase.php @@ -0,0 +1,200 @@ + '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 index 0000000000..41492a0500 --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/Entry.php @@ -0,0 +1,150 @@ + $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 index 0000000000..51ef2991dc --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/Extension/BaseAttribute.php @@ -0,0 +1,115 @@ + $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: + * <g:[$name] type='[$type]'>[$value]</g:[$name]> + * + * @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: + * <g:[$name] type='[$type]'>[$value]</g:[$name]> + * + * @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 index 0000000000..bcb753aa61 --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/Feed.php @@ -0,0 +1,59 @@ + $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 index 0000000000..7961de4b00 --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/ItemEntry.php @@ -0,0 +1,147 @@ +addGbaseAttribute('item_type', $value, 'text'); + return $this; + } + + /** + * Adds a custom attribute to the entry in the following format: + * <g:[$name] type='[$type]'>[$value]</g:[$name]> + * + * @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 index 0000000000..eea296d587 --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/ItemFeed.php @@ -0,0 +1,45 @@ +_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 index 0000000000..1b22eb3d7f --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/Query.php @@ -0,0 +1,265 @@ +_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 index 0000000000..22b81b987d --- /dev/null +++ b/lib/zend/Zend/Gdata/Gbase/SnippetEntry.php @@ -0,0 +1,45 @@ +_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 index 0000000000..bf5a76e912 --- /dev/null +++ b/lib/zend/Zend/Gdata/HttpClient.php @@ -0,0 +1,245 @@ +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 index 0000000000..f271f9b6c7 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media.php @@ -0,0 +1,56 @@ + '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 index 0000000000..cb462aee85 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Entry.php @@ -0,0 +1,133 @@ + $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 index 0000000000..352d31f29c --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaCategory.php @@ -0,0 +1,147 @@ + $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 index 0000000000..66b18b61c9 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaContent.php @@ -0,0 +1,521 @@ + $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 index 0000000000..05504c4804 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaCopyright.php @@ -0,0 +1,115 @@ + $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 index 0000000000..bf765451e0 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaCredit.php @@ -0,0 +1,148 @@ + $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 index 0000000000..020388bde9 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaDescription.php @@ -0,0 +1,115 @@ + $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 index 0000000000..ce5bcd9c20 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaGroup.php @@ -0,0 +1,565 @@ + $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 index 0000000000..bbd58bebf2 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaHash.php @@ -0,0 +1,114 @@ + $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 index 0000000000..7b734bf804 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaKeywords.php @@ -0,0 +1,51 @@ + $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 index 0000000000..de208f8c07 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaPlayer.php @@ -0,0 +1,177 @@ + $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 index 0000000000..6f4048a22e --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaRating.php @@ -0,0 +1,117 @@ + $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 index 0000000000..76df5e8c14 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaRestriction.php @@ -0,0 +1,148 @@ + $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 index 0000000000..b1b426204a --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaText.php @@ -0,0 +1,210 @@ + $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 index 0000000000..b650102a73 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaThumbnail.php @@ -0,0 +1,209 @@ + $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 index 0000000000..06bf6f6d79 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Extension/MediaTitle.php @@ -0,0 +1,117 @@ + $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 index 0000000000..518fb30279 --- /dev/null +++ b/lib/zend/Zend/Gdata/Media/Feed.php @@ -0,0 +1,69 @@ + $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 index 0000000000..3e97762725 --- /dev/null +++ b/lib/zend/Zend/Gdata/Query.php @@ -0,0 +1,415 @@ +_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 index 0000000000..d0df9429a7 --- /dev/null +++ b/lib/zend/Zend/Http/Client.php @@ -0,0 +1,1194 @@ + 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: + * + * $this->setAuth('shahar', 'secret', Zend_Http_Client::AUTH_BASIC); + * + * + * To disable authentication: + * + * $this->setAuth(false); + * + * + * @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 index 0000000000..89eb95b0a9 --- /dev/null +++ b/lib/zend/Zend/Http/Client/Adapter/Exception.php @@ -0,0 +1,33 @@ + '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 index 0000000000..544fbebd80 --- /dev/null +++ b/lib/zend/Zend/Http/Client/Adapter/Socket.php @@ -0,0 +1,337 @@ + 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 index 0000000000..aad25f203f --- /dev/null +++ b/lib/zend/Zend/Http/Client/Adapter/Test.php @@ -0,0 +1,193 @@ + $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 index 0000000000..357305745c --- /dev/null +++ b/lib/zend/Zend/Http/Client/Exception.php @@ -0,0 +1,33 @@ + '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", "
") + * @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", "
") + * @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 index 0000000000..9e708136e6 --- /dev/null +++ b/lib/zend/Zend/Loader.php @@ -0,0 +1,258 @@ + $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: + * + * spl_autoload_register(array('Zend_Loader', 'autoload')); + * + * + * @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 index 0000000000..499ff21b6a --- /dev/null +++ b/lib/zend/Zend/Mime.php @@ -0,0 +1,252 @@ + $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 index 0000000000..0d0dda86a0 --- /dev/null +++ b/lib/zend/Zend/Mime/Decode.php @@ -0,0 +1,243 @@ + 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 index 0000000000..2c22e9b9dd --- /dev/null +++ b/lib/zend/Zend/Mime/Exception.php @@ -0,0 +1,36 @@ +_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 index 0000000000..4149533ed8 --- /dev/null +++ b/lib/zend/Zend/Mime/Part.php @@ -0,0 +1,218 @@ +_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 index 0000000000..11bba274b7 --- /dev/null +++ b/lib/zend/Zend/Registry.php @@ -0,0 +1,195 @@ +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 index 0000000000..92300684e6 --- /dev/null +++ b/lib/zend/Zend/Uri.php @@ -0,0 +1,164 @@ +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 index 0000000000..fe9a2713cf --- /dev/null +++ b/lib/zend/Zend/Uri/Exception.php @@ -0,0 +1,37 @@ +_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 index 0000000000..31255108e8 --- /dev/null +++ b/lib/zend/Zend/Validate/Abstract.php @@ -0,0 +1,348 @@ +_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 index 0000000000..2f6468e2bc --- /dev/null +++ b/lib/zend/Zend/Validate/Hostname.php @@ -0,0 +1,444 @@ + "'%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 index 0000000000..c1e1f003a7 --- /dev/null +++ b/lib/zend/Zend/Validate/Hostname/At.php @@ -0,0 +1,50 @@ + "'%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 index 0000000000..1a107308f6 --- /dev/null +++ b/lib/zend/Zend/Version.php @@ -0,0 +1,51 @@ +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 index 0000000000..1a00826079 --- /dev/null +++ b/portfolio/type/gdata/version.php @@ -0,0 +1,7 @@ +version = 2008072500; +$plugin->requires = 2008072500; +$plugin->cron = 0; + +?> -- 2.39.5