Afficher simplement et rapidement une liste de livres Amazon.
Le code proposé permet à quiconque disposant d'un compte partenaire Amazon de requeter et d'afficher les résultats:
En utilisant les API REST d'Amazon et PHP, ItemSearch, ItemLookUp et BrowseNodeLookup
En combinant dans une toute petite classe autonome quelques primitives, sauce MVC
Vous pourrez ajouter d'autres vues et requetes sur la base des fonctions existantes
J'ai utilisé quelques primitives pour l'éxecution de la classe, la base d'un MicroDispatcher HMVC en Php:
DEFINE('ROOT_URL', ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://' ). $_SERVER['HTTP_HOST']. $_SERVER['SCRIPT_NAME'].'/'); DEFINE('DEFAULT_PARAM',''); // Very Tiny Action Urler function actionUrl($class, $method, $args){ $url = $class. '/'.$method.'/'; ksort($args); $params = ''; foreach ($args as $key=>$value){ $params .= (!empty($value) && $value != DEFAULT_PARAM) ? $key.'/'. $value .'/' : ''; } return ROOT_URL . $url.$params; } // Very Tiny Request Parameter function parseUrl($url){ $requestParams = new stdClass(); $query = str_replace(ROOT_URL, '/', $url); $params = explode('/', $query ); array_shift($params); $requestParams->className = array_shift($params); $requestParams->methodName = array_shift($params); $args = array(); $nbargs = count($params)-1; for($i=0; $i < $nbargs; $i=$i+2){ $args[$params[$i]] = $params[$i+1]; //0-1, 2-3, 4-5 } $requestParams->args = $args; return $requestParams; } function getParam($paramName = FALSE, $default = DEFAULT_PARAM){ static $requestParams; if (!isset($requestParams)){ if (isset($_SERVER['PATH_INFO'])){ $query = $_SERVER['PATH_INFO']; $requestParams = parseUrl($query); $requestParams->args = array_merge($requestParams->args , $_GET); }else{ $requestParams->className = FALSE; $requestParams->methodName = FALSE; $requestParams->args = $_GET; } } if($paramName){ if (isset($requestParams->args[$paramName]) && ($requestParams->args[$paramName] != DEFAULT_PARAM)){ return $requestParams->args[$paramName]; }else{ return $default; } }else{ return $requestParams; } }
Et une petite fonction de pagination, classique, tranquille, qui pagine ...:
function paginate($page, $nombre_de_page, $url){ $request = parseUrl($url); // on veut afficher au maximum 9 pages sous la forme // " <<-1-2-3-4-5-6-7-8-9->> " // on va donc faire une boucle que l'on va décaler // à chaque fois de une page, à partir de la cinquième page // et jusqu'à l'avant avant ...n page. $menu = ""; $decale = 0; if ($page > 5 && $page <= ($nombre_de_page-4)){ $decale = $page-5; }elseif ($page < 5){ $decale = 0; }elseif ($page > ($nombre_de_page-5)){ $decale = $nombre_de_page-9; } // ensuite on veut afficher des "boutons" précedent et suivant $request->args['page'] = $page+1; $plus = ($page == $nombre_de_page)? '' : '›'; $request->args['page'] = $page-1; $moins = ($page == 1)?"":'‹'; // en fonction du nombre de page on distingue deux fin de boucle // possible... $fin_de_boucle = ($nombre_de_page < 10)?"$nombre_de_page":"".(9+$decale).""; // on fait une boucle avec tout le bazar du haut... for ($i =1+$decale; $i <= $fin_de_boucle; $i++){ $request->args['page'] = $i; $menu .= ($i == $page) ? ''.$i.'' : ' '.$i.''; } return '' . $moins.$menu.$plus . ''; }
Enfin , la classe Amazon elle même
Class Amazon{ private $AWS_key = "Change this to your AWS Access Key"; private $AWS_secretKey = "Change this to your AWS Access Secret Key"; private $AWS_AssociateTag = "Change this to your AWS Tracking Id"; private $AWS_base_url = "http://ecs.amazonaws.fr/onca/xml?";// France private $AWS_BooksNodes = 301061; // France function __construct(){ } private function makeUrl($params){ $query_string = ""; foreach ($params as $key => $value) { $query_string .= "&" . $key . "=" . $value; } $url = str_replace("?&","?", $this->AWS_base_url.$query_string); $host = parse_url($url,PHP_URL_HOST); $paramstart = strpos($url,"?"); $workurl = substr($url,$paramstart+1); $workurl = str_replace(",","%2C",$workurl); $workurl = str_replace(":","%3A",$workurl); $params = explode("&",$workurl); sort($params); $signstr = "GET\n" . $host . "\n/onca/xml\n" . implode("&",$params); $signstr = base64_encode(hash_hmac('sha256', $signstr, $this->AWS_secretKey, true)); $signstr = urlencode($signstr); $request = $url . "&Signature=" . $signstr; return $request; } private function runRequest(array $params){ $request = $this->makeUrl($params); $xml = $this->getAmazonPage($request, $code, $headers); return $xml; } private function getAmazonPage($url, &$code, &$headers) { if (function_exists('curl_exec')) { $ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt ($ch, CURLOPT_USERAGENT, ' Fx NION /1.0 (+ http://www.les-ames-tendres.com /)'); curl_setopt ($ch, CURLOPT_HEADER, 1); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_TIMEOUT, 120); if (!ini_get('open_basedir') && !ini_get('safe_mode')){ curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, TRUE); }else{ curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, FALSE); } $result = curl_exec ($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $hsize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $headers = substr($result, 0, $hsize - 2); $result = substr($result, $hsize); curl_close($ch); return $result; } $code = 200; $headers = ""; $result = implode('', file($url)); } private function defaultsAmazonParams(){ /* AWS / ECS 4.0 Requestparameters */ $params = array( 'Service' => 'AWSECommerceService', 'AWSAccessKeyId'=> $this->AWS_key, 'AssociateTag' => $this->AWS_AssociateTag, 'Timestamp' => gmstrftime("%Y-%m-%dT%H:%M:%S.000Z"), 'Version' => '2009-10-01' ); return $params; } private function actionUrl($method, $args = array()){ return actionUrl('amazon', $method, $args); } private function actionUrlNice($method, $args = array()){ return $this->actionUrl($method, array( "node"=> !empty($args['node']) ? $args['node'] : getParam('node'), "title"=> !empty($args['title']) ? $args['title'] : getParam('title'), "author"=> !empty($args['author']) ? $args['author'] :getParam('author'), "keywords"=>!empty($args['keywords']) ? $args['keywords'] :getParam('keywords'), "page"=>!empty($args['page']) ? $args['page'] :getParam('page'), )); } // Begin Model Functions ***************************************************/ private function _searchBookFull($node, $title='', $author='', $keywords='', $page=1){ $params = array( 'Operation' => 'ItemSearch', 'SearchIndex' => 'Books', 'Sort' => 'salesrank', 'BrowseNode' => $node, 'ItemPage' => $page, 'Title' => str_replace(" ","%20",$title), 'Keywords' => str_replace(" ","%20",$keywords), 'Author' => str_replace(" ","%20",$author), 'ResponseGroup' => 'Medium', //Request, Small, Medium, Large ... ); $params = array_merge($params,$this->defaultsAmazonParams()); return $this->runRequest($params); } private function _searchBook($title='', $author='', $keywords='', $page=1){ return $this->_searchBookFull('', $title, $author, $keywords, $page); } private function _getBook($ASIN){ $params = array( 'Operation' => 'ItemLookup', 'IdType' => 'ASIN', 'ResponseGroup' => 'Medium', //Request, Small, Medium, Large ... 'ItemId' => $ASIN, ); $params = array_merge($params,$this->defaultsAmazonParams()); return $this->runRequest($params); } private function _getNodes($nodeBegin){ $params = array( 'Service' => 'AWSECommerceService', 'AWSAccessKeyId'=> $this->AWS_key, 'Operation' => 'BrowseNodeLookup', 'BrowseNodeId' => $nodeBegin, 'Version' => '2009-10-01', 'Timestamp' => gmstrftime("%Y-%m-%dT%H:%M:%S.000Z") ); $params = array_merge($params,$this->defaultsAmazonParams()); return $this->runRequest($params); } // End Model Functions ***************************************************/ // Begin Controller Functions ********************************************/ public function getBook($asin){ $book = $this->_getBook($asin); return $this->viewGetBook($book); } public function searchBook($title='', $author='', $keywords='', $page=1){ $book = $this->_searchBook($title, $keywords,$author, $page); return $this->viewSearch($book, 'searchBook'); } public function searchBookFull($node=301061, $title='', $author='', $keywords='', $page=1){ $book = $this->_searchBookFull($node, $title, $author, $keywords, $page); return $this->viewSearch($book,'searchBookFull'); } public function getNodes($node){ $nodeList = $this->_getNodes($node); return $this->viewNodes($nodeList); } // End Controller Functions **********************************************/ // Begin View Functions **************************************************/ private function viewGetBook($xmlString){ $result = simplexml_load_string($xmlString); $listItem = $result->Items->Item; $output = ''; $output .= '
'; $output .= ''; $output .= ''; $output .= ''; $output .= ' | ';
$output .= ''.$title.'';
$output .= ' '.$publisher . ''; $output .= ' |
// La base, on instancie la classe. $Amazon = new Amazon(); // Afficher le browser à partir d'un noeud de départ echo $Amazon->getNodes(getParam('node',$NodeLivres )); // Afficher la liste des livres à partir des paramétres fournis en url. echo $Amazon->searchBookFull(getParam('node',$NodeThemes), getParam('title',''), getParam('author',''), getParam('keywords',''), getParam('page','')); // recherche par titre seulement, avec une valeur par défaut echo $Amazon->searchBook(getParam('title','oulipo')); // Affichage d'un livre correspondant à un ASIN echo $list = $Amazon->getBook('2070373630'); // Affichage d'une liste de livres echo $list = $Amazon->getBook('2070373630,2290017558,2266211781'); //Affichage d'un formulaire de filtre echo $Amazon->filter();
Recopiez les codes ci dessus , SURTOUT modifiez les paramétres correspondant à votre compte dans le ficher amazon.php: