文書の過去の版を表示しています。


GJ!(Web拍手)の改造

http://hmlab.info/minor/

上記リンクのGJは、Javascriptを使って、画面が切り替わることなく拍手ができるのがおもしろい。ただ、ファイルに書き込むタイプなので、時々ファイルをロックしたままになることがあるので、この部分をMysqlで処理するようにした。

Mysqlのテーブル

まず、データベースにテーブルを作成しておきます。

CREATE TABLE `gj_log` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `entry_id` INT(15) UNSIGNED NOT NULL DEFAULT '0',
  `date` VARCHAR(15) DEFAULT NULL,
  `ip` VARCHAR(15) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;
 
CREATE TABLE `gj_views` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `entry_id` INT(15) UNSIGNED NOT NULL DEFAULT '0',
  `views` INT(15) UNSIGNED NOT NULL DEFAULT '0',
  `entry_url` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
);

MovableTypeのテンプレート

テンプレートを少し改造。

<div class="goodjob">
<input id = "<$MTEntryPermalink$>" type = "image"  src = "" alt="clap" style="vertical-align:middle;" onClick="goodjob('<$MTEntryPermalink$>','<$mt:EntryID$>') ">
<script type="text/javascript">showbutton('<$MTEntryPermalink$>','<$mt:EntryID$>','');</script>
<span id="<$MTEntryPermalink$>_gj_mark"></span>
</div>

設定ファイル

データベースの設定を記述しておく。

gj_cfg.php
<?
$DBHost = 'localhost';
$DBUser = 'xxxx';
$DBPassword = 'xxxx';
$Database = 'xxxx';
$gj_log_table = 'gj_log';
$gj_views_table = 'gj_views';
?>

実行ファイル

gj.php
<?php
error_reporting(0);
include('gj_cfg.php');
 
$ButtonImg ="./img/good_job.gif";//通常ボタン
$R_STR = 0;//Red
$G_STR = 0;//Green
$B_STR = 255;//Blue
 
$ButtonImg2 ="./img/thanks.gif";//感謝ボタン
$R_STR2 = 0;//Red
$G_STR2 = 0;//Green
$B_STR2 = 255;//Blue
 
$R_STR3 = 255;//Red
$G_STR3 = 0;//Green
$B_STR3 = 0;//Blue
 
$STRPOSX = 58;//拍手表示X位置(ピクセル単位)
$STRPOSY = 3;//拍手表示Y位置(ピクセル単位)
 
$KETA = 3;//拍手数表示桁数
 
if(!isset($_GET["pagename"])) {exit(0);}
$pagename = $_GET["pagename"];
 
