ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilObjSCORMTracking.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */
4
13{
14
15 function extractData()
16 {
17 $this->insert = array();
18 if (is_array($_GET["iL"]))
19 {
20 foreach($_GET["iL"] as $key => $value)
21 {
22 $this->insert[] = array("left" => $value, "right" => $_GET["iR"][$key]);
23 }
24 }
25 if (is_array($_POST["iL"]))
26 {
27 foreach($_POST["iL"] as $key => $value)
28 {
29 $this->insert[] = array("left" => $value, "right" => $_POST["iR"][$key]);
30 }
31 }
32
33 $this->update = array();
34 if (is_array($_GET["uL"]))
35 {
36 foreach($_GET["uL"] as $key => $value)
37 {
38 $this->update[] = array("left" => $value, "right" => $_GET["uR"][$key]);
39 }
40 }
41 if (is_array($_POST["uL"]))
42 {
43 foreach($_POST["uL"] as $key => $value)
44 {
45 $this->update[] = array("left" => $value, "right" => $_POST["uR"][$key]);
46 }
47 }
48 }
49
50 function store($obj_id=0, $sahs_id=0, $extractData=1)
51 {
52 global $ilDB, $ilUser;
53
54 $ref_id = $_GET["ref_id"];
55 if (empty($obj_id))
56 {
57 $obj_id = ilObject::_lookupObjId($_GET["ref_id"]);
58 }
59
60 // writing to scorm test log
61 $f = fopen("./Modules/ScormAicc/log/scorm.log", "a");
62 fwrite($f, "\nCALLING SCORM store()\n");
63 fwrite($f,'POST: '.print_r($_POST,true));
64
65
66 if (empty($sahs_id))
67 $sahs_id = ($_GET["sahs_id"] != "") ? $_GET["sahs_id"] : $_POST["sahs_id"];
68
69 if ($extractData==1)
70 $this->extractData();
71
72 if (is_object($ilUser))
73 {
74 $user_id = $ilUser->getId();
75 }
76
77
78
79 if ($obj_id <= 1)
80 {
81 fwrite($f, "Error: No obj_id given.\n");
82 }
83 else
84 {
85 foreach($this->insert as $insert)
86 {
87 $set = $ilDB->queryF('
88 SELECT * FROM scorm_tracking
89 WHERE user_id = %s
90 AND sco_id = %s
91 AND lvalue = %s
92 AND obj_id = %s',
93 array('integer','integer','text','integer'),
94 array($user_id,$sahs_id,$insert["left"],$obj_id));
95 if ($rec = $ilDB->fetchAssoc($set))
96 {
97 fwrite($f, "Error Insert, left value already exists. L:".$insert["left"].",R:".
98 $insert["right"].",sahs_id:".$sahs_id.",user_id:".$user_id."\n");
99 }
100 else
101 {
102 $ilDB->insert('scorm_tracking', array(
103 'obj_id' => array('integer', $obj_id),
104 'user_id' => array('integer', $user_id),
105 'sco_id' => array('integer', $sahs_id),
106 'lvalue' => array('text', $insert["left"]),
107 'rvalue' => array('clob', $insert["right"]),
108 'c_timestamp' => array('timestamp', ilUtil::now())
109 ));
110
111 fwrite($f, "Insert - L:".$insert["left"].",R:".
112 $insert["right"].",sahs_id:".$sahs_id.",user_id:".$user_id."\n");
113 }
114 }
115 foreach($this->update as $update)
116 {
117 $set = $ilDB->queryF('
118 SELECT * FROM scorm_tracking
119 WHERE user_id = %s
120 AND sco_id = %s
121 AND lvalue = %s
122 AND obj_id = %s',
123 array('integer','integer','text','integer'),
124 array($user_id,$sahs_id,$update["left"],$obj_id));
125
126 if ($rec = $ilDB->fetchAssoc($set))
127 {
128 $ilDB->update('scorm_tracking',
129 array(
130 'rvalue' => array('clob', $update["right"]),
131 'c_timestamp' => array('timestamp', ilUtil::now())
132 ),
133 array(
134 'user_id' => array('integer', $user_id),
135 'sco_id' => array('integer', $sahs_id),
136 'lvalue' => array('text', $update["left"]),
137 'obj_id' => array('integer', $obj_id)
138 )
139 );
140 }
141 else
142 {
143 fwrite($f, "ERROR Update, left value does not exist. L:".$update["left"].",R:".
144 $update["right"].",sahs_id:".$sahs_id.",user_id:".$user_id."\n");
145 }
146
147 }
148 }
149 fclose($f);
150
151 // update status
152 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
153 ilLPStatusWrapper::_updateStatus($obj_id, $user_id);
154
155 // update time and numbers of attempts in change event
156 //NOTE: is possibly not correct (it is count of commit with changed values); be careful to performance issues
157 ilObjSCORMTracking::_syncReadEvent($obj_id, $user_id, "sahs", $ref_id);
158 }
159
160 public static function storeJsApi($obj_id=0) {
161 // global $ilLog, $ilUser;
162
163 // if (is_object($ilUser)) {
164 // $user_id = $ilUser->getId();
165 // }
166 // if (empty($obj_id)) $obj_id = ilObject::_lookupObjId($_GET["ref_id"]);
167 $obj_id = (int)$_GET["package_id"];
168 $in = file_get_contents("php://input");
169 // $ilLog->write($in);
170 $data = json_decode($in);
171 $user_id = (int)$data->p;
172
173 header('Content-Type: text/plain; charset=UTF-8');
174
175 $rval=self::storeJsApiCmi($user_id,$obj_id,$data);
176 if($rval!=true) {
177 print("storeJsApiCmi failed");
178 } else {
179 $rval=self::syncGlobalStatus($user_id, $obj_id, $data, $data->now_global_status);
180 if($rval!=true) print("syncGlobalStatus failed");
181 }
182 if($rval==true) print("ok");
183 }
184
185 public static function storeJsApiCmi($user_id, $obj_id, $data) {
186 global $ilLog, $ilDB;
187
188 $b_updateStatus=false;
189
190 $b_messageLog=false;
191 if ($ilLog->current_log_level == 30)
192 $b_messageLog=true;
193
194 if ($b_messageLog)
195 $ilLog->write("ScormAicc: CALLING SCORM storeJsApi() ".$_POST);
196
197
198 $aa_data = array();
199 // if (is_array($_POST["S"])) {
200 // foreach($_POST["S"] as $key => $value) {
201 // $aa_data[] = array("sco_id" => $value, "left" => $_POST["L"][$key], "right" => $_POST["R"][$key]);
202 // }
203 // }
204 for ($i=0;$i<count($data->cmi);$i++) {
205 $aa_data[] = array("sco_id" => (int) $data->cmi[$i][0], "left" => $data->cmi[$i][1], "right" => $data->cmi[$i][2]);
206// $aa_data[] = array("sco_id" => (int) $data->cmi[$i][0], "left" => $data->cmi[$i][1], "right" => rawurldecode($data->cmi[$i][2]));
207 }
208
209 if ($obj_id <= 1) {
210 $ilLog->write("ScormAicc: storeJsApi: Error: No valid obj_id given.");
211 }
212 else {
213 foreach($aa_data as $a_data) {
214 $set = $ilDB->queryF('
215 SELECT rvalue FROM scorm_tracking
216 WHERE user_id = %s
217 AND sco_id = %s
218 AND lvalue = %s
219 AND obj_id = %s',
220 array('integer','integer','text','integer'),
221 array($user_id,$a_data["sco_id"],$a_data["left"],$obj_id));
222 if ($rec = $ilDB->fetchAssoc($set)) {
223 if ($a_data["left"] == 'cmi.core.lesson_status' && $a_data["right"] != $rec["rvalue"]) {
224 $b_updateStatus = true;
225 }
226 $ilDB->update('scorm_tracking',
227 array(
228 'rvalue' => array('clob', $a_data["right"]),
229 'c_timestamp' => array('timestamp', ilUtil::now())
230 ),
231 array(
232 'user_id' => array('integer', $user_id),
233 'sco_id' => array('integer', $a_data["sco_id"]),
234 'lvalue' => array('text', $a_data["left"]),
235 'obj_id' => array('integer', $obj_id)
236 )
237 );
238 if ($b_messageLog) {
239 $ilLog->write("ScormAicc: storeJsApi Updated - L:".$a_data["left"].",R:".
240 $a_data["right"]." for obj_id:".$obj_id.",sco_id:".$a_data["sco_id"].",user_id:".$user_id);
241 }
242 }
243 else {
244 if ($a_data["left"] == 'cmi.core.lesson_status') {
245 $b_updateStatus = true;
246 }
247 $ilDB->insert('scorm_tracking', array(
248 'obj_id' => array('integer', $obj_id),
249 'user_id' => array('integer', $user_id),
250 'sco_id' => array('integer', $a_data["sco_id"]),
251 'lvalue' => array('text', $a_data["left"]),
252 'rvalue' => array('clob', $a_data["right"]),
253 'c_timestamp' => array('timestamp', ilUtil::now())
254 ));
255 if ($b_messageLog) {
256 $ilLog->write("ScormAicc: storeJsApi Inserted - L:".$a_data["left"].",R:".
257 $a_data["right"]." for obj_id:".$obj_id.",sco_id:".$a_data["sco_id"].",user_id:".$user_id);
258 }
259 }
260 }
261 }
262
263 // update status
264 // if ($b_updateStatus == true) {
265 // include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
266 // ilLPStatusWrapper::_updateStatus($obj_id, $user_id);
267 // }
268
269 return true;
270 }
271
272//erase later see ilSCORM2004StoreData
273 public static function syncGlobalStatus($userId, $packageId, $data, $new_global_status) {
274
275 global $ilDB, $ilLog;
276 $saved_global_status=$data->saved_global_status;
277 $ilLog->write("saved_global_status=".$saved_global_status);
278
279 //last_visited!
280
281 // get attempts
282 if (!$data->packageAttempts) {
283 $val_set = $ilDB->queryF('SELECT package_attempts FROM sahs_user WHERE obj_id = %s AND user_id = %s',
284 array('integer','integer'), array($packageId,$userId));
285 $val_rec = $ilDB->fetchAssoc($val_set);
286 $attempts = $val_rec["package_attempts"];
287 } else {
288 $attempts=$data->packageAttempts;
289 }
290 if ($attempts == null) $attempts = 1;
291
292 //update percentage_completed, sco_total_time_sec,status in sahs_user
293 $totalTime=(int)$data->totalTimeCentisec;
294 $totalTime=round($totalTime/100);
295 $ilDB->queryF('UPDATE sahs_user SET sco_total_time_sec=%s, status=%s, percentage_completed=%s, package_attempts=%s WHERE obj_id = %s AND user_id = %s',
296 array('integer', 'integer', 'integer', 'integer', 'integer', 'integer'),
297 array($totalTime, $new_global_status, $data->percentageCompleted, $attempts, $packageId, $userId));
298
299// self::ensureObjectDataCacheExistence();
300 global $ilObjDataCache;
301 include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
302 ilChangeEvent::_recordReadEvent("sahs", (int)$_GET['ref_id'],$packageId, $userId, false, $attempts, $totalTime);
303
304 //end sync access number and time in read event table
305
306 // update learning progress
307 if ($new_global_status != null) {//could only happen when synchronising from SCORM Offline Player
308 include_once("./Services/Tracking/classes/class.ilObjUserTracking.php");
309 include_once("./Services/Tracking/classes/class.ilLPStatus.php");
310 ilLPStatus::writeStatus($packageId, $userId,$new_global_status,$data->percentageCompleted);
311
312// here put code for soap to MaxCMS e.g. when if($saved_global_status != $new_global_status)
313 }
314 return true;
315 }
316
317
324 public static function _syncReadEvent($a_obj_id, $a_user_id, $a_type, $a_ref_id)
325 {
326 global $ilDB, $ilLog;
327 $val_set = $ilDB->queryF('SELECT package_attempts, total_time_sec, sco_total_time_sec, time_from_lms FROM sahs_user, sahs_lm '
328 .'WHERE sahs_user.obj_id = %s AND sahs_user.user_id = %s AND sahs_user.obj_id = sahs_lm.id',
329 array('integer','integer'),
330 array($a_obj_id,$a_user_id));
331
332 $val_rec = $ilDB->fetchAssoc($val_set);
333
334 if ($val_rec["package_attempts"] == null) {
335 $val_rec["package_attempts"]="";
336 }
337 $attempts = $val_rec["package_attempts"];
338
339 $time = 0;
340 // if ($val_rec["time_from_lms"] == "y") {
341 // $time = (int)$val_rec["total_time_sec"];
342 // } else {
343 $time = (int)$val_rec["sco_total_time_sec"];
344 // }
345
346 // get learning time for old ILIAS-Versions
347 if ($time == 0) {
348 $sco_set = $ilDB->queryF('
349 SELECT sco_id, rvalue FROM scorm_tracking
350 WHERE obj_id = %s
351 AND user_id = %s
352 AND lvalue = %s
353 AND sco_id <> %s',
354 array('integer','integer','text','integer'),
355 array($a_obj_id,$a_user_id, 'cmi.core.total_time',0));
356
357 while($sco_rec = $ilDB->fetchAssoc($sco_set))
358 {
359 $tarr = explode(":", $sco_rec["rvalue"]);
360 $sec = (int) $tarr[2] + (int) $tarr[1] * 60 +
361 (int) substr($tarr[0], strlen($tarr[0]) - 3) * 60 * 60;
362 $time += $sec;
363 }
364 }
365
366 include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
367 ilChangeEvent::_recordReadEvent($a_type, $a_ref_id, $a_obj_id, $a_user_id, false, $attempts, $time);
368 }
369
370 public static function _insertTrackData($a_sahs_id, $a_lval, $a_rval, $a_obj_id)
371 {
372 global $ilDB, $ilUser;
373
374 $ilDB->insert('scorm_tracking', array(
375 'obj_id' => array('integer', $a_obj_id),
376 'user_id' => array('integer', $ilUser->getId()),
377 'sco_id' => array('integer', $a_sahs_id),
378 'lvalue' => array('text', $a_lval),
379 'rvalue' => array('clob', $a_rval),
380 'c_timestamp' => array('timestamp', ilUtil::now())
381 ));
382
383 if ($a_lval == "cmi.core.lesson_status")
384 {
385 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
386 ilLPStatusWrapper::_updateStatus($a_obj_id, $ilUser->getId());
387 }
388 }
389
390
397 public static function _getInProgress($scorm_item_id,$a_obj_id,$a_blocked_user_ids = null)
398 {
399 global $ilDB;
400
401 if(is_array($scorm_item_id))
402 {
403 $in = $ilDB->in('sco_id', $scorm_item_id, false, 'integer');
404
405 $res = $ilDB->queryF('SELECT user_id,sco_id FROM scorm_tracking
406 WHERE '.$in.'
407 AND obj_id = %s
408 GROUP BY user_id, sco_id',
409 array('integer'),array($a_obj_id));
410
411 }
412 else
413 {
414 $res = $ilDB->queryF('SELECT user_id,sco_id FROM scorm_tracking
415 WHERE sco_id = %s
416 AND obj_id = %s',
417 array('integer','integer'),array($scorm_item_id,$a_obj_id)
418 );
419 }
420
421 $in_progress = array();
422
423 while($row = $ilDB->fetchObject($res))
424 {
425 // #15061 - see _getProgressInfo()
426 if(!($a_blocked_user_ids &&
427 is_array($a_blocked_user_ids[$row->sco_id]) &&
428 in_array($row->user_id, $a_blocked_user_ids[$row->sco_id])))
429 {
430 $in_progress[$row->sco_id][] = $row->user_id;
431 }
432 }
433 return $in_progress;
434 }
435
442 public static function _getCompleted($scorm_item_id,$a_obj_id)
443 {
444 global $ilDB;
445
446 if(is_array($scorm_item_id))
447 {
448 $in = $ilDB->in('sco_id', $scorm_item_id, false, 'integer');
449
450 $res = $ilDB->queryF('SELECT DISTINCT(user_id) FROM scorm_tracking
451 WHERE '.$in.'
452 AND obj_id = %s
453 AND lvalue = %s
454 AND ('.$ilDB->like('rvalue', 'clob', 'completed').' OR '.$ilDB->like('rvalue', 'clob', 'passed').')',
455 array('integer','text'),
456 array($a_obj_id,'cmi.core.lesson_status'));
457 }
458 else
459 {
460 $res = $ilDB->queryF('SELECT DISTINCT(user_id) FROM scorm_tracking
461 WHERE sco_id = %s
462 AND obj_id = %s
463 AND lvalue = %s
464 AND ('.$ilDB->like('rvalue', 'clob', 'completed').' OR '.$ilDB->like('rvalue', 'clob', 'passed').')',
465 array('integer','integer','text'),
466 array($scorm_item_id,$a_obj_id,'cmi.core.lesson_status'));
467 }
468
469 while($row = $ilDB->fetchObject($res))
470 {
471 $user_ids[] = $row->user_id;
472 }
473 return $user_ids ? $user_ids : array();
474 }
475
476 public static function _getCollectionStatus($a_scos, $a_obj_id, $a_user_id)
477 {
478 global $ilDB;
479
480
481 $status = "not_attempted";
482
483 if (is_array($a_scos))
484 {
485 $in = $ilDB->in('sco_id', $a_scos, false, 'integer');
486
487 $res = $ilDB->queryF('SELECT sco_id, rvalue FROM scorm_tracking
488 WHERE '.$in.'
489 AND obj_id = %s
490 AND lvalue = %s
491 AND user_id = %s',
492 array('integer','text', 'integer'),
493 array($a_obj_id,'cmi.core.lesson_status', $a_user_id));
494
495 $cnt = 0;
496 $completed = true;
497 $failed = false;
498 while ($rec = $ilDB->fetchAssoc($res))
499 {
500 if ($rec["rvalue"] == "failed")
501 {
502 $failed = true;
503 }
504 if ($rec["rvalue"] != "completed" && $rec["rvalue"] != "passed")
505 {
506 $completed = false;
507 }
508 $cnt++;
509 }
510 if ($cnt > 0)
511 {
512 $status = "in_progress";
513 }
514 if ($completed && $cnt == count($a_scos))
515 {
516 $status = "completed";
517 }
518 if ($failed)
519 {
520 $status = "failed";
521 }
522
523 }
524 return $status;
525 }
526
527
528 public static function _countCompleted($a_scos, $a_obj_id, $a_user_id)
529 {
530 global $ilDB;
531
532 if (is_array($a_scos))
533 {
534 $in = $ilDB->in('sco_id', $a_scos, false, 'integer');
535
536 $res = $ilDB->queryF('SELECT sco_id, rvalue FROM scorm_tracking
537 WHERE '.$in.'
538 AND obj_id = %s
539 AND lvalue = %s
540 AND user_id = %s',
541 array('integer','text', 'integer'),
542 array($a_obj_id,'cmi.core.lesson_status', $a_user_id));
543
544 $cnt = 0;
545 while ($rec = $ilDB->fetchAssoc($res))
546 {
547 if ($rec["rvalue"] == "completed" || $rec["rvalue"] == "passed")
548 {
549 $cnt++;
550 }
551 }
552 }
553 return $cnt;
554 }
555//not correct because of assets!
562 public static function lookupLastAccessTimes($a_obj_id)
563 {
564 global $ilDB;
565
566 $query = 'SELECT user_id, MAX(c_timestamp) tst '.
567 'FROM scorm_tracking '.
568 'WHERE obj_id = '.$ilDB->quote($a_obj_id,'integer').' '.
569 'GROUP BY user_id';
570 $res = $ilDB->query($query);
571
572 $users = array();
573 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
574 {
575 $users[$row->user_id] = $row->tst;
576 }
577 return $users;
578 }
579
580
586 public static function _getTrackedUsers($a_obj_id)
587 {
588 global $ilDB, $ilLog;
589
590 $res = $ilDB->queryF('SELECT DISTINCT user_id FROM scorm_tracking
591 WHERE obj_id = %s
592 AND lvalue = %s',
593 array('integer','text'),
594 array($a_obj_id,'cmi.core.lesson_status'));
595
596 $users = array();
597 while ($row = $ilDB->fetchAssoc($res))
598 {
599 $users[] = $row["user_id"];
600 }
601 return $users;
602 }
603
610 public static function _getFailed($scorm_item_id,$a_obj_id)
611 {
612 global $ilDB;
613
614 if(is_array($scorm_item_id))
615 {
616 $in = $ilDB->in('sco_id', $scorm_item_id, false, 'integer');
617
618 $res = $ilDB->queryF('
619 SELECT DISTINCT(user_id) FROM scorm_tracking
620 WHERE '.$in.'
621 AND obj_id = %s
622 AND lvalue = %s
623 AND '.$ilDB->like('rvalue', 'clob', 'failed').' ',
624 array('integer','text'),
625 array($a_obj_id,'cmi.core.lesson_status'));
626 }
627 else
628 {
629
630 $res = $ilDB->queryF('
631 SELECT DISTINCT(user_id) FROM scorm_tracking
632 WHERE sco_id = %s
633 AND obj_id = %s
634 AND lvalue = %s
635 AND '.$ilDB->like('rvalue', 'clob', 'failed').' ',
636 array('integer','integer','text'),
637 array($scorm_item_id,$a_obj_id,'cmi.core.lesson_status'));
638 }
639
640 while($row = $ilDB->fetchObject($res))
641 {
642 $user_ids[] = $row->user_id;
643 }
644 return $user_ids ? $user_ids : array();
645 }
646
653 public static function _getCountCompletedPerUser($a_scorm_item_ids,$a_obj_id)
654 {
655 global $ilDB;
656
657 $in = $ilDB->in('sco_id', $a_scorm_item_ids, false, 'integer');
658
659 // Why does this query use a like search against "passed" and "failed"
660 //because it's clob and we support Oracle
661 $res = $ilDB->queryF('
662 SELECT user_id, COUNT(user_id) completed FROM scorm_tracking
663 WHERE '.$in.'
664 AND obj_id = %s
665 AND lvalue = %s
666 AND ('.$ilDB->like('rvalue', 'clob', 'completed').' OR '.$ilDB->like('rvalue', 'clob', 'passed').')
667 GROUP BY user_id',
668 array('integer', 'text'),
669 array($a_obj_id, 'cmi.core.lesson_status')
670 );
671 while($row = $ilDB->fetchObject($res))
672 {
673 $users[$row->user_id] = $row->completed;
674 }
675 return $users ? $users : array();
676 }
677
684 public static function _getProgressInfo($sco_item_ids,$a_obj_id)
685 {
686 global $ilDB;
687
688 $in = $ilDB->in('sco_id', $sco_item_ids, false, 'integer');
689
690 $res = $ilDB->queryF('
691 SELECT * FROM scorm_tracking
692 WHERE '.$in.'
693 AND obj_id = %s
694 AND lvalue = %s ',
695 array('integer','text'),
696 array($a_obj_id,'cmi.core.lesson_status'));
697
698 $info['completed'] = array();
699 $info['failed'] = array();
700
701 $user_ids = array();
702 while($row = $ilDB->fetchObject($res))
703 {
704 switch($row->rvalue)
705 {
706 case 'completed':
707 case 'passed':
708 $info['completed'][$row->sco_id][] = $row->user_id;
709 $user_ids[$row->sco_id][] = $row->user_id;
710 break;
711
712 case 'failed':
713 $info['failed'][$row->sco_id][] = $row->user_id;
714 $user_ids[$row->sco_id][] = $row->user_id;
715 break;
716 }
717 }
718 $info['in_progress'] = ilObjSCORMTracking::_getInProgress($sco_item_ids,$a_obj_id,$user_ids);
719
720 return $info;
721 }
722
723 public static function scorm12PlayerUnload()
724 {
725 global $ilUser, $ilDB;
726
727 //$user_id = $ilUser->getID();
728 $user_id = (int)$_GET["p"];
729 $ref_id = (int)$_GET["ref_id"];
730 // $obj_id = ilObject::_lookupObjId($ref_id);
731 $obj_id = (int)$_GET["package_id"];
732 if ($obj_id <= 1){
733 $GLOBALS['ilLog']->write(__METHOD__.' no valid obj_id');
734 } else {
735 $last_visited=$_POST['last_visited'];
736 $endDate = date('Y-m-d H:i:s', mktime(date('H'), date('i')+5, date('s'), date('m'), date('d'), date('Y')));
737 $ilDB->manipulateF('UPDATE sahs_user
738 SET last_visited = %s, hash_end =%s, last_access = %s
739 WHERE obj_id = %s AND user_id = %s',
740 array('text', 'timestamp', 'timestamp', 'integer', 'integer'),
741 array($last_visited, $endDate, date('Y-m-d H:i:s'), $obj_id, $user_id)
742 );
743 // update time and numbers of attempts in change event
744 //NOTE: here it is correct (not count of commit with changed values); be careful to performance issues
745 ilObjSCORMTracking::_syncReadEvent($obj_id, $user_id, "sahs", $ref_id);
746 }
747 header('Content-Type: text/plain; charset=UTF-8');
748 print("");
749 }
750
751 public static function checkIfAllowed($packageId,$userId,$hash){
752 global $ilDB;
753 $res = $ilDB->queryF('select hash from sahs_user where obj_id=%s AND user_id=%s AND hash_end>%s',
754 array('integer','integer','timestamp'),
755 array($packageId,$userId,date('Y-m-d H:i:s'))
756 );
757 $rowtmp=$ilDB->fetchAssoc($res);
758 if ($rowtmp['hash']==$hash) return;
759 else die("not allowed");
760 }
761
762} // END class.ilObjSCORMTracking
763?>
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$failed
Definition: Utf8Test.php:85
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
if(! $in) print
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
static _recordReadEvent($a_type, $a_ref_id, $obj_id, $usr_id, $isCatchupWriteEvents=true, $a_ext_rc=false, $a_ext_time=false)
Records a read event and catches up with write events.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static writeStatus($a_obj_id, $a_user_id, $a_status, $a_percentage=false, $a_force_per=false)
Write status for user and object.
Class ilObjSCORMTracking.
static _getTrackedUsers($a_obj_id)
Get all tracked users.
static _getProgressInfo($sco_item_ids, $a_obj_id)
Get info about.
static syncGlobalStatus($userId, $packageId, $data, $new_global_status)
static _getCompleted($scorm_item_id, $a_obj_id)
like necessary because of Oracle
static _countCompleted($a_scos, $a_obj_id, $a_user_id)
static _getInProgress($scorm_item_id, $a_obj_id, $a_blocked_user_ids=null)
static _getCollectionStatus($a_scos, $a_obj_id, $a_user_id)
static _syncReadEvent($a_obj_id, $a_user_id, $a_type, $a_ref_id)
Synch read event table.
static _getFailed($scorm_item_id, $a_obj_id)
like necessary because of Oracle
static lookupLastAccessTimes($a_obj_id)
Lookup last acccess time for all users of a scorm module @global ilDB $ilDB.
static storeJsApiCmi($user_id, $obj_id, $data)
static _getCountCompletedPerUser($a_scorm_item_ids, $a_obj_id)
Get users who have status completed or passed.
static _insertTrackData($a_sahs_id, $a_lval, $a_rval, $a_obj_id)
static checkIfAllowed($packageId, $userId, $hash)
store($obj_id=0, $sahs_id=0, $extractData=1)
static _lookupObjId($a_id)
static now()
Return current timestamp in Y-m-d H:i:s format.
$info
Definition: example_052.php:80
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
$insert
$ref_id
Definition: sahs_server.php:39
$packageId
global $ilDB
$ilUser
Definition: imgupload.php:18
$a_type
Definition: workflow.php:93