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
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 {
425 if((bool)$row["is_final"])
426 {
428 }
429 else
430 {
431 // #15379
433 }
434 break;
435
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 {
516 $tmp_completed[$user_id]++;
517 break;
518
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?>
An exception for terminatinating execution or to throw for unit testing.
static getInstanceByObjId($a_obj_id)
get singleton instance
getSuggestedObjectiveIds()
Get all objectives where the user failed the initial test.
static isValidType($a_type)
Is given type valid?
findObjectiveIds($a_type=null, $a_status=null, $a_is_final=null)
Find objective ids by type and/or status.
getFailedObjectiveIds($a_is_final=true)
Get all objectives where the user failed the qualified test.
saveObjectiveResult($a_objective_id, $a_type, $a_status, $a_result_percentage, $a_limit_percentage, $a_tries, $a_is_final)
Save objective result.
static deleteResultsForUser($a_user_id)
Delete all result entries for user.
static getSummarizedObjectiveStatusForLP($a_obj_id, array $a_objective_ids, $a_user_id=null)
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.
getCourseResultsForUserPresentation()
Get all results for course and user.
getCompletedObjectiveIds()
Get all objectives where the user completed the qualified test.
static isValidStatus($a_status)
Is given status valid?
__construct($a_course_obj_id, $a_user_id)
Constructor.
static getObjectiveStatusForLP($a_user_id, $a_obj_id, array $a_objective_ids)
static resetFinalByObjective($a_objective_id)
static hasResults($a_container_id, $a_user_id)
static lookupResult($a_course_obj_id, $a_user_id, $a_objective_id, $a_tst_type)
Lookup user result.
getCompletedObjectiveIdsByType($a_type)
All completed objectives by type.
static deleteResultsForCourse($a_course_id)
Delete all result entries for course.
const LP_STATUS_COMPLETED_NUM
const LP_STATUS_IN_PROGRESS_NUM
const LP_STATUS_FAILED_NUM
$counter
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
global $ilDB
$a_type
Definition: workflow.php:93