function wikiplugin_memberlist($data, $params)
{
    global $prefs;
    static $execution = 0;
    $key = 'memberlist-execution-' . ++$execution;
    if (!isset($params['groups'])) {
        return "^Missing group list^";
    }
    $groups = $params['groups'];
    Perms::bulk(array('type' => 'group'), 'object', $groups);
    $validGroups = wikiplugin_memberlist_get_group_details($groups);
    if (isset($_POST[$key])) {
        if (isset($_POST['join'])) {
            wikiplugin_memberlist_join($validGroups, $_POST['join']);
        }
        if (isset($_POST['leave'])) {
            wikiplugin_memberlist_leave($validGroups, $_POST['leave']);
        }
        if (isset($_POST['remove'])) {
            wikiplugin_memberlist_remove($validGroups, $_POST['remove']);
        }
        if (isset($_POST['add'])) {
            wikiplugin_memberlist_add($validGroups, $_POST['add']);
        }
        header('Location: ' . $_SERVER['REQUEST_URI']);
        exit;
    }
    if (isset($_REQUEST['transition'], $_REQUEST['member'])) {
        if ($prefs['feature_group_transition'] == 'y') {
            require_once 'lib/transitionlib.php';
            $transitionlib = new TransitionLib('group');
            $transitionlib->triggerTransition($_REQUEST['transition'], $_REQUEST['member']);
            $url = $_SERVER['REQUEST_URI'];
            $url = str_replace('transition=', 'x=', $url);
            $url = str_replace('member=', 'x=', $url);
            header('Location: ' . $url);
            exit;
        }
    }
    $canApply = false;
    foreach ($validGroups as $group) {
        if ($group['can_add'] || $group['can_remove'] || $group['can_join'] || $group['can_leave']) {
            $canApply = true;
            break;
        }
    }
    global $smarty;
    $smarty->assign('execution_key', $key);
    $smarty->assign('can_apply', $canApply);
    $smarty->assign('memberlist_groups', $validGroups);
    return '~np~' . $smarty->fetch('wiki-plugins/wikiplugin_memberlist.tpl') . '~/np~';
}
function wikiplugin_memberlist($data, $params)
{
    global $prefs, $userlib, $user;
    static $execution = 0;
    $exec_key = 'memberlist-execution-' . ++$execution;
    if (!isset($params['groups'])) {
        return "^Missing group list^";
    }
    $groups = $params['groups'];
    $defaults = array();
    $plugininfo = wikiplugin_memberlist_info();
    foreach ($plugininfo['params'] as $key => $param) {
        $defaults["{$key}"] = $param['default'];
    }
    $params = array_merge($defaults, $params);
    if ($prefs['feature_user_watches'] == 'y') {
        if (!empty($user)) {
            $tikilib = TikiLib::lib('tiki');
            if (isset($_REQUEST['watch'])) {
                $tikilib->add_user_watch($user, 'user_joins_group', $_REQUEST['watch'], 'group');
            } else {
                if (isset($_REQUEST['unwatch'])) {
                    $tikilib->remove_user_watch($user, 'user_joins_group', $_REQUEST['unwatch'], 'group');
                }
            }
        }
    }
    if (count($groups) === 1 && $groups[0] === '*') {
        // all available
        $groups = $userlib->list_all_groups();
    }
    if (!empty($params['membersOnly'])) {
        if ($params['membersOnly'] === '%user%') {
            $params['membersOnly'] = $GLOBALS['user'];
        }
        $usergroups = $userlib->get_user_groups($params['membersOnly']);
        $in_group = array();
        foreach ($groups as $group) {
            if (in_array($group, $usergroups) && $group != 'Anonymous') {
                $in_group[] = $group;
            }
        }
        $groups = $in_group;
        unset($in_group);
    }
    if (!empty($params['including'])) {
        $includinggroups = $userlib->get_including_groups($params['including']);
        $in_group = array();
        foreach ($groups as $group) {
            if (in_array($group, $includinggroups)) {
                $in_group[] = $group;
            }
        }
        $groups = $in_group;
        unset($in_group);
    }
    Perms::bulk(array('type' => 'group'), 'object', $groups);
    if ($params['readOnly'] == 'y') {
        $readOnly = true;
    } else {
        $readOnly = false;
    }
    $validGroups = wikiplugin_memberlist_get_group_details($groups, $params['max'], $params['sort_mode'], $readOnly);
    if (isset($_POST[$exec_key])) {
        if (isset($_POST['join'])) {
            wikiplugin_memberlist_join($validGroups, $_POST['join']);
        }
        if (isset($_POST['leave'])) {
            wikiplugin_memberlist_leave($validGroups, $_POST['leave']);
        }
        if (isset($_POST['remove'])) {
            wikiplugin_memberlist_remove($validGroups, $_POST['remove']);
        }
        if (isset($_POST['add'])) {
            wikiplugin_memberlist_add($validGroups, $_POST['add']);
        }
        if (isset($_POST['defgroup'])) {
            wikiplugin_memberlist_add($validGroups, $_POST['defgroup'], true);
        }
        header('Location: ' . $_SERVER['REQUEST_URI']);
        exit;
    }
    if (isset($_REQUEST['transition'], $_REQUEST['member'])) {
        if ($prefs['feature_group_transition'] == 'y') {
            require_once 'lib/transitionlib.php';
            $transitionlib = new TransitionLib('group');
            $transitionlib->triggerTransition($_REQUEST['transition'], $_REQUEST['member']);
            $url = $_SERVER['REQUEST_URI'];
            $url = str_replace('transition=', 'x=', $url);
            $url = str_replace('member=', 'x=', $url);
            header('Location: ' . $url);
            exit;
        }
    }
    $canApply = false;
    foreach ($validGroups as $group) {
        if ($group['can_add'] || $group['can_remove'] || $group['can_join'] || $group['can_leave']) {
            $canApply = true;
            break;
        }
    }
    if ($params['showDescriptions'] === 'y') {
        foreach ($validGroups as $name => &$group) {
            $group['info'] = $userlib->get_group_info($name);
        }
    }
    global $smarty;
    $smarty->assign('execution_key', $exec_key);
    $smarty->assign('can_apply', $canApply);
    $smarty->assign('defaultGroup', $params['defaultGroup']);
    $smarty->assign('memberlist_groups', $validGroups);
    $smarty->assign('displayMode', $params['displayMode']);
    // seems conditionally adding tabs in the tpl doesn't work (unclosed {tabset} errors etc) - a Smarty 3 change?
    if (empty($params['displayMode']) && $prefs['feature_tabs'] === 'y') {
        $oldTabs = $prefs['feature_tabs'];
        $prefs['feature_tabs'] = 'n';
        // css workarounds for when in non tabs mode
        TikiLib::lib('header')->add_css('.memberlist > fieldset { border: none; margin:  0; padding:  0; }
			.memberlist > fieldset > legend { display: none; }');
    }
    $out = '~np~' . $smarty->fetch('wiki-plugins/wikiplugin_memberlist.tpl') . '~/np~';
    if (empty($params['displayMode']) && !empty($oldTabs)) {
        $prefs['feature_tabs'] = $oldTabs;
    }
    return $out;
}
function wikiplugin_memberlist($data, $params)
{
    global $prefs, $user, $page;
    $mail = false;
    $tikilib = TikiLib::lib('tiki');
    $userlib = TikiLib::lib('user');
    $smarty = TikiLib::lib('smarty');
    static $execution = 0;
    $exec_key = 'memberlist-execution-' . ++$execution;
    if (!isset($params['groups'])) {
        return "^Missing group list^";
    }
    $groups = $params['groups'];
    $defaults = array();
    $plugininfo = wikiplugin_memberlist_info();
    foreach ($plugininfo['params'] as $key => $param) {
        $defaults["{$key}"] = $param['default'];
    }
    $params = array_merge($defaults, $params);
    if ($prefs['feature_user_watches'] == 'y') {
        if (!empty($user)) {
            if (isset($_REQUEST['watch'])) {
                $tikilib->add_user_watch($user, 'user_joins_group', $_REQUEST['watch'], 'group');
            } else {
                if (isset($_REQUEST['unwatch'])) {
                    $tikilib->remove_user_watch($user, 'user_joins_group', $_REQUEST['unwatch'], 'group');
                }
            }
        }
    }
    if (count($groups) === 1 && $groups[0] === '*') {
        // all available
        $groups = $userlib->list_all_groups();
    }
    if (!empty($params['membersOnly'])) {
        if ($params['membersOnly'] === '%user%') {
            $params['membersOnly'] = $GLOBALS['user'];
        }
        $usergroups = $userlib->get_user_groups($params['membersOnly']);
        $in_group = array();
        foreach ($groups as $group) {
            if (in_array($group, $usergroups) && $group != 'Anonymous') {
                $in_group[] = $group;
            }
        }
        $groups = $in_group;
        unset($in_group);
    }
    if (!empty($params['including'])) {
        $includinggroups = $userlib->get_including_groups($params['including']);
        $in_group = array();
        foreach ($groups as $group) {
            if (in_array($group, $includinggroups)) {
                $in_group[] = $group;
            }
        }
        $groups = $in_group;
        unset($in_group);
    }
    if ($params['addon_groups_approval_buttons'] == 'y') {
        $pageInfo = $tikilib->get_page_info($page);
        $pageLang = $pageInfo['lang'];
        $api = new TikiAddons_Api_Group();
        $group_base = $api->getOrganicGroupBaseName($params['groups'][0]);
        $smarty->assign('mail_group', $group_base);
        $itemId = $api->getItemIdFromToken($params['groups'][0]);
        $smarty->assign('mail_organicgroup_id', $itemId);
        $userid = "user" . $userlib->get_user_id($user);
        $smarty->assign('mail_userid', $userid);
        $smarty->assign('mail_url', $api->getGroupHomePage($params['groups'][0]) . '?itemId=' . $itemId);
        $foo = parse_url($_SERVER["REQUEST_URI"]);
        $machine = $tikilib->httpPrefix(true) . dirname($foo["path"]);
        if (substr($machine, -1) == '/') {
            $machine = substr($machine, 0, -1);
        }
        $smarty->assign('mail_machine', $machine);
        $file_wel = $smarty->fetchLang($pageLang, "mail/admin_approval_user_joins_group_notification.tpl");
        $file_rej = $smarty->fetchLang($pageLang, "mail/admin_rejection_user_group_notification.tpl");
        $smarty->assign('welcome_content', $file_wel);
        $smarty->assign('reject_content', $file_rej);
        $smarty->assign('Need_app', $exec_key);
    } else {
        $smarty->assign('Need_app', '');
    }
    Perms::bulk(array('type' => 'group'), 'object', $groups);
    if ($params['readOnly'] == 'y') {
        $readOnly = true;
    } else {
        $readOnly = false;
    }
    $validGroups = wikiplugin_memberlist_get_group_details($groups, $params['max'], $params['sort_mode'], $readOnly);
    if (isset($_POST[$exec_key])) {
        if (isset($_POST['join'])) {
            wikiplugin_memberlist_join($validGroups, $_POST['join']);
        }
        if (isset($_POST['leave'])) {
            wikiplugin_memberlist_leave($validGroups, $_POST['leave']);
        }
        if (isset($_POST['remove'])) {
            if (isset($params['email_to_removed_user']) && $params['email_to_removed_user'] == 'y' || isset($_POST['text_area'])) {
                $mail = 'true';
            }
            wikiplugin_memberlist_remove($validGroups, $_POST['remove'], $mail, $params);
        }
        if (isset($_POST['add'])) {
            $addit = array();
            foreach ($_POST['add'] as $key => $value) {
                if ($params['addon_groups_approval_buttons'] == 'y') {
                    $basegroup = $api->getOrganicGroupBaseToken($key);
                    $valgroup[] = $basegroup;
                    $addit['add'][$basegroup] = $value;
                    $removeit['add'][$api->getOrganicGroupPendingToken($key)][] = $value;
                } else {
                    $valgroup[] = $key;
                    $addit['add'][$key] = $value;
                }
            }
            if (isset($params['email_to_added_user']) && $params['email_to_added_user'] == 'y' || isset($_POST['text_area'])) {
                $mail = 'true';
            }
            $validrem = wikiplugin_memberlist_get_group_details($valgroup, $params['max'], $params['sort_mode'], $readOnly);
            if ($params['addon_groups_approval_buttons'] == 'y' && isset($removeit['add'])) {
                wikiplugin_memberlist_remove($validGroups, $removeit['add'], 'false', $params);
            }
            wikiplugin_memberlist_add($validrem, $addit['add'], '', $mail, $params);
        }
        if (isset($_POST['defgroup'])) {
            wikiplugin_memberlist_add($validGroups, $_POST['defgroup'], true);
        }
        header('Location: ' . $_SERVER['REQUEST_URI']);
        exit;
    }
    if (isset($_REQUEST['transition'], $_REQUEST['member'])) {
        if ($prefs['feature_group_transition'] == 'y') {
            require_once 'lib/transitionlib.php';
            $transitionlib = new TransitionLib('group');
            $transitionlib->triggerTransition($_REQUEST['transition'], $_REQUEST['member']);
            $url = $_SERVER['REQUEST_URI'];
            $url = str_replace('transition=', 'x=', $url);
            $url = str_replace('member=', 'x=', $url);
            header('Location: ' . $url);
            exit;
        }
    }
    $canApply = false;
    foreach ($validGroups as $group) {
        if ($group['can_add'] || $group['can_remove'] || $group['can_join'] || $group['can_leave']) {
            $canApply = true;
            break;
        }
    }
    if ($params['showDescriptions'] === 'y') {
        foreach ($validGroups as $name => &$group) {
            $group['info'] = $userlib->get_group_info($name);
        }
    }
    $smarty = TikiLib::lib('smarty');
    $smarty->assign('execution_key', $exec_key);
    $smarty->assign('can_apply', $canApply);
    $smarty->assign('defaultGroup', $params['defaultGroup']);
    $smarty->assign('memberlist_groups', $validGroups);
    $smarty->assign('displayMode', $params['displayMode']);
    // seems conditionally adding tabs in the tpl doesn't work (unclosed {tabset} errors etc) - a Smarty 3 change?
    if (empty($params['displayMode']) && $prefs['feature_tabs'] === 'y') {
        $oldTabs = $prefs['feature_tabs'];
        $prefs['feature_tabs'] = 'n';
        // css workarounds for when in non tabs mode
        TikiLib::lib('header')->add_css('.memberlist > fieldset { border: none; margin:  0; padding:  0; }
			.memberlist > fieldset > legend { display: none; }');
    }
    $out = '~np~' . $smarty->fetch('wiki-plugins/wikiplugin_memberlist.tpl') . '~/np~';
    if (empty($params['displayMode']) && !empty($oldTabs)) {
        $prefs['feature_tabs'] = $oldTabs;
    }
    return $out;
}