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 mod_data\form;
18
 
19
use context;
20
use core\notification;
21
use moodle_exception;
22
use moodle_url;
23
use core_form\dynamic_form;
24
use mod_data\manager;
25
use mod_data\preset;
26
 
27
/**
28
 * Save database as preset form.
29
 *
30
 * @package    mod_data
31
 * @copyright  2021 Mihail Geshoski <paulh@moodle.com>
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
34
class save_as_preset extends dynamic_form {
35
 
36
    /**
37
     * Form definition
38
     */
39
    protected function definition() {
40
 
41
        $this->_form->addElement('hidden', 'd');
42
        $this->_form->setType('d', PARAM_INT);
43
        $this->_form->addElement('hidden', 'action', 'save');
44
        $this->_form->setType('action', PARAM_ALPHANUM);
45
        $this->_form->addElement('hidden', 'oldpresetname', '');
46
        $this->_form->setType('oldpresetname', PARAM_FILE);
47
 
48
        $this->_form->addElement('text', 'name', get_string('name'), ['size' => 60]);
49
        $this->_form->setType('name', PARAM_FILE);
50
        $this->_form->addRule('name', null, 'required');
51
 
52
        // Overwrite checkbox will be hidden by default. It will only appear if there is an error when saving the preset.
53
        $this->_form->addElement('checkbox', 'overwrite', '', get_string('overrwritedesc', 'data'), ['class' => 'hidden']);
54
 
55
        $this->_form->addElement('textarea', 'description', get_string('description'), ['rows' => 5, 'cols' => 60]);
56
        $this->_form->setType('name', PARAM_TEXT);
57
    }
58
 
59
    /**
60
     * Return form context
61
     *
62
     * @return context
63
     */
64
    protected function get_context_for_dynamic_submission(): context {
65
        global $DB;
66
 
67
        $d = $this->optional_param('d', null, PARAM_INT);
68
        $data = $DB->get_record('data', array('id' => $d), '*', MUST_EXIST);
69
        $course = $DB->get_record('course', array('id' => $data->course), '*', MUST_EXIST);
70
        $cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
71
 
72
        return \context_module::instance($cm->id, MUST_EXIST);
73
    }
74
 
75
    /**
76
     * Perform some validation.
77
     *
78
     * @param array $formdata
79
     * @param array $files
80
     * @return array
81
     */
82
    public function validation($formdata, $files): array {
83
 
84
        $errors = parent::validation($formdata, $files);
85
        $context = $this->get_context_for_dynamic_submission();
86
        $cm = get_coursemodule_from_id('', $context->instanceid, 0, false, MUST_EXIST);
87
        $manager = manager::create_from_coursemodule($cm);
88
 
89
        if (!empty($formdata['overwrite'])) {
90
            $presets = $manager->get_available_presets();
91
            $selectedpreset = new \stdClass();
92
            foreach ($presets as $preset) {
93
                if ($preset->name == $formdata['name']) {
94
                    $selectedpreset = $preset;
95
                    break;
96
                }
97
            }
98
            if (!$selectedpreset instanceof preset || !$selectedpreset->can_manage()) {
99
                $errors['name'] = get_string('cannotoverwritepreset', 'data');
100
            }
101
        } else if ($formdata['action'] == 'saveaspreset' || $formdata['oldpresetname'] != $formdata['name']) {
102
 
103
            // If the preset exists when a new preset is saved or name has changed, then we need to throw an error.
104
            $sitepresets = $manager->get_available_saved_presets();
105
            $usercandelete = false;
106
            foreach ($sitepresets as $preset) {
107
                if ($formdata['name'] == $preset->name) {
108
                    if ($preset->can_manage()) {
109
                        $errors['name'] = get_string('errorpresetexists', 'data');
110
                        $usercandelete = true;
111
                    } else {
112
                        $errors['name'] = get_string('errorpresetexistsbutnotoverwrite', 'data');
113
                    }
114
                    break;
115
                }
116
            }
117
            // If there are some errors, the checkbox should be displayed, to let users overwrite the preset.
118
            if (!empty($errors) && $usercandelete) {
119
                $this->_form->getElement('overwrite')->removeAttribute('class');
120
            }
121
        }
122
 
123
        return $errors;
124
    }
125
 
