記事にショートコードでアフィリエイトリンクを挿入していたが、リンク切れの修正が面倒。管理画面で一元管理できるように修正してみよう

Amazonのアフィリエイトリンクの生成はショートコードを用いて行っている。

Amzonアフィリエイトリンクをショートコードで作成する

ASPのツールもアソシエイトツールバーも使わずにアマゾンのアフェリエイトリンクをそれなりのデザインで生成する方法

以前このような記事を書いたけど、いくつか問題点があるので修正することにした。具体的には以下の2点。

今回修正する問題点は2点

  • リンクの修正が面倒
  • ASIN由来のURLで画像が表示されない

他にも問題点があるが今回は上記2点の問題に対処する。

リンクの修正

アフィリエイトのリンク先を修正することはよく起きる。特に多いのがリンク切れ。Amazonアフィリエイトの場合だと対象の商品がAmazonで販売終了した場合に起きる。このような場合、各記事に貼り付けたリンクの修正が必要になる。以前の記事で書いたようにショートコードでリンクを生成しているならショートコードを修正しなければならない。複数の記事に同じ商品のリンクが貼ってあればすべて直す必要がある。

この記事の執筆時点ではまだ30記事もないけど、それでも同じリンクがいくつかある。現状ですでに面倒・・・。

ちたまん

今後200記事とか1000記事とかになったら労力が半端ないね

ツン子

ASIN由来のURLで画像が表示されない

以前はASINから画像URLを生成していた。この方法だと一部の商品で画像が正しく表示されない。ついでにこの問題にも対応しようと思う

そこで管理画面でAmazonのアフィリエイト商品を管理する方法に変えようと思う

まず完成例を見せよう

サブメニューAmazon商品

このように管理画面に「アフィリエイト設定」というメニューを追加した。メインメニューとしてアフィリエイト全般の設定をする「アフィリエイト設定」、サブメニューとして「Amzon商品」とした。

メインメニューのアフィリエイト設定は現状ではアソシエイトIDを登録するだけなので画像は割愛。ゆくゆくは楽天IDやアドセンスの設定もここに追加する予定。上記画像はサブメニューのもの。

そしてこのサブメニュー「Amazon商品」が今回の本題。

中身は上図のように新規登録と登録済みの商品一覧が表示されるようになっている。新規登録で必要な項目はDP、ブランド、タイトル、検索キーワード、画像URLの5つ。DPとはASINまたはISBN-10のコードの入力欄。検索キーワードは楽天用の検索ワード。

画像URLは任意

画像URLは任意入力としている。基本的にはASINから画像URLを自動生成するので画像URLは必要ないが、もし画像URLの項目が入力されている場合はそちらを優先するようにしている。つまりASINから画像が取得できない場合はAmazonの商品ページかから手動でリンクを取得してここに貼り付けておけば画像が表示できない問題を回避できる。

次にそれでは登録済みの商品一覧のほうを見ていこう。

ここでは操作として3つ用意した。

  • 修正する
  • 商品ページ
  • ショートコード

「修正する」ボタンは各商品の修正が必要な場合にクリックする。単純に入力を間違えた場合はもちろんだが、リンク切れ時に別商品に変える場合もここで修正する。

「商品ページ」ボタンはAmazonの該当ページを開いて確認するためのも

「ショートコード」ボタンはクリックすることで記事貼り付けようのショートコードをクリップボードにコピーする機能。ここで取得したショートコードを記事に貼り付けて利用する

このようにしておけば管理画面で商品を修正するだけで各記事に埋め込んだショートコードから生成される商品の情報も自動で変更されるので、商品の修正が容易になるというわけ

functions.php

ではコードを見ていこう。

今回もfunctions.phpに記述していくけど大きく分けて4つの内容を記述するのでそれぞれ分けて説明していく

データベースにテーブルを追加

<?php
/*************************************************

	Data Base
	
*************************************************/
global $wpdb;

//DBのバージョン
$cmt_db_version = '0.1.7';

//現在のDBバージョン取得
$installed_ver = get_option( 'cmt_meta_version');

// DBバージョンが違ったら実行
if( $installed_ver != $cmt_db_version ) {
	require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
	
	$sql = "CREATE TABLE " . $wpdb->prefix .'AFF_AMZ_T' . " (
			ID_C bigint UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
			DP_C char(10),
			BRAND_C char(30),
			TITLE_C char(60),
			SEARCH_C char(60),
			URL_C char(255)
			
		)
		CHARACTER SET 'utf8';";
	
	dbDelta($sql);

	
//オプションにDBバージョン保存
	update_option('cmt_meta_version', $cmt_db_version);
}

?>

商品管理はMySQLを使用する。ワードプレスで利用されているMySQLデータベースにテーブルを追加する形だ。

