7bb93c71b52ce20a94e03ba921b038c651c89bad
[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/>.
17 /**
18  * File manager
19  *
20  * @package    moodlecore
21  * @subpackage file
22  * @copyright  1999 onwards Dongsheng Cai <dongsheng@moodle.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 global $CFG;
28 require_once('HTML/QuickForm/element.php');
29 require_once($CFG->dirroot.'/lib/filelib.php');
30 require_once($CFG->dirroot.'/repository/lib.php');
32 class MoodleQuickForm_filemanager extends HTML_QuickForm_element {
33     public $_helpbutton = '';
34     protected $_options    = array('mainfile'=>'', 'subdirs'=>1, 'maxbytes'=>-1, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
36     function MoodleQuickForm_filemanager($elementName=null, $elementLabel=null, $attributes=null, $options=null) {
37         global $CFG, $PAGE;
39         $options = (array)$options;
40         foreach ($options as $name=>$value) {
41             if (array_key_exists($name, $this->_options)) {
42                 $this->_options[$name] = $value;
43             }
44         }
45         if (!empty($options['maxbytes'])) {
46             $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $options['maxbytes']);
47         }
48         $this->_type = 'filemanager';
49         parent::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
50     }
52     function setName($name) {
53         $this->updateAttributes(array('name'=>$name));
54     }
56     function getName() {
57         return $this->getAttribute('name');
58     }
60     function setValue($value) {
61         $this->updateAttributes(array('value'=>$value));
62     }
64     function getValue() {
65         return $this->getAttribute('value');
66     }
68     function getMaxbytes() {
69         return $this->_options['maxbytes'];
70     }
72     function setMaxbytes($maxbytes) {
73         global $CFG;
74         $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $maxbytes);
75     }
77     function getSubdirs() {
78         return $this->_options['subdirs'];
79     }
81     function setSubdirs($allow) {
82         $this->_options['subdirs'] = $allow;
83     }
85     function getMaxfiles() {
86         return $this->_options['maxfiles'];
87     }
89     function setMaxfiles($num) {
90         $this->_options['maxfiles'] = $num;
91     }
93     function setHelpButton($helpbuttonargs, $function='helpbutton'){
94         debugging('component setHelpButton() is not used any more, please use $mform->setHelpButton() instead');
95     }
97     function getHelpButton() {
98         return $this->_helpbutton;
99     }
101     function getElementTemplateType() {
102         if ($this->_flagFrozen){
103             return 'nodisplay';
104         } else {
105             return 'default';
106         }
107     }
109     function toHtml() {
110         global $CFG, $USER, $COURSE, $PAGE, $OUTPUT;
111         require_once("$CFG->dirroot/repository/lib.php");
113         // security - never ever allow guest/not logged in user to upload anything or use this element!
114         if (isguestuser() or !isloggedin()) {
115             print_error('noguest');
116         }
118         if ($this->_flagFrozen) {
119             return $this->getFrozenHtml();
120         }
122         $id          = $this->_attributes['id'];
123         $elname      = $this->_attributes['name'];
124         $subdirs     = $this->_options['subdirs'];
125         $maxbytes    = $this->_options['maxbytes'];
126         $draftitemid = $this->getValue();
127         $accepted_types = $this->_options['accepted_types'];
129         if (empty($draftitemid)) {
130             // no existing area info provided - let's use fresh new draft area
131             require_once("$CFG->libdir/filelib.php");
132             $this->setValue(file_get_unused_draft_itemid());
133             $draftitemid = $this->getValue();
134         }
136         $client_id = uniqid();
138         // filemanager options
139         $options = new stdClass();
140         $options->mainfile  = $this->_options['mainfile'];
141         $options->maxbytes  = $this->_options['maxbytes'];
142         $options->maxfiles  = $this->getMaxfiles();
143         $options->client_id = $client_id;
144         $options->itemid    = $draftitemid;
145         $options->subdirs   = $this->_options['subdirs'];
146         $options->target    = $id;
147         $options->accepted_types = $accepted_types;
148         $options->return_types = FILE_INTERNAL;
149         $options->context = $PAGE->context;
150         $options->elementname = $elname;
152         $html = $this->_getTabs();
153         $html .= form_filemanager_render($options);
155         $html .= '<input id="id_'.$elname.'" value="'.$draftitemid.'" name="'.$elname.'" type="hidden" class="filemanagerhidden"/>';
156         return $html;
157     }
162 /**
163  * Data structure representing a file manager.
164  *
165  * @copyright 2010 Dongsheng Cai
166  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
167  * @since     Moodle 2.0
168  */
169 class form_filemanaer_x {
170     //TODO: do not use this abstraction (skodak)
172     public $options;
173     public function __construct(stdClass $options) {
174         global $CFG, $USER, $PAGE;
175         require_once($CFG->dirroot. '/repository/lib.php');
176         $defaults = array(
177             'maxbytes'=>-1,
178             'maxfiles'=>-1,
179             'itemid'=>0,
180             'subdirs'=>0,
181             'client_id'=>uniqid(),
182             'accepted_types'=>'*',
183             'return_types'=>FILE_INTERNAL,
184             'context'=>$PAGE->context
185             );
186         foreach ($defaults as $key=>$value) {
187             if (empty($options->$key)) {
188                 $options->$key = $value;
189             }
190         }
192         $fs = get_file_storage();
194         // initilise options, getting files in root path
195         $this->options = file_get_drafarea_files($options->itemid, '/');
197         // calculate file count
198         $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
199         $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id', false);
200         $filecount = count($files);
201         $this->options->filecount = $filecount;
203         // copying other options
204         foreach ($options as $name=>$value) {
205             $this->options->$name = $value;
206         }
208         // building file picker options
209         $params = new stdClass();
210         $params->accepted_types = $options->accepted_types;
211         $params->return_types = $options->return_types;
212         $params->context = $options->context;
213         $params->env = 'filemanager';
214         $params->disable_types = !empty($options->disable_types)?$options->disable_types:array();
215         $filepicker_options = initialise_filepicker($params);
216         $this->options->filepicker = $filepicker_options;
217     }
220 /**
221  * Print the file manager
222  *
223  * <pre>
224  * $OUTPUT->file_manager($options);
225  * </pre>
226  *
227  * @param array $options associative array with file manager options
228  *   options are:
229  *       maxbytes=>-1,
230  *       maxfiles=>-1,
231  *       itemid=>0,
232  *       subdirs=>false,
233  *       client_id=>uniqid(),
234  *       acepted_types=>'*',
235  *       return_types=>FILE_INTERNAL,
236  *       context=>$PAGE->context
237  * @return string HTML fragment
238  */
239 function form_filemanager_render($options) {
240     global $CFG, $OUTPUT, $PAGE;
242     $fm = new form_filemanaer_x($options); //TODO: this is unnecessary here, the nested options are getting too complex
244     static $filemanagertemplateloaded;
246     $html = '';
247     $options = $fm->options;
248     $straddfile  = get_string('addfile', 'repository');
249     $strmakedir  = get_string('makeafolder', 'moodle');
250     $strdownload = get_string('downloadfolder', 'repository');
251     $strloading  = get_string('loading', 'repository');
253     $icon_progress = $OUTPUT->pix_icon('i/loading_small', $strloading).'';
255     $client_id = $options->client_id;
256     $itemid    = $options->itemid;
257     list($context, $course, $cm) = get_context_info_array($options->context->id);
258     if (is_object($course)) {
259         $course_maxbytes = $course->maxbytes;
260     } else {
261         $course_maxbytes = $CFG->maxbytes;
262     }
264     if ($options->maxbytes == -1 || empty($options->maxbytes)) {
265         $options->maxbytes = $CFG->maxbytes;
266     }
268     if (empty($options->filecount)) {
269         $extra = ' style="display:none"';
270     } else {
271         $extra = '';
272     }
274     $maxsize = get_string('maxfilesize', 'moodle', display_size(get_max_upload_file_size($CFG->maxbytes, $course_maxbytes, $options->maxbytes)));
275     $html .= <<<FMHTML
276 <div class="filemanager-loading mdl-align" id='filemanager-loading-{$client_id}'>
277 $icon_progress
278 </div>
279 <div id="filemanager-wrapper-{$client_id}" style="display:none">
280     <div class="fm-breadcrumb" id="fm-path-{$client_id}"></div>
281     <div class="filemanager-toolbar">
282         <input type="button" class="fm-btn-add" id="btnadd-{$client_id}" onclick="return false" value="{$straddfile}" />
283         <input type="button" class="fm-btn-mkdir" id="btncrt-{$client_id}" onclick="return false" value="{$strmakedir}" />
284         <input type="button" class="fm-btn-download" id="btndwn-{$client_id}" onclick="return false" {$extra} value="{$strdownload}" />
285         <span> $maxsize </span>
286     </div>
287     <div class="filemanager-container" id="filemanager-{$client_id}">
288         <ul id="draftfiles-{$client_id}" class="fm-filelist">
289             <li>Loading...</li>
290         </ul>
291     </div>
292 </div>
293 <div class='clearer'></div>
294 FMHTML;
295     if (empty($filemanagertemplateloaded)) {
296         $filemanagertemplateloaded = true;
297         $html .= <<<FMHTML
298 <div id="fm-template" style="display:none">___fullname___ ___action___</div>
299 FMHTML;
300     }
302     $module = array(
303         'name'=>'form_filemanager',
304         'fullpath'=>'/lib/form/filemanager.js',
305         'requires' => array('core_filepicker', 'base', 'io-base', 'node', 'node-event-simulate', 'json', 'yui2-button', 'yui2-container', 'yui2-layout', 'yui2-menu', 'yui2-treeview'),
306         'strings' => array(array('loading', 'repository'), array('nomorefiles', 'repository'), array('confirmdeletefile', 'repository'),
307              array('add', 'repository'), array('accessiblefilepicker', 'repository'), array('move', 'moodle'),
308              array('cancel', 'moodle'), array('download', 'moodle'), array('ok', 'moodle'),
309              array('emptylist', 'repository'), array('nofilesattached', 'repository'), array('entername', 'repository'), array('enternewname', 'repository'),
310              array('zip', 'editor'), array('unzip', 'moodle'), array('rename', 'moodle'), array('delete', 'moodle'),
311              array('cannotdeletefile', 'error'), array('confirmdeletefile', 'repository'),
312              array('nopathselected', 'repository'), array('popupblockeddownload', 'repository'),
313              array('draftareanofiles', 'repository'), array('path', 'moodle'), array('setmainfile', 'repository'),
314              array('moving', 'repository'), array('files', 'moodle')
315         )
316     );
317     $PAGE->requires->js_module($module);
318     $PAGE->requires->js_init_call('M.form_filemanager.init', array($options), true, $module);
320     // non javascript file manager
321     $filemanagerurl = new moodle_url('/repository/draftfiles_manager.php', array(
322         'env'=>'filemanager',
323         'action'=>'browse',
324         'itemid'=>$itemid,
325         'subdirs'=>$options->subdirs,
326         'maxbytes'=>$options->maxbytes,
327         'maxfiles'=>$options->maxfiles,
328         'ctx_id'=>$PAGE->context->id,
329         'course'=>$PAGE->course->id,
330         'sesskey'=>sesskey(),
331         ));
333     $html .= '<noscript>';
334     $html .= "<div><object type='text/html' data='$filemanagerurl' height='160' width='600' style='border:1px solid #000'></object></div>";
335     $html .= '</noscript>';
338     return $html;