PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/scorm/mod_form.php

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