このコードの骨組みはかなり前にweb上で探して拝借させてもらったものだ。$cmt_db_versionの内容を書き換えた時だけそれ以降のコードが実行されるようになっている。

独自メニュー、サブメニューを追加する

まず管理画面に独自のメニュー、サブメニューを追加するためのコード

<?php
/*************************************************

	独自メニューの追加
	
*************************************************/


add_action('admin_menu', 'custom_menu_page');
function custom_menu_page()
{
	add_menu_page('ブログ設定', 'ブログ設定', 'manage_options', 'blog_menu_page', 'add_blog_menu_page', 'dashicons-admin-generic', 4);
	add_action('admin_init', 'register_custom_setting');
	
	add_menu_page('アフィリエイト設定', 'アフィリエイト設定', 'manage_options', 'aff_menu_page', 'add_aff_menu_page', 'dashicons-admin-generic', 4);
	add_action('admin_init', 'register_aff_setting');
	
}
add_action('admin_menu', 'add_custom_submenu_page');
function add_custom_submenu_page()
{
    add_submenu_page('aff_menu_page', 'Amazon商品', 'Amazon商品', 'manage_options', 'aff_submenu_page_1', 'add_aff_submenu_page_1', 1);
}


/************************************************ アフィリエイト設定 */


function add_aff_menu_page(){
	// メニューの内容(ここは本題ではないので省略)
}

function add_aff_submenu_page_1(){
	// サブメニューの内容(後述)
}
?>

サブメニューの内容

