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
if (!defined('MOODLE_INTERNAL')) {
18
    die('Direct access to this script is forbidden.');    //  It must be included from a Moodle page.
19
}
20
 
21
require_once($CFG->dirroot.'/course/moodleform_mod.php');
22
require_once($CFG->dirroot.'/mod/scorm/locallib.php');
23
 
24
class mod_scorm_mod_form extends moodleform_mod {
25
 
26
    public function definition() {
27
        global $CFG, $COURSE, $OUTPUT;
28
        $cfgscorm = get_config('scorm');
29
 
30
        $mform = $this->_form;
31
 
32
        if (!$CFG->slasharguments) {
33
            $mform->addElement('static', '', '', $OUTPUT->notification(get_string('slashargs', 'scorm'), 'notifyproblem'));
34
        }
35
 
36
        $mform->addElement('header', 'general', get_string('general', 'form'));
37
 
38
        // Name.
39
        $mform->addElement('text', 'name', get_string('name'));
40
        if (!empty($CFG->formatstringstriptags)) {
41
            $mform->setType('name', PARAM_TEXT);
42
        } else {
43
            $mform->setType('name', PARAM_CLEANHTML);
44
        }
45
        $mform->addRule('name', null, 'required', null, 'client');
46
        $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
47
 
48
        // Summary.
49
        $this->standard_intro_elements();
50
 
51
        // Package.
52
        $mform->addElement('header', 'packagehdr', get_string('packagehdr', 'scorm'));
53
        $mform->setExpanded('packagehdr', true);
54
 
55
        // Scorm types.
56
        $scormtypes = array(SCORM_TYPE_LOCAL => get_string('typelocal', 'scorm'));
57
 
58
        if ($cfgscorm->allowtypeexternal) {
59
            $scormtypes[SCORM_TYPE_EXTERNAL] = get_string('typeexternal', 'scorm');
60
        }
61
 
62
        if ($cfgscorm->allowtypelocalsync) {
63
            $scormtypes[SCORM_TYPE_LOCALSYNC] = get_string('typelocalsync', 'scorm');
64
        }
65
 
66
        if ($cfgscorm->allowtypeexternalaicc) {
67
            $scormtypes[SCORM_TYPE_AICCURL] = get_string('typeaiccurl', 'scorm');
68
        }
69
 
70
        // Reference.
71
        if (count($scormtypes) > 1) {
72
            $mform->addElement('select', 'scormtype', get_string('scormtype', 'scorm'), $scormtypes);
73
            $mform->setType('scormtype', PARAM_ALPHA);
74
            $mform->addHelpButton('scormtype', 'scormtype', 'scorm');
75
            $mform->addElement('text', 'packageurl', get_string('packageurl', 'scorm'), array('size' => 60));
76
            $mform->setType('packageurl', PARAM_RAW);
77
            $mform->addHelpButton('packageurl', 'packageurl', 'scorm');
78
            $mform->hideIf('packageurl', 'scormtype', 'eq', SCORM_TYPE_LOCAL);
79
        } else {
80
            $mform->addElement('hidden', 'scormtype', SCORM_TYPE_LOCAL);
81
            $mform->setType('scormtype', PARAM_ALPHA);
82
        }
83
 
84
        // New local package upload.
85
        $filemanageroptions = array();
86
        $filemanageroptions['accepted_types'] = array('.zip', '.xml');
87
        $filemanageroptions['maxbytes'] = 0;
88
        $filemanageroptions['maxfiles'] = 1;
89
        $filemanageroptions['subdirs'] = 0;
90
 
91
        $mform->addElement('filemanager', 'packagefile', get_string('package', 'scorm'), null, $filemanageroptions);
92
        $mform->addHelpButton('packagefile', 'package', 'scorm');
93
        $mform->hideIf('packagefile', 'scormtype', 'noteq', SCORM_TYPE_LOCAL);
94
 
95
        // Update packages timing.
96
        $mform->addElement('select', 'updatefreq', get_string('updatefreq', 'scorm'), scorm_get_updatefreq_array());
97
        $mform->setType('updatefreq', PARAM_INT);
98
        $mform->setDefault('updatefreq', $cfgscorm->updatefreq);
99
        $mform->addHelpButton('updatefreq', 'updatefreq', 'scorm');
100
 
101
        // Display Settings.
102
        $mform->addElement('header', 'displaysettings', get_string('appearance'));
103
 
104
        // Framed / Popup Window.
105
        $mform->addElement('select', 'popup', get_string('display', 'scorm'), scorm_get_popup_display_array());
106
        $mform->setDefault('popup', $cfgscorm->popup);
107
        $mform->setAdvanced('popup', $cfgscorm->popup_adv);
108
 
109
        // Width.
110
        $mform->addElement('text', 'width', get_string('width', 'scorm'), 'maxlength="5" size="5"');
111
        $mform->setDefault('width', $cfgscorm->framewidth);
112
        $mform->setType('width', PARAM_INT);
113
        $mform->setAdvanced('width', $cfgscorm->framewidth_adv);
114
        $mform->hideIf('width', 'popup', 'eq', 0);
115
 
116
        // Height.
117
        $mform->addElement('text', 'height', get_string('height', 'scorm'), 'maxlength="5" size="5"');
118
        $mform->setDefault('height', $cfgscorm->frameheight);
119
        $mform->setType('height', PARAM_INT);
120
        $mform->setAdvanced('height', $cfgscorm->frameheight_adv);
121
        $mform->hideIf('height', 'popup', 'eq', 0);
122
 
123
        // Window Options.
124
        $winoptgrp = array();
125
        foreach (scorm_get_popup_options_array() as $key => $value) {
126
            $winoptgrp[] = &$mform->createElement('checkbox', $key, '', get_string($key, 'scorm'));
127
            $mform->setDefault($key, $value);
128
        }
129
        $mform->addGroup($winoptgrp, 'winoptgrp', get_string('options', 'scorm'), '<br />', false);
130
        $mform->hideIf('winoptgrp', 'popup', 'eq', 0);
131
        $mform->setAdvanced('winoptgrp', $cfgscorm->winoptgrp_adv);
132
 
133
        // Skip view page.
134
        $skipviewoptions = scorm_get_skip_view_array();
135
        $mform->addElement('select', 'skipview', get_string('skipview', 'scorm'), $skipviewoptions);
136
        $mform->addHelpButton('skipview', 'skipview', 'scorm');
137
        $mform->setDefault('skipview', $cfgscorm->skipview);
138
        $mform->setAdvanced('skipview', $cfgscorm->skipview_adv);
139
 
140
        // Hide Browse.
141
        $mform->addElement('selectyesno', 'hidebrowse', get_string('hidebrowse', 'scorm'));
142
        $mform->addHelpButton('hidebrowse', 'hidebrowse', 'scorm');
143
        $mform->setDefault('hidebrowse', $cfgscorm->hidebrowse);
144
        $mform->setAdvanced('hidebrowse', $cfgscorm->hidebrowse_adv);
145
 
146
        // Display course structure.
147
        $mform->addElement('selectyesno', 'displaycoursestructure', get_string('displaycoursestructure', 'scorm'));
148
        $mform->addHelpButton('displaycoursestructure', 'displaycoursestructure', 'scorm');
149
        $mform->setDefault('displaycoursestructure', $cfgscorm->displaycoursestructure);
150
        $mform->setAdvanced('displaycoursestructure', $cfgscorm->displaycoursestructure_adv);
151
 
152
        // Toc display.
153
        $mform->addElement('select', 'hidetoc', get_string('hidetoc', 'scorm'), scorm_get_hidetoc_array());
154
        $mform->addHelpButton('hidetoc', 'hidetoc', 'scorm');
155
        $mform->setDefault('hidetoc', $cfgscorm->hidetoc);
156
        $mform->setAdvanced('hidetoc', $cfgscorm->hidetoc_adv);
157
        $mform->disabledIf('hidetoc', 'scormtype', 'eq', SCORM_TYPE_AICCURL);
158
 
159
        // Navigation panel display.
160
        $mform->addElement('select', 'nav', get_string('nav', 'scorm'), scorm_get_navigation_display_array());
161
        $mform->addHelpButton('nav', 'nav', 'scorm');
162
        $mform->setDefault('nav', $cfgscorm->nav);
163
        $mform->setAdvanced('nav', $cfgscorm->nav_adv);
164
        $mform->hideIf('nav', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
165
 
166
        // Navigation panel position from left.
167
        $mform->addElement('text', 'navpositionleft', get_string('fromleft', 'scorm'), 'maxlength="5" size="5"');
168
        $mform->setDefault('navpositionleft', $cfgscorm->navpositionleft);
169
        $mform->setType('navpositionleft', PARAM_INT);
170
        $mform->setAdvanced('navpositionleft', $cfgscorm->navpositionleft_adv);
171
        $mform->hideIf('navpositionleft', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
172
        $mform->hideIf('navpositionleft', 'nav', 'noteq', SCORM_NAV_FLOATING);
173
 
174
        // Navigation panel position from top.
175
        $mform->addElement('text', 'navpositiontop', get_string('fromtop', 'scorm'), 'maxlength="5" size="5"');
176
        $mform->setDefault('navpositiontop', $cfgscorm->navpositiontop);
177
        $mform->setType('navpositiontop', PARAM_INT);
178
        $mform->setAdvanced('navpositiontop', $cfgscorm->navpositiontop_adv);
179
        $mform->hideIf('navpositiontop', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
180
        $mform->hideIf('navpositiontop', 'nav', 'noteq', SCORM_NAV_FLOATING);
181
 
182
        // Display attempt status.
183
        $mform->addElement('select', 'displayattemptstatus', get_string('displayattemptstatus', 'scorm'),
184
                           scorm_get_attemptstatus_array());
185
        $mform->addHelpButton('displayattemptstatus', 'displayattemptstatus', 'scorm');
186
        $mform->setDefault('displayattemptstatus', $cfgscorm->displayattemptstatus);
187
        $mform->setAdvanced('displayattemptstatus', $cfgscorm->displayattemptstatus_adv);
188
 
189
        // Availability.
190
        $mform->addElement('header', 'availability', get_string('availability'));
191
 
192
        $mform->addElement('date_time_selector', 'timeopen', get_string("scormopen", "scorm"), array('optional' => true));
193
        $mform->addElement('date_time_selector', 'timeclose', get_string("scormclose", "scorm"), array('optional' => true));
194
 
195
        // Grade Settings.
196
        $mform->addElement('header', 'gradesettings', get_string('gradenoun'));
197
 
198
        // Grade Method.
199
        $mform->addElement('select', 'grademethod', get_string('grademethod', 'scorm'), scorm_get_grade_method_array());
200
        $mform->addHelpButton('grademethod', 'grademethod', 'scorm');
201
        $mform->setDefault('grademethod', $cfgscorm->grademethod);
202
 
203
        // Maximum Grade.
204
        for ($i = 0; $i <= 100; $i++) {
205
            $grades[$i] = "$i";
206
        }
207
        $mform->addElement('select', 'maxgrade', get_string('maximumgrade'), $grades);
208
        $mform->setDefault('maxgrade', $cfgscorm->maxgrade);
209
        $mform->hideIf('maxgrade', 'grademethod', 'eq', GRADESCOES);
210
 
211
        // Attempts management.
212
        $mform->addElement('header', 'attemptsmanagementhdr', get_string('attemptsmanagement', 'scorm'));
213
 
214
        // Max Attempts.
215
        $mform->addElement('select', 'maxattempt', get_string('maximumattempts', 'scorm'), scorm_get_attempts_array());
216
        $mform->addHelpButton('maxattempt', 'maximumattempts', 'scorm');
217
        $mform->setDefault('maxattempt', $cfgscorm->maxattempt);
218
 
219
        // What Grade.
220
        $mform->addElement('select', 'whatgrade', get_string('whatgrade', 'scorm'),  scorm_get_what_grade_array());
221
        $mform->hideIf('whatgrade', 'maxattempt', 'eq', 1);
222
        $mform->addHelpButton('whatgrade', 'whatgrade', 'scorm');
223
        $mform->setDefault('whatgrade', $cfgscorm->whatgrade);
224
 
225
        // Force new attempt.
226
        $newattemptselect = scorm_get_forceattempt_array();
227
        $mform->addElement('select', 'forcenewattempt', get_string('forcenewattempts', 'scorm'), $newattemptselect);
228
        $mform->addHelpButton('forcenewattempt', 'forcenewattempts', 'scorm');
229
        $mform->setDefault('forcenewattempt', $cfgscorm->forcenewattempt);
230
 
231
        // Last attempt lock - lock the enter button after the last available attempt has been made.
232
        $mform->addElement('selectyesno', 'lastattemptlock', get_string('lastattemptlock', 'scorm'));
233
        $mform->addHelpButton('lastattemptlock', 'lastattemptlock', 'scorm');
234
        $mform->setDefault('lastattemptlock', $cfgscorm->lastattemptlock);
235
 
236
        // Compatibility settings.
237
        $mform->addElement('header', 'compatibilitysettingshdr', get_string('compatibilitysettings', 'scorm'));
238
 
239
        // Force completed.
240
        $mform->addElement('selectyesno', 'forcecompleted', get_string('forcecompleted', 'scorm'));
241
        $mform->addHelpButton('forcecompleted', 'forcecompleted', 'scorm');
242
        $mform->setDefault('forcecompleted', $cfgscorm->forcecompleted);
243
 
244
        // Autocontinue.
245
        $mform->addElement('selectyesno', 'auto', get_string('autocontinue', 'scorm'));
246
        $mform->addHelpButton('auto', 'autocontinue', 'scorm');
247
        $mform->setDefault('auto', $cfgscorm->auto);
248
 
249
        // Autocommit.
250
        $mform->addElement('selectyesno', 'autocommit', get_string('autocommit', 'scorm'));
251
        $mform->addHelpButton('autocommit', 'autocommit', 'scorm');
252
        $mform->setDefault('autocommit', $cfgscorm->autocommit);
253
 
254
        // Mastery score overrides status.
255
        $mform->addElement('selectyesno', 'masteryoverride', get_string('masteryoverride', 'scorm'));
256
        $mform->addHelpButton('masteryoverride', 'masteryoverride', 'scorm');
257
        $mform->setDefault('masteryoverride', $cfgscorm->masteryoverride);
258
 
259
        // Hidden Settings.
260
        $mform->addElement('hidden', 'datadir', null);
261
        $mform->setType('datadir', PARAM_RAW);
262
        $mform->addElement('hidden', 'pkgtype', null);
263
        $mform->setType('pkgtype', PARAM_RAW);
264
        $mform->addElement('hidden', 'launch', null);
265
        $mform->setType('launch', PARAM_RAW);
266
        $mform->addElement('hidden', 'redirect', null);
267
        $mform->setType('redirect', PARAM_RAW);
268
        $mform->addElement('hidden', 'redirecturl', null);
269
        $mform->setType('redirecturl', PARAM_RAW);
270
 
271
        $this->standard_coursemodule_elements();
272
 
273
        // A SCORM module should define this within itself and is not needed here.
274
        $suffix = $this->get_suffix();
275
        $completionpassgradeel = 'completionpassgrade' . $suffix;
276
        // The 'completionpassgrade' is a radio element with multiple options, so we should remove all of them.
277
        while ($mform->elementExists($completionpassgradeel)) {
278
            $mform->removeElement($completionpassgradeel);
279
        }
280
 
281
        // Buttons.
282
        $this->add_action_buttons();
283
    }
284
 
285
    public function data_preprocessing(&$defaultvalues) {
286
        global $CFG, $COURSE;
287
 
288
        if (isset($defaultvalues['popup']) && ($defaultvalues['popup'] == 1) && isset($defaultvalues['options'])) {
289
            if (!empty($defaultvalues['options'])) {
290
                $options = explode(',', $defaultvalues['options']);
291
                foreach ($options as $option) {
292
                    list($element, $value) = explode('=', $option);
293
                    $element = trim($element);
294
                    $defaultvalues[$element] = trim($value);
295
                }
296
            }
297
        }
298
        if (isset($defaultvalues['grademethod'])) {
299
            $defaultvalues['grademethod'] = intval($defaultvalues['grademethod']);
300
        }
301
        if (isset($defaultvalues['width']) && (strpos($defaultvalues['width'], '%') === false)
302
                                           && ($defaultvalues['width'] <= 100)) {
303
            $defaultvalues['width'] .= '%';
304
        }
305
        if (isset($defaultvalues['height']) && (strpos($defaultvalues['height'], '%') === false)
306
                                           && ($defaultvalues['height'] <= 100)) {
307
            $defaultvalues['height'] .= '%';
308
        }
309
        $scorms = get_all_instances_in_course('scorm', $COURSE);
310
        $coursescorm = current($scorms);
311
 
312
        $draftitemid = file_get_submitted_draft_itemid('packagefile');
313
        file_prepare_draft_area($draftitemid, $this->context->id, 'mod_scorm', 'package', 0,
314
            array('subdirs' => 0, 'maxfiles' => 1));
315
        $defaultvalues['packagefile'] = $draftitemid;
316
 
317
        if (($COURSE->format == 'singleactivity') && ((count($scorms) == 0) || ($defaultvalues['instance'] == $coursescorm->id))) {
318
            $defaultvalues['redirect'] = 'yes';
319
            $defaultvalues['redirecturl'] = $CFG->wwwroot.'/course/view.php?id='.$defaultvalues['course'];
320
        } else {
321
            $defaultvalues['redirect'] = 'no';
322
            $defaultvalues['redirecturl'] = $CFG->wwwroot.'/mod/scorm/view.php?id='.$defaultvalues['coursemodule'];
323
        }
324
        if (isset($defaultvalues['version'])) {
325
            $defaultvalues['pkgtype'] = (substr($defaultvalues['version'], 0, 5) == 'SCORM') ? 'scorm' : 'aicc';
326
        }
327
        if (isset($defaultvalues['instance'])) {
328
            $defaultvalues['datadir'] = $defaultvalues['instance'];
329
        }
330
        if (empty($defaultvalues['timeopen'])) {
331
            $defaultvalues['timeopen'] = 0;
332
        }
333
        if (empty($defaultvalues['timeclose'])) {
334
            $defaultvalues['timeclose'] = 0;
335
        }
336
 
337
        // Set some completion default data.
338
        $suffix = $this->get_suffix();
339
        $completionstatusrequiredel = 'completionstatusrequired' . $suffix;
340
        $cvalues = array();
341
        if (!empty($defaultvalues[$completionstatusrequiredel]) && !is_array($defaultvalues[$completionstatusrequiredel])) {
342
            // Unpack values.
343
            foreach (scorm_status_options() as $key => $value) {
344
                if (($defaultvalues[$completionstatusrequiredel] & $key) == $key) {
345
                    $cvalues[$key] = 1;
346
                }
347
            }
348
        } else if (empty($this->_instance) && !array_key_exists($completionstatusrequiredel, $defaultvalues)) {
349
            // When in add mode, set a default completion rule that requires the SCORM's status be set to "Completed".
350
            $cvalues[4] = 1;
351
        }
352
 
353
        if (!empty($cvalues)) {
354
            $defaultvalues[$completionstatusrequiredel] = $cvalues;
355
        }
356
 
357
        $completionscorerequiredel = 'completionscorerequired' . $suffix;
358
        if (isset($defaultvalues[$completionscorerequiredel])) {
359
            $completionscoreenabledel = 'completionscoreenabled' . $suffix;
360
            $defaultvalues[$completionscoreenabledel] = 1;
361
        }
362
    }
363
 
364
    public function validation($data, $files) {
365
        global $CFG, $USER;
366
        $errors = parent::validation($data, $files);
367
 
368
        $type = $data['scormtype'];
369
 
370
        if ($type === SCORM_TYPE_LOCAL) {
371
            if (empty($data['packagefile'])) {
372
                $errors['packagefile'] = get_string('required');
373
 
374
            } else {
375
                $draftitemid = file_get_submitted_draft_itemid('packagefile');
376
 
377
                file_prepare_draft_area($draftitemid, $this->context->id, 'mod_scorm', 'packagefilecheck', null,
378
                    array('subdirs' => 0, 'maxfiles' => 1));
379
 
380
                // Get file from users draft area.
381
                $usercontext = context_user::instance($USER->id);
382
                $fs = get_file_storage();
383
                $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id', false);
384
 
385
                if (count($files) < 1) {
386
                    $errors['packagefile'] = get_string('required');
387
                    return $errors;
388
                }
389
                $file = reset($files);
390
                if (!$file->is_external_file() && !empty($data['updatefreq'])) {
391
                    // Make sure updatefreq is not set if using normal local file.
392
                    $errors['updatefreq'] = get_string('updatefreq_error', 'mod_scorm');
393
                }
394
                if (strtolower($file->get_filename()) == 'imsmanifest.xml') {
395
                    if (!$file->is_external_file()) {
396
                        $errors['packagefile'] = get_string('aliasonly', 'mod_scorm');
397
                    } else {
398
                        $repository = repository::get_repository_by_id($file->get_repository_id(), context_system::instance());
399
                        if (!$repository->supports_relative_file()) {
400
                            $errors['packagefile'] = get_string('repositorynotsupported', 'mod_scorm');
401
                        }
402
                    }
403
                } else if (strtolower(substr($file->get_filename(), -3)) == 'xml') {
404
                    $errors['packagefile'] = get_string('invalidmanifestname', 'mod_scorm');
405
                } else {
406
                    // Validate this SCORM package.
407
                    $errors = array_merge($errors, scorm_validate_package($file));
408
                }
409
            }
410
 
411
        } else if ($type === SCORM_TYPE_EXTERNAL) {
412
            $reference = $data['packageurl'];
413
            // Syntax check.
414
            if (!preg_match('/(http:\/\/|https:\/\/|www).*\/imsmanifest.xml$/i', $reference)) {
415
                $errors['packageurl'] = get_string('invalidurl', 'scorm');
416
            } else {
417
                // Availability check.
418
                $result = scorm_check_url($reference);
419
                if (is_string($result)) {
420
                    $errors['packageurl'] = $result;
421
                }
422
            }
423
 
424
        } else if ($type === 'packageurl') {
425
            $reference = $data['reference'];
426
            // Syntax check.
427
            if (!preg_match('/(http:\/\/|https:\/\/|www).*(\.zip|\.pif)$/i', $reference)) {
428
                $errors['packageurl'] = get_string('invalidurl', 'scorm');
429
            } else {
430
                // Availability check.
431
                $result = scorm_check_url($reference);
432
                if (is_string($result)) {
433
                    $errors['packageurl'] = $result;
434
                }
435
            }
436
 
437
        } else if ($type === SCORM_TYPE_AICCURL) {
438
            $reference = $data['packageurl'];
439
            // Syntax check.
440
            if (!preg_match('/(http:\/\/|https:\/\/|www).*/', $reference)) {
441
                $errors['packageurl'] = get_string('invalidurl', 'scorm');
442
            } else {
443
                // Availability check.
444
                $result = scorm_check_url($reference);
445
                if (is_string($result)) {
446
                    $errors['packageurl'] = $result;
447
                }
448
            }
449
 
450
        }
451
 
452
        // Validate availability dates.
453
        if ($data['timeopen'] && $data['timeclose']) {
454
            if ($data['timeopen'] > $data['timeclose']) {
455
                $errors['timeclose'] = get_string('closebeforeopen', 'scorm');
456
            }
457
        }
458
        $suffix = $this->get_suffix();
459
        $completionstatusallscosel = 'completionstatusallscos' . $suffix;
460
        if (!empty($data[$completionstatusallscosel])) {
461
            $completionstatusrequiredel = 'completionstatusrequired' . $suffix;
462
            $requirestatus = false;
463
            foreach (scorm_status_options(true) as $key => $value) {
464
                if (!empty($data[$completionstatusrequiredel][$key])) {
465
                    $requirestatus = true;
466
                }
467
            }
468
            if (!$requirestatus) {
469
                $errors[$completionstatusallscosel] = get_string('youmustselectastatus', 'scorm');
470
            }
471
        }
472
 
473
        // Validate 'Require minimum score' value.
474
        $completionscorerequiredel = 'completionscorerequired' . $this->get_suffix();
475
        $completionscoreenabledel = 'completionscoreenabled' . $this->get_suffix();
476
        if (array_key_exists($completionscoreenabledel, $data) &&
477
                $data[$completionscoreenabledel] &&
478
                array_key_exists($completionscorerequiredel, $data) &&
479
                strlen($data[$completionscorerequiredel]) &&
480
                $data[$completionscorerequiredel] <= 0
481
        ) {
482
            $errors['completionscoregroup' . $this->get_suffix()] = get_string('minimumscoregreater', 'scorm');
483
        }
484
 
485
        return $errors;
486
    }
487
 
488
    // Need to translate the "options" and "reference" field.
489
    public function set_data($defaultvalues) {
490
        $defaultvalues = (array)$defaultvalues;
491
 
492
        if (isset($defaultvalues['scormtype']) and isset($defaultvalues['reference'])) {
493
            switch ($defaultvalues['scormtype']) {
494
                case SCORM_TYPE_LOCALSYNC :
495
                case SCORM_TYPE_EXTERNAL:
496
                case SCORM_TYPE_AICCURL:
497
                    $defaultvalues['packageurl'] = $defaultvalues['reference'];
498
            }
499
        }
500
        unset($defaultvalues['reference']);
501
 
502
        if (!empty($defaultvalues['options'])) {
503
            $options = explode(',', $defaultvalues['options']);
504
            foreach ($options as $option) {
505
                $opt = explode('=', $option);
506
                if (isset($opt[1])) {
507
                    $defaultvalues[$opt[0]] = $opt[1];
508
                }
509
            }
510
        }
511
 
512
        parent::set_data($defaultvalues);
513
    }
514
 
515
    public function add_completion_rules() {
516
        $suffix = $this->get_suffix();
517
        $mform =& $this->_form;
518
        $items = [];
519
 
520
        // Require score.
521
        $group = [];
522
        $completionscorerequiredel = 'completionscorerequired' . $suffix;
523
        $completionscoreenabledel = 'completionscoreenabled' . $suffix;
524
        $group[] =& $mform->createElement(
525
            'checkbox',
526
            $completionscoreenabledel,
527
            null,
528
            get_string('completionscorerequired', 'scorm')
529
        );
530
        $group[] =& $mform->createElement('text', $completionscorerequiredel, '', ['size' => 5]);
531
        $mform->setType($completionscorerequiredel, PARAM_INT);
532
        $completionscoregroupel = 'completionscoregroup' . $suffix;
533
        $mform->addGroup($group, $completionscoregroupel, '', '', false);
534
        $mform->hideIf($completionscorerequiredel, $completionscoreenabledel, 'notchecked');
535
        $mform->setDefault($completionscorerequiredel, 0);
536
 
537
        $items[] = $completionscoregroupel;
538
 
539
        // Require status.
540
        $completionstatusrequiredel = 'completionstatusrequired' . $suffix;
541
        foreach (scorm_status_options(true) as $key => $value) {
542
            $key = $completionstatusrequiredel . '['.$key.']';
543
            $mform->addElement('checkbox', $key, '', $value);
544
            $mform->setType($key, PARAM_BOOL);
545
            $mform->hideIf($key, $completionstatusrequiredel, 'notchecked');
546
            $items[] = $key;
547
        }
548
 
549
        $completionstatusallscosel = 'completionstatusallscos' . $suffix;
550
        $mform->addElement('checkbox', $completionstatusallscosel, get_string('completionstatusallscos', 'scorm'));
551
        $mform->setType($completionstatusallscosel, PARAM_BOOL);
552
        $mform->addHelpButton($completionstatusallscosel, 'completionstatusallscos', 'scorm');
553
        $mform->setDefault($completionstatusallscosel, 0);
554
        $items[] = $completionstatusallscosel;
555
 
556
        return $items;
557
    }
558
 
559
    public function completion_rule_enabled($data) {
560
        $suffix = $this->get_suffix();
561
        $status = !empty($data['completionstatusrequired' . $suffix]);
562
        $score = !empty($data['completionscoreenabled' . $suffix]) &&
563
                strlen($data['completionscorerequired' . $suffix] && $data['completionscorerequired' . $suffix] > 0);
564
 
565
        return $status || $score;
566
    }
567
 
568
    /**
569
     * Allows module to modify the data returned by form get_data().
570
     * This method is also called in the bulk activity completion form.
571
     *
572
     * Only available on moodleform_mod.
573
     *
574
     * @param stdClass $data the form data to be modified.
575
     */
576
    public function data_postprocessing($data) {
577
        parent::data_postprocessing($data);
578
        // Convert completionstatusrequired to a proper integer, if any.
579
        $total = 0;
580
        $suffix = $this->get_suffix();
581
        if (isset($data->{'completionstatusrequired' . $suffix}) && is_array($data->{'completionstatusrequired' . $suffix})) {
582
            foreach ($data->{'completionstatusrequired' . $suffix} as $state => $value) {
583
                if ($value) {
584
                    $total |= $state;
585
                }
586
            }
587
            if (!$total) {
588
                $total  = null;
589
            }
590
            $data->{'completionstatusrequired' . $suffix} = $total;
591
        }
592
 
593
        if (!empty($data->completionunlocked)) {
594
            // Turn off completion settings if the checkboxes aren't ticked.
595
            $completion = $data->{'completion' . $suffix};
596
            $autocompletion = isset($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
597
 
598
            if (!(isset($data->{'completionstatusrequired' . $suffix}) && $autocompletion)) {
599
                $data->{'completionstatusrequired' . $suffix} = null;
600
            }
601
            // Else do nothing: completionstatusrequired has been already converted into a correct integer representation.
602
 
603
            if (!(isset($data->{'completionscoreenabled' . $suffix}) && $autocompletion)) {
604
                $data->{'completionscorerequired' . $suffix} = null;
605
            }
606
        }
607
    }
608
}