Differences Between: [Versions 311 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 namespace core_contentbank\form; 18 19 /** 20 * Upload files to content bank form 21 * 22 * @package core_contentbank 23 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class upload_files extends \core_form\dynamic_form { 27 28 /** 29 * Add elements to this form. 30 */ 31 public function definition() { 32 $mform = $this->_form; 33 34 $mform->addElement('hidden', 'contextid'); 35 $mform->setType('contextid', PARAM_INT); 36 37 $mform->addElement('hidden', 'id'); 38 $mform->setType('id', PARAM_INT); 39 40 $mform->addElement('filepicker', 'file', get_string('file', 'core_contentbank'), null, $this->get_options()); 41 $mform->addHelpButton('file', 'file', 'core_contentbank'); 42 $mform->addRule('file', null, 'required'); 43 } 44 45 /** 46 * Validate incoming data. 47 * 48 * @param array $data 49 * @param array $files 50 * @return array 51 */ 52 public function validation($data, $files) { 53 $errors = array(); 54 $draftitemid = $data['file']; 55 $options = $this->get_options(); 56 if (file_is_draft_area_limit_reached($draftitemid, $options['areamaxbytes'])) { 57 $errors['file'] = get_string('userquotalimit', 'error'); 58 } 59 return $errors; 60 } 61 62 /** 63 * Check if current user has access to this form, otherwise throw exception 64 * 65 * Sometimes permission check may depend on the action and/or id of the entity. 66 * If necessary, form data is available in $this->_ajaxformdata or 67 * by calling $this->optional_param() 68 */ 69 protected function check_access_for_dynamic_submission(): void { 70 require_capability('moodle/contentbank:upload', $this->get_context_for_dynamic_submission()); 71 72 // Check the context used by the content bank is allowed. 73 $cb = new \core_contentbank\contentbank(); 74 if (!$cb->is_context_allowed($this->get_context_for_dynamic_submission())) { 75 throw new \moodle_exception('contextnotallowed', 'core_contentbank'); 76 } 77 78 // If $id is defined, the file content will be replaced (instead of uploading a new one). 79 // Check that the user has the right permissions to replace this content file. 80 $id = $this->optional_param('id', null, PARAM_INT); 81 if ($id) { 82 $content = $cb->get_content_from_id($id); 83 $contenttype = $content->get_content_type_instance(); 84 if (!$contenttype->can_manage($content) || !$contenttype->can_upload()) { 85 throw new \moodle_exception('nopermissions', 'error', '', null, get_string('replacecontent', 'contentbank')); 86 } 87 } 88 } 89 90 /** 91 * Returns form context 92 * 93 * If context depends on the form data, it is available in $this->_ajaxformdata or 94 * by calling $this->optional_param() 95 * 96 * @return \context 97 */ 98 protected function get_context_for_dynamic_submission(): \context { 99 $contextid = $this->optional_param('contextid', null, PARAM_INT); 100 return \context::instance_by_id($contextid, MUST_EXIST); 101 } 102 103 /** 104 * File upload options 105 * 106 * @return array 107 * @throws \coding_exception 108 */ 109 protected function get_options(): array { 110 global $CFG; 111 112 $maxbytes = $CFG->userquota; 113 $maxareabytes = $CFG->userquota; 114 if (has_capability('moodle/user:ignoreuserquota', $this->get_context_for_dynamic_submission())) { 115 $maxbytes = USER_CAN_IGNORE_FILE_SIZE_LIMITS; 116 $maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED; 117 } 118 119 $cb = new \core_contentbank\contentbank(); 120 $id = $this->optional_param('id', null, PARAM_INT); 121 if ($id) { 122 $content = $cb->get_content_from_id($id); 123 $contenttype = $content->get_content_type_instance(); 124 $extensions = $contenttype->get_manageable_extensions(); 125 $acceptedtypes = implode(',', $extensions); 126 } else { 127 $acceptedtypes = $cb->get_supported_extensions_as_string($this->get_context_for_dynamic_submission()); 128 } 129 130 return ['subdirs' => 1, 'maxbytes' => $maxbytes, 'maxfiles' => -1, 'accepted_types' => $acceptedtypes, 131 'areamaxbytes' => $maxareabytes]; 132 } 133 134 /** 135 * Process the form submission, used if form was submitted via AJAX 136 * 137 * This method can return scalar values or arrays that can be json-encoded, they will be passed to the caller JS. 138 * 139 * Submission data can be accessed as: $this->get_data() 140 * 141 * @return mixed 142 */ 143 public function process_dynamic_submission() { 144 global $USER; 145 146 // Get the file and create the content based on it. 147 $usercontext = \context_user::instance($USER->id); 148 $fs = get_file_storage(); 149 $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $this->get_data()->file, 'itemid, filepath, 150 filename', false); 151 if (!empty($files)) { 152 $file = reset($files); 153 $cb = new \core_contentbank\contentbank(); 154 try { 155 if ($this->get_data()->id) { 156 $content = $cb->get_content_from_id($this->get_data()->id); 157 $contenttype = $content->get_content_type_instance(); 158 $content = $contenttype->replace_content($file, $content); 159 } else { 160 $content = $cb->create_content_from_file($this->get_context_for_dynamic_submission(), $USER->id, $file); 161 } 162 $params = ['id' => $content->get_id(), 'contextid' => $this->get_context_for_dynamic_submission()->id]; 163 $url = new \moodle_url('/contentbank/view.php', $params); 164 } catch (\Exception $e) { 165 // Redirect to the right page (depending on if content is new or existing) and display an error. 166 if ($this->get_data()->id) { 167 $content = $cb->get_content_from_id($this->get_data()->id); 168 $params = [ 169 'id' => $content->get_id(), 170 'contextid' => $this->get_context_for_dynamic_submission()->id, 171 'errormsg' => 'notvalidpackage', 172 ]; 173 $url = new \moodle_url('/contentbank/view.php', $params); 174 } else { 175 $url = new \moodle_url('/contentbank/index.php', [ 176 'contextid' => $this->get_context_for_dynamic_submission()->id, 177 'errormsg' => 'notvalidpackage'], 178 ); 179 } 180 } 181 182 return ['returnurl' => $url->out(false)]; 183 } 184 185 return null; 186 } 187 188 /** 189 * Load in existing data as form defaults 190 * 191 * Can be overridden to retrieve existing values from db by entity id and also 192 * to preprocess editor and filemanager elements 193 * 194 * Example: 195 * $this->set_data(get_entity($this->_ajaxformdata['id'])); 196 */ 197 public function set_data_for_dynamic_submission(): void { 198 $data = (object)[ 199 'contextid' => $this->optional_param('contextid', null, PARAM_INT), 200 'id' => $this->optional_param('id', null, PARAM_INT), 201 ]; 202 $this->set_data($data); 203 } 204 205 /** 206 * Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX 207 * 208 * This is used in the form elements sensitive to the page url, such as Atto autosave in 'editor' 209 * 210 * If the form has arguments (such as 'id' of the element being edited), the URL should 211 * also have respective argument. 212 * 213 * @return \moodle_url 214 */ 215 protected function get_page_url_for_dynamic_submission(): \moodle_url { 216 $params = ['contextid' => $this->get_context_for_dynamic_submission()->id]; 217 218 $id = $this->optional_param('id', null, PARAM_INT); 219 if ($id) { 220 $url = '/contentbank/view.php'; 221 $params['id'] = $id; 222 } else { 223 $url = '/contentbank/index.php'; 224 } 225 226 return new \moodle_url($url, $params); 227 } 228 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body