ログイン
ユーザ名:

パスワード:

IDとパスワードを記憶

パスワード紛失

新規登録
メニュー
カレンダー
2006年 8月
« 7月   9月 »
 12345
6789101112
13141516171819
20212223242526
2728293031  
月別過去ログ
カテゴリ一覧
日記のみのRSS
RSSに登録
Subscribe RSS

Subscribe with livedoor Reader

はてなRSSに追加
プロフィール

2006年8月20日(日曜日)

XOOPSモジュール版WordPressでAjaxを使った投票システムを作ってみた

カテゴリー: - A-tak @ 10時53分36秒 閲覧数 1241 回 コメント (11) このエントリーを含むはてなブックマーク

[2007.4.11 追記]
グラフ付きも作ってみました。グラフ付き投票システムはこちら
[2007.4.11 追記おわり]

ちょっと前にXOOPSモジュール版WordPressで記事の閲覧回数をカウントして表示する仕組みをつくりました
これは、おすすめの記事を訪問してくれた人の目にとまるところに表示することで便利に使ってもらおうという意図があったのですが、どうもランキングを見ていると、たいして役に立たなさそうなリア・ディゾンの記事が一位になっていて、意味をなしていないような気がしてきたので別の仕組みを導入することにしました。

そこで考えたのが、実際に記事を見た人に投票してもらう仕組み。閲覧数が多いというのは、実際はGoogleでたまたま上位に表示されているだけで、必ずしもその記事が有用であるとは言えないわけです。じゃあどうやって、有用かどうかを評価するかと考えると、やっぱり実際に記事を読んだ人に評価してもらうしかないかな、と。

少しでも投票することに対する負担を軽減するためにAjax(Asynchronous Javascript + XMLの略。JavascriptとXMLを使った非同期通信のこと)を使って画面遷移なしで投票できるようにしてみました。よくある投票の仕組みって画面遷移するから自分も押さない事が多かったんですよね。Ajaxならバックグラウンドで処理してくれるから少しはマシかと。

まずは投票結果を保存するテーブルを作成。
以下のスクリプトをMySqlのコマンドやphpMyAdminなどで実行してください。

CREATE TABLE `xoops_wp_popularity` (
  `postnumber` int(11) NOT NULL default ‘0′,
  `good` int(11) NOT NULL default ‘0′,
  `bad` int(11) NOT NULL default ‘0′,
  PRIMARY KEY  (`postnumber`)
) TYPE=MyISAM;

サーバー側がvote.php。Webサーバーのルートディレクトリに「Ajax」というディレクトリを作成して置きます。
最初に記事IDが数値かどうかを判断しているのでSQLインジェクションは防げていると思うけど、どうだろう。かなり適当感漂うけど、そのうちリファクタリングします。 行が長いので途中で改行しています。

$conn = mysql_connect("server","user","password");

上記のserver,user,passwordには環境に合わせてデータベース接続に必要な情報を入れてください。

[追記]
JavaScriptから受け取ったIDをそのまま表示している部分があったのでコメントアウトしました。受け取った値が数値かどうかを検証しているので問題はないはずですが、後で仕様変更で文字もOKになったときに、タグを埋め込まれたりしてセキュリティーホールになってしまうかもしれないですから。

<?php
//美乳
//WordPress人気投票(vote.php)

$fail = "fail";

