1<?php 2/* 3 +-----------------------------------------------------------------------------+ 4 | ILIAS open source | 5 +-----------------------------------------------------------------------------+ 6 | Copyright (c) 1998-2005 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/** 25* Class ilObj<module_name> 26* 27* @author Stefan Meyer <meyer@leifos.com> 28* @version $Id$ 29* 30*/ 31class ilObjCourseGrouping 32{ 33 public $db; 34 35 protected static $assignedObjects = array(); 36 37 /** 38 * @var null | \ilLogger 39 */ 40 private $logger = null; 41 42 /** 43 * Constructor 44 * @access public 45 * @param int reference_id or object_id 46 */ 47 public function __construct($a_id = 0) 48 { 49 global $DIC; 50 51 $ilDB = $DIC['ilDB']; 52 53 $this->logger = $DIC->logger()->crs(); 54 55 $this->setType('crsg'); 56 $this->db = $ilDB; 57 58 $this->setId($a_id); 59 60 if ($a_id) { 61 $this->read(); 62 } 63 } 64 public function setId($a_id) 65 { 66 $this->id = $a_id; 67 } 68 public function getId() 69 { 70 return $this->id; 71 } 72 73 public function setContainerRefId($a_ref_id) 74 { 75 $this->ref_id = $a_ref_id; 76 } 77 public function getContainerRefId() 78 { 79 return $this->ref_id; 80 } 81 public function setContainerObjId($a_obj_id) 82 { 83 $this->obj_id = $a_obj_id; 84 } 85 public function getContainerObjId() 86 { 87 return $this->obj_id; 88 } 89 public function getContainerType() 90 { 91 return $this->container_type; 92 } 93 public function setContainerType($a_type) 94 { 95 $this->container_type = $a_type; 96 } 97 98 public function setType($a_type) 99 { 100 $this->type = $a_type; 101 } 102 public function getType() 103 { 104 return $this->type; 105 } 106 107 public function setTitle($a_title) 108 { 109 $this->title = $a_title; 110 } 111 public function getTitle() 112 { 113 return $this->title; 114 } 115 public function setDescription($a_desc) 116 { 117 $this->description = $a_desc; 118 } 119 public function getDescription() 120 { 121 return $this->description; 122 } 123 public function setUniqueField($a_uni) 124 { 125 $this->unique_field = $a_uni; 126 } 127 public function getUniqueField() 128 { 129 return $this->unique_field; 130 } 131 132 public function getCountAssignedItems() 133 { 134 return count($this->getAssignedItems()); 135 } 136 137 public function getAssignedItems() 138 { 139 global $DIC; 140 141 $tree = $DIC['tree']; 142 143 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 144 $condition_data = ilConditionHandler::_getPersistedConditionsOfTrigger($this->getType(), $this->getId()); 145 $conditions = array(); 146 foreach ($condition_data as $condition) { 147 if ($tree->isDeleted($condition['target_ref_id'])) { 148 continue; 149 } 150 $conditions[] = $condition; 151 } 152 return count($conditions) ? $conditions : array(); 153 } 154 155 public function delete() 156 { 157 global $DIC; 158 159 $ilDB = $DIC['ilDB']; 160 161 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 162 163 if ($this->getId() and $this->getType() === 'crsg') { 164 $query = "DELETE FROM object_data WHERE obj_id = " . $ilDB->quote($this->getId(), 'integer') . " "; 165 $res = $ilDB->manipulate($query); 166 167 $query = "DELETE FROM crs_groupings " . 168 "WHERE crs_grp_id = " . $ilDB->quote($this->getId(), 'integer') . " "; 169 $res = $ilDB->manipulate($query); 170 171 // Delete conditions 172 $condh = new ilConditionHandler(); 173 $condh->deleteByObjId($this->getId()); 174 175 return true; 176 } 177 return false; 178 } 179 180 public function create($a_course_ref_id, $a_course_id) 181 { 182 global $DIC; 183 184 $ilUser = $DIC['ilUser']; 185 $ilDB = $DIC['ilDB']; 186 187 // INSERT IN object_data 188 $this->setId($ilDB->nextId("object_data")); 189 $query = "INSERT INTO object_data " . 190 "(obj_id, type,title,description,owner,create_date,last_update) " . 191 "VALUES " . 192 "(" . 193 $ilDB->quote($this->getId(), "integer") . "," . 194 $ilDB->quote($this->type, "text") . "," . 195 $ilDB->quote($this->getTitle(), "text") . "," . 196 $ilDB->quote($this->getDescription(), "text") . "," . 197 $ilDB->quote($ilUser->getId(), "integer") . "," . 198 $ilDB->now() . "," . 199 $ilDB->now() . 200 ')'; 201 202 $ilDB->manipulate($query); 203 204 // INSERT in crs_groupings 205 $query = "INSERT INTO crs_groupings (crs_grp_id,crs_ref_id,crs_id,unique_field) " . 206 "VALUES (" . 207 $ilDB->quote($this->getId(), 'integer') . ", " . 208 $ilDB->quote($a_course_ref_id, 'integer') . ", " . 209 $ilDB->quote($a_course_id, 'integer') . ", " . 210 $ilDB->quote($this->getUniqueField(), 'text') . " " . 211 ")"; 212 $res = $ilDB->manipulate($query); 213 214 return $this->getId(); 215 } 216 217 public function update() 218 { 219 global $DIC; 220 221 $ilDB = $DIC['ilDB']; 222 223 if ($this->getId() and $this->getType() === 'crsg') { 224 // UPDATe object_data 225 $query = "UPDATE object_data " . 226 "SET title = " . $ilDB->quote($this->getTitle(), 'text') . ", " . 227 "description = " . $ilDB->quote($this->getDescription(), 'text') . " " . 228 "WHERE obj_id = " . $ilDB->quote($this->getId(), 'integer') . " " . 229 "AND type = " . $ilDB->quote($this->getType(), 'text') . " "; 230 $res = $ilDB->manipulate($query); 231 232 // UPDATE crs_groupings 233 $query = "UPDATE crs_groupings " . 234 "SET unique_field = " . $ilDB->quote($this->getUniqueField(), 'text') . " " . 235 "WHERE crs_grp_id = " . $ilDB->quote($this->getId(), 'integer') . " "; 236 $res = $ilDB->manipulate($query); 237 238 // UPDATE conditions 239 $query = "UPDATE conditions " . 240 "SET value = " . $ilDB->quote($this->getUniqueField(), 'text') . " " . 241 "WHERE trigger_obj_id = " . $ilDB->quote($this->getId(), 'integer') . " " . 242 "AND trigger_type = 'crsg'"; 243 $res = $ilDB->manipulate($query); 244 245 return true; 246 } 247 return false; 248 } 249 250 public function isAssigned($a_course_id) 251 { 252 foreach ($this->getAssignedItems() as $condition_data) { 253 if ($a_course_id == $condition_data['target_obj_id']) { 254 return true; 255 } 256 } 257 return false; 258 } 259 260 public function read() 261 { 262 global $DIC; 263 264 $ilObjDataCache = $DIC['ilObjDataCache']; 265 $ilDB = $DIC['ilDB']; 266 267 $query = "SELECT * FROM object_data " . 268 "WHERE obj_id = " . $ilDB->quote($this->getId(), 'integer') . " "; 269 270 $res = $this->db->query($query); 271 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 272 $this->setTitle($row->title); 273 $this->setDescription($row->description); 274 } 275 276 $query = "SELECT * FROM crs_groupings " . 277 "WHERE crs_grp_id = " . $ilDB->quote($this->getId(), 'integer') . " "; 278 $res = $ilDB->query($query); 279 280 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 281 $this->setUniqueField($row->unique_field); 282 $this->setContainerRefId($row->crs_ref_id); 283 $this->setContainerObjId($row->crs_id); 284 $this->setContainerType($ilObjDataCache->lookupType($this->getContainerObjId())); 285 } 286 287 return true; 288 } 289 290 public function _checkAccess($grouping_id) 291 { 292 global $DIC; 293 294 $ilAccess = $DIC['ilAccess']; 295 $tree = $DIC['tree']; 296 297 $tmp_grouping_obj = new ilObjCourseGrouping($grouping_id); 298 299 $found_invisible = false; 300 foreach ($tmp_grouping_obj->getAssignedItems() as $condition) { 301 if (!$ilAccess->checkAccess('write', '', $condition['target_ref_id'])) { 302 $found_invisible = true; 303 break; 304 } 305 } 306 return $found_invisible ? false : true; 307 } 308 309 310 /** 311 * @param int $a_obj_id 312 * @return array 313 * 314 * Returns a list of all groupings for which the current user hast write permission on all assigned objects. Or groupings 315 * the given object id is assigned to. 316 */ 317 public static function _getVisibleGroupings($a_obj_id) 318 { 319 global $DIC; 320 321 $ilObjDataCache = $DIC['ilObjDataCache']; 322 $ilAccess = $DIC['ilAccess']; 323 $ilDB = $DIC['ilDB']; 324 325 $container_type = $ilObjDataCache->lookupType($a_obj_id) == 'grp' ? 'grp' : 'crs'; 326 327 328 // First get all groupings 329 $query = "SELECT * FROM object_data WHERE type = 'crsg' ORDER BY title"; 330 $res = $ilDB->query($query); 331 $groupings = array(); 332 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 333 $groupings[] = $row->obj_id; 334 } 335 336 //check access 337 foreach ($groupings as $grouping_id) { 338 $tmp_grouping_obj = new ilObjCourseGrouping($grouping_id); 339 340 // Check container type 341 if ($tmp_grouping_obj->getContainerType() != $container_type) { 342 continue; 343 } 344 // Check if container is current container 345 if ($tmp_grouping_obj->getContainerObjId() == $a_obj_id) { 346 $visible_groupings[] = $grouping_id; 347 continue; 348 } 349 // check if items are assigned 350 if (count($items = $tmp_grouping_obj->getAssignedItems())) { 351 foreach ($items as $condition_data) { 352 if ($ilAccess->checkAccess('write', '', $condition_data['target_ref_id'])) { 353 $visible_groupings[] = $grouping_id; 354 break; 355 } 356 } 357 } 358 } 359 return $visible_groupings ? $visible_groupings : array(); 360 } 361 362 public function assign($a_crs_ref_id, $a_course_id) 363 { 364 // Add the parent course of grouping 365 $this->__addCondition($this->getContainerRefId(), $this->getContainerObjId()); 366 $this->__addCondition($a_crs_ref_id, $a_course_id); 367 368 return true; 369 } 370 371 public function deassign($a_crs_ref_id, $a_course_id) 372 { 373 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 374 375 376 $condh = new ilConditionHandler(); 377 378 // DELETE also original course if its the last 379 if ($this->getCountAssignedCourses() == 2) { 380 $condh->deleteByObjId($this->getId()); 381 382 return true; 383 } 384 385 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $this->getId()) as $cond_data) { 386 if ($cond_data['target_ref_id'] == $a_crs_ref_id and 387 $cond_data['target_obj_id'] == $a_course_id) { 388 $condh->deleteCondition($cond_data['id']); 389 } 390 } 391 392 return true; 393 } 394 395 /** 396 * @param int $a_target_id 397 * @param int $a_copy_id 398 */ 399 public function cloneGrouping($a_target_id, $a_copy_id) 400 { 401 $this->logger->debug('Start cloning membership limitations...'); 402 $mappings = \ilCopyWizardOptions::_getInstance($a_copy_id)->getMappings(); 403 $target_ref_id = 0; 404 $target_obj_id = 0; 405 406 if (array_key_exists($this->getContainerRefId(), $mappings) && $mappings[$this->getContainerRefId()]) { 407 $target_ref_id = $mappings[$this->getContainerRefId()]; 408 $target_obj_id = \ilObject::_lookupObjId($target_ref_id); 409 $this->logger->dump($target_ref_id); 410 $this->logger->dump($target_obj_id); 411 } 412 if (!$target_ref_id || !$target_obj_id) { 413 $this->logger->debug('No target ref_id found.'); 414 return false; 415 } 416 417 $new_grouping = new \ilObjCourseGrouping(); 418 $new_grouping->setTitle($this->getTitle()); 419 $new_grouping->setDescription($this->getDescription()); 420 $new_grouping->setContainerRefId($target_ref_id); 421 $new_grouping->setContainerObjId($target_obj_id); 422 $new_grouping->setContainerType(\ilObject::_lookupType($target_obj_id)); 423 $new_grouping->setUniqueField($this->getUniqueField()); 424 $new_grouping->create($target_ref_id, $target_obj_id); 425 426 $obj_instance = \ilObjectFactory::getInstanceByRefId($this->getContainerRefId(), false); 427 if (!$obj_instance instanceof \ilObject) { 428 $this->logger->info('Cannot create object instance for membership limitation'); 429 return false; 430 } 431 $limitation_items = self::_getGroupingItems($obj_instance); 432 $this->logger->dump($limitation_items); 433 434 foreach ($limitation_items as $item_ref_id) { 435 $target_item_ref_id = 0; 436 $target_item_obj_id = 0; 437 if (array_key_exists($item_ref_id, $mappings) && $mappings[$item_ref_id]) { 438 $target_item_ref_id = $mappings[$item_ref_id]; 439 $target_item_obj_id = \ilObject::_lookupObjId($target_item_ref_id); 440 } 441 if (!$target_item_ref_id || !$target_item_obj_id) { 442 $this->logger->info('No mapping found for: ' . $item_ref_id); 443 continue; 444 } 445 $new_grouping->assign($target_item_ref_id, $target_item_obj_id); 446 } 447 448 return true; 449 } 450 451 452 // PRIVATE 453 public function __addCondition($a_target_ref_id, $a_target_obj_id) 454 { 455 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 456 457 $tmp_condh = new ilConditionHandler(); 458 $tmp_condh->enableAutomaticValidation(false); 459 460 $tmp_condh->setTargetRefId($a_target_ref_id); 461 $tmp_condh->setTargetObjId($a_target_obj_id); 462 $tmp_condh->setTargetType(\ilObject::_lookupType($a_target_obj_id)); 463 $tmp_condh->setTriggerRefId(0); 464 $tmp_condh->setTriggerObjId($this->getId()); 465 $tmp_condh->setTriggerType('crsg'); 466 $tmp_condh->setOperator('not_member'); 467 $tmp_condh->setValue($this->getUniqueField()); 468 469 if (!$tmp_condh->checkExists()) { 470 $tmp_condh->storeCondition(); 471 472 return true; 473 } 474 return false; 475 } 476 477 // STATIC 478 public static function _deleteAll($a_course_id) 479 { 480 global $DIC; 481 482 $ilDB = $DIC['ilDB']; 483 484 // DELETE CONDITIONS 485 foreach ($groupings = ilObjCourseGrouping::_getGroupings($a_course_id) as $grouping_id) { 486 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 487 488 $condh = new ilConditionHandler(); 489 $condh->deleteByObjId($grouping_id); 490 } 491 492 $query = "DELETE FROM crs_groupings " . 493 "WHERE crs_id = " . $ilDB->quote($a_course_id, 'integer') . " "; 494 $res = $ilDB->manipulate($query); 495 496 return true; 497 } 498 499 /** 500 * @param $a_course_id 501 * @return int[] 502 */ 503 public static function _getGroupings($a_course_id) 504 { 505 global $DIC; 506 507 $ilDB = $DIC['ilDB']; 508 509 $query = "SELECT * FROM crs_groupings " . 510 "WHERE crs_id = " . $ilDB->quote($a_course_id, 'integer') . " "; 511 512 $res = $ilDB->query($query); 513 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 514 $groupings[] = $row->crs_grp_id; 515 } 516 return $groupings ? $groupings : array(); 517 } 518 519 public static function _checkCondition($trigger_obj_id, $operator, $value, $a_usr_id = 0) 520 { 521 // in the moment i alway return true, there are some problems with presenting the condition if it fails, 522 // only course register class check manually if this condition is fullfilled 523 return true; 524 } 525 526 527 /** 528 * Get all ids of courses that are grouped with another course 529 * @access static 530 * @param integer object_id of one course 531 * @param array integer ids of courses or empty array if course is not in grouping 532 */ 533 public static function _getGroupingCourseIds($a_course_ref_id, $a_course_id) 534 { 535 global $DIC; 536 537 $tree = $DIC['tree']; 538 539 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 540 541 // get all grouping ids the course is assigned to 542 foreach (ilConditionHandler::_getPersistedConditionsOfTarget($a_course_ref_id, $a_course_id, 'crs') as $condition) { 543 if ($condition['trigger_type'] == 'crsg') { 544 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $condition['trigger_obj_id']) as $target_condition) { 545 if ($tree->isDeleted($target_condition['target_ref_id'])) { 546 continue; 547 } 548 $course_ids[] = array('id' => $target_condition['target_obj_id'], 549 'unique' => $target_condition['value']); 550 } 551 } 552 } 553 return $course_ids ? $course_ids : array(); 554 } 555 556 557 /** 558 * Alway call checkGroupingDependencies before 559 * @return array Assigned objects 560 */ 561 public static function getAssignedObjects() 562 { 563 return self::$assignedObjects ? self::$assignedObjects : array(); 564 } 565 566 public static function _checkGroupingDependencies(&$container_obj, $a_user_id = null) 567 { 568 global $DIC; 569 570 $ilUser = $DIC['ilUser']; 571 $lng = $DIC['lng']; 572 $tree = $DIC['tree']; 573 574 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 575 576 $user_id = is_null($a_user_id) ? $ilUser->getId() : $a_user_id; 577 578 579 $trigger_ids = array(); 580 foreach (ilConditionHandler::_getPersistedConditionsOfTarget( 581 $container_obj->getRefId(), 582 $container_obj->getId(), 583 $container_obj->getType() 584 ) as $condition) { 585 if ($condition['operator'] == 'not_member') { 586 $trigger_ids[] = $condition['trigger_obj_id']; 587 break; 588 } 589 } 590 if (!count($trigger_ids)) { 591 return true; 592 } 593 $matriculation_message = $assigned_message = ''; 594 self::$assignedObjects = array(); 595 foreach ($trigger_ids as $trigger_id) { 596 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $trigger_id) as $condition) { 597 // Handle deleted items 598 if ($tree->isDeleted($condition['target_ref_id'])) { 599 continue; 600 } 601 if ($condition['operator'] == 'not_member') { 602 switch ($condition['value']) { 603 case 'matriculation': 604 if (!strlen(ilObjUser::lookupMatriculation($user_id))) { 605 if (!$matriculation_message) { 606 $matriculation_message = $lng->txt('crs_grp_matriculation_required'); 607 } 608 } 609 } 610 if ($container_obj->getType() == 'crs') { 611 include_once('Modules/Course/classes/class.ilCourseParticipants.php'); 612 $members = ilCourseParticipants::_getInstanceByObjId($condition['target_obj_id']); 613 if ($members->isGroupingMember($user_id, $condition['value'])) { 614 if (!$assigned_message) { 615 self::$assignedObjects[] = $condition['target_obj_id']; 616 $assigned_message = $lng->txt('crs_grp_already_assigned'); 617 } 618 } 619 } elseif ($container_obj->getType() == 'grp') { 620 include_once('Modules/Group/classes/class.ilGroupParticipants.php'); 621 $members = ilGroupParticipants::_getInstanceByObjId($condition['target_obj_id']); 622 if ($members->isGroupingMember($user_id, $condition['value'])) { 623 if (!$assigned_message) { 624 self::$assignedObjects[] = $condition['target_obj_id']; 625 $assigned_message = $lng->txt('grp_grp_already_assigned'); 626 } 627 } 628 } else { 629 if (ilObjGroup::_isMember($user_id, $condition['target_ref_id'], $condition['value'])) { 630 if (!$assigned_message) { 631 self::$assignedObjects[] = $condition['target_obj_id']; 632 $assigned_message = $lng->txt('crs_grp_already_assigned'); 633 } 634 } 635 } 636 } 637 } 638 } 639 if ($matriculation_message) { 640 $container_obj->appendMessage($matriculation_message); 641 return false; 642 } elseif ($assigned_message) { 643 $container_obj->appendMessage($assigned_message); 644 return false; 645 } 646 return true; 647 } 648 649 650 /** 651 * Get courses/groups that are assigned to the same membership limitation 652 * 653 * @param object container object 654 * @return array array of reference ids 655 */ 656 public static function _getGroupingItems($container_obj) 657 { 658 global $DIC; 659 660 $tree = $DIC['tree']; 661 $ilObjDataCache = $DIC['ilObjDataCache']; 662 $ilAccess = $DIC['ilAccess']; 663 $tree = $DIC['tree']; 664 665 include_once './Services/Conditions/classes/class.ilConditionHandler.php'; 666 667 $trigger_ids = array(); 668 foreach (ilConditionHandler::_getPersistedConditionsOfTarget( 669 $container_obj->getRefId(), 670 $container_obj->getId(), 671 $container_obj->getType() 672 ) as $condition) { 673 if ($condition['operator'] == 'not_member') { 674 $trigger_ids[] = $condition['trigger_obj_id']; 675 } 676 } 677 if (!count($trigger_ids)) { 678 return false; 679 } 680 $hash_table = array(); 681 foreach ($trigger_ids as $trigger_id) { 682 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $trigger_id) as $condition) { 683 // Continue if trigger is deleted 684 if ($tree->isDeleted($condition['target_ref_id'])) { 685 continue; 686 } 687 688 if ($condition['operator'] == 'not_member') { 689 if (!$hash_table[$condition['target_ref_id']]) { 690 $items[] = $condition['target_ref_id']; 691 } 692 $hash_table[$condition['target_ref_id']] = true; 693 } 694 } 695 } 696 return $items ? $items : array(); 697 } 698} // END class.ilObjCourseGrouping 699