1<?php
2
3use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\Hasher;
4use ILIAS\GlobalScreen\Scope\MainMenu\Provider\StaticMainMenuProvider;
5
6/**
7 * Class ilMMTopItemGUI
8 * @ilCtrl_IsCalledBy ilMMTopItemGUI: ilObjMainMenuGUI
9 * @ilCtrl_Calls      ilMMTopItemGUI: ilMMItemTranslationGUI
10 * @author            Fabian Schmid <fs@studer-raimann.ch>
11 */
12class ilMMTopItemGUI extends ilMMAbstractItemGUI
13{
14    use Hasher;
15
16    const CMD_VIEW_TOP_ITEMS = 'subtab_topitems';
17    const CMD_ADD = 'topitem_add';
18    const CMD_RESTORE = 'restore';
19    const CMD_CREATE = 'topitem_create';
20    const CMD_EDIT = 'topitem_edit';
21    const CMD_DELETE = 'topitem_delete';
22    const CMD_CONFIRM_DELETE = 'topitem_confirm_delete';
23    const CMD_TRANSLATE = 'topitem_translate';
24    const CMD_UPDATE = 'topitem_update';
25    const CMD_SAVE_TABLE = 'save_table';
26    const CMD_CANCEL = 'cancel';
27    const CMD_RENDER_INTERRUPTIVE = 'render_interruptive_modal';
28    const CMD_CONFIRM_RESTORE = 'confirmRestore';
29    const CMD_FLUSH = 'flush';
30
31    private function dispatchCommand($cmd)
32    {
33        global $DIC;
34        switch ($cmd) {
35            case self::CMD_VIEW_TOP_ITEMS:
36                $this->access->checkAccessAndThrowException("visible,read");
37                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, $cmd);
38
39                return $this->index($DIC);
40            case self::CMD_ADD:
41                $this->access->checkAccessAndThrowException("write");
42                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, self::CMD_VIEW_TOP_ITEMS, true, self::class);
43
44                return $this->add($DIC);
45            case self::CMD_CREATE:
46                $this->access->checkAccessAndThrowException("write");
47                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, self::CMD_VIEW_TOP_ITEMS, true, self::class);
48
49                return $this->create($DIC);
50            case self::CMD_EDIT:
51                $this->access->checkAccessAndThrowException("write");
52                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, self::CMD_VIEW_TOP_ITEMS, true, self::class);
53
54                return $this->edit($DIC);
55            case self::CMD_UPDATE:
56                $this->access->checkAccessAndThrowException("write");
57                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, self::CMD_VIEW_TOP_ITEMS, true, self::class);
58
59                return $this->update($DIC);
60            case self::CMD_SAVE_TABLE:
61                $this->access->checkAccessAndThrowException("write");
62                $this->saveTable();
63
64                break;
65            case self::CMD_CONFIRM_DELETE:
66                $this->access->checkAccessAndThrowException("write");
67
68                return $this->confirmDelete();
69            case self::CMD_DELETE:
70                $this->access->checkAccessAndThrowException("write");
71                $this->delete();
72                break;
73            case self::CMD_CANCEL:
74                $this->cancel();
75                break;
76            case self::CMD_CONFIRM_RESTORE:
77                return $this->confirmRestore();
78                break;
79            case self::CMD_FLUSH:
80                $this->access->checkAccessAndThrowException('write');
81                $this->flush();
82                break;
83            case self::CMD_RESTORE:
84                $this->access->checkAccessAndThrowException("write");
85
86                $this->restore();
87                break;
88            case self::CMD_RENDER_INTERRUPTIVE:
89                $this->access->checkAccessAndThrowException("write");
90                $this->renderInterruptiveModal();
91                break;
92        }
93
94        return "";
95    }
96
97    private function saveTable()
98    {
99        global $DIC;
100        $r = $DIC->http()->request()->getParsedBody();
101        foreach ($r[self::IDENTIFIER] as $identification_string => $data) {
102            $item = $this->repository->getItemFacadeForIdentificationString($identification_string);
103            $item->setPosition((int) $data['position']);
104            $item->setActiveStatus((bool) $data['active']);
105            $this->repository->updateItem($item);
106        }
107        $this->cancel();
108    }
109
110    public function executeCommand()
111    {
112        $next_class = $this->ctrl->getNextClass();
113
114        if ($next_class == '') {
115            $cmd = $this->determineCommand(self::CMD_VIEW_TOP_ITEMS, self::CMD_DELETE);
116            $this->tpl->setContent($this->dispatchCommand($cmd));
117
118            return;
119        }
120
121        switch ($next_class) {
122            case strtolower(ilMMItemTranslationGUI::class):
123                $this->tab_handling->initTabs(ilObjMainMenuGUI::TAB_MAIN, self::CMD_VIEW_TOP_ITEMS, true);
124                $g = new ilMMItemTranslationGUI($this->getMMItemFromRequest(), $this->repository);
125                $this->ctrl->forwardCommand($g);
126                break;
127            default:
128                break;
129        }
130    }
131
132    /**
133     * @return string
134     */
135    private function index() : string
136    {
137        if ($this->access->hasUserPermissionTo('write')) {
138            // ADD NEW
139            $b = ilLinkButton::getInstance();
140            $b->setCaption($this->lng->txt(self::CMD_ADD), false);
141            $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_ADD));
142            $this->toolbar->addButtonInstance($b);
143
144            // REMOVE LOST ITEMS
145            if ($this->repository->hasLostItems()) {
146                $b = ilLinkButton::getInstance();
147                $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_FLUSH));
148                $b->setCaption($this->lng->txt(self::CMD_FLUSH), false);
149                $this->toolbar->addButtonInstance($b);
150            }
151        }
152
153        // TABLE
154        $table = new ilMMTopItemTableGUI($this, new ilMMItemRepository(), $this->access);
155        $table->setShowRowsSelector(false);
156
157        return $table->getHTML();
158    }
159
160    private function cancel()
161    {
162        $this->ctrl->redirectByClass(self::class, self::CMD_VIEW_TOP_ITEMS);
163    }
164
165    private function doubleCancel()
166    {
167        $this->ctrl->redirectByClass(self::class, self::CMD_CANCEL);
168    }
169
170    /**
171     * @param $DIC
172     * @return string
173     * @throws Throwable
174     */
175    private function add(\ILIAS\DI\Container $DIC) : string
176    {
177        $f = new ilMMTopItemFormGUI($DIC->ctrl(), $DIC->ui()->factory(), $DIC->ui()->renderer(), $this->lng, $DIC->http(), $this->repository->getItemFacade(), $this->repository);
178
179        return $f->getHTML();
180    }
181
182    /**
183     * @param \ILIAS\DI\Container $DIC
184     * @return string
185     * @throws Throwable
186     */
187    private function create(\ILIAS\DI\Container $DIC)
188    {
189        $f = new ilMMTopItemFormGUI($DIC->ctrl(), $DIC->ui()->factory(), $DIC->ui()->renderer(), $this->lng, $DIC->http(), $this->repository->getItemFacade(), $this->repository);
190        if ($f->save()) {
191            $this->cancel();
192        }
193
194        return $f->getHTML();
195    }
196
197    /**
198     * @param $DIC
199     * @return string
200     * @throws Throwable
201     */
202    private function edit(\ILIAS\DI\Container $DIC) : string
203    {
204        $f = new ilMMTopItemFormGUI($DIC->ctrl(), $DIC->ui()->factory(), $DIC->ui()->renderer(), $this->lng, $DIC->http(), $this->getMMItemFromRequest(), $this->repository);
205
206        return $f->getHTML();
207    }
208
209    /**
210     * @param \ILIAS\DI\Container $DIC
211     * @return string
212     * @throws Throwable
213     */
214    private function update(\ILIAS\DI\Container $DIC)
215    {
216        $item = $this->getMMItemFromRequest();
217        if ($item->isEditable()) {
218            $f = new ilMMTopItemFormGUI($DIC->ctrl(), $DIC->ui()->factory(), $DIC->ui()->renderer(), $this->lng, $DIC->http(), $item, $this->repository);
219            if ($f->save()) {
220                $this->cancel();
221            }
222
223            return $f->getHTML();
224        }
225
226        return "";
227    }
228
229    private function delete()
230    {
231        $item = $this->getMMItemFromRequest();
232        if ($item->isDeletable()) {
233            $this->repository->deleteItem($item);
234        }
235        ilUtil::sendSuccess($this->lng->txt("msg_topitem_deleted"), true);
236        $this->cancel();
237    }
238
239    /**
240     * @return string
241     * @throws Throwable
242     */
243    private function confirmDelete() : string
244    {
245        $this->ctrl->saveParameterByClass(self::class, self::IDENTIFIER);
246        $i = $this->getMMItemFromRequest();
247        $c = new ilConfirmationGUI();
248        $c->addItem(self::IDENTIFIER, $this->hash($i->getId()), $i->getDefaultTitle());
249        $c->setFormAction($this->ctrl->getFormActionByClass(self::class));
250        $c->setConfirm($this->lng->txt(self::CMD_DELETE), self::CMD_DELETE);
251        $c->setCancel($this->lng->txt(self::CMD_CANCEL), self::CMD_CANCEL);
252        $c->setHeaderText($this->lng->txt(self::CMD_CONFIRM_DELETE));
253
254        return $c->getHTML();
255    }
256
257    private function confirmRestore() : string
258    {
259        $c = new ilConfirmationGUI();
260        $c->setFormAction($this->ctrl->getFormActionByClass(self::class));
261        $c->setConfirm($this->lng->txt(self::CMD_DELETE), self::CMD_RESTORE);
262        $c->setCancel($this->lng->txt(self::CMD_CANCEL), self::CMD_CANCEL);
263        $c->setHeaderText($this->lng->txt('msg_restore_confirm'));
264
265        return $c->getHTML();
266    }
267
268    private function flush()
269    {
270        $this->repository->flushLostItems();
271        ilUtil::sendSuccess($this->lng->txt("msg_subitem_flushed"), true);
272        $this->cancel();
273    }
274
275    private function restore()
276    {
277        ilGSProviderStorage::flushDB();
278        ilGSIdentificationStorage::flushDB();
279        ilMMItemStorage::flushDB();
280        ilMMCustomItemStorage::flushDB();
281        ilMMItemTranslationStorage::flushDB();
282        ilMMTypeActionStorage::flushDB();
283
284        $r = function ($path, $xml_name) {
285            foreach (new DirectoryIterator($path) as $fileInfo) {
286                $filename = $fileInfo->getPathname() . $xml_name;
287                if ($fileInfo->isDir() && !$fileInfo->isDot() && file_exists($filename)) {
288                    $xml = simplexml_load_file($filename);
289                    if (isset($xml->gsproviders)) {
290                        foreach ($xml->gsproviders as $item) {
291                            if (isset($item->gsprovider)) {
292                                foreach ($item->gsprovider as $provider) {
293                                    $attributes = $provider->attributes();
294                                    if ($attributes->purpose == StaticMainMenuProvider::PURPOSE_MAINBAR) {
295                                        $classname = $attributes->class_name[0];
296                                        ilGSProviderStorage::registerIdentifications($classname, StaticMainMenuProvider::PURPOSE_MAINBAR);
297                                    }
298                                }
299                            }
300                        }
301                    }
302                }
303            }
304        };
305        $r("./Services", "/service.xml");
306        $r("./Modules", "/module.xml");
307
308        ilGlobalCache::flushAll();
309
310        ilUtil::sendSuccess($this->lng->txt('msg_restored'), true);
311
312        $this->cancel();
313    }
314}
315