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
 * Form for creating new H5P Content
18
 *
19
 * @package    mod_hvp
20
 * @copyright  2016 Joubel AS <contact@joubel.com>
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
defined('MOODLE_INTERNAL') || die();
25
 
26
require_once($CFG->dirroot . '/course/moodleform_mod.php');
27
 
28
class mod_hvp_mod_form extends moodleform_mod {
29
 
30
    public function definition() {
31
        global $CFG, $COURSE, $PAGE;
32
 
33
        $mform =& $this->_form;
34
 
35
        // Name.
36
        $mform->addElement('hidden', 'name', '');
37
        $mform->setType('name', PARAM_TEXT);
38
 
39
        // Intro.
40
        if (method_exists($this, 'standard_intro_elements')) {
41
            $this->standard_intro_elements();
42
        } else {
43
            $this->add_intro_editor(false, get_string('intro', 'hvp'));
44
        }
45
 
46
        // Action.
47
        $h5paction = array();
48
        $h5paction[] = $mform->createElement('radio', 'h5paction', '', get_string('upload', 'hvp'), 'upload');
49
        $h5paction[] = $mform->createElement('radio', 'h5paction', '', get_string('create', 'hvp'), 'create');
50
        $mform->addGroup($h5paction, 'h5pactiongroup', get_string('action', 'hvp'), array('<br/>'), false);
51
        $mform->setDefault('h5paction', 'create');
52
 
53
        // Upload.
54
        $mform->addElement('filepicker', 'h5pfile', get_string('h5pfile', 'hvp'), null,
55
            array('maxbytes' => $COURSE->maxbytes, 'accepted_types' => '*'));
56
 
57
        // Editor placeholder.
58
        if ($CFG->theme == 'boost' || in_array('boost', $PAGE->theme->parents)) {
59
            $h5peditor   = [];
60
            $h5peditor[] = $mform->createElement('html',
61
                                                 '<div class="h5p-editor">' . get_string('javascriptloading', 'hvp') . '</div>');
62
            $mform->addGroup($h5peditor, 'h5peditor', get_string('editor', 'hvp'));
63
        } else {
64
            $mform->addElement('static', 'h5peditor', get_string('editor', 'hvp'),
65
                               '<div class="h5p-editor">' . get_string('javascriptloading', 'hvp') . '</div>');
66
        }
67
 
68
        // Hidden fields.
69
        $mform->addElement('hidden', 'h5plibrary', '');
70
        $mform->setType('h5plibrary', PARAM_RAW);
71
        $mform->addElement('hidden', 'h5pparams', '');
72
        $mform->setType('h5pparams', PARAM_RAW);
73
        $mform->addElement('hidden', 'h5pmaxscore', '');
74
        $mform->setType('h5pmaxscore', PARAM_INT);
75
 
76
        $core = \mod_hvp\framework::instance();
77
        $displayoptions = $core->getDisplayOptionsForEdit();
78
        if (isset($displayoptions[H5PCore::DISPLAY_OPTION_FRAME])) {
79
            // Display options group.
80
            $mform->addElement('header', 'displayoptions', get_string('displayoptions', 'hvp'));
81
 
82
            $mform->addElement('checkbox', H5PCore::DISPLAY_OPTION_FRAME, get_string('enableframe', 'hvp'));
83
            $mform->setType(H5PCore::DISPLAY_OPTION_FRAME, PARAM_BOOL);
84
            $mform->setDefault(H5PCore::DISPLAY_OPTION_FRAME, true);
85
 
86
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_DOWNLOAD])) {
87
                $mform->addElement('checkbox', H5PCore::DISPLAY_OPTION_DOWNLOAD, get_string('enabledownload', 'hvp'));
88
                $mform->setType(H5PCore::DISPLAY_OPTION_DOWNLOAD, PARAM_BOOL);
89
                $mform->setDefault(H5PCore::DISPLAY_OPTION_DOWNLOAD, $displayoptions[H5PCore::DISPLAY_OPTION_DOWNLOAD]);
90
                $mform->disabledIf(H5PCore::DISPLAY_OPTION_DOWNLOAD, 'frame');
91
            }