126
    /**
127
     * Check if current user has access to this form, otherwise throw exception.
128
     *
129
     * @return void
130
     * @throws moodle_exception
131
     */
132
    protected function check_access_for_dynamic_submission(): void {
133
        global $DB;
134
 
135
        if (!has_capability('mod/data:managetemplates', $this->get_context_for_dynamic_submission())) {
136
            throw new moodle_exception('saveaspresetmissingcapability', 'data');
137
        }
138
 
139
        $action = $this->optional_param('action', '', PARAM_ALPHANUM);
140
        if ($action == 'saveaspreset') {
141
            // For saving it as a new preset, some fields need to be created; otherwise, an exception will be raised.
142
            $instanceid = $this->optional_param('d', null, PARAM_INT);
143
            $hasfields = $DB->record_exists('data_fields', ['dataid' => $instanceid]);
144
 
145
            if (!$hasfields) {
146
                throw new moodle_exception('nofieldindatabase', 'data');
147
            }
148
        }
149
    }
150
 
151
    /**
152
     * Process the form submission, used if form was submitted via AJAX.
153
     *
154
     * @return array
155
     */
156
    public function process_dynamic_submission(): array {
157
        global $DB, $CFG;
158
        require_once($CFG->dirroot . '/mod/data/lib.php');
159
 
160
        $formdata = $this->get_data();
161
        $result = false;
162
        $errors = [];
163
        $data = $DB->get_record('data', array('id' => $formdata->d), '*', MUST_EXIST);
164
        $course = $DB->get_record('course', array('id' => $data->course), '*', MUST_EXIST);
165
        $cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
166
        $context = \context_module::instance($cm->id, MUST_EXIST);
167
 
168
        try {
169
            $manager = manager::create_from_instance($data);
170
            if (!empty($formdata->overwrite)) {
171
                $presets = $manager->get_available_presets();
172
                $selectedpreset = new \stdClass();
173
                foreach ($presets as $preset) {
174
                    if ($preset->name == $formdata->name) {
175
                        $selectedpreset = $preset;
176
                        break;
177
                    }
178
                }
179
                if ($selectedpreset instanceof preset && $selectedpreset->can_manage()) {
180
                    $selectedpreset->delete();
181
                }
182
            }
183
            $presetname = $formdata->name;
184
            if (!empty($formdata->oldpresetname)) {
185
                $presetname = $formdata->oldpresetname;
186
            }
187
            $preset = preset::create_from_instance($manager, $presetname, $formdata->description);
188
            if (!empty($formdata->oldpresetname)) {
189
                // Update the name and the description, to save the new data.
190
                $preset->name = $formdata->name;
191
                $preset->description = $formdata->description;
192
            }
193
            $result = $preset->save();
194
 
195
            if ($result) {
196
                // Add notification in the session to be shown when the page is reloaded on the JS side.
197
                $previewurl = new moodle_url(
198
                    '/mod/data/preset.php',
199
                    ['id' => $cm->id, 'fullname' => $preset->get_fullname(), 'action' => 'preview']
200
                );
201
                notification::success(get_string('savesuccess', 'mod_data', (object)['url' => $previewurl->out()]));
202
            }
203
        } catch (\Exception $exception) {
204
            $errors[] = $exception->getMessage();
205
        }
206
 
207
        return [
208
            'result' => $result,
209
            'errors' => $errors,
210
        ];
211
    }
212
 
213
    /**
214
     * Load in existing data as form defaults.
215
     *
216
     * @return void
217
     */
218
    public function set_data_for_dynamic_submission(): void {
219
        $data = (object)[
220
            'd' => $this->optional_param('d', 0, PARAM_INT),
221
            'action' => $this->optional_param('action', '', PARAM_ALPHANUM),
222
            'oldpresetname' => $this->optional_param('presetname', '', PARAM_FILE),
223
            'name' => $this->optional_param('presetname', '', PARAM_FILE),
224
            'description' => $this->optional_param('presetdescription', '', PARAM_TEXT),
225
        ];
226
        $this->set_data($data);
227
    }
228
 
229
    /**
230
     * Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
231
     *
232
     * @return moodle_url
233
     */
234
    protected function get_page_url_for_dynamic_submission(): moodle_url {
235
        $d = $this->optional_param('d', null, PARAM_INT);
236
 
237
        return new moodle_url('/user/field.php', ['d' => $d]);
238
    }
239
}