| 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 | /**
 | 
        
           |  |  | 18 |  * Process ajax requests
 | 
        
           |  |  | 19 |  *
 | 
        
           |  |  | 20 |  * @package assignfeedback_editpdf
 | 
        
           |  |  | 21 |  * @copyright  2012 Davo Smith
 | 
        
           |  |  | 22 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 23 |  */
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 | use \assignfeedback_editpdf\document_services;
 | 
        
           |  |  | 26 | use \assignfeedback_editpdf\combined_document;
 | 
        
           |  |  | 27 | use \assignfeedback_editpdf\page_editor;
 | 
        
           |  |  | 28 | use \assignfeedback_editpdf\comments_quick_list;
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 | define('AJAX_SCRIPT', true);
 | 
        
           |  |  | 31 |   | 
        
           |  |  | 32 | require('../../../../config.php');
 | 
        
           |  |  | 33 | require_once($CFG->dirroot . '/mod/assign/locallib.php');
 | 
        
           |  |  | 34 |   | 
        
           |  |  | 35 | require_sesskey();
 | 
        
           |  |  | 36 |   | 
        
           |  |  | 37 | $action = optional_param('action', '', PARAM_ALPHANUM);
 | 
        
           |  |  | 38 | $assignmentid = required_param('assignmentid', PARAM_INT);
 | 
        
           |  |  | 39 | $userid = required_param('userid', PARAM_INT);
 | 
        
           |  |  | 40 | $attemptnumber = required_param('attemptnumber', PARAM_INT);
 | 
        
           |  |  | 41 | $readonly = optional_param('readonly', false, PARAM_BOOL);
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 | $cm = \get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
 | 
        
           |  |  | 44 | $context = \context_module::instance($cm->id);
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 | $assignment = new \assign($context, null, null);
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 | require_login($assignment->get_course(), false, $cm);
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 | if (!$assignment->can_view_submission($userid)) {
 | 
        
           |  |  | 51 |     throw new \moodle_exception('nopermission');
 | 
        
           |  |  | 52 | }
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 | if ($action === 'pollconversions') {
 | 
        
           |  |  | 55 |     // Poll conversions does not require session lock.
 | 
        
           |  |  | 56 |     \core\session\manager::write_close();
 | 
        
           |  |  | 57 |   | 
        
           |  |  | 58 |     $draft = true;
 | 
        
           |  |  | 59 |     if (!has_capability('mod/assign:grade', $context)) {
 | 
        
           |  |  | 60 |         // A student always sees the readonly version.
 | 
        
           |  |  | 61 |         $readonly = true;
 | 
        
           |  |  | 62 |         $draft = false;
 | 
        
           |  |  | 63 |         require_capability('mod/assign:submit', $context);
 | 
        
           |  |  | 64 |     }
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 |     if ($readonly) {
 | 
        
           |  |  | 67 |         // Whoever is viewing the readonly version should not use the drafts, but the actual annotations.
 | 
        
           |  |  | 68 |         $draft = false;
 | 
        
           |  |  | 69 |     }
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 |     // Get a lock for the PDF/Image conversion of the assignment files.
 | 
        
           |  |  | 72 |     $lockfactory = \core\lock\lock_config::get_lock_factory('assignfeedback_editpdf_pollconversions');
 | 
        
           |  |  | 73 |     $resource = "user:{$userid},assignmentid:{$assignmentid},attemptnumber:{$attemptnumber}";
 | 
        
           |  |  | 74 |     $lock = $lockfactory->get_lock($resource, 0);
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 |     // Could not get lock, send back JSON to poll again.
 | 
        
           |  |  | 77 |     if (!$lock) {
 | 
        
           |  |  | 78 |         echo json_encode([
 | 
        
           |  |  | 79 |             'status' => 0
 | 
        
           |  |  | 80 |         ]);
 | 
        
           |  |  | 81 |         die();
 | 
        
           |  |  | 82 |     }
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |     // Obtained lock, now process the assignment conversion.
 | 
        
           |  |  | 85 |     try {
 | 
        
           |  |  | 86 |         $response = (object) [
 | 
        
           |  |  | 87 |             'status' => -1,
 | 
        
           |  |  | 88 |             'filecount' => 0,
 | 
        
           |  |  | 89 |             'pagecount' => 0,
 | 
        
           |  |  | 90 |             'pageready' => 0,
 | 
        
           |  |  | 91 |             'partial' => false,
 | 
        
           |  |  | 92 |             'pages' => [],
 | 
        
           |  |  | 93 |         ];
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 |         $combineddocument = document_services::get_combined_document_for_attempt($assignment, $userid, $attemptnumber);
 | 
        
           |  |  | 96 |         $response->status = $combineddocument->get_status();
 | 
        
           |  |  | 97 |         $response->filecount = $combineddocument->get_document_count();
 | 
        
           |  |  | 98 |   | 
        
           |  |  | 99 |         $readystatuslist = [combined_document::STATUS_READY, combined_document::STATUS_READY_PARTIAL];
 | 
        
           |  |  | 100 |         $completestatuslist = [combined_document::STATUS_COMPLETE, combined_document::STATUS_FAILED];
 | 
        
           |  |  | 101 |   | 
        
           |  |  | 102 |         if (in_array($response->status, $readystatuslist)) {
 | 
        
           |  |  | 103 |             // It seems that the files for this submission haven't been combined in cron yet.
 | 
        
           |  |  | 104 |             // Try to combine them in the user session.
 | 
        
           |  |  | 105 |             $combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
 | 
        
           |  |  | 106 |             $response->status = $combineddocument->get_status();
 | 
        
           |  |  | 107 |             $response->filecount = $combineddocument->get_document_count();
 | 
        
           |  |  | 108 |         }
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 |         if (in_array($response->status, $completestatuslist)) {
 | 
        
           |  |  | 111 |             $pages = document_services::get_page_images_for_attempt($assignment,
 | 
        
           |  |  | 112 |                                                                     $userid,
 | 
        
           |  |  | 113 |                                                                     $attemptnumber,
 | 
        
           |  |  | 114 |                                                                     $readonly);
 | 
        
           |  |  | 115 |   | 
        
           |  |  | 116 |             $response->pagecount = $combineddocument->get_page_count();
 | 
        
           |  |  | 117 |   | 
        
           |  |  | 118 |             $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |             // The readonly files are stored in a different file area.
 | 
        
           |  |  | 121 |             $filearea = document_services::PAGE_IMAGE_FILEAREA;
 | 
        
           |  |  | 122 |             if ($readonly) {
 | 
        
           |  |  | 123 |                 $filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA;
 | 
        
           |  |  | 124 |             }
 | 
        
           |  |  | 125 |             $response->partial = $combineddocument->is_partial_conversion();
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 |             foreach ($pages as $id => $pagefile) {
 | 
        
           |  |  | 128 |                 $index = count($response->pages);
 | 
        
           |  |  | 129 |                 $page = new stdClass();
 | 
        
           |  |  | 130 |                 $comments = page_editor::get_comments($grade->id, $index, $draft);
 | 
        
           |  |  | 131 |                 $page->url = moodle_url::make_pluginfile_url($context->id,
 | 
        
           |  |  | 132 |                                                             'assignfeedback_editpdf',
 | 
        
           |  |  | 133 |                                                             $filearea,
 | 
        
           |  |  | 134 |                                                             $grade->id,
 | 
        
           |  |  | 135 |                                                             '/',
 | 
        
           |  |  | 136 |                                                             $pagefile->get_filename())->out();
 | 
        
           |  |  | 137 |                 $page->comments = $comments;
 | 
        
           |  |  | 138 |                 if ($imageinfo = $pagefile->get_imageinfo()) {
 | 
        
           |  |  | 139 |                     $page->width = $imageinfo['width'];
 | 
        
           |  |  | 140 |                     $page->height = $imageinfo['height'];
 | 
        
           |  |  | 141 |                 } else {
 | 
        
           |  |  | 142 |                     $page->width = 0;
 | 
        
           |  |  | 143 |                     $page->height = 0;
 | 
        
           |  |  | 144 |                 }
 | 
        
           |  |  | 145 |                 $annotations = page_editor::get_annotations($grade->id, $index, $draft);
 | 
        
           |  |  | 146 |                 $page->annotations = $annotations;
 | 
        
           |  |  | 147 |                 $response->pages[] = $page;
 | 
        
           |  |  | 148 |             }
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 |             $component = 'assignfeedback_editpdf';
 | 
        
           |  |  | 151 |             $filearea = document_services::PAGE_IMAGE_FILEAREA;
 | 
        
           |  |  | 152 |             $filepath = '/';
 | 
        
           |  |  | 153 |             $fs = get_file_storage();
 | 
        
           |  |  | 154 |             $files = $fs->get_directory_files($context->id, $component, $filearea, $grade->id, $filepath);
 | 
        
           |  |  | 155 |             $response->pageready = count($files);
 | 
        
           |  |  | 156 |         }
 | 
        
           |  |  | 157 |     } catch (\Throwable $e) {
 | 
        
           |  |  | 158 |         // Release lock, and re-throw exception.
 | 
        
           |  |  | 159 |         $lock->release();
 | 
        
           |  |  | 160 |         throw $e;
 | 
        
           |  |  | 161 |     }
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |     echo json_encode($response);
 | 
        
           |  |  | 164 |     $lock->release();
 | 
        
           |  |  | 165 |     die();
 | 
        
           |  |  | 166 | } else if ($action == 'savepage') {
 | 
        
           |  |  | 167 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 168 |   | 
        
           |  |  | 169 |     $response = new stdClass();
 | 
        
           |  |  | 170 |     $response->errors = array();
 | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 |     $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |     $pagejson = required_param('page', PARAM_RAW);
 | 
        
           |  |  | 175 |     $page = json_decode($pagejson);
 | 
        
           |  |  | 176 |     $index = required_param('index', PARAM_INT);
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 |     $added = page_editor::set_comments($grade->id, $index, $page->comments);
 | 
        
           |  |  | 179 |     if ($added != count($page->comments)) {
 | 
        
           |  |  | 180 |         array_push($response->errors, get_string('couldnotsavepage', 'assignfeedback_editpdf', $index+1));
 | 
        
           |  |  | 181 |     }
 | 
        
           |  |  | 182 |     $added = page_editor::set_annotations($grade->id, $index, $page->annotations);
 | 
        
           |  |  | 183 |     if ($added != count($page->annotations)) {
 | 
        
           |  |  | 184 |         array_push($response->errors, get_string('couldnotsavepage', 'assignfeedback_editpdf', $index+1));
 | 
        
           |  |  | 185 |     }
 | 
        
           |  |  | 186 |     echo json_encode($response);
 | 
        
           |  |  | 187 |     die();
 | 
        
           |  |  | 188 |   | 
        
           |  |  | 189 | } else if ($action == 'generatepdf') {
 | 
        
           |  |  | 190 |   | 
        
           |  |  | 191 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 192 |     $response = new stdClass();
 | 
        
           |  |  | 193 |     $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 194 |     $file = document_services::generate_feedback_document($assignment, $userid, $attemptnumber);
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 |     $response->url = '';
 | 
        
           |  |  | 197 |     if ($file) {
 | 
        
           |  |  | 198 |         $url = moodle_url::make_pluginfile_url($assignment->get_context()->id,
 | 
        
           |  |  | 199 |                                                'assignfeedback_editpdf',
 | 
        
           |  |  | 200 |                                                document_services::FINAL_PDF_FILEAREA,
 | 
        
           |  |  | 201 |                                                $grade->id,
 | 
        
           |  |  | 202 |                                                '/',
 | 
        
           |  |  | 203 |                                                $file->get_filename(),
 | 
        
           |  |  | 204 |                                                false);
 | 
        
           |  |  | 205 |         $response->url = $url->out(true);
 | 
        
           |  |  | 206 |         $response->filename = $file->get_filename();
 | 
        
           |  |  | 207 |     }
 | 
        
           |  |  | 208 |   | 
        
           |  |  | 209 |     echo json_encode($response);
 | 
        
           |  |  | 210 |     die();
 | 
        
           |  |  | 211 | } else if ($action == 'loadquicklist') {
 | 
        
           |  |  | 212 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 |     $result = comments_quick_list::get_comments();
 | 
        
           |  |  | 215 |   | 
        
           |  |  | 216 |     echo json_encode($result);
 | 
        
           |  |  | 217 |     die();
 | 
        
           |  |  | 218 |   | 
        
           |  |  | 219 | } else if ($action == 'addtoquicklist') {
 | 
        
           |  |  | 220 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 221 |   | 
        
           |  |  | 222 |     $comment = required_param('commenttext', PARAM_RAW);
 | 
        
           |  |  | 223 |     $width = required_param('width', PARAM_INT);
 | 
        
           |  |  | 224 |     $colour = required_param('colour', PARAM_ALPHA);
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 |     $result = comments_quick_list::add_comment($comment, $width, $colour);
 | 
        
           |  |  | 227 |   | 
        
           |  |  | 228 |     echo json_encode($result);
 | 
        
           |  |  | 229 |     die();
 | 
        
           |  |  | 230 | } else if ($action == 'revertchanges') {
 | 
        
           |  |  | 231 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 |     $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |     $result = page_editor::revert_drafts($gradeid);
 | 
        
           |  |  | 236 |   | 
        
           |  |  | 237 |     echo json_encode($result);
 | 
        
           |  |  | 238 |     die();
 | 
        
           |  |  | 239 | } else if ($action == 'removefromquicklist') {
 | 
        
           |  |  | 240 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 241 |   | 
        
           |  |  | 242 |     $commentid = required_param('commentid', PARAM_INT);
 | 
        
           |  |  | 243 |   | 
        
           |  |  | 244 |     $result = comments_quick_list::remove_comment($commentid);
 | 
        
           |  |  | 245 |   | 
        
           |  |  | 246 |     echo json_encode($result);
 | 
        
           |  |  | 247 |     die();
 | 
        
           |  |  | 248 | } else if ($action == 'deletefeedbackdocument') {
 | 
        
           |  |  | 249 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 |     $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 252 |     $result = document_services::delete_feedback_document($assignment, $userid, $attemptnumber);
 | 
        
           |  |  | 253 |   | 
        
           |  |  | 254 |     $result = $result && page_editor::unrelease_drafts($grade->id);
 | 
        
           |  |  | 255 |     echo json_encode($result);
 | 
        
           |  |  | 256 |     die();
 | 
        
           |  |  | 257 | } else if ($action == 'rotatepage') {
 | 
        
           |  |  | 258 |     require_capability('mod/assign:grade', $context);
 | 
        
           |  |  | 259 |     $response = new stdClass();
 | 
        
           |  |  | 260 |     $index = required_param('index', PARAM_INT);
 | 
        
           |  |  | 261 |     $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
 | 
        
           |  |  | 262 |     $rotateleft = required_param('rotateleft', PARAM_BOOL);
 | 
        
           |  |  | 263 |     $filearea = document_services::PAGE_IMAGE_FILEAREA;
 | 
        
           |  |  | 264 |     $pagefile = document_services::rotate_page($assignment, $userid, $attemptnumber, $index, $rotateleft);
 | 
        
           |  |  | 265 |     $page = new stdClass();
 | 
        
           |  |  | 266 |     $page->url = moodle_url::make_pluginfile_url($context->id, document_services::COMPONENT, $filearea,
 | 
        
           |  |  | 267 |         $grade->id, '/', $pagefile->get_filename())->out();
 | 
        
           |  |  | 268 |     if ($imageinfo = $pagefile->get_imageinfo()) {
 | 
        
           |  |  | 269 |         $page->width = $imageinfo['width'];
 | 
        
           |  |  | 270 |         $page->height = $imageinfo['height'];
 | 
        
           |  |  | 271 |     } else {
 | 
        
           |  |  | 272 |         $page->width = 0;
 | 
        
           |  |  | 273 |         $page->height = 0;
 | 
        
           |  |  | 274 |     }
 | 
        
           |  |  | 275 |     $response = (object)['page' => $page];
 | 
        
           |  |  | 276 |     echo json_encode($response);
 | 
        
           |  |  | 277 |     die();
 | 
        
           |  |  | 278 | }
 | 
        
           |  |  | 279 |   |