92
 
93
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_EMBED])) {
94
                $mform->addElement('checkbox', H5PCore::DISPLAY_OPTION_EMBED, get_string('enableembed', 'hvp'));
95
                $mform->setType(H5PCore::DISPLAY_OPTION_EMBED, PARAM_BOOL);
96
                $mform->setDefault(H5PCore::DISPLAY_OPTION_EMBED, $displayoptions[H5PCore::DISPLAY_OPTION_EMBED]);
97
                $mform->disabledIf(H5PCore::DISPLAY_OPTION_EMBED, 'frame');
98
            }
99
 
100
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_COPYRIGHT])) {
101
                $mform->addElement('checkbox', H5PCore::DISPLAY_OPTION_COPYRIGHT, get_string('enablecopyright', 'hvp'));
102
                $mform->setType(H5PCore::DISPLAY_OPTION_COPYRIGHT, PARAM_BOOL);
103
                $mform->setDefault(H5PCore::DISPLAY_OPTION_COPYRIGHT, $displayoptions[H5PCore::DISPLAY_OPTION_COPYRIGHT]);
104
                $mform->disabledIf(H5PCore::DISPLAY_OPTION_COPYRIGHT, 'frame');
105
            }
106
        }
107
 
108
        // Grade settings.
109
        $this->standard_grading_coursemodule_elements();
110
        $mform->removeElement('grade');
111
 
112
        // Max grade.
113
        $mform->addElement('text', 'maximumgrade', get_string('maximumgrade', 'hvp'));
114
        $mform->setType('maximumgrade', PARAM_INT);
115
        $mform->setDefault('maximumgrade', 10);
116
 
117
        // Standard course module settings.
118
        $this->standard_coursemodule_elements();
119
 
120
        $this->add_action_buttons();
121
    }
122
 
123
    /**
124
     * Sets display options within default values
125
     *
126
     * @param $defaultvalues
127
     */
128
    private function set_display_options(&$defaultvalues) {
129
        // Individual display options are not stored, must be extracted from disable.
130
        if (isset($defaultvalues['disable'])) {
131
            $h5pcore = \mod_hvp\framework::instance('core');
132
            $displayoptions = $h5pcore->getDisplayOptionsForEdit($defaultvalues['disable']);
133
            if (isset ($displayoptions[H5PCore::DISPLAY_OPTION_FRAME])) {
134
                $defaultvalues[H5PCore::DISPLAY_OPTION_FRAME] = $displayoptions[H5PCore::DISPLAY_OPTION_FRAME];
135
            }
136
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_DOWNLOAD])) {
137
                $defaultvalues[H5PCore::DISPLAY_OPTION_DOWNLOAD] = $displayoptions[H5PCore::DISPLAY_OPTION_DOWNLOAD];
138
            }
139
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_EMBED])) {
140
                $defaultvalues[H5PCore::DISPLAY_OPTION_EMBED] = $displayoptions[H5PCore::DISPLAY_OPTION_EMBED];
141
            }
142
            if (isset($displayoptions[H5PCore::DISPLAY_OPTION_COPYRIGHT])) {
143
                $defaultvalues[H5PCore::DISPLAY_OPTION_COPYRIGHT] = $displayoptions[H5PCore::DISPLAY_OPTION_COPYRIGHT];
144
            }
145
        }
146
    }
147
 
148
    /**
149
     * Sets max grade in default values from grade item
150
     *
151
     * @param $content
152
     * @param $defaultvalues
153
     */
154
    private function set_max_grade($content, &$defaultvalues) {
155
        // Set default maxgrade.
156
        if (isset($content) && isset($content['id'])
157
            && isset($defaultvalues) && isset($defaultvalues['course'])) {
158
 
159
            // Get the gradeitem and set maxgrade.
160
            $gradeitem = grade_item::fetch(array(
161
                'itemtype' => 'mod',
162
                'itemmodule' => 'hvp',
163
                'iteminstance' => $content['id'],
164
                'courseid' => $defaultvalues['course']
165
            ));
166
 
167
            if (isset($gradeitem) && isset($gradeitem->grademax)) {
168
                $defaultvalues['maximumgrade'] = $gradeitem->grademax;
169
            }
170
        }
171
    }
