ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
142  public static function _isReferenceHandlingOptional($a_type)
143  {
144  switch ($a_type) {
145  case 'st':
146  return true;
147 
148  default:
149  return false;
150  }
151  }
152 
158  public static function lookupEffectiveHiddenStatusByTarget($a_target_ref_id)
159  {
160  global $DIC;
161 
162  $obj_definition = $DIC["objDefinition"];
163  $tree = $DIC->repositoryTree();
164 
165  // check if parent takes over control of condition
166  $parent_ref_id = $tree->getParentId($a_target_ref_id);
167  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
168  $parent_type = ilObject::_lookupType($parent_obj_id);
169 
170  $class = $obj_definition->getClassName($parent_type);
171  $class_name = "il" . $class . "ConditionController";
172  $location = $obj_definition->getLocation($parent_type);
173 
174  // if yes, get from parent
175  if ($class != "" && is_file($location . "/class." . $class_name . ".php")) {
177  $controller = new $class_name();
178  if ($controller->isContainerConditionController($parent_ref_id)) {
179  $set = $controller->getConditionSetForRepositoryObject($a_target_ref_id);
180  return $set->getHiddenStatus();
181  }
182  }
183 
184  return self::lookupPersistedHiddenStatusByTarget($a_target_ref_id);
185  }
186 
192  public static function lookupPersistedHiddenStatusByTarget($a_target_ref_id)
193  {
194  global $DIC;
195 
196  $ilDB = $DIC['ilDB'];
197 
198  $query = 'SELECT hidden_status FROM conditions ' .
199  'WHERE target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer');
200  $res = $ilDB->query($query);
201  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
202  return $row->hidden_status;
203  }
204  return false;
205  }
206 
217  public static function _adjustMovedObjectConditions($a_ref_id)
218  {
219  global $DIC;
220 
221  return true;
222 
223  $tree = $DIC['tree'];
224 
225  if ($tree->checkForParentType($a_ref_id, 'crs')) {
226  // Nothing to do
227  return true;
228  }
229 
230  // Need another implementation that has better performance
231  $childs = $tree->getSubTree($tree->getNodeData($a_ref_id), false);
232  $conditions = self::_getDistinctTargetRefIds();
233 
234  foreach (array_intersect($conditions, $childs) as $target_ref) {
235  if (!$tree->checkForParentType($target_ref, 'crs')) {
236  self::_deleteTargetConditionsByRefId($target_ref);
237  }
238  }
239  return true;
240  }
241 
249  protected static function _getDistinctTargetRefIds()
250  {
251  global $DIC;
252 
253  $ilDB = $DIC['ilDB'];
254 
255  $query = "SELECT DISTINCT target_ref_id ref FROM conditions ";
256  $res = $ilDB->query($query);
257  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
258  $ref_ids[] = $row->ref;
259  }
260  return $ref_ids ? $ref_ids : array();
261  }
262 
273  protected static function _deleteTargetConditionsByRefId($a_target_ref_id)
274  {
275  global $DIC;
276 
277  $ilDB = $DIC['ilDB'];
278 
279  $query = "DELETE FROM conditions " .
280  "WHERE target_ref_id = " . $ilDB->quote($a_target_ref_id, 'integer') . " " .
281  "AND target_type != 'st' ";
282  $res = $ilDB->manipulate($query);
283  return true;
284  }
285 
294  {
295  return $this->condition_reference_type = $a_type;
296  }
297 
304  public function getReferenceHandlingType()
305  {
306  return (int) $this->condition_reference_type;
307  }
308 
309  // SET GET
310  public function setErrorMessage($a_msg)
311  {
312  $this->error_message = $a_msg;
313  }
314  public function getErrorMessage()
315  {
316  return $this->error_message;
317  }
318 
322  public function setTargetRefId($a_target_ref_id)
323  {
324  return $this->target_ref_id = $a_target_ref_id;
325  }
326 
330  public function getTargetRefId()
331  {
332  return $this->target_ref_id;
333  }
334 
338  public function setTargetObjId($a_target_obj_id)
339  {
340  return $this->target_obj_id = $a_target_obj_id;
341  }
342 
346  public function getTargetObjId()
347  {
348  return $this->target_obj_id;
349  }
350 
354  public function setTargetType($a_target_type)
355  {
356  return $this->target_type = $a_target_type;
357  }
358 
362  public function getTargetType()
363  {
364  return $this->target_type;
365  }
366 
370  public function setTriggerRefId($a_trigger_ref_id)
371  {
372  return $this->trigger_ref_id = $a_trigger_ref_id;
373  }
374 
378  public function getTriggerRefId()
379  {
380  return $this->trigger_ref_id;
381  }
382 
386  public function setTriggerObjId($a_trigger_obj_id)
387  {
388  return $this->trigger_obj_id = $a_trigger_obj_id;
389  }
390 
394  public function getTriggerObjId()
395  {
396  return $this->trigger_obj_id;
397  }
398 
402  public function setTriggerType($a_trigger_type)
403  {
404  return $this->trigger_type = $a_trigger_type;
405  }
406 
410  public function getTriggerType()
411  {
412  return $this->trigger_type;
413  }
414 
418  public function setOperator($a_operator)
419  {
420  return $this->operator = $a_operator;
421  }
422 
426  public function getOperator()
427  {
428  return $this->operator;
429  }
430 
434  public function setValue($a_value)
435  {
436  return $this->value = $a_value;
437  }
438 
442  public function getValue()
443  {
444  return $this->value;
445  }
446 
451  public function setObligatory($a_obl)
452  {
453  $this->obligatory = $a_obl;
454  }
455 
460  public function getObligatory()
461  {
462  return (bool) $this->obligatory;
463  }
464 
465  public function setHiddenStatus($a_status)
466  {
467  $this->hidden_status = $a_status;
468  }
469 
470  public function getHiddenStatus()
471  {
472  return $this->hidden_status;
473  }
474 
475 
479  public function enableAutomaticValidation($a_validate = true)
480  {
481  $this->validation = $a_validate;
482  }
483 
489  public function getTriggerTypes()
490  {
491  global $DIC;
492 
494  $objDefinition = $DIC['objDefinition'];
495 
496  $trigger_types = array('crs','exc','tst','sahs', 'svy', 'lm', 'iass', 'prg', 'copa');
497 
498  // Add operator lp trigger
500  // only if object type has lp
501  foreach ($objDefinition->getAllRepositoryTypes() as $t) {
503  if (!in_array($t, $trigger_types)) {
504  $trigger_types[] = $t;
505  }
506  }
507  }
508  }
509 
510  foreach ($objDefinition->getPlugins() as $p_type => $p_info) {
511  if (@include_once $p_info['location'] . '/class.ilObj' . $p_info['class_name'] . 'Access.php') {
512  include_once './Services/Conditions/interfaces/interface.ilConditionHandling.php';
513  $name = 'ilObj' . $p_info['class_name'] . 'Access';
514  $reflection = new ReflectionClass($name);
515  if ($reflection->implementsInterface('ilConditionHandling')) {
516  $trigger_types[] = $p_type;
517  }
518  }
519  }
520 
521 
522  $active_triggers = array();
523  foreach ($trigger_types as $type) {
524  if (count($this->getOperatorsByTriggerType($type))) {
525  $active_triggers[] = $type;
526  }
527  }
528 
529 
530 
531 
532  return $active_triggers;
533  }
534 
535 
542  {
543  global $DIC;
544 
545  $objDefinition = $DIC['objDefinition'];
546 
547  switch ($a_type) {
548  case 'crsg':
549  return array('not_member');
550  }
551 
552  $class = $objDefinition->getClassName($a_type);
553  $location = $objDefinition->getLocation($a_type);
554  $full_class = "ilObj" . $class . "Access";
555  include_once($location . "/class." . $full_class . ".php");
556 
557  include_once './Services/Conditions/interfaces/interface.ilConditionHandling.php';
558 
559  $reflection = new ReflectionClass($full_class);
560  if ($reflection->implementsInterface('ilConditionHandling')) {
561  $operators = call_user_func(
562  array($full_class, 'getConditionOperators'),
563  $a_type
564  );
565  } else {
566  $operators = [];
567  }
568 
569  // Add operator lp
570  include_once("Services/Tracking/classes/class.ilObjUserTracking.php");
572  // only if object type has lp
573  include_once("Services/Object/classes/class.ilObjectLP.php");
575  array_unshift($operators, self::OPERATOR_LP);
576  }
577  }
578  return $operators;
579  }
580 
584  public function storeCondition()
585  {
586  global $DIC;
587 
588  $ilDB = $DIC['ilDB'];
589 
590  // first insert, then validate: it's easier to check for circles if the new condition is in the db table
591  $next_id = $ilDB->nextId('conditions');
592  $query = 'INSERT INTO conditions (condition_id,target_ref_id,target_obj_id,target_type,' .
593  'trigger_ref_id,trigger_obj_id,trigger_type,operator,value,ref_handling,obligatory,hidden_status) ' .
594  'VALUES (' .
595  $ilDB->quote($next_id, 'integer') . ',' .
596  $ilDB->quote($this->getTargetRefId(), 'integer') . "," .
597  $ilDB->quote($this->getTargetObjId(), 'integer') . "," .
598  $ilDB->quote($this->getTargetType(), 'text') . "," .
599  $ilDB->quote($this->getTriggerRefId(), 'integer') . "," .
600  $ilDB->quote($this->getTriggerObjId(), 'integer') . "," .
601  $ilDB->quote($this->getTriggerType(), 'text') . "," .
602  $ilDB->quote($this->getOperator(), 'text') . "," .
603  $ilDB->quote($this->getValue(), 'text') . ", " .
604  $ilDB->quote($this->getReferenceHandlingType(), 'integer') . ', ' .
605  $ilDB->quote($this->getObligatory(), 'integer') . ', ' .
606  $ilDB->quote($this->getHiddenStatus(), 'integer') . ' ' .
607  ')';
608 
609  $res = $ilDB->manipulate($query);
610 
611  if ($this->validation && !$this->validate()) {
612  $this->deleteCondition($next_id);
613  return false;
614  }
615  return true;
616  }
617 
618  public function checkExists()
619  {
620  global $DIC;
621 
622  $ilDB = $DIC['ilDB'];
623 
624  $query = "SELECT * FROM conditions " .
625  "WHERE target_ref_id = " . $ilDB->quote($this->getTargetRefId(), 'integer') . " " .
626  "AND target_obj_id = " . $ilDB->quote($this->getTargetObjId(), 'integer') . " " .
627  "AND trigger_ref_id = " . $ilDB->quote($this->getTriggerRefId(), 'integer') . " " .
628  "AND trigger_obj_id = " . $ilDB->quote($this->getTriggerObjId(), 'integer') . " " .
629  "AND operator = " . $ilDB->quote($this->getOperator(), 'text');
630  $res = $ilDB->query($query);
631 
632  return $res->numRows() ? true : false;
633  }
637  public function updateCondition($a_id)
638  {
639  global $DIC;
640 
641  $ilDB = $DIC['ilDB'];
642 
643  $query = "UPDATE conditions SET " .
644  "target_ref_id = " . $ilDB->quote($this->getTargetRefId(), 'integer') . ", " .
645  "operator = " . $ilDB->quote($this->getOperator(), 'text') . ", " .
646  "value = " . $ilDB->quote($this->getValue(), 'text') . ", " .
647  "ref_handling = " . $this->db->quote($this->getReferenceHandlingType(), 'integer') . ", " .
648  'obligatory = ' . $this->db->quote($this->getObligatory(), 'integer') . ' ' .
649  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
650  $res = $ilDB->manipulate($query);
651 
652  return true;
653  }
654 
662  public function updateHiddenStatus($a_status)
663  {
664  global $DIC;
665 
666  $ilDB = $DIC['ilDB'];
667 
668  $query = 'UPDATE conditions SET ' .
669  'hidden_status = ' . $ilDB->quote($a_status, 'integer') . ' ' .
670  'WHERE target_ref_id = ' . $ilDB->quote($this->getTargetRefId(), 'integer');
671  $ilDB->manipulate($query);
672  return true;
673  }
674 
681  public static function updateObligatory($a_id, $a_status)
682  {
683  global $DIC;
684 
685  $ilDB = $DIC['ilDB'];
686 
687  $query = "UPDATE conditions SET " .
688  'obligatory = ' . $ilDB->quote($a_status, 'integer') . ' ' .
689  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
690  $res = $ilDB->manipulate($query);
691 
692  return true;
693  }
694 
699  public function delete($a_ref_id)
700  {
701  global $DIC;
702 
703  $ilDB = $DIC['ilDB'];
704 
705  $query = "DELETE FROM conditions WHERE " .
706  "target_ref_id = " . $ilDB->quote($a_ref_id, 'integer') . " " .
707  "OR trigger_ref_id = " . $ilDB->quote($a_ref_id, 'integer');
708  $res = $ilDB->manipulate($query);
709 
710  return true;
711  }
716  public function deleteByObjId($a_obj_id)
717  {
718  global $DIC;
719 
720  $ilDB = $DIC['ilDB'];
721 
722  $query = "DELETE FROM conditions WHERE " .
723  "target_obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " " .
724  "OR trigger_obj_id = " . $ilDB->quote($a_obj_id, 'integer');
725  $res = $ilDB->manipulate($query);
726 
727  return true;
728  }
729 
733  public function deleteCondition($a_id)
734  {
735  global $DIC;
736 
737  $ilDB = $DIC['ilDB'];
738 
739  $query = "DELETE FROM conditions " .
740  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
741  $res = $ilDB->manipulate($query);
742 
743  return true;
744  }
745 
754  public static function getNumberOfConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
755  {
756  global $DIC;
757  $db = $DIC->database();
758 
759  $query = 'select count(*) num from conditions ' .
760  'where trigger_obj_id = ' . $db->quote($a_trigger_id, ilDBConstants::T_INTEGER) . ' ' .
761  'and trigger_type = ' . $db->quote($a_trigger_obj_type, ilDBConstants::T_TEXT);
762  $res = $db->query($query);
764  return (int) $row->num;
765  }
766 
771  public static function _getPersistedConditionsOfTrigger($a_trigger_obj_type, $a_trigger_id)
772  {
773  global $DIC;
774 
775  $ilDB = $DIC['ilDB'];
776 
777  $query = "SELECT * FROM conditions " .
778  "WHERE trigger_obj_id = " . $ilDB->quote($a_trigger_id, 'integer') . " " .
779  " AND trigger_type = " . $ilDB->quote($a_trigger_obj_type, 'text');
780 
781  $res = $ilDB->query($query);
782  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
783  $tmp_array['id'] = $row->condition_id;
784  $tmp_array['target_ref_id'] = $row->target_ref_id;
785  $tmp_array['target_obj_id'] = $row->target_obj_id;
786  $tmp_array['target_type'] = $row->target_type;
787  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
788  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
789  $tmp_array['trigger_type'] = $row->trigger_type;
790  $tmp_array['operator'] = $row->operator;
791  $tmp_array['value'] = $row->value;
792  $tmp_array['ref_handling'] = $row->ref_handling;
793  $tmp_array['obligatory'] = $row->obligatory;
794  $tmp_array['hidden_status'] = $row->hidden_status;
795 
796  $conditions[] = $tmp_array;
797  unset($tmp_array);
798  }
799 
800  return $conditions ? $conditions : array();
801  }
802 
810  public static function _getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type = "")
811  {
812  global $DIC;
813 
814  $obj_definition = $DIC["objDefinition"];
815  $tree = $DIC->repositoryTree();
816 
817  // get type if no type given
818  if ($a_target_type == "") {
819  $a_target_type = ilObject::_lookupType($a_target_obj_id);
820  }
821 
822  // check if parent takes over control of condition
823  $parent_ref_id = $tree->getParentId($a_target_ref_id);
824  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
825  $parent_type = ilObject::_lookupType($parent_obj_id);
826 
827  $class = $obj_definition->getClassName($parent_type);
828  $class_name = "il" . $class . "ConditionController";
829  $location = $obj_definition->getLocation($parent_type);
830 
831  // if yes, get from parent
832  if ($class != "" && is_file($location . "/class." . $class_name . ".php")
833  && $a_target_type == ilObject::_lookupType($a_target_ref_id, true)) {
835  $controller = new $class_name();
836  if ($controller->isContainerConditionController($parent_ref_id)) {
838  $set = $controller->getConditionSetForRepositoryObject($a_target_ref_id);
839 
840  // convert to old structure
841  $cond = array();
842  foreach ($set->getConditions() as $c) {
843  $obligatory = $set->getAllObligatory()
844  ? true
845  : $c->getObligatory();
846  $trigger = $c->getTrigger();
847  $cond[] = array(
848  "target_ref_id" => $a_target_ref_id,
849  "target_obj_id" => $a_target_obj_id,
850  "target_type" => $a_target_type,
851  "trigger_ref_id" => $trigger->getRefId(),
852  "trigger_obj_id" => $trigger->getObjId(),
853  "trigger_type" => $trigger->getType(),
854  "operator" => $c->getOperator(),
855  "value" => $c->getValue(),
856  "ref_handling" => 1,
857  "obligatory" => (int) $obligatory,
858  "num_obligatory" => $set->getNumObligatory(),
859  "hidden_status" => (int) $set->getHiddenStatus()
860  );
861  }
862  return $cond;
863  }
864  }
865 
866  return self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type);
867  }
868 
876  public static function _getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type = "")
877  {
878  global $DIC;
879 
880  $ilDB = $DIC['ilDB'];
881 
882  // get type if no type given
883  if ($a_target_type == "") {
884  $a_target_type = ilObject::_lookupType($a_target_obj_id);
885  }
886 
887  // check conditions for target cache
888  if (isset(self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
889  $a_target_type])) {
890  return self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
891  $a_target_type];
892  }
893 
894  // check rows cache
895  if (isset(self::$cond_target_rows[$a_target_type . ":" . $a_target_obj_id])) {
896  $rows = self::$cond_target_rows[$a_target_type . ":" . $a_target_obj_id];
897  } else {
898  // query data from db
899  $query = "SELECT * FROM conditions " .
900  "WHERE target_obj_id = " . $ilDB->quote($a_target_obj_id, 'integer') . " " .
901  " AND target_type = " . $ilDB->quote($a_target_type, 'text');
902 
903  $res = $ilDB->query($query);
904  $rows = array();
905  while ($row = $ilDB->fetchAssoc($res)) {
906  $rows[] = $row;
907  }
908  }
909 
910  reset($rows);
911  $conditions = array();
912  foreach ($rows as $row) {
913  if ($row["ref_handling"] == self::UNIQUE_CONDITIONS) {
914  if ($row["target_ref_id"] != $a_target_ref_id) {
915  continue;
916  }
917  }
918 
919  $row["id"] = $row["condition_id"];
920  $conditions[] = $row;
921  }
922 
923  // write conditions for target cache
924  self::$cond_for_target_cache[$a_target_ref_id . ":" . $a_target_obj_id . ":" .
925  $a_target_type] = $conditions;
926 
927  return $conditions;
928  }
929 
936  public static function preloadPersistedConditionsForTargetRecords($a_type, $a_obj_ids)
937  {
938  global $DIC;
939 
940  $ilDB = $DIC['ilDB'];
941 
942  if (is_array($a_obj_ids) && count($a_obj_ids) > 0) {
943  $res = $ilDB->query("SELECT * FROM conditions " .
944  "WHERE " . $ilDB->in("target_obj_id", $a_obj_ids, false, "integer") .
945  " AND target_type = " . $ilDB->quote($a_type, 'text'));
946  $rows = array();
947  while ($row = $ilDB->fetchAssoc($res)) {
948  self::$cond_target_rows[$a_type . ":" . $row["target_obj_id"]][]
949  = $row;
950  }
951  // init obj ids without any record
952  foreach ($a_obj_ids as $obj_id) {
953  if (!is_array(self::$cond_target_rows[$a_type . ":" . $obj_id])) {
954  self::$cond_target_rows[$a_type . ":" . $obj_id] = array();
955  }
956  }
957  }
958  }
959 
960  public static function _getCondition($a_id)
961  {
962  global $DIC;
963 
964  $ilDB = $DIC['ilDB'];
965 
966  $query = "SELECT * FROM conditions " .
967  "WHERE condition_id = " . $ilDB->quote($a_id, 'integer');
968 
969  $res = $ilDB->query($query);
970  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
971  $tmp_array['id'] = $row->condition_id;
972  $tmp_array['target_ref_id'] = $row->target_ref_id;
973  $tmp_array['target_obj_id'] = $row->target_obj_id;
974  $tmp_array['target_type'] = $row->target_type;
975  $tmp_array['trigger_ref_id'] = $row->trigger_ref_id;
976  $tmp_array['trigger_obj_id'] = $row->trigger_obj_id;
977  $tmp_array['trigger_type'] = $row->trigger_type;
978  $tmp_array['operator'] = $row->operator;
979  $tmp_array['value'] = $row->value;
980  $tmp_array['ref_handling'] = $row->ref_handling;
981  $tmp_array['obligatory'] = $row->obligatory;
982  $tmp_array['hidden_status'] = $row->hidden_status;
983 
984  return $tmp_array;
985  }
986  return false;
987  }
988 
989 
990 
996  public static function _checkCondition($condition, $a_usr_id = 0)
997  {
998  global $DIC;
999 
1000  $ilUser = $DIC['ilUser'];
1001  $objDefinition = $DIC['objDefinition'];
1002 
1003  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
1004 
1005  //$condition = ilConditionHandler::_getCondition($a_id);
1006 
1007  // check lp
1008  if ($condition['operator'] == self::OPERATOR_LP) {
1009  include_once './Services/Tracking/classes/class.ilLPStatus.php';
1010  return ilLPStatus::_hasUserCompleted($condition['trigger_obj_id'], $a_usr_id);
1011  }
1012 
1013  switch ($condition['trigger_type']) {
1014  case 'crsg':
1015  include_once './Modules/Course/classes/class.ilObjCourseGrouping.php';
1016  return ilObjCourseGrouping::_checkCondition($condition['trigger_obj_id'], $condition['operator'], $condition['value'], $a_usr_id);
1017  }
1018 
1019  $class = $objDefinition->getClassName($condition['trigger_type']);
1020  $location = $objDefinition->getLocation($condition['trigger_type']);
1021  $full_class = "ilObj" . $class . "Access";
1022  include_once($location . "/class." . $full_class . ".php");
1023 
1024  $fullfilled = call_user_func(
1025  array($full_class, 'checkCondition'),
1026  $condition['trigger_obj_id'],
1027  $condition['operator'],
1028  $condition['value'],
1029  $a_usr_id
1030  );
1031  return $fullfilled;
1032  }
1033 
1041  public static function getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type = '')
1042  {
1043  $conditions = self::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id);
1044 
1045  $opt = array();
1046  foreach ($conditions as $con) {
1047  if ($con['obligatory']) {
1048  continue;
1049  }
1050 
1051  $opt[] = $con;
1052  }
1053  return $opt;
1054  }
1055 
1063  public static function getPersistedOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_obj_type = '')
1064  {
1065  $conditions = self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id);
1066 
1067  $opt = array();
1068  foreach ($conditions as $con) {
1069  if ($con['obligatory']) {
1070  continue;
1071  }
1072 
1073  $opt[] = $con;
1074  }
1075  return $opt;
1076  }
1077 
1078 
1084  public static function lookupObligatoryConditionsOfTarget($a_target_ref_id, $a_target_obj_id)
1085  {
1086  global $DIC;
1087 
1088  $ilDB = $DIC['ilDB'];
1089 
1090  $query = 'SELECT max(num_obligatory) obl from conditions WHERE ' .
1091  'target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer') . ' ' .
1092  'AND target_obj_id = ' . $ilDB->quote($a_target_obj_id, 'integer') . ' ' .
1093  'GROUP BY (num_obligatory)';
1094  $res = $ilDB->query($query);
1095 
1096  $obl = 0;
1097  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1098  $obl = $row->obl;
1099  }
1100  return $obl;
1101  }
1102 
1109  public static function calculateEffectiveRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type = '')
1110  {
1111  global $DIC;
1112 
1113  $ilDB = $DIC['ilDB'];
1114 
1115  // Get all conditions
1116  $all = self::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1117  $opt = self::getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1118 
1119  $set_obl = 0;
1120  if (isset($all[0])) {
1121  $set_obl = $all[0]['num_obligatory'];
1122  }
1123 
1124  // existing value is valid
1125  if ($set_obl > 0 and
1126  $set_obl < count($all) and
1127  $set_obl > (count($all) - count($opt) + 1)) {
1128  return $set_obl;
1129  }
1130 
1131  if (count($opt)) {
1132  $result = count($all) - count($opt) + 1;
1133  } else {
1134  $result = count($all);
1135  }
1136  return $result;
1137  }
1138 
1145  public static function calculatePersistedRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_target_obj_type = '', $a_force_update = false)
1146  {
1147  global $DIC;
1148 
1149  $ilDB = $DIC['ilDB'];
1150 
1151  // Get all conditions
1152  $all = self::_getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1153  $opt = self::getPersistedOptionalConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_obj_type);
1154 
1155  $set_obl = 0;
1156  if (isset($all[0])) {
1157  $set_obl = $all[0]['num_obligatory'];
1158  }
1159 
1160  // existing value is valid
1161  if ($set_obl > 0 and
1162  $set_obl < count($all) and
1163  $set_obl > (count($all) - count($opt) + 1)) {
1164  return $set_obl;
1165  }
1166 
1167  if (count($opt)) {
1168  $result = count($all) - count($opt) + 1;
1169  } else {
1170  $result = count($all);
1171  }
1172  if ($a_force_update) {
1173  self::saveNumberOfRequiredTriggers($a_target_ref_id, $a_target_obj_id, $result);
1174  }
1175  return $result;
1176  }
1177 
1183  public static function saveNumberOfRequiredTriggers($a_target_ref_id, $a_target_obj_id, $a_num)
1184  {
1185  global $DIC;
1186 
1187  $ilDB = $DIC['ilDB'];
1188 
1189  $query = 'UPDATE conditions ' .
1190  'SET num_obligatory = ' . $ilDB->quote($a_num, 'integer') . ' ' .
1191  'WHERE target_ref_id = ' . $ilDB->quote($a_target_ref_id, 'integer') . ' ' .
1192  'AND target_obj_id = ' . $ilDB->quote($a_target_obj_id, 'integer');
1193  $ilDB->manipulate($query);
1194  return;
1195  }
1196 
1200  public static function _checkAllConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type = "", $a_usr_id = 0)
1201  {
1202  global $DIC;
1203 
1204  $ilUser = $DIC['ilUser'];
1205  $tree = $DIC['tree'];
1206 
1207  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
1208 
1209  $conditions = ilConditionHandler::_getEffectiveConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type);
1210 
1211  if (!count($conditions)) {
1212  return true;
1213  }
1214 
1215  // @todo check this
1216  include_once './Services/Container/classes/class.ilMemberViewSettings.php';
1217  if (ilMemberViewSettings::getInstance()->isActive()) {
1218  return true;
1219  }
1220 
1221  // First check obligatory conditions
1222  $optional = self::getEffectiveOptionalConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type);
1223  $num_required = self::calculateEffectiveRequiredTriggers($a_target_ref_id, $a_target_id, $a_target_type);
1224  $passed = 0;
1225  foreach ($conditions as $condition) {
1226  if ($tree->isDeleted($condition['trigger_ref_id'])) {
1227  continue;
1228  }
1229  $check = ilConditionHandler::_checkCondition($condition, $a_usr_id);
1230 
1231  if ($check) {
1232  ++$passed;
1233  if ($passed >= $num_required) {
1234  return true;
1235  }
1236  } else {
1237  if (!count($optional)) {
1238  return false;
1239  }
1240  }
1241  }
1242  // not all optional conditions passed
1243  return false;
1244  }
1245 
1246  // PRIVATE
1247  protected function validate()
1248  {
1249  global $DIC;
1250 
1251  $ilDB = $DIC['ilDB'];
1252 
1253  // check if obj_id is already assigned
1254  $trigger_obj = &ilObjectFactory::getInstanceByRefId($this->getTriggerRefId());
1255  $target_obj = &ilObjectFactory::getInstanceByRefId($this->getTargetRefId());
1256 
1257 
1258  $query = "SELECT * FROM conditions WHERE " .
1259  "trigger_ref_id = " . $ilDB->quote($trigger_obj->getRefId(), 'integer') . " " .
1260  "AND target_ref_id = " . $ilDB->quote($target_obj->getRefId(), 'integer');
1261 
1262  $res = $this->db->query($query);
1263  if ($res->numRows() > 1) {
1264  $this->setErrorMessage($this->lng->txt('condition_already_assigned'));
1265 
1266  unset($trigger_obj);
1267  unset($target_obj);
1268  return false;
1269  }
1270 
1271  // check for circle
1272  $this->target_obj_id = $target_obj->getId();
1273  if ($this->checkCircle($this->getTargetRefId(), $target_obj->getId())) {
1274  $this->setErrorMessage($this->lng->txt('condition_circle_created'));
1275 
1276  unset($trigger_obj);
1277  unset($target_obj);
1278  return false;
1279  }
1280  return true;
1281  }
1282 
1283  protected function checkCircle($a_ref_id, $a_obj_id)
1284  {
1285  foreach (ilConditionHandler::_getPersistedConditionsOfTarget($a_ref_id, $a_obj_id) as $condition) {
1286  if ($condition['trigger_obj_id'] == $this->target_obj_id and $condition['operator'] == $this->getOperator()) {
1287  $this->circle = true;
1288  break;
1289  } else {
1290  $this->checkCircle($condition['trigger_ref_id'], $condition['trigger_obj_id']);
1291  }
1292  }
1293  return $this->circle;
1294  }
1295 
1296  public static function cloneDependencies($a_src_ref_id, $a_target_ref_id, $a_copy_id)
1297  {
1298  include_once './Services/CopyWizard/classes/class.ilCopyWizardOptions.php';
1299  $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
1300  $mappings = $cwo->getMappings();
1301 
1302  $valid = 0;
1304  foreach ($conditions as $con) {
1305  if ($mappings[$con['trigger_ref_id']]) {
1306  $newCondition = new ilConditionHandler();
1307 
1308  $target_obj = ilObject::_lookupObjId($a_target_ref_id);
1309  $target_typ = ilObject::_lookupType($target_obj);
1310 
1311  $newCondition->setTargetRefId($a_target_ref_id);
1312  $newCondition->setTargetObjId($target_obj);
1313  $newCondition->setTargetType($target_typ);
1314 
1315  $trigger_ref = $mappings[$con['trigger_ref_id']];
1316  $trigger_obj = ilObject::_lookupObjId($trigger_ref);
1317  $trigger_typ = ilObject::_lookupType($trigger_obj);
1318 
1319  $newCondition->setTriggerRefId($trigger_ref);
1320  $newCondition->setTriggerObjId($trigger_obj);
1321  $newCondition->setTriggerType($trigger_typ);
1322  $newCondition->setOperator($con['operator']);
1323  $newCondition->setValue($con['value']);
1324  $newCondition->setReferenceHandlingType($con['ref_handling']);
1325  $newCondition->setObligatory($con['obligatory']);
1326 
1327  // :TODO: not sure about this
1328  $newCondition->setHiddenStatus(self::lookupPersistedHiddenStatusByTarget($a_src_ref_id));
1329 
1330  if ($newCondition->storeCondition()) {
1331  $valid++;
1332  }
1333  }
1334  }
1335  if ($valid) {
1336  $tgt_obj_id = ilObject::_lookupObjId($a_target_ref_id);
1337 
1338  // num_obligatory
1339  self::calculatePersistedRequiredTriggers($a_target_ref_id, $tgt_obj_id, ilObject::_lookupType($tgt_obj_id), true);
1340  }
1341  }
1342 }
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...
deleteByObjId($a_obj_id)
delete all trigger and target entries This method is called from ilObject::delete() if an object is r...
$result
$type
global $DIC
Definition: saml.php:7
setValue($a_value)
set value
$location
Definition: buildRTE.php:44
setTargetType($a_target_type)
set target object type
static isSupportedObjectType($a_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)
$a_type
Definition: workflow.php:92
getTargetObjId()
get target obj id
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)
$ilUser
Definition: imgupload.php:18
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.
$row
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 _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...
static getInstance()
Get instance.
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
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