*prechod na novsiu verziu ZF
[sport-group.git] / library / Zend / Gdata / App.php
blob2df94fa5e752e7be4a787d068a4edb3f2804f774
1 <?php
3 /**
4 * Zend Framework
6 * LICENSE
8 * This source file is subject to the new BSD license that is bundled
9 * with this package in the file LICENSE.txt.
10 * It is also available through the world-wide-web at this URL:
11 * http://framework.zend.com/license/new-bsd
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@zend.com so we can send you a copy immediately.
16 * @category Zend
17 * @package Zend_Gdata
18 * @subpackage App
19 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
20 * @license http://framework.zend.com/license/new-bsd New BSD License
21 * @version $Id: App.php 16971 2009-07-22 18:05:45Z mikaelkael $
24 /**
25 * Zend_Gdata_Feed
27 require_once 'Zend/Gdata/App/Feed.php';
29 /**
30 * Zend_Gdata_Http_Client
32 require_once 'Zend/Http/Client.php';
34 /**
35 * Zend_Version
37 require_once 'Zend/Version.php';
39 /**
40 * Zend_Gdata_App_MediaSource
42 require_once 'Zend/Gdata/App/MediaSource.php';
44 /**
45 * Provides Atom Publishing Protocol (APP) functionality. This class and all
46 * other components of Zend_Gdata_App are designed to work independently from
47 * other Zend_Gdata components in order to interact with generic APP services.
49 * @category Zend
50 * @package Zend_Gdata
51 * @subpackage App
52 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
53 * @license http://framework.zend.com/license/new-bsd New BSD License
55 class Zend_Gdata_App
58 /** Default major protocol version.
60 * @see _majorProtocolVersion
62 const DEFAULT_MAJOR_PROTOCOL_VERSION = 1;
64 /** Default minor protocol version.
66 * @see _minorProtocolVersion
68 const DEFAULT_MINOR_PROTOCOL_VERSION = null;
70 /**
71 * Client object used to communicate
73 * @var Zend_Http_Client
75 protected $_httpClient;
77 /**
78 * Client object used to communicate in static context
80 * @var Zend_Http_Client
82 protected static $_staticHttpClient = null;
84 /**
85 * Override HTTP PUT and DELETE request methods?
87 * @var boolean
89 protected static $_httpMethodOverride = false;
91 /**
92 * Enable gzipped responses?
94 * @var boolean
96 protected static $_gzipEnabled = false;
98 /**
99 * Use verbose exception messages. In the case of HTTP errors,
100 * use the body of the HTTP response in the exception message.
102 * @var boolean
104 protected static $_verboseExceptionMessages = true;
107 * Default URI to which to POST.
109 * @var string
111 protected $_defaultPostUri = null;
114 * Packages to search for classes when using magic __call method, in order.
116 * @var array
118 protected $_registeredPackages = array(
119 'Zend_Gdata_App_Extension',
120 'Zend_Gdata_App');
123 * Maximum number of redirects to follow during HTTP operations
125 * @var int
127 protected static $_maxRedirects = 5;
130 * Indicates the major protocol version that should be used.
131 * At present, recognized values are either 1 or 2. However, any integer
132 * value >= 1 is considered valid.
134 * Under most circumtances, this will be automatically set by
135 * Zend_Gdata_App subclasses.
137 * @see setMajorProtocolVersion()
138 * @see getMajorProtocolVersion()
140 protected $_majorProtocolVersion;
143 * Indicates the minor protocol version that should be used. Can be set
144 * to either an integer >= 0, or NULL if no minor version should be sent
145 * to the server.
147 * At present, this field is not used by any Google services, but may be
148 * used in the future.
150 * Under most circumtances, this will be automatically set by
151 * Zend_Gdata_App subclasses.
153 * @see setMinorProtocolVersion()
154 * @see getMinorProtocolVersion()
156 protected $_minorProtocolVersion;
159 * Whether we want to use XML to object mapping when fetching data.
161 * @var boolean
163 protected $_useObjectMapping = true;
166 * Create Gdata object
168 * @param Zend_Http_Client $client
169 * @param string $applicationId
171 public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0')
173 $this->setHttpClient($client, $applicationId);
174 // Set default protocol version. Subclasses should override this as
175 // needed once a given service supports a new version.
176 $this->setMajorProtocolVersion(self::DEFAULT_MAJOR_PROTOCOL_VERSION);
177 $this->setMinorProtocolVersion(self::DEFAULT_MINOR_PROTOCOL_VERSION);
181 * Adds a Zend Framework package to the $_registeredPackages array.
182 * This array is searched when using the magic __call method below
183 * to instantiante new objects.
185 * @param string $name The name of the package (eg Zend_Gdata_App)
186 * @return void
188 public function registerPackage($name)
190 array_unshift($this->_registeredPackages, $name);
194 * Retrieve feed as string or object
196 * @param string $uri The uri from which to retrieve the feed
197 * @param string $className The class which is used as the return type
198 * @return string|Zend_Gdata_App_Feed Returns string only if the object
199 * mapping has been disabled explicitly
200 * by passing false to the
201 * useObjectMapping() function.
203 public function getFeed($uri, $className='Zend_Gdata_App_Feed')
205 return $this->importUrl($uri, $className, null);
209 * Retrieve entry as string or object
211 * @param string $uri
212 * @param string $className The class which is used as the return type
213 * @return string|Zend_Gdata_App_Entry Returns string only if the object
214 * mapping has been disabled explicitly
215 * by passing false to the
216 * useObjectMapping() function.
218 public function getEntry($uri, $className='Zend_Gdata_App_Entry')
220 return $this->importUrl($uri, $className, null);
224 * Get the Zend_Http_Client object used for communication
226 * @return Zend_Http_Client
228 public function getHttpClient()
230 return $this->_httpClient;
234 * Set the Zend_Http_Client object used for communication
236 * @param Zend_Http_Client $client The client to use for communication
237 * @throws Zend_Gdata_App_HttpException
238 * @return Zend_Gdata_App Provides a fluent interface
240 public function setHttpClient($client,
241 $applicationId = 'MyCompany-MyApp-1.0')
243 if ($client === null) {
244 $client = new Zend_Http_Client();
246 if (!$client instanceof Zend_Http_Client) {
247 require_once 'Zend/Gdata/App/HttpException.php';
248 throw new Zend_Gdata_App_HttpException(
249 'Argument is not an instance of Zend_Http_Client.');
251 $userAgent = $applicationId . ' Zend_Framework_Gdata/' .
252 Zend_Version::VERSION;
253 $client->setHeaders('User-Agent', $userAgent);
254 $client->setConfig(array(
255 'strictredirects' => true
258 $this->_httpClient = $client;
259 Zend_Gdata::setStaticHttpClient($client);
260 return $this;
264 * Set the static HTTP client instance
266 * Sets the static HTTP client object to use for retrieving the feed.
268 * @param Zend_Http_Client $httpClient
269 * @return void
271 public static function setStaticHttpClient(Zend_Http_Client $httpClient)
273 self::$_staticHttpClient = $httpClient;
278 * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used.
280 * @return Zend_Http_Client
282 public static function getStaticHttpClient()
284 if (!self::$_staticHttpClient instanceof Zend_Http_Client) {
285 $client = new Zend_Http_Client();
286 $userAgent = 'Zend_Framework_Gdata/' . Zend_Version::VERSION;
287 $client->setHeaders('User-Agent', $userAgent);
288 $client->setConfig(array(
289 'strictredirects' => true
292 self::$_staticHttpClient = $client;
294 return self::$_staticHttpClient;
298 * Toggle using POST instead of PUT and DELETE HTTP methods
300 * Some feed implementations do not accept PUT and DELETE HTTP
301 * methods, or they can't be used because of proxies or other
302 * measures. This allows turning on using POST where PUT and
303 * DELETE would normally be used; in addition, an
304 * X-Method-Override header will be sent with a value of PUT or
305 * DELETE as appropriate.
307 * @param boolean $override Whether to override PUT and DELETE with POST.
308 * @return void
310 public static function setHttpMethodOverride($override = true)
312 self::$_httpMethodOverride = $override;
316 * Get the HTTP override state
318 * @return boolean
320 public static function getHttpMethodOverride()
322 return self::$_httpMethodOverride;
326 * Toggle requesting gzip encoded responses
328 * @param boolean $enabled Whether or not to enable gzipped responses
329 * @return void
331 public static function setGzipEnabled($enabled = false)
333 if ($enabled && !function_exists('gzinflate')) {
334 require_once 'Zend/Gdata/App/InvalidArgumentException.php';
335 throw new Zend_Gdata_App_InvalidArgumentException(
336 'You cannot enable gzipped responses if the zlib module ' .
337 'is not enabled in your PHP installation.');
340 self::$_gzipEnabled = $enabled;
344 * Get the HTTP override state
346 * @return boolean
348 public static function getGzipEnabled()
350 return self::$_gzipEnabled;
354 * Get whether to use verbose exception messages
356 * In the case of HTTP errors, use the body of the HTTP response
357 * in the exception message.
359 * @return boolean
361 public static function getVerboseExceptionMessages()
363 return self::$_verboseExceptionMessages;
367 * Set whether to use verbose exception messages
369 * In the case of HTTP errors, use the body of the HTTP response
370 * in the exception message.
372 * @param boolean $verbose Whether to use verbose exception messages
374 public static function setVerboseExceptionMessages($verbose)
376 self::$_verboseExceptionMessages = $verbose;
380 * Set the maximum number of redirects to follow during HTTP operations
382 * @param int $maxRedirects Maximum number of redirects to follow
383 * @return void
385 public static function setMaxRedirects($maxRedirects)
387 self::$_maxRedirects = $maxRedirects;
391 * Get the maximum number of redirects to follow during HTTP operations
393 * @return int Maximum number of redirects to follow
395 public static function getMaxRedirects()
397 return self::$_maxRedirects;
401 * Set the major protocol version that should be used. Values < 1 will
402 * cause a Zend_Gdata_App_InvalidArgumentException to be thrown.
404 * @see _majorProtocolVersion
405 * @param int $value The major protocol version to use.
406 * @throws Zend_Gdata_App_InvalidArgumentException
408 public function setMajorProtocolVersion($value)
410 if (!($value >= 1)) {
411 require_once('Zend/Gdata/App/InvalidArgumentException.php');
412 throw new Zend_Gdata_App_InvalidArgumentException(
413 'Major protocol version must be >= 1');
415 $this->_majorProtocolVersion = $value;
419 * Get the major protocol version that is in use.
421 * @see _majorProtocolVersion
422 * @return int The major protocol version in use.
424 public function getMajorProtocolVersion()
426 return $this->_majorProtocolVersion;
430 * Set the minor protocol version that should be used. If set to NULL, no
431 * minor protocol version will be sent to the server. Values < 0 will
432 * cause a Zend_Gdata_App_InvalidArgumentException to be thrown.
434 * @see _minorProtocolVersion
435 * @param (int|NULL) $value The minor protocol version to use.
436 * @throws Zend_Gdata_App_InvalidArgumentException
438 public function setMinorProtocolVersion($value)
440 if (!($value >= 0)) {
441 require_once('Zend/Gdata/App/InvalidArgumentException.php');
442 throw new Zend_Gdata_App_InvalidArgumentException(
443 'Minor protocol version must be >= 0');
445 $this->_minorProtocolVersion = $value;
449 * Get the minor protocol version that is in use.
451 * @see _minorProtocolVersion
452 * @return (int|NULL) The major protocol version in use, or NULL if no
453 * minor version is specified.
455 public function getMinorProtocolVersion()
457 return $this->_minorProtocolVersion;
461 * Provides pre-processing for HTTP requests to APP services.
463 * 1. Checks the $data element and, if it's an entry, extracts the XML,
464 * multipart data, edit link (PUT,DELETE), etc.
465 * 2. If $data is a string, sets the default content-type header as
466 * 'application/atom+xml' if it's not already been set.
467 * 3. Adds a x-http-method override header and changes the HTTP method
468 * to 'POST' if necessary as per getHttpMethodOverride()
470 * @param string $method The HTTP method for the request - 'GET', 'POST',
471 * 'PUT', 'DELETE'
472 * @param string $url The URL to which this request is being performed,
473 * or null if found in $data
474 * @param array $headers An associative array of HTTP headers for this
475 * request
476 * @param mixed $data The Zend_Gdata_App_Entry or XML for the
477 * body of the request
478 * @param string $contentTypeOverride The override value for the
479 * content type of the request body
480 * @return array An associative array containing the determined
481 * 'method', 'url', 'data', 'headers', 'contentType'
483 public function prepareRequest($method,
484 $url = null,
485 $headers = array(),
486 $data = null,
487 $contentTypeOverride = null)
489 // As a convenience, if $headers is null, we'll convert it back to
490 // an empty array.
491 if ($headers === null) {
492 $headers = array();
495 $rawData = null;
496 $finalContentType = null;
497 if ($url == null) {
498 $url = $this->_defaultPostUri;
501 if (is_string($data)) {
502 $rawData = $data;
503 if ($contentTypeOverride === null) {
504 $finalContentType = 'application/atom+xml';
506 } elseif ($data instanceof Zend_Gdata_App_MediaEntry) {
507 $rawData = $data->encode();
508 if ($data->getMediaSource() !== null) {
509 $finalContentType = $rawData->getContentType();
510 $headers['MIME-version'] = '1.0';
511 $headers['Slug'] = $data->getMediaSource()->getSlug();
512 } else {
513 $finalContentType = 'application/atom+xml';
515 if ($method == 'PUT' || $method == 'DELETE') {
516 $editLink = $data->getEditLink();
517 if ($editLink != null && $url == null) {
518 $url = $editLink->getHref();
521 } elseif ($data instanceof Zend_Gdata_App_Entry) {
522 $rawData = $data->saveXML();
523 $finalContentType = 'application/atom+xml';
524 if ($method == 'PUT' || $method == 'DELETE') {
525 $editLink = $data->getEditLink();
526 if ($editLink != null) {
527 $url = $editLink->getHref();
530 } elseif ($data instanceof Zend_Gdata_App_MediaSource) {
531 $rawData = $data->encode();
532 if ($data->getSlug() !== null) {
533 $headers['Slug'] = $data->getSlug();
535 $finalContentType = $data->getContentType();
538 if ($method == 'DELETE') {
539 $rawData = null;
542 // Set an If-Match header if:
543 // - This isn't a DELETE
544 // - If this isn't a GET, the Etag isn't weak
545 // - A similar header (If-Match/If-None-Match) hasn't already been
546 // set.
547 if ($method != 'DELETE' && (
548 !array_key_exists('If-Match', $headers) &&
549 !array_key_exists('If-None-Match', $headers)
550 ) ) {
551 $allowWeak = $method == 'GET';
552 if ($ifMatchHeader = $this->generateIfMatchHeaderData(
553 $data, $allowWeak)) {
554 $headers['If-Match'] = $ifMatchHeader;
558 if ($method != 'POST' && $method != 'GET' && Zend_Gdata_App::getHttpMethodOverride()) {
559 $headers['x-http-method-override'] = $method;
560 $method = 'POST';
561 } else {
562 $headers['x-http-method-override'] = null;
565 if ($contentTypeOverride != null) {
566 $finalContentType = $contentTypeOverride;
569 return array('method' => $method, 'url' => $url,
570 'data' => $rawData, 'headers' => $headers,
571 'contentType' => $finalContentType);
575 * Performs a HTTP request using the specified method
577 * @param string $method The HTTP method for the request - 'GET', 'POST',
578 * 'PUT', 'DELETE'
579 * @param string $url The URL to which this request is being performed
580 * @param array $headers An associative array of HTTP headers
581 * for this request
582 * @param string $body The body of the HTTP request
583 * @param string $contentType The value for the content type
584 * of the request body
585 * @param int $remainingRedirects Number of redirects to follow if request
586 * s results in one
587 * @return Zend_Http_Response The response object
589 public function performHttpRequest($method, $url, $headers = null,
590 $body = null, $contentType = null, $remainingRedirects = null)
592 require_once 'Zend/Http/Client/Exception.php';
593 if ($remainingRedirects === null) {
594 $remainingRedirects = self::getMaxRedirects();
596 if ($headers === null) {
597 $headers = array();
599 // Append a Gdata version header if protocol v2 or higher is in use.
600 // (Protocol v1 does not use this header.)
601 $major = $this->getMajorProtocolVersion();
602 $minor = $this->getMinorProtocolVersion();
603 if ($major >= 2) {
604 $headers['GData-Version'] = $major +
605 (($minor === null) ? '.' + $minor : '');
608 // check the overridden method
609 if (($method == 'POST' || $method == 'PUT') && $body === null &&
610 $headers['x-http-method-override'] != 'DELETE') {
611 require_once 'Zend/Gdata/App/InvalidArgumentException.php';
612 throw new Zend_Gdata_App_InvalidArgumentException(
613 'You must specify the data to post as either a ' .
614 'string or a child of Zend_Gdata_App_Entry');
616 if ($url === null) {
617 require_once 'Zend/Gdata/App/InvalidArgumentException.php';
618 throw new Zend_Gdata_App_InvalidArgumentException(
619 'You must specify an URI to which to post.');
621 $headers['Content-Type'] = $contentType;
622 if (Zend_Gdata_App::getGzipEnabled()) {
623 // some services require the word 'gzip' to be in the user-agent
624 // header in addition to the accept-encoding header
625 if (strpos($this->_httpClient->getHeader('User-Agent'),
626 'gzip') === false) {
627 $headers['User-Agent'] =
628 $this->_httpClient->getHeader('User-Agent') . ' (gzip)';
630 $headers['Accept-encoding'] = 'gzip, deflate';
631 } else {
632 $headers['Accept-encoding'] = 'identity';
635 // Make sure the HTTP client object is 'clean' before making a request
636 // In addition to standard headers to reset via resetParameters(),
637 // also reset the Slug header
638 $this->_httpClient->resetParameters();
639 $this->_httpClient->setHeaders('Slug', null);
641 // Set the params for the new request to be performed
642 $this->_httpClient->setHeaders($headers);
643 $this->_httpClient->setUri($url);
644 $this->_httpClient->setConfig(array('maxredirects' => 0));
646 // Set the proper adapter if we are handling a streaming upload
647 $usingMimeStream = false;
648 $oldHttpAdapter = null;
650 if ($body instanceof Zend_Gdata_MediaMimeStream) {
651 $usingMimeStream = true;
652 $this->_httpClient->setRawDataStream($body, $contentType);
653 $oldHttpAdapter = $this->_httpClient->getAdapter();
655 if ($oldHttpAdapter instanceof Zend_Http_Client_Adapter_Proxy) {
656 require_once 'Zend/Gdata/HttpAdapterStreamingProxy.php';
657 $newAdapter = new Zend_Gdata_HttpAdapterStreamingProxy();
658 } else {
659 require_once 'Zend/Gdata/HttpAdapterStreamingSocket.php';
660 $newAdapter = new Zend_Gdata_HttpAdapterStreamingSocket();
662 $this->_httpClient->setAdapter($newAdapter);
663 } else {
664 $this->_httpClient->setRawData($body, $contentType);
667 try {
668 $response = $this->_httpClient->request($method);
669 // reset adapter
670 if ($usingMimeStream) {
671 $this->_httpClient->setAdapter($oldHttpAdapter);
673 } catch (Zend_Http_Client_Exception $e) {
674 // reset adapter
675 if ($usingMimeStream) {
676 $this->_httpClient->setAdapter($oldHttpAdapter);
678 require_once 'Zend/Gdata/App/HttpException.php';
679 throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
681 if ($response->isRedirect() && $response->getStatus() != '304') {
682 if ($remainingRedirects > 0) {
683 $newUrl = $response->getHeader('Location');
684 $response = $this->performHttpRequest(
685 $method, $newUrl, $headers, $body,
686 $contentType, $remainingRedirects);
687 } else {
688 require_once 'Zend/Gdata/App/HttpException.php';
689 throw new Zend_Gdata_App_HttpException(
690 'Number of redirects exceeds maximum', null, $response);
693 if (!$response->isSuccessful()) {
694 require_once 'Zend/Gdata/App/HttpException.php';
695 $exceptionMessage = 'Expected response code 200, got ' .
696 $response->getStatus();
697 if (self::getVerboseExceptionMessages()) {
698 $exceptionMessage .= "\n" . $response->getBody();
700 $exception = new Zend_Gdata_App_HttpException($exceptionMessage);
701 $exception->setResponse($response);
702 throw $exception;
704 return $response;
708 * Imports a feed located at $uri.
710 * @param string $uri
711 * @param Zend_Http_Client $client The client used for communication
712 * @param string $className The class which is used as the return type
713 * @throws Zend_Gdata_App_Exception
714 * @return string|Zend_Gdata_App_Feed Returns string only if the object
715 * mapping has been disabled explicitly
716 * by passing false to the
717 * useObjectMapping() function.
719 public static function import($uri, $client = null,
720 $className='Zend_Gdata_App_Feed')
722 $app = new Zend_Gdata_App($client);
723 $requestData = $app->prepareRequest('GET', $uri);
724 $response = $app->performHttpRequest(
725 $requestData['method'], $requestData['url']);
727 $feedContent = $response->getBody();
728 if (!$this->_useObjectMapping) {
729 return $feedContent;
731 $feed = self::importString($feedContent, $className);
732 if ($client != null) {
733 $feed->setHttpClient($client);
735 return $feed;
739 * Imports the specified URL (non-statically).
741 * @param string $url The URL to import
742 * @param string $className The class which is used as the return type
743 * @param array $extraHeaders Extra headers to add to the request, as an
744 * array of string-based key/value pairs.
745 * @throws Zend_Gdata_App_Exception
746 * @return string|Zend_Gdata_App_Feed Returns string only if the object
747 * mapping has been disabled explicitly
748 * by passing false to the
749 * useObjectMapping() function.
751 public function importUrl($url, $className='Zend_Gdata_App_Feed',
752 $extraHeaders = array())
754 $response = $this->get($url, $extraHeaders);
756 $feedContent = $response->getBody();
757 if (!$this->_useObjectMapping) {
758 return $feedContent;
761 $protocolVersionStr = $response->getHeader('GData-Version');
762 $majorProtocolVersion = null;
763 $minorProtocolVersion = null;
764 if ($protocolVersionStr !== null) {
765 // Extract protocol major and minor version from header
766 $delimiterPos = strpos($protocolVersionStr, '.');
767 $length = strlen($protocolVersionStr);
768 $major = substr($protocolVersionStr, 0, $delimiterPos);
769 $minor = substr($protocolVersionStr, $delimiterPos + 1, $length);
770 $majorProtocolVersion = $major;
771 $minorProtocolVersion = $minor;
774 $feed = self::importString($feedContent, $className,
775 $majorProtocolVersion, $minorProtocolVersion);
776 if ($this->getHttpClient() != null) {
777 $feed->setHttpClient($this->getHttpClient());
779 $etag = $response->getHeader('ETag');
780 if ($etag !== null) {
781 $feed->setEtag($etag);
783 return $feed;
788 * Imports a feed represented by $string.
790 * @param string $string
791 * @param string $className The class which is used as the return type
792 * @param integer $majorProcolVersion (optional) The major protocol version
793 * of the data model object that is to be created.
794 * @param integer $minorProcolVersion (optional) The minor protocol version
795 * of the data model object that is to be created.
796 * @throws Zend_Gdata_App_Exception
797 * @return Zend_Gdata_App_Feed
799 public static function importString($string,
800 $className='Zend_Gdata_App_Feed', $majorProtocolVersion = null,
801 $minorProtocolVersion = null)
803 // Load the feed as an XML DOMDocument object
804 @ini_set('track_errors', 1);
805 $doc = new DOMDocument();
806 $success = @$doc->loadXML($string);
807 @ini_restore('track_errors');
809 if (!$success) {
810 require_once 'Zend/Gdata/App/Exception.php';
811 throw new Zend_Gdata_App_Exception(
812 "DOMDocument cannot parse XML: $php_errormsg");
815 $feed = new $className();
816 $feed->setMajorProtocolVersion($majorProtocolVersion);
817 $feed->setMinorProtocolVersion($minorProtocolVersion);
818 $feed->transferFromXML($string);
819 $feed->setHttpClient(self::getstaticHttpClient());
820 return $feed;
825 * Imports a feed from a file located at $filename.
827 * @param string $filename
828 * @param string $className The class which is used as the return type
829 * @param string $useIncludePath Whether the include_path should be searched
830 * @throws Zend_Gdata_App_Exception
831 * @return Zend_Gdata_App_Feed
833 public static function importFile($filename,
834 $className='Zend_Gdata_App_Feed', $useIncludePath = false)
836 @ini_set('track_errors', 1);
837 $feed = @file_get_contents($filename, $useIncludePath);
838 @ini_restore('track_errors');
839 if ($feed === false) {
840 require_once 'Zend/Gdata/App/Exception.php';
841 throw new Zend_Gdata_App_Exception(
842 "File could not be loaded: $php_errormsg");
844 return self::importString($feed, $className);
848 * GET a URI using client object.
850 * @param string $uri GET URI
851 * @param array $extraHeaders Extra headers to add to the request, as an
852 * array of string-based key/value pairs.
853 * @throws Zend_Gdata_App_HttpException
854 * @return Zend_Http_Response
856 public function get($uri, $extraHeaders = array())
858 $requestData = $this->prepareRequest('GET', $uri, $extraHeaders);
859 return $this->performHttpRequest(
860 $requestData['method'], $requestData['url'],
861 $requestData['headers']);
865 * POST data with client object
867 * @param mixed $data The Zend_Gdata_App_Entry or XML to post
868 * @param string $uri POST URI
869 * @param array $headers Additional HTTP headers to insert.
870 * @param string $contentType Content-type of the data
871 * @param array $extraHeaders Extra headers to add to the request, as an
872 * array of string-based key/value pairs.
873 * @return Zend_Http_Response
874 * @throws Zend_Gdata_App_Exception
875 * @throws Zend_Gdata_App_HttpException
876 * @throws Zend_Gdata_App_InvalidArgumentException
878 public function post($data, $uri = null, $remainingRedirects = null,
879 $contentType = null, $extraHeaders = null)
881 $requestData = $this->prepareRequest(
882 'POST', $uri, $extraHeaders, $data, $contentType);
883 return $this->performHttpRequest(
884 $requestData['method'], $requestData['url'],
885 $requestData['headers'], $requestData['data'],
886 $requestData['contentType']);
890 * PUT data with client object
892 * @param mixed $data The Zend_Gdata_App_Entry or XML to post
893 * @param string $uri PUT URI
894 * @param array $headers Additional HTTP headers to insert.
895 * @param string $contentType Content-type of the data
896 * @param array $extraHeaders Extra headers to add to the request, as an
897 * array of string-based key/value pairs.
898 * @return Zend_Http_Response
899 * @throws Zend_Gdata_App_Exception
900 * @throws Zend_Gdata_App_HttpException
901 * @throws Zend_Gdata_App_InvalidArgumentException
903 public function put($data, $uri = null, $remainingRedirects = null,
904 $contentType = null, $extraHeaders = null)
906 $requestData = $this->prepareRequest(
907 'PUT', $uri, $extraHeaders, $data, $contentType);
908 return $this->performHttpRequest(
909 $requestData['method'], $requestData['url'],
910 $requestData['headers'], $requestData['data'],
911 $requestData['contentType']);
915 * DELETE entry with client object
917 * @param mixed $data The Zend_Gdata_App_Entry or URL to delete
918 * @return void
919 * @throws Zend_Gdata_App_Exception
920 * @throws Zend_Gdata_App_HttpException
921 * @throws Zend_Gdata_App_InvalidArgumentException
923 public function delete($data, $remainingRedirects = null)
925 if (is_string($data)) {
926 $requestData = $this->prepareRequest('DELETE', $data);
927 } else {
928 $headers = array();
930 $requestData = $this->prepareRequest(
931 'DELETE', null, $headers, $data);
933 return $this->performHttpRequest($requestData['method'],
934 $requestData['url'],
935 $requestData['headers'],
937 $requestData['contentType'],
938 $remainingRedirects);
942 * Inserts an entry to a given URI and returns the response as a
943 * fully formed Entry.
945 * @param mixed $data The Zend_Gdata_App_Entry or XML to post
946 * @param string $uri POST URI
947 * @param string $className The class of entry to be returned.
948 * @param array $extraHeaders Extra headers to add to the request, as an
949 * array of string-based key/value pairs.
950 * @return Zend_Gdata_App_Entry The entry returned by the service after
951 * insertion.
953 public function insertEntry($data, $uri, $className='Zend_Gdata_App_Entry',
954 $extraHeaders = array())
956 $response = $this->post($data, $uri, null, null, $extraHeaders);
958 $returnEntry = new $className($response->getBody());
959 $returnEntry->setHttpClient(self::getstaticHttpClient());
961 $etag = $response->getHeader('ETag');
962 if ($etag !== null) {
963 $returnEntry->setEtag($etag);
966 return $returnEntry;
970 * Update an entry
972 * @param mixed $data Zend_Gdata_App_Entry or XML (w/ID and link rel='edit')
973 * @param string|null The URI to send requests to, or null if $data
974 * contains the URI.
975 * @param string|null The name of the class that should be deserialized
976 * from the server response. If null, then 'Zend_Gdata_App_Entry'
977 * will be used.
978 * @param array $extraHeaders Extra headers to add to the request, as an
979 * array of string-based key/value pairs.
980 * @return Zend_Gdata_App_Entry The entry returned from the server
981 * @throws Zend_Gdata_App_Exception
983 public function updateEntry($data, $uri = null, $className = null,
984 $extraHeaders = array())
986 if ($className === null && $data instanceof Zend_Gdata_App_Entry) {
987 $className = get_class($data);
988 } elseif ($className === null) {
989 $className = 'Zend_Gdata_App_Entry';
992 $response = $this->put($data, $uri, null, null, $extraHeaders);
993 $returnEntry = new $className($response->getBody());
994 $returnEntry->setHttpClient(self::getstaticHttpClient());
996 $etag = $response->getHeader('ETag');
997 if ($etag !== null) {
998 $returnEntry->setEtag($etag);
1001 return $returnEntry;
1005 * Provides a magic factory method to instantiate new objects with
1006 * shorter syntax than would otherwise be required by the Zend Framework
1007 * naming conventions. For instance, to construct a new
1008 * Zend_Gdata_Calendar_Extension_Color, a developer simply needs to do
1009 * $gCal->newColor(). For this magic constructor, packages are searched
1010 * in the same order as which they appear in the $_registeredPackages
1011 * array
1013 * @param string $method The method name being called
1014 * @param array $args The arguments passed to the call
1015 * @throws Zend_Gdata_App_Exception
1017 public function __call($method, $args)
1019 if (preg_match('/^new(\w+)/', $method, $matches)) {
1020 $class = $matches[1];
1021 $foundClassName = null;
1022 foreach ($this->_registeredPackages as $name) {
1023 try {
1024 // Autoloading disabled on next line for compatibility
1025 // with magic factories. See ZF-6660.
1026 if (!class_exists($name . '_' . $class, false)) {
1027 require_once 'Zend/Loader.php';
1028 @Zend_Loader::loadClass($name . '_' . $class);
1030 $foundClassName = $name . '_' . $class;
1031 break;
1032 } catch (Zend_Exception $e) {
1033 // package wasn't here- continue searching
1036 if ($foundClassName != null) {
1037 $reflectionObj = new ReflectionClass($foundClassName);
1038 $instance = $reflectionObj->newInstanceArgs($args);
1039 if ($instance instanceof Zend_Gdata_App_FeedEntryParent) {
1040 $instance->setHttpClient($this->_httpClient);
1042 // Propogate version data
1043 $instance->setMajorProtocolVersion(
1044 $this->_majorProtocolVersion);
1045 $instance->setMinorProtocolVersion(
1046 $this->_minorProtocolVersion);
1048 return $instance;
1049 } else {
1050 require_once 'Zend/Gdata/App/Exception.php';
1051 throw new Zend_Gdata_App_Exception(
1052 "Unable to find '${class}' in registered packages");
1054 } else {
1055 require_once 'Zend/Gdata/App/Exception.php';
1056 throw new Zend_Gdata_App_Exception("No such method ${method}");
1061 * Retrieve all entries for a feed, iterating through pages as necessary.
1062 * Be aware that calling this function on a large dataset will take a
1063 * significant amount of time to complete. In some cases this may cause
1064 * execution to timeout without proper precautions in place.
1066 * @param $feed The feed to iterate through.
1067 * @return mixed A new feed of the same type as the one originally
1068 * passed in, containing all relevent entries.
1070 public function retrieveAllEntriesForFeed($feed) {
1071 $feedClass = get_class($feed);
1072 $reflectionObj = new ReflectionClass($feedClass);
1073 $result = $reflectionObj->newInstance();
1074 do {
1075 foreach ($feed as $entry) {
1076 $result->addEntry($entry);
1079 $next = $feed->getLink('next');
1080 if ($next !== null) {
1081 $feed = $this->getFeed($next->href, $feedClass);
1082 } else {
1083 $feed = null;
1086 while ($feed != null);
1087 return $result;
1091 * This method enables logging of requests by changing the
1092 * Zend_Http_Client_Adapter used for performing the requests.
1093 * NOTE: This will not work if you have customized the adapter
1094 * already to use a proxy server or other interface.
1096 * @param $logfile The logfile to use when logging the requests
1098 public function enableRequestDebugLogging($logfile)
1100 $this->_httpClient->setConfig(array(
1101 'adapter' => 'Zend_Gdata_App_LoggingHttpClientAdapterSocket',
1102 'logfile' => $logfile
1107 * Retrieve next set of results based on a given feed.
1109 * @param Zend_Gdata_App_Feed $feed The feed from which to
1110 * retreive the next set of results.
1111 * @param string $className (optional) The class of feed to be returned.
1112 * If null, the next feed (if found) will be the same class as
1113 * the feed that was given as the first argument.
1114 * @return Zend_Gdata_App_Feed|null Returns a
1115 * Zend_Gdata_App_Feed or null if no next set of results
1116 * exists.
1118 public function getNextFeed($feed, $className = null)
1120 $nextLink = $feed->getNextLink();
1121 if (!$nextLink) {
1122 return null;
1124 $nextLinkHref = $nextLink->getHref();
1126 if ($className === null) {
1127 $className = get_class($feed);
1130 return $this->getFeed($nextLinkHref, $className);
1134 * Retrieve previous set of results based on a given feed.
1136 * @param Zend_Gdata_App_Feed $feed The feed from which to
1137 * retreive the previous set of results.
1138 * @param string $className (optional) The class of feed to be returned.
1139 * If null, the previous feed (if found) will be the same class as
1140 * the feed that was given as the first argument.
1141 * @return Zend_Gdata_App_Feed|null Returns a
1142 * Zend_Gdata_App_Feed or null if no previous set of results
1143 * exists.
1145 public function getPreviousFeed($feed, $className = null)
1147 $previousLink = $feed->getPreviousLink();
1148 if (!$previousLink) {
1149 return null;
1151 $previousLinkHref = $previousLink->getHref();
1153 if ($className === null) {
1154 $className = get_class($feed);
1157 return $this->getFeed($previousLinkHref, $className);
1161 * Returns the data for an If-Match header based on the current Etag
1162 * property. If Etags are not supported by the server or cannot be
1163 * extracted from the data, then null will be returned.
1165 * @param boolean $allowWeak If false, then if a weak Etag is detected,
1166 * then return null rather than the Etag.
1167 * @return string|null $data
1169 public function generateIfMatchHeaderData($data, $allowWeek)
1171 $result = '';
1172 // Set an If-Match header if an ETag has been set (version >= 2 only)
1173 if ($this->_majorProtocolVersion >= 2 &&
1174 $data instanceof Zend_Gdata_App_Entry) {
1175 $etag = $data->getEtag();
1176 if (($etag !== null) &&
1177 ($allowWeek || substr($etag, 0, 2) != 'W/')) {
1178 $result = $data->getEtag();
1181 return $result;
1185 * Determine whether service object is using XML to object mapping.
1187 * @return boolean True if service object is using XML to object mapping,
1188 * false otherwise.
1190 public function usingObjectMapping()
1192 return $this->_useObjectMapping;
1196 * Enable/disable the use of XML to object mapping.
1198 * @param boolean $value Pass in true to use the XML to object mapping.
1199 * Pass in false or null to disable it.
1200 * @return void
1202 public function useObjectMapping($value)
1204 if ($value === True) {
1205 $this->_useObjectMapping = true;
1206 } else {
1207 $this->_useObjectMapping = false;