172
 
173
    public function data_preprocessing(&$defaultvalues) {
174
        global $DB;
175
        $core = \mod_hvp\framework::instance();
176
 
177
        $content = null;
178
        if (!empty($defaultvalues['id'])) {
179
            // Load Content.
180
            $content = $core->loadContent($defaultvalues['id']);
181
        }
182
 
183
        $this->set_max_grade($content, $defaultvalues);
184
 
185
        // Aaah.. we meet again h5pfile!
186
        $draftitemid = file_get_submitted_draft_itemid('h5pfile');
187
        file_prepare_draft_area($draftitemid, $this->context->id, 'mod_hvp', 'package', 0);
188
        $defaultvalues['h5pfile'] = $draftitemid;
189
        $this->set_display_options($defaultvalues);
190
 
191
        // Determine default action.
192
        if (!get_config('mod_hvp', 'hub_is_enabled') && $content === null &&
193
            $DB->get_field_sql("SELECT id FROM {hvp_libraries} WHERE runnable = 1", null, IGNORE_MULTIPLE) === false) {
194
            $defaultvalues['h5paction'] = 'upload';
195
        }
196
 
197
        // Set editor defaults.
198
        $defaultvalues['h5plibrary'] = ($content === null ? 0 : H5PCore::libraryToString($content['library']));
199
 
200
        // Combine params and metadata in one JSON object.
201
        $params = ($content === null ? '{}' : $core->filterParameters($content));
202
        $maincontentdata = array('params' => json_decode($params));
203
        if (isset($content['metadata'])) {
204
            $maincontentdata['metadata'] = $content['metadata'];
205
        }
206
        $defaultvalues['h5pparams'] = json_encode($maincontentdata, true);
207
 
208
        // Completion settings check.
209
        if (empty($defaultvalues['completionusegrade'])) {
210
            $defaultvalues['completionpass'] = 0; // Forced unchecked.
211
        }
212
 
213
        // Add required editor assets.
214
        require_once('locallib.php');
215
        $mformid = $this->_form->getAttribute('id');
216
        \hvp_add_editor_assets($content === null ? null : $defaultvalues['id'], $mformid);
217
    }
218
 
219
    /**
220
     * Validate uploaded H5P
221
     *
222
     * @param $data
223
     * @param $errors
224
     */
225
    private function validate_upload($data, &$errors) {
226
        global $CFG;
227
 
228
        if (empty($data['h5pfile'])) {
229
            // Field missing.
230
            $errors['h5pfile'] = get_string('required');
231
        } else {
232
            $files = $this->get_draft_files('h5pfile');
233
            if (count($files) < 1) {
234
                // No file uploaded.
235
                $errors['h5pfile'] = get_string('required');
236
            } else {
237
                // Prepare to validate package.
238
                $file = reset($files);
239
                $interface = \mod_hvp\framework::instance('interface');
240
 
241
                $path = $CFG->tempdir . uniqid('/hvp-');
242
                $interface->getUploadedH5pFolderPath($path);
243
                $path .= '.h5p';
244
                $interface->getUploadedH5pPath($path);
245
                $file->copy_content_to($path);
246
 
247
                $h5pvalidator = \mod_hvp\framework::instance('validator');
248
                if (! $h5pvalidator->isValidPackage()) {
249
                    // Errors while validating the package.
250
                    $errors = array_map(function ($message) {
251
                        return $message->message;
252
                    }, \mod_hvp\framework::messages('error'));
253
 
254
                    $messages = array_merge(\mod_hvp\framework::messages('info'), $errors);
255
                    $errors['h5pfile'] = implode('<br/>', $messages);
256
                } else {
257
                    foreach ($h5pvalidator->h5pC->mainJsonData['preloadedDependencies'] as $dep) {
258
                        if ($dep['machineName'] === $h5pvalidator->h5pC->mainJsonData['mainLibrary']) {
259
                            if ($h5pvalidator->h5pF->libraryHasUpgrade($dep)) {
260
                                // We do not allow storing old content due to security concerns.
261
                                $errors['h5pfile'] = get_string('olduploadoldcontent', 'hvp');
262
                            }
263
                        }
264
                    }
265
                }
266
            }
267
        }
268
    }
