Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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