Services_AmazonのキャッシュをCache_Liteに変更。Services_Amazonの結果をSimpleXmlに変更。Services_Amazonは_sendRequest()以外に拡張できるメソッドが無いので結構手間だった。_sendRequest()内でキャッシュの処理を行ったりXMLのParseしちゃってる。TemplateMethodにしてくれてるとClassをExtendsして拡張しやすかったのだけれど。
SimpleXMLで結果を取り出すとServices_Amazonを使う意味があまりなくなるのだけれど。。。。PEARのBugにRequestとして挙がってるのでそのうち対応されるのだろうけど。待ってられない。
class Utena_Amazon extends Services_AmazonECS4 { //継承するのでついでにIDを直書きする。 const AWS_TOKEN ="****"; const AA_ID ="utena-22"; //レスポンスのXML public $raw_xml = ""; public function __construct(){ parent::__construct(Utena_Amazon::AWS_TOKEN,Utena_Amazon::AA_ID); $this->setVersion('2007-02-22'); } //Localeに自前プロキシサーバーを追加 public function setLocale($locale){ $urls = array( 'US' => 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService', 'UK' => 'http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService', 'DE' => 'http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService', 'JP' => 'http://ecs.amazonaws.jp/onca/xml?Service=AWSECommerceService', 'FR' => 'http://ecs.amazonaws.fr/onca/xml?Service=AWSECommerceService', 'CA' => 'http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService', ); //cache server $urls["UTENA"] = "http://api.bookmacro.com/amazon?Service=AWSECommerceService"; $locale = strtoupper($locale); if (empty($urls[$locale])) { return PEAR::raiseError('Invalid locale'); } $this->setBaseUrl($urls[$locale]); return true; } //SimilarityLookupをArray対応にする。 //http://pear.php.net/bugs/bug.php?id=10687 //に報告済み function SimilarityLookup($item_id, $options = array()) { if(is_array($item_id)){ $item_id = implode(",", $item_id); } return parent::SimilarityLookup($item_id,$options); } //URL組み立て部分を切り出し。 protected function _RestURI($params){ $params['AWSAccessKeyId'] = $this->_keyid; $params['AssociateTag'] = $this->_associd; $params['Version'] = $this->_version; $url = $this->_baseurl; if(!$url){ return PEAR::raiseError("Request End Point have not set yet"); } foreach ($params as $k => $v) { $url .= '&' . $k . '=' . urlencode($v); } return $url; } //Cache_Liteに切り替え protected function setCache($container = 'file', $container_options = array()){ if(!class_exists('Cache_Lite')){ @include_once 'Cache_Lite.php'; } @$cache = new Cache_Lite($container_options); if (is_object($cache)) { $this->_cache = $cache; return true; } else { $this->_cache = null; return parent::setCache($container,$container_options); } } //Cacheに何か処理をフックするポイント protected function _getCache($cache_id){ if( $this->_cache == null ){ return null; } if( $data = $this->_cache->get($cache_id) ){ return simplexml_load_string($data); } return null; } //Cache_LiteとCacheはAPIが違うのでここで差異を吸収する protected function _setCache($cache_id, $data){ if( $this->_cache == null ){ return null; } $this->_cache->save($data->asXML(), $cache_id, $this->_cache_expire); } protected function _httpRequest($url){ //HTTP通信を切り替える if($this->_cache != null){ $res = $this->_cache->get( md5(strstr($url, "?")) ); if( $res ){ return $res; } } ////////////// $http = &new HTTP_Request($url); $http->setHttpVer('1.0'); $http->addHeader( 'User-Agent', 'Utena_Amazon/'.$this->getApiVersion() ); $http->sendRequest(); $http->disconnect(); if ($http->getResponseCode() != 200){ return PEAR::raiseError( 'Amazon returned invalid HTTP response code ' . $http->getResponseCode() ); } $res = $http->getResponseBody(); if( PEAR::isError($res)){ return PEAR::raiseError("HTTP Request Error"); } if($this->_cache != null){ $this->_cache->save( md5( strstr($url, "?")), $res ); } return $res; } protected function _parseResponse($result){ //ココを切り替えることでsimpleXMLにする $result = str_replace("xmlns", "_xmlns", $result); $this->raw_xml = $result; $xml = simplexml_load_string($result); //何を返却するか・・・ //何をキャッシュするべきか if( isset($xml->Errors) ){ $str; foreach( $xml->Error as $error ){ $str .= "$error->Code:$error->Message\n"; } return PEAR::raiseError($str); } //$this->_processing_time = $xml->{"RequestProcessingTime"}; unset($xml["_xmlns"]); unset($xml->OperationRequest); return $xml; } public function _sendRequest($params){ $this->_errors = array(); if ($this->_keyid==null) { return PEAR::raiseError('Access Key ID have not been set'); } $url = $this->_RestURI($params); $this->_lasturl = $url; if (PEAR::isError($url)) { return $url; } // Return cached data if available $cache_id = false; if (isset($this->_cache) && !$this->_ignoreCache($params['Operation'])) { $cache_id = $this->_generateCacheId($params); } if( $cache_id ){ $cache = $this->_getCache( $cache_id ); if (!is_null($cache)) { $this->_processing_time = 0; return $cache; } } //http request $result = $this->_httpRequest($url); if (PEAR::isError($result)) { var_dump($result); exit(); return $result; } //parse XML $content = $this->_parseResponse($result); if (PEAR::isError($content)) { return PEAR::raiseError("Cannot Get Content.. "); } //cache if ($cache_id) { $this->_setCache($cache_id,$content); } return $content; } }