Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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

   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   * This file contains the forms to create and edit an instance of this module
  19   *
  20   * @package assignfeedback_offline
  21   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
  26  
  27  /**
  28   * CSV Grade importer
  29   *
  30   * @package   assignfeedback_offline
  31   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  32   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class assignfeedback_offline_grade_importer {
  35  
  36      /** @var string $importid - unique id for this import operation - must be passed between requests */
  37      public $importid;
  38  
  39      /** @var csv_import_reader $csvreader - the csv importer class */
  40      private $csvreader;
  41  
  42      /** @var assignment $assignment - the assignment class */
  43      private $assignment;
  44  
  45      /** @var int $gradeindex the column index containing the grades */
  46      private $gradeindex = -1;
  47  
  48      /** @var int $idindex the column index containing the unique id  */
  49      private $idindex = -1;
  50  
  51      /** @var int $modifiedindex the column index containing the last modified time */
  52      private $modifiedindex = -1;
  53  
  54      /** @var array $validusers only the enrolled users with the correct capability in this course */
  55      private $validusers;
  56  
  57      /** @var array $feedbackcolumnindexes A lookup of column indexes for feedback plugin text import columns */
  58      private $feedbackcolumnindexes = array();
  59  
  60      /** @var string $encoding Encoding to use when reading the csv file. Defaults to utf-8. */
  61      private $encoding;
  62  
  63      /** @var string $separator How each bit of information is separated in the file. Defaults to comma separated. */
  64      private $separator;
  65  
  66      /**
  67       * Constructor
  68       *
  69       * @param string $importid A unique id for this import
  70       * @param assign $assignment The current assignment
  71       */
  72      public function __construct($importid, assign $assignment, $encoding = 'utf-8', $separator = 'comma') {
  73          $this->importid = $importid;
  74          $this->assignment = $assignment;
  75          $this->encoding = $encoding;
  76          $this->separator = $separator;
  77      }
  78  
  79      /**
  80       * Parse a csv file and save the content to a temp file
  81       * Should be called before init()
  82       *
  83       * @param string $csvdata The csv data
  84       * @return bool false is a failed import
  85       */
  86      public function parsecsv($csvdata) {
  87          $this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
  88          $this->csvreader->load_csv_content($csvdata, $this->encoding, $this->separator);
  89      }
  90  
  91      /**
  92       * Initialise the import reader and locate the column indexes.
  93       *
  94       * @return bool false is a failed import
  95       */
  96      public function init() {
  97          if ($this->csvreader == null) {
  98              $this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
  99          }
 100          $this->csvreader->init();
 101  
 102          $columns = $this->csvreader->get_columns();
 103  
 104          $strgrade = get_string('gradenoun');
 105          $strid = get_string('recordid', 'assign');
 106          $strmodified = get_string('lastmodifiedgrade', 'assign');
 107  
 108          foreach ($this->assignment->get_feedback_plugins() as $plugin) {
 109              if ($plugin->is_enabled() && $plugin->is_visible()) {
 110                  foreach ($plugin->get_editor_fields() as $field => $description) {
 111                      $this->feedbackcolumnindexes[$description] = array('plugin'=>$plugin,
 112                                                                         'field'=>$field,
 113                                                                         'description'=>$description);
 114                  }
 115              }
 116          }
 117  
 118          if ($columns) {
 119              foreach ($columns as $index => $column) {
 120                  if (isset($this->feedbackcolumnindexes[$column])) {
 121                      $this->feedbackcolumnindexes[$column]['index'] = $index;
 122                  }
 123                  if ($column == $strgrade) {
 124                      $this->gradeindex = $index;
 125                  }
 126                  if ($column == $strid) {
 127                      $this->idindex = $index;
 128                  }
 129                  if ($column == $strmodified) {
 130                      $this->modifiedindex = $index;
 131                  }
 132              }
 133          }
 134  
 135          if ($this->idindex < 0 || $this->gradeindex < 0 || $this->modifiedindex < 0) {
 136              return false;
 137          }
 138  
 139          $groupmode = groups_get_activity_groupmode($this->assignment->get_course_module());
 140          // All users.
 141          $groupid = 0;
 142          $groupname = '';
 143          if ($groupmode) {
 144              $groupid = groups_get_activity_group($this->assignment->get_course_module(), true);
 145              $groupname = groups_get_group_name($groupid).'-';
 146          }
 147          $this->validusers = $this->assignment->list_participants($groupid, false);
 148          return true;
 149      }
 150  
 151      /**
 152       * Return the encoding for this csv import.
 153       *
 154       * @return string The encoding for this csv import.
 155       */
 156      public function get_encoding() {
 157          return $this->encoding;
 158      }
 159  
 160      /**
 161       * Return the separator for this csv import.
 162       *
 163       * @return string The separator for this csv import.
 164       */
 165      public function get_separator() {
 166          return $this->separator;
 167      }
 168  
 169      /**
 170       * Get the next row of data from the csv file (only the columns we care about)
 171       *
 172       * @return stdClass or false The stdClass is an object containing user, grade and lastmodified
 173       */
 174      public function next() {
 175          global $DB;
 176          $result = new stdClass();
 177  
 178          while ($record = $this->csvreader->next()) {
 179              $idstr = $record[$this->idindex];
 180              // Strip the integer from the end of the participant string.
 181              $id = substr($idstr, strlen(get_string('hiddenuser', 'assign')));
 182              if ($userid = $this->assignment->get_user_id_for_uniqueid($id)) {
 183                  if (array_key_exists($userid, $this->validusers)) {
 184                      $result->grade = $record[$this->gradeindex];
 185                      $result->modified = strtotime($record[$this->modifiedindex]);
 186                      $result->user = $this->validusers[$userid];
 187                      $result->feedback = array();
 188                      foreach ($this->feedbackcolumnindexes as $description => $details) {
 189                          if (!empty($details['index'])) {
 190                              $details['value'] = $record[$details['index']];
 191                              $result->feedback[] = $details;
 192                          }
 193                      }
 194  
 195                      return $result;
 196                  }
 197              }
 198          }
 199  
 200          // If we got here the csvreader had no more rows.
 201          return false;
 202      }
 203  
 204      /**
 205       * Close the grade importer file and optionally delete any temp files
 206       *
 207       * @param bool $delete
 208       */
 209      public function close($delete) {
 210          $this->csvreader->close();
 211          if ($delete) {
 212              $this->csvreader->cleanup();
 213          }
 214      }
 215  }
 216