<?php
function add_aff_submenu_page_1(){
	
	global $wpdb;
	if(!empty($_POST['mode'])){
		if( $_POST['mode'] == 'add' && !empty($_POST['dp']) ){
		
			$wpdb->insert( 
				$wpdb->prefix .'AFF_AMZ_T', 
				array(
					'DP_C' => $_POST['dp'],
					'BRAND_C' => $_POST['brand'],
					'TITLE_C' => $_POST['title'],
					'SEARCH_C' => $_POST['search'],
					'URL_C' => $_POST['url']
				), 
				array('%s','%s','%s','%s','%s') 
			);
		}else{
			$wpdb->update( 
				$wpdb->prefix .'AFF_AMZ_T', 
				array( 
					'DP_C' => $_POST['dp'],
					'BRAND_C' => $_POST['brand'],
					'TITLE_C' => $_POST['title'],
					'SEARCH_C' => $_POST['search'],
					'URL_C' => $_POST['url']
				), 
				array( 'ID_C' => $_POST['mode'] ), 
				array('%s','%s','%s','%s','%s') , 
				array( '%d' ) 
			);
		}
	}
	$sql = "SELECT * FROM ".$wpdb->prefix .'AFF_AMZ_T';

	$results = $wpdb->get_results( $sql );
	
	?>
	
	<div class="wrap myMenu" >
		<h2>Amazon商品管理</h2>
		<h3>新規商品追加</h3>
		<form method="post" action="" enctype="multipart/form-data" encoding="multipart/form-data">
			
			<table border="1" style="border-collapse: collapse;">
				<tr>
					
					<th>DP / ブランド</th>
					<th>タイトル</th>
					<th>検索ワード</th>
					<th>画像URL</th>
					<th>操作</th>

				</tr>
				<tr>
					
					<td>
						<input type="text" name="dp" value="" style="width:12em;">
						<input type="text" name="brand" value="" style="width:12em;">
					</td>
					<td><textarea name="title" style="width:15em;height:4.8em;"></textarea></td>
					<td><textarea name="search" style="width:15em;height:4.8em;"></textarea></td>
					<td><textarea name="url" style="width:20em;height:4.8em;"></textarea></td>
					<td>
						<input type="hidden" name="mode" value="add" />
						<input type="submit" value="登録する">
					</td>
				</tr>
			</table>
			
			
		</form>
		
		<h3>登録済み商品</h3>
		<table border="1" style="border-collapse: collapse;">
			<tr>
				<th>画像</th>
				<th>DP / ブランド</th>
				<th>タイトル</th>
				<th>検索ワード</th>
				<th>画像URL</th>
				<th>操作</th>

			</tr>
			<?php foreach($results as $r):?>
			<?php
				if(!empty($r->URL_C)){
					$imgUrl = $r->URL_C;
				}else{
					$imgUrl = 'https://images-fe.ssl-images-amazon.com/images/P/' . $r->DP_C . '.09.MZZZZZZZ.jpg';
				}
			?>
			<tr>
				<form method="post" action="" enctype="multipart/form-data" encoding="multipart/form-data">
					
					<td><img src="<?php echo $imgUrl?>" /></td>
					<td>
						<input type="text" name="dp" value="<?php echo $r->DP_C; ?>" style="width:12em;" />
						<input type="text" name="brand" value="<?php echo $r->BRAND_C; ?>" style="width:12em;" />
					</td>
					<td><textarea name="title" style="width:15em;height:4.8em;"><?php echo $r->TITLE_C; ?></textarea></td>
					<td><textarea name="search" style="width:15em;height:4.8em;"><?php echo $r->SEARCH_C; ?></textarea></td>
					<td><textarea name="url" style="width:15em;height:4.8em;"><?php echo $r->URL_C; ?></textarea></td>
					<td>
						<input type="hidden" name="mode" value="<?php echo $r->ID_C; ?>" />
						<input type="submit" value="修正する">
						<button type="button" onclick="window.open('https://www.amazon.co.jp/dp/<?php echo $r->DP_C; ?>', '_blank')">商品ページ</button>
						<button onClick="copyClip(this)" value="

該当する商品がみつかりません

">ショートコード</button> </td> </form> </tr> <?php endforeach; ?> </table> </div> <script> function copyClip(obj){ navigator.clipboard.writeText(obj.value); }; </script> <?php } ?>

勢いで雑に作ったのであまり参考にしないほうがいいかも(汗

POSTデータ$_POST[‘mode’]の内容で新規追加かレコードの修正かを分岐してる。「add」の場合が新規追加でそれ以外は修正となる。emptyならどちらも行わない。

ショートコードの内容

<?php
// Amazon商品ページ
function createAmzLink($atts){
	
	global $wpdb;
	
	$id = get_option('amzID');
	
	$sql = "SELECT * FROM ".$wpdb->prefix .'AFF_AMZ_T';

	$results = $wpdb->get_results( $wpdb->prepare(
		"SELECT * FROM ".$wpdb->prefix .'AFF_AMZ_T WHERE ID_C = %d',
		$atts['id']
	));
	
	if(count($results) > 0){
		$url = 'https://www.amazon.co.jp/exec/obidos/ASIN/' .$results[0]->DP_C.'/'.$id;
		$rUrl = 'https://search.rakuten.co.jp/search/mall/' .$results[0]->SEARCH_C;
		if(!empty($results[0]->URL_C)){
			$imgUrl = $results[0]->URL_C;
		}else{
			$imgUrl = 'https://images-fe.ssl-images-amazon.com/images/P/' . $results[0]->DP_C . '.09.MZZZZZZZ.jpg';
		}
		$html = '<ul class="amzLink fPadding1x">'."\n";
		$html .= '	<li class="imgArea"><a href="' .$url . '" target="_blank"><img src="'. $imgUrl .'" /></a></li>'."\n";
		$html .= '	<li class="bodyArea">';
		$html .= '		<h4>'. $results[0]->BRAND_C .'</h4>'."\n";
		$html .= '		<h5>'. $results[0]->TITLE_C .'</h5>'."\n";
		$html .= '		<ul class="linkList">'."\n";
		$html .= '			<li class="amz"><a class="linkBtn" href="' .$url. '" target="_blank">Amazonで見る</a></li>'."\n";
		$html .= '			<li class="raku"><a class="linkBtn" href="' .$rUrl. '" target="_blank">楽天で探す</a></li>'."\n";
		$html .= '		</ul>'."\n";
		$html .= '	</li>'."\n";
		$html .= '</ul>'."\n";
	}else{
		$html = '<p>該当する商品がみつかりません</p>';
	}
	return $html;
	
}

add_shortcode('amzLink','createAmzLink');
?>

ショートコードは[amzLink id=○]というように使用する。ここでいうIDはDBに登録した商品のIDフィールドのことをいう。このIDはDB登録時に自動で設定される。そのため直感的にわかりにくいので管理ページにコピペボタンを設置したわけだ。スラッグのような固有名を付けたほうが使い良いと思うがとりあえずこれで。

現状の問題点

リンクを一元管理できるようになり便利になったもののまだ問題点はある。まず記事執筆中にリンクを貼りたくなった時にメニューを表示する必要があること。記事編集画面とメニューの表示は同時に出来ないので一度執筆を中断するか別タブで表示する必要がある。記事編集画面から別ウィンドウで今回のメニュー画面を出せるとよさそうだ。

もう一点はリンク切れ時の修正は楽になったものの、リンク切れを検知する方法が無いこと。記事数が増え紹介する商品が増えればリンク切れも増えてくると思うので、リンク切れの検知機能と可能なら自動修正機能も追加したい。

リンク切れは検知機能を導入しないと、ブログ運営者はリンク切れに気づくことが難しい。

ちたまん

放置されたままだとユーザーはクリックしても該当ページが表示されないからイラっとするよね。

ツン子

うん。なのでこの点は早めに改善したいと思っている。

ちたまん

他にも使っていれば問題点が出てくると思うので今後も改良していきたい。