MDL-33414: The setting $showviewlink needs to be passed by reference
[moodle.git] / mod / assign / assignmentplugin.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 functions for assign_plugin abstract class
19  *
20  *
21  * @package   mod_assign
22  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 /**
29  * Abstract class for assign_plugin (submission/feedback).
30  *
31  * @package   mod_assign
32  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
33  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  */
35 abstract class assign_plugin {
37     /** @var assign $assignment the assignment record that contains the global settings for this assign instance */
38     protected $assignment;
39     /** @var string $type assignment plugin type */
40     private $type = '';
41     /** @var string $error error message */
42     private $error = '';
45     /**
46      * Constructor for the abstract plugin type class
47      *
48      * @param assign $assignment
49      * @param string $type
50      */
51     public final function __construct(assign $assignment, $type) {
52         $this->assignment = $assignment;
53         $this->type = $type;
54     }
56     /**
57      * Is this the first plugin in the list?
58      *
59      * @return bool
60      */
61     public final function is_first() {
62         $order = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
64         if ($order == 0) {
65             return true;
66         }
67         return false;
68     }
70     /**
71      * Is this the last plugin in the list?
72      *
73      * @return bool
74      */
75     public final function is_last() {
76         if ((count(get_plugin_list($this->get_subtype()))-1) == get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder')) {
77             return true;
78         }
80         return false;
81     }
83     /**
84      * This function should be overridden to provide an array of elements that can be added to a moodle
85      * form for display in the settings page for the assignment.
86      * @param MoodleQuickForm $mform The form to add the elements to
87      * @return $array
88      */
89     public function get_settings(MoodleQuickForm $mform) {
90         return;
91     }
93     /**
94      * Allows the plugin to update the defaultvalues passed in to
95      * the settings form (needed to set up draft areas for editor
96      * and filemanager elements)
97      * @param array $defaultvalues
98      */
99     public function data_preprocessing(&$defaultvalues) {
100         return;
101     }
103     /**
104      * The assignment subtype is responsible for saving it's own settings as the database table for the
105      * standard type cannot be modified.
106      *
107      * @param stdClass $formdata - the data submitted from the form
108      * @return bool - on error the subtype should call set_error and return false.
109      */
110     public function save_settings(stdClass $formdata) {
111         return true;
112     }
114     /**
115      * Save the error message from the last error
116      *
117      * @param string $msg - the error description
118      */
119     protected final function set_error($msg) {
120         $this->error = $msg;
121     }
123     /**
124      * What was the last error?
125      *
126      *
127      * @return string
128      */
129     public final function get_error() {
130         return $this->error;
131     }
133     /**
134      * Should return the name of this plugin type.
135      *
136      * @return string - the name
137      */
138     public abstract function get_name();
140     /**
141      * Should return the subtype of this plugin.
142      *
143      * @return string - either 'assignsubmission' or 'feedback'
144      */
145     public abstract function get_subtype();
147     /**
148      * Should return the type of this plugin.
149      *
150      * @return string - the type
151      */
152     public final function get_type() {
153         return $this->type;
154     }
156     /**
157      * Get the installed version of this plugin
158      *
159      * @return string
160      */
161     public final function get_version() {
162         $version = get_config($this->get_subtype() . '_' . $this->get_type(), 'version');
163         if ($version) {
164             return $version;
165         } else {
166             return '';
167         }
168     }
170     /**
171      * Get the required moodle version for this plugin
172      *
173      * @return string
174      */
175     public final function get_requires() {
176         $requires = get_config($this->get_subtype() . '_' . $this->get_type(), 'requires');
177         if ($requires) {
178             return $requires;
179         } else {
180             return '';
181         }
182     }
184     /**
185      * Save any custom data for this form submission
186      *
187      * @param stdClass $submissionorgrade - assign_submission or assign_grade
188      *              For submission plugins this is the submission data, for feedback plugins it is the grade data
189      * @param stdClass $data - the data submitted from the form
190      * @return bool - on error the subtype should call set_error and return false.
191      */
192     public function save(stdClass $submissionorgrade, stdClass $data) {
193         return true;
194     }
196     /**
197      * Set this plugin to enabled
198      *
199      * @return bool
200      */
201     public final function enable() {
202         return $this->set_config('enabled', 1);
203     }
205     /**
206      * Set this plugin to disabled
207      *
208      * @return bool
209      */
210     public final function disable() {
211         return $this->set_config('enabled', 0);
212     }
214     /**
215      * Allows hiding this plugin from the submission/feedback screen if it is not enabled.
216      *
217      * @return bool - if false - this plugin will not accept submissions / feedback
218      */
219     public final function is_enabled() {
220         return $this->get_config('enabled');
221     }
223     /**
224      * Get any additional fields for the submission/grading form for this assignment.
225      *
226      * @param mixed $submissionorgrade submission|grade - For submission plugins this is the submission data, for feedback plugins it is the grade data
227      * @param MoodleQuickForm $mform - This is the form
228      * @param stdClass $data - This is the form data that can be modified for example by a filemanager element
229      * @return boolean - true if we added anything to the form
230      */
231     public function get_form_elements($submissionorgrade, MoodleQuickForm $mform, stdClass $data) {
232         return false;
233     }
235     /**
236      * Should not output anything - return the result as a string so it can be consumed by webservices.
237      *
238      * @param stdClass $submissionorgrade assign_submission or assign_grade
239      *                 For submission plugins this is the submission data, for feedback plugins it is the grade data
240      * @return string - return a string representation of the submission in full
241      */
242     public function view(stdClass $submissionorgrade) {
243         return '';
244     }
246     /**
247      * Get the numerical sort order for this plugin
248      *
249      * @return int
250      */
251     public final function get_sort_order() {
252         $order = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
253         return $order?$order:0;
254     }
256     /**
257      * Is this plugin enaled?
258      *
259      * @return bool
260      */
261     public final function is_visible() {
262         $disabled = get_config($this->get_subtype() . '_' . $this->get_type(), 'disabled');
263         return !$disabled;
264     }
267     /**
268      * Has this plugin got a custom settings.php file?
269      *
270      * @return bool
271      */
272     public final function has_admin_settings() {
273         global $CFG;
275         return file_exists($CFG->dirroot . '/mod/assign/' . substr($this->get_subtype(), strlen('assign')) . '/' . $this->get_type() . '/settings.php');
276     }
278     /**
279      * Set a configuration value for this plugin
280      *
281      * @param string $name The config key
282      * @param string $value The config value
283      * @return bool
284      */
285     public final function set_config($name, $value) {
286         global $DB;
288         $current = $DB->get_record('assign_plugin_config', array('assignment'=>$this->assignment->get_instance()->id, 'subtype'=>$this->get_subtype(), 'plugin'=>$this->get_type(), 'name'=>$name), '*', IGNORE_MISSING);
290         if ($current) {
291             $current->value = $value;
292             return $DB->update_record('assign_plugin_config', $current);
293         } else {
294             $setting = new stdClass();
295             $setting->assignment = $this->assignment->get_instance()->id;
296             $setting->subtype = $this->get_subtype();
297             $setting->plugin = $this->get_type();
298             $setting->name = $name;
299             $setting->value = $value;
301             return $DB->insert_record('assign_plugin_config', $setting) > 0;
302         }
303     }
305     /**
306      * Get a configuration value for this plugin
307      *
308      * @param mixed $setting The config key (string) or null
309      * @return mixed string | false
310      */
311     public final function get_config($setting = null) {
312         global $DB;
314         if ($setting) {
315             if (!$this->assignment->has_instance()) {
316                 return false;
317             }
318             $assignment = $this->assignment->get_instance();
319             if ($assignment) {
320                 $result = $DB->get_record('assign_plugin_config', array('assignment'=>$assignment->id, 'subtype'=>$this->get_subtype(), 'plugin'=>$this->get_type(), 'name'=>$setting), '*', IGNORE_MISSING);
321                 if ($result) {
322                     return $result->value;
323                 }
324             }
325             return false;
326         }
327         $results = $DB->get_records('assign_plugin_config', array('assignment'=>$this->assignment->get_instance()->id, 'subtype'=>$this->get_subtype(), 'plugin'=>$this->get_type()));
329         $config = new stdClass();
330         if (is_array($results)) {
331             foreach ($results as $setting) {
332                 $name = $setting->name;
333                 $config->$name = $setting->value;
334             }
335         }
336         return $config;
337     }
339     /**
340      * Should not output anything - return the result as a string so it can be consumed by webservices.
341      *
342      * @param stdClass $submissionorgrade assign_submission or assign_grade
343      *                 For submission plugins this is the submission data, for feedback plugins it is the grade data
344      * @param bool $showviewlink Modifed to return whether or not to show a link to the full submission/feedback
345      * @return string - return a string representation of the submission in full
346      */
347     public function view_summary(stdClass $submissionorgrade, & $showviewlink) {
348         return '';
349     }
351     /**
352      * Given a field name, should return the text of an editor field that is part of
353      * this plugin. This is used when exporting to portfolio.
354      *
355      * @param string $name Name of the field.
356      * @param int $submissionid The id of the submission
357      * @return string - The text for the editor field
358      */
359     public function get_editor_text($name, $submissionid) {
360         return '';
361     }
363     /**
364      * Produce a list of files suitable for export that represent this feedback or submission
365      *
366      * @param stdClass $submissionorgrade assign_submission or assign_grade
367      *                 For submission plugins this is the submission data, for feedback plugins it is the grade data
368      * @return array - return an array of files indexed by filename
369      */
370     public function get_files(stdClass $submissionorgrade) {
371         return array();
372     }
374      /**
375      * Given a field name, should return the format of an editor field that is part of
376      * this plugin. This is used when exporting to portfolio.
377      *
378      * @param string $name Name of the field.
379      * @param int $submissionid The id of the submission
380      * @return int - The format for the editor field
381      */
382     public function get_editor_format($name, $submissionid) {
383         return 0;
384     }
386      /**
387      * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
388      * and version.
389      *
390      * @param string $type The old assignment subtype
391      * @param int $version The old assignment version
392      * @return bool True if upgrade is possible
393      */
394     public function can_upgrade($type, $version) {
395         return false;
396     }
398      /**
399      * Upgrade the settings from the old assignment to the new one
400      *
401      * @param context $oldcontext The context for the old assignment module
402      * @param stdClass $oldassignment The data record for the old assignment
403      * @param string $log Record upgrade messages in the log
404      * @return bool true or false - false will trigger a rollback
405      */
406     public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
407         $log = $log . ' ' . get_string('upgradenotimplemented', 'mod_assign', array('type'=>$this->type, 'subtype'=>$this->get_subtype()));
408         return false;
409     }
411     /**
412      * Upgrade the submission from the old assignment to the new one
413      *
414      * @param context $oldcontext The data record for the old context
415      * @param stdClass $oldassignment The data record for the old assignment
416      * @param stdClass $oldsubmissionorgrade The data record for the old submission
417      * @param stdClass $submissionorgrade assign_submission or assign_grade The new submission or grade
418      * @param string $log Record upgrade messages in the log
419      * @return boolean true or false - false will trigger a rollback
420      */
421     public function upgrade(context $oldcontext, stdClass $oldassignment, stdClass $oldsubmissionorgrade, stdClass $submissionorgrade, & $log) {
422         $log = $log . ' ' . get_string('upgradenotimplemented', 'mod_assign', array('type'=>$this->type, 'subtype'=>$this->get_subtype()));
423         return false;
424     }
426     /**
427      * Formatting for log info
428      *
429      * @param stdClass $submissionorgrade assign_submission or assign_grade The new submission or grade
430      * @return string
431      */
432     public function format_for_log(stdClass $submissionorgrade) {
433         // format the info for each submission plugin add_to_log
434         return '';
435     }
437     /**
438      * The assignment has been deleted - remove the plugin specific data
439      *
440      * @return bool
441      */
442     public function delete_instance() {
443         return true;
444     }
446     /**
447      * Run cron for this plugin
448      */
449     public static function cron() {
450     }
452     /**
453      * Is this assignment plugin empty? (ie no submission or feedback)
454      * @param stdClass $submissionorgrade assign_submission or assign_grade
455      * @return bool
456      */
457     public function is_empty(stdClass $submissionorgrade) {
458         return true;
459     }
461     /**
462      * Get file areas returns a list of areas this plugin stores files
463      * @return array - An array of fileareas (keys) and descriptions (values)
464      */
465     public function get_file_areas() {
466         return array();
467     }
470     /**
471      * Default implementation of file_get_info for plugins.
472      * This is used by the filebrowser to browse a plugins file areas.
473      *
474      * This implementation should work for most plugins but can be overridden if required.
475      * @param file_browser $browser
476      * @param string $filearea
477      * @param int $itemid
478      * @param string $filepath
479      * @param string $filename
480      * @return file_info_stored
481      */
482     public function get_file_info($browser, $filearea, $itemid, $filepath, $filename) {
483         global $CFG, $DB, $USER;
484         $urlbase = $CFG->wwwroot.'/pluginfile.php';
486         // permission check on the itemid
488         if ($this->get_subtype() == 'assignsubmission') {
489             if ($itemid) {
490                 $record = $DB->get_record('assign_submission', array('id'=>$itemid), 'userid', IGNORE_MISSING);
491                 if (!$record) {
492                     return null;
493                 }
494                 if (!$this->assignment->can_view_submission($record->userid)) {
495                     return null;
496                 }
497             }
498         } else {
499             // not supported for feedback plugins
500             return null;
501         }
503         $fs = get_file_storage();
504         $filepath = is_null($filepath) ? '/' : $filepath;
505         $filename = is_null($filename) ? '.' : $filename;
506         if (!($storedfile = $fs->get_file($this->assignment->get_context()->id,
507                                           $this->get_subtype() . '_' . $this->get_type(),
508                                           $filearea,
509                                           $itemid,
510                                           $filepath,
511                                           $filename))) {
512             return null;
513         }
514         return new file_info_stored($browser,
515                                     $this->assignment->get_context(),
516                                     $storedfile,
517                                     $urlbase,
518                                     $filearea,
519                                     $itemid,
520                                     true,
521                                     true,
522                                     false);
523     }