ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilConditionHandler.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
67 {
68  const UNIQUE_CONDITIONS = 1;
69  const SHARED_CONDITIONS = 0;
70 
71  var $db;
72  var $lng;
73 
74 
76 
83  var $operator;
84  var $value;
86 
88  static $cond_for_target_cache = array();
89  static $cond_target_rows = array();
90 
91 
96  function ilConditionHandler()
97  {
98  global $ilDB,$lng;
99 
100  $this->db =& $ilDB;
101  $this->lng =& $lng;
102  $this->validation = true;
103  }
104 
113  public static function _isReferenceHandlingOptional($a_type)
114  {
115  switch($a_type)
116  {
117  case 'st':
118  return true;
119 
120  default:
121  return false;
122  }
123  }
124 
135  public static function _adjustMovedObjectConditions($a_ref_id)
136  {
137  global $tree;
138 
139  if($tree->checkForParentType($a_ref_id,'crs'))
140  {
141  // Nothing to do
142  return true;
143  }
144 
145  // Need another implementation that has better performance
146  $childs = $tree->getSubTree($tree->getNodeData($a_ref_id),false);
148 
149  foreach(array_intersect($conditions,$childs) as $target_ref)
150  {
151  if(!$tree->checkForParentType($target_ref,'crs'))
152  {
154  }
155  }
156  return true;
157  }
158 
166  public static function _getDistinctTargetRefIds()
167  {
168  global $ilDB;
169 
170  $query = "SELECT DISTINCT target_ref_id ref FROM conditions ";
171  $res = $ilDB->query($query);
172  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
173  {
174  $ref_ids[] = $row->ref;
175  }
176  return $ref_ids ? $ref_ids : array();
177  }
178 
189  public static function _deleteTargetConditionsByRefId($a_target_ref_id)
190  {
191  global $ilDB;
192 
193  $query = "DELETE FROM conditions ".
194  "WHERE target_ref_id = ".$ilDB->quote($a_target_ref_id,'integer')." ".
195  "AND target_type != 'st' ";
196  $res = $ilDB->manipulate($query);
197  return true;
198  }
199 
207  public function setReferenceHandlingType($a_type)
208  {
209  return $this->condition_reference_type = $a_type;
210  }
211 
218  public function getReferenceHandlingType()
219  {
220  return (int) $this->condition_reference_type;
221  }
222 
223  // SET GET
224  function setErrorMessage($a_msg)
225  {
226  $this->error_message = $a_msg;
227  }
228  function getErrorMessage()
229  {
230  return $this->error_message;
231  }
232 
236  function setTargetRefId($a_target_ref_id)
237  {
238  return $this->target_ref_id = $a_target_ref_id;
239  }
240 
244  function getTargetRefId()
245  {
246  return $this->target_ref_id;
247  }
248 
252  function setTargetObjId($a_target_obj_id)
253  {
254  return $this->target_obj_id = $a_target_obj_id;
255  }
256 
260  function getTargetObjId()
261  {
262  return $this->target_obj_id;
263  }
264 
268  function setTargetType($a_target_type)
269  {
270  return $this->target_type = $a_target_type;
271  }
272 
276  function getTargetType()
277  {
278  return $this->target_type;
279  }
280 
284  function setTriggerRefId($a_trigger_ref_id)
285  {
286  return $this->trigger_ref_id = $a_trigger_ref_id;
287  }
288 
292  function getTriggerRefId()
293  {
294  return $this->trigger_ref_id;
295  }
296 
300  function setTriggerObjId($a_trigger_obj_id)
301  {
302  return $this->trigger_obj_id = $a_trigger_obj_id;
303  }
304 
308  function getTriggerObjId()
309  {
310  return $this->trigger_obj_id;
311  }
312 
316  function setTriggerType($a_trigger_type)
317  {
318  return $this->trigger_type = $a_trigger_type;
319  }
320 
324  function getTriggerType()
325  {
326  return $this->trigger_type;
327  }
328 
332  function setOperator($a_operator)
333  {
334  return $this->operator = $a_operator;
335  }
336 
340  function getOperator()
341  {
342  return $this->operator;
343  }
344 
348  function setValue($a_value)
349  {
350  return $this->value = $a_value;
351  }
352 
356  function getValue()
357  {
358  return $this->value;
359  }
360 
364  function enableAutomaticValidation($a_validate = true)
365  {
366  $this->validation = $a_validate;
367  }
368 
374  function getTriggerTypes()
375  {
376  return array('crs','exc','tst','sahs', 'svy');
377  }
378 
379 
380  function getOperatorsByTargetType($a_type)
381  {
382  switch($a_type)
383  {
384  case 'crs':
385  case 'exc':
386  return array('passed');
387 
388  case 'tst':
389  return array('passed','finished','not_finished');
390 
391  case 'crsg':
392  return array('not_member');
393 
394  case 'sahs':
395  return array('finished');
396 
397  case 'svy':
398  return array('finished');
399 
400  default:
401  return array();
402  }
403  }
404 
410  function storeCondition()
411  {
412  global $ilDB;
413 
414  // first insert, then validate: it's easier to check for circles if the new condition is in the db table
415  $next_id = $ilDB->nextId('conditions');
416  $query = 'INSERT INTO conditions (condition_id,target_ref_id,target_obj_id,target_type,'.
417  'trigger_ref_id,trigger_obj_id,trigger_type,operator,value,ref_handling) '.
418  'VALUES ('.
419  $ilDB->quote($next_id,'integer').','.
420  $ilDB->quote($this->getTargetRefId(),'integer').",".
421  $ilDB->quote($this->getTargetObjId(),'integer').",".
422  $ilDB->quote($this->getTargetType(),'text').",".
423  $ilDB->quote($this->getTriggerRefId(),'integer').",".
424  $ilDB->quote($this->getTriggerObjId(),'integer').",".
425  $ilDB->quote($this->getTriggerType(),'text').",".
426  $ilDB->quote($this->getOperator(),'text').",".
427  $ilDB->quote($this->getValue(),'text').", ".
428  $ilDB->quote($this->getReferenceHandlingType(),'integer').
429  ')';
430 
431  $res = $ilDB->manipulate($query);
432 
433  if ($this->validation && !$this->validate())
434  {
435  $this->deleteCondition($next_id);
436  return false;
437  }
438  return true;
439  }
440 
441  function checkExists()
442  {
443  global $ilDB;
444 
445  $query = "SELECT * FROM conditions ".
446  "WHERE target_ref_id = ".$ilDB->quote($this->getTargetRefId(),'integer')." ".
447  "AND target_obj_id = ".$ilDB->quote($this->getTargetObjId(),'integer')." ".
448  "AND trigger_ref_id = ".$ilDB->quote($this->getTriggerRefId(),'integer')." ".
449  "AND trigger_obj_id = ".$ilDB->quote($this->getTriggerObjId(),'integer')." ".
450  "AND operator = ".$ilDB->quote($this->getOperator(),'text');
451  $res = $ilDB->query($query);
452 
453  return $res->numRows() ? true : false;
454  }
458  function updateCondition($a_id)
459  {
460  global $ilDB;
461 
462  $query = "UPDATE conditions SET ".
463  "target_ref_id = ".$ilDB->quote($this->getTargetRefId(),'integer').", ".
464  "operator = ".$ilDB->quote($this->getOperator(),'text').", ".
465  "value = ".$ilDB->quote($this->getValue(),'text').", ".
466  "ref_handling = ".$this->db->quote($this->getReferenceHandlingType(),'integer')." ".
467  "WHERE condition_id = ".$ilDB->quote($a_id,'integer');
468  $res = $ilDB->manipulate($query);
469 
470  return true;
471  }
472 
473 
478  function delete($a_ref_id)
479  {
480  global $ilDB;
481 
482  $query = "DELETE FROM conditions WHERE ".
483  "target_ref_id = ".$ilDB->quote($a_ref_id,'integer')." ".
484  "OR trigger_ref_id = ".$ilDB->quote($a_ref_id,'integer');
485  $res = $ilDB->manipulate($query);
486 
487  return true;
488  }
493  function deleteByObjId($a_obj_id)
494  {
495  global $ilDB;
496 
497  $query = "DELETE FROM conditions WHERE ".
498  "target_obj_id = ".$ilDB->quote($a_obj_id,'integer')." ".
499  "OR trigger_obj_id = ".$ilDB->quote($a_obj_id,'integer');
500  $res = $ilDB->manipulate($query);
501 
502  return true;
503  }
504 
508  function deleteCondition($a_id)
509  {
510  global $ilDB;
511 
512  $query = "DELETE FROM conditions ".
513  "WHERE condition_id = ".$ilDB->quote($a_id,'integer');
514  $res = $ilDB->manipulate($query);
515 
516  return true;
517  }
518 
523  function _getConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
524  {
525  global $ilDB;
526 
527  $query = "SELECT * FROM conditions ".
528  "WHERE trigger_obj_id = ".$ilDB->quote($a_trigger_id,'integer')." ".
529  " AND trigger_type = ".$ilDB->quote($a_trigger_obj_type,'text');
530 
531  $res = $ilDB->query($query);
532  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
533  {
534  $tmp_array['id'] = $row->condition_id;
535  $tmp_array['target_ref_id'] = $row->target_ref_id;
536  $tmp_array['target_obj_id'] = $row->target_obj_id;
537  $tmp_array['target_type'] = $row->target_type;
538  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
539  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
540  $tmp_array['trigger_type'] = $row->trigger_type;
541  $tmp_array['operator'] = $row->operator;
542  $tmp_array['value'] = $row->value;
543  $tmp_array['ref_handling'] = $row->ref_handling;
544 
545  $conditions[] = $tmp_array;
546  unset($tmp_array);
547  }
548 
549  return $conditions ? $conditions : array();
550  }
551 
562  function _getConditionsOfTarget($a_target_ref_id,$a_target_obj_id, $a_target_type = "")
563  {
564  global $ilDB, $ilBench;
565 
566  // get type if no type given
567  if ($a_target_type == "")
568  {
569  $a_target_type = ilObject::_lookupType($a_target_obj_id);
570  }
571 
572  // check conditions for target cache
573  if (isset(self::$cond_for_target_cache[$a_target_ref_id.":".$a_target_obj_id.":".
574  $a_target_type]))
575  {
576  return self::$cond_for_target_cache[$a_target_ref_id.":".$a_target_obj_id.":".
577  $a_target_type];
578  }
579 
580  // check rows cache
581  if (isset(self::$cond_target_rows[$a_target_type.":".$a_target_obj_id]))
582  {
583  $rows = self::$cond_target_rows[$a_target_type.":".$a_target_obj_id];
584  }
585  else
586  {
587  // query data from db
588  $query = "SELECT * FROM conditions ".
589  "WHERE target_obj_id = ".$ilDB->quote($a_target_obj_id,'integer')." ".
590  " AND target_type = ".$ilDB->quote($a_target_type,'text');
591 
592  $res = $ilDB->query($query);
593  $rows = array();
594  while ($row = $ilDB->fetchAssoc($res))
595  {
596  $rows[] = $row;
597  }
598  }
599 
600  reset($rows);
601  $conditions = array();
602  foreach ($rows as $row)
603  {
604  if ($row["ref_handling"] == self::UNIQUE_CONDITIONS)
605  {
606  if ($row["target_ref_id"] != $a_target_ref_id)
607  {
608  continue;
609  }
610  }
611 
612  $row["id"] = $row["condition_id"];
613  $conditions[] = $row;
614  }
615 
616  // write conditions for target cache
617  self::$cond_for_target_cache[$a_target_ref_id.":".$a_target_obj_id.":".
618  $a_target_type] = $conditions;
619 
620  return $conditions;
621  }
622 
629  function preloadConditionsForTargetRecords($a_type, $a_obj_ids)
630  {
631  global $ilDB;
632 
633  if (is_array($a_obj_ids) && count($a_obj_ids) > 0)
634  {
635  $res = $ilDB->query("SELECT * FROM conditions ".
636  "WHERE ".$ilDB->in("target_obj_id", $a_obj_ids, false, "integer").
637  " AND target_type = ".$ilDB->quote($a_type,'text'));
638  $rows = array();
639  while ($row = $ilDB->fetchAssoc($res))
640  {
641  self::$cond_target_rows[$a_type.":".$row["target_obj_id"]][]
642  = $row;
643  }
644  // init obj ids without any record
645  foreach ($a_obj_ids as $obj_id)
646  {
647  if (!is_array(self::$cond_target_rows[$a_type.":".$obj_id]))
648  {
649  self::$cond_target_rows[$a_type.":".$obj_id] = array();
650  }
651  }
652  }
653  }
654 
655  function _getCondition($a_id)
656  {
657  global $ilDB;
658 
659  $query = "SELECT * FROM conditions ".
660  "WHERE condition_id = ".$ilDB->quote($a_id,'integer');
661 
662  $res = $ilDB->query($query);
663  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
664  {
665  $tmp_array['id'] = $row->condition_id;
666  $tmp_array['target_ref_id'] = $row->target_ref_id;
667  $tmp_array['target_obj_id'] = $row->target_obj_id;
668  $tmp_array['target_type'] = $row->target_type;
669  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
670  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
671  $tmp_array['trigger_type'] = $row->trigger_type;
672  $tmp_array['operator'] = $row->operator;
673  $tmp_array['value'] = $row->value;
674  $tmp_array['ref_handling'] = $row->ref_handling;
675 
676  return $tmp_array;
677  }
678  return false;
679  }
680 
681 
682 
688  function _checkCondition($a_id,$a_usr_id = 0)
689  {
690  global $ilUser;
691 
692  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
693 
694  $condition = ilConditionHandler::_getCondition($a_id);
695 
696  switch($condition['trigger_type'])
697  {
698  case "tst":
699  include_once './Modules/Test/classes/class.ilObjTestAccess.php';
700  return ilObjTestAccess::_checkCondition($condition['trigger_obj_id'],$condition['operator'],$condition['value'],$a_usr_id);
701 
702  case "crs":
703  include_once './Modules/Course/classes/class.ilObjCourse.php';
704  return ilObjCourse::_checkCondition($condition['trigger_obj_id'],$condition['operator'],$condition['value'],$a_usr_id);
705 
706  case 'exc':
707  include_once './Modules/Exercise/classes/class.ilObjExercise.php';
708  return ilObjExercise::_checkCondition($condition['trigger_obj_id'],$condition['operator'],$condition['value'],$a_usr_id);
709 
710  case 'crsg':
711  include_once './Modules/Course/classes/class.ilObjCourseGrouping.php';
712  return ilObjCourseGrouping::_checkCondition($condition['trigger_obj_id'],$condition['operator'],$condition['value'],$a_usr_id);
713 
714  case 'sahs':
715  include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
716  return in_array($a_usr_id,$completed = ilLPStatusWrapper::_getCompleted($condition['trigger_obj_id']));
717 
718  case 'svy':
719  include_once './Modules/Survey/classes/class.ilObjSurvey.php';
720  return ilObjSurvey::_checkCondition($condition['trigger_obj_id'],$condition['operator'],$condition['value'],$a_usr_id);
721 
722  default:
723  return false;
724 
725  }
726 
727  }
728 
732  function _checkAllConditionsOfTarget($a_target_ref_id,$a_target_id, $a_target_type = "",$a_usr_id = 0)
733  {
734  global $ilBench,$ilUser,$tree;
735 
736  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
737 
738  foreach(ilConditionHandler::_getConditionsOfTarget($a_target_ref_id,$a_target_id, $a_target_type) as $condition)
739  {
740  if($tree->isDeleted($condition['trigger_ref_id']))
741  {
742  continue;
743  }
744 
745  $ilBench->start("ilConditionHandler", "checkCondition");
746  $check = ilConditionHandler::_checkCondition($condition['id'],$a_usr_id);
747  $ilBench->stop("ilConditionHandler", "checkCondition");
748 
749  include_once './Services/Container/classes/class.ilMemberViewSettings.php';
750  if(!$check and !ilMemberViewSettings::getInstance()->isActive())
751  {
752  return false;
753  }
754  }
755  return true;
756  }
757 
758  // PRIVATE
759  function validate()
760  {
761  global $ilDB;
762 
763  // check if obj_id is already assigned
764  $trigger_obj =& ilObjectFactory::getInstanceByRefId($this->getTriggerRefId());
765  $target_obj =& ilObjectFactory::getInstanceByRefId($this->getTargetRefId());
766 
767 
768  $query = "SELECT * FROM conditions WHERE ".
769  "trigger_ref_id = ".$ilDB->quote($trigger_obj->getId(),'integer')." ".
770  "AND target_ref_id = ".$ilDB->quote($target_obj->getId(),'integer');
771 
772  $res = $this->db->query($query);
773  if($res->numRows() > 1)
774  {
775  $this->setErrorMessage($this->lng->txt('condition_already_assigned'));
776 
777  unset($trigger_obj);
778  unset($target_obj);
779  return false;
780  }
781 
782  // check for circle
783  $this->target_obj_id = $target_obj->getId();
784  if($this->checkCircle($this->getTargetRefId(),$target_obj->getId()))
785  {
786  $this->setErrorMessage($this->lng->txt('condition_circle_created'));
787 
788  unset($trigger_obj);
789  unset($target_obj);
790  return false;
791  }
792  return true;
793  }
794 
795  function checkCircle($a_ref_id,$a_obj_id)
796  {
797  foreach(ilConditionHandler::_getConditionsOfTarget($a_ref_id,$a_obj_id) as $condition)
798  {
799  if($condition['trigger_obj_id'] == $this->target_obj_id and $condition['operator'] == $this->getOperator())
800  {
801  $this->circle = true;
802  break;
803  }
804  else
805  {
806  $this->checkCircle($condition['trigger_ref_id'],$condition['trigger_obj_id']);
807  }
808  }
809  return $this->circle;
810  }
811 }
812 
813 ?>