ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups 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 * 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["status"]))
180  {
181  $info['completed'][] = $row["user_id"];
182  }
183  if (self::_isInProgress($row["status"], $row["status"]))
184  {
185  $info['in_progress'][] = $row["user_id"];
186  }
187  if (self::_isFailed($row["status"], $row["status"]))
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 * 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["status"]))
217  {
218  $status = "in_progress";
219  }
220  if (self::_isCompleted($row["status"], $row["status"]))
221  {
222  $status = "completed";
223  }
224  if (self::_isFailed($row["status"], $row["status"]))
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  return $status;
340  }
341 
342  public static function _countCompleted($a_scos, $a_obj_id, $a_user_id, $a_omit_failed = false)
343  {
344  global $ilDB;
345 
346  if (is_array($a_scos))
347  {
348  $in = $ilDB->in('cp_node.cp_node_id', $a_scos, false, 'integer');
349 
350  $res = $ilDB->queryF(
351  'SELECT cp_node.cp_node_id id,
352  cmi_node.completion_status completion,
353  cmi_node.success_status success
354  FROM cp_node, cmi_node
355  WHERE '.$in.'
356  AND cp_node.cp_node_id = cmi_node.cp_node_id
357  AND cp_node.slm_id = %s
358  AND cmi_node.user_id = %s',
359  array('integer', 'integer'),
360  array($a_obj_id, $a_user_id)
361  );
362 
363 
364  $cnt = 0;
365  while ($rec = $ilDB->fetchAssoc($res))
366  {
367  // #8171: alex, added (!$a_omit_failed || $rec["success"] != "failed")
368  // since completed/failed combination should not be included in
369  // percentage calculation at ilLPStatusSCOM::determinePercentage
370  if (($rec["completion"] == "completed" || $rec["success"] == "passed")
371  && (!$a_omit_failed || $rec["success"] != "failed"))
372  {
373  $cnt++;
374  }
375  }
376 
377  }
378  return $cnt;
379  }
380 
387  function _syncReadEvent($a_obj_id, $a_user_id, $a_type, $a_ref_id)
388  {
389  global $ilDB, $ilLog;
390 
391  // get attempts
392  $val_set = $ilDB->queryF('
393  SELECT * FROM cmi_custom
394  WHERE user_id = %s
395  AND sco_id = %s
396  AND lvalue = %s
397  AND obj_id = %s',
398  array('integer','integer', 'text','integer'),
399  array($a_user_id, 0,'package_attempts',$a_obj_id));
400 
401  $val_rec = $ilDB->fetchAssoc($val_set);
402 
403  $val_rec["rvalue"] = str_replace("\r\n", "\n", $val_rec["rvalue"]);
404  if ($val_rec["rvalue"] == null) {
405  $val_rec["rvalue"]="";
406  }
407 
408  $attempts = $val_rec["rvalue"];
409 
410  // time
411  $scos = array();
412  $val_set = $ilDB->queryF(
413  'SELECT cp_node_id FROM cp_node
414  WHERE nodename = %s
415  AND cp_node.slm_id = %s',
416  array('text', 'integer'),
417  array('item', $a_obj_id)
418  );
419  while($val_rec = $ilDB->fetchAssoc($val_set))
420  {
421  array_push($scos,$val_rec['cp_node_id']);
422  }
423  $time = 0;
424  foreach ($scos as $sco)
425  {
426  include_once("./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php");
427  $data_set = $ilDB->queryF('
428  SELECT c_timestamp last_access, session_time, success_status, completion_status,
429  c_raw, cp_node_id, total_time
430  FROM cmi_node
431  WHERE cp_node_id = %s
432  AND user_id = %s',
433  array('integer','integer'),
434  array($sco, $a_user_id)
435  );
436 
437  while($data_rec = $ilDB->fetchAssoc($data_set))
438  {
439  // see bug report 7246
440 // $sec = ilObjSCORM2004LearningModule::_ISODurationToCentisec($data_rec["session_time"]) / 100;
441  $sec = ilObjSCORM2004LearningModule::_ISODurationToCentisec($data_rec["total_time"]) / 100;
442  }
443  $time += (int) $sec;
444  $sec = 0;
445 //$ilLog->write("++".$time);
446  }
447 
448  include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
449  ilChangeEvent::_recordReadEvent($a_type, $a_ref_id,
450  $a_obj_id, $a_user_id, false, $attempts, $time);
451  }
452 
453 
457  static function _isCompleted($a_status, $a_satisfied)
458  {
459  if ($a_status == "completed")
460  {
461  return true;
462  }
463 
464  return false;
465  }
466 
470  static function _isInProgress($a_status, $a_satisfied)
471  {
472  if ($a_status != "completed")
473  {
474  return true;
475  }
476 
477  return false;
478  }
479 
483  static function _isFailed($a_status, $a_satisfied)
484  {
485  if ($a_status == "completed" && $a_satisfied == "notSatisfied")
486  {
487  return true;
488  }
489 
490  return false;
491  }
492 
493 } // END class.ilSCORM2004Tracking
494 ?>