ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCourseObjectiveResult.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 
34 define('IL_OBJECTIVE_STATUS_EMPTY','empty');
35 define('IL_OBJECTIVE_STATUS_PRETEST','pretest');
36 define('IL_OBJECTIVE_STATUS_FINAL','final');
37 define('IL_OBJECTIVE_STATUS_NONE','none');
38 define('IL_OBJECTIVE_STATUS_FINISHED','finished');
39 define('IL_OBJECTIVE_STATUS_PRETEST_NON_SUGGEST','pretest_non_suggest');
40 
41 
43 {
44  var $db = null;
45  var $user_id = null;
46 
47 
48  function ilCourseObjectiveResult($a_usr_id)
49  {
50  global $ilDB;
51 
52  $this->db =& $ilDB;
53 
54  $this->user_id = $a_usr_id;
55  }
56  function getUserId()
57  {
58  return $this->user_id;
59  }
60 
61  function getAccomplished($a_crs_id)
62  {
63  return ilCourseObjectiveResult::_getAccomplished($this->getUserId(),$a_crs_id);
64  }
65  function _getAccomplished($a_user_id,$a_crs_id)
66  {
67  global $ilDB;
68 
69  include_once 'Modules/Course/classes/class.ilCourseObjective.php';
70  $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id);
71 
72  if(!is_array($objectives))
73  {
74  return array();
75  }
76  $query = "SELECT objective_id FROM crs_objective_status ".
77  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
78  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
79  $res = $ilDB->query($query);
80  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
81  {
82  $accomplished[] = $row->objective_id;
83  }
84  return $accomplished ? $accomplished : array();
85  }
86 
87  function getSuggested($a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
88  {
89  return ilCourseObjectiveResult::_getSuggested($this->getUserId(),$a_crs_id,$a_status);
90  }
91 
92  function _getSuggested($a_user_id,$a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
93  {
94  global $ilDB;
95 
96  include_once './Modules/Course/classes/class.ilCourseObjective.php';
97  $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id);
98 
99  $finished = array();
100  if($a_status == IL_OBJECTIVE_STATUS_FINAL or
101  $a_status == IL_OBJECTIVE_STATUS_FINISHED)
102  {
103  // check finished
104  $query = "SELECT objective_id FROM crs_objective_status ".
105  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer')." ".
106  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
107  $res = $ilDB->query($query);
108  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
109  {
110  $finished[] = $row->objective_id;
111  }
112  }
113  else
114  {
115  // Pretest
116  $query = "SELECT objective_id FROM crs_objective_status_p ".
117  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
118  "AND user_id = ".$ilDB->quote($a_user_id ,'integer');
119  $res = $ilDB->query($query);
120  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
121  {
122  $finished[] = $row->objective_id;
123  }
124  }
125  foreach($objectives as $objective_id)
126  {
127  if(!in_array($objective_id,$finished))
128  {
129  $suggested[] = $objective_id;
130  }
131  }
132  return $suggested ? $suggested : array();
133  }
134 
141  public static function getSuggestedQuestions($a_usr_id,$a_crs_id)
142  {
143  foreach(self::_getSuggested($a_usr_id,$a_crs_id) as $objective_id)
144  {
145  include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
146  $obj = new ilCourseObjectiveQuestion($objective_id);
147  foreach($obj->getFinalTestQuestions() as $qst)
148  {
149  $qsts[] = $qst['question_id'];
150  }
151  }
152  return $qsts ? $qsts : array();
153  }
154 
155  function reset($a_course_id)
156  {
157  global $ilDB;
158 
159  include_once './Modules/Course/classes/class.ilCourseObjective.php';
160  include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
161 
162 
163  foreach($objectives = ilCourseObjective::_getObjectiveIds($a_course_id) as $objective_id)
164  {
165  $tmp_obj_question =& new ilCourseObjectiveQuestion($objective_id);
166 
167  foreach($tmp_obj_question->getTests() as $test_data)
168  {
169  #$this->__deleteEntries($tmp_obj_question->getQuestionsByTest($test_data['ref_id']));
170 
171  if($tmp_test =& ilObjectFactory::getInstanceByRefId($test_data['ref_id']))
172  {
173  $tmp_test->removeTestResultsForUser($this->getUserId());
174  unset($tmp_test);
175  }
176  }
177  }
178 
179  if(count($objectives))
180  {
181  $query = "DELETE FROM crs_objective_status ".
182  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
183  "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')." ";
184  $res = $ilDB->manipulate($query);
185 
186  $query = "DELETE FROM crs_objective_status_p ".
187  "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
188  "AND user_id = ".$ilDB->quote($this->getUserId())."";
189  $res = $ilDB->manipulate($query);
190  }
191 
192  return true;
193  }
194 
195  function getStatus($a_course_id)
196  {
197  include_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
198  include_once 'Modules/Course/classes/class.ilCourseObjective.php';
199  $objective_ids = ilCourseObjective::_getObjectiveIds($a_course_id);
200  $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
201  $accomplished = $this->getAccomplished($a_course_id);
202  $suggested = $this->getSuggested($a_course_id);
203 
204  if(!count($objective_ids))
205  {
207  }
208 
209  if(count($accomplished) == count($objective_ids))
210  {
212  }
213 
214  $all_pretest_answered = false;
215  $all_final_answered = false;
216  foreach($objectives as $data)
217  {
218  if(assQuestion::_areAnswered($this->getUserId(),$data['questions']))
219  {
220  if($data['tst_status'])
221  {
222  $all_final_answered = true;
223  }
224  else
225  {
226  $all_pretest_answered = true;
227  }
228  }
229  }
230  if($all_final_answered)
231  {
233  }
234  if($all_pretest_answered and
235  !count($suggested))
236  {
238  }
239  elseif($all_pretest_answered)
240  {
242  }
244  }
245 
246  function hasAccomplishedObjective($a_objective_id)
247  {
248  global $ilDB;
249 
250  $query = "SELECT status FROM crs_objective_status ".
251  "WHERE objective_id = ".$ilDB->quote($a_objective_id ,'integer')." ".
252  "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')."";
253 
254  $res = $this->db->query($query);
255  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
256  {
257  return true;
258  }
259  return false;
260  }
261 
262  function readStatus($a_crs_id)
263  {
264  include_once './Modules/Course/classes/class.ilCourseObjective.php';
265 
266  $objective_ids = ilCourseObjective::_getObjectiveIds($a_crs_id);
267  $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
269  return true;
270  }
271 
272 
273 
274 
275  // PRIVATE
276  function __deleteEntries($a_objective_ids)
277  {
278  global $ilLog;
279 
280  $ilLog->logStack();
281  #$ilLog(__METHOD__.': Call of deprecated method.');
282 
283  return true;
284  }
285 
286  public static function _deleteUser($user_id)
287  {
288  global $ilDB;
289 
290  $query = "DELETE FROM crs_objective_status ".
291  "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
292  $res = $ilDB->manipulate($query);
293 
294  $query = "DELETE FROM crs_objective_status_p ".
295  "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
296  $res = $ilDB->manipulate($query);
297  return true;
298  }
299 
300  function _updateObjectiveResult($a_user_id,$a_active_id,$a_question_id)
301  {
302  // find all objectives this question is assigned to
303  if(!$objectives = ilCourseObjectiveResult::_readAssignedObjectivesOfQuestion($a_question_id))
304  {
305  // no objectives found. TODO user has passed a test. After that questions of that test are assigned to an objective.
306  // => User has not passed
307  return true;
308  }
309  ilCourseObjectiveResult::_updateObjectiveStatus($a_user_id,$objectives);
310 
311  return true;
312  }
313 
314  function _readAssignedObjectivesOfQuestion($a_question_id)
315  {
316  global $ilDB;
317 
318  // get all objtives and questions this current question is assigned to
319  $query = "SELECT q2.question_id qid,q2.objective_id ob FROM crs_objective_qst q1, ".
320  "crs_objective_qst q2 ".
321  "WHERE q1.question_id = ".$ilDB->quote($a_question_id ,'integer')." ".
322  "AND q1.objective_id = q2.objective_id ";
323 
324  $res = $ilDB->query($query);
325  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
326  {
327  $objectives['all_objectives'][$row->ob] = $row->ob;
328  $objectives['all_questions'][$row->qid] = $row->qid;
329  }
330  if(!is_array($objectives))
331  {
332  return false;
333  }
334  $objectives['objectives'] = ilCourseObjectiveResult::_readAssignedObjectives($objectives['all_objectives']);
335  return $objectives ? $objectives : array();
336  }
337 
338 
339  function _readAssignedObjectives($a_all_objectives)
340  {
341  global $ilDB;
342 
343  // Read necessary points
344  $query = "SELECT t.objective_id obj,t.ref_id ref, question_id,tst_status,tst_limit ".
345  "FROM crs_objective_tst t JOIN crs_objective_qst q ".
346  "ON (t.objective_id = q.objective_id AND t.ref_id = q.ref_id) ".
347  "WHERE ".$ilDB->in('t.objective_id',$a_all_objectives,false,'integer');
348 
349  $res = $ilDB->query($query);
350  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
351  {
352  /*
353  $objectives[$row->obj."_".$row->ref]['questions'][$row->question_id] = $row->question_id;
354  $objectives[$row->obj."_".$row->ref]['tst_status'] = $row->tst_status;
355  $objectives[$row->obj."_".$row->ref]['tst_limit'] = $row->tst_limit;
356  $objectives[$row->obj."_".$row->ref]['objective_id'] = $row->obj;
357  */
358 
359  $objectives[$row->obj."_".$row->tst_status]['questions'][$row->question_id] = $row->question_id;
360  $objectives[$row->obj."_".$row->tst_status]['tst_status'] = $row->tst_status;
361  $objectives[$row->obj."_".$row->tst_status]['tst_limit'] = $row->tst_limit;
362  $objectives[$row->obj."_".$row->tst_status]['objective_id'] = $row->obj;
363 
364 
365  }
366  return $objectives ? $objectives : array();
367  }
368 
369  function _updateObjectiveStatus($a_user_id,$objectives)
370  {
371  global $ilDB,$ilUser;
372 
373  if(!count($objectives['all_questions']) or
374  !count($objectives['all_objectives']))
375  {
376  return false;
377  }
378  // Read reachable points
379  /*
380  $types = $ilDB->addTypesToArray(array(), 'integer', count($objectives['all_questions']));
381  $placeholders = $ilDB->addTypesToArray(array(), '%s', count($objectives['all_questions']));
382  $res = $ilDB->queryF("SELECT question_id,points FROM qpl_questions WHERE question_id IN(". implode(",", $placeholders) .")",
383  $types,
384  $objectives['all_questions']
385  );
386  */
387  $query = "SELECT question_id,points FROM qpl_questions ".
388  "WHERE ".$ilDB->in('question_id',(array) $objectives['all_questions'],false,'integer');
389  $res = $ilDB->query($query);
390  while($row = $ilDB->fetchAssoc($res))
391  {
392  $objectives['all_question_points'][$row['question_id']]['max_points'] = $row['points'];
393  }
394  // Read reached points
395  $query = "SELECT question_fi, MAX(points) as reached FROM tst_test_result ".
396  "JOIN tst_active ON (active_id = active_fi) ".
397  "WHERE user_fi = ".$ilDB->quote($a_user_id,'integer')." ".
398  "AND ".$ilDB->in('question_fi',(array) $objectives['all_questions'],false,'integer')." ".
399  #"AND question_fi IN (".implode(",",ilUtil::quoteArray($objectives['all_questions'])).") ".
400  "GROUP BY question_fi,user_fi";
401  $res = $ilDB->query($query);
402  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
403  {
404  $objectives['all_question_points'][$row->question_fi]['reached_points'] = $row->reached;
405  }
406 
407  // Check accomplished
408  $fullfilled = array();
409  $pretest = array();
410  foreach($objectives['objectives'] as $kind => $data)
411  {
412  // objective does not allow to change status
413  if(ilCourseObjectiveResult::__isFullfilled($objectives['all_question_points'],$data))
414  {
415  // Status 0 means pretest fullfilled, status 1 means final test fullfilled
416  if($data['tst_status'])
417  {
418  $fullfilled[] = array($data['objective_id'],$ilUser->getId(),$data['tst_status']);
419  }
420  else
421  {
422  $pretest[] = array($data['objective_id'],$ilUser->getId());
423  }
424  }
425  }
426  if(count($fullfilled))
427  {
428  $ilDB->executeMultiple($ilDB->prepare("REPLACE INTO crs_objective_status VALUES(?,?,?)"),
429  $fullfilled);
430  ilCourseObjectiveResult::__updatePassed($a_user_id,$objectives['all_objectives']);
431  }
432  if(count($pretest))
433  {
434  $ilDB->executeMultiple($ilDB->prepare("REPLACE INTO crs_objective_status_p VALUES(?,?)"),
435  $pretest);
436  }
437 
438  return true;
439  }
440 
441  function __isFullfilled($question_points,$objective_data)
442  {
443  if(!is_array($objective_data['questions']))
444  {
445  return false;
446  }
447  $max_points = 0;
448  $reached_points = 0;
449  foreach($objective_data['questions'] as $question_id)
450  {
451  $max_points += $question_points[$question_id]['max_points'];
452  $reached_points += $question_points[$question_id]['reached_points'];
453  }
454  if(!$max_points)
455  {
456  return false;
457  }
458 
459  return $reached_points >= $objective_data['tst_limit'] ? true : false;
460 
461  return (($reached_points / $max_points * 100) >= $objective_data['tst_limit']) ? true : false;
462  }
463 
464  function __updatePassed($a_user_id,$objective_ids)
465  {
466  global $ilDB;
467 
468  $passed = array();
469 
470  $query = "SELECT COUNT(t1.crs_id) num,t1.crs_id FROM crs_objectives t1 ".
471  "JOIN crs_objectives t2 WHERE t1.crs_id = t2.crs_id and ".
472  $ilDB->in('t1.objective_id',$objective_ids,false,'integer')." ".
473  "GROUP BY t1.crs_id";
474  $res = $ilDB->query($query);
475  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
476  {
477  $query = "SELECT COUNT(cs.objective_id) num_passed FROM crs_objective_status cs ".
478  "JOIN crs_objectives co ON cs.objective_id = co.objective_id ".
479  "WHERE crs_id = ".$ilDB->quote($row->crs_id ,'integer')." ".
480  "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
481 
482  $user_res = $ilDB->query($query);
483  while($user_row = $user_res->fetchRow(DB_FETCHMODE_OBJECT))
484  {
485  if($user_row->num_passed == $row->num)
486  {
487  $passed[] = $row->crs_id;
488  }
489  }
490  }
491  if(count($passed))
492  {
493  foreach($passed as $crs_id)
494  {
495  include_once('Modules/Course/classes/class.ilCourseParticipants.php');
496  $members = ilCourseParticipants::_getInstanceByObjId($crs_id);
497  $members->updatePassed($a_user_id,true);
498  }
499  }
500  }
501 
502 }
503 ?>