MDL-33547: Fix for mod_assign portfolio export for a list of files.
[moodle.git] / mod / assign / portfolio_callback.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// this file contains all the functions that aren't needed by core moodle
18// but start becoming required once we're actually inside the assignment module.
19
20/**
21 * This file contains the callback class required by the portfolio api.
22 *
23 * @package mod_assign
24 * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 */
27
28defined('MOODLE_INTERNAL') || die();
29
30/** Include assign locallib.php */
31require_once($CFG->dirroot . '/mod/assign/locallib.php');
32/** Include portfolio caller.php */
33require_once($CFG->libdir . '/portfolio/caller.php');
34
35/**
36 * portfolio caller class for mod_assign.
37 *
38 * @package mod_assign
39 * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 */
42class assign_portfolio_caller extends portfolio_module_caller_base {
43
44
45 /** @var int callback arg - the id of submission we export */
46 protected $sid;
47
48 /** @var string callback arg - the area of submission files we export */
49 protected $area;
50
51 /** @var int callback arg - the id of file we export */
52 protected $fileid;
53
54 /** @var int callback arg - the cmid of the assignment we export */
55 protected $cmid;
56
57 /** @var string callback arg - the plugintype of the editor we export */
58 protected $plugin;
59
60 /** @var string callback arg - the name of the editor field we export */
61 protected $editor;
62
63
64 /**
65 * callback arg for a single file export
66 */
67 public static function expected_callbackargs() {
68 return array(
69 'cmid' => true,
70 'sid' => false,
71 'area' => false,
509e59ca 72 'component' => false,
bbd0e548
DW
73 'fileid' => false,
74 'plugin' => false,
75 'editor' => false,
76 );
77 }
78
79 /**
80 * the constructor
81 * @param array $callbackargs
82 */
83 function __construct($callbackargs) {
84 parent::__construct($callbackargs);
85 $this->cm = get_coursemodule_from_id('assign', $this->cmid, 0, false, MUST_EXIST);
86 }
87
88 /**
89 *
90 * Load data needed for the portfolio export
91 *
92 * If the assignment type implements portfolio_load_data(), the processing is delegated
93 * to it. Otherwise, the caller must provide either fileid (to export single file) or
94 * submissionid and filearea (to export all data attached to the given submission file area) via callback arguments.
95 *
96 * @throws portfolio_caller_exception
97 */
98 public function load_data() {
99
100 $context = context_module::instance($this->cmid);
101
102 if (empty($this->fileid)) {
103 if (empty($this->sid) || empty($this->area)) {
104 throw new portfolio_caller_exception('invalidfileandsubmissionid', 'mod_assign');
105 }
106
107 }
108
bbd0e548
DW
109 // export either an area of files or a single file (see function for more detail)
110 // the first arg is an id or null. If it is an id, the rest of the args are ignored
111 // if it is null, the rest of the args are used to load a list of files from get_areafiles
509e59ca 112 $this->set_file_and_format_data($this->fileid, $context->id, $this->component, $this->area, $this->sid, 'timemodified', false);
bbd0e548
DW
113
114 }
115
116 /**
117 * prepares the package up before control is passed to the portfolio plugin.
118 *
119 * @throws portfolio_caller_exception
120 * @return mixed
121 */
122 public function prepare_package() {
123
124 if ($this->plugin && $this->editor) {
125 $options = portfolio_format_text_options();
126 $context = context_module::instance($this->cmid);
127 $options->context = $context;
128
129 $plugin = $this->get_submission_plugin();
130
131 $text = $plugin->get_editor_text($this->editor, $this->sid);
132 $format = $plugin->get_editor_format($this->editor, $this->sid);
133
134 $html = format_text($text, $format, $options);
135 $html = portfolio_rewrite_pluginfile_urls($html, $context->id, 'mod_assign', $this->area, $this->sid, $this->exporter->get('format'));
136
137 if (in_array($this->exporter->get('formatclass'), array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) {
138 if ($files = $this->exporter->get('caller')->get('multifiles')) {
139 foreach ($files as $file) {
140 $this->exporter->copy_existing_file($file);
141 }
142 }
143 return $this->exporter->write_new_file($html, 'assignment.html', !empty($files));
144 } else if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
145 $leapwriter = $this->exporter->get('format')->leap2a_writer();
146 $entry = new portfolio_format_leap2a_entry($this->area . $this->cmid, print_context_name($context), 'resource', $html);
147
148 $entry->add_category('web', 'resource_type');
149 $entry->author = $this->user;
150 $leapwriter->add_entry($entry);
151 if ($files = $this->exporter->get('caller')->get('multifiles')) {
152 $leapwriter->link_files($entry, $files, $this->area . $this->cmid . 'file');
153 foreach ($files as $file) {
154 $this->exporter->copy_existing_file($file);
155 }
156 }
157 return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
158 } else {
159 debugging('invalid format class: ' . $this->exporter->get('formatclass'));
160 }
161
162 }
163
164
165 if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
166 $leapwriter = $this->exporter->get('format')->leap2a_writer();
167 $files = array();
168 if ($this->singlefile) {
169 $files[] = $this->singlefile;
170 } elseif ($this->multifiles) {
171 $files = $this->multifiles;
172 } else {
173 throw new portfolio_caller_exception('invalidpreparepackagefile', 'portfolio', $this->get_return_url());
174 }
175
176 $entryids = array();
177 foreach ($files as $file) {
178 $entry = new portfolio_format_leap2a_file($file->get_filename(), $file);
179 $entry->author = $this->user;
180 $leapwriter->add_entry($entry);
181 $this->exporter->copy_existing_file($file);
182 $entryids[] = $entry->id;
183 }
184 if (count($files) > 1) {
185 $baseid = 'assign' . $this->cmid . $this->area;
186 $context = context_module::instance($this->cmid);
187
188 // if we have multiple files, they should be grouped together into a folder
189 $entry = new portfolio_format_leap2a_entry($baseid . 'group', print_context_name($context), 'selection');
190 $leapwriter->add_entry($entry);
191 $leapwriter->make_selection($entry, $entryids, 'Folder');
192 }
193 return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
194 }
195 return $this->prepare_package_file();
196 }
197
198 /**
199 * fetch the plugin by its type
200 *
201 * @return assign_submission_plugin
202 */
203 private function get_submission_plugin() {
204 global $CFG;
205 if (!$this->plugin || !$this->cmid) {
206 return null;
207 }
208
209 require_once($CFG->dirroot . '/mod/assign/locallib.php');
210
211 $context = context_module::instance($this->cmid);
212
213 $assignment = new assign($context, null, null);
214 return $assignment->get_submission_plugin_by_type($this->plugin);
215 }
216
217 /**
218 * get sha1 file
219 * calculate a sha1 has of either a single file or a list
220 * of files based on the data set by load_data
221 *
222 * @return string
223 */
224 public function get_sha1() {
225
226 if ($this->plugin && $this->editor) {
227 $plugin = $this->get_submission_plugin();
228 $options = portfolio_format_text_options();
229 $options->context = context_module::instance($this->cmid);
230
231 $textsha1 = sha1(format_text($plugin->get_editor_text($this->editor, $this->sid),
232 $plugin->get_editor_format($this->editor, $this->sid), $options));
233 $filesha1 = '';
234 try {
235 $filesha1 = $this->get_sha1_file();
236 } catch (portfolio_caller_exception $e) {} // no files
237 return sha1($textsha1 . $filesha1);
238 }
239 return $this->get_sha1_file();
240 }
241
242 /**
243 * calculate the time to transfer either a single file or a list
244 * of files based on the data set by load_data
245 *
246 * @return int
247 */
248 public function expected_time() {
249 return $this->expected_time_file();
250 }
251
252 /**
253 * checking the permissions
254 *
255 * @return bool
256 */
257 public function check_permissions() {
258 $context = context_module::instance($this->cmid);
259 return has_capability('mod/assign:exportownsubmission', $context);
260 }
261
262 /**
263 * display a module name
264 *
265 * @return string
266 */
267 public static function display_name() {
268 return get_string('modulename', 'assign');
269 }
270
271 /**
272 * return array of formats supported by this portfolio call back
273 * @return array
274 */
275 public static function base_supported_formats() {
276
277 return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_LEAP2A);
278
279 }
280}
281