diff --git a/CHANGES.md b/CHANGES.md
index 90a1408..c94fd53 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,6 @@
+Changes in version 2017-07-19 (2017071902)
+- Fix: Completion support
+
Changes in version 2017-07-18 (2017071801)
- New: icon.png and icon.svg
diff --git a/db/install.xml b/db/install.xml
index a17e49e..d293144 100755
--- a/db/install.xml
+++ b/db/install.xml
@@ -46,6 +46,8 @@
+
+
diff --git a/db/upgrade.php b/db/upgrade.php
index 9b52428..784b9fd 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -1582,6 +1582,8 @@ function xmldb_game_upgrade($oldversion) {
// Launch change of type for field thisfield.
$dbman->change_field_type($table, $field);
+
+ upgrade_mod_savepoint(true, $ver, 'game');
}
if ($oldversion < ($ver = 2017062801)) {
@@ -1597,6 +1599,7 @@ function xmldb_game_upgrade($oldversion) {
} else {
$dbman->add_field($table, $field);
}
+
}
if ($oldversion < ($ver = 2017062801)) {
@@ -1642,11 +1645,15 @@ function xmldb_game_upgrade($oldversion) {
} else {
$dbman->add_field($table, $field);
}
+
+ upgrade_mod_savepoint(true, $ver, 'game');
}
if ($oldversion < ($ver = 2017070301)) {
$sql = "UPDATE {$CFG->prefix}game SET glossarycategoryid=0 WHERE glossarycategoryid < 0";
$DB->execute( $sql);
+
+ upgrade_mod_savepoint(true, $ver, 'game');
}
if ($oldversion < ($ver = 2017070403)) {
@@ -1674,6 +1681,35 @@ function xmldb_game_upgrade($oldversion) {
}
$DB->update_record( 'game_snakes_database', $updrec);
}
+
+ upgrade_mod_savepoint(true, $ver, 'game');
+ }
+
+ if ($oldversion < ($ver = 2017071901)) {
+
+ // Define field completionattemptsexhausted to be added to quiz.
+ $table = new xmldb_table('game');
+ $field = new xmldb_field('completionattemptsexhausted', XMLDB_TYPE_INTEGER, '1', null, null, null, '0');
+
+ // Conditionally launch add field completionattemptsexhausted.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ upgrade_mod_savepoint(true, $ver, 'game');
+ }
+
+ if ($oldversion < ($ver = 2017071902)) {
+ // Define field completionpass to be added to quiz.
+ $table = new xmldb_table('game');
+ $field = new xmldb_field('completionpass', XMLDB_TYPE_INTEGER, '1', null, null, null, 0, 'completionattemptsexhausted');
+
+ // Conditionally launch add field completionpass.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ upgrade_mod_savepoint(true, $ver, 'game');
}
return true;
diff --git a/lib.php b/lib.php
index f26604d..4789729 100644
--- a/lib.php
+++ b/lib.php
@@ -1352,8 +1352,6 @@ function game_reset_userdata($data) {
function game_get_completion_state($course, $cm, $userid, $type) {
global $CFG, $DB;
- require_once($CFG->dirroot . '/mod/game/locallib.php');
-
if (($cm->completion == 0) or ($cm->completion == 1)) {
// Completion option is not enabled so just return $type.
return $type;
@@ -1368,9 +1366,25 @@ function game_get_completion_state($course, $cm, $userid, $type) {
print_error('invalidcoursemodule');
}
- $grade = $DB->get_record_select('game_grades', "userid=$userid AND gameid = $cm->instance", null, 'id,score');
+ // Check for passing grade.
+ if ($game->completionpass) {
+ require_once($CFG->libdir . '/gradelib.php');
+ $item = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod',
+ 'itemmodule' => 'game', 'iteminstance' => $cm->instance, 'outcomeid' => null));
+ if ($item) {
+ $grades = grade_grade::fetch_users_grades($item, array($userid), false);
+ if (!empty($grades[$userid])) {
+ return $grades[$userid]->is_passed($item);
+ }
+ }
+ }
+
+ return false;
+
+ //$sql = "SELECT MAX(score) as score FROM {$CFG->prefix}game_grades WHERE gameid=$cm->instance AND userid=$userid";
+ //$grade = $DB->get_record_sql( $sql);
- return $grade && $grade->score > 0;
+ //return $grade && $grade->score > 0;
}
/**
@@ -1441,3 +1455,38 @@ function game_pix_url( $filename, $module='') {
return $OUTPUT->pix_url($filename, $module);
}
}
+
+/**
+ * Callback which returns human-readable strings describing the active completion custom rules for the module instance.
+ *
+ * @param cm_info|stdClass $cm object with fields ->completion and ->customdata['customcompletionrules']
+ * @return array $descriptions the array of descriptions for the custom rules.
+ */
+function mod_game_get_completion_active_rule_descriptions($cm) {
+ // Values will be present in cm_info, and we assume these are up to date.
+ if (empty($cm->customdata['customcompletionrules'])
+ || $cm->completion != COMPLETION_TRACKING_AUTOMATIC) {
+ return [];
+ }
+
+ $descriptions = [];
+ foreach ($cm->customdata['customcompletionrules'] as $key => $val) {
+ switch ($key) {
+ case 'completionattemptsexhausted':
+ if (empty($val)) {
+ continue;
+ }
+ $descriptions[] = get_string('completionattemptsexhausteddesc', 'quiz');
+ break;
+ case 'completionpass':
+ if (empty($val)) {
+ continue;
+ }
+ $descriptions[] = get_string('completionpassdesc', 'quiz', format_time($val));
+ break;
+ default:
+ break;
+ }
+ }
+ return $descriptions;
+}
diff --git a/mod_form.php b/mod_form.php
index 4207069..1842d36 100644
--- a/mod_form.php
+++ b/mod_form.php
@@ -162,9 +162,12 @@ class mod_game_mod_form extends moodleform_mod {
$mform->addElement('selectyesno', 'disablesummarize', get_string('disablesummarize', 'game'));
// Grade options.
- $mform->addElement('header', 'gradeoptions', get_string('grades', 'grades'));
+ //$mform->addElement('header', 'gradeoptions', get_string('grades', 'grades'));
+ $this->standard_grading_coursemodule_elements();
+ $mform->removeElement('grade');
$mform->addElement('text', 'grade', get_string( 'grademax', 'grades'), array('size' => 4));
$mform->setType('grade', PARAM_INT);
+
$gradingtypeoptions = array();
$gradingtypeoptions[ GAME_GRADEHIGHEST] = get_string('gradehighest', 'game');
$gradingtypeoptions[ GAME_GRADEAVERAGE] = get_string('gradeaverage', 'game');
@@ -520,6 +523,19 @@ class mod_game_mod_form extends moodleform_mod {
}
}
+ if (array_key_exists('completion', $data) && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC) {
+ $completionpass = isset($data['completionpass']) ? $data['completionpass'] : $this->current->completionpass;
+
+ // Show an error if require passing grade was selected and the grade to pass was set to 0.
+ if ($completionpass && (empty($data['gradepass']) || grade_floatval($data['gradepass']) == 0)) {
+ if (isset($data['completionpass'])) {
+ $errors['completionpassgroup'] = get_string('gradetopassnotset', 'quiz');
+ } else {
+ $errors['gradepass'] = get_string('gradetopassmustbeset', 'quiz');
+ }
+ }
+ }
+
return $errors;
}
@@ -602,4 +618,37 @@ class mod_game_mod_form extends moodleform_mod {
parent::set_data($defaultvalues);
}
+
+ /**
+ * Display module-specific activity completion rules.
+ * Part of the API defined by moodleform_mod
+ * @return array Array of string IDs of added items, empty array if none
+ */
+ public function add_completion_rules() {
+ $mform = $this->_form;
+ $items = array();
+
+ $group = array();
+ $group[] = $mform->createElement('advcheckbox', 'completionpass', null, get_string('completionpass', 'quiz'),
+ array('group' => 'cpass'));
+
+ $group[] = $mform->createElement('advcheckbox', 'completionattemptsexhausted', null,
+ get_string('completionattemptsexhausted', 'quiz'),
+ array('group' => 'cattempts'));
+ $mform->disabledIf('completionattemptsexhausted', 'completionpass', 'notchecked');
+ $mform->addGroup($group, 'completionpassgroup', get_string('completionpass', 'quiz'), ' ', false);
+ $mform->addHelpButton('completionpassgroup', 'completionpass', 'quiz');
+ $items[] = 'completionpassgroup';
+ return $items;
+ }
+
+ /**
+ * Called during validation. Indicates whether a module-specific completion rule is selected.
+ *
+ * @param array $data Input data (not yet validated)
+ * @return bool True if one or more rules is enabled, false if none are.
+ */
+ public function completion_rule_enabled($data) {
+ return !empty($data['completionattemptsexhausted']) || !empty($data['completionpass']);
+ }
}
diff --git a/version.php b/version.php
index c1aa9f2..5091471 100644
--- a/version.php
+++ b/version.php
@@ -35,10 +35,10 @@ if (!isset( $plugin)) {
}
$plugin->component = 'mod_game'; // Full name of the plugin (used for diagnostics).
-$plugin->version = 2017071801; // The current module version (Date: YYYYMMDDXX).
+$plugin->version = 2017071902; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2010112400; // Requires Moodle 2.0.
$plugin->cron = 0; // Period for cron to check this module (secs).
-$plugin->release = '2017-07-18';
+$plugin->release = '2017-07-19';
$plugin->maturity = MATURITY_STABLE;
if ($useplugin != 2) {