269
 
270
    /**
271
     * Validate new H5P
272
     *
273
     * @param $data
274
     */
275
    private function validate_created(&$data, &$errors) {
276
        // Validate library and params used in editor.
277
        $core = \mod_hvp\framework::instance();
278
 
279
        // Get library array from string.
280
        $library = H5PCore::libraryFromString($data['h5plibrary']);
281
 
282
        if (!$library) {
283
            $errors['h5peditor'] = get_string('librarynotselected', 'hvp');
284
        } else {
285
            // Check that library exists.
286
            $library['libraryId'] = $core->h5pF->getLibraryId($library['machineName'],
287
                $library['majorVersion'],
288
                $library['minorVersion']);
289
            if (!$library['libraryId']) {
290
                $errors['h5peditor'] = get_string('nosuchlibrary', 'hvp');
291
            } else {
292
                $data['h5plibrary'] = $library;
293
 
294
                if ($core->h5pF->libraryHasUpgrade($library)) {
295
                    // We do not allow storing old content due to security concerns.
296
                    $errors['h5peditor'] = get_string('anunexpectedsave', 'hvp');
297
                } else {
298
                    // Verify that parameters are valid.
299
                    if (empty($data['h5pparams'])) {
300
                        $errors['h5peditor'] = get_string('noparameters', 'hvp');
301
                    } else {
302
                        $params = json_decode($data['h5pparams']);
303
                        if ($params === null) {
304
                            $errors['h5peditor'] = get_string('invalidparameters', 'hvp');
305
                        } else {
306
                            $data['h5pparams'] = $params;
307
                        }
308
                    }
309
                }
310
            }
311
        }
312
    }
313
 
314
    /**
315
     * Validates editor form
316
     *
317
     * @param array $data
318
     * @param array $files
319
     *
320
     * @return array
321
     */
322
    public function validation($data, $files) {
323
        $errors = parent::validation($data, $files);
324
 
325
        // Validate max grade as a non-negative numeric value.
326
        if (!is_numeric($data['maximumgrade']) || $data['maximumgrade'] < 0) {
327
            $errors['maximumgrade'] = get_string('maximumgradeerror', 'hvp');
328
        }
329
 
330
        if ($data['h5paction'] === 'upload') {
331
            // Validate uploaded H5P file.
332
            unset($errors['name']); // Will be set in data_postprocessing().
333
            $this->validate_upload($data, $errors);
334
        } else {
335
            $this->validate_created($data, $errors);
336
        }
337
 
338
        if (array_key_exists('completion', $data) && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC) {
339
            $completionpass = isset($data['completionpass']) ? $data['completionpass'] : $this->current->completionpass;
340
            // Show an error if require passing grade was selected and the grade to pass was set to 0.
341
            if ($completionpass && (empty($data['gradepass']) || grade_floatval($data['gradepass']) == 0)) {
342
                if (isset($data['completionpass'])) {
343
                    $errors['completionpassgroup'] = get_string('gradetopassnotset', 'hvp');
344
                } else {
345
                    $errors['gradepass'] = get_string('gradetopassmustbeset', 'hvp');
346
                }
347
            }
348
        }
349
 
350
        return $errors;
351
    }
352
 
353
    /**
354
     * Allows modules to modify the data returned by form get_data().
355
     * This method is also called in the bulk activity completion form.
356
     *
357
     * Only available on moodleform_mod.
358
     *
359
     * @param stdClass $data passed by reference
360
     */