$id = $_GET['id'];
if (!is_numeric($id)){
 print $fail;
 return;
}
$conn = mysql_connect("server","user","password");
mysql_select_db("xoops");
switch ($_GET["vote"]){
 case "good" :
  voteGood($id);
  //print "good: " . $id;
  break;
 case "bad" :
  voteBad($id);
  //print "bad: " . $id;
  break;
 default :
  print($fail);
}
function voteGood($p_number){
 $result = isExsits($p_number);
 $test = 0;
 while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
  $row[1] += 1;
  $sql = sprintf("update xoops_wp_popularity
         set good = %d where postnumber = %d;", $row[1], $row[0]);
  @mysql_query($sql);
  $test = 1;
 }
 if ($test == 0) {
  $sql = sprintf("insert into xoops_wp_popularity(postnumber, good, bad)
                                           values(%d, 1, 0);",$p_number);
  @mysql_query($sql);
 }
}
function voteBad($p_number){
 $result = isExsits($p_number);
 $test = 0;
 while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
  $row[2] += 1;
  $sql = sprintf("update xoops_wp_popularity set bad = %d
                  where postnumber = %d;",$row[2],$row[0]);
  @mysql_query($sql);
  $test = 1;
 }
 if ($test == 0) {
  $sql = sprintf("insert into xoops_wp_popularity(postnumber, good, bad)
                                       values(%d, ‘0′, ‘1′);",$p_number);
  @mysql_query($sql);
 }
}
function isExsits($p_number){
 $sql = sprintf("select postnumber, good, bad from xoops_wp_popularity
                                    where postnumber = %d;",$p_number);
 return mysql_query($sql);
}
?>

以下は、Ajaxで使うJavascript。ファイル名はvotescript.jsとしてvote.phpと同じルートのajaxディレクトリに入れます。
vote.phpを呼び出しています。
あと、prototype.js(バージョンは1.5.0)を使っています。 prototype.jsもajaxディレクトリにいれます。

// JavaScript Document
// 美乳(votescript.js)
function voteGood(id)
{
 displayProgress();
 new Ajax.Request("/ajax/vote.php?id=" + id + "&vote=good",
 { method: ‘get’, onSuccess: displayResult, onFailure : displayFail });
}
function voteBad(id)
{
 displayProgress();
 new Ajax.Request("/ajax/vote.php?id=" + id + "&vote=bad",
 { method: ‘get’, onSuccess : displayResult ,onFailure : displayFail});
}
function displayProgress()
{
 $("vote-result").innerHTML = ‘投票処理中・・・’
}
function displayResult(responseHttpObj)
{
 if (responseHttpObj.responseText == ‘fail’)
 {
  $("vote-result").innerHTML
 = ‘ごめんなさい、サーバーに問題が発生していてうまく投票できませんでした’;
 }else{
  $("vote-result").innerHTML = ‘投票ありがとうございます!’;
 }
}
function displayFail()
{
 $("vote-result").innerHTML = ‘サーバーエラー!’;
}

XOOPSのテンプレートにJavaScriptの読み込みを追加します。
XOOPSのディレクトリのthemeディレクトリの中を探っていくとtheme.htmlがあるはずです。
これのheadタグの間に

<script language="javascript" src="/ajax/prototype.js"></script>
<script language="javascript" src="/ajax/votescript.js"></script>

を追加します。

WordPressのcomments-template.phpに以下のような行を追加します。
一行目の

<?php /* Don’t remove this line */ if (!defined(’XOOPS_ROOT_PATH’)) { exit; }?>

となっている所の下に追加するといいでしょう。

comments-template.phpはxoopsの中の「modules/wordpress/themes/(テーマ名)」の中にあります。

<div class="vote-box" id="vote-result">
この記事は良かったですか?
<input type="submit" name="Submit" value="良い"
 onClick="voteGood(<?php print($post->ID); ?>);">
<input type="submit" name="Submit" value="イマイチ"
 onClick="voteBad(<?php print($post->ID); ?>);">
</div> 

これでAjaxな投票ボタンは表示されます。

ランキングの表示は以下のような感じのソースをカスタムブロックに入れると良いでしょう。

global $xoopsUser,$xoopsDB;
$sql = "select m.postnumber, m.good ,p.post_title
        FROM ".$xoopsDB->prefix(’wp_popularity’)." m 
        INNER JOIN ".$xoopsDB->prefix(’wp_posts’)." p
        ON m.postnumber = p.ID WHERE m.good <> 0 ORDER BY m.good DESC LIMIT 10";
$res = $xoopsDB->query($sql);
$rank=0;
while($value = $xoopsDB->fetchArray($res)){
 $rank = $rank + 1;
 echo $rank.".<a href=http://a-tak.com/xoops/modules/wordpress/index.php?p=
                .$value["postnumber"]."&more=1&c=1">".$value["post_title"]
                ."(".$value["good"]." votes)</a><br/>";
}
echo "11位以降は
<a href="http://a-tak.com/xoops/modules/info/index.php?id=11">こちら</a><br/>";
echo date("m月d日 H時i分")." 更新";

こんな感じでAjaxな投票ボタンが出来た。
でも、よく考えるとXMLなんて全然使ってないのでAjax(エージャックス)じゃなくてAjaだな。
Aja・・・アジャ?なんかかっこわるい。

PHPとかよくわからずに作っているのでソースがやたら汚かったり、もしかしたらセキュリティーホールがあるかも。何か問題あったら教えて下さい。


この記事は良かったですか?(探していた情報、面白い) 投票すると結果がここに表示されます

この記事を読んだ人には、こんな記事もおすすめです


コメント

このコメントのRSS

TrackBack URL(スパム対策の為、トラックバック元の記事にこのサイトへのリンクが必要です) : http://a-tak.com/xoops/modules/wordpress/2006/08/20/1006/trackback/

  1. すみません。。
    どこに何をおいたらいいのか、書いてあるスクリプトをどんな名前で保存すればいいのか、パーミッション設定はあるのか等全くわかりません。。

    一番上のスクリプトはsqlに直接書くものですか?
    二番目のスクリプトは「vote.php」として「wordpress」フォルダ内に「ajax」ディレクトリを作って入れればいいですか?
    三番目のスクリプトは「prototype.js」として「wordpress」フォルダ内に「ajax」ディレクトリを作って入れればいいですか?
    四番目のスクリプトはwordpressの記事テーマに書けばいいですか?
    五番目のスクリプトはどの「comments-template.php」に記述すればいいですか?
    六番目のスクリプトはカスタムブロックで新規に作れば表示されるのでしょうか?
    以上お手数ですがよろしくおねがいします。

    Comment by しろうと — 2007年7月2日(月曜日) @ 13時39分49秒


  2. >一番上のスクリプトはsqlに直接書くものですか?
    そうですね。phpMyAdminなどで実行してください。

    >二番目のスクリプトは「vote.php」として「wordpress」フォルダ内に「ajax」ディレクト リを作って入れればいいですか?

    これはちょっと違いますね。Vote.phpはトップディレクトリにajaxというフォルダを作っておいています。javascriptの7行目にパスがあるので、場所を変えたい場合は、こちらも変えてください。

    >三番目のスクリプトは「prototype.js」として「wordpress」フォルダ内に「ajax」ディレクトリを作って入れればいいですか?

    これもvote.phpと同じところに置くことを想定してます。Theme.htmlでsrcを「/」から始めてますから、ルートディレクトリの中のajaxフォルダの中になりますね。

    >四番目のスクリプトはwordpressの記事テーマに書けばいいですか?

    いえ、xoopsのテーマの方です。

    >五番目のスクリプトはどの「comments-template.php」に記述すればいいですか?

    wordpressのthemesフォルダの中の使っているテーマと同じ名前のディレクトリ内にあるファイルですね。

    >六番目のスクリプトはカスタムブロックで新規に作れば表示されるのでしょうか?

    はい。そうですね。アドレスは適時書き換えてください。

    Comment by A-tak — 2007年7月2日(月曜日) @ 20時50分44秒


  3. ありがとうございます。
    度々恐縮ですがもう少し教えてください。。

    ・sqlにテーブルを追加しました。
    ・トップディレクトリに「vote.php」「prototype.js」を追加しましたが「votescript.js」というものは追加しなくていいのでしょうか?追加するとなるとどのようなスクリプトなのでしょうか?
    ・「comments-template.php」内に指定のスクリプトを埋め込んだのですが、押しても反応しません。formが無いのかと思いformでvote.phpを指定しても「fail」と表示されるだけで動いてくれません。。
    ・所々全角の「”」が混ざっていましたがこれは半角の「"」の記述ミスでしょうか?
    素人で申し訳ありませんがよろしくお願いします。。

    Comment by しろうと — 2007年7月3日(火曜日) @ 04時17分42秒


  4. >トップディレクトリに「vote.php」「prototype.js」を追加しましたが「votescript.js」というものは追加しなくていいのでしょうか?追加するとなるとどのようなスクリプトなのでしょうか?

    トップディレクトリに「ajax」というフォルダを作ってその中に入れる必要があります。
    votescript.jsは3番目のソースです。
    「// JavaScript Document」ではじまっているのです。

    たぶんこれが無いので、ボタンを押しても何も起きないのだと思います。

    あと、全角が混じってるのはすみません。間違いです。
    どこで混じってしまったのやら・・・

    Comment by A-tak — 2007年7月3日(火曜日) @ 12時04分57秒


  5. 最後の質問にします。これで動かなかったら諦めますのでよろしければお付き合いください。。

    1番目のソース:Mysqlに書けばいいとのことでTelnetで書き込みました。多分間違いないですよね?
    2番目のソース:MysqlのID・パスワード・ユーザ名・データベース名を書き込み「vote.php」としてルート階層に作った「ajax」フォルダに入れました。スクリプト内に変更必要箇所は無いですよね?
    3番目のソース:「votescript.js」として保存し、ルート階層に作った「ajax」フォルダに入れました。「prototype.js」は最新版を以下からダウンロードし同じフォルダに入れています。
    http://www.prototypejs.org/download
    4番目のソース:これはtheme.htmlの<head>タグ内に入れましたがそのまま入れるとページを読み込んだ際にエラーが出ます。このスクリプトタグで何かを挟まなくてはいけないのですか?
    (例:<script language="javascript" src="/ajax/prototype.js">何かのスクリプトを挟む?</script>)
    また「script language=」は正しくて「script type=」等に変更は必要ないでしょうか?
    5番目のソース:comments-template.phpに書きましたがformタグを入れなくてよいのでしょうか?formタグを追加する場合はどこに飛ばす設定にすればいいですか?
    例:<form action="どこに飛ばせばいいですか?">

    ここまででうまく動いていないので6番目のソースはまだ入れてません。
    すみませんがよろしくお願い致します。

    Comment by しろうと — 2007年7月4日(水曜日) @ 14時57分49秒


  6. 夜勤とかあってみれてませんでした。
    既にグラフ版に作り替えているので、元のソースはないのですが。、半角→全角の問題もあったので、家に帰ったらソースを見てみます。
    そしてまた返答します。

    Comment by A-tak — 2007年7月6日(金曜日) @ 12時24分02秒


  7. お忙しいなかありがとうございます!
    あれから自分なりに色々と挑戦してみたところ4番目のソースをtheme.htmlに入れてもエラーが出なくなりました。
    しかし5番目のスクリプトを記事ページ内に書き込み、ボタンを押してみると「投票処理中・・・」と出たまま止まってしまいます。。
    IEの下の情報バーには「ページでエラーが発生しました。」と出ています。
    一応telnetでデータベースに何か書き込まれているか見て見ましたが「0」のままでした。
    恐れ入りますがよろしくお願いします。
    ちなみにグラフ版は難しそうなので挑戦もしていません。。

    Comment by しろうと — 2007年7月6日(金曜日) @ 14時39分32秒


  8. お忙しいなかありがとうございます!
    あれからなんとか試行錯誤を繰り返し、4番目のソースをtheme.htmlに入れてもエラーが出なくなりました。
    しかし5番目のソースを記事ページに入れてボタンを押しても「投票処理中・・・」と出たまま止まってしまいます。。
    IEの下の情報バーにはエラーのマークが表示されています。
    状況が良くなっているのかもわかりませんがご報告させていただきました。。

    Comment by しろうと — 2007年7月7日(土曜日) @ 08時23分10秒


  9. >IEの下の情報バーにはエラーのマークが表示されています。

    たぶんJavaScriptに問題があると思うのですが、JavaScriptの何行目にエラーがあるとかいう情報は出ませんでしたっけ?
    IEは普段使っていないのでよくわからないのですが、FirefoxではJavaスクリプトコンソールという画面があって、何行目に問題があってエラーになっているか表示されます。

    Comment by A-tak — 2007年7月7日(土曜日) @ 11時33分31秒


  10. Prototypeのバージョンは1.5.0でやってます。
    試しに1.5.1に置き換えてみたら、なぜかグラフが動かなくなってしまいました・・・。謎です。とりあえず元のバージョンに戻しました。
    もしかしたら、グラフなしのバージョンでも問題が出るかもしれないので1.5.0を入れてみてください。

    あと、ソースの全角が入り交じっていたのをなおしました。ふぁいる場所やcomments-template.phpの追加場所も追記しました。参考にどうぞ。

    Comment by A-tak — 2007年7月7日(土曜日) @ 11時59分00秒


  11. あと、JavaScriptを変更した場合はキャッシュが残ってるかもしれないので、ブラウザの更新を押してください。

    Comment by A-tak — 2007年7月7日(土曜日) @ 12時17分01秒


コメントの投稿

スパム対策のため、2文字以上の連続した平仮名かカタカナがコメント内に必要です
コメントは、すぐに表示されない場合があります
以下のHTMLタグが使用可能です。
<a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <br> <code> <em> <i> <strike> <strong>


テクノラティプロフィール

71 queries. 0.446 sec.
Powered by WordPress Module based on WordPress ME & WordPress

さがしもの
 
現在、
 1587 の記事と
 1313 のコメントがあります
このブログの自己満足度
 241 %です
最近の投稿
最近のコメント
人気エントリー
アクセス数が多いエントリー
さがしモノ