1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5
6/**
7* Parent class of all container content GUIs.
8*
9* These classes are responsible for displaying the content, i.e. the
10* side column and main column and its subitems in container objects.
11*
12* @author Alex Killing <alex.killing@gmx.de>
13* @version $Id$
14*
15*/
16abstract class ilContainerContentGUI
17{
18    /**
19     * @var ilTemplate
20     */
21    protected $tpl;
22
23    /**
24     * @var ilCtrl
25     */
26    protected $ctrl;
27
28    /**
29     * @var ilObjUser
30     */
31    protected $user;
32
33    /**
34     * @var ilLanguage
35     */
36    protected $lng;
37
38    /**
39     * @var ilAccessHandler
40     */
41    protected $access;
42
43    /**
44     * @var ilPluginAdmin
45     */
46    protected $plugin_admin;
47
48    /**
49     * @var ilDB
50     */
51    protected $db;
52
53    /**
54     * @var ilRbacSystem
55     */
56    protected $rbacsystem;
57
58    /**
59     * @var ilSetting
60     */
61    protected $settings;
62
63    /**
64     * @var ilObjectDefinition
65     */
66    protected $obj_definition;
67
68    const DETAILS_DEACTIVATED = 0;
69    const DETAILS_TITLE = 1;
70    const DETAILS_ALL = 2;
71
72    const VIEW_MODE_LIST = 0;
73    const VIEW_MODE_TILE = 1;
74
75    protected $details_level = self::DETAILS_DEACTIVATED;
76
77    /**
78     * @var ilContainerRenderer
79     */
80    protected $renderer;
81
82    public $container_gui;
83    public $container_obj;
84
85    /**
86     * @var ilLogger
87     */
88    protected $log;
89
90    /**
91     * @var int
92     */
93    protected $view_mode;
94
95    /**
96    * Constructor
97    *
98    */
99    public function __construct(&$container_gui_obj)
100    {
101        global $DIC;
102
103        $this->tpl = $DIC["tpl"];
104        $this->ctrl = $DIC->ctrl();
105        $this->user = $DIC->user();
106        $this->lng = $DIC->language();
107        $this->access = $DIC->access();
108        $this->plugin_admin = $DIC["ilPluginAdmin"];
109        $this->db = $DIC->database();
110        $this->rbacsystem = $DIC->rbac()->system();
111        $this->settings = $DIC->settings();
112        $this->obj_definition = $DIC["objDefinition"];
113        $tpl = $DIC["tpl"];
114
115        $this->container_gui = $container_gui_obj;
116        $this->container_obj = $this->container_gui->object;
117
118        $tpl->addJavaScript("./Services/Container/js/Container.js");
119
120        $this->log = ilLoggerFactory::getLogger('cont');
121
122        $this->view_mode = (ilContainer::_lookupContainerSetting($this->container_obj->getId(), "list_presentation") == "tile" &&
123            !$this->container_gui->isActiveAdministrationPanel() &&
124            !$this->container_gui->isActiveOrdering())
125            ? self::VIEW_MODE_TILE
126            : self::VIEW_MODE_LIST;
127    }
128
129    /**
130     * Get view mode
131     */
132    protected function getViewMode()
133    {
134        return $this->view_mode;
135    }
136
137
138    /**
139     * get details level
140     *
141     * @access protected
142     * @param
143     * @return
144     */
145    protected function getDetailsLevel($a_item_id)
146    {
147        return $this->details_level;
148    }
149
150    /**
151    * Get container object.
152    *
153    * @return 	object		container object instance
154    */
155    public function getContainerObject()
156    {
157        return $this->container_obj;
158    }
159
160    /**
161    * Get container GUI object
162    *
163    * @return 	object		container GUI instance
164    */
165    public function getContainerGUI()
166    {
167        return $this->container_gui;
168    }
169
170    /**
171    * Sets view output into column layout
172    *
173    * This method sets the output of the right and main column
174    * in the global standard template.
175    */
176    public function setOutput()
177    {
178        $tpl = $this->tpl;
179        $ilCtrl = $this->ctrl;
180
181        // note: we do not want to get the center html in case of
182        // asynchronous calls to blocks in the right column (e.g. news)
183        // see #13012
184        if ($ilCtrl->getNextClass() == "ilcolumngui" &&
185            $ilCtrl->isAsynch()) {
186            $tpl->setRightContent($this->getRightColumnHTML());
187        }
188
189        // BEGIN ChangeEvent: record read event.
190        require_once('Services/Tracking/classes/class.ilChangeEvent.php');
191        $ilUser = $this->user;
192
193        $obj_id = ilObject::_lookupObjId($this->getContainerObject()->getRefId());
194        ilChangeEvent::_recordReadEvent(
195            $this->getContainerObject()->getType(),
196            $this->getContainerObject()->getRefId(),
197            $obj_id,
198            $ilUser->getId()
199        );
200        // END ChangeEvent: record read event.
201
202
203        $tpl->setContent($this->getCenterColumnHTML());
204
205        // see above, all other cases (this was the old position of setRightContent,
206        // maybe the position above is ok and all ifs can be removed)
207        if ($ilCtrl->getNextClass() != "ilcolumngui" ||
208            !$ilCtrl->isAsynch()) {
209            $tpl->setRightContent($this->getRightColumnHTML());
210        }
211    }
212
213    /**
214    * Get HTML for right column
215    */
216    protected function getRightColumnHTML()
217    {
218        $ilUser = $this->user;
219        $lng = $this->lng;
220        $ilCtrl = $this->ctrl;
221        $ilAccess = $this->access;
222        $ilPluginAdmin = $this->plugin_admin;
223
224        $ilCtrl->saveParameterByClass("ilcolumngui", "col_return");
225
226        $obj_id = ilObject::_lookupObjId($this->getContainerObject()->getRefId());
227        $obj_type = ilObject::_lookupType($obj_id);
228
229        include_once("Services/Block/classes/class.ilColumnGUI.php");
230        $column_gui = new ilColumnGUI($obj_type, IL_COL_RIGHT);
231
232        if ($column_gui->getScreenMode() == IL_SCREEN_FULL) {
233            return "";
234        }
235
236        $this->getContainerGUI()->setColumnSettings($column_gui);
237
238        if ($ilCtrl->getNextClass() == "ilcolumngui" &&
239            $column_gui->getCmdSide() == IL_COL_RIGHT &&
240            $column_gui->getScreenMode() == IL_SCREEN_SIDE) {
241            $html = $ilCtrl->forwardCommand($column_gui);
242        } else {
243            if (!$ilCtrl->isAsynch()) {
244                $html = "";
245
246                // user interface plugin slot + default rendering
247                include_once("./Services/UIComponent/classes/class.ilUIHookProcessor.php");
248                $uip = new ilUIHookProcessor(
249                    "Services/Container",
250                    "right_column",
251                    array("container_content_gui" => $this)
252                );
253                if (!$uip->replaced()) {
254                    $html = $ilCtrl->getHTML($column_gui);
255                }
256                $html = $uip->getHTML($html);
257            }
258        }
259
260        return $html;
261    }
262
263    /**
264    * Get HTML for center column
265    */
266    protected function getCenterColumnHTML()
267    {
268        $ilCtrl = $this->ctrl;
269        $tpl = $this->tpl;
270        $ilDB = $this->db;
271
272        $ilCtrl->saveParameterByClass("ilcolumngui", "col_return");
273
274        $tpl->addOnLoadCode("il.Object.setRedrawListItemUrl('" .
275            $ilCtrl->getLinkTarget($this->container_gui, "redrawListItem", "", true) . "');");
276
277        $tpl->addOnLoadCode("il.Object.setRatingUrl('" .
278            $ilCtrl->getLinkTargetByClass(
279                array(get_class($this->container_gui), "ilcommonactiondispatchergui", "ilratinggui"),
280                "saveRating",
281                "",
282                true,
283                false
284            ) . "');");
285
286        switch ($ilCtrl->getNextClass()) {
287            case "ilcolumngui":
288                $this->container_gui->setSideColumnReturn();
289                $html = $this->__forwardToColumnGUI();
290                break;
291
292            default:
293                $ilDB->useSlave(true);
294                $html = $this->getMainContent();
295                $ilDB->useSlave(false);
296                break;
297        }
298
299        return $html;
300    }
301
302    /**
303    * Get content HTML for main column, this one must be
304    * overwritten in derived classes.
305    */
306    abstract public function getMainContent();
307
308    /**
309     * Init container renderer
310     */
311    protected function initRenderer()
312    {
313        include_once('./Services/Container/classes/class.ilContainerSorting.php');
314        $sorting = ilContainerSorting::_getInstance($this->getContainerObject()->getId());
315
316        include_once "Services/Container/classes/class.ilContainerRenderer.php";
317        $this->renderer = new ilContainerRenderer(
318            ($this->getContainerGUI()->isActiveAdministrationPanel() && !$_SESSION["clipboard"]),
319            $this->getContainerGUI()->isMultiDownloadEnabled(),
320            $this->getContainerGUI()->isActiveOrdering() && (get_class($this) != "ilContainerObjectiveGUI") // no block sorting in objective view
321            ,
322            $sorting->getBlockPositions(),
323            $this->container_gui,
324            $this->getViewMode()
325        );
326    }
327
328    /**
329    * Get columngui output
330    */
331    final private function __forwardToColumnGUI()
332    {
333        $ilCtrl = $this->ctrl;
334        $ilAccess = $this->access;
335
336        include_once("Services/Block/classes/class.ilColumnGUI.php");
337
338        // this gets us the subitems we need in setColumnSettings()
339        // todo: this should be done in ilCourseGUI->getSubItems
340
341        $obj_id = ilObject::_lookupObjId($this->getContainerObject()->getRefId());
342        $obj_type = ilObject::_lookupType($obj_id);
343
344        if (!$ilCtrl->isAsynch()) {
345            //if ($column_gui->getScreenMode() != IL_SCREEN_SIDE)
346            if (ilColumnGUI::getScreenMode() != IL_SCREEN_SIDE) {
347                // right column wants center
348                if (ilColumnGUI::getCmdSide() == IL_COL_RIGHT) {
349                    $column_gui = new ilColumnGUI($obj_type, IL_COL_RIGHT);
350                    $this->getContainerGUI()->setColumnSettings($column_gui);
351                    $html = $ilCtrl->forwardCommand($column_gui);
352                }
353                // left column wants center
354                if (ilColumnGUI::getCmdSide() == IL_COL_LEFT) {
355                    $column_gui = new ilColumnGUI($obj_type, IL_COL_LEFT);
356                    $this->getContainerGUI()->setColumnSettings($column_gui);
357                    $html = $ilCtrl->forwardCommand($column_gui);
358                }
359            } else {
360                $html = $this->getMainContent();
361            }
362        }
363
364        return $html;
365    }
366
367    /**
368    * cleaer administration commands determination
369    */
370    protected function clearAdminCommandsDetermination()
371    {
372        $this->adminCommands = false;
373    }
374
375    /**
376    * determin admin commands
377    */
378    protected function determineAdminCommands($a_ref_id, $a_admin_com_included_in_list = false)
379    {
380        $rbacsystem = $this->rbacsystem;
381
382        //echo "-".$a_admin_com_included_in_list."-";
383
384        if (!$this->adminCommands) {
385            if (!$this->getContainerGUI()->isActiveAdministrationPanel()) {
386                if ($rbacsystem->checkAccess("delete", $a_ref_id)) {
387                    $this->adminCommands = true;
388                }
389            } else {
390                $this->adminCommands = $a_admin_com_included_in_list;
391            }
392        }
393    }
394
395    /**
396    * Get ListGUI object for item
397    */
398    protected function getItemGUI($item_data, $a_show_path = false)
399    {
400        include_once 'Services/Object/classes/class.ilObjectListGUIFactory.php';
401
402        // get item list gui object
403        if (!is_object($this->list_gui[$item_data["type"]])) {
404            $item_list_gui = &ilObjectListGUIFactory::_getListGUIByType($item_data["type"]);
405            $item_list_gui->setContainerObject($this->getContainerGUI());
406            $this->list_gui[$item_data["type"]] = &$item_list_gui;
407        } else {
408            $item_list_gui = &$this->list_gui[$item_data["type"]];
409        }
410
411        // unique js-ids
412        $item_list_gui->setParentRefId($item_data["parent"]);
413
414        $item_list_gui->setDefaultCommandParameters(array());
415        $item_list_gui->disableTitleLink(false);
416        $item_list_gui->resetConditionTarget();
417
418        // show administration command buttons (or not)
419        if (!$this->getContainerGUI()->isActiveAdministrationPanel()) {
420            //			$item_list_gui->enableDelete(false);
421//			$item_list_gui->enableLink(false);
422//			$item_list_gui->enableCut(false);
423        }
424
425        // activate common social commands
426        $item_list_gui->enableComments(true);
427        $item_list_gui->enableNotes(true);
428        $item_list_gui->enableTags(true);
429        $item_list_gui->enableRating(true);
430
431        // reset
432        $item_list_gui->forceVisibleOnly(false);
433
434        // container specific modifications
435        $this->getContainerGUI()->modifyItemGUI($item_list_gui, $item_data, $a_show_path);
436
437        return $item_list_gui;
438    }
439
440    /**
441    * Determine all blocks that are embedded in the container page
442    */
443    public function determinePageEmbeddedBlocks($a_container_page_html)
444    {
445        $type_grps = $this->getGroupedObjTypes();
446
447        // iterate all types
448        foreach ($type_grps as $type => $v) {
449            // set template (overall or type specific)
450            if (is_int(strpos($a_container_page_html, "[list-" . $type . "]"))) {
451                $this->addEmbeddedBlock("type", $type);
452            }
453        }
454
455        // determine item groups
456        while (preg_match('~\[(item-group-([0-9]*))\]~i', $a_container_page_html, $found)) {
457            $this->addEmbeddedBlock("itgr", (int) $found[2]);
458
459            $a_container_page_html = preg_replace('~\[' . $found[1] . '\]~i', $html, $a_container_page_html);
460        }
461    }
462
463    /**
464    * Add embedded block
465    *
466    * @param
467    */
468    public function addEmbeddedBlock($block_type, $block_parameter)
469    {
470        $this->embedded_block[$block_type][] = $block_parameter;
471    }
472
473    /**
474    * Get page embedded blocks
475    */
476    public function getEmbeddedBlocks()
477    {
478        return $this->embedded_block;
479    }
480
481    /**
482    * Render Page Embedded Blocks
483    */
484    public function renderPageEmbeddedBlocks()
485    {
486        $lng = $this->lng;
487
488        // item groups
489        if (is_array($this->embedded_block["itgr"])) {
490            $item_groups = array();
491            if (is_array($this->items["itgr"])) {
492                foreach ($this->items["itgr"] as $ig) {
493                    $item_groups[$ig["ref_id"]] = $ig;
494                }
495            }
496
497            foreach ($this->embedded_block["itgr"] as $ref_id) {
498                if (isset($item_groups[$ref_id])) {
499                    $this->renderItemGroup($item_groups[$ref_id]);
500                }
501            }
502        }
503
504        // type specific blocks
505        if (is_array($this->embedded_block["type"])) {
506            foreach ($this->embedded_block["type"] as $k => $type) {
507                if (is_array($this->items[$type]) &&
508                    $this->renderer->addTypeBlock($type)) {
509                    // :TODO: obsolete?
510                    if ($type == 'sess') {
511                        $this->items['sess'] = ilUtil::sortArray($this->items['sess'], 'start', 'ASC', true, true);
512                    }
513
514                    $position = 1;
515
516                    foreach ($this->items[$type] as $k => $item_data) {
517                        if (!$this->renderer->hasItem($item_data["child"])) {
518                            $html = $this->renderItem($item_data, $position++);
519                            if ($html != "") {
520                                $this->renderer->addItemToBlock($type, $item_data["type"], $item_data["child"], $html);
521                            }
522                        }
523                    }
524                }
525            }
526        }
527    }
528
529    /**
530     * Render an item
531     * @param $a_item_data
532     * @param int $a_position
533     * @param bool $a_force_icon
534     * @param string $a_pos_prefix
535     * @return string
536     */
537    public function renderItem($a_item_data, $a_position = 0, $a_force_icon = false, $a_pos_prefix = "")
538    {
539        $ilSetting = $this->settings;
540        $ilAccess = $this->access;
541        $ilCtrl = $this->ctrl;
542
543        // Pass type, obj_id and tree to checkAccess method to improve performance
544        if (!$ilAccess->checkAccess('visible', '', $a_item_data['ref_id'], $a_item_data['type'], $a_item_data['obj_id'], $a_item_data['tree'])) {
545            return '';
546        }
547
548        if ($this->getViewMode() == self::VIEW_MODE_TILE) {
549            return $this->renderCard($a_item_data, $a_position, $a_force_icon, $a_pos_prefix);
550        }
551
552        $item_list_gui = $this->getItemGUI($a_item_data);
553        if ($ilSetting->get("icon_position_in_lists") == "item_rows" ||
554            $a_item_data["type"] == "sess" || $a_force_icon) {
555            $item_list_gui->enableIcon(true);
556        }
557
558        if ($this->getContainerGUI()->isActiveAdministrationPanel() && !$_SESSION["clipboard"]) {
559            $item_list_gui->enableCheckbox(true);
560        } elseif ($this->getContainerGUI()->isMultiDownloadEnabled()) {
561            // display multi download checkboxes
562            $item_list_gui->enableDownloadCheckbox($a_item_data["ref_id"], true);
563        }
564
565        if ($this->getContainerGUI()->isActiveItemOrdering() && ($a_item_data['type'] != 'sess' || get_class($this) != 'ilContainerSessionsContentGUI')) {
566            $item_list_gui->setPositionInputField(
567                $a_pos_prefix . "[" . $a_item_data["ref_id"] . "]",
568                sprintf('%d', (int) $a_position * 10)
569            );
570        }
571
572        if ($a_item_data['type'] == 'sess' and get_class($this) != 'ilContainerObjectiveGUI') {
573            switch ($this->getDetailsLevel($a_item_data['obj_id'])) {
574                case self::DETAILS_TITLE:
575                    $item_list_gui->setDetailsLevel(ilObjectListGUI::DETAILS_MINIMAL);
576                    $item_list_gui->enableExpand(true);
577                    $item_list_gui->setExpanded(false);
578                    $item_list_gui->enableDescription(false);
579                    $item_list_gui->enableProperties(true);
580                    break;
581
582                case self::DETAILS_ALL:
583                    $item_list_gui->setDetailsLevel(ilObjectListGUI::DETAILS_ALL);
584                    $item_list_gui->enableExpand(true);
585                    $item_list_gui->setExpanded(true);
586                    $item_list_gui->enableDescription(true);
587                    $item_list_gui->enableProperties(true);
588                    break;
589
590                default:
591                    $item_list_gui->setDetailsLevel(ilObjectListGUI::DETAILS_ALL);
592                    $item_list_gui->enableExpand(true);
593                    $item_list_gui->enableDescription(true);
594                    $item_list_gui->enableProperties(true);
595                    break;
596            }
597        }
598
599        if (method_exists($this, "addItemDetails")) {
600            $this->addItemDetails($item_list_gui, $a_item_data);
601        }
602
603        // show subitems
604        if ($a_item_data['type'] == 'sess' and (
605                                            $this->getDetailsLevel($a_item_data['obj_id']) != self::DETAILS_TITLE or
606                                            $this->getContainerGUI()->isActiveAdministrationPanel() or
607                                            $this->getContainerGUI()->isActiveItemOrdering()
608                                            )
609        ) {
610            $pos = 1;
611
612            include_once('./Services/Container/classes/class.ilContainerSorting.php');
613            include_once('./Services/Object/classes/class.ilObjectActivation.php');
614            $items = ilObjectActivation::getItemsByEvent($a_item_data['obj_id']);
615            $items = ilContainerSorting::_getInstance($this->getContainerObject()->getId())->sortSubItems('sess', $a_item_data['obj_id'], $items);
616            $items = ilContainer::getCompleteDescriptions($items);
617
618            $item_readable = $ilAccess->checkAccess('read', '', $a_item_data['ref_id']);
619
620            foreach ($items as $item) {
621                // TODO: this should be removed and be handled by if(strlen($sub_item_html))
622                // 	see mantis: 0003944
623                if (!$ilAccess->checkAccess('visible', '', $item['ref_id'])) {
624                    continue;
625                }
626
627                $item_list_gui2 = $this->getItemGUI($item);
628                $item_list_gui2->enableIcon(true);
629                $item_list_gui2->enableItemDetailLinks(false);
630
631                // unique js-ids
632                $item_list_gui2->setParentRefId($a_item_data['ref_id']);
633
634                // @see mantis 10488
635                if (!$item_readable and !$ilAccess->checkAccess('write', '', $item['ref_id'])) {
636                    $item_list_gui2->forceVisibleOnly(true);
637                }
638
639                if ($this->getContainerGUI()->isActiveAdministrationPanel() && !$_SESSION["clipboard"]) {
640                    $item_list_gui2->enableCheckbox(true);
641                } elseif ($this->getContainerGUI()->isMultiDownloadEnabled()) {
642                    // display multi download checkbox
643                    $item_list_gui2->enableDownloadCheckbox($item['ref_id'], true);
644                }
645
646                if ($this->getContainerGUI()->isActiveItemOrdering()) {
647                    $item_list_gui2->setPositionInputField(
648                        "[sess][" . $a_item_data['obj_id'] . "][" . $item["ref_id"] . "]",
649                        sprintf('%d', (int) $pos * 10)
650                    );
651                    $pos++;
652                }
653
654                // #10611
655                ilObjectActivation::addListGUIActivationProperty($item_list_gui2, $item);
656
657                $sub_item_html = $item_list_gui2->getListItemHTML(
658                    $item['ref_id'],
659                    $item['obj_id'],
660                    $item['title'],
661                    $item['description']
662                );
663
664                $this->determineAdminCommands($item["ref_id"], $item_list_gui2->adminCommandsIncluded());
665                if (strlen($sub_item_html)) {
666                    $item_list_gui->addSubItemHTML($sub_item_html);
667                }
668            }
669        }
670
671
672        if ($ilSetting->get("item_cmd_asynch")) {
673            $asynch = true;
674            $ilCtrl->setParameter($this->container_gui, "cmdrefid", $a_item_data['ref_id']);
675            $asynch_url = $ilCtrl->getLinkTarget(
676                $this->container_gui,
677                "getAsynchItemList",
678                "",
679                true,
680                false
681            );
682            $ilCtrl->setParameter($this->container_gui, "cmdrefid", "");
683
684            //#0020343
685            $fold_set = new ilSetting('fold');
686            if ($a_item_data['type'] == 'fold' && $fold_set->get("bgtask_download") && $fold_set->get("enable_download_folder")) {
687                include_once "Services/BackgroundTask/classes/class.ilFolderDownloadBackgroundTaskHandler.php";
688                ilFolderDownloadBackgroundTaskHandler::initObjectListAction();
689            }
690        }
691
692        include_once "Services/Object/classes/class.ilObjectActivation.php";
693        ilObjectActivation::addListGUIActivationProperty($item_list_gui, $a_item_data);
694
695        $html = $item_list_gui->getListItemHTML(
696            $a_item_data['ref_id'],
697            $a_item_data['obj_id'],
698            $a_item_data['title'],
699            $a_item_data['description'],
700            $asynch,
701            false,
702            $asynch_url
703        );
704        $this->determineAdminCommands(
705            $a_item_data["ref_id"],
706            $item_list_gui->adminCommandsIncluded()
707        );
708
709
710        return $html;
711    }
712
713    /**
714     * Render card
715     * @param $a_item_data
716     * @param int $a_position
717     * @param bool $a_force_icon
718     * @param string $a_pos_prefix
719     * @return string
720     */
721    public function renderCard($a_item_data, $a_position = 0, $a_force_icon = false, $a_pos_prefix = "")
722    {
723        global $DIC;
724        $f = $DIC->ui()->factory();
725        $r = $DIC->ui()->renderer();
726        $user = $DIC->user();
727        $access = $DIC->access();
728
729        $item_list_gui = $this->getItemGUI($a_item_data);
730        $item_list_gui->setAjaxHash(ilCommonActionDispatcherGUI::buildAjaxHash(
731            ilCommonActionDispatcherGUI::TYPE_REPOSITORY,
732            $a_item_data['ref_id'],
733            $a_item_data['type'],
734            $a_item_data['obj_id']
735        ));
736        $item_list_gui->initItem(
737            $a_item_data['ref_id'],
738            $a_item_data['obj_id'],
739            $a_item_data['title'],
740            $a_item_data['description']
741        );
742
743        // actions
744        $item_list_gui->insertCommands();
745        $actions = [];
746        foreach ($item_list_gui->current_selection_list->getItems() as $item) {
747            if (!isset($item["onclick"]) || $item["onclick"] == "") {
748                $button =
749                    $f->button()->shy($item["title"], $item["link"]);
750            } else {
751                $button =
752                    $f->button()->shy($item["title"], "")->withAdditionalOnLoadCode(function ($id) use ($item) {
753                        return
754                            "$('#$id').click(function(e) { " . $item["onclick"] . "});";
755                    });
756            }
757            $actions[] = $button;
758        }
759
760
761        $def_command = $item_list_gui->getDefaultCommand();
762        $dropdown = $f->dropdown()->standard($actions);
763
764        $img = $DIC->object()->commonSettings()->tileImage()->getByObjId($a_item_data['obj_id']);
765
766        if ($img->exists()) {
767            $path = $img->getFullPath();
768        } else {
769            $path = ilUtil::getImagePath("cont_tile/cont_tile_default_" . $a_item_data['type'] . ".svg");
770            if (!is_file($path)) {
771                $path = ilUtil::getImagePath("cont_tile/cont_tile_default.svg");
772            }
773        }
774
775        $sections = [];
776        $title = $a_item_data["title"];
777
778        // workaround for scorm
779        $modified_link =
780            $item_list_gui->modifySAHSlaunch($def_command["link"], $def_command["frame"]);
781
782        // workaround for #26205
783        // we should get rid of _top links completely and gifure our how
784        // to manage scorm links better
785        if ($def_command["frame"] == "_top") {
786            $def_command["frame"] = "";
787        }
788
789        $image = $f->image()->responsive($path, "");
790        if ($def_command["link"] != "") {	// #24256
791            if ($def_command["frame"] != "" && ($modified_link == $def_command["link"])) {
792                $image = $image->withAdditionalOnLoadCode(function ($id) use ($def_command) {
793                    return
794                        "$('#$id').click(function(e) { window.open('" . str_replace("&amp;", "&", $def_command["link"]) . "', '" . $def_command["frame"] . "');});";
795                });
796
797                $button =
798                    $f->button()->shy($title, "")->withAdditionalOnLoadCode(function ($id) use ($def_command) {
799                        return
800                            "$('#$id').click(function(e) { window.open('" . str_replace("&amp;", "&", $def_command["link"]) . "', '" . $def_command["frame"] . "');});";
801                    });
802                $title = $r->render($button);
803            } else {
804                $image = $image->withAction($modified_link);
805            }
806        }
807
808        // description, @todo: move to new ks element
809        if ($a_item_data["description"] != "") {
810            $sections[] = $f->legacy("<div class='il_info il-multi-line-cap-3'>" . $a_item_data["description"] . "</div>");
811        }
812
813        if ($a_item_data["type"] == "sess") {
814            $app_info = ilSessionAppointment::_lookupAppointment($a_item_data['obj_id']);
815            if ($title != "") {
816                $title = ": " . $title;
817            }
818            $title = ilSessionAppointment::_appointmentToString($app_info['start'], $app_info['end'], $app_info['fullday']) .
819                $title;
820        }
821
822        $icon = $f->icon()->standard($a_item_data["type"], $this->lng->txt("obj_" . $a_item_data["type"]))
823            ->withIsOutlined(true);
824
825        // card title action
826        $card_title_action = "";
827        if ($def_command["link"] != "" && ($def_command["frame"] == "" || $modified_link != $def_command["link"])) {	// #24256
828            $card_title_action = $modified_link;
829        } else if ($def_command['link'] == "" &&
830            $item_list_gui->getInfoScreenStatus() &&
831            $access->checkAccessOfUser(
832                $user->getId(),
833                "visible",
834                "",
835                $a_item_data["ref_id"]
836            )) {
837            $card_title_action = ilLink::_getLink($a_item_data["ref_id"]);
838            if ($image->getAction() == "") {
839                $image = $image->withAction($card_title_action);
840            }
841        }
842
843
844        $card = $f->card()->repositoryObject(
845            $title . "<span data-list-item-id='" . $item_list_gui->getUniqueItemId(true) . "'></span>",
846            $image
847        )->withObjectIcon(
848            $icon
849        )->withActions(
850            $dropdown
851        );
852
853        if ($card_title_action != "") {
854            $card = $card->withTitleAction($card_title_action);
855        }
856
857        // properties
858        $l = [];
859        foreach ($item_list_gui->determineProperties() as $p) {
860            if ($p["alert"] && $p["property"] != $this->lng->txt("learning_progress")) {
861                $l[(string) $p["property"]] = (string) $p["value"];
862            }
863        }
864
865        if (count($l) > 0) {
866            $prop_list = $f->listing()->descriptive($l);
867            $sections[] = $prop_list;
868        }
869        if (count($sections) > 0) {
870            $card = $card->withSections($sections);
871        }
872        // learning progress
873        include_once "Services/Tracking/classes/class.ilLPStatus.php";
874        $lp = ilLPStatus::getListGUIStatus($a_item_data["obj_id"], false);
875        if ($lp) {
876            $percentage = (int) ilLPStatus::_lookupPercentage($a_item_data["obj_id"], $user->getId());
877            if ($lp["status"] == ilLPStatus::LP_STATUS_COMPLETED_NUM) {
878                $percentage = 100;
879            }
880            //var_dump(ilLPStatus::_lookupPercentage($a_item_data["obj_id"], $user->getId())); exit;
881            $progressmeter = $f->chart()->progressMeter()->mini(100, $percentage);
882            $card = $card->withProgress($progressmeter);
883        }
884
885        return $card;
886    }
887
888    /**
889    * Insert blocks into container page
890    */
891    public function insertPageEmbeddedBlocks($a_output_html)
892    {
893        $this->determinePageEmbeddedBlocks($a_output_html);
894        $this->renderPageEmbeddedBlocks($this->items);
895
896        // iterate all types
897        foreach ($this->getGroupedObjTypes() as $type => $v) {
898            // set template (overall or type specific)
899            if (is_int(strpos($a_output_html, "[list-" . $type . "]"))) {
900                $a_output_html = preg_replace(
901                    '~\[list-' . $type . '\]~i',
902                    $this->renderer->renderSingleTypeBlock($type),
903                    $a_output_html
904                );
905            }
906        }
907
908        // insert all item groups
909        while (preg_match('~\[(item-group-([0-9]*))\]~i', $a_output_html, $found)) {
910            $itgr_ref_id = (int) $found[2];
911
912            $a_output_html = preg_replace(
913                '~\[' . $found[1] . '\]~i',
914                $this->renderer->renderSingleCustomBlock($itgr_ref_id),
915                $a_output_html
916            );
917        }
918
919        return $a_output_html;
920    }
921
922    /**
923     * Render single block
924     *
925     * @param string block id
926     * @return string
927     */
928    public function getSingleTypeBlockAsynch($type)
929    {
930        $this->initRenderer();
931        // get all sub items
932        $this->items = $this->getContainerObject()->getSubItems(
933            $this->getContainerGUI()->isActiveAdministrationPanel()
934        );
935
936
937        $ref_ids = array_map(function ($i) {
938            $parts = explode("_", $i);
939            return $parts[2];
940        }, $_POST["ids"]);
941
942        // iterate all types
943        if (is_array($this->items[$type]) &&
944            $this->renderer->addTypeBlock($type)) {
945            //$this->renderer->setBlockPosition($type, ++$pos);
946
947            $position = 1;
948            foreach ($this->items[$type] as $item_data) {
949                $item_ref_id = $item_data["child"];
950
951                if (in_array($item_ref_id, $ref_ids)) {
952                    continue;
953                }
954
955                if ($this->block_limit > 0 && $position == $this->block_limit + 1) {
956                    if ($position == $this->block_limit + 1) {
957                        // render more button
958                        $this->renderer->addShowMoreButton($type);
959                    }
960                    continue;
961                }
962
963                if (!$this->renderer->hasItem($item_ref_id)) {
964                    $html = $this->renderItem($item_data, $position++);
965                    if ($html != "") {
966                        $this->renderer->addItemToBlock($type, $item_data["type"], $item_ref_id, $html);
967                    }
968                }
969            }
970        }
971
972        return $this->renderer->renderSingleTypeBlock($type);
973    }
974
975    /**
976    * Get grouped repository object types.
977    *
978    * @return	array	array of object types
979    */
980    public function getGroupedObjTypes()
981    {
982        $objDefinition = $this->obj_definition;
983
984        if (empty($this->type_grps)) {
985            $this->type_grps =
986                $objDefinition->getGroupedRepositoryObjectTypes($this->getContainerObject()->getType());
987        }
988        return $this->type_grps;
989    }
990
991    /**
992    * Get introduction.
993    */
994    public function getIntroduction()
995    {
996        $ilUser = $this->user;
997        $lng = $this->lng;
998        $ilCtrl = $this->ctrl;
999
1000        $lng->loadLanguageModule("rep");
1001
1002        $tpl = new ilTemplate("tpl.rep_intro.html", true, true, "Services/Repository");
1003        $tpl->setVariable("IMG_REP_LARGE", ilObject::_getIcon("", "big", "root"));
1004        $tpl->setVariable("TXT_WELCOME", $lng->txt("rep_intro"));
1005        $tpl->setVariable("TXT_INTRO_1", $lng->txt("rep_intro1"));
1006        $tpl->setVariable("TXT_INTRO_2", $lng->txt("rep_intro2"));
1007        $tpl->setVariable("TXT_INTRO_3", sprintf($lng->txt("rep_intro3"), $lng->txt("add")));
1008        $tpl->setVariable("TXT_INTRO_4", sprintf($lng->txt("rep_intro4"), $lng->txt("cat_add")));
1009        $tpl->setVariable("TXT_INTRO_5", $lng->txt("rep_intro5"));
1010        $tpl->setVariable("TXT_INTRO_6", $lng->txt("rep_intro6"));
1011
1012        return $tpl->get();
1013    }
1014
1015    /**
1016     * Get item groups HTML
1017     *
1018     * @param
1019     * @return
1020     */
1021    public function getItemGroupsHTML($a_pos = 0)
1022    {
1023        if (is_array($this->items["itgr"])) {
1024            foreach ($this->items["itgr"] as $itgr) {
1025                if (!$this->renderer->hasCustomBlock($itgr["child"])) {
1026                    $this->renderItemGroup($itgr);
1027
1028                    $this->renderer->setBlockPosition($itgr["ref_id"], ++$a_pos);
1029                }
1030            }
1031        }
1032        return $a_pos;
1033    }
1034
1035    /**
1036     * Render item group
1037     *
1038     * @param
1039     * @return
1040     */
1041    public function renderItemGroup($a_itgr)
1042    {
1043        $ilAccess = $this->access;
1044        $ilUser = $this->user;
1045
1046        // #16493
1047        $perm_ok = ($ilAccess->checkAccess("visible", "", $a_itgr['ref_id']) &&
1048             $ilAccess->checkAccess("read", "", $a_itgr['ref_id']));
1049
1050        include_once('./Services/Container/classes/class.ilContainerSorting.php');
1051        include_once('./Services/Object/classes/class.ilObjectActivation.php');
1052        $items = ilObjectActivation::getItemsByItemGroup($a_itgr['ref_id']);
1053
1054        // if no permission is given, set the items to "rendered" but
1055        // do not display the whole block
1056        if (!$perm_ok) {
1057            foreach ($items as $item) {
1058                $this->renderer->hideItem($item["child"]);
1059            }
1060            return;
1061        }
1062
1063        $item_list_gui = $this->getItemGUI($a_itgr);
1064        $item_list_gui->enableNotes(false);
1065        $item_list_gui->enableTags(false);
1066        $item_list_gui->enableComments(false);
1067        $item_list_gui->enableTimings(false);
1068        $item_list_gui->getListItemHTML(
1069            $a_itgr["ref_id"],
1070            $a_itgr["obj_id"],
1071            $a_itgr["title"],
1072            $a_itgr["description"]
1073        );
1074        $commands_html = $item_list_gui->getCommandsHTML();
1075
1076        // determine behaviour
1077        include_once("./Modules/ItemGroup/classes/class.ilObjItemGroup.php");
1078        include_once("./Modules/ItemGroup/classes/class.ilItemGroupBehaviour.php");
1079        $beh = ilObjItemGroup::lookupBehaviour($a_itgr["obj_id"]);
1080        include_once("./Services/Container/classes/class.ilContainerBlockPropertiesStorage.php");
1081        $stored_val = ilContainerBlockPropertiesStorage::getProperty("itgr_" . $a_itgr["ref_id"], $ilUser->getId(), "opened");
1082        if ($stored_val !== false && $beh != ilItemGroupBehaviour::ALWAYS_OPEN) {
1083            $beh = ($stored_val == "1")
1084                ? ilItemGroupBehaviour::EXPANDABLE_OPEN
1085                : ilItemGroupBehaviour::EXPANDABLE_CLOSED;
1086        }
1087
1088        $data = array(
1089            "behaviour" => $beh,
1090            "store-url" => "./ilias.php?baseClass=ilcontainerblockpropertiesstorage&cmd=store" .
1091                "&cont_block_id=itgr_" . $a_itgr['ref_id']
1092        );
1093        if (ilObjItemGroup::lookupHideTitle($a_itgr["obj_id"]) &&
1094            !$this->getContainerGUI()->isActiveAdministrationPanel()) {
1095            $this->renderer->addCustomBlock($a_itgr["ref_id"], "", $commands_html, $data);
1096        } else {
1097            $this->renderer->addCustomBlock($a_itgr["ref_id"], $a_itgr["title"], $commands_html, $data);
1098        }
1099
1100
1101        // render item group sub items
1102
1103        $items = ilContainerSorting::_getInstance(
1104            $this->getContainerObject()->getId()
1105        )->sortSubItems('itgr', $a_itgr['obj_id'], $items);
1106
1107        // #18285
1108        $items = ilContainer::getCompleteDescriptions($items);
1109
1110        $position = 1;
1111        foreach ($items as $item) {
1112            // we are NOT using hasItem() here, because item might be in multiple item groups
1113            $html2 = $this->renderItem($item, $position++, false, "[itgr][" . $a_itgr['obj_id'] . "]");
1114            if ($html2 != "") {
1115                // :TODO: show it multiple times?
1116                $this->renderer->addItemToBlock($a_itgr["ref_id"], $item["type"], $item["child"], $html2, true);
1117            }
1118        }
1119    }
1120}
1121