87fcc1938ecba6d9f332982fcf5c8d3f3761cee8
[moodle.git] / mod / assign / submission / onlinetext / locallib.php
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/>.
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  */
27 defined('MOODLE_INTERNAL') || die();
28 // File area for online text submission assignment.
29 define('ASSIGNSUBMISSION_ONLINETEXT_FILEAREA', 'submissions_onlinetext');
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 {
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     }
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;
58         return $DB->get_record('assignsubmission_onlinetext', array('submission'=>$submissionid));
59     }
61     /**
62      * Add form elements for settings
63      *
64      * @param mixed $submission can be null
65      * @param MoodleQuickForm $mform
66      * @param stdClass $data
67      * @return true if elements were added to the form
68      */
69     public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) {
70         $elements = array();
72         $editoroptions = $this->get_edit_options();
73         $submissionid = $submission ? $submission->id : 0;
75         if (!isset($data->onlinetext)) {
76             $data->onlinetext = '';
77         }
78         if (!isset($data->onlinetextformat)) {
79             $data->onlinetextformat = editors_get_preferred_format();
80         }
82         if ($submission) {
83             $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
84             if ($onlinetextsubmission) {
85                 $data->onlinetext = $onlinetextsubmission->onlinetext;
86                 $data->onlinetextformat = $onlinetextsubmission->onlineformat;
87             }
89         }
91         $data = file_prepare_standard_editor($data,
92                                              'onlinetext',
93                                              $editoroptions,
94                                              $this->assignment->get_context(),
95                                              'assignsubmission_onlinetext',
96                                              ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
97                                              $submissionid);
98         $mform->addElement('editor', 'onlinetext_editor', html_writer::tag('span', $this->get_name(),
99             array('class' => 'accesshide')), null, $editoroptions);
101         return true;
102     }
104     /**
105      * Editor format options
106      *
107      * @return array
108      */
109     private function get_edit_options() {
110          $editoroptions = array(
111            'noclean' => false,
112            'maxfiles' => EDITOR_UNLIMITED_FILES,
113            'maxbytes' => $this->assignment->get_course()->maxbytes,
114            'context' => $this->assignment->get_context(),
115            'return_types' => FILE_INTERNAL | FILE_EXTERNAL
116         );
117         return $editoroptions;
118     }
120     /**
121      * Save data to the database and trigger plagiarism plugin,
122      * if enabled, to scan the uploaded content via events trigger
123      *
124      * @param stdClass $submission
125      * @param stdClass $data
126      * @return bool
127      */
128     public function save(stdClass $submission, stdClass $data) {
129         global $USER, $DB;
131         $editoroptions = $this->get_edit_options();
133         $data = file_postupdate_standard_editor($data,
134                                                 'onlinetext',
135                                                 $editoroptions,
136                                                 $this->assignment->get_context(),
137                                                 'assignsubmission_onlinetext',
138                                                 ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
139                                                 $submission->id);
141         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
143         $text = format_text($data->onlinetext,
144                             $data->onlinetext_editor['format'],
145                             array('context'=>$this->assignment->get_context()));
147         $fs = get_file_storage();
149         $files = $fs->get_area_files($this->assignment->get_context()->id,
150                                      'assignsubmission_onlinetext',
151                                      ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
152                                      $submission->id,
153                                      'id',
154                                      false);
156         $params = array(
157             'context' => context_module::instance($this->assignment->get_course_module()->id),
158             'objectid' => $submission->id,
159             'other' => array(
160                 'pathnamehashes' => array_keys($files),
161                 'content' => trim($text)
162             )
163         );
164         $event = \assignsubmission_onlinetext\event\assessable_uploaded::create($params);
165         $event->trigger();
167         if ($onlinetextsubmission) {
169             $onlinetextsubmission->onlinetext = $data->onlinetext;
170             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
172             return $DB->update_record('assignsubmission_onlinetext', $onlinetextsubmission);
173         } else {
175             $onlinetextsubmission = new stdClass();
176             $onlinetextsubmission->onlinetext = $data->onlinetext;
177             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
179             $onlinetextsubmission->submission = $submission->id;
180             $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
181             return $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0;
182         }
183     }
185     /**
186      * Return a list of the text fields that can be imported/exported by this plugin
187      *
188      * @return array An array of field names and descriptions. (name=>description, ...)
189      */
190     public function get_editor_fields() {
191         return array('onlinetext' => get_string('pluginname', 'assignsubmission_comments'));
192     }
194     /**
195      * Get the saved text content from the editor
196      *
197      * @param string $name
198      * @param int $submissionid
199      * @return string
200      */
201     public function get_editor_text($name, $submissionid) {
202         if ($name == 'onlinetext') {
203             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
204             if ($onlinetextsubmission) {
205                 return $onlinetextsubmission->onlinetext;
206             }
207         }
209         return '';
210     }
212     /**
213      * Get the content format for the editor
214      *
215      * @param string $name
216      * @param int $submissionid
217      * @return int
218      */
219     public function get_editor_format($name, $submissionid) {
220         if ($name == 'onlinetext') {
221             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
222             if ($onlinetextsubmission) {
223                 return $onlinetextsubmission->onlineformat;
224             }
225         }
227         return 0;
228     }
231      /**
232       * Display onlinetext word count in the submission status table
233       *
234       * @param stdClass $submission
235       * @param bool $showviewlink - If the summary has been truncated set this to true
236       * @return string
237       */
238     public function view_summary(stdClass $submission, & $showviewlink) {
239         global $CFG;
241         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
242         // Always show the view link.
243         $showviewlink = true;
245         if ($onlinetextsubmission) {
246             $text = $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
247                                                              $onlinetextsubmission->submission,
248                                                              $this->get_type(),
249                                                              'onlinetext',
250                                                              'assignsubmission_onlinetext');
252             $shorttext = shorten_text($text, 140);
253             $plagiarismlinks = '';
255             if (!empty($CFG->enableplagiarism)) {
256                 require_once($CFG->libdir . '/plagiarismlib.php');
258                 $plagiarismlinks .= plagiarism_get_links(array('userid' => $submission->userid,
259                     'content' => trim($text),
260                     'cmid' => $this->assignment->get_course_module()->id,
261                     'course' => $this->assignment->get_course()->id,
262                     'assignment' => $submission->assignment));
263             }
264             if ($text != $shorttext) {
265                 $wordcount = get_string('numwords', 'assignsubmission_onlinetext', count_words($text));
267                 return $shorttext . $plagiarismlinks . $wordcount;
268             } else {
269                 return $shorttext . $plagiarismlinks;
270             }
271         }
272         return '';
273     }
275     /**
276      * Produce a list of files suitable for export that represent this submission.
277      *
278      * @param stdClass $submission - For this is the submission data
279      * @param stdClass $user - This is the user record for this submission
280      * @return array - return an array of files indexed by filename
281      */
282     public function get_files(stdClass $submission, stdClass $user) {
283         global $DB;
285         $files = array();
286         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
288         if ($onlinetextsubmission) {
289             $finaltext = $this->assignment->download_rewrite_pluginfile_urls($onlinetextsubmission->onlinetext, $user, $this);
290             $formattedtext = format_text($finaltext,
291                                          $onlinetextsubmission->onlineformat,
292                                          array('context'=>$this->assignment->get_context()));
293             $submissioncontent = '<html><body>'. $formattedtext . '</body></html>';
295             $filename = get_string('onlinetextfilename', 'assignsubmission_onlinetext');
296             $files[$filename] = array($submissioncontent);
298             $fs = get_file_storage();
300             $fsfiles = $fs->get_area_files($this->assignment->get_context()->id,
301                                            'assignsubmission_onlinetext',
302                                            ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
303                                            $submission->id,
304                                            'timemodified',
305                                            false);
307             foreach ($fsfiles as $file) {
308                 $files[$file->get_filename()] = $file;
309             }
310         }
312         return $files;
313     }
315     /**
316      * Display the saved text content from the editor in the view table
317      *
318      * @param stdClass $submission
319      * @return string
320      */
321     public function view(stdClass $submission) {
322         $result = '';
324         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
326         if ($onlinetextsubmission) {
328             // Render for portfolio API.
329             $result .= $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
330                                                                 $onlinetextsubmission->submission,
331                                                                 $this->get_type(),
332                                                                 'onlinetext',
333                                                                 'assignsubmission_onlinetext');
335         }
337         return $result;
338     }
340     /**
341      * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type and version.
342      *
343      * @param string $type old assignment subtype
344      * @param int $version old assignment version
345      * @return bool True if upgrade is possible
346      */
347     public function can_upgrade($type, $version) {
348         if ($type == 'online' && $version >= 2011112900) {
349             return true;
350         }
351         return false;
352     }
355     /**
356      * Upgrade the settings from the old assignment to the new plugin based one
357      *
358      * @param context $oldcontext - the database for the old assignment context
359      * @param stdClass $oldassignment - the database for the old assignment instance
360      * @param string $log record log events here
361      * @return bool Was it a success?
362      */
363     public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
364         // No settings to upgrade.
365         return true;
366     }
368     /**
369      * Upgrade the submission from the old assignment to the new one
370      *
371      * @param context $oldcontext - the database for the old assignment context
372      * @param stdClass $oldassignment The data record for the old assignment
373      * @param stdClass $oldsubmission The data record for the old submission
374      * @param stdClass $submission The data record for the new submission
375      * @param string $log Record upgrade messages in the log
376      * @return bool true or false - false will trigger a rollback
377      */
378     public function upgrade(context $oldcontext,
379                             stdClass $oldassignment,
380                             stdClass $oldsubmission,
381                             stdClass $submission,
382                             & $log) {
383         global $DB;
385         $onlinetextsubmission = new stdClass();
386         $onlinetextsubmission->onlinetext = $oldsubmission->data1;
387         $onlinetextsubmission->onlineformat = $oldsubmission->data2;
389         $onlinetextsubmission->submission = $submission->id;
390         $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
392         if ($onlinetextsubmission->onlinetext === null) {
393             $onlinetextsubmission->onlinetext = '';
394         }
396         if ($onlinetextsubmission->onlineformat === null) {
397             $onlinetextsubmission->onlineformat = editors_get_preferred_format();
398         }
400         if (!$DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0) {
401             $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid);
402             return false;
403         }
405         // Now copy the area files.
406         $this->assignment->copy_area_files_for_upgrade($oldcontext->id,
407                                                         'mod_assignment',
408                                                         'submission',
409                                                         $oldsubmission->id,
410                                                         $this->assignment->get_context()->id,
411                                                         'assignsubmission_onlinetext',
412                                                         ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
413                                                         $submission->id);
414         return true;
415     }
417     /**
418      * Formatting for log info
419      *
420      * @param stdClass $submission The new submission
421      * @return string
422      */
423     public function format_for_log(stdClass $submission) {
424         // Format the info for each submission plugin (will be logged).
425         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
426         $onlinetextloginfo = '';
427         $text = format_text($onlinetextsubmission->onlinetext,
428                             $onlinetextsubmission->onlineformat,
429                             array('context'=>$this->assignment->get_context()));
430         $onlinetextloginfo .= get_string('numwordsforlog',
431                                          'assignsubmission_onlinetext',
432                                          count_words($text));
434         return $onlinetextloginfo;
435     }
437     /**
438      * The assignment has been deleted - cleanup
439      *
440      * @return bool
441      */
442     public function delete_instance() {
443         global $DB;
444         $DB->delete_records('assignsubmission_onlinetext',
445                             array('assignment'=>$this->assignment->get_instance()->id));
447         return true;
448     }
450     /**
451      * No text is set for this plugin
452      *
453      * @param stdClass $submission
454      * @return bool
455      */
456     public function is_empty(stdClass $submission) {
457         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
459         return empty($onlinetextsubmission->onlinetext);
460     }
462     /**
463      * Get file areas returns a list of areas this plugin stores files
464      * @return array - An array of fileareas (keys) and descriptions (values)
465      */
466     public function get_file_areas() {
467         return array(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA=>$this->get_name());
468     }
470     /**
471      * Copy the student's submission from a previous submission. Used when a student opts to base their resubmission
472      * on the last submission.
473      * @param stdClass $sourcesubmission
474      * @param stdClass $destsubmission
475      */
476     public function copy_submission(stdClass $sourcesubmission, stdClass $destsubmission) {
477         global $DB;
479         // Copy the files across (attached via the text editor).
480         $contextid = $this->assignment->get_context()->id;
481         $fs = get_file_storage();
482         $files = $fs->get_area_files($contextid, 'assignsubmission_onlinetext',
483                                      ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $sourcesubmission->id, 'id', false);
484         foreach ($files as $file) {
485             $fieldupdates = array('itemid' => $destsubmission->id);
486             $fs->create_file_from_storedfile($fieldupdates, $file);
487         }
489         // Copy the assignsubmission_onlinetext record.
490         $onlinetextsubmission = $this->get_onlinetext_submission($sourcesubmission->id);
491         if ($onlinetextsubmission) {
492             unset($onlinetextsubmission->id);
493             $onlinetextsubmission->submission = $destsubmission->id;
494             $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission);
495         }
496         return true;
497     }
499     /**
500      * Return a description of external params suitable for uploading an onlinetext submission from a webservice.
501      *
502      * @return external_description|null
503      */
504     public function get_external_parameters() {
505         $editorparams = array('text' => new external_value(PARAM_TEXT, 'The text for this submission.'),
506                               'format' => new external_value(PARAM_INT, 'The format for this submission'),
507                               'itemid' => new external_value(PARAM_INT, 'The draft area id for files attached to the submission'));
508         $editorstructure = new external_single_structure($editorparams);
509         return array('onlinetext_editor' => $editorstructure);
510     }