ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCourseObjectiveQuestion.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 
35 {
37  const TYPE_FINAL_TEST = 1;
38 
39  public $db = null;
40 
41  public $objective_id = null;
42  public $questions;
43  protected $tests = array();
44 
45  function ilCourseObjectiveQuestion($a_objective_id)
46  {
47  global $ilDB;
48 
49  $this->db =& $ilDB;
50 
51  $this->objective_id = $a_objective_id;
52 
53  $this->__read();
54  }
55 
56 
67  public static function _isTestAssignedToObjective($a_test_id,$a_objective_id)
68  {
69  global $ilDB;
70 
71  $query = "SELECT qst_ass_id FROM crs_objective_qst ".
72  "WHERE ref_id = ".$ilDB->quote($a_test_id ,'integer')." ".
73  "AND objective_id = ".$ilDB->quote($a_objective_id ,'integer');
74  $res = $ilDB->query($query);
75  return $res->numRows() ? true : false;
76  }
77 
87  public function cloneDependencies($a_new_objective,$a_copy_id)
88  {
89  global $ilObjDataCache,$ilLog,$ilDB;
90 
91  include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
92  $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
93  $mappings = $cwo->getMappings();
94  foreach($this->getQuestions() as $question)
95  {
96  if(!isset($mappings["$question[ref_id]"]) or !$mappings["$question[ref_id]"])
97  {
98  continue;
99  }
100  $question_ref_id = $question['ref_id'];
101  $question_obj_id = $question['obj_id'];
102  $question_qst_id = $question['question_id'];
103  $new_ref_id = $mappings[$question_ref_id];
104  $new_obj_id = $ilObjDataCache->lookupObjId($new_ref_id);
105 
106  if($new_obj_id == $question_obj_id)
107  {
108  $ilLog->write(__METHOD__.': Test has been linked. Keeping question id.');
109  // Object has been linked
110  $new_question_id = $question_qst_id;
111  }
112  else
113  {
114  $new_question_info = $mappings[$question_ref_id.'_'.$question_qst_id];
115  $new_question_arr = explode('_',$new_question_info);
116  if(!isset($new_question_arr[1]) or !$new_question_arr[1])
117  {
118  continue;
119  }
120  $new_question_id = $new_question_arr[1];
121  $ilLog->write(__METHOD__.': New question id is: '.$new_question_id);
122  }
123 
124  $new_question = new ilCourseObjectiveQuestion($a_new_objective);
125  $new_question->setTestRefId($new_ref_id);
126  $new_question->setTestObjId($new_obj_id);
127  $new_question->setQuestionId($new_question_id);
128  $new_question->add();
129  }
130 
131  // Copy tests
132  foreach($this->getTests() as $test)
133  {
134  $new_test_id = $mappings["$test[ref_id]"];
135 
136  $query = "UPDATE crs_objective_tst ".
137  "SET tst_status = ".$this->db->quote($test['tst_status'] ,'integer').", ".
138  "tst_limit = ".$this->db->quote($test['tst_limit'] ,'integer')." ".
139  "WHERE objective_id = ".$this->db->quote($a_new_objective ,'integer')." ".
140  "AND ref_id = ".$this->db->quote($new_test_id ,'integer');
141  $res = $ilDB->manipulate($query);
142  }
143  }
144 
153  public static function _getAssignableTests($a_container_ref_id)
154  {
155  global $tree;
156 
157  return $tree->getSubTree($tree->getNodeData($a_container_ref_id),true,'tst');
158  }
159 
160  // ######################################################## Methods for test table
161  function setTestStatus($a_status)
162  {
163  $this->tst_status = $a_status;
164  }
165  function getTestStatus()
166  {
167  return (int) $this->tst_status;
168  }
169  function setTestSuggestedLimit($a_limit)
170  {
171  $this->tst_limit = $a_limit;
172  }
174  {
175  return (int) $this->tst_limit;
176  }
177  function __addTest()
178  {
179  global $ilDB;
180 
181  $query = "UPDATE crs_objective_tst ".
182  "SET tst_status = ".$this->db->quote($this->getTestStatus() ,'integer')." ".
183  "WHERE objective_id = ".$this->db->quote($this->getObjectiveId() ,'integer')." ".
184  "AND ref_id = ".$this->db->quote($this->getTestRefId() ,'integer')." ";
185  $res = $ilDB->manipulate($query);
186 
187 
188  // CHECK if entry already exists
189  $query = "SELECT * FROM crs_objective_tst ".
190  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ".
191  "AND ref_id = ".$ilDB->quote($this->getTestRefId() ,'integer')."";
192 
193  $res = $this->db->query($query);
194  if($res->numRows())
195  {
196  return false;
197  }
198 
199  // Check for existing limit
200  $query = "SELECT tst_limit FROM crs_objective_tst ".
201  "WHERE objective_id = ".$this->db->quote($this->getObjectiveId() ,'integer')." ".
202  "AND tst_status = ".$this->db->quote($this->getTestStatus() ,'integer')." ";
203 
204  $res = $this->db->query($query);
205 
206  $limit = -1;
207  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
208  {
209  $limit = $row->tst_limit;
210  }
211 
212  $next_id = $ilDB->nextId('crs_objective_tst');
213  $query = "INSERT INTO crs_objective_tst (test_objective_id,objective_id,ref_id,obj_id,tst_status,tst_limit) ".
214  "VALUES( ".
215  $ilDB->quote($next_id,'integer').", ".
216  $ilDB->quote($this->getObjectiveId() ,'integer').", ".
217  $ilDB->quote($this->getTestRefId() ,'integer').", ".
218  $ilDB->quote($this->getTestObjId() ,'integer').", ".
219  $ilDB->quote($this->getTestStatus() ,'integer').", ".
220  $this->db->quote($limit ,'integer')." ".
221  ")";
222  $res = $ilDB->manipulate($query);
223 
224  return true;
225  }
226 
227  function __deleteTest($a_test_ref_id)
228  {
229  global $ilDB;
230 
231  // Delete questions
232  $query = "DELETE FROM crs_objective_qst ".
233  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ".
234  "AND ref_id = ".$ilDB->quote($a_test_ref_id ,'integer')." ";
235  $res = $ilDB->manipulate($query);
236 
237  // delete tst entries
238  $query = "DELETE FROM crs_objective_tst ".
239  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ".
240  "AND ref_id = ".$ilDB->quote($a_test_ref_id ,'integer')." ";
241  $res = $ilDB->manipulate($query);
242 
243  unset($this->tests[$a_test_ref_id]);
244 
245  return true;
246  }
247 
258  public static function _updateTestLimits($a_objective_id,$a_status,$a_limit)
259  {
260  global $ilDB;
261 
262  $query = "UPDATE crs_objective_tst ".
263  "SET tst_limit = ".$ilDB->quote($a_limit ,'integer')." ".
264  "WHERE tst_status = ".$ilDB->quote($a_status ,'integer')." ".
265  "AND objective_id = ".$ilDB->quote($a_objective_id ,'integer');
266  $res = $ilDB->manipulate($query);
267  return true;
268  }
269 
270  function updateTest($a_objective_id)
271  {
272  global $ilDB;
273 
274  $query = "UPDATE crs_objective_tst ".
275  "SET tst_status = ".$ilDB->quote($this->getTestStatus() ,'integer').", ".
276  "tst_limit = ".$ilDB->quote($this->getTestSuggestedLimit() ,'integer')." ".
277  "WHERE test_objective_id = ".$ilDB->quote($a_objective_id ,'integer')."";
278  $res = $ilDB->manipulate($query);
279 
280  return true;
281  }
282 
283  function getTests()
284  {
285  global $ilDB;
286 
287  $query = "SELECT * FROM crs_objective_tst cot ".
288  "JOIN object_data obd ON cot.obj_id = obd.obj_id ".
289  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ".
290  "ORDER BY title ";
291 
292  $res = $this->db->query($query);
293  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
294  {
295  $test['test_objective_id'] = $row->test_objective_id;
296  $test['objective_id'] = $row->objective_id;
297  $test['ref_id'] = $row->ref_id;
298  $test['obj_id'] = $row->obj_id;
299  $test['tst_status'] = $row->tst_status;
300  $test['tst_limit'] = $row->tst_limit;
301  $test['title'] = $row->title;
302 
303  $tests[] = $test;
304  }
305 
306  return $tests ? $tests : array();
307  }
308 
316  public function getSelfAssessmentTests()
317  {
318  foreach($this->tests as $test)
319  {
320  if($test['status'] == self::TYPE_SELF_ASSESSMENT)
321  {
322  $self[] = $test;
323  }
324  }
325  return $self ? $self : array();
326  }
327 
334  public function getFinalTests()
335  {
336  foreach($this->tests as $test)
337  {
338  if($test['status'] == self::TYPE_FINAL_TEST)
339  {
340  $final[] = $test;
341  }
342  }
343  return $final ? $final : array();
344  }
345 
346  function _getTest($a_test_objective_id)
347  {
348  global $ilDB;
349 
350  $query = "SELECT * FROM crs_objective_tst ".
351  "WHERE test_objective_id = ".$ilDB->quote($a_test_objective_id ,'integer')." ";
352 
353  $res = $ilDB->query($query);
354  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
355  {
356  $test['test_objective_id'] = $row->test_objective_id;
357  $test['objective_id'] = $row->objective_id;
358  $test['ref_id'] = $row->ref_id;
359  $test['obj_id'] = $row->obj_id;
360  $test['tst_status'] = $row->tst_status;
361  $test['tst_limit'] = $row->tst_limit;
362  }
363 
364  return $test ? $test : array();
365  }
366 
367  // ############################################################# METHODS for question table
368  function getQuestions()
369  {
370  return $this->questions ? $this->questions : array();
371  }
372 
379  public function getSelfAssessmentQuestions()
380  {
381  foreach($this->questions as $question)
382  {
383  if($question['test_type'] == self::TYPE_SELF_ASSESSMENT)
384  {
385  $self[] = $question;
386  }
387  }
388  return $self ? $self : array();
389  }
390 
397  public function getSelfAssessmentPoints()
398  {
399  foreach($this->getSelfAssessmentQuestions() as $question)
400  {
401  $points += $question['points'];
402  }
403  return $points ? $points : 0;
404  }
405 
412  public function getFinalTestPoints()
413  {
414  foreach($this->getFinalTestQuestions() as $question)
415  {
416  $points += $question['points'];
417  }
418  return $points ? $points : 0;
419  }
420 
427  public function isSelfAssessmentQuestion($a_question_id)
428  {
429  foreach($this->questions as $question)
430  {
431  if($question['question_id'] == $a_question_id)
432  {
433  return $question['test_type'] == self::TYPE_SELF_ASSESSMENT;
434  }
435  }
436  return false;
437  }
438 
446  public function isFinalTestQuestion($a_question_id)
447  {
448  foreach($this->questions as $question)
449  {
450  if($question['question_id'] == $a_question_id)
451  {
452  return $question['test_type'] == self::TYPE_FINAL_TEST;
453  }
454  }
455  return false;
456 
457  }
458 
465  public function getFinalTestQuestions()
466  {
467  foreach($this->questions as $question)
468  {
469  if($question['test_type'] == self::TYPE_FINAL_TEST)
470  {
471  $final[] = $question;
472  }
473  }
474  return $final ? $final : array();
475  }
476 
477 
478 
486  public function getQuestionsOfTest($a_test_id)
487  {
488  foreach($this->getQuestions() as $qst)
489  {
490  if($a_test_id == $qst['obj_id'])
491  {
492  $questions[] = $qst;
493  }
494  }
495  return $questions ? $questions : array();
496  }
497 
498  function getQuestion($question_id)
499  {
500  return $this->questions[$question_id] ? $this->questions[$question_id] : array();
501  }
502 
503  function getObjectiveId()
504  {
505  return $this->objective_id;
506  }
507 
508  function setTestRefId($a_ref_id)
509  {
510  $this->tst_ref_id = $a_ref_id;
511  }
512  function getTestRefId()
513  {
514  return $this->tst_ref_id ? $this->tst_ref_id : 0;
515  }
516  function setTestObjId($a_obj_id)
517  {
518  $this->tst_obj_id = $a_obj_id;
519  }
520  function getTestObjId()
521  {
522  return $this->tst_obj_id ? $this->tst_obj_id : 0;
523  }
524  function setQuestionId($a_question_id)
525  {
526  $this->question_id = $a_question_id;
527  }
528  function getQuestionId()
529  {
530  return $this->question_id;
531  }
532 
533 
535  {
536  include_once './Modules/Test/classes/class.ilObjTest.php';
537 
538  $points = 0;
539  foreach($this->getQuestions() as $question)
540  {
541  $tmp_test =& ilObjectFactory::getInstanceByRefId($question['ref_id']);
542 
543  $tmp_question =& ilObjTest::_instanciateQuestion($question['question_id']);
544 
545  $points += $tmp_question->getMaximumPoints();
546 
547  unset($tmp_question);
548  unset($tmp_test);
549  }
550  return $points;
551  }
552 
553  function getMaxPointsByTest($a_test_ref_id)
554  {
555  $points = 0;
556 
557  $tmp_test =& ilObjectFactory::getInstanceByRefId($a_test_ref_id);
558 
559  foreach($this->getQuestions() as $question)
560  {
561  if($question['ref_id'] == $a_test_ref_id)
562  {
563  $tmp_question =& ilObjTest::_instanciateQuestion($question['question_id']);
564 
565  $points += $tmp_question->getMaximumPoints();
566 
567  unset($tmp_question);
568  }
569  }
570  unset($tmp_test);
571 
572  return $points;
573  }
574 
583  public static function _lookupMaximumPointsOfQuestion($a_question_id)
584  {
585  include_once('Modules/TestQuestionPool/classes/class.assQuestion.php');
586  return assQuestion::_getMaximumPoints($a_question_id);
587  }
588 
589 
590  function getNumberOfQuestionsByTest($a_test_ref_id)
591  {
592  $counter = 0;
593 
594  foreach($this->getQuestions() as $question)
595  {
596  if($question['ref_id'] == $a_test_ref_id)
597  {
598  ++$counter;
599  }
600  }
601  return $counter;
602  }
603 
604  function getQuestionsByTest($a_test_ref_id)
605  {
606  foreach($this->getQuestions() as $question)
607  {
608  if($question['ref_id'] == $a_test_ref_id)
609  {
610  $qst[] = $question['question_id'];
611  }
612  }
613  return $qst ? $qst : array();
614  }
615 
623  public function updateLimits()
624  {
625  global $ilDB;
626 
627  foreach($this->tests as $ref_id => $test_data)
628  {
629  switch($test_data['status'])
630  {
632  $points = $this->getSelfAssessmentPoints();
633  break;
634 
635  case self::TYPE_FINAL_TEST:
636  $points = $this->getFinalTestPoints();
637  break;
638  }
639  if($test_data['limit'] == -1 or $test_data['limit'] > $points)
640  {
641  switch($test_data['status'])
642  {
644  $points = $this->getSelfAssessmentPoints();
645  break;
646 
647  case self::TYPE_FINAL_TEST:
648  $points = $this->getFinalTestPoints();
649  break;
650  }
651  $query = "UPDATE crs_objective_tst ".
652  "SET tst_limit = ".$this->db->quote($points ,'integer')." ".
653  "WHERE test_objective_id = ".$this->db->quote($test_data['test_objective_id'] ,'integer')." ";
654  $res = $ilDB->manipulate($query);
655  }
656  }
657  }
658 
659 
660  function add()
661  {
662  global $ilDB;
663 
664  $query = "DELETE FROM crs_objective_qst ".
665  "WHERE objective_id = ".$this->db->quote($this->getObjectiveId() ,'integer')." ".
666  "AND question_id = ".$this->db->quote($this->getQuestionId() ,'integer')." ";
667  $res = $ilDB->manipulate($query);
668 
669  $next_id = $ilDB->nextId('crs_objective_qst');
670  $query = "INSERT INTO crs_objective_qst (qst_ass_id, objective_id,ref_id,obj_id,question_id) ".
671  "VALUES( ".
672  $ilDB->quote($next_id,'integer').", ".
673  $ilDB->quote($this->getObjectiveId() ,'integer').", ".
674  $ilDB->quote($this->getTestRefId() ,'integer').", ".
675  $ilDB->quote($this->getTestObjId() ,'integer').", ".
676  $ilDB->quote($this->getQuestionId() ,'integer').
677  ")";
678  $res = $ilDB->manipulate($query);
679 
680  $this->__addTest();
681 
682  $this->__read();
683 
684  return true;
685  }
686  function delete($qst_id)
687  {
688  global $ilDB;
689 
690  if(!$qst_id)
691  {
692  return false;
693  }
694 
695  $query = "SELECT * FROM crs_objective_qst ".
696  "WHERE qst_ass_id = ".$ilDB->quote($qst_id ,'integer')." ";
697 
698  $res = $this->db->query($query);
699  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
700  {
701  $test_rid = $row->ref_id;
702  $test_oid = $row->obj_id;
703  }
704 
705  $query = "DELETE FROM crs_objective_qst ".
706  "WHERE qst_ass_id = ".$ilDB->quote($qst_id ,'integer')." ";
707  $res = $ilDB->manipulate($query);
708 
709  // delete test if it was the last question
710  $query = "SELECT * FROM crs_objective_qst ".
711  "WHERE ref_id = ".$ilDB->quote($test_rid ,'integer')." ".
712  "AND obj_id = ".$ilDB->quote($test_oid ,'integer')." ".
713  "AND objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ";
714 
715  $res = $this->db->query($query);
716  if(!$res->numRows())
717  {
718  $this->__deleteTest($test_rid);
719  }
720 
721  return true;
722  }
723 
724  function deleteAll()
725  {
726  global $ilDB;
727 
728  $query = "DELETE FROM crs_objective_qst ".
729  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ";
730  $res = $ilDB->manipulate($query);
731 
732  $query = "DELETE FROM crs_objective_tst ".
733  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ";
734  $res = $ilDB->manipulate($query);
735 
736  return true;
737  }
738 
739 
740  // PRIVATE
741  function __read()
742  {
743  global $ilDB,$tree;
744 
745  include_once './Modules/Test/classes/class.ilObjTest.php';
746  include_once('Modules/Course/classes/class.ilCourseObjective.php');
747 
748  $container_ref_ids = ilObject::_getAllReferences(ilCourseObjective::_lookupContainerIdByObjectiveId($this->objective_id));
749  $container_ref_id = current($container_ref_ids);
750 
751  // Read test data
752  $query = "SELECT * FROM crs_objective_tst ".
753  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ";
754  $res = $this->db->query($query);
755  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
756  {
757  $this->tests[$row->ref_id]['test_objective_id'] = $row->test_objective_id;
758  $this->tests[$row->ref_id]['ref_id'] = $row->ref_id;
759  $this->tests[$row->ref_id]['obj_id'] = $row->obj_id;
760  $this->tests[$row->ref_id]['status'] = $row->tst_status;
761  $this->tests[$row->ref_id]['limit'] = $row->tst_limit;
762  }
763 
764  $this->questions = array();
765  $query = "SELECT * FROM crs_objective_qst coq ".
766  "JOIN qpl_questions qq ON coq.question_id = qq.question_id ".
767  "WHERE objective_id = ".$ilDB->quote($this->getObjectiveId() ,'integer')." ".
768  "ORDER BY title";
769 
770  $res = $this->db->query($query);
771  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
772  {
773  if(!$tree->isInTree($row->ref_id) or !$tree->isGrandChild($container_ref_id,$row->ref_id))
774  {
775  $this->__deleteTest($row->ref_id);
776  continue;
777  }
778  if(!$question = ilObjTest::_instanciateQuestion($row->question_id))
779  {
780  $this->delete($row->question_id);
781  continue;
782  }
783 
784  $qst['ref_id'] = $row->ref_id;
785  $qst['obj_id'] = $row->obj_id;
786  $qst['question_id'] = $row->question_id;
787  $qst['qst_ass_id'] = $row->qst_ass_id;
788  $qst['title'] = $question->getTitle();
789  $qst['description'] = $question->getComment();
790  $qst['test_type'] = $this->tests[$row->ref_id]['status'];
791  $qst['points'] = $question->getPoints();
792 
793  $this->questions[$row->qst_ass_id] = $qst;
794  }
795 
796  return true;
797  }
798 
799  // STATIC
807  public function _hasTests($a_course_id)
808  {
809  global $ilDB;
810 
811  $query = "SELECT co.objective_id FROM crs_objectives co JOIN ".
812  "crs_objective_tst cot ON co.objective_id = cot.objective_id ".
813  "WHERE crs_id = ".$ilDB->quote($a_course_id ,'integer')." ";
814  $res = $ilDB->query($query);
815  return $res->numRows() ? true : false;
816  }
817 
818 
819  function _isAssigned($a_objective_id,$a_tst_ref_id,$a_question_id)
820  {
821  global $ilDB;
822 
823  $query = "SELECT crs_qst.objective_id objective_id FROM crs_objective_qst crs_qst, crs_objectives crs_obj ".
824  "WHERE crs_qst.objective_id = crs_obj.objective_id ".
825  "AND crs_qst.objective_id = ".$ilDB->quote($a_objective_id ,'integer') ." ".
826  "AND ref_id = ".$ilDB->quote($a_tst_ref_id ,'integer')." ".
827  "AND question_id = ".$ilDB->quote($a_question_id ,'integer')." ";
828 
829  $res = $ilDB->query($query);
830  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
831  {
832  $objective_id = $row->objective_id;
833  }
834 
835  return $objective_id ? $objective_id : 0;
836  }
837 
838 }
839 ?>