//---------------------------------------------------
if($_GET["mode"] == "button") //ボタン描画(button 0=normal/1=Thank you)
{
 
	if (!($mysql = mysql_connect($DBHost,$DBUser,$DBPassword))) {
		exit(0);
	}
	if (!(mysql_select_db($Database))) {
		exit(0);
	}
 
	if ($pagename < 1 ) {
		$img = imagecreatefromgif($ButtonImg);
		$col = imagecolorallocate($img, $R_STR3, $G_STR3, $B_STR3);
		imagestring($img, 3, $STRPOSX, $STRPOSY, "ERR", $col);
		imagegif($img);
		imagedestroy($img);
		exit(0);
		}
 
	$query = "SELECT views FROM $gj_views_table WHERE entry_id = '$pagename'";
	$res = mysql_query($query);
	$row = mysql_fetch_object($res);
	$count = intval($row->views);
 
	Header ("Content-type: image/gif");
 
	if($_GET["button"] == 1) //拍手後のボタン
	{
		$img = imagecreatefromgif($ButtonImg2);
		$col = imagecolorallocate($img, $R_STR2, $G_STR2, $B_STR2);
	}
	else //通常のボタン
	{
		$img = imagecreatefromgif($ButtonImg);
		$col = imagecolorallocate($img, $R_STR, $G_STR, $B_STR);
	}	
 
	imagestring($img, 3, $STRPOSX, $STRPOSY, sprintf("%0".$KETA."d",$count), $col);
	imagegif($img);
	imagedestroy($img);
	exit(0);
}
//---------------------------------------------------
else if($_GET["mode"] == "gj") //拍手をインクリメント
{
 
	if (!($mysql = mysql_connect($DBHost,$DBUser,$DBPassword))) {
		exit(0);
	}
	if (!(mysql_select_db($Database))) {
		exit(0);
	}
 
//重複をチェック
	$date = date("Y-m-d");
	$ip = $_SERVER['REMOTE_ADDR'];
	$query = "SELECT id FROM $gj_log_table WHERE entry_id = '$pagename' and date ='$date' and ip = '$ip'";
	$res = mysql_query($query);
	if (mysql_num_rows($res) == 0) {
		$query = "INSERT INTO $gj_log_table VALUES (null,'$pagename','$date','$ip')";
		$res2 = mysql_query($query);
		$count_plus = 1;
    } else {
		$count_plus = 0;
    }
 
//過去のログを消去
	$query = "delete from $gj_log_table where date <> '$date'";
	$res2 = mysql_query($query);
 
//インクリメント
	$url = $_GET["pageurl"];
	$query = "SELECT views FROM $gj_views_table WHERE entry_id = '$pagename'";
	$res = mysql_query($query);
	$row = mysql_fetch_object($res);
	$views = intval($row->views);
	if (mysql_num_rows($res) == 0) {
		$query = "INSERT INTO $gj_views_table VALUES (null,'$pagename','1', '$url')";
		$res2 = mysql_query($query);
	} else {
		$views += $count_plus;
		$query = "UPDATE $gj_views_table SET views='$views', entry_url='$url' WHERE entry_id = '$pagename'";
		$res2 = mysql_query($query);
	}
 
	exit(0);
//---------------------------------------------------
} else {
	exit(1);
}

ランキング

ランキングを表示するスクリプトを別ファイルにして、負荷を下げる。

ranking.php
<?
 
include('gj_cfg.php');
 
$INFOMAX = 100;
 
print("<html>");
print("<head>");
print("<title>拍手ランキング</title>");
print("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
print("</head>");
print("<body><center>");
 
if (!($mysql = mysql_connect($DBHost,$DBUser,$DBPassword))) {
echo "データベースに接続できませんでした。(1)";}
mysql_query("SET NAMES utf8", $mysql);
if (!(mysql_select_db($Database))) {
echo "データベースに接続できませんでした。(2)";}
 
//総拍手数
$query = "SELECT sum(views) total, avg(views) average FROM mt_entry, $gj_views_table where mt_entry.entry_id = $gj_views_table.entry_id";
$res = mysql_query($query);
$row = mysql_fetch_object($res);
$count = intval($row->total);
$avg = $row->average;
 
print("<h2>拍手ランキング</h2>");
print("<a href=\"JavaScript:history.back();\">戻る</a>");
print(" 総拍手数 ".$count);
printf(" 平均 %.1f", $avg);
 
print("<table border=\"1\" cellspacing=\"0\" cellpadding=\"1\">");
print("<tr><td>順位</td><td>ページ</td><td>拍手数</td></tr>");
 
//ランキングの抽出
$query = "SELECT entry_blog_id, mt_entry.entry_id entry_id, entry_title, views, entry_url FROM mt_entry, $gj_views_table where mt_entry.entry_id = $gj_views_table.entry_id ORDER by views DESC LIMIT 0,$INFOMAX";
$res = mysql_query($query);
 
$jun = 1; $sjun = 1; $excount = 0;
 
if ($res) {
 
	while($row = mysql_fetch_object($res)) {
		$title = $row->entry_title;
		$views = $row->views;
		$url = $row->entry_url;
		$school = $school_list[$row->entry_blog_id];
 
		if ($excount == $views) {$jun--;} else {$jun = $sjun;}
		if ($jun > $INFOMAX) break;
		print("<tr><td align=\"right\">" . $jun . "</td>");
		print("<td><a href =\"$url\">$title</a></td>");
		print("<td align=\"right\">" . $views . "</td></tr>");
		$jun++; $sjun++; $excount = $views;
	}
}
 
	print("</table>");
	print("</center></body>");
	print("</html>");
 
exit(1);
 
?>