1<?php namespace ILIAS\MainMenu\Provider;
2
3use ILIAS\DI\Container;
4use ILIAS\GlobalScreen\Helper\BasicAccessCheckClosures;
5use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Information\TypeInformation;
6use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Information\TypeInformationCollection;
7use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\ComplexItemRenderer;
8use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\LinkListItemRenderer;
9use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\LostItemRenderer;
10use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\SeparatorItemRenderer;
11use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\TopParentItemRenderer;
12use ILIAS\GlobalScreen\Scope\MainMenu\Factory\hasAction;
13use ILIAS\GlobalScreen\Scope\MainMenu\Factory\hasTitle;
14use ILIAS\GlobalScreen\Scope\MainMenu\Factory\isChild;
15use ILIAS\GlobalScreen\Scope\MainMenu\Factory\isItem;
16use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Complex;
17use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Link;
18use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\LinkList;
19use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Lost;
20use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\RepositoryLink;
21use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Separator;
22use ILIAS\GlobalScreen\Scope\MainMenu\Factory\TopItem\TopLinkItem;
23use ILIAS\GlobalScreen\Scope\MainMenu\Factory\TopItem\TopParentItem;
24use ILIAS\GlobalScreen\Scope\MainMenu\Provider\AbstractStaticMainMenuProvider;
25use ILIAS\GlobalScreen\Scope\MainMenu\Provider\StaticMainMenuProvider;
26use ILIAS\UI\Component\Component;
27use ILIAS\UI\Component\JavaScriptBindable;
28use ilMMCustomItemStorage;
29use ilMMItemStorage;
30use ilMMTypeHandlerLink;
31use ilMMTypeHandlerRepositoryLink;
32use ilMMTypeHandlerSeparator;
33use ilMMTypeHandlerTopLink;
34
35/**
36 * Class CustomMainBarProvider
37 *
38 * @author Fabian Schmid <fs@studer-raimann.ch>
39 */
40class CustomMainBarProvider extends AbstractStaticMainMenuProvider implements StaticMainMenuProvider
41{
42
43    /**
44     * @var BasicAccessCheckClosures
45     */
46    private $access_helper;
47    /**
48     * @var \ILIAS\DI\Container
49     */
50    protected $dic;
51
52
53    /**
54     * @inheritDoc
55     */
56    public function __construct(Container $dic)
57    {
58        parent::__construct($dic);
59        $this->access_helper = BasicAccessCheckClosures::getInstance();
60    }
61
62
63    /**
64     * @return TopParentItem[]
65     */
66    public function getStaticTopItems() : array
67    {
68        /**
69         * @var $item ilMMCustomItemStorage
70         */
71        $top_items = [];
72        foreach (ilMMCustomItemStorage::where(['top_item' => true])->get() as $item) {
73            $top_items[] = $this->getSingleCustomItem($item, true);
74        }
75
76        return $top_items;
77    }
78
79
80    /**
81     * @return isItem[]
82     */
83    public function getStaticSubItems() : array
84    {
85        /**
86         * @var $item ilMMCustomItemStorage
87         */
88        $items = [];
89        foreach (ilMMCustomItemStorage::where(['top_item' => false])->get() as $item) {
90            $items[] = $this->getSingleCustomItem($item, true);
91        }
92
93        return $items;
94    }
95
96
97    /**
98     * @param ilMMCustomItemStorage $storage
99     * @param bool                  $register
100     *
101     * @return isItem
102     */
103    public function getSingleCustomItem(ilMMCustomItemStorage $storage, $register = false) : isItem
104    {
105        $identification = $this->globalScreen()->identification()->core($this)->identifier($storage->getIdentifier());
106
107        $item = $this->globalScreen()->mainBar()->custom($storage->getType(), $identification);
108
109        // See https://mantis.ilias.de/view.php?id=30743
110        if ($item instanceof Link || $item instanceof TopLinkItem) {
111            $item = $item->withVisibilityCallable(function () {
112                $active = $this->access_helper->isPublicSectionActive();
113                if ($active()) {
114                    return true;
115                }
116
117                return $this->access_helper->isUserLoggedIn()();
118            });
119        }
120
121        if ($item instanceof hasTitle && $storage->getDefaultTitle() !== '') {
122            $item = $item->withTitle($storage->getDefaultTitle());
123        }
124        if ($item instanceof hasAction) {
125            $item = $item->withAction("#");
126            // always close MainBar when a link has been clicked
127            $item = $item->addComponentDecorator(static function (Component $c) : Component {
128                if ($c instanceof JavaScriptBindable) {
129                    return $c->withAdditionalOnLoadCode(function ($id) {
130                        return "$('#$id').click(function() { il.UI.maincontrols.mainbar.disengageAll();})";
131                    });
132                }
133            });
134        }
135        if ($item instanceof isChild) {
136            $mm_item = ilMMItemStorage::find($identification->serialize());
137            $parent_identification = '';
138            if ($mm_item instanceof ilMMItemStorage) {
139                $parent_identification = $mm_item->getParentIdentification();
140            }
141
142            if ($parent_identification) {
143                $item = $item->withParent(
144                    $this->globalScreen()
145                        ->identification()
146                        ->fromSerializedIdentification($parent_identification)
147                );
148            }
149        }
150
151        if ($register) {
152            ilMMItemStorage::register($item);
153        }
154
155        return $item;
156    }
157
158
159    /**
160     * @inheritDoc
161     */
162    public function provideTypeInformation() : TypeInformationCollection
163    {
164        $c = new TypeInformationCollection();
165        // TopParentItem
166        $c->add(new TypeInformation(
167                TopParentItem::class,
168                $this->translateType(TopParentItem::class),
169                new TopParentItemRenderer())
170        );
171        // TopLinkItem
172        $c->add(new TypeInformation(
173                TopLinkItem::class,
174                $this->translateType(TopLinkItem::class),
175                new \ilMMTopLinkItemRenderer(),
176                new ilMMTypeHandlerTopLink())
177        );
178        // Link
179        $c->add(new TypeInformation(
180                Link::class,
181                $this->translateType(Link::class),
182                new \ilMMLinkItemRenderer(),
183                new ilMMTypeHandlerLink())
184        );
185
186        // LinkList
187        $link_list = new TypeInformation(
188            LinkList::class,
189            $this->translateType(LinkList::class),
190            new LinkListItemRenderer()
191        );
192        $link_list->setCreationPrevented(true);
193        $c->add($link_list);
194
195        // Separator
196        $c->add(new TypeInformation(
197                Separator::class,
198                $this->translateType(Separator::class),
199                new SeparatorItemRenderer(),
200                new ilMMTypeHandlerSeparator(),
201                $this->translateByline(Separator::class))
202        );
203
204        // RepositoryLink
205        $c->add(new TypeInformation(
206                RepositoryLink::class,
207                $this->translateType(RepositoryLink::class),
208                new \ilMMRepositoryLinkItemRenderer(),
209                new ilMMTypeHandlerRepositoryLink())
210        );
211
212        // Lost
213        $lost = new TypeInformation(
214            Lost::class,
215            $this->translateType(Lost::class),
216            new LostItemRenderer()
217        );
218        $lost->setCreationPrevented(true);
219        $c->add($lost);
220
221        // Complex
222        $complex = new TypeInformation(
223            Complex::class,
224            $this->translateType(Complex::class),
225            new ComplexItemRenderer()
226        );
227        $complex->setCreationPrevented(true);
228        $c->add($complex);
229
230        return $c;
231    }
232
233
234    /**
235     * @param string $type
236     *
237     * @return string
238     */
239    private function translateType(string $type) : string
240    {
241        $last_part = substr(strrchr($type, "\\"), 1);
242        $last_part = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $last_part));
243
244        return $this->dic->language()->txt("type_" . strtolower($last_part));
245    }
246
247
248    /**
249     * @param string $type
250     *
251     * @return string
252     */
253    private function translateByline(string $type) : string
254    {
255        $last_part = substr(strrchr($type, "\\"), 1);
256        $last_part = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $last_part));
257
258        return $this->dic->language()->txt("type_" . strtolower($last_part) . "_info");
259    }
260
261
262    /**
263     * @inheritDoc
264     */
265    public function getProviderNameForPresentation() : string
266    {
267        return "Custom";
268    }
269}
270