自宅サーバの整理箱

自宅サーバを構築しwordpress,fedora,CentOSの作業メモ

*

WP Rakuten Linkがエラー。楽天アフィリエイトプラグイン「wp-rakuten-link」を楽天APIの更新に対応させた。

   

楽天アフィリエイトには大変便利な「wp-rakuten-link」ですが、作者様の更新がしばらく停止しており、先日5/24の楽天APIの旧インターフェースの停止に伴いエラーとなり利用(表示)されなくなっていました。

■旧楽天API「api.rakuten.co.jp」が2015/5/24で完全廃止、これに伴い新API「https://app.rakuten.co.jp」へ移行しなければいけない。

楽天市場のアフィリエイトで少しでも収入があった私としては、これは大ピンチ!そこで自力で修正しました。他にも困っている方がいるかとおもいますので、作者様が更新するまでの間、私の修正した内容を公開したいと思います。

基本的にメソッド毎コピペで入れ替えてもらえれば簡単にできます。

投稿画面のWP Rakuten Linkのカテゴリ表示を復活させる

記事への挿入時にドロップダウンリストでカテゴリが表示されますが、まずはこれの表示を復活させます。

修正するプラグイン:wp-contents/plugin/wp-rakuten-link
ソースファイル:rakuten_link.php

■function rakuten_itemsearch(keyword, cat_num)を以下のように修正します。

			function rakuten_itemsearch(keyword, cat_num){

				jQuery("#rakuten_itemresult_" + cat_num).html("検索中……");

				if( r_keyword[cat_num] != keyword){
					r_page[cat_num] = 1;
				}

				r_keyword[cat_num] = keyword;

				switch (cat_num){
					case 0:
						var data_obj = {
								"applicationId": "<?php echo $rakuten_options['developer_id'] ?>",
								"affiliateId": "<?php echo $rakuten_options['affiliate_id'] ?>",
								"genreId" : jQuery("#rakuten_genre").val(),
								"hits": "<?php echo $rakuten_options['result_num'] ?>",
								"page": r_page[cat_num],
								"format": "json",
								"formatVersion" : "2",
								"keyword": r_keyword[cat_num]
						}
						$rakutenurl="https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222?";
						break;

					case 1:
						var data_obj = {
								"applicationId": "<?php echo $rakuten_options['developer_id'] ?>",
								"affiliateId": "<?php echo $rakuten_options['affiliate_id'] ?>",
								"booksGenreId" : jQuery("#rakuten_book_genre").val(),
								"hits": "<?php echo $rakuten_options['result_num'] ?>",
								"page": r_page[cat_num],
								"keyword": r_keyword[cat_num],
								"format": "json",
								"formatVersion" : "2",
								"genreInformationFlag": "1"
						}
						$rakutenurl="https://app.rakuten.co.jp/services/api/BooksTotal/Search/20130522?";
						break;
					default:
						return false;
						break;
				}

				jQuery.ajax({

					url: $rakutenurl,
					data: data_obj,
					dataType: "jsonp",
					error: function(){
						jQuery("#rakuten_itemresult_" + cat_num).html("検索処理中にエラーが発生しました。");
						return false;
					},
					success: function(data) {
							switch(cat_num){
								case 0:
									var head = data;
									var items = data.Items;
									break;

								case 1:
 									var head  = data;
									var items = data.Items;
									var genre = data.GenreInformation;
									break;
							}
							jQuery("#rakuten_itemresult_" + cat_num).html("");
							jQuery("#rakuten_itemresult_" + cat_num).append(head.count + " 件の商品が見つかりました! (" + head.page + "/" + head.pageCount + "ページ)&nbsp;");

							jQuery("#rakuten_itemresult_" + cat_num).append('<input type="button" value="前のページ" id="rakuten_beforepage" class="button-secondary action" onclick="rakuten_pagemove(' + (r_page[cat_num] - 1) + ', ' + cat_num + ')">');
							jQuery("#rakuten_itemresult_" + cat_num).append('<input type="button" value="次のページ" id="rakuten_nextpage" class="button-secondary action" onclick="rakuten_pagemove(' + (r_page[cat_num] + 1) + ', ' + cat_num + ')">');
							jQuery("#rakuten_itemresult_" + cat_num).append('<br />');
							jQuery('<ul class="rakuten_itemlist" />').appendTo("div#rakuten_itemresult_" + cat_num);

							// ページ送りの処理とか
							if ( parseInt(r_page[cat_num]) <= 1 ){
								jQuery("#rakuten_beforepage").remove();
							}
							if ( parseInt(r_page[cat_num]) >= head.pageCount ){
								jQuery("#rakuten_nextpage").remove();
							}

							// アイテムの表示部分
							jQuery.each(items, function(i, item) {

								var tips = "";
								var content = "";

								switch(cat_num){
									case 0:

										if ( items[i].imageFlag == "1" ) {
											var simage = items[i].smallImageUrls;
											var img = "<img src='" + simage[0] + "' class="rakuten_itemimg" title="" + items[i].itemName + "" />";

										} else {
											var img = "[商品画像なし]";
										}

										tips =
										items[i].itemName;

										content = 
										"<a href="" + items[i].itemUrl + "" target="_blank" class="tooltip">" + img + "<span>" + tips + "</span></a><br />" + 
										'価格:' + items[i].itemPrice + ' 円<br />' +
										'<a href="' + items[i].shopUrl + '" target="_blank">' + items[i].shopName + '</a><br /> ' +
										'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].itemName + '','' + items[i].itemCode + '')" title="[rakuten]'+ items[i].itemCode + '[/rakuten]">[挿入]</a>';

										jQuery("<li/>").append(content).appendTo("#rakuten_itemresult_" + cat_num + "> ul");
										break;

									case 1:
										var img = "<img src='" + items[i].smallImageUrl+ "' class="rakuten_itemimg" title="" + items[i].itemName + "" />";
										if (items[i].artistName != ""){
											content = 
											items[i].title + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '','' + genre.booksGenreId + ':' + items[i].jan + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].jan + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />アーティスト:' + items[i].artistName + '<br />発売元:' + items[i].label + "<br />" + items[i].itemCaption;

										} else if (items[i].label != "") {
											content = 
											'販売元:' + items[i].label + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '','' + genre.booksGenreId + ':' + items[i].jan + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].jan + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />タイトル:' + items[i].title + '<br />' + items[i].itemCaption;

										} else {
											content = 
											'著者:' + items[i].author + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '', '' + genre.booksGenreId + ':' + items[i].isbn + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].isbn + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />タイトル:' + items[i].title + '<br />出版社:' + items[i].publisherName + '<br />' + items[i].itemCaption;

										}

										content = 
										"<a href="" + items[i].itemUrl + "" target="_blank" class="tooltip">" + img + "<span>" + tips + "</span></a><br />" + 
										'価格:' + items[i].itemPrice + ' 円<br />' + content;


										jQuery("<li/>").append(content).appendTo("#rakuten_itemresult_" + cat_num + "> ul");
										break;
								}

							});

					}

				});

			}

