[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/assign/submission/file/ -> locallib.php (source)

   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 submission plugin
  19   *
  20   * This class provides all the functionality for the new assign module.
  21   *
  22   * @package assignsubmission_file
  23   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  require_once($CFG->libdir.'/eventslib.php');
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  // File areas for file submission assignment.
  32  define('ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES', 5);
  33  define('ASSIGNSUBMISSION_FILE_FILEAREA', 'submission_files');
  34  
  35  /**
  36   * Library class for file submission plugin extending submission plugin base class
  37   *
  38   * @package   assignsubmission_file
  39   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  40   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class assign_submission_file extends assign_submission_plugin {
  43  
  44      /**
  45       * Get the name of the file submission plugin
  46       * @return string
  47       */
  48      public function get_name() {
  49          return get_string('file', 'assignsubmission_file');
  50      }
  51  
  52      /**
  53       * Get file submission information from the database
  54       *
  55       * @param int $submissionid
  56       * @return mixed
  57       */
  58      private function get_file_submission($submissionid) {
  59          global $DB;
  60          return $DB->get_record('assignsubmission_file', array('submission'=>$submissionid));
  61      }
  62  
  63      /**
  64       * Get the default setting for file submission plugin
  65       *
  66       * @param MoodleQuickForm $mform The form to add elements to
  67       * @return void
  68       */
  69      public function get_settings(MoodleQuickForm $mform) {
  70          global $CFG, $COURSE;
  71  
  72          $defaultmaxfilesubmissions = $this->get_config('maxfilesubmissions');
  73          $defaultmaxsubmissionsizebytes = $this->get_config('maxsubmissionsizebytes');
  74  
  75          $settings = array();
  76          $options = array();
  77          for ($i = 1; $i <= get_config('assignsubmission_file', 'maxfiles'); $i++) {
  78              $options[$i] = $i;
  79          }
  80  
  81          $name = get_string('maxfilessubmission', 'assignsubmission_file');
  82          $mform->addElement('select', 'assignsubmission_file_maxfiles', $name, $options);
  83          $mform->addHelpButton('assignsubmission_file_maxfiles',
  84                                'maxfilessubmission',
  85                                'assignsubmission_file');
  86          $mform->setDefault('assignsubmission_file_maxfiles', $defaultmaxfilesubmissions);
  87          $mform->disabledIf('assignsubmission_file_maxfiles', 'assignsubmission_file_enabled', 'notchecked');
  88  
  89          $choices = get_max_upload_sizes($CFG->maxbytes,
  90                                          $COURSE->maxbytes,
  91                                          get_config('assignsubmission_file', 'maxbytes'));
  92  
  93          $settings[] = array('type' => 'select',
  94                              'name' => 'maxsubmissionsizebytes',
  95                              'description' => get_string('maximumsubmissionsize', 'assignsubmission_file'),
  96                              'options'=> $choices,
  97                              'default'=> $defaultmaxsubmissionsizebytes);
  98  
  99          $name = get_string('maximumsubmissionsize', 'assignsubmission_file');
 100          $mform->addElement('select', 'assignsubmission_file_maxsizebytes', $name, $choices);
 101          $mform->addHelpButton('assignsubmission_file_maxsizebytes',
 102                                'maximumsubmissionsize',
 103                                'assignsubmission_file');
 104          $mform->setDefault('assignsubmission_file_maxsizebytes', $defaultmaxsubmissionsizebytes);
 105          $mform->disabledIf('assignsubmission_file_maxsizebytes',
 106                             'assignsubmission_file_enabled',
 107                             'notchecked');
 108      }
 109  
 110      /**
 111       * Save the settings for file submission plugin
 112       *
 113       * @param stdClass $data
 114       * @return bool
 115       */
 116      public function save_settings(stdClass $data) {
 117          $this->set_config('maxfilesubmissions', $data->assignsubmission_file_maxfiles);
 118          $this->set_config('maxsubmissionsizebytes', $data->assignsubmission_file_maxsizebytes);
 119          return true;
 120      }
 121  
 122      /**
 123       * File format options
 124       *
 125       * @return array
 126       */
 127      private function get_file_options() {
 128          $fileoptions = array('subdirs'=>1,
 129                                  'maxbytes'=>$this->get_config('maxsubmissionsizebytes'),
 130                                  'maxfiles'=>$this->get_config('maxfilesubmissions'),
 131                                  'accepted_types'=>'*',
 132                                  'return_types'=>FILE_INTERNAL);
 133          if ($fileoptions['maxbytes'] == 0) {
 134              // Use module default.
 135              $fileoptions['maxbytes'] = get_config('assignsubmission_file', 'maxbytes');
 136          }
 137          return $fileoptions;
 138      }
 139  
 140      /**
 141       * Add elements to submission form
 142       *
 143       * @param mixed $submission stdClass|null
 144       * @param MoodleQuickForm $mform
 145       * @param stdClass $data
 146       * @return bool
 147       */
 148      public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) {
 149  
 150          if ($this->get_config('maxfilesubmissions') <= 0) {
 151              return false;
 152          }
 153  
 154          $fileoptions = $this->get_file_options();
 155          $submissionid = $submission ? $submission->id : 0;
 156  
 157          $data = file_prepare_standard_filemanager($data,
 158                                                    'files',
 159                                                    $fileoptions,
 160                                                    $this->assignment->get_context(),
 161                                                    'assignsubmission_file',
 162                                                    ASSIGNSUBMISSION_FILE_FILEAREA,
 163                                                    $submissionid);
 164          $mform->addElement('filemanager', 'files_filemanager', $this->get_name(), null, $fileoptions);
 165  
 166          return true;
 167      }
 168  
 169      /**
 170       * Count the number of files
 171       *
 172       * @param int $submissionid
 173       * @param string $area
 174       * @return int
 175       */
 176      private function count_files($submissionid, $area) {
 177  
 178          $fs = get_file_storage();
 179          $files = $fs->get_area_files($this->assignment->get_context()->id,
 180                                       'assignsubmission_file',
 181                                       $area,
 182                                       $submissionid,
 183                                       'id',
 184                                       false);
 185  
 186          return count($files);
 187      }
 188  
 189      /**
 190       * Save the files and trigger plagiarism plugin, if enabled,
 191       * to scan the uploaded files via events trigger
 192       *
 193       * @param stdClass $submission
 194       * @param stdClass $data
 195       * @return bool
 196       */
 197      public function save(stdClass $submission, stdClass $data) {
 198          global $USER, $DB;
 199  
 200          $fileoptions = $this->get_file_options();
 201  
 202          $data = file_postupdate_standard_filemanager($data,
 203                                                       'files',
 204                                                       $fileoptions,
 205                                                       $this->assignment->get_context(),
 206                                                       'assignsubmission_file',
 207                                                       ASSIGNSUBMISSION_FILE_FILEAREA,
 208                                                       $submission->id);
 209  
 210          $filesubmission = $this->get_file_submission($submission->id);
 211  
 212          // Plagiarism code event trigger when files are uploaded.
 213  
 214          $fs = get_file_storage();
 215          $files = $fs->get_area_files($this->assignment->get_context()->id,
 216                                       'assignsubmission_file',
 217                                       ASSIGNSUBMISSION_FILE_FILEAREA,
 218                                       $submission->id,
 219                                       'id',
 220                                       false);
 221  
 222          $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA);
 223  
 224          $params = array(
 225              'context' => context_module::instance($this->assignment->get_course_module()->id),
 226              'courseid' => $this->assignment->get_course()->id,
 227              'objectid' => $submission->id,
 228              'other' => array(
 229                  'content' => '',
 230                  'pathnamehashes' => array_keys($files)
 231              )
 232          );
 233          if (!empty($submission->userid) && ($submission->userid != $USER->id)) {
 234              $params['relateduserid'] = $submission->userid;
 235          }
 236          $event = \assignsubmission_file\event\assessable_uploaded::create($params);
 237          $event->set_legacy_files($files);
 238          $event->trigger();
 239  
 240          $groupname = null;
 241          $groupid = 0;
 242          // Get the group name as other fields are not transcribed in the logs and this information is important.
 243          if (empty($submission->userid) && !empty($submission->groupid)) {
 244              $groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), '*', MUST_EXIST);
 245              $groupid = $submission->groupid;
 246          } else {
 247              $params['relateduserid'] = $submission->userid;
 248          }
 249  
 250          // Unset the objectid and other field from params for use in submission events.
 251          unset($params['objectid']);
 252          unset($params['other']);
 253          $params['other'] = array(
 254              'submissionid' => $submission->id,
 255              'submissionattempt' => $submission->attemptnumber,
 256              'submissionstatus' => $submission->status,
 257              'filesubmissioncount' => $count,
 258              'groupid' => $groupid,
 259              'groupname' => $groupname
 260          );
 261  
 262          if ($filesubmission) {
 263              $filesubmission->numfiles = $this->count_files($submission->id,
 264                                                             ASSIGNSUBMISSION_FILE_FILEAREA);
 265              $updatestatus = $DB->update_record('assignsubmission_file', $filesubmission);
 266              $params['objectid'] = $filesubmission->id;
 267  
 268              $event = \assignsubmission_file\event\submission_updated::create($params);
 269              $event->set_assign($this->assignment);
 270              $event->trigger();
 271              return $updatestatus;
 272          } else {
 273              $filesubmission = new stdClass();
 274              $filesubmission->numfiles = $this->count_files($submission->id,
 275                                                             ASSIGNSUBMISSION_FILE_FILEAREA);
 276              $filesubmission->submission = $submission->id;
 277              $filesubmission->assignment = $this->assignment->get_instance()->id;
 278              $filesubmission->id = $DB->insert_record('assignsubmission_file', $filesubmission);
 279              $params['objectid'] = $filesubmission->id;
 280  
 281              $event = \assignsubmission_file\event\submission_created::create($params);
 282              $event->set_assign($this->assignment);
 283              $event->trigger();
 284              return $filesubmission->id > 0;
 285          }
 286      }
 287  
 288      /**
 289       * Produce a list of files suitable for export that represent this feedback or submission
 290       *
 291       * @param stdClass $submission The submission
 292       * @param stdClass $user The user record - unused
 293       * @return array - return an array of files indexed by filename
 294       */
 295      public function get_files(stdClass $submission, stdClass $user) {
 296          $result = array();
 297          $fs = get_file_storage();
 298  
 299          $files = $fs->get_area_files($this->assignment->get_context()->id,
 300                                       'assignsubmission_file',
 301                                       ASSIGNSUBMISSION_FILE_FILEAREA,
 302                                       $submission->id,
 303                                       'timemodified',
 304                                       false);
 305  
 306          foreach ($files as $file) {
 307              $result[$file->get_filepath().$file->get_filename()] = $file;
 308          }
 309          return $result;
 310      }
 311  
 312      /**
 313       * Display the list of files  in the submission status table
 314       *
 315       * @param stdClass $submission
 316       * @param bool $showviewlink Set this to true if the list of files is long
 317       * @return string
 318       */
 319      public function view_summary(stdClass $submission, & $showviewlink) {
 320          $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA);
 321  
 322          // Show we show a link to view all files for this plugin?
 323          $showviewlink = $count > ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES;
 324          if ($count <= ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES) {
 325              return $this->assignment->render_area_files('assignsubmission_file',
 326                                                          ASSIGNSUBMISSION_FILE_FILEAREA,
 327                                                          $submission->id);
 328          } else {
 329              return get_string('countfiles', 'assignsubmission_file', $count);
 330          }
 331      }
 332  
 333      /**
 334       * No full submission view - the summary contains the list of files and that is the whole submission
 335       *
 336       * @param stdClass $submission
 337       * @return string
 338       */
 339      public function view(stdClass $submission) {
 340          return $this->assignment->render_area_files('assignsubmission_file',
 341                                                      ASSIGNSUBMISSION_FILE_FILEAREA,
 342                                                      $submission->id);
 343      }
 344  
 345  
 346  
 347      /**
 348       * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
 349       * and version.
 350       *
 351       * @param string $type
 352       * @param int $version
 353       * @return bool True if upgrade is possible
 354       */
 355      public function can_upgrade($type, $version) {
 356  
 357          $uploadsingletype ='uploadsingle';
 358          $uploadtype ='upload';
 359  
 360          if (($type == $uploadsingletype || $type == $uploadtype) && $version >= 2011112900) {
 361              return true;
 362          }
 363          return false;
 364      }
 365  
 366  
 367      /**
 368       * Upgrade the settings from the old assignment
 369       * to the new plugin based one
 370       *
 371       * @param context $oldcontext - the old assignment context
 372       * @param stdClass $oldassignment - the old assignment data record
 373       * @param string $log record log events here
 374       * @return bool Was it a success? (false will trigger rollback)
 375       */
 376      public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
 377          global $DB;
 378  
 379          if ($oldassignment->assignmenttype == 'uploadsingle') {
 380              $this->set_config('maxfilesubmissions', 1);
 381              $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes);
 382              return true;
 383          } else if ($oldassignment->assignmenttype == 'upload') {
 384              $this->set_config('maxfilesubmissions', $oldassignment->var1);
 385              $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes);
 386  
 387              // Advanced file upload uses a different setting to do the same thing.
 388              $DB->set_field('assign',
 389                             'submissiondrafts',
 390                             $oldassignment->var4,
 391                             array('id'=>$this->assignment->get_instance()->id));
 392  
 393              // Convert advanced file upload "hide description before due date" setting.
 394              $alwaysshow = 0;
 395              if (!$oldassignment->var3) {
 396                  $alwaysshow = 1;
 397              }
 398              $DB->set_field('assign',
 399                             'alwaysshowdescription',
 400                             $alwaysshow,
 401                             array('id'=>$this->assignment->get_instance()->id));
 402              return true;
 403          }
 404      }
 405  
 406      /**
 407       * Upgrade the submission from the old assignment to the new one
 408       *
 409       * @param context $oldcontext The context of the old assignment
 410       * @param stdClass $oldassignment The data record for the old oldassignment
 411       * @param stdClass $oldsubmission The data record for the old submission
 412       * @param stdClass $submission The data record for the new submission
 413       * @param string $log Record upgrade messages in the log
 414       * @return bool true or false - false will trigger a rollback
 415       */
 416      public function upgrade(context $oldcontext,
 417                              stdClass $oldassignment,
 418                              stdClass $oldsubmission,
 419                              stdClass $submission,
 420                              & $log) {
 421          global $DB;
 422  
 423          $filesubmission = new stdClass();
 424  
 425          $filesubmission->numfiles = $oldsubmission->numfiles;
 426          $filesubmission->submission = $submission->id;
 427          $filesubmission->assignment = $this->assignment->get_instance()->id;
 428  
 429          if (!$DB->insert_record('assignsubmission_file', $filesubmission) > 0) {
 430              $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid);
 431              return false;
 432          }
 433  
 434          // Now copy the area files.
 435          $this->assignment->copy_area_files_for_upgrade($oldcontext->id,
 436                                                          'mod_assignment',
 437                                                          'submission',
 438                                                          $oldsubmission->id,
 439                                                          $this->assignment->get_context()->id,
 440                                                          'assignsubmission_file',
 441                                                          ASSIGNSUBMISSION_FILE_FILEAREA,
 442                                                          $submission->id);
 443  
 444          return true;
 445      }
 446  
 447      /**
 448       * The assignment has been deleted - cleanup
 449       *
 450       * @return bool
 451       */
 452      public function delete_instance() {
 453          global $DB;
 454          // Will throw exception on failure.
 455          $DB->delete_records('assignsubmission_file',
 456                              array('assignment'=>$this->assignment->get_instance()->id));
 457  
 458          return true;
 459      }
 460  
 461      /**
 462       * Formatting for log info
 463       *
 464       * @param stdClass $submission The submission
 465       * @return string
 466       */
 467      public function format_for_log(stdClass $submission) {
 468          // Format the info for each submission plugin (will be added to log).
 469          $filecount = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA);
 470  
 471          return get_string('numfilesforlog', 'assignsubmission_file', $filecount);
 472      }
 473  
 474      /**
 475       * Return true if there are no submission files
 476       * @param stdClass $submission
 477       */
 478      public function is_empty(stdClass $submission) {
 479          return $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA) == 0;
 480      }
 481  
 482      /**
 483       * Determine if a submission is empty
 484       *
 485       * This is distinct from is_empty in that it is intended to be used to
 486       * determine if a submission made before saving is empty.
 487       *
 488       * @param stdClass $data The submission data
 489       * @return bool
 490       */
 491      public function submission_is_empty(stdClass $data) {
 492          $files = file_get_drafarea_files($data->files_filemanager);
 493          return count($files->list) == 0;
 494      }
 495  
 496      /**
 497       * Get file areas returns a list of areas this plugin stores files
 498       * @return array - An array of fileareas (keys) and descriptions (values)
 499       */
 500      public function get_file_areas() {
 501          return array(ASSIGNSUBMISSION_FILE_FILEAREA=>$this->get_name());
 502      }
 503  
 504      /**
 505       * Copy the student's submission from a previous submission. Used when a student opts to base their resubmission
 506       * on the last submission.
 507       * @param stdClass $sourcesubmission
 508       * @param stdClass $destsubmission
 509       */
 510      public function copy_submission(stdClass $sourcesubmission, stdClass $destsubmission) {
 511          global $DB;
 512  
 513          // Copy the files across.
 514          $contextid = $this->assignment->get_context()->id;
 515          $fs = get_file_storage();
 516          $files = $fs->get_area_files($contextid,
 517                                       'assignsubmission_file',
 518                                       ASSIGNSUBMISSION_FILE_FILEAREA,
 519                                       $sourcesubmission->id,
 520                                       'id',
 521                                       false);
 522          foreach ($files as $file) {
 523              $fieldupdates = array('itemid' => $destsubmission->id);
 524              $fs->create_file_from_storedfile($fieldupdates, $file);
 525          }
 526  
 527          // Copy the assignsubmission_file record.
 528          if ($filesubmission = $this->get_file_submission($sourcesubmission->id)) {
 529              unset($filesubmission->id);
 530              $filesubmission->submission = $destsubmission->id;
 531              $DB->insert_record('assignsubmission_file', $filesubmission);
 532          }
 533          return true;
 534      }
 535  
 536      /**
 537       * Return a description of external params suitable for uploading a file submission from a webservice.
 538       *
 539       * @return external_description|null
 540       */
 541      public function get_external_parameters() {
 542          return array(
 543              'files_filemanager' => new external_value(
 544                  PARAM_INT,
 545                  'The id of a draft area containing files for this submission.',
 546                  VALUE_OPTIONAL
 547              )
 548          );
 549      }
 550  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1