この記事は、a-blog cms Advent Calendar 2018 の13日目の記事です。
通常記事詳細ページにはFacebookやTwitterなどのSNSボタンを設置しますが、SNSアカウントがないサイト訪問者向けにサイト独自に「いいね!」ボタンを設置したいことがあるかと思います。本稿では少々踏み込んだ内容になりますが、カスタマイズの事例として、サイト独自の「いいね!」ボタンを実装する方法をご紹介します。(WordPressでいうところのWP ULikeのようなものです)
※データベースを変更する内容が含まれているので、ご利用の場合は自己責任でお願いいたします。
実装の流れ
- a-blog cmsが適用されない領域を作る
- a-blog cmsが適用されない領域に「いいね!」ボタン用のphpを設置
- テーマの entry.html に「いいね!」ボタンの雛形を設置
- 「いいね!」ボタン用のphpと、entry.htmlに設置した「いいね!」ボタンの雛形を連携
1. a-blog cmsが適用されない領域を作る
まずa-blog cms領域直下にある、.htaccessでa-blog cmsが適用されないディレクトリを作成します。今回は、/system/ 以下をa-blog cmsが適用されないディレクトリにします。
修正前
# a-blog cms以外のコンテンツ(a-blog cmsを動作させないディレクトリ)
# RewriteCond %{REQUEST_URI} !^/?other/
# RewriteCond %{REQUEST_URI} !^/?other2/
修正後
# a-blog cms以外のコンテンツ(a-blog cmsを動作させないディレクトリ)
RewriteCond %{REQUEST_URI} !^/?system/?
2. a-blog cmsが適用されない領域に「いいね!」ボタン用のphpを設置
/system/like/?mode=get&eid=1
のようなリクエストを送れば数値を返す、 /system/like/?mode=put&eid=1
のようなリクエストを送ればカウントアップして数値を返す(cookieで1度クリックすると1年間再度クリックできない)phpプログラムを組みます。eidでどの記事の「いいね!」が押されたか特定します。
<?php
/**
* いいね!ボタン
* /system/like/?mode=get&eid=1
* /system/like/?mode=put&eid=1
*/
require_once('../../config.server.php');
$dsn = 'mysql:dbname='.DB_NAME.';host='.DB_HOST.';charset=utf8';
$pdo = new PDO($dsn, DB_USER, DB_PASS);
// テーブルがなければ新規制作
$sql = "CREATE TABLE IF NOT EXISTS `like_table`
(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`entry_id` INT,
`account_id` VARCHAR(255),
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$stmt = $pdo -> prepare($sql);
$stmt -> execute();
// パラメータ受取
$mode = filter_input(INPUT_GET, 'mode');
$eid = filter_input(INPUT_GET, 'eid');
$userid = filter_input(INPUT_COOKIE, 'userid');
// Cookieがなければ発行
if( !$userid ){
$ticket = md5(uniqid(mt_rand(), true));
$expire = time() + ( 60 * 60 * 24 * 365 ); //1年間間保持
setcookie('userid', $ticket, $expire, '/');
$userid = $ticket;
}
// 表示処理
if( $mode == 'get' && $eid ){
$stmt = $pdo->prepare("SELECT COUNT(*) FROM `like_table` WHERE `entry_id` = ?");
$stmt->execute([$eid]);
echo $stmt->fetchColumn();
}
// 追加処理
if( $mode == 'put' && $eid && $userid ){
// 投票済みでないかチェック
$stmt = $pdo->prepare("SELECT COUNT(*) FROM `like_table` WHERE `entry_id` = ? AND `account_id` = ?");
$stmt->execute([$eid, $userid]);
// 投票済みでなければ投票
if( $stmt->fetchColumn() == 0 ){
$stmt = $pdo->prepare("INSERT INTO `like_table` (`entry_id`, `account_id`) VALUES (?, ?)");
$stmt->execute([$eid, $userid]);
}
// 数値を返す
$stmt = $pdo->prepare("SELECT COUNT(*) FROM `like_table` WHERE `entry_id` = ?");
$stmt->execute([$eid]);
echo $stmt->fetchColumn();
}
?>
3. テーマの entry.html に「いいね!」ボタンを設置
entry.htmlに「いいね!」ボタンの雛形を設置します。どの記事の「いいね!」が押されたか特定するため、data-vote-entry-id="%{EID}"
でエントリーIDを特定します。
<!-- BEGIN_MODULE Entry_Body -->
<!-- BEGIN entry:loop -->
<div class="vote" id="vote">
<p class="vote-lead">この記事が気に入ったら「いいね!」ボタンを押してください</p>
<a href="#" class="vote-button" data-vote-entry-id="%{EID}">
<span class="icon"><i class="fa fa-heart"></i>いいね!</span>
<span class="number"></span>
</a>
</div>
<!-- END entry:loop -->
<!-- END_MODULE Entry_Body -->
4.「いいね!」ボタン用のphpと、entry.htmlに設置した「いいね!」ボタンの雛形を連携
下準備が整ったので2で作成したphpと、3で作成したentry.htmlをJavaScriptで連携させます。ページを開いたら「いいね!」ボタンが表示されるよう、下記のJavaScriptをサイトに組み込みます。/system/like/index.php に対して、表示の場合はmodeにget、クリックされた場合はmodeにput、eidは記事のIDのパラメータを渡します。
$(document).ready(function(){
$('.vote-button').each(function(){
var $vote = $(this);
// 表示処理
$.ajax({
type: 'GET',
url: '/system/like/',
cache: false,
data: {
'mode': 'get',
'eid': $vote.data('vote-entry-id')
},
success: function(data){
$vote.find('.number').text(data);
}
});
// 追加処理
$vote.click(function(){
$.ajax({
type: 'POST',
url: '/system/like/',
cache: false,
data: {
'mode': 'put',
'eid': $vote.data('vote-entry-id')
},
success: function(data){
$vote.find('.number').text(data);
}
});
return(false);
});
});
});
動作確認
これで「いいね!」ボタンは完成です。このように記事のIDを使うことで様々なシステムとの連携が可能です。Good / Badボタンにしたり、「どのくらい役に立ちましたか?」などで1~5段階にしたり、もう一度「いいね!」したら「いいね!」を取り消すなどの応用も可能です。同様の仕組みで、a-blog cmsでクイックアンケート機能を構築する方法もまとめましたのでぜひご覧ください。