Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 39 and 311]

   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   * A scheduled task.
  19   *
  20   * @package    assignfeedback_editpdf
  21   * @copyright  2016 Damyon Wiese
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace assignfeedback_editpdf\task;
  25  
  26  use core\task\scheduled_task;
  27  use assignfeedback_editpdf\document_services;
  28  use assignfeedback_editpdf\combined_document;
  29  use context_module;
  30  use assign;
  31  
  32  /**
  33   * Simple task to convert submissions to pdf in the background.
  34   * @copyright  2016 Damyon Wiese
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class convert_submissions extends scheduled_task {
  38  
  39      /**
  40       * Get a descriptive name for this task (shown to admins).
  41       *
  42       * @return string
  43       */
  44      public function get_name() {
  45          return get_string('preparesubmissionsforannotation', 'assignfeedback_editpdf');
  46      }
  47  
  48      /**
  49       * Do the job.
  50       * Throw exceptions on errors (the job will be retried).
  51       */
  52      public function execute() {
  53          global $CFG, $DB;
  54  
  55          require_once($CFG->dirroot . '/mod/assign/locallib.php');
  56  
  57          // Conversion speed varies significantly and mostly depends on the documents content.
  58          // We don't want the task to get stuck forever trying to process the whole queue in one go,
  59          // so fetch 100 records only to make sure the task will be working for reasonable time.
  60          // With the task's default schedule, 100 records per run means the task is capable to process
  61          // 9600 conversions per day (100 * 4 * 24).
  62          $records = $DB->get_records('assignfeedback_editpdf_queue', [], '', '*', 0, 100);
  63  
  64          $assignmentcache = array();
  65  
  66          $conversionattemptlimit = !empty($CFG->conversionattemptlimit) ? $CFG->conversionattemptlimit : 3;
  67          foreach ($records as $record) {
  68              $submissionid = $record->submissionid;
  69              $submission = $DB->get_record('assign_submission', array('id' => $submissionid), '*', IGNORE_MISSING);
  70              if (!$submission || $record->attemptedconversions >= $conversionattemptlimit) {
  71                  // Submission no longer exists; or we've exceeded the conversion attempt limit.
  72                  $DB->delete_records('assignfeedback_editpdf_queue', array('id' => $record->id));
  73                  continue;
  74              }
  75  
  76              // Record that we're attempting the conversion ahead of time.
  77              // We can't do this afterwards as its possible for the conversion process to crash the script entirely.
  78              $DB->set_field('assignfeedback_editpdf_queue', 'attemptedconversions',
  79                      $record->attemptedconversions + 1, ['id' => $record->id]);
  80  
  81              $assignmentid = $submission->assignment;
  82              $attemptnumber = $record->submissionattempt;
  83  
  84              if (empty($assignmentcache[$assignmentid])) {
  85                  $cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
  86                  $context = context_module::instance($cm->id);
  87  
  88                  $assignment = new assign($context, null, null);
  89                  $assignmentcache[$assignmentid] = $assignment;
  90              } else {
  91                  $assignment = $assignmentcache[$assignmentid];
  92              }
  93  
  94              $users = array();
  95              if ($submission->userid) {
  96                  array_push($users, $submission->userid);
  97              } else {
  98                  $members = $assignment->get_submission_group_members($submission->groupid, true);
  99  
 100                  foreach ($members as $member) {
 101                      array_push($users, $member->id);
 102                  }
 103              }
 104  
 105              mtrace('Convert ' . count($users) . ' submission attempt(s) for assignment ' . $assignmentid);
 106              $conversionrequirespolling = false;
 107  
 108              foreach ($users as $userid) {
 109                  try {
 110                      $combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
 111                      switch ($combineddocument->get_status()) {
 112                          case combined_document::STATUS_READY:
 113                          case combined_document::STATUS_READY_PARTIAL:
 114                          case combined_document::STATUS_PENDING_INPUT:
 115                              // The document has not been converted yet or is somehow still ready.
 116                              $conversionrequirespolling = true;
 117                              continue 2;
 118                      }
 119                      document_services::get_page_images_for_attempt(
 120                              $assignment,
 121                              $userid,
 122                              $attemptnumber,
 123                              false
 124                          );
 125                      document_services::get_page_images_for_attempt(
 126                              $assignment,
 127                              $userid,
 128                              $attemptnumber,
 129                              true
 130                          );
 131                  } catch (\moodle_exception $e) {
 132                      mtrace('Conversion failed with error:' . $e->errorcode);
 133                  }
 134              }
 135  
 136              // Remove from queue.
 137              if (!$conversionrequirespolling) {
 138                  $DB->delete_records('assignfeedback_editpdf_queue', array('id' => $record->id));
 139              }
 140  
 141          }
 142      }
 143  
 144  }