Skip to content

Commit

Permalink
MDL-44712 SCORM: Improve multi-sco activity completion.
Browse files Browse the repository at this point in the history
  • Loading branch information
danmarsden committed Aug 17, 2016
1 parent 3ca3cc7 commit b30a884
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 37 deletions.
1 change: 1 addition & 0 deletions mod/scorm/backup/moodle1/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function get_paths() {
'timeopen' => '0',
'timeclose' => '0',
'introformat' => '0',
'completionstatusallscos' => 0,
),
'renamefields' => array(
'summary' => 'intro'
Expand Down
2 changes: 1 addition & 1 deletion mod/scorm/backup/moodle2/backup_scorm_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected function define_structure() {
'auto', 'popup', 'options', 'width',
'height', 'timeopen', 'timeclose', 'timemodified',
'completionstatusrequired', 'completionscorerequired',
'displayactivityname'));
'completionstatusallscos', 'displayactivityname'));

$scoes = new backup_nested_element('scoes');

Expand Down
4 changes: 3 additions & 1 deletion mod/scorm/backup/moodle2/restore_scorm_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ protected function process_scorm($data) {
if (!isset($data->displayactivityname)) {
$data->displayactivityname = true;
}

if (!isset($data->completionstatusallscos)) {
$data->completionstatusallscos = false;
}
// insert the scorm record
$newitemid = $DB->insert_record('scorm', $data);
// immediately after inserting "activity" record, call this
Expand Down
4 changes: 3 additions & 1 deletion mod/scorm/classes/external.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,8 @@ public static function get_scorms_by_courses($courseids = array()) {
if (has_capability('moodle/course:manageactivities', $context)) {

$additionalfields = array('updatefreq', 'options', 'completionstatusrequired', 'completionscorerequired',
'autocommit', 'timemodified', 'section', 'visible', 'groupmode', 'groupingid');
'completionstatusallscos', 'autocommit', 'timemodified', 'section', 'visible',
'groupmode', 'groupingid');
$viewablefields = array_merge($viewablefields, $additionalfields);

}
Expand Down Expand Up @@ -818,6 +819,7 @@ public static function get_scorms_by_courses_returns() {
'completionstatusrequired' => new external_value(PARAM_INT, 'Status passed/completed required?',
VALUE_OPTIONAL),
'completionscorerequired' => new external_value(PARAM_INT, 'Minimum score required', VALUE_OPTIONAL),
'completionstatusallscos' => new external_value(PARAM_INT, 'Require all scos to return completion status', VALUE_OPTIONAL),
'autocommit' => new external_value(PARAM_BOOL, 'Save track data automatically?', VALUE_OPTIONAL),
'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
'section' => new external_value(PARAM_INT, 'Course section id', VALUE_OPTIONAL),
Expand Down
1 change: 1 addition & 0 deletions mod/scorm/db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="completionstatusrequired" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="completionscorerequired" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="completionstatusallscos" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="displayactivityname" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="autocommit" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
Expand Down
12 changes: 12 additions & 0 deletions mod/scorm/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,17 @@ function xmldb_scorm_upgrade($oldversion) {
// Moodle v3.1.0 release upgrade line.
// Put any upgrade step following this.

// MDL-44712 improve multi-sco activity completion.
if ($oldversion < 2016080900) {
$table = new xmldb_table('scorm');

$field = new xmldb_field('completionstatusallscos', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'completionscorerequired');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

upgrade_mod_savepoint(true, 2016080900, 'scorm');
}

return true;
}
3 changes: 3 additions & 0 deletions mod/scorm/lang/en/scorm.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
$string['completionscorerequired_help'] = 'Enabling this setting will require a user to have at least the minimum score entered to be marked complete in this SCORM activity, as well as any other Activity Completion requirements.';
$string['completionstatus_passed'] = 'Passed';
$string['completionstatus_completed'] = 'Completed';
$string['completionstatusallscos'] = 'Require all scos to return completion status';
$string['completionstatusallscos_help'] = 'Some SCORM packages contain multiple components or "scos" - when this is enabled all scos within the package must return the relevant lesson_status for this activity to be flagged complete.';
$string['completionstatusrequired'] = 'Require status';
$string['completionstatusrequired_help'] = 'Checking one or more statuses will require a user to achieve at least one of the checked statuses in order to be marked complete in this SCORM activity, as well as any other Activity Completion requirements.';
$string['confirmloosetracks'] = 'WARNING: The package seems to be changed or modified. If the package structure is changed, some users tracks may be lost during update process.';
Expand Down Expand Up @@ -413,3 +415,4 @@
$string['whatgradedesc'] = 'Whether the highest, average (mean), first or last completed attempt is recorded in the gradebook if multiple attempts are allowed.';
$string['width'] = 'Width';
$string['window'] = 'Window';
$string['youmustselectastatus'] = 'You must select a status to require';
24 changes: 20 additions & 4 deletions mod/scorm/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ function scorm_add_instance($scorm, $mform=null) {
if (empty($scorm->timeclose)) {
$scorm->timeclose = 0;
}
if (empty($scorm->completionstatusallscos)) {
$scorm->completionstatusallscos = 0;
}
$cmid = $scorm->coursemodule;
$cmidnumber = $scorm->cmidnumber;
$courseid = $scorm->course;
Expand Down Expand Up @@ -192,6 +195,9 @@ function scorm_update_instance($scorm, $mform=null) {
if (empty($scorm->timeclose)) {
$scorm->timeclose = 0;
}
if (empty($scorm->completionstatusallscos)) {
$scorm->completionstatusallscos = 0;
}

$cmid = $scorm->coursemodule;
$cmidnumber = $scorm->cmidnumber;
Expand Down Expand Up @@ -1210,6 +1216,7 @@ function scorm_get_completion_state($course, $cm, $userid, $type) {
"
SELECT
id,
scoid,
element,
value
FROM
Expand Down Expand Up @@ -1240,23 +1247,32 @@ function scorm_get_completion_state($course, $cm, $userid, $type) {
// Get status.
$statuses = array_flip(scorm_status_options());
$nstatus = 0;

// Check any track for these values.
$scostatus = array();
foreach ($tracks as $track) {
if (!in_array($track->element, array('cmi.core.lesson_status', 'cmi.completion_status', 'cmi.success_status'))) {
continue;
}

if (array_key_exists($track->value, $statuses)) {
$scostatus[$track->scoid] = true;
$nstatus |= $statuses[$track->value];
}
}

if ($scorm->completionstatusrequired & $nstatus) {
if (!empty($scorm->completionstatusallscos)) {
// Iterate over all scos and make sure each has a lesson_status.
$scos = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id, 'scormtype' => 'sco'));
foreach ($scos as $sco) {
if (empty($scostatus[$sco->id])) {
return completion_info::aggregate_completion_states($type, $result, false);
}
}
return completion_info::aggregate_completion_states($type, $result, true);
} else if ($scorm->completionstatusrequired & $nstatus) {
return completion_info::aggregate_completion_states($type, $result, true);
} else {
return completion_info::aggregate_completion_states($type, $result, false);
}

}

// Check for score.
Expand Down
17 changes: 17 additions & 0 deletions mod/scorm/mod_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,17 @@ public function validation($data, $files) {
$errors['timeclose'] = get_string('closebeforeopen', 'scorm');
}
}
if (!empty($data['completionstatusallscos'])) {
$requirestatus = false;
foreach (scorm_status_options(true) as $key => $value) {
if (!empty($data['completionstatusrequired'][$key])) {
$requirestatus = true;
}
}
if (!$requirestatus) {
$errors['completionstatusallscos'] = get_string('youmustselectastatus', 'scorm');
}
}

return $errors;
}
Expand Down Expand Up @@ -513,6 +524,12 @@ public function add_completion_rules() {
}
$mform->addHelpButton($firstkey, 'completionstatusrequired', 'scorm');

$mform->addElement('checkbox', 'completionstatusallscos', get_string('completionstatusallscos', 'scorm'));
$mform->setType('completionstatusallscos', PARAM_BOOL);
$mform->addHelpButton('completionstatusallscos', 'completionstatusallscos', 'scorm');
$mform->setDefault('completionstatusallscos', 0);
$items[] = 'completionstatusallscos';

return $items;
}

Expand Down
187 changes: 187 additions & 0 deletions mod/scorm/tests/behat/completion_condition_require_status.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
@mod @mod_scorm @_file_upload @_switch_frame
Feature: Scorm multi-sco completion
In order to let students access a scorm package
As a teacher
I need to add scorm activity to a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |

@javascript
Scenario: Test completion with a single sco completion.
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Enable completion tracking | Yes |
And I press "Save and display"
And I add a "SCORM package" to section "1"
And I set the following fields to these values:
| Name | Basic Multi-sco SCORM package |
| Description | Description |
| Completion tracking | Show activity as complete when conditions are met |
| Require all scos to return completion status | 0 |
And I set the field "Completed" to "1"
And I upload "mod/scorm/tests/packages/RuntimeMinimumCalls_SCORM12.zip" file to "Package file" filemanager
And I click on "Save and display" "button"
Then I should see "Basic Multi-sco SCORM package"
And I log out
And I log in as "student1"
And I follow "Course 1"
And I follow "Basic Multi-sco SCORM package"
And I should see "Normal"
And I press "Enter"
And I switch to "scorm_object" iframe
And I should see "Play of the game"
And I switch to the main frame
And I follow "Exit activity"
Then I should see "Basic Multi-sco SCORM package"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
Then "Student 1" user has completed "Basic Multi-sco SCORM package" activity

@javascript
Scenario: Test completion with all scos
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Enable completion tracking | Yes |
And I press "Save and display"
And I add a "SCORM package" to section "1"
And I set the following fields to these values:
| Name | ADV Multi-sco SCORM package |
| Description | Description |
| Completion tracking | Show activity as complete when conditions are met |
| Require all scos to return completion status | 1 |
And I set the field "Completed" to "1"
And I upload "mod/scorm/tests/packages/RuntimeMinimumCalls_SCORM12.zip" file to "Package file" filemanager
And I click on "Save and display" "button"
Then I should see "ADV Multi-sco SCORM package"
And I log out
And I log in as "student1"
And I follow "Course 1"
And I follow "ADV Multi-sco SCORM package"
And I should see "Normal"
And I press "Enter"
And I switch to "scorm_object" iframe
And I should see "Play of the game"
And I switch to the main frame
And I follow "Exit activity"
Then I should see "ADV Multi-sco SCORM package"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
Then "Student 1" user has not completed "ADV Multi-sco SCORM package" activity
And I log out
And I log in as "student1"
And I follow "Course 1"
And I follow "ADV Multi-sco SCORM package"
And I should see "Normal"
And I press "Enter"
And I switch to "scorm_object" iframe
And I should see "Play of the game"

And I switch to the main frame
And I click on "Par?" "list_item"
And I switch to "scorm_object" iframe
And I should see "Par"

And I switch to the main frame
And I click on "Keeping Score" "list_item"
And I switch to "scorm_object" iframe
And I should see "Scoring"

And I switch to the main frame
And I click on "Other Scoring Systems" "list_item"
And I switch to "scorm_object" iframe
And I should see "Other Scoring Systems"

And I switch to the main frame
And I click on "The Rules of Golf" "list_item"
And I switch to "scorm_object" iframe
And I should see "The Rules of Golf"

And I switch to the main frame
And I click on "Playing Golf Quiz" "list_item"
And I switch to "scorm_object" iframe
And I should see "Knowledge Check"

And I switch to the main frame
And I click on "Taking Care of the Course" "list_item"
And I switch to "scorm_object" iframe
And I should see "Etiquette - Care For the Course"

And I switch to the main frame
And I click on "Avoiding Distraction" "list_item"
And I switch to "scorm_object" iframe
And I should see "Etiquette - Avoiding Distraction"

And I switch to the main frame
And I click on "Playing Politely" "list_item"
And I switch to "scorm_object" iframe
And I should see "Etiquette - Playing the Game"

And I switch to the main frame
And I click on "Etiquette Quiz" "list_item"
And I switch to "scorm_object" iframe
And I should see "Knowledge Check"

And I switch to the main frame
And I click on "Handicapping Overview" "list_item"
And I switch to "scorm_object" iframe
And I should see "Handicapping"

And I switch to the main frame
And I click on "Calculating a Handicap" "list_item"
And I switch to "scorm_object" iframe
And I should see "Calculating a Handicap"

And I switch to the main frame
And I click on "Calculating a Handicapped Score" "list_item"
And I switch to "scorm_object" iframe
And I should see "Calculating a Score"

And I switch to the main frame
And I click on "Handicapping Example" "list_item"
And I switch to "scorm_object" iframe
And I should see "Calculating a Score"

And I switch to the main frame
And I click on "Handicapping Quiz" "list_item"
And I switch to "scorm_object" iframe
And I should see "Knowledge Check"

And I switch to the main frame
And I click on "How to Have Fun Playing Golf" "list_item"
And I switch to "scorm_object" iframe
And I should see "How to Have Fun Golfing"

And I switch to the main frame
And I click on "How to Make Friends Playing Golf" "list_item"
And I switch to "scorm_object" iframe
And I should see "How to Make Friends on the Golf Course"

And I switch to the main frame
And I click on "Having Fun Quiz" "list_item"
And I switch to "scorm_object" iframe
And I should see "Knowledge Check"
And I switch to the main frame
And I follow "Exit activity"
Then I should see "ADV Multi-sco SCORM package"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And "Student 1" user has completed "ADV Multi-sco SCORM package" activity
4 changes: 2 additions & 2 deletions mod/scorm/tests/externallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -770,8 +770,8 @@ public function test_mod_scorm_get_scorms_by_courses() {
self::setUser($teacher);

$additionalfields = array('updatefreq', 'timemodified', 'options',
'completionstatusrequired', 'completionscorerequired', 'autocommit',
'section', 'visible', 'groupmode', 'groupingid');
'completionstatusrequired', 'completionscorerequired', 'completionstatusallscos',
'autocommit', 'section', 'visible', 'groupmode', 'groupingid');

foreach ($additionalfields as $field) {
$fieldtype = $returndescription->keys['scorms']->content->keys[$field]->type;
Expand Down
Binary file not shown.
Loading

0 comments on commit b30a884

Please sign in to comment.