1<?php
2/**
3 * DokuWiki Plugin groupadmin (Admin Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  James Phillpotts <james.dokuwiki@potes.org.uk>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11
12if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
13if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
14if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
15
16require_once DOKU_PLUGIN.'admin.php';
17
18class admin_plugin_groupadmin extends DokuWiki_Admin_Plugin {
19
20    var $_auth = null;
21    var $_group_name = '';
22
23    /**
24     * Constructor
25     */
26    function admin_plugin_groupadmin(){
27        global $auth;
28
29        $this->setupLocale();
30
31        if (!isset($auth)) {
32            $this->disabled = $this->lang['noauth'];
33        } else if (!$auth->canDo('getUsers')) {
34            $this->disabled = $this->lang['nosupport'];
35        } else {
36
37            // we're good to go
38            $this->_auth = & $auth;
39
40        }
41    }
42
43    /**
44     * return some info
45     */
46    function getInfo(){
47        $info = parent::getInfo();
48        $info['desc'] = $info['desc'].' '.$this->disabled;
49        return $info;
50    }
51
52    public function getMenuSort() { return 3; }
53
54    /**
55     * return prompt for admin menu
56     */
57    function getMenuText($language) {
58        if (!is_null($this->_auth))
59        return parent::getMenuText($language);
60
61        return $this->getLang('title').' '.$this->disabled;
62    }
63
64    public function forAdminOnly() { return true; }
65
66    public function handle() {
67        global $ID;
68
69        if (!isset($_REQUEST['cmd'])) return;   // first time - nothing to do
70
71        $this->output = 'invalid';
72        if (!checkSecurityToken()) return;
73        if (!is_array($_REQUEST['cmd'])) return;
74
75        if (is_null($this->_auth)) return false;
76
77        if (is_array($fn)) {
78            $cmd = key($fn);
79            $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null;
80        } else {
81            $cmd = $fn;
82            $param = null;
83        }
84
85        switch (key($_REQUEST['cmd'])) {
86            case 'save' :
87                $this->_group_name = $_REQUEST['groupname'];
88                $this->_saveGroup($param);
89                $this->_group_name = null;
90                break;
91            case 'load' :
92                $this->_group_name = $_REQUEST['groupname'];
93                break;
94        }
95    }
96
97    public function html() {
98        $all_users = $this->_auth->retrieveUsers();
99        if ($this->_auth->canDo("getGroups")) {
100            $group_list = $this->_auth->retrieveGroups();
101        } else {
102            $group_list = array();
103            foreach ($all_users as $user => $userinfo) {
104                extract($userinfo);
105                $group_list = array_merge($group_list, $grps);
106            }
107            $group_list = array_unique($group_list);
108        }
109
110        ptln('<p>'.htmlspecialchars($this->getLang('description')).'</p>');
111
112        ptln('<form action="'.wl($ID).'" method="post">');
113
114        // output hidden values to ensure dokuwiki will return back to this plugin
115        ptln('  <input type="hidden" name="do"   value="admin" />');
116        ptln('  <input type="hidden" name="page" value="'.$this->getPluginName().'" />');
117        formSecurityToken();
118
119        ptln('  <label for="groupname">'.$this->getLang('selectgroup').'</label>');
120        ptln('  <select id="groupname" name="groupname">');
121        ptln('    <option value="">'.$this->getLang('blankgroup').'</option>');
122        foreach ($group_list as $group) {
123            if ($this->_group_name == $group) {
124                ptln('    <option value="'.$group.'" selected="selected">'.$group.'</option>');
125            } else {
126                ptln('    <option value="'.$group.'">'.$group.'</option>');
127            }
128        }
129
130        ptln('  </select>');
131        ptln('  <input type="submit" name="cmd[load]"  value="'.$this->getLang('btn_load').'" /><br/><br/>');
132        if ($this->_group_name) {
133            ptln('  <div>');
134            $filter = array();
135            $filter['grps'] = $this->_group_name;
136            $users_in_group = $this->_auth->retrieveUsers(0, -1, $filter);
137
138            ptln('<table><tr><td>');
139            ptln('    <select id="allusers" class="groupadminselection" multiple="multiple" size="20" ondblclick="add()">');
140            foreach ($all_users as $user => $userinfo) {
141                extract($userinfo);
142                if (!in_array($userinfo, $users_in_group)) {
143                    ptln('    <option value="'.$user.'">'.$userinfo['name'].' ('.$user.')</option>');
144                }
145            }
146            ptln('    </select>');
147            ptln('</td><td>');
148            ptln('    <button type="button" class="groupadminselection" onclick="add()">'.$this->getLang('btn_add').'</button><br/>');
149            ptln('    <button type="button" class="groupadminselection" onclick="addall()">'.$this->getLang('btn_addall').'</button><br/>');
150            ptln('    <button type="button" class="groupadminselection" onclick="remove()">'.$this->getLang('btn_remove').'</button><br/>');
151            ptln('    <button type="button" class="groupadminselection" onclick="removeall()">'.$this->getLang('btn_removeall').'</button>');
152            ptln('</td><td>');
153            ptln('    <select id="groupusers" class="groupadminselection" multiple="multiple" size="20" ondoubleclick="remove()">');
154            foreach ($users_in_group as $user => $userinfo) {
155                ptln('    <option value="'.$user.'">'.$userinfo['name'].' ('.$user.')</option>');
156            }
157            ptln('    </select>');
158            ptln('</td></tr></table>');
159
160            foreach ($all_users as $user => $userinfo) {
161                extract($userinfo);
162                if (in_array($userinfo, $users_in_group)) {
163                    ptln('  <input type="hidden" name="users[]" id="users.'.$user.'" value="'.$user.'"/>');
164                } else {
165                    ptln('  <input type="hidden" id="users.'.$user.'" value="'.$user.'"/>');
166                }
167            }
168
169            ptln('  <noscript>');
170            ptln('  <style>table { display:none; }</style>');
171            foreach ($all_users as $user => $userinfo) {
172                extract($userinfo);
173                if (in_array($userinfo, $users_in_group)) {
174                    ptln('  <input type="checkbox" name="noscriptusers[]" id="noscript.'.$user.'" value="'.$user.'" checked="checked"/>');
175                } else {
176                    ptln('  <input type="checkbox" name="noscriptusers[]" id="noscript.'.$user.'" value="'.$user.'" />');
177                                    }
178                ptln('<label for="noscript.'.$user.'">'.$userinfo['name'].' ('.$user.')</label><br/>');
179            }
180            ptln('  </noscript>');
181
182            ptln('  <input type="submit" name="cmd[save]"  value="'.$this->getLang('btn_save').'" />');
183            ptln('  <div>');
184        }
185        ptln('</form>');
186    }
187
188    function _saveGroup() {
189        if ($_POST['noscriptusers']) {
190            $usernames = $_POST['noscriptusers'];
191        } else {
192            $usernames = $_POST['users'];
193        }
194
195        $group_filter = array();
196        $group_filter['grps'] = $this->_group_name;
197        $oldusersinfo = $this->_auth->retrieveUsers(0, -1, $group_filter);
198        $oldusers = array_keys($this->_auth->retrieveUsers(0, -1, $group_filter));
199        $removed_users = array();
200        foreach ($oldusers as $olduser) {
201            if (!in_array($olduser, $usernames)) {
202                $newgrps = array();
203                extract($oldusersinfo[$olduser]);
204                foreach($grps as $grpname) {
205                    if ($grpname != $this->_group_name) {
206                        array_push($newgrps, $grpname);
207                    }
208                }
209                $this->_modifyUser($olduser, $newgrps);
210            }
211        }
212
213        foreach ($usernames as $newuser) {
214            if (!in_array($newuser, $oldusers)) {
215                $newuserinfo = $this->_auth->getUserData($newuser);
216                array_push($newuserinfo['grps'],$this->_group_name);
217                $this->_modifyUser($newuser, $newuserinfo['grps']);
218            }
219        }
220        msg($this->lang['update_ok'],1);
221    }
222
223    function _modifyUser($username, $newgrps) {
224        $changes = array();
225        $changes['grps'] = $newgrps;
226        $this->_auth->triggerUserMod('modify', array($username, $changes));
227    }
228}
229