Help us understand the problem. What is going on with this article?

a-blog cmsでサイト独自の「いいね!」機能を構築する

More than 1 year has passed since last update.

この記事は、a-blog cms Advent Calendar 2018 の13日目の記事です。

likepreview.gif

通常記事詳細ページにはFacebookやTwitterなどのSNSボタンを設置しますが、SNSアカウントがないサイト訪問者向けにサイト独自に「いいね!」ボタンを設置したいことがあるかと思います。本稿では少々踏み込んだ内容になりますが、カスタマイズの事例として、サイト独自の「いいね!」ボタンを実装する方法をご紹介します。(WordPressでいうところのWP ULikeのようなものです)
※データベースを変更する内容が含まれているので、ご利用の場合は自己責任でお願いいたします。

実装の流れ

  1. a-blog cmsが適用されない領域を作る
  2. a-blog cmsが適用されない領域に「いいね!」ボタン用のphpを設置
  3. テーマの entry.html に「いいね!」ボタンの雛形を設置
  4. 「いいね!」ボタン用のphpと、entry.htmlに設置した「いいね!」ボタンの雛形を連携

1. a-blog cmsが適用されない領域を作る

まずa-blog cms領域直下にある、.htaccessでa-blog cmsが適用されないディレクトリを作成します。今回は、/system/ 以下をa-blog cmsが適用されないディレクトリにします。

修正前

/.htaccess
# a-blog cms以外のコンテンツ(a-blog cmsを動作させないディレクトリ)
# RewriteCond %{REQUEST_URI} !^/?other/
# RewriteCond %{REQUEST_URI} !^/?other2/

修正後

/.htaccess
# 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でどの記事の「いいね!」が押されたか特定します。

/system/like/index.php
<?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を特定します。

/themes/*****/entry.html
<!-- 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のパラメータを渡します。

/themes/*****/js/common.js
$(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でクイックアンケート機能を構築する方法もまとめましたのでぜひご覧ください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした