Skip to content

Instantly share code, notes, and snippets.

@woodroots
Created April 5, 2013 13:24
Show Gist options
  • Save woodroots/5319238 to your computer and use it in GitHub Desktop.
Save woodroots/5319238 to your computer and use it in GitHub Desktop.
AmazonからAPIを使って商品データを取得し、WordPressに投稿する方法
<?php
//Amazon共通の定数
define('AF','nets0f-22'); //トラッキング
define('AC','AAAAAAAAAAAAAAAA'); //アクセスキー
define('SEC','abcdefghijklmnopqrstuvwxyz'); //シークレットキー
define('URL','http://ecs.amazonaws.jp/onca/xml'); //リクエスト先のURL
//認証取得用function
function urlencode_rfc3986($str) {
return str_replace('%7E', '~', rawurlencode($str));
}
function get_key($param){
ksort($param);
$canonical_string = '';
foreach ($param as $k => $v) {
$canonical_string .= '&'.urlencode_rfc3986($k).'='.urlencode_rfc3986($v);
}
$canonical_string = substr($canonical_string, 1);
$parsed_url = parse_url(URL);
$string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}";
$signature = base64_encode(hash_hmac('sha256', $string_to_sign, SEC, true));
// 返り値のURLにアクセスするとXMLが取得できます。
return URL.'?'.$canonical_string.'&Signature='.urlencode_rfc3986($signature);
}
//画像をサーバに保存するfunction
//URLを投げたら指定したディレクトリに保存するだけ。。。。
function dl_image($url){
$tempimg = file_get_contents($url);
file_put_contents(WP_CONTENT_DIR.'/upload/'.basename($url),$tempimg);
unset($tempimg);
return WP_CONTENT_DIR.'/upload/'.basename($url);
}
//ここから実際の取得処理------------------------------------------
//取得処理はwp_cronで動かしますのでadd_actionは不要です。
function get_amazon(){
$ct = array(
'1' => '562020' //WP上のカテゴリID => Amazon上のカテゴリNo
);
//ページカウンター
//1ページずつ取っていきます。どこまで取得できたかをget_optionで保持している
if(get_option('count')){
$i = get_option('count');
} else {
$i = 1;
add_option('count',1);
}
foreach($ct as $key=>$val){
//Amazonで必要なパラメーター類
$param = array(
'Service' => 'AWSECommerceService',
'AWSAccessKeyId' => AC,
'Operation' => 'ItemSearch',
'AssociateTag' => AF,
'ResponseGroup' => 'ItemAttributes,Images,Reviews',
'SearchIndex' => 'DVD',
'BrowseNode' => $val,
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
'ItemPage' => $i
);
//先に定義した認証パラメータ付きURLを生成
$recurl = get_key($param);
//ページカウントを進める
//XML取得の途中で落ちてもいいようにforeach入る前にしてますがforeach後のほうが自然かも
update_option('count',$i + 1);
//XML取得
$xml = simplexml_load_file($recurl);
foreach($xml->Items->Item as $key2=>$val2){
$actarray = array();
foreach($val2->ItemAttributes->Actor as $act){
$actarray[] = (String)$act;
}
//ここで記事として投稿処理を行う
//ページスラッグがEANコード(ISBN的なものだと思われる)、タグをキャストとして投稿していますが適宜カスタムフィールドや本文などにしてもいい。
$postid = wp_insert_post(array(
'post_status' => 'publish',
'post_category' => array($key),
'post_title' => $val2->ItemAttributes->Title,
'post_name' => $val2->ItemAttributes->EAN,
'tags_input' => $actarray
));
//重複チェック
//同じ商品を取ってしまった場合、EANが同じになるので末尾に「-2」などと付加される。その「-」があれば一回投稿した記事を削除する。
//なお、無条件で「-」入りだと削除しているのでEAN以外をpost_nameにしていると間違って削除されるおそれがあります。
$temppost = get_page($postid);
if(strpos($temppost->post_name, '-') === true){
wp_delete_post($postid);
} else {
//カスタムフィールドの付加
//商品URLや画像URLに加えて最終更新日としてtime()を追加している。理由は後述。
if($postid){
add_post_meta($postid,'DetailPageURL',(String)$val2->DetailPageURL,true);
add_post_meta($postid,'SmallImage',(Array)$val2->SmallImage,true);
add_post_meta($postid,'MediumImage',(Array)$val2->MediumImage,true);
add_post_meta($postid,'LargeImage',(Array)$val2->LargeImage,true);
add_post_meta($postid,'IFrameURL',(String)$val2->CustomerReviews->IFrameURL,true);
add_post_meta($postid,'LastUpdate',(String)time(),true);
//画像をローカルに保存する
$smalimg = $val2->SmallImage->URL;
$smalimg_local = dl_image($smalimg);
$midimg = $val2->MediumImage->URL;
$midimg_local = dl_image($midimg);
$largeimg = $val2->LargeImage->URL;
$largeimg_local = dl_image($largeimg);
}
}
}//end foreach xml
}//end foreach
}//Amazonからの取得処理ここまで
//Cronの設定---------------------------------------------------------
//デフォルトのdailyやweeklyだけだと使い勝手が悪いのでいくつか足しておく
//このcron_schedulesとwp_schedule_eventはテンプレ的にこのままでいいでしょう。
add_filter('cron_schedules','cron_add');
function cron_add($schedules){
$schedules['90min'] = array(
'interval' => 5400,
'display' => __( '90min' )
);
$schedules['100min'] = array(
'interval' => 6000,
'display' => __( '100min' )
);
$schedules['120min'] = array(
'interval' => 7200,
'display' => __( '120min' )
);
return $schedules;
}
//Cronに上記のget_amazon()を登録する
//90分単位で動作します。
add_action('cron_for_amazon', 'get_amazon');
function my_activation() {
if ( !wp_next_scheduled( 'cron_for_amazon' ) ) {
wp_schedule_event(time(), '90min', 'cron_for_amazon');
}
}
add_action('wp', 'my_activation');
//ここからは商品データアップデート処理------------------------------------------
//Amazonは規約で24時間以上のキャッシュ保存が認められません。そこで前述のカスタムフィールドに加えている「LastUpdate」を見て、24時間が経過している場合は更新処理を行います。
function update_amazon(){
if(is_single()){
global $post;
//LastUpdateと現在時刻の差が「60秒*60分*24時間」以上なら処理する
if($post->LastUpdate < (time() - 86400 )){
$param = array(
'Service' => 'AWSECommerceService',
'AWSAccessKeyId' => AC,
'Operation' => 'ItemLookup',
'AssociateTag' => AF,
'ResponseGroup' => 'ItemAttributes,Images,Reviews',
'IdType' => 'EAN',
'SearchIndex' => 'DVD',
'ItemId' => $post->post_name, //EANさえあれば商品は引っ張れる
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
);
$recurl = get_key($param);
$xml = simplexml_load_file($recurl);
if($xml->Items->Item){
foreach($xml->Items->Item as $val2){
update_post_meta($postid,'DetailPageURL',(String)$val2->DetailPageURL);
update_post_meta($postid,'SmallImage',(Array)$val2->SmallImage);
update_post_meta($postid,'MediumImage',(Array)$val2->MediumImage);
update_post_meta($postid,'LargeImage',(Array)$val2->LargeImage);
update_post_meta($postid,'IFrameURL',(String)$val2->CustomerReviews->IFrameURL);
update_post_meta($postid,'LastUpdate',(String)time());
//画像の差し替え
//引数無しfile_put_contentsなので上書きされます
$smalimg = $val2->SmallImage->URL;
$smalimg_local = dl_image($smalimg);
$midimg = $val2->MediumImage->URL;
$midimg_local = dl_image($midimg);
$largeimg = $val2->LargeImage->URL;
$largeimg_local = dl_image($largeimg);
}
}
}
}
}//func end
//shutdownにフックすることで見る人にも優しい(はず)
add_action('shutdown','update_amazon');
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment