1<?php 2 3namespace dokuwiki\Ui; 4 5use dokuwiki\Extension\AdminPlugin; 6use dokuwiki\Extension\PluginInterface; 7use dokuwiki\Utf8\Sort; 8 9/** 10 * Class Admin 11 * 12 * Displays the Admin screen 13 * 14 * @package dokuwiki\Ui 15 * @author Andreas Gohr <andi@splitbrain.org> 16 * @author Håkan Sandell <hakan.sandell@home.se> 17 */ 18class Admin extends Ui 19{ 20 protected $forAdmins = ['usermanager', 'acl', 'extension', 'config', 'logviewer', 'styling']; 21 protected $forManagers = ['revert', 'popularity']; 22 /** @var array[] */ 23 protected $menu; 24 25 /** 26 * Display the UI element 27 * 28 * @return void 29 */ 30 public function show() 31 { 32 $this->menu = $this->getPluginList(); 33 echo '<div class="ui-admin">'; 34 echo p_locale_xhtml('admin'); 35 36 $this->showMenu('admin'); 37 $this->showMenu('manager'); 38 $this->showSecurityCheck(); 39 $this->showVersion(); 40 $this->showMenu('other'); 41 echo '</div>'; 42 } 43 44 /** 45 * Show the given menu of available plugins 46 * 47 * @param string $type admin|manager|other 48 */ 49 protected function showMenu($type) 50 { 51 if (!$this->menu[$type]) return; 52 53 if ($type === 'other') { 54 echo p_locale_xhtml('adminplugins'); 55 $class = 'admin_plugins'; 56 } else { 57 $class = 'admin_tasks'; 58 } 59 60 echo "<ul class=\"$class\">"; 61 foreach ($this->menu[$type] as $item) { 62 $this->showMenuItem($item); 63 } 64 echo '</ul>'; 65 } 66 67 /** 68 * Display the DokuWiki version 69 */ 70 protected function showVersion() 71 { 72 echo '<div id="admin__version">'; 73 echo getVersion(); 74 echo '<br>'; 75 echo implode('<br>', array_map('hsc', array_values(getRuntimeVersions()))); 76 echo '</div>'; 77 } 78 79 /** 80 * data security check 81 * 82 * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL 83 * 84 * it verifies either: 85 * 'savedir' has been moved elsewhere, or 86 * has protection to prevent the webserver serving files from it 87 * 88 * The actual check is carried out via JavaScript. See behaviour.js 89 */ 90 protected function showSecurityCheck() 91 { 92 global $conf; 93 if (!str_starts_with($conf['savedir'], './')) return; 94 $img = DOKU_URL . $conf['savedir'] . 95 '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png'; 96 echo '<div id="security__check" data-src="' . $img . '"></div>'; 97 } 98 99 /** 100 * Display a single Admin menu item 101 * 102 * @param array $item 103 */ 104 protected function showMenuItem($item) 105 { 106 global $ID; 107 if (blank($item['prompt'])) return; 108 echo '<li><div class="li">'; 109 echo '<a href="' . wl($ID, 'do=admin&page=' . $item['plugin']) . '">'; 110 echo '<span class="icon">'; 111 echo inlineSVG($item['icon']); 112 echo '</span>'; 113 echo '<span class="prompt">'; 114 echo $item['prompt']; 115 echo '</span>'; 116 echo '</a>'; 117 echo '</div></li>'; 118 } 119 120 /** 121 * Build list of admin functions from the plugins that handle them 122 * 123 * Checks the current permissions to decide on manager or admin plugins 124 * 125 * @return array list of plugins with their properties 126 */ 127 protected function getPluginList() 128 { 129 global $conf; 130 131 $pluginlist = plugin_list('admin'); 132 $menu = ['admin' => [], 'manager' => [], 'other' => []]; 133 134 foreach ($pluginlist as $p) { 135 /** @var AdminPlugin $obj */ 136 if (!($obj = plugin_load('admin', $p)) instanceof PluginInterface) continue; 137 138 // check permissions 139 if (!$obj->isAccessibleByCurrentUser()) continue; 140 if (!$obj->showInMenu()) continue; 141 142 if (in_array($p, $this->forAdmins, true)) { 143 $type = 'admin'; 144 } elseif (in_array($p, $this->forManagers, true)) { 145 $type = 'manager'; 146 } else { 147 $type = 'other'; 148 } 149 150 $menu[$type][$p] = [ 151 'plugin' => $p, 152 'prompt' => $obj->getMenuText($conf['lang']), 153 'icon' => $obj->getMenuIcon(), 154 'sort' => $obj->getMenuSort() 155 ]; 156 } 157 158 // sort by name, then sort 159 uasort($menu['admin'], [$this, 'menuSort']); 160 uasort($menu['manager'], [$this, 'menuSort']); 161 uasort($menu['other'], [$this, 'menuSort']); 162 163 return $menu; 164 } 165 166 /** 167 * Custom sorting for admin menu 168 * 169 * We sort alphabetically first, then by sort value 170 * 171 * @param array $a 172 * @param array $b 173 * @return int 174 */ 175 protected function menuSort($a, $b) 176 { 177 $strcmp = Sort::strcmp($a['prompt'], $b['prompt']); 178 if ($strcmp != 0) return $strcmp; 179 return $a['sort'] <=> $b['sort']; 180 } 181} 182