Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace quiz_statistics\task;
18
 
19
use core\dml\sql_join;
20
use mod_quiz\quiz_attempt;
21
use quiz_statistics_report;
22
 
23
defined('MOODLE_INTERNAL') || die();
24
 
25
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
26
require_once($CFG->dirroot . '/mod/quiz/report/statistics/statisticslib.php');
27
require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
28
require_once($CFG->dirroot . '/mod/quiz/report/statistics/report.php');
29
 
30
/**
31
 * Re-calculate question statistics.
32
 *
33
 * @package    quiz_statistics
34
 * @copyright  2022 Catalyst IT Australia Pty Ltd
35
 * @author     Nathan Nguyen <nathannguyen@catalyst-au.net>
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class recalculate extends \core\task\adhoc_task {
39
    /**
40
     * The time to delay queued runs by, to prevent repeated recalculations.
41
     */
42
    const DELAY = HOURSECS;
43
 
44
    /**
45
     * Create a new instance of the task.
46
     *
47
     * This sets the properties so that only one task will be queued at a time for a given quiz.
48
     *
49
     * @param int $quizid
50
     * @return recalculate
51
     */
52
    public static function instance(int $quizid): recalculate {
53
        $task = new self();
54
        $task->set_component('quiz_statistics');
55
        $task->set_custom_data((object)[
56
            'quizid' => $quizid,
57
        ]);
58
        return $task;
59
    }
60
 
61
 
62
    public function get_name(): string {
63
        return get_string('recalculatetask', 'quiz_statistics');
64
    }
65
 
66
    public function execute(): void {
67
        global $DB;
68
        $dateformat = get_string('strftimedatetimeshortaccurate', 'core_langconfig');
69
        $data = $this->get_custom_data();
70
        $quiz = $DB->get_record('quiz', ['id' => $data->quizid]);
71
        if (!$quiz) {
72
            mtrace('Could not find quiz with ID ' . $data->quizid . '.');
73
            return;
74
        }
75
        $course = $DB->get_record('course', ['id' => $quiz->course]);
76
        if (!$course) {
77
            mtrace('Could not find course with ID ' . $quiz->course . '.');
78
            return;
79
        }
80
        $attemptcount = $DB->count_records('quiz_attempts', ['quiz' => $data->quizid, 'state' => quiz_attempt::FINISHED]);
81
        if ($attemptcount === 0) {
82
            mtrace('Could not find any finished attempts for course with ID ' . $data->quizid . '.');
83
            return;
84
        }
85
 
86
        mtrace("Re-calculating statistics for quiz {$quiz->name} ({$quiz->id}) " .
87
            "from course {$course->shortname} ({$course->id}) with {$attemptcount} attempts, start time " .
88
            userdate(time(), $dateformat) . " ...");
89
 
90
        $qubaids = quiz_statistics_qubaids_condition(
91
            $quiz->id,
92
            new sql_join(),
93
            $quiz->grademethod
94
        );
95
 
96
        $report = new quiz_statistics_report();
97
        $report->clear_cached_data($qubaids);
98
        $report->calculate_questions_stats_for_question_bank($quiz->id);
99
        mtrace('    Calculations completed at ' . userdate(time(), $dateformat) . '.');
100
    }
101
 
102
    /**
103
     * Queue an instance of this task to happen after a delay.
104
     *
105
     * Multiple events may happen over a short period that require a recalculation. Rather than
106
     * run the recalculation each time, this will queue a single run of the task for a given quiz,
107
     * within the delay period.
108
     *
109
     * @param int $quizid The quiz to run the recalculation for.
110
     * @return bool true of the task was queued.
111
     */
112
    public static function queue_future_run(int $quizid): bool {
113
        $task = self::instance($quizid);
114
        $task->set_next_run_time(time() + self::DELAY);
115
        return \core\task\manager::queue_adhoc_task($task, true);
116
    }
117
}