instance)) {
error("assignment ID was incorrect");
}
if (! $course = get_record("course", "id", $assignment->course)) {
error("Course is misconfigured");
}
} else {
if (!$assignment = get_record("assignment", "id", $a)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $assignment->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id, false, $cm);
require_capability('mod/assignment:grade', get_context_instance(CONTEXT_MODULE, $cm->id));
// (Shirai098): 提出された課題の明白な手抜きを見抜く機能 (2008/10/28)
// レベル1:内容が完全に一致する提出物が複数存在する
// レベル2:内容が酷似した提出物が複数存在する
// レベル3:内容の一部が類似した提出物が複数存在する
// レベル4:内容が外部情報からのコピー&ペーストである可能性のある提出物が存在する
// 課題の提出物の情報を取得する
require_once($CFG->libdir.'/filelib.php');
// 二つのファイルをバイナリモードで比較する
function file_compare($source, $target)
{
if (($fp1 = fopen($source, 'rb')) == false) return false;
if (($fp2 = fopen($target, 'rb')) == false) return false;
$flag = true;
while (!feof($fp1) && !feof($fp2)) {
$data1 = fread($fp1, 1024);
$data2 = fread($fp2, 1024);
if ($data1 !== $data2) {
fclose($fp1);
fclose($fp2);
return false;
}
}
if ((!feof($fp1)) || (!feof($fp2))) return false;
return true;
}
// デバッグ用出力を有効にする場合はコメント記号を外す
// define('bhc_debug', true);
function get_uploaded_assignment_for_boneheadcheck($courseid, $id)
{
global $CFG;
// ファイルリストの取得
$uploadeddata = array();
$uploaded_cnt = 0;
$filearea = $CFG->dataroot.'/'.$courseid.'/moddata/assignment/'.$id;
$cdir = opendir($filearea);
while (($uid = readdir($cdir)) !== false) {
if (($uid == '.') || ($uid == '..')) continue;
$udir = opendir($filearea.'/'.$uid);
$list = array();
while (($ufile = readdir($udir)) !== false) {
if (($ufile == '.') || ($ufile == '..')) continue;
$uploaded_cnt++;
$info['uid'] = $uid;
if ($user = get_record('user', 'id', $info['uid'])) {
$info['fullname'] = fullname($user);
} else {
$info['fullname'] = $info['uid'];
}
$info['filename'] = $ufile;
$info['fullpath'] = $filearea.'/'.$uid.'/'.$ufile;
$info['filesize'] = filesize($info['fullpath']);
$info['ffurl'] = get_file_url($courseid.'/moddata/assignment/'.$id.'/'.$uid.'/'.$ufile, null, 'coursefile');
$info['ctime'] = filectime($info['fullpath']);
$info['mtime'] = filemtime($info['fullpath']);
$list[] = $info;
}
if (!empty($list)) $uploadeddata[$uid] = $list;
}
// 確認用出力
if (defined('bhc_debug')) {
$cnt = 0;
foreach ($uploadeddata as $uid => $list) {
echo 'User: '.$uid.'
';
foreach ($list as $info) {
$cnt++;
echo '--> '.$info['filename'].'
';
echo ' '.$info['fullpath'].'
';
echo ' '.$info['filesize'].'
';
echo ' '.$info['ffurl'].'
';
}
}
echo '合計:'.$cnt.'ファイル
';
}
return $uploadeddata;
}
function bonehead_check_level1($uploadeddata)
{
// チェック開始
// 1次チェック(ファイルサイズで抽出)
$uploaded_cnt = 0;
$suspects1 = array();
foreach ($uploadeddata as $uid => $list) {
foreach ($list as $info) {
$uploaded_cnt++;
$suspects1[$info['filesize']][] = $info;
}
}
foreach ($suspects1 as $fsize => $suspects) {
if (count($suspects) <= 1) unset($suspects1[$fsize]);
}
// 確認用出力
if (defined('bhc_debug')) {
$cnt = 0;
foreach ($suspects1 as $fsize => $suspects) {
echo '
ファイルサイズ: '.$fsize.'
';
foreach ($suspects as $info) {
$cnt++;
echo $info['uid'].'の'.$info['filename'].'
';
echo '-->'.$info['fullpath'].'
';
echo '-->'.$info['filesize'].'
';
echo '-->'.$info['ffurl'].'
';
}
}
echo '合計:'.$cnt.'ファイル
';
}
// 2次チェック(SHA1ハッシュ値を調べて抽出)
$suspects2 = array();
foreach ($suspects1 as $fsize => $suspects) {
foreach ($suspects as $info) {
if (($sha1 = sha1_file($info['fullpath'])) == false) {
error('ファイルが見付かりませんでした');
die;
}
$info['sha1'] = $sha1;
$suspects2[$fsize][$sha1][] = $info;
}
foreach ($suspects2[$fsize] as $sha1 => $list) {
if (count($list) <= 1) unset($suspects2[$fsize][$sha1]);
}
}
// 3次チェック(厳密なチェック):(1)とその他の比較
$suspects3 = array();
foreach ($suspects2 as $fsize => $suspects) {
foreach ($suspects as $sha1 => $list) {
$source = '';
foreach ($list as $info) {
if ($source === '') {
$source = $info['fullpath'];
$info['compare'] = '-';
} else {
if (file_compare($source, $info['fullpath'])) {
$info['compare'] = 'Yes';
} else {
$info['compare'] = 'No';
}
}
$suspects3[$fsize][$sha1][] = $info;
}
}
}
$total_cnt = 0;
echo '検査結果表示完全に一致するファイル)
';
foreach ($suspects3 as $fsize => $suspects) {
foreach ($suspects as $sha1 => $list) {
$cnt = 0;
echo '
';
echo '
No. | ユーザ名 | ファイル名 | 作成日時 | 更新日時 | '; echo '(1)と厳密に等しいか? | '; echo '
---|---|---|---|---|---|
($cnt) | ".$info['fullname'].' | '; echo ''.$info['filename'].''; echo ' | '; echo ''.date('Y/m/d H:i:s', $info['ctime']).' | '; echo ''.date('Y/m/d H:i:s', $info['mtime']).' | '; echo ''.$info['compare'].' | '; echo '