[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/include/Zend/Gdata/ -> App.php (source)

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


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1