Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 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 definition for the library class for file feedback plugin
  19   *
  20   *
  21   * @package   assignfeedback_file
  22   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use \mod_assign\output\assign_header;
  29  
  30  // File areas for file feedback assignment.
  31  define('ASSIGNFEEDBACK_FILE_FILEAREA', 'feedback_files');
  32  define('ASSIGNFEEDBACK_FILE_BATCH_FILEAREA', 'feedback_files_batch');
  33  define('ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA', 'feedback_files_import');
  34  define('ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES', 5);
  35  define('ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS', 5);
  36  define('ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME', 120);
  37  
  38  /**
  39   * Library class for file feedback plugin extending feedback plugin base class.
  40   *
  41   * @package   assignfeedback_file
  42   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  43   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  44   */
  45  class assign_feedback_file extends assign_feedback_plugin {
  46  
  47      /**
  48       * Get the name of the file feedback plugin.
  49       *
  50       * @return string
  51       */
  52      public function get_name() {
  53          return get_string('file', 'assignfeedback_file');
  54      }
  55  
  56      /**
  57       * Get file feedback information from the database.
  58       *
  59       * @param int $gradeid
  60       * @return mixed
  61       */
  62      public function get_file_feedback($gradeid) {
  63          global $DB;
  64          return $DB->get_record('assignfeedback_file', array('grade'=>$gradeid));
  65      }
  66  
  67      /**
  68       * File format options.
  69       *
  70       * @return array
  71       */
  72      private function get_file_options() {
  73          global $COURSE;
  74  
  75          $fileoptions = array('subdirs'=>1,
  76                               'maxbytes'=>$COURSE->maxbytes,
  77                               'accepted_types'=>'*',
  78                               'return_types'=>FILE_INTERNAL);
  79          return $fileoptions;
  80      }
  81  
  82      /**
  83       * Has the feedback file been modified?
  84       *
  85       * @param stdClass $grade Grade object.
  86       * @param stdClass $data Form data.
  87       * @return boolean True if the file area has been modified, else false.
  88       */
  89      public function is_feedback_modified(stdClass $grade, stdClass $data) {
  90          global $USER;
  91  
  92          $filekey = null;
  93          $draftareainfo = null;
  94          foreach ($data as $key => $value) {
  95              if (strpos($key, 'files_') === 0 && strpos($key, '_filemanager')) {
  96                  $filekey = $key;
  97              }
  98          }
  99          if (isset($filekey)) {
 100              $draftareainfo = file_get_draft_area_info($data->$filekey);
 101              $filecount = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA);
 102              if ($filecount != $draftareainfo['filecount']) {
 103                  return true;
 104              } else {
 105                  // We need to check that the files in the draft area are the same as in the file area.
 106                  $usercontext = context_user::instance($USER->id);
 107                  $fs = get_file_storage();
 108                  $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $data->$filekey, 'id', true);
 109                  $files = $fs->get_area_files($this->assignment->get_context()->id,
 110                                       'assignfeedback_file',
 111                                       ASSIGNFEEDBACK_FILE_FILEAREA,
 112                                       $grade->id,
 113                                       'id',
 114                                       false);
 115                  foreach ($files as $key => $file) {
 116                      // Flag for recording if we have a matching file.
 117                      $matchflag = false;
 118                      foreach ($draftfiles as $draftkey => $draftfile) {
 119                          if (!$file->is_directory()) {
 120                              // File name is the same, but it could be a different file with the same name.
 121                              if ($draftfile->get_filename() == $file->get_filename()) {
 122                                  // If the file name is the same but the content hash is different, or
 123                                  // The file path for the file has changed, then we have a modification.
 124                                  if ($draftfile->get_contenthash() != $file->get_contenthash() ||
 125                                          $draftfile->get_filepath() != $file->get_filepath()) {
 126                                      return true;
 127                                  }
 128                                  // These files match. Check the next file.
 129                                  $matchflag = true;
 130                                  // We have a match on the file name so we can move to the next file and not
 131                                  // proceed through the other draftfiles.
 132                                  break;
 133                              }
 134                          }
 135                      }
 136                      // If the file does not match then there has been a modification.
 137                      if (!$matchflag) {
 138                          return true;
 139                      }
 140                  }
 141              }
 142          }
 143          return false;
 144      }
 145  
 146      /**
 147       * Copy all the files from one file area to another.
 148       *
 149       * @param file_storage $fs - The source context id
 150       * @param int $fromcontextid - The source context id
 151       * @param string $fromcomponent - The source component
 152       * @param string $fromfilearea - The source filearea
 153       * @param int $fromitemid - The source item id
 154       * @param int $tocontextid - The destination context id
 155       * @param string $tocomponent - The destination component
 156       * @param string $tofilearea - The destination filearea
 157       * @param int $toitemid - The destination item id
 158       * @return boolean
 159       */
 160      private function copy_area_files(file_storage $fs,
 161                                       $fromcontextid,
 162                                       $fromcomponent,
 163                                       $fromfilearea,
 164                                       $fromitemid,
 165                                       $tocontextid,
 166                                       $tocomponent,
 167                                       $tofilearea,
 168                                       $toitemid) {
 169  
 170          $newfilerecord = new stdClass();
 171          $newfilerecord->contextid = $tocontextid;
 172          $newfilerecord->component = $tocomponent;
 173          $newfilerecord->filearea = $tofilearea;
 174          $newfilerecord->itemid = $toitemid;
 175  
 176          if ($files = $fs->get_area_files($fromcontextid, $fromcomponent, $fromfilearea, $fromitemid)) {
 177              foreach ($files as $file) {
 178                  if ($file->is_directory() and $file->get_filepath() === '/') {
 179                      // We need a way to mark the age of each draft area.
 180                      // By not copying the root dir we force it to be created
 181                      // automatically with current timestamp.
 182                      continue;
 183                  }
 184  
 185                  $existingfile = $fs->get_file(
 186                      $newfilerecord->contextid,
 187                      $newfilerecord->component,
 188                      $newfilerecord->filearea,
 189                      $newfilerecord->itemid,
 190                      $file->get_filepath(),
 191                      $file->get_filename()
 192                  );
 193                  if ($existingfile) {
 194                      // If the file already exists, remove it so it can be updated.
 195                      $existingfile->delete();
 196                  }
 197  
 198                  $newfile = $fs->create_file_from_storedfile($newfilerecord, $file);
 199              }
 200          }
 201          return true;
 202      }
 203  
 204      /**
 205       * Get form elements for grading form.
 206       *
 207       * @param stdClass $grade
 208       * @param MoodleQuickForm $mform
 209       * @param stdClass $data
 210       * @param int $userid The userid we are currently grading
 211       * @return bool true if elements were added to the form
 212       */
 213      public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) {
 214  
 215          $fileoptions = $this->get_file_options();
 216          $gradeid = $grade ? $grade->id : 0;
 217          $elementname = 'files_' . $userid;
 218  
 219          $data = file_prepare_standard_filemanager($data,
 220                                                    $elementname,
 221                                                    $fileoptions,
 222                                                    $this->assignment->get_context(),
 223                                                    'assignfeedback_file',
 224                                                    ASSIGNFEEDBACK_FILE_FILEAREA,
 225                                                    $gradeid);
 226          $mform->addElement('filemanager', $elementname . '_filemanager', $this->get_name(), null, $fileoptions);
 227  
 228          return true;
 229      }
 230  
 231      /**
 232       * Count the number of files.
 233       *
 234       * @param int $gradeid
 235       * @param string $area
 236       * @return int
 237       */
 238      private function count_files($gradeid, $area) {
 239  
 240          $fs = get_file_storage();
 241          $files = $fs->get_area_files($this->assignment->get_context()->id,
 242                                       'assignfeedback_file',
 243                                       $area,
 244                                       $gradeid,
 245                                       'id',
 246                                       false);
 247  
 248          return count($files);
 249      }
 250  
 251      /**
 252       * Update the number of files in the file area.
 253       *
 254       * @param stdClass $grade The grade record
 255       * @return bool - true if the value was saved
 256       */
 257      public function update_file_count($grade) {
 258          global $DB;
 259  
 260          $filefeedback = $this->get_file_feedback($grade->id);
 261          if ($filefeedback) {
 262              $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA);
 263              return $DB->update_record('assignfeedback_file', $filefeedback);
 264          } else {
 265              $filefeedback = new stdClass();
 266              $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA);
 267              $filefeedback->grade = $grade->id;
 268              $filefeedback->assignment = $this->assignment->get_instance()->id;
 269              return $DB->insert_record('assignfeedback_file', $filefeedback) > 0;
 270          }
 271      }
 272  
 273      /**
 274       * Save the feedback files.
 275       *
 276       * @param stdClass $grade
 277       * @param stdClass $data
 278       * @return bool
 279       */
 280      public function save(stdClass $grade, stdClass $data) {
 281          $fileoptions = $this->get_file_options();
 282  
 283          // The element name may have been for a different user.
 284          foreach ($data as $key => $value) {
 285              if (strpos($key, 'files_') === 0 && strpos($key, '_filemanager')) {
 286                  $elementname = substr($key, 0, strpos($key, '_filemanager'));
 287              }
 288          }
 289  
 290          $data = file_postupdate_standard_filemanager($data,
 291                                                       $elementname,
 292                                                       $fileoptions,
 293                                                       $this->assignment->get_context(),
 294                                                       'assignfeedback_file',
 295                                                       ASSIGNFEEDBACK_FILE_FILEAREA,
 296                                                       $grade->id);
 297  
 298          return $this->update_file_count($grade);
 299      }
 300  
 301      /**
 302       * Display the list of files in the feedback status table.
 303       *
 304       * @param stdClass $grade
 305       * @param bool $showviewlink - Set to true to show a link to see the full list of files
 306       * @return string
 307       */
 308      public function view_summary(stdClass $grade, & $showviewlink) {
 309  
 310          $count = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA);
 311  
 312          // Show a view all link if the number of files is over this limit.
 313          $showviewlink = $count > ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES;
 314  
 315          if ($count <= ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES) {
 316              return $this->assignment->render_area_files('assignfeedback_file',
 317                                                          ASSIGNFEEDBACK_FILE_FILEAREA,
 318                                                          $grade->id);
 319          } else {
 320              return get_string('countfiles', 'assignfeedback_file', $count);
 321          }
 322      }
 323  
 324      /**
 325       * Display the list of files in the feedback status table.
 326       *
 327       * @param stdClass $grade
 328       * @return string
 329       */
 330      public function view(stdClass $grade) {
 331          return $this->assignment->render_area_files('assignfeedback_file',
 332                                                      ASSIGNFEEDBACK_FILE_FILEAREA,
 333                                                      $grade->id);
 334      }
 335  
 336      /**
 337       * The assignment has been deleted - cleanup.
 338       *
 339       * @return bool
 340       */
 341      public function delete_instance() {
 342          global $DB;
 343          // Will throw exception on failure.
 344          $DB->delete_records('assignfeedback_file',
 345                              array('assignment'=>$this->assignment->get_instance()->id));
 346  
 347          return true;
 348      }
 349  
 350      /**
 351       * Return true if there are no feedback files.
 352       *
 353       * @param stdClass $grade
 354       */
 355      public function is_empty(stdClass $grade) {
 356          return $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA) == 0;
 357      }
 358  
 359      /**
 360       * Get file areas returns a list of areas this plugin stores files.
 361       *
 362       * @return array - An array of fileareas (keys) and descriptions (values)
 363       */
 364      public function get_file_areas() {
 365          return array(ASSIGNFEEDBACK_FILE_FILEAREA=>$this->get_name());
 366      }
 367  
 368      /**
 369       * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
 370       * and version.
 371       *
 372       * @param string $type old assignment subtype
 373       * @param int $version old assignment version
 374       * @return bool True if upgrade is possible
 375       */
 376      public function can_upgrade($type, $version) {
 377          if (($type == 'upload' || $type == 'uploadsingle') && $version >= 2011112900) {
 378              return true;
 379          }
 380          return false;
 381      }
 382  
 383      /**
 384       * Upgrade the settings from the old assignment to the new plugin based one.
 385       *
 386       * @param context $oldcontext - the context for the old assignment
 387       * @param stdClass $oldassignment - the data for the old assignment
 388       * @param string $log - can be appended to by the upgrade
 389       * @return bool was it a success? (false will trigger a rollback)
 390       */
 391      public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
 392          // First upgrade settings (nothing to do).
 393          return true;
 394      }
 395  
 396      /**
 397       * Upgrade the feedback from the old assignment to the new one.
 398       *
 399       * @param context $oldcontext - the database for the old assignment context
 400       * @param stdClass $oldassignment The data record for the old assignment
 401       * @param stdClass $oldsubmission The data record for the old submission
 402       * @param stdClass $grade The data record for the new grade
 403       * @param string $log Record upgrade messages in the log
 404       * @return bool true or false - false will trigger a rollback
 405       */
 406      public function upgrade(context $oldcontext,
 407                              stdClass $oldassignment,
 408                              stdClass $oldsubmission,
 409                              stdClass $grade,
 410                              & $log) {
 411          global $DB;
 412  
 413          // Now copy the area files.
 414          $this->assignment->copy_area_files_for_upgrade($oldcontext->id,
 415                                                          'mod_assignment',
 416                                                          'response',
 417                                                          $oldsubmission->id,
 418                                                          $this->assignment->get_context()->id,
 419                                                          'assignfeedback_file',
 420                                                          ASSIGNFEEDBACK_FILE_FILEAREA,
 421                                                          $grade->id);
 422  
 423          // Now count them!
 424          $filefeedback = new stdClass();
 425          $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA);
 426          $filefeedback->grade = $grade->id;
 427          $filefeedback->assignment = $this->assignment->get_instance()->id;
 428          if (!$DB->insert_record('assignfeedback_file', $filefeedback) > 0) {
 429              $log .= get_string('couldnotconvertgrade', 'mod_assign', $grade->userid);
 430              return false;
 431          }
 432          return true;
 433      }
 434  
 435      /**
 436       * Return a list of the batch grading operations performed by this plugin.
 437       * This plugin supports batch upload files and upload zip.
 438       *
 439       * @return array The list of batch grading operations
 440       */
 441      public function get_grading_batch_operations() {
 442          return array('uploadfiles'=>get_string('uploadfiles', 'assignfeedback_file'));
 443      }
 444  
 445      /**
 446       * Upload files and send them to multiple users.
 447       *
 448       * @param array $users - An array of user ids
 449       * @return string - The response html
 450       */
 451      public function view_batch_upload_files($users) {
 452          global $CFG, $DB, $USER;
 453  
 454          require_capability('mod/assign:grade', $this->assignment->get_context());
 455          require_once($CFG->dirroot . '/mod/assign/feedback/file/batchuploadfilesform.php');
 456          require_once($CFG->dirroot . '/mod/assign/renderable.php');
 457  
 458          $formparams = array('cm'=>$this->assignment->get_course_module()->id,
 459                              'users'=>$users,
 460                              'context'=>$this->assignment->get_context());
 461  
 462          $usershtml = '';
 463  
 464          $usercount = 0;
 465          foreach ($users as $userid) {
 466              if ($usercount >= ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS) {
 467                  $moreuserscount = count($users) - ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS;
 468                  $usershtml .= get_string('moreusers', 'assignfeedback_file', $moreuserscount);
 469                  break;
 470              }
 471              $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
 472  
 473              $usersummary = new assign_user_summary($user,
 474                                                     $this->assignment->get_course()->id,
 475                                                     has_capability('moodle/site:viewfullnames',
 476                                                     $this->assignment->get_course_context()),
 477                                                     $this->assignment->is_blind_marking(),
 478                                                     $this->assignment->get_uniqueid_for_user($user->id),
 479                                                     // TODO Does not support custom user profile fields (MDL-70456).
 480                                                     \core_user\fields::get_identity_fields($this->assignment->get_context(), false));
 481              $usershtml .= $this->assignment->get_renderer()->render($usersummary);
 482              $usercount += 1;
 483          }
 484  
 485          $formparams['usershtml'] = $usershtml;
 486  
 487          $mform = new assignfeedback_file_batch_upload_files_form(null, $formparams);
 488  
 489          if ($mform->is_cancelled()) {
 490              redirect(new moodle_url('view.php',
 491                                      array('id'=>$this->assignment->get_course_module()->id,
 492                                            'action'=>'grading')));
 493              return;
 494          } else if ($data = $mform->get_data()) {
 495              // Copy the files from the draft area to a temporary import area.
 496              $data = file_postupdate_standard_filemanager($data,
 497                                                           'files',
 498                                                           $this->get_file_options(),
 499                                                           $this->assignment->get_context(),
 500                                                           'assignfeedback_file',
 501                                                           ASSIGNFEEDBACK_FILE_BATCH_FILEAREA,
 502                                                           $USER->id);
 503              $fs = get_file_storage();
 504  
 505              // Now copy each of these files to the users feedback file area.
 506              foreach ($users as $userid) {
 507                  $grade = $this->assignment->get_user_grade($userid, true);
 508                  $this->assignment->notify_grade_modified($grade);
 509  
 510                  $this->copy_area_files($fs,
 511                                         $this->assignment->get_context()->id,
 512                                         'assignfeedback_file',
 513                                         ASSIGNFEEDBACK_FILE_BATCH_FILEAREA,
 514                                         $USER->id,
 515                                         $this->assignment->get_context()->id,
 516                                         'assignfeedback_file',
 517                                         ASSIGNFEEDBACK_FILE_FILEAREA,
 518                                         $grade->id);
 519  
 520                  $filefeedback = $this->get_file_feedback($grade->id);
 521                  if ($filefeedback) {
 522                      $filefeedback->numfiles = $this->count_files($grade->id,
 523                                                                   ASSIGNFEEDBACK_FILE_FILEAREA);
 524                      $DB->update_record('assignfeedback_file', $filefeedback);
 525                  } else {
 526                      $filefeedback = new stdClass();
 527                      $filefeedback->numfiles = $this->count_files($grade->id,
 528                                                                   ASSIGNFEEDBACK_FILE_FILEAREA);
 529                      $filefeedback->grade = $grade->id;
 530                      $filefeedback->assignment = $this->assignment->get_instance()->id;
 531                      $DB->insert_record('assignfeedback_file', $filefeedback);
 532                  }
 533              }
 534  
 535              // Now delete the temporary import area.
 536              $fs->delete_area_files($this->assignment->get_context()->id,
 537                                     'assignfeedback_file',
 538                                     ASSIGNFEEDBACK_FILE_BATCH_FILEAREA,
 539                                     $USER->id);
 540  
 541              redirect(new moodle_url('view.php',
 542                                      array('id'=>$this->assignment->get_course_module()->id,
 543                                            'action'=>'grading')));
 544              return;
 545          } else {
 546  
 547              $header = new assign_header($this->assignment->get_instance(),
 548                                          $this->assignment->get_context(),
 549                                          false,
 550                                          $this->assignment->get_course_module()->id,
 551                                          get_string('batchuploadfiles', 'assignfeedback_file'));
 552              $o = '';
 553              $o .= $this->assignment->get_renderer()->render($header);
 554              $o .= $this->assignment->get_renderer()->render(new assign_form('batchuploadfiles', $mform));
 555              $o .= $this->assignment->get_renderer()->render_footer();
 556          }
 557  
 558          return $o;
 559      }
 560  
 561      /**
 562       * User has chosen a custom grading batch operation and selected some users.
 563       *
 564       * @param string $action - The chosen action
 565       * @param array $users - An array of user ids
 566       * @return string - The response html
 567       */
 568      public function grading_batch_operation($action, $users) {
 569  
 570          if ($action == 'uploadfiles') {
 571              return $this->view_batch_upload_files($users);
 572          }
 573          return '';
 574      }
 575  
 576      /**
 577       * View the upload zip form.
 578       *
 579       * @return string - The html response
 580       */
 581      public function view_upload_zip() {
 582          global $CFG, $USER;
 583  
 584          require_capability('mod/assign:grade', $this->assignment->get_context());
 585          require_once($CFG->dirroot . '/mod/assign/feedback/file/uploadzipform.php');
 586          require_once($CFG->dirroot . '/mod/assign/feedback/file/importziplib.php');
 587          require_once($CFG->dirroot . '/mod/assign/feedback/file/importzipform.php');
 588  
 589          $formparams = array('context'=>$this->assignment->get_context(),
 590                              'cm'=>$this->assignment->get_course_module()->id);
 591          $mform = new assignfeedback_file_upload_zip_form(null, $formparams);
 592  
 593          $o = '';
 594  
 595          $confirm = optional_param('confirm', 0, PARAM_BOOL);
 596          $renderer = $this->assignment->get_renderer();
 597  
 598          // Delete any existing files.
 599          $importer = new assignfeedback_file_zip_importer();
 600          $contextid = $this->assignment->get_context()->id;
 601  
 602          if ($mform->is_cancelled()) {
 603              $importer->delete_import_files($contextid);
 604              $urlparams = array('id'=>$this->assignment->get_course_module()->id,
 605                                 'action'=>'grading');
 606              $url = new moodle_url('view.php', $urlparams);
 607              redirect($url);
 608              return;
 609          } else if ($confirm) {
 610              $params = array('assignment'=>$this->assignment, 'importer'=>$importer);
 611  
 612              $mform = new assignfeedback_file_import_zip_form(null, $params);
 613              if ($mform->is_cancelled()) {
 614                  $importer->delete_import_files($contextid);
 615                  $urlparams = array('id'=>$this->assignment->get_course_module()->id,
 616                                     'action'=>'grading');
 617                  $url = new moodle_url('view.php', $urlparams);
 618                  redirect($url);
 619                  return;
 620              }
 621  
 622              $o .= $importer->import_zip_files($this->assignment, $this);
 623              $importer->delete_import_files($contextid);
 624          } else if (($data = $mform->get_data()) &&
 625                     ($zipfile = $mform->save_stored_file('feedbackzip',
 626                                                          $contextid,
 627                                                          'assignfeedback_file',
 628                                                          ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA,
 629                                                          $USER->id,
 630                                                          '/',
 631                                                          'import.zip',
 632                                                          true))) {
 633  
 634              $importer->extract_files_from_zip($zipfile, $contextid);
 635  
 636              $params = array('assignment'=>$this->assignment, 'importer'=>$importer);
 637  
 638              $mform = new assignfeedback_file_import_zip_form(null, $params);
 639  
 640              $header = new assign_header($this->assignment->get_instance(),
 641                                          $this->assignment->get_context(),
 642                                          false,
 643                                          $this->assignment->get_course_module()->id,
 644                                          get_string('confirmuploadzip', 'assignfeedback_file'));
 645              $o .= $renderer->render($header);
 646              $o .= $renderer->render(new assign_form('confirmimportzip', $mform));
 647              $o .= $renderer->render_footer();
 648  
 649          } else {
 650  
 651              $header = new assign_header($this->assignment->get_instance(),
 652                                          $this->assignment->get_context(),
 653                                          false,
 654                                          $this->assignment->get_course_module()->id,
 655                                          get_string('uploadzip', 'assignfeedback_file'));
 656              $o .= $renderer->render($header);
 657              $o .= $renderer->render(new assign_form('uploadfeedbackzip', $mform));
 658              $o .= $renderer->render_footer();
 659          }
 660  
 661          return $o;
 662      }
 663  
 664      /**
 665       * Called by the assignment module when someone chooses something from the
 666       * grading navigation or batch operations list.
 667       *
 668       * @param string $action - The page to view
 669       * @return string - The html response
 670       */
 671      public function view_page($action) {
 672          if ($action == 'uploadfiles') {
 673              $users = required_param('selectedusers', PARAM_SEQUENCE);
 674              return $this->view_batch_upload_files(explode(',', $users));
 675          }
 676          if ($action == 'uploadzip') {
 677              return $this->view_upload_zip();
 678          }
 679  
 680          return '';
 681      }
 682  
 683      /**
 684       * Return a list of the grading actions performed by this plugin.
 685       * This plugin supports upload zip.
 686       *
 687       * @return array The list of grading actions
 688       */
 689      public function get_grading_actions() {
 690          return array('uploadzip'=>get_string('uploadzip', 'assignfeedback_file'));
 691      }
 692  
 693      /**
 694       * Return a description of external params suitable for uploading a feedback file from a webservice.
 695       *
 696       * @return external_description|null
 697       */
 698      public function get_external_parameters() {
 699          return array(
 700              'files_filemanager' => new external_value(
 701                  PARAM_INT,
 702                  'The id of a draft area containing files for this feedback.',
 703                  VALUE_OPTIONAL
 704              )
 705          );
 706      }
 707  
 708      /**
 709       * Return the plugin configs for external functions.
 710       *
 711       * @return array the list of settings
 712       * @since Moodle 3.2
 713       */
 714      public function get_config_for_external() {
 715          return (array) $this->get_config();
 716      }
 717  }