File indexing completed on 2024-12-22 05:37:02

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Service
0017  * @subpackage Ebay
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id: Finding.php 22824 2010-08-09 18:59:54Z renanbr $
0021  */
0022 
0023 /**
0024  * @see Zend_Service_Ebay_Abstract
0025  */
0026 // require_once 'Zend/Service/Ebay/Abstract.php';
0027 
0028 /** @see Zend_Xml_Security */
0029 // require_once 'Zend/Xml/Security.php';
0030 
0031 /**
0032  * @category   Zend
0033  * @package    Zend_Service
0034  * @subpackage Ebay
0035  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0036  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0037  * @uses       Zend_Service_Ebay_Abstract
0038  */
0039 class Zend_Service_Ebay_Finding extends Zend_Service_Ebay_Abstract
0040 {
0041     const SERVICE_NAME         = 'FindingService';
0042     const SERVICE_VERSION      = '1.0.0';
0043     const RESPONSE_DATA_FORMAT = 'XML';
0044 
0045     const ENDPOINT_URI  = 'http://svcs.ebay.com';
0046     const ENDPOINT_PATH = 'services/search/FindingService/v1';
0047 
0048     const XMLNS_FINDING = 'e';
0049     const XMLNS_MS      = 'ms';
0050 
0051     /**
0052      * @var array
0053      */
0054     protected static $_xmlNamespaces = array(
0055         self::XMLNS_FINDING => 'http://www.ebay.com/marketplace/search/v1/services',
0056         self::XMLNS_MS      => 'http://www.ebay.com/marketplace/services'
0057     );
0058 
0059     /**
0060      *
0061      * @var array
0062      */
0063     protected $_options = array(
0064         self::OPTION_GLOBAL_ID => 'EBAY-US'
0065     );
0066 
0067     /**
0068      * @return array
0069      */
0070     public static function getXmlNamespaces()
0071     {
0072         return self::$_xmlNamespaces;
0073     }
0074 
0075     /**
0076      * @param  Zend_Config|array|string $options Application Id or array of options
0077      * @throws Zend_Service_Ebay_Finding_Exception When application id is missing
0078      * @return void
0079      */
0080     public function __construct($options)
0081     {
0082         // prepare options
0083         if (is_string($options)) {
0084             // application id was given
0085             $options = array(self::OPTION_APP_ID => $options);
0086         } else {
0087             // check application id
0088             $options = parent::optionsToArray($options);
0089             if (!array_key_exists(self::OPTION_APP_ID, $options)) {
0090                 /**
0091                  * @see Zend_Service_Ebay_Finding_Exception
0092                  */
0093                 // require_once 'Zend/Service/Ebay/Finding/Exception.php';
0094                 throw new Zend_Service_Ebay_Finding_Exception(
0095                     'Application Id is missing.');
0096             }
0097         }
0098 
0099         // load options
0100         parent::setOption($options);
0101     }
0102 
0103     /**
0104      * @param  Zend_Rest_Client $client
0105      * @return Zend_Service_Ebay_Finding Provides a fluent interface
0106      */
0107     public function setClient($client)
0108     {
0109         if (!$client instanceof Zend_Rest_Client) {
0110             /**
0111              * @see Zend_Service_Ebay_Finding_Exception
0112              */
0113             // require_once 'Zend/Service/Ebay/Finding/Exception.php';
0114             throw new Zend_Service_Ebay_Finding_Exception(
0115                 'Client object must extend Zend_Rest_Client.');
0116         }
0117         $this->_client = $client;
0118 
0119         return $this;
0120     }
0121 
0122     /**
0123      * @return Zend_Rest_Client
0124      */
0125     public function getClient()
0126     {
0127         if (!$this->_client instanceof Zend_Rest_Client) {
0128             /**
0129              * @see Zend_Rest_Client
0130              */
0131             // require_once 'Zend/Rest/Client.php';
0132             $this->_client = new Zend_Rest_Client();
0133         }
0134         return $this->_client;
0135     }
0136 
0137     /**
0138      * Finds items by a keyword query and/or category and allows searching
0139      * within item descriptions.
0140      *
0141      * @param  string            $keywords
0142      * @param  boolean           $descriptionSearch
0143      * @param  integer           $categoryId
0144      * @param  Zend_Config|array $options
0145      * @link   http://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html
0146      * @return Zend_Service_Ebay_Finding_Response_Items
0147      */
0148     public function findItemsAdvanced($keywords, $descriptionSearch = true, $categoryId = null, $options = null)
0149     {
0150         // prepare options
0151         $options                      = parent::optionsToArray($options);
0152         $options['keywords']          = $keywords;
0153         $options['descriptionSearch'] = $descriptionSearch;
0154         if (!empty($categoryId)) {
0155             $options['categoryId'] = $categoryId;
0156         }
0157 
0158         // do request
0159         return $this->_findItems($options, 'findItemsAdvanced');
0160     }
0161 
0162     /**
0163      * Finds items in a specific category. Results can be filtered and sorted.
0164      *
0165      * @param  integer           $categoryId
0166      * @param  Zend_Config|array $options
0167      * @link   http://developer.ebay.com/DevZone/finding/CallRef/findItemsByCategory.html
0168      * @return Zend_Service_Ebay_Finding_Response_Items
0169      */
0170     public function findItemsByCategory($categoryId, $options = null)
0171     {
0172         // prepare options
0173         $options               = parent::optionsToArray($options);
0174         $options['categoryId'] = $categoryId;
0175 
0176         // do request
0177         return $this->_findItems($options, 'findItemsByCategory');
0178     }
0179 
0180     /**
0181      * Finds items on eBay based upon a keyword query and returns details for
0182      * matching items.
0183      *
0184      * @param  string            $keywords
0185      * @param  Zend_Config|array $options
0186      * @link   http://developer.ebay.com/DevZone/finding/CallRef/findItemsByKeywords.html
0187      * @return Zend_Service_Ebay_Finding_Response_Items
0188      */
0189     public function findItemsByKeywords($keywords, $options = null)
0190     {
0191         // prepare options
0192         $options             = parent::optionsToArray($options);
0193         $options['keywords'] = $keywords;
0194 
0195         // do request
0196         return $this->_findItems($options, 'findItemsByKeywords');
0197     }
0198 
0199     /**
0200      * Finds items based upon a product ID, such as an ISBN, UPC, EAN, or ePID.
0201      *
0202      * @param  integer           $productId
0203      * @param  string            $productIdType Default value is ReferenceID
0204      * @param  Zend_Config|array $options
0205      * @link   http://developer.ebay.com/DevZone/finding/CallRef/findItemsByProduct.html
0206      * @return Zend_Service_Ebay_Finding_Response_Items
0207      */
0208     public function findItemsByProduct($productId, $productIdType = null, $options = null)
0209     {
0210         if (null == $productIdType) {
0211             $productIdType = 'ReferenceID';
0212         }
0213 
0214         // prepare options
0215         $options              = parent::optionsToArray($options);
0216         $options['productId'] = array(''     => $productId,
0217                                       'type' => $productIdType);
0218 
0219         // do request
0220         return $this->_findItems($options, 'findItemsByProduct');
0221     }
0222 
0223     /**
0224      * Finds items in eBay stores. Can search a specific store or can search all
0225      * stores with a keyword query.
0226      *
0227      * @param  string            $storeName
0228      * @param  Zend_Config|array $options
0229      * @link   http://developer.ebay.com/DevZone/finding/CallRef/findItemsIneBayStores.html
0230      * @return Zend_Service_Ebay_Finding_Response_Items
0231      */
0232     public function findItemsInEbayStores($storeName, $options = null)
0233     {
0234         // prepare options
0235         $options              = parent::optionsToArray($options);
0236         $options['storeName'] = $storeName;
0237 
0238         // do request
0239         return $this->_findItems($options, 'findItemsIneBayStores');
0240     }
0241 
0242     /**
0243      * @param  array  $options
0244      * @param  string $operation
0245      * @return Zend_Service_Ebay_Finding_Response_Items
0246      */
0247     protected function _findItems(array $options, $operation)
0248     {
0249         // set default output selector value
0250         if (!array_key_exists('outputSelector', $options)) {
0251             $options['outputSelector'] = array('AspectHistogram',
0252                                                'CategoryHistogram',
0253                                                'SellerInfo',
0254                                                'StoreInfo');
0255         }
0256 
0257         // do request
0258         $dom = $this->_request($operation, $options);
0259 
0260         /**
0261          * @see Zend_Service_Ebay_Finding_Response_Items
0262          */
0263         // require_once 'Zend/Service/Ebay/Finding/Response/Items.php';
0264         $response = new Zend_Service_Ebay_Finding_Response_Items($dom->firstChild);
0265         return $response->setOperation($operation)
0266                         ->setOption($options);
0267     }
0268 
0269     /**
0270      * Gets category and/or aspect metadata for the specified category.
0271      *
0272      * @param  integer           $categoryId
0273      * @param  Zend_Config|array $options
0274      * @link   http://developer.ebay.com/DevZone/finding/CallRef/getHistograms.html
0275      * @return Zend_Service_Ebay_Finding_Response_Histograms
0276      */
0277     public function getHistograms($categoryId, $options = null)
0278     {
0279         // prepare options
0280         $options               = parent::optionsToArray($options);
0281         $options['categoryId'] = $categoryId;
0282 
0283         // do request
0284         $operation = 'getHistograms';
0285         $dom       = $this->_request($operation, $options);
0286 
0287         /**
0288          * @see Zend_Service_Ebay_Finding_Response_Histograms
0289          */
0290         // require_once 'Zend/Service/Ebay/Finding/Response/Histograms.php';
0291         $response = new Zend_Service_Ebay_Finding_Response_Histograms($dom->firstChild);
0292         return $response->setOperation($operation)
0293                         ->setOption($options);
0294     }
0295 
0296     /**
0297      * Checks specified keywords and returns correctly spelled keywords for best
0298      * search results.
0299      *
0300      * @param  string            $keywords
0301      * @param  Zend_Config|array $options
0302      * @link   http://developer.ebay.com/DevZone/finding/CallRef/getSearchKeywordsRecommendation.html
0303      * @return Zend_Service_Ebay_Finding_Response_Keywords
0304      */
0305     public function getSearchKeywordsRecommendation($keywords, $options = null)
0306     {
0307         // prepare options
0308         $options             = parent::optionsToArray($options);
0309         $options['keywords'] = $keywords;
0310 
0311         // do request
0312         $operation = 'getSearchKeywordsRecommendation';
0313         $dom       = $this->_request($operation, $options);
0314 
0315         /**
0316          * @see Zend_Service_Ebay_Finding_Response_Keywords
0317          */
0318         // require_once 'Zend/Service/Ebay/Finding/Response/Keywords.php';
0319         $response = new Zend_Service_Ebay_Finding_Response_Keywords($dom->firstChild);
0320         return $response->setOperation($operation)
0321                         ->setOption($options);
0322     }
0323 
0324     /**
0325      * @param  string $operation
0326      * @param  array  $options
0327      * @link   http://developer.ebay.com/DevZone/finding/Concepts/MakingACall.html#StandardURLParameters
0328      * @return DOMDocument
0329      */
0330     protected function _request($operation, array $options = null)
0331     {
0332         // generate default options
0333         // constructor load global-id and application-id values
0334         $default = array('OPERATION-NAME'       => $operation,
0335                          'SERVICE-NAME'         => self::SERVICE_NAME,
0336                          'SERVICE-VERSION'      => self::SERVICE_VERSION,
0337                          'GLOBAL-ID'            => $this->getOption(self::OPTION_GLOBAL_ID),
0338                          'SECURITY-APPNAME'     => $this->getOption(self::OPTION_APP_ID),
0339                          'RESPONSE-DATA-FORMAT' => self::RESPONSE_DATA_FORMAT,
0340                          'REST-PAYLOAD'         => '');
0341 
0342         // prepare options to ebay syntax
0343         $options = $default + $this->_optionsToNameValueSyntax($options);
0344 
0345         // do request
0346         $client = $this->getClient();
0347         $client->getHttpClient()->resetParameters();
0348         $response = $client->setUri(self::ENDPOINT_URI)
0349                            ->restGet(self::ENDPOINT_PATH, $options);
0350 
0351         return $this->_parseResponse($response);
0352     }
0353 
0354     /**
0355      * Search for error from request.
0356      *
0357      * If any error is found a DOMDocument is returned, this object contains a
0358      * DOMXPath object as "ebayFindingXPath" attribute.
0359      *
0360      * @param  Zend_Http_Response $response
0361      * @link   http://developer.ebay.com/DevZone/finding/CallRef/types/ErrorSeverity.html
0362      * @see    Zend_Service_Ebay_Finding_Abstract::_initXPath()
0363      * @throws Zend_Service_Ebay_Finding_Exception When any error occurrs during request
0364      * @return DOMDocument
0365      */
0366     protected function _parseResponse(Zend_Http_Response $response)
0367     {
0368         // error message
0369         $message = '';
0370 
0371         // first trying, loading XML
0372         $dom = new DOMDocument();
0373         if (!$dom = @Zend_Xml_Security::scan($response->getBody(), $dom)) {
0374             $message = 'It was not possible to load XML returned.';
0375         }
0376 
0377         // second trying, check request status
0378         if ($response->isError()) {
0379             $message = $response->getMessage()
0380                      . ' (HTTP status code #' . $response->getStatus() . ')';
0381         }
0382 
0383         // third trying, search for error message into XML response
0384         // only first error that contains severiry=Error is read
0385         $xpath = new DOMXPath($dom);
0386         foreach (self::$_xmlNamespaces as $alias => $uri) {
0387             $xpath->registerNamespace($alias, $uri);
0388         }
0389         $ns           = self::XMLNS_FINDING;
0390         $nsMs         = self::XMLNS_MS;
0391         $expression   = "//$nsMs:errorMessage[1]/$ns:error/$ns:severity[.='Error']";
0392         $severityNode = $xpath->query($expression)->item(0);
0393         if ($severityNode) {
0394             $errorNode = $severityNode->parentNode;
0395             // ebay message
0396             $messageNode = $xpath->query("//$ns:message[1]", $errorNode)->item(0);
0397             if ($messageNode) {
0398                 $message = 'eBay error: ' . $messageNode->nodeValue;
0399             } else {
0400                 $message = 'eBay error: unknown';
0401             }
0402             // ebay error id
0403             $errorIdNode = $xpath->query("//$ns:errorId[1]", $errorNode)->item(0);
0404             if ($errorIdNode) {
0405                 $message .= ' (#' . $errorIdNode->nodeValue . ')';
0406             }
0407         }
0408 
0409         // throw exception when an error was detected
0410         if (strlen($message) > 0) {
0411             /**
0412              * @see Zend_Service_Ebay_Finding_Exception
0413              */
0414             // require_once 'Zend/Service/Ebay/Finding/Exception.php';
0415             throw new Zend_Service_Ebay_Finding_Exception($message);
0416         }
0417 
0418         // add xpath to dom document
0419         // it allows service_ebay_finding classes use this
0420         $dom->ebayFindingXPath = $xpath;
0421 
0422         return $dom;
0423     }
0424 }