xref: /dokuwiki/inc/Ui/Admin.php (revision e1d9dcc8b460b6f029ac9c8d5d3b8d23b6e73402)
10470c28fSAndreas Gohr<?php
20470c28fSAndreas Gohrnamespace dokuwiki\Ui;
30470c28fSAndreas Gohr
40470c28fSAndreas Gohr/**
50470c28fSAndreas Gohr * Class Admin
60470c28fSAndreas Gohr *
70470c28fSAndreas Gohr * Displays the Admin screen
80470c28fSAndreas Gohr *
90470c28fSAndreas Gohr * @package dokuwiki\Ui
100470c28fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org>
110470c28fSAndreas Gohr * @author Håkan Sandell <hakan.sandell@home.se>
120470c28fSAndreas Gohr */
130470c28fSAndreas Gohrclass Admin extends Ui {
140470c28fSAndreas Gohr
1564cdf779SAndreas Gohr    protected $forAdmins = array('usermanager', 'acl', 'extension', 'config', 'styling');
1664cdf779SAndreas Gohr    protected $forManagers = array('revert', 'popularity');
1764cdf779SAndreas Gohr    /** @var array[] */
180470c28fSAndreas Gohr    protected $menu;
190470c28fSAndreas Gohr
200470c28fSAndreas Gohr    /**
210470c28fSAndreas Gohr     * Display the UI element
220470c28fSAndreas Gohr     *
230470c28fSAndreas Gohr     * @return void
240470c28fSAndreas Gohr     */
250470c28fSAndreas Gohr    public function show() {
260470c28fSAndreas Gohr        $this->menu = $this->getPluginList();
275d2e38cbSAndreas Gohr        echo '<div class="ui-admin">';
280470c28fSAndreas Gohr        echo p_locale_xhtml('admin');
290470c28fSAndreas Gohr        $this->showSecurityCheck();
3064cdf779SAndreas Gohr        $this->showMenu('admin');
3164cdf779SAndreas Gohr        $this->showMenu('manager');
320470c28fSAndreas Gohr        $this->showVersion();
3364cdf779SAndreas Gohr        $this->showMenu('other');
34713faa94SAndreas Gohr        echo '</div>';
350470c28fSAndreas Gohr    }
360470c28fSAndreas Gohr
370470c28fSAndreas Gohr    /**
3864cdf779SAndreas Gohr     * Show the given menu of available plugins
3964cdf779SAndreas Gohr     *
4064cdf779SAndreas Gohr     * @param string $type admin|manager|other
410470c28fSAndreas Gohr     */
4264cdf779SAndreas Gohr    protected function showMenu($type) {
4364cdf779SAndreas Gohr        if (!$this->menu[$type]) return;
440470c28fSAndreas Gohr
4564cdf779SAndreas Gohr        if ($type === 'other') {
460470c28fSAndreas Gohr            echo p_locale_xhtml('adminplugins');
4764cdf779SAndreas Gohr            $class = 'admin_plugins';
4864cdf779SAndreas Gohr        } else {
4964cdf779SAndreas Gohr            $class = 'admin_tasks';
5064cdf779SAndreas Gohr        }
5164cdf779SAndreas Gohr
5264cdf779SAndreas Gohr        echo "<ul class=\"$class\">";
5364cdf779SAndreas Gohr        foreach ($this->menu[$type] as $item) {
540470c28fSAndreas Gohr            $this->showMenuItem($item);
550470c28fSAndreas Gohr        }
560470c28fSAndreas Gohr        echo '</ul>';
570470c28fSAndreas Gohr    }
580470c28fSAndreas Gohr
590470c28fSAndreas Gohr    /**
600470c28fSAndreas Gohr     * Display the DokuWiki version
610470c28fSAndreas Gohr     */
620470c28fSAndreas Gohr    protected function showVersion() {
630470c28fSAndreas Gohr        echo '<div id="admin__version">';
640470c28fSAndreas Gohr        echo getVersion();
650470c28fSAndreas Gohr        echo '</div>';
660470c28fSAndreas Gohr    }
670470c28fSAndreas Gohr
680470c28fSAndreas Gohr    /**
690470c28fSAndreas Gohr     * data security check
700470c28fSAndreas Gohr     *
710470c28fSAndreas Gohr     * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL
720470c28fSAndreas Gohr     *
730470c28fSAndreas Gohr     * it verifies either:
740470c28fSAndreas Gohr     *   'savedir' has been moved elsewhere, or
750470c28fSAndreas Gohr     *   has protection to prevent the webserver serving files from it
760470c28fSAndreas Gohr     */
770470c28fSAndreas Gohr    protected function showSecurityCheck() {
780470c28fSAndreas Gohr        global $conf;
790470c28fSAndreas Gohr        if(substr($conf['savedir'], 0, 2) !== './') return;
8064159a61SAndreas Gohr        $img = DOKU_URL . $conf['savedir'] .
8164159a61SAndreas Gohr            '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png';
820470c28fSAndreas Gohr        echo '<a style="border:none; float:right;"
830470c28fSAndreas Gohr                href="http://www.dokuwiki.org/security#web_access_security">
8464159a61SAndreas Gohr                <img src="' . $img . '" alt="Your data directory seems to be protected properly."
850470c28fSAndreas Gohr                onerror="this.parentNode.style.display=\'none\'" /></a>';
860470c28fSAndreas Gohr    }
870470c28fSAndreas Gohr
880470c28fSAndreas Gohr    /**
890470c28fSAndreas Gohr     * Display a single Admin menu item
900470c28fSAndreas Gohr     *
910470c28fSAndreas Gohr     * @param array $item
920470c28fSAndreas Gohr     */
930470c28fSAndreas Gohr    protected function showMenuItem($item) {
940470c28fSAndreas Gohr        global $ID;
950470c28fSAndreas Gohr        if(blank($item['prompt'])) return;
960470c28fSAndreas Gohr        echo '<li><div class="li">';
97220b8a20SAndreas Gohr        echo '<a href="' . wl($ID, 'do=admin&amp;page=' . $item['plugin']) . '">';
98220b8a20SAndreas Gohr        echo '<span class="icon">';
994cd2074fSAndreas Gohr        echo inlineSVG($item['icon']);
1000470c28fSAndreas Gohr        echo '</span>';
101220b8a20SAndreas Gohr        echo '<span class="prompt">';
1020470c28fSAndreas Gohr        echo $item['prompt'];
103220b8a20SAndreas Gohr        echo '</span>';
1040470c28fSAndreas Gohr        echo '</a>';
1050470c28fSAndreas Gohr        echo '</div></li>';
1060470c28fSAndreas Gohr    }
1070470c28fSAndreas Gohr
1080470c28fSAndreas Gohr    /**
1090470c28fSAndreas Gohr     * Build  list of admin functions from the plugins that handle them
1100470c28fSAndreas Gohr     *
1110470c28fSAndreas Gohr     * Checks the current permissions to decide on manager or admin plugins
1120470c28fSAndreas Gohr     *
1130470c28fSAndreas Gohr     * @return array list of plugins with their properties
1140470c28fSAndreas Gohr     */
1150470c28fSAndreas Gohr    protected function getPluginList() {
1160470c28fSAndreas Gohr        global $conf;
1170470c28fSAndreas Gohr
1180470c28fSAndreas Gohr        $pluginlist = plugin_list('admin');
11964cdf779SAndreas Gohr        $menu = ['admin' => [], 'manager' => [], 'other' => []];
12064cdf779SAndreas Gohr
1210470c28fSAndreas Gohr        foreach($pluginlist as $p) {
122*e1d9dcc8SAndreas Gohr            /** @var \dokuwiki\Extension\AdminPlugin $obj */
1230470c28fSAndreas Gohr            if(($obj = plugin_load('admin', $p)) === null) continue;
1240470c28fSAndreas Gohr
1250470c28fSAndreas Gohr            // check permissions
12664cdf779SAndreas Gohr            if (!$obj->isAccessibleByCurrentUser()) continue;
1270470c28fSAndreas Gohr
12864cdf779SAndreas Gohr            if (in_array($p, $this->forAdmins, true)) {
12964cdf779SAndreas Gohr                $type = 'admin';
13064cdf779SAndreas Gohr            } elseif (in_array($p, $this->forManagers, true)){
13164cdf779SAndreas Gohr                $type = 'manager';
13264cdf779SAndreas Gohr            } else {
13364cdf779SAndreas Gohr                $type = 'other';
13464cdf779SAndreas Gohr            }
13564cdf779SAndreas Gohr
13664cdf779SAndreas Gohr            $menu[$type][$p] = array(
1370470c28fSAndreas Gohr                'plugin' => $p,
1380470c28fSAndreas Gohr                'prompt' => $obj->getMenuText($conf['lang']),
1390470c28fSAndreas Gohr                'icon' => $obj->getMenuIcon(),
1400470c28fSAndreas Gohr                'sort' => $obj->getMenuSort(),
1410470c28fSAndreas Gohr            );
1420470c28fSAndreas Gohr        }
1430470c28fSAndreas Gohr
1440470c28fSAndreas Gohr        // sort by name, then sort
14564cdf779SAndreas Gohr        uasort($menu['admin'], [$this, 'menuSort']);
14664cdf779SAndreas Gohr        uasort($menu['manager'], [$this, 'menuSort']);
14764cdf779SAndreas Gohr        uasort($menu['other'], [$this, 'menuSort']);
1480470c28fSAndreas Gohr
1490470c28fSAndreas Gohr        return $menu;
1500470c28fSAndreas Gohr    }
1510470c28fSAndreas Gohr
15264cdf779SAndreas Gohr    /**
15364cdf779SAndreas Gohr     * Custom sorting for admin menu
15464cdf779SAndreas Gohr     *
15564cdf779SAndreas Gohr     * We sort alphabetically first, then by sort value
15664cdf779SAndreas Gohr     *
15764cdf779SAndreas Gohr     * @param array $a
15864cdf779SAndreas Gohr     * @param array $b
15964cdf779SAndreas Gohr     * @return int
16064cdf779SAndreas Gohr     */
16164cdf779SAndreas Gohr    protected function menuSort($a, $b) {
16264cdf779SAndreas Gohr        $strcmp = strcasecmp($a['prompt'], $b['prompt']);
16364cdf779SAndreas Gohr        if($strcmp != 0) return $strcmp;
16464cdf779SAndreas Gohr        if($a['sort'] === $b['sort']) return 0;
16564cdf779SAndreas Gohr        return ($a['sort'] < $b['sort']) ? -1 : 1;
16664cdf779SAndreas Gohr    }
1670470c28fSAndreas Gohr}
168