See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 403]
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 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 */ 27 28 global $CFG; 29 30 require_once('HTML/QuickForm/element.php'); 31 require_once($CFG->dirroot.'/lib/filelib.php'); 32 require_once($CFG->dirroot.'/repository/lib.php'); 33 require_once ('templatable_form_element.php'); 34 35 /** 36 * Filemanager form element 37 * 38 * FilemaneManager lets user to upload/manage multiple files 39 * @package core_form 40 * @category form 41 * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class MoodleQuickForm_filemanager extends HTML_QuickForm_element implements templatable { 45 use templatable_form_element { 46 export_for_template as export_for_template_base; 47 } 48 49 /** @var string html for help button, if empty then no help will icon will be dispalyed. */ 50 public $_helpbutton = ''; 51 52 /** @var array options provided to initalize filemanager */ 53 // PHP doesn't support 'key' => $value1 | $value2 in class definition 54 // We cannot do $_options = array('return_types'=> FILE_INTERNAL | FILE_REFERENCE); 55 // So I have to set null here, and do it in constructor 56 protected $_options = array('mainfile' => '', 'subdirs' => 1, 'maxbytes' => -1, 'maxfiles' => -1, 57 'accepted_types' => '*', 'return_types' => null, 'areamaxbytes' => FILE_AREA_MAX_BYTES_UNLIMITED); 58 59 /** 60 * Constructor 61 * 62 * @param string $elementName (optional) name of the filemanager 63 * @param string $elementLabel (optional) filemanager label 64 * @param array $attributes (optional) Either a typical HTML attribute string 65 * or an associative array 66 * @param array $options set of options to initalize filemanager 67 */ 68 public function __construct($elementName=null, $elementLabel=null, $attributes=null, $options=null) { 69 global $CFG, $PAGE; 70 71 $options = (array)$options; 72 foreach ($options as $name=>$value) { 73 if (array_key_exists($name, $this->_options)) { 74 $this->_options[$name] = $value; 75 } 76 } 77 if (!empty($options['maxbytes'])) { 78 $this->_options['maxbytes'] = get_user_max_upload_file_size($PAGE->context, $CFG->maxbytes, $options['maxbytes']); 79 } 80 if (empty($options['return_types'])) { 81 $this->_options['return_types'] = (FILE_INTERNAL | FILE_REFERENCE | FILE_CONTROLLED_LINK); 82 } 83 $this->_type = 'filemanager'; 84 parent::__construct($elementName, $elementLabel, $attributes); 85 } 86 87 /** 88 * Old syntax of class constructor. Deprecated in PHP7. 89 * 90 * @deprecated since Moodle 3.1 91 */ 92 public function MoodleQuickForm_filemanager($elementName=null, $elementLabel=null, $attributes=null, $options=null) { 93 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); 94 self::__construct($elementName, $elementLabel, $attributes, $options); 95 } 96 97 /** 98 * Called by HTML_QuickForm whenever form event is made on this element 99 * 100 * @param string $event Name of event 101 * @param mixed $arg event arguments 102 * @param object $caller calling object 103 * @return bool 104 */ 105 function onQuickFormEvent($event, $arg, &$caller) 106 { 107 switch ($event) { 108 case 'createElement': 109 $caller->setType($arg[0], PARAM_INT); 110 break; 111 } 112 return parent::onQuickFormEvent($event, $arg, $caller); 113 } 114 115 /** 116 * Sets name of filemanager 117 * 118 * @param string $name name of the filemanager 119 */ 120 function setName($name) { 121 $this->updateAttributes(array('name'=>$name)); 122 } 123 124 /** 125 * Returns name of filemanager 126 * 127 * @return string 128 */ 129 function getName() { 130 return $this->getAttribute('name'); 131 } 132 133 /** 134 * Updates filemanager attribute value 135 * 136 * @param string $value value to set 137 */ 138 function setValue($value) { 139 $this->updateAttributes(array('value'=>$value)); 140 } 141 142 /** 143 * Returns filemanager attribute value 144 * 145 * @return string 146 */ 147 function getValue() { 148 return $this->getAttribute('value'); 149 } 150 151 /** 152 * Returns maximum file size which can be uploaded 153 * 154 * @return int 155 */ 156 function getMaxbytes() { 157 return $this->_options['maxbytes']; 158 } 159 160 /** 161 * Sets maximum file size which can be uploaded 162 * 163 * @param int $maxbytes file size 164 */ 165 function setMaxbytes($maxbytes) { 166 global $CFG, $PAGE; 167 $this->_options['maxbytes'] = get_user_max_upload_file_size($PAGE->context, $CFG->maxbytes, $maxbytes); 168 } 169 170 /** 171 * Returns the maximum size of the area. 172 * 173 * @return int 174 */ 175 function getAreamaxbytes() { 176 return $this->_options['areamaxbytes']; 177 } 178 179 /** 180 * Sets the maximum size of the area. 181 * 182 * @param int $areamaxbytes size limit 183 */ 184 function setAreamaxbytes($areamaxbytes) { 185 $this->_options['areamaxbytes'] = $areamaxbytes; 186 } 187 188 /** 189 * Returns true if subdirectoy can be created, else false 190 * 191 * @return bool 192 */ 193 function getSubdirs() { 194 return $this->_options['subdirs']; 195 } 196 197 /** 198 * Set option to create sub directory, while uploading file 199 * 200 * @param bool $allow true if sub directory can be created. 201 */ 202 function setSubdirs($allow) { 203 $this->_options['subdirs'] = $allow; 204 } 205 206 /** 207 * Returns maximum number of files which can be uploaded 208 * 209 * @return int 210 */ 211 function getMaxfiles() { 212 return $this->_options['maxfiles']; 213 } 214 215 /** 216 * Sets maximum number of files which can be uploaded. 217 * 218 * @param int $num number of files 219 */ 220 function setMaxfiles($num) { 221 $this->_options['maxfiles'] = $num; 222 } 223 224 /** 225 * Returns html for help button. 226 * 227 * @return string html for help button 228 */ 229 function getHelpButton() { 230 return $this->_helpbutton; 231 } 232 233 /** 234 * Returns type of filemanager element 235 * 236 * @return string 237 */ 238 function getElementTemplateType() { 239 if ($this->_flagFrozen){ 240 return 'nodisplay'; 241 } else { 242 return 'default'; 243 } 244 } 245 246 /** 247 * Returns HTML for filemanager form element. 248 * 249 * @return string 250 */ 251 function toHtml() { 252 global $CFG, $USER, $COURSE, $PAGE, $OUTPUT; 253 require_once("$CFG->dirroot/repository/lib.php"); 254 255 // security - never ever allow guest/not logged in user to upload anything or use this element! 256 if (isguestuser() or !isloggedin()) { 257 throw new \moodle_exception('noguest'); 258 } 259 260 if ($this->_flagFrozen) { 261 return $this->getFrozenHtml(); 262 } 263 264 $id = $this->_attributes['id']; 265 $elname = $this->_attributes['name']; 266 $subdirs = $this->_options['subdirs']; 267 $maxbytes = $this->_options['maxbytes']; 268 $draftitemid = $this->getValue(); 269 $accepted_types = $this->_options['accepted_types']; 270 271 if (empty($draftitemid)) { 272 // no existing area info provided - let's use fresh new draft area 273 require_once("$CFG->libdir/filelib.php"); 274 $this->setValue(file_get_unused_draft_itemid()); 275 $draftitemid = $this->getValue(); 276 } 277 278 $client_id = uniqid(); 279 280 // filemanager options 281 $options = new stdClass(); 282 $options->mainfile = $this->_options['mainfile']; 283 $options->maxbytes = $this->_options['maxbytes']; 284 $options->maxfiles = $this->getMaxfiles(); 285 $options->client_id = $client_id; 286 $options->itemid = $draftitemid; 287 $options->subdirs = $this->_options['subdirs']; 288 $options->target = $id; 289 $options->accepted_types = $accepted_types; 290 $options->return_types = $this->_options['return_types']; 291 $options->context = $PAGE->context; 292 $options->areamaxbytes = $this->_options['areamaxbytes']; 293 294 $html = $this->_getTabs(); 295 $fm = new form_filemanager($options); 296 $output = $PAGE->get_renderer('core', 'files'); 297 $html .= $output->render($fm); 298 299 $html .= html_writer::empty_tag('input', array('value' => $draftitemid, 'name' => $elname, 'type' => 'hidden', 'id' => $id)); 300 301 if (!empty($options->accepted_types) && $options->accepted_types != '*') { 302 $html .= html_writer::tag('p', get_string('filesofthesetypes', 'form')); 303 $util = new \core_form\filetypes_util(); 304 $filetypes = $options->accepted_types; 305 $filetypedescriptions = $util->describe_file_types($filetypes); 306 $html .= $OUTPUT->render_from_template('core_form/filetypes-descriptions', $filetypedescriptions); 307 } 308 309 return $html; 310 } 311 312 public function export_for_template(renderer_base $output) { 313 $context = $this->export_for_template_base($output); 314 $context['html'] = $this->toHtml(); 315 return $context; 316 } 317 318 /** 319 * Check that all files have the allowed type. 320 * 321 * @param int $value Draft item id with the uploaded files. 322 * @return string|null Validation error message or null. 323 */ 324 public function validateSubmitValue($value) { 325 326 if (empty($value)) { 327 return; 328 } 329 330 $filetypesutil = new \core_form\filetypes_util(); 331 $allowlist = $filetypesutil->normalize_file_types($this->_options['accepted_types']); 332 333 if (empty($allowlist) || $allowlist === ['*']) { 334 // Any file type is allowed, nothing to check here. 335 return; 336 } 337 338 $draftfiles = file_get_all_files_in_draftarea($value); 339 $wrongfiles = array(); 340 341 if (empty($draftfiles)) { 342 // No file uploaded, nothing to check here. 343 return; 344 } 345 346 foreach ($draftfiles as $file) { 347 if (!$filetypesutil->is_allowed_file_type($file->filename, $allowlist)) { 348 $wrongfiles[] = $file->filename; 349 } 350 } 351 352 if ($wrongfiles) { 353 $a = array( 354 'allowlist' => implode(', ', $allowlist), 355 'wrongfiles' => implode(', ', $wrongfiles), 356 ); 357 return get_string('err_wrongfileextension', 'core_form', $a); 358 } 359 360 return; 361 } 362 } 363 364 /** 365 * Data structure representing a file manager. 366 * 367 * This class defines the data structure for file mnager 368 * 369 * @package core_form 370 * @copyright 2010 Dongsheng Cai 371 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 372 * @todo do not use this abstraction (skodak) 373 */ 374 class form_filemanager implements renderable { 375 /** @var stdClass $options options for filemanager */ 376 public $options; 377 378 /** 379 * Constructor 380 * 381 * @param stdClass $options options for filemanager 382 * default options are: 383 * maxbytes=>-1, 384 * areamaxbytes => FILE_AREA_MAX_BYTES_UNLIMITED, 385 * maxfiles=>-1, 386 * itemid=>0, 387 * subdirs=>false, 388 * client_id=>uniqid(), 389 * acepted_types=>'*', 390 * return_types=>FILE_INTERNAL, 391 * context=>$PAGE->context, 392 * author=>fullname($USER), 393 * licenses=>array build from $CFG->licenses, 394 * defaultlicense=>$CFG->sitedefaultlicense 395 */ 396 public function __construct(stdClass $options) { 397 global $CFG, $USER, $PAGE; 398 require_once($CFG->dirroot. '/repository/lib.php'); 399 require_once($CFG->libdir . '/licenselib.php'); 400 $defaults = array( 401 'maxbytes'=>-1, 402 'areamaxbytes' => FILE_AREA_MAX_BYTES_UNLIMITED, 403 'maxfiles'=>-1, 404 'itemid'=>0, 405 'subdirs'=>0, 406 'client_id'=>uniqid(), 407 'accepted_types'=>'*', 408 'return_types'=>FILE_INTERNAL, 409 'context'=>$PAGE->context, 410 'author'=>fullname($USER), 411 'licenses'=>array() 412 ); 413 414 $defaults['licenses'] = license_manager::get_licenses(); 415 416 if (!empty($CFG->sitedefaultlicense)) { 417 $defaults['defaultlicense'] = $CFG->sitedefaultlicense; 418 } 419 foreach ($defaults as $key=>$value) { 420 // Using !isset() prevents us from overwriting falsey values with defaults (as empty() did). 421 if (!isset($options->$key)) { 422 $options->$key = $value; 423 } 424 } 425 426 $fs = get_file_storage(); 427 428 // initilise options, getting files in root path 429 $this->options = file_get_drafarea_files($options->itemid, '/'); 430 431 // calculate file count 432 $usercontext = context_user::instance($USER->id); 433 $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id', false); 434 $filecount = count($files); 435 $this->options->filecount = $filecount; 436 437 // copying other options 438 foreach ($options as $name=>$value) { 439 $this->options->$name = $value; 440 } 441 442 // calculate the maximum file size as minimum from what is specified in filepicker options, 443 // course options, global configuration and php settings 444 $coursebytes = $maxbytes = 0; 445 list($context, $course, $cm) = get_context_info_array($this->options->context->id); 446 if (is_object($course)) { 447 $coursebytes = $course->maxbytes; 448 } 449 if (!empty($this->options->maxbytes) && $this->options->maxbytes > 0) { 450 $maxbytes = $this->options->maxbytes; 451 } 452 $this->options->maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $coursebytes, $maxbytes); 453 454 $this->options->userprefs = array(); 455 $this->options->userprefs['recentviewmode'] = get_user_preferences('filemanager_recentviewmode', ''); 456 user_preference_allow_ajax_update('filemanager_recentviewmode', PARAM_INT); 457 458 // building file picker options 459 $params = new stdClass(); 460 $params->accepted_types = $options->accepted_types; 461 $params->return_types = $options->return_types; 462 $params->context = $options->context; 463 $params->env = 'filemanager'; 464 $params->disable_types = !empty($options->disable_types)?$options->disable_types:array(); 465 $filepicker_options = initialise_filepicker($params); 466 $this->options->filepicker = $filepicker_options; 467 } 468 469 public function get_nonjsurl() { 470 global $PAGE; 471 return new moodle_url('/repository/draftfiles_manager.php', array( 472 'env'=>'filemanager', 473 'action'=>'browse', 474 'itemid'=>$this->options->itemid, 475 'subdirs'=>$this->options->subdirs, 476 'maxbytes'=>$this->options->maxbytes, 477 'areamaxbytes' => $this->options->areamaxbytes, 478 'maxfiles'=>$this->options->maxfiles, 479 'ctx_id'=>$PAGE->context->id, // TODO ? 480 'course'=>$PAGE->course->id, // TODO ? 481 'sesskey'=>sesskey(), 482 )); 483 } 484 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body