ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilCourseObjectiveResult.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 
5 define('IL_OBJECTIVE_STATUS_EMPTY','empty');
6 define('IL_OBJECTIVE_STATUS_PRETEST','pretest');
7 define('IL_OBJECTIVE_STATUS_FINAL','final');
8 define('IL_OBJECTIVE_STATUS_NONE','none');
9 define('IL_OBJECTIVE_STATUS_FINISHED','finished');
10 define('IL_OBJECTIVE_STATUS_PRETEST_NON_SUGGEST','pretest_non_suggest');
11 
20 {
21  var $db = null;
22  var $user_id = null;
23 
24 
29  public function __construct($a_usr_id)
30  {
31  global $ilDB;
32 
33  $this->db = $ilDB;
34 
35  $this->user_id = $a_usr_id;
36  }
37  function getUserId()
38  {
39  return $this->user_id;
40  }
41 
42  function getAccomplished($a_crs_id)
43  {
44  return ilCourseObjectiveResult::_getAccomplished($this->getUserId(),$a_crs_id);
45  }
46  public static function _getAccomplished($a_user_id,$a_crs_id)
47  {
48  global $ilDB;
49 
50  include_once 'Modules/Course/classes/class.ilCourseObjective.php';
51  // begin-patch lok
52  $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
53  // end-patch lok
54 
55  if(!is_array($objectives))
56  {
57  return array();
58  }
59  $query = "SELECT objective_id FROM crs_objective_status ".
60  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
61  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
62  $res = $ilDB->query($query);
63  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
64  {
65  $accomplished[] = $row->objective_id;
66  }
67  return $accomplished ? $accomplished : array();
68  }
69 
70  function getSuggested($a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
71  {
72  return ilCourseObjectiveResult::_getSuggested($this->getUserId(),$a_crs_id,$a_status);
73  }
74 
75  public static function _getSuggested($a_user_id,$a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
76  {
77  global $ilDB;
78 
79  include_once './Modules/Course/classes/class.ilCourseObjective.php';
80  // begin-patch lok
81  $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
82  // end-patch lok
83 
84  $finished = array();
85  if($a_status == IL_OBJECTIVE_STATUS_FINAL or
86  $a_status == IL_OBJECTIVE_STATUS_FINISHED)
87  {
88  // check finished
89  $query = "SELECT objective_id FROM crs_objective_status ".
90  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer')." ".
91  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
92  $res = $ilDB->query($query);
93  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
94  {
95  $finished[] = $row->objective_id;
96  }
97  }
98  else
99  {
100  // Pretest
101  $query = "SELECT objective_id FROM crs_objective_status_p ".
102  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
103  "AND user_id = ".$ilDB->quote($a_user_id ,'integer');
104  $res = $ilDB->query($query);
105  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
106  {
107  $finished[] = $row->objective_id;
108  }
109  }
110  foreach($objectives as $objective_id)
111  {
112  if(!in_array($objective_id,$finished))
113  {
114  $suggested[] = $objective_id;
115  }
116  }
117  return $suggested ? $suggested : array();
118  }
119 
126  public static function getSuggestedQuestions($a_usr_id,$a_crs_id)
127  {
128  foreach(self::_getSuggested($a_usr_id,$a_crs_id) as $objective_id)
129  {
130  include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
131  $obj = new ilCourseObjectiveQuestion($objective_id);
132  foreach($obj->getFinalTestQuestions() as $qst)
133  {
134  $qsts[] = $qst['question_id'];
135  }
136  }
137  return $qsts ? $qsts : array();
138  }
139 
140  protected function resetTestForUser(ilObjTest $a_test, $a_user_id)
141  {
142  // this is done in ilTestLP (see below)
143  // $a_test->removeTestResultsForUser($a_user_id);
144 
145  // #15038
146  include_once "Modules/Test/classes/class.ilTestLP.php";
147  $test_lp = ilTestLP::getInstance($a_test->getId());
148  $test_lp->resetLPDataForUserIds(array($a_user_id));
149 
150  // #15205 - see ilObjTestGUI::confirmDeleteSelectedUserDataObject()
151  $active_id = $a_test->getActiveIdOfUser($a_user_id);
152  if($active_id)
153  {
154  $a_test->removeTestActives(array($active_id));
155  }
156  }
157 
158  function reset($a_course_id)
159  {
160  global $ilDB;
161 
162  include_once './Modules/Course/classes/class.ilCourseObjective.php';
163  include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
164 
165  include_once './Services/Object/classes/class.ilObjectFactory.php';
166  $factory = new ilObjectFactory();
167 
168  include_once './Modules/Course/classes/Objectives/class.ilLOTestAssignments.php';
169  include_once './Modules/Course/classes/Objectives/class.ilLOSettings.php';
170  $assignments = ilLOTestAssignments::getInstance($a_course_id);
171  foreach(array_merge
172  (
173  $assignments->getAssignmentsByType(ilLOSettings::TYPE_TEST_INITIAL),
174  $assignments->getAssignmentsByType(ilLOSettings::TYPE_TEST_QUALIFIED)
175  )
176  as $assignment)
177  {
178  $tst = $factory->getInstanceByRefId($assignment->getTestRefId(),FALSE);
179  if($tst instanceof ilObjTest)
180  {
181  global $lng;
182 
183  require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
184  $participantData = new ilTestParticipantData($ilDB, $lng);
185  $participantData->setUserIds(array($this->getUserId()));
186  $participantData->load($tst->getTestId());
187  $tst->removeTestResults($participantData);
188 
189  }
190  }
191 
192  $initial = ilLOSettings::getInstanceByObjId($a_course_id)->getInitialTest();
193  $initial_tst = $factory->getInstanceByRefId($initial, FALSE);
194  if($initial_tst instanceof ilObjTest)
195  {
196  $this->resetTestForUser($initial_tst, $this->getUserId());
197  }
198 
199  $qualified = ilLOSettings::getInstanceByObjId($a_course_id)->getQualifiedTest();
200  $qualified_tst = $factory->getInstanceByRefId($qualified, FALSE);
201  if($qualified_tst instanceof ilObjTest)
202  {
203  $this->resetTestForUser($qualified_tst, $this->getUserId());
204  }
205 
206  $objectives = ilCourseObjective::_getObjectiveIds($a_course_id,FALSE);
207 
208  if(count($objectives))
209  {
210  $query = "DELETE FROM crs_objective_status ".
211  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
212  "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')." ";
213  $res = $ilDB->manipulate($query);
214 
215  $query = "DELETE FROM crs_objective_status_p ".
216  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
217  "AND user_id = ".$ilDB->quote($this->getUserId())."";
218  $res = $ilDB->manipulate($query);
219 
220  $query = "DELETE FROM loc_user_results ".
221  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
222  "AND user_id = ".$ilDB->quote($this->getUserId())."";
223  }
224 
225  // update/reset LP for course
226  include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
227  ilLPStatusWrapper::_updateStatus($a_course_id, $this->getUserId());
228 
229  return true;
230  }
231 
232  function getStatus($a_course_id)
233  {
234  include_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
235  include_once 'Modules/Course/classes/class.ilCourseObjective.php';
236  // begin-patch lok
237  $objective_ids = ilCourseObjective::_getObjectiveIds($a_course_id,true);
238  // end-patch lok
239  $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
240  $accomplished = $this->getAccomplished($a_course_id);
241  $suggested = $this->getSuggested($a_course_id);
242 
243  if(!count($objective_ids))
244  {
246  }
247 
248  if(count($accomplished) == count($objective_ids))
249  {
251  }
252 
253  $all_pretest_answered = false;
254  $all_final_answered = false;
255  foreach($objectives as $data)
256  {
257  if(assQuestion::_areAnswered($this->getUserId(),$data['questions']))
258  {
259  if($data['tst_status'])
260  {
261  $all_final_answered = true;
262  }
263  else
264  {
265  $all_pretest_answered = true;
266  }
267  }
268  }
269  if($all_final_answered)
270  {
272  }
273  if($all_pretest_answered and
274  !count($suggested))
275  {
277  }
278  elseif($all_pretest_answered)
279  {
281  }
283  }
284 
285  function hasAccomplishedObjective($a_objective_id)
286  {
287  global $ilDB;
288 
289  $query = "SELECT status FROM crs_objective_status ".
290  "WHERE objective_id = ".$ilDB->quote($a_objective_id ,'integer')." ".
291  "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')."";
292 
293  $res = $this->db->query($query);
294  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
295  {
296  return true;
297  }
298  return false;
299  }
300 
301  function readStatus($a_crs_id)
302  {
303  include_once './Modules/Course/classes/class.ilCourseObjective.php';
304 
305  // begin-patch lok
306  $objective_ids = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
307  // end-patch lok
308  $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
310  return true;
311  }
312 
313 
314 
315 
316  // PRIVATE
317  function __deleteEntries($a_objective_ids)
318  {
319  global $ilLog;
320 
321  $ilLog->logStack();
322  #$ilLog(__METHOD__.': Call of deprecated method.');
323 
324  return true;
325  }
326 
327  public static function _deleteUser($user_id)
328  {
329  global $ilDB;
330 
331  $query = "DELETE FROM crs_objective_status ".
332  "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
333  $res = $ilDB->manipulate($query);
334 
335  $query = "DELETE FROM crs_objective_status_p ".
336  "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
337  $res = $ilDB->manipulate($query);
338  return true;
339  }
340 
341  public static function _updateObjectiveResult($a_user_id,$a_active_id,$a_question_id)
342  {
343  // find all objectives this question is assigned to
344  if(!$objectives = self::_readAssignedObjectivesOfQuestion($a_question_id))
345  {
346  // no objectives found. TODO user has passed a test. After that questions of that test are assigned to an objective.
347  // => User has not passed
348  return true;
349  }
350  self::_updateObjectiveStatus($a_user_id,$objectives);
351 
352  return true;
353  }
354 
355  public static function _readAssignedObjectivesOfQuestion($a_question_id)
356  {
357  global $ilDB;
358 
359  // get all objtives and questions this current question is assigned to
360  $query = "SELECT q2.question_id qid,q2.objective_id ob FROM crs_objective_qst q1, ".
361  "crs_objective_qst q2 ".
362  "WHERE q1.question_id = ".$ilDB->quote($a_question_id ,'integer')." ".
363  "AND q1.objective_id = q2.objective_id ";
364 
365  $res = $ilDB->query($query);
366  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
367  {
368  $objectives['all_objectives'][$row->ob] = $row->ob;
369  $objectives['all_questions'][$row->qid] = $row->qid;
370  }
371  if(!is_array($objectives))
372  {
373  return false;
374  }
375  $objectives['objectives'] = self::_readAssignedObjectives($objectives['all_objectives']);
376  return $objectives ? $objectives : array();
377  }
378 
379 
380  public static function _readAssignedObjectives($a_all_objectives)
381  {
382  global $ilDB;
383 
384  // Read necessary points
385  $query = "SELECT t.objective_id obj,t.ref_id ref, question_id,tst_status,tst_limit ".
386  "FROM crs_objective_tst t JOIN crs_objective_qst q ".
387  "ON (t.objective_id = q.objective_id AND t.ref_id = q.ref_id) ".
388  "WHERE ".$ilDB->in('t.objective_id',$a_all_objectives,false,'integer');
389 
390  $res = $ilDB->query($query);
391  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
392  {
393  /*
394  $objectives[$row->obj."_".$row->ref]['questions'][$row->question_id] = $row->question_id;
395  $objectives[$row->obj."_".$row->ref]['tst_status'] = $row->tst_status;
396  $objectives[$row->obj."_".$row->ref]['tst_limit'] = $row->tst_limit;
397  $objectives[$row->obj."_".$row->ref]['objective_id'] = $row->obj;
398  */
399 
400  $objectives[$row->obj."_".$row->tst_status]['questions'][$row->question_id] = $row->question_id;
401  $objectives[$row->obj."_".$row->tst_status]['tst_status'] = $row->tst_status;
402  $objectives[$row->obj."_".$row->tst_status]['tst_limit'] = $row->tst_limit;
403  $objectives[$row->obj."_".$row->tst_status]['objective_id'] = $row->obj;
404 
405 
406  }
407  return $objectives ? $objectives : array();
408  }
409 
410  static function _updateObjectiveStatus($a_user_id,$objectives)
411  {
412  global $ilDB,$ilUser;
413 
414  if(!count($objectives['all_questions']) or
415  !count($objectives['all_objectives']))
416  {
417  return false;
418  }
419  // Read reachable points
420  $query = "SELECT question_id,points FROM qpl_questions ".
421  "WHERE ".$ilDB->in('question_id',(array) $objectives['all_questions'],false,'integer');
422  $res = $ilDB->query($query);
423  while($row = $ilDB->fetchAssoc($res))
424  {
425  $objectives['all_question_points'][$row['question_id']]['max_points'] = $row['points'];
426  }
427  // Read reached points
428  $query = "SELECT question_fi, MAX(points) as reached FROM tst_test_result ".
429  "JOIN tst_active ON (active_id = active_fi) ".
430  "WHERE user_fi = ".$ilDB->quote($a_user_id,'integer')." ".
431  "AND ".$ilDB->in('question_fi',(array) $objectives['all_questions'],false,'integer')." ".
432  #"AND question_fi IN (".implode(",",ilUtil::quoteArray($objectives['all_questions'])).") ".
433  "GROUP BY question_fi,user_fi";
434  $res = $ilDB->query($query);
435  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
436  {
437  $objectives['all_question_points'][$row->question_fi]['reached_points'] = $row->reached;
438  }
439 
440  // Check accomplished
441  $fullfilled = array();
442  $pretest = array();
443  foreach($objectives['objectives'] as $kind => $data)
444  {
445  // objective does not allow to change status
446  if(ilCourseObjectiveResult::__isFullfilled($objectives['all_question_points'],$data))
447  {
448  // Status 0 means pretest fullfilled, status 1 means final test fullfilled
449  if($data['tst_status'])
450  {
451  $fullfilled[] = array($data['objective_id'],$ilUser->getId(),$data['tst_status']);
452  }
453  else
454  {
455  $pretest[] = array($data['objective_id'],$ilUser->getId());
456  }
457  }
458  }
459  if(count($fullfilled))
460  {
461  foreach($fullfilled as $fullfilled_arr)
462  {
463  $ilDB->replace(
464  'crs_objective_status',
465  array(
466  'objective_id' => array('integer',$fullfilled_arr[0]),
467  'user_id' => array('integer',$fullfilled_arr[1])
468  ),
469  array(
470  'status' => array('integer',$fullfilled_arr[2])
471  )
472  );
473  }
474  ilCourseObjectiveResult::__updatePassed($a_user_id,$objectives['all_objectives']);
475  }
476  if(count($pretest))
477  {
478  foreach($pretest as $pretest_arr)
479  {
480  $ilDB->replace(
481  'crs_objective_status_p',
482  array(
483  'objective_id' => array('integer',$pretest_arr[0]),
484  'user_id' => array('integer',$pretest_arr[1])
485  ),
486  array()
487  );
488  }
489  }
490  return true;
491  }
492 
493  public static function __isFullfilled($question_points,$objective_data)
494  {
495  if(!is_array($objective_data['questions']))
496  {
497  return false;
498  }
499  $max_points = 0;
500  $reached_points = 0;
501  foreach($objective_data['questions'] as $question_id)
502  {
503  $max_points += $question_points[$question_id]['max_points'];
504  $reached_points += $question_points[$question_id]['reached_points'];
505  }
506  if(!$max_points)
507  {
508  return false;
509  }
510 
511  return $reached_points >= $objective_data['tst_limit'] ? true : false;
512 
513  return (($reached_points / $max_points * 100) >= $objective_data['tst_limit']) ? true : false;
514  }
515 
523  static function __updatePassed($a_user_id,$objective_ids)
524  {
525  global $ilDB;
526 
527  $passed = array();
528 
529  $query = "SELECT COUNT(t1.crs_id) num,t1.crs_id FROM crs_objectives t1 ".
530  "JOIN crs_objectives t2 WHERE t1.crs_id = t2.crs_id and ".
531  $ilDB->in('t1.objective_id',$objective_ids,false,'integer')." ".
532  "GROUP BY t1.crs_id";
533  $res = $ilDB->query($query);
534  $crs_ids = array();
535  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
536  {
537  $query = "SELECT COUNT(cs.objective_id) num_passed FROM crs_objective_status cs ".
538  "JOIN crs_objectives co ON cs.objective_id = co.objective_id ".
539  "WHERE crs_id = ".$ilDB->quote($row->crs_id ,'integer')." ".
540  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
541 
542  $user_res = $ilDB->query($query);
543  while($user_row = $user_res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
544  {
545  if($user_row->num_passed == $row->num)
546  {
547  $passed[] = $row->crs_id;
548  }
549  }
550  $crs_ids[$row->crs_id] = $row->crs_id;
551  }
552  if(count($passed))
553  {
554  foreach($passed as $crs_id)
555  {
556  include_once('Modules/Course/classes/class.ilCourseParticipants.php');
557  $members = ilCourseParticipants::_getInstanceByObjId($crs_id);
558  $members->updatePassed($a_user_id,true);
559  }
560  }
561 
562  // update tracking status
563  foreach ($crs_ids as $cid)
564  {
565  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
566  ilLPStatusWrapper::_updateStatus($cid, $a_user_id);
567  }
568  }
569 
570 }
571 ?>
static _readAssignedObjectivesOfQuestion($a_question_id)
static getInstanceByObjId($a_obj_id)
get singleton instance
static getInstance($a_container_id)
Get instance by container id.
static getSuggestedQuestions($a_usr_id, $a_crs_id)
get suggested questions ids
Class ilObjectFactory.
const IL_OBJECTIVE_STATUS_EMPTY
const IL_OBJECTIVE_STATUS_FINISHED
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
static _getObjectiveIds($course_id, $a_activated_only=false)
getSuggested($a_crs_id, $a_status=IL_OBJECTIVE_STATUS_FINAL)
resetTestForUser(ilObjTest $a_test, $a_user_id)
const IL_OBJECTIVE_STATUS_PRETEST_NON_SUGGEST
static _getSuggested($a_user_id, $a_crs_id, $a_status=IL_OBJECTIVE_STATUS_FINAL)
getActiveIdOfUser($user_id="", $anonymous_id="")
Gets the active id of a given user.
getId()
get object id public
removeTestActives($activeIds)
const IL_OBJECTIVE_STATUS_NONE
$ilUser
Definition: imgupload.php:18
static _updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static _getAccomplished($a_user_id, $a_crs_id)
const IL_OBJECTIVE_STATUS_FINAL
Create styles array
The data for the language used.
const IL_OBJECTIVE_STATUS_PRETEST
static _readAssignedObjectives($a_all_objectives)
global $lng
Definition: privfeed.php:17
global $ilDB
static __updatePassed($a_user_id, $objective_ids)
can be protected?
static _updateObjectiveStatus($a_user_id, $objectives)
static getInstance($a_obj_id)
class ilcourseobjectiveQuestion
static __isFullfilled($question_points, $objective_data)