ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules 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 
80 {
81  const OPERATOR_PASSED = 'passed';
82  const OPERATOR_FINISHED = 'finished';
83  const OPERATOR_NOT_FINISHED = 'not_finished';
84  const OPERATOR_NOT_MEMBER = 'not_member';
85  const OPERATOR_FAILED = 'failed';
86  const OPERATOR_LP = 'learning_progress';
87  const OPERATOR_ACCREDITED_OR_PASSED = 'accredited_or_passed';
88 
89  const UNIQUE_CONDITIONS = 1;
90  const SHARED_CONDITIONS = 0; // conditions are used for all tree references of the target object
91  // this is currently only used for lm chapters and likely to be abandonded in the future
92 
93  public $db;
94  public $lng;
95 
96 
98 
101  public $target_type;
105  public $operator;
106  public $value;
107  public $validation;
108 
109 
110  private $obligatory = true;
111  private $hidden_status = false;
112 
113  public $conditions;
114  public static $cond_for_target_cache = array();
115  public static $cond_target_rows = array();
116 
117 
122  public function __construct()
123  {
124  global $DIC;
125 
126  $ilDB = $DIC['ilDB'];
127  $lng = $DIC['lng'];
128 
129  $this->db = &$ilDB;
130  $this->lng = &$lng;
131  $this->validation = true;
132  }
133 
134  public static function resetCache() : void
135  {
136  self::$cond_for_target_cache = [];
137  self::$cond_target_rows = [];
138  }
139 
148  public static function _isReferenceHandlingOptional($a_type)
149  {
150  switch ($a_type) {
151  case 'st':
152  return true;
153 
154  default:
155  return false;
156  }
157  }
158 
164  public static function lookupEffectiveHiddenStatusByTarget($a_target_ref_id)
165  {
166  global $DIC;
167 
168  $obj_definition = $DIC["objDefinition"];
169  $tree = $DIC->repositoryTree();
170 
171  // check if parent takes over control of condition
172  $parent_ref_id = $tree->getParentId($a_target_ref_id);
173  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
174  $parent_type = ilObject::_lookupType($parent_obj_id);
175 
176  $class = $obj_definition->getClassName($parent_type);
177  $class_name = "il" . $class . "ConditionController";
178  $location = $obj_definition->getLocation($parent_type);
179 
180  // if yes, get from parent
181  if ($class != "" && is_file($location . "/class." . $class_name . ".php")) {
183  $controller = new $class_name();
184  if ($controller->isContainerConditionController($parent_ref_id)) {
185  $set = $controller->getConditionSetForRepositoryObject($a_target_ref_id);
186  return $set->getHiddenStatus();
187  }
188  }
189 
190  return self::lookupPersistedHiddenStatusByTarget($a_target_ref_id);
191  }
192 
198  public static function lookupPersistedHiddenStatusByTarget($a_target_ref_id)
199  {
200  global $DIC;
201 
202  $ilDB = $DIC['ilDB'];
203 
204  $query = 'SELECT hidden_status FROM conditions ' .
205  'WHERE target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer');
206  $res = $ilDB->query($query);
207  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
208  return $row->hidden_status;
209  }
210  return false;
211  }
212 
223  public static function _adjustMovedObjectConditions($a_ref_id)
224  {
225  global $DIC;
226 
227  return true;
228 
229  $tree = $DIC['tree'];
230 
231  if ($tree->checkForParentType($a_ref_id, 'crs')) {
232  // Nothing to do
233  return true;
234  }
235 
236  // Need another implementation that has better performance
237  $childs = $tree->getSubTree($tree->getNodeData($a_ref_id), false);
238  $conditions = self::_getDistinctTargetRefIds();
239 
240  foreach (array_intersect($conditions, $childs) as $target_ref) {
241  if (!$tree->checkForParentType($target_ref, 'crs')) {
242  self::_deleteTargetConditionsByRefId($target_ref);
243  }
244  }
245  return true;
246  }
247 
255  protected static function _getDistinctTargetRefIds()
256  {
257  global $DIC;
258 
259  $ilDB = $DIC['ilDB'];
260 
261  $query = "SELECT DISTINCT target_ref_id ref FROM conditions ";
262  $res = $ilDB->query($query);
263  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
264  $ref_ids[] = $row->ref;
265  }
266  return $ref_ids ? $ref_ids : array();
267  }
268 
279  protected static function _deleteTargetConditionsByRefId($a_target_ref_id)
280  {
281  global $DIC;
282 
283  $ilDB = $DIC['ilDB'];
284 
285  $query = "DELETE FROM conditions " .
286  "WHERE target_ref_id = " . $ilDB->quote($a_target_ref_id, 'integer') . " " .
287  "AND target_type != 'st' ";
288  $res = $ilDB->manipulate($query);
289  return true;
290  }
291 
299  public function setReferenceHandlingType($a_type)
300  {
301  return $this->condition_reference_type = $a_type;
302  }
303 
310  public function getReferenceHandlingType()
311  {
312  return (int) $this->condition_reference_type;
313  }
314 
315  // SET GET
316  public function setErrorMessage($a_msg)
317  {
318  $this->error_message = $a_msg;
319  }
320  public function getErrorMessage()
321  {
322  return $this->error_message;
323  }
324 
328  public function setTargetRefId($a_target_ref_id)
329  {
330  return $this->target_ref_id = $a_target_ref_id;
331  }
332 
336  public function getTargetRefId()
337  {
338  return $this->target_ref_id;
339  }
340 
344  public function setTargetObjId($a_target_obj_id)
345  {
346  return $this->target_obj_id = $a_target_obj_id;
347  }
348 
352  public function getTargetObjId()
353  {
354  return $this->target_obj_id;
355  }
356 
360  public function setTargetType($a_target_type)
361  {
362  return $this->target_type = $a_target_type;
363  }
364 
368  public function getTargetType()
369  {
370  return $this->target_type;
371  }
372 
376  public function setTriggerRefId($a_trigger_ref_id)
377  {
378  return $this->trigger_ref_id = $a_trigger_ref_id;
379  }
380 
384  public function getTriggerRefId()
385  {
386  return $this->trigger_ref_id;
387  }
388 
392  public function setTriggerObjId($a_trigger_obj_id)
393  {
394  return $this->trigger_obj_id = $a_trigger_obj_id;
395  }
396 
400  public function getTriggerObjId()
401  {
402  return $this->trigger_obj_id;
403  }
404 
408  public function setTriggerType($a_trigger_type)
409  {
410  return $this->trigger_type = $a_trigger_type;
411  }
412 
416  public function getTriggerType()
417  {
418  return $this->trigger_type;
419  }
420 
424  public function setOperator($a_operator)
425  {
426  return $this->operator = $a_operator;
427  }
428 
432  public function getOperator()
433  {
434  return $this->operator;
435  }
436 
440  public function setValue($a_value)
441  {
442  return $this->value = $a_value;
443  }
444 
448  public function getValue()
449  {
450  return $this->value;
451  }
452 
457  public function setObligatory($a_obl)
458  {
459  $this->obligatory = $a_obl;
460  }
461 
466  public function getObligatory()
467  {
468  return (bool) $this->obligatory;
469  }
470 
471  public function setHiddenStatus($a_status)
472  {
473  $this->hidden_status = $a_status;
474  }
475 
476  public function getHiddenStatus()
477  {
478  return $this->hidden_status;
479  }
480 
481 
485  public function enableAutomaticValidation($a_validate = true)
486  {
487  $this->validation = $a_validate;
488  }
489 
495  public function getTriggerTypes()
496  {
497  global $DIC;
498 
500  $objDefinition = $DIC['objDefinition'];
501 
502  $trigger_types = array('crs','exc','tst','sahs', 'svy', 'lm', 'iass', 'prg', 'copa', 'lti', 'cmix');
503 
504  // Add operator lp trigger
506  // only if object type has lp
507  foreach ($objDefinition->getAllRepositoryTypes() as $t) {
509  if (!in_array($t, $trigger_types)) {
510  $trigger_types[] = $t;
511  }
512  }
513  }
514  }
515 
516  foreach ($objDefinition->getPlugins() as $p_type => $p_info) {
517  if (@include_once $p_info['location'] . '/class.ilObj' . $p_info['class_name'] . 'Access.php') {
518  include_once './Services/Conditions/interfaces/interface.ilConditionHandling.php';
519  $name = 'ilObj' . $p_info['class_name'] . 'Access';
520  $reflection = new ReflectionClass($name);
521  if ($reflection->implementsInterface('ilConditionHandling')) {
522  $trigger_types[] = $p_type;
523  }
524  }
525  }
526 
527 
528  $active_triggers = array();
529  foreach ($trigger_types as $type) {
530  if (count($this->getOperatorsByTriggerType($type))) {
531  $active_triggers[] = $type;
532  }
533  }
534 
535 
536 
537 
538  return $active_triggers;
539  }
540 
541 
547  public function getOperatorsByTriggerType($a_type)
548  {
549  global $DIC;
550 
551  $objDefinition = $DIC['objDefinition'];
552 
553  switch ($a_type) {
554  case 'crsg':
555  return array('not_member');
556  }
557 
558  $class = $objDefinition->getClassName($a_type);
559  $location = $objDefinition->getLocation($a_type);
560  $full_class = "ilObj" . $class . "Access";
561  include_once($location . "/class." . $full_class . ".php");
562 
563  include_once './Services/Conditions/interfaces/interface.ilConditionHandling.php';
564 
565  $reflection = new ReflectionClass($full_class);
566  if ($reflection->implementsInterface('ilConditionHandling')) {
567  $operators = call_user_func(
568  array($full_class, 'getConditionOperators'),
569  $a_type
570  );
571  } else {
572  $operators = [];
573  }
574 
575  // Add operator lp
576  include_once("Services/Tracking/classes/class.ilObjUserTracking.php");
578  // only if object type has lp
579  include_once("Services/Object/classes/class.ilObjectLP.php");
580  if (ilObjectLP::isSupportedObjectType($a_type)) {
581  array_unshift($operators, self::OPERATOR_LP);
582  }
583  }
584  return $operators;
585  }
586 
590  public function storeCondition()
591  {
592  global $DIC;
593 
594  $ilDB = $DIC['ilDB'];
595 
596  // first insert, then validate: it's easier to check for circles if the new condition is in the db table
597  $next_id = $ilDB->nextId('conditions');
598  $query = 'INSERT INTO conditions (condition_id,target_ref_id,target_obj_id,target_type,' .
599  'trigger_ref_id,trigger_obj_id,trigger_type,operator,value,ref_handling,obligatory,hidden_status) ' .
600  'VALUES (' .
601  $ilDB->quote($next_id, 'integer') . ',' .
602  $ilDB->quote($this->getTargetRefId(), 'integer') . "," .
603  $ilDB->quote($this->getTargetObjId(), 'integer') . "," .
604  $ilDB->quote($this->getTargetType(), 'text') . "," .
605  $ilDB->quote($this->getTriggerRefId(), 'integer') . "," .
606  $ilDB->quote($this->getTriggerObjId(), 'integer') . "," .
607  $ilDB->quote($this->getTriggerType(), 'text') . "," .
608  $ilDB->quote($this->getOperator(), 'text') . "," .
609  $ilDB->quote($this->getValue(), 'text') . ", " .
610  $ilDB->quote($this->getReferenceHandlingType(), 'integer') . ', ' .
611  $ilDB->quote($this->getObligatory(), 'integer') . ', ' .
612  $ilDB->quote($this->getHiddenStatus(), 'integer') . ' ' .
613  ')';
614 
615  $res = $ilDB->manipulate($query);
616 
617  if ($this->validation && !$this->validate()) {
618  $this->deleteCondition($next_id);
619  return false;
620  }
621  return true;
622  }
623 
624  public function checkExists()
625  {
626  global $DIC;
627 
628  $ilDB = $DIC['ilDB'];
629 
630  $query = "SELECT * FROM conditions " .
631  "WHERE target_ref_id = " . $ilDB->quote($this->getTargetRefId(), 'integer') . " " .
632  "AND target_obj_id = " . $ilDB->quote($this->getTargetObjId(), 'integer') . " " .
633  "AND trigger_ref_id = " . $ilDB->quote($this->getTriggerRefId(), 'integer') . " " .
634  "AND trigger_obj_id = " . $ilDB->quote($this->getTriggerObjId(), 'integer') . " " .
635  "AND operator = " . $ilDB->quote($this->getOperator(), 'text');
636  $res = $ilDB->query($query);
637 
638  return $res->numRows() ? true : false;
639  }
643  public function updateCondition($a_id)
644  {
645  global $DIC;
646 
647  $ilDB = $DIC['ilDB'];
648 
649  $query = "UPDATE conditions SET " .
650  "target_ref_id = " . $ilDB->quote($this->getTargetRefId(), 'integer') . ", " .
651  "operator = " . $ilDB->quote($this->getOperator(), 'text') . ", " .
652  "value = " . $ilDB->quote($this->getValue(), 'text') . ", " .
653  "ref_handling = " . $this->db->quote($this->getReferenceHandlingType(), 'integer') . ", " .
654  'obligatory = ' . $this->db->quote($this->getObligatory(), 'integer') . ' ' .
655  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
656  $res = $ilDB->manipulate($query);
657 
658  return true;
659  }
660 
668  public function updateHiddenStatus($a_status)
669  {
670  global $DIC;
671 
672  $ilDB = $DIC['ilDB'];
673 
674  $query = 'UPDATE conditions SET ' .
675  'hidden_status = ' . $ilDB->quote($a_status, 'integer') . ' ' .
676  'WHERE target_ref_id = ' . $ilDB->quote($this->getTargetRefId(), 'integer');
677  $ilDB->manipulate($query);
678  return true;
679  }
680 
687  public static function updateObligatory($a_id, $a_status)
688  {
689  global $DIC;
690 
691  $ilDB = $DIC['ilDB'];
692 
693  $query = "UPDATE conditions SET " .
694  'obligatory = ' . $ilDB->quote($a_status, 'integer') . ' ' .
695  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
696  $res = $ilDB->manipulate($query);
697 
698  return true;
699  }
700 
705  public function delete($a_ref_id)
706  {
707  global $DIC;
708 
709  $ilDB = $DIC['ilDB'];
710 
711  $query = "DELETE FROM conditions WHERE " .
712  "target_ref_id = " . $ilDB->quote($a_ref_id, 'integer') . " " .
713  "OR trigger_ref_id = " . $ilDB->quote($a_ref_id, 'integer');
714  $res = $ilDB->manipulate($query);
715 
716  return true;
717  }
722  public function deleteByObjId($a_obj_id)
723  {
724  global $DIC;
725 
726  $ilDB = $DIC['ilDB'];
727 
728  $query = "DELETE FROM conditions WHERE " .
729  "target_obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " " .
730  "OR trigger_obj_id = " . $ilDB->quote($a_obj_id, 'integer');
731  $res = $ilDB->manipulate($query);
732 
733  return true;
734  }
735 
739  public function deleteCondition($a_id)
740  {
741  global $DIC;
742 
743  $ilDB = $DIC['ilDB'];
744 
745  $query = "DELETE FROM conditions " .
746  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
747  $res = $ilDB->manipulate($query);
748 
749  return true;
750  }
751 
760  public static function getNumberOfConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
761  {
762  global $DIC;
763  $db = $DIC->database();
764 
765  $query = 'select count(*) num from conditions ' .
766  'where trigger_obj_id = ' . $db->quote($a_trigger_id, ilDBConstants::T_INTEGER) . ' ' .
767  'and trigger_type = ' . $db->quote($a_trigger_obj_type, ilDBConstants::T_TEXT);
768  $res = $db->query($query);
769  $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
770  return (int) $row->num;
771  }
772 
777  public static function _getPersistedConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
778  {
779  global $DIC;
780 
781  $ilDB = $DIC['ilDB'];
782 
783  $query = "SELECT * FROM conditions " .
784  "WHERE trigger_obj_id = " . $ilDB->quote($a_trigger_id, 'integer') . " " .
785  " AND trigger_type = " . $ilDB->quote($a_trigger_obj_type, 'text');
786 
787  $res = $ilDB->query($query);
788  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
789  $tmp_array['id'] = $row->condition_id;
790  $tmp_array['target_ref_id'] = $row->target_ref_id;
791  $tmp_array['target_obj_id'] = $row->target_obj_id;
792  $tmp_array['target_type'] = $row->target_type;
793  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
794  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
795  $tmp_array['trigger_type'] = $row->trigger_type;
796  $tmp_array['operator'] = $row->operator;
797  $tmp_array['value'] = $row->value;
798  $tmp_array['ref_handling'] = $row->ref_handling;
799  $tmp_array['obligatory'] = $row->obligatory;
800  $tmp_array['hidden_status'] = $row->hidden_status;
801 
802  $conditions[] = $tmp_array;
803  unset($tmp_array);
804  }
805 
806  return $conditions ? $conditions : array();
807  }
808 
816  public static function _getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type = "")
817  {
818  global $DIC;
819 
820  $obj_definition = $DIC["objDefinition"];
821  $tree = $DIC->repositoryTree();
822 
823  // get type if no type given
824  if ($a_target_type == "") {
825  $a_target_type = ilObject::_lookupType($a_target_obj_id);
826  }
827 
828  // check if parent takes over control of condition
829  $parent_ref_id = $tree->getParentId($a_target_ref_id);
830  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
831  $parent_type = ilObject::_lookupType($parent_obj_id);
832 
833  $class = $obj_definition->getClassName($parent_type);
834  $class_name = "il" . $class . "ConditionController";
835  $location = $obj_definition->getLocation($parent_type);
836 
837  // if yes, get from parent
838  if ($class != "" && is_file($location . "/class." . $class_name . ".php")
839  && $a_target_type == ilObject::_lookupType($a_target_ref_id, true)) {
841  $controller = new $class_name();
842  if ($controller->isContainerConditionController($parent_ref_id)) {
844  $set = $controller->getConditionSetForRepositoryObject($a_target_ref_id);
845 
846  // convert to old structure
847  $cond = array();
848  foreach ($set->getConditions() as $c) {
849  $obligatory = $set->getAllObligatory()
850  ? true
851  : $c->getObligatory();
852  $trigger = $c->getTrigger();
853  $cond[] = array(
854  "target_ref_id" => $a_target_ref_id,
855  "target_obj_id" => $a_target_obj_id,
856  "target_type" => $a_target_type,
857  "trigger_ref_id" => $trigger->getRefId(),
858  "trigger_obj_id" => $trigger->getObjId(),
859  "trigger_type" => $trigger->getType(),
860  "operator" => $c->getOperator(),
861  "value" => $c->getValue(),
862  "ref_handling" => 1,
863  "obligatory" => (int) $obligatory,
864  "num_obligatory" => $set->getNumObligatory(),
865  "hidden_status" => (int) $set->getHiddenStatus()
866  );
867  }
868  return $cond;
869  }
870  }
871 
872  return self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type);
873  }
874 
882  public static function _getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type = "")
883  {
884  global $DIC;
885 
886  $ilDB = $DIC['ilDB'];
887 
888  // get type if no type given
889  if ($a_target_type == "") {
890  $a_target_type = ilObject::_lookupType($a_target_obj_id);
891  }
892 
893  // check conditions for target cache
894  if (isset(self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
895  $a_target_type])) {
896  return self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
897  $a_target_type];
898  }
899 
900  // check rows cache
901  if (isset(self::$cond_target_rows[$a_target_type . ":" . $a_target_obj_id])) {
902  $rows = self::$cond_target_rows[$a_target_type . ":" . $a_target_obj_id];
903  } else {
904  // query data from db
905  $query = "SELECT * FROM conditions " .
906  "WHERE target_obj_id = " . $ilDB->quote($a_target_obj_id, 'integer') . " " .
907  " AND target_type = " . $ilDB->quote($a_target_type, 'text');
908 
909  $res = $ilDB->query($query);
910  $rows = array();
911  while ($row = $ilDB->fetchAssoc($res)) {
912  $rows[] = $row;
913  }
914  }
915 
916  reset($rows);
917  $conditions = array();
918  foreach ($rows as $row) {
919  if ($row["ref_handling"] == self::UNIQUE_CONDITIONS) {
920  if ($row["target_ref_id"] != $a_target_ref_id) {
921  continue;
922  }
923  }
924 
925  $row["id"] = $row["condition_id"];
926  $conditions[] = $row;
927  }
928 
929  // write conditions for target cache
930  self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
931  $a_target_type] = $conditions;
932 
933  return $conditions;
934  }
935 
942  public static function preloadPersistedConditionsForTargetRecords($a_type, $a_obj_ids)
943  {
944  global $DIC;
945 
946  $ilDB = $DIC['ilDB'];
947 
948  if (is_array($a_obj_ids) && count($a_obj_ids) > 0) {
949  $res = $ilDB->query("SELECT * FROM conditions " .
950  "WHERE " . $ilDB->in("target_obj_id", $a_obj_ids, false, "integer") .
951  " AND target_type = " . $ilDB->quote($a_type, 'text'));
952  $rows = array();
953  while ($row = $ilDB->fetchAssoc($res)) {
954  self::$cond_target_rows[$a_type . ":" . $row["target_obj_id"]][]
955  = $row;
956  }
957  // init obj ids without any record
958  foreach ($a_obj_ids as $obj_id) {
959  if (!is_array(self::$cond_target_rows[$a_type . ":" . $obj_id])) {
960  self::$cond_target_rows[$a_type . ":" . $obj_id] = array();
961  }
962  }
963  }
964  }
965 
966  public static function _getCondition($a_id)
967  {
968  global $DIC;
969 
970  $ilDB = $DIC['ilDB'];
971 
972  $query = "SELECT * FROM conditions " .
973  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
974 
975  $res = $ilDB->query($query);
976  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
977  $tmp_array['id'] = $row->condition_id;
978  $tmp_array['target_ref_id'] = $row->target_ref_id;
979  $tmp_array['target_obj_id'] = $row->target_obj_id;
980  $tmp_array['target_type'] = $row->target_type;
981  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
982  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
983  $tmp_array['trigger_type'] = $row->trigger_type;
984  $tmp_array['operator'] = $row->operator;
985  $tmp_array['value'] = $row->value;
986  $tmp_array['ref_handling'] = $row->ref_handling;
987  $tmp_array['obligatory'] = $row->obligatory;
988  $tmp_array['hidden_status'] = $row->hidden_status;
989 
990  return $tmp_array;
991  }
992  return false;
993  }
994 
995 
996 
1002  public static function _checkCondition($condition, $a_usr_id = 0)
1003  {
1004  global $DIC;
1005 
1006  $ilUser = $DIC['ilUser'];
1007  $objDefinition = $DIC['objDefinition'];
1008 
1009  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
1010 
1011  //$condition = ilConditionHandler::_getCondition($a_id);
1012 
1013  // check lp
1014  if ($condition['operator'] == self::OPERATOR_LP) {
1015  include_once './Services/Tracking/classes/class.ilLPStatus.php';
1016  return ilLPStatus::_hasUserCompleted($condition['trigger_obj_id'], $a_usr_id);
1017  }
1018 
1019  switch ($condition['trigger_type']) {
1020  case 'crsg':
1021  include_once './Modules/Course/classes/class.ilObjCourseGrouping.php';
1022  return ilObjCourseGrouping::_checkCondition($condition['trigger_obj_id'], $condition['operator'], $condition['value'], $a_usr_id);
1023  }
1024 
1025  $class = $objDefinition->getClassName($condition['trigger_type']);
1026  $location = $objDefinition->getLocation($condition['trigger_type']);
1027  $full_class = "ilObj" . $class . "Access";
1028  include_once($location . "/class." . $full_class . ".php");
1029 
1030  $fullfilled = call_user_func(
1031  array($full_class, 'checkCondition'),
1032  $condition['trigger_obj_id'],
1033  $condition['operator'],
1034  $condition['value'],
1035  $a_usr_id
1036  );
1037  return $fullfilled;
1038  }
1039 
1047  public static function getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type = '')
1048  {
1049  $conditions = self::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id);
1050 
1051  $opt = array();
1052  foreach ($conditions as $con) {
1053  if ($con['obligatory']) {
1054  continue;
1055  }
1056 
1057  $opt[] = $con;
1058  }
1059  return $opt;
1060  }
1061 
1069  public static function getPersistedOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type = '')
1070  {
1071  $conditions = self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id);
1072 
1073  $opt = array();
1074  foreach ($conditions as $con) {
1075  if ($con['obligatory']) {
1076  continue;
1077  }
1078 
1079  $opt[] = $con;
1080  }
1081  return $opt;
1082  }
1083 
1084 
1090  public static function lookupObligatoryConditionsOfTarget($a_target_ref_id, $a_target_obj_id)
1091  {
1092  global $DIC;
1093 
1094  $ilDB = $DIC['ilDB'];
1095 
1096  $query = 'SELECT max(num_obligatory) obl from conditions WHERE ' .
1097  'target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer') . ' ' .
1098  'AND target_obj_id = ' . $ilDB->quote($a_target_obj_id, 'integer') . ' ' .
1099  'GROUP BY (num_obligatory)';
1100  $res = $ilDB->query($query);
1101 
1102  $obl = 0;
1103  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1104  $obl = $row->obl;
1105  }
1106  return $obl;
1107  }
1108 
1115  public static function calculateEffectiveRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type = '')
1116  {
1117  global $DIC;
1118 
1119  $ilDB = $DIC['ilDB'];
1120 
1121  // Get all conditions
1122  $all = self::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1123  $opt = self::getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1124 
1125  $set_obl = 0;
1126  if (isset($all[0])) {
1127  $set_obl = $all[0]['num_obligatory'];
1128  }
1129 
1130  // existing value is valid
1131  if ($set_obl > 0 and
1132  $set_obl < count($all) and
1133  $set_obl > (count($all) - count($opt) + 1)) {
1134  return $set_obl;
1135  }
1136 
1137  if (count($opt)) {
1138  $result = count($all) - count($opt) + 1;
1139  } else {
1140  $result = count($all);
1141  }
1142  return $result;
1143  }
1144 
1151  public static function calculatePersistedRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type = '', $a_force_update = false)
1152  {
1153  global $DIC;
1154 
1155  $ilDB = $DIC['ilDB'];
1156 
1157  // Get all conditions
1158 
1159  self::resetCache();
1160  $all = self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1161  $opt = self::getPersistedOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1162 
1163  $set_obl = 0;
1164  if (isset($all[0])) {
1165  $set_obl = $all[0]['num_obligatory'];
1166  }
1167 
1168  // existing value is valid
1169  if ($set_obl > 0 and
1170  $set_obl < count($all) and
1171  $set_obl > (count($all) - count($opt) + 1)) {
1172  return $set_obl;
1173  }
1174 
1175  if (count($opt)) {
1176  $result = count($all) - count($opt) + 1;
1177  } else {
1178  $result = count($all);
1179  }
1180  if ($a_force_update) {
1181  self::saveNumberOfRequiredTriggers($a_target_ref_id, $a_target_obj_id, $result);
1182  }
1183  return $result;
1184  }
1185 
1191  public static function saveNumberOfRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_num)
1192  {
1193  global $DIC;
1194 
1195  $ilDB = $DIC['ilDB'];
1196 
1197  $query = 'UPDATE conditions ' .
1198  'SET num_obligatory = ' . $ilDB->quote($a_num, 'integer') . ' ' .
1199  'WHERE target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer') . ' ' .
1200  'AND target_obj_id = ' . $ilDB->quote($a_target_obj_id, 'integer');
1201  $ilDB->manipulate($query);
1202  return;
1203  }
1204 
1208  public static function _checkAllConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type = "", $a_usr_id = 0)
1209  {
1210  global $DIC;
1211 
1212  $ilUser = $DIC['ilUser'];
1213  $tree = $DIC['tree'];
1214  $logger = $DIC->logger()->ac();
1215 
1216  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
1217 
1218  $conditions = ilConditionHandler::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type);
1219 
1220  if (!count($conditions)) {
1221  return true;
1222  }
1223 
1224  // @todo check this
1225  include_once './Services/Container/classes/class.ilMemberViewSettings.php';
1226  if (ilMemberViewSettings::getInstance()->isActive()) {
1227  return true;
1228  }
1229 
1230  // First check obligatory conditions
1231  $optional = self::getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type);
1232  $num_required = self::calculateEffectiveRequiredTriggers($a_target_ref_id, $a_target_id, $a_target_type);
1233  $passed = 0;
1234  foreach ($conditions as $condition) {
1235  if ($tree->isDeleted($condition['trigger_ref_id'])) {
1236  continue;
1237  }
1238  $check = ilConditionHandler::_checkCondition($condition, $a_usr_id);
1239 
1240  if ($check) {
1241  ++$passed;
1242  } else {
1243  // #0027223 if condition is obligatory => return false
1244  if ($condition['obligatory']) {
1245  return false;
1246  }
1247  }
1248  }
1249  if ($passed >= $num_required) {
1250  return true;
1251  }
1252 
1253  // not all optional conditions passed
1254  return false;
1255  }
1256 
1257  // PRIVATE
1258  protected function validate()
1259  {
1260  global $DIC;
1261 
1262  $ilDB = $DIC['ilDB'];
1263 
1264  // check if obj_id is already assigned
1265  $trigger_obj = &ilObjectFactory::getInstanceByRefId($this->getTriggerRefId());
1266  $target_obj = &ilObjectFactory::getInstanceByRefId($this->getTargetRefId());
1267 
1268 
1269  $query = "SELECT * FROM conditions WHERE " .
1270  "trigger_ref_id = " . $ilDB->quote($trigger_obj->getRefId(), 'integer') . " " .
1271  "AND target_ref_id = " . $ilDB->quote($target_obj->getRefId(), 'integer');
1272 
1273  $res = $this->db->query($query);
1274  if ($res->numRows() > 1) {
1275  $this->setErrorMessage($this->lng->txt('condition_already_assigned'));
1276 
1277  unset($trigger_obj);
1278  unset($target_obj);
1279  return false;
1280  }
1281 
1282  // check for circle
1283  $this->target_obj_id = $target_obj->getId();
1284  if ($this->checkCircle($this->getTargetRefId(), $target_obj->getId())) {
1285  $this->setErrorMessage($this->lng->txt('condition_circle_created'));
1286 
1287  unset($trigger_obj);
1288  unset($target_obj);
1289  return false;
1290  }
1291  return true;
1292  }
1293 
1294  protected function checkCircle($a_ref_id, $a_obj_id)
1295  {
1296  foreach (ilConditionHandler::_getPersistedConditionsOfTarget($a_ref_id, $a_obj_id) as $condition) {
1297  if ($condition['trigger_obj_id'] == $this->target_obj_id and $condition['operator'] == $this->getOperator()) {
1298  $this->circle = true;
1299  break;
1300  } else {
1301  $this->checkCircle($condition['trigger_ref_id'], $condition['trigger_obj_id']);
1302  }
1303  }
1304  return $this->circle;
1305  }
1306 
1307  public static function cloneDependencies($a_src_ref_id, $a_target_ref_id, $a_copy_id)
1308  {
1309  include_once './Services/CopyWizard/classes/class.ilCopyWizardOptions.php';
1310  $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
1311  $mappings = $cwo->getMappings();
1312 
1313  $valid = 0;
1315  foreach ($conditions as $con) {
1316  if ($mappings[$con['trigger_ref_id']]) {
1317  $newCondition = new ilConditionHandler();
1318 
1319  $target_obj = ilObject::_lookupObjId($a_target_ref_id);
1320  $target_typ = ilObject::_lookupType($target_obj);
1321 
1322  $newCondition->setTargetRefId($a_target_ref_id);
1323  $newCondition->setTargetObjId($target_obj);
1324  $newCondition->setTargetType($target_typ);
1325 
1326  $trigger_ref = $mappings[$con['trigger_ref_id']];
1327  $trigger_obj = ilObject::_lookupObjId($trigger_ref);
1328  $trigger_typ = ilObject::_lookupType($trigger_obj);
1329 
1330  $newCondition->setTriggerRefId($trigger_ref);
1331  $newCondition->setTriggerObjId($trigger_obj);
1332  $newCondition->setTriggerType($trigger_typ);
1333  $newCondition->setOperator($con['operator']);
1334  $newCondition->setValue($con['value']);
1335  $newCondition->setReferenceHandlingType($con['ref_handling']);
1336  $newCondition->setObligatory($con['obligatory']);
1337 
1338  // :TODO: not sure about this
1339  $newCondition->setHiddenStatus(self::lookupPersistedHiddenStatusByTarget($a_src_ref_id));
1340 
1341  if ($newCondition->storeCondition()) {
1342  $valid++;
1343 
1344  //Copy num_obligatory, to be checked below
1345  self::saveNumberOfRequiredTriggers(
1346  $a_target_ref_id,
1347  $target_obj,
1348  $con['num_obligatory']
1349  );
1350  }
1351  }
1352  }
1353  if ($valid) {
1354  $tgt_obj_id = ilObject::_lookupObjId($a_target_ref_id);
1355 
1356  // num_obligatory
1357  self::calculatePersistedRequiredTriggers($a_target_ref_id, $tgt_obj_id, ilObject::_lookupType($tgt_obj_id), true);
1358  }
1359  }
1360 }
storeCondition()
store new condition in database
static saveNumberOfRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_num)
Save number of obigatory triggers.
static _getPersistedConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
Get all persisted conditions of trigger object Note: This only gets persisted conditions NOT (dynamic...
$c
Definition: cli.php:37
deleteByObjId($a_obj_id)
delete all trigger and target entries This method is called from ilObject::delete() if an object is r...
$result
$type
setValue($a_value)
set value
$location
Definition: buildRTE.php:44
setTargetType($a_target_type)
set target object type
$valid
static _checkCondition($condition, $a_usr_id=0)
checks wether a single condition is fulfilled every trigger object type must implement a static metho...
setTargetRefId($a_target_ref_id)
set target ref id
getTriggerRefId()
get target ref id
static calculatePersistedRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type='', $a_force_update=false)
calculate number of obligatory items
getObligatory()
Get obligatory status.
static lookupPersistedHiddenStatusByTarget($a_target_ref_id)
Lookup persistedhidden status.
getReferenceHandlingType()
get reference handling type
static lookupObligatoryConditionsOfTarget($a_target_ref_id, $a_target_obj_id)
Lookup obligatory conditions of target.
setTriggerObjId($a_trigger_obj_id)
set trigger object id
getTargetRefId()
get target ref id
__construct()
constructor public
static calculateEffectiveRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type='')
calculate number of obligatory items
static _checkCondition($trigger_obj_id, $operator, $value, $a_usr_id=0)
getTargetObjId()
get target obj id
if($format !==null) $name
Definition: metadata.php:230
static _enabledLearningProgress()
check wether learing progress is enabled or not
static _getInstance($a_copy_id)
Get instance of copy wizard options.
foreach($_POST as $key=> $value) $res
static getPersistedOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type='')
Get optional conditions.
static _hasUserCompleted($a_obj_id, $a_user_id)
Lookup user object completion.
static _lookupObjId($a_id)
global $DIC
Definition: goto.php:24
static _getDistinctTargetRefIds()
Get all target ref ids.
static _checkAllConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type="", $a_usr_id=0)
checks wether all conditions of a target object are fulfilled
getTriggerObjId()
get trigger obj id
static _deleteTargetConditionsByRefId($a_target_ref_id)
Delete conditions by target ref id Note: only conditions on the target type are deleted Conditions on...
$query
static _lookupType($a_id, $a_reference=false)
lookup object type
checkCircle($a_ref_id, $a_obj_id)
setTriggerType($a_trigger_type)
set trigger object type
getOperatorsByTriggerType($a_type)
Get operators by trigger type.
INTERNAL CLASS: Please do not use in consumer code.
$rows
Definition: xhr_table.php:10
setTriggerRefId($a_trigger_ref_id)
set trigger ref id
getTriggerType()
get trigger obj type
static preloadPersistedConditionsForTargetRecords($a_type, $a_obj_ids)
Preload conditions for target records.
static getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type='')
Get optional conditions.
setTargetObjId($a_target_obj_id)
set target object id
static isSupportedObjectType($type)
static _isReferenceHandlingOptional($a_type)
is reference handling optional
setOperator($a_operator)
set operator
static updateObligatory($a_id, $a_status)
Toggle condition obligatory status.
static _adjustMovedObjectConditions($a_ref_id)
In the moment it is not allowed to create preconditions on objects that are located outside of a cour...
updateHiddenStatus($a_status)
Update hidden status type $ilDB.
setReferenceHandlingType($a_type)
set reference handling type
setObligatory($a_obl)
Set obligatory status.
global $ilDB
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static _getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type="")
get all persisted conditions of target object
static cloneDependencies($a_src_ref_id, $a_target_ref_id, $a_copy_id)
deleteCondition($a_id)
delete condition
$ilUser
Definition: imgupload.php:18
updateCondition($a_id)
update condition
static getNumberOfConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
get all conditions of trigger object
getTargetType()
get target obj type
enableAutomaticValidation($a_validate=true)
enable automated validation