e38acd766a953209524e4ae89ce51c861125d250
[moodle.git] / lib / portfolio / formats.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 all the class definitions of the export formats.
19  * They are implemented in php classes rather than just a simpler hash
20  * Because it provides an easy way to do subtyping using php inheritance.
21  *
22  * @package core_portfolio
23  * @copyright 2008 Penny Leach <penny@catalyst.net.nz>,
24  *                 Martin Dougiamas <http://dougiamas.com>
25  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
28 defined('MOODLE_INTERNAL') || die();
30 /**
31  * Base class to inherit from.
32  * Do not use this anywhere in supported_formats
33  *
34  * @package core_portfolio
35  * @category portfolio
36  * @copyright 2008 Penny Leach <penny@catalyst.net.nz>,
37  *                 Martin Dougiamas <http://dougiamas.com>
38  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  *
40  */
41 abstract class portfolio_format {
43     /**
44      * Array of mimetypes this format supports
45      *
46      * @throws coding_exception
47      */
48     public static function mimetypes() {
49         throw new coding_exception('mimetypes() method needs to be overridden in each subclass of portfolio_format');
50     }
52     /**
53      * For multipart formats, eg html with attachments,
54      * we need to have a directory to place associated files from
55      * inside the zip file. This is the name of that directory
56      *
57      * @throws coding_exception
58      */
59     public static function get_file_directory() {
60         throw new coding_exception('get_file_directory() method needs to be overridden in each subclass of portfolio_format');
61     }
63     /**
64      * Given a file, return a snippet of markup in whatever format
65      * to link to that file.
66      * Usually involves the path given by {@see get_file_directory}.
67      * This is not supported in subclasses of portfolio_format_file
68      * since they're all just single files.
69      *
70      * @param stored_file $file file information object
71      * @param array $options array of options to pass. can contain:
72      *              attributes => hash of existing html attributes (eg title, height, width, etc)
73      *
74      * @throws coding_exception
75      */
76     public static function file_output($file, $options=null) {
77         throw new coding_exception('file_output() method needs to be overridden in each subclass of portfolio_format');
78     }
80     /**
81      * Create portfolio tag
82      *
83      * @param stored_file $file file information object
84      * @param string $path file path
85      * @param array $attributes portfolio attributes
86      * @return string
87      */
88     public static function make_tag($file, $path, $attributes) {
89         $srcattr = 'href';
90         $tag     = 'a';
91         $content = $file->get_filename();
92         if (in_array($file->get_mimetype(), portfolio_format_image::mimetypes())) {
93             $srcattr = 'src';
94             $tag     = 'img';
95             $content = '';
96         }
98         $attributes[$srcattr] = $path; // this will override anything we might have been passed (which is good)
99         $dom = new DomDocument();
100         $elem = null;
101         if ($content) {
102             $elem = $dom->createElement($tag, $content);
103         } else {
104             $elem = $dom->createElement($tag);
105         }
107         foreach ($attributes as $key => $value) {
108             $elem->setAttribute($key, $value);
109         }
110         $dom->appendChild($elem);
111         return $dom->saveXML($elem);
112     }
114     /**
115      * Whether this format conflicts with the given format.
116      * This is used for the case where an export location
117      * "generally" supports something like FORMAT_PLAINHTML
118      * but then in a specific export case, must add attachments,
119      * which means that FORMAT_RICHHTML is supported in that case,
120      * which implies removing support for FORMAT_PLAINHTML.
121      * Note that conflicts don't have to be bi-directional
122      * (eg FORMAT_PLAINHTML conflicts with FORMAT_RICHHTML
123      * but not the other way around) and things within the class hierarchy
124      * are resolved automatically anyway.
125      * This is really just between subclasses of format_rich
126      * and subclasses of format_file.
127      *
128      * @param string $format one of the FORMAT_XX constants
129      * @return bool
130      */
131     public static function conflicts($format) {
132         return false;
133     }
136 /**
137  * The most basic type - pretty much everything is a subtype
138  *
139  * @package core_portfolio
140  * @category portfolio
141  * @copyright 2009 Penny Leach <penny@catalyst.net.nz>, Martin Dougiamas
142  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
143  */
144 class portfolio_format_file extends portfolio_format {
146     /**
147      * Array of mimetypes this format supports
148      *
149      * @return array
150      */
151     public static function mimetypes() {
152         return array();
153     }
155     /**
156      * For multipart formats, eg html with attachments,
157      * we need to have a directory to place associated files from
158      * inside the zip file. This is the name of that directory
159      *
160      * @return bool
161      */
162     public static function get_file_directory() {
163         return false;
164     }
166     /**
167      * Given a file, return a snippet of markup in whatever format
168      * to link to that file.
169      * Usually involves the path given by {@see get_file_directory}.
170      * This is not supported in subclasses of portfolio_format_file
171      * since they're all just single files.
172      *
173      * @param stored_file $file informations object
174      * @param array $options array of options to pass. can contain:
175      *              attributes => hash of existing html attributes (eg title, height, width, etc)
176      */
177     public static function file_output($file, $options=null) {
178         throw new portfolio_exception('fileoutputnotsupported', 'portfolio');
179     }
182 /**
183  * Image format, subtype of file.
184  *
185  * @package core_portfolio
186  * @category portfolio
187  * @copyright 2009 Penny Leach
188  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
189  */
190 class portfolio_format_image extends portfolio_format_file {
191     /**
192      * Return all mimetypes that use image.gif (eg all images)
193      *
194      * @return string
195      */
196     public static function mimetypes() {
197         return mimeinfo_from_icon('type', 'image', true);
198     }
200     /**
201      * Whether this format conflicts with the given format.
202      * This is used for the case where an export location
203      * "generally" supports something like FORMAT_PLAINHTML
204      * but then in a specific export case, must add attachments,
205      * which means that FORMAT_RICHHTML is supported in that case,
206      * which implies removing support for FORMAT_PLAINHTML.
207      * Note that conflicts don't have to be bi-directional
208      * (eg FORMAT_PLAINHTML conflicts with FORMAT_RICHHTML
209      * but not the other way around) and things within the class hierarchy
210      * are resolved automatically anyway.
211      * This is really just between subclasses of format_rich
212      * and subclasses of format_file.
213      *
214      * @param string $format one of the FORMAT_XX constants
215      * @return bool
216      */
217     public static function conflicts($format) {
218         return ($format == PORTFOLIO_FORMAT_RICHHTML
219             || $format == PORTFOLIO_FORMAT_PLAINHTML);
220     }
223 /**
224  * HTML format
225  * Could be used for an external cms or something in case we want to be really specific.
226  *
227  * @package core_portfolio
228  * @category portfolio
229  * @copyright 2008 Penny Leach
230  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
231  */
232 class portfolio_format_plainhtml extends portfolio_format_file {
234     /**
235      * Return html mimetype
236      *
237      * @return array
238      */
239     public static function mimetypes() {
240         return array('text/html');
241     }
243     /**
244      * Whether this format conflicts with the given format.
245      * This is used for the case where an export location
246      * "generally" supports something like FORMAT_PLAINHTML
247      * but then in a specific export case, must add attachments,
248      * which means that FORMAT_RICHHTML is supported in that case,
249      * which implies removing support for FORMAT_PLAINHTML.
250      * Note that conflicts don't have to be bi-directional
251      * (eg FORMAT_PLAINHTML conflicts with FORMAT_RICHHTML
252      * but not the other way around) and things within the class hierarchy
253      * are resolved automatically anyway.
254      * This is really just between subclasses of format_rich
255      * and subclasses of format_file.
256      *
257      * @param string $format one of the FORMAT_XX constants
258      * @return bool
259      */
260     public static function conflicts($format) {
261         return ($format == PORTFOLIO_FORMAT_RICHHTML
262             || $format == PORTFOLIO_FORMAT_FILE);
263     }
266 /**
267  * Video format
268  * For portfolio plugins that support videos specifically
269  *
270  * @package core_portfolio
271  * @category portfolio
272  * @copyright 2008 Penny Leach
273  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
274  */
275 class portfolio_format_video extends portfolio_format_file {
277      /**
278       * Return video mimetypes
279       *
280       * @return array
281       */
282     public static function mimetypes() {
283         return array_merge(
284             mimeinfo_from_icon('type', 'video', true),
285             mimeinfo_from_icon('type', 'avi', true)
286         );
287     }
290 /**
291  * Class for plain text format.
292  * Not sure why we would need this yet,
293  * but since resource module wants to export it... we can
294  *
295  * @package core_portfolio
296  * @category portfolio
297  * @copyright 2008 Penny Leach
298  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
299  */
300 class portfolio_format_text extends portfolio_format_file {
302     /**
303      * Return plain text mimetypes
304      *
305      * @return array
306      */
307     public static function mimetypes() {
308         return array('text/plain');
309     }
311     /**
312      * Whether this format conflicts with the given format.
313      * This is used for the case where an export location
314      * "generally" supports something like FORMAT_PLAINHTML
315      * but then in a specific export case, must add attachments,
316      * which means that FORMAT_RICHHTML is supported in that case,
317      * which implies removing support for FORMAT_PLAINHTML.
318      * Note that conflicts don't have to be bi-directional
319      * (eg FORMAT_PLAINHTML conflicts with FORMAT_RICHHTML
320      * but not the other way around) and things within the class hierarchy
321      * are resolved automatically anyway.
322      * This is really just between subclasses of format_rich
323      * and subclasses of format_file.
324      *
325      * @param string $format one of the FORMAT_XX constants
326      * @return bool
327      */
328     public static function conflicts($format ) {
329         return ($format == PORTFOLIO_FORMAT_PLAINHTML
330             || $format == PORTFOLIO_FORMAT_RICHHTML);
331     }
334 /**
335  * Base class for rich formats.
336  * These are multipart - eg things with attachments
337  *
338  * @package core_portfolio
339  * @category portfolio
340  * @copyright 2009 Penny Leach
341  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
342  */
343 abstract class portfolio_format_rich extends portfolio_format {
345     /**
346      * Return rich text mimetypes
347      *
348      * @return array
349      */
350     public static function mimetypes() {
351         return array();
352     }
356 /**
357  * Richhtml - html with attachments.
358  * The most commonly used rich format
359  * eg inline images
360  *
361  * @package core_portfolio
362  * @category portfolio
363  * @copyright 2009 Penny Leach
364  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
365  */
366 class portfolio_format_richhtml extends portfolio_format_rich {
368     /**
369      * For multipart formats, eg html with attachments,
370      * we need to have a directory to place associated files from
371      * inside the zip file. this is the name of that directory
372      *
373      * @return string
374      */
375     public static function get_file_directory() {
376         return 'site_files/';
377     }
379     /**
380      * Given a file, return a snippet of markup in whatever format
381      * to link to that file.
382      * Usually involves the path given by {@see get_file_directory}.
383      * This is not supported in subclasses of portfolio_format_file
384      * since they're all just single files.
385      *
386      * @param stored_file $file information for existing file
387      * @param array $options array of options to pass. can contain:
388      *              attributes => hash of existing html attributes (eg title, height, width, etc)
389      * @return string
390      */
391     public static function file_output($file, $options=null) {
392         $path = self::get_file_directory() . $file->get_filename();
393         $attributes = array();
394         if (!empty($options['attributes']) && is_array($options['attributes'])) {
395             $attributes = $options['attributes'];
396         }
397         return self::make_tag($file, $path, $attributes);
398     }
400     /**
401      * Whether this format conflicts with the given format.
402      * This is used for the case where an export location
403      * "generally" supports something like FORMAT_PLAINHTML
404      * but then in a specific export case, must add attachments,
405      * which means that FORMAT_RICHHTML is supported in that case,
406      * which implies removing support for FORMAT_PLAINHTML.
407      * Note that conflicts don't have to be bi-directional
408      * (eg FORMAT_PLAINHTML conflicts with FORMAT_RICHHTML
409      * but not the other way around) and things within the class hierarchy
410      * are resolved automatically anyway.
411      * This is really just between subclasses of format_rich
412      * and subclasses of format_file.
413      *
414      * @todo MDL-31305 - revisit the conflict with file, since we zip here
415      * @param string $format one of the FORMAT_XX constants
416      * @return bool
417      */
418     public static function conflicts($format) { // TODO revisit the conflict with file, since we zip here
419         return ($format == PORTFOLIO_FORMAT_PLAINHTML || $format == PORTFOLIO_FORMAT_FILE);
420     }
424 /**
425  * Class used for leap2a format
426  *
427  * @package core_portfolio
428  * @category portfolio
429  * @copyright 2009 Penny Leach
430  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
431  */
432 class portfolio_format_leap2a extends portfolio_format_rich {
434     /**
435      * For multipart formats, eg html with attachments,
436      * we need to have a directory to place associated files from
437      * inside the zip file. this is the name of that directory
438      *
439      * @return string
440      */
441     public static function get_file_directory() {
442         return 'files/';
443     }
445     /**
446      * Return the file prefix
447      *
448      * @return string
449      */
450     public static function file_id_prefix() {
451         return 'storedfile';
452     }
454     /**
455      * Return the link to a file
456      *
457      * @param stored_file $file information for existing file
458      * @param array $options array of options to pass. can contain:
459      *              attributes => hash of existing html attributes (eg title, height, width, etc)
460      * @return string
461      */
462     public static function file_output($file, $options=null) {
463         $id = '';
464         if (!is_array($options)) {
465             $options = array();
466         }
467         if (!array_key_exists('entry', $options)) {
468             $options['entry'] = true;
469         }
470         if (!empty($options['entry'])) {
471             $path = 'portfolio:' . self::file_id_prefix() . $file->get_id();
472         } else {
473             $path = self::get_file_directory() . $file->get_filename();
474         }
475         $attributes = array();
476         if (!empty($options['attributes']) && is_array($options['attributes'])) {
477             $attributes = $options['attributes'];
478         }
479         $attributes['rel']    = 'enclosure';
480         return self::make_tag($file, $path, $attributes);
481     }
483     /**
484      * Generate portfolio_format_leap2a
485      *
486      * @param stdclass $user user information object
487      * @return portfolio_format_leap2a_writer
488      */
489     public static function leap2a_writer(stdclass $user=null) {
490         global $CFG;
491         if (empty($user)) {
492             global $USER;
493             $user = $USER;
494         }
495         require_once($CFG->libdir . '/portfolio/formats/leap2a/lib.php');
496         return new portfolio_format_leap2a_writer($user);
497     }
499     /**
500      * Return the manifest name
501      *
502      * @return string
503      */
504     public static function manifest_name() {
505         return 'leap2a.xml';
506     }
510 // later.... a moodle plugin might support this.
511 // it's commented out in portfolio_supported_formats so cannot currently be used.
512 //class portfolio_format_mbkp extends portfolio_format_rich {}
514 /**
515  * 'PDF format', subtype of file.
516  * For portfolio plugins that support PDFs specifically.
517  *
518  * @package core_portfolio
519  * @category portfolio
520  * @copyright 2009 Dan Poltawski
521  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
522  */
523 class portfolio_format_pdf extends portfolio_format_file {
525     /**
526      * Return pdf mimetypes
527      *
528      * @return array
529      */
530     public static function mimetypes() {
531         return array('application/pdf');
532     }
535 /**
536  * 'Document format', subtype of file.
537  * For portfolio plugins that support documents specifically.
538  *
539  * @package core_portfolio
540  * @category portfolio
541  * @copyright 2009 Dan Poltawski
542  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
543  */
544 class portfolio_format_document extends portfolio_format_file {
546     /**
547      * Return documents mimetypes
548      *
549      * @return array of documents mimetypes
550      */
551     public static function mimetypes() {
552         return array_merge(
553             array('text/plain', 'text/rtf'),
554             mimeinfo_from_icon('type', 'word', true),
555             mimeinfo_from_icon('type', 'docx', true),
556             mimeinfo_from_icon('type', 'odt', true)
557         );
558     }
561 /**
562  * 'Spreadsheet format', subtype of file.
563  * For portfolio plugins that support spreadsheets specifically.
564  *
565  * @package core_portfolio
566  * @category portfolio
567  * @copyright 2009 Dan Poltawski
568  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
569  */
570 class portfolio_format_spreadsheet extends portfolio_format_file {
572     /**
573      * Return spreadsheet spreadsheet mimetypes
574      *
575      * @return array of documents mimetypes
576      */
577     public static function mimetypes() {
578         return array_merge(
579             mimeinfo_from_icon('type', 'excel', true),
580             mimeinfo_from_icon('type', 'xlsm', true),
581             mimeinfo_from_icon('type', 'ods', true)
582         );
583     }
586 /**
587  * 'Presentation format', subtype of file.
588  * For portfolio plugins that support presentation specifically.
589  *
590  * @package core_portfolio
591  * @category portfolio
592  * @copyright 2009 Dan Poltawski
593  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
594  */
595 class portfolio_format_presentation extends portfolio_format_file {
597     /**
598      * Return presentation documents mimetypes
599      *
600      * @return array presentation document mimetypes
601      */
602     public static function mimetypes() {
603         return mimeinfo_from_icon('type', 'powerpoint', true);
604     }