opigno_scorm_quiz.module in Opigno 7
Module hook definitions.
File
modules/scorm/quiz/opigno_scorm_quiz.moduleView source
<?php
/**
* @file
* Module hook definitions.
*/
/**
* Implements hook_opigno_scorm_ui_register_cmi_paths().
*/
function opigno_scorm_quiz_opigno_scorm_ui_register_cmi_paths($scorm_version) {
switch ($scorm_version) {
case '2004':
$data = array(
'cmi.score.raw' => array(),
'cmi.score.min' => array(),
'cmi.score.max' => array(),
'cmi.score.scaled' => array(),
'cmi.suspend_data' => array(),
'cmi.success_status' => array(),
'cmi.objectives' => array(),
'cmi.objectives._count' => array(
'readOnly' => 1,
),
'cmi.objectives._children' => array(
'readOnly' => 1,
),
'cmi.objectives.n.id' => array(),
'cmi.objectives.n.score' => array(),
'cmi.objectives.n.score._children' => array(
'readOnly' => 1,
),
'cmi.objectives.n.score.scaled' => array(),
'cmi.objectives.n.score.raw' => array(),
'cmi.objectives.n.score.min' => array(),
'cmi.objectives.n.score.max' => array(),
'cmi.objectives.n.success_status' => array(),
'cmi.objectives.n.completion_status' => array(),
'cmi.objectives.n.progress_measure' => array(),
'cmi.objectives.n.description' => array(),
);
break;
case '1.2':
$data = array(
'cmi.core.score.raw' => array(),
'cmi.core.score.max' => array(),
'cmi.core.score.min' => array(),
'cmi.core.score._children' => array(),
'cmi.suspend_data' => array(),
'cmi.core.lesson_status' => array(),
'cmi.objectives' => array(),
'cmi.objectives._count' => array(
'readOnly' => 1,
),
'cmi.objectives._children' => array(
'readOnly' => 1,
),
'cmi.objectives.n.id' => array(),
'cmi.objectives.n.score' => array(),
'cmi.objectives.n.score._children' => array(
'readOnly' => 1,
),
'cmi.objectives.n.score.raw' => array(),
'cmi.objectives.n.score.min' => array(),
'cmi.objectives.n.score.max' => array(),
'cmi.objectives.n.status' => array(),
);
break;
}
return $data;
}
/**
* Implements hook_opigno_scorm_ui_register_cmi_data().
*/
function opigno_scorm_quiz_opigno_scorm_ui_register_cmi_data($scorm, $scos, $scorm_version) {
global $user;
switch ($scorm_version) {
case '2004':
$data = array(
'cmi.score.raw' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.score.raw', ''),
'cmi.score.min' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.score.min', ''),
'cmi.score.max' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.score.max', ''),
'cmi.score.scaled' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.score.scaled', ''),
'cmi.success_status' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.success_status', ''),
'cmi.objectives' => array(),
);
// Get last visited SCO.
$last_sco = opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'user.sco', '');
if ($last_sco != '') {
$data['cmi.suspend_data'] = opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.suspend_data.' . $last_sco, '');
}
else {
$data['cmi.suspend_data'] = opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.suspend_data', '');
}
break;
case '1.2':
$data = array(
'cmi.core.score.raw' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.core.score.raw', ''),
'cmi.core.score.min' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.core.score.min', ''),
'cmi.core.score.max' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.core.score.max', ''),
'cmi.core.lesson_status' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.core.lesson_status', ''),
'cmi.suspend_data' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.suspend_data', ''),
'cmi.core.score._children' => opigno_scorm_ui_scorm_cmi_get($user->uid, $scorm->id, 'cmi.core.score._children', 'raw,min,max'),
'cmi.objectives' => array(),
);
break;
}
// Fetch the objectives.
foreach ($scos as $sco) {
if (!empty($sco->attributes['objectives'])) {
foreach ($sco->attributes['objectives'] as $objective) {
$stored_objective = opigno_scorm_quiz_load_objective($user->uid, $scorm->id, $objective['id']);
if ($scorm_version == '2004') {
$defaults = array(
'id' => $objective['id'],
'score' => array(
'scaled' => 0,
'raw' => 0,
'min' => 0,
'max' => 0,
),
'success_status' => '',
'completion_status' => '',
'progress_measure' => '',
'description' => '',
);
}
else {
$defaults = array(
'id' => $objective['id'],
'score' => array(
'raw' => 0,
'min' => 0,
'max' => 0,
),
'status' => '',
);
}
if (!empty($stored_objective)) {
$stored_objective = (array) $stored_objective;
$stored_objective += $defaults;
}
else {
$stored_objective = $defaults;
}
$data['cmi.objectives'][] = $stored_objective;
}
}
}
return $data;
}
/**
* Implements hook_opigno_scorm_ui_add_assets().
*/
function opigno_scorm_quiz_opigno_scorm_ui_add_assets() {
$path = drupal_get_path('module', 'opigno_scorm_quiz');
drupal_add_js("{$path}/js/opigno_scorm_quiz.js");
}
/**
* Implements hook_opigno_scorm_ui_commit().
*/
function opigno_scorm_quiz_opigno_scorm_ui_commit($scorm, $sco_id, $data) {
global $user;
// Store objectives and results.
if (!empty($data->cmi->objectives)) {
for ($i = 0, $len = count($data->cmi->objectives); $i < $len; $i++) {
opigno_scorm_scorm_cmi_set($user->uid, $scorm->id, "cmi.objectives.{$i}", $data->cmi->objectives[$i]);
}
}
if (!empty($data->scorm_version)) {
switch ($data->scorm_version) {
case '2004':
// Store the score.
if (!empty($data->cmi->score)) {
foreach (array(
'raw',
'min',
'max',
'scaled',
) as $key) {
if (isset($data->cmi->score->{$key})) {
opigno_scorm_scorm_cmi_set($user->uid, $scorm->id, "cmi.score.{$key}", $data->cmi->score->{$key});
}
}
}
// Store the success status.
if (!empty($data->cmi->success_status)) {
opigno_scorm_scorm_cmi_set($user->uid, $scorm->id, 'cmi.success_status', $data->cmi->success_status);
}
break;
case '1.2':
// Store the score.
if (!empty($data->cmi->core->score)) {
foreach (array(
'raw',
'min',
'max',
) as $key) {
if (isset($data->cmi->core->score->{$key})) {
opigno_scorm_scorm_cmi_set($user->uid, $scorm->id, "cmi.core.score.{$key}", $data->cmi->core->score->{$key});
}
}
}
break;
}
}
}
/**
* Implements of hook_quiz_question_info().
*/
function opigno_scorm_quiz_quiz_question_info() {
return array(
'opigno_scorm_quiz_question' => array(
'name' => t('SCORM Package'),
'description' => t('Question using SCORM packages.'),
'question provider' => 'OpignoScormQuizQuestion',
'response provider' => 'OpignoScormQuizResponse',
'module' => 'quiz_question',
),
);
}
/**
* Implements hook_config().
*
* Quiz Question triggers a Fatal Error if this function is not present.
* This is a no op.
*/
function opigno_scorm_quiz_question_config() {
// No op
}
/**
* Implements hook_node_type_insert().
*/
function opigno_scorm_quiz_node_type_insert($info) {
if ($info->type == 'opigno_scorm_quiz_question') {
quiz_question_add_body_field('opigno_scorm_quiz_question');
variable_set('node_options_opigno_scorm_quiz_question', array(
'status',
));
// Disable comments by default.
if (module_exists('comment')) {
variable_set('comment_opigno_scorm_quiz_question', COMMENT_NODE_CLOSED);
}
variable_set('node_submitted_opigno_scorm_quiz_question', 0);
$field = field_info_field('opigno_scorm_package');
if (empty($field)) {
field_create_field(array(
'active' => 1,
'cardinality' => 1,
'deleted' => 0,
'entity_types' => array(),
'field_name' => 'opigno_scorm_package',
'foreign keys' => array(
'fid' => array(
'columns' => array(
'fid' => 'fid',
),
'table' => 'file_managed',
),
),
'indexes' => array(
'fid' => array(
0 => 'fid',
),
),
'locked' => 0,
'module' => 'opigno_scorm_ui',
'settings' => array(
'display_default' => 0,
'display_field' => 0,
'uri_scheme' => 'public',
),
'translatable' => 0,
'type' => 'opigno_scorm_package',
));
}
$field = field_info_field('opigno_scorm_round_method');
if (empty($field)) {
field_create_field(array(
'active' => 1,
'cardinality' => 1,
'deleted' => 0,
'entity_types' => array(),
'field_name' => 'opigno_scorm_round_method',
'foreign keys' => array(),
'indexes' => array(
'value' => array(
0 => 'value',
),
),
'locked' => 0,
'module' => 'list',
'settings' => array(
'allowed_values' => array(
'ceil' => 'Round up',
'round' => 'Round to closest',
'floor' => 'Round down',
),
'allowed_values_function' => '',
),
'translatable' => 0,
'type' => 'list_text',
));
}
$instance = field_info_instance('node', 'opigno_scorm_quiz_question', 'opigno_scorm_package');
if (empty($instance)) {
field_create_instance(array(
'bundle' => 'opigno_scorm_quiz_question',
'deleted' => 0,
'description' => '',
'display' => array(
'default' => array(
'label' => 'hidden',
'module' => 'opigno_scorm_ui',
'settings' => array(),
'type' => 'opigno_scorm_player',
'weight' => 0,
),
'teaser' => array(
'label' => 'hidden',
'module' => 'opigno_scorm_ui',
'settings' => array(),
'type' => 'opigno_scorm_player',
'weight' => 0,
),
),
'entity_type' => 'node',
'field_name' => 'opigno_scorm_package',
'label' => 'SCORM',
'required' => 1,
'settings' => array(
'description_field' => 0,
'file_directory' => 'opigno_scorm',
'file_extensions' => 'zip',
'max_filesize' => '',
'user_register_form' => FALSE,
),
'widget' => array(
'active' => 1,
'module' => 'file',
'settings' => array(
'progress_indicator' => 'throbber',
),
'type' => 'file_generic',
'weight' => 32,
),
));
}
$instance = field_info_instance('node', 'opigno_scorm_quiz_question', 'opigno_scorm_round_method');
if (empty($instance)) {
field_create_instance(array(
'bundle' => 'opigno_scorm_quiz_question',
'default_value' => array(
0 => array(
'value' => 'round',
),
),
'deleted' => 0,
'description' => 'Some SCORM packages use a float point number for scoring, whereas we require an integer. Choose the appropriate method for rounding the final score.',
'display' => array(
'default' => array(
'label' => 'above',
'settings' => array(),
'type' => 'hidden',
'weight' => 2,
),
'teaser' => array(
'label' => 'above',
'settings' => array(),
'type' => 'hidden',
'weight' => 0,
),
),
'entity_type' => 'node',
'field_name' => 'opigno_scorm_round_method',
'label' => 'Round method',
'required' => 1,
'settings' => array(
'user_register_form' => FALSE,
),
'widget' => array(
'active' => 1,
'module' => 'options',
'settings' => array(),
'type' => 'options_buttons',
'weight' => 33,
),
));
}
}
}
/**
* Load all objective data for the given SCORM.
*
* Helper function to load objective CMI data that was stored. Pass the ID
* of the objective to fetch the data for it.
*
* @param int $uid
* @param int $scorm_id
* @param string $objective_id
*
* @return object|null
*/
function opigno_scorm_quiz_load_objective($uid, $scorm_id, $objective_id) {
$objectives =& drupal_static(__FUNCTION__);
if (!isset($objectives)) {
// We query the database ourselves here instead of relying on opigno_scorm_scorm_cmi_get(),
// as we need a LIKE query.
$result = db_select('opigno_scorm_scorm_cmi_data', 'o')
->fields('o')
->condition('o.uid', $uid)
->condition('o.scorm_id', $scorm_id)
->condition('o.cmi_key', 'cmi.objectives.%', 'LIKE')
->execute();
while ($row = $result
->fetchObject()) {
// Make sure this is one of ours.
if (preg_match('/^cmi\\.objectives\\.[0-9]+$/', $row->cmi_key)) {
$data = unserialize($row->value);
// Allow modules to alter the data.
$context = array(
'uid' => $uid,
'scorm_id' => $scorm_id,
'original_value' => $data,
);
drupal_alter('opigno_scorm_scorm_cmi_get', $data, $row->cmi_key, $context);
$objectives[$data->id] = $data;
}
}
}
return isset($objectives[$objective_id]) ? $objectives[$objective_id] : NULL;
}
Functions
Name | Description |
---|---|
opigno_scorm_quiz_load_objective | Load all objective data for the given SCORM. |
opigno_scorm_quiz_node_type_insert | Implements hook_node_type_insert(). |
opigno_scorm_quiz_opigno_scorm_ui_add_assets | Implements hook_opigno_scorm_ui_add_assets(). |
opigno_scorm_quiz_opigno_scorm_ui_commit | Implements hook_opigno_scorm_ui_commit(). |
opigno_scorm_quiz_opigno_scorm_ui_register_cmi_data | Implements hook_opigno_scorm_ui_register_cmi_data(). |
opigno_scorm_quiz_opigno_scorm_ui_register_cmi_paths | Implements hook_opigno_scorm_ui_register_cmi_paths(). |
opigno_scorm_quiz_question_config | Implements hook_config(). |
opigno_scorm_quiz_quiz_question_info | Implements of hook_quiz_question_info(). |