]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiGroup.php
renamed ->Username => _userid for consistency
[SourceForge/phpwiki.git] / lib / WikiGroup.php
1 <?php
2 rcs_id('$Id: WikiGroup.php,v 1.8 2004-01-27 23:23:39 rurban Exp $');
3 /*
4  Copyright 2002 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 if (!defined('GROUP_NONE')) {
24     $group_method = 0; 
25     define('GROUP_NONE',        $group_method++);
26     define('GROUP_WIKIPAGE',    $group_method++); 
27     define('GROUP_DB',          $group_method++);
28     define('GROUP_FILE',        $group_method++);
29     define('GROUP_LDAP',        $group_method++);
30 }
31 if (!defined('GROUP_METHOD')) define('GROUP_METHOD', GROUP_WIKIPAGE);
32
33 /**
34  * WikiGroup is an abstract class to provide the base functions for determining
35  * group membership.
36  * 
37  * WikiGroup is an abstract class with three functions:
38  * <ol><li />Provide the static method getGroup with will return the proper
39  *         subclass.
40  *     <li />Provide an interface for subclasses to implement.
41  *     <li />Provide fallover methods (with error msgs) if not impemented in subclass.
42  * </ol>
43  * Do not ever instantiate this class use: $group = &WikiGroup::getGroup($request);
44  * This will instantiate the proper subclass.
45  * @author Joby Walker <zorloc@imperium.org>
46  */ 
47 class WikiGroup{
48     /** User name */
49     var $username;
50     /** The global WikiRequest object */
51     var $request;
52     /** Array of groups $username is confirmed to belong to */
53     var $membership;
54     
55     /**
56      * Initializes a WikiGroup object which should never happen.  Use:
57      * $group = &WikiGroup::getGroup($request);
58      * @param object $request The global WikiRequest object -- ignored.
59      */ 
60     function WikiGroup(&$request){    
61         return;
62     }
63
64     /**
65      * Gets the current username and erases $this->membership if is different than
66      * the stored $this->username
67      * @return string Current username.
68      */ 
69     function _getUserName(){
70         $request = &$this->request;
71         $user = $request->getUser();
72         $username = $user->getID();
73         if ($username != $this->username) {
74             $this->membership = array();
75             $this->username = $username;
76         }
77         return $username;
78     }
79     
80     /**
81      * Static method to return the WikiGroup subclass used in this wiki.  Controlled
82      * by the constant GROUP_METHOD.
83      * @param object $request The global WikiRequest object.
84      * @return object Subclass of WikiGroup selected via GROUP_METHOD.
85      */ 
86     function getGroup($request){
87         switch (GROUP_METHOD){
88             case GROUP_NONE: 
89                 return new GroupNone($request);
90                 break;
91             case GROUP_WIKIPAGE: 
92                 return new GroupWikiPage($request);
93                 break;
94             case GROUP_DB:
95                 return new GroupDB($request);
96                 break;
97             case GROUP_FILE: 
98                 return new GroupFile($request);
99                 break;
100 #            case GROUP_LDAP: 
101 #                return new GroupLDAP($request);
102 #                break;
103             default:
104                 trigger_error(_("No GROUP_METHOD defined"), E_USER_WARNING);
105                 return new WikiGroup($request);
106         }
107     }
108
109     /**
110      * Determines if the current user is a member of a group.
111      * 
112      * This method is an abstraction.  The group is ignored, an error is sent, and
113      * false (not a member of the group) is returned.
114      * @param string $group Name of the group to check for membership (ignored).
115      * @return boolean True if user is a member, else false (always false).
116      */ 
117     function isMember($group){
118         trigger_error("Method 'isMember' not implemented in this GROUP_METHOD", 
119                       E_USER_WARNING);
120         return false;
121     }
122     
123     /**
124      * Determines all of the groups of which the current user is a member.
125      * 
126      * This method is an abstraction.  An error is sent and an empty 
127      * array is returned.
128      * @return array Array of groups to which the user belongs (always empty).
129      */ 
130     function getAllGroupsIn(){
131         trigger_error("Method 'getAllGroupsIn' not implemented in this GROUP_METHOD",
132                       E_USER_WARNING);
133         return array();
134     }
135
136     /**
137      * Determines all of the members of a particular group.
138      * 
139      * This method is an abstraction.  The group is ignored, an error is sent, 
140      * and an empty array is returned
141      * @param string $group Name of the group to get the full membership list of.
142      * @return array Array of usernames that have joined the group (always empty).
143      */ 
144     function getMembersOf($group){
145         trigger_error("Method 'getMembersof' not implemented in this GROUP_METHOD", 
146                       E_USER_WARNING);
147         return array();
148     }
149
150     /**
151      * Add the current or specified user to a group.
152      * 
153      * This method is an abstraction.  The group and user are ignored, an error 
154      * is sent, and false (not added) is always returned.
155      * @param string $group User added to this group.
156      * @param string $user Username to add to the group (default = current user).
157      * @return bool On true user was added, false if not.
158      */ 
159     function setMemberOf($group, $user = false){
160         trigger_error("Method 'setMemberOf' not implemented in this GROUP_METHOD", 
161                       E_USER_WARNING);
162         return false;
163     }
164     
165     /**
166      * Remove the current or specified user to a group.
167      * 
168      * This method is an abstraction.  The group and user are ignored, and error
169      * is sent, and false (not removed) is always returned.
170      * @param string $group User removed from this group.
171      * @param string $user Username to remove from the group (default = current user).
172      * @return bool On true user was removed, false if not.
173      */ 
174     function removeMemberOf($group, $user = false){
175         trigger_error("Method 'removeMemberOf' not implemented in this GROUP_METHOD", 
176                       E_USER_WARNING);
177         return false;
178     }
179 }
180
181 /**
182  * GroupNone disables all Group funtionality
183  * 
184  * All of the GroupNone functions return false or empty values to indicate failure or 
185  * no results.  Use GroupNone if group controls are not desired.
186  * @author Joby Walker <zorloc@imperium.org>
187  */ 
188 class GroupNone extends WikiGroup{
189
190     /**
191      * Constructor
192      * 
193      * Ignores the parameter provided.
194      * @param object $request The global WikiRequest object - ignored.
195      */ 
196     function GroupNone(&$request){
197         return;
198     }    
199
200     /**
201      * Determines if the current user is a member of a group.
202      * 
203      * The group is ignored and false (not a member of the group) is returned.
204      * @param string $group Name of the group to check for membership (ignored).
205      * @return boolean True if user is a member, else false (always false).
206      */ 
207     function isMember($group){
208         return false;
209     }
210     
211     /**
212      * Determines all of the groups of which the current user is a member.
213      * 
214      * The group is ignored and an empty array (a member of no groups) is returned.
215      * @param string $group Name of the group to check for membership (ignored).
216      * @return array Array of groups to which the user belongs (always empty).
217      */ 
218     function getAllGroupsIn(){
219         return array();
220     }
221
222     /**
223      * Determines all of the members of a particular group.
224      * 
225      * The group is ignored and an empty array (a member of no groups) is returned.
226      * @param string $group Name of the group to check for membership (ignored).
227      * @return array Array of groups user belongs to (always empty).
228      */ 
229     function getMembersOf($group){
230         return array();
231     }
232
233 }
234
235 /**
236  * GroupWikiPage provides group functionality via pages within the Wiki.
237  * 
238  * GroupWikiPage is the Wiki way of managing a group.  Every group will have 
239  * a page. To modify the membership of the group, one only needs to edit the 
240  * membership list on the page.
241  * @author Joby Walker <zorloc@imperium.org>
242  */ 
243 class GroupWikiPage extends WikiGroup{
244     
245     /**
246      * Constructor
247      * 
248      * Initiallizes the three superclass instance variables
249      * @param object $request The global WikiRequest object.
250      */ 
251     function GroupWikiPage(&$request){
252         $this->request = &$request;
253         $this->username = null;
254         $this->membership = array();
255     }
256
257     /**
258      * Determines if the current user is a member of a group.
259      * 
260      * To determine membership in a particular group, this method checks the 
261      * superclass instance variable $membership to see if membership has 
262      * already been determined.  If not, then the group page is parsed to 
263      * determine membership.
264      * @param string $group Name of the group to check for membership.
265      * @return boolean True if user is a member, else false.
266      */ 
267     function isMember($group){
268         $request = $this->request;
269         $username = $this->_getUserName();
270         if (isset($this->membership[$group])) {
271             return $this->membership[$group];
272         }
273         $group_page = $request->getPage($group);
274         if ($this->_inGroupPage($group_page)) {
275             $this->membership[$group] = true;
276             return true;
277         }
278         $this->membership[$group] = false;
279         return false;
280     }
281     
282     /**
283     * Private method to take a WikiDB_Page and parse to determine if the
284     * current_user is a member of the group.
285     * @param object $group_page WikiDB_Page object for the group's page
286     * @return boolean True if user is a member, else false.
287     * @access private
288     */
289     function _inGroupPage($group_page){
290         $group_revision = $group_page->getCurrentRevision();
291         if ($group_revision->hasDefaultContents()) {
292             $group = $group_page->getName();
293             trigger_error(sprintf(_("Group %s does not exist"),$group), E_USER_WARNING);
294             return false;
295         }
296         $contents = $group_revision->getContent();
297         $match = '/^\s*[\*\#]+\s*' . $username . '\s*$/';
298         foreach($contents as $line){
299             if (preg_match($match, $line)) {
300                 return true;
301             }
302         }
303         return false;
304     }
305     
306     /**
307      * Determines all of the groups of which the current user is a member.
308      * 
309      * Checks the root Group page ('CategoryGroup') for the list of all groups, 
310      * then checks each group to see if the current user is a member.
311      * @param string $group Name of the group to check for membership.
312      * @return array Array of groups to which the user belongs.
313      */ 
314     function getAllGroupsIn(){
315         $request = &$this->request;
316         $username = $this->_getUserName();
317         $membership = array();
318         $dbh = &$request->getDbh();
319         $master_page = $request->getPage('CategoryGroup');
320         $master_list = $master_page->getLinks(true);
321         while($group_page = $master_list->next()){
322             if ($this->_inGroupPage($group_page)) {
323                 $group = $group_page->getName();
324                 $membership[$group] = true;
325             } else {
326                 $membership[$group] = false;
327             }
328         }
329         $this->membership = $membership;
330         return $membership;
331     }
332
333     /**
334      * Determines all of the members of a particular group.
335      * 
336      * Checks a group's page to return all the current members.  Currently this
337      * method is disabled and triggers an error and returns an empty array.
338      * @param string $group Name of the group to get the full membership list of.
339      * @return array Array of usernames that have joined the group (always empty).
340      */ 
341     function getMembersOf($group){
342         trigger_error("GroupWikiPage::getMembersof is not yet implimented",
343                       E_USER_WARNING);
344         return array();
345         /*
346         * Waiting for a reliable way to check if a string is a username.
347         $request = $this->request;
348         $user = $this->user;
349         $group_page = $request->getPage($group);
350         $group_revision = $group_page->getCurrentRevision();
351         if ($group_revision->hasDefaultContents()) {
352             trigger_error("Group $group does not exist", E_USER_WARNING);
353             return false;
354         }
355         $contents = $group_revision->getContent();
356         $match = '/^(\s*[\*\#]+\s*)(\w+)(\s*)$/';
357         $members = array();
358         foreach($contents as $line){
359             $matches = array();
360             if(preg_match($match, $line, $matches)){
361                 $members[] = $matches[2];
362             }
363         }
364         return $members;
365         */
366     }
367 }
368
369 /**
370  * GroupDb is configured by $DbAuthParams[] statements
371  * 
372  * @author ReiniUrban
373  */ 
374 class GroupDb extends WikiGroup {
375     
376     /**
377      * Constructor
378      * 
379      * @param object $request The global WikiRequest object.
380      */ 
381     function GroupDb(&$request){
382         $this->request = &$request;
383         $this->username = null;
384         $this->membership = array();
385
386         if (empty($DBAuthParams['group_members']) or empty($DBAuthParams['user_groups'])) {
387             trigger_error(_("No GROUP_DB statements defined"), E_USER_WARNING);
388             return false;
389         }
390         $dbh = _PassUser::getAuthDbh();
391         $this->_is_member = $dbh->_backend->prepare(preg_replace(array('"$userid"','"$groupname"'),array('?','?'),$DBAuthParams['is_member']));
392         $this->_group_members = $dbh->_backend->prepare(preg_replace('"$groupname"','?',$DBAuthParams['group_members']));
393         $this->_user_groups = $dbh->_backend->prepare(preg_replace('"$userid"','?',$DBAuthParams['user_groups']));
394     }
395
396     /**
397      * Determines if the current user is a member of a group.
398      * 
399      * To determine membership in a particular group, this method checks the 
400      * superclass instance variable $membership to see if membership has 
401      * already been determined.  If not, then the group page is parsed to 
402      * determine membership.
403      * @param string $group Name of the group to check for membership.
404      * @return boolean True if user is a member, else false.
405      */ 
406     function isMember($group) {
407         $request = $this->request;
408         $username = $this->_getUserName();
409         if (isset($this->membership[$group])) {
410             return $this->membership[$group];
411         }
412         $dbh = _PassUser::getAuthDbh();
413         $db_result = $dbh->_backend->execute($this->_is_member,$username,$group);
414         if ($db_result->numRows() > 0) {
415             $this->membership[$group] = true;
416             return true;
417         }
418         $this->membership[$group] = false;
419         return false;
420     }
421     
422     /**
423      * Determines all of the groups of which the current user is a member.
424      * 
425      * then checks each group to see if the current user is a member.
426      * @param string $group Name of the group to check for membership.
427      * @return array Array of groups to which the user belongs.
428      */ 
429     function getAllGroupsIn(){
430         $request = &$this->request;
431         $username = $this->_getUserName();
432         $membership = array();
433
434         $dbh = _PassUser::getAuthDbh();
435         $db_result = $dbh->_backend->execute($this->_user_groups,$username);
436         if ($db_result->numRows() > 0) {
437             while (list($group) = $db_result->fetchRow()) {
438                 $membership[] = $group;
439             }
440         }
441         $this->membership = $membership;
442         return $membership;
443     }
444
445     /**
446      * Determines all of the members of a particular group.
447      * 
448      * Checks a group's page to return all the current members.  Currently this
449      * method is disabled and triggers an error and returns an empty array.
450      * @param string $group Name of the group to get the full membership list of.
451      * @return array Array of usernames that have joined the group.
452      */ 
453     function getMembersOf($group){
454         $request = &$this->request;
455         $username = $this->_getUserName();
456         $members = array();
457
458         $dbh = _PassUser::getAuthDbh();
459         $db_result = $dbh->_backend->execute($this->_group_members,$group);
460         if ($db_result->numRows() > 0) {
461             while (list($userid) = $db_result->fetchRow()) {
462                 $members[] = $userid;
463             }
464         }
465         return $members;
466     }
467 }
468
469 /**
470  * GroupFile is configured by AUTH_GROUP_FILE
471  * groupname: user1 user2 ...
472  * 
473  * @author ReiniUrban
474  */ 
475 class GroupFile extends WikiGroup {
476     
477     /**
478      * Constructor
479      * 
480      * @param object $request The global WikiRequest object.
481      */ 
482     function GroupFile(&$request){
483         $this->request = &$request;
484         $this->username = null;
485         $this->membership = array();
486
487         if (!defined('AUTH_GROUP_FILE')) {
488             trigger_error(_("AUTH_GROUP_FILE not defined"), E_USER_WARNING);
489             return false;
490         }
491         if (!file_exists(AUTH_GROUP_FILE)) {
492             trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE), E_USER_WARNING);
493             return false;
494         }
495         require 'lib/pear/File_Passwd.php';
496         $this->_file = File_Passwd($file);
497     }
498
499     /**
500      * Determines if the current user is a member of a group.
501      * 
502      * To determine membership in a particular group, this method checks the 
503      * superclass instance variable $membership to see if membership has 
504      * already been determined.  If not, then the group file is parsed to 
505      * determine membership.
506      * @param string $group Name of the group to check for membership.
507      * @return boolean True if user is a member, else false.
508      */ 
509     function isMember($group) {
510         $request = $this->request;
511         $username = $this->_getUserName();
512         if (isset($this->membership[$group])) {
513             return $this->membership[$group];
514         }
515
516         foreach ($this->_file->users[] as $g => $u) {
517             $users = explode(' ',$u);
518             if (in_array($username,$users)) {
519                 $this->membership[$group] = true;
520                 return true;
521             }
522         }
523         $this->membership[$group] = false;
524         return false;
525     }
526     
527     /**
528      * Determines all of the groups of which the current user is a member.
529      * 
530      * then checks each group to see if the current user is a member.
531      * @param string $group Name of the group to check for membership.
532      * @return array Array of groups to which the user belongs.
533      */ 
534     function getAllGroupsIn(){
535         $request = &$this->request;
536         $username = $this->_getUserName();
537         $membership = array();
538
539         foreach ($this->_file->users[] as $group => $u) {
540             $users = explode(' ',$u);
541             if (in_array($username,$users)) {
542                 $this->membership[$group] = true;
543                 $membership[] = $group;
544             }
545         }
546         $this->membership = $membership;
547         return $membership;
548     }
549
550     /**
551      * Determines all of the members of a particular group.
552      * 
553      * Checks a group's page to return all the current members.  Currently this
554      * method is disabled and triggers an error and returns an empty array.
555      * @param string $group Name of the group to get the full membership list of.
556      * @return array Array of usernames that have joined the group.
557      */ 
558     function getMembersOf($group){
559         $request = &$this->request;
560         $username = $this->_getUserName();
561         $members = array();
562
563         if (!empty($this->_file->users[$group])) {
564             return explode(' ',$this->_file->users[$group]);
565         }
566         return $members;
567     }
568 }
569
570 // $Log: not supported by cvs2svn $
571 // Revision 1.7  2004/01/26 16:52:40  rurban
572 // added GroupDB and GroupFile classes
573 //
574 // Revision 1.6  2003/12/07 19:29:11  carstenklapp
575 // Code Housecleaning: fixed syntax errors. (php -l *.php)
576 //
577 // Revision 1.5  2003/02/22 20:49:55  dairiki
578 // Fixes for "Call-time pass by reference has been deprecated" errors.
579 //
580 // Revision 1.4  2003/01/21 04:02:39  zorloc
581 // Added Log entry and page footer.
582 //
583
584 // Local Variables:
585 // mode: php
586 // tab-width: 8
587 // c-basic-offset: 4
588 // c-hanging-comment-ender-p: nil
589 // indent-tabs-mode: nil
590 // End:
591 ?>