1<?php 2/* 3 +-----------------------------------------------------------------------------+ 4 | ILIAS open source | 5 +-----------------------------------------------------------------------------+ 6 | Copyright (c) 1998-2006 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// note: the values are derived from ilObjCourse constants 25// to enable easy migration from course view setting to container view setting 26 27require_once "./Services/Object/classes/class.ilObject.php"; 28 29/** 30* Class ilContainer 31* 32* Base class for all container objects (categories, courses, groups) 33* 34* @author Alex Killing <alex.killing@gmx.de> 35* @version $Id$ 36* 37* @extends ilObject 38*/ 39class ilContainer extends ilObject 40{ 41 /** 42 * @var ilDB 43 */ 44 protected $db; 45 46 /** 47 * @var Logger 48 */ 49 protected $log; 50 51 /** 52 * @var ilAccessHandler 53 */ 54 protected $access; 55 56 /** 57 * @var ilErrorHandling 58 */ 59 protected $error; 60 61 /** 62 * @var ilRbacSystem 63 */ 64 protected $rbacsystem; 65 66 /** 67 * @var ilTree 68 */ 69 protected $tree; 70 71 /** 72 * @var ilObjUser 73 */ 74 protected $user; 75 76 /** 77 * @var ilObjectDefinition 78 */ 79 protected $obj_definition; 80 81 protected $order_type = 0; 82 protected $hiddenfilesfound = false; 83 protected $news_timeline = false; 84 protected $news_timeline_auto_entries = false; 85 86 // container view constants 87 const VIEW_SESSIONS = 0; 88 const VIEW_OBJECTIVE = 1; 89 const VIEW_TIMING = 2; 90 const VIEW_ARCHIVE = 3; 91 const VIEW_SIMPLE = 4; 92 const VIEW_BY_TYPE = 5; 93 const VIEW_INHERIT = 6; 94 95 const VIEW_DEFAULT = self::VIEW_BY_TYPE; 96 97 98 const SORT_TITLE = 0; 99 const SORT_MANUAL = 1; 100 const SORT_ACTIVATION = 2; 101 const SORT_INHERIT = 3; 102 const SORT_CREATION = 4; 103 104 const SORT_DIRECTION_ASC = 0; 105 const SORT_DIRECTION_DESC = 1; 106 107 const SORT_NEW_ITEMS_POSITION_TOP = 0; 108 const SORT_NEW_ITEMS_POSITION_BOTTOM = 1; 109 110 const SORT_NEW_ITEMS_ORDER_TITLE = 0; 111 const SORT_NEW_ITEMS_ORDER_CREATION = 1; 112 const SORT_NEW_ITEMS_ORDER_ACTIVATION = 2; 113 114 public static $data_preloaded = false; 115 116 /** 117 * @var ilSetting 118 */ 119 protected $setting; 120 121 /** 122 * @var ilObjectTranslation 123 */ 124 protected $obj_trans = null; 125 126 /** 127 * @var ilRecommendedContentManager 128 */ 129 protected $recommended_content_manager; 130 131 public function __construct($a_id = 0, $a_reference = true) 132 { 133 global $DIC; 134 135 $this->db = $DIC->database(); 136 $this->log = $DIC["ilLog"]; 137 $this->access = $DIC->access(); 138 $this->error = $DIC["ilErr"]; 139 $this->rbacsystem = $DIC->rbac()->system(); 140 $this->tree = $DIC->repositoryTree(); 141 $this->user = $DIC->user(); 142 $this->obj_definition = $DIC["objDefinition"]; 143 144 145 $this->setting = $DIC["ilSetting"]; 146 parent::__construct($a_id, $a_reference); 147 include_once("./Services/Object/classes/class.ilObjectTranslation.php"); 148 149 if ($this->getId() > 0) { 150 $this->obj_trans = ilObjectTranslation::getInstance($this->getId()); 151 } 152 $this->recommended_content_manager = new ilRecommendedContentManager(); 153 } 154 155 /** 156 * Get object translation 157 * @return ilObjectTranslation 158 */ 159 public function getObjectTranslation() 160 { 161 return $this->obj_trans; 162 } 163 164 /** 165 * Get object translation 166 * @param ilObjectTranslation $obj_trans 167 */ 168 public function setObjectTranslation(ilObjectTranslation $obj_trans) 169 { 170 $this->obj_trans = $obj_trans; 171 } 172 173 /** 174 * Create directory for the container. 175 * It is <webspace_dir>/container_data. 176 */ 177 public function createContainerDirectory() 178 { 179 $webspace_dir = ilUtil::getWebspaceDir(); 180 $cont_dir = $webspace_dir . "/container_data"; 181 if (!is_dir($cont_dir)) { 182 ilUtil::makeDir($cont_dir); 183 } 184 $obj_dir = $cont_dir . "/obj_" . $this->getId(); 185 if (!is_dir($obj_dir)) { 186 ilUtil::makeDir($obj_dir); 187 } 188 } 189 190 /** 191 * Get the container directory. 192 * 193 * @return string container directory 194 */ 195 public function getContainerDirectory() 196 { 197 return $this->_getContainerDirectory($this->getId()); 198 } 199 200 /** 201 * Get the container directory. 202 * 203 * @return string container directory 204 */ 205 public static function _getContainerDirectory($a_id) 206 { 207 return ilUtil::getWebspaceDir() . "/container_data/obj_" . $a_id; 208 } 209 210 /** 211 * Set Found hidden files (set by getSubItems). 212 * 213 * @param boolean $a_hiddenfilesfound Found hidden files (set by getSubItems) 214 */ 215 public function setHiddenFilesFound($a_hiddenfilesfound) 216 { 217 $this->hiddenfilesfound = $a_hiddenfilesfound; 218 } 219 220 /** 221 * Get Found hidden files (set by getSubItems). 222 * 223 * @return boolean Found hidden files (set by getSubItems) 224 */ 225 public function getHiddenFilesFound() 226 { 227 return $this->hiddenfilesfound; 228 } 229 230 /** 231 * get ID of assigned style sheet object 232 */ 233 public function getStyleSheetId() 234 { 235 return $this->style_id; 236 } 237 238 /** 239 * set ID of assigned style sheet object 240 */ 241 public function setStyleSheetId($a_style_id) 242 { 243 $this->style_id = $a_style_id; 244 } 245 246 /** 247 * Set news timeline 248 * 249 * @param bool $a_val activate news timeline 250 */ 251 public function setNewsTimeline($a_val) 252 { 253 $this->news_timeline = $a_val; 254 } 255 256 /** 257 * Get news timeline 258 * 259 * @return bool activate news timeline 260 */ 261 public function getNewsTimeline() 262 { 263 return $this->news_timeline; 264 } 265 266 /** 267 * Set news timeline auto entries 268 * 269 * @param bool $a_val include automatically created entries 270 */ 271 public function setNewsTimelineAutoEntries($a_val) 272 { 273 $this->news_timeline_auto_entries = $a_val; 274 } 275 276 /** 277 * Get news timeline auto entries 278 * 279 * @return bool include automatically created entries 280 */ 281 public function getNewsTimelineAutoEntries() 282 { 283 return $this->news_timeline_auto_entries; 284 } 285 286 /** 287 * Set news timline is landing page 288 * 289 * @param bool $a_val is news timline landing page? 290 */ 291 public function setNewsTimelineLandingPage($a_val) 292 { 293 $this->news_timeline_landing_page = $a_val; 294 } 295 296 /** 297 * Get news timline is landing page 298 * 299 * @return bool is news timline landing page? 300 */ 301 public function getNewsTimelineLandingPage() 302 { 303 return $this->news_timeline_landing_page; 304 } 305 306 /** 307 * Is news timeline effective? 308 * 309 * @return bool 310 */ 311 public function isNewsTimelineEffective() 312 { 313 if ($this->getUseNews()) { 314 if ($this->getNewsTimeline()) { 315 return true; 316 } 317 } 318 return false; 319 } 320 321 /** 322 * Is news timeline landing page effective? 323 * 324 * @return bool 325 */ 326 public function isNewsTimelineLandingPageEffective() 327 { 328 if ($this->getUseNews()) { 329 if ($this->getNewsTimeline()) { 330 if ($this->getNewsTimelineLandingPage()) { 331 return true; 332 } 333 } 334 } 335 return false; 336 } 337 338 339 /** 340 * Set news block activated 341 * 342 * @param bool $a_val news block activated 343 */ 344 public function setNewsBlockActivated($a_val) 345 { 346 $this->news_block_activated = $a_val; 347 } 348 349 /** 350 * Get news block activated 351 * 352 * @return bool news block activated 353 */ 354 public function getNewsBlockActivated() 355 { 356 return $this->news_block_activated; 357 } 358 359 /** 360 * Set use news 361 * 362 * @param bool $a_val use news system? 363 */ 364 public function setUseNews($a_val) 365 { 366 $this->use_news = $a_val; 367 } 368 369 /** 370 * Get use news 371 * 372 * @return bool use news system? 373 */ 374 public function getUseNews() 375 { 376 return $this->use_news; 377 } 378 379 /** 380 * Lookup a container setting. 381 * 382 * @param int container id 383 * @param string setting keyword 384 * 385 * @return string setting value 386 */ 387 public static function _lookupContainerSetting($a_id, $a_keyword, $a_default_value = null) 388 { 389 global $DIC; 390 391 $ilDB = $DIC->database(); 392 393 $q = "SELECT * FROM container_settings WHERE " . 394 " id = " . $ilDB->quote($a_id, 'integer') . " AND " . 395 " keyword = " . $ilDB->quote($a_keyword, 'text'); 396 $set = $ilDB->query($q); 397 $rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC); 398 399 if (isset($rec['value'])) { 400 return $rec["value"]; 401 } 402 if ($a_default_value === null) { 403 return ''; 404 } 405 return $a_default_value; 406 } 407 408 /** 409 * @param $a_id 410 * @param $a_keyword 411 * @param $a_value 412 */ 413 public static function _writeContainerSetting($a_id, $a_keyword, $a_value) 414 { 415 global $DIC; 416 417 $ilDB = $DIC->database(); 418 419 $query = "DELETE FROM container_settings WHERE " . 420 "id = " . $ilDB->quote($a_id, 'integer') . " " . 421 "AND keyword = " . $ilDB->quote($a_keyword, 'text'); 422 $res = $ilDB->manipulate($query); 423 424 $log = ilLoggerFactory::getLogger("cont"); 425 $log->debug("Write container setting, id: " . $a_id . ", keyword: " . $a_keyword . ", value: " . $a_value); 426 427 $query = "INSERT INTO container_settings (id, keyword, value) VALUES (" . 428 $ilDB->quote($a_id, 'integer') . ", " . 429 $ilDB->quote($a_keyword, 'text') . ", " . 430 $ilDB->quote($a_value, 'text') . 431 ")"; 432 433 $res = $ilDB->manipulate($query); 434 } 435 436 public static function _getContainerSettings($a_id) 437 { 438 global $DIC; 439 440 $ilDB = $DIC->database(); 441 442 $res = array(); 443 444 $sql = "SELECT * FROM container_settings WHERE " . 445 " id = " . $ilDB->quote($a_id, 'integer'); 446 $set = $ilDB->query($sql); 447 while ($row = $ilDB->fetchAssoc($set)) { 448 $res[$row["keyword"]] = $row["value"]; 449 } 450 451 return $res; 452 } 453 454 public static function _deleteContainerSettings($a_id, $a_keyword = null, $a_keyword_like = false) 455 { 456 global $DIC; 457 458 $ilDB = $DIC->database(); 459 460 if (!$a_id) { 461 return; 462 } 463 464 $sql = "DELETE FROM container_settings WHERE " . 465 " id = " . $ilDB->quote($a_id, 'integer'); 466 if ($a_keyword) { 467 if (!$a_keyword_like) { 468 $sql .= " AND keyword = " . $ilDB->quote($a_keyword, "text"); 469 } else { 470 $sql .= " AND " . $ilDB->like("keyword", "text", $a_keyword); 471 } 472 } 473 $ilDB->manipulate($sql); 474 } 475 476 public static function _exportContainerSettings(ilXmlWriter $a_xml, $a_obj_id) 477 { 478 // container settings 479 $settings = self::_getContainerSettings($a_obj_id); 480 if (sizeof($settings)) { 481 $a_xml->xmlStartTag("ContainerSettings"); 482 483 foreach ($settings as $keyword => $value) { 484 // :TODO: proper custom icon export/import 485 if (stristr($keyword, "icon")) { 486 continue; 487 } 488 489 $a_xml->xmlStartTag( 490 'ContainerSetting', 491 array( 492 'id' => $keyword, 493 ) 494 ); 495 496 $a_xml->xmlData($value); 497 $a_xml->xmlEndTag("ContainerSetting"); 498 } 499 500 $a_xml->xmlEndTag("ContainerSettings"); 501 } 502 } 503 504 /** 505 * Clone container settings 506 * 507 * @access public 508 * @param int target ref_id 509 * @param int copy id 510 * @return object new object 511 */ 512 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false) 513 { 514 /** @var ilObjCourse $new_obj */ 515 $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree); 516 517 // translations 518 include_once("./Services/Object/classes/class.ilObjectTranslation.php"); 519 $ot = ilObjectTranslation::getInstance($this->getId()); 520 $ot->copy($new_obj->getId()); 521 522 include_once('./Services/Container/classes/class.ilContainerSortingSettings.php'); 523 #18624 - copy all sorting settings 524 ilContainerSortingSettings::_cloneSettings($this->getId(), $new_obj->getId()); 525 526 // copy content page 527 include_once("./Services/Container/classes/class.ilContainerPage.php"); 528 if (ilContainerPage::_exists( 529 "cont", 530 $this->getId() 531 )) { 532 $orig_page = new ilContainerPage($this->getId()); 533 $orig_page->copy($new_obj->getId(), "cont", $new_obj->getId()); 534 } 535 536 // #20614 - copy style 537 include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 538 $style_id = $this->getStyleSheetId(); 539 if ($style_id > 0) { 540 if (!!ilObjStyleSheet::_lookupStandard($style_id)) { 541 $style_obj = ilObjectFactory::getInstanceByObjId($style_id); 542 $new_id = $style_obj->ilClone(); 543 $new_obj->setStyleSheetId($new_id); 544 $new_obj->update(); 545 } else { 546 $new_obj->setStyleSheetId($this->getStyleSheetId()); 547 } 548 } 549 550 // #10271 - copy start objects page 551 include_once("./Services/Container/classes/class.ilContainerStartObjectsPage.php"); 552 if (ilContainerStartObjectsPage::_exists( 553 "cstr", 554 $this->getId() 555 )) { 556 $orig_page = new ilContainerStartObjectsPage($this->getId()); 557 $orig_page->copy($new_obj->getId(), "cstr", $new_obj->getId()); 558 } 559 560 // #10271 561 foreach (self::_getContainerSettings($this->getId()) as $keyword => $value) { 562 self::_writeContainerSetting($new_obj->getId(), $keyword, $value); 563 } 564 565 $new_obj->setNewsTimeline($this->getNewsTimeline()); 566 $new_obj->setNewsBlockActivated($this->getNewsBlockActivated()); 567 $new_obj->setUseNews($this->getUseNews()); 568 $new_obj->setNewsTimelineAutoEntries($this->getNewsTimelineAutoEntries()); 569 $new_obj->setNewsTimelineLandingPage($this->getNewsTimelineLandingPage()); 570 ilBlockSetting::cloneSettingsOfBlock("news", $this->getId(), $new_obj->getId()); 571 $mom_noti = new ilMembershipNotifications($this->getRefId()); 572 $mom_noti->cloneSettings($new_obj->getRefId()); 573 574 return $new_obj; 575 } 576 577 /** 578 * Clone object dependencies (container sorting) 579 * 580 * @access public 581 * @param int target ref id of new course 582 * @param int copy id 583 * return bool 584 */ 585 public function cloneDependencies($a_target_id, $a_copy_id) 586 { 587 $ilLog = $this->log; 588 589 parent::cloneDependencies($a_target_id, $a_copy_id); 590 591 include_once('./Services/Container/classes/class.ilContainerSorting.php'); 592 ilContainerSorting::_getInstance($this->getId())->cloneSorting($a_target_id, $a_copy_id); 593 594 // fix internal links to other objects 595 ilContainer::fixInternalLinksAfterCopy($a_target_id, $a_copy_id, $this->getRefId()); 596 597 // fix item group references in page content 598 include_once("./Modules/ItemGroup/classes/class.ilObjItemGroup.php"); 599 ilObjItemGroup::fixContainerItemGroupRefsAfterCloning($this, $a_copy_id); 600 601 include_once('Services/Object/classes/class.ilObjectLP.php'); 602 $olp = ilObjectLP::getInstance($this->getId()); 603 $collection = $olp->getCollectionInstance(); 604 if ($collection) { 605 $collection->cloneCollection($a_target_id, $a_copy_id); 606 } 607 608 return true; 609 } 610 611 /** 612 * clone all objects according to this container 613 * 614 * @param string $session_id 615 * @param string $client_id 616 * @param string $new_type 617 * @param int $ref_id 618 * @param int $clone_source 619 * @param array $options 620 * @param bool force soap 621 * @param int submode 1 => copy all, 2 => copy content 622 * @return new refid if clone has finished or parameter ref id if cloning is still in progress 623 * @return array(copy_id => xyz, ref_id => new ref_id) 624 */ 625 public function cloneAllObject($session_id, $client_id, $new_type, $ref_id, $clone_source, $options, $soap_call = false, $a_submode = 1) 626 { 627 $ilLog = $this->log; 628 629 include_once('./Services/Link/classes/class.ilLink.php'); 630 include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php'); 631 632 $ilAccess = $this->access; 633 $ilErr = $this->error; 634 $rbacsystem = $this->rbacsystem; 635 $tree = $this->tree; 636 $ilUser = $this->user; 637 638 // Save wizard options 639 $copy_id = ilCopyWizardOptions::_allocateCopyId(); 640 $wizard_options = ilCopyWizardOptions::_getInstance($copy_id); 641 $wizard_options->saveOwner($ilUser->getId()); 642 $wizard_options->saveRoot($clone_source); 643 644 // add entry for source container 645 $wizard_options->initContainer($clone_source, $ref_id); 646 647 foreach ($options as $source_id => $option) { 648 $wizard_options->addEntry($source_id, $option); 649 } 650 $wizard_options->read(); 651 $wizard_options->storeTree($clone_source); 652 653 include_once './Services/Object/classes/class.ilObjectCopyGUI.php'; 654 if ($a_submode == ilObjectCopyGUI::SUBMODE_CONTENT_ONLY) { 655 ilLoggerFactory::getLogger('obj')->info('Copy content only...'); 656 ilLoggerFactory::getLogger('obj')->debug('Added mapping, source ID: ' . $clone_source . ', target ID: ' . $ref_id); 657 $wizard_options->read(); 658 $wizard_options->dropFirstNode(); 659 $wizard_options->appendMapping($clone_source, $ref_id); 660 } 661 662 663 #print_r($options); 664 // Duplicate session to avoid logout problems with backgrounded SOAP calls 665 $new_session_id = ilSession::_duplicate($session_id); 666 // Start cloning process using soap call 667 include_once 'Services/WebServices/SOAP/classes/class.ilSoapClient.php'; 668 669 $soap_client = new ilSoapClient(); 670 $soap_client->setResponseTimeout(5); 671 $soap_client->enableWSDL(true); 672 673 $ilLog->write(__METHOD__ . ': Trying to call Soap client...'); 674 if ($soap_client->init()) { 675 ilLoggerFactory::getLogger('obj')->info('Calling soap clone method'); 676 $res = $soap_client->call('ilClone', array($new_session_id . '::' . $client_id, $copy_id)); 677 } else { 678 ilLoggerFactory::getLogger('obj')->warning('SOAP clone call failed. Calling clone method manually'); 679 $wizard_options->disableSOAP(); 680 $wizard_options->read(); 681 include_once('./webservice/soap/include/inc.soap_functions.php'); 682 $res = ilSoapFunctions::ilClone($new_session_id . '::' . $client_id, $copy_id); 683 } 684 return array( 685 'copy_id' => $copy_id, 686 'ref_id' => (int) $res 687 ); 688 } 689 690 /** 691 * delete category and all related data 692 * 693 * @return boolean true if all object data were removed; false if only a references were removed 694 */ 695 public function delete() 696 { 697 // always call parent delete function first!! 698 if (!parent::delete()) { 699 return false; 700 } 701 // delete translations 702 $this->obj_trans->delete(); 703 704 return true; 705 } 706 707 /** 708 * Get container view mode 709 */ 710 public function getViewMode() 711 { 712 return ilContainer::VIEW_BY_TYPE; 713 } 714 715 /** 716 * Get order type default implementation 717 */ 718 public function getOrderType() 719 { 720 return $this->order_type ? $this->order_type : ilContainer::SORT_TITLE; 721 } 722 723 public function setOrderType($a_value) 724 { 725 $this->order_type = $a_value; 726 } 727 728 /** 729 * Is classification filter active? 730 * @return bool 731 */ 732 public function isClassificationFilterActive() : bool 733 { 734 // apply container classification filters 735 $repo = new ilClassificationSessionRepository($this->getRefId()); 736 foreach (ilClassificationProvider::getValidProviders($this->getRefId(), $this->getId(), $this->getType()) as $class_provider) { 737 $id = get_class($class_provider); 738 $current = $repo->getValueForProvider($id); 739 if ($current) { 740 return true; 741 } 742 } 743 return false; 744 } 745 746 /** 747 * Note grp/crs currently allow to filter in their whole subtrees 748 * Catetories only their direct childs 749 * @return bool 750 */ 751 public function filteredSubtree() : bool 752 { 753 if ($this->isClassificationFilterActive() && in_array($this->getType(), ["grp", "crs"])) { 754 return true; 755 } 756 return false; 757 } 758 759 /** 760 * Get initial subitems 761 * 762 * @return array 763 */ 764 protected function getInitialSubitems() : array 765 { 766 $tree = $this->tree; 767 if ($this->filteredSubtree()) { 768 $objects = $tree->getSubTree($tree->getNodeData($this->getRefId())); 769 } else { 770 $objects = $tree->getChilds($this->getRefId(), "title"); 771 } 772 return $objects; 773 } 774 775 /** 776 * Get subitems of container 777 * 778 * @param bool administration panel enabled 779 * @param bool side blocks enabled 780 * 781 * @return array 782 */ 783 public function getSubItems( 784 $a_admin_panel_enabled = false, 785 $a_include_side_block = false, 786 $a_get_single = 0, 787 \ilContainerUserFilter $container_user_filter = null 788 ) { 789 $objDefinition = $this->obj_definition; 790 791 // Caching 792 if (is_array($this->items[(int) $a_admin_panel_enabled][(int) $a_include_side_block]) && 793 !$a_get_single) { 794 return $this->items[(int) $a_admin_panel_enabled][(int) $a_include_side_block]; 795 } 796 797 $objects = $this->getInitialSubitems(); 798 $objects = $this->applyContainerUserFilter($objects, $container_user_filter); 799 $objects = self::getCompleteDescriptions($objects); 800 801 // apply container classification filters 802 $repo = new ilClassificationSessionRepository($this->getRefId()); 803 foreach (ilClassificationProvider::getValidProviders($this->getRefId(), $this->getId(), $this->getType()) as $class_provider) { 804 $id = get_class($class_provider); 805 $current = $repo->getValueForProvider($id); 806 if ($current) { 807 $class_provider->setSelection($current); 808 $filtered = $class_provider->getFilteredObjects(); 809 $objects = array_filter($objects, function ($i) use ($filtered) { 810 return (is_array($filtered) && in_array($i["obj_id"], $filtered)); 811 }); 812 //if (count($filtered) > 0) { 813 // var_dump($filtered); 814 // echo "<br><br>"; 815 // var_dump($objects); 816 // exit; 817 //} 818 } 819 } 820 821 $found = false; 822 $all_ref_ids = array(); 823 824 if (!self::$data_preloaded) { 825 include_once("./Services/Object/classes/class.ilObjectListGUIPreloader.php"); 826 $preloader = new ilObjectListGUIPreloader(ilObjectListGUI::CONTEXT_REPOSITORY); 827 } 828 829 include_once('Services/Container/classes/class.ilContainerSorting.php'); 830 $sort = ilContainerSorting::_getInstance($this->getId()); 831 832 // TODO: check this 833 // get items attached to a session 834 include_once './Modules/Session/classes/class.ilEventItems.php'; 835 $event_items = ilEventItems::_getItemsOfContainer($this->getRefId()); 836 837 $classification_filter_active = $this->isClassificationFilterActive(); 838 foreach ($objects as $key => $object) { 839 if ($a_get_single > 0 && $object["child"] != $a_get_single) { 840 continue; 841 } 842 843 // hide object types in devmode 844 if ($objDefinition->getDevMode($object["type"]) || $object["type"] == "adm" 845 || $object["type"] == "rolf") { 846 continue; 847 } 848 849 // remove inactive plugins 850 if ($objDefinition->isInactivePlugin($object["type"])) { 851 continue; 852 } 853 854 // BEGIN WebDAV: Don't display hidden Files, Folders and Categories 855 if (in_array($object['type'], array('file','fold','cat'))) { 856 include_once 'Modules/File/classes/class.ilObjFileAccess.php'; 857 if (ilObjFileAccess::_isFileHidden($object['title'])) { 858 $this->setHiddenFilesFound(true); 859 if (!$a_admin_panel_enabled) { 860 continue; 861 } 862 } 863 } 864 // END WebDAV: Don't display hidden Files, Folders and Categories 865 866 // including event items! 867 if (!self::$data_preloaded) { 868 $preloader->addItem($object["obj_id"], $object["type"], $object["child"]); 869 } 870 871 // filter out items that are attached to an event 872 if (in_array($object['ref_id'], $event_items) && !$classification_filter_active) { 873 continue; 874 } 875 876 // filter side block items 877 if (!$a_include_side_block && $objDefinition->isSideBlock($object['type'])) { 878 continue; 879 } 880 881 $all_ref_ids[] = $object["child"]; 882 } 883 884 // data preloader 885 if (!self::$data_preloaded) { 886 $preloader->preload(); 887 unset($preloader); 888 889 self::$data_preloaded = true; 890 } 891 892 foreach ($objects as $key => $object) { 893 // see above, objects were filtered 894 if (!in_array($object["child"], $all_ref_ids)) { 895 continue; 896 } 897 898 // group object type groups together (e.g. learning resources) 899 $type = $objDefinition->getGroupOfObj($object["type"]); 900 if ($type == "") { 901 $type = $object["type"]; 902 } 903 904 // this will add activation properties 905 $this->addAdditionalSubItemInformation($object); 906 907 $this->items[$type][$key] = $object; 908 909 $this->items["_all"][$key] = $object; 910 if ($object["type"] != "sess") { 911 $this->items["_non_sess"][$key] = $object; 912 } 913 } 914 $this->items[(int) $a_admin_panel_enabled][(int) $a_include_side_block] 915 = $sort->sortItems($this->items); 916 917 return $this->items[(int) $a_admin_panel_enabled][(int) $a_include_side_block]; 918 } 919 920 /** 921 * Check whether we got any items 922 */ 923 public function gotItems() 924 { 925 if (is_array($this->items["_all"]) && count($this->items["_all"]) > 0) { 926 return true; 927 } 928 return false; 929 } 930 931 /** 932 * Add additional information to sub item, e.g. used in 933 * courses for timings information etc. 934 */ 935 public function addAdditionalSubItemInformation(&$object) 936 { 937 } 938 939 /** 940 * Get grouped repository object types. 941 * 942 * @return array array of object types 943 */ 944 public function getGroupedObjTypes() 945 { 946 $objDefinition = $this->obj_definition; 947 948 if (empty($this->type_grps)) { 949 $this->type_grps = $objDefinition->getGroupedRepositoryObjectTypes($this->getType()); 950 } 951 return $this->type_grps; 952 } 953 954 /** 955 * Check whether page editing is allowed for container 956 */ 957 public function enablePageEditing() 958 { 959 $ilSetting = $this->setting; 960 961 // @todo: this will need a more general approach 962 if ($ilSetting->get("enable_cat_page_edit")) { 963 return true; 964 } 965 } 966 967 /** 968 * Create 969 */ 970 public function create() 971 { 972 global $DIC; 973 974 $lng = $DIC->language(); 975 976 $ret = parent::create(); 977 978 // set translation object, since we have an object id now 979 $this->obj_trans = ilObjectTranslation::getInstance($this->getId()); 980 981 // add default translation 982 $this->addTranslation( 983 $this->getTitle(), 984 $this->getDescription(), 985 $lng->getDefaultLanguage(), 986 true 987 ); 988 989 if (((int) $this->getStyleSheetId()) > 0) { 990 include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 991 ilObjStyleSheet::writeStyleUsage($this->getId(), $this->getStyleSheetId()); 992 } 993 994 $log = ilLoggerFactory::getLogger("cont"); 995 $log->debug("Create Container, id: " . $this->getId()); 996 997 self::_writeContainerSetting($this->getId(), "news_timeline", (int) $this->getNewsTimeline()); 998 self::_writeContainerSetting($this->getId(), "news_timeline_incl_auto", (int) $this->getNewsTimelineAutoEntries()); 999 self::_writeContainerSetting($this->getId(), "news_timeline_landing_page", (int) $this->getNewsTimelineLandingPage()); 1000 include_once("./Services/Object/classes/class.ilObjectServiceSettingsGUI.php"); 1001 self::_writeContainerSetting($this->getId(), ilObjectServiceSettingsGUI::NEWS_VISIBILITY, (int) $this->getNewsBlockActivated()); 1002 self::_writeContainerSetting($this->getId(), ilObjectServiceSettingsGUI::USE_NEWS, (int) $this->getUseNews()); 1003 1004 return $ret; 1005 } 1006 1007 /** 1008 * @inheritdoc 1009 */ 1010 public function putInTree($a_parent_ref) 1011 { 1012 parent::putInTree($a_parent_ref); 1013 1014 // copy title, icon actions visibilities 1015 if (self::_lookupContainerSetting(ilObject::_lookupObjId($a_parent_ref), "hide_header_icon_and_title")) { 1016 self::_writeContainerSetting($this->getId(), "hide_header_icon_and_title", true); 1017 } 1018 if (self::_lookupContainerSetting(ilObject::_lookupObjId($a_parent_ref), "hide_top_actions")) { 1019 self::_writeContainerSetting($this->getId(), "hide_top_actions", true); 1020 } 1021 } 1022 1023 /** 1024 * Update 1025 */ 1026 public function update() 1027 { 1028 $ret = parent::update(); 1029 1030 $trans = $this->getObjectTranslation(); 1031 $trans->setDefaultTitle($this->getTitle()); 1032 $trans->setDefaultDescription($this->getLongDescription()); 1033 $trans->save(); 1034 1035 include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 1036 ilObjStyleSheet::writeStyleUsage($this->getId(), $this->getStyleSheetId()); 1037 1038 $log = ilLoggerFactory::getLogger("cont"); 1039 $log->debug("Update Container, id: " . $this->getId()); 1040 1041 self::_writeContainerSetting($this->getId(), "news_timeline", (int) $this->getNewsTimeline()); 1042 self::_writeContainerSetting($this->getId(), "news_timeline_incl_auto", (int) $this->getNewsTimelineAutoEntries()); 1043 self::_writeContainerSetting($this->getId(), "news_timeline_landing_page", (int) $this->getNewsTimelineLandingPage()); 1044 include_once("./Services/Object/classes/class.ilObjectServiceSettingsGUI.php"); 1045 self::_writeContainerSetting($this->getId(), ilObjectServiceSettingsGUI::NEWS_VISIBILITY, (int) $this->getNewsBlockActivated()); 1046 self::_writeContainerSetting($this->getId(), ilObjectServiceSettingsGUI::USE_NEWS, (int) $this->getUseNews()); 1047 1048 return $ret; 1049 } 1050 1051 1052 /** 1053 * read 1054 * 1055 * @access public 1056 * @param 1057 * @return 1058 */ 1059 public function read() 1060 { 1061 parent::read(); 1062 1063 include_once("./Services/Container/classes/class.ilContainerSortingSettings.php"); 1064 $this->setOrderType(ilContainerSortingSettings::_lookupSortMode($this->getId())); 1065 1066 include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 1067 $this->setStyleSheetId((int) ilObjStyleSheet::lookupObjectStyle($this->getId())); 1068 1069 $this->readContainerSettings(); 1070 $this->obj_trans = ilObjectTranslation::getInstance($this->getId()); 1071 } 1072 1073 /** 1074 * Read container settings 1075 * 1076 * @param 1077 * @return 1078 */ 1079 public function readContainerSettings() 1080 { 1081 $this->setNewsTimeline(self::_lookupContainerSetting($this->getId(), "news_timeline")); 1082 $this->setNewsTimelineAutoEntries(self::_lookupContainerSetting($this->getId(), "news_timeline_incl_auto")); 1083 $this->setNewsTimelineLandingPage(self::_lookupContainerSetting($this->getId(), "news_timeline_landing_page")); 1084 include_once("./Services/Object/classes/class.ilObjectServiceSettingsGUI.php"); 1085 $this->setNewsBlockActivated(self::_lookupContainerSetting( 1086 $this->getId(), 1087 ilObjectServiceSettingsGUI::NEWS_VISIBILITY, 1088 $this->setting->get('block_activated_news', true) 1089 )); 1090 $this->setUseNews(self::_lookupContainerSetting($this->getId(), ilObjectServiceSettingsGUI::USE_NEWS, true)); 1091 } 1092 1093 1094 /** 1095 * overwrites description fields to long or short description in an assoc array 1096 * keys needed (obj_id and description) 1097 * 1098 * @param array $objects 1099 * @return array 1100 */ 1101 public static function getCompleteDescriptions(array $objects) 1102 { 1103 global $DIC; 1104 1105 $ilSetting = $DIC->settings(); 1106 $ilObjDataCache = $DIC["ilObjDataCache"]; 1107 // using long descriptions? 1108 $short_desc = $ilSetting->get("rep_shorten_description"); 1109 $short_desc_max_length = $ilSetting->get("rep_shorten_description_length"); 1110 if (!$short_desc || $short_desc_max_length != ilObject::DESC_LENGTH) { 1111 // using (part of) shortened description 1112 if ($short_desc && $short_desc_max_length && $short_desc_max_length < ilObject::DESC_LENGTH) { 1113 foreach ($objects as $key => $object) { 1114 $objects[$key]["description"] = ilUtil::shortenText($object["description"], $short_desc_max_length, true); 1115 } 1116 } 1117 // using (part of) long description 1118 else { 1119 $obj_ids = array(); 1120 foreach ($objects as $key => $object) { 1121 $obj_ids[] = $object["obj_id"]; 1122 } 1123 if (sizeof($obj_ids)) { 1124 $long_desc = ilObject::getLongDescriptions($obj_ids); 1125 foreach ($objects as $key => $object) { 1126 // #12166 - keep translation, ignore long description 1127 if ($ilObjDataCache->isTranslatedDescription($object["obj_id"])) { 1128 $long_desc[$object["obj_id"]] = $object["description"]; 1129 } 1130 if ($short_desc && $short_desc_max_length) { 1131 $long_desc[$object["obj_id"]] = ilUtil::shortenText($long_desc[$object["obj_id"]], $short_desc_max_length, true); 1132 } 1133 $objects[$key]["description"] = $long_desc[$object["obj_id"]]; 1134 } 1135 } 1136 } 1137 } 1138 return $objects; 1139 } 1140 1141 /** 1142 * Fix internal links after copy process 1143 * 1144 * @param int $a_target_id ref if of new container 1145 * @param int $a_copy_id copy process id 1146 */ 1147 protected static function fixInternalLinksAfterCopy($a_target_id, $a_copy_id, $a_source_ref_id) 1148 { 1149 global $DIC; 1150 1151 /** @var ilObjectDefinition $obj_definition */ 1152 $obj_definition = $DIC["objDefinition"]; 1153 1154 $obj_id = ilObject::_lookupObjId($a_target_id); 1155 include_once("./Services/Container/classes/class.ilContainerPage.php"); 1156 1157 include_once("./Services/CopyWizard/classes/class.ilCopyWizardOptions.php"); 1158 $cwo = ilCopyWizardOptions::_getInstance($a_copy_id); 1159 $mapping = $cwo->getMappings(); 1160 1161 if (ilContainerPage::_exists("cont", $obj_id)) { 1162 $pg = new ilContainerPage($obj_id); 1163 $pg->handleRepositoryLinksOnCopy($mapping, $a_source_ref_id); 1164 $pg->update(true, true); 1165 } 1166 1167 foreach ($mapping as $old_ref_id => $new_ref_id) { 1168 if (!is_numeric($old_ref_id) || !is_numeric($new_ref_id)) { 1169 continue; 1170 } 1171 1172 $type = ilObject::_lookupType($new_ref_id, true); 1173 $class = 'il' . $obj_definition->getClassName($type) . 'PageCollector'; 1174 $loc = $obj_definition->getLocation($type); 1175 $file = $loc . '/class.' . $class . '.php'; 1176 1177 if (is_file($file)) { 1178 /** @var ilCOPageCollectorInterface $coll */ 1179 $coll = new $class(); 1180 foreach ($coll->getAllPageIds(ilObject::_lookupObjId($new_ref_id)) as $page_id) { 1181 if (ilPageObject::_exists($page_id['parent_type'], $page_id['id'], $page_id['lang'])) { 1182 /** @var ilPageObject $page */ 1183 $page = ilPageObjectFactory::getInstance($page_id['parent_type'], $page_id['id'], 0, $page_id['lang']); 1184 $page->handleRepositoryLinksOnCopy($mapping, $a_source_ref_id); 1185 $page->update(true, true); 1186 } 1187 } 1188 } 1189 } 1190 } 1191 1192 /** 1193 * Remove all translations of container 1194 */ 1195 public function removeTranslations() 1196 { 1197 $this->obj_trans->delete(); 1198 } 1199 1200 /** 1201 * Delete translation 1202 * 1203 * @param $a_lang 1204 */ 1205 public function deleteTranslation($a_lang) 1206 { 1207 $this->obj_trans->removeLanguage($a_lang); 1208 $this->obj_trans->save(); 1209 } 1210 1211 /** 1212 * Add translation 1213 * 1214 * @param $a_title 1215 * @param $a_desc 1216 * @param $a_lang 1217 * @param $a_lang_default 1218 * @return bool 1219 */ 1220 public function addTranslation($a_title, $a_desc, $a_lang, $a_lang_default) 1221 { 1222 if (empty($a_title)) { 1223 $a_title = "NO TITLE"; 1224 } 1225 1226 $this->obj_trans->addLanguage($a_lang, $a_title, $a_desc, $a_lang_default, true); 1227 $this->obj_trans->save(); 1228 1229 return true; 1230 } 1231 1232 /** 1233 * Apply container user filter on objects 1234 * 1235 * @todo this deserces a decentralized general concept (consumers provide object filter types) 1236 * @todo move selects to respective components 1237 * 1238 * @param $objects 1239 * @param ilContainerUserFilter|null $container_user_filter 1240 * @return array 1241 * @throws ilException 1242 */ 1243 protected function applyContainerUserFilter($objects, ilContainerUserFilter $container_user_filter = null) 1244 { 1245 global $DIC; 1246 $db = $DIC->database(); 1247 1248 if (is_null($container_user_filter)) { 1249 return $objects; 1250 } 1251 1252 if ($container_user_filter->isEmpty() && !ilContainer::_lookupContainerSetting($this->getId(), "filter_show_empty", false)) { 1253 return []; 1254 } 1255 1256 1257 $obj_ids = array_map(function ($i) { 1258 return $i["obj_id"]; 1259 }, $objects); 1260 $filter_data = $container_user_filter->getData(); 1261 foreach ($filter_data as $key => $val) { 1262 if (count($obj_ids) == 0) { // stop if no object ids are left 1263 continue; 1264 } 1265 if (!in_array(substr($key, 0, 4), ["adv_", "std_"])) { 1266 continue; 1267 } 1268 if ($val == "") { 1269 continue; 1270 } 1271 $field_id = substr($key, 4); 1272 $val = ilUtil::stripSlashes($val); 1273 $query_parser = new ilQueryParser($val); 1274 if (substr($key, 0, 4) == "std_") { 1275 // object type 1276 if ($field_id == ilContainerFilterField::STD_FIELD_OBJECT_TYPE) { 1277 $result = null; 1278 $set = $db->queryF( 1279 "SELECT obj_id FROM object_data " . 1280 " WHERE " . $db->in("obj_id", $obj_ids, false, "integer") . 1281 " AND type = %s", 1282 array("text"), 1283 array($val) 1284 ); 1285 $result_obj_ids = []; 1286 while ($rec = $db->fetchAssoc($set)) { 1287 $result_obj_ids[] = $rec["obj_id"]; 1288 } 1289 $obj_ids = array_intersect($obj_ids, $result_obj_ids); 1290 } elseif ($field_id == ilContainerFilterField::STD_FIELD_ONLINE) { 1291 if (in_array($val, [1,2])) { 1292 $online_where = ($val == 1) 1293 ? " (offline <> " . $db->quote(1, "integer") . " OR offline IS NULL) " 1294 :" offline = " . $db->quote(1, "integer") . " "; 1295 $result = null; 1296 $set = $db->queryF( 1297 "SELECT obj_id FROM object_data " . 1298 " WHERE " . $db->in("obj_id", $obj_ids, false, "integer") . 1299 " AND " . $online_where, 1300 [], 1301 [] 1302 ); 1303 $result_obj_ids = []; 1304 while ($rec = $db->fetchAssoc($set)) { 1305 $result_obj_ids[] = $rec["obj_id"]; 1306 } 1307 $obj_ids = array_intersect($obj_ids, $result_obj_ids); 1308 $obj_ids = $this->legacyOnlineFilter($obj_ids, $objects, $val); 1309 } 1310 } elseif ($field_id == ilContainerFilterField::STD_FIELD_TUTORIAL_SUPPORT) { 1311 $result = null; 1312 $set = $db->queryF( 1313 "SELECT DISTINCT(obj_id) FROM obj_members m JOIN usr_data u ON (u.usr_id = m.usr_id) " . 1314 " WHERE " . $db->in("m.obj_id", $obj_ids, false, "integer") . 1315 " AND " . $db->like("u.lastname", "text", $val) . 1316 " AND m.contact = %s", 1317 array("integer"), 1318 array(1) 1319 ); 1320 $result_obj_ids = []; 1321 while ($rec = $db->fetchAssoc($set)) { 1322 $result_obj_ids[] = $rec["obj_id"]; 1323 } 1324 $obj_ids = array_intersect($obj_ids, $result_obj_ids); 1325 } elseif ($field_id == ilContainerFilterField::STD_FIELD_COPYRIGHT) { 1326 $result = null; 1327 $set = $db->queryF( 1328 "SELECT DISTINCT(rbac_id) FROM il_meta_rights " . 1329 " WHERE " . $db->in("rbac_id", $obj_ids, false, "integer") . 1330 " AND description = %s ", 1331 array("text"), 1332 array('il_copyright_entry__' . IL_INST_ID . '__' . $val) 1333 ); 1334 $result_obj_ids = []; 1335 while ($rec = $db->fetchAssoc($set)) { 1336 $result_obj_ids[] = $rec["rbac_id"]; 1337 } 1338 $obj_ids = array_intersect($obj_ids, $result_obj_ids); 1339 } else { 1340 include_once 'Services/Search/classes/class.ilObjectSearchFactory.php'; 1341 include_once 'Services/Search/classes/class.ilQueryParser.php'; 1342 1343 #$query_parser->setCombination($this->options['title_ao']); 1344 $query_parser->setCombination(QP_COMBINATION_OR); 1345 $query_parser->parse(); 1346 $meta_search = ilObjectSearchFactory::_getAdvancedSearchInstance($query_parser); 1347 1348 //$meta_search->setFilter($this->filter); // object types ['lm', ...] 1349 switch ($field_id) { 1350 case ilContainerFilterField::STD_FIELD_TITLE_DESCRIPTION: 1351 case ilContainerFilterField::STD_FIELD_DESCRIPTION: 1352 case ilContainerFilterField::STD_FIELD_TITLE: 1353 $meta_search->setMode('title_description'); 1354 break; 1355 case ilContainerFilterField::STD_FIELD_KEYWORD: 1356 $meta_search->setMode('keyword_all'); 1357 break; 1358 case ilContainerFilterField::STD_FIELD_AUTHOR: 1359 $meta_search->setMode('contribute'); 1360 break; 1361 1362 } 1363 //$meta_search->setOptions($this->options); 1364 $result = $meta_search->performSearch(); 1365 } 1366 } else { // advanced metadata search 1367 $field = ilAdvancedMDFieldDefinition::getInstance($field_id); 1368 1369 $field_form = ilADTFactory::getInstance()->getSearchBridgeForDefinitionInstance($field->getADTDefinition(), true, false); 1370 $field_form->setElementId("query[" . $key . "]"); 1371 $field_form->validate(); 1372 1373 /** 1374 * Workaround: 1375 * 1376 * Only text fields take care of $parser_value being passed through 1377 * new ilQueryParser($parser_value), thus other fields pass values by setting 1378 * directly in the ADT objects. This could go to a new bridge. 1379 */ 1380 if ($field instanceof ilAdvancedMDFieldDefinitionSelectMulti) { 1381 $field_form->getADT()->setSelections([$val]); 1382 } 1383 if ($field instanceof ilAdvancedMDFieldDefinitionSelect) { 1384 $adt = $field_form->getADT(); 1385 if ($adt instanceof ilADTMultiEnumText) { 1386 $field_form->getADT()->setSelections([$val]); 1387 } else { 1388 $field_form->getADT()->setSelection($val); 1389 } 1390 } 1391 1392 include_once 'Services/Search/classes/class.ilQueryParser.php'; 1393 include_once 'Services/Search/classes/class.ilObjectSearchFactory.php'; 1394 $adv_md_search = ilObjectSearchFactory::_getAdvancedMDSearchInstance($query_parser); 1395 //$adv_md_search->setFilter($this->filter); // this could be set to an array of object types 1396 $adv_md_search->setDefinition($field); // e.g. ilAdvancedMDFieldDefinitionSelectMulti 1397 $adv_md_search->setIdFilter(array(0)); 1398 $adv_md_search->setSearchElement($field_form); // e.g. ilADTEnumSearchBridgeMulti 1399 $result = $adv_md_search->performSearch(); 1400 } 1401 1402 // intersect results 1403 if ($result instanceof ilSearchResult) { 1404 $result_obj_ids = array_map( 1405 function ($i) { 1406 return $i["obj_id"]; 1407 }, 1408 $result->getEntries() 1409 ); 1410 $obj_ids = array_intersect($obj_ids, $result_obj_ids); 1411 } 1412 } 1413 $objects = array_filter($objects, function ($o) use ($obj_ids) { 1414 return in_array($o["obj_id"], $obj_ids); 1415 }); 1416 1417 return $objects; 1418 } 1419 1420 /** 1421 * Legacy online filter 1422 * 1423 * This can be removed, once all objects use the central online/offline property 1424 * 1425 * @param $obj_ids 1426 * @param $objects 1427 * @param $val 1428 * @return mixed 1429 */ 1430 protected function legacyOnlineFilter($obj_ids, $objects, $val) 1431 { 1432 $legacy_types = ["glo", "wiki", "qpl", "book", "dcl", "prtt"]; 1433 foreach ($legacy_types as $type) { 1434 $lobjects = array_filter($objects, function($o) use ($type) { 1435 return ($o["type"] == $type); 1436 }); 1437 $lobj_ids = array_map(function($i){ 1438 return $i["obj_id"]; 1439 }, $lobjects); 1440 switch($type) { 1441 case "glo": 1442 $status = ilObjGlossaryAccess::_lookupOnlineStatus($lobj_ids); 1443 break; 1444 case "wiki": 1445 $status = ilObjWikiAccess::_lookupOnlineStatus($lobj_ids); 1446 break; 1447 case "book": 1448 $status = ilObjBookingPoolAccess::_lookupOnlineStatus($lobj_ids); 1449 break; 1450 case "qpl": 1451 $status = []; 1452 foreach ($lobj_ids as $lid) { 1453 $status[$lid] = ilObjQuestionPoolAccess::isOnline($lid); 1454 } 1455 break; 1456 case "dcl": 1457 $status = []; 1458 foreach ($lobj_ids as $lid) { 1459 $status[$lid] = ilObjDataCollectionAccess::_lookupOnline($lid); 1460 } 1461 break; 1462 case "prtt": 1463 $status = ilObjPortfolioTemplateAccess::_lookupOnlineStatus($lobj_ids); 1464 break; 1465 } 1466 foreach($status as $obj_id => $online) { 1467 if ($val == 1 && !$online || $val == 2 && $online) { 1468 if (($key = array_search($obj_id, $obj_ids)) !== false) { 1469 unset($obj_ids[$key]); 1470 } 1471 } else if (!in_array($obj_id, $obj_ids)) { 1472 $obj_ids[] = $obj_id; 1473 } 1474 } 1475 } 1476 1477 return $obj_ids; 1478 } 1479 1480} // END class ilContainer 1481