[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

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


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1