diff --git a/lib/db/services.php b/lib/db/services.php index 7803aa83a59..d270a7573bc 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1140,6 +1140,7 @@ $services = array( 'core_user_get_users_by_field', 'core_user_add_user_private_files', 'mod_assign_view_grading_table', + 'mod_scorm_view_scorm', ), 'enabled' => 0, 'restrictedusers' => 0, diff --git a/mod/scorm/classes/external.php b/mod/scorm/classes/external.php new file mode 100644 index 00000000000..e6425b4cc82 --- /dev/null +++ b/mod/scorm/classes/external.php @@ -0,0 +1,105 @@ +. + +/** + * SCORM module external API + * + * @package mod_scorm + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ + +defined('MOODLE_INTERNAL') || die; + +require_once($CFG->libdir . '/externallib.php'); +require_once($CFG->dirroot . '/mod/scorm/lib.php'); + +/** + * SCORM module external functions + * + * @package mod_scorm + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ +class mod_scorm_external extends external_api { + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.0 + */ + public static function view_scorm_parameters() { + return new external_function_parameters( + array( + 'scormid' => new external_value(PARAM_INT, 'scorm instance id') + ) + ); + } + + /** + * Trigger the course module viewed event. + * + * @param int $scormid the scorm instance id + * @return array of warnings and status result + * @since Moodle 3.0 + * @throws moodle_exception + */ + public static function view_scorm($scormid) { + global $DB, $CFG; + require_once($CFG->dirroot . '/mod/scorm/lib.php'); + + $params = self::validate_parameters(self::view_scorm_parameters(), + array( + 'scormid' => $scormid + )); + $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); + + // Call the scorm/lib API. + scorm_view($scorm, $course, $cm, $context); + + $result = array(); + $result['status'] = true; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.0 + */ + public static function view_scorm_returns() { + return new external_single_structure( + array( + 'status' => new external_value(PARAM_BOOL, 'status: true if success'), + 'warnings' => new external_warnings() + ) + ); + } +} diff --git a/mod/scorm/db/services.php b/mod/scorm/db/services.php new file mode 100644 index 00000000000..1a95c3e0cf3 --- /dev/null +++ b/mod/scorm/db/services.php @@ -0,0 +1,36 @@ +. + +/** + * SCORM external functions and service definitions. + * + * @package mod_scorm + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ + +$functions = array( + + 'mod_scorm_view_scorm' => array( + 'classname' => 'mod_scorm_external', + 'methodname' => 'view_scorm', + 'description' => 'Trigger the course module viewed event.', + 'type' => 'write', + 'capabilities' => '' + ), +); diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index bb5bfc21148..1e2164ffcc9 100644 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -1440,3 +1440,27 @@ function scorm_check_mode($scorm, &$newattempt, &$attempt, $userid, &$mode) { } } } + +/** + * Trigger the course_module_viewed event. + * + * @param stdClass $scorm scorm object + * @param stdClass $course course object + * @param stdClass $cm course module object + * @param stdClass $context context object + * @since Moodle 3.0 + */ +function scorm_view($scorm, $course, $cm, $context) { + + // Trigger course_module_viewed event. + $params = array( + 'context' => $context, + 'objectid' => $scorm->id + ); + + $event = \mod_scorm\event\course_module_viewed::create($params); + $event->add_record_snapshot('course_modules', $cm); + $event->add_record_snapshot('course', $course); + $event->add_record_snapshot('scorm', $scorm); + $event->trigger(); +} diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php index d76312fcfcf..747213755b4 100644 --- a/mod/scorm/locallib.php +++ b/mod/scorm/locallib.php @@ -840,7 +840,15 @@ function scorm_get_all_attempts($scormid, $userid) { return $attemptids; } -function scorm_view_display ($user, $scorm, $action, $cm) { +/** + * Displays the entry form and toc if required. + * + * @param stdClass $user user object + * @param stdClass $scorm scorm object + * @param string $action base URL for the organizations select box + * @param stdClass $cm course module object + */ +function scorm_print_launch ($user, $scorm, $action, $cm) { global $CFG, $DB, $PAGE, $OUTPUT, $COURSE; if ($scorm->updatefreq == SCORM_UPDATE_EVERYTIME) { diff --git a/mod/scorm/tests/externallib_test.php b/mod/scorm/tests/externallib_test.php new file mode 100644 index 00000000000..176fee51b49 --- /dev/null +++ b/mod/scorm/tests/externallib_test.php @@ -0,0 +1,100 @@ +. + +/** + * SCORM module external functions tests + * + * @package mod_scorm + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +require_once($CFG->dirroot . '/webservice/tests/helpers.php'); +require_once($CFG->dirroot . '/mod/scorm/lib.php'); + +/** + * SCORM module external functions tests + * + * @package mod_scorm + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ +class mod_scorm_external_testcase extends externallib_advanced_testcase { + + /** + * Test view_scorm + */ + public function test_view_scorm() { + global $DB; + + $this->resetAfterTest(true); + + $this->setAdminUser(); + // Setup test data. + $course = $this->getDataGenerator()->create_course(); + $scorm = $this->getDataGenerator()->create_module('scorm', array('course' => $course->id)); + $context = context_module::instance($scorm->cmid); + $cm = get_coursemodule_from_instance('scorm', $scorm->id); + + // Test invalid instance id. + try { + mod_scorm_external::view_scorm(0); + $this->fail('Exception expected due to invalid mod_scorm instance id.'); + } catch (moodle_exception $e) { + $this->assertEquals('invalidrecord', $e->errorcode); + } + + // Test not-enrolled user. + $user = self::getDataGenerator()->create_user(); + $this->setUser($user); + try { + mod_scorm_external::view_scorm($scorm->id); + $this->fail('Exception expected due to not enrolled user.'); + } catch (moodle_exception $e) { + $this->assertEquals('requireloginerror', $e->errorcode); + } + + // Test user with full capabilities. + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + + $result = mod_scorm_external::view_scorm($scorm->id); + $result = external_api::clean_returnvalue(mod_scorm_external::view_scorm_returns(), $result); + + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = array_shift($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_scorm\event\course_module_viewed', $event); + $this->assertEquals($context, $event->get_context()); + $moodleurl = new \moodle_url('/mod/scorm/view.php', array('id' => $cm->id)); + $this->assertEquals($moodleurl, $event->get_url()); + $this->assertEventContextNotUsed($event); + $this->assertNotEmpty($event->get_name()); + } +} diff --git a/mod/scorm/tests/lib_test.php b/mod/scorm/tests/lib_test.php new file mode 100644 index 00000000000..a0e4a60760f --- /dev/null +++ b/mod/scorm/tests/lib_test.php @@ -0,0 +1,79 @@ +. + +/** + * SCORM module library functions tests + * + * @package mod_scorm + * @category test + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +require_once($CFG->dirroot . '/webservice/tests/helpers.php'); +require_once($CFG->dirroot . '/mod/scorm/lib.php'); + +/** + * SCORM module library functions tests + * + * @package mod_scorm + * @category test + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.0 + */ +class mod_scorm_lib_testcase extends externallib_advanced_testcase { + + /** + * Test scorm_view + * @return void + */ + public function test_scorm_view() { + global $CFG; + + $this->resetAfterTest(); + + $this->setAdminUser(); + // Setup test data. + $course = $this->getDataGenerator()->create_course(); + $scorm = $this->getDataGenerator()->create_module('scorm', array('course' => $course->id)); + $context = context_module::instance($scorm->cmid); + $cm = get_coursemodule_from_instance('scorm', $scorm->id); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + + scorm_view($scorm, $course, $cm, $context); + + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = array_shift($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_scorm\event\course_module_viewed', $event); + $this->assertEquals($context, $event->get_context()); + $url = new \moodle_url('/mod/scorm/view.php', array('id' => $cm->id)); + $this->assertEquals($url, $event->get_url()); + $this->assertEventContextNotUsed($event); + $this->assertNotEmpty($event->get_name()); + } + +} diff --git a/mod/scorm/version.php b/mod/scorm/version.php index 13747d8d472..54f91618ef4 100644 --- a/mod/scorm/version.php +++ b/mod/scorm/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2015051101; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2015051102; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2015050500; // Requires this Moodle version. $plugin->component = 'mod_scorm'; // Full name of the plugin (used for diagnostics). $plugin->cron = 300; diff --git a/mod/scorm/view.php b/mod/scorm/view.php index f6dc57c92b3..fd98432af92 100644 --- a/mod/scorm/view.php +++ b/mod/scorm/view.php @@ -15,6 +15,7 @@ // along with Moodle. If not, see . require_once("../../config.php"); +require_once($CFG->dirroot.'/mod/scorm/lib.php'); require_once($CFG->dirroot.'/mod/scorm/locallib.php'); require_once($CFG->dirroot.'/course/lib.php'); @@ -123,14 +124,7 @@ $shortname = format_string($course->shortname, true, array('context' => $context $pagetitle = strip_tags($shortname.': '.format_string($scorm->name)); // Trigger module viewed event. -$event = \mod_scorm\event\course_module_viewed::create(array( - 'objectid' => $scorm->id, - 'context' => $contextmodule, -)); -$event->add_record_snapshot('course', $course); -$event->add_record_snapshot('scorm', $scorm); -$event->add_record_snapshot('course_modules', $cm); -$event->trigger(); +scorm_view($scorm, $course, $cm, $contextmodule); if (empty($preventskip) && empty($launch) && (has_capability('mod/scorm:skipview', $contextmodule))) { scorm_simple_play($scorm, $USER, $contextmodule, $cm->id); @@ -179,7 +173,7 @@ if (!empty($scorm->timeclose) && $timenow > $scorm->timeclose) { $scormopen = false; } if ($scormopen && empty($launch)) { - scorm_view_display($USER, $scorm, 'view.php?id='.$cm->id, $cm); + scorm_print_launch($USER, $scorm, 'view.php?id='.$cm->id, $cm); } if (!empty($forcejs)) { echo $OUTPUT->box(get_string("forcejavascriptmessage", "scorm"), "generalbox boxaligncenter forcejavascriptmessage"); diff --git a/mod/upgrade.txt b/mod/upgrade.txt index bff2c991f08..2eaa8aeb1d2 100644 --- a/mod/upgrade.txt +++ b/mod/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /mod/* - activity modules, information provided here is intended especially for developers. +=== 3.0 === + +* Function scorm_view_display was renamed to scorm_print_launch to avoid confussion with new function scorm_view. + === 2.9 === * Added Grade to pass field to mod_form for activities that support grading. diff --git a/version.php b/version.php index 1228df7869d..27a235a6316 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015071600.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015071600.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.