1<?php
2
3if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
4if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
5require_once(DOKU_PLUGIN.'admin.php');
6require_once(DOKU_INC.'inc/common.php');
7
8class admin_plugin_virtualgroup extends DokuWiki_Admin_Plugin {
9
10    var $users;
11    var $groups;
12    var $_auth = null;        // auth object
13
14    var $editgroup = false;
15    var $edit = false;
16
17    var $data = array();
18
19    function admin_plugin_virtualgroup () {
20        global $auth;
21
22        $this->setupLocale();
23
24        if (isset($auth)) {
25
26           // we're good to go
27          $this->_auth = & $auth;
28
29        }
30
31    }
32
33    function getInfo(){
34        return confToHash(dirname(__FILE__).'/plugin.info.txt');
35    }
36
37    function getMenuSort() {
38      return 999;
39    }
40
41    /**
42     * handle user request
43     */
44    function handle() {
45        global $auth;
46        $this->_load();
47
48        $act  = $_REQUEST['cmd'];
49        $uid  = $_REQUEST['uid'];
50        switch ($act) {
51            case 'del' :$this->del($uid);break;
52            case 'edit':$this->edit($uid);break;
53            case 'add' :$this->add($uid);break;
54            case 'addgroup':$this->addgroup($uid);break;
55            case 'editgroup':$this->editgroup($uid);break;
56            case 'delgroup' :$this->delgroup($uid);break;
57        }
58
59    }
60
61    function edit($user) {
62        if (!checkSecurityToken()) return false;
63        $grp = array();
64        // on input change the data
65        if (isset($_REQUEST['grp']) && isset($this->users[$user])) {
66
67            $grp = $_REQUEST['grp'];
68
69            // get the groups as array
70            $grp = str_replace(' ','',$grp);
71            $grps = array_unique(explode(',',$grp));
72            $this->users[$user] = $grps;
73            $this->_save();
74            return;
75        } else {
76            $grp = $this->users[$user];
77        }
78
79        // go to edit mode ;-)
80        $this->edit = true;
81        $this->data['user'] = $user;
82        $this->data['grp'] = $grp;
83    }
84
85    function editgroup($group) {
86        if (!checkSecurityToken()) return false;
87
88        // on input change the data
89        if (isset($_REQUEST['users']) && isset($this->groups[$group])) {
90
91            // get the users as array
92            $users = str_replace(' ','',$_REQUEST['users']);
93            $users = array_unique(explode(',',$users));
94
95            // delete removed users from group
96            foreach (array_diff($this->groups[$group],$users) as $user) {
97                $idx = array_search($group,$this->users[$user]);
98                if ($idx !== false) {
99                    unset($this->users[$user][$idx]);
100                    $this->users[$user]=array_values($this->users[$user]);
101                    if (!count($this->users[$user])) {
102                        unset($this->users[$user]);
103                    }
104                }
105            }
106
107            // add new users to group
108            foreach (array_diff($users,$this->groups[$group]) as $user) {
109                if ($user && (!isset($this->users[$user]) || !in_array($group,$this->users[$user]))) {
110                    $this->users[$user][] = $group;
111                }
112            }
113            $this->_save();
114            return;
115        }
116
117        // go to edit mode ;-)
118        $this->editgroup = true;
119        $this->data['users'] = $this->groups[$group];
120        $this->data['group'] = $group;
121    }
122
123    function del($user) {
124        if (!checkSecurityToken()) return false;
125        // user don't exist
126        if (!$this->users[$user]) {
127            return;
128        }
129
130        // delete the user
131        unset($this->users[$user]);
132        $this->_save();
133    }
134
135    function delgroup($group) {
136        if (!checkSecurityToken()) return false;
137        // group doesn't exist
138        if (!$this->groups[$group]) {
139            return;
140        }
141
142        // delete all users from group
143        foreach ($this->groups[$group] as $user) {
144            $idx = array_search($group,$this->users[$user]);
145            if ($idx !== false) {
146                unset($this->users[$user][$idx]);
147                $this->users[$user]=array_values($this->users[$user]);
148                if (!count($this->users[$user])) {
149                    unset($this->users[$user]);
150                }
151            }
152        }
153        $this->_save();
154    }
155
156function add($user) {
157        if (!checkSecurityToken()) return false;
158        $grp = $_REQUEST['grp'];
159        if (empty($user)) {
160            msg($this->getLang('nouser'),-1);
161            return;
162        }
163        if (empty($grp)) {
164            msg($this->getLang('nogrp'),-1);
165            return;
166        }
167
168        // get the groups as array
169        $grp = str_replace(' ','',$grp);
170        $grps = explode(',',$grp);
171
172        // append the groups to the user
173        if ($this->users[$user]) {
174            $this->users[$user] = array_merge($this->users[$user],$grps);
175            $this->users[$user] = array_unique($this->users[$user]);
176        } else {
177            $this->users[$user] = $grps;
178        }
179
180        // save the changes
181        $this->_save();
182
183    }
184
185    function addgroup($group) {
186        if (!checkSecurityToken()) return false;
187
188        if (empty($group)) {
189            msg($this->getLang('nogrp'),-1);
190            return;
191        }
192        if (empty($_REQUEST['users'])) {
193            msg($this->getLang('nouser'),-1);
194            return;
195        }
196
197        // get the users as array
198        $users = str_replace(' ','',$_REQUEST['users']);
199        $users = array_unique(explode(',',$users));
200
201        // add new users to group
202        foreach ($users as $user) {
203                if ($user && (!isset($this->users[$user]) || !in_array($group,$this->users[$user]))) {
204                    $this->users[$user][] = $group;
205                }
206        }
207        $this->_save();
208        return;
209    }
210
211
212    function _save() {
213        global $auth;
214        global $conf;
215        foreach ($this->users as $u => $grps) {
216            $cleanUser = $auth->cleanUser($u);
217            if ($u != $cleanUser) {
218                if (empty($cleanUser)) {
219                    msg($this->getLang('usercharerr'),-1);
220                    unset($this->users[$u]);
221                    continue;
222                }
223                $this->users[ $cleanUser ] = $this->users[$u];
224                unset($this->users[$u]);
225            }
226
227            $groupCount = count($this->users[$cleanUser]);
228            for ($i=0; $i<$groupCount; $i++) {
229                $clean = $auth->cleanGroup($this->users[$cleanUser][$i]);
230
231                if (empty($clean)) {
232                    msg($this->getLang('grpcharerr'),-1);
233                    unset($this->users[$cleanUser][$i]);
234                } else {
235                    if ($clean != $this->users[$cleanUser][$i]) {
236                        $this->users[$cleanUser][$i] = $clean;
237                    }
238                }
239            }
240
241            if (count($this->users[$cleanUser]) == 0) {
242                unset($this->users[$cleanUser]);
243            }
244        }
245
246        // determein the path to the data
247        $userFile = $conf['savedir'] . '/virtualgrp.php';
248
249        // serialize it
250        $content = serialize($this->users);
251
252        // save it
253        file_put_contents($userFile, $content);
254
255        // update groups-array, since the users-array probably has changed.
256        $this->groups = $this->translateUsers();
257    }
258
259
260    /**
261     * load the users -> group connection
262     */
263    function _load() {
264        global $conf;
265        // determein the path to the data
266        $userFile = $conf['savedir'] . '/virtualgrp.php';
267
268        // if there is no file we hava no data ;-)
269        if (!is_file($userFile)) {
270            $this->users = array();
271            return;
272        }
273
274        // read the file
275        $content = file_get_contents($userFile);
276
277        // if its empty we have no data also
278        if (empty($content)) {
279            $this->users = array();
280            return;
281        }
282
283        $users = unserialize($content);
284        // check for invalid data
285        if ($users === FALSE) {
286            $this->users = array();
287            @unlink($userFile);
288            return;
289        }
290
291        // place the users array
292        $this->users = $users;
293        $this->groups = $this->translateUsers();
294    }
295
296    /**
297     * translate the users-Array (groups a user is in) to a group-array (users in a group) and sort the user lists
298     */
299    function translateUsers() {
300        $groups = array();
301
302        foreach ($this->users as $user => $grps) {
303            foreach ($grps as $grp) {
304                $groups[$grp][]=$user;
305            }
306        }
307
308        foreach ($groups as $group => $users) {
309            sort($users);
310            $groups[$group]=$users;
311        }
312
313        return $groups;
314    }
315
316    /**
317     * output appropriate html
318     */
319    function html() {
320        global $ID;
321        $form = new Doku_Form(array('id' => 'vg', 'action' => wl($ID)));
322        $form->addHidden('cmd', $this->edit?'edit':'add');
323        $form->addHidden('sectok', getSecurityToken());
324        $form->addHidden('page', $this->getPluginName());
325        $form->addHidden('do', 'admin');
326        $form->startFieldset($this->getLang($this->edit ? 'edituser' : 'adduser'));
327        if ($this->edit) {
328            $form->addElement(form_makeField('text', 'user', $this->data['user'],
329                                             $this->getLang('user'), '', '',
330                                             array('disabled' => 'disabled')));
331            $form->addHidden('uid', $this->data['user']);
332        } else {
333            $form->addElement(form_makeField('text', 'uid', '',
334                                             $this->getLang('user')));
335        }
336        $form->addElement(form_makeField('text', 'grp',
337                                         $this->edit ? implode(', ',$this->data['grp'])
338                                                     : '',
339                                         $this->getLang('grp')));
340        $form->addElement(form_makeButton('submit', '',
341                                          $this->getLang($this->edit?'change':'add')));
342        $form->printForm();
343
344
345        ptln('<table class="inline" id="vg__show">');
346        ptln('  <tr>');
347        ptln('    <th class="user">'.hsc($this->getLang('users')).'</th>');
348        ptln('    <th class="grp">'.hsc($this->getLang('grps')).'</th>');
349        ptln('    <th> </th>');
350        ptln('  </tr>');
351        foreach ($this->users as $user => $grps) {
352            $userdata=$this->_auth->getUserData($user);
353
354            ptln('  <tr>');
355            ptln('    <td>'.hsc($user).(isset($userdata['name'])?hsc(' ('.$userdata['name'].')'):'').'</td>');
356            ptln('    <td>'.hsc(implode(', ',$grps)).'</td>');
357            ptln('    <td class="act">');
358            ptln('      <a class="vg_edit" href="'.wl($ID,array('do'=>'admin','page'=>$this->getPluginName(),'cmd'=>'edit' ,'uid'=>$user, 'sectok'=>getSecurityToken())).'">'.hsc($this->getLang('edit')).'</a>');
359            ptln(' &bull; ');
360            ptln('      <a class="vg_del" href="'.wl($ID,array('do'=>'admin','page'=>$this->getPluginName(),'cmd'=>'del','uid'=>$user, 'sectok'=>getSecurityToken())).'">'.hsc($this->getLang('del')).'</a>');
361            ptln('    </td>');
362            ptln('  </tr>');
363        }
364
365        ptln('</table>');
366
367        $form = new Doku_Form(array('id' => 'vg', 'action' => wl($ID)));
368        $form->addHidden('cmd', $this->editgroup?'editgroup':'addgroup');
369        $form->addHidden('sectok', getSecurityToken());
370        $form->addHidden('page', $this->getPluginName());
371        $form->addHidden('do', 'admin');
372        if ($this->editgroup) {
373            $form->startFieldset($this->getLang('editgroup'));
374            $form->addElement(form_makeField('text', 'group', $this->data['group'],
375                                             $this->getLang('grp'), '', '',
376                                             array('disabled' => 'disabled')));
377            $form->addHidden('uid', $this->data['group']);
378            $form->addElement(form_makeField('text', 'users',implode(', ',$this->data['users']),$this->getLang('users')));
379        } else {
380            $form->startFieldset($this->getLang('addgroup'));
381            $form->addElement(form_makeField('text', 'uid','', $this->getLang('grp')));
382            $form->addElement(form_makeField('text', 'users', '', $this->getLang('users')));
383        }
384        $form->addElement(form_makeButton('submit', '',
385                                          $this->getLang($this->editgroup?'change':'add')));
386        $form->printForm();
387
388
389        ptln('<table class="inline" id="vg__show">');
390        ptln('  <tr>');
391        ptln('    <th class="grp">'.hsc($this->getLang('grps')).'</th>');
392        ptln('    <th class="user">'.hsc($this->getLang('users')).'</th>');
393        ptln('    <th class="act"> </th>');
394        ptln('  </tr>');
395        foreach ($this->groups as $group => $users) {
396            ptln('  <tr>');
397            ptln('    <td>'.hsc($group).'</td>');
398            ptln('    <td>'.hsc(implode(', ',$users)).'</td>');
399            ptln('    <td class="act">');
400            ptln('      <a class="vg_edit" href="'.wl($ID,array('do'=>'admin','page'=>$this->getPluginName(),'cmd'=>'editgroup' ,'uid'=>$group, 'sectok'=>getSecurityToken())).'">'.hsc($this->getLang('edit')).'</a>');
401            ptln(' &bull; ');
402            ptln('      <a class="vg_del" href="'.wl($ID,array('do'=>'admin','page'=>$this->getPluginName(),'cmd'=>'delgroup','uid'=>$group, 'sectok'=>getSecurityToken())).'">'.hsc($this->getLang('del')).'</a>');
403            ptln('    </td>');
404            ptln('  </tr>');
405        }
406
407        ptln('</table>');
408    }
409}
410