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 assignfeedback_editpdf\task;
18
 
19
use core\task\adhoc_task;
20
use core\task\manager;
21
use assignfeedback_editpdf\document_services;
22
use assignfeedback_editpdf\combined_document;
23
use assignfeedback_editpdf\pdf;
24
use context_module;
25
use moodle_exception;
26
use assign;
27
 
28
/**
29
 * An adhoc task to convert submissions to pdf in the background.
30
 *
31
 * @copyright  2022 Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
32
 * @package    assignfeedback_editpdf
33
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
35
class convert_submission extends adhoc_task {
36
 
37
    /**
38
     * Run the task.
39
     */
40
    public function execute() {
41
        global $CFG, $DB;
42
        require_once($CFG->dirroot . '/mod/assign/locallib.php');
43
 
44
        $data = $this->get_custom_data();
45
 
46
        $submission = $DB->get_record('assign_submission', ['id' => $data->submissionid], '*', IGNORE_MISSING);
47
        if (!$submission) {
48
            mtrace('Submission no longer exists');
49
            return;
50
        }
51
 
52
        // Early exit if ghostscript isn't correctly configured.
53
        $result = pdf::test_gs_path(false);
54
        if ($result->status !== pdf::GSPATH_OK) {
55
            $statusstring = get_string('test_' . $result->status, 'assignfeedback_editpdf');
56
            throw new moodle_exception('pathtogserror', 'assignfeedback_editpdf', '', $statusstring, $result->status);
57
        }
58
 
59
        $cm = get_coursemodule_from_instance('assign', $submission->assignment, 0, false, MUST_EXIST);
60
        $context = context_module::instance($cm->id);
61
        $assign = new assign($context, null, null);
62
 
63
        if ($submission->userid) {
64
            $users = [$submission->userid];
65
        } else {
66
            $users = [];
67
            $members = $assign->get_submission_group_members($submission->groupid, true);
68
            foreach ($members as $member) {
69
                $users[] = $member->id;
70
            }
71
        }
72
 
73
        $conversionrequirespolling = false;
74
        foreach ($users as $userid) {
75
            mtrace('Converting submission for user id ' . $userid);
76
 
77
            // If the assignment is not vieweable, we should not try to convert the documents
78
            // for this submission, as it will cause the adhoc task to fail with a permission
79
            // error.
80
            //
81
            // Comments on MDL-56810 indicate that submission conversion should not be attempted
82
            // if the submission is not viewable due to the user not being enrolled.
83
            if (!$assign->can_view_submission($userid)) {
84
                continue;
85
            }
86
            // Note: Before MDL-71468, the scheduled task version of this
87
            // task would stop attempting to poll the conversion after a
88
            // configured number of attempts were made to poll it, see:
89
            //
90
            // mod/assign/feedback/editpdf/classes/task/convert_submissions.php@MOODLE_400_STABLE
91
            //
92
            // This means that currently this adhoc task, if it fails, will retry forever. But
93
            // the fail-delay mechanism will ensure that it eventually only tries once per day.
94
            //
95
            // See MDL-75457 for details on re-implementing the conversionattemptlimit.
96
            //
97
            // Also note: This code must not be in a try/catch - an exception needs to be thrown to
98
            // allow the task API to mark the task as failed and update its faildelay. Using
99
            // manager::adhoc_task_failed in the catch block will not work, as the task API
100
            // will later assume the task completed successfully (as no exception was thrown) and
101
            // complete it (removing it from the adhoc task queue).
102
            $combineddocument = document_services::get_combined_pdf_for_attempt($assign, $userid, $data->submissionattempt);
103
            switch ($combineddocument->get_status()) {
104
                case combined_document::STATUS_READY:
105
                case combined_document::STATUS_READY_PARTIAL:
106
                case combined_document::STATUS_PENDING_INPUT:
107
                    // The document has not been converted yet or is somehow still ready.
108
                    $conversionrequirespolling = true;
109
                    continue 2;
110
                case combined_document::STATUS_FAILED:
111
                    // Although STATUS_FAILED indicates a "permanent error" it should be possible
112
                    // in some cases to fix the underlying problem, allowing the conversion to
113
                    // complete. So we throw an exception here, allowing the adhoc task to retry.
114
                    //
115
                    // Currently this can result in the task trying indefinitely (although it will
116
                    // settle on trying once per day due to the faildelay exponential backoff)
117
                    // however once the conversionattepmtlimit is re-implemented in MDL-75457 the
118
                    // task will eventually get dropped.
119
                    throw new \moodle_exception('documentcombinationfailed');
120
            }
121
 
122
            document_services::get_page_images_for_attempt($assign, $userid, $data->submissionattempt, false);
123
            document_services::get_page_images_for_attempt($assign, $userid, $data->submissionattempt, true);
124
        }
125
 
126
        if ($conversionrequirespolling) {
127
            mtrace('Conversion still in progress. Requeueing self to check again.');
128
            $task = new self;
129
            $task->set_custom_data($data);
130
            $task->set_next_run_time(time() + MINSECS);
131
            manager::queue_adhoc_task($task);
132
        } else {
133
            mtrace('The document has been successfully converted');
134
        }
135
    }
136
}