166794031d6a6261ea39093eb4e228eb3d2723b0
[moodle.git] / lib / form / filemanager.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/>.
18 /**
19  * FileManager form element
20  *
21  * Contains HTML class for a filemanager form element
22  *
23  * @package   core_form
24  * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com>
25  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
28 global $CFG;
30 require_once('HTML/QuickForm/element.php');
31 require_once($CFG->dirroot.'/lib/filelib.php');
32 require_once($CFG->dirroot.'/repository/lib.php');
34 /**
35  * Filemanager form element
36  *
37  * FilemaneManager lets user to upload/manage multiple files
38  * @package   core_form
39  * @category  form
40  * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com>
41  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42  */
43 class MoodleQuickForm_filemanager extends HTML_QuickForm_element {
44     /** @var string html for help button, if empty then no help will icon will be dispalyed. */
45     public $_helpbutton = '';
47     /** @var array options provided to initalize filemanager */
48     // PHP doesn't support 'key' => $value1 | $value2 in class definition
49     // We cannot do $_options = array('return_types'=> FILE_INTERNAL | FILE_REFERENCE);
50     // So I have to set null here, and do it in constructor
51     protected $_options    = array('mainfile'=>'', 'subdirs'=>1, 'maxbytes'=>-1, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=> null, 'areamaxbytes' => -1);
53     /**
54      * Constructor
55      *
56      * @param string $elementName (optional) name of the filemanager
57      * @param string $elementLabel (optional) filemanager label
58      * @param array $attributes (optional) Either a typical HTML attribute string
59      *              or an associative array
60      * @param array $options set of options to initalize filemanager
61      */
62     function MoodleQuickForm_filemanager($elementName=null, $elementLabel=null, $attributes=null, $options=null) {
63         global $CFG, $PAGE;
65         $options = (array)$options;
66         foreach ($options as $name=>$value) {
67             if (array_key_exists($name, $this->_options)) {
68                 $this->_options[$name] = $value;
69             }
70         }
71         if (!empty($options['maxbytes'])) {
72             $this->_options['maxbytes'] = get_user_max_upload_file_size($PAGE->context, $CFG->maxbytes, $options['maxbytes']);
73         }
74         if (empty($options['return_types'])) {
75             $this->_options['return_types'] = (FILE_INTERNAL | FILE_REFERENCE);
76         }
77         $this->_type = 'filemanager';
78         parent::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
79     }
81     /**
82      * Sets name of filemanager
83      *
84      * @param string $name name of the filemanager
85      */
86     function setName($name) {
87         $this->updateAttributes(array('name'=>$name));
88     }
90     /**
91      * Returns name of filemanager
92      *
93      * @return string
94      */
95     function getName() {
96         return $this->getAttribute('name');
97     }
99     /**
100      * Updates filemanager attribute value
101      *
102      * @param string $value value to set
103      */
104     function setValue($value) {
105         $this->updateAttributes(array('value'=>$value));
106     }
108     /**
109      * Returns filemanager attribute value
110      *
111      * @return string
112      */
113     function getValue() {
114         return $this->getAttribute('value');
115     }
117     /**
118      * Returns maximum file size which can be uploaded
119      *
120      * @return int
121      */
122     function getMaxbytes() {
123         return $this->_options['maxbytes'];
124     }
126     /**
127      * Sets maximum file size which can be uploaded
128      *
129      * @param int $maxbytes file size
130      */
131     function setMaxbytes($maxbytes) {
132         global $CFG, $PAGE;
133         $this->_options['maxbytes'] = get_user_max_upload_file_size($PAGE->context, $CFG->maxbytes, $maxbytes);
134     }
136     /**
137      * Returns the maximum size of the area.
138      *
139      * @return int
140      */
141     function getAreamaxbytes() {
142         return $this->_options['areamaxbytes'];
143     }
145     /**
146      * Sets the maximum size of the area.
147      *
148      * @param int $areamaxbytes size limit
149      */
150     function setAreamaxbytes($areamaxbytes) {
151         $this->_options['areamaxbytes'] = $areamaxbytes;
152     }
154     /**
155      * Returns true if subdirectoy can be created, else false
156      *
157      * @return bool
158      */
159     function getSubdirs() {
160         return $this->_options['subdirs'];
161     }
163     /**
164      * Set option to create sub directory, while uploading  file
165      *
166      * @param bool $allow true if sub directory can be created.
167      */
168     function setSubdirs($allow) {
169         $this->_options['subdirs'] = $allow;
170     }
172     /**
173      * Returns maximum number of files which can be uploaded
174      *
175      * @return int
176      */
177     function getMaxfiles() {
178         return $this->_options['maxfiles'];
179     }
181     /**
182      * Sets maximum number of files which can be uploaded.
183      *
184      * @param int $num number of files
185      */
186     function setMaxfiles($num) {
187         $this->_options['maxfiles'] = $num;
188     }
190     /**
191      * Returns html for help button.
192      *
193      * @return string html for help button
194      */
195     function getHelpButton() {
196         return $this->_helpbutton;
197     }
199     /**
200      * Returns type of filemanager element
201      *
202      * @return string
203      */
204     function getElementTemplateType() {
205         if ($this->_flagFrozen){
206             return 'nodisplay';
207         } else {
208             return 'default';
209         }
210     }
212     /**
213      * Returns HTML for filemanager form element.
214      *
215      * @return string
216      */
217     function toHtml() {
218         global $CFG, $USER, $COURSE, $PAGE, $OUTPUT;
219         require_once("$CFG->dirroot/repository/lib.php");
221         // security - never ever allow guest/not logged in user to upload anything or use this element!
222         if (isguestuser() or !isloggedin()) {
223             print_error('noguest');
224         }
226         if ($this->_flagFrozen) {
227             return $this->getFrozenHtml();
228         }
230         $id          = $this->_attributes['id'];
231         $elname      = $this->_attributes['name'];
232         $subdirs     = $this->_options['subdirs'];
233         $maxbytes    = $this->_options['maxbytes'];
234         $draftitemid = $this->getValue();
235         $accepted_types = $this->_options['accepted_types'];
237         if (empty($draftitemid)) {
238             // no existing area info provided - let's use fresh new draft area
239             require_once("$CFG->libdir/filelib.php");
240             $this->setValue(file_get_unused_draft_itemid());
241             $draftitemid = $this->getValue();
242         }
244         $client_id = uniqid();
246         // filemanager options
247         $options = new stdClass();
248         $options->mainfile  = $this->_options['mainfile'];
249         $options->maxbytes  = $this->_options['maxbytes'];
250         $options->maxfiles  = $this->getMaxfiles();
251         $options->client_id = $client_id;
252         $options->itemid    = $draftitemid;
253         $options->subdirs   = $this->_options['subdirs'];
254         $options->target    = $id;
255         $options->accepted_types = $accepted_types;
256         $options->return_types = $this->_options['return_types'];
257         $options->context = $PAGE->context;
258         $options->areamaxbytes = $this->_options['areamaxbytes'];
260         $html = $this->_getTabs();
261         $fm = new form_filemanager($options);
262         $output = $PAGE->get_renderer('core', 'files');
263         $html .= $output->render($fm);
265         $html .= '<input value="'.$draftitemid.'" name="'.$elname.'" type="hidden" />';
266         // label element needs 'for' attribute work
267         $html .= '<input value="" id="id_'.$elname.'" type="hidden" />';
269         return $html;
270     }
273 /**
274  * Data structure representing a file manager.
275  *
276  * This class defines the data structure for file mnager
277  *
278  * @package   core_form
279  * @copyright 2010 Dongsheng Cai
280  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
281  * @todo      do not use this abstraction (skodak)
282  */
283 class form_filemanager implements renderable {
284     /** @var stdClass $options options for filemanager */
285     public $options;
287     /**
288      * Constructor
289      *
290      * @param stdClass $options options for filemanager
291      *   default options are:
292      *       maxbytes=>-1,
293      *       maxfiles=>-1,
294      *       itemid=>0,
295      *       subdirs=>false,
296      *       client_id=>uniqid(),
297      *       acepted_types=>'*',
298      *       return_types=>FILE_INTERNAL,
299      *       context=>$PAGE->context,
300      *       author=>fullname($USER),
301      *       licenses=>array build from $CFG->licenses,
302      *       defaultlicense=>$CFG->sitedefaultlicense
303      */
304     public function __construct(stdClass $options) {
305         global $CFG, $USER, $PAGE;
306         require_once($CFG->dirroot. '/repository/lib.php');
307         $defaults = array(
308             'maxbytes'=>-1,
309             'maxfiles'=>-1,
310             'itemid'=>0,
311             'subdirs'=>0,
312             'client_id'=>uniqid(),
313             'accepted_types'=>'*',
314             'return_types'=>FILE_INTERNAL,
315             'context'=>$PAGE->context,
316             'author'=>fullname($USER),
317             'licenses'=>array()
318             );
319         if (!empty($CFG->licenses)) {
320             $array = explode(',', $CFG->licenses);
321             foreach ($array as $license) {
322                 $l = new stdClass();
323                 $l->shortname = $license;
324                 $l->fullname = get_string($license, 'license');
325                 $defaults['licenses'][] = $l;
326             }
327         }
328         if (!empty($CFG->sitedefaultlicense)) {
329             $defaults['defaultlicense'] = $CFG->sitedefaultlicense;
330         }
331         foreach ($defaults as $key=>$value) {
332             if (empty($options->$key)) {
333                 $options->$key = $value;
334             }
335         }
337         $fs = get_file_storage();
339         // initilise options, getting files in root path
340         $this->options = file_get_drafarea_files($options->itemid, '/');
342         // calculate file count
343         $usercontext = context_user::instance($USER->id);
344         $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id', false);
345         $filecount = count($files);
346         $this->options->filecount = $filecount;
348         // copying other options
349         foreach ($options as $name=>$value) {
350             $this->options->$name = $value;
351         }
353         // calculate the maximum file size as minimum from what is specified in filepicker options,
354         // course options, global configuration and php settings
355         $coursebytes = $maxbytes = 0;
356         list($context, $course, $cm) = get_context_info_array($this->options->context->id);
357         if (is_object($course)) {
358             $coursebytes = $course->maxbytes;
359         }
360         if (!empty($this->options->maxbytes) && $this->options->maxbytes > 0) {
361             $maxbytes = $this->options->maxbytes;
362         }
363         $this->options->maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $coursebytes, $maxbytes);
365         // building file picker options
366         $params = new stdClass();
367         $params->accepted_types = $options->accepted_types;
368         $params->return_types = $options->return_types;
369         $params->context = $options->context;
370         $params->env = 'filemanager';
371         $params->disable_types = !empty($options->disable_types)?$options->disable_types:array();
372         $filepicker_options = initialise_filepicker($params);
373         $this->options->filepicker = $filepicker_options;
374     }
376     public function get_nonjsurl() {
377         global $PAGE;
378         return new moodle_url('/repository/draftfiles_manager.php', array(
379             'env'=>'filemanager',
380             'action'=>'browse',
381             'itemid'=>$this->options->itemid,
382             'subdirs'=>$this->options->subdirs,
383             'maxbytes'=>$this->options->maxbytes,
384             'maxfiles'=>$this->options->maxfiles,
385             'ctx_id'=>$PAGE->context->id, // TODO ?
386             'course'=>$PAGE->course->id, // TODO ?
387             'sesskey'=>sesskey(),
388             ));
389     }