Ejemplo n.º 1
0
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}&amp;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}&amp;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>";
    }
}
Ejemplo n.º 2
0
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");
    }
}