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 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [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 comment feedback plugin
  19   *
  20   * @package   assignfeedback_comments
  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  use core_external\external_single_structure;
  26  use core_external\external_value;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  // File component for feedback comments.
  31  define('ASSIGNFEEDBACK_COMMENTS_COMPONENT', 'assignfeedback_comments');
  32  
  33  // File area for feedback comments.
  34  define('ASSIGNFEEDBACK_COMMENTS_FILEAREA', 'feedback');
  35  
  36  /**
  37   * Library class for comment feedback plugin extending feedback plugin base class.
  38   *
  39   * @package   assignfeedback_comments
  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_comments extends assign_feedback_plugin {
  44  
  45      /**
  46       * Get the name of the online comment feedback plugin.
  47       * @return string
  48       */
  49      public function get_name() {
  50          return get_string('pluginname', 'assignfeedback_comments');
  51      }
  52  
  53      /**
  54       * Get the feedback comment from the database.
  55       *
  56       * @param int $gradeid
  57       * @return stdClass|false The feedback comments for the given grade if it exists.
  58       *                        False if it doesn't.
  59       */
  60      public function get_feedback_comments($gradeid) {
  61          global $DB;
  62          return $DB->get_record('assignfeedback_comments', array('grade'=>$gradeid));
  63      }
  64  
  65      /**
  66       * Get quickgrading form elements as html.
  67       *
  68       * @param int $userid The user id in the table this quickgrading element relates to
  69       * @param mixed $grade - The grade data - may be null if there are no grades for this user (yet)
  70       * @return mixed - A html string containing the html form elements required for quickgrading
  71       */
  72      public function get_quickgrading_html($userid, $grade) {
  73          $commenttext = '';
  74          if ($grade) {
  75              $feedbackcomments = $this->get_feedback_comments($grade->id);
  76              if ($feedbackcomments) {
  77                  $commenttext = $feedbackcomments->commenttext;
  78              }
  79          }
  80  
  81          $pluginname = get_string('pluginname', 'assignfeedback_comments');
  82          $labeloptions = array('for'=>'quickgrade_comments_' . $userid,
  83                                'class'=>'accesshide');
  84          $textareaoptions = array('name'=>'quickgrade_comments_' . $userid,
  85                                   'id'=>'quickgrade_comments_' . $userid,
  86                                   'class'=>'quickgrade');
  87          return html_writer::tag('label', $pluginname, $labeloptions) .
  88                 html_writer::tag('textarea', $commenttext, $textareaoptions);
  89      }
  90  
  91      /**
  92       * Has the plugin quickgrading form element been modified in the current form submission?
  93       *
  94       * @param int $userid The user id in the table this quickgrading element relates to
  95       * @param stdClass $grade The grade
  96       * @return boolean - true if the quickgrading form element has been modified
  97       */
  98      public function is_quickgrading_modified($userid, $grade) {
  99          $commenttext = '';
 100          if ($grade) {
 101              $feedbackcomments = $this->get_feedback_comments($grade->id);
 102              if ($feedbackcomments) {
 103                  $commenttext = $feedbackcomments->commenttext;
 104              }
 105          }
 106          // Note that this handles the difference between empty and not in the quickgrading
 107          // form at all (hidden column).
 108          $newvalue = optional_param('quickgrade_comments_' . $userid, false, PARAM_RAW);
 109          return ($newvalue !== false) && ($newvalue != $commenttext);
 110      }
 111  
 112      /**
 113       * Has the comment feedback been modified?
 114       *
 115       * @param stdClass $grade The grade object.
 116       * @param stdClass $data Data from the form submission.
 117       * @return boolean True if the comment feedback has been modified, else false.
 118       */
 119      public function is_feedback_modified(stdClass $grade, stdClass $data) {
 120          $commenttext = '';
 121          if ($grade) {
 122              $feedbackcomments = $this->get_feedback_comments($grade->id);
 123              if ($feedbackcomments) {
 124                  $commenttext = $feedbackcomments->commenttext;
 125              }
 126          }
 127  
 128          $formtext = $data->assignfeedbackcomments_editor['text'];
 129  
 130          // Need to convert the form text to use @@PLUGINFILE@@ and format it so we can compare it with what is stored in the DB.
 131          if (isset($data->assignfeedbackcomments_editor['itemid'])) {
 132              $formtext = file_rewrite_urls_to_pluginfile($formtext, $data->assignfeedbackcomments_editor['itemid']);
 133              $formtext = format_text($formtext, FORMAT_HTML);
 134          }
 135  
 136          if ($commenttext == $formtext) {
 137              return false;
 138          } else {
 139              return true;
 140          }
 141      }
 142  
 143  
 144      /**
 145       * Override to indicate a plugin supports quickgrading.
 146       *
 147       * @return boolean - True if the plugin supports quickgrading
 148       */
 149      public function supports_quickgrading() {
 150          return true;
 151      }
 152  
 153      /**
 154       * Return a list of the text fields that can be imported/exported by this plugin.
 155       *
 156       * @return array An array of field names and descriptions. (name=>description, ...)
 157       */
 158      public function get_editor_fields() {
 159          return array('comments' => get_string('pluginname', 'assignfeedback_comments'));
 160      }
 161  
 162      /**
 163       * Get the saved text content from the editor.
 164       *
 165       * @param string $name
 166       * @param int $gradeid
 167       * @return string
 168       */
 169      public function get_editor_text($name, $gradeid) {
 170          if ($name == 'comments') {
 171              $feedbackcomments = $this->get_feedback_comments($gradeid);
 172              if ($feedbackcomments) {
 173                  return $feedbackcomments->commenttext;
 174              }
 175          }
 176  
 177          return '';
 178      }
 179  
 180      /**
 181       * Get the saved text content from the editor.
 182       *
 183       * @param string $name
 184       * @param string $value
 185       * @param int $gradeid
 186       * @return string
 187       */
 188      public function set_editor_text($name, $value, $gradeid) {
 189          global $DB;
 190  
 191          if ($name == 'comments') {
 192              $feedbackcomment = $this->get_feedback_comments($gradeid);
 193              if ($feedbackcomment) {
 194                  $feedbackcomment->commenttext = $value;
 195                  return $DB->update_record('assignfeedback_comments', $feedbackcomment);
 196              } else {
 197                  $feedbackcomment = new stdClass();
 198                  $feedbackcomment->commenttext = $value;
 199                  $feedbackcomment->commentformat = FORMAT_HTML;
 200                  $feedbackcomment->grade = $gradeid;
 201                  $feedbackcomment->assignment = $this->assignment->get_instance()->id;
 202                  return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
 203              }
 204          }
 205  
 206          return false;
 207      }
 208  
 209      /**
 210       * Save quickgrading changes.
 211       *
 212       * @param int $userid The user id in the table this quickgrading element relates to
 213       * @param stdClass $grade The grade
 214       * @return boolean - true if the grade changes were saved correctly
 215       */
 216      public function save_quickgrading_changes($userid, $grade) {
 217          global $DB;
 218          $feedbackcomment = $this->get_feedback_comments($grade->id);
 219          $quickgradecomments = optional_param('quickgrade_comments_' . $userid, null, PARAM_RAW);
 220          if (!$quickgradecomments && $quickgradecomments !== '') {
 221              return true;
 222          }
 223          if ($feedbackcomment) {
 224              $feedbackcomment->commenttext = $quickgradecomments;
 225              return $DB->update_record('assignfeedback_comments', $feedbackcomment);
 226          } else {
 227              $feedbackcomment = new stdClass();
 228              $feedbackcomment->commenttext = $quickgradecomments;
 229              $feedbackcomment->commentformat = FORMAT_HTML;
 230              $feedbackcomment->grade = $grade->id;
 231              $feedbackcomment->assignment = $this->assignment->get_instance()->id;
 232              return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
 233          }
 234      }
 235  
 236      /**
 237       * Save the settings for feedback comments plugin
 238       *
 239       * @param stdClass $data
 240       * @return bool
 241       */
 242      public function save_settings(stdClass $data) {
 243          $this->set_config('commentinline', !empty($data->assignfeedback_comments_commentinline));
 244          return true;
 245      }
 246  
 247      /**
 248       * Get the default setting for feedback comments plugin
 249       *
 250       * @param MoodleQuickForm $mform The form to add elements to
 251       * @return void
 252       */
 253      public function get_settings(MoodleQuickForm $mform) {
 254          $default = $this->get_config('commentinline');
 255          if ($default === false) {
 256              // Apply the admin default if we don't have a value yet.
 257              $default = get_config('assignfeedback_comments', 'inline');
 258          }
 259          $mform->addElement('selectyesno',
 260                             'assignfeedback_comments_commentinline',
 261                             get_string('commentinline', 'assignfeedback_comments'));
 262          $mform->addHelpButton('assignfeedback_comments_commentinline', 'commentinline', 'assignfeedback_comments');
 263          $mform->setDefault('assignfeedback_comments_commentinline', $default);
 264          // Disable comment online if comment feedback plugin is disabled.
 265          $mform->hideIf('assignfeedback_comments_commentinline', 'assignfeedback_comments_enabled', 'notchecked');
 266     }
 267  
 268      /**
 269       * Convert the text from any submission plugin that has an editor field to
 270       * a format suitable for inserting in the feedback text field.
 271       *
 272       * @param stdClass $submission
 273       * @param stdClass $data - Form data to be filled with the converted submission text and format.
 274       * @param stdClass|null $grade
 275       * @return boolean - True if feedback text was set.
 276       */
 277      protected function convert_submission_text_to_feedback($submission, $data, $grade) {
 278          global $DB;
 279  
 280          $format = false;
 281          $text = '';
 282  
 283          foreach ($this->assignment->get_submission_plugins() as $plugin) {
 284              $fields = $plugin->get_editor_fields();
 285              if ($plugin->is_enabled() && $plugin->is_visible() && !$plugin->is_empty($submission) && !empty($fields)) {
 286                  $user = $DB->get_record('user', ['id' => $submission->userid]);
 287                  // Copy the files to the feedback area.
 288                  if ($files = $plugin->get_files($submission, $user)) {
 289                      $fs = get_file_storage();
 290                      $component = 'assignfeedback_comments';
 291                      $filearea = ASSIGNFEEDBACK_COMMENTS_FILEAREA;
 292                      $itemid = $grade->id;
 293                      $fieldupdates = [
 294                          'component' => $component,
 295                          'filearea' => $filearea,
 296                          'itemid' => $itemid
 297                      ];
 298                      foreach ($files as $file) {
 299                          if ($file instanceof stored_file) {
 300                              // Before we create it, check that it doesn't already exist.
 301                              if (!$fs->file_exists(
 302                                      $file->get_contextid(),
 303                                      $component,
 304                                      $filearea,
 305                                      $itemid,
 306                                      $file->get_filepath(),
 307                                      $file->get_filename())) {
 308                                  $fs->create_file_from_storedfile($fieldupdates, $file);
 309                              }
 310                          }
 311                      }
 312                  }
 313                  foreach ($fields as $key => $description) {
 314                      $rawtext = clean_text($plugin->get_editor_text($key, $submission->id));
 315                      $newformat = $plugin->get_editor_format($key, $submission->id);
 316  
 317                      if ($format !== false && $newformat != $format) {
 318                          // There are 2 or more editor fields using different formats, set to plain as a fallback.
 319                          $format = FORMAT_PLAIN;
 320                      } else {
 321                          $format = $newformat;
 322                      }
 323                      $text .= $rawtext;
 324                  }
 325              }
 326          }
 327  
 328          if ($format === false) {
 329              $format = FORMAT_HTML;
 330          }
 331          $data->assignfeedbackcomments = $text;
 332          $data->assignfeedbackcommentsformat = $format;
 333  
 334          return true;
 335      }
 336  
 337      /**
 338       * Get form elements for the grading page
 339       *
 340       * @param stdClass|null $grade
 341       * @param MoodleQuickForm $mform
 342       * @param stdClass $data
 343       * @return bool true if elements were added to the form
 344       */
 345      public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) {
 346          $commentinlinenabled = $this->get_config('commentinline');
 347          $submission = $this->assignment->get_user_submission($userid, false);
 348          $feedbackcomments = false;
 349  
 350          if ($grade) {
 351              $feedbackcomments = $this->get_feedback_comments($grade->id);
 352          }
 353  
 354          // Check first for data from last form submission in case grading validation failed.
 355          if (!empty($data->assignfeedbackcomments_editor['text'])) {
 356              $data->assignfeedbackcomments = $data->assignfeedbackcomments_editor['text'];
 357              $data->assignfeedbackcommentsformat = $data->assignfeedbackcomments_editor['format'];
 358          } else if ($feedbackcomments && !empty($feedbackcomments->commenttext)) {
 359              $data->assignfeedbackcomments = $feedbackcomments->commenttext;
 360              $data->assignfeedbackcommentsformat = $feedbackcomments->commentformat;
 361          } else {
 362              // No feedback given yet - maybe we need to copy the text from the submission?
 363              if (!empty($commentinlinenabled) && $submission) {
 364                  $this->convert_submission_text_to_feedback($submission, $data, $grade);
 365              } else { // Set it to empty.
 366                  $data->assignfeedbackcomments = '';
 367                  $data->assignfeedbackcommentsformat = FORMAT_HTML;
 368              }
 369          }
 370  
 371          file_prepare_standard_editor(
 372              $data,
 373              'assignfeedbackcomments',
 374              $this->get_editor_options(),
 375              $this->assignment->get_context(),
 376              ASSIGNFEEDBACK_COMMENTS_COMPONENT,
 377              ASSIGNFEEDBACK_COMMENTS_FILEAREA,
 378              $grade->id
 379          );
 380  
 381          $mform->addElement('editor', 'assignfeedbackcomments_editor', $this->get_name(), null, $this->get_editor_options());
 382  
 383          return true;
 384      }
 385  
 386      /**
 387       * Saving the comment content into database.
 388       *
 389       * @param stdClass $grade
 390       * @param stdClass $data
 391       * @return bool
 392       */
 393      public function save(stdClass $grade, stdClass $data) {
 394          global $DB;
 395  
 396          // Save the files.
 397          $data = file_postupdate_standard_editor(
 398              $data,
 399              'assignfeedbackcomments',
 400              $this->get_editor_options(),
 401              $this->assignment->get_context(),
 402              ASSIGNFEEDBACK_COMMENTS_COMPONENT,
 403              ASSIGNFEEDBACK_COMMENTS_FILEAREA,
 404              $grade->id
 405          );
 406  
 407          $feedbackcomment = $this->get_feedback_comments($grade->id);
 408          if ($feedbackcomment) {
 409              $feedbackcomment->commenttext = $data->assignfeedbackcomments;
 410              $feedbackcomment->commentformat = $data->assignfeedbackcommentsformat;
 411              return $DB->update_record('assignfeedback_comments', $feedbackcomment);
 412          } else {
 413              $feedbackcomment = new stdClass();
 414              $feedbackcomment->commenttext = $data->assignfeedbackcomments;
 415              $feedbackcomment->commentformat = $data->assignfeedbackcommentsformat;
 416              $feedbackcomment->grade = $grade->id;
 417              $feedbackcomment->assignment = $this->assignment->get_instance()->id;
 418              return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
 419          }
 420      }
 421  
 422      /**
 423       * Display the comment in the feedback table.
 424       *
 425       * @param stdClass $grade
 426       * @param bool $showviewlink Set to true to show a link to view the full feedback
 427       * @return string
 428       */
 429      public function view_summary(stdClass $grade, & $showviewlink) {
 430          $feedbackcomments = $this->get_feedback_comments($grade->id);
 431          if ($feedbackcomments) {
 432              $text = $this->rewrite_feedback_comments_urls($feedbackcomments->commenttext, $grade->id);
 433              $text = format_text(
 434                  $text,
 435                  $feedbackcomments->commentformat,
 436                  [
 437                      'context' => $this->assignment->get_context()
 438                  ]
 439              );
 440  
 441              // Show the view all link if the text has been shortened.
 442              $short = shorten_text($text, 140);
 443              $showviewlink = $short != $text;
 444              return $short;
 445          }
 446          return '';
 447      }
 448  
 449      /**
 450       * Display the comment in the feedback table.
 451       *
 452       * @param stdClass $grade
 453       * @return string
 454       */
 455      public function view(stdClass $grade) {
 456          $feedbackcomments = $this->get_feedback_comments($grade->id);
 457          if ($feedbackcomments) {
 458              $text = $this->rewrite_feedback_comments_urls($feedbackcomments->commenttext, $grade->id);
 459              $text = format_text(
 460                  $text,
 461                  $feedbackcomments->commentformat,
 462                  [
 463                      'context' => $this->assignment->get_context()
 464                  ]
 465              );
 466  
 467              return $text;
 468          }
 469          return '';
 470      }
 471  
 472      /**
 473       * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
 474       * and version.
 475       *
 476       * @param string $type old assignment subtype
 477       * @param int $version old assignment version
 478       * @return bool True if upgrade is possible
 479       */
 480      public function can_upgrade($type, $version) {
 481  
 482          if (($type == 'upload' || $type == 'uploadsingle' ||
 483               $type == 'online' || $type == 'offline') && $version >= 2011112900) {
 484              return true;
 485          }
 486          return false;
 487      }
 488  
 489      /**
 490       * Upgrade the settings from the old assignment to the new plugin based one
 491       *
 492       * @param context $oldcontext - the context for the old assignment
 493       * @param stdClass $oldassignment - the data for the old assignment
 494       * @param string $log - can be appended to by the upgrade
 495       * @return bool was it a success? (false will trigger a rollback)
 496       */
 497      public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
 498          if ($oldassignment->assignmenttype == 'online') {
 499              $this->set_config('commentinline', $oldassignment->var1);
 500              return true;
 501          }
 502          return true;
 503      }
 504  
 505      /**
 506       * Upgrade the feedback from the old assignment to the new one
 507       *
 508       * @param context $oldcontext - the database for the old assignment context
 509       * @param stdClass $oldassignment The data record for the old assignment
 510       * @param stdClass $oldsubmission The data record for the old submission
 511       * @param stdClass $grade The data record for the new grade
 512       * @param string $log Record upgrade messages in the log
 513       * @return bool true or false - false will trigger a rollback
 514       */
 515      public function upgrade(context $oldcontext,
 516                              stdClass $oldassignment,
 517                              stdClass $oldsubmission,
 518                              stdClass $grade,
 519                              & $log) {
 520          global $DB;
 521  
 522          $feedbackcomments = new stdClass();
 523          $feedbackcomments->commenttext = $oldsubmission->submissioncomment;
 524          $feedbackcomments->commentformat = FORMAT_HTML;
 525  
 526          $feedbackcomments->grade = $grade->id;
 527          $feedbackcomments->assignment = $this->assignment->get_instance()->id;
 528          if (!$DB->insert_record('assignfeedback_comments', $feedbackcomments) > 0) {
 529              $log .= get_string('couldnotconvertgrade', 'mod_assign', $grade->userid);
 530              return false;
 531          }
 532  
 533          return true;
 534      }
 535  
 536      /**
 537       * If this plugin adds to the gradebook comments field, it must specify the format of the text
 538       * of the comment
 539       *
 540       * Only one feedback plugin can push comments to the gradebook and that is chosen by the assignment
 541       * settings page.
 542       *
 543       * @param stdClass $grade The grade
 544       * @return int
 545       */
 546      public function format_for_gradebook(stdClass $grade) {
 547          $feedbackcomments = $this->get_feedback_comments($grade->id);
 548          if ($feedbackcomments) {
 549              return $feedbackcomments->commentformat;
 550          }
 551          return FORMAT_MOODLE;
 552      }
 553  
 554      /**
 555       * If this plugin adds to the gradebook comments field, it must format the text
 556       * of the comment
 557       *
 558       * Only one feedback plugin can push comments to the gradebook and that is chosen by the assignment
 559       * settings page.
 560       *
 561       * @param stdClass $grade The grade
 562       * @return string
 563       */
 564      public function text_for_gradebook(stdClass $grade) {
 565          $feedbackcomments = $this->get_feedback_comments($grade->id);
 566          if ($feedbackcomments) {
 567              return $feedbackcomments->commenttext;
 568          }
 569          return '';
 570      }
 571  
 572      /**
 573       * Return any files this plugin wishes to save to the gradebook.
 574       *
 575       * @param stdClass $grade The assign_grades object from the db
 576       * @return array
 577       */
 578      public function files_for_gradebook(stdClass $grade) : array {
 579          return [
 580              'contextid' => $this->assignment->get_context()->id,
 581              'component' => ASSIGNFEEDBACK_COMMENTS_COMPONENT,
 582              'filearea' => ASSIGNFEEDBACK_COMMENTS_FILEAREA,
 583              'itemid' => $grade->id
 584          ];
 585      }
 586  
 587      /**
 588       * The assignment has been deleted - cleanup
 589       *
 590       * @return bool
 591       */
 592      public function delete_instance() {
 593          global $DB;
 594          // Will throw exception on failure.
 595          $DB->delete_records('assignfeedback_comments',
 596                              array('assignment'=>$this->assignment->get_instance()->id));
 597          return true;
 598      }
 599  
 600      /**
 601       * Returns true if there are no feedback comments for the given grade.
 602       *
 603       * @param stdClass $grade
 604       * @return bool
 605       */
 606      public function is_empty(stdClass $grade) {
 607          return $this->view($grade) == '';
 608      }
 609  
 610      /**
 611       * Get file areas returns a list of areas this plugin stores files
 612       * @return array - An array of fileareas (keys) and descriptions (values)
 613       */
 614      public function get_file_areas() {
 615          return array(ASSIGNFEEDBACK_COMMENTS_FILEAREA => $this->get_name());
 616      }
 617  
 618      /**
 619       * Return a description of external params suitable for uploading an feedback comment from a webservice.
 620       *
 621       * @return \core_external\external_description|null
 622       */
 623      public function get_external_parameters() {
 624          $editorparams = array('text' => new external_value(PARAM_RAW, 'The text for this feedback.'),
 625                                'format' => new external_value(PARAM_INT, 'The format for this feedback'));
 626          $editorstructure = new external_single_structure($editorparams, 'Editor structure', VALUE_OPTIONAL);
 627          return array('assignfeedbackcomments_editor' => $editorstructure);
 628      }
 629  
 630      /**
 631       * Return the plugin configs for external functions.
 632       *
 633       * @return array the list of settings
 634       * @since Moodle 3.2
 635       */
 636      public function get_config_for_external() {
 637          return (array) $this->get_config();
 638      }
 639  
 640      /**
 641       * Convert encoded URLs in $text from the @@PLUGINFILE@@/... form to an actual URL.
 642       *
 643       * @param string $text the Text to check
 644       * @param int $gradeid The grade ID which refers to the id in the gradebook
 645       */
 646      private function rewrite_feedback_comments_urls(string $text, int $gradeid) {
 647          return file_rewrite_pluginfile_urls(
 648              $text,
 649              'pluginfile.php',
 650              $this->assignment->get_context()->id,
 651              ASSIGNFEEDBACK_COMMENTS_COMPONENT,
 652              ASSIGNFEEDBACK_COMMENTS_FILEAREA,
 653              $gradeid
 654          );
 655      }
 656  
 657      /**
 658       * File format options.
 659       *
 660       * @return array
 661       */
 662      private function get_editor_options() {
 663          global $COURSE;
 664  
 665          return [
 666              'subdirs' => 1,
 667              'maxbytes' => $COURSE->maxbytes,
 668              'accepted_types' => '*',
 669              'context' => $this->assignment->get_context(),
 670              'maxfiles' => EDITOR_UNLIMITED_FILES
 671          ];
 672      }
 673  }