/** * Retrieves SCO tracking data for the given user id and attempt number * * @param int $scoid the sco id * @param int $userid the user id * @param int $attempt the attempt number * @return array warnings and the scoes data * @since Moodle 3.0 */ public static function get_scorm_sco_tracks($scoid, $userid, $attempt = 0) { global $USER, $DB; $params = self::validate_parameters(self::get_scorm_sco_tracks_parameters(), array('scoid' => $scoid, 'userid' => $userid, 'attempt' => $attempt)); $tracks = array(); $warnings = array(); $sco = scorm_get_sco($params['scoid'], SCO_ONLY); if (!$sco) { throw new moodle_exception('cannotfindsco', 'scorm'); } $scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('scorm', $scorm->id); $context = context_module::instance($cm->id); self::validate_context($context); $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); // Extra checks so only users with permissions can view other users attempts. if ($USER->id != $user->id) { require_capability('mod/scorm:viewreport', $context); } scorm_require_available($scorm, true, $context); if (empty($params['attempt'])) { $params['attempt'] = scorm_get_last_attempt($scorm->id, $user->id); } $attempted = false; if ($scormtracks = scorm_get_tracks($sco->id, $params['userid'], $params['attempt'])) { // Check if attempted. if ($scormtracks->status != '') { $attempted = true; foreach ($scormtracks as $element => $value) { $tracks[] = array('element' => $element, 'value' => $value); } } } if (!$attempted) { $warnings[] = array('item' => 'attempt', 'itemid' => $params['attempt'], 'warningcode' => 'notattempted', 'message' => get_string('notattempted', 'scorm')); } $result = array(); $result['data']['attempt'] = $params['attempt']; $result['data']['tracks'] = $tracks; $result['warnings'] = $warnings; return $result; }
/** * Test scorm_get_availability_status and scorm_require_available * @return void */ public function test_scorm_check_and_require_available() { global $DB; // Set to the student user. self::setUser($this->student); // Usual case. list($status, $warnings) = scorm_get_availability_status($this->scorm, false); $this->assertEquals(true, $status); $this->assertCount(0, $warnings); // SCORM not open. $this->scorm->timeopen = time() + DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, false); $this->assertEquals(false, $status); $this->assertCount(1, $warnings); // SCORM closed. $this->scorm->timeopen = 0; $this->scorm->timeclose = time() - DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, false); $this->assertEquals(false, $status); $this->assertCount(1, $warnings); // SCORM not open and closed. $this->scorm->timeopen = time() + DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, false); $this->assertEquals(false, $status); $this->assertCount(2, $warnings); // Now additional checkings with different parameters values. list($status, $warnings) = scorm_get_availability_status($this->scorm, true, $this->context); $this->assertEquals(false, $status); $this->assertCount(2, $warnings); // SCORM not open. $this->scorm->timeopen = time() + DAYSECS; $this->scorm->timeclose = 0; list($status, $warnings) = scorm_get_availability_status($this->scorm, true, $this->context); $this->assertEquals(false, $status); $this->assertCount(1, $warnings); // SCORM closed. $this->scorm->timeopen = 0; $this->scorm->timeclose = time() - DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, true, $this->context); $this->assertEquals(false, $status); $this->assertCount(1, $warnings); // SCORM not open and closed. $this->scorm->timeopen = time() + DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, true, $this->context); $this->assertEquals(false, $status); $this->assertCount(2, $warnings); // As teacher now. self::setUser($this->teacher); // SCORM not open and closed. $this->scorm->timeopen = time() + DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, false); $this->assertEquals(false, $status); $this->assertCount(2, $warnings); // Now, we use the special capability. // SCORM not open and closed. $this->scorm->timeopen = time() + DAYSECS; list($status, $warnings) = scorm_get_availability_status($this->scorm, true, $this->context); $this->assertEquals(true, $status); $this->assertCount(0, $warnings); // Check exceptions does not broke anything. scorm_require_available($this->scorm, true, $this->context); // Now, expect exceptions. $this->setExpectedException('moodle_exception', get_string("notopenyet", "scorm", userdate($this->scorm->timeopen))); // Now as student other condition. self::setUser($this->student); $this->scorm->timeopen = 0; $this->scorm->timeclose = time() - DAYSECS; $this->setExpectedException('moodle_exception', get_string("expired", "scorm", userdate($this->scorm->timeclose))); scorm_require_available($this->scorm, false); }
/** * Retrieves SCO tracking data for the given user id and attempt number * * @param int $scoid the sco id * @param int $userid the user id * @param int $attempt the attempt number * @return array warnings and the scoes data * @since Moodle 3.0 */ public static function get_scorm_sco_tracks($scoid, $userid, $attempt = 0) { global $USER, $DB; $params = self::validate_parameters(self::get_scorm_sco_tracks_parameters(), array('scoid' => $scoid, 'userid' => $userid, 'attempt' => $attempt)); $tracks = array(); $warnings = array(); $sco = scorm_get_sco($params['scoid'], SCO_ONLY); if (!$sco) { throw new moodle_exception('cannotfindsco', 'scorm'); } $scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('scorm', $scorm->id); $context = context_module::instance($cm->id); self::validate_context($context); // Validate the user obtaining the context, it will fail if the user doesn't exists or have been deleted. context_user::instance($params['userid']); // Extra checks so only users with permissions can view other users attempts. if ($USER->id != $params['userid']) { require_capability('mod/scorm:viewreport', $context); } scorm_require_available($scorm, true, $context); if (empty($params['attempt'])) { $params['attempt'] = scorm_get_last_attempt($scorm->id, $params['userid']); } if ($scormtracks = scorm_get_tracks($sco->id, $params['userid'], $params['attempt'])) { foreach ($scormtracks as $element => $value) { $tracks[] = array( 'element' => $element, 'value' => $value, ); } } $result = array(); $result['data']['attempt'] = $params['attempt']; $result['data']['tracks'] = $tracks; $result['warnings'] = $warnings; return $result; }
} } $PAGE->set_url('/mod/scorm/loadSCO.php', array('scoid' => $scoid, 'id' => $cm->id)); if (!isloggedin()) { // Prevent login page from being shown in iframe. // Using simple html instead of exceptions here as shown inside iframe/object. echo html_writer::start_tag('html'); echo html_writer::tag('head', ''); echo html_writer::tag('body', get_string('loggedinnot')); echo html_writer::end_tag('html'); exit; } require_login($course, false, $cm, false); // Call require_login anyway to set up globals correctly. // Check if SCORM is available. scorm_require_available($scorm); $context = context_module::instance($cm->id); // Forge SCO URL. list($sco, $scolaunchurl) = scorm_get_sco_and_launch_url($scorm, $scoid, $context); if ($sco->scormtype == 'asset') { $attempt = scorm_get_last_attempt($scorm->id, $USER->id); $element = scorm_version_check($scorm->version, SCORM_13) ? 'cmi.completion_status' : 'cmi.core.lesson_status'; $value = 'completed'; scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, $element, $value); } // Trigger the SCO launched event. scorm_launch_sco($scorm, $sco, $cm, $context, $scolaunchurl); header('Content-Type: text/html; charset=UTF-8'); if ($sco->scormtype == 'asset') { // HTTP 302 Found => Moved Temporarily. header('Location: ' . $scolaunchurl);
/** * Trigger the course module viewed event. * * @param int $scormid the SCORM instance id * @param int $scoid the SCO id * @return array of warnings and status result * @since Moodle 3.1 * @throws moodle_exception */ public static function launch_sco($scormid, $scoid = 0) { global $DB; $params = self::validate_parameters(self::launch_sco_parameters(), array('scormid' => $scormid, 'scoid' => $scoid)); $warnings = array(); // Request and permission validation. $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST); list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm'); $context = context_module::instance($cm->id); self::validate_context($context); // If the SCORM is not open this function will throw exceptions. scorm_require_available($scorm); if (!empty($params['scoid']) and !($sco = scorm_get_sco($params['scoid'], SCO_ONLY))) { throw new moodle_exception('cannotfindsco', 'scorm'); } list($sco, $scolaunchurl) = scorm_get_sco_and_launch_url($scorm, $params['scoid'], $context); // Trigger the SCO launched event. scorm_launch_sco($scorm, $sco, $cm, $context, $scolaunchurl); $result = array(); $result['status'] = true; $result['warnings'] = $warnings; return $result; }