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>

設定ファイル

データベースの設定を記述しておく。ファイル名はgjcfg.php<code php> <? $DBHost = 'localhost'; $DBUser = 'xxxx'; $DBPassword = 'xxxx'; $Database = 'xxxx'; $gjlogtable = 'gjlog'; $gjviewstable = 'gjviews'; ?> </code> ===== 実行ファイル ===== gj.php<code php> <?php errorreporting(0); include('gj_cfg.php');

$ButtonImg =“./img/goodjob.gif”;通常ボタン $RSTR = 0;Red $GSTR = 0;Green $B_STR = 255;Blue $ButtonImg2 =“./img/thanks.gif”;感謝ボタン $RSTR2 = 0;Red $GSTR2 = 0;Green $B_STR2 = 255;Blue $RSTR3 = 255;Red $GSTR3 = 0;Green $BSTR3 = 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 = mysqlconnect($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['REMOTEADDR']; $query = “SELECT id FROM $gjlogtable WHERE entryid = '$pagename' and date ='$date' and ip = '$ip'”; $res = mysqlquery($query); if (mysqlnumrows($res) == 0) { $query = “INSERT INTO $gjlogtable VALUES (null,'$pagename','$date','$ip')”; $res2 = mysqlquery($query); $countplus = 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 $gjviewstable WHERE entryid = '$pagename'”; $res = mysqlquery($query); $row = mysqlfetchobject($res); $views = intval($row→views); if (mysqlnumrows($res) == 0) { $query = “INSERT INTO $gjviewstable VALUES (null,'$pagename','1', '$url')”; $res2 = mysqlquery($query); } else { $views += $countplus; $query = “UPDATE $gjviewstable SET views='$views', entryurl='$url' WHERE entryid = '$pagename'”; $res2 = mysqlquery($query); } exit(0); ————————————————— } else {

exit(1);

} </code>

ランキング

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

<?
 
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);
 
?>