記事画面でWP Rakuten Linkで挿入した楽天リンクを復活させる

記事にすでに表示された商品取得部分も新しいものへ変更していきます。ここはキャッシュ用にXMLで取得していますのでフォーマットはXML。

■public function get_dataを以下のように修正します。

	public function get_data($itemcode){

		mb_internal_encoding("UTF-8");
		$rakuten_options = get_option('wp_rakuten_options');
		$itemcode = htmlspecialchars($itemcode);

		$output = '';

		// キャッシュの存在確認
		if ( $update_time = $this->check_cache($itemcode) ){
			if ( $xml =  simplexml_load_string(@file_get_contents(dirname(__FILE__) . '/cache/' . str_replace(":", "_", $itemcode) . '.xml')) ){
				$output = '<!-- cache -->';

			} else {
				return "Error: Failed to load cache file.";
			}

		// キャッシュがなければ取りに行く
		} else {

			if ( $rakuten_options['developer_id'] == '' ){
				return "Error: Developers ID has not been set.";
			}

			if ( preg_match("/^(d{3}):(d+)/", $itemcode, $match) ){

				if ( $match[1] == '001'){ // 001 = Books
					$url = 
					"https://app.rakuten.co.jp/services/api/BooksTotal/Search/20130522?applicationId=" . $rakuten_options['developer_id'] . 
					"&affiliateId=" . $rakuten_options['affiliate_id'] . 
					"&format=xml" .
					"&isbnjan=" . $match[2];
				}

			} else {
				$url = 
				"https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222?applicationId=" . $rakuten_options['developer_id'] . 
				"&affiliateId=" . $rakuten_options['affiliate_id'] . 
				"&format=xml" .
				"&itemCode=" . $itemcode;
			}

			$origin = @file_get_contents($url);
			if ( !empty($origin) ) {

				// http://d.hatena.ne.jp/ilo/20080101/1199199418 を参考にさせていただきつつ、処理
				$origin = str_replace('header:Header', 'Header', $origin);
				$origin = str_replace('itemCodeSearch:ItemCodeSearch', 'ItemCodeSearch', $origin);
				$origin = str_replace('booksBookSearch:BooksBookSearch', 'BooksBookSearch', $origin);

				$origin = str_replace($rakuten_options['developer_id'],'DELETED', $origin);
				$xml = simplexml_load_string($origin);


			} else {
				return "Error: Failed to retrieve data for this request.";

			}

		}

		// 表示処理部分
		if ( $xml->count > 0 ){

			if ( $match[1] != '001' ) {
				$body = $xml->Items->Item;
				$sImage = ($body->imageFlag == "1") ? '<img src="'.$body->smallImageUrls->imageUrl.'" alt="' .$body->itemName.'" title="' .$body->itemName.'" />' : '<img src="' . WP_PLUGIN_URL . '/' . basename(dirname(__FILE__)) . '/not_found_s.jpg" width="64" height="64" alt="商品画像なし" title="商品画像がありません" />';
				$mImage = ($body->imageFlag == "1") ? '<img src="'.$body->mediumImageUrls->imageUrl.'" alt="' .$body->itemName.'" title="' .$body->itemName.'" />' : '<img src="' . WP_PLUGIN_URL . '/' . basename(dirname(__FILE__)) . '/not_found_m.jpg" width="128" height="128" alt="商品画像なし" title="商品画像がありません" />';
				$shop_name = $body->shopName;
				$shop_url  = $body->shopUrl;

			} else {
				$body = $xml->Items->Item;

				if ( $api_category == 'BooksBookSearch' ) {
					$sImage = '<img src="'.$body->smallImageUrls->imageUrl.'" alt="商品画像" title="' .$body->itemName.'" />';
					$mImage = '<img src="'.$body->mediumImageUrls->imageUrl.'" alt="商品画像" title="' .$body->itemName.'" />';
					$shop_name = "楽天ブックス";
					$shop_url  = "http://books.rakuten.co.jp/";
				}

			}

			$caution = "このサイトで掲載されている情報は、「" . htmlspecialchars(get_option('blogname')) . "」の作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗(www.rakuten.co.jp)に表示されている価格が、その商品の販売に適用されます。";

			$rak_words = array(
				"#ItemName#" => ( isset($body->title) ) ? $body->title : attribute_escape($body->itemName),
				"#CatchCopy#" => ( isset($body->catchcopy) ) ? attribute_escape($body->catchcopy) : "",
				"#ItemPrice#" => number_format("$body->itemPrice", 0) . ' 円',
				"#ItemCaption#" => (strlen($body->itemCaption) >= $rakuten_options['caption_char']) ? mb_substr($body->itemCaption, 0, $rakuten_options['caption_char'])."..." : htmlspecialchars($body->itemCaption),
				"#Url#" => ($this->is_mobile()) ? 'http://hb.afl.rakuten.co.jp/hgc/'.$rakuten_options['affiliate_id'].'/?m=' . urlencode($body->itemUrl) : $body->affiliateUrl,
				"#sImage#" => $sImage,
				"#mImage#" => $mImage,
				"#ItemStatus#" => ($body->availability == 0) ? "(販売不可)":"",
				"#Tax#" => ($body->taxFlag == 0) ? "(税込)":"(税別)",
				"#Postage#" => ($body->postageFlag == 0) ? "(送料込)":"(送料別)",
				"#CCard#" => ($body->creditCardFlag == 0) ? "(カード不可)":"(カード可)",
				"#AsuRaku#" => ($body->asurakuFlag == 0) ? "(翌日配送不可)":"(翌日配送可)",
				"#RCount#" => $body->reviewCount,
				"#RAvg#" => $body->reviewAverage,
				"#ShopName#" => $shop_name,
				"#ShopCode#" => $body->shopCode,
				"#ShopUrl#" => '<a href="' . $shop_url . '" target="' . (($rakuten_options['target_window'] == "blank") ? "_blank":"_self") . '">' . $shop_name . '</a>',
				"#Target#" => ($rakuten_options['target_window'] == 'blank') ? 'target="_blank"':'target="_self"',
				"#LastDate#" => $update_time,
				"#Caution#" => $caution,
				"#CautionTips#" => '<font class="rakuten_warn"><a class="tooltip">[ご利用にあたって]<span>'.$caution.'</span></a></font>',
			);

			// テンプレートが存在するか確認。
			if ( $rakuten_options['item_template'] != '' ) {
				$output = strtr(stripslashes($rakuten_options['item_template']), $rak_words);

			} else {
				$default_template =<<< TMP
		<div class="rakuten_image">
			<p><a href="#Url#" #Target#>#mImage#</a></p>
			#CautionTips#
		</div>
		<div class="rakuten_info">
			<p class="rakuten_itemname"><a href="#Url#" #Target#>#ItemName#</a></p>
			<p class="rakuten_caption">#ItemCaption#</p>
			<p><em>販売価格:</em> #ItemPrice# <font class="rakuten_time">(#LastDate# 更新)</font></p>
			<p><em>販売店舗:</em> #ShopUrl#</p>
		</div>
TMP;
				$output = strtr(stripslashes($default_template), $rak_words);

			}

		$credit_code =<<< CREDIT
<!-- Rakuten Web Services Attribution Snippet FROM HERE -->
<a href="http://webservice.rakuten.co.jp/" target="_blank">Supported by 楽天ウェブサービス</a>
<!-- Rakuten Web Services Attribution Snippet TO HERE -->
CREDIT;

		if ( $rakuten_options['show_credit'] != 'no' ) {
			$output.= '<div class="rakuten_credit" style="clear:both;">' . $credit_code .'</div>';
		}

		return $output;

		} else {
			return "好評につき売切れです";

		}

	}

