MDL-37030 Assignment: Fix error on download all submissions.
[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 /**
29  * File area for online text submission assignment
30  */
31 define('ASSIGNSUBMISSION_ONLINETEXT_FILEAREA', 'submissions_onlinetext');
33 /**
34  * library class for onlinetext submission plugin extending submission plugin base class
35  *
36  * @package assignsubmission_onlinetext
37  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
38  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class assign_submission_onlinetext extends assign_submission_plugin {
42     /**
43      * Get the name of the online text submission plugin
44      * @return string
45      */
46     public function get_name() {
47         return get_string('onlinetext', 'assignsubmission_onlinetext');
48     }
51    /**
52     * Get onlinetext submission information from the database
53     *
54     * @param  int $submissionid
55     * @return mixed
56     */
57     private function get_onlinetext_submission($submissionid) {
58         global $DB;
60         return $DB->get_record('assignsubmission_onlinetext', array('submission'=>$submissionid));
61     }
63     /**
64      * Add form elements for settings
65      *
66      * @param mixed $submission can be null
67      * @param MoodleQuickForm $mform
68      * @param stdClass $data
69      * @return true if elements were added to the form
70      */
71     public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) {
72         $elements = array();
74         $editoroptions = $this->get_edit_options();
75         $submissionid = $submission ? $submission->id : 0;
77         if (!isset($data->onlinetext)) {
78             $data->onlinetext = '';
79         }
80         if (!isset($data->onlinetextformat)) {
81             $data->onlinetextformat = editors_get_preferred_format();
82         }
84         if ($submission) {
85             $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
86             if ($onlinetextsubmission) {
87                 $data->onlinetext = $onlinetextsubmission->onlinetext;
88                 $data->onlinetextformat = $onlinetextsubmission->onlineformat;
89             }
91         }
94         $data = file_prepare_standard_editor($data, 'onlinetext', $editoroptions, $this->assignment->get_context(), 'assignsubmission_onlinetext', ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $submissionid);
95         $mform->addElement('editor', 'onlinetext_editor', '', null, $editoroptions);
96         return true;
97     }
99     /**
100      * Editor format options
101      *
102      * @return array
103      */
104     private function get_edit_options() {
105          $editoroptions = array(
106            'noclean' => false,
107            'maxfiles' => EDITOR_UNLIMITED_FILES,
108            'maxbytes' => $this->assignment->get_course()->maxbytes,
109            'context' => $this->assignment->get_context(),
110            'return_types' => FILE_INTERNAL | FILE_EXTERNAL
111         );
112         return $editoroptions;
113     }
115      /**
116       * Save data to the database and trigger plagiarism plugin, if enabled, to scan the uploaded content via events trigger
117       *
118       * @param stdClass $submission
119       * @param stdClass $data
120       * @return bool
121       */
122      public function save(stdClass $submission, stdClass $data) {
123         global $USER, $DB;
125         $editoroptions = $this->get_edit_options();
127         $data = file_postupdate_standard_editor($data, 'onlinetext', $editoroptions, $this->assignment->get_context(), 'assignsubmission_onlinetext', ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $submission->id);
129         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
131         $fs = get_file_storage();
132         $files = $fs->get_area_files($this->assignment->get_context()->id, 'assignsubmission_onlinetext', ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $submission->id, "id", false);
133         // Let Moodle know that an assessable content was uploaded (eg for plagiarism detection)
134         $eventdata = new stdClass();
135         $eventdata->modulename = 'assign';
136         $eventdata->cmid = $this->assignment->get_course_module()->id;
137         $eventdata->itemid = $submission->id;
138         $eventdata->courseid = $this->assignment->get_course()->id;
139         $eventdata->userid = $USER->id;
140         $eventdata->content = trim(format_text($data->onlinetext, $data->onlinetext_editor['format'], array('context'=>$this->assignment->get_context())));
141         if ($files) {
142             $eventdata->pathnamehashes = array_keys($files);
143         }
144         events_trigger('assessable_content_uploaded', $eventdata);
146         if ($onlinetextsubmission) {
148             $onlinetextsubmission->onlinetext = $data->onlinetext;
149             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
152             return $DB->update_record('assignsubmission_onlinetext', $onlinetextsubmission);
153         } else {
155             $onlinetextsubmission = new stdClass();
156             $onlinetextsubmission->onlinetext = $data->onlinetext;
157             $onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
159             $onlinetextsubmission->submission = $submission->id;
160             $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
161             return $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0;
162         }
165     }
167     /**
168      * Return a list of the text fields that can be imported/exported by this plugin
169      *
170      * @return array An array of field names and descriptions. (name=>description, ...)
171      */
172     public function get_editor_fields() {
173         return array('onlinetext' => get_string('pluginname', 'assignsubmission_comments'));
174     }
176     /**
177      * Get the saved text content from the editor
178      *
179      * @param string $name
180      * @param int $submissionid
181      * @return string
182      */
183     public function get_editor_text($name, $submissionid) {
184         if ($name == 'onlinetext') {
185             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
186             if ($onlinetextsubmission) {
187                 return $onlinetextsubmission->onlinetext;
188             }
189         }
191         return '';
192     }
194     /**
195      * Get the content format for the editor
196      *
197      * @param string $name
198      * @param int $submissionid
199      * @return int
200      */
201     public function get_editor_format($name, $submissionid) {
202         if ($name == 'onlinetext') {
203             $onlinetextsubmission = $this->get_onlinetext_submission($submissionid);
204             if ($onlinetextsubmission) {
205                 return $onlinetextsubmission->onlineformat;
206             }
207         }
210          return 0;
211     }
214      /**
215       * Display onlinetext word count in the submission status table
216       *
217       * @param stdClass $submission
218       * @param bool $showviewlink - If the summary has been truncated set this to true
219       * @return string
220       */
221     public function view_summary(stdClass $submission, & $showviewlink) {
222         global $CFG;
224         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
225         // always show the view link
226         $showviewlink = true;
228         if ($onlinetextsubmission) {
229             $text = $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
230                                                              $onlinetextsubmission->submission,
231                                                              $this->get_type(),
232                                                              'onlinetext',
233                                                              'assignsubmission_onlinetext');
235             $shorttext = shorten_text($text, 140);
236             $plagiarismlinks = '';
237             if (!empty($CFG->enableplagiarism)) {
238                 require_once($CFG->libdir . '/plagiarismlib.php');
239                 $plagiarismlinks .= plagiarism_get_links(array('userid' => $submission->userid,
240                     'content' => trim(format_text($onlinetextsubmission->onlinetext, $onlinetextsubmission->onlineformat, array('context'=>$this->assignment->get_context()))),
241                     'cmid' => $this->assignment->get_course_module()->id,
242                     'course' => $this->assignment->get_course()->id,
243                     'assignment' => $submission->assignment));
244             }
245             if ($text != $shorttext) {
246                 return $shorttext . $plagiarismlinks . get_string('numwords', 'assignsubmission_onlinetext', count_words($text));
247             } else {
248                 return $shorttext . $plagiarismlinks;
249             }
250         }
251         return '';
252     }
254     /**
255      * Produce a list of files suitable for export that represent this submission
256      *
257      * @param stdClass $submission - For this is the submission data
258      * @param stdClass $user - This is the user record for this submission
259      * @return array - return an array of files indexed by filename
260      */
261     public function get_files(stdClass $submission, stdClass $user) {
262         global $DB;
263         $files = array();
264         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
265         if ($onlinetextsubmission) {
266             $finaltext = $this->assignment->download_rewrite_pluginfile_urls($onlinetextsubmission->onlinetext, $user, $this);
267             $submissioncontent = "<html><body>". format_text($finaltext, $onlinetextsubmission->onlineformat, array('context'=>$this->assignment->get_context())). "</body></html>";
269             $files[get_string('onlinetextfilename', 'assignsubmission_onlinetext')] = array($submissioncontent);
271             $fs = get_file_storage();
273             $fsfiles = $fs->get_area_files($this->assignment->get_context()->id, 'assignsubmission_onlinetext', ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $submission->id, "timemodified", false);
275             foreach ($fsfiles as $file) {
276                 $files[$file->get_filename()] = $file;
277             }
278         }
280         return $files;
281     }
283     /**
284      * Display the saved text content from the editor in the view table
285      *
286      * @param stdClass $submission
287      * @return string
288      */
289     public function view(stdClass $submission) {
290         $result = '';
292         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
295         if ($onlinetextsubmission) {
297             // render for portfolio API
298             $result .= $this->assignment->render_editor_content(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $onlinetextsubmission->submission, $this->get_type(), 'onlinetext', 'assignsubmission_onlinetext');
300         }
302         return $result;
303     }
305      /**
306      * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type and version.
307      *
308      * @param string $type old assignment subtype
309      * @param int $version old assignment version
310      * @return bool True if upgrade is possible
311      */
312     public function can_upgrade($type, $version) {
313         if ($type == 'online' && $version >= 2011112900) {
314             return true;
315         }
316         return false;
317     }
320     /**
321      * Upgrade the settings from the old assignment to the new plugin based one
322      *
323      * @param context $oldcontext - the database for the old assignment context
324      * @param stdClass $oldassignment - the database for the old assignment instance
325      * @param string $log record log events here
326      * @return bool Was it a success?
327      */
328     public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
329         // first upgrade settings (nothing to do)
330         return true;
331     }
333     /**
334      * Upgrade the submission from the old assignment to the new one
335      *
336      * @param context $oldcontext - the database for the old assignment context
337      * @param stdClass $oldassignment The data record for the old assignment
338      * @param stdClass $oldsubmission The data record for the old submission
339      * @param stdClass $submission The data record for the new submission
340      * @param string $log Record upgrade messages in the log
341      * @return bool true or false - false will trigger a rollback
342      */
343     public function upgrade(context $oldcontext, stdClass $oldassignment, stdClass $oldsubmission, stdClass $submission, & $log) {
344         global $DB;
346         $onlinetextsubmission = new stdClass();
347         $onlinetextsubmission->onlinetext = $oldsubmission->data1;
348         $onlinetextsubmission->onlineformat = $oldsubmission->data2;
350         $onlinetextsubmission->submission = $submission->id;
351         $onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
353         if ($onlinetextsubmission->onlinetext === null) {
354             $onlinetextsubmission->onlinetext = '';
355         }
357         if ($onlinetextsubmission->onlineformat === null) {
358             $onlinetextsubmission->onlineformat = editors_get_preferred_format();
359         }
361         if (!$DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0) {
362             $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid);
363             return false;
364         }
366         // now copy the area files
367         $this->assignment->copy_area_files_for_upgrade($oldcontext->id,
368                                                         'mod_assignment',
369                                                         'submission',
370                                                         $oldsubmission->id,
371                                                         // New file area
372                                                         $this->assignment->get_context()->id,
373                                                         'assignsubmission_onlinetext',
374                                                         ASSIGNSUBMISSION_ONLINETEXT_FILEAREA,
375                                                         $submission->id);
376         return true;
377     }
379     /**
380      * Formatting for log info
381      *
382      * @param stdClass $submission The new submission
383      * @return string
384      */
385     public function format_for_log(stdClass $submission) {
386         // format the info for each submission plugin add_to_log
387         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
388         $onlinetextloginfo = '';
389         $text = format_text($onlinetextsubmission->onlinetext,
390                             $onlinetextsubmission->onlineformat,
391                             array('context'=>$this->assignment->get_context()));
392         $onlinetextloginfo .= get_string('numwordsforlog', 'assignsubmission_onlinetext', count_words($text));
394         return $onlinetextloginfo;
395     }
397     /**
398      * The assignment has been deleted - cleanup
399      *
400      * @return bool
401      */
402     public function delete_instance() {
403         global $DB;
404         // will throw exception on failure
405         $DB->delete_records('assignsubmission_onlinetext', array('assignment'=>$this->assignment->get_instance()->id));
407         return true;
408     }
410     /**
411      * No text is set for this plugin
412      *
413      * @param stdClass $submission
414      * @return bool
415      */
416     public function is_empty(stdClass $submission) {
417         $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
419         return empty($onlinetextsubmission->onlinetext);
420     }
422     /**
423      * Get file areas returns a list of areas this plugin stores files
424      * @return array - An array of fileareas (keys) and descriptions (values)
425      */
426     public function get_file_areas() {
427         return array(ASSIGNSUBMISSION_ONLINETEXT_FILEAREA=>$this->get_name());
428     }