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