361
    public function data_postprocessing($data) {
362
        // Determine disabled content features.
363
        $options = array(
364
            H5PCore::DISPLAY_OPTION_FRAME     => isset($data->frame) ? $data->frame : 0,
365
            H5PCore::DISPLAY_OPTION_DOWNLOAD  => isset($data->export) ? $data->export : 0,
366
            H5PCore::DISPLAY_OPTION_EMBED     => isset($data->embed) ? $data->embed : 0,
367
            H5PCore::DISPLAY_OPTION_COPYRIGHT => isset($data->copyright) ? $data->copyright : 0,
368
        );
369
        $core          = \mod_hvp\framework::instance();
370
        $data->disable = $core->getStorableDisplayOptions($options, 0);
371
 
372
        if (isset($data->h5pparams)) {
373
            // Remove metadata wrapper from form data.
374
            $params = json_decode($data->h5pparams);
375
            if ($params !== null) {
376
                $data->params = json_encode($params->params);
377
                if (isset($params->metadata)) {
378
                    $data->metadata = $params->metadata;
379
                }
380
            }
381
            // Cleanup.
382
            unset($data->h5pparams);
383
        }
384
 
385
        if (isset($data->h5paction)  && $data->h5paction === 'upload') {
386
            if (empty($data->metadata)) {
387
                $data->metadata = new stdClass();
388
            }
389
 
390
            if (empty($data->metadata->title)) {
391
                // Fix for legacy content upload to work.
392
                // Fetch title from h5p.json or use a default string if not available.
393
                $h5pvalidator = \mod_hvp\framework::instance('validator');
394
                $data->metadata->title = empty($h5pvalidator->h5pC->mainJsonData['title'])
395
                    ? 'Uploaded Content'
396
                    : $h5pvalidator->h5pC->mainJsonData['title'];
397
            }
398
            $data->name = $data->metadata->title; // Sort of a hack,
399
            // but there is no JavaScript that sets the value when there is no editor...
400
        }
401
    }
402
 
403
    /**
404
     * This should not be overridden, but we have to in order to support Moodle <3.2
405
     * and older Totara sites.
406
     *
407
     * Moodle 3.1 LTS is supported until May 2019, after that this can be dropped.
408
     * (could cause issues for new features if they add more to this in Core)
409
     *
410
     * @return object submitted data; NULL if not valid or not submitted or cancelled
411
     */
412
    public function get_data() {
413
        $data = parent::get_data();
414
 
415
        if ($data) {
416
            // Check if moodleform_mod class has already taken care of the data for us.
417
            // If not this is an older Moodle or Totara site that we need to treat differently.
418
 
419
            $class = new ReflectionClass('moodleform_mod');
420
            $method = $class->getMethod('get_data');
421
            if ($method->class !== 'moodleform_mod') {
422
                // Moodleform_mod class doesn't override get_data so we need to convert it ourselves.
423
 
424
                // Convert the grade pass value - we may be using a language which uses commas,
425
                // rather than decimal points, in numbers. These need to be converted so that
426
                // they can be added to the DB.
427
                if (isset($data->gradepass)) {
428
                    $data->gradepass = unformat_float($data->gradepass);
429
                }
430
                $this->data_postprocessing($data);
431
            }
432
        }
433
        return $data;
434
    }
435
 
436
    public function add_completion_rules() {
437
        global $CFG;
438
 
439
        $mform   =& $this->_form;
440
 
441
        // Changes for Moodle 4.3 - MDL-78516.
442
        if ($CFG->branch < 403) {
443
            $suffix = '';
444
        } else {
445
            $suffix = $this->get_suffix();
446
        }
447
 
448
        $items   = array();
449
        $group   = array();
450
        $group[] = $mform->createElement('advcheckbox', 'completionpass' . $suffix, null, get_string('completionpass', 'hvp'),
451
            array('group' => 'cpass'));
452
        $mform->disabledIf('completionpass' . $suffix, 'completionusegrade', 'notchecked');
453
        $mform->addGroup($group, 'completionpassgroup' . $suffix, get_string('completionpass', 'hvp'), ' &nbsp; ', false);
454
        $mform->addHelpButton('completionpassgroup' . $suffix, 'completionpass', 'hvp');
455
        $items[] = 'completionpassgroup' . $suffix;
456
 
457
        return $items;
458
    }
459
}