Comment added.
[moodle.git] / mod / scorm / locallib.php
CommitLineData
e4aa175a 1
2<?php // $Id$
3define("VALUESCOES",0);
4define("VALUEHIGHEST",1);
5define("VALUEAVERAGE",2);
6define("VALUESUM",3);
7
8/// Local Library of functions and constants for module scorm
9
10/**
11* Create a new temporary subdirectory with a random name in the given path
12*
13* @param string $strpath The scorm data directory
14* @return string/boolean
15*/
16function scorm_datadir($strPath)
17{
18 global $CFG;
19
20 if (is_dir($strPath)) {
21 do {
22 // Create a random string of 8 chars
23 $randstring = NULL;
24 $lchar = '';
25 $len = 8;
26 for ($i=0; $i<$len; $i++) {
27 $char = chr(rand(48,122));
28 while (!ereg('[a-zA-Z0-9]', $char)){
29 if ($char == $lchar) continue;
30 $char = chr(rand(48,90));
31 }
32 $randstring .= $char;
33 $lchar = $char;
34 }
35 $datadir='/'.$randstring;
36 } while (file_exists($strPath.$datadir));
37 mkdir($strPath.$datadir, $CFG->directorypermissions);
38 @chmod($strPath.$datadir, $CFG->directorypermissions); // Just in case mkdir didn't do it
39 return $strPath.$datadir;
40 } else {
41 return false;
42 }
43}
44
45/**
46* Given a package directory, this function will check if the package is valid
47*
48* @param string $packagedir The package directory
49* @return mixed
50*/
51function scorm_validate($packagedir) {
52
53 ////$f = "D:\\test.txt";
54 ////@$ft = fopen($f,"a");
55 ////fwrite($ft,"\n Xu ly trong ham scorm_validate \n");
56
57
58 $validation = new stdClass();
59 if (is_file($packagedir.'/imsmanifest.xml')) {
60 $validation->result = 'found';
61 $validation->pkgtype = 'SCORM';
62 } else {
63 if ($handle = opendir($packagedir)) {
64 while (($file = readdir($handle)) !== false) {
65 $ext = substr($file,strrpos($file,'.'));
66 if (strtolower($ext) == '.cst') {
67 $validation->result = 'found';
68 $validation->pkgtype = 'AICC';
69 break;
70 }
71 }
72 closedir($handle);
73 }
74 if (!isset($validation->result)) {
75 $validation->result = 'nomanifest';
76 $validation->pkgtype = 'SCORM';
77 }
78 }
79 return $validation;
80}
81
82function scorm_get_user_data($userid) {
83/// Gets user info required to display the table of scorm results
84/// for report.php
85
86 return get_record('user','id',$userid,'','','','','firstname, lastname, picture');
87}
88
89function scorm_string_wrap($stringa, $len=15) {
90// Crop the given string into max $len characters lines
91 $textlib = textlib_get_instance();
92 if ($textlib->strlen($stringa, current_charset()) > $len) {
93 $words = explode(' ', $stringa);
94 $newstring = '';
95 $substring = '';
96 foreach ($words as $word) {
97 if (($textlib->strlen($substring, current_charset())+$textlib->strlen($word, current_charset())+1) < $len) {
98 $substring .= ' '.$word;
99 } else {
100 $newstring .= ' '.$substring.'<br />';
101 $substring = $word;
102 }
103 }
104 if (!empty($substring)) {
105 $newstring .= ' '.$substring;
106 }
107 return $newstring;
108 } else {
109 return $stringa;
110 }
111}
112
113function scorm_eval_prerequisites($prerequisites,$usertracks) {
114
115 //$f = "D:\\test.txt";
116 //@$ft = fopen($f,"a");
117 ////fwrite($ft,"\n Xu ly trong ham scorm_eval_prerequisites \n");
118
119
120 $element = '';
121 $stack = array();
122 $statuses = array(
123 'passed' => 'passed',
124 'completed' => 'completed',
125 'failed' => 'failed',
126 'incomplete' => 'incomplete',
127 'browsed' => 'browsed',
128 'not attempted' => 'notattempted',
129 'p' => 'passed',
130 'c' => 'completed',
131 'f' => 'failed',
132 'i' => 'incomplete',
133 'b' => 'browsed',
134 'n' => 'notattempted'
135 );
136 $i=0;
137 while ($i<strlen($prerequisites)) {
138 $symbol = $prerequisites[$i];
139 switch ($symbol) {
140 case '&':
141 case '|':
142 $symbol .= $symbol;
143 case '~':
144 case '(':
145 case ')':
146 case '*':
147 //case '{':
148 //case '}':
149 //case ',':
150 $element = trim($element);
151
152 if (!empty($element)) {
153 $element = trim($element);
154 if (isset($usertracks[$element])) {
155 $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
156 '(\''.$usertracks[$element]->status.'\' == \'passed\'))';
157 } else if (($operator = strpos($element,'=')) !== false) {
158 $item = trim(substr($element,0,$operator));
159 if (!isset($usertracks[$item])) {
160 return false;
161 }
162
163 $value = trim(trim(substr($element,$operator+1)),'"');
164 if (isset($statuses[$value])) {
165 $status = $statuses[$value];
166 } else {
167 return false;
168 }
169
170 $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
171 } else if (($operator = strpos($element,'<>')) !== false) {
172 $item = trim(substr($element,0,$operator));
173 if (!isset($usertracks[$item])) {
174 return false;
175 }
176
177 $value = trim(trim(substr($element,$operator+2)),'"');
178 if (isset($statuses[$value])) {
179 $status = $statuses[$value];
180 } else {
181 return false;
182 }
183
184 $element = '(\''.$usertracks[$item]->status.'\' != \''.$status.'\')';
185 } else if (is_numeric($element)) {
186 if ($symbol == '*') {
187 $symbol = '';
188 $open = strpos($prerequisites,'{',$i);
189 $opened = 1;
190 $closed = 0;
191 for ($close=$open+1; (($opened > $closed) && ($close<strlen($prerequisites))); $close++) {
192 if ($prerequisites[$close] == '}') {
193 $closed++;
194 } else if ($prerequisites[$close] == '{') {
195 $opened++;
196 }
197 }
198 $i = $close;
199
200 $setelements = explode(',', substr($prerequisites, $open+1, $close-($open+1)-1));
201 $settrue = 0;
202 foreach ($setelements as $setelement) {
203 if (scorm_eval_prerequisites($setelement,$usertracks)) {
204 $settrue++;
205 }
206 }
207
208 if ($settrue >= $element) {
209 $element = 'true';
210 } else {
211 $element = 'false';
212 }
213 }
214 } else {
215 return false;
216 }
217
218 array_push($stack,$element);
219 $element = '';
220 }
221 if ($symbol == '~') {
222 $symbol = '!';
223 }
224 if (!empty($symbol)) {
225 array_push($stack,$symbol);
226 }
227 break;
228 default:
229 $element .= $symbol;
230 break;
231 }
232 $i++;
233 }
234 if (!empty($element)) {
235 $element = trim($element);
236 if (isset($usertracks[$element])) {
237 $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
238 '(\''.$usertracks[$element]->status.'\' == \'passed\'))';
239 } else if (($operator = strpos($element,'=')) !== false) {
240 $item = trim(substr($element,0,$operator));
241 if (!isset($usertracks[$item])) {
242 return false;
243 }
244
245 $value = trim(trim(substr($element,$operator+1)),'"');
246 if (isset($statuses[$value])) {
247 $status = $statuses[$value];
248 } else {
249 return false;
250 }
251
252 $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
253 } else if (($operator = strpos($element,'<>')) !== false) {
254 $item = trim(substr($element,0,$operator));
255 if (!isset($usertracks[$item])) {
256 return false;
257 }
258
259 $value = trim(trim(substr($element,$operator+1)),'"');
260 if (isset($statuses[$value])) {
261 $status = $statuses[$value];
262 } else {
263 return false;
264 }
265
266 $element = '(\''.$usertracks[$item]->status.'\' != \''.trim($status).'\')';
267 } else {
268 return false;
269 }
270
271 array_push($stack,$element);
272 }
273 return eval('return '.implode($stack).';');
274}
275
276function scorm_insert_statistic($statisticInput){
277
278 $id = null;
279 if ($statistic = get_record_select('scorm_statistic',"userid='$statisticInput->userid' AND scormid='$statisticInput->scormid'")) {
280
281 $statistic->durationtime = $statisticInput->duration;
282 $statistic->accesstime = $statisticInput->accesstime;
283 $statistic->status = $statisticInput->status;
284 $statistic->attemptnumber = $statisticInput->attemptnumber;
285 $id = update_record('scorm_statistic',$statistic);
286 } else {
287 ////fwrite($ft,"Insert trong ham scorm_insert_track \n");
288 $id = insert_record('scorm_statistic',$statisticInput);
289 }
290 return $id;
291
292}
293function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
294
295// //$f = "D:\\test.txt";
296// //@$ft = fopen($f,"a");
297 ////fwrite($ft,"\n Xu ly trong ham scorm_insert_track \n");
298
299 $id = null;
300 if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND attempt='$attempt' AND element='$element'")) {
301 $track->value = $value;
302 $track->timemodified = time();
303 ////fwrite($ft,$userid."Update trong ham scorm_insert_track voi cac gia tri userid = ");
304 $id = update_record('scorm_scoes_track',$track);
305 } else {
306 $track->userid = $userid;
307 $track->scormid = $scormid;
308 $track->scoid = $scoid;
309 $track->attempt = $attempt;
310 $track->element = $element;
311 $track->value = addslashes($value);
312 $track->timemodified = time();
313 ////fwrite($ft,"Insert trong ham scorm_insert_track \n");
314 $id = insert_record('scorm_scoes_track',$track);
315 }
316 return $id;
317}
318
319function scorm_insert_trackmodel($userid,$scormid,$scoid,$attempt) {
320
321// //$f = "D:\\test.txt";
322// //@$ft = fopen($f,"a");
323
324 $id = null;
325 if ($suspendtrack = get_record_select('scorm_suspendtrack',"userid='$userid' AND scormid='$scormid'")) {
326 $suspendtrack->suspendscoid = $scoid;
327 $suspendtrack->attempt = $attempt;
328
329 $id = update_record('scorm_suspendtrack',$suspendtrack);
330 } else {
331 $suspendtrack->scormid = $scormid;
332 $suspendtrack->suspendscoid = $scoid;
333 $suspendtrack->userid = $userid;
334 $suspendtrack->attempt = $attempt;
335 $id = insert_record('scorm_suspendtrack',$suspendtrack);
336 }
337 return $id;
338}
339
340function scorm_get_suspendscoid($scormid,$userid) {
341 if ($sco = get_record("scorm_suspendtrack","scormid",$scormid,"userid",$userid)) {
342 $suspendscoid = $sco->suspendscoid;
343 return $suspendscoid;
344 } else {
345 return 0;
346 }
347}
348
349function scorm_add_time($a, $b) {
350 $aes = explode(':',$a);
351 $bes = explode(':',$b);
352 $aseconds = explode('.',$aes[2]);
353 $bseconds = explode('.',$bes[2]);
354 $change = 0;
355
356 $acents = 0; //Cents
357 if (count($aseconds) > 1) {
358 $acents = $aseconds[1];
359 }
360 $bcents = 0;
361 if (count($bseconds) > 1) {
362 $bcents = $bseconds[1];
363 }
364 $cents = $acents + $bcents;
365 $change = floor($cents / 100);
366 $cents = $cents - ($change * 100);
367 if (floor($cents) < 10) {
368 $cents = '0'. $cents;
369 }
370
371 $secs = $aseconds[0] + $bseconds[0] + $change; //Seconds
372 $change = floor($secs / 60);
373 $secs = $secs - ($change * 60);
374 if (floor($secs) < 10) {
375 $secs = '0'. $secs;
376 }
377
378 $mins = $aes[1] + $bes[1] + $change; //Minutes
379 $change = floor($mins / 60);
380 $mins = $mins - ($change * 60);
381 if ($mins < 10) {
382 $mins = '0' . $mins;
383 }
384
385 $hours = $aes[0] + $bes[0] + $change; //Hours
386 if ($hours < 10) {
387 $hours = '0' . $hours;
388 }
389
390 if ($cents != '0') {
391 return $hours . ":" . $mins . ":" . $secs . '.' . $cents;
392 } else {
393 return $hours . ":" . $mins . ":" . $secs;
394 }
395}
396
397function scorm_external_link($link) {
398// check if a link is external
399 $result = false;
400 $link = strtolower($link);
401 if (substr($link,0,7) == 'http://') {
402 $result = true;
403 } else if (substr($link,0,8) == 'https://') {
404 $result = true;
405 } else if (substr($link,0,4) == 'www.') {
406 $result = true;
407 }
408 return $result;
409}
410
411function scorm_grade_user($scoes, $userid, $grademethod=VALUESCOES) {
412
413 //$f = "D:\\test.txt";
414 //@$ft = fopen($f,"a");
415 //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");
416
417 $scores = NULL;
418 $scores->scoes = 0;
419 $scores->values = 0;
420 $scores->max = 0;
421 $scores->sum = 0;
422
423 if (!$scoes) {
424 return '';
425 }
426
427 $current = current($scoes);
428 $attempt = scorm_get_last_attempt($current->scorm, $userid);
429 foreach ($scoes as $sco) {
430 if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
431 if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {
432 $scores->scoes++;
433 }
434 if (!empty($userdata->score_raw)) {
435 $scores->values++;
436 $scores->sum += $userdata->score_raw;
437 $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
438 }
439 }
440 }
441 switch ($grademethod) {
442 case VALUEHIGHEST:
443 return $scores->max;
444 break;
445 case VALUEAVERAGE:
446 if ($scores->values > 0) {
447 return $scores->sum/$scores->values;
448 } else {
449 return 0;
450 }
451 break;
452 case VALUESUM:
453 return $scores->sum;
454 break;
455 case VALUESCOES:
456 return $scores->scoes;
457 break;
458 }
459}
460
461//Lay diem theo Sco cha.. Thuc chat la theo bai kiem tra
462function scorm_get_score_from_parent($sco,$userid,$grademethod=VALUESCOES)
463{
464
465 $scores = NULL;
466 $scores->scoes = 0;
467 $scores->values = 0;
468 $scores->scaled = 0;
469 $scores->max = 0;
470 $scores->sum = 0;
471
472 $scoes_total = 0;
473 $scoes_count = 0;
474 $attempt = scorm_get_last_attempt($sco->scorm, $userid);
475 $scoes = get_records('scorm_scoes', 'parent', $sco->identifier);
476 foreach ($scoes as $sco)
477 {
478 $scoes_total++;
479 if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
480 if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
481 $scoes_count++;
482 }
483
484
485 $scoreraw = $userdata->score_raw;
486
487 if (!empty($userdata->score_raw)) {
488 $scores->values++;
489 $scores->sum += $userdata->score_raw;
490 $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
491 }
492 if (!empty($userdata->score_scaled)) {
493 $scores->scaled = $scores->scaled + $userdata->score_scaled;
494 }
495
496 }
497 }
498 if ($scoes_count > 0)
499 {
500 $scores->scaled = ($scores->scaled)/($scoes_count);
501 }
502 switch ($grademethod) {
503 case VALUEHIGHEST:
504 return $scores->max;
505 break;
506 case VALUEAVERAGE:
507 if ($scores->values > 0) {
508 return $scores->sum/$scores->values;
509 } else {
510 return 0;
511 }
512 break;
513 case VALUESUM:
514 return $scores->sum;
515 break;
516 case VALUESCOES:
517 return $scores->scaled;
518 break;
519 }
520
521}
522
523// Lay ra so luong cac scoes duoc user thuc hien xong
524function scorm_get_user_sco_count($scormid, $userid)
525{
526 $scoes_count = 0;
527 $attempt = scorm_get_last_attempt($current->scorm, $userid);
528 $scoes = get_records('scorm_scoes', 'scorm', $scormid);
529
530
531
532 foreach ($scoes as $sco)
533 {
534 if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
535
536 if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
537 $scoes_count++;
538 }
539 }
540
541 }
542 return $scoes_count;
543
544}
545
546function scorm_grade_user_new($scoes, $userid, $grademethod=VALUESCOES) {
547
548 //$f = "D:\\test.txt";
549 //@$ft = fopen($f,"a");
550 //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");
551
552 $scores = NULL;
553 $scores->scoes = 0;
554 $scores->values = 0;
555 $scores->scaled = 0;
556 $scores->max = 0;
557 $scores->sum = 0;
558
559 if (!$scoes) {
560 //fwrite($ft,"\n Khong xuat hien mot SCO duoc tinh diem \n");
561 return '';
562 }
563
564 $current = current($scoes);
565 $attempt = scorm_get_last_attempt($current->scorm, $userid);
566 //fwrite($ft,"\n ---------------------------------------\n");
567 foreach ($scoes as $sco) {
568 if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
569 if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
570 $scores->scoes++;
571 //fwrite($ft,"\n Them mot khoa hoan thanh co id la ".$sco->id." co gia tri scaled la ".$userdata->score_scaled." \n");
572
573 }
574 $scaled = $userdata->score_scaled;
575 $scoreraw = $userdata->score_raw;
576 if ($scaled ==0){
577 $scores->scaled = $scores->scaled / $scores->scoes;
578 //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");
579
580 }
581
582 if (!empty($userdata->score_raw)) {
583 $scores->values++;
584 $scores->sum += $userdata->score_raw;
585 $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
586 }
587
588 if (!empty($scaled)) {
589 //fwrite($ft,"\n go ---->>> \n");
590 $scores->scaled = (($scores->scaled) * ($scores->scoes-1) + $scaled)/($scores->scoes);
591 //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");
592
593 }
594
595 }
596 }
597 //fwrite($ft,"\n ----+++++++++++------\n");
598 //fwrite($ft,"\n Kieu gia tri tra ve la ".$grademethod);
599 switch ($grademethod) {
600 case VALUEHIGHEST:
601 //fwrite($ft,"\n Gia tri tra ve thouoc loai cao nhat");
602 return $scores->max;
603 break;
604 case VALUEAVERAGE:
605 //fwrite($ft,"\n Gia tri tra ve thouoc loai trung binh");
606 if ($scores->values > 0) {
607 return $scores->sum/$scores->values;
608 } else {
609 return 0;
610 }
611 break;
612 case VALUESUM:
613 //fwrite($ft,"\n Gia tri tra ve thouoc loai tong cong");
614 return $scores->sum;
615 break;
616 case VALUESCOES:
617 //fwrite($ft,"\n Gia tri tra ve thouoc loai scoes co gia tri".$scores->scaled);
618 return $scores->scaled;
619 break;
620 }
621}
622
623function scorm_count_launchable($scormid,$organization) {
624 return count_records_select('scorm_scoes',"scorm=$scormid AND organization='$organization' AND launch<>''");
625}
626
627function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
628 global $CFG;
629
630 //$f = "D:\\test.txt";
631 //@$ft = fopen($f,"a");
632 //fwrite($ft,"\n Xu ly trong ham scorm_get_toc \n");
633
634 //
635 $suspendscoid = scorm_get_suspendscoid($scorm->id,$user->id);
636 //
637
638 $strexpand = get_string('expcoll','scorm');
639 $modestr = '';
640 if ($mode == 'browse') {
641 $modestr = '&amp;mode='.$mode;
642 }
643 $scormpixdir = $CFG->modpixpath.'/scorm/pix';
644
645 $result = new stdClass();
646 $result->toc = "<ul id='0' class='$liststyle'>\n";
647 $tocmenus = array();
648 $result->prerequisites = true;
649 $incomplete = false;
650
651 //
652 // Get the current organization infos
653 //
654 $organizationsql = '';
655 if (!empty($currentorg)) {
656 if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
657 $result->toc .= "\t<li>$organizationtitle</li>\n";
658 $tocmenus[] = $organizationtitle;
659 }
660 $organizationsql = "AND organization='$currentorg'";
661 }
662 //
663 // If not specified retrieve the last attempt number
664 //
665 if (empty($attempt)) {
666 $attempt = scorm_get_last_attempt($scorm->id, $user->id);
667 }
668 $result->attemptleft = $scorm->maxattempt - $attempt;
669
670 //fwrite($ft,"\n So lan attempt con lai la \n".$result->attemptleft);
671
672 if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
673 //
674 // Lay du lieu da duoc tracking cho moi doi tuong hoc tap
675 //
676 $usertracks = array();
677 foreach ($scoes as $sco) {
678 //Kiem tra xem $sco co phai la phan muc khong. Neu la trang Asset hoac SCO thi xu ly tiep
679 if (!empty($sco->launch)) {
680 if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
681 if ($usertrack->status == '') {
682 $usertrack->status = 'notattempted';
683 }
684 // Ghi lai thong tin $usertracks theo tung doi tuong sco
685 $usertracks[$sco->identifier] = $usertrack;
686 }
687 }
688 }
689
690 $level=0;
691 $sublist=1;
692 $previd = 0;
693 $nextid = 0;
694 $findnext = false;
695 $parents[$level]='/';
696
697 foreach ($scoes as $sco) {
698 if ($parents[$level]!=$sco->parent) {
699 if ($newlevel = array_search($sco->parent,$parents)) {
700 for ($i=0; $i<($level-$newlevel); $i++) {
701 $result->toc .= "\t\t</ul></li>\n";
702 }
703 $level = $newlevel;
704 } else {
705 $i = $level;
706 $closelist = '';
707 while (($i > 0) && ($parents[$level] != $sco->parent)) {
708 $closelist .= "\t\t</ul></li>\n";
709 $i--;
710 }
711 if (($i == 0) && ($sco->parent != $currentorg)) {
712 $style = '';
713 if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
714 $style = ' style="display: none;"';
715 }
716 $result->toc .= "\t\t<li><ul id='$sublist' class='$liststyle'$style>\n";
717 $level++;
718 } else {
719 $result->toc .= $closelist;
720 $level = $i;
721 }
722 $parents[$level]=$sco->parent;
723 }
724 }
725 $result->toc .= "\t\t<li>";
726 $nextsco = next($scoes);
727 if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
728 $sublist++;
729 $icon = 'minus';
730 if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
731 $icon = 'plus';
732 }
733 $result->toc .= '<a href="javascript:expandCollide(img'.$sublist.','.$sublist.','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$scormpixdir.'/'.$icon.'.gif" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
734 } else {
735 $result->toc .= '<img src="'.$scormpixdir.'/spacer.gif" />';
736 }
737 if (empty($sco->title)) {
738 $sco->title = $sco->identifier;
739 }
740 if (!empty($sco->launch)) {
741 $startbold = '';
742 $endbold = '';
743 $score = '';
744 if (empty($scoid) && ($mode != 'normal')) {
745 $scoid = $sco->id;
746 }
747 //Neu la sco suspend thi hien thi anh khac
748 if ($suspendscoid == $sco->id){
749 $result->toc .= '<img src="'.$scormpixdir.'/suspend.gif" alt="Dang tam dung o day" title="Dang dung o day" />';
750 } else {
751 //-----------------------
752 if (isset($usertracks[$sco->identifier])) {
753 $usertrack = $usertracks[$sco->identifier];
754 $strstatus = get_string($usertrack->status,'scorm');
755 $result->toc .= '<img src="'.$scormpixdir.'/'.$usertrack->status.'.gif" alt="'.$strstatus.'" title="'.$strstatus.'" />';
756
757 if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {
758 //Neu khoa hoc chua duoc attempted hoac chua hoan thanh hoac la chi browsed
759 $incomplete = true;
760 if ($play && empty($scoid)) {
761 $scoid = $sco->id;
762 }
763 }
764 if ($usertrack->score_raw != '') {
765 $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';
766 }
767 } else {
768 if ($play && empty($scoid)) {
769 $scoid = $sco->id;
770 }
771 if ($sco->scormtype == 'sco') {
772 $result->toc .= '<img src="'.$scormpixdir.'/notattempted.gif" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
773 $incomplete = true;
774 } else {
775 $result->toc .= '<img src="'.$scormpixdir.'/asset.gif" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
776 }
777 }
778 }
779 if ($sco->id == $scoid) {
780 $startbold = '<b>';
781 $endbold = '</b>';
782 $findnext = true;
783 $shownext = $sco->next;
784 $showprev = $sco->previous;
785 }
786
787 if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
788 if (!empty($sco->launch)) {
789 $previd = $sco->id;
790 }
791 }
792 if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks)) {
793 if ($sco->id == $scoid) {
794 $result->prerequisites = true;
795 }
796 if (scorm_isChoice($scorm->id,$sco->id) == 1)
797 {
798 $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
799 $result->toc .= '&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
800 $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
801 }
802 else
803 {
804 $result->toc .= '&nbsp;'.$startbold.format_string($sco->title).$score.$endbold."</li>\n";
805 $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
806 }
807 } else {
808 if ($sco->id == $scoid) {
809 $result->prerequisites = false;
810 }
811 $result->toc .= '&nbsp;'.$sco->title."</li>\n";
812 }
813 } else {
814 $result->toc .= '&nbsp;'.$sco->title."</li>\n";
815 }
816 if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
817 if (!empty($nextsco->launch)) {
818 $nextid = $nextsco->id;
819 }
820 }
821 }
822 for ($i=0;$i<$level;$i++) {
823 $result->toc .= "\t\t</ul></li>\n";
824 }
825
826 if ($play) {
827 $sco = get_record('scorm_scoes','id',$scoid);
828 $sco->previd = $previd;
829 $sco->nextid = $nextid;
830 $result->sco = $sco;
831 $result->incomplete = $incomplete;
832 } else {
833 $result->incomplete = $incomplete;
834 }
835 }
836 $result->toc .= "\t</ul>\n";
837 if ($scorm->hidetoc == 0) {
838 $result->toc .= '
839 <script language="javascript" type="text/javascript">
840 <!--
841 function expandCollide(which,list,item) {
842 var nn=document.ids?true:false
843 var w3c=document.getElementById?true:false
844 var beg=nn?"document.ids.":w3c?"document.getElementById(":"document.all.";
845 var mid=w3c?").style":".style";
846
847 if (eval(beg+list+mid+".display") != "none") {
848 which.src = "'.$scormpixdir.'/plus.gif";
849 eval(beg+list+mid+".display=\'none\';");
850 new cookie("hide:SCORMitem" + item, 1, 356, "/").set();
851 } else {
852 which.src = "'.$scormpixdir.'/minus.gif";
853 eval(beg+list+mid+".display=\'block\';");
854 new cookie("hide:SCORMitem" + item, 1, -1, "/").set();
855 }
856 }
857 -->
858 </script>'."\n";
859 }
860
861 $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid=';
862 $result->tocmenu = popup_form($url,$tocmenus, "tocmenu", $sco->id, '', '', '', true);
863
864 return $result;
865}
866
867function scorm_get_last_attempt($scormid, $userid) {
868
869 //$f = "D:\\test.txt";
870 //@$ft = fopen($f,"a");
871 ////fwrite($ft,"\n Xu ly trong ham scorm_get_last_attempt \n");
872
873/// Find the last attempt number for the given user id and scorm id
874 if ($lastattempt = get_record('scorm_scoes_track', 'userid', $userid, 'scormid', $scormid, '', '', 'max(attempt) as a')) {
875 if (empty($lastattempt->a)) {
876 return '1';
877 } else {
878 return $lastattempt->a;
879 }
880 }
881}
882
883// Khi mot nguoi truy nhap vao mot SCO thi se thiet lap
884// nguoi do da no luc thuc hien no
885function scorm_set_attempt($scoid,$userid)
886{
887 //Lay gia tri last attempt
888 if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {
889 $attempt = scorm_get_last_attempt($scormid,$userid);
890 } else {
891 $attempt = 1;
892 }
893 //Chi set attempt cho cac SCO
894 $scormtype = get_field('scorm_scoes','scormtype','id',$scoid) ;
895 if ($scormtype == 'sco'){
896 $element = 'cmi.attempt_status';
897 $value = 'attempted';
898 scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value);
899 }
900}
901function scorm_get_tracks($scoid,$userid,$attempt='') {
902
903 //$f = "D:\\test.txt";
904 //@$ft = fopen($f,"a");
905 ////fwrite($ft,"\n Xu ly trong ham scorm_get_tracks \n");
906
907/// Gets all tracks of specified sco and user
908 global $CFG;
909
910 if (empty($attempt)) {
911 if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {
912 $attempt = scorm_get_last_attempt($scormid,$userid);
913 } else {
914 $attempt = 1;
915 }
916 }
917 $attemptsql = ' AND attempt=' . $attempt;
918 if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid".$attemptsql,'element ASC')) {
919 $usertrack->userid = $userid;
920 $usertrack->scoid = $scoid;
921 $usertrack->score_raw = '';
922 $usertrack->score_scaled = '';
923 $usertrack->status = '';
924 $usertrack->success_status = '';
925 $usertrack->attempt_status = '';
926 $usertrack->satisfied_status = '';
927 $usertrack->total_time = '00:00:00';
928 $usertrack->session_time = '00:00:00';
929 $usertrack->timemodified = 0;
930 foreach ($tracks as $track) {
931 $element = $track->element;
932 $usertrack->{$element} = $track->value;
933 switch ($element) {
934 case 'cmi.core.lesson_status':
935 case 'cmi.attempt_status':
936 $usertrack->status = $track->value;
937 $usertrack->attempt_status = $track->value;
938 break;
939 case 'cmi.completion_status':
940 if ($track->value == 'not attempted') {
941 $track->value = 'notattempted';
942 $usertrack->attempt_status = $track->value;
943 }
944 $usertrack->status = $track->value;
945 break;
946 case 'cmi.success_status':
947 $usertrack->success_status = $track->value;
948 if ($track->value=='passed'){
949 $usertrack->satisfied_status = 'satisfied';
950 }
951 if ($track->value=='failed'){
952 $usertrack->satisfied_status = 'notSatisfied';
953 }
954 break;
955 case 'cmi.core.score.raw':
956 case 'cmi.score.raw':
957 $usertrack->score_raw = $track->value;
958 break;
959 case 'cmi.score.scaled':
960 $usertrack->score_scaled = $track->value;
961 break;
962 case 'cmi.core.session_time':
963 case 'cmi.session_time':
964 $usertrack->session_time = $track->value;
965 break;
966 case 'cmi.core.total_time':
967 case 'cmi.total_time':
968 $usertrack->total_time = $track->value;
969 break;
970 }
971 if (isset($track->timemodified) && ($track->timemodified > $usertrack->timemodified)) {
972 $usertrack->timemodified = $track->timemodified;
973 }
974 }
975 return $usertrack;
976 } else {
977 return false;
978 }
979}
980
981
982function scorm_get_AbsoluteTimeLimit($scoid){
983 $sco = get_record("scorm_scoes","id",$scoid);
984 if (!empty($sco)){
985 return $sco->attemptAbsoluteDurationLimit;
986 }
987 return 0;
988}
989//-----------------------------------------------------
990/// Library of functions and constants for parsing packages
991
992function scorm_parse($scorm) {
993 global $CFG;
994
995 //$f = "D:\\test.txt";
996 //@$ft = fopen($f,"a");
997 ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse \n");
998
999 // Parse scorm manifest
1000 if ($scorm->pkgtype == 'AICC') {
1001 $scorm->launch = scorm_parse_aicc($scorm->dir.'/'.$scorm->id,$scorm->id);
1002 } else {
1003 if (basename($scorm->reference) != 'imsmanifest.xml') {
1004 $scorm->launch = scorm_parse_scorm($scorm->dir.'/'.$scorm->id,$scorm->id);
1005 } else {
1006 $scorm->launch = scorm_parse_scorm($CFG->dataroot.'/'.$scorm->course.'/'.dirname($scorm->reference),$scorm->id);
1007 }
1008 }
1009
1010 return $scorm->launch;
1011}
1012
1013/**
1014* Take the header row of an AICC definition file
1015* and returns sequence of columns and a pointer to
1016* the sco identifier column.
1017*
1018* @param string $row AICC header row
1019* @param string $mastername AICC sco identifier column
1020* @return mixed
1021*/
1022function scorm_get_aicc_columns($row,$mastername='system_id') {
1023 $tok = strtok(strtolower($row),"\",\n\r");
1024 $result->columns = array();
1025 $i=0;
1026 while ($tok) {
1027 if ($tok !='') {
1028 $result->columns[] = $tok;
1029 if ($tok == $mastername) {
1030 $result->mastercol = $i;
1031 }
1032 $i++;
1033 }
1034 $tok = strtok("\",\n\r");
1035 }
1036 return $result;
1037}
1038
1039/**
1040* Given a colums array return a string containing the regular
1041* expression to match the columns in a text row.
1042*
1043* @param array $column The header columns
1044* @param string $remodule The regular expression module for a single column
1045* @return string
1046*/
1047function scorm_forge_cols_regexp($columns,$remodule='(".*")?,') {
1048 $regexp = '/^';
1049 foreach ($columns as $column) {
1050 $regexp .= $remodule;
1051 }
1052 $regexp = substr($regexp,0,-1) . '/';
1053 return $regexp;
1054}
1055
1056function scorm_parse_aicc($pkgdir,$scormid){
1057
1058 //$f = "D:\\test.txt";
1059 //@$ft = fopen($f,"a");
1060 ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_aicc \n");
1061
1062 $version = 'AICC';
1063 $ids = array();
1064 $courses = array();
1065 if ($handle = opendir($pkgdir)) {
1066 while (($file = readdir($handle)) !== false) {
1067 $ext = substr($file,strrpos($file,'.'));
1068 $extension = strtolower(substr($ext,1));
1069 $id = strtolower(basename($file,$ext));
1070 $ids[$id]->$extension = $file;
1071 }
1072 closedir($handle);
1073 }
1074 foreach ($ids as $courseid => $id) {
1075 if (isset($id->crs)) {
1076 if (is_file($pkgdir.'/'.$id->crs)) {
1077 $rows = file($pkgdir.'/'.$id->crs);
1078 foreach ($rows as $row) {
1079 if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {
1080 switch (strtolower(trim($matches[1]))) {
1081 case 'course_id':
1082 $courses[$courseid]->id = trim($matches[2]);
1083 break;
1084 case 'course_title':
1085 $courses[$courseid]->title = trim($matches[2]);
1086 break;
1087 case 'version':
1088 $courses[$courseid]->version = 'AICC_'.trim($matches[2]);
1089 break;
1090 }
1091 }
1092 }
1093 }
1094 }
1095 if (isset($id->des)) {
1096 $rows = file($pkgdir.'/'.$id->des);
1097 $columns = scorm_get_aicc_columns($rows[0]);
1098 $regexp = scorm_forge_cols_regexp($columns->columns);
1099 for ($i=1;$i<count($rows);$i++) {
1100 if (preg_match($regexp,$rows[$i],$matches)) {
1101 for ($j=0;$j<count($columns->columns);$j++) {
1102 $column = $columns->columns[$j];
1103 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
1104 }
1105 }
1106 }
1107 }
1108 if (isset($id->au)) {
1109 $rows = file($pkgdir.'/'.$id->au);
1110 $columns = scorm_get_aicc_columns($rows[0]);
1111 $regexp = scorm_forge_cols_regexp($columns->columns);
1112 for ($i=1;$i<count($rows);$i++) {
1113 if (preg_match($regexp,$rows[$i],$matches)) {
1114 for ($j=0;$j<count($columns->columns);$j++) {
1115 $column = $columns->columns[$j];
1116 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
1117 }
1118 }
1119 }
1120 }
1121 if (isset($id->cst)) {
1122 $rows = file($pkgdir.'/'.$id->cst);
1123 $columns = scorm_get_aicc_columns($rows[0],'block');
1124 $regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
1125 for ($i=1;$i<count($rows);$i++) {
1126 if (preg_match($regexp,$rows[$i],$matches)) {
1127 for ($j=0;$j<count($columns->columns);$j++) {
1128 if ($j != $columns->mastercol) {
1129 $courses[$courseid]->elements[substr(trim($matches[$j+1]),1,-1)]->parent = substr(trim($matches[$columns->mastercol+1]),1,-1);
1130 }
1131 }
1132 }
1133 }
1134 }
1135 if (isset($id->ort)) {
1136 $rows = file($pkgdir.'/'.$id->ort);
1137 }
1138 if (isset($id->pre)) {
1139 $rows = file($pkgdir.'/'.$id->pre);
1140 $columns = scorm_get_aicc_columns($rows[0],'structure_element');
1141 $regexp = scorm_forge_cols_regexp($columns->columns,'(.+),');
1142 for ($i=1;$i<count($rows);$i++) {
1143 if (preg_match($regexp,$rows[$i],$matches)) {
1144 $courses[$courseid]->elements[$columns->mastercol+1]->prerequisites = substr(trim($matches[1-$columns->mastercol+1]),1,-1);
1145 }
1146 }
1147 }
1148 if (isset($id->cmp)) {
1149 $rows = file($pkgdir.'/'.$id->cmp);
1150 }
1151 }
1152 //print_r($courses);
1153 $launch = 0;
1154 if (isset($courses)) {
1155 foreach ($courses as $course) {
1156 unset($sco);
1157 $sco->identifier = $course->id;
1158 $sco->scorm = $scormid;
1159 $sco->organization = '';
1160 $sco->title = $course->title;
1161 $sco->parent = '/';
1162 $sco->launch = '';
1163 $sco->scormtype = '';
1164 //print_r($sco);
1165 $id = insert_record('scorm_scoes',$sco);
1166 if ($launch == 0) {
1167 $launch = $id;
1168 }
1169 if (isset($course->elements)) {
1170 foreach($course->elements as $element) {
1171 unset($sco);
1172 $sco->identifier = $element->system_id;
1173 $sco->scorm = $scormid;
1174 $sco->organization = $course->id;
1175 $sco->title = $element->title;
1176 if (strtolower($element->parent) == 'root') {
1177 $sco->parent = '/';
1178 } else {
1179 $sco->parent = $element->parent;
1180 }
1181 if (isset($element->file_name)) {
1182 $sco->launch = $element->file_name;
1183 $sco->scormtype = 'sco';
1184 } else {
1185 $element->file_name = '';
1186 $sco->scormtype = '';
1187 }
1188 if (!isset($element->prerequisites)) {
1189 $element->prerequisites = '';
1190 }
1191 $sco->prerequisites = $element->prerequisites;
1192 if (!isset($element->max_time_allowed)) {
1193 $element->max_time_allowed = '';
1194 }
1195 $sco->maxtimeallowed = $element->max_time_allowed;
1196 if (!isset($element->time_limit_action)) {
1197 $element->time_limit_action = '';
1198 }
1199 $sco->timelimitaction = $element->time_limit_action;
1200 if (!isset($element->mastery_score)) {
1201 $element->mastery_score = '';
1202 }
1203 $sco->masteryscore = $element->mastery_score;
1204 $sco->previous = 0;
1205 $sco->next = 0;
1206 $id = insert_record('scorm_scoes',$sco);
1207 if ($launch==0) {
1208 $launch = $id;
1209 }
1210 }
1211 }
1212 }
1213 }
1214 set_field('scorm','version','AICC','id',$scormid);
1215 return $launch;
1216}
1217
1218function scorm_get_resources($blocks) {
1219
1220 //$f = "D:\\test.txt";
1221 //@$ft = fopen($f,"a");
1222 ////fwrite($ft,"\n Xu ly trong ham scorm_get_resources \n");
1223
1224 foreach ($blocks as $block) {
1225 if ($block['name'] == 'RESOURCES') {
1226 foreach ($block['children'] as $resource) {
1227 if ($resource['name'] == 'RESOURCE') {
1228 $resources[addslashes($resource['attrs']['IDENTIFIER'])] = $resource['attrs'];
1229 }
1230 }
1231 }
1232 }
1233 return $resources;
1234}
1235
1236function scorm_get_manifest($blocks,$scoes) {
1237
1238 //$f = "D:\\test.txt";
1239 //@$ft = fopen($f,"a");
1240 ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_get_manifest. \n");
1241 ////////fwrite($ft,$blocks." la gia tri block la \n");
1242
1243 static $parents = array();
1244 static $resources;
1245
1246 static $manifest;
1247 static $organization;
1248
1249 if (count($blocks) > 0) {
1250 foreach ($blocks as $block) {
1251 switch ($block['name']) {
1252 case 'METADATA':
1253 if (isset($block['children'])) {
1254 foreach ($block['children'] as $metadata) {
1255 if ($metadata['name'] == 'SCHEMAVERSION') {
1256 if (empty($scoes->version)) {
1257 if (isset($metadata['tagData']) && (preg_match("/^(1\.2)$|^(CAM )?(1\.3)$/",$metadata['tagData'],$matches))) {
1258 $scoes->version = 'SCORM_'.$matches[count($matches)-1];
1259 } else {
1260 $scoes->version = 'SCORM_1.2';
1261 }
1262 }
1263 }
1264 }
1265 }
1266 break;
1267 case 'MANIFEST':
1268 $manifest = addslashes($block['attrs']['IDENTIFIER']); //Lay thuoc tinh IDENTFIER cua MANIFEST
1269 $organization = '';
1270 $resources = array();
1271 $resources = scorm_get_resources($block['children']);
1272 $scoes = scorm_get_manifest($block['children'],$scoes);
1273 if (count($scoes->elements) <= 0) {
1274 foreach ($resources as $item => $resource) {
1275 if (!empty($resource['HREF'])) {
1276 $sco = new stdClass();
1277 $sco->identifier = $item;
1278 $sco->title = $item;
1279 $sco->parent = '/';
1280 $sco->launch = addslashes($resource['HREF']);
1281 $sco->scormtype = addslashes($resource['ADLCP:SCORMTYPE']);
1282 $scoes->elements[$manifest][$organization][$item] = $sco;
1283 }
1284 }
1285 }
1286 break;
1287 case 'ORGANIZATIONS':
1288 if (!isset($scoes->defaultorg)) {
1289 $scoes->defaultorg = addslashes($block['attrs']['DEFAULT']);
1290 }
1291 $scoes = scorm_get_manifest($block['children'],$scoes);
1292 break;
1293 case 'ORGANIZATION':
1294 $identifier = addslashes($block['attrs']['IDENTIFIER']);
1295 $organization = '';
1296 $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
1297 $scoes->elements[$manifest][$organization][$identifier]->parent = '/';
1298 $scoes->elements[$manifest][$organization][$identifier]->launch = '';
1299 $scoes->elements[$manifest][$organization][$identifier]->scormtype = '';
1300
1301 $parents = array();
1302 $parent = new stdClass();
1303 $parent->identifier = $identifier;
1304 $parent->organization = $organization;
1305 array_push($parents, $parent);
1306 $organization = $identifier;
1307
1308 $scoes = scorm_get_manifest($block['children'],$scoes);
1309
1310 array_pop($parents);
1311 break;
1312 case 'ITEM':
1313 $parent = array_pop($parents);
1314 array_push($parents, $parent);
1315
1316 $identifier = addslashes($block['attrs']['IDENTIFIER']);
1317 $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
1318 $scoes->elements[$manifest][$organization][$identifier]->parent = $parent->identifier;
1319 if (!isset($block['attrs']['ISVISIBLE'])) {
1320 $block['attrs']['ISVISIBLE'] = 'true';
1321 }
1322 $scoes->elements[$manifest][$organization][$identifier]->isvisible = addslashes($block['attrs']['ISVISIBLE']);
1323 if (!isset($block['attrs']['PARAMETERS'])) {
1324 $block['attrs']['PARAMETERS'] = '';
1325 }
1326 $scoes->elements[$manifest][$organization][$identifier]->parameters = addslashes($block['attrs']['PARAMETERS']);
1327 if (!isset($block['attrs']['IDENTIFIERREF'])) {
1328 $scoes->elements[$manifest][$organization][$identifier]->launch = '';
1329 $scoes->elements[$manifest][$organization][$identifier]->scormtype = 'asset';
1330 } else {
1331 $idref = addslashes($block['attrs']['IDENTIFIERREF']);
1332 $base = '';
1333 if (isset($resources[$idref]['XML:BASE'])) {
1334 $base = $resources[$idref]['XML:BASE'];
1335 }
1336 $scoes->elements[$manifest][$organization][$identifier]->launch = addslashes($base.$resources[$idref]['HREF']);
1337 if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {
1338 $resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';
1339 }
1340 $scoes->elements[$manifest][$organization][$identifier]->scormtype = addslashes($resources[$idref]['ADLCP:SCORMTYPE']);
1341 }
1342
1343 //////fwrite($ft,"---Dang lam viec voi ITEM co Identifier = ".$identifier);
1344 $parent = new stdClass();
1345 $parent->identifier = $identifier;
1346 $parent->organization = $organization;
1347 array_push($parents, $parent);
1348
1349 $scoes = scorm_get_manifest($block['children'],$scoes);
1350
1351 array_pop($parents);
1352 break;
1353 case 'TITLE':
1354 $parent = array_pop($parents);
1355 array_push($parents, $parent);
1356 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->title = addslashes($block['tagData']);
1357 break;
1358 case 'ADLCP:PREREQUISITES':
1359 if ($block['attrs']['TYPE'] == 'aicc_script') {
1360 $parent = array_pop($parents);
1361 array_push($parents, $parent);
1362 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->prerequisites = addslashes($block['tagData']);
1363 }
1364 break;
1365 case 'ADLCP:MAXTIMEALLOWED':
1366 $parent = array_pop($parents);
1367 array_push($parents, $parent);
1368 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->maxtimeallowed = addslashes($block['tagData']);
1369 break;
1370 case 'ADLCP:TIMELIMITACTION':
1371 $parent = array_pop($parents);
1372 array_push($parents, $parent);
1373 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->timelimitaction = addslashes($block['tagData']);
1374 break;
1375 case 'ADLCP:DATAFROMLMS':
1376 $parent = array_pop($parents);
1377 array_push($parents, $parent);
1378 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->datafromlms = addslashes($block['tagData']);
1379 break;
1380 case 'ADLCP:MASTERYSCORE':
1381 $parent = array_pop($parents);
1382 array_push($parents, $parent);
1383 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->masteryscore = addslashes($block['tagData']);
1384 break;
1385 case 'ADLNAV:PRESENTATION':
1386 $parent = array_pop($parents);
1387 array_push($parents, $parent);
1388 foreach ($block['children'] as $adlnav) {
1389 if ($adlnav['name'] == 'ADLNAV:NAVIGATIONINTERFACE') { //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title." Xuat hien dieu khien NAV \n");
1390 foreach ($adlnav['children'] as $adlnavInterface){
1391 if ($adlnavInterface['name'] == 'ADLNAV:HIDELMSUI'){
1392 //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title." Xuat hien dieu khien NAV HIDELMSUI\n");
1393 //////fwrite($ft," Gia tri thuoc tinh an la ".$adlnavInterface['tagData']);
1394 if ($adlnavInterface['tagData'] == 'continue') {
1395 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->next = 1;
1396// //////fwrite($ft," Thiet lap thuoc tinh an OK ");
1397 }
1398 if ($adlnavInterface['tagData'] == 'previous') {
1399 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->previous = 1;
1400// //////fwrite($ft," Thiet lap thuoc tinh an OK ");
1401 }
1402 }
1403
1404 }
1405
1406 }
1407 }
1408 break;
1409
1410 case 'IMSSS:SEQUENCING':
1411 $parent = array_pop($parents);
1412 array_push($parents, $parent);
1413 foreach ($block['children'] as $sequencing) {
1414 //////fwrite($ft,"\n Xuat hien IMSSS:SEQUENCING cua ".$parent->identifier);
1415 if ($sequencing['name']=='IMSSS:CONTROLMODE'){
1416 //Xu ly cac Control Mode voi mot Item trong SCO
1417 if ($sequencing['attrs']['CHOICE'] == 'false'){
1418 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choice = 0;
1419 //////fwrite($ft,"\n Xuat hien lua chon choice \n");
1420 }
1421 if ($sequencing['attrs']['CHOICEEXIT'] == 'false'){
1422 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choiceexit = 0;
1423 }
1424 if ($sequencing['attrs']['FLOW'] == 'true'){
1425 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->flow = 1;
1426 }
1427 if ($sequencing['attrs']['FORWARDONLY'] == 'true'){
1428 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->forwardonly = 1;
1429 }
1430 if ($sequencing['attrs']['USECURRENTATTEMPTOBJECTINFO'] == 'true'){
1431 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptobjectinfo = 1;
1432 }
1433 if ($sequencing['attrs']['USECURRENTATTEMPTPROGRESSINFO'] == 'true'){
1434 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptprogressinfo = 1;
1435 }
1436 }
1437 if ($sequencing['name']=='ADLSEQ:CONSTRAINEDCHOICECONSIDERATIONS'){
1438 //Xu ly cac dieu kien rang buoc thu tu
1439 if ($sequencing['attrs']['CONSTRAINCHOICE'] == 'true'){
1440 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->constrainChoice = 1;
1441 }
1442 if ($sequencing['attrs']['PREVENTACTIVATION'] == 'true'){
1443 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->preventactivation = 1;
1444 }
1445
1446 }
1447 if ($sequencing['name']=='IMSSS:OBJECTIVES'){
1448 //Xu ly cac cac gia tri muc tieu
1449 foreach ($sequencing['children'] as $objective){
1450 if($objective['name']=='IMSSS:PRIMARYOBJECTIVE'){
1451 //Xac dinh primary objective de lay thong so
1452 foreach ($objective['children'] as $primaryobjective){
1453 if($primaryobjective['name']=='IMSSS:MINNORMALIZEDMEASURE'){ $scoes->elements[$manifest][$parent->organization][$parent->identifier]->minnormalizedmeasure = $primaryobjective['tagData'];
1454 }
1455 }
1456 }
1457 }
1458 }
1459 if ($sequencing['name']=='IMSSS:LIMITCONDITIONS'){
1460 //Xu ly cac cac gia tri cac dieu kien gioi han
1461 if (!empty($sequencing['attrs']['ATTEMPTLIMIT'])){
1462 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptLimit = $sequencing['attrs']['ATTEMPTLIMIT'];
1463 }
1464 if (!empty($sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'])){
1465 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptAbsoluteDurationLimit = $sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'];
1466 }
1467 }
1468 if ($sequencing['name']=='IMSSS:ROLLUPRULES'){
1469 $rolluprules = array();
1470 //Phan danh cho RollupRule
1471 if (!empty($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED'])){
1472 if ($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED']== 'false'){
1473 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupobjectivesatisfied = 0;
1474 }
1475 }
1476 if (!empty($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION'])){
1477 if ($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION']== 'false'){
1478 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupprogresscompletion = 0;
1479 }
1480 }
1481 if (!empty($sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'])){
1482 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->objectivemeasureweight = $sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'];
1483 }
1484
1485 if (!empty($sequencing['children'])){
1486 foreach ($sequencing['children'] as $sequencingrolluprule){
1487 if ($sequencingrolluprule['name']=='IMSSS:ROLLUPRULE' ){
1488 $rolluprule = new stdClass();
1489 if ($sequencingrolluprule['attrs']['CHILDACTIVITYSET'] !=' '){
1490 $rolluprule->childactivityset = $sequencingrolluprule['attrs']['CHILDACTIVITYSET'];
1491 ////fwrite($ft,"\n Thiet lap them 1 childActivitySet la ".$rolluprule->childactivityset);
1492
1493 //Phan xu ly danh sach condition
1494 if (!empty($sequencingrolluprule['children'])){
1495 foreach ($sequencingrolluprule['children'] as $rolluproleconditions)
1496 {
1497 if ($rolluproleconditions['name']=='IMSSS:ROLLUPCONDITIONS'){
1498 $conditions = array();
1499 if (!empty($rolluproleconditions['attrs']['conditionCombination'])){
1500 $rolluprule->conditionCombination = $rolluproleconditions['attrs']['conditionCombination'];
1501 }
1502 foreach ($rolluproleconditions['children'] as $rolluprulecondition){
1503 if ($rolluprulecondition['name']=='IMSSS:ROLLUPCONDITION'){
1504 $condition = new stdClass();
1505 if (!empty($rolluprulecondition['attrs']['OPERATOR'])){
1506 $condition->operator = $rolluprulecondition['attrs']['OPERATOR'];
1507 }
1508 if (!empty($rolluprulecondition['attrs']['CONDITION'])){
1509 $condition->condition = $rolluprulecondition['attrs']['CONDITION'];
1510 }
1511 array_push($conditions,$condition);
1512 ////fwrite($ft,"Da them mot rolluprulecondition");
1513 }
1514
1515 }
1516 $rolluprule->conditions = $conditions;
1517 }
1518 if ($rolluproleconditions['name']=='IMSSS:ROLLUPACTION'){
1519 $rolluprule->rollupruleaction = $rolluproleconditions['attrs']['ACTION'];
1520 }
1521 }
1522 }
1523 //Ket thuc xu ly danh sach condition
1524
1525 }
1526 ////fwrite($ft,"\n Dua them 1 rule vao \n");
1527 array_push($rolluprules, $rolluprule);
1528 ////fwrite($ft,"\n Dua them 1 rule vao mang \n");
1529 }
1530
1531 }
1532 }
1533 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules = $rolluprules;
1534
1535// ////fwrite($ft,"\n >>>>NOW TEST ");
1536// foreach ($scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules as $rolluptest){
1537// ////fwrite($ft,"\n >>>> Gia tri Test thu duoc la:".$rolluptest->childactivityset);
1538
1539 }
1540
1541
1542
1543 if ($sequencing['name']=='IMSSS:SEQUENCINGRULES'){
1544 //Xu ly cac dieu kien Rules cua Sequencing
1545 //////fwrite($ft,"\n Xuat hien SEQUENCINGRULES >>>>>>>>>>");
1546 $sequencingrules = array();
1547 foreach ($sequencing['children'] as $conditionrules){
1548 if($conditionrules['name']=='IMSSS:EXITCONDITIONRULE'){
1549 $sequencingrule = new stdClass();
1550 //Phan xu ly danh sach condition
1551 //////fwrite($ft,"\n Xuat hien exitrule >>>>>>>>>>");
1552 if (!empty($conditionrules['children'])){
1553 foreach ($conditionrules['children'] as $conditionrule)
1554 {
1555 if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
1556 $ruleconditions = array();
1557 if (!empty($conditionrule['attrs']['conditionCombination'])){
1558 $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
1559 }
1560 foreach ($conditionrule['children'] as $rulecondition){
1561 if ($rulecondition['name']=='IMSSS:RULECONDITION'){
1562 $condition = new stdClass();
1563 if (!empty($rulecondition['attrs']['OPERATOR'])){
1564 $condition->operator = $rulecondition['attrs']['OPERATOR'];
1565 }
1566 if (!empty($rulecondition['attrs']['CONDITION'])){
1567 $condition->condition = $rulecondition['attrs']['CONDITION'];
1568 }
1569 if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
1570 $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
1571 }
1572 if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
1573 $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
1574 }
1575 array_push($ruleconditions,$condition);
1576 ////fwrite($ft,"\n Da them mot rulecondition trong exitrule");
1577 }
1578
1579 }
1580 $sequencingrule->ruleconditions = $ruleconditions;
1581 }
1582 if ($conditionrule['name']=='IMSSS:RULEACTION'){
1583 $sequencingrule->exitconditionruleaction = $conditionrule['attrs']['ACTION'];
1584 }
1585 }
1586 }
1587 //Ket thuc xu ly danh sach condition
1588 array_push($sequencingrules,$sequencingrule);
1589 }
1590 if ($conditionrules['name']=='IMSSS:PRECONDITIONRULE'){
1591 $sequencingrule = new stdClass();
1592 //Phan xu ly danh sach condition
1593 if (!empty($conditionrules['children'])){
1594 foreach ($conditionrules['children'] as $conditionrule)
1595 {
1596 if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
1597 $ruleconditions = array();
1598 if (!empty($conditionrule['attrs']['conditionCombination'])){
1599 $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
1600 }
1601 foreach ($conditionrule['children'] as $rulecondition){
1602 if ($rulecondition['name']=='IMSSS:RULECONDITION'){
1603 $condition = new stdClass();
1604 if (!empty($rulecondition['attrs']['OPERATOR'])){
1605 $condition->operator = $rulecondition['attrs']['OPERATOR'];
1606 }
1607 if (!empty($rulecondition['attrs']['CONDITION'])){
1608 $condition->condition = $rulecondition['attrs']['CONDITION'];
1609 }
1610 if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
1611 $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
1612 }
1613 if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
1614 $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
1615 }
1616 array_push($ruleconditions,$condition);
1617 ////fwrite($ft,"\n Da them mot rulecondition trong prerule");
1618 }
1619
1620 }
1621 $sequencingrule->ruleconditions = $ruleconditions;
1622 }
1623 if ($conditionrule['name']=='IMSSS:RULEACTION'){
1624 $sequencingrule->preconditionruleaction = $conditionrule['attrs']['ACTION'];
1625 }
1626 }
1627 }
1628 //Ket thuc xu ly danh sach condition
1629 array_push($sequencingrules,$sequencingrule);
1630 }
1631 if($conditionrules['name']=='IMSSS:POSTCONDITIONRULE'){
1632 $sequencingrule = new stdClass();
1633 //Phan xu ly danh sach condition
1634 if (!empty($conditionrules['children'])){
1635 foreach ($conditionrules['children'] as $conditionrule)
1636 {
1637 if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
1638 $ruleconditions = array();
1639 if (!empty($conditionrule['attrs']['conditionCombination'])){
1640 $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
1641 }
1642 foreach ($conditionrule['children'] as $rulecondition){
1643 if ($rulecondition['name']=='IMSSS:RULECONDITION'){
1644 $condition = new stdClass();
1645 if (!empty($rulecondition['attrs']['OPERATOR'])){
1646 $condition->operator = $rulecondition['attrs']['OPERATOR'];
1647 }
1648 if (!empty($rulecondition['attrs']['CONDITION'])){
1649 $condition->condition = $rulecondition['attrs']['CONDITION'];
1650 }
1651 if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
1652 $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
1653 }
1654 if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
1655 $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
1656 }
1657 array_push($ruleconditions,$condition);
1658 ////fwrite($ft,"\n Da them mot rulecondition trong postrule");
1659 }
1660
1661 }
1662 $sequencingrule->ruleconditions = $ruleconditions;
1663 }
1664 if ($conditionrule['name']=='IMSSS:RULEACTION'){
1665 $sequencingrule->postconditionruleaction = $conditionrule['attrs']['ACTION'];
1666 }
1667 }
1668 }
1669 //Ket thuc xu ly danh sach condition
1670 array_push($sequencingrules,$sequencingrule);
1671 }
1672 $scoes->elements[$manifest][$parent->organization][$parent->identifier]->sequencingrules = $sequencingrules;
1673 }
1674 }
1675 }
1676
1677 break;
1678
1679 }
1680 }
1681 }
1682
1683 return $scoes;
1684}
1685
1686function scorm_parse_scorm($pkgdir,$scormid) {
1687 global $CFG;
1688
1689 //$f = "D:\\test.txt";
1690 //@$ft = fopen($f,"a");
1691 //////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_scorm \n");
1692
1693 $launch = 0;
1694 $manifestfile = $pkgdir.'/imsmanifest.xml';
1695
1696 if (is_file($manifestfile)) {
1697
1698 $xmlstring = file_get_contents($manifestfile);
1699 $objXML = new xml2Array();
1700 $manifests = $objXML->parse($xmlstring);
1701
1702 $scoes = new stdClass();
1703 $scoes->version = '';
1704 $scoes = scorm_get_manifest($manifests,$scoes);
1705
1706 if (count($scoes->elements) > 0) {
1707 foreach ($scoes->elements as $manifest => $organizations) {
1708 foreach ($organizations as $organization => $items) {
1709 foreach ($items as $identifier => $item) {
1710 $item->scorm = $scormid;
1711 $item->manifest = $manifest;
1712 $item->organization = $organization;
1713 //////fwrite($ft,"\n ---- Item chuan bi dua vao la ".$item->identifier);
1714 $id = insert_record('scorm_scoes',$item);
1715 //////fwrite($ft,"\n Lay duoc ScoID la ".$id);
1716 $item->scormid = $scormid;
1717 $item->scoid = $id;
1718 $idControlMode = insert_record('scorm_sequencing_controlmode',$item);
1719
1720 if (!empty($item->sequencingrules)){
1721 ////fwrite($ft,"\n ++++++++Them SequencingRules cho SCO: ".$item->scoid) ;
1722 foreach($item->sequencingrules as $sequencingrule){
1723 ////fwrite($ft,"\n ----Chuan bi them 1 sequencingrule vao CSDL: ");
1724 $sequencingrule->scormid = $scormid;
1725 $sequencingrule->scoid = $item->scoid;
1726 ////fwrite($ft,"\n ----Thong tin Scormid: ".$sequencingrule->scormid);
1727 ////fwrite($ft,"\n ----Thong tin Scoid: ".$sequencingrule->scoid);
1728 $idruleconditions = insert_record('scorm_sequencing_ruleconditions',$sequencingrule);
1729 foreach($sequencingrule->ruleconditions as $rulecondition){
1730 $rulecondition->scormid = $sequencingrule->scormid;
1731 $rulecondition->scoid = $sequencingrule->scoid;
1732 $rulecondition->ruleconditionsid = $idruleconditions;
1733 $idrulecondition = insert_record('scorm_sequencing_rulecondition',$rulecondition);
1734 ////fwrite($ft,"\n ----Da them 1 sequencingrulecondition vao CSDL: ");
1735 }
1736
1737 }
1738 }
1739
1740 if (!empty($item->rolluprules)){
1741 ////fwrite($ft,"\n ++++++++Them RollupRules cho SCO: ".$item->scoid) ;
1742 $idControlMode = insert_record('scorm_sequencing_rolluprules',$item);
1743 ////fwrite($ft,"\n ----Gia tri idRollupRules \n");
1744 foreach($item->rolluprules as $rollup)
1745 {
1746 ////fwrite($ft,"\n ----Chuan bi them 1 rule vao CSDL ");
1747 $rollup->rolluprulesid =$idControlMode;
1748 $rollup->scormid = $scormid;
1749 $rollup->scoid = $item->scoid;
1750
1751 ////fwrite($ft,"\n ----Cac thong tin cua Rule: \n ");
1752 ////fwrite($ft,"\n ----rolluprulesid: ".$rollup->rolluprulesid);
1753 ////fwrite($ft,"\n ----scormid: ".$rollup->scormid );
1754 ////fwrite($ft,"\n ----scoid: ".$rollup->scoid);
1755 ////fwrite($ft,"\n ----activichild: ".$rollup->childactivityset);
1756 ////fwrite($ft,"\n ----rollupaction: ".$rollup->rollupruleaction);
1757 $idRollupRule = insert_record('scorm_sequencing_rolluprule',$rollup);
1758 ////fwrite($ft,"\n ----Dua them 1 rule vao CSDL -- Chuan bi them condition vao rule".$idRollupRule);
1759 $rollup->rollupruleid = $idRollupRule;
1760 $idconditions = insert_record('scorm_sequencing_rollupruleconditions',$rollup);
1761 ////fwrite($ft,"\n --Dua cac condition con vao CSDL");
1762 foreach($rollup->conditions as $condition){
1763 $condition->ruleconditionsid = $idconditions;
1764 $condition->scormid = $rollup->scormid;
1765 $condition->scoid = $rollup->scoid;
1766 $idcondition = insert_record('scorm_sequencing_rolluprulecondition',$condition);
1767 ////fwrite($ft,"\n --Da dua them 1 condition vao CSDL");
1768 }
1769
1770
1771 }
1772 }
1773 if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
1774 $launch = $id;
1775 }
1776 }
1777 }
1778 }
1779 set_field('scorm','version',$scoes->version,'id',$scormid);
1780 }
1781 }
1782
1783 return $launch;
1784}
1785
1786function scorm_course_format_display($user,$course) {
1787 global $CFG;
1788
1789 $strupdate = get_string('update');
1790 $strmodule = get_string('modulename','scorm');
1791
1792 echo '<div class="mod-scorm">';
1793 if ($scorms = get_all_instances_in_course('scorm', $course)) {
1794 // The module SCORM activity with the least id is the course
1795 $scorm = current($scorms);
1796 if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
1797 error("Course Module ID was incorrect");
1798 }
1799 $colspan = '';
1800 $headertext = '<table width="100%"><tr><td class="title">'.get_string('name').': <b>'.format_string($scorm->name).'</b>';
1801 if (isteacher($course->id, $user->id, true)) {
1802 if (isediting($course->id)) {
1803 // Display update icon
1804 $path = $CFG->wwwroot.'/course';
1805 $headertext .= '<span class="commands">'.
1806 '<a title="'.$strupdate.'" href="'.$path.'/mod.php?update='.$cm->id.'&amp;sesskey='.sesskey().'">'.
1807 '<img src="'.$CFG->pixpath.'/t/edit.gif" hspace="2" height="11" width="11" border="0" alt="'.$strupdate.'" /></a></span>';
1808 }
1809 $headertext .= '</td>';
1810 // Display report link
1811 $trackedusers = get_record('scorm_scoes_track', 'scormid', $scorm->id, '', '', '', '', 'count(distinct(userid)) as c');
1812 if ($trackedusers->c > 0) {
1813 $headertext .= '<td class="reportlink">'.
1814 '<a target="'.$CFG->framename.'" href="'.$CFG->wwwroot.'/mod/scorm/report.php?id='.$cm->id.'">'.
1815 get_string('viewallreports','scorm',$trackedusers->c).'</a>';
1816 } else {
1817 $headertext .= '<td class="reportlink">'.get_string('noreports','scorm');
1818 }
1819 $colspan = ' colspan="2"';
1820 }
1821 $headertext .= '</td></tr><tr><td'.$colspan.'>'.format_text(get_string('summary').':<br />'.$scorm->summary).'</td></tr></table>';
1822 print_simple_box($headertext,'','100%');
1823 scorm_view_display($user, $scorm, 'view.php?id='.$course->id, $cm, '100%');
1824 } else {
1825 if (isteacheredit($course->id, $user->id)) {
1826 // Create a new activity
1827 redirect('mod.php?id='.$course->id.'&amp;section=0&sesskey='.sesskey().'&amp;add=scorm');
1828 } else {
1829 notify('Could not find a scorm course here');
1830 }
1831 }
1832 echo '</div>';
1833}
1834
1835function scorm_view_display ($user, $scorm, $action, $cm, $blockwidth='') {
1836 global $CFG;
1837 $organization = optional_param('organization', '', PARAM_INT);
1838
1839 print_simple_box_start('center',$blockwidth);
1840?>
1841 <div class="structurehead"><?php print_string('coursestruct','scorm') ?></div>
1842<?php
1843 if (empty($organization)) {
1844 $organization = $scorm->launch;
1845 }
1846 if ($orgs = get_records_select_menu('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,title')) {
1847 if (count($orgs) > 1) {
1848 ?>
1849 <div class='center'>
1850 <?php print_string('organizations','scorm') ?>
1851 <form name='changeorg' method='post' action='<?php echo $action ?>'>
1852 <?php choose_from_menu($orgs, 'organization', "$organization", '','submit()') ?>
1853 </form>
1854 </div>
1855<?php
1856 }
1857 }
1858 $orgidentifier = '';
1859 if ($org = get_record('scorm_scoes','id',$organization)) {
1860 if (($org->organization == '') && ($org->launch == '')) {
1861 $orgidentifier = $org->identifier;
1862 } else {
1863 $orgidentifier = $org->organization;
1864 }
1865 }
1866 $result = scorm_get_toc($user,$scorm,'structlist',$orgidentifier);
1867 $incomplete = $result->incomplete;
1868// echo ("Toc ---");
1869 echo $result->toc;
1870// echo ("Ket thuc");
1871 print_simple_box_end();
1872?>
1873 <div class="center">
1874 <form name="theform" method="post" action="<?php echo $CFG->wwwroot ?>/mod/scorm/player.php?id=<?php echo $cm->id ?>"<?php echo $scorm->popup == 1?' target="newwin"':'' ?>>
1875 <?php
1876
1877// Thiet lap suspend
1878 $suspend = get_record("scorm_suspendtrack","scormid",$scorm->id,"userid",$user->id);
1879
1880//------------------
1881 if ($scorm->hidebrowse == 0) {
1882 print_string("mode","scorm");
1883 echo ': <input type="radio" id="b" name="mode" value="browse" /><label for="b">'.get_string('browse','scorm').'</label>'."\n";
1884 if ($incomplete === true) {
1885 echo '<input type="radio" id="n" name="mode" value="normal" checked="checked" /><label for="n">'.get_string('normal','scorm')."</label>\n";
1886
1887 //Neu co luu tru thi co the chon continue de tiep tu
1888 if (!empty($suspend))
1889 {
1890 echo '<input type="radio" id="n" name="mode" value="continue" checked="checked" /><label for="n">'.get_string('continue','scorm')."</label>\n";
1891 }
1892
1893 } else {
1894 echo '<input type="radio" id="r" name="mode" value="review" checked="checked" /><label for="r">'.get_string('review','scorm')."</label>\n";
1895 }
1896 } else {
1897 if ($incomplete === true) {
1898 echo '<input type="hidden" name="mode" value="normal" />'."\n";
1899 } else {
1900 echo '<input type="hidden" name="mode" value="review" />'."\n";
1901 }
1902 }
1903 if (($incomplete === false) && (($result->attemptleft > 0)||($scorm->maxattempt == 0))) {
1904?>
1905 <br />
1906 <input type="checkbox" id="a" name="newattempt" />
1907 <label for="a"><?php print_string('newattempt','scorm') ?></label>
1908<?php
1909 }
1910 ?>
1911 <br />
1912 <input type="hidden" name="scoid" />
1913 <input type="hidden" name="currentorg" value="<?php echo $orgidentifier ?>" />
1914 <input type="submit" value="<?php print_string('entercourse','scorm') ?>" />
1915 </form>
1916 </div>
1917<?php
1918}
1919
1920function scorm_update_status($scormid,$scoid)
1921{
1922
1923}
1924
1925
1926function scorm_repeater($what, $times) {
1927 if ($times <= 0) {
1928 return null;
1929 }
1930 $return = '';
1931 for ($i=0; $i<$times;$i++) {
1932 $return .= $what;
1933 }
1934 return $return;
1935}
1936
1937//chuyen toi SCO duoc thuc hien tiep theo
1938function scorm_get_nextsco($scormid,$scoid)
1939{
1940
1941
1942
1943}
1944//Chuyen toi SCO duoc thuc hien truoc
1945function scorm_get_presco($scormid,$scoid)
1946{
1947
1948
1949
1950}
1951//Xac dinh xem doi tuong do co cho phep lua chon khong
1952function scorm_isChoice($scormid,$scoid)
1953{
1954// //$f = "D:\\test.txt";
1955// //@$ft = fopen($f,"a");
1956 $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);
1957// ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scormid la ".$scormid." scoid la: ".$scoid);
1958 $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);
1959// ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scoparent scormid la ".$scormid." scoid la: ".$scoparent->scoid);
1960
1961
1962// ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice gia tri la: ".$scoparent->choice);
1963 return $scoparent->choice;
1964}
1965
1966//Xac dinh xem doi tuong do co cho phep lua chon thoat khong
1967function scorm_isChoiceexit($scormid,$scoid)
1968{
1969 $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);
1970 $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);
1971
1972 return $scoparent->choiceexit;
1973}
1974/* Usage
1975 Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML;
1976
1977 $objXML = new xml2Array();
1978 $arrOutput = $objXML->parse($strYourXML);
1979 print_r($arrOutput); //print it out, or do whatever!
1980
1981*/
1982class xml2Array {
1983
1984 var $arrOutput = array();
1985 var $resParser;
1986 var $strXmlData;
1987
1988 /**
1989 * Convert a utf-8 string to html entities
1990 *
1991 * @param string $str The UTF-8 string
1992 * @return string
1993 */
1994 function utf8_to_entities($str) {
1995 $entities = '';
1996 $values = array();
1997 $lookingfor = 1;
1998
1999 for ($i = 0; $i < strlen($str); $i++) {
2000 $thisvalue = ord($str[$i]);
2001 if ($thisvalue < 128) {
2002 $entities .= $str[$i]; // Leave ASCII chars unchanged
2003 } else {
2004 if (count($values) == 0) {
2005 $lookingfor = ($thisvalue < 224) ? 2 : 3;
2006 }
2007 $values[] = $thisvalue;
2008 if (count($values) == $lookingfor) {
2009 $number = ($lookingfor == 3) ?
2010 (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64):
2011 (($values[0] % 32) * 64) + ($values[1] % 64);
2012 $entities .= '&#' . $number . ';';
2013 $values = array();
2014 $lookingfor = 1;
2015 }
2016 }
2017 }
2018 return $entities;
2019 }
2020
2021 /**
2022 * Parse an XML text string and create an array tree that rapresent the XML structure
2023 *
2024 * @param string $strInputXML The XML string
2025 * @return array
2026 */
2027 function parse($strInputXML) {
2028 $this->resParser = xml_parser_create ('UTF-8');
2029 xml_set_object($this->resParser,$this);
2030 xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
2031
2032 xml_set_character_data_handler($this->resParser, "tagData");
2033
2034 $this->strXmlData = xml_parse($this->resParser,$strInputXML );
2035 if(!$this->strXmlData) {
2036 die(sprintf("XML error: %s at line %d",
2037 xml_error_string(xml_get_error_code($this->resParser)),
2038 xml_get_current_line_number($this->resParser)));
2039 }
2040
2041 xml_parser_free($this->resParser);
2042
2043 return $this->arrOutput;
2044 }
2045
2046 function tagOpen($parser, $name, $attrs) {
2047 $tag=array("name"=>$name,"attrs"=>$attrs);
2048 array_push($this->arrOutput,$tag);
2049 }
2050
2051 function tagData($parser, $tagData) {
2052 if(trim($tagData)) {
2053 if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
2054 $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $this->utf8_to_entities($tagData);
2055 } else {
2056 $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $this->utf8_to_entities($tagData);
2057 }
2058 }
2059 }
2060
2061 function tagClosed($parser, $name) {
2062 $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1];
2063 array_pop($this->arrOutput);
2064 }
2065
2066}
2067?>