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