MDL-37030 Assignment: Fix error on download all submissions.
[moodle.git] / mod / assign / assignmentplugin.php
CommitLineData
bbd0e548
DW
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 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 */
25
26defined('MOODLE_INTERNAL') || die();
27
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 */
35abstract class assign_plugin {
36
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 = '';
43
44
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 }
55
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');
63
64 if ($order == 0) {
65 return true;
66 }
67 return false;
68 }
69
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 }
79
80 return false;
81 }
82
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 }
92
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 }
102
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 }
113
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 }
122
123 /**
124 * What was the last error?
125 *
126 *
127 * @return string
128 */
129 public final function get_error() {
130 return $this->error;
131 }
132
133 /**
134 * Should return the name of this plugin type.
135 *
136 * @return string - the name
137 */
138 public abstract function get_name();
139
140 /**
141 * Should return the subtype of this plugin.
142 *
143 * @return string - either 'assignsubmission' or 'feedback'
144 */
145 public abstract function get_subtype();
146
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 }
155
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 }
169
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 }
183
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 }
195
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 }
204
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 }
213
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 */
b473171a 219 public function is_enabled() {
bbd0e548
DW
220 return $this->get_config('enabled');
221 }
222
fc7b7d52
DW
223
224 /**
225 * Get any additional fields for the submission/grading form for this assignment.
226 *
227 * @param mixed $submissionorgrade submission|grade - For submission plugins this is the submission data,
228 * for feedback plugins it is the grade data
229 * @param MoodleQuickForm $mform - This is the form
230 * @param stdClass $data - This is the form data that can be modified for example by a filemanager element
231 * @param int $userid - This is the userid for the current submission.
232 * This is passed separately as there may not yet be a submission or grade.
233 * @return boolean - true if we added anything to the form
234 */
235 public function get_form_elements_for_user($submissionorgrade, MoodleQuickForm $mform, stdClass $data, $userid) {
236 return $this->get_form_elements($submissionorgrade, $mform, $data);
237 }
238
bbd0e548
DW
239 /**
240 * Get any additional fields for the submission/grading form for this assignment.
fc7b7d52 241 * This function is retained for backwards compatibility - new plugins should override {@link get_form_elements_for_user()}.
bbd0e548
DW
242 *
243 * @param mixed $submissionorgrade submission|grade - For submission plugins this is the submission data, for feedback plugins it is the grade data
244 * @param MoodleQuickForm $mform - This is the form
245 * @param stdClass $data - This is the form data that can be modified for example by a filemanager element
246 * @return boolean - true if we added anything to the form
247 */
248 public function get_form_elements($submissionorgrade, MoodleQuickForm $mform, stdClass $data) {
249 return false;
250 }
251
252 /**
253 * Should not output anything - return the result as a string so it can be consumed by webservices.
254 *
9682626e 255 * @param stdClass $submissionorgrade assign_submission or assign_grade
bbd0e548
DW
256 * For submission plugins this is the submission data, for feedback plugins it is the grade data
257 * @return string - return a string representation of the submission in full
258 */
259 public function view(stdClass $submissionorgrade) {
260 return '';
261 }
262
263 /**
264 * Get the numerical sort order for this plugin
265 *
266 * @return int
267 */
268 public final function get_sort_order() {
269 $order = get_config($this->get_subtype() . '_' . $this->get_type(), 'sortorder');
270 return $order?$order:0;
271 }
272
273 /**
274 * Is this plugin enaled?
275 *
276 * @return bool
277 */
278 public final function is_visible() {
279 $disabled = get_config($this->get_subtype() . '_' . $this->get_type(), 'disabled');
280 return !$disabled;
281 }
282
283
284 /**
285 * Has this plugin got a custom settings.php file?
286 *
287 * @return bool
288 */
289 public final function has_admin_settings() {
290 global $CFG;
291
292 return file_exists($CFG->dirroot . '/mod/assign/' . substr($this->get_subtype(), strlen('assign')) . '/' . $this->get_type() . '/settings.php');
293 }
294
295 /**
296 * Set a configuration value for this plugin
297 *
298 * @param string $name The config key
299 * @param string $value The config value
300 * @return bool
301 */
302 public final function set_config($name, $value) {
303 global $DB;
304
305 $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);
306
307 if ($current) {
308 $current->value = $value;
12945803 309 return $DB->update_record('assign_plugin_config', $current);
bbd0e548
DW
310 } else {
311 $setting = new stdClass();
312 $setting->assignment = $this->assignment->get_instance()->id;
313 $setting->subtype = $this->get_subtype();
314 $setting->plugin = $this->get_type();
315 $setting->name = $name;
316 $setting->value = $value;
317
318 return $DB->insert_record('assign_plugin_config', $setting) > 0;
319 }
320 }
321
322 /**
323 * Get a configuration value for this plugin
324 *
325 * @param mixed $setting The config key (string) or null
326 * @return mixed string | false
327 */
328 public final function get_config($setting = null) {
329 global $DB;
330
331 if ($setting) {
332 if (!$this->assignment->has_instance()) {
333 return false;
334 }
335 $assignment = $this->assignment->get_instance();
336 if ($assignment) {
337 $result = $DB->get_record('assign_plugin_config', array('assignment'=>$assignment->id, 'subtype'=>$this->get_subtype(), 'plugin'=>$this->get_type(), 'name'=>$setting), '*', IGNORE_MISSING);
338 if ($result) {
339 return $result->value;
340 }
341 }
342 return false;
343 }
344 $results = $DB->get_records('assign_plugin_config', array('assignment'=>$this->assignment->get_instance()->id, 'subtype'=>$this->get_subtype(), 'plugin'=>$this->get_type()));
345
346 $config = new stdClass();
347 if (is_array($results)) {
348 foreach ($results as $setting) {
349 $name = $setting->name;
350 $config->$name = $setting->value;
351 }
352 }
353 return $config;
354 }
355
356 /**
357 * Should not output anything - return the result as a string so it can be consumed by webservices.
358 *
9682626e 359 * @param stdClass $submissionorgrade assign_submission or assign_grade
bbd0e548
DW
360 * For submission plugins this is the submission data, for feedback plugins it is the grade data
361 * @param bool $showviewlink Modifed to return whether or not to show a link to the full submission/feedback
362 * @return string - return a string representation of the submission in full
363 */
7ee1548a 364 public function view_summary(stdClass $submissionorgrade, & $showviewlink) {
bbd0e548
DW
365 return '';
366 }
367
df47b77f 368 /**
7a2b911c 369 * Given a field name and value should update the text for this field in the plugins submission or grade
df47b77f
DW
370 *
371 * @param string $name Name of the field.
372 * @param string $value Updated text
373 * @param int $submissionorgradeid The id of the submission or grade
374 * @return bool - true if the value was updated
375 */
376 public function set_editor_text($name, $value, $submissionorgradeid) {
377 return false;
378 }
379
380 /**
7a2b911c 381 * Given a field name and value should update the format for this field in the plugins submission or grade
df47b77f
DW
382 *
383 * @param string $name Name of the field.
7a2b911c
DW
384 * @param int $format Updated format.
385 * @param int $submissionorgradeid The id of the submission or grade.
df47b77f
DW
386 * @return bool - true if the value was updated
387 */
7a2b911c 388 public function set_editor_format($name, $format, $submissionorgradeid) {
df47b77f
DW
389 return false;
390 }
391
392 /**
393 * Return a list of the fields that can be exported or imported via text.
394 *
395 * @return array - The list of field names (strings) and descriptions. ($name => $description)
396 */
397 public function get_editor_fields() {
398 return array();
399 }
400
bbd0e548
DW
401 /**
402 * Given a field name, should return the text of an editor field that is part of
403 * this plugin. This is used when exporting to portfolio.
404 *
405 * @param string $name Name of the field.
df47b77f 406 * @param int $submissionorgradeid The id of the submission or grade
bbd0e548
DW
407 * @return string - The text for the editor field
408 */
df47b77f 409 public function get_editor_text($name, $submissionorgradeid) {
bbd0e548
DW
410 return '';
411 }
412
413 /**
414 * Produce a list of files suitable for export that represent this feedback or submission
415 *
9682626e 416 * @param stdClass $submissionorgrade assign_submission or assign_grade
bbd0e548 417 * For submission plugins this is the submission data, for feedback plugins it is the grade data
2406815b
DW
418 * @param stdClass $user The user record for the current submission.
419 * Needed for url rewriting if this is a group submission.
bbd0e548
DW
420 * @return array - return an array of files indexed by filename
421 */
2406815b 422 public function get_files(stdClass $submissionorgrade, stdClass $user) {
bbd0e548
DW
423 return array();
424 }
425
7a2b911c 426 /**
bbd0e548
DW
427 * Given a field name, should return the format of an editor field that is part of
428 * this plugin. This is used when exporting to portfolio.
429 *
430 * @param string $name Name of the field.
431 * @param int $submissionid The id of the submission
432 * @return int - The format for the editor field
433 */
434 public function get_editor_format($name, $submissionid) {
435 return 0;
436 }
437
7a2b911c 438 /**
bbd0e548
DW
439 * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
440 * and version.
441 *
442 * @param string $type The old assignment subtype
443 * @param int $version The old assignment version
444 * @return bool True if upgrade is possible
445 */
446 public function can_upgrade($type, $version) {
447 return false;
448 }
449
7a2b911c 450 /**
bbd0e548
DW
451 * Upgrade the settings from the old assignment to the new one
452 *
453 * @param context $oldcontext The context for the old assignment module
454 * @param stdClass $oldassignment The data record for the old assignment
455 * @param string $log Record upgrade messages in the log
456 * @return bool true or false - false will trigger a rollback
457 */
458 public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
459 $log = $log . ' ' . get_string('upgradenotimplemented', 'mod_assign', array('type'=>$this->type, 'subtype'=>$this->get_subtype()));
460 return false;
461 }
462
463 /**
464 * Upgrade the submission from the old assignment to the new one
465 *
466 * @param context $oldcontext The data record for the old context
467 * @param stdClass $oldassignment The data record for the old assignment
468 * @param stdClass $oldsubmissionorgrade The data record for the old submission
469 * @param stdClass $submissionorgrade assign_submission or assign_grade The new submission or grade
470 * @param string $log Record upgrade messages in the log
471 * @return boolean true or false - false will trigger a rollback
472 */
473 public function upgrade(context $oldcontext, stdClass $oldassignment, stdClass $oldsubmissionorgrade, stdClass $submissionorgrade, & $log) {
474 $log = $log . ' ' . get_string('upgradenotimplemented', 'mod_assign', array('type'=>$this->type, 'subtype'=>$this->get_subtype()));
475 return false;
476 }
477
478 /**
479 * Formatting for log info
9682626e 480 *
bbd0e548
DW
481 * @param stdClass $submissionorgrade assign_submission or assign_grade The new submission or grade
482 * @return string
483 */
484 public function format_for_log(stdClass $submissionorgrade) {
485 // format the info for each submission plugin add_to_log
486 return '';
487 }
488
489 /**
490 * The assignment has been deleted - remove the plugin specific data
491 *
492 * @return bool
493 */
494 public function delete_instance() {
495 return true;
496 }
497
498 /**
499 * Run cron for this plugin
500 */
501 public static function cron() {
502 }
503
504 /**
505 * Is this assignment plugin empty? (ie no submission or feedback)
506 * @param stdClass $submissionorgrade assign_submission or assign_grade
507 * @return bool
508 */
509 public function is_empty(stdClass $submissionorgrade) {
510 return true;
511 }
512
513 /**
514 * Get file areas returns a list of areas this plugin stores files
515 * @return array - An array of fileareas (keys) and descriptions (values)
516 */
517 public function get_file_areas() {
518 return array();
519 }
520
521
522 /**
523 * Default implementation of file_get_info for plugins.
524 * This is used by the filebrowser to browse a plugins file areas.
525 *
526 * This implementation should work for most plugins but can be overridden if required.
527 * @param file_browser $browser
528 * @param string $filearea
529 * @param int $itemid
530 * @param string $filepath
531 * @param string $filename
532 * @return file_info_stored
533 */
534 public function get_file_info($browser, $filearea, $itemid, $filepath, $filename) {
535 global $CFG, $DB, $USER;
536 $urlbase = $CFG->wwwroot.'/pluginfile.php';
537
538 // permission check on the itemid
539
540 if ($this->get_subtype() == 'assignsubmission') {
541 if ($itemid) {
542 $record = $DB->get_record('assign_submission', array('id'=>$itemid), 'userid', IGNORE_MISSING);
543 if (!$record) {
544 return null;
545 }
546 if (!$this->assignment->can_view_submission($record->userid)) {
547 return null;
548 }
549 }
550 } else {
551 // not supported for feedback plugins
552 return null;
553 }
554
555 $fs = get_file_storage();
556 $filepath = is_null($filepath) ? '/' : $filepath;
557 $filename = is_null($filename) ? '.' : $filename;
558 if (!($storedfile = $fs->get_file($this->assignment->get_context()->id,
559 $this->get_subtype() . '_' . $this->get_type(),
560 $filearea,
561 $itemid,
562 $filepath,
563 $filename))) {
564 return null;
565 }
566 return new file_info_stored($browser,
567 $this->assignment->get_context(),
568 $storedfile,
569 $urlbase,
570 $filearea,
571 $itemid,
572 true,
573 true,
574 false);
575 }
576
df47b77f
DW
577 /**
578 * This allows a plugin to render a page in the context of the assignment
579 *
580 * If the plugin creates a link to the assignment view.php page with
581 * The following required parameters:
582 * id=coursemoduleid
583 * plugin=type
584 * pluginsubtype=assignfeedback|assignsubmission
585 * pluginaction=customaction
586 *
587 * Then this function will be called to display the page with the pluginaction passed as action
588 * @param string $action The plugin specified action
589 * @return string
590 */
591 public function view_page($action) {
592 return '';
593 }
594
595 /**
596 * If this plugin should not include a column in the grading table or a row on the summary page
7a9fd6da 597 * then return false
df47b77f
DW
598 *
599 * @return bool
600 */
601 public function has_user_summary() {
602 return true;
603 }
604
bbd0e548 605}