=$ess['starttime'] and $checktime<=$sess['endtime']
and $method==$sess['method'] and $state==$sess['state']) {
return $sess;
}
}
return false;
}
//
// 指定した授業で,指定した評価を得たユーザ(複数)の情報を返す.
// $statuss は評価の配列(例:array('Y','P','X'))または評価の文字(例:'Y')
// または指定しない 指定しない場合は全ての評価を指定したことになる.
// 返される情報は2次元配列(1番目の要素は userid)
//
function autoattend_get_users_bystatus($sessid, $statuss='')
{
global $CFG;
$status = '';
if (is_array($statuss)) {
$substs = implode("' or status='", $statuss);
if (!empty($substs)) $status = " and ( status='".$substs."' )";
}
else {
if (!empty($statuss)) $status = " and status='".$statuss."' ";
}
$return = array();
$qry = "select * ".
" from {$CFG->prefix}autoattend_students ".
" where attsid=".$sessid." ".$status.
" order by studentid asc";
//print "QUERY = $qry
";
if ($users = get_records_sql($qry)) {
foreach($users as $key => $user) {
$return[$user->studentid]['id'] = $user->id;
$return[$user->studentid]['attsid'] = $user->attsid;
$return[$user->studentid]['studentid'] = $user->studentid;
$return[$user->studentid]['status'] = $user->status;
$return[$user->studentid]['called'] = $user->called;
$return[$user->studentid]['calledby'] = $user->calledby;
$return[$user->studentid]['calledtime'] = $user->calledtime;
$return[$user->studentid]['remarks'] = $user->remarks;
$return[$user->studentid]['ipaddress'] = $user->ipaddress;
}
}
return $return;
}
//
// 指定した授業での,指定したユーザの情報を返す.
//
function autoattend_get_user_atsession($sessid, $userid)
{
global $CFG;
$return = array();
$qry = "select * ".
" from {$CFG->prefix}autoattend_students ".
" where attsid=".$sessid." and studentid=".$userid;
//print "QUERY = $qry
";
if ($users = get_records_sql($qry)) {
foreach($users as $key => $user) {
$return['id'] = $user->id;
$return['attsid'] = $user->attsid;
$return['studentid'] = $user->studentid;
$return['status'] = $user->status;
$return['called'] = $user->called;
$return['calledby'] = $user->calledby;
$return['calledtime'] = $user->calledtime;
$return['remarks'] = $user->remarks;
$return['ipaddress'] = $user->ipaddress;
}
}
return $return;
}
//
// クローズしている時刻であるが,まだクローズしていない授業の情報を返す..
// $methods はデフォルトの点呼方法の配列(例:array('A','S')または点呼方法の文字(例:'S')
// または指定なし.指定しない場合は全ての方法を指定したことになる.
// また,現在授業中ものも含めて返す場合は $incopen を true にする.
//
function autoattend_get_unclosedsessions($courseid, $methods='', $ntime='', $incopen=false)
{
global $CFG, $TIME_OFFSET;
require_once($CFG->dirroot.'/blocks/autoattend/lib.php');
$method = '';
if (is_array($methods)) {
$submth = implode("' or method='", $methods);
if (!empty($submth)) $method = " and ( method='".$submth."' )";
}
else {
if (!empty($methods)) $method = " and method='".$methods."' ";
}
if (empty($ntime)) $ntime = time();
$ntime += $TIME_OFFSET;
$return = array();
if ($incopen) $ctime = "starttime";
else $ctime = "endtime";
$qry = "select * ".
" from {$CFG->prefix}autoattend_sessions ".
" where courseid=".$courseid." and state<>'C'".$method." and (sessdate+".$ctime.")<='".$ntime."' ".
" order by sessdate, starttime asc";
//print "QUERY = $qry
";
if ($sesss = get_records_sql($qry)) {
foreach($sesss as $key => $sess) {
$stime = $sess->sessdate + $sess->starttime - $TIME_OFFSET;
$etime = $sess->sessdate + $sess->endtime - $TIME_OFFSET;
$return[$sess->id]['id'] = $sess->id;
$return[$sess->id]['courseid'] = $sess->courseid;
$return[$sess->id]['method'] = $sess->method;
$return[$sess->id]['state'] = $sess->state;
$return[$sess->id]['sessdate'] = $sess->sessdate;
$return[$sess->id]['starttime'] = $stime;
$return[$sess->id]['endtime'] = $etime;
$return[$sess->id]['latetime'] = $sess->latetime;
$return[$sess->id]['attendkey'] = $sess->attendkey;
$return[$sess->id]['allowip'] = $sess->allowip;
$return[$sess->id]['denysameip'] = $sess->denysameip;
$return[$sess->id]['description'] = $sess->description;
}
}
return $return;
}
//
// 学生用の授業用データレコードの追加
//
function autoattend_add_user_insession($sessid, $userid)
{
$rec->attsid = $sessid;
$rec->studentid = $userid;
$rec->status = 'Y';
$result = insert_record('autoattend_students', $rec);
return $result;
}
//
// 指定された授業の学生データをリセットする.
//
function autoattend_reset_session_user($courseid, $sessid)
{
$stdnts = get_course_students($courseid);
foreach($stdnts as $stdnt) {
$user = autoattend_get_user_atsession($sessid, $stdnt->id);
if (empty($user)) {
autoattend_add_user_insession($sessid, $stdnt->id);
}
else {
$rec->id = $user['id'];
$rec->attsid = $user['attsid'];
$rec->studentid = $user['studentid'];
$rec->status = 'Y';
$rec->called = 'D';
$rec->calledby = '0';
$rec->calledtime = '0';
$rec->remarks = '';
$rec->ipaddress = '';
update_record('autoattend_students', $rec);
}
unset($rec);
}
return;
}
//
// 学生(s)の登録状態を最新の状態に更新する.
//
function autoattend_update_sessions_users($courseid, $ntime='')
{
if (empty($ntime)) $ntime = time();
$sesss = autoattend_get_unclosedsessions($courseid, '', $ntime, true);
$stdnts = get_course_students($courseid);
foreach($sesss as $sess) {
foreach($stdnts as $stdnt) {
$user = autoattend_get_user_atsession($sess['id'], $stdnt->id);
if (empty($user)) {
autoattend_add_user_insession($sess['id'], $stdnt->id);
}
}
}
return $sesss;
}
//
// 授業の点呼状態を最新の状態に更新する.
//
function autoattend_update_sessions_state($sesss, $ntime='')
{
if (empty($ntime)) $ntime = time();
if (!empty($sesss) and is_array($sesss)) {
foreach($sesss as $key=>$sess) {
$stime = $sess['starttime'];
$etime = $sess['endtime'];
if ($ntime > $etime) $state = 'C';
else if ($ntime >= $stime and $ntime <= $etime) $state = 'O';
else {
error(get_string('nevererror','block_autoattend')." IN autoattend_update_sessions_state()");
}
$rec->id = $sess['id'];
$rec->state = $state;
update_record('autoattend_sessions', $rec);
unset($rec);
$sesss[$key]['state'] = $state;
}
}
return $sesss;
}
//
// 全てのデータを最新の状態に更新する
//
function autoattend_update_sessions($courseid, $ntime='')
{
global $USER;
if (empty($ntime)) $ntime = time();
$sesss = autoattend_update_sessions_users($courseid, $ntime); // 学生の授業レコードを登録
$sesss = autoattend_update_sessions_state($sesss, $ntime); // 授業の状態を更新
$logs = autoattend_get_courselogs($courseid);
if ($sesss) {
foreach($sesss as $sess) {
if ($sess['method']=='A') { // 自動処理
autoattend_complete_autoattend($logs, $sess, $ntime);
}
else if ($sess['method']=='S') { // 半自動モードの授業で終了したものをクローズ
autoattend_close_semiautoattend($sess, $ntime);
}
}
add_to_log($courseid, 'autoattend', 'refresh data',
'refreshSessions.php?course='.$courseid.'&attsid='.$sess['id']);
}
}
//
// 自動モードの処理
//
function autoattend_complete_autoattend($logs, $sess, $ntime='')
{
if (empty($logs)) return;
$users = autoattend_get_users_bystatus($sess['id'], 'Y');
if ($users) {
require_once("tuis_tools.php");
if (empty($ntime)) $ntime = time();
$stime = $sess['starttime'];
$etime = $sess['endtime'];
$ltime = $sess['latetime'];
$allowip = $sess['allowip'];
$ipfmts = tuis_to_subnetformats($allowip);
//$difipf = $sess['denysameip'];
$difipf = false; // Autoの場合は色々問題ありそうなので,この機能は使用しない
$used_ips = array();
$sesslogs = array();
foreach($logs as $log) {
$logtime = $log->time;
if ($logtime>=$stime and $logtime<=$etime) $sesslogs[] = $log;
}
foreach($users as $stdid=>$user) {
$status = 'X';
$match_ip = '';
$match_tm = 0;
$userlogs = array();
foreach($sesslogs as $log) {
if ($log->userid==$user['studentid']) $userlogs[] = $log;
}
if (!empty($userlogs)) {
$valid_log = autoattend_check_valid_logip($userlogs, $ipfmts, $used_ips, $difipf);
if (!empty($valid_log)) {
$match_ip = $valid_log['ip'];
$match_tm = $valid_log['time'];
}
if (!empty($match_ip)) {
$status = 'P';
if ($difipf) $used_ips[] = $match_ip;
if ($ltime!=0) {
if ($match_tm > $stime + $ltime) $status = 'L';
}
$rec->ipaddress = $match_ip;
}
}
// ここで,$status は X, P, L のいずれか.
//print "state = {$sess['state']} status = $status
";
if ($sess['state']=='C' or $status!='X') {
$rec->id = $user['id'];
$rec->attsid = $sess['id'];
$rec->studentid = $stdid;
$rec->status = $status;
$rec->called = 'A';
$rec->calledby = CALLED_BY_AUTO;
$rec->calletime = $ntime;
$result = update_record('autoattend_students', $rec);
if ($result) {
$loginfo =AUTO_SUBMIT_LOG."={$sess['id']},$stdid,Y,$status";
add_to_log($sess['courseid'], 'autoattend', 'submit autoattend',
'refreshSessions.php?courseid='.$sess['courseid'].'&attsid='.$sess['id'], $loginfo);
}
}
unset($rec);
}
}
}
//
// 半自動モードのクローズ処理
//
function autoattend_close_semiautoattend($sess, $ntime='')
{
if ($sess['state']=='C') {
$users = autoattend_get_users_bystatus($sess['id'], 'Y');
if ($users) {
if (empty($ntime)) $ntime = time();
foreach($users as $stdid=>$user) {
$rec->id = $user['id'];
$rec->attsid = $sess['id'];
$rec->studentid = $stdid;
$rec->status = 'X';
$rec->called = 'S';
$rec->calledby = CALLED_BY_SEMIAUTO;
$rec->calletime = $ntime;
update_record('autoattend_students', $rec);
unset($rec);
}
}
}
}
//
// logの中から許可されたフォーマット ipfmts に一致するIPを探す
// ただしdifipf が trueの場合,配列 userd_ipsに含まれるIPは一致から除外する.
function autoattend_check_valid_logip($userlogs, $ipfmts, $used_ips, $difipf)
{
$return = array();
if (empty($userlogs)) return $return;
require_once("tuis_tools.php");
foreach($userlogs as $log) {
$chkip = $log->ip;
if (empty($ipfmts) or tuis_match_ipaddr($chkip, $ipfmts)) {
$chkip_f = true;
if ($difipf and !empty($used_ips)) {
foreach($used_ips as $used_ip) { // 同一IPチェック
if ($chkip==$used_ip) {
$chkip_f = false;
break;
}
}
}
if ($chkip_f) {
$return['ip'] = $chkip;
$return['time'] = $log->time;
$return['userid'] = $log->userid;
return $return;
}
}
}
return $return;
}
//
// 半自動モードに於いて接続IPの検査を行う.
//
function autoattend_check_invalid_semiautoip($att)
{
require_once("tuis_tools.php");
$ipaddr = getremoteaddr();
$allowip = $att->allowip;
$difipf = $att->denysameip;
$iperrmesg = '';
$ipfmts = tuis_to_subnetformats($allowip);
if (empty($ipfmts) or tuis_match_ipaddr($ipaddr, $ipfmts)) {
if ($difipf) {
$logs = autoattend_get_courselogs($att->courseid);
$used_ips = autoattend_get_semiautoip($logs, $att->id);
if ($used_ips) {
foreach($used_ips as $used_ip) {
if ($ipaddr==$used_ip) {
$iperrmesg = get_string('sameusedip','block_autoattend')." ".$ipaddr;
break;
}
}
}
}
}
else {
$iperrmesg = get_string('mismatchip','block_autoattend')." ".$ipaddr;
}
return $iperrmesg;
}
//
// ログの中から半自動モードで出席を送信したIPを取り出す
//
function autoattend_get_semiautoip($logs, $sessid)
{
$return = array();
$chkinfo = SEMIAUTO_SUBMIT_LOG."=$sessid,";
$chklen = strlen($chkinfo);
foreach($logs as $log) {
if (!strncmp($log->info, $chkinfo, $chklen)) {
$return[] = $log->ip;
}
}
return $return;
}
//
// 指定したコースのログを得る
//
function autoattend_get_courselogs($courseid)
{
global $CFG;
$return = array();
$qry = "select * from {$CFG->prefix}log where course=".$courseid." and (action='view' or action='review') order by time asc";
//print "QUERY = $qry
";
$logs = get_records_sql($qry);
//print_r($logs);
return $logs;
}
?>