|
1 <?php |
|
2 |
|
3 /** |
|
4 * Zend Framework |
|
5 * |
|
6 * LICENSE |
|
7 * |
|
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. |
|
15 * |
|
16 * @category Zend |
|
17 * @package Zend_Gdata |
|
18 * @subpackage App |
|
19 * @copyright Copyright (c) 2005-2010 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 22972 2010-09-18 20:33:53Z ramon $ |
|
22 */ |
|
23 |
|
24 /** |
|
25 * Zend_Gdata_Feed |
|
26 */ |
|
27 require_once 'Zend/Gdata/App/Feed.php'; |
|
28 |
|
29 /** |
|
30 * Zend_Gdata_Http_Client |
|
31 */ |
|
32 require_once 'Zend/Http/Client.php'; |
|
33 |
|
34 /** |
|
35 * Zend_Version |
|
36 */ |
|
37 require_once 'Zend/Version.php'; |
|
38 |
|
39 /** |
|
40 * Zend_Gdata_App_MediaSource |
|
41 */ |
|
42 require_once 'Zend/Gdata/App/MediaSource.php'; |
|
43 |
|
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. |
|
48 * |
|
49 * @category Zend |
|
50 * @package Zend_Gdata |
|
51 * @subpackage App |
|
52 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
53 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
54 */ |
|
55 class Zend_Gdata_App |
|
56 { |
|
57 |
|
58 /** Default major protocol version. |
|
59 * |
|
60 * @see _majorProtocolVersion |
|
61 */ |
|
62 const DEFAULT_MAJOR_PROTOCOL_VERSION = 1; |
|
63 |
|
64 /** Default minor protocol version. |
|
65 * |
|
66 * @see _minorProtocolVersion |
|
67 */ |
|
68 const DEFAULT_MINOR_PROTOCOL_VERSION = null; |
|
69 |
|
70 /** |
|
71 * Client object used to communicate |
|
72 * |
|
73 * @var Zend_Http_Client |
|
74 */ |
|
75 protected $_httpClient; |
|
76 |
|
77 /** |
|
78 * Client object used to communicate in static context |
|
79 * |
|
80 * @var Zend_Http_Client |
|
81 */ |
|
82 protected static $_staticHttpClient = null; |
|
83 |
|
84 /** |
|
85 * Override HTTP PUT and DELETE request methods? |
|
86 * |
|
87 * @var boolean |
|
88 */ |
|
89 protected static $_httpMethodOverride = false; |
|
90 |
|
91 /** |
|
92 * Enable gzipped responses? |
|
93 * |
|
94 * @var boolean |
|
95 */ |
|
96 protected static $_gzipEnabled = false; |
|
97 |
|
98 /** |
|
99 * Use verbose exception messages. In the case of HTTP errors, |
|
100 * use the body of the HTTP response in the exception message. |
|
101 * |
|
102 * @var boolean |
|
103 */ |
|
104 protected static $_verboseExceptionMessages = true; |
|
105 |
|
106 /** |
|
107 * Default URI to which to POST. |
|
108 * |
|
109 * @var string |
|
110 */ |
|
111 protected $_defaultPostUri = null; |
|
112 |
|
113 /** |
|
114 * Packages to search for classes when using magic __call method, in order. |
|
115 * |
|
116 * @var array |
|
117 */ |
|
118 protected $_registeredPackages = array( |
|
119 'Zend_Gdata_App_Extension', |
|
120 'Zend_Gdata_App'); |
|
121 |
|
122 /** |
|
123 * Maximum number of redirects to follow during HTTP operations |
|
124 * |
|
125 * @var int |
|
126 */ |
|
127 protected static $_maxRedirects = 5; |
|
128 |
|
129 /** |
|
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. |
|
133 * |
|
134 * Under most circumtances, this will be automatically set by |
|
135 * Zend_Gdata_App subclasses. |
|
136 * |
|
137 * @see setMajorProtocolVersion() |
|
138 * @see getMajorProtocolVersion() |
|
139 */ |
|
140 protected $_majorProtocolVersion; |
|
141 |
|
142 /** |
|
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. |
|
146 * |
|
147 * At present, this field is not used by any Google services, but may be |
|
148 * used in the future. |
|
149 * |
|
150 * Under most circumtances, this will be automatically set by |
|
151 * Zend_Gdata_App subclasses. |
|
152 * |
|
153 * @see setMinorProtocolVersion() |
|
154 * @see getMinorProtocolVersion() |
|
155 */ |
|
156 protected $_minorProtocolVersion; |
|
157 |
|
158 /** |
|
159 * Whether we want to use XML to object mapping when fetching data. |
|
160 * |
|
161 * @var boolean |
|
162 */ |
|
163 protected $_useObjectMapping = true; |
|
164 |
|
165 /** |
|
166 * Create Gdata object |
|
167 * |
|
168 * @param Zend_Http_Client $client |
|
169 * @param string $applicationId |
|
170 */ |
|
171 public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0') |
|
172 { |
|
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); |
|
178 } |
|
179 |
|
180 /** |
|
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. |
|
184 * |
|
185 * @param string $name The name of the package (eg Zend_Gdata_App) |
|
186 * @return void |
|
187 */ |
|
188 public function registerPackage($name) |
|
189 { |
|
190 array_unshift($this->_registeredPackages, $name); |
|
191 } |
|
192 |
|
193 /** |
|
194 * Retrieve feed as string or object |
|
195 * |
|
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. |
|
202 */ |
|
203 public function getFeed($uri, $className='Zend_Gdata_App_Feed') |
|
204 { |
|
205 return $this->importUrl($uri, $className, null); |
|
206 } |
|
207 |
|
208 /** |
|
209 * Retrieve entry as string or object |
|
210 * |
|
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. |
|
217 */ |
|
218 public function getEntry($uri, $className='Zend_Gdata_App_Entry') |
|
219 { |
|
220 return $this->importUrl($uri, $className, null); |
|
221 } |
|
222 |
|
223 /** |
|
224 * Get the Zend_Http_Client object used for communication |
|
225 * |
|
226 * @return Zend_Http_Client |
|
227 */ |
|
228 public function getHttpClient() |
|
229 { |
|
230 return $this->_httpClient; |
|
231 } |
|
232 |
|
233 /** |
|
234 * Set the Zend_Http_Client object used for communication |
|
235 * |
|
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 |
|
239 */ |
|
240 public function setHttpClient($client, |
|
241 $applicationId = 'MyCompany-MyApp-1.0') |
|
242 { |
|
243 if ($client === null) { |
|
244 $client = new Zend_Http_Client(); |
|
245 } |
|
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.'); |
|
250 } |
|
251 $userAgent = $applicationId . ' Zend_Framework_Gdata/' . |
|
252 Zend_Version::VERSION; |
|
253 $client->setHeaders('User-Agent', $userAgent); |
|
254 $client->setConfig(array( |
|
255 'strictredirects' => true |
|
256 ) |
|
257 ); |
|
258 $this->_httpClient = $client; |
|
259 self::setStaticHttpClient($client); |
|
260 return $this; |
|
261 } |
|
262 |
|
263 /** |
|
264 * Set the static HTTP client instance |
|
265 * |
|
266 * Sets the static HTTP client object to use for retrieving the feed. |
|
267 * |
|
268 * @param Zend_Http_Client $httpClient |
|
269 * @return void |
|
270 */ |
|
271 public static function setStaticHttpClient(Zend_Http_Client $httpClient) |
|
272 { |
|
273 self::$_staticHttpClient = $httpClient; |
|
274 } |
|
275 |
|
276 |
|
277 /** |
|
278 * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used. |
|
279 * |
|
280 * @return Zend_Http_Client |
|
281 */ |
|
282 public static function getStaticHttpClient() |
|
283 { |
|
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 |
|
290 ) |
|
291 ); |
|
292 self::$_staticHttpClient = $client; |
|
293 } |
|
294 return self::$_staticHttpClient; |
|
295 } |
|
296 |
|
297 /** |
|
298 * Toggle using POST instead of PUT and DELETE HTTP methods |
|
299 * |
|
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. |
|
306 * |
|
307 * @param boolean $override Whether to override PUT and DELETE with POST. |
|
308 * @return void |
|
309 */ |
|
310 public static function setHttpMethodOverride($override = true) |
|
311 { |
|
312 self::$_httpMethodOverride = $override; |
|
313 } |
|
314 |
|
315 /** |
|
316 * Get the HTTP override state |
|
317 * |
|
318 * @return boolean |
|
319 */ |
|
320 public static function getHttpMethodOverride() |
|
321 { |
|
322 return self::$_httpMethodOverride; |
|
323 } |
|
324 |
|
325 /** |
|
326 * Toggle requesting gzip encoded responses |
|
327 * |
|
328 * @param boolean $enabled Whether or not to enable gzipped responses |
|
329 * @return void |
|
330 */ |
|
331 public static function setGzipEnabled($enabled = false) |
|
332 { |
|
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.'); |
|
338 |
|
339 } |
|
340 self::$_gzipEnabled = $enabled; |
|
341 } |
|
342 |
|
343 /** |
|
344 * Get the HTTP override state |
|
345 * |
|
346 * @return boolean |
|
347 */ |
|
348 public static function getGzipEnabled() |
|
349 { |
|
350 return self::$_gzipEnabled; |
|
351 } |
|
352 |
|
353 /** |
|
354 * Get whether to use verbose exception messages |
|
355 * |
|
356 * In the case of HTTP errors, use the body of the HTTP response |
|
357 * in the exception message. |
|
358 * |
|
359 * @return boolean |
|
360 */ |
|
361 public static function getVerboseExceptionMessages() |
|
362 { |
|
363 return self::$_verboseExceptionMessages; |
|
364 } |
|
365 |
|
366 /** |
|
367 * Set whether to use verbose exception messages |
|
368 * |
|
369 * In the case of HTTP errors, use the body of the HTTP response |
|
370 * in the exception message. |
|
371 * |
|
372 * @param boolean $verbose Whether to use verbose exception messages |
|
373 */ |
|
374 public static function setVerboseExceptionMessages($verbose) |
|
375 { |
|
376 self::$_verboseExceptionMessages = $verbose; |
|
377 } |
|
378 |
|
379 /** |
|
380 * Set the maximum number of redirects to follow during HTTP operations |
|
381 * |
|
382 * @param int $maxRedirects Maximum number of redirects to follow |
|
383 * @return void |
|
384 */ |
|
385 public static function setMaxRedirects($maxRedirects) |
|
386 { |
|
387 self::$_maxRedirects = $maxRedirects; |
|
388 } |
|
389 |
|
390 /** |
|
391 * Get the maximum number of redirects to follow during HTTP operations |
|
392 * |
|
393 * @return int Maximum number of redirects to follow |
|
394 */ |
|
395 public static function getMaxRedirects() |
|
396 { |
|
397 return self::$_maxRedirects; |
|
398 } |
|
399 |
|
400 /** |
|
401 * Set the major protocol version that should be used. Values < 1 will |
|
402 * cause a Zend_Gdata_App_InvalidArgumentException to be thrown. |
|
403 * |
|
404 * @see _majorProtocolVersion |
|
405 * @param int $value The major protocol version to use. |
|
406 * @throws Zend_Gdata_App_InvalidArgumentException |
|
407 */ |
|
408 public function setMajorProtocolVersion($value) |
|
409 { |
|
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'); |
|
414 } |
|
415 $this->_majorProtocolVersion = $value; |
|
416 } |
|
417 |
|
418 /** |
|
419 * Get the major protocol version that is in use. |
|
420 * |
|
421 * @see _majorProtocolVersion |
|
422 * @return int The major protocol version in use. |
|
423 */ |
|
424 public function getMajorProtocolVersion() |
|
425 { |
|
426 return $this->_majorProtocolVersion; |
|
427 } |
|
428 |
|
429 /** |
|
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. |
|
433 * |
|
434 * @see _minorProtocolVersion |
|
435 * @param (int|NULL) $value The minor protocol version to use. |
|
436 * @throws Zend_Gdata_App_InvalidArgumentException |
|
437 */ |
|
438 public function setMinorProtocolVersion($value) |
|
439 { |
|
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'); |
|
444 } |
|
445 $this->_minorProtocolVersion = $value; |
|
446 } |
|
447 |
|
448 /** |
|
449 * Get the minor protocol version that is in use. |
|
450 * |
|
451 * @see _minorProtocolVersion |
|
452 * @return (int|NULL) The major protocol version in use, or NULL if no |
|
453 * minor version is specified. |
|
454 */ |
|
455 public function getMinorProtocolVersion() |
|
456 { |
|
457 return $this->_minorProtocolVersion; |
|
458 } |
|
459 |
|
460 /** |
|
461 * Provides pre-processing for HTTP requests to APP services. |
|
462 * |
|
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() |
|
469 * |
|
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' |
|
482 */ |
|
483 public function prepareRequest($method, |
|
484 $url = null, |
|
485 $headers = array(), |
|
486 $data = null, |
|
487 $contentTypeOverride = null) |
|
488 { |
|
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(); |
|
493 } |
|
494 |
|
495 $rawData = null; |
|
496 $finalContentType = null; |
|
497 if ($url == null) { |
|
498 $url = $this->_defaultPostUri; |
|
499 } |
|
500 |
|
501 if (is_string($data)) { |
|
502 $rawData = $data; |
|
503 if ($contentTypeOverride === null) { |
|
504 $finalContentType = 'application/atom+xml'; |
|
505 } |
|
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'; |
|
514 } |
|
515 if ($method == 'PUT' || $method == 'DELETE') { |
|
516 $editLink = $data->getEditLink(); |
|
517 if ($editLink != null && $url == null) { |
|
518 $url = $editLink->getHref(); |
|
519 } |
|
520 } |
|
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(); |
|
528 } |
|
529 } |
|
530 } elseif ($data instanceof Zend_Gdata_App_MediaSource) { |
|
531 $rawData = $data->encode(); |
|
532 if ($data->getSlug() !== null) { |
|
533 $headers['Slug'] = $data->getSlug(); |
|
534 } |
|
535 $finalContentType = $data->getContentType(); |
|
536 } |
|
537 |
|
538 if ($method == 'DELETE') { |
|
539 $rawData = null; |
|
540 } |
|
541 |
|
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; |
|
555 } |
|
556 } |
|
557 |
|
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; |
|
563 } |
|
564 |
|
565 if ($contentTypeOverride != null) { |
|
566 $finalContentType = $contentTypeOverride; |
|
567 } |
|
568 |
|
569 return array('method' => $method, 'url' => $url, |
|
570 'data' => $rawData, 'headers' => $headers, |
|
571 'contentType' => $finalContentType); |
|
572 } |
|
573 |
|
574 /** |
|
575 * Performs a HTTP request using the specified method |
|
576 * |
|
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 |
|
588 */ |
|
589 public function performHttpRequest($method, $url, $headers = null, |
|
590 $body = null, $contentType = null, $remainingRedirects = null) |
|
591 { |
|
592 require_once 'Zend/Http/Client/Exception.php'; |
|
593 if ($remainingRedirects === null) { |
|
594 $remainingRedirects = self::getMaxRedirects(); |
|
595 } |
|
596 if ($headers === null) { |
|
597 $headers = array(); |
|
598 } |
|
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 : ''); |
|
606 } |
|
607 |
|
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'); |
|
615 } |
|
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.'); |
|
620 } |
|
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)'; |
|
629 } |
|
630 $headers['Accept-encoding'] = 'gzip, deflate'; |
|
631 } else { |
|
632 $headers['Accept-encoding'] = 'identity'; |
|
633 } |
|
634 |
|
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 and If-Match headers |
|
638 $this->_httpClient->resetParameters(); |
|
639 $this->_httpClient->setHeaders(array('Slug', 'If-Match')); |
|
640 |
|
641 // Set the params for the new request to be performed |
|
642 $this->_httpClient->setHeaders($headers); |
|
643 require_once 'Zend/Uri/Http.php'; |
|
644 $uri = Zend_Uri_Http::fromString($url); |
|
645 preg_match("/^(.*?)(\?.*)?$/", $url, $matches); |
|
646 $this->_httpClient->setUri($matches[1]); |
|
647 $queryArray = $uri->getQueryAsArray(); |
|
648 foreach ($queryArray as $name => $value) { |
|
649 $this->_httpClient->setParameterGet($name, $value); |
|
650 } |
|
651 |
|
652 |
|
653 $this->_httpClient->setConfig(array('maxredirects' => 0)); |
|
654 |
|
655 // Set the proper adapter if we are handling a streaming upload |
|
656 $usingMimeStream = false; |
|
657 $oldHttpAdapter = null; |
|
658 |
|
659 if ($body instanceof Zend_Gdata_MediaMimeStream) { |
|
660 $usingMimeStream = true; |
|
661 $this->_httpClient->setRawDataStream($body, $contentType); |
|
662 $oldHttpAdapter = $this->_httpClient->getAdapter(); |
|
663 |
|
664 if ($oldHttpAdapter instanceof Zend_Http_Client_Adapter_Proxy) { |
|
665 require_once 'Zend/Gdata/HttpAdapterStreamingProxy.php'; |
|
666 $newAdapter = new Zend_Gdata_HttpAdapterStreamingProxy(); |
|
667 } else { |
|
668 require_once 'Zend/Gdata/HttpAdapterStreamingSocket.php'; |
|
669 $newAdapter = new Zend_Gdata_HttpAdapterStreamingSocket(); |
|
670 } |
|
671 $this->_httpClient->setAdapter($newAdapter); |
|
672 } else { |
|
673 $this->_httpClient->setRawData($body, $contentType); |
|
674 } |
|
675 |
|
676 try { |
|
677 $response = $this->_httpClient->request($method); |
|
678 // reset adapter |
|
679 if ($usingMimeStream) { |
|
680 $this->_httpClient->setAdapter($oldHttpAdapter); |
|
681 } |
|
682 } catch (Zend_Http_Client_Exception $e) { |
|
683 // reset adapter |
|
684 if ($usingMimeStream) { |
|
685 $this->_httpClient->setAdapter($oldHttpAdapter); |
|
686 } |
|
687 require_once 'Zend/Gdata/App/HttpException.php'; |
|
688 throw new Zend_Gdata_App_HttpException($e->getMessage(), $e); |
|
689 } |
|
690 if ($response->isRedirect() && $response->getStatus() != '304') { |
|
691 if ($remainingRedirects > 0) { |
|
692 $newUrl = $response->getHeader('Location'); |
|
693 $response = $this->performHttpRequest( |
|
694 $method, $newUrl, $headers, $body, |
|
695 $contentType, $remainingRedirects); |
|
696 } else { |
|
697 require_once 'Zend/Gdata/App/HttpException.php'; |
|
698 throw new Zend_Gdata_App_HttpException( |
|
699 'Number of redirects exceeds maximum', null, $response); |
|
700 } |
|
701 } |
|
702 if (!$response->isSuccessful()) { |
|
703 require_once 'Zend/Gdata/App/HttpException.php'; |
|
704 $exceptionMessage = 'Expected response code 200, got ' . |
|
705 $response->getStatus(); |
|
706 if (self::getVerboseExceptionMessages()) { |
|
707 $exceptionMessage .= "\n" . $response->getBody(); |
|
708 } |
|
709 $exception = new Zend_Gdata_App_HttpException($exceptionMessage); |
|
710 $exception->setResponse($response); |
|
711 throw $exception; |
|
712 } |
|
713 return $response; |
|
714 } |
|
715 |
|
716 /** |
|
717 * Imports a feed located at $uri. |
|
718 * |
|
719 * @param string $uri |
|
720 * @param Zend_Http_Client $client The client used for communication |
|
721 * @param string $className The class which is used as the return type |
|
722 * @throws Zend_Gdata_App_Exception |
|
723 * @return string|Zend_Gdata_App_Feed Returns string only if the object |
|
724 * mapping has been disabled explicitly |
|
725 * by passing false to the |
|
726 * useObjectMapping() function. |
|
727 */ |
|
728 public static function import($uri, $client = null, |
|
729 $className='Zend_Gdata_App_Feed') |
|
730 { |
|
731 $app = new Zend_Gdata_App($client); |
|
732 $requestData = $app->prepareRequest('GET', $uri); |
|
733 $response = $app->performHttpRequest( |
|
734 $requestData['method'], $requestData['url']); |
|
735 |
|
736 $feedContent = $response->getBody(); |
|
737 if (!$this->_useObjectMapping) { |
|
738 return $feedContent; |
|
739 } |
|
740 $feed = self::importString($feedContent, $className); |
|
741 if ($client != null) { |
|
742 $feed->setHttpClient($client); |
|
743 } |
|
744 return $feed; |
|
745 } |
|
746 |
|
747 /** |
|
748 * Imports the specified URL (non-statically). |
|
749 * |
|
750 * @param string $url The URL to import |
|
751 * @param string $className The class which is used as the return type |
|
752 * @param array $extraHeaders Extra headers to add to the request, as an |
|
753 * array of string-based key/value pairs. |
|
754 * @throws Zend_Gdata_App_Exception |
|
755 * @return string|Zend_Gdata_App_Feed Returns string only if the object |
|
756 * mapping has been disabled explicitly |
|
757 * by passing false to the |
|
758 * useObjectMapping() function. |
|
759 */ |
|
760 public function importUrl($url, $className='Zend_Gdata_App_Feed', |
|
761 $extraHeaders = array()) |
|
762 { |
|
763 $response = $this->get($url, $extraHeaders); |
|
764 |
|
765 $feedContent = $response->getBody(); |
|
766 if (!$this->_useObjectMapping) { |
|
767 return $feedContent; |
|
768 } |
|
769 |
|
770 $protocolVersionStr = $response->getHeader('GData-Version'); |
|
771 $majorProtocolVersion = null; |
|
772 $minorProtocolVersion = null; |
|
773 if ($protocolVersionStr !== null) { |
|
774 // Extract protocol major and minor version from header |
|
775 $delimiterPos = strpos($protocolVersionStr, '.'); |
|
776 $length = strlen($protocolVersionStr); |
|
777 $major = substr($protocolVersionStr, 0, $delimiterPos); |
|
778 $minor = substr($protocolVersionStr, $delimiterPos + 1, $length); |
|
779 $majorProtocolVersion = $major; |
|
780 $minorProtocolVersion = $minor; |
|
781 } |
|
782 |
|
783 $feed = self::importString($feedContent, $className, |
|
784 $majorProtocolVersion, $minorProtocolVersion); |
|
785 if ($this->getHttpClient() != null) { |
|
786 $feed->setHttpClient($this->getHttpClient()); |
|
787 } |
|
788 $etag = $response->getHeader('ETag'); |
|
789 if ($etag !== null) { |
|
790 $feed->setEtag($etag); |
|
791 } |
|
792 return $feed; |
|
793 } |
|
794 |
|
795 |
|
796 /** |
|
797 * Imports a feed represented by $string. |
|
798 * |
|
799 * @param string $string |
|
800 * @param string $className The class which is used as the return type |
|
801 * @param integer $majorProcolVersion (optional) The major protocol version |
|
802 * of the data model object that is to be created. |
|
803 * @param integer $minorProcolVersion (optional) The minor protocol version |
|
804 * of the data model object that is to be created. |
|
805 * @throws Zend_Gdata_App_Exception |
|
806 * @return Zend_Gdata_App_Feed |
|
807 */ |
|
808 public static function importString($string, |
|
809 $className='Zend_Gdata_App_Feed', $majorProtocolVersion = null, |
|
810 $minorProtocolVersion = null) |
|
811 { |
|
812 if (!class_exists($className, false)) { |
|
813 require_once 'Zend/Loader.php'; |
|
814 @Zend_Loader::loadClass($className); |
|
815 } |
|
816 |
|
817 // Load the feed as an XML DOMDocument object |
|
818 @ini_set('track_errors', 1); |
|
819 $doc = new DOMDocument(); |
|
820 $success = @$doc->loadXML($string); |
|
821 @ini_restore('track_errors'); |
|
822 |
|
823 if (!$success) { |
|
824 require_once 'Zend/Gdata/App/Exception.php'; |
|
825 throw new Zend_Gdata_App_Exception( |
|
826 "DOMDocument cannot parse XML: $php_errormsg"); |
|
827 } |
|
828 |
|
829 $feed = new $className(); |
|
830 $feed->setMajorProtocolVersion($majorProtocolVersion); |
|
831 $feed->setMinorProtocolVersion($minorProtocolVersion); |
|
832 $feed->transferFromXML($string); |
|
833 $feed->setHttpClient(self::getstaticHttpClient()); |
|
834 return $feed; |
|
835 } |
|
836 |
|
837 |
|
838 /** |
|
839 * Imports a feed from a file located at $filename. |
|
840 * |
|
841 * @param string $filename |
|
842 * @param string $className The class which is used as the return type |
|
843 * @param string $useIncludePath Whether the include_path should be searched |
|
844 * @throws Zend_Gdata_App_Exception |
|
845 * @return Zend_Gdata_App_Feed |
|
846 */ |
|
847 public static function importFile($filename, |
|
848 $className='Zend_Gdata_App_Feed', $useIncludePath = false) |
|
849 { |
|
850 @ini_set('track_errors', 1); |
|
851 $feed = @file_get_contents($filename, $useIncludePath); |
|
852 @ini_restore('track_errors'); |
|
853 if ($feed === false) { |
|
854 require_once 'Zend/Gdata/App/Exception.php'; |
|
855 throw new Zend_Gdata_App_Exception( |
|
856 "File could not be loaded: $php_errormsg"); |
|
857 } |
|
858 return self::importString($feed, $className); |
|
859 } |
|
860 |
|
861 /** |
|
862 * GET a URI using client object. |
|
863 * |
|
864 * @param string $uri GET URI |
|
865 * @param array $extraHeaders Extra headers to add to the request, as an |
|
866 * array of string-based key/value pairs. |
|
867 * @throws Zend_Gdata_App_HttpException |
|
868 * @return Zend_Http_Response |
|
869 */ |
|
870 public function get($uri, $extraHeaders = array()) |
|
871 { |
|
872 $requestData = $this->prepareRequest('GET', $uri, $extraHeaders); |
|
873 return $this->performHttpRequest( |
|
874 $requestData['method'], $requestData['url'], |
|
875 $requestData['headers']); |
|
876 } |
|
877 |
|
878 /** |
|
879 * POST data with client object |
|
880 * |
|
881 * @param mixed $data The Zend_Gdata_App_Entry or XML to post |
|
882 * @param string $uri POST URI |
|
883 * @param array $headers Additional HTTP headers to insert. |
|
884 * @param string $contentType Content-type of the data |
|
885 * @param array $extraHeaders Extra headers to add to the request, as an |
|
886 * array of string-based key/value pairs. |
|
887 * @return Zend_Http_Response |
|
888 * @throws Zend_Gdata_App_Exception |
|
889 * @throws Zend_Gdata_App_HttpException |
|
890 * @throws Zend_Gdata_App_InvalidArgumentException |
|
891 */ |
|
892 public function post($data, $uri = null, $remainingRedirects = null, |
|
893 $contentType = null, $extraHeaders = null) |
|
894 { |
|
895 $requestData = $this->prepareRequest( |
|
896 'POST', $uri, $extraHeaders, $data, $contentType); |
|
897 return $this->performHttpRequest( |
|
898 $requestData['method'], $requestData['url'], |
|
899 $requestData['headers'], $requestData['data'], |
|
900 $requestData['contentType']); |
|
901 } |
|
902 |
|
903 /** |
|
904 * PUT data with client object |
|
905 * |
|
906 * @param mixed $data The Zend_Gdata_App_Entry or XML to post |
|
907 * @param string $uri PUT URI |
|
908 * @param array $headers Additional HTTP headers to insert. |
|
909 * @param string $contentType Content-type of the data |
|
910 * @param array $extraHeaders Extra headers to add to the request, as an |
|
911 * array of string-based key/value pairs. |
|
912 * @return Zend_Http_Response |
|
913 * @throws Zend_Gdata_App_Exception |
|
914 * @throws Zend_Gdata_App_HttpException |
|
915 * @throws Zend_Gdata_App_InvalidArgumentException |
|
916 */ |
|
917 public function put($data, $uri = null, $remainingRedirects = null, |
|
918 $contentType = null, $extraHeaders = null) |
|
919 { |
|
920 $requestData = $this->prepareRequest( |
|
921 'PUT', $uri, $extraHeaders, $data, $contentType); |
|
922 return $this->performHttpRequest( |
|
923 $requestData['method'], $requestData['url'], |
|
924 $requestData['headers'], $requestData['data'], |
|
925 $requestData['contentType']); |
|
926 } |
|
927 |
|
928 /** |
|
929 * DELETE entry with client object |
|
930 * |
|
931 * @param mixed $data The Zend_Gdata_App_Entry or URL to delete |
|
932 * @return void |
|
933 * @throws Zend_Gdata_App_Exception |
|
934 * @throws Zend_Gdata_App_HttpException |
|
935 * @throws Zend_Gdata_App_InvalidArgumentException |
|
936 */ |
|
937 public function delete($data, $remainingRedirects = null) |
|
938 { |
|
939 if (is_string($data)) { |
|
940 $requestData = $this->prepareRequest('DELETE', $data); |
|
941 } else { |
|
942 $headers = array(); |
|
943 |
|
944 $requestData = $this->prepareRequest( |
|
945 'DELETE', null, $headers, $data); |
|
946 } |
|
947 return $this->performHttpRequest($requestData['method'], |
|
948 $requestData['url'], |
|
949 $requestData['headers'], |
|
950 '', |
|
951 $requestData['contentType'], |
|
952 $remainingRedirects); |
|
953 } |
|
954 |
|
955 /** |
|
956 * Inserts an entry to a given URI and returns the response as a |
|
957 * fully formed Entry. |
|
958 * |
|
959 * @param mixed $data The Zend_Gdata_App_Entry or XML to post |
|
960 * @param string $uri POST URI |
|
961 * @param string $className The class of entry to be returned. |
|
962 * @param array $extraHeaders Extra headers to add to the request, as an |
|
963 * array of string-based key/value pairs. |
|
964 * @return Zend_Gdata_App_Entry The entry returned by the service after |
|
965 * insertion. |
|
966 */ |
|
967 public function insertEntry($data, $uri, $className='Zend_Gdata_App_Entry', |
|
968 $extraHeaders = array()) |
|
969 { |
|
970 if (!class_exists($className, false)) { |
|
971 require_once 'Zend/Loader.php'; |
|
972 @Zend_Loader::loadClass($className); |
|
973 } |
|
974 |
|
975 $response = $this->post($data, $uri, null, null, $extraHeaders); |
|
976 |
|
977 $returnEntry = new $className($response->getBody()); |
|
978 $returnEntry->setHttpClient(self::getstaticHttpClient()); |
|
979 |
|
980 $etag = $response->getHeader('ETag'); |
|
981 if ($etag !== null) { |
|
982 $returnEntry->setEtag($etag); |
|
983 } |
|
984 |
|
985 return $returnEntry; |
|
986 } |
|
987 |
|
988 /** |
|
989 * Update an entry |
|
990 * |
|
991 * @param mixed $data Zend_Gdata_App_Entry or XML (w/ID and link rel='edit') |
|
992 * @param string|null The URI to send requests to, or null if $data |
|
993 * contains the URI. |
|
994 * @param string|null The name of the class that should be deserialized |
|
995 * from the server response. If null, then 'Zend_Gdata_App_Entry' |
|
996 * will be used. |
|
997 * @param array $extraHeaders Extra headers to add to the request, as an |
|
998 * array of string-based key/value pairs. |
|
999 * @return Zend_Gdata_App_Entry The entry returned from the server |
|
1000 * @throws Zend_Gdata_App_Exception |
|
1001 */ |
|
1002 public function updateEntry($data, $uri = null, $className = null, |
|
1003 $extraHeaders = array()) |
|
1004 { |
|
1005 if ($className === null && $data instanceof Zend_Gdata_App_Entry) { |
|
1006 $className = get_class($data); |
|
1007 } elseif ($className === null) { |
|
1008 $className = 'Zend_Gdata_App_Entry'; |
|
1009 } |
|
1010 |
|
1011 if (!class_exists($className, false)) { |
|
1012 require_once 'Zend/Loader.php'; |
|
1013 @Zend_Loader::loadClass($className); |
|
1014 } |
|
1015 |
|
1016 $response = $this->put($data, $uri, null, null, $extraHeaders); |
|
1017 $returnEntry = new $className($response->getBody()); |
|
1018 $returnEntry->setHttpClient(self::getstaticHttpClient()); |
|
1019 |
|
1020 $etag = $response->getHeader('ETag'); |
|
1021 if ($etag !== null) { |
|
1022 $returnEntry->setEtag($etag); |
|
1023 } |
|
1024 |
|
1025 return $returnEntry; |
|
1026 } |
|
1027 |
|
1028 /** |
|
1029 * Provides a magic factory method to instantiate new objects with |
|
1030 * shorter syntax than would otherwise be required by the Zend Framework |
|
1031 * naming conventions. For instance, to construct a new |
|
1032 * Zend_Gdata_Calendar_Extension_Color, a developer simply needs to do |
|
1033 * $gCal->newColor(). For this magic constructor, packages are searched |
|
1034 * in the same order as which they appear in the $_registeredPackages |
|
1035 * array |
|
1036 * |
|
1037 * @param string $method The method name being called |
|
1038 * @param array $args The arguments passed to the call |
|
1039 * @throws Zend_Gdata_App_Exception |
|
1040 */ |
|
1041 public function __call($method, $args) |
|
1042 { |
|
1043 if (preg_match('/^new(\w+)/', $method, $matches)) { |
|
1044 $class = $matches[1]; |
|
1045 $foundClassName = null; |
|
1046 foreach ($this->_registeredPackages as $name) { |
|
1047 try { |
|
1048 // Autoloading disabled on next line for compatibility |
|
1049 // with magic factories. See ZF-6660. |
|
1050 if (!class_exists($name . '_' . $class, false)) { |
|
1051 require_once 'Zend/Loader.php'; |
|
1052 @Zend_Loader::loadClass($name . '_' . $class); |
|
1053 } |
|
1054 $foundClassName = $name . '_' . $class; |
|
1055 break; |
|
1056 } catch (Zend_Exception $e) { |
|
1057 // package wasn't here- continue searching |
|
1058 } |
|
1059 } |
|
1060 if ($foundClassName != null) { |
|
1061 $reflectionObj = new ReflectionClass($foundClassName); |
|
1062 $instance = $reflectionObj->newInstanceArgs($args); |
|
1063 if ($instance instanceof Zend_Gdata_App_FeedEntryParent) { |
|
1064 $instance->setHttpClient($this->_httpClient); |
|
1065 |
|
1066 // Propogate version data |
|
1067 $instance->setMajorProtocolVersion( |
|
1068 $this->_majorProtocolVersion); |
|
1069 $instance->setMinorProtocolVersion( |
|
1070 $this->_minorProtocolVersion); |
|
1071 } |
|
1072 return $instance; |
|
1073 } else { |
|
1074 require_once 'Zend/Gdata/App/Exception.php'; |
|
1075 throw new Zend_Gdata_App_Exception( |
|
1076 "Unable to find '${class}' in registered packages"); |
|
1077 } |
|
1078 } else { |
|
1079 require_once 'Zend/Gdata/App/Exception.php'; |
|
1080 throw new Zend_Gdata_App_Exception("No such method ${method}"); |
|
1081 } |
|
1082 } |
|
1083 |
|
1084 /** |
|
1085 * Retrieve all entries for a feed, iterating through pages as necessary. |
|
1086 * Be aware that calling this function on a large dataset will take a |
|
1087 * significant amount of time to complete. In some cases this may cause |
|
1088 * execution to timeout without proper precautions in place. |
|
1089 * |
|
1090 * @param $feed The feed to iterate through. |
|
1091 * @return mixed A new feed of the same type as the one originally |
|
1092 * passed in, containing all relevent entries. |
|
1093 */ |
|
1094 public function retrieveAllEntriesForFeed($feed) { |
|
1095 $feedClass = get_class($feed); |
|
1096 $reflectionObj = new ReflectionClass($feedClass); |
|
1097 $result = $reflectionObj->newInstance(); |
|
1098 do { |
|
1099 foreach ($feed as $entry) { |
|
1100 $result->addEntry($entry); |
|
1101 } |
|
1102 |
|
1103 $next = $feed->getLink('next'); |
|
1104 if ($next !== null) { |
|
1105 $feed = $this->getFeed($next->href, $feedClass); |
|
1106 } else { |
|
1107 $feed = null; |
|
1108 } |
|
1109 } |
|
1110 while ($feed != null); |
|
1111 return $result; |
|
1112 } |
|
1113 |
|
1114 /** |
|
1115 * This method enables logging of requests by changing the |
|
1116 * Zend_Http_Client_Adapter used for performing the requests. |
|
1117 * NOTE: This will not work if you have customized the adapter |
|
1118 * already to use a proxy server or other interface. |
|
1119 * |
|
1120 * @param $logfile The logfile to use when logging the requests |
|
1121 */ |
|
1122 public function enableRequestDebugLogging($logfile) |
|
1123 { |
|
1124 $this->_httpClient->setConfig(array( |
|
1125 'adapter' => 'Zend_Gdata_App_LoggingHttpClientAdapterSocket', |
|
1126 'logfile' => $logfile |
|
1127 )); |
|
1128 } |
|
1129 |
|
1130 /** |
|
1131 * Retrieve next set of results based on a given feed. |
|
1132 * |
|
1133 * @param Zend_Gdata_App_Feed $feed The feed from which to |
|
1134 * retreive the next set of results. |
|
1135 * @param string $className (optional) The class of feed to be returned. |
|
1136 * If null, the next feed (if found) will be the same class as |
|
1137 * the feed that was given as the first argument. |
|
1138 * @return Zend_Gdata_App_Feed|null Returns a |
|
1139 * Zend_Gdata_App_Feed or null if no next set of results |
|
1140 * exists. |
|
1141 */ |
|
1142 public function getNextFeed($feed, $className = null) |
|
1143 { |
|
1144 $nextLink = $feed->getNextLink(); |
|
1145 if (!$nextLink) { |
|
1146 return null; |
|
1147 } |
|
1148 $nextLinkHref = $nextLink->getHref(); |
|
1149 |
|
1150 if ($className === null) { |
|
1151 $className = get_class($feed); |
|
1152 } |
|
1153 |
|
1154 return $this->getFeed($nextLinkHref, $className); |
|
1155 } |
|
1156 |
|
1157 /** |
|
1158 * Retrieve previous set of results based on a given feed. |
|
1159 * |
|
1160 * @param Zend_Gdata_App_Feed $feed The feed from which to |
|
1161 * retreive the previous set of results. |
|
1162 * @param string $className (optional) The class of feed to be returned. |
|
1163 * If null, the previous feed (if found) will be the same class as |
|
1164 * the feed that was given as the first argument. |
|
1165 * @return Zend_Gdata_App_Feed|null Returns a |
|
1166 * Zend_Gdata_App_Feed or null if no previous set of results |
|
1167 * exists. |
|
1168 */ |
|
1169 public function getPreviousFeed($feed, $className = null) |
|
1170 { |
|
1171 $previousLink = $feed->getPreviousLink(); |
|
1172 if (!$previousLink) { |
|
1173 return null; |
|
1174 } |
|
1175 $previousLinkHref = $previousLink->getHref(); |
|
1176 |
|
1177 if ($className === null) { |
|
1178 $className = get_class($feed); |
|
1179 } |
|
1180 |
|
1181 return $this->getFeed($previousLinkHref, $className); |
|
1182 } |
|
1183 |
|
1184 /** |
|
1185 * Returns the data for an If-Match header based on the current Etag |
|
1186 * property. If Etags are not supported by the server or cannot be |
|
1187 * extracted from the data, then null will be returned. |
|
1188 * |
|
1189 * @param boolean $allowWeak If false, then if a weak Etag is detected, |
|
1190 * then return null rather than the Etag. |
|
1191 * @return string|null $data |
|
1192 */ |
|
1193 public function generateIfMatchHeaderData($data, $allowWeek) |
|
1194 { |
|
1195 $result = ''; |
|
1196 // Set an If-Match header if an ETag has been set (version >= 2 only) |
|
1197 if ($this->_majorProtocolVersion >= 2 && |
|
1198 $data instanceof Zend_Gdata_App_Entry) { |
|
1199 $etag = $data->getEtag(); |
|
1200 if (($etag !== null) && |
|
1201 ($allowWeek || substr($etag, 0, 2) != 'W/')) { |
|
1202 $result = $data->getEtag(); |
|
1203 } |
|
1204 } |
|
1205 return $result; |
|
1206 } |
|
1207 |
|
1208 /** |
|
1209 * Determine whether service object is using XML to object mapping. |
|
1210 * |
|
1211 * @return boolean True if service object is using XML to object mapping, |
|
1212 * false otherwise. |
|
1213 */ |
|
1214 public function usingObjectMapping() |
|
1215 { |
|
1216 return $this->_useObjectMapping; |
|
1217 } |
|
1218 |
|
1219 /** |
|
1220 * Enable/disable the use of XML to object mapping. |
|
1221 * |
|
1222 * @param boolean $value Pass in true to use the XML to object mapping. |
|
1223 * Pass in false or null to disable it. |
|
1224 * @return void |
|
1225 */ |
|
1226 public function useObjectMapping($value) |
|
1227 { |
|
1228 if ($value === True) { |
|
1229 $this->_useObjectMapping = true; |
|
1230 } else { |
|
1231 $this->_useObjectMapping = false; |
|
1232 } |
|
1233 } |
|
1234 |
|
1235 } |