AIDAデザイン

ホームページデザイン制作会社、CMS、ブログのカスタマイズ、Facebookページ、通常のサイト制作

top > [WordPress] Ajaxでダウンロードされた数をカウントしてランキングページを作成する

AIDAデザイン ブログ

今回、お客様のご要望で「イラストサイトを作りたいが、ダウンロードされた数でランキング一覧のページも欲しい」というご要望がありましたので、それを実現させるための方法を残しておきます。

まずは下調べ

まず要件として
・各ページにダウンロードボタンを付け、ダウンロードボタンを押されたら画像をダウンロード
・ダウンロード数をカウントする
・ダウンロード数の多いものからランキング形式で一覧ページを作成する
というものでした。

簡単に思いついたのが「ダウンロードをカウントするプラグインを入れればいいかな・・・」と思いました。
WordPress Download Managerとか、Simple Download Monitorなど、いくつかみつかったものの、ダウンロード数は表示できなかったり、ダウンロードさせる画像の登録が面倒だったり。

そして致命的だったのが「ランキング一覧」を作る手段がない・・・!
いや、DBのどこかには保存されているはずなのでDBを直接叩けばできなくはないんでしょうけども、既存のテーマを使用するということもあって、アップデートを考えるとあまりやりたくないな、と思い、結局自作することにしました。

概要を考える・・・

とはいえ、そんなに高いスキルも持ち合わせていないため、なるべく既存の枠組みのなかでできないかなと考え、次のような内容にすることにしました。

・ダウンロードボタンを押されたら画像をダウンロード
→aタグのdownload属性。
お客様のご要望としてはzipファイルをクリックしたときのような、ダウンロードフォルダにファイルが保存されるような形式を望んでおられましたのでこれかなと。
<a href="" download="image" >
とすると、image.jpgなど元のファイルの拡張子でダウンロードされます。
最終的には、IEとiOSのSafariが非対応(2019年2月現在)だったため、この案は却下され通常のページを開く仕様になりました。
現在の対応状況について詳しくはこちらで確認してください。

・ダウンロード数をカウントする
→外部からダウンロードボタンを押されたらカスタムフィールドの値+1にすることにしました。
これなら一覧も作りやすい。
ちょうどAdvanced Custom Fields(以下ACF)も使用していたため、今回はACF+jQuery+Ajaxでページ遷移無しでクリックされたらカウントしつつファイルダウンロード、という仕組みにすることになりました。

【詳細ページ】
・HTML
<div class="download" data-id="記事ID"><a href="画像のURL">無料ダウンロード</a></div>

・jQuery
jQuery(function($){
$('.download a').on("click", function(event) {
event.preventDefault();
var url_add = $(this).attr('href');
var post_id = $('.download').attr('data-id');
var ajaxurl = '';

if(url_add && post_id){
$.ajax({
dataType: "text",
url:ajaxurl,
type: 'POST',
data:{
'action': 'countDL',
'urladd':url_add,
'postid':post_id
}
})
// Ajaxリクエストが成功した時発動
.done( (data) => {
async:false;
window.open(url_add + '?download', '_self');
})
// Ajaxリクエストが失敗した時発動
.fail( (data) => {
alert('ダウンロードに失敗しました。再度お試しください。')
})
}
});
});


簡単に処理内容をお伝えしますと、
event.preventDefault(); は、aタグのリンクを無効にします。
一旦リンクを処理を無効にした上で、HTMLタグの記事IDと画像のURLを取得し、一旦格納します。(url_addとpost_id)
両方の値があれば、Ajax処理としてWordPressの持っているadmin-ajax.phpへdataをPOSTしています。
(dataに'secure'オプションを付けたほうが良いという話もありますが、また別の機会に紹介します。)
POSTされた値がどこに行くか。
actionで指定されたcountDLにポストされますが、それはfunctions.phpに記述します。


【functions.php】
function countDL() {
$postid=$_POST['postid'];
$file=$_POST['urladd'];
$num=get_post_meta($postid, 'download_count', true);
if(!$num){
$num=0;
}
$num++;
update_field('download_count', $num, $postid);
}

add_action('wp_ajax_nopriv_countDL','countDL');
add_action('wp_ajax_countDL','countDL');

送られてきた値から、該当するページのdownload_countというカスタムフィールドの値に+1して、アップデートしています。
そして、Ajaxの処理が成功したら、
window.open(url_add + '?download', '_self');
で、元の画像のURLに?downloadを付けて開くようにしています。
ここがホントは<a download>にしたかった箇所ですが、対応していないブラウザがあるので仕方ないですね・・・

これは、.htaccessファイルで、
# download query
RewriteEngine on
RewriteCond %{QUERY_STRING} ^download
RewriteRule ^(.+)$ - [T=application/octet-stream]

として、?downloadのクエリストリングが付いている場合は、画像をダウンロードします。

以上で、「ダウンロード」ボタンを押されたらカウントを追加して画像をダウンロードする、という一連の流れになります。
ブラウザによってダウンロードの挙動が異なるのが残念ですね。
zipにする方法なども検討したのですが、スマホも考慮に入れるとなかなかスマートな対応は難しいです。
aタグのdownload属性については今後のブラウザのバージョンアップで対応してくれるのではないかと期待しています。