=$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; } ?>