<?php

// Detect illegal access
// http://kikky.net/pc/php_var_server.html

require_once('config.php');
// confirm_single_access(2, true);

if (($result = confirm_single_access(2)) === true) {
    echo '単一のアクセスです．<br />';
} else {
    var_dump($result);
    echo '<br />';
    echo '単一のアクセスではありません．';
}
echo '<br />';
var_dump($_SERVER['REMOTE_ADDR']); echo '<br />';
var_dump($_SERVER['HTTP_X_FORWARDED_FOR']); echo '<br />';

// 単一アクセスであるかどうかを調べる
class confirm_single_access {

    var $acccheckrootdir;   // アクセス履歴ファイルを保存するルートフォルダ
    var $cookiename;        // クッキーの名称

    var $error;             // 何らかのエラーが生じた場合にエラーメッセージをセットする．

    function confirm_single_access()
    {
        global $CFG;
        // 初期設定
        $this->acccheckrootdir = $CFG->dataroot.'/accesscheck';
        $this->cookiename      = 'SingleAccess'.$CFG->sessioncookie;
    }

    // アクセス履歴ファイル名を取得
    function get_logfilename($id)
    {
        return 'user_'.$id.'.log';
    }
    // アクセス履歴ファイルのパス名を取得
    function get_logfiledir($cid)
    {
        return $this->acccheckrootdir.'/'.$cid;
    }
    // アクセス履歴ファイルのフルパスを取得
    function get_logfilepath($id, $cid)
    {
        return $this->get_logfiledir($cid).'/'.$this->get_logfilename($id);
    }
    // エラー発生時
    function 

    ///////////////////////////////////////////////////////////////////////////////////////
    // 指定されたユーザが指定されたコースにおいてユニークなログインであるかどうかを調べる．
    // $id      : ユーザID
    // $cid     : コースID．0の場合はサイト全体
    // $reset   : true の場合は$cid内のアクセス履歴ファイルを削除する．
          $cid == 0 の場合は全てのコース内のアクセス履歴ファイルを削除する
          $id == 0 の場合は該当するコースの全アクセス履歴ファイルを削除する
          アクセス履歴ファイルを削除した後にそのフォルダ内にアクセス履歴ファイルが存在しない場合はフォルダも削除する．
    // ユニークである場合に戻り値は true，　ユニークではない場合はfalseを返す．
    // 何らかの問題が生じた場合は利便性を考慮してtrueを返すが，エラーメッセージを$this->errorにセットする
    function confirm_single_access($id = 0, $cid = 0, $reset = false)
    {
        global $CFG;
        // 初期設定
        $logfiledir  = $this->get_logfiledir($cid);
        $logfilename = 'user_'.$id.'.log';
        $logfilepath = $hits->get_logfilepath($id, $cid);

        // フォルダのチェック
        if (!file_exists($this->acccheckrootdir)) {
            if (!@mkdir($this->acccheckrootdir)) return 'フォルダを作成できません';
        }
        if (!file_exists($logfiledir)) {
            if (!@mkdir($logfiledir)) return 'フォルダを作成できません';
        }
        if (!is_dir($logfilepath)) return 'フォルダを作成できません';

        // クリア時
        if ($reset) {
            @unlink($accesscheckpath);
        }

        // アクセス履歴ファイルのチェック
        unset($lastdata);
        if (file_exists($accesscheckpath)) {
            // 現ユーザの以前のアクセス履歴
            if ($handle = fopen($accesscheckpath, 'r')) {
                if (($str = fgets($handle)) == false) return 'ファイルを読めません';
            } else return 'ファイルを開けません';
            $lastdata = unserialize($str);
        }

        // 現ユーザのアクセス履歴の取得
        unset($accdata);
        $accdata->http_user_agent      = $_SERVER['HTTP_USER_AGENT'];
        $accdata->remote_addr          = $_SERVER['REMOTE_ADDR'];
        $accdata->remote_port          = $_SERVER['REMOTE_PORT'];
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $accdata->http_x_forwarded_for = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $accdata->http_x_forwarded_for = '';
        }
        if (!empty($_COOKIE[$cookiename])) $acccookie = $_COOKIE[$cookiename]; else $acccookie = '';
        $accdata->session_test    = $acccookie;
        $accdata->time            = time();

        // 不正な多重アクセスではないかチェック
        if (!empty($lastdata)) {
            $flag = false;
            if ($accdata->http_user_agent != $lastdata->http_user_agent) $flag = true;
            if ($accdata->remote_addr     != $lastdata->remote_addr)     $flag = true;
    //      if ($accdata->remote_port     != $lastdata->remote_port)     $flag = true;
            if ($accdata->http_x_forwarded_for
                                          != $lastdata->http_x_forwarded_for) $flag = true;
            if ($accdata->session_test    != $lastdata->session_test)    $flag = true;
    // var_dump($lastdata); echo '<br />';
    // var_dump($accdata);  echo '<br />';
            if ($flag) return '多重アクセスです';
        }

        // アクセス履歴ファイルの更新
        $accdata->session_test    = $_SESSION['SESSION']->session_test;
        $serialdata = serialize($accdata);
        if ($handle = fopen($accesscheckpath, 'w')) {
            if (fputs($handle, $serialdata) == false) return 'ファイルに保存できません';
            fclose($handle);
        } else return 'ファイルを開けません';

        // クッキーを更新
        if (check_php_version('5.2.0')) {
            setcookie($cookiename, $accdata->session_test, time() + 3600, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly);
        } else {
            setcookie($cookiename, $accdata->session_test, time() + 3600, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure);
        }

        return true;
    }
}

?>
