Línea 51... |
Línea 51... |
51 |
* @copyright 2008 Tim Hunt
|
51 |
* @copyright 2008 Tim Hunt
|
52 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
52 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
53 |
*/
|
53 |
*/
|
54 |
class quiz_attempt {
|
54 |
class quiz_attempt {
|
Línea -... |
Línea 55... |
- |
|
55 |
|
- |
|
56 |
/** @var string to identify the "not started" state, when an attempt has been pre-generated. */
|
55 |
|
57 |
const NOT_STARTED = 'notstarted';
|
56 |
/** @var string to identify the in progress state. */
|
58 |
/** @var string to identify the in progress state. */
|
57 |
const IN_PROGRESS = 'inprogress';
|
59 |
const IN_PROGRESS = 'inprogress';
|
58 |
/** @var string to identify the overdue state. */
|
60 |
/** @var string to identify the overdue state. */
|
- |
|
61 |
const OVERDUE = 'overdue';
|
- |
|
62 |
/** @var string to identify the submitted state, when an attempt is awaiting grading. */
|
59 |
const OVERDUE = 'overdue';
|
63 |
const SUBMITTED = 'submitted';
|
60 |
/** @var string to identify the finished state. */
|
64 |
/** @var string to identify the finished state. */
|
61 |
const FINISHED = 'finished';
|
65 |
const FINISHED = 'finished';
|
62 |
/** @var string to identify the abandoned state. */
|
66 |
/** @var string to identify the abandoned state. */
|
Línea 1646... |
Línea 1650... |
1646 |
|
1650 |
|
1647 |
// Otherwise, we were in quiz_attempt::IN_PROGRESS, and time has now expired.
|
1651 |
// Otherwise, we were in quiz_attempt::IN_PROGRESS, and time has now expired.
|
1648 |
// Transition to the appropriate state.
|
1652 |
// Transition to the appropriate state.
|
1649 |
switch ($this->quizobj->get_quiz()->overduehandling) {
|
1653 |
switch ($this->quizobj->get_quiz()->overduehandling) {
|
1650 |
case 'autosubmit':
|
1654 |
case 'autosubmit':
|
- |
|
1655 |
$this->process_submit($timestamp, false, $studentisonline ? $timestamp : $timeclose, $studentisonline);
|
1651 |
$this->process_finish($timestamp, false, $studentisonline ? $timestamp : $timeclose, $studentisonline);
|
1656 |
$this->process_grade_submission($studentisonline ? $timestamp : $timeclose);
|
Línea 1652... |
Línea 1657... |
1652 |
return;
|
1657 |
return;
|
1653 |
|
1658 |
|
1654 |
case 'graceperiod':
|
1659 |
case 'graceperiod':
|
Línea 1803... |
Línea 1808... |
1803 |
* @param bool $processsubmitted if true, and question responses in the current
|
1808 |
* @param bool $processsubmitted if true, and question responses in the current
|
1804 |
* POST request are stored to be graded, before the attempt is finished.
|
1809 |
* POST request are stored to be graded, before the attempt is finished.
|
1805 |
* @param ?int $timefinish if set, use this as the finish time for the attempt.
|
1810 |
* @param ?int $timefinish if set, use this as the finish time for the attempt.
|
1806 |
* (otherwise use $timestamp as the finish time as well).
|
1811 |
* (otherwise use $timestamp as the finish time as well).
|
1807 |
* @param bool $studentisonline is the student currently interacting with Moodle?
|
1812 |
* @param bool $studentisonline is the student currently interacting with Moodle?
|
- |
|
1813 |
* @deprecated since Moodle 5.0 MDL-68806 use process_submit() and process_grade_submission() instead
|
- |
|
1814 |
* @todo Final deprecation in Moodle 6.0 MDL-80956
|
1808 |
*/
|
1815 |
*/
|
1809 |
public function process_finish($timestamp, $processsubmitted, $timefinish = null, $studentisonline = false) {
|
1816 |
public function process_finish($timestamp, $processsubmitted, $timefinish = null, $studentisonline = false) {
|
- |
|
1817 |
debugging('quiz_attempt::process_finish is deprecated. Please use quiz_attempt::process_submit to store ' .
|
- |
|
1818 |
'answers and mark an attempt submitted, and quiz_attempt::process_grade_submission to do automatic grading.');
|
- |
|
1819 |
$this->process_submit($timestamp, $processsubmitted, $timefinish, $studentisonline);
|
- |
|
1820 |
$this->process_grade_submission($timefinish ?? $timestamp);
|
- |
|
1821 |
}
|
- |
|
1822 |
|
- |
|
1823 |
/**
|
- |
|
1824 |
* Submit the attempt.
|
- |
|
1825 |
*
|
- |
|
1826 |
* The separate $timefinish argument should be used when the quiz attempt
|
- |
|
1827 |
* is being processed asynchronously (for example when cron is submitting
|
- |
|
1828 |
* attempts where the time has expired).
|
- |
|
1829 |
*
|
- |
|
1830 |
* @param int $timestamp the time to record as last modified time.
|
- |
|
1831 |
* @param bool $processsubmitted if true, and question responses in the current
|
- |
|
1832 |
* POST request are stored to be graded, before the attempt is finished.
|
- |
|
1833 |
* @param ?int $timefinish if set, use this as the finish time for the attempt.
|
- |
|
1834 |
* (otherwise use $timestamp as the finish time as well).
|
- |
|
1835 |
* @param bool $studentisonline is the student currently interacting with Moodle?
|
- |
|
1836 |
*/
|
- |
|
1837 |
public function process_submit(
|
- |
|
1838 |
int $timestamp,
|
- |
|
1839 |
bool $processsubmitted,
|
- |
|
1840 |
?int $timefinish = null,
|
- |
|
1841 |
bool $studentisonline = false
|
- |
|
1842 |
): void {
|
1810 |
global $DB;
|
1843 |
global $DB;
|
Línea 1811... |
Línea 1844... |
1811 |
|
1844 |
|
Línea 1812... |
Línea 1845... |
1812 |
$transaction = $DB->start_delegated_transaction();
|
1845 |
$transaction = $DB->start_delegated_transaction();
|
1813 |
|
1846 |
|
1814 |
if ($processsubmitted) {
|
1847 |
if ($processsubmitted) {
|
1815 |
$this->quba->process_all_actions($timestamp);
|
- |
|
Línea 1816... |
Línea 1848... |
1816 |
}
|
1848 |
$this->quba->process_all_actions($timestamp);
|
Línea 1817... |
Línea 1849... |
1817 |
$this->quba->finish_all_questions($timestamp);
|
1849 |
}
|
Línea 1818... |
Línea 1850... |
1818 |
|
1850 |
|
1819 |
question_engine::save_questions_usage_by_activity($this->quba);
|
1851 |
question_engine::save_questions_usage_by_activity($this->quba);
|
- |
|
1852 |
|
- |
|
1853 |
$originalattempt = clone $this->attempt;
|
- |
|
1854 |
|
- |
|
1855 |
$this->attempt->timemodified = $timestamp;
|
- |
|
1856 |
$this->attempt->timefinish = $timefinish ?? $timestamp;
|
- |
|
1857 |
$this->attempt->state = self::SUBMITTED;
|
- |
|
1858 |
$this->attempt->timecheckstate = null;
|
- |
|
1859 |
|
- |
|
1860 |
$DB->update_record('quiz_attempts', $this->attempt);
|
- |
|
1861 |
|
- |
|
1862 |
if (!$this->is_preview()) {
|
- |
|
1863 |
// Trigger event.
|
- |
|
1864 |
$this->fire_state_transition_event('\mod_quiz\event\attempt_submitted', $timestamp, $studentisonline);
|
- |
|
1865 |
\core\hook\manager::get_instance()->dispatch(new attempt_state_changed($originalattempt, $this->attempt));
|
- |
|
1866 |
}
|
- |
|
1867 |
|
- |
|
1868 |
$transaction->allow_commit();
|
- |
|
1869 |
}
|
- |
|
1870 |
|
- |
|
1871 |
/**
|
- |
|
1872 |
* Perform automatic grading for a submitted attempt.
|
- |
|
1873 |
*
|
- |
|
1874 |
* @param int $timestamp the time to record as last modified time.
|
- |
|
1875 |
*/
|
- |
|
1876 |
public function process_grade_submission(int $timestamp): void {
|
- |
|
1877 |
global $DB;
|
- |
|
1878 |
|
- |
|
1879 |
$transaction = $DB->start_delegated_transaction();
|
- |
|
1880 |
$this->quba->finish_all_questions($timestamp);
|
- |
|
1881 |
question_engine::save_questions_usage_by_activity($this->quba);
|
1820 |
|
1882 |
|
1821 |
$originalattempt = clone $this->attempt;
|
1883 |
$originalattempt = clone $this->attempt;
|
1822 |
|
- |
|
1823 |
$this->attempt->timemodified = $timestamp;
|
- |
|
Línea -... |
Línea 1884... |
- |
|
1884 |
|
1824 |
$this->attempt->timefinish = $timefinish ?? $timestamp;
|
1885 |
$this->attempt->timemodified = $timestamp;
|
1825 |
$this->attempt->sumgrades = $this->quba->get_total_mark();
|
1886 |
|
1826 |
$this->attempt->state = self::FINISHED;
|
1887 |
$this->attempt->sumgrades = $this->quba->get_total_mark();
|
1827 |
$this->attempt->timecheckstate = null;
|
1888 |
$this->attempt->state = self::FINISHED;
|
1828 |
$this->attempt->gradednotificationsenttime = null;
|
1889 |
|
Línea 1829... |
Línea 1890... |
1829 |
|
1890 |
if (
|
Línea 1830... |
Línea 1891... |
1830 |
if (!$this->requires_manual_grading() ||
|
1891 |
!$this->requires_manual_grading() ||
|
1831 |
!has_capability('mod/quiz:emailnotifyattemptgraded', $this->get_quizobj()->get_context(),
|
1892 |
!has_capability('mod/quiz:emailnotifyattemptgraded', $this->get_quizobj()->get_context(), $this->get_userid())
|
Línea 1832... |
Línea 1893... |
1832 |
$this->get_userid())) {
|
1893 |
) {
|
1833 |
$this->attempt->gradednotificationsenttime = $this->attempt->timefinish;
|
1894 |
$this->attempt->gradednotificationsenttime = $timestamp;
|
Línea 1834... |
Línea 1895... |
1834 |
}
|
1895 |
}
|
1835 |
|
1896 |
|
1836 |
$DB->update_record('quiz_attempts', $this->attempt);
|
1897 |
$DB->update_record('quiz_attempts', $this->attempt);
|
1837 |
|
1898 |
|
Línea 1945... |
Línea 2006... |
1945 |
$this->fire_state_transition_event('\mod_quiz\event\attempt_reopened', $timestamp, false);
|
2006 |
$this->fire_state_transition_event('\mod_quiz\event\attempt_reopened', $timestamp, false);
|
Línea 1946... |
Línea 2007... |
1946 |
|
2007 |
|
1947 |
di::get(hook\manager::class)->dispatch(new attempt_state_changed($originalattempt, $this->attempt));
|
2008 |
di::get(hook\manager::class)->dispatch(new attempt_state_changed($originalattempt, $this->attempt));
|
1948 |
$timeclose = $this->get_access_manager($timestamp)->get_end_time($this->attempt);
|
2009 |
$timeclose = $this->get_access_manager($timestamp)->get_end_time($this->attempt);
|
1949 |
if ($timeclose && $timestamp > $timeclose) {
|
2010 |
if ($timeclose && $timestamp > $timeclose) {
|
- |
|
2011 |
$this->process_submit($timestamp, false, $timeclose);
|
1950 |
$this->process_finish($timestamp, false, $timeclose);
|
2012 |
$this->process_grade_submission($timeclose);
|
Línea 1951... |
Línea 2013... |
1951 |
}
|
2013 |
}
|
1952 |
|
2014 |
|
Línea 2156... |
Línea 2218... |
2156 |
} else {
|
2218 |
} else {
|
2157 |
// But, if there is no grade period, and the final responses were too
|
2219 |
// But, if there is no grade period, and the final responses were too
|
2158 |
// late to be processed, record the close time, to reduce confusion.
|
2220 |
// late to be processed, record the close time, to reduce confusion.
|
2159 |
$finishtime = $timeclose;
|
2221 |
$finishtime = $timeclose;
|
2160 |
}
|
2222 |
}
|
2161 |
$this->process_finish($timenow, !$toolate, $finishtime, true);
|
2223 |
$this->process_submit($timenow, !$toolate, $finishtime, true);
|
- |
|
2224 |
$this->process_grade_submission($finishtime);
|
2162 |
}
|
2225 |
}
|
Línea 2163... |
Línea 2226... |
2163 |
|
2226 |
|
2164 |
} catch (question_out_of_sequence_exception $e) {
|
2227 |
} catch (question_out_of_sequence_exception $e) {
|
2165 |
throw new moodle_exception('submissionoutofsequencefriendlymessage', 'question',
|
2228 |
throw new moodle_exception('submissionoutofsequencefriendlymessage', 'question',
|