xref: /dokuwiki/inc/Ui/Admin.php (revision 6c16a3a9aa602bb7e269fb6d5d18e1353e17f97f)
10470c28fSAndreas Gohr<?php
2e2d055f5SAndreas Gohr
30470c28fSAndreas Gohrnamespace dokuwiki\Ui;
40470c28fSAndreas Gohr
579a2d784SGerrit Uitslaguse dokuwiki\Extension\AdminPlugin;
6e2d055f5SAndreas Gohruse dokuwiki\Extension\PluginInterface;
72d85e841SAndreas Gohruse dokuwiki\Utf8\Sort;
82d85e841SAndreas Gohr
90470c28fSAndreas Gohr/**
100470c28fSAndreas Gohr * Class Admin
110470c28fSAndreas Gohr *
120470c28fSAndreas Gohr * Displays the Admin screen
130470c28fSAndreas Gohr *
140470c28fSAndreas Gohr * @package dokuwiki\Ui
150470c28fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org>
160470c28fSAndreas Gohr * @author Håkan Sandell <hakan.sandell@home.se>
170470c28fSAndreas Gohr */
18e2d055f5SAndreas Gohrclass Admin extends Ui
19e2d055f5SAndreas Gohr{
20e2d055f5SAndreas Gohr    protected $forAdmins = ['usermanager', 'acl', 'extension', 'config', 'logviewer', 'styling'];
21e2d055f5SAndreas Gohr    protected $forManagers = ['revert', 'popularity'];
2264cdf779SAndreas Gohr    /** @var array[] */
230470c28fSAndreas Gohr    protected $menu;
240470c28fSAndreas Gohr
250470c28fSAndreas Gohr    /**
260470c28fSAndreas Gohr     * Display the UI element
270470c28fSAndreas Gohr     *
280470c28fSAndreas Gohr     * @return void
290470c28fSAndreas Gohr     */
30e2d055f5SAndreas Gohr    public function show()
31e2d055f5SAndreas Gohr    {
320470c28fSAndreas Gohr        $this->menu = $this->getPluginList();
335d2e38cbSAndreas Gohr        echo '<div class="ui-admin">';
340470c28fSAndreas Gohr        echo p_locale_xhtml('admin');
35052e1c84SAndreas Gohr
3664cdf779SAndreas Gohr        $this->showMenu('admin');
3764cdf779SAndreas Gohr        $this->showMenu('manager');
38052e1c84SAndreas Gohr        $this->showSecurityCheck();
390470c28fSAndreas Gohr        $this->showVersion();
4064cdf779SAndreas Gohr        $this->showMenu('other');
41713faa94SAndreas Gohr        echo '</div>';
420470c28fSAndreas Gohr    }
430470c28fSAndreas Gohr
440470c28fSAndreas Gohr    /**
4564cdf779SAndreas Gohr     * Show the given menu of available plugins
4664cdf779SAndreas Gohr     *
4764cdf779SAndreas Gohr     * @param string $type admin|manager|other
480470c28fSAndreas Gohr     */
49e2d055f5SAndreas Gohr    protected function showMenu($type)
50e2d055f5SAndreas Gohr    {
5164cdf779SAndreas Gohr        if (!$this->menu[$type]) return;
520470c28fSAndreas Gohr
5364cdf779SAndreas Gohr        if ($type === 'other') {
540470c28fSAndreas Gohr            echo p_locale_xhtml('adminplugins');
5564cdf779SAndreas Gohr            $class = 'admin_plugins';
5664cdf779SAndreas Gohr        } else {
5764cdf779SAndreas Gohr            $class = 'admin_tasks';
5864cdf779SAndreas Gohr        }
5964cdf779SAndreas Gohr
6064cdf779SAndreas Gohr        echo "<ul class=\"$class\">";
6164cdf779SAndreas Gohr        foreach ($this->menu[$type] as $item) {
620470c28fSAndreas Gohr            $this->showMenuItem($item);
630470c28fSAndreas Gohr        }
640470c28fSAndreas Gohr        echo '</ul>';
650470c28fSAndreas Gohr    }
660470c28fSAndreas Gohr
670470c28fSAndreas Gohr    /**
680470c28fSAndreas Gohr     * Display the DokuWiki version
690470c28fSAndreas Gohr     */
70e2d055f5SAndreas Gohr    protected function showVersion()
71e2d055f5SAndreas Gohr    {
720470c28fSAndreas Gohr        echo '<div id="admin__version">';
730470c28fSAndreas Gohr        echo getVersion();
740470c28fSAndreas Gohr        echo '</div>';
750470c28fSAndreas Gohr    }
760470c28fSAndreas Gohr
770470c28fSAndreas Gohr    /**
780470c28fSAndreas Gohr     * data security check
790470c28fSAndreas Gohr     *
800470c28fSAndreas Gohr     * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL
810470c28fSAndreas Gohr     *
820470c28fSAndreas Gohr     * it verifies either:
830470c28fSAndreas Gohr     *   'savedir' has been moved elsewhere, or
840470c28fSAndreas Gohr     *   has protection to prevent the webserver serving files from it
85052e1c84SAndreas Gohr     *
86052e1c84SAndreas Gohr     * The actual check is carried out via JavaScript. See behaviour.js
870470c28fSAndreas Gohr     */
88e2d055f5SAndreas Gohr    protected function showSecurityCheck()
89e2d055f5SAndreas Gohr    {
900470c28fSAndreas Gohr        global $conf;
91*6c16a3a9Sfiwswe        if (!str_starts_with($conf['savedir'], './')) return;
9264159a61SAndreas Gohr        $img = DOKU_URL . $conf['savedir'] .
9364159a61SAndreas Gohr            '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png';
94d3f829c2SAndreas Gohr        echo '<div id="security__check" data-src="' . $img . '"></div>';
950470c28fSAndreas Gohr    }
960470c28fSAndreas Gohr
970470c28fSAndreas Gohr    /**
980470c28fSAndreas Gohr     * Display a single Admin menu item
990470c28fSAndreas Gohr     *
1000470c28fSAndreas Gohr     * @param array $item
1010470c28fSAndreas Gohr     */
102e2d055f5SAndreas Gohr    protected function showMenuItem($item)
103e2d055f5SAndreas Gohr    {
1040470c28fSAndreas Gohr        global $ID;
1050470c28fSAndreas Gohr        if (blank($item['prompt'])) return;
1060470c28fSAndreas Gohr        echo '<li><div class="li">';
107220b8a20SAndreas Gohr        echo '<a href="' . wl($ID, 'do=admin&amp;page=' . $item['plugin']) . '">';
108220b8a20SAndreas Gohr        echo '<span class="icon">';
1094cd2074fSAndreas Gohr        echo inlineSVG($item['icon']);
1100470c28fSAndreas Gohr        echo '</span>';
111220b8a20SAndreas Gohr        echo '<span class="prompt">';
1120470c28fSAndreas Gohr        echo $item['prompt'];
113220b8a20SAndreas Gohr        echo '</span>';
1140470c28fSAndreas Gohr        echo '</a>';
1150470c28fSAndreas Gohr        echo '</div></li>';
1160470c28fSAndreas Gohr    }
1170470c28fSAndreas Gohr
1180470c28fSAndreas Gohr    /**
1190470c28fSAndreas Gohr     * Build  list of admin functions from the plugins that handle them
1200470c28fSAndreas Gohr     *
1210470c28fSAndreas Gohr     * Checks the current permissions to decide on manager or admin plugins
1220470c28fSAndreas Gohr     *
1230470c28fSAndreas Gohr     * @return array list of plugins with their properties
1240470c28fSAndreas Gohr     */
125e2d055f5SAndreas Gohr    protected function getPluginList()
126e2d055f5SAndreas Gohr    {
1270470c28fSAndreas Gohr        global $conf;
1280470c28fSAndreas Gohr
1290470c28fSAndreas Gohr        $pluginlist = plugin_list('admin');
13064cdf779SAndreas Gohr        $menu = ['admin' => [], 'manager' => [], 'other' => []];
13164cdf779SAndreas Gohr
1320470c28fSAndreas Gohr        foreach ($pluginlist as $p) {
13379a2d784SGerrit Uitslag            /** @var AdminPlugin $obj */
134e2d055f5SAndreas Gohr            if (!($obj = plugin_load('admin', $p)) instanceof PluginInterface) continue;
1350470c28fSAndreas Gohr
1360470c28fSAndreas Gohr            // check permissions
13764cdf779SAndreas Gohr            if (!$obj->isAccessibleByCurrentUser()) continue;
1380470c28fSAndreas Gohr
13964cdf779SAndreas Gohr            if (in_array($p, $this->forAdmins, true)) {
14064cdf779SAndreas Gohr                $type = 'admin';
14164cdf779SAndreas Gohr            } elseif (in_array($p, $this->forManagers, true)) {
14264cdf779SAndreas Gohr                $type = 'manager';
14364cdf779SAndreas Gohr            } else {
14464cdf779SAndreas Gohr                $type = 'other';
14564cdf779SAndreas Gohr            }
14664cdf779SAndreas Gohr
147e2d055f5SAndreas Gohr            $menu[$type][$p] = [
1480470c28fSAndreas Gohr                'plugin' => $p,
1490470c28fSAndreas Gohr                'prompt' => $obj->getMenuText($conf['lang']),
1500470c28fSAndreas Gohr                'icon' => $obj->getMenuIcon(),
151e2d055f5SAndreas Gohr                'sort' => $obj->getMenuSort()
152e2d055f5SAndreas Gohr            ];
1530470c28fSAndreas Gohr        }
1540470c28fSAndreas Gohr
1550470c28fSAndreas Gohr        // sort by name, then sort
15664cdf779SAndreas Gohr        uasort($menu['admin'], [$this, 'menuSort']);
15764cdf779SAndreas Gohr        uasort($menu['manager'], [$this, 'menuSort']);
15864cdf779SAndreas Gohr        uasort($menu['other'], [$this, 'menuSort']);
1590470c28fSAndreas Gohr
1600470c28fSAndreas Gohr        return $menu;
1610470c28fSAndreas Gohr    }
1620470c28fSAndreas Gohr
16364cdf779SAndreas Gohr    /**
16464cdf779SAndreas Gohr     * Custom sorting for admin menu
16564cdf779SAndreas Gohr     *
16664cdf779SAndreas Gohr     * We sort alphabetically first, then by sort value
16764cdf779SAndreas Gohr     *
16864cdf779SAndreas Gohr     * @param array $a
16964cdf779SAndreas Gohr     * @param array $b
17064cdf779SAndreas Gohr     * @return int
17164cdf779SAndreas Gohr     */
172e2d055f5SAndreas Gohr    protected function menuSort($a, $b)
173e2d055f5SAndreas Gohr    {
1742d85e841SAndreas Gohr        $strcmp = Sort::strcmp($a['prompt'], $b['prompt']);
17564cdf779SAndreas Gohr        if ($strcmp != 0) return $strcmp;
176e2d055f5SAndreas Gohr        return $a['sort'] <=> $b['sort'];
17764cdf779SAndreas Gohr    }
1780470c28fSAndreas Gohr}
179