1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4include_once("./Services/UIComponent/Explorer2/classes/class.ilTreeExplorerGUI.php"); 5 6/** 7 * Repository explorer GUI class 8 * 9 * @author Alex Killing <alex.killing@gmx.de> 10 * @version $Id$ 11 * 12 * @todo: isClickable, top node id 13 * 14 * @ingroup ServicesRepository 15 */ 16class ilRepositoryExplorerGUI extends ilTreeExplorerGUI 17{ 18 /** 19 * @var ilSetting 20 */ 21 protected $settings; 22 23 /** 24 * @var ilObjectDefinition 25 */ 26 protected $obj_definition; 27 28 /** 29 * @var ilLanguage 30 */ 31 protected $lng; 32 33 /** 34 * @var ilCtrl 35 */ 36 protected $ctrl; 37 38 /** 39 * @var ilAccessHandler 40 */ 41 protected $access; 42 43 /** 44 * @var ilRbacSystem 45 */ 46 protected $rbacsystem; 47 48 /** 49 * @var ilDB 50 */ 51 protected $db; 52 53 /** 54 * @var ilObjUser 55 */ 56 protected $user; 57 58 protected $type_grps = array(); 59 protected $session_materials = array(); 60 61 protected $parent_node_id = []; 62 protected $node_data = []; 63 64 /** 65 * Constructor 66 */ 67 public function __construct($a_parent_obj, $a_parent_cmd) 68 { 69 global $DIC; 70 71 $this->tree = $DIC->repositoryTree(); 72 $this->settings = $DIC->settings(); 73 $this->obj_definition = $DIC["objDefinition"]; 74 $this->lng = $DIC->language(); 75 $this->ctrl = $DIC->ctrl(); 76 $this->access = $DIC->access(); 77 $this->rbacsystem = $DIC->rbac()->system(); 78 $this->db = $DIC->database(); 79 $this->user = $DIC->user(); 80 $tree = $DIC->repositoryTree(); 81 $ilSetting = $DIC->settings(); 82 $objDefinition = $DIC["objDefinition"]; 83 84 $this->cur_ref_id = (int) $_GET["ref_id"]; 85 86 $this->top_node_id = 0; 87 if ($ilSetting->get("rep_tree_limit_grp_crs") && $this->cur_ref_id > 0) { 88 $path = $tree->getPathId($this->cur_ref_id); 89 foreach ($path as $n) { 90 if ($top_node > 0) { 91 break; 92 } 93 if (in_array( 94 ilObject::_lookupType(ilObject::_lookupObjId($n)), 95 array("crs", "grp") 96 )) { 97 $this->top_node_id = $n; 98 } 99 } 100 } 101 102 parent::__construct("rep_exp", $a_parent_obj, $a_parent_cmd, $tree); 103 104 $this->setSkipRootNode(false); 105 $this->setNodeOpen($this->tree->readRootId()); 106 $this->setAjax(true); 107 $this->setOrderField("title"); 108 if ($ilSetting->get("repository_tree_pres") == "" || 109 ($ilSetting->get("rep_tree_limit_grp_crs") && $this->top_node_id == 0)) { 110 $this->setTypeWhiteList($objDefinition->getExplorerContainerTypes()); 111 } elseif ($ilSetting->get("repository_tree_pres") == "all_types") { 112 $white = array(); 113 foreach ($objDefinition->getSubObjectsRecursively("root") as $rtype) { 114 if (/* $rtype["name"] != "itgr" && */ !$objDefinition->isSideBlock($rtype["name"])) { 115 $white[] = $rtype["name"]; 116 } 117 } 118 $this->setTypeWhiteList($white); 119 } 120 if ((int) $_GET["ref_id"] > 0) { 121 $this->setPathOpen((int) $_GET["ref_id"]); 122 } 123 124 $this->setChildLimit((int) $ilSetting->get("rep_tree_limit_number")); 125 } 126 127 /** 128 * Get root node 129 * 130 * @param 131 * @return 132 */ 133 public function getRootNode() 134 { 135 if ($this->top_node_id > 0) { 136 $root_node = $this->getTree()->getNodeData($this->top_node_id); 137 } else { 138 $root_node = parent::getRootNode(); 139 } 140 $this->node_data[$root_node["child"]] = $root_node; 141 return $root_node; 142 } 143 144 /** 145 * Get node content 146 * 147 * @param array 148 * @return 149 */ 150 public function getNodeContent($a_node) 151 { 152 $lng = $this->lng; 153 154 $title = $a_node["title"]; 155 156 if ($a_node["child"] == $this->getNodeId($this->getRootNode())) { 157 if ($title == "ILIAS") { 158 $title = $lng->txt("repository"); 159 } 160 } elseif ($a_node["type"] == "sess" && 161 !trim($title)) { 162 // #14367 - see ilObjSessionListGUI 163 include_once('./Modules/Session/classes/class.ilSessionAppointment.php'); 164 $app_info = ilSessionAppointment::_lookupAppointment($a_node["obj_id"]); 165 $title = ilSessionAppointment::_appointmentToString($app_info['start'], $app_info['end'], $app_info['fullday']); 166 } 167 168 return $title; 169 } 170 171 /** 172 * Get node icon 173 * 174 * @param array 175 * @return 176 */ 177 public function getNodeIcon($a_node) 178 { 179 $obj_id = ilObject::_lookupObjId($a_node["child"]); 180 return ilObject::_getIcon($obj_id, "tiny", $a_node["type"]); 181 } 182 183 /** 184 * Get node icon alt text 185 * 186 * @param array node array 187 * @return string alt text 188 */ 189 public function getNodeIconAlt($a_node) 190 { 191 $lng = $this->lng; 192 193 if ($a_node["child"] == $this->getNodeId($this->getRootNode())) { 194 $title = $a_node["title"]; 195 if ($title == "ILIAS") { 196 $title = $lng->txt("repository"); 197 } 198 return $title; 199 } 200 201 $lng = $this->lng; 202 return $lng->txt("obj_" . $a_node["type"]) . ": " . $this->getNodeContent($a_node); 203 } 204 205 /** 206 * Is node highlighted? 207 * 208 * @param mixed $a_node node object/array 209 * @return boolean node visible true/false 210 */ 211 public function isNodeHighlighted($a_node) 212 { 213 if ($a_node["child"] == $_GET["ref_id"] || 214 ($_GET["ref_id"] == "" && $a_node["child"] == $this->getNodeId($this->getRootNode()))) { 215 return true; 216 } 217 return false; 218 } 219 220 /** 221 * Get href for node 222 * 223 * @param mixed $a_node node object/array 224 * @return string href attribute 225 */ 226 public function getNodeHref($a_node) 227 { 228 $ilCtrl = $this->ctrl; 229 230 switch ($a_node["type"]) { 231 case "root": 232 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 233 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", ""); 234 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 235 return $link; 236 237 case "cat": 238 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 239 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", ""); 240 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 241 return $link; 242 243 case "catr": 244 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 245 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", "redirect"); 246 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 247 return $link; 248 249 case "grp": 250 $ilCtrl->setParameterByClass("ilobjgroupgui", "ref_id", $a_node["child"]); 251 $link = $ilCtrl->getLinkTargetByClass(array("ilrepositorygui", "ilobjgroupgui"), ""); 252 $ilCtrl->setParameterByClass("ilobjgroupgui", "ref_id", $_GET["ref_id"]); 253 return $link; 254 255 case "grpr": 256 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 257 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", "redirect"); 258 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 259 return $link; 260 261 case "crs": 262 $ilCtrl->setParameterByClass("ilobjcoursegui", "ref_id", $a_node["child"]); 263 $link = $ilCtrl->getLinkTargetByClass(array("ilrepositorygui", "ilobjcoursegui"), "view"); 264 $ilCtrl->setParameterByClass("ilobjcoursegui", "ref_id", $_GET["ref_id"]); 265 return $link; 266 267 case "crsr": 268 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 269 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", "redirect"); 270 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 271 return $link; 272 273 case 'rcrs': 274 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 275 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", "infoScreen"); 276 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 277 return $link; 278 279 case 'prg': 280 $ilCtrl->setParameterByClass("ilobjstudyprogrammegui", "ref_id", $a_node["child"]); 281 $link = $ilCtrl->getLinkTargetByClass(array("ilrepositorygui", "ilobjstudyprogrammegui"), "view"); 282 $ilCtrl->setParameterByClass("ilobjstudyprogrammegui", "ref_id", $_GET["ref_id"]); 283 return $link; 284 case "prgr": 285 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $a_node["child"]); 286 $link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", "redirect"); 287 $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $_GET["ref_id"]); 288 return $link; 289 290 default: 291 include_once('./Services/Link/classes/class.ilLink.php'); 292 return ilLink::_getStaticLink($a_node["child"], $a_node["type"], true); 293 294 } 295 } 296 297 /** 298 * Is node visible 299 * 300 * @param 301 * @return 302 */ 303 public function isNodeVisible($a_node) 304 { 305 $ilAccess = $this->access; 306 $tree = $this->tree; 307 $ilSetting = $this->settings; 308 309 if (!$ilAccess->checkAccess('visible', '', $a_node["child"])) { 310 return false; 311 } 312 313 if ($ilSetting->get("repository_tree_pres") == "all_types") { 314 /*$container_parent_id = $tree->checkForParentType($a_node["child"], 'grp'); 315 if (!$container_parent_id) { 316 $container_parent_id = $tree->checkForParentType($a_node["child"], 'crs'); 317 }*/ 318 // see #21215 319 $container_parent_id = $this->getParentCourseOrGroup($a_node["child"]); 320 if ($container_parent_id > 0) { 321 // do not display session materials for container course/group 322 if ($container_parent_id != $a_node["child"]) { 323 // get container event items only once 324 if (!isset($this->session_materials[$container_parent_id])) { 325 include_once './Modules/Session/classes/class.ilEventItems.php'; 326 $this->session_materials[$container_parent_id] = ilEventItems::_getItemsOfContainer($container_parent_id); 327 } 328 if (in_array($a_node["child"], $this->session_materials[$container_parent_id])) { 329 return false; 330 } 331 } 332 } 333 } 334 335 return true; 336 } 337 338 /** 339 * Get upper course or group 340 * 341 * @param int $node_id 342 * @return int 343 */ 344 protected function getParentCourseOrGroup($node_id) 345 { 346 $current_node_id = $node_id; 347 while (isset($this->parent_node_id[$current_node_id])) { 348 $parent_node_id = $this->parent_node_id[$current_node_id]; 349 if (isset($this->node_data[$parent_node_id]) && in_array($this->node_data[$parent_node_id]["type"], ["grp", "crs"])) { 350 return $parent_node_id; 351 } 352 $current_node_id = $parent_node_id; 353 } 354 return 0; 355 } 356 357 358 /** 359 * Sort childs 360 * 361 * @param array $a_childs array of child nodes 362 * @param mixed $a_parent_node parent node 363 * 364 * @return array array of childs nodes 365 */ 366 public function sortChilds($a_childs, $a_parent_node_id) 367 { 368 $objDefinition = $this->obj_definition; 369 $ilAccess = $this->access; 370 371 $parent_obj_id = ilObject::_lookupObjId($a_parent_node_id); 372 if ($parent_obj_id > 0) { 373 $parent_type = ilObject::_lookupType($parent_obj_id); 374 } else { 375 $parent_type = "dummy"; 376 $this->type_grps["dummy"] = array("root" => "dummy"); 377 } 378 379 // alex: if this is not initialized, things are messed up 380 // see bug 0015978 381 $this->type_grps = array(); 382 383 if (empty($this->type_grps[$parent_type])) { 384 $this->type_grps[$parent_type] = 385 $objDefinition->getGroupedRepositoryObjectTypes($parent_type); 386 } 387 388 // #14465 - item groups 389 include_once('./Services/Object/classes/class.ilObjectActivation.php'); 390 $group = array(); 391 $igroup = array(); // used for item groups, see bug #0015978 392 $in_any_group = array(); 393 foreach ($a_childs as $child) { 394 // item group: get childs 395 if ($child["type"] == "itgr") { 396 $g = $child["child"]; 397 $items = ilObjectActivation::getItemsByItemGroup($g); 398 if ($items) { 399 // add item group ref id to item group block 400 $this->type_grps[$parent_type]["itgr"]["ref_ids"][] = $g; 401 402 // #16697 - check item group permissions 403 $may_read = $ilAccess->checkAccess('read', '', $g); 404 405 // see bug #0015978 406 if ($may_read) { 407 include_once("./Services/Container/classes/class.ilContainerSorting.php"); 408 $items = ilContainerSorting::_getInstance($parent_obj_id)->sortSubItems('itgr', $child["obj_id"], $items); 409 } 410 411 foreach ($items as $item) { 412 $in_any_group[] = $item["child"]; 413 414 if ($may_read) { 415 $igroup[$g][] = $item; 416 $group[$g][] = $item; 417 } 418 } 419 } 420 } 421 // type group 422 else { 423 $g = $objDefinition->getGroupOfObj($child["type"]); 424 if ($g == "") { 425 $g = $child["type"]; 426 } 427 $group[$g][] = $child; 428 } 429 } 430 431 $in_any_group = array_unique($in_any_group); 432 433 // custom block sorting? 434 include_once("./Services/Container/classes/class.ilContainerSorting.php"); 435 $sort = ilContainerSorting::_getInstance($parent_obj_id); 436 $block_pos = $sort->getBlockPositions(); 437 if (is_array($block_pos) && count($block_pos) > 0) { 438 $tmp = $this->type_grps[$parent_type]; 439 440 $this->type_grps[$parent_type] = array(); 441 foreach ($block_pos as $block_type) { 442 // type group 443 if (!is_numeric($block_type) && 444 array_key_exists($block_type, $tmp)) { 445 $this->type_grps[$parent_type][$block_type] = $tmp[$block_type]; 446 unset($tmp[$block_type]); 447 } 448 // item group 449 else { 450 // using item group ref id directly 451 $this->type_grps[$parent_type][$block_type] = array(); 452 } 453 } 454 455 // append missing 456 if (sizeof($tmp)) { 457 foreach ($tmp as $block_type => $grp) { 458 $this->type_grps[$parent_type][$block_type] = $grp; 459 } 460 } 461 462 unset($tmp); 463 } 464 465 $childs = array(); 466 $done = array(); 467 468 foreach ($this->type_grps[$parent_type] as $t => $g) { 469 // type group 470 if (is_array($group[$t])) { 471 // see bug #0015978 472 // custom sorted igroups 473 if (is_array($igroup[$t])) { 474 foreach ($igroup[$t] as $k => $item) { 475 if (!in_array($item["child"], $done)) { 476 $childs[] = $item; 477 $done[] = $item["child"]; 478 } 479 } 480 } else { 481 // do we have to sort this group?? 482 include_once("./Services/Container/classes/class.ilContainer.php"); 483 include_once("./Services/Container/classes/class.ilContainerSorting.php"); 484 $sort = ilContainerSorting::_getInstance($parent_obj_id); 485 $group = $sort->sortItems($group); 486 487 // need extra session sorting here 488 if ($t == "sess") { 489 } 490 491 foreach ($group[$t] as $k => $item) { 492 if (!in_array($item["child"], $done) && 493 !in_array($item["child"], $in_any_group)) { // #16697 494 $childs[] = $item; 495 $done[] = $item["child"]; 496 } 497 } 498 } 499 } 500 // item groups (if not custom block sorting) 501 elseif ($t == "itgr" && 502 is_array($g["ref_ids"])) { 503 foreach ($g["ref_ids"] as $ref_id) { 504 if (isset($group[$ref_id])) { 505 foreach ($group[$ref_id] as $k => $item) { 506 if (!in_array($item["child"], $done)) { 507 $childs[] = $item; 508 $done[] = $item["child"]; 509 } 510 } 511 } 512 } 513 } 514 } 515 516 return $childs; 517 } 518 519 /** 520 * Get childs of node 521 * 522 * @param 523 * @return 524 */ 525 public function getChildsOfNode($a_parent_node_id) 526 { 527 $rbacsystem = $this->rbacsystem; 528 529 if (!$rbacsystem->checkAccess("read", $a_parent_node_id)) { 530 return array(); 531 } 532 533 $obj_id = ilObject::_lookupObjId($a_parent_node_id); 534 if (!ilConditionHandler::_checkAllConditionsOfTarget($a_parent_node_id, $obj_id)) { 535 return array(); 536 } 537 538 $childs = parent::getChildsOfNode($a_parent_node_id); 539 540 foreach ($childs as $c) { 541 $this->parent_node_id[$c["child"]] = $a_parent_node_id; 542 $this->node_data[$c["child"]] = $c; 543 } 544 545 return $childs; 546 } 547 548 /** 549 * Is node clickable? 550 * 551 * @param mixed $a_node node object/array 552 * @return boolean node clickable true/false 553 */ 554 public function isNodeClickable($a_node) 555 { 556 $rbacsystem = $this->rbacsystem; 557 $tree = $this->tree; 558 $ilDB = $this->db; 559 $ilUser = $this->user; 560 $ilAccess = $this->access; 561 562 $obj_id = ilObject::_lookupObjId($a_node["child"]); 563 if (!ilConditionHandler::_checkAllConditionsOfTarget($a_node["child"], $obj_id)) { 564 return false; 565 } 566 567 switch ($a_node["type"]) { 568 case 'tst': 569 if (!$rbacsystem->checkAccess("read", $a_node["child"])) { 570 return false; 571 } 572 573 $query = sprintf("SELECT * FROM tst_tests WHERE obj_fi=%s", $obj_id); 574 $res = $ilDB->query($query); 575 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 576 return (bool) $row->complete; 577 } 578 return false; 579 580 case 'svy': 581 if (!$rbacsystem->checkAccess("read", $a_node["child"])) { 582 return false; 583 } 584 585 $query = sprintf("SELECT * FROM svy_svy WHERE obj_fi=%s", $obj_id); 586 $res = $ilDB->query($query); 587 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 588 return (bool) $row->complete; 589 } 590 return false; 591 592 // media pools can only be edited 593 case "mep": 594 if ($rbacsystem->checkAccess("read", $a_node["child"])) { 595 return true; 596 } else { 597 return false; 598 } 599 break; 600 case 'grpr': 601 case 'crsr': 602 case 'catr': 603 include_once('./Services/ContainerReference/classes/class.ilContainerReferenceAccess.php'); 604 return ilContainerReferenceAccess::_isAccessible($a_node["child"]); 605 606 case 'prg': 607 return $rbacsystem->checkAccess("read", $a_node["child"]); 608 609 // all other types are only clickable, if read permission is given 610 default: 611 if ($rbacsystem->checkAccess("read", $a_node["child"])) { 612 // check if lm is online 613 if ($a_node["type"] == "lm") { 614 include_once("./Modules/LearningModule/classes/class.ilObjLearningModule.php"); 615 $lm_obj = new ilObjLearningModule($a_node["child"]); 616 if (($lm_obj->getOfflineStatus()) && (!$rbacsystem->checkAccess('write', $a_node["child"]))) { 617 return false; 618 } 619 } 620 // check if fblm is online 621 if ($a_node["type"] == "htlm") { 622 include_once("./Modules/HTMLLearningModule/classes/class.ilObjFileBasedLM.php"); 623 $lm_obj = new ilObjFileBasedLM($a_node["child"]); 624 if (($lm_obj->getOfflineStatus()) && (!$rbacsystem->checkAccess('write', $a_node["child"]))) { 625 return false; 626 } 627 } 628 // check if fblm is online 629 if ($a_node["type"] == "sahs") { 630 include_once("./Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php"); 631 $lm_obj = new ilObjSAHSLearningModule($a_node["child"]); 632 if (($lm_obj->getOfflineStatus()) && (!$rbacsystem->checkAccess('write', $a_node["child"]))) { 633 return false; 634 } 635 } 636 // check if glossary is online 637 if ($a_node["type"] == "glo") { 638 $obj_id = ilObject::_lookupObjectId($a_node["child"]); 639 if ((!ilObjGlossary::_lookupOnline($obj_id)) && 640 (!$rbacsystem->checkAccess('write', $a_node["child"]))) { 641 return false; 642 } 643 } 644 645 return true; 646 } else { 647 return false; 648 } 649 break; 650 } 651 } 652} 653