function submit_work($id, $on_behalf_of = null) { global $tool_content, $workPath, $uid, $course_id, $works_url, $langUploadSuccess, $langBack, $langUploadError, $langExerciseNotPermit, $langUnwantedFiletype, $langAutoJudgeEmptyFile, $langAutoJudgeInvalidFileType, $langAutoJudgeScenariosPassed, $course_code, $langOnBehalfOfUserComment, $langOnBehalfOfGroupComment, $course_id; $connector = q(get_config('autojudge_connector')); $connector = new $connector(); $langExt = $connector->getSupportedLanguages(); //checks for submission validity end here if (isset($on_behalf_of)) { $user_id = $on_behalf_of; } else { $user_id = $uid; } $submit_ok = FALSE; // Default do not allow submission if (isset($uid) && $uid) { // check if logged-in if ($GLOBALS['status'] == 10) { // user is guest $submit_ok = FALSE; } else { // user NOT guest if (isset($_SESSION['courses']) && isset($_SESSION['courses'][$_SESSION['dbname']])) { // user is registered to this lesson $row = Database::get()->querySingle("SELECT deadline, late_submission, CAST(UNIX_TIMESTAMP(deadline)-UNIX_TIMESTAMP(NOW()) AS SIGNED) AS time\n FROM assignment WHERE id = ?d", $id); if ($row->time < 0 && (int) $row->deadline && !$row->late_submission and !$on_behalf_of) { $submit_ok = FALSE; // after assignment deadline } else { $submit_ok = TRUE; // before deadline } } else { //user NOT registered to this lesson $submit_ok = FALSE; } } } //checks for submission validity end here $row = Database::get()->querySingle("SELECT title, group_submissions, auto_judge, auto_judge_scenarios, lang, max_grade FROM assignment WHERE course_id = ?d AND id = ?d", $course_id, $id); $title = q($row->title); $group_sub = $row->group_submissions; $auto_judge = $row->auto_judge; $auto_judge_scenarios = $auto_judge == true ? unserialize($row->auto_judge_scenarios) : null; $lang = $row->lang; $max_grade = $row->max_grade; $nav[] = $works_url; $nav[] = array('url' => "{$_SERVER['SCRIPT_NAME']}?id={$id}", 'name' => $title); if ($submit_ok) { if ($group_sub) { $group_id = isset($_POST['group_id']) ? intval($_POST['group_id']) : -1; $gids = user_group_info($on_behalf_of ? null : $user_id, $course_id); $local_name = isset($gids[$group_id]) ? greek_to_latin($gids[$group_id]) : ''; } else { $group_id = 0; $local_name = uid_to_name($user_id); $am = Database::get()->querySingle("SELECT am FROM user WHERE id = ?d", $user_id)->am; if (!empty($am)) { $local_name .= $am; } $local_name = greek_to_latin($local_name); } $local_name = replace_dangerous_char($local_name); if (isset($on_behalf_of) and (!isset($_FILES) or !$_FILES['userfile']['size'])) { $_FILES['userfile']['name'] = ''; $_FILES['userfile']['tmp_name'] = ''; $no_files = true; } else { $no_files = false; } validateUploadedFile($_FILES['userfile']['name'], 2); if (preg_match('/\\.(ade|adp|bas|bat|chm|cmd|com|cpl|crt|exe|hlp|hta|' . 'inf|ins|isp|jse|lnk|mdb|mde|msc|msi|msp|mst|pcd|pif|reg|scr|sct|shs|' . 'shb|url|vbe|vbs|wsc|wsf|wsh)$/', $_FILES['userfile']['name'])) { $tool_content .= "<p class=\"caution\">{$langUnwantedFiletype}: {$_FILES['userfile']['name']}<br />"; $tool_content .= "<a href=\"{$_SERVER['SCRIPT_NAME']}?course={$course_code}&id={$id}\">{$langBack}</a></p><br />"; return; } $secret = work_secret($id); $ext = get_file_extension($_FILES['userfile']['name']); $filename = "{$secret}/{$local_name}" . (empty($ext) ? '' : '.' . $ext); if (!isset($on_behalf_of)) { $msg1 = delete_submissions_by_uid($user_id, -1, $id); if ($group_sub) { if (array_key_exists($group_id, $gids)) { $msg1 = delete_submissions_by_uid(-1, $group_id, $id); } } } else { $msg1 = ''; } if ($no_files or move_uploaded_file($_FILES['userfile']['tmp_name'], "{$workPath}/{$filename}")) { if (file_get_contents("{$workPath}/{$filename}") != false) { if ($no_files) { $filename = ''; } else { @chmod("{$workPath}/{$filename}", 0644); } $msg2 = $langUploadSuccess; $submit_ip = $_SERVER['REMOTE_ADDR']; if (isset($on_behalf_of)) { if ($group_sub) { $auto_comments = sprintf($langOnBehalfOfGroupComment, uid_to_name($uid), $gids[$group_id]); } else { $auto_comments = sprintf($langOnBehalfOfUserComment, uid_to_name($uid), uid_to_name($user_id)); } //group_sub $stud_comments = $auto_comments; $grade_comments = $_POST['stud_comments']; $grade_valid = filter_input(INPUT_POST, 'grade', FILTER_VALIDATE_FLOAT); isset($_POST['grade']) && $grade_valid !== false ? $grade = $grade_valid : ($grade = NULL); $grade_ip = $submit_ip; } else { $stud_comments = $_POST['stud_comments']; $grade = NULL; $grade_comments = $grade_ip = ""; } if (!$group_sub or array_key_exists($group_id, $gids)) { $file_name = $_FILES['userfile']['name']; $sid = Database::get()->query("INSERT INTO assignment_submit\n (uid, assignment_id, submission_date, submission_ip, file_path,\n file_name, comments, grade, grade_comments, grade_submission_ip,\n grade_submission_date, group_id)\n VALUES (?d, ?d, NOW(), ?s, ?s, ?s, ?s, ?f, ?s, ?s, NOW(), ?d)", $user_id, $id, $submit_ip, $filename, $file_name, $stud_comments, $grade, $grade_comments, $grade_ip, $group_id)->lastInsertID; Log::record($course_id, MODULE_ID_ASSIGN, LOG_INSERT, array('id' => $sid, 'title' => $title, 'assignment_id' => $id, 'filepath' => $filename, 'filename' => $file_name, 'comments' => $stud_comments, 'group_id' => $group_id)); // update attendance book as well update_attendance_book($id, 'assignment'); if ($on_behalf_of and isset($_POST['email'])) { $email_grade = $_POST['grade']; $email_comments = "\n{$auto_comments}\n\n" . $_POST['stud_comments']; grade_email_notify($id, $sid, $email_grade, $email_comments); } } $tool_content .= "<div class='alert alert-success'>{$msg2}<br>{$msg1}<br><a href='{$_SERVER['SCRIPT_NAME']}?course={$course_code}&id={$id}'>{$langBack}</a></div><br>"; } else { $tool_content .= "<div class='alert alert-danger'>{$langAutoJudgeEmptyFile}<br><a href='{$_SERVER['SCRIPT_NAME']}?course={$course_code}'>{$langBack}</a></div><br>"; } } else { $tool_content .= "<div class='alert alert-danger'>{$langUploadError}<br><a href='{$_SERVER['SCRIPT_NAME']}?course={$course_code}'>{$langBack}</a></div><br>"; } // Auto-judge: Send file to hackearth if ($auto_judge && $ext === $langExt[$lang]) { $content = file_get_contents("{$workPath}/{$filename}"); // Run each scenario and count how many passed $auto_judge_scenarios_output = array(array('student_output' => '', 'passed' => 0)); $passed = 0; $i = 0; $partial = 0; $errorsComment = ''; $weight_sum = 0; foreach ($auto_judge_scenarios as $curScenario) { $input = new AutoJudgeConnectorInput(); $input->input = $curScenario['input']; $input->code = $content; $input->lang = $lang; $result = $connector->compile($input); // Check if we have compilation errors. if ($result->compileStatus !== $result::COMPILE_STATUS_OK) { // Write down the error message. $num = $i + 1; $errorsComment = $result->compileStatus . " " . $result->output . "<br />"; $auto_judge_scenarios_output[$i]['passed'] = 0; } else { // Get all needed values to run the assertion. $auto_judge_scenarios_output[$i]['student_output'] = $result->output; $scenarioOutputExpectation = trim($curScenario['output']); $scenarionAssertion = $curScenario['assertion']; // Do it now. $assertionResult = doScenarioAssertion($scenarionAssertion, $auto_judge_scenarios_output[$i]['student_output'], $scenarioOutputExpectation); // Check if assertion passed. if ($assertionResult) { $passed++; $auto_judge_scenarios_output[$i]['passed'] = 1; $partial += $curScenario['weight']; } else { $num = $i + 1; $auto_judge_scenarios_output[$i]['passed'] = 0; } } $weight_sum += $curScenario['weight']; $i++; } // 3 decimal digits precision $grade = round($partial / $weight_sum * $max_grade, 3); // allow an error of 0.001 if ($max_grade - $grade <= 0.001) { $grade = $max_grade; } // Add the output as a comment $comment = $langAutoJudgeScenariosPassed . ': ' . $passed . '/' . count($auto_judge_scenarios); rtrim($errorsComment, '<br />'); if ($errorsComment !== '') { $comment .= '<br /><br />' . $errorsComment; } submit_grade_comments($id, $sid, $grade, $comment, false, $auto_judge_scenarios_output, true); } else { if ($auto_judge && $ext !== $langExt[$lang]) { if ($lang == null) { die('Auto Judge is enabled but no language is selected'); } if ($langExt[$lang] == null) { die('An unsupported language was selected. Perhaps platform-wide auto judge settings have been changed?'); } submit_grade_comments($id, $sid, 0, sprintf($langAutoJudgeInvalidFileType, $langExt[$lang], $ext), false, null, true); } } // End Auto-judge } else { // not submit_ok $tool_content .= "<div class='alert alert-danger'>{$langExerciseNotPermit}<br><a href='{$_SERVER['SCRIPT_NAME']}?course={$course_code}'>{$langBack}</a></div><br>"; } }
function submit_work($uid, $group_id, $id, $file) { global $groupPath, $langUploadError, $langUploadSuccess, $langBack, $m, $tool_content, $workPath, $group_sql, $webDir, $course_code, $is_editor; $ext = get_file_extension($file); $local_name = greek_to_latin('Group ' . $group_id . (empty($ext) ? '' : '.' . $ext)); $original_filename = Database::get()->querySingle("SELECT filename FROM document WHERE $group_sql AND path = ?s", $file)->filename; $source = $groupPath . $file; $destination = work_secret($id) . "/$local_name"; delete_submissions_by_uid($uid, $group_id, $id, $destination); if (is_dir($source)) { $original_filename = $original_filename . '.zip'; $zip_filename = $webDir . 'courses/temp/' . safe_filename('zip'); zip_documents_directory($zip_filename, $file, $is_editor); $source = $zip_filename; } if (copy($source, "$workPath/$destination")) { Database::get()->query("INSERT INTO assignment_submit (uid, assignment_id, submission_date, submission_ip, file_path, file_name, comments, group_id, grade_comments) VALUES (?d, ?d, NOW(), '$_SERVER[REMOTE_ADDR]', ?s, ?s, ?s, ?d, ''", $uid, $id, $destination, $original_filename, $_POST['comments'], $group_id); $tool_content .="<div class='alert alert-success'>$langUploadSuccess <br>$m[the_file] \"$original_filename\" $m[was_submitted]<br> <a href='index.php?course=$course_code'>$langBack</a></div><br>"; } else { $tool_content .="<div class='alert alert-danger'>$langUploadError<br> <a href='index.php?course=$course_code'>$langBack</a></div><br>"; } }
function submit_work($id, $on_behalf_of = null) { global $course_id, $uid, $langOnBehalfOfGroupComment, $works_url, $langOnBehalfOfUserComment, $workPath, $langUploadSuccess, $langUploadError, $course_code, $langAutoJudgeEmptyFile, $langAutoJudgeInvalidFileType, $langAutoJudgeScenariosPassed; $connector = AutojudgeApp::getAutojudge(); $langExt = $connector->getSupportedLanguages(); $row = Database::get()->querySingle("SELECT id, title, group_submissions, submission_type, deadline, late_submission, CAST(UNIX_TIMESTAMP(deadline)-UNIX_TIMESTAMP(NOW()) AS SIGNED) AS time, auto_judge, auto_judge_scenarios, lang, max_grade FROM assignment WHERE course_id = ?d AND id = ?d", $course_id, $id); $auto_judge = $row->auto_judge; $auto_judge_scenarios = ($auto_judge == true) ? unserialize($row->auto_judge_scenarios) : null; $lang = $row->lang; $max_grade = $row->max_grade; $nav[] = $works_url; $nav[] = array('url' => "$_SERVER[SCRIPT_NAME]?id=$id", 'name' => q($row->title)); $submit_ok = FALSE; // Default do not allow submission if (isset($uid) && $uid) { // check if logged-in if ($GLOBALS['status'] == USER_GUEST) { // user is guest $submit_ok = FALSE; } else { // user NOT guest if (isset($_SESSION['courses']) && isset($_SESSION['courses'][$_SESSION['dbname']])) { // user is registered to this lesson if (($row->time < 0 && (int) $row->deadline && !$row->late_submission) and !$on_behalf_of) { $submit_ok = FALSE; // after assignment deadline } else { $submit_ok = TRUE; // before deadline } } else { //user NOT registered to this lesson $submit_ok = FALSE; } } } //checks for submission validity end here if ($submit_ok) { $success_msgs = array(); $error_msgs = array(); //Preparing variables $user_id = isset($on_behalf_of) ? $on_behalf_of : $uid; if ($row->group_submissions) { $group_id = isset($_POST['group_id']) ? intval($_POST['group_id']) : -1; $gids = user_group_info($on_behalf_of ? null : $user_id, $course_id); } else { $group_id = 0; } // If submission type is Online Text if($row->submission_type){ $filename = ''; $file_name = ''; $success_msgs[] = $langUploadSuccess; } else { // If submission type is File if ($row->group_submissions) { $local_name = isset($gids[$group_id]) ? greek_to_latin($gids[$group_id]) : ''; } else { $student_name = trim(uid_to_name($user_id)); $local_name = !empty($student_name)? $student_name : uid_to_name($user_id, 'username'); $am = Database::get()->querySingle("SELECT am FROM user WHERE id = ?d", $user_id)->am; if (!empty($am)) { $local_name .= $am; } $local_name = greek_to_latin($local_name); } $local_name = replace_dangerous_char($local_name); if (isset($on_behalf_of) and !isset($_FILES)) { $_FILES['userfile']['name'] = ''; $_FILES['userfile']['tmp_name'] = ''; $no_files = true; } else { $no_files = false; } $file_name = $_FILES['userfile']['name']; validateUploadedFile($file_name, 2); $secret = work_secret($row->id); $ext = get_file_extension($file_name); $filename = "$secret/$local_name" . (empty($ext) ? '' : '.' . $ext); if ($no_files or move_uploaded_file($_FILES['userfile']['tmp_name'], "$workPath/$filename")) { if ($no_files) { $filename = ''; } else { @chmod("$workPath/$filename", 0644); } $success_msgs[] = $langUploadSuccess; } else { $error_msgs[] = $langUploadError; Session::Messages($error_msgs, 'alert-danger'); redirect_to_home_page("modules/work/index.php?course=$course_code&id=$id"); } } $submit_ip = $_SERVER['REMOTE_ADDR']; $submission_text = isset($_POST['submission_text']) ? purify($_POST['submission_text']) : NULL; if (isset($on_behalf_of)) { if ($row->group_submissions) { $stud_comments = sprintf($langOnBehalfOfGroupComment, uid_to_name($uid), $gids[$group_id]); } else { $stud_comments = sprintf($langOnBehalfOfUserComment, uid_to_name($uid), uid_to_name($user_id)); } $grade_comments = $_POST['stud_comments']; $grade_valid = filter_input(INPUT_POST, 'grade', FILTER_VALIDATE_FLOAT); (isset($_POST['grade']) && $grade_valid!== false) ? $grade = $grade_valid : $grade = NULL; $grade_ip = $submit_ip; } else { if ($row->group_submissions) { if (array_key_exists($group_id, $gids)) { $del_submission_msg = delete_submissions_by_uid(-1, $group_id, $row->id); if (!empty($del_submission_msg)) { $success_msgs[] = $del_submission_msg; } } } else { $del_submission_msg = delete_submissions_by_uid($user_id, -1, $row->id); if (!empty($del_submission_msg)) { $success_msgs[] = $del_submission_msg; } } $stud_comments = $_POST['stud_comments']; $grade = NULL; $grade_comments = $grade_ip = ""; } if (!$row->group_submissions || array_key_exists($group_id, $gids)) { $data = array( $user_id, $row->id, $submit_ip, $filename, $file_name, $submission_text, $stud_comments, $grade, $grade_comments, $grade_ip, $group_id ); $sid = Database::get()->query("INSERT INTO assignment_submit (uid, assignment_id, submission_date, submission_ip, file_path, file_name, submission_text, comments, grade, grade_comments, grade_submission_ip, grade_submission_date, group_id) VALUES (?d, ?d, NOW(), ?s, ?s, ?s, ?s, ?s, ?f, ?s, ?s, NOW(), ?d)", $data)->lastInsertID; Log::record($course_id, MODULE_ID_ASSIGN, LOG_INSERT, array('id' => $sid, 'title' => $row->title, 'assignment_id' => $row->id, 'filepath' => $filename, 'filename' => $file_name, 'comments' => $stud_comments, 'group_id' => $group_id)); if ($row->group_submissions) { $group_id = Database::get()->querySingle("SELECT group_id FROM assignment_submit WHERE id = ?d", $sid)->group_id; $user_ids = Database::get()->queryArray("SELECT user_id FROM group_members WHERE group_id = ?d", $group_id); foreach ($user_ids as $user_id) { update_attendance_book($user_id, $row->id, GRADEBOOK_ACTIVITY_ASSIGNMENT); update_gradebook_book($user_id, $row->id, $grade/$row->max_grade, GRADEBOOK_ACTIVITY_ASSIGNMENT); } } else { $quserid = Database::get()->querySingle("SELECT uid FROM assignment_submit WHERE id = ?d", $sid)->uid; // update attendance book as well update_attendance_book($quserid, $row->id, GRADEBOOK_ACTIVITY_ASSIGNMENT); //update gradebook if needed update_gradebook_book($quserid, $id, $grade/$row->max_grade, GRADEBOOK_ACTIVITY_ASSIGNMENT); } if ($on_behalf_of and isset($_POST['email'])) { $email_grade = $_POST['grade']; $email_comments = "\n$auto_comments\n\n" . $_POST['stud_comments']; grade_email_notify($row->id, $sid, $email_grade, $email_comments); } } // Auto-judge: Send file to hackearth if(AutojudgeApp::getAutojudge()->isEnabled()) { if ($auto_judge && $ext === $langExt[$lang]) { $content = file_get_contents("$workPath/$filename"); // Run each scenario and count how many passed $auto_judge_scenarios_output = array( array( 'student_output'=> '', 'passed'=> 0, ) ); $passed = 0; $i = 0; $partial = 0; $errorsComment = ''; $weight_sum = 0; foreach($auto_judge_scenarios as $curScenario) { $input = new AutoJudgeConnectorInput(); $input->input = $curScenario['input']; $input->code = $content; $input->lang = $lang; $result = $connector->compile($input); // Check if we have compilation errors. if ($result->compileStatus !== $result::COMPILE_STATUS_OK) { // Write down the error message. $num = $i+1; $errorsComment = $result->compileStatus." ".$result->output."<br />"; $auto_judge_scenarios_output[$i]['passed'] = 0; } else { // Get all needed values to run the assertion. $auto_judge_scenarios_output[$i]['student_output'] = $result->output; $scenarioOutputExpectation = trim($curScenario['output']); $scenarionAssertion = $curScenario['assertion']; // Do it now. $assertionResult = doScenarioAssertion( $scenarionAssertion, $auto_judge_scenarios_output[$i]['student_output'], $scenarioOutputExpectation ); // Check if assertion passed. if ($assertionResult) { $passed++; $auto_judge_scenarios_output[$i]['passed'] = 1; $partial += $curScenario['weight']; } else { $num = $i+1; $auto_judge_scenarios_output[$i]['passed'] = 0; } } $weight_sum += $curScenario['weight']; $i++; } // 3 decimal digits precision $grade = round($partial / $weight_sum * $max_grade, 3); // allow an error of 0.001 if($max_grade - $grade <= 0.001) $grade = $max_grade; // Add the output as a comment $comment = $langAutoJudgeScenariosPassed.': '.$passed.'/'.count($auto_judge_scenarios); rtrim($errorsComment, '<br />'); if ($errorsComment !== '') { $comment .= '<br /><br />'.$errorsComment; } submit_grade_comments(array( 'assignment' => $id, 'submission' => $sid, 'grade' => $grade, 'comments' => $comment, 'email' => false, 'auto_judge_scenarios_output' => $auto_judge_scenarios_output, 'preventUiAlterations' => true, )); } else if ($auto_judge && $ext !== $langExt[$lang]) { if($lang == null) { die('Auto Judge is enabled but no language is selected'); } if($langExt[$lang] == null) { die('An unsupported language was selected. Perhaps platform-wide auto judge settings have been changed?'); } submit_grade_comments($id, $sid, 0, sprintf($langAutoJudgeInvalidFileType, $langExt[$lang], $ext), false, null, true); } } // End Auto-judge Session::Messages($success_msgs, 'alert-success'); redirect_to_home_page("modules/work/index.php?course=$course_code&id=$id"); } else { // not submit_ok Session::Messages($langExerciseNotPermit); redirect_to_home_page("modules/work/index.php?course=$course_code"); } }