Merge branch 'm20_MDL-26176_cleanup' of github.com:danmarsden/moodle
[moodle.git] / mod / scorm / datamodels / aicclib.php
CommitLineData
e5dd8e3b 1<?php
e23cc5d2 2
dc383b6f 3function scorm_add_time($a, $b) {
4 $aes = explode(':',$a);
5 $bes = explode(':',$b);
6 $aseconds = explode('.',$aes[2]);
7 $bseconds = explode('.',$bes[2]);
8 $change = 0;
9
10 $acents = 0; //Cents
11 if (count($aseconds) > 1) {
12 $acents = $aseconds[1];
13 }
14 $bcents = 0;
15 if (count($bseconds) > 1) {
16 $bcents = $bseconds[1];
17 }
18 $cents = $acents + $bcents;
19 $change = floor($cents / 100);
20 $cents = $cents - ($change * 100);
21 if (floor($cents) < 10) {
22 $cents = '0'. $cents;
23 }
24
25 $secs = $aseconds[0] + $bseconds[0] + $change; //Seconds
26 $change = floor($secs / 60);
27 $secs = $secs - ($change * 60);
28 if (floor($secs) < 10) {
29 $secs = '0'. $secs;
30 }
31
32 $mins = $aes[1] + $bes[1] + $change; //Minutes
33 $change = floor($mins / 60);
34 $mins = $mins - ($change * 60);
35 if ($mins < 10) {
36 $mins = '0' . $mins;
37 }
38
39 $hours = $aes[0] + $bes[0] + $change; //Hours
40 if ($hours < 10) {
41 $hours = '0' . $hours;
42 }
43
44 if ($cents != '0') {
45 return $hours . ":" . $mins . ":" . $secs . '.' . $cents;
46 } else {
47 return $hours . ":" . $mins . ":" . $secs;
48 }
49}
50
51/**
52* Take the header row of an AICC definition file
53* and returns sequence of columns and a pointer to
54* the sco identifier column.
55*
56* @param string $row AICC header row
57* @param string $mastername AICC sco identifier column
58* @return mixed
59*/
60function scorm_get_aicc_columns($row,$mastername='system_id') {
61 $tok = strtok(strtolower($row),"\",\n\r");
39790bd8 62 $result = new stdClass();
dc383b6f 63 $result->columns = array();
64 $i=0;
65 while ($tok) {
66 if ($tok !='') {
67 $result->columns[] = $tok;
68 if ($tok == $mastername) {
69 $result->mastercol = $i;
70 }
71 $i++;
72 }
73 $tok = strtok("\",\n\r");
74 }
75 return $result;
76}
77
78/**
79* Given a colums array return a string containing the regular
80* expression to match the columns in a text row.
81*
82* @param array $column The header columns
83* @param string $remodule The regular expression module for a single column
84* @return string
85*/
86function scorm_forge_cols_regexp($columns,$remodule='(".*")?,') {
87 $regexp = '/^';
88 foreach ($columns as $column) {
89 $regexp .= $remodule;
90 }
91 $regexp = substr($regexp,0,-1) . '/';
92 return $regexp;
93}
94
9528568b 95
96function scorm_parse_aicc($scorm) {
bf347041 97 global $DB;
98
9528568b 99 if (!isset($scorm->cmid)) {
100 $cm = get_coursemodule_from_instance('scorm', $scorm->id);
101 $scorm->cmid = $cm->id;
102 }
e23cc5d2 103 $context = get_context_instance(CONTEXT_MODULE, $scorm->cmid);
9528568b 104
105 $fs = get_file_storage();
106
64f93798 107 $files = $fs->get_area_files($context->id, 'mod_scorm', 'content', 0, '', false);
9528568b 108
109
dc383b6f 110 $version = 'AICC';
111 $ids = array();
112 $courses = array();
113 $extaiccfiles = array('crs','des','au','cst','ort','pre','cmp');
9528568b 114
115 foreach ($files as $file) {
116 $filename = $file->get_filename();
117 $ext = substr($filename,strrpos($filename,'.'));
118 $extension = strtolower(substr($ext,1));
119 if (in_array($extension,$extaiccfiles)) {
120 $id = strtolower(basename($filename,$ext));
121 $ids[$id]->$extension = $file;
dc383b6f 122 }
dc383b6f 123 }
9528568b 124
dc383b6f 125 foreach ($ids as $courseid => $id) {
126 if (isset($id->crs)) {
e23cc5d2 127 $contents = $id->crs->get_content();
128 $rows = explode("\r\n", $contents);
129 if (is_array($rows)) {
130 foreach ($rows as $row) {
131 if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {
132 switch (strtolower(trim($matches[1]))) {
133 case 'course_id':
134 $courses[$courseid]->id = trim($matches[2]);
135 break;
136 case 'course_title':
137 $courses[$courseid]->title = trim($matches[2]);
138 break;
139 case 'version':
140 $courses[$courseid]->version = 'AICC_'.trim($matches[2]);
141 break;
142 }
dc383b6f 143 }
144 }
145 }
146 }
147 if (isset($id->des)) {
e23cc5d2 148 $contents = $id->des->get_content();
149 $rows = explode("\r\n", $contents);
dc383b6f 150 $columns = scorm_get_aicc_columns($rows[0]);
151 $regexp = scorm_forge_cols_regexp($columns->columns);
152 for ($i=1;$i<count($rows);$i++) {
153 if (preg_match($regexp,$rows[$i],$matches)) {
154 for ($j=0;$j<count($columns->columns);$j++) {
155 $column = $columns->columns[$j];
156 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
157 }
158 }
159 }
160 }
161 if (isset($id->au)) {
e23cc5d2 162 $contents = $id->au->get_content();
163 $rows = explode("\r\n", $contents);
dc383b6f 164 $columns = scorm_get_aicc_columns($rows[0]);
165 $regexp = scorm_forge_cols_regexp($columns->columns);
166 for ($i=1;$i<count($rows);$i++) {
167 if (preg_match($regexp,$rows[$i],$matches)) {
168 for ($j=0;$j<count($columns->columns);$j++) {
169 $column = $columns->columns[$j];
170 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
171 }
172 }
173 }
174 }
175 if (isset($id->cst)) {
e23cc5d2 176 $contents = $id->cst->get_content();
177 $rows = explode("\r\n", $contents);
dc383b6f 178 $columns = scorm_get_aicc_columns($rows[0],'block');
179 $regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
180 for ($i=1;$i<count($rows);$i++) {
181 if (preg_match($regexp,$rows[$i],$matches)) {
182 for ($j=0;$j<count($columns->columns);$j++) {
183 if ($j != $columns->mastercol) {
184 $courses[$courseid]->elements[substr(trim($matches[$j+1]),1,-1)]->parent = substr(trim($matches[$columns->mastercol+1]),1,-1);
185 }
186 }
187 }
188 }
189 }
190 if (isset($id->ort)) {
e23cc5d2 191 $contents = $id->ort->get_content();
192 $rows = explode("\r\n", $contents);
f6520280 193 $columns = scorm_get_aicc_columns($rows[0],'course_element');
194 $regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
195 for ($i=1;$i<count($rows);$i++) {
196 if (preg_match($regexp,$rows[$i],$matches)) {
197 for ($j=0;$j<count($matches)-1;$j++) {
198 if ($j != $columns->mastercol) {
199 $courses[$courseid]->elements[substr(trim($matches[$j+1]),1,-1)]->parent = substr(trim($matches[$columns->mastercol+1]),1,-1);
200 }
201 }
202 }
203 }
dc383b6f 204 }
205 if (isset($id->pre)) {
e23cc5d2 206 $contents = $id->pre->get_content();
207 $rows = explode("\r\n", $contents);
dc383b6f 208 $columns = scorm_get_aicc_columns($rows[0],'structure_element');
209 $regexp = scorm_forge_cols_regexp($columns->columns,'(.+),');
210 for ($i=1;$i<count($rows);$i++) {
211 if (preg_match($regexp,$rows[$i],$matches)) {
212 $courses[$courseid]->elements[$columns->mastercol+1]->prerequisites = substr(trim($matches[1-$columns->mastercol+1]),1,-1);
213 }
214 }
215 }
216 if (isset($id->cmp)) {
e23cc5d2 217 $contents = $id->cmp->get_content();
218 $rows = explode("\r\n", $contents);
dc383b6f 219 }
220 }
221 //print_r($courses);
222
9528568b 223 $oldscoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id));
d9e6517a 224
dc383b6f 225 $launch = 0;
226 if (isset($courses)) {
227 foreach ($courses as $course) {
39790bd8 228 $sco = new stdClass();
dc383b6f 229 $sco->identifier = $course->id;
9528568b 230 $sco->scorm = $scorm->id;
dc383b6f 231 $sco->organization = '';
232 $sco->title = $course->title;
233 $sco->parent = '/';
234 $sco->launch = '';
235 $sco->scormtype = '';
236
237 //print_r($sco);
9528568b 238 if ($ss = $DB->get_record('scorm_scoes', array('scorm'=>$scorm->id,'identifier'=>$sco->identifier))) {
bf347041 239 $id = $ss->id;
240 $DB->update_record('scorm_scoes',$sco);
dc383b6f 241 unset($oldscoes[$id]);
242 } else {
bf347041 243 $id = $DB->insert_record('scorm_scoes',$sco);
dc383b6f 244 }
245
246 if ($launch == 0) {
247 $launch = $id;
248 }
249 if (isset($course->elements)) {
250 foreach($course->elements as $element) {
251 unset($sco);
252 $sco->identifier = $element->system_id;
9528568b 253 $sco->scorm = $scorm->id;
dc383b6f 254 $sco->organization = $course->id;
255 $sco->title = $element->title;
d9e6517a 256
f6520280 257 if (!isset($element->parent) || strtolower($element->parent) == 'root') {
dc383b6f 258 $sco->parent = '/';
259 } else {
260 $sco->parent = $element->parent;
261 }
262 if (isset($element->file_name)) {
263 $sco->launch = $element->file_name;
264 $sco->scormtype = 'sco';
f6520280 265 $sco->previous = 0;
266 $sco->next = 0;
267 $id = null;
268 if ($oldscoid = scorm_array_search('identifier',$sco->identifier,$oldscoes)) {
269 $sco->id = $oldscoid;
dd88de0e
PS
270 $DB->update_record('scorm_scoes',$sco);
271 $id = $oldscoid;
bf347041 272 $DB->delete_records('scorm_scoes_data', array('scoid'=>$oldscoid));
f6520280 273 unset($oldscoes[$oldscoid]);
274 } else {
bf347041 275 $id = $DB->insert_record('scorm_scoes',$sco);
f6520280 276 }
277 if (!empty($id)) {
39790bd8 278 $scodata = new stdClass();
f6520280 279 $scodata->scoid = $id;
280 if (isset($element->web_launch)) {
281 $scodata->name = 'parameters';
282 $scodata->value = $element->web_launch;
bf347041 283 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
f6520280 284 }
285 if (isset($element->prerequisites)) {
286 $scodata->name = 'prerequisites';
287 $scodata->value = $element->prerequisites;
bf347041 288 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
f6520280 289 }
290 if (isset($element->max_time_allowed)) {
291 $scodata->name = 'max_time_allowed';
292 $scodata->value = $element->max_time_allowed;
bf347041 293 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
f6520280 294 }
295 if (isset($element->time_limit_action)) {
296 $scodata->name = 'time_limit_action';
297 $scodata->value = $element->time_limit_action;
bf347041 298 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
f6520280 299 }
300 if (isset($element->mastery_score)) {
301 $scodata->name = 'mastery_score';
302 $scodata->value = $element->mastery_score;
bf347041 303 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
f6520280 304 }
52005f34 305 if (isset($element->core_vendor)) {
306 $scodata->name = 'datafromlms';
6dbcacee 307 $scodata->value = preg_replace('/<cr>/i', "\r\n", $element->core_vendor);
c6089d93 308 $dataid = $DB->insert_record('scorm_scoes_data',$scodata);
52005f34 309 }
f6520280 310 }
311 if ($launch==0) {
312 $launch = $id;
313 }
dc383b6f 314 }
315 }
316 }
317 }
318 }
319 if (!empty($oldscoes)) {
320 foreach($oldscoes as $oldsco) {
bf347041 321 $DB->delete_records('scorm_scoes', array('id'=>$oldsco->id));
322 $DB->delete_records('scorm_scoes_track', array('scoid'=>$oldsco->id));
dc383b6f 323 }
324 }
9528568b 325
326 $scorm->version = 'AICC';
327
328 $scorm->launch = $launch;
329
330 return true;
dc383b6f 331}
332
7cc7cf58 333function scorm_get_toc($user,$scorm,$toclink=TOCJSLINK,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false, $tocheader=false) {
d436d197 334 global $CFG, $DB, $PAGE, $OUTPUT;
d9e6517a 335
dc383b6f 336 $modestr = '';
337 if ($mode == 'browse') {
338 $modestr = '&amp;mode='.$mode;
d9e6517a 339 }
d9e6517a 340
dc383b6f 341 $result = new stdClass();
eea0c8ea
PH
342 if ($tocheader) {
343 $result->toc = '<div id="scorm_layout">';
344 $result->toc .= '<div id="scorm_toc">';
345 $result->toc .= '<div id="scorm_tree">';
346 }
347 $result->toc .= '<ul>';
dc383b6f 348 $tocmenus = array();
349 $result->prerequisites = true;
350 $incomplete = false;
d9e6517a 351
dc383b6f 352 //
353 // Get the current organization infos
354 //
dc383b6f 355 if (!empty($currentorg)) {
bf347041 356 if (($organizationtitle = $DB->get_field('scorm_scoes','title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
5c2aa157
DM
357 if ($play) {
358 $result->toctitle = "$organizationtitle";
359 }
360 else {
361 $result->toc .= "\t<li>$organizationtitle</li>\n";
362 }
dc383b6f 363 $tocmenus[] = $organizationtitle;
364 }
dc383b6f 365 }
366 //
367 // If not specified retrieve the last attempt number
368 //
369 if (empty($attempt)) {
370 $attempt = scorm_get_last_attempt($scorm->id, $user->id);
371 }
372 $result->attemptleft = $scorm->maxattempt - $attempt;
82605bea 373 if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
dc383b6f 374 //
375 // Retrieve user tracking data for each learning object
d9e6517a 376 //
dc383b6f 377 $usertracks = array();
378 foreach ($scoes as $sco) {
379 if (!empty($sco->launch)) {
f3f58e0b
DM
380 if (empty($scoid)) {
381 $scoid = $sco->id;
382 }
82605bea 383 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
dc383b6f 384 if ($usertrack->status == '') {
385 $usertrack->status = 'notattempted';
386 }
387 $usertracks[$sco->identifier] = $usertrack;
388 }
389 }
390 }
391
392 $level=0;
393 $sublist=1;
394 $previd = 0;
395 $nextid = 0;
396 $findnext = false;
397 $parents[$level]='/';
d9e6517a 398
82605bea 399 foreach ($scoes as $pos => $sco) {
f6520280 400 $isvisible = false;
bf347041 401 $sco->title = $sco->title;
82605bea 402 if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
403 $isvisible = true;
f6520280 404 }
dc383b6f 405 if ($parents[$level]!=$sco->parent) {
406 if ($newlevel = array_search($sco->parent,$parents)) {
407 for ($i=0; $i<($level-$newlevel); $i++) {
eea0c8ea 408 $result->toc .= "\t\t</li></ul></li>\n";
dc383b6f 409 }
410 $level = $newlevel;
411 } else {
412 $i = $level;
413 $closelist = '';
414 while (($i > 0) && ($parents[$level] != $sco->parent)) {
eea0c8ea 415 $closelist .= "\t\t</li></ul></li>\n";
dc383b6f 416 $i--;
417 }
418 if (($i == 0) && ($sco->parent != $currentorg)) {
5c2aa157 419 $result->toc .= "\t\t<ul>\n";
dc383b6f 420 $level++;
421 } else {
422 $result->toc .= $closelist;
423 $level = $i;
424 }
425 $parents[$level]=$sco->parent;
426 }
427 }
f6520280 428 if ($isvisible) {
429 $result->toc .= "\t\t<li>";
430 }
9fb2de4e 431 if (isset($scoes[$pos+1])) {
432 $nextsco = $scoes[$pos+1];
433 } else {
434 $nextsco = false;
435 }
f6520280 436 $nextisvisible = false;
82605bea 437 if (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true'))) {
438 $nextisvisible = true;
f6520280 439 }
440 if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
dc383b6f 441 $sublist++;
dc383b6f 442 }
443 if (empty($sco->title)) {
444 $sco->title = $sco->identifier;
445 }
446 if (!empty($sco->launch)) {
f6520280 447 if ($isvisible) {
f6520280 448 $score = '';
449 if (empty($scoid) && ($mode != 'normal')) {
450 $scoid = $sco->id;
530a61d5 451 }
f6520280 452 if (isset($usertracks[$sco->identifier])) {
453 $usertrack = $usertracks[$sco->identifier];
454 $strstatus = get_string($usertrack->status,'scorm');
455 if ($sco->scormtype == 'sco') {
485f4ce6 456 $statusicon = '<img src="'.$OUTPUT->pix_url($usertrack->status, 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" />';
f6520280 457 } else {
485f4ce6 458 $statusicon = '<img src="'.$OUTPUT->pix_url('assetc', 'scorm').'" alt="'.get_string('assetlaunched','scorm').'" title="'.get_string('assetlaunched','scorm').'" />';
f6520280 459 }
d9e6517a 460
f6520280 461 if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {
462 $incomplete = true;
463 if ($play && empty($scoid)) {
464 $scoid = $sco->id;
465 }
466 }
467 if ($usertrack->score_raw != '') {
468 $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';
469 }
470 $strsuspended = get_string('suspended','scorm');
946b6f0d 471 if ($incomplete && isset($usertrack->{'cmi.core.exit'}) && ($usertrack->{'cmi.core.exit'} == 'suspend')) {
485f4ce6 472 $statusicon = '<img src="'.$OUTPUT->pix_url('suspend', 'scorm').'" alt="'.$strstatus.' - '.$strsuspended.'" title="'.$strstatus.' - '.$strsuspended.'" />';
f6520280 473 }
474 } else {
dc383b6f 475 if ($play && empty($scoid)) {
476 $scoid = $sco->id;
477 }
f6520280 478 $incomplete = true;
479 if ($sco->scormtype == 'sco') {
485f4ce6 480 $statusicon = '<img src="'.$OUTPUT->pix_url('notattempted', 'scorm').'" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
f6520280 481 } else {
485f4ce6 482 $statusicon = '<img src="'.$OUTPUT->pix_url('asset', 'scorm').'" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
f6520280 483 }
530a61d5 484 }
f6520280 485 if ($sco->id == $scoid) {
f6520280 486 $findnext = true;
dc383b6f 487 }
d9e6517a 488
f6520280 489 if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
490 if (!empty($sco->launch)) {
491 $previd = $sco->id;
492 }
dc383b6f 493 }
f6520280 494 if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks)) {
495 if ($sco->id == $scoid) {
496 $result->prerequisites = true;
497 }
7cc7cf58 498
5c2aa157 499 $thisscoidstr = '&scoid='.$sco->id;
821aa03d 500 $link = 'a='.$scorm->id.$thisscoidstr.'&currentorg='.$currentorg.$modestr.'&attempt='.$attempt;
7cc7cf58
DM
501
502 if ($toclink == TOCFULLURL) { //display toc with urls for structure page
503 $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
504 $result->toc .= $statusicon.'&nbsp;<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n";
505 } else {
506 if ($sco->launch) {
507 $result->toc .= '<a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
508 } else {
509 $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
510 }
eea0c8ea 511 }
f6520280 512 $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
513 } else {
514 if ($sco->id == $scoid) {
515 $result->prerequisites = false;
516 }
eea0c8ea
PH
517 if ($play) {
518 // should be disabled
519 $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
39340358 520 } else {
eea0c8ea
PH
521 $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."\n";
522 }
523 }
524 if (($nextsco === false) || $nextsco->parent == $sco->parent) {
525 $result->toc .= '</li>';
dc383b6f 526 }
dc383b6f 527 }
528 } else {
c852a628 529 $result->toc .= '&nbsp;'.format_string($sco->title)."</li>\n";
dc383b6f 530 }
531 if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
532 if (!empty($nextsco->launch)) {
533 $nextid = $nextsco->id;
534 }
535 }
536 }
537 for ($i=0;$i<$level;$i++) {
538 $result->toc .= "\t\t</ul></li>\n";
539 }
d9e6517a 540
dc383b6f 541 if ($play) {
f6520280 542 $sco = scorm_get_sco($scoid);
dc383b6f 543 $sco->previd = $previd;
544 $sco->nextid = $nextid;
545 $result->sco = $sco;
546 $result->incomplete = $incomplete;
547 } else {
548 $result->incomplete = $incomplete;
549 }
550 }
eea0c8ea 551 $result->toc .= '</ul>';
5c2aa157
DM
552
553 // NEW IMS TOC
eea0c8ea
PH
554 if ($tocheader) {
555 $result->toc .= '</div></div></div>';
556 $result->toc .= '<div id="scorm_navpanel"></div>';
557 }
5c2aa157
DM
558
559
dc383b6f 560 if ($scorm->hidetoc == 0) {
25b6fe05 561 $result->toc .= html_writer::script(js_writer::set_variable('scormdata', array(
485f4ce6
PH
562 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
563 'minusicon' => $OUTPUT->pix_url('minus', 'scorm'))));
25b6fe05
PS
564 $result->toc .= html_writer::script('', $CFG->wwwroot.'/lib/cookies.js');
565 $result->toc .= html_writer::script('', $CFG->wwwroot.'/mod/scorm/datamodels/scorm_datamodels.js');
dc383b6f 566 }
d9e6517a 567
f8dab966
PS
568 $url = new moodle_url('/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr);
569 $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenus, $sco->id, null, "tocmenu");
dc383b6f 570
571 return $result;
572}