xref: /dokuwiki/inc/Ui/Admin.php (revision dafc98922abc2dbb479268485b585726c6815168)
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();
7479f150bdSAndreas Gohr        echo '<br>';
75*dafc9892Ssplitbrain        echo implode('<br>', array_map('hsc', array_values(getRuntimeVersions())));
760470c28fSAndreas Gohr        echo '</div>';
770470c28fSAndreas Gohr    }
780470c28fSAndreas Gohr
790470c28fSAndreas Gohr    /**
800470c28fSAndreas Gohr     * data security check
810470c28fSAndreas Gohr     *
820470c28fSAndreas Gohr     * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL
830470c28fSAndreas Gohr     *
840470c28fSAndreas Gohr     * it verifies either:
850470c28fSAndreas Gohr     *   'savedir' has been moved elsewhere, or
860470c28fSAndreas Gohr     *   has protection to prevent the webserver serving files from it
87052e1c84SAndreas Gohr     *
88052e1c84SAndreas Gohr     * The actual check is carried out via JavaScript. See behaviour.js
890470c28fSAndreas Gohr     */
90e2d055f5SAndreas Gohr    protected function showSecurityCheck()
91e2d055f5SAndreas Gohr    {
920470c28fSAndreas Gohr        global $conf;
936c16a3a9Sfiwswe        if (!str_starts_with($conf['savedir'], './')) return;
9464159a61SAndreas Gohr        $img = DOKU_URL . $conf['savedir'] .
9564159a61SAndreas Gohr            '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png';
96d3f829c2SAndreas Gohr        echo '<div id="security__check" data-src="' . $img . '"></div>';
970470c28fSAndreas Gohr    }
980470c28fSAndreas Gohr
990470c28fSAndreas Gohr    /**
1000470c28fSAndreas Gohr     * Display a single Admin menu item
1010470c28fSAndreas Gohr     *
1020470c28fSAndreas Gohr     * @param array $item
1030470c28fSAndreas Gohr     */
104e2d055f5SAndreas Gohr    protected function showMenuItem($item)
105e2d055f5SAndreas Gohr    {
1060470c28fSAndreas Gohr        global $ID;
1070470c28fSAndreas Gohr        if (blank($item['prompt'])) return;
1080470c28fSAndreas Gohr        echo '<li><div class="li">';
109220b8a20SAndreas Gohr        echo '<a href="' . wl($ID, 'do=admin&amp;page=' . $item['plugin']) . '">';
110220b8a20SAndreas Gohr        echo '<span class="icon">';
1114cd2074fSAndreas Gohr        echo inlineSVG($item['icon']);
1120470c28fSAndreas Gohr        echo '</span>';
113220b8a20SAndreas Gohr        echo '<span class="prompt">';
1140470c28fSAndreas Gohr        echo $item['prompt'];
115220b8a20SAndreas Gohr        echo '</span>';
1160470c28fSAndreas Gohr        echo '</a>';
1170470c28fSAndreas Gohr        echo '</div></li>';
1180470c28fSAndreas Gohr    }
1190470c28fSAndreas Gohr
1200470c28fSAndreas Gohr    /**
1210470c28fSAndreas Gohr     * Build  list of admin functions from the plugins that handle them
1220470c28fSAndreas Gohr     *
1230470c28fSAndreas Gohr     * Checks the current permissions to decide on manager or admin plugins
1240470c28fSAndreas Gohr     *
1250470c28fSAndreas Gohr     * @return array list of plugins with their properties
1260470c28fSAndreas Gohr     */
127e2d055f5SAndreas Gohr    protected function getPluginList()
128e2d055f5SAndreas Gohr    {
1290470c28fSAndreas Gohr        global $conf;
1300470c28fSAndreas Gohr
1310470c28fSAndreas Gohr        $pluginlist = plugin_list('admin');
13264cdf779SAndreas Gohr        $menu = ['admin' => [], 'manager' => [], 'other' => []];
13364cdf779SAndreas Gohr
1340470c28fSAndreas Gohr        foreach ($pluginlist as $p) {
13579a2d784SGerrit Uitslag            /** @var AdminPlugin $obj */
136e2d055f5SAndreas Gohr            if (!($obj = plugin_load('admin', $p)) instanceof PluginInterface) continue;
1370470c28fSAndreas Gohr
1380470c28fSAndreas Gohr            // check permissions
13964cdf779SAndreas Gohr            if (!$obj->isAccessibleByCurrentUser()) continue;
14031afae8aSAndreas Gohr            if (!$obj->showInMenu()) continue;
1410470c28fSAndreas Gohr
14264cdf779SAndreas Gohr            if (in_array($p, $this->forAdmins, true)) {
14364cdf779SAndreas Gohr                $type = 'admin';
14464cdf779SAndreas Gohr            } elseif (in_array($p, $this->forManagers, true)) {
14564cdf779SAndreas Gohr                $type = 'manager';
14664cdf779SAndreas Gohr            } else {
14764cdf779SAndreas Gohr                $type = 'other';
14864cdf779SAndreas Gohr            }
14964cdf779SAndreas Gohr
150e2d055f5SAndreas Gohr            $menu[$type][$p] = [
1510470c28fSAndreas Gohr                'plugin' => $p,
1520470c28fSAndreas Gohr                'prompt' => $obj->getMenuText($conf['lang']),
1530470c28fSAndreas Gohr                'icon' => $obj->getMenuIcon(),
154e2d055f5SAndreas Gohr                'sort' => $obj->getMenuSort()
155e2d055f5SAndreas Gohr            ];
1560470c28fSAndreas Gohr        }
1570470c28fSAndreas Gohr
1580470c28fSAndreas Gohr        // sort by name, then sort
15964cdf779SAndreas Gohr        uasort($menu['admin'], [$this, 'menuSort']);
16064cdf779SAndreas Gohr        uasort($menu['manager'], [$this, 'menuSort']);
16164cdf779SAndreas Gohr        uasort($menu['other'], [$this, 'menuSort']);
1620470c28fSAndreas Gohr
1630470c28fSAndreas Gohr        return $menu;
1640470c28fSAndreas Gohr    }
1650470c28fSAndreas Gohr
16664cdf779SAndreas Gohr    /**
16764cdf779SAndreas Gohr     * Custom sorting for admin menu
16864cdf779SAndreas Gohr     *
16964cdf779SAndreas Gohr     * We sort alphabetically first, then by sort value
17064cdf779SAndreas Gohr     *
17164cdf779SAndreas Gohr     * @param array $a
17264cdf779SAndreas Gohr     * @param array $b
17364cdf779SAndreas Gohr     * @return int
17464cdf779SAndreas Gohr     */
175e2d055f5SAndreas Gohr    protected function menuSort($a, $b)
176e2d055f5SAndreas Gohr    {
1772d85e841SAndreas Gohr        $strcmp = Sort::strcmp($a['prompt'], $b['prompt']);
17864cdf779SAndreas Gohr        if ($strcmp != 0) return $strcmp;
179e2d055f5SAndreas Gohr        return $a['sort'] <=> $b['sort'];
18064cdf779SAndreas Gohr    }
1810470c28fSAndreas Gohr}
182