ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilLOUserResults.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
12 {
13  protected $course_obj_id; // [int]
14  protected $user_id; // [int]
15 
16  const TYPE_INITIAL = 1;
17  const TYPE_QUALIFIED = 2;
18 
19  const STATUS_COMPLETED = 1;
20  const STATUS_FAILED = 2;
21 
29  public function __construct($a_course_obj_id, $a_user_id)
30  {
31  $this->course_obj_id = (int)$a_course_obj_id;
32  $this->user_id = (int)$a_user_id;
33  }
34 
35 
39  public static function lookupResult($a_course_obj_id, $a_user_id, $a_objective_id, $a_tst_type)
40  {
41  global $ilDB;
42 
43  $query = 'SELECT * FROM loc_user_results '.
44  'WHERE user_id = '.$ilDB->quote($a_user_id,'integer').' '.
45  'AND course_id = '.$ilDB->quote($a_course_obj_id,'integer').' '.
46  'AND objective_id = '.$ilDB->quote($a_objective_id,'integer').' '.
47  'AND type = '.$ilDB->quote($a_tst_type,'integer');
48  $res = $ilDB->query($query);
49  $ur = array(
50  'status' => self::STATUS_FAILED,
51  'result_perc' => 0,
52  'limit_perc' => 0,
53  'tries' => 0,
54  'is_final' => 0
55  );
56  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
57  {
58  $ur['status'] = $row->status;
59  $ur['result_perc'] = $row->result_perc;
60  $ur['limit_perc'] = $row->limit_perc;
61  $ur['tries'] = $row->tries;
62  $ur['is_final'] = $row->is_final;
63  }
64  return $ur;
65  }
66 
67  public static function resetFinalByObjective($a_objective_id)
68  {
69  $query = 'UPDATE loc_user_results '.
70  'SET is_final = '.$GLOBALS['ilDB']->quote(0,'integer').' '.
71  'WHERE objective_id = '.$GLOBALS['ilDB']->quote($a_objective_id,'integer');
72  $GLOBALS['ilDB']->manipulate($query);
73  }
74 
75 
82  protected static function isValidType($a_type)
83  {
84  return in_array((int)$a_type, array(self::TYPE_INITIAL, self::TYPE_QUALIFIED));
85  }
86 
93  protected static function isValidStatus($a_status)
94  {
95  return in_array((int)$a_status, array(self::STATUS_COMPLETED, self::STATUS_FAILED));
96  }
97 
104  public static function deleteResultsForUser($a_user_id)
105  {
106  global $ilDB;
107 
108  if(!(int)$a_user_id)
109  {
110  return false;
111  }
112 
113  $ilDB->manipulate("DELETE FROM loc_user_results".
114  " WHERE user_id = ".$ilDB->quote($a_user_id, "integer"));
115  return true;
116  }
117 
118 
125  public static function deleteResultsForCourse($a_course_id)
126  {
127  global $ilDB;
128 
129  if(!(int)$a_course_id)
130  {
131  return false;
132  }
133 
134  $ilDB->manipulate("DELETE FROM loc_user_results".
135  " WHERE course_id = ".$ilDB->quote($a_course_id, "integer"));
136  return true;
137  }
138 
143  public function delete()
144  {
145  global $ilDB;
146 
147  $query = 'DELETE FROM loc_user_results '.
148  'WHERE course_id = '.$ilDB->quote($this->course_obj_id).' '.
149  'AND user_id = '.$ilDB->quote($this->user_id);
150  $ilDB->manipulate($query);
151  }
152 
163  public static function deleteResultsFromLP($a_course_id, array $a_user_ids, $a_remove_initial, $a_remove_qualified, array $a_objective_ids)
164  {
165  global $ilDB;
166 
167  if(!(int)$a_course_id ||
168  !sizeof($a_user_ids))
169  {
170  return false;
171  }
172 
173  $base_sql = "DELETE FROM loc_user_results".
174  " WHERE course_id = ".$ilDB->quote($a_course_id, "integer").
175  " AND ".$ilDB->in("user_id", $a_user_ids, "", "integer");
176 
177  if((bool)$a_remove_initial)
178  {
179  $sql = $base_sql.
180  " AND type = ".$ilDB->quote(self::TYPE_INITIAL, "integer");
181  $ilDB->manipulate($sql);
182  }
183 
184  if((bool)$a_remove_qualified)
185  {
186  $sql = $base_sql.
187  " AND type = ".$ilDB->quote(self::TYPE_QUALIFIED, "integer");
188  $ilDB->manipulate($sql);
189  }
190 
191  if(is_array($a_objective_ids))
192  {
193  $sql = $base_sql.
194  " AND ".$ilDB->in("objective_id", $a_objective_ids, "", "integer");
195  $ilDB->manipulate($sql);
196  }
197 
198  $ilDB->manipulate($sql);
199  return true;
200  }
201 
202 
215  public function saveObjectiveResult($a_objective_id, $a_type, $a_status, $a_result_percentage, $a_limit_percentage, $a_tries, $a_is_final)
216  {
217  global $ilDB;
218 
219  if(!self::isValidType($a_type) ||
220  !self::isValidStatus($a_status))
221  {
222  return false;
223  }
224  $ilDB->replace("loc_user_results",
225  array(
226  "course_id" => array("integer", $this->course_obj_id),
227  "user_id" => array("integer", $this->user_id),
228  "objective_id" => array("integer", $a_objective_id),
229  "type" => array("integer", $a_type)
230  ),
231  array(
232  "status" => array("integer", $a_status),
233  "result_perc" => array("integer", $a_result_percentage),
234  "limit_perc" => array("integer", $a_limit_percentage),
235  "tries" => array("integer", $a_tries),
236  "is_final" => array("integer", $a_is_final),
237  "tstamp" => array("integer", time()),
238  )
239  );
240  return true;
241  }
242 
251  protected function findObjectiveIds($a_type = null, $a_status = null, $a_is_final = null)
252  {
253  global $ilDB;
254 
255  $res = array();
256 
257  $sql = "SELECT objective_id".
258  " FROM loc_user_results".
259  " WHERE course_id = ".$ilDB->quote($this->course_obj_id, "integer").
260  " AND user_id = ".$ilDB->quote($this->user_id, "integer");
261 
262  if($this->isValidType($a_type))
263  {
264  $sql .= " AND type = ".$ilDB->quote($a_type, "integer");
265  }
266  if($this->isValidStatus($a_status))
267  {
268  $sql .= " AND status = ".$ilDB->quote($a_status, "integer");
269  }
270  if($a_is_final !== null)
271  {
272  $sql .= " AND is_final = ".$ilDB->quote($a_is_final, "integer");
273  }
274 
275  $set = $ilDB->query($sql);
276  while($row = $ilDB->fetchAssoc($set))
277  {
278  $res[] = $row["objective_id"];
279  }
280 
281  return $res;
282  }
283 
290  {
291  return $this->findObjectiveIds($a_type, self::STATUS_COMPLETED);
292  }
293 
299  public function getSuggestedObjectiveIds()
300  {
301  return $this->findObjectiveIds(self::TYPE_INITIAL, self::STATUS_FAILED);
302  }
303 
309  public function getCompletedObjectiveIds()
310  {
311  include_once './Modules/Course/classes/Objectives/class.ilLOSettings.php';
312  $settings = ilLOSettings::getInstanceByObjId($this->course_obj_id);
313 
314  if(!$settings->isInitialTestQualifying() or !$settings->worksWithInitialTest())
315  {
316  return $this->findObjectiveIds(self::TYPE_QUALIFIED, self::STATUS_COMPLETED);
317  }
318 
319  // status of final final test overwrites initial qualified.
320  if(
321  $settings->isInitialTestQualifying() &&
322  $settings->worksWithInitialTest()
323  )
324  {
325  $completed = array();
326  $completed_candidates = array_unique(
327  array_merge(
328  $this->findObjectiveIds(self::TYPE_INITIAL, self::STATUS_COMPLETED),
329  $this->findObjectiveIds(self::TYPE_QUALIFIED, self::STATUS_COMPLETED)
330  ));
331  $failed_final = (array) $this->findObjectiveIds(self::TYPE_QUALIFIED, self::STATUS_FAILED);
332 
333  foreach($completed_candidates as $objective_completed)
334  {
335  if(!in_array($objective_completed, $failed_final))
336  {
337  $completed[] = $objective_completed;
338  }
339  }
340  return $completed;
341  }
342  }
343 
350  public function getFailedObjectiveIds($a_is_final = true)
351  {
352  return $this->findObjectiveIds(self::TYPE_QUALIFIED, self::STATUS_FAILED, $a_is_final);
353  }
354 
361  {
362  global $ilDB;
363 
364  $res = array();
365 
366  include_once("./Modules/Course/classes/Objectives/class.ilLOSettings.php");
367  $settings = ilLOSettings::getInstanceByObjId($this->course_obj_id);
368 
369  $set = $ilDB->query("SELECT *".
370  " FROM loc_user_results".
371  " WHERE course_id = ".$ilDB->quote($this->course_obj_id, "integer").
372  " AND user_id = ".$ilDB->quote($this->user_id, "integer"));
373  while($row = $ilDB->fetchAssoc($set))
374  {
375  // do not read initial test results, if disabled.
376  if(
377  $row['type'] == self::TYPE_INITIAL &&
378  !$settings->worksWithInitialTest()
379  )
380  {
381  continue;
382  }
383 
384  $objective_id = $row["objective_id"];
385  $type = $row["type"];
386  unset($row["objective_id"]);
387  unset($row["type"]);
388  $res[$objective_id][$type] = $row;
389  }
390 
391  return $res;
392  }
393 
394  public static function getObjectiveStatusForLP($a_user_id, $a_obj_id, array $a_objective_ids)
395  {
396  global $ilDB;
397 
398  // are initital test(s) qualifying?
399  include_once "Modules/Course/classes/Objectives/class.ilLOSettings.php";
400  $lo_set = ilLOSettings::getInstanceByObjId($a_obj_id);
401  $initial_qualifying = $lo_set->isInitialTestQualifying();
402 
403  // this method returns LP status codes!
404  include_once "Services/Tracking/classes/class.ilLPStatus.php";
405 
406  $res = array();
407 
408  $sql = "SELECT lor.objective_id, lor.user_id, lor.status, lor.is_final".
409  " FROM loc_user_results lor".
410  " JOIN crs_objectives cobj ON (cobj.objective_id = lor.objective_id)".
411  " WHERE ".$ilDB->in("lor.objective_id", $a_objective_ids, "", "integer");
412  if(!(bool)$initial_qualifying)
413  {
414  $sql .= " AND lor.type = ".$ilDB->quote(self::TYPE_QUALIFIED, "integer");
415  }
416  $sql .= " AND lor.user_id = ".$ilDB->quote($a_user_id, "integer").
417  " AND cobj.active = ".$ilDB->quote(1, "integer").
418  " ORDER BY lor.type"; // qualified must come last!
419  $set = $ilDB->query($sql);
420  while($row = $ilDB->fetchAssoc($set))
421  {
422  switch($row["status"])
423  {
424  case self::STATUS_FAILED:
425  if((bool)$row["is_final"])
426  {
428  }
429  else
430  {
431  // #15379
433  }
434  break;
435 
436  case self::STATUS_COMPLETED:
438  break;
439 
440  default:
441  /*
442  $status = ilLPStatus::LP_STATUS_NOT_ATTEMPTED_NUM;
443  break;
444  */
445  continue;
446  }
447 
448  // if both initial and qualified, qualified will overwrite initial
449  $res[$row["objective_id"]] = $status;
450  }
451 
452  return $res;
453  }
454 
455  public static function getSummarizedObjectiveStatusForLP($a_obj_id, array $a_objective_ids, $a_user_id = null)
456  {
457  global $ilDB;
458 
459  $GLOBALS['DIC']->logger()->trac()->debug('Get summorized objective status');
460 
461  // change event is NOT parsed here!
462 
463  // are initital test(s) qualifying?
464  include_once "Modules/Course/classes/Objectives/class.ilLOSettings.php";
465  $lo_set = ilLOSettings::getInstanceByObjId($a_obj_id);
466  $initial_qualifying = $lo_set->isInitialTestQualifying();
467 
468  // this method returns LP status codes!
469  include_once "Services/Tracking/classes/class.ilLPStatus.php";
470 
471  $res = $tmp_completed = array();
472 
473  $sql = "SELECT lor.objective_id, lor.user_id, lor.status, lor.type, lor.is_final".
474  " FROM loc_user_results lor".
475  " JOIN crs_objectives cobj ON (cobj.objective_id = lor.objective_id)".
476  " WHERE ".$ilDB->in("lor.objective_id", $a_objective_ids, "", "integer").
477  " AND cobj.active = ".$ilDB->quote(1, "integer");
478  if(!(bool)$initial_qualifying)
479  {
480  $sql .= " AND lor.type = ".$ilDB->quote(self::TYPE_QUALIFIED, "integer");
481  }
482  if($a_user_id)
483  {
484  $sql .= " AND lor.user_id = ".$ilDB->quote($a_user_id, "integer");
485  }
486  $sql .= " ORDER BY lor.type DESC"; // qualified must come first!
487  $set = $ilDB->query($sql);
488 
489  $has_final_result = array();
490  while($row = $ilDB->fetchAssoc($set))
491  {
492  if($row['type'] == self::TYPE_QUALIFIED)
493  {
494  $has_final_result[$row['objective_id']] = $row['user_id'];
495  }
496 
497  $user_id = (int) $row["user_id"];
498  $status = (int) $row["status"];
499 
500  // initial tests only count if no qualified test
501  if(
502  $row["type"] == self::TYPE_INITIAL &&
503  in_array($row['user_id'], (array) $has_final_result[$row['objective_id']])
504  )
505  {
506 
507  continue;
508  }
509 
510  // user did do something
512 
513  switch($status)
514  {
515  case self::STATUS_COMPLETED:
516  $tmp_completed[$user_id]++;
517  break;
518 
519  case self::STATUS_FAILED:
520  if((bool)$row["is_final"])
521  {
522  // object is failed when at least 1 objective is failed without any tries left
524  }
525  break;
526  }
527  }
528 
529  $all_nr = sizeof($a_objective_ids);
530  foreach($tmp_completed as $user_id => $counter)
531  {
532  // if used as precondition object should be completed ASAP, status can be lost on subsequent tries
533  if($counter == $all_nr)
534  {
536  }
537  }
538 
539  if($a_user_id)
540  {
541  // might return null!
542  return $res[$a_user_id];
543  }
544  else
545  {
546  return $res;
547  }
548  }
549 
550  public static function hasResults($a_container_id, $a_user_id)
551  {
552  global $ilDB;
553 
554  $query = 'SELECT objective_id FROM loc_user_results '.
555  'WHERE course_id = '.$ilDB->quote($a_container_id,'integer').' '.
556  'AND user_id = '.$ilDB->quote($a_user_id,'integer');
557 
558  $res = $ilDB->query($query);
559  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
560  {
561  return true;
562  }
563  return false;
564  }
565 }
566 
567 ?>
const LP_STATUS_COMPLETED_NUM
static getObjectiveStatusForLP($a_user_id, $a_obj_id, array $a_objective_ids)
static getInstanceByObjId($a_obj_id)
get singleton instance
static resetFinalByObjective($a_objective_id)
getCompletedObjectiveIdsByType($a_type)
All completed objectives by type.
static getSummarizedObjectiveStatusForLP($a_obj_id, array $a_objective_ids, $a_user_id=null)
static lookupResult($a_course_obj_id, $a_user_id, $a_objective_id, $a_tst_type)
Lookup user result.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
const LP_STATUS_IN_PROGRESS_NUM
static deleteResultsForUser($a_user_id)
Delete all result entries for user.
getSuggestedObjectiveIds()
Get all objectives where the user failed the initial test.
getCompletedObjectiveIds()
Get all objectives where the user completed the qualified test.
$counter
saveObjectiveResult($a_objective_id, $a_type, $a_status, $a_result_percentage, $a_limit_percentage, $a_tries, $a_is_final)
Save objective result.
$a_type
Definition: workflow.php:93
static deleteResultsForCourse($a_course_id)
Delete all result entries for course.
Create styles array
The data for the language used.
getFailedObjectiveIds($a_is_final=true)
Get all objectives where the user failed the qualified test.
findObjectiveIds($a_type=null, $a_status=null, $a_is_final=null)
Find objective ids by type and/or status.
global $ilDB
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static isValidStatus($a_status)
Is given status valid?
static deleteResultsFromLP($a_course_id, array $a_user_ids, $a_remove_initial, $a_remove_qualified, array $a_objective_ids)
Delete all (qualified) result entries for course members.
static isValidType($a_type)
Is given type valid?
getCourseResultsForUserPresentation()
Get all results for course and user.
static hasResults($a_container_id, $a_user_id)
const LP_STATUS_FAILED_NUM
__construct($a_course_obj_id, $a_user_id)
Constructor.