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