1<?php
2
3/* Copyright (c) 1998-2012 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5use ILIAS\BackgroundTasks\BucketMeta;
6use ILIAS\BackgroundTasks\Implementation\Bucket\State;
7
8/**
9 * Handles display of the main menu
10 *
11 * @author  Alex Killing
12 * @version $Id$
13 */
14class ilMainMenuGUI
15{
16
17    /**
18     * @var ilRbacSystem
19     */
20    protected $rbacsystem;
21    /**
22     * @var ilObjUser
23     */
24    protected $user;
25    /**
26     * @var ilLanguage
27     */
28    protected $lng;
29    /**
30     * @var ilPluginAdmin
31     */
32    protected $plugin_admin;
33    /**
34     * @var ilTree
35     */
36    protected $tree;
37    /**
38     * @var ilAccessHandler
39     */
40    protected $access;
41    /**
42     * @var ilNavigationHistory
43     */
44    protected $nav_history;
45    /**
46     * @var ilSetting
47     */
48    protected $settings;
49    /**
50     * @var ilCtrl
51     */
52    protected $ctrl;
53    /**
54     * @var ilHelpGUI
55     */
56    protected $help;
57    /**
58     * @var ilTemplate
59     */
60    public $tpl;
61    public $target;
62    public $start_template;
63    /**
64     * @var ilGlobalTemplate
65     */
66    protected $main_tpl;
67    protected $mode; // [int]
68    protected $topbar_back_url; // [stringt]
69    protected $topbar_back_caption; // [string]
70    const MODE_FULL = 1;
71    const MODE_TOPBAR_ONLY = 2;
72    const MODE_TOPBAR_REDUCED = 3;
73    const MODE_TOPBAR_MEMBERVIEW = 4;
74
75
76    /**
77     * @param string  $a_target                       target frame
78     * @param boolean $a_use_start_template           true means: target scripts should
79     *                                                be called through start template
80     */
81    public function __construct($a_target = "_top", $a_use_start_template = false, ilGlobalTemplate $a_main_tpl = null)
82    {
83        global $DIC;
84
85        if ($a_main_tpl != null) {
86            $this->main_tpl = $a_main_tpl;
87        } else {
88            $this->main_tpl = $DIC["tpl"];
89        }
90
91        $this->rbacsystem = $DIC->rbac()->system();
92        $this->user = $DIC->user();
93        $this->lng = $DIC->language();
94        $this->plugin_admin = $DIC["ilPluginAdmin"];
95        $this->tree = $DIC->repositoryTree();
96        $this->access = $DIC->access();
97        $this->nav_history = $DIC["ilNavigationHistory"];
98        $this->settings = $DIC->settings();
99        $this->ctrl = $DIC->ctrl();
100        $this->help = $DIC["ilHelp"];
101        $this->ui = $DIC->ui();
102        $rbacsystem = $DIC->rbac()->system();
103        $ilUser = $DIC->user();
104
105        $this->tpl = new ilTemplate(
106            "tpl.main_menu.html",
107            true,
108            true,
109            "Services/MainMenu"
110        );
111        $this->target = $a_target;
112        $this->start_template = $a_use_start_template;
113
114        $this->setMode(self::MODE_FULL);
115
116        // member view
117        $set = ilMemberViewSettings::getInstance();
118        if ($set->isActive()) {
119            $this->initMemberView();
120        }
121    }
122
123
124    /**
125     * @param int $a_value        accepts values:
126     *                            self::MODE_TOPBAR_ONLY:
127     *                            self::MODE_TOPBAR_REDUCED:
128     *                            self::MODE_TOPBAR_MEMBERVIEW:
129     *                            case self::MODE_FULL:
130     */
131    public function setMode(int $a_value)
132    {
133        $this->mode = (int) $a_value;
134    }
135
136
137    /**
138     * @return int
139     */
140    public function getMode() : int
141    {
142        return $this->mode;
143    }
144
145
146    /**
147     * @param      $a_url
148     * @param null $a_caption
149     */
150    public function setTopBarBack($a_url, $a_caption = null)
151    {
152        $this->topbar_back_url = $a_url;
153        $this->topbar_back_caption = trim($a_caption);
154    }
155
156
157    /**
158     * @return string
159     */
160    public function getSpacerClass()
161    {
162        switch ($this->getMode()) {
163            case self::MODE_TOPBAR_ONLY:
164            case self::MODE_TOPBAR_REDUCED:
165            case self::MODE_TOPBAR_MEMBERVIEW:
166                return "ilFixedTopSpacerBarOnly";
167
168            case self::MODE_FULL:
169                return "ilFixedTopSpacer";
170        }
171    }
172
173
174    /**
175     * @param string $a_active "desktop"|"repository"|"search"|"chat_invitation"|"administration"
176     *
177     * @deprecated
178     *
179     */
180    public function setActive($a_active)
181    {
182        $this->active = $a_active;
183    }
184
185
186    /**
187     * @deprecated
188     * Set target parameter for login (public sector).
189     * This is used by the main menu
190     */
191    public function setLoginTargetPar($a_val)
192    {
193        $this->login_target_par = $a_val;
194    }
195
196
197    /**
198     * @deprecated
199     * Get target parameter for login
200     */
201    public function getLoginTargetPar()
202    {
203        return $this->login_target_par;
204    }
205
206
207    /**
208     * Set all template variables (images, scripts, target frames, ...)
209     */
210    private function setTemplateVars()
211    {
212        $rbacsystem = $this->rbacsystem;
213        $lng = $this->lng;
214        $ilUser = $this->user;
215        $ilPluginAdmin = $this->plugin_admin;
216        $main_tpl = $this->main_tpl;
217
218        if ($this->logo_only) {
219            $this->tpl->setVariable("HEADER_URL", $this->getHeaderURL());
220            $this->tpl->setVariable("HEADER_ICON", ilUtil::getImagePath("HeaderIcon.svg"));
221            $this->tpl->setVariable("HEADER_ICON_RESPONSIVE", ilUtil::getImagePath("HeaderIconResponsive.svg"));
222
223            // #15759
224            $header_top_title = ilObjSystemFolder::_getHeaderTitle();
225            if (trim($header_top_title) != "" && $this->tpl->blockExists("header_top_title")) {
226                $this->tpl->setCurrentBlock("header_top_title");
227                $this->tpl->setVariable("TXT_HEADER_TITLE", $header_top_title);
228                $this->tpl->parseCurrentBlock();
229            }
230
231            return;
232        }
233
234        // get user interface plugins
235
236        if ($this->getMode() != self::MODE_TOPBAR_REDUCED
237            && $this->getMode() != self::MODE_TOPBAR_MEMBERVIEW
238        ) {
239            // search
240            if ($rbacsystem->checkAccess('search', ilSearchSettings::_getSearchSettingRefId())) {
241                $main_search = new ilMainMenuSearchGUI();
242                $html = "";
243
244                // user interface plugin slot + default rendering
245                $uip = new ilUIHookProcessor(
246                    "Services/MainMenu",
247                    "main_menu_search",
248                    array("main_menu_gui" => $this, "main_menu_search_gui" => $main_search)
249                );
250                if (!$uip->replaced()) {
251                    $html = $main_search->getHTML();
252                }
253                $html = $uip->getHTML($html);
254
255                if (strlen($html)) {
256                    $this->tpl->setVariable('SEARCHBOX', $html);
257                    $this->addToolbarTooltip("ilMMSearch", "mm_tb_search");
258                }
259            }
260
261            $this->renderStatusBox($this->tpl);
262
263            // online help
264            $this->renderHelpButtons();
265
266            $this->renderOnScreenChatMenu();
267            $this->renderBackgroundTasks();
268            $this->renderAwareness();
269        }
270
271        if ($this->getMode() == self::MODE_FULL) {
272            $this->tpl->setVariable("MAIN_MENU_LIST_ENTRIES", "-");
273        }
274
275        if ($this->getMode() != self::MODE_TOPBAR_MEMBERVIEW) {
276            $link_dir = (defined("ILIAS_MODULE"))
277                ? "../"
278                : "";
279
280            // login stuff
281            if ($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) {
282                if (ilRegistrationSettings::_lookupRegistrationType() != IL_REG_DISABLED) {
283                    $this->tpl->setCurrentBlock("registration_link");
284                    $this->tpl->setVariable("TXT_REGISTER", $lng->txt("register"));
285                    $this->tpl->setVariable("LINK_REGISTER", $link_dir . "register.php?client_id=" . rawurlencode(CLIENT_ID) . "&lang=" . $ilUser->getCurrentLanguage());
286                    $this->tpl->parseCurrentBlock();
287                }
288
289
290                $this->tpl->setCurrentBlock("userisanonymous");
291                $this->tpl->setVariable("TXT_NOT_LOGGED_IN", $lng->txt("not_logged_in"));
292                $this->tpl->setVariable("TXT_LOGIN", $lng->txt("log_in"));
293
294                // #13058
295                $target_str = ($this->getLoginTargetPar() != "")
296                    ? $this->getLoginTargetPar()
297                    : $this->buildLoginTarget();
298                $this->tpl->setVariable(
299                    "LINK_LOGIN",
300                    $link_dir . "login.php?target=" . $target_str . "&client_id=" . rawurlencode(CLIENT_ID) . "&cmd=force_login&lang=" . $ilUser->getCurrentLanguage()
301                );
302                $this->tpl->parseCurrentBlock();
303            } else {
304                $this->tpl->setCurrentBlock("userisloggedin");
305                $this->tpl->setVariable("TXT_LOGIN_AS", $lng->txt("login_as"));
306                $user_img_src = $ilUser->getPersonalPicturePath("small", true);
307                $user_img_alt = $ilUser->getFullname();
308                $this->tpl->setVariable("USER_IMG", ilUtil::img($user_img_src, $user_img_alt));
309                $this->tpl->setVariable("USR_LINK_PROFILE", "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToProfile");
310                $this->tpl->setVariable("USR_TXT_PROFILE", $lng->txt("personal_profile"));
311                $this->tpl->setVariable("USR_LINK_SETTINGS", "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToSettings");
312                $this->tpl->setVariable("USR_TXT_SETTINGS", $lng->txt("personal_settings"));
313                $this->tpl->setVariable("TXT_LOGOUT2", $lng->txt("logout"));
314                $this->tpl->setVariable("LINK_LOGOUT2", $link_dir . "logout.php?lang=" . $ilUser->getCurrentLanguage());
315                $this->tpl->setVariable("USERNAME", $ilUser->getFullname());
316                $this->tpl->setVariable("LOGIN", $ilUser->getLogin());
317                $this->tpl->setVariable("MATRICULATION", $ilUser->getMatriculation());
318                $this->tpl->setVariable("EMAIL", $ilUser->getEmail());
319                $this->tpl->parseCurrentBlock();
320
321                $this->addToolbarTooltip("userlog", "mm_tb_user");
322            }
323        } else {
324            // member view info
325            $this->tpl->setVariable("TOPBAR_CLASS", " ilMemberViewMainHeader");
326            $this->tpl->setVariable("MEMBER_VIEW_INFO", $lng->txt("mem_view_long"));
327        }
328
329        if (!$this->topbar_back_url) {
330            $header_top_title = ilObjSystemFolder::_getHeaderTitle();
331            if (trim($header_top_title) != "" && $this->tpl->blockExists("header_top_title")) {
332                $this->tpl->setCurrentBlock("header_top_title");
333                // php7-workaround alex: added phpversion() to help during development of php7 compatibility
334                $this->tpl->setVariable("TXT_HEADER_TITLE", $header_top_title);
335                $this->tpl->parseCurrentBlock();
336            }
337        } else {
338            $this->tpl->setCurrentBlock("header_back_bl");
339            $this->tpl->setVariable("URL_HEADER_BACK", $this->topbar_back_url);
340            $this->tpl->setVariable(
341                "TXT_HEADER_BACK",
342                $this->topbar_back_caption
343                ? $this->topbar_back_caption
344                : $lng->txt("back")
345            );
346            $this->tpl->parseCurrentBlock();
347        }
348
349        $this->tpl->setVariable("LOCATION_STYLESHEET", ilUtil::getStyleSheetLocation());
350
351        if ($this->getMode() == self::MODE_FULL) {
352            // $this->tpl->setVariable("TXT_LOGOUT", $lng->txt("logout"));
353            $this->tpl->setVariable("HEADER_URL", $this->getHeaderURL());
354            $this->tpl->setVariable("HEADER_ICON", ilUtil::getImagePath("HeaderIcon.svg"));
355            $this->tpl->setVariable("HEADER_ICON_RESPONSIVE", ilUtil::getImagePath("HeaderIconResponsive.svg"));
356        }
357
358        $this->tpl->setVariable("TXT_MAIN_MENU", $lng->txt("main_menu"));
359
360        $this->tpl->parseCurrentBlock();
361    }
362
363
364    /**
365     * @param ilTemplate $a_tpl
366     */
367    private function renderStatusBox(ilTemplate $a_tpl)
368    {
369        $ilUser = $this->user;
370        $ui_factory = $this->ui->factory();
371        $ui_renderer = $this->ui->renderer();
372    }
373
374
375    /**
376     * @return bool
377     * @deprecated Please use RBAC directly
378     */
379    public static function _checkAdministrationPermission()
380    {
381        global $DIC;
382
383        $rbacsystem = $DIC->rbac()->system();
384
385        //if($rbacsystem->checkAccess("visible,read", SYSTEM_FOLDER_ID))
386        if ($rbacsystem->checkAccess("visible", SYSTEM_FOLDER_ID)) {
387            return true;
388        }
389
390        return false;
391    }
392
393
394    /**
395     * @return string
396     * @throws ilTemplateException
397     * @deprecated
398     */
399    public function getHTML()
400    {
401        // this is a workaround for bugs like 14016
402        // the main menu does not need the YUI connection, but many other
403        // features since they rely on il.Util.sendAjaxGetRequestToUrl (see Services/Javascript)
404        // which still uses YUI. This should be migrated to jQuery with a future major release
405        ilYuiUtil::initConnection();
406
407        $this->setTemplateVars();
408
409        return $this->tpl->get();
410    }
411
412
413    /**
414     * @return bool
415     */
416    protected function initMemberView() : bool
417    {
418        $lng = $this->lng;
419
420        $ref_id = ilMemberViewSettings::getInstance()->getCurrentRefId();
421
422        if (!$ref_id) {
423            return false;
424        }
425
426        $url = ilLink::_getLink(
427            $ref_id,
428            ilObject::_lookupType(ilObject::_lookupObjId($ref_id)),
429            array('mv' => 0)
430        );
431
432        $this->setMode(self::MODE_TOPBAR_MEMBERVIEW);
433        $this->setTopBarBack($url, $lng->txt('mem_view_close'));
434
435        return true;
436    }
437
438
439    private function renderHelpButtons()
440    {
441        $ilHelp = $this->help;
442        $lng = $this->lng;
443        $ilCtrl = $this->ctrl;
444        $ilSetting = $this->settings;
445        $ilUser = $this->user;
446        $main_tpl = $this->main_tpl;
447
448        // screen id
449        if ((defined("OH_REF_ID") && OH_REF_ID > 0) || DEVMODE == 1) {
450            if ($ilHelp->getScreenId() != "") {
451                if ($this->getMode() == self::MODE_FULL) {
452                    $this->tpl->setCurrentBlock("screen_id");
453                    $this->tpl->setVariable("SCREEN_ID", $ilHelp->getScreenId());
454                    $this->tpl->parseCurrentBlock();
455                }
456            }
457        }
458
459        $help_active = false;
460
461        $helpl = new ilGroupedListGUI();
462        $helpl->setAsDropDown(true, true);
463
464        if ($ilHelp->hasSections()) {
465            $help_active = true;
466
467            $lng->loadLanguageModule("help");
468            //$this->tpl->setCurrentBlock("help_icon");
469
470            // add javascript needed by help (to do: move to help class)
471            $main_tpl->addJavascript("./Services/Help/js/ilHelp.js");
472            $acc = new ilAccordionGUI();
473            $acc->addJavascript($main_tpl);
474            $acc->addCss();
475
476            ilTooltipGUI::addTooltip(
477                "help_tr",
478                $lng->txt("help_open_online_help"),
479                "",
480                "bottom center",
481                "top center",
482                false
483            );
484            $helpl->addEntry("<span>&nbsp;</span> " . $lng->txt("help_topcis"), "#", "", "il.Help.listHelp(event, false);");
485        }
486
487        $module_id = (int) $ilSetting->get("help_module");
488        if ((OH_REF_ID > 0 || $module_id > 0) && $ilUser->getLanguage() == "de"
489            && $ilSetting->get("help_mode") != "1"
490        ) {
491            $help_active = true;
492
493            $lng->loadLanguageModule("help");
494            $main_tpl->addJavascript("./Services/Help/js/ilHelp.js");
495
496            ilTooltipGUI::addTooltip(
497                "help_tt",
498                $lng->txt("help_toggle_tooltips"),
499                "",
500                "bottom center",
501                "top center",
502                false
503            );
504            $helpl->addEntry('<span id="help_tt_switch_on" class="glyphicon glyphicon-ok"></span> ' . $lng->txt("help_tooltips"), "#", "", "return il.Help.switchTooltips(event);");
505        }
506
507        if ($help_active && $ilHelp->hasSections()) {
508            $this->tpl->setCurrentBlock("help");
509            $this->tpl->setVariable("TXT_HELP", $lng->txt("help"));
510            $this->tpl->setVariable("HELP_CLICK", "il.Help.listHelp(event, false);");
511            $this->tpl->parseCurrentBlock();
512
513            $this->addToolbarTooltip("mm_help", "mm_tb_help");
514
515            // always set ajax url
516            $ilHelp->setCtrlPar();
517            $this->main_tpl->addOnLoadCode(
518                "il.Help.setAjaxUrl('" .
519                $ilCtrl->getLinkTargetByClass("ilhelpgui", "", "", true)
520                . "');"
521            );
522        }
523    }
524
525    private function renderOnScreenChatMenu()
526    {
527        $menu = new ilOnScreenChatMenuGUI();
528        $this->tpl->setVariable('ONSCREENCHAT', $menu->getMainMenuHTML());
529        $this->addToolbarTooltip("onscreenchatmenu-dropdown", "mm_tb_oschat");
530    }
531
532
533    /**
534     * Render awareness tool
535     */
536    public function renderAwareness()
537    {
538        include_once("./Services/Awareness/classes/class.ilAwarenessGUI.php");
539        $aw = ilAwarenessGUI::getInstance();
540
541        $this->tpl->setVariable("AWARENESS", $aw->getMainMenuHTML());
542        $this->addToolbarTooltip("awareness_trigger", "mm_tb_aware");
543    }
544
545    /**
546     * Toggle rendering of main menu, search, user info
547     *
548     * @param bool $a_value
549     *
550     * @deprecated do not use in other contextx
551     *
552     * @see        ilImprintGUI
553     */
554    public function showLogoOnly(bool $a_value)
555    {
556        $this->logo_only = (bool) $a_value;
557    }
558
559
560    /**
561     * @return string
562     */
563    private function getHeaderURL() : string
564    {
565        $url = ilUserUtil::getStartingPointAsUrl();
566
567        if (!$url) {
568            $url = "./goto.php?target=root_1";
569        }
570
571        return $url;
572    }
573
574
575    private function renderBackgroundTasks()
576    {
577        global $DIC;
578
579        $main_tpl = $this->main_tpl;
580
581        if ($DIC->user()->isAnonymous() || (int) $DIC->user()->getId() === 0) {
582            return;
583        }
584
585        $DIC->language()->loadLanguageModule("background_tasks");
586        $factory = $DIC->ui()->factory();
587        $persistence = $DIC->backgroundTasks()->persistence();
588        $metas = $persistence->getBucketMetaOfUser($DIC->user()->getId());
589        if (!count($metas)) {
590            return;
591        }
592
593        $numberOfUserInteractions = count(
594            array_filter(
595                $metas,
596                function (BucketMeta $meta) {
597                    return $meta->getState() == State::USER_INTERACTION;
598                }
599            )
600        );
601        $numberOfNotUserInteractions = count($metas) - $numberOfUserInteractions;
602
603        $popover = $factory->popover()
604            ->listing(array())
605            ->withFixedPosition()
606            ->withTitle($DIC->language()->txt("background_tasks_running")); // needs to have empty content
607        $DIC->ctrl()->clearParametersByClass(ilBTControllerGUI::class);
608        $DIC->ctrl()->setParameterByClass(
609            ilBTControllerGUI::class,
610            ilBTControllerGUI::FROM_URL,
611            ilBTControllerGUI::hash("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}")
612        );
613        $DIC->ctrl()->setParameterByClass(
614            ilBTControllerGUI::class,
615            ilBTControllerGUI::REPLACE_SIGNAL,
616            $popover->getReplaceContentSignal()->getId()
617        );
618
619        $url = $DIC->ctrl()->getLinkTargetByClass([ilBTControllerGUI::class], ilBTControllerGUI::CMD_GET_POPOVER_CONTENT, "", true);
620        $popover = $popover->withAsyncContentUrl($url);
621
622        $glyph = $factory->symbol()->glyph()
623            ->briefcase()
624            ->withOnClick($popover->getShowSignal())
625            ->withCounter($factory->counter()->novelty($numberOfUserInteractions))
626            ->withCounter($factory->counter()->status($numberOfNotUserInteractions));
627
628        $main_tpl->addJavascript('./Services/BackgroundTasks/js/background_task_refresh.js');
629
630        $this->tpl->setVariable(
631            'BACKGROUNDTASKS',
632            $DIC->ui()->renderer()->render([$glyph, $popover])
633        );
634
635        $this->tpl->setVariable('BACKGROUNDTASKS_REFRESH_URI', $url);
636
637        $this->addToolbarTooltip("mm_tb_background_tasks", "mm_tb_bgtasks");
638    }
639
640
641    /**
642     * Add toolbar tooltip
643     *
644     * @param string $element_id
645     * @param string $help_id
646     */
647    protected function addToolbarTooltip(string $element_id, string $help_id)
648    {
649        if (ilHelp::getMainMenuTooltip($help_id) != "") {
650            ilTooltipGUI::addTooltip(
651                $element_id,
652                ilHelp::getMainMenuTooltip($help_id),
653                "",
654                "top right",
655                "top left",
656                false
657            );
658        }
659    }
660
661
662    protected function buildLoginTarget()
663    {
664        global $DIC;
665
666        $tree = $DIC->repositoryTree();
667        $ilUser = $DIC->user();
668
669        $target_str = "";
670
671        // repository
672        if ($_GET["ref_id"] != "") {
673            if ($tree->isInTree($_GET["ref_id"]) && $_GET["ref_id"] != $tree->getRootId()) {
674                $obj_id = ilObject::_lookupObjId($_GET["ref_id"]);
675                $type = ilObject::_lookupType($obj_id);
676                $target_str = $type . "_" . $_GET["ref_id"];
677            }
678        } // personal workspace
679        else {
680            if ($_GET["wsp_id"] != "" && $_GET["wsp_id"] > 0) {
681                include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
682                $tree = new ilWorkspaceTree($ilUser->getId());
683                $obj_id = $tree->lookupObjectId((int) $_GET["wsp_id"]);
684                if ($obj_id) {
685                    $type = ilObject::_lookupType($obj_id);
686                    $target_str = $type . "_" . (int) $_GET["wsp_id"] . "_wsp";
687                }
688            } // portfolio
689            else {
690                if ($_GET["prt_id"] != "") {
691                    $target_str = "prtf_" . (int) $_GET["prt_id"];
692                }
693            }
694        }
695
696        return $target_str;
697    }
698}
699