概要
MovableTypeで作成している記事詳細に独自のいいねボタンを設置し、いいねの件数によって、記事ランキングを生成します。
独自のいいねボタンの実装には、PHPKOBOさんが作成されている「Ajaxいいねボタン v2.23」を使用します。
https://jpn.phpkobo.com/ajax-iine-button
このいいねボタン実装には、データベースが必要ですが、MovableTypeと組み合わせ前提での話なので、問題ないと思います。
いいねボタンのインストール方法は、公式サイトのインストレーション・ガイドに詳しく記載がありますので割愛します。
注意・前提
- インストールする際は、MovableTypeと同じデータベースにしてください。
- 公開環境とCMS環境が分かれている場合は、実装できません。
- 今回のソースでは、ページネーションは無いので最新10件といった使い方を想定しています。
- MovableType Data API(v4)を使用します。
いいねボタンのインストールと配置
いいねボタンのインストールが完了すると、データベース内に4つのテーブルが追加されます。
ここに、いいねカウントが溜まっていきます。
tbl_btn
tbl_hist
tbl_poll
tbl_voter
いいねボタンを使うには、記事アーカイブのhead もしくは、全体のhead内に、スクリプト読み込みの記述を追加してください。
<script type="text/javascript" src="/__設置パス__/iine/cn/cn.php"></script>
記事詳細(記事アーカイブ)で、いいねボタンを設置したい所に、ボタン用のタグを追加します。
<div class="ajax-iine" data-pid="<$mt:EntryID$>" data-tid="tpl-sb-green-m"></div>
その際 data-pid が、記事IDとなるようにしてください。
理由としては、追加された4つのテーブル内には、MovableType情報は含まれていないので、記事データと紐付けを行うキーが必要になるためです。
data-pidは、いいね数と対で保存されるため、詳細ページ毎に一意にする必要があります。
ランキングリストの実装
いいねの多い順にMovableType Data APIを使って記事情報を取得します。
変更する箇所は、データベース接続情報、こちらは、MovableTypeと同じ いいねボタをインストールした情報を入れてください。
$server = “localhost”;
$userName = “__username__”;
$password = “__password__”;
$dbName = “__database_name__”;
MovableTypeがインストールされているディレクトリまでのURL。
$api_path = ‘https://example.com/mt/’;
カテゴリやカスタムフィールドでの絞り込みも可能ですが、今回は、絞り込みは行っていません。
<?php
/**
* いいねの多い順に記事データを取得
*
* @param int $num 取得件数
* @return array 投稿記事データ
*/
function get_article($int = 10){
//データベース情報
$server = "localhost";
$userName = "__username__";
$password = "__password__";
$dbName = "__database_name__";
//MTがインストールされているディレクトリまでのURL
$mt_url = "https://example.com/mt";
//DB接続
$mysqli = new mysqli($server, $userName, $password,$dbName);
if ($mysqli->connect_error){
echo $mysqli->connect_error;
exit();
}else{
$mysqli->set_charset("utf-8");
}
//取得条件
$sql = "SELECT tbl_btn.poll_id, tbl_btn.vcnt, tbl_poll.poll_id, tbl_poll.pid FROM tbl_btn LEFT JOIN tbl_poll ON tbl_btn.poll_id = tbl_poll.poll_id WHERE vcnt >= 0 ORDER BY vcnt DESC LIMIT " . $int;
$result = $mysqli->query($sql);
//クエリー失敗
if(!$result) {
return false;
}
//連想配列でIDを設定
$test = array();
while($row = $result->fetch_array(MYSQLI_ASSOC)){
$ids[] = $row["pid"];
}
$result->free(); //結果セットを解放
$mysqli->close(); // データベース切断
//いいね記事数順に、1件ずつデータ取得
$arr = array();
if($ids){
foreach($ids as $id){
//APIパス
$url = $mt_url ."/mt-data-api.cgi/v4/sites/1/entries/".$id."?fields=id,permalink,title";
@$response = file_get_contents($url);
//取得失敗
if (!$response) {
return false;
}
$arr[] = json_decode($response);
}
}
return $arr;
}
?>
続いて、表示したいHTMLを整形します。
<?php
/**
* いいねランキング 実行結果HTML取得処理
*
* @return string 実行結果HTML
*/
function generate_cache(){
//いいねランキングデータの取得
$entries = get_article(false, 10);
$entrie_data = "";
$count = 1;
if($entries){
$entrie_data .= "<ul>";
foreach($entries as $entry){
//記事リンクを変数に追加
$entrie_data .= '<li>'.$count.'位:<a href="'.$entry->permalink.'">'.$entry->title.''.$entry->id.'</a></li>';
$count++;
}
$entrie_data .= "</ul>";
}
return $entrie_data;
}
?>
表示毎にデータベースに接続して、Data APIにアクセスしているとパフォーマンスが落ちるので、擬似キャッシュファイルを生成して、一定時間は処理しないようにします。
キャッシュファイルがない場合にはファイル生成しますが、ディレクトリの生成処理はないので、格納するディレクトリは手動で作成を行い書き込み権限を付けておいてください。
キャッシュファイルを置くディレクトリとキャッシュ時間を設定してください。
$cache_file = $_SERVER[‘DOCUMENT_ROOT’] . “cache/ranking.cache”;
$cacheTime = 60 * 60 * 1;
<?php
/**
* いいねランキング キャッシュ処理
*
* @return ランキングリストHTMLの書き出し
*/
function ranking_data(){
//キャッシュファイル名
$cache_file = $_SERVER['DOCUMENT_ROOT'] . "cache/ranking.cache";
//キャッシュ時間
$cacheTime = 60 * 60 * 1; //1時間(秒 * 分 * 時)
//キャッシュファイルが存在しない場合、ファイルを生成
if(!file_exists($cache_file)){
touch($cache_file);
}
//キャッシュファイルの生成時間を取得
$genTime = filemtime($cache_file);
if(($genTime + $cacheTime) < time() ){
$cacheFlag = 1;
}
//キャッシュファイルの読み込み
$cachedata = file_get_contents($cache_file);
if( $cachedata == "" || isset($cacheFlag) ){
//初回実行/キャッシュ切れ
$entries = generate_cache();
//htmlデータをキャッシュファイルに保存
file_put_contents($cache_file, $entries, LOCK_EX);
} else {
//キャッシュから表示
$entries = $cachedata;
}
echo $entries;
}
?>
管理画面などからのキャッシュクリアはないので、即時反映したい場合には、FTP上でキャッシュファイルを削除してください。
上記、3つの関数をランキングを出したいページに記載するか、別ファイルでインクルードなりしてください。
最後に、ランキング情報を掲載したいところに、実行する関数を挿入してください。
<?php
//ランキング処理関数読み込み
ranking_data();
?>
コメント