記事投稿画面のWP Rakuten Linkの商品検索、挿入部分を新APIに対応

最後に挿入時の検索部分の処理も変更します、それぞれ楽天BOOKと楽天市場で処理が分岐しているので、注意して修正していきます。

■rakuten_itemsearch(keyword, cat_num)を以下のように修正します。

			function rakuten_itemsearch(keyword, cat_num){

				jQuery("#rakuten_itemresult_" + cat_num).html("検索中……");

				if( r_keyword[cat_num] != keyword){
					r_page[cat_num] = 1;
				}

				r_keyword[cat_num] = keyword;

				switch (cat_num){
					case 0:
						var data_obj = {
								"applicationId": "<?php echo $rakuten_options['developer_id'] ?>",
								"affiliateId": "<?php echo $rakuten_options['affiliate_id'] ?>",
								"genreId" : jQuery("#rakuten_genre").val(),
								"hits": "<?php echo $rakuten_options['result_num'] ?>",
								"page": r_page[cat_num],
								"format": "json",
								"formatVersion" : "2",
								"keyword": r_keyword[cat_num]
						}
						$rakutenurl="https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222?";
						break;

					case 1:
						var data_obj = {
								"applicationId": "<?php echo $rakuten_options['developer_id'] ?>",
								"affiliateId": "<?php echo $rakuten_options['affiliate_id'] ?>",
								"booksGenreId" : jQuery("#rakuten_book_genre").val(),
								"hits": "<?php echo $rakuten_options['result_num'] ?>",
								"page": r_page[cat_num],
								"keyword": r_keyword[cat_num],
								"format": "json",
								"formatVersion" : "2",
								"genreInformationFlag": "1"
						}
						$rakutenurl="https://app.rakuten.co.jp/services/api/BooksTotal/Search/20130522?";
						break;
					default:
						return false;
						break;
				}

				jQuery.ajax({

					url: $rakutenurl,
					data: data_obj,
					dataType: "jsonp",
					error: function(){
						jQuery("#rakuten_itemresult_" + cat_num).html("検索処理中にエラーが発生しました。");
						return false;
					},
					success: function(data) {
							switch(cat_num){
								case 0:
									var head = data;
									var items = data.Items;
									break;

								case 1:
 									var head  = data;
									var items = data.Items;
									var genre = data.GenreInformation;
									break;
							}
							jQuery("#rakuten_itemresult_" + cat_num).html("");
							jQuery("#rakuten_itemresult_" + cat_num).append(head.count + " 件の商品が見つかりました! (" + head.page + "/" + head.pageCount + "ページ)&nbsp;");

							jQuery("#rakuten_itemresult_" + cat_num).append('<input type="button" value="前のページ" id="rakuten_beforepage" class="button-secondary action" onclick="rakuten_pagemove(' + (r_page[cat_num] - 1) + ', ' + cat_num + ')">');
							jQuery("#rakuten_itemresult_" + cat_num).append('<input type="button" value="次のページ" id="rakuten_nextpage" class="button-secondary action" onclick="rakuten_pagemove(' + (r_page[cat_num] + 1) + ', ' + cat_num + ')">');
							jQuery("#rakuten_itemresult_" + cat_num).append('<br />');
							jQuery('<ul class="rakuten_itemlist" />').appendTo("div#rakuten_itemresult_" + cat_num);

							// ページ送りの処理とか
							if ( parseInt(r_page[cat_num]) <= 1 ){
								jQuery("#rakuten_beforepage").remove();
							}
							if ( parseInt(r_page[cat_num]) >= head.pageCount ){
								jQuery("#rakuten_nextpage").remove();
							}

							// アイテムの表示部分
							jQuery.each(items, function(i, item) {

								var tips = "";
								var content = "";

								switch(cat_num){
									case 0:

										if ( items[i].imageFlag == "1" ) {
											var simage = items[i].smallImageUrls;
											var img = "<img src='" + simage[0] + "' class="rakuten_itemimg" title="" + items[i].itemName + "" />";

										} else {
											var img = "[商品画像なし]";
										}

										tips =
										items[i].itemName;

										content = 
										"<a href="" + items[i].itemUrl + "" target="_blank" class="tooltip">" + img + "<span>" + tips + "</span></a><br />" + 
										'価格:' + items[i].itemPrice + ' 円<br />' +
										'<a href="' + items[i].shopUrl + '" target="_blank">' + items[i].shopName + '</a><br /> ' +
										'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].itemName + '','' + items[i].itemCode + '')" title="[rakuten]'+ items[i].itemCode + '[/rakuten]">[挿入]</a>';

										jQuery("<li/>").append(content).appendTo("#rakuten_itemresult_" + cat_num + "> ul");
										break;

									case 1:
										var img = "<img src='" + items[i].smallImageUrl+ "' class="rakuten_itemimg" title="" + items[i].itemName + "" />";
										if (items[i].artistName != ""){
											content = 
											items[i].title + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '','' + genre.booksGenreId + ':' + items[i].jan + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].jan + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />アーティスト:' + items[i].artistName + '<br />発売元:' + items[i].label + "<br />" + items[i].itemCaption;

										} else if (items[i].label != "") {
											content = 
											'販売元:' + items[i].label + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '','' + genre.booksGenreId + ':' + items[i].jan + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].jan + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />タイトル:' + items[i].title + '<br />' + items[i].itemCaption;

										} else {
											content = 
											'著者:' + items[i].author + '<br />' +
											'<a href="#rak_menu_tab" style="font-size: 8pt" onclick="add_this('' + items[i].title + '', '' + genre.booksGenreId + ':' + items[i].isbn + '')" title="[rakuten]'+ genre.booksGenreId + ':' + items[i].isbn + '[/rakuten]">[挿入]</a>';

											tips = 'カテゴリ:' + genre.booksGenreName + '<br />タイトル:' + items[i].title + '<br />出版社:' + items[i].publisherName + '<br />' + items[i].itemCaption;

										}

										content = 
										"<a href="" + items[i].itemUrl + "" target="_blank" class="tooltip">" + img + "<span>" + tips + "</span></a><br />" + 
										'価格:' + items[i].itemPrice + ' 円<br />' + content;


										jQuery("<li/>").append(content).appendTo("#rakuten_itemresult_" + cat_num + "> ul");
										break;
								}

							});

					}

				});

			}

修正したソースファイルをアップロードすれば、楽天APIのアップデートに伴い使えなくなっていたWP Rakuten Linkが復活して使えるようになります。
細かい部分はあまり確認していませんので、うまくできていない場所があるかもしれませんが、私が使う上では問題なく、使えてます。

修正結果の差分リストと修正済みソースの公開

修正したソースもご参考までにアップします。

修正した箇所を比較したリストも以下に公開します。わかりにくいですが行番号を参考にどうぞ。
WP RAKUTEN LINK API更新の差分リスト

wp-rakuten-link-diff2

wp-rakuten-link-diff3

wp-rakuten-link-diff4

wp-rakuten-link-diff5

wp-rakuten-link-diff6

wp-rakuten-link-diff7

wp-rakuten-link-diff8

 - Word Press, アフィリエイト

 Total 687 views