"Fossies" - the Fresh Open Source Software Archive

Member "moodle/mod/assign/submission/onlinetext/locallib.php" (6 Sep 2019, 28732 Bytes) of package /linux/www/moodle-3.6.6.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "locallib.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.6.5_vs_3.6.6.

    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 onlinetext submission plugin
   19  *
   20  * This class provides all the functionality for the new assign module.
   21  *
   22  * @package assignsubmission_onlinetext
   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 defined('MOODLE_INTERNAL') || die();
   28 // File area for online text submission assignment.
   29 define('ASSIGNSUBMISSION_ONLINETEXT_FILEAREA', 'submissions_onlinetext');
   30 
   31 /**
   32  * library class for onlinetext submission plugin extending submission plugin base class
   33  *
   34  * @package assignsubmission_onlinetext
   35  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
   36  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
   37  */
   38 class assign_submission_onlinetext extends assign_submission_plugin {
   39 
   40     /**
   41      * Get the name of the online text submission plugin
   42      * @return string
   43      */
   44     public function get_name() {
   45         return get_string('onlinetext', 'assignsubmission_onlinetext');
   46     }
   47 
   48 
   49     /**
   50      * Get onlinetext submission information from the database
   51      *
   52      * @param  int $submissionid
   53      * @return mixed
   54      */
   55     private function get_onlinetext_submission($submissionid) {
   56         global $DB;
   57 
   58         return $DB->get_record('assignsubmission_onlinetext', array('submission'=>$submissionid));
   59     }
   60 
   61     /**
   62      * Get the settings for onlinetext submission plugin
   63      *
   64      * @param MoodleQuickForm $mform The form to add elements to
   65      * @return void
   66      */
   67     public function get_settings(MoodleQuickForm $mform) {
   68         global $CFG, $COURSE;
   69 
   70         $defaultwordlimit = $this->get_config('wordlimit') == 0 ? '' : $this->get_config('wordlimit');
   71         $defaultwordlimitenabled = $this->get_config('wordlimitenabled');
   72 
   73         $options = array('size' => '6', 'maxlength' => '6');
   74         $name = get_string('wordlimit', 'assignsubmission_onlinetext');
   75 
   76         // Create a text box that can be enabled/disabled for onlinetext word limit.
   77         $wordlimitgrp = array();
   78         $wordlimitgrp[] = $mform->createElement('text', 'assignsubmission_onlinetext_wordlimit', '', $options);
   79         $wordlimitgrp[] = $mform->createElement('checkbox', 'assignsubmission_onlinetext_wordlimit_enabled',
   80                 '', get_string('enable'));
   81         $mform->addGroup($wordlimitgrp, 'assignsubmission_onlinetext_wordlimit_group', $name, ' ', false);
   82         $mform->addHelpButton('assignsubmission_onlinetext_wordlimit_group',
   83                               'wordlimit',
   84                               'assignsubmission_onlinetext');
   85         $mform->disabledIf('assignsubmission_onlinetext_wordlimit',
   86                            'assignsubmission_onlinetext_wordlimit_enabled',
   87                            'notchecked');
   88 
   89         // Add numeric rule to text field.
   90         $wordlimitgrprules = array();
   91         $wordlimitgrprules['assignsubmission_onlinetext_wordlimit'][] = array(null, 'numeric', null, 'client');
   92         $mform->addGroupRule('assignsubmission_onlinetext_wordlimit_group', $wordlimitgrprules);
   93 
   94         // Rest of group setup.
   95         $mform->setDefault('assignsubmission_onlinetext_wordlimit', $defaultwordlimit);
   96         $mform->setDefault('assignsubmission_onlinetext_wordlimit_enabled', $defaultwordlimitenabled);
   97         $mform->setType('assignsubmission_onlinetext_wordlimit', PARAM_INT);
   98         $mform->disabledIf('assignsubmission_onlinetext_wordlimit_group',
   99                            'assignsubmission_onlinetext_enabled',
  100                            'notchecked');
  101     }
  102 
  103     /**
  104      * Save the settings for onlinetext submission plugin
  105      *
  106      * @param stdClass $data
  107      * @return bool
  108      */
  109     public function save_settings(stdClass $data) {
  110         if (empty($data->assignsubmission_onlinetext_wordlimit) || empty($data->assignsubmission_onlinetext_wordlimit_enabled)) {
  111             $wordlimit = 0;
  112             $wordlimitenabled = 0;
  113         } else {
  114             $wordlimit = $data->assignsubmission_onlinetext_wordlimit;
  115             $wordlimitenabled = 1;
  116         }
  117 
  118         $this->set_config('wordlimit', $wordlimit);
  119         $this->set_config('wordlimitenabled', $wordlimitenabled);
  120 
  121         return true;
  122     }
  123 
  124     /**
  125      * Add form elements for settings
  126      *
  127      * @param mixed $submission can be null
  128      * @param MoodleQuickForm $mform
  129      * @param stdClass $data
  130      * @return true if elements were added to the form
  131      */
  132     public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) {
  133         $elements = array();
  134 
  135         $editoroptions = $this->get_edit_options();
  136         $submissionid = $submission ? $submission->id : 0;
  137 
  138         if (!isset($data->onlinetext)) {
  139             $data->onlinetext = '';
  140         }
  141         if (!isset($data->onlinetextformat)) {
  142             $data->onlinetextformat = editors_get_preferred_format();
  143         }
  144 
  145         if ($submission) {
  146             $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  147             if ($onlinetextsubmission) {
  148                 $data->onlinetext = $onlinetextsubmission->onlinetext;
  149                 $data->onlinetextformat = $onlinetextsubmission->onlineformat;
  150             }
  151 
  152         }
  153 
  154         $data = file_prepare_standard_editor($data,
  155                                              'onlinetext',
  156                                              $editoroptions,
  157                                              $this->assignment->get_context(),
  158                                              'assignsubmission_onlinetext',
  159                                              ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  160                                              $submissionid);
  161         $mform->addElement('editor', 'onlinetext_editor', $this->get_name(), null, $editoroptions);
  162 
  163         return true;
  164     }
  165 
  166     /**
  167      * Editor format options
  168      *
  169      * @return array
  170      */
  171     private function get_edit_options() {
  172         $editoroptions = array(
  173             'noclean' => false,
  174             'maxfiles' => EDITOR_UNLIMITED_FILES,
  175             'maxbytes' => $this->assignment->get_course()->maxbytes,
  176             'context' => $this->assignment->get_context(),
  177             'return_types' => (FILE_INTERNAL | FILE_EXTERNAL | FILE_CONTROLLED_LINK),
  178             'removeorphaneddrafts' => true // Whether or not to remove any draft files which aren't referenced in the text.
  179         );
  180         return $editoroptions;
  181     }
  182 
  183     /**
  184      * Save data to the database and trigger plagiarism plugin,
  185      * if enabled, to scan the uploaded content via events trigger
  186      *
  187      * @param stdClass $submission
  188      * @param stdClass $data
  189      * @return bool
  190      */
  191     public function save(stdClass $submission, stdClass $data) {
  192         global $USER, $DB;
  193 
  194         $editoroptions = $this->get_edit_options();
  195 
  196         $data = file_postupdate_standard_editor($data,
  197                                                 'onlinetext',
  198                                                 $editoroptions,
  199                                                 $this->assignment->get_context(),
  200                                                 'assignsubmission_onlinetext',
  201                                                 ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  202                                                 $submission->id);
  203 
  204         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  205 
  206         $fs = get_file_storage();
  207 
  208         $files = $fs->get_area_files($this->assignment->get_context()->id,
  209                                      'assignsubmission_onlinetext',
  210                                      ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  211                                      $submission->id,
  212                                      'id',
  213                                      false);
  214 
  215         // Check word count before submitting anything.
  216         $exceeded = $this->check_word_count(trim($data->onlinetext));
  217         if ($exceeded) {
  218             $this->set_error($exceeded);
  219             return false;
  220         }
  221 
  222         $params = array(
  223             'context' => context_module::instance($this->assignment->get_course_module()->id),
  224             'courseid' => $this->assignment->get_course()->id,
  225             'objectid' => $submission->id,
  226             'other' => array(
  227                 'pathnamehashes' => array_keys($files),
  228                 'content' => trim($data->onlinetext),
  229                 'format' => $data->onlinetext_editor['format']
  230             )
  231         );
  232         if (!empty($submission->userid) && ($submission->userid != $USER->id)) {
  233             $params['relateduserid'] = $submission->userid;
  234         }
  235         if ($this->assignment->is_blind_marking()) {
  236             $params['anonymous'] = 1;
  237         }
  238         $event = \assignsubmission_onlinetext\event\assessable_uploaded::create($params);
  239         $event->trigger();
  240 
  241         $groupname = null;
  242         $groupid = 0;
  243         // Get the group name as other fields are not transcribed in the logs and this information is important.
  244         if (empty($submission->userid) && !empty($submission->groupid)) {
  245             $groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), MUST_EXIST);
  246             $groupid = $submission->groupid;
  247         } else {
  248             $params['relateduserid'] = $submission->userid;
  249         }
  250 
  251         $count = count_words($data->onlinetext);
  252 
  253         // Unset the objectid and other field from params for use in submission events.
  254         unset($params['objectid']);
  255         unset($params['other']);
  256         $params['other'] = array(
  257             'submissionid' => $submission->id,
  258             'submissionattempt' => $submission->attemptnumber,
  259             'submissionstatus' => $submission->status,
  260             'onlinetextwordcount' => $count,
  261             'groupid' => $groupid,
  262             'groupname' => $groupname
  263         );
  264 
  265         if ($onlinetextsubmission) {
  266 
  267             $onlinetextsubmission->onlinetext = $data->onlinetext;
  268             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
  269             $params['objectid'] = $onlinetextsubmission->id;
  270             $updatestatus = $DB->update_record('assignsubmission_onlinetext', $onlinetextsubmission);
  271             $event = \assignsubmission_onlinetext\event\submission_updated::create($params);
  272             $event->set_assign($this->assignment);
  273             $event->trigger();
  274             return $updatestatus;
  275         } else {
  276 
  277             $onlinetextsubmission = new stdClass();
  278             $onlinetextsubmission->onlinetext = $data->onlinetext;
  279             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
  280 
  281             $onlinetextsubmission->submission = $submission->id;
  282             $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
  283             $onlinetextsubmission->id = $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission);
  284             $params['objectid'] = $onlinetextsubmission->id;
  285             $event = \assignsubmission_onlinetext\event\submission_created::create($params);
  286             $event->set_assign($this->assignment);
  287             $event->trigger();
  288             return $onlinetextsubmission->id > 0;
  289         }
  290     }
  291 
  292     /**
  293      * Return a list of the text fields that can be imported/exported by this plugin
  294      *
  295      * @return array An array of field names and descriptions. (name=>description, ...)
  296      */
  297     public function get_editor_fields() {
  298         return array('onlinetext' => get_string('pluginname', 'assignsubmission_onlinetext'));
  299     }
  300 
  301     /**
  302      * Get the saved text content from the editor
  303      *
  304      * @param string $name
  305      * @param int $submissionid
  306      * @return string
  307      */
  308     public function get_editor_text($name, $submissionid) {
  309         if ($name == 'onlinetext') {
  310             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
  311             if ($onlinetextsubmission) {
  312                 return $onlinetextsubmission->onlinetext;
  313             }
  314         }
  315 
  316         return '';
  317     }
  318 
  319     /**
  320      * Get the content format for the editor
  321      *
  322      * @param string $name
  323      * @param int $submissionid
  324      * @return int
  325      */
  326     public function get_editor_format($name, $submissionid) {
  327         if ($name == 'onlinetext') {
  328             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
  329             if ($onlinetextsubmission) {
  330                 return $onlinetextsubmission->onlineformat;
  331             }
  332         }
  333 
  334         return 0;
  335     }
  336 
  337 
  338      /**
  339       * Display onlinetext word count in the submission status table
  340       *
  341       * @param stdClass $submission
  342       * @param bool $showviewlink - If the summary has been truncated set this to true
  343       * @return string
  344       */
  345     public function view_summary(stdClass $submission, & $showviewlink) {
  346         global $CFG;
  347 
  348         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  349         // Always show the view link.
  350         $showviewlink = true;
  351 
  352         if ($onlinetextsubmission) {
  353             // This contains the shortened version of the text plus an optional 'Export to portfolio' button.
  354             $text = $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  355                                                              $onlinetextsubmission->submission,
  356                                                              $this->get_type(),
  357                                                              'onlinetext',
  358                                                              'assignsubmission_onlinetext', true);
  359 
  360             // The actual submission text.
  361             $onlinetext = trim($onlinetextsubmission->onlinetext);
  362             // The shortened version of the submission text.
  363             $shorttext = shorten_text($onlinetext, 140);
  364 
  365             $plagiarismlinks = '';
  366 
  367             if (!empty($CFG->enableplagiarism)) {
  368                 require_once($CFG->libdir . '/plagiarismlib.php');
  369 
  370                 $plagiarismlinks .= plagiarism_get_links(array('userid' => $submission->userid,
  371                     'content' => $onlinetext,
  372                     'cmid' => $this->assignment->get_course_module()->id,
  373                     'course' => $this->assignment->get_course()->id,
  374                     'assignment' => $submission->assignment));
  375             }
  376             // We compare the actual text submission and the shortened version. If they are not equal, we show the word count.
  377             if ($onlinetext != $shorttext) {
  378                 $wordcount = get_string('numwords', 'assignsubmission_onlinetext', count_words($onlinetext));
  379 
  380                 return $plagiarismlinks . $wordcount . $text;
  381             } else {
  382                 return $plagiarismlinks . $text;
  383             }
  384         }
  385         return '';
  386     }
  387 
  388     /**
  389      * Produce a list of files suitable for export that represent this submission.
  390      *
  391      * @param stdClass $submission - For this is the submission data
  392      * @param stdClass $user - This is the user record for this submission
  393      * @return array - return an array of files indexed by filename
  394      */
  395     public function get_files(stdClass $submission, stdClass $user) {
  396         global $DB;
  397 
  398         $files = array();
  399         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  400 
  401         // Note that this check is the same logic as the result from the is_empty function but we do
  402         // not call it directly because we already have the submission record.
  403         if ($onlinetextsubmission) {
  404             // Do not pass the text through format_text. The result may not be displayed in Moodle and
  405             // may be passed to external services such as document conversion or portfolios.
  406             $formattedtext = $this->assignment->download_rewrite_pluginfile_urls($onlinetextsubmission->onlinetext, $user, $this);
  407             $head = '<head><meta charset="UTF-8"></head>';
  408             $submissioncontent = '<!DOCTYPE html><html>' . $head . '<body>'. $formattedtext . '</body></html>';
  409 
  410             $filename = get_string('onlinetextfilename', 'assignsubmission_onlinetext');
  411             $files[$filename] = array($submissioncontent);
  412 
  413             $fs = get_file_storage();
  414 
  415             $fsfiles = $fs->get_area_files($this->assignment->get_context()->id,
  416                                            'assignsubmission_onlinetext',
  417                                            ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  418                                            $submission->id,
  419                                            'timemodified',
  420                                            false);
  421 
  422             foreach ($fsfiles as $file) {
  423                 $files[$file->get_filename()] = $file;
  424             }
  425         }
  426 
  427         return $files;
  428     }
  429 
  430     /**
  431      * Display the saved text content from the editor in the view table
  432      *
  433      * @param stdClass $submission
  434      * @return string
  435      */
  436     public function view(stdClass $submission) {
  437         global $CFG;
  438         $result = '';
  439 
  440         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  441 
  442         if ($onlinetextsubmission) {
  443 
  444             // Render for portfolio API.
  445             $result .= $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  446                                                                 $onlinetextsubmission->submission,
  447                                                                 $this->get_type(),
  448                                                                 'onlinetext',
  449                                                                 'assignsubmission_onlinetext');
  450 
  451             $plagiarismlinks = '';
  452 
  453             if (!empty($CFG->enableplagiarism)) {
  454                 require_once($CFG->libdir . '/plagiarismlib.php');
  455 
  456                 $plagiarismlinks .= plagiarism_get_links(array('userid' => $submission->userid,
  457                     'content' => trim($onlinetextsubmission->onlinetext),
  458                     'cmid' => $this->assignment->get_course_module()->id,
  459                     'course' => $this->assignment->get_course()->id,
  460                     'assignment' => $submission->assignment));
  461             }
  462         }
  463 
  464         return $plagiarismlinks . $result;
  465     }
  466 
  467     /**
  468      * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type and version.
  469      *
  470      * @param string $type old assignment subtype
  471      * @param int $version old assignment version
  472      * @return bool True if upgrade is possible
  473      */
  474     public function can_upgrade($type, $version) {
  475         if ($type == 'online' && $version >= 2011112900) {
  476             return true;
  477         }
  478         return false;
  479     }
  480 
  481 
  482     /**
  483      * Upgrade the settings from the old assignment to the new plugin based one
  484      *
  485      * @param context $oldcontext - the database for the old assignment context
  486      * @param stdClass $oldassignment - the database for the old assignment instance
  487      * @param string $log record log events here
  488      * @return bool Was it a success?
  489      */
  490     public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
  491         // No settings to upgrade.
  492         return true;
  493     }
  494 
  495     /**
  496      * Upgrade the submission from the old assignment to the new one
  497      *
  498      * @param context $oldcontext - the database for the old assignment context
  499      * @param stdClass $oldassignment The data record for the old assignment
  500      * @param stdClass $oldsubmission The data record for the old submission
  501      * @param stdClass $submission The data record for the new submission
  502      * @param string $log Record upgrade messages in the log
  503      * @return bool true or false - false will trigger a rollback
  504      */
  505     public function upgrade(context $oldcontext,
  506                             stdClass $oldassignment,
  507                             stdClass $oldsubmission,
  508                             stdClass $submission,
  509                             & $log) {
  510         global $DB;
  511 
  512         $onlinetextsubmission = new stdClass();
  513         $onlinetextsubmission->onlinetext = $oldsubmission->data1;
  514         $onlinetextsubmission->onlineformat = $oldsubmission->data2;
  515 
  516         $onlinetextsubmission->submission = $submission->id;
  517         $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
  518 
  519         if ($onlinetextsubmission->onlinetext === null) {
  520             $onlinetextsubmission->onlinetext = '';
  521         }
  522 
  523         if ($onlinetextsubmission->onlineformat === null) {
  524             $onlinetextsubmission->onlineformat = editors_get_preferred_format();
  525         }
  526 
  527         if (!$DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0) {
  528             $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid);
  529             return false;
  530         }
  531 
  532         // Now copy the area files.
  533         $this->assignment->copy_area_files_for_upgrade($oldcontext->id,
  534                                                         'mod_assignment',
  535                                                         'submission',
  536                                                         $oldsubmission->id,
  537                                                         $this->assignment->get_context()->id,
  538                                                         'assignsubmission_onlinetext',
  539                                                         ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
  540                                                         $submission->id);
  541         return true;
  542     }
  543 
  544     /**
  545      * Formatting for log info
  546      *
  547      * @param stdClass $submission The new submission
  548      * @return string
  549      */
  550     public function format_for_log(stdClass $submission) {
  551         // Format the info for each submission plugin (will be logged).
  552         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  553         $onlinetextloginfo = '';
  554         $onlinetextloginfo .= get_string('numwordsforlog',
  555                                          'assignsubmission_onlinetext',
  556                                          count_words($onlinetextsubmission->onlinetext));
  557 
  558         return $onlinetextloginfo;
  559     }
  560 
  561     /**
  562      * The assignment has been deleted - cleanup
  563      *
  564      * @return bool
  565      */
  566     public function delete_instance() {
  567         global $DB;
  568         $DB->delete_records('assignsubmission_onlinetext',
  569                             array('assignment'=>$this->assignment->get_instance()->id));
  570 
  571         return true;
  572     }
  573 
  574     /**
  575      * No text is set for this plugin
  576      *
  577      * @param stdClass $submission
  578      * @return bool
  579      */
  580     public function is_empty(stdClass $submission) {
  581         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
  582         $wordcount = 0;
  583         $hasinsertedresources = false;
  584 
  585         if (isset($onlinetextsubmission->onlinetext)) {
  586             $wordcount = count_words(trim($onlinetextsubmission->onlinetext));
  587             // Check if the online text submission contains video, audio or image elements
  588             // that can be ignored and stripped by count_words().
  589             $hasinsertedresources = preg_match('/<\s*((video|audio)[^>]*>(.*?)<\s*\/\s*(video|audio)>)|(img[^>]*>(.*?))/',
  590                     trim($onlinetextsubmission->onlinetext));
  591         }
  592 
  593         return $wordcount == 0 && !$hasinsertedresources;
  594     }
  595 
  596     /**
  597      * Determine if a submission is empty
  598      *
  599      * This is distinct from is_empty in that it is intended to be used to
  600      * determine if a submission made before saving is empty.
  601      *
  602      * @param stdClass $data The submission data
  603      * @return bool
  604      */
  605     public function submission_is_empty(stdClass $data) {
  606         if (!isset($data->onlinetext_editor)) {
  607             return true;
  608         }
  609         $wordcount = 0;
  610         $hasinsertedresources = false;
  611 
  612         if (isset($data->onlinetext_editor['text'])) {
  613             $wordcount = count_words(trim((string)$data->onlinetext_editor['text']));
  614             // Check if the online text submission contains video, audio or image elements
  615             // that can be ignored and stripped by count_words().
  616             $hasinsertedresources = preg_match('/<\s*((video|audio)[^>]*>(.*?)<\s*\/\s*(video|audio)>)|(img[^>]*>(.*?))/',
  617                     trim((string)$data->onlinetext_editor['text']));
  618         }
  619 
  620         return $wordcount == 0 && !$hasinsertedresources;
  621     }
  622 
  623     /**
  624      * Get file areas returns a list of areas this plugin stores files
  625      * @return array - An array of fileareas (keys) and descriptions (values)
  626      */
  627     public function get_file_areas() {
  628         return array(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA=>$this->get_name());
  629     }
  630 
  631     /**
  632      * Copy the student's submission from a previous submission. Used when a student opts to base their resubmission
  633      * on the last submission.
  634      * @param stdClass $sourcesubmission
  635      * @param stdClass $destsubmission
  636      */
  637     public function copy_submission(stdClass $sourcesubmission, stdClass $destsubmission) {
  638         global $DB;
  639 
  640         // Copy the files across (attached via the text editor).
  641         $contextid = $this->assignment->get_context()->id;
  642         $fs = get_file_storage();
  643         $files = $fs->get_area_files($contextid, 'assignsubmission_onlinetext',
  644                                      ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $sourcesubmission->id, 'id', false);
  645         foreach ($files as $file) {
  646             $fieldupdates = array('itemid' => $destsubmission->id);
  647             $fs->create_file_from_storedfile($fieldupdates, $file);
  648         }
  649 
  650         // Copy the assignsubmission_onlinetext record.
  651         $onlinetextsubmission = $this->get_onlinetext_submission($sourcesubmission->id);
  652         if ($onlinetextsubmission) {
  653             unset($onlinetextsubmission->id);
  654             $onlinetextsubmission->submission = $destsubmission->id;
  655             $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission);
  656         }
  657         return true;
  658     }
  659 
  660     /**
  661      * Return a description of external params suitable for uploading an onlinetext submission from a webservice.
  662      *
  663      * @return external_description|null
  664      */
  665     public function get_external_parameters() {
  666         $editorparams = array('text' => new external_value(PARAM_RAW, 'The text for this submission.'),
  667                               'format' => new external_value(PARAM_INT, 'The format for this submission'),
  668                               'itemid' => new external_value(PARAM_INT, 'The draft area id for files attached to the submission'));
  669         $editorstructure = new external_single_structure($editorparams, 'Editor structure', VALUE_OPTIONAL);
  670         return array('onlinetext_editor' => $editorstructure);
  671     }
  672 
  673     /**
  674      * Compare word count of onlinetext submission to word limit, and return result.
  675      *
  676      * @param string $submissiontext Onlinetext submission text from editor
  677      * @return string Error message if limit is enabled and exceeded, otherwise null
  678      */
  679     public function check_word_count($submissiontext) {
  680         global $OUTPUT;
  681 
  682         $wordlimitenabled = $this->get_config('wordlimitenabled');
  683         $wordlimit = $this->get_config('wordlimit');
  684 
  685         if ($wordlimitenabled == 0) {
  686             return null;
  687         }
  688 
  689         // Count words and compare to limit.
  690         $wordcount = count_words($submissiontext);
  691         if ($wordcount <= $wordlimit) {
  692             return null;
  693         } else {
  694             $errormsg = get_string('wordlimitexceeded', 'assignsubmission_onlinetext',
  695                     array('limit' => $wordlimit, 'count' => $wordcount));
  696             return $OUTPUT->error_text($errormsg);
  697         }
  698     }
  699 
  700     /**
  701      * Return the plugin configs for external functions.
  702      *
  703      * @return array the list of settings
  704      * @since Moodle 3.2
  705      */
  706     public function get_config_for_external() {
  707         return (array) $this->get_config();
  708     }
  709 }
  710 
  711