ILIAS  release_4-4 Revision
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilSCORM2004Tracking.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
13 {
19  {
20  }
21 
22  function _getInProgress($scorm_item_id,$a_obj_id)
23  {
24 
25 die("Not Implemented: ilSCORM2004Tracking_getInProgress");
26 /*
27  global $ilDB;
28 
29  if(is_array($scorm_item_id))
30  {
31  $where = "WHERE sco_id IN(";
32  $where .= implode(",",ilUtil::quoteArray($scorm_item_id));
33  $where .= ") ";
34  $where .= ("AND obj_id = ".$ilDB->quote($a_obj_id)." ");
35 
36  }
37  else
38  {
39  $where = "WHERE sco_id = ".$ilDB->quote($scorm_item_id)." ";
40  $where .= ("AND obj_id = ".$ilDB->quote($a_obj_id)." ");
41  }
42 
43 
44  $query = "SELECT user_id,sco_id FROM scorm_tracking ".
45  $where.
46  "GROUP BY user_id, sco_id";
47 
48 
49  $res = $ilDB->query($query);
50  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
51  {
52  $in_progress[$row->sco_id][] = $row->user_id;
53  }
54  return is_array($in_progress) ? $in_progress : array();
55 */
56  }
57 
58  function _getCompleted($scorm_item_id,$a_obj_id)
59  {
60  global $ilDB;
61 
62 die("Not Implemented: ilSCORM2004Tracking_getCompleted");
63 /*
64  if(is_array($scorm_item_id))
65  {
66  $where = "WHERE sco_id IN(".implode(",",ilUtil::quoteArray($scorm_item_id)).") ";
67  }
68  else
69  {
70  $where = "sco_id = ".$ilDB->quote($scorm_item_id)." ";
71  }
72 
73  $query = "SELECT DISTINCT(user_id) FROM scorm_tracking ".
74  $where.
75  "AND obj_id = ".$ilDB->quote($a_obj_id)." ".
76  "AND lvalue = 'cmi.core.lesson_status' ".
77  "AND ( rvalue = 'completed' ".
78  "OR rvalue = 'passed')";
79  $res = $ilDB->query($query);
80  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
81  {
82  $user_ids[] = $row->user_id;
83  }
84  return $user_ids ? $user_ids : array();
85 */
86  }
87 
88  function _getFailed($scorm_item_id,$a_obj_id)
89  {
90  global $ilDB;
91 
92 die("Not Implemented: ilSCORM2004Tracking_getFailed");
93 /*
94  if(is_array($scorm_item_id))
95  {
96  $where = "WHERE sco_id IN('".implode("','",$scorm_item_id)."') ";
97  }
98  else
99  {
100  $where = "sco_id = '".$scorm_item_id."' ";
101  }
102 
103  $query = "SELECT DISTINCT(user_id) FROM scorm_tracking ".
104  $where.
105  "AND obj_id = '".$a_obj_id."' ".
106  "AND lvalue = 'cmi.core.lesson_status' ".
107  "AND rvalue = 'failed'";
108  $res = $ilDB->query($query);
109  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
110  {
111  $user_ids[] = $row->user_id;
112  }
113  return $user_ids ? $user_ids : array();
114 */
115  }
116 
124  function _getCountCompletedPerUser($a_scorm_item_ids, $a_obj_id, $a_omit_failed = false)
125  {
126  global $ilDB;
127 
128  $in = $ilDB->in('cp_node.cp_node_id', $a_scorm_item_ids, false, 'integer');
129 
130  // #8171: success_status vs. completion status
131  $omit_failed = '';
132  if($a_omit_failed)
133  {
134  $omit_failed = ' AND success_status <> '.$ilDB->quote('failed', 'text');
135  }
136 
137  $res = $ilDB->queryF('
138  SELECT cmi_node.user_id user_id, COUNT(user_id) completed FROM cp_node, cmi_node
139  WHERE '.$in.$omit_failed.'
140  AND cp_node.cp_node_id = cmi_node.cp_node_id
141  AND cp_node.slm_id = %s
142  AND completion_status = %s
143  GROUP BY cmi_node.user_id',
144  array('integer', 'text'),
145  array($a_obj_id, 'completed')
146  );
147  while($row = $ilDB->fetchObject($res))
148  {
149  $users[$row->user_id] = $row->completed;
150  }
151 
152  return $users ? $users : array();
153  }
154 
155 
161  function _getProgressInfo($a_obj_id)
162  {
163  global $ilDB;
164 
165  $res = $ilDB->queryF('
166  SELECT user_id, status, satisfied FROM cmi_gobjective
167  WHERE objective_id = %s
168  AND scope_id = %s',
169  array('text', 'integer'),
170  array('-course_overall_status-', $a_obj_id)
171  );
172 
173  $info['completed'] = array();
174  $info['failed'] = array();
175  $info['in_progress'] = array();
176 
177  while($row = $ilDB->fetchAssoc($res))
178  {
179  if (self::_isCompleted($row["status"], $row["satisfied"]))
180  {
181  $info['completed'][] = $row["user_id"];
182  }
183  if (self::_isInProgress($row["status"], $row["satisfied"]))
184  {
185  $info['in_progress'][] = $row["user_id"];
186  }
187  if (self::_isFailed($row["status"], $row["satisfied"]))
188  {
189  $info['failed'][] = $row["user_id"];
190  }
191  }
192 
193  return $info;
194  }
195 
201  function _getProgressInfoOfUser($a_obj_id, $a_user_id)
202  {
203  global $ilDB, $ilLog;
204 
205  $res = $ilDB->queryF('
206  SELECT status, satisfied FROM cmi_gobjective
207  WHERE objective_id = %s
208  AND scope_id = %s AND user_id = %s',
209  array('text', 'integer', 'integer'),
210  array('-course_overall_status-', $a_obj_id, $a_user_id)
211  );
212 
213  $status = "not_attempted";
214  if ($row = $ilDB->fetchAssoc($res))
215  {
216  if (self::_isInProgress($row["status"], $row["satisfied"]))
217  {
218  $status = "in_progress";
219  }
220  if (self::_isCompleted($row["status"], $row["satisfied"]))
221  {
222  $status = "completed";
223  }
224  if (self::_isFailed($row["status"], $row["satisfied"]))
225  {
226  $status = "failed";
227  }
228  }
229  return $status;
230  }
231 
237  function _getTrackedUsers($a_obj_id)
238  {
239  global $ilDB, $ilLog;
240 
241  $res = $ilDB->queryF('
242  SELECT DISTINCT user_id FROM cmi_gobjective
243  WHERE objective_id = %s
244  AND scope_id = %s',
245  array('text', 'integer'),
246  array('-course_overall_status-', $a_obj_id)
247  );
248 
249  $users = array();
250  while ($row = $ilDB->fetchAssoc($res))
251  {
252  $users[] = $row["user_id"];
253  }
254  return $users;
255  }
256 
257  function _getItemProgressInfo($a_scorm_item_ids, $a_obj_id, $a_omit_failed = false)
258  {
259  global $ilDB;
260 
261  $in = $ilDB->in('cp_node.cp_node_id', $a_scorm_item_ids, false, 'integer');
262 
263  $res = $ilDB->queryF(
264  'SELECT cp_node.cp_node_id id,
265  cmi_node.user_id user_id,
266  cmi_node.completion_status completion,
267  cmi_node.success_status success
268  FROM cp_node, cmi_node
269  WHERE '.$in.'
270  AND cp_node.cp_node_id = cmi_node.cp_node_id
271  AND cp_node.slm_id = %s',
272  array('integer'),
273  array($a_obj_id)
274  );
275 
276  $info['completed'] = array();
277  $info['failed'] = array();
278  $info['in_progress'] = array();
279 
280  while($row = $ilDB->fetchAssoc($res))
281  {
282  // if any data available, set in progress.
283  $info['in_progress'][$row["id"]][] = $row["user_id"];
284  if ($row["completion"] == "completed" || $row["success"] == "passed")
285  {
286  // #8171: success_status vs. completion status
287  if(!$a_omit_failed || $row["success"] != "failed")
288  {
289  $info['completed'][$row["id"]][] = $row["user_id"];
290  }
291  }
292  if ($row["success"] == "failed")
293  {
294  $info['failed'][$row["id"]][] = $row["user_id"];
295  }
296  }
297  return $info;
298  }
299 
300  public static function _getCollectionStatus($a_scos, $a_obj_id, $a_user_id)
301  {
302  global $ilDB;
303 
304  $status = "not_attempted";
305 
306  if (is_array($a_scos))
307  {
308  $in = $ilDB->in('cp_node.cp_node_id', $a_scos, false, 'integer');
309 
310  $res = $ilDB->queryF(
311  'SELECT cp_node.cp_node_id id,
312  cmi_node.completion_status completion,
313  cmi_node.success_status success
314  FROM cp_node, cmi_node
315  WHERE '.$in.'
316  AND cp_node.cp_node_id = cmi_node.cp_node_id
317  AND cp_node.slm_id = %s
318  AND cmi_node.user_id = %s',
319  array('integer', 'integer'),
320  array($a_obj_id, $a_user_id)
321  );
322 
323  $started = false;
324  $cntcompleted = 0;
325  $failed = false;
326  while ($rec = $ilDB->fetchAssoc($res))
327  {
328  if ($rec["completion"] == "completed" || $rec["success"] == "passed")
329  {
330  $cntcompleted++;
331  }
332  if ($rec["success"] == "failed") $failed = true;
333  $started = true;
334  }
335  if ($started == true) $status = "in_progress";
336  if ($failed == true) $status = "failed";
337  else if ($cntcompleted == count($a_scos)) $status = "completed";
338 
339  // check max attempts
340  if ($status == "in_progress" && self::_hasMaxAttempts($a_obj_id, $a_user_id))
341  {
342  $status = "failed";
343  }
344  }
345  return $status;
346  }
347 
348  public static function _hasMaxAttempts($a_obj_id, $a_user_id)
349  {
350  global $ilDB;
351  // see ilSCORM13Player
352  $res = $ilDB->queryF(
353  'SELECT max_attempt FROM sahs_lm WHERE id = %s',
354  array('integer'),
355  array($a_obj_id)
356  );
357  $row = $ilDB->fetchAssoc($res);
358  $max_attempts = $row['max_attempt'];
359 
360  if ($max_attempts)
361  {
362  $val_set = $ilDB->queryF('SELECT package_attempts FROM sahs_user WHERE obj_id = %s AND user_id = %s',
363  array('integer','integer'), array($a_obj_id,$a_user_id));
364  $val_rec = $ilDB->fetchAssoc($val_set);
365  $attempts = $val_rec["package_attempts"];
366  if ($attempts == null) $attempts = 0;
367 
368  if ($attempts >= $max_attempts)
369  {
370  return true;
371  }
372  }
373 
374  return false;
375  }
376 
377  public static function _countCompleted($a_scos, $a_obj_id, $a_user_id,
378  $a_omit_failed = false)
379  {
380  global $ilDB;
381 
382  if (is_array($a_scos))
383  {
384  $in = $ilDB->in('cp_node.cp_node_id', $a_scos, false, 'integer');
385 
386  $res = $ilDB->queryF(
387  'SELECT cp_node.cp_node_id id,
388  cmi_node.completion_status completion,
389  cmi_node.success_status success
390  FROM cp_node, cmi_node
391  WHERE '.$in.'
392  AND cp_node.cp_node_id = cmi_node.cp_node_id
393  AND cp_node.slm_id = %s
394  AND cmi_node.user_id = %s',
395  array('integer', 'integer'),
396  array($a_obj_id, $a_user_id)
397  );
398 
399 
400  $cnt = 0;
401  while ($rec = $ilDB->fetchAssoc($res))
402  {
403  // #8171: alex, added (!$a_omit_failed || $rec["success"] != "failed")
404  // since completed/failed combination should not be included in
405  // percentage calculation at ilLPStatusSCOM::determinePercentage
406  if (($rec["completion"] == "completed" || $rec["success"] == "passed")
407  && (!$a_omit_failed || $rec["success"] != "failed"))
408  {
409  $cnt++;
410  }
411  }
412 
413  }
414  return $cnt;
415  }
416 
423  function _syncReadEvent($a_obj_id, $a_user_id, $a_type, $a_ref_id)
424  {
425  global $ilDB;
426  // get attempts and time
427  $val_set = $ilDB->queryF('
428  SELECT package_attempts, sco_total_time_sec
429  FROM sahs_user WHERE obj_id = %s AND user_id = %s',
430  array('integer','integer'), array($a_obj_id,$a_user_id));
431  $val_rec = $ilDB->fetchAssoc($val_set);
432  $time = $val_rec["sco_total_time_sec"]; //could be changed to total_time_sec if switch is available
433  $attempts = $val_rec["package_attempts"];
434  if ($attempts == null) $attempts = "";
435 
436  if ($attempts != "" && $time == null) { //use old way
437  $time = self::getSumTotalTimeSecondsFromScos($a_obj_id, $a_user_id,true);
438  }
439 
440  include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
441  ilChangeEvent::_recordReadEvent($a_type, $a_ref_id,
442  $a_obj_id, $a_user_id, false, $attempts, $time);
443  }
444 
448  static function _isCompleted($a_status, $a_satisfied)
449  {
450  if ($a_status == "completed" || $a_satisfied == "satisfied")
451  {
452  return true;
453  }
454 
455  return false;
456  }
457 
461  static function _isInProgress($a_status, $a_satisfied)
462  {
463  if ($a_status != "completed")
464  {
465  return true;
466  }
467 
468  return false;
469  }
470 
474  static function _isFailed($a_status, $a_satisfied)
475  {
476  if ($a_status == "completed" && $a_satisfied == "notSatisfied")
477  {
478  return true;
479  }
480 
481  return false;
482  }
483 
487  function getSumTotalTimeSecondsFromScos($a_obj_id, $a_user_id, $a_write=false)
488  {
489  global $ilDB, $ilLog;
490  $scos = array();
491  $val_set = $ilDB->queryF(
492  'SELECT cp_node_id FROM cp_node
493  WHERE nodename = %s
494  AND cp_node.slm_id = %s',
495  array('text', 'integer'),
496  array('item', $a_obj_id)
497  );
498  while($val_rec = $ilDB->fetchAssoc($val_set))
499  {
500  array_push($scos,$val_rec['cp_node_id']);
501  }
502  $time = 0;
503  foreach ($scos as $sco)
504  {
505  include_once("./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php");
506  $data_set = $ilDB->queryF('
507  SELECT total_time
508  FROM cmi_node
509  WHERE cp_node_id = %s
510  AND user_id = %s',
511  array('integer','integer'),
512  array($sco, $a_user_id)
513  );
514 
515  while($data_rec = $ilDB->fetchAssoc($data_set))
516  {
517  $sec = ilObjSCORM2004LearningModule::_ISODurationToCentisec($data_rec["total_time"]) / 100;
518  }
519  $time += (int) $sec;
520  $sec = 0;
521 //$ilLog->write("++".$time);
522  }
523  if ($a_write && $time>0) {
524  $ilDB->queryF('UPDATE sahs_user SET sco_total_time_sec=%s WHERE obj_id = %s AND user_id = %s',
525  array('integer', 'integer', 'integer'),
526  array($time, $a_obj_id, $a_user_id));
527  }
528  return $time;
529  }
530 
531 }
532 // END class.ilSCORM2004Tracking
533 ?>
ilObjSCORM2004Tracking()
Constructor public.
static _hasMaxAttempts($a_obj_id, $a_user_id)
_syncReadEvent($a_obj_id, $a_user_id, $a_type, $a_ref_id)
Synch read event table.
_getCompleted($scorm_item_id, $a_obj_id)
_getTrackedUsers($a_obj_id)
Get all tracked users.
_ISODurationToCentisec($str)
convert ISO 8601 Timeperiods to centiseconds ta
_getItemProgressInfo($a_scorm_item_ids, $a_obj_id, $a_omit_failed=false)
static _isInProgress($a_status, $a_satisfied)
static _countCompleted($a_scos, $a_obj_id, $a_user_id, $a_omit_failed=false)
static _isCompleted($a_status, $a_satisfied)
Class ilSCORM2004Tracking.
$failed
Definition: Utf8Test.php:86
_getProgressInfo($a_obj_id)
Get overall scorm status.
_getInProgress($scorm_item_id, $a_obj_id)
_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.
_getFailed($scorm_item_id, $a_obj_id)
static _getCollectionStatus($a_scos, $a_obj_id, $a_user_id)
getSumTotalTimeSecondsFromScos($a_obj_id, $a_user_id, $a_write=false)
should be avoided; store value to increase performance for further requests
static _isFailed($a_status, $a_satisfied)
_getProgressInfoOfUser($a_obj_id, $a_user_id)
Get overall scorm status.
_getCountCompletedPerUser($a_scorm_item_ids, $a_obj_id, $a_omit_failed=false)
Get progress of selected scos.