function scorm_format_toc_for_treeview($user, $scorm, $scoes, $usertracks, $cmid, $toclink = TOCJSLINK, $currentorg = '', $attempt = '', $play = false, $organizationsco = null, $children = false) { global $CFG; $result = new stdClass(); $result->prerequisites = true; $result->incomplete = true; $result->toc = ''; if (!$children) { $attemptsmade = scorm_get_attempt_count($user->id, $scorm); $result->attemptleft = $scorm->maxattempt == 0 ? 1 : $scorm->maxattempt - $attemptsmade; } if (!$children) { $result->toc = "<ul>\n"; if (!$play && !empty($organizationsco)) { $result->toc .= "\t<li>" . $organizationsco->title . "</li>\n"; } } $prevsco = ''; if (!empty($scoes)) { foreach ($scoes as $sco) { $result->toc .= "\t<li>\n"; $scoid = $sco->id; $sco->isvisible = true; if ($sco->isvisible) { $score = ''; if (isset($usertracks[$sco->identifier])) { $viewscore = has_capability('mod/scorm:viewscores', context_module::instance($cmid)); if (isset($usertracks[$sco->identifier]->score_raw) && $viewscore) { if ($usertracks[$sco->identifier]->score_raw != '') { $score = '(' . get_string('score', 'scorm') . ': ' . $usertracks[$sco->identifier]->score_raw . ')'; } } } if (!empty($sco->prereq)) { if ($sco->id == $scoid) { $result->prerequisites = true; } if (!empty($prevsco) && scorm_version_check($scorm->version, SCORM_13) && !empty($prevsco->hidecontinue)) { if ($sco->scormtype == 'sco') { $result->toc .= '<span>' . $sco->statusicon . ' ' . format_string($sco->title) . '</span>'; } else { $result->toc .= '<span> ' . format_string($sco->title) . '</span>'; } } else { if ($toclink == TOCFULLURL) { $url = $CFG->wwwroot . '/mod/scorm/player.php?' . $sco->url; if (!empty($sco->launch)) { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon . ' <a href="' . $url . '">' . format_string($sco->title) . '</a>' . $score . "\n"; } else { $result->toc .= ' <a data-scoid="' . $sco->id . '" href="' . $url . '">' . format_string($sco->title) . '</a>' . $score . "\n"; } } else { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon . ' ' . format_string($sco->title) . $score . "\n"; } else { $result->toc .= ' ' . format_string($sco->title) . $score . "\n"; } } } else { if (!empty($sco->launch)) { if ($sco->scormtype == 'sco') { $result->toc .= '<a data-scoid="' . $sco->id . '" title="' . $sco->url . '">' . $sco->statusicon . ' ' . format_string($sco->title) . ' ' . $score . '</a>'; } else { $result->toc .= '<a data-scoid="' . $sco->id . '" title="' . $sco->url . '"> ' . format_string($sco->title) . ' ' . $score . '</a>'; } } else { if ($sco->scormtype == 'sco') { $result->toc .= '<span>' . $sco->statusicon . ' ' . format_string($sco->title) . '</span>'; } else { $result->toc .= '<span> ' . format_string($sco->title) . '</span>'; } } } } } else { if ($play) { if ($sco->scormtype == 'sco') { $result->toc .= '<span>' . $sco->statusicon . ' ' . format_string($sco->title) . '</span>'; } else { $result->toc .= ' ' . format_string($sco->title) . '</span>'; } } else { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon . ' ' . format_string($sco->title) . "\n"; } else { $result->toc .= ' ' . format_string($sco->title) . "\n"; } } } } else { $result->toc .= "\t\t " . format_string($sco->title) . "\n"; } if (!empty($sco->children)) { $result->toc .= "\n\t\t<ul>\n"; $childresult = scorm_format_toc_for_treeview($user, $scorm, $sco->children, $usertracks, $cmid, $toclink, $currentorg, $attempt, $play, $organizationsco, true); $result->toc .= $childresult->toc; $result->toc .= "\t\t</ul>\n"; $result->toc .= "\t</li>\n"; } else { $result->toc .= "\t</li>\n"; } $prevsco = $sco; } $result->incomplete = $sco->incomplete; } if (!$children) { $result->toc .= "</ul>\n"; } return $result; }
/** * Return the number of attempts done by a user in the given SCORM. * * @param int $scormid the scorm id * @param int $userid the user id * @param bool $ignoremissingcompletion ignores attempts that haven't reported a grade/completion * @return array of warnings and the attempts count * @since Moodle 3.0 */ public static function get_scorm_attempt_count($scormid, $userid, $ignoremissingcompletion = false) { global $USER, $DB; $params = self::validate_parameters(self::get_scorm_attempt_count_parameters(), array('scormid' => $scormid, 'userid' => $userid, 'ignoremissingcompletion' => $ignoremissingcompletion)); $attempts = array(); $warnings = array(); $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', 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); } // If the SCORM is not open this function will throw exceptions. scorm_require_available($scorm); $attemptscount = scorm_get_attempt_count($user->id, $scorm, false, $params['ignoremissingcompletion']); $result = array(); $result['attemptscount'] = $attemptscount; $result['warnings'] = $warnings; return $result; }
function scorm_get_toc($user,$scorm,$cmid,$toclink=TOCJSLINK,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false, $tocheader=false) { global $CFG, $DB, $PAGE, $OUTPUT; $modestr = ''; if ($mode == 'browse') { $modestr = '&mode='.$mode; } $result = new stdClass(); if ($tocheader) { $result->toc = '<div id="scorm_layout">'; $result->toc .= '<div id="scorm_toc">'; $result->toc .= '<div id="scorm_tree">'; } $result->toc .= '<ul>'; $tocmenus = array(); $result->prerequisites = true; $incomplete = false; // // Get the current organization infos // if (!empty($currentorg)) { if (($organizationtitle = $DB->get_field('scorm_scoes','title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') { if ($play) { $result->toctitle = "$organizationtitle"; } else { $result->toc .= "\t<li>$organizationtitle</li>\n"; } $tocmenus[] = $organizationtitle; } } // // If not specified retrieve the last attempt number // if (empty($attempt)) { $attempt = scorm_get_attempt_count($user->id, $scorm); } $result->attemptleft = $scorm->maxattempt == 0 ? 1 : $scorm->maxattempt - $attempt; if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){ // // Retrieve user tracking data for each learning object // $usertracks = array(); foreach ($scoes as $sco) { if (!empty($sco->launch)) { if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) { if ($usertrack->status == '') { $usertrack->status = 'notattempted'; } $usertracks[$sco->identifier] = $usertrack; } } } $level=0; $sublist=1; $previd = 0; $nextid = 0; $findnext = false; $parents[$level]='/'; $prevsco = ''; foreach ($scoes as $pos => $sco) { $isvisible = false; $sco->title = $sco->title; if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) { $isvisible = true; } if ($parents[$level] != $sco->parent) { if ($newlevel = array_search($sco->parent,$parents)) { for ($i=0; $i<($level-$newlevel); $i++) { $result->toc .= "\t\t</li></ul></li>\n"; } $level = $newlevel; } else { $i = $level; $closelist = ''; while (($i > 0) && ($parents[$level] != $sco->parent)) { if ($i === 1 && $level > 1) { $closelist .= "\t\t</ul></li>\n"; } else { $closelist .= "\t</li></ul></li>\n"; } $i--; } if (($i == 0) && ($sco->parent != $currentorg)) { $result->toc .= "\n\t<ul>\n"; $level++; } else { $result->toc .= $closelist; $level = $i; } $parents[$level] = $sco->parent; } } if ($isvisible) { $result->toc .= "<li>"; } if (isset($scoes[$pos+1])) { $nextsco = $scoes[$pos+1]; } else { $nextsco = false; } $nextisvisible = false; if (($nextsco !== false) && (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true')))) { $nextisvisible = true; } if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) { $sublist++; } if (empty($sco->title)) { $sco->title = $sco->identifier; } if ($isvisible) { if (!empty($sco->launch)) { $score = ''; if (empty($scoid) && ($mode != 'normal')) { $scoid = $sco->id; } if (isset($usertracks[$sco->identifier])) { $usertrack = $usertracks[$sco->identifier]; $strstatus = get_string($usertrack->status,'scorm'); if ($sco->scormtype == 'sco') { $statusicon = '<img src="'.$OUTPUT->pix_url($usertrack->status, 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" />'; } else { $statusicon = '<img src="'.$OUTPUT->pix_url('assetc', 'scorm').'" alt="'.get_string('assetlaunched','scorm').'" title="'.get_string('assetlaunched','scorm').'" />'; } if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) { $incomplete = true; if ($play && empty($scoid)) { $scoid = $sco->id; } } if ($usertrack->score_raw != '' && has_capability('mod/scorm:viewscores', get_context_instance(CONTEXT_MODULE,$cmid))) { $score = '('.get_string('score','scorm').': '.$usertrack->score_raw.')'; } $strsuspended = get_string('suspended','scorm'); $exitvar = 'cmi.core.exit'; if (scorm_version_check($scorm->version, SCORM_13)) { $exitvar = 'cmi.exit'; } if ($incomplete && isset($usertrack->{$exitvar}) && ($usertrack->{$exitvar} == 'suspend')) { $statusicon = '<img src="'.$OUTPUT->pix_url('suspend', 'scorm').'" alt="'.$strstatus.' - '.$strsuspended.'" title="'.$strstatus.' - '.$strsuspended.'" />'; } } else { if ($play && empty($scoid)) { $scoid = $sco->id; } $incomplete = true; if ($sco->scormtype == 'sco') { $statusicon = '<img src="'.$OUTPUT->pix_url('notattempted', 'scorm').'" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />'; } else { $statusicon = '<img src="'.$OUTPUT->pix_url('asset', 'scorm').'" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />'; } } if ($sco->id == $scoid) { $findnext = true; } if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) { if (!empty($sco->launch)) { $previd = $sco->id; } } if (scorm_version_check($scorm->version, SCORM_13)) { require_once($CFG->dirroot.'/mod/scorm/datamodels/sequencinglib.php'); $prereq = scorm_seq_evaluate($sco->id,$usertracks); } else { //TODO: split check for sco->prerequisites only for AICC as I think that's the only case it's set. $prereq = empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks); } if ($prereq) { if ($sco->id == $scoid) { $result->prerequisites = true; } if (!empty($prevsco) && scorm_version_check($scorm->version, SCORM_13) && !empty($prevsco->hidecontinue)) { $result->toc .= '<span>'.$statusicon.' '.format_string($sco->title).'</span>'; } else if ($toclink == TOCFULLURL) { //display toc with urls for structure page $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr.'&scoid='.$sco->id; $result->toc .= $statusicon.' <a href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n"; } else { //display toc for inside scorm player if ($sco->launch) { $link = 'a='.$scorm->id.'&scoid='.$sco->id.'¤torg='.$currentorg.$modestr.'&attempt='.$attempt; $result->toc .= '<a title="'.$link.'">'.$statusicon.' '.format_string($sco->title).' '.$score.'</a>'; } else { $result->toc .= '<span>'.$statusicon.' '.format_string($sco->title).'</span>'; } } $tocmenus[$sco->id] = scorm_repeater('−',$level) . '>' . format_string($sco->title); } else { if ($sco->id == $scoid) { $result->prerequisites = false; } if ($play) { // should be disabled $result->toc .= '<span>'.$statusicon.' '.format_string($sco->title).'</span>'; } else { $result->toc .= $statusicon.' '.format_string($sco->title)."\n"; } } } else { $result->toc .= ' '.format_string($sco->title); } if (($nextsco === false) || $nextsco->parent == $sco->parent) { $result->toc .= "</li>\n"; } } if (($nextsco !== false) && ($nextid == 0) && ($findnext)) { if (!empty($nextsco->launch)) { $nextid = $nextsco->id; } } $prevsco = $sco; } for ($i=0;$i<$level;$i++) { $result->toc .= "\t\t</ul></li>\n"; } if ($play) { // it is possible that $scoid is still not set, in this case we don't want an empty object if ($scoid) { $sco = scorm_get_sco($scoid); } $sco->previd = $previd; $sco->nextid = $nextid; $result->sco = $sco; $result->incomplete = $incomplete; } else { $result->incomplete = $incomplete; } } $result->toc .= '</ul>'; // NEW IMS TOC if ($tocheader) { $result->toc .= '</div></div></div>'; $result->toc .= '<div id="scorm_navpanel"></div>'; } $url = new moodle_url('/mod/scorm/player.php?a='.$scorm->id.'¤torg='.$currentorg.$modestr); $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenus, $sco->id, null, "tocmenu"); return $result; }
function scorm_format_toc_for_treeview($user, $scorm, $scoes, $usertracks, $cmid, $toclink=TOCJSLINK, $currentorg='', $attempt='', $play=false, $organizationsco=null, $children=false) { global $CFG; $result = new stdClass(); $result->prerequisites = true; $result->incomplete = true; $result->toc = ''; if (!$children) { $attemptsmade = scorm_get_attempt_count($user->id, $scorm); $result->attemptleft = $scorm->maxattempt == 0 ? 1 : $scorm->maxattempt - $attemptsmade; } if (!$children) { $result->toc = html_writer::start_tag('ul'); if (!$play && !empty($organizationsco)) { $result->toc .= html_writer::start_tag('li').$organizationsco->title.html_writer::end_tag('li'); } } $prevsco = ''; if (!empty($scoes)) { foreach ($scoes as $sco) { $result->toc .= html_writer::start_tag('li'); $scoid = $sco->id; $sco->isvisible = true; if ($sco->isvisible) { $score = ''; if (isset($usertracks[$sco->identifier])) { $viewscore = has_capability('mod/scorm:viewscores', context_module::instance($cmid)); if (isset($usertracks[$sco->identifier]->score_raw) && $viewscore) { if ($usertracks[$sco->identifier]->score_raw != '') { $score = '('.get_string('score', 'scorm').': '.$usertracks[$sco->identifier]->score_raw.')'; } } } if (!empty($sco->prereq)) { if ($sco->id == $scoid) { $result->prerequisites = true; } if (!empty($prevsco) && scorm_version_check($scorm->version, SCORM_13) && !empty($prevsco->hidecontinue)) { if ($sco->scormtype == 'sco') { $result->toc .= html_writer::span($sco->statusicon.' '.format_string($sco->title)); } else { $result->toc .= html_writer::span(' '.format_string($sco->title)); } } else if ($toclink == TOCFULLURL) { $url = $CFG->wwwroot.'/mod/scorm/player.php?'.$sco->url; if (!empty($sco->launch)) { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon.' '; $result->toc .= html_writer::link($url, format_string($sco->title)).$score; } else { $result->toc .= ' '.html_writer::link($url, format_string($sco->title), array('data-scoid' => $sco->id)).$score; } } else { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon.' '.format_string($sco->title).$score; } else { $result->toc .= ' '.format_string($sco->title).$score; } } } else { if (!empty($sco->launch)) { if ($sco->scormtype == 'sco') { $result->toc .= html_writer::tag('a', $sco->statusicon.' '. format_string($sco->title).' '.$score, array('data-scoid' => $sco->id, 'title' => $sco->url)); } else { $result->toc .= html_writer::tag('a', ' '.format_string($sco->title).' '.$score, array('data-scoid' => $sco->id, 'title' => $sco->url)); } } else { if ($sco->scormtype == 'sco') { $result->toc .= html_writer::span($sco->statusicon.' '.format_string($sco->title)); } else { $result->toc .= html_writer::span(' '.format_string($sco->title)); } } } } else { if ($play) { if ($sco->scormtype == 'sco') { $result->toc .= html_writer::span($sco->statusicon.' '.format_string($sco->title)); } else { $result->toc .= ' '.format_string($sco->title).html_writer::end_span(); } } else { if ($sco->scormtype == 'sco') { $result->toc .= $sco->statusicon.' '.format_string($sco->title); } else { $result->toc .= ' '.format_string($sco->title); } } } } else { $result->toc .= " ".format_string($sco->title); } if (!empty($sco->children)) { $result->toc .= html_writer::start_tag('ul'); $childresult = scorm_format_toc_for_treeview($user, $scorm, $sco->children, $usertracks, $cmid, $toclink, $currentorg, $attempt, $play, $organizationsco, true); $result->toc .= $childresult->toc; $result->toc .= html_writer::end_tag('ul'); $result->toc .= html_writer::end_tag('li'); } else { $result->toc .= html_writer::end_tag('li'); } $prevsco = $sco; } $result->incomplete = $sco->incomplete; } if (!$children) { $result->toc .= html_writer::end_tag('ul'); } return $result; }
/** * Generate the user attempt status string * * @param object $user Current context user * @param object $scorm a moodle scrom object - mdl_scorm * @return string - Attempt status string */ function scorm_get_attempt_status($user, $scorm) { global $DB; $attempts = scorm_get_attempt_count($user->id, $scorm, true); if(empty($attempts)) { $attemptcount = 0; } else { $attemptcount = count($attempts); } $result = '<p>'.get_string('noattemptsallowed', 'scorm').': '; if ($scorm->maxattempt > 0) { $result .= $scorm->maxattempt . '<BR>'; } else { $result .= get_string('unlimited').'<BR>'; } $result .= get_string('noattemptsmade', 'scorm').': ' . $attemptcount . '<BR>'; if ($scorm->maxattempt == 1) { switch ($scorm->grademethod) { case GRADEHIGHEST: $grademethod = get_string('gradehighest', 'scorm'); break; case GRADEAVERAGE: $grademethod = get_string('gradeaverage', 'scorm'); break; case GRADESUM: $grademethod = get_string('gradesum', 'scorm'); break; case GRADESCOES: $grademethod = get_string('gradescoes', 'scorm'); break; } } else { switch ($scorm->whatgrade) { case HIGHESTATTEMPT: $grademethod = get_string('highestattempt', 'scorm'); break; case AVERAGEATTEMPT: $grademethod = get_string('averageattempt', 'scorm'); break; case FIRSTATTEMPT: $grademethod = get_string('firstattempt', 'scorm'); break; case LASTATTEMPT: $grademethod = get_string('lastattempt', 'scorm'); break; } } if(!empty($attempts)) { $i = 1; foreach($attempts as $attempt) { $gradereported = scorm_grade_user_attempt($scorm, $user->id, $attempt->attemptnumber); $result .= get_string('gradeforattempt', 'scorm').' ' . $i . ': ' . $gradereported .'%<BR>'; $i++; } } $calculatedgrade = scorm_grade_user($scorm, $user->id); $result .= get_string('grademethod', 'scorm'). ': ' . $grademethod; if(empty($attempts)) { $result .= '<BR>' . get_string('gradereported','scorm') . ': ' . get_string('none') . '<BR>'; } else { $result .= '<BR>' . get_string('gradereported','scorm') . ': ' . $calculatedgrade . ($scorm->grademethod == GRADESCOES ? '' : '%') .'<BR>'; } $result .= '</p>'; if ($attemptcount >= $scorm->maxattempt and $scorm->maxattempt > 0) { $result .= '<p><font color="#cc0000">'.get_string('exceededmaxattempts','scorm').'</font></p>'; } return $result; }
function scorm_get_toc($user, $scorm, $cmid, $toclink=TOCJSLINK, $currentorg='', $scoid='', $mode='normal', $attempt='', $play=false, $tocheader=false) { global $CFG, $DB, $OUTPUT; if (empty($attempt)) { $attempt = scorm_get_attempt_count($user->id, $scorm); } $result = new stdClass(); $organizationsco = null; if ($tocheader) { $result->toc = "<div id=\"scorm_layout\">\n"; $result->toc .= "<div id=\"scorm_toc\">\n"; $result->toc .= "<div id=\"scorm_tree\">\n"; } if (!empty($currentorg)) { $organizationsco = $DB->get_record('scorm_scoes', array('scorm'=>$scorm->id, 'identifier'=>$currentorg)); if (!empty($organizationsco->title)) { if ($play) { $result->toctitle = $organizationsco->title; } } } $scoes = scorm_get_toc_object($user, $scorm, $currentorg, $scoid, $mode, $attempt, $play, $organizationsco); $treeview = scorm_format_toc_for_treeview($user, $scorm, $scoes['scoes'][0]->children, $scoes['usertracks'], $cmid, $toclink, $currentorg, $attempt, $play, $organizationsco, false); if ($tocheader) { $result->toc .= $treeview->toc; } else { $result->toc = $treeview->toc; } if (!empty($scoes['scoid'])) { $scoid = $scoes['scoid']; } if (empty($scoid)) { $result->sco = $scoes['scoes'][0]->children[0]; } else { $result->sco = scorm_get_sco($scoid); } if ($scorm->hidetoc == SCORM_TOC_POPUP) { $tocmenu = scorm_format_toc_for_droplist($scorm, $scoes['scoes'][0]->children, $scoes['usertracks'], $currentorg, $organizationsco); $modestr = ''; if ($mode == 'browse') { $modestr = '&mode='.$mode; } $url = new moodle_url('/mod/scorm/player.php?a='.$scorm->id.'¤torg='.$currentorg.$modestr); $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenu, $result->sco->id, null, "tocmenu"); } $result->prerequisites = $treeview->prerequisites; $result->incomplete = $treeview->incomplete; $result->attemptleft = $treeview->attemptleft; if ($tocheader) { $result->toc .= "</div></div></div>\n"; $result->toc .= "<div id=\"scorm_navpanel\"></div>\n"; } return $result; }
function scorm_view_display($user, $scorm, $action, $cm, $boxwidth = '') { global $CFG, $DB; if ($scorm->updatefreq == UPDATE_EVERYTIME) { scorm_parse($scorm, false); } $organization = optional_param('organization', '', PARAM_INT); if ($scorm->displaycoursestructure == 1) { print_simple_box_start('center', $boxwidth); ?> <div class="structurehead"><?php print_string('contents', 'scorm'); ?> </div> <?php } if (empty($organization)) { $organization = $scorm->launch; } if ($orgs = $DB->get_records_menu('scorm_scoes', array('scorm' => $scorm->id, 'organization' => '', 'launch' => ''), 'id', 'id,title')) { if (count($orgs) > 1) { ?> <div class='scorm-center'> <?php print_string('organizations', 'scorm'); ?> <form id='changeorg' method='post' action='<?php echo $action; ?> '> <?php choose_from_menu($orgs, 'organization', "{$organization}", '', 'submit()'); ?> </form> </div> <?php } } $orgidentifier = ''; if ($sco = scorm_get_sco($organization, SCO_ONLY)) { if ($sco->organization == '' && $sco->launch == '') { $orgidentifier = $sco->identifier; } else { $orgidentifier = $sco->organization; } } /* $orgidentifier = ''; if ($org = $DB->get_record('scorm_scoes', array('id'=>$organization))) { if (($org->organization == '') && ($org->launch == '')) { $orgidentifier = $org->identifier; } else { $orgidentifier = $org->organization; } }*/ $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR)); // Just to be safe if (!file_exists($CFG->dirroot . '/mod/scorm/datamodels/' . $scorm->version . 'lib.php')) { $scorm->version = 'scorm_12'; } require_once $CFG->dirroot . '/mod/scorm/datamodels/' . $scorm->version . 'lib.php'; $result = scorm_get_toc($user, $scorm, 'structlist', $orgidentifier); $incomplete = $result->incomplete; // do we want the TOC to be displayed? if ($scorm->displaycoursestructure == 1) { echo $result->toc; print_simple_box_end(); } // is this the first attempt ? $attemptcount = scorm_get_attempt_count($user, $scorm); // do not give the player launch FORM if the SCORM object is locked after the final attempt if ($scorm->lastattemptlock == 0 || $result->attemptleft > 0) { ?> <div class="scorm-center"> <form id="theform" method="post" action="<?php echo $CFG->wwwroot; ?> /mod/scorm/player.php"> <?php if ($scorm->hidebrowse == 0) { print_string('mode', 'scorm'); echo ': <input type="radio" id="b" name="mode" value="browse" /><label for="b">' . get_string('browse', 'scorm') . '</label>' . "\n"; echo '<input type="radio" id="n" name="mode" value="normal" checked="checked" /><label for="n">' . get_string('normal', 'scorm') . "</label>\n"; } else { echo '<input type="hidden" name="mode" value="normal" />' . "\n"; } if ($scorm->forcenewattempt == 1) { if ($incomplete === false) { echo '<input type="hidden" name="newattempt" value="on" />' . "\n"; } } elseif ($attemptcount != 0 && $incomplete === false && ($result->attemptleft > 0 || $scorm->maxattempt == 0)) { ?> <br /> <input type="checkbox" id="a" name="newattempt" /> <label for="a"><?php print_string('newattempt', 'scorm'); ?> </label> <?php } ?> <br /> <input type="hidden" name="scoid"/> <input type="hidden" name="id" value="<?php echo $cm->id; ?> "/> <input type="hidden" name="currentorg" value="<?php echo $orgidentifier; ?> " /> <input type="submit" value="<?php print_string('enter', 'scorm'); ?> " /> </form> </div> <?php } }
function scorm_get_toc($user, $scorm, $liststyle, $currentorg = '', $scoid = '', $mode = 'normal', $attempt = '', $play = false, $tocheader = false) { global $CFG, $DB, $PAGE, $OUTPUT; $strexpand = get_string('expcoll', 'scorm'); $modestr = ''; if ($mode == 'browse') { $modestr = '&mode=' . $mode; } $result = new stdClass(); //$result->toc = "<ul id='s0' class='$liststyle'>\n"; if ($tocheader) { $result->toc = '<div id="scorm_layout">'; $result->toc .= '<div id="scorm_toc">'; $result->toc .= '<div id="scorm_tree">'; } $result->toc .= '<ul>'; $tocmenus = array(); $result->prerequisites = true; $incomplete = false; // // Get the current organization infos // if (!empty($currentorg)) { if (($organizationtitle = $DB->get_field('scorm_scoes', 'title', array('scorm' => $scorm->id, 'identifier' => $currentorg))) != '') { if ($play) { $result->toctitle = "{$organizationtitle}"; } else { $result->toc .= "\t<li>{$organizationtitle}</li>\n"; } $tocmenus[] = $organizationtitle; } } // // If not specified retrieve the last attempt number // if (empty($attempt)) { $attempt = scorm_get_attempt_count($user->id, $scorm); } $result->attemptleft = $scorm->maxattempt == 0 ? 1 : $scorm->maxattempt - $attempt; $conditions['scorm'] = $scorm->id; if ($scoes = scorm_get_scoes($scorm->id, $currentorg)) { // // Retrieve user tracking data for each learning object // $usertracks = array(); foreach ($scoes as $sco) { if (!empty($sco->launch)) { if ($usertrack = scorm_get_tracks($sco->id, $user->id, $attempt)) { if ($usertrack->status == '') { $usertrack->status = 'notattempted'; } $usertracks[$sco->identifier] = $usertrack; } } } $level = 0; $sublist = 1; $previd = 0; $nextid = 0; $findnext = false; $parents[$level] = '/'; foreach ($scoes as $pos => $sco) { $isvisible = false; $sco->title = $sco->title; if (!isset($sco->isvisible) || isset($sco->isvisible) && $sco->isvisible == 'true') { $isvisible = true; } if ($parents[$level] != $sco->parent) { if ($newlevel = array_search($sco->parent, $parents)) { for ($i = 0; $i < $level - $newlevel; $i++) { $result->toc .= "\t\t</li></ul></li>\n"; } $level = $newlevel; } else { $i = $level; $closelist = ''; while ($i > 0 && $parents[$level] != $sco->parent) { $closelist .= "\t\t</li></ul></li>\n"; $i--; } if ($i == 0 && $sco->parent != $currentorg) { $style = ''; if (isset($_COOKIE['hide:SCORMitem' . $sco->id])) { $style = ' style="display: none;"'; } //$result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n"; $result->toc .= "\t\t<ul>\n"; $level++; } else { $result->toc .= $closelist; $level = $i; } $parents[$level] = $sco->parent; } } if ($isvisible) { $result->toc .= "<li>"; } if (isset($scoes[$pos + 1])) { $nextsco = $scoes[$pos + 1]; } else { $nextsco = false; } $nextisvisible = false; if ($nextsco !== false && (!isset($nextsco->isvisible) || isset($nextsco->isvisible) && $nextsco->isvisible == 'true')) { $nextisvisible = true; } if ($nextisvisible && $nextsco !== false && $sco->parent != $nextsco->parent && ($level == 0 || $level > 0 && $nextsco->parent == $sco->identifier)) { $sublist++; $icon = 'minus'; if (isset($_COOKIE['hide:SCORMitem' . $nextsco->id])) { $icon = 'plus'; } //$result->toc .= '<a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>'; } else { if ($isvisible) { //$result->toc .= '<img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />'; } } if (empty($sco->title)) { $sco->title = $sco->identifier; } if (!empty($sco->launch)) { if ($isvisible) { $startbold = ''; $endbold = ''; $score = ''; if (empty($scoid) && $mode != 'normal') { $scoid = $sco->id; } if (isset($usertracks[$sco->identifier])) { $usertrack = $usertracks[$sco->identifier]; $strstatus = get_string($usertrack->status, 'scorm'); if ($sco->scormtype == 'sco') { $statusicon = '<img src="' . $OUTPUT->pix_url($usertrack->status, 'scorm') . '" alt="' . $strstatus . '" title="' . $strstatus . '" />'; } else { $statusicon = '<img src="' . $OUTPUT->pix_url('assetc', 'scorm') . '" alt="' . get_string('assetlaunched', 'scorm') . '" title="' . get_string('assetlaunched', 'scorm') . '" />'; } if ($usertrack->status == 'notattempted' || $usertrack->status == 'incomplete' || $usertrack->status == 'browsed') { $incomplete = true; if ($play && empty($scoid)) { $scoid = $sco->id; } } if ($usertrack->score_raw != '') { $score = '(' . get_string('score', 'scorm') . ': ' . $usertrack->score_raw . ')'; } $strsuspended = get_string('suspended', 'scorm'); if ($incomplete && isset($usertrack->{'cmi.core.exit'}) && $usertrack->{'cmi.core.exit'} == 'suspend') { $statusicon = '<img src="' . $OUTPUT->pix_url('suspend', 'scorm') . '" alt="' . $strstatus . ' - ' . $strsuspended . '" title="' . $strstatus . ' - ' . $strsuspended . '" />'; } } else { if ($play && empty($scoid)) { $scoid = $sco->id; } $incomplete = true; if ($sco->scormtype == 'sco') { $statusicon = '<img src="' . $OUTPUT->pix_url('notattempted', 'scorm') . '" alt="' . get_string('notattempted', 'scorm') . '" title="' . get_string('notattempted', 'scorm') . '" />'; } else { $statusicon = '<img src="' . $OUTPUT->pix_url('asset', 'scorm') . '" alt="' . get_string('asset', 'scorm') . '" title="' . get_string('asset', 'scorm') . '" />'; } } if ($sco->id == $scoid) { $startbold = '<b>'; $endbold = '</b>'; $findnext = true; $shownext = isset($sco->next) ? $sco->next : 0; $showprev = isset($sco->previous) ? $sco->previous : 0; } if ($nextid == 0 && scorm_count_launchable($scorm->id, $currentorg) > 1 && $nextsco !== false && !$findnext) { if (!empty($sco->launch)) { $previd = $sco->id; } } if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites, $usertracks)) { if ($sco->id == $scoid) { $result->prerequisites = true; } // $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr.'&scoid='.$sco->id; $thisscoidstr = '&scoid=' . $sco->id; //$link = $CFG->wwwroot.'/mod/scorm/loadSCO.php?a='.$scorm->id.$thisscoidstr.$modestr; $link = 'a=' . $scorm->id . $thisscoidstr . '¤torg=' . $currentorg . $modestr . '&attempt=' . $attempt; //$result->toc .= $statusicon.' '.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."\n"; //$result->toc .= $startbold.'<a title="'.$link.'">'.$statusicon.' '.format_string($sco->title).' '.$score.'</a>'.$endbold."\n"; if ($sco->launch) { $result->toc .= '<a title="' . $link . '">' . $statusicon . ' ' . format_string($sco->title) . ' ' . $score . '</a>'; } else { $result->toc .= '<span>' . $statusicon . ' ' . format_string($sco->title) . '</span>'; } $tocmenus[$sco->id] = scorm_repeater('−', $level) . '>' . format_string($sco->title); } else { if ($sco->id == $scoid) { $result->prerequisites = false; } if ($play) { // should be disabled $result->toc .= '<span>' . $statusicon . ' ' . format_string($sco->title) . '</span>'; } else { $result->toc .= $statusicon . ' ' . format_string($sco->title) . "\n"; } } if ($nextsco === false || $nextsco->parent == $sco->parent) { $result->toc .= '</li>'; } } } else { $result->toc .= ' ' . format_string($sco->title) . "\n"; } if ($nextsco !== false && $nextid == 0 && $findnext) { if (!empty($nextsco->launch)) { $nextid = $nextsco->id; } } } for ($i = 0; $i < $level; $i++) { $result->toc .= "\t\t</ul></li>\n"; } if ($play) { // it is possible that scoid is still not set, in this case we dont want an empty object if ($scoid) { $sco = scorm_get_sco($scoid); } $sco->previd = $previd; $sco->nextid = $nextid; $result->sco = $sco; $result->incomplete = $incomplete; } else { $result->incomplete = $incomplete; } } $result->toc .= '</ul>'; // NEW IMS TOC if ($tocheader) { $result->toc .= '</div></div></div>'; $result->toc .= '<div id="scorm_navpanel"></div>'; } if ($scorm->hidetoc == 0) { $PAGE->requires->data_for_js('scormdata', array('plusicon' => $OUTPUT->pix_url('plus', 'scorm'), 'minusicon' => $OUTPUT->pix_url('minus', 'scorm'))); $PAGE->requires->js('/lib/cookies.js'); $PAGE->requires->js('/mod/scorm/datamodels/scorm_datamodels.js'); } $url = new moodle_url('/mod/scorm/player.php?a=' . $scorm->id . '¤torg=' . $currentorg . $modestr); $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenus, $sco->id, null, "tocmenu"); return $result; }