Page 1 of 1

Restricted Adminmenu for users

Posted: Sun Feb 26, 2017 1:24 pm
by cmb
There's also German documentation about this.

While CMSimple_XH is not supposed to be a multi-user system, it is sometimes desirable to differentiate between a user who should not have access to the full administration, and the admin who should. This is basically impossible without making modifications throughout the code base, but sometimes a simple workaround may be sufficient.

This workaround is showing only a restricted adminmenu to the user, but let the admin have access to the full adminmenu. This can be implemented rather easily by using the possibility to use a custom adminmenu (what is available as of CMSimple_XH 1.6).

I'm offering an example. Put the following code into cmsimple/userfuncs.php:

Code: Select all

<?php

function custom_adminmenu($plugins = array())
{
    if (isset($_GET['real_admin']) || isset($_COOKIE['real_admin'])) {
        setcookie('real_admin', 1, 0);
        return XH_adminMenu($plugins);
    } else {
        return user_adminMenu($plugins);
    }
}

function user_adminMenu($plugins = array())
{
    global $sn, $edit, $s, $u, $cf, $tx, $su, $plugin_tx;

    if ($s < 0) {
        $su = $u[0];
    }
    $changeMode = $edit ? 'normal' : 'edit';
    $changeText = $edit ? $tx['editmenu']['normal'] : $tx['editmenu']['edit'];

    $filesMenu = array();
    foreach (array('images', 'downloads', 'media') as $item) {
        $filesMenu[] =  array(
            'label' => utf8_ucfirst($tx['editmenu'][$item]),
            'url' => $sn . '?&normal&' . $item
        );
    }
    $settingsMenu = array(
        array(
            'label' => utf8_ucfirst($tx['editmenu']['configuration']),
            'url' => $sn . '?file=config&action=array'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['language']),
            'url' => $sn . '?file=language&action=array'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['template']),
            'url' => $sn . '?file=template&action=edit'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['stylesheet']),
            'url' => $sn . '?file=stylesheet&action=edit'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['log']),
            'url' => $sn . '?file=log&action=view'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['validate']),
            'url' => $sn . '?&validate'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['backups']),
            'url' => $sn . '?&xh_backups'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['pagedata']),
            'url' => $sn . '?&xh_pagedata'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['sysinfo']),
            'url' => $sn . '?&sysinfo'
        )
    );
    $hiddenPlugins = explode(',', $cf['plugins']['hidden']);
    $hiddenPlugins = array_map('trim', $hiddenPlugins);
    $plugins = array_diff($plugins, $hiddenPlugins);
    $total = count($plugins);
    $rows = 12;
    $columns = ceil($total / $rows);
    $rows = ceil($total / $columns);
    $width = 125 * $columns;
    $marginLeft = min($width, 250) - $width;
    natcasesort($plugins);
    $plugins = array_values($plugins);
    $orderedPlugins = array();
    for ($j = 0; $j < $rows; ++$j) {
        for ($i = 0; $i < $total; $i += $rows) {
            $orderedPlugins[] = isset($plugins[$i + $j]) ? $plugins[$i + $j] : '';
        }
    }
    $plugins = $orderedPlugins;
    $pluginMenu = array();
    foreach ($plugins as $plugin) {
        $label = isset($plugin_tx[$plugin]['menu_plugin'])
            ? $plugin_tx[$plugin]['menu_plugin']
            : ucfirst($plugin);
        $pluginMenuItem = array('label' => $label);
        if ($plugin != '') {
            $pluginMenuItem['url'] = $sn . '?' . $plugin . '&normal';
            foreach (XH_registerPluginMenuItem($plugin) as $item) {
                $pluginMenuItem['children'][] = $item;
            }
        }
        $pluginMenu[] = $pluginMenuItem;
    }
    $menu = array(
        array(
            'label' => $changeText,
            'url' => $sn . '?' . $su . '&' . $changeMode,
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['pagemanager']),
            'url' => $sn . '?&normal&xhpages'
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['files']),
            'url' => $sn . '?&normal&userfiles',
            'children' => $filesMenu
            ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['plugins']),
            'url' => $sn, // TODO: use more sensible URL
            'id' => 'xh_adminmenu_plugins',
            'children' => array()
        ),
        array(
            'label' => utf8_ucfirst($tx['editmenu']['logout']),
            'url' => $sn . '?&logout'
        )
    );

    $t = "\n" . '<div id="xh_adminmenu">';
    $t .= "\n" . '<ul>' . "\n";
    foreach ($menu as $item) {
        $t .= XH_adminMenuItem($item);
    }
    $t .= '</ul>' . "\n"
        . '<div class="xh_break"></div>' . "\n" . '</div>' . "\n";
    return $t;
}
 
Then modifiy cmsimple/config.php and replace the following line:

Code: Select all

$cf['editmenu']['external']="";
with:

Code: Select all

$cf['editmenu']['external']="custom_adminmenu";
After login, the "Settings" menu is completely gone, and the "Plugins" menu doesn't show any plugins. If you want to switch to the "real_admin" mode, just browse to your site with the respective query string appended, e.g. http://example.com/?real_admin. Then you have access to the full admin menu, and also a cookie will be set, so that you don't have to enter the ?real_admin over and over again. The cookie will be valid until you close the browser.

Of course it is possible to further modify the restricted admin menu; see function custom_adminmenu() (in cmsimple/userfuncs.php) which is basically a slightly modified copy of XH_adminMenu() (in cmsimple/adminfuncs.php). The code is supposed to be somewhat self-explaining.

Important note: even if the user can't see some menu items, they still can browse to the hidden functionality by manually entering the appropriate URL in the browser's address bar!