09071fb3cea44aba463c63009ef1cac877cf2f5a
[moodle.git] / lib / form / filepicker.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  * Filepicker form element
20  *
21  * Contains HTML class for a single filepicker 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/button.php");
31 require_once($CFG->dirroot.'/repository/lib.php');
33 /**
34  * Filepicker form element
35  *
36  * HTML class for a single filepicker element (based on button)
37  *
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_filepicker extends HTML_QuickForm_input {
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('maxbytes'=>0, 'accepted_types'=>'*', 'return_types'=>null);
53     /**
54      * Constructor
55      *
56      * @param string $elementName (optional) name of the filepicker
57      * @param string $elementLabel (optional) filepicker 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 filepicker
61      */
62     function MoodleQuickForm_filepicker($elementName=null, $elementLabel=null, $attributes=null, $options=null) {
63         global $CFG;
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['return_types'])) {
72             $this->_options['return_types'] = FILE_INTERNAL | FILE_REFERENCE;
73         }
74         if (!empty($options['maxbytes'])) {
75             $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $options['maxbytes']);
76         }
77         $this->_type = 'filepicker';
78         parent::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
79     }
81     /**
82      * Sets help button for filepicker
83      *
84      * @param mixed $helpbuttonargs arguments to create help button
85      * @param string $function name of the callback function
86      * @deprecated since Moodle 2.0. Please do not call this function any more.
87      * @todo MDL-31047 this api will be removed.
88      * @see MoodleQuickForm::setHelpButton()
89      */
90     function setHelpButton($helpbuttonargs, $function='helpbutton') {
91         debugging('component setHelpButton() is not used any more, please use $mform->setHelpButton() instead');
92     }
94     /**
95      * Returns html for help button.
96      *
97      * @return string html for help button
98      */
99     function getHelpButton() {
100         return $this->_helpbutton;
101     }
103     /**
104      * Returns type of filepicker element
105      *
106      * @return string
107      */
108     function getElementTemplateType() {
109         if ($this->_flagFrozen){
110             return 'nodisplay';
111         } else {
112             return 'default';
113         }
114     }
116     /**
117      * Returns HTML for filepicker form element.
118      *
119      * @return string
120      */
121     function toHtml() {
122         global $CFG, $COURSE, $USER, $PAGE, $OUTPUT;
123         $id     = $this->_attributes['id'];
124         $elname = $this->_attributes['name'];
126         if ($this->_flagFrozen) {
127             return $this->getFrozenHtml();
128         }
129         if (!$draftitemid = (int)$this->getValue()) {
130             // no existing area info provided - let's use fresh new draft area
131             $draftitemid = file_get_unused_draft_itemid();
132             $this->setValue($draftitemid);
133         }
135         if ($COURSE->id == SITEID) {
136             $context = get_context_instance(CONTEXT_SYSTEM);
137         } else {
138             $context = get_context_instance(CONTEXT_COURSE, $COURSE->id);
139         }
141         $client_id = uniqid();
143         $args = new stdClass();
144         // need these three to filter repositories list
145         $args->accepted_types = $this->_options['accepted_types']?$this->_options['accepted_types']:'*';
146         $args->return_types = FILE_INTERNAL | FILE_REFERENCE;
147         $args->itemid = $draftitemid;
148         $args->maxbytes = $this->_options['maxbytes'];
149         $args->context = $PAGE->context;
150         $args->buttonname = $elname.'choose';
151         $args->elementname = $elname;
153         $html = $this->_getTabs();
154         $fp = new file_picker($args);
155         $options = $fp->options;
156         $options->context = $PAGE->context;
157         $html .= $OUTPUT->render($fp);
158         $html .= '<input type="hidden" name="'.$elname.'" id="'.$id.'" value="'.$draftitemid.'" class="filepickerhidden"/>';
160         $module = array('name'=>'form_filepicker', 'fullpath'=>'/lib/form/filepicker.js', 'requires'=>array('core_filepicker', 'node', 'node-event-simulate', 'core_dndupload'));
161         $PAGE->requires->js_init_call('M.form_filepicker.init', array($fp->options), true, $module);
163         $nonjsfilepicker = new moodle_url('/repository/draftfiles_manager.php', array(
164             'env'=>'filepicker',
165             'action'=>'browse',
166             'itemid'=>$draftitemid,
167             'subdirs'=>0,
168             'maxbytes'=>$options->maxbytes,
169             'maxfiles'=>1,
170             'ctx_id'=>$PAGE->context->id,
171             'course'=>$PAGE->course->id,
172             'sesskey'=>sesskey(),
173             ));
175         // non js file picker
176         $html .= '<noscript>';
177         $html .= "<div><object type='text/html' data='$nonjsfilepicker' height='160' width='600' style='border:1px solid #000'></object></div>";
178         $html .= '</noscript>';
180         return $html;
181     }
183     /**
184      * export uploaded file
185      *
186      * @param array $submitValues values submitted.
187      * @param bool $assoc specifies if returned array is associative
188      * @return array
189      */
190     function exportValue(&$submitValues, $assoc = false) {
191         global $USER;
193         $draftitemid = $this->_findValue($submitValues);
194         if (null === $draftitemid) {
195             $draftitemid = $this->getValue();
196         }
198         // make sure max one file is present and it is not too big
199         if (!is_null($draftitemid)) {
200             $fs = get_file_storage();
201             $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
202             if ($files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id DESC', false)) {
203                 $file = array_shift($files);
204                 if ($this->_options['maxbytes'] and $file->get_filesize() > $this->_options['maxbytes']) {
205                     // bad luck, somebody tries to sneak in oversized file
206                     $file->delete();
207                 }
208                 foreach ($files as $file) {
209                     // only one file expected
210                     $file->delete();
211                 }
212             }
213         }
215         return $this->_prepareValue($draftitemid, true);
216     }