root/trunk/modules/user/classes/DA_User.php

Revision 2425 (checked in by demian, 1 month ago)

replaced tabs with spaces

Line 
1 <?php
2 /* Reminder: always indent with 4 spaces (no tabs). */
3 // +---------------------------------------------------------------------------+
4 // | Copyright (c) 2006, Demian Turner                                         |
5 // | All rights reserved.                                                      |
6 // |                                                                           |
7 // | Redistribution and use in source and binary forms, with or without        |
8 // | modification, are permitted provided that the following conditions        |
9 // | are met:                                                                  |
10 // |                                                                           |
11 // | o Redistributions of source code must retain the above copyright          |
12 // |   notice, this list of conditions and the following disclaimer.           |
13 // | o Redistributions in binary form must reproduce the above copyright       |
14 // |   notice, this list of conditions and the following disclaimer in the     |
15 // |   documentation and/or other materials provided with the distribution.    |
16 // | o The names of the authors may not be used to endorse or promote          |
17 // |   products derived from this software without specific prior written      |
18 // |   permission.                                                             |
19 // |                                                                           |
20 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
21 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         |
22 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     |
23 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
24 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     |
25 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          |
26 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     |
27 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
28 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
29 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     |
30 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      |
31 // |                                                                           |
32 // +---------------------------------------------------------------------------+
33 // | Seagull 0.6                                                               |
34 // +---------------------------------------------------------------------------+
35 // | DA_User.php                                                               |
36 // +---------------------------------------------------------------------------+
37 // | Authors:   Demian Turner <demian@phpkitchen.com>                          |
38 // +---------------------------------------------------------------------------+
39 // $Id: DA_User.php,v 1.14 2005/06/21 23:26:24 demian Exp $
40
41 require_once 'DB/DataObject.php';
42
43 //  role sync constants
44 define('SGL_ROLESYNC_ADD',              1);
45 define('SGL_ROLESYNC_REMOVE',           2);
46 define('SGL_ROLESYNC_ADDREMOVE',        3);
47 define('SGL_ROLESYNC_VIEWONLY',         4);
48
49 /**
50  * Data access methods for the user module.
51  *
52  * @package User
53  * @author  Demian Turner <demian@phpkitchen.com>
54  */
55 class DA_User extends SGL_Manager
56 {
57     /**
58      * Constructor - set default resources.
59      *
60      * @return DA_User
61      */
62     function DA_User()
63     {
64         parent::SGL_Manager();
65     }
66
67     /**
68      * Returns a singleton DA_User instance.
69      *
70      * example usage:
71      * $da = & DA_User::singleton();
72      * warning: in order to work correctly, the DA
73      * singleton must be instantiated statically and
74      * by reference
75      *
76      * @access  public
77      * @static
78      * @return  DA_User reference to DA_User object
79      */
80     function &singleton()
81     {
82         static $instance;
83
84         // If the instance is not there, create one
85         if (!isset($instance)) {
86             $instance = new DA_User();
87         }
88         return $instance;
89     }
90
91     //  //////////////////////////////////////////////////
92     //  /////////////////   USERS   //////////////////////
93     //  //////////////////////////////////////////////////
94
95     function addUser($oUser)
96     {
97         SGL_DB::setConnection();
98         $this->dbh->autocommit();
99
100         $userId = $this->dbh->nextId($this->conf['table']['user']);
101         $oUser->usr_id = $userId;
102         $ok = $oUser->insert();
103
104         if (!$ok) {
105             return PEAR::raiseError('Problem inserting user DataObject');
106         }
107         //  assign permissions associated with role user belongs to
108         //  first get all perms associated with user's role
109         $aRolePerms = $this->getPermsByRoleId($oUser->role_id);
110         if (PEAR::isError($aRolePerms)) {
111             return $aRolePerms;
112         }
113
114         //  then assign them to the user_permission table
115         $ok = $this->addPermsByUserId($aRolePerms, $oUser->usr_id);
116         if (PEAR::isError($ok)) {
117             return $ok;
118         }
119         //  assign preferences associated with org user belongs to
120         //  first get all prefs associated with user's org or default
121         //  prefs if orgs are disabled
122         if (@$this->conf['OrgMgr']['enabled']) {
123             $aPrefs = $this->getUserPrefsByOrgId($oUser->organisation_id, SGL_RET_ID_VALUE);
124         } else {
125             $aPrefs = $this->getMasterPrefs(SGL_RET_ID_VALUE);
126         }
127         if (PEAR::isError($aPrefs)) {
128             return $aPrefs;
129         }
130
131         //  then assign them to the user_preference table
132         $ok = $this->addPrefsByUserId($aPrefs, $oUser->usr_id);
133         if (PEAR::isError($ok)) {
134             return $ok;
135         }
136
137         if ($ok && !SGL_Error::count()) {
138             $this->dbh->commit();
139             return $userId;
140         } else {
141             $this->dbh->rollback();
142             return SGL_Error::getLast();
143         }
144     }
145
146     function updateUser($oUser, $roleIdOrig = null, $orgIdOrig = null)
147     {
148
149         SGL_DB::setConnection();
150         $this->dbh->autocommit();
151
152         $ok = $oUser->update();
153
154         if (!$ok) {
155             return PEAR::raiseError('Problem inserting user DataObject');
156         }
157         //  change perms if role is modified
158         if (!is_null($roleIdOrig) && ($oUser->role_id != $roleIdOrig)) {
159
160             //  disallow usr_id(1) admin from changing role
161             if ($oUser->usr_id == SGL_ADMIN) {
162                 return PEAR::raiseError('User with ID = 1 cannot change role');
163             }
164
165
166             //  first delete old perms
167             $ok = $this->deletePermsByUserId($oUser->usr_id);
168             if (PEAR::isError($ok)) {
169                 return $ok;
170             }
171             //  assign permissions associated with role user has been moved to
172             //  first get all perms associated with user's new role
173             $aRolePerms = $this->getPermsByRoleId($oUser->role_id);
174
175             //  then assign them to the user_permission table
176             $ok = $this->addPermsByUserId($aRolePerms, $oUser->usr_id);
177             if (PEAR::isError($ok)) {
178                 return $ok;
179             }
180         }
181
182         //  change prefs if org is modified
183         if (!is_null($orgIdOrig) && ($oUser->organisation_id  != $orgIdOrig)) {
184
185             //  first delete old preferences
186             $ok = $this->deletePrefsByUserId($oUser->usr_id);
187             if (PEAR::isError($ok)) {
188                 return $ok;
189             }
190             //  assign preferences associated with org user belongs to
191             //  first get all prefs associated with user's org
192             $aOrgPrefs = $this->getUserPrefsByOrgId($oUser->organisation_id, SGL_RET_ID_VALUE);
193
194             //  then assign them to the user_preference table
195             $ok = $this->addPrefsByUserId($aOrgPrefs, $oUser->usr_id);
196             if (PEAR::isError($ok)) {
197                 return $ok;
198             }
199         }
200
201         if ($ok && !SGL_Error::count()) {
202             $this->dbh->commit();
203             return true;
204         } else {
205             $this->dbh->rollback();
206             return PEAR::raiseError('Problem encountered adding user');
207         }
208     }
209
210     /**
211      * Returns a DataObjects Usr object.
212      *
213      * @access private
214      * @param integer   $id optional user id
215      * @return object   A DataObjects user object
216      */
217     function getUserById($id = null)
218     {
219         $oUser = DB_DataObject::factory($this->conf['table']['user']);
220         if (!is_null($id)) {
221             $oUser->get($id);
222         }
223         return $oUser;
224     }
225
226
227     //  //////////////////////////////////////////////////
228     //  /////////////////   PERMS   //////////////////////
229     //  //////////////////////////////////////////////////
230
231     /**
232      * A grouped delete.
233      *
234      * @param array $aPerms An array of elements of the form <perm_name>^<module_id>
235      * @return mixed    True on success, number of errors on failure
236      */
237     function deleteOrphanedPerms($aPerms)
238     {
239         SGL::logMessage(null, PEAR_LOG_DEBUG);
240
241         if (count($aPerms)) {
242             $this->dbh->autocommit();
243
244             foreach ($aPerms as $k => $v) {
245                 //  undelimit form value into perm name, moduleId
246                 $p = explode('^', $v);
247                 $query = "
248                     DELETE FROM {$this->conf['table']['permission']}
249                     WHERE name='{$p[0]}'
250                     AND module_id = {$p[1]}";
251                 $ok = $this->dbh->query($query);
252
253                 if (PEAR::isError($ok)) {
254                     $this->dbh->rollBack();
255                     return $ok;
256                 }
257             }
258             $this->dbh->commit();
259         }
260         return true;
261     }
262
263     /**
264      * Returns an array of permissions for the given role.
265      *
266      * @access public
267      * @param integer $id   The id of the role to retrieve perms for
268      * @return array        An array of permissions
269      */
270     function getPermsByRoleId($roleId = 0)
271     {
272         //  no logMessage allowed here
273         $query = "  SELECT  permission_id
274                     FROM    {$this->conf['table']['role_permission']}
275                     WHERE   role_id = " . $roleId;
276
277         $aRolePerms = $this->dbh->getCol($query);
278         return $aRolePerms;
279     }
280
281     /**
282      * Returns assoc array of all perms per given role id.
283      *
284      * @access  public
285      * @param   int     $roleId         id of target role
286      * @return  array   $aRolePerms     array of perms returned
287      * @see     getPermsNotInRole()
288      * @todo    merge with getPermsByRoleId() ?
289      */
290     function getPermNamesByRoleId($roleId)
291     {
292         SGL::logMessage(null, PEAR_LOG_DEBUG);
293
294         $query = "
295             SELECT  rp.permission_id, p.name
296             FROM    {$this->conf['table']['role_permission']} rp,
297                     {$this->conf['table']['permission']} p
298             WHERE   rp.permission_id = p.permission_id
299             AND     role_id = $roleId
300             ";
301
302         $aRolePerms = $this->dbh->getAssoc($query);
303         return $aRolePerms;
304     }
305
306     /**
307      * Returns an array of permissions by user id.
308      *
309      * @param integer $userId
310      * @return array    An array of permission ids
311      */
312     function getPermsByUserId($userId = 0)
313     {
314         SGL::logMessage(null, PEAR_LOG_DEBUG);
315
316         $query = "
317             SELECT  permission_id
318             FROM    {$this->conf['table']['user_permission']}
319             WHERE   usr_id = $userId
320                 ";
321         $aUserPerms = $this->dbh->getCol($query);
322         return $aUserPerms;
323     }
324
325     /**
326      * Returns an assoc array of all perms.
327      *
328      * @access  public
329      * @param   int     $moduleId   only select perms for one module
330      * @param   int     $type       return type constant
331      * @return  array   $aAllPerms  array of perms returned
332      */
333     function getPermsByModuleId($moduleId = '', $type = SGL_RET_ID_VALUE)
334     {
335         SGL::logMessage(null, PEAR_LOG_DEBUG);
336
337         switch ($type) {
338
339         case SGL_RET_ARRAY:
340             $filter = (!empty($moduleId))
341                 ? "  AND p.module_id = $moduleId"
342                 : '';
343             $query = "
344                 SELECT permission_id, p.name, m.name AS module_name, p.module_id
345                 FROM    {$this->conf['table']['permission']} p,
346                         {$this->conf['table']['module']} m
347                 WHERE p.module_id = m.module_id
348                 $filter
349                 ORDER BY name";
350             $aAllPerms = $this->dbh->getAll($query, DB_FETCHMODE_ASSOC);
351             break;
352
353         case SGL_RET_ID_VALUE:
354         default:
355             $filter = (!empty($moduleId))
356                 ? "WHERE  module_id = $moduleId"
357                 : '';
358
359             $query = "
360                 SELECT permission_id, name
361                 FROM {$this->conf['table']['permission']}
362                 $filter
363                 ORDER BY name";
364             $aAllPerms = $this->dbh->getAssoc($query);
365         }
366         return $aAllPerms;
367     }
368
369     /**
370      * Inserts permissions to the user_permission table.
371      *
372      * @access public
373      * @param array $aRolePerms     An array of permission ids
374      * @param integer $userId       The id of the user perms are being inserted for
375      * @return boolean              True on success, PEAR error on failure
376      */
377     function addPermsByUserId($aRolePerms, $userId)
378     {
379         //  no logMessage allowed here
380         if (count($aRolePerms)) {
381             $this->dbh->autocommit();
382             foreach ($aRolePerms as $permId) {
383                 $ok = $this->dbh->query('
384                     INSERT INTO ' . $this->conf['table']['user_permission'] . '
385                     (user_permission_id, usr_id, permission_id)
386                     VALUES (' . $this->dbh->nextId($this->conf['table']['user_permission']) . ', ' . $userId . ", $permId)");
387                 if (PEAR::isError($ok)) {
388                     $this->dbh->rollBack();
389                     return $ok;
390                 }
391             }
392             $this->dbh->commit();
393         }
394         return true;
395     }
396
397     /**
398      * Adds perms to the master set.
399      *
400      * Use when adding new modules
401      *
402      * @param array $aPerms A hash of perms, name => description
403      * @param int $moduleId
404      * @return boolean              True on success, PEAR error on failure
405      */
406     function addMasterPerms($aPerms, $moduleId)
407     {
408         if (count($aPerms)) {
409             $this->dbh->autocommit();
410             foreach ($aPerms as $name => $description) {
411                 $query = "
412                     INSERT INTO {$this->conf['table']['permission']}
413                         (permission_id, name, description, module_id)
414                     VALUES (". $this->dbh->nextId($this->conf['table']['permission']) .
415                         ", '$name', '$description', $moduleId)";
416                 $ok = $this->dbh->query($query);
417                 if (PEAR::isError($ok)) {
418                     $this->dbh->rollBack();
419                     return $ok;
420                 }
421             }
422             $this->dbh->commit();
423         }
424         return true;
425     }
426
427     /**
428      * Deletes perms from the master set.
429      *
430      * Use when removing modules
431      *
432      * @param array $aPerms An array of perm names
433      * @return boolean
434      */
435     function deleteMasterPerms($aPerms)
436     {
437         if (count($aPerms)) {
438             $this->dbh->autocommit();
439             foreach ($aPerms as $name) {
440                 $query = "DELETE FROM {$this->conf['table']['permission']} WHERE name = '$name'";
441                 $ok = $this->dbh->query($query);
442                 if (PEAR::isError($ok)) {
443                     $this->dbh->rollBack();
444                     return $ok;
445                 }
446             }
447             $this->dbh->commit();
448         }
449         return true;
450     }
451
452     /**
453      * Deletes permissions for a given user.
454      *
455      * @access public
456      * @param integer $userId       The id of the user perms are being deleted for
457      * @return boolean              True on success, PEAR error on failure
458      */
459     function deletePermsByUserId($userId)
460     {
461         $query = "DELETE FROM {$this->conf['table']['user_permission']} WHERE usr_id = $userId";
462         return $this->dbh->query($query);
463     }
464
465     /**
466      * Deletes a permission given a user id and the perm id.
467      *
468      * @access public
469      * @param integer $userId       The id of the user perms are being deleted for
470      * @param integer $permId       The id of the perm to be deleted
471      * @return boolean              True on success, PEAR error on failure
472      */
473     function deletePermByUserIdAndPermId($userId, $permId)
474     {
475         $query = "  DELETE FROM {$this->conf['table']['user_permission']}
476                     WHERE usr_id = $userId
477                     AND permission_id = $permId
478         ";
479         return $this->dbh->query($query);
480     }
481
482     /**
483      * Like a 'difference' operation, returns the balance of getPermNamesByRoleId.
484      *
485      * Returns an assoc array of all users who are not in getPermNamesByRoleId(),
486      * builds WHERE clause of role members to exclude,
487      * only creates NOT IN clause if role is non-empty
488      *
489      * @access  public
490      * @param   array   $aRolePerms     hash of perms to exclude
491      * @return  array   $aOtherPerms    array of perms returned
492      * @see     getPermNamesByRoleId()
493      */
494     function getPermsNotInRole($aRolePerms)
495     {
496         SGL::logMessage(null, PEAR_LOG_DEBUG);
497
498         $query = "
499             SELECT  p.permission_id, p.name
500             FROM    {$this->conf['table']['permission']} p";
501
502         if (count($aRolePerms)) {
503             $whereClause = '';
504             foreach ($aRolePerms as $key => $value) {
505                 $whereClause .= " $key NOT IN (p.permission_id) AND ";
506             }
507             $whereClause = substr($whereClause, 0, -4);
508             $query .= " WHERE $whereClause";
509         }
510         $aOtherPerms = $this->dbh->getAssoc($query);
511         return $aOtherPerms;
512     }
513
514     //  //////////////////////////////////////////////////
515     //  /////////////////   PREFS   //////////////////////
516     //  //////////////////////////////////////////////////
517
518     /**
519      * Returns an array of preferences for the given org.
520      *
521      * @access public
522      * @param integer $orgId    The id of the org to retrieve preferences for
523      * @return array            An array of preferences
524      */
525     function getUserPrefsByOrgId($orgId = 0, $type = SGL_RET_NAME_VALUE)
526     {
527         //  no logMessage allowed here
528         switch ($type) {
529         case SGL_RET_ID_VALUE:
530             $term = 'op.preference_id';
531             break;
532
533         case SGL_RET_NAME_VALUE:
534         default:
535             $term = 'name';
536         }
537
538         $query = "
539             SELECT  $term, value
540             FROM    {$this->conf['table']['preference']} p,
541                     {$this->conf['table']['org_preference']} op
542             WHERE   p.preference_id = op.preference_id
543             AND     op.organisation_id = " . $orgId;
544
545         $aRes = $this->dbh->getAssoc($query);
546         if (!DB::isError($aRes) && count($aRes)) {
547             //  return default prefs if none exist for given org id
548             return $aRes;
549         } elseif ($orgId != 0) {
550             return $this->getMasterPrefs($type);
551         } else {
552             SGL::raiseError('There was a db error, there are no prefs associated with the org',
553                 SGL_ERROR_NODATA);
554         }
555     }
556
557     /**
558      * Returns an array of preferences by user id.
559      *
560      * If no arg is passed, zero is assumed which returns a default set of name/value pref pairs.
561      * The more aptly named getMasterPrefs() above returns a master set of id/value pref pairs
562      *
563         [aPrefs] => Array
564             (
565                 [sessionTimeout] => 1800
566                 [timezone] => UTC
567                 [theme] => default
568                 [dateFormat] => UK
569                 [language] => fr-iso-8859-1
570                 [resPerPage] => 10
571                 [showExecutionTimes] => 1
572                 [locale] => en_GB
573             )
574      * @access  public
575      * @return  mixed   An array of prefs on success, else PEAR::raiseError
576      */
577     function getPrefsByUserId($uid = 0)
578     {
579         SGL::logMessage(null, PEAR_LOG_DEBUG);
580
581         $query = "
582             SELECT  name, value
583             FROM    {$this->conf['table']['preference']} p,
584                     {$this->conf['table']['user_preference']} up
585             WHERE   p.preference_id = up.preference_id
586             AND     up.usr_id = " . $uid;
587         $aRes = $this->dbh->getAssoc($query);
588
589         if (!PEAR::isError($aRes) && count($aRes)) {
590             return $aRes;
591         } elseif (!PEAR::isError($aRes)) {
592
593             //  return default prefs if none exist for given user id
594             if ($uid != 0) { // uid of 0 is the anonymous/public user
595                 return $this->getPrefsByUserId();
596             } else {
597                 $aRes = $this->getMasterPrefs();
598                 if (PEAR::isError($aRes) || !count($aRes)) {
599                     SGL::raiseError('No default prefs have been set!',
600                         SGL_ERROR_NODATA, PEAR_ERROR_DIE);
601                 } else {
602                     return $aRes;
603                 }
604             }
605         } elseif (PEAR::isError($aRes, DB_ERROR_NOSUCHTABLE)) {
606             SGL::raiseError('You have a Seagull database with no tables ...',
607                 SGL_ERROR_NODATA, PEAR_ERROR_DIE);
608
609         } else {
610             SGL::raiseError('Unknown DB error occurred, pls file bug',
611                 SGL_ERROR_NODATA, PEAR_ERROR_DIE);
612         }
613     }
614
615     /**
616      * Gets master set of preferences, two return types available.
617      *
618      * @access  public
619      * @param int   $type   Return type
620      * @return  array       A hash of preference_id/name => default_value prefs
621      */
622     function getMasterPrefs($type = SGL_RET_NAME_VALUE)
623     {
624         //  no logMessage allowed here
625
626         switch ($type) {
627         case SGL_RET_ID_VALUE:
628             $term = 'preference_id';
629             break;
630
631         case SGL_RET_NAME_VALUE:
632         default:
633             $term = 'name';
634         }
635         $query = "
636             SELECT  $term, default_value
637             FROM    {$this->conf['table']['preference']}";
638         $aRes = $this->dbh->getAssoc($query);
639
640         //  set default theme from config
641         $key = ($type == SGL_RET_NAME_VALUE) ? 'theme' : 3;
642         $c = &SGL_Config::singleton();
643         $defaultTheme = $c->get(array('site' => 'defaultTheme'));
644         $aRes[$key] = $defaultTheme;
645
646         return $aRes;
647     }
648
649     /**
650      * Get preferences mapping.
651      *
652      * @access  public
653      * @return  array   An hash of preference id => name
654      */
655     function getPrefsMapping()
656     {
657         SGL::logMessage(null, PEAR_LOG_DEBUG);
658         $query = "
659             SELECT  preference_id, name
660             FROM    {$this->conf['table']['preference']}";
661         $aRes = $this->dbh->getAssoc($query);
662         if (!PEAR::isError($aRes)) {
663             return array_flip($aRes);
664         } else {
665             return $aRes;
666         }
667     }
668
669     /**
670      * Syncs the default preferences.
671      *
672      * @todo error checking, rename to resetPrefs
673      */
674     function syncDefaultPrefs()
675     {
676         SGL::logMessage(null, PEAR_LOG_DEBUG);
677
678         $this->dbh->autocommit();
679         $query1 = " DELETE FROM {$this->conf['table']['user_preference']}
680                     WHERE usr_id = " . SGL_GUEST;
681         $ok = $this->dbh->query($query1);
682         if (PEAR::isError($ok)) {
683             $this->dbh->rollBack();
684             return $ok;
685         }
686
687         //  get master set of prefs
688         $aPrefs = $this->getMasterPrefs(SGL_RET_ID_VALUE);
689         if (PEAR::isError($aPrefs)) {
690             $this->dbh->rollBack();
691             return $aPrefs;
692         }
693
694         foreach ($aPrefs as $prefId => $prefValue) {
695             $query2 ="
696             INSERT INTO {$this->conf['table']['user_preference']}
697                 (   user_preference_id,
698                     usr_id,
699                     preference_id,
700                     value)
701             VALUES(" .
702                     $this->dbh->nextId($this->conf['table']['user_preference']) . ', ' .
703                     SGL_GUEST . ",
704                     $prefId,
705                     '$prefValue'
706             )";
707             $ok = $this->dbh->query($query2);
708             if (PEAR::isError($ok)) {
709                 $this->dbh->rollBack();
710                 return $ok;
711             }
712         }
713         $this->dbh->commit();
714         return true;
715     }
716
717     /**
718      * Inserts preferences to the user_preference table.
719      *
720      * @access public
721      * @param array $aPrefs         An hash of preferences (prefId, prefValue)
722      * @param integer $userId       The id of the user prefs are being inserted for
723      * @return boolean              True on success, PEAR error on failure
724      */
725     function addPrefsByUserId($aPrefs, $userId)
726     {
727         if (count($aPrefs)) {
728             $this->dbh->autocommit();
729             foreach ($aPrefs as $prefId => $prefValue) {
730                 $ok = $this->dbh->query("
731                     INSERT INTO {$this->conf['table']['user_preference']}
732                     (user_preference_id, usr_id, preference_id, value)
733                     VALUES (" . $this->dbh->nextId($this->conf['table']['user_preference']) . ', ' . $userId . ", $prefId, '$prefValue')");
734                 if (PEAR::isError($ok)) {
735                     $this->dbh->rollBack();
736                     return $ok;
737                 }
738             }
739             $this->dbh->commit();
740         }
741         return true;
742     }
743
744     /**
745      * Updates user preferences.
746      *
747      * @param array $aPrefs A hash of prefId => values
748      * @return boolean
749      * @TODO check for errors, wrap in transaction
750      */
751     function updatePrefsByUserId($aPrefs, $userId)
752     {
753         if (count($aPrefs)) {
754             $this->dbh->autocommit();
755             foreach ($aPrefs as $prefId => $prefValue) {
756                 $ok = $this->dbh->query("
757                     UPDATE {$this->conf['table']['user_preference']}
758                     SET value = '$prefValue'
759                     WHERE preference_id = '$prefId'
760                     AND usr_id = $userId
761                     ");
762                 if (PEAR::isError($ok)) {
763                     $this->dbh->rollBack();
764                     return $ok;
765                 }
766             }
767             $this->dbh->commit();
768         }
769         return true;
770     }
771
772     /**
773      * Adds new master preferences.
774      *
775      * Use when adding new modules
776      *
777      * @param array $aPrefs A hash of prefId => values
778      * @return boolean
779      * @TODO check for errors, wrap in transaction
780      */
781     function addMasterPrefs($aPrefs)
782     {
783         if (count($aPrefs)) {
784             $this->dbh->autocommit();
785             foreach ($aPrefs as $prefName => $prefValue) {
786                 $ok = $this->dbh->query("
787                     INSERT INTO {$this->conf['table']['preference']}
788                     (preference_id, name, default_value)
789                     VALUES (" . $this->dbh->nextId($this->conf['table']['preference']) . ",
790                     '$prefName', '$prefValue')");
791                 if (PEAR::isError($ok)) {
792                     $this->dbh->rollBack();
793                     return $ok;
794                 }
795             }
796             $this->dbh->commit();
797         }
798         return true;
799     }
800
801     /**
802      * Updates master preferences.
803      *
804      * @param array $aPrefs A hash of prefId => values
805      * @return boolean
806      * @TODO check for errors, wrap in transaction
807      */
808     function updateMasterPrefs($aPrefs)
809     {
810         if (count($aPrefs)) {
811             $this->dbh->autocommit();
812             foreach ($aPrefs as $prefName => $prefValue) {
813                 $ok = $this->dbh->query("
814                     UPDATE {$this->conf['table']['preference']}
815                     SET default_value = '$prefValue'
816                     WHERE name = '$prefName'");
817                 if (PEAR::isError($ok)) {
818                     $this->dbh->rollBack();
819                     return $ok;
820                 }
821             }
822             $this->dbh->commit();
823         }
824         return true;
825     }
826
827     /**
828      * Complement of addMasterPrefs().
829      *
830      * @param array $aPrefs An array of pref names
831      * @return boolean
832      */
833     function deleteMasterPrefs($aPrefs)
834     {
835         if (count($aPrefs)) {
836             $this->dbh->autocommit();
837             foreach ($aPrefs as $pref) {
838                 $query = "DELETE FROM {$this->conf['table']['preference']} WHERE name = '$pref'";
839                 $ok = $this->dbh->query($query);
840                 if (PEAR::isError($ok)) {
841                     $this->dbh->rollBack();
842                     return $ok;
843                 }
844             }
845             $this->dbh->commit();
846         }
847         return true;
848     }
849
850     /**
851      * Deletes preferences for a given user.
852      *
853      * @access public
854      * @param integer $userId       The id of the user preferences are being deleted for
855      * @return boolean              True on success, PEAR error on failure
856      */
857     function deletePrefsByUserId($userId)
858     {
859         $query = "DELETE FROM {$this->conf['table']['user_preference']} WHERE usr_id = " . $userId;
860         return $this->dbh->query($query);
861     }
862
863
864     //  //////////////////////////////////////////////////
865     //  /////////////////   ROLES   //////////////////////
866     //  //////////////////////////////////////////////////
867
868
869     /**
870      * Returns an assoc array of all roles.
871      *
872      * @access  public
873      * @param   boolean $bExcludeGuest  whether admin should be excluded
874      * @return  array   $aAllRoles      array of roles returned
875      */
876     function getRoles($bExcludeRoot = false)
877     {
878         SGL::logMessage(null, PEAR_LOG_DEBUG);
879
880         $whereClause = ($bExcludeRoot) ? ' AND role_id <> ' . SGL_ADMIN : '';
881
882         $query = "
883             SELECT role_id, name
884             FROM    " . $this->conf['table']['role'] . "
885             WHERE  role_id <> " . SGL_GUEST . "
886             AND    role_id <> " . SGL_UNASSIGNED .
887             $whereClause;
888         $aAllRoles = $this->dbh->getAssoc($query);
889
890         //  remove roles that have no perms set
891         foreach ($aAllRoles as $roleId => $name) {
892             if ($roleId === SGL_ADMIN) {
893                 continue;
894             }
895             $query =
896                 'SELECT COUNT(*) FROM ' . $this->conf['table']['role_permission'] .
897                 ' WHERE role_id =' . $roleId;
898             $count = $this->dbh->getOne($query);
899             if ($count < 1) {
900                 unset($aAllRoles[$roleId]);
901             }
902         }
903         return $aAllRoles;
904     }
905
906     function getRoleNameById($id)
907     {
908         SGL::logMessage(null, PEAR_LOG_DEBUG);
909
910         $query = "
911             SELECT name
912             FROM    " . $this->conf['table']['role'] . "
913             WHERE  role_id = " . $id;
914         return $this->dbh->getOne($query);
915     }
916
917     /**
918      * Returns a string of all emails per given group.
919      *
920      * @access  public
921      * @param   int     $gid            id of target group
922      * @return  string  $emailList      role's emails
923      */
924     function getEmailsByRole($rid)
925     {
926         SGL::logMessage(null, PEAR_LOG_DEBUG);
927
928         $query = "
929             SELECT  usr_id, email
930             FROM    " . $this->conf['table']['user'] . "
931             WHERE   role_id = $rid
932                 ";
933         $emailList = implode(';', $this->dbh->getAssoc($query));
934         return $emailList;
935     }
936
937     /**
938      * Returns an array of user ids.
939      *
940      * @param integer $roleId
941      * @return array
942      */
943     function getUsersByRoleId($roleId)
944     {
945         SGL::logMessage(null, PEAR_LOG_DEBUG);
946         $query = "
947             SELECT  usr_id
948             FROM    {$this->conf['table']['user']}
949             WHERE   role_id = " . $roleId;
950
951         $aRoleUsers = $this->dbh->getCol($query);
952         return $aRoleUsers;
953     }
954
955     /**
956      * Returns an array of user ids.
957      *
958      * @param integer $orgId
959      * @return array
960      */
961     function getUsersByOrgId($orgId)
962     {
963         SGL::logMessage(null, PEAR_LOG_DEBUG);
964         $query = "
965             SELECT  usr_id
966             FROM    {$this->conf['table']['user']}
967             WHERE   organisation_id = " . $orgId;
968
969         $aOrgUsers = $this->dbh->getCol($query);
970         return $aOrgUsers;
971     }
972
973     /**
974      * Updates role-permission assignments.
975      *
976      * @access  public
977      * @param   array       $aPerms array of perms to add/remove
978      * @param   string      $roleId role ID to associate permissions with
979      * @param   constant    action  whether to add/remove perm
980      * @return  void
981      */
982     function updateRolePermissionAssocs($aPerms, $roleId, $action)
983     {
984         SGL::logMessage(null, PEAR_LOG_DEBUG);
985
986         if ($action == SGL_ROLE_REMOVE) {
987             foreach ($aPerms as $permId => $permName) {
988                 $this->dbh->query('
989                     DELETE FROM ' . $this->conf['table']['role_permission'] . "
990                     WHERE   permission_id = $permId
991                     AND     role_id = $roleId");
992             }
993         } else {
994             //  add perms
995             foreach ($aPerms as $permId => $permName) {
996                 $this->dbh->query('
997                     INSERT INTO ' . $this->conf['table']['role_permission'] . "
998                         (role_permission_id, role_id, permission_id)
999                     VALUES (" . $this->dbh->nextId($this->conf['table']['role_permission']) . ", $roleId, $permId)");
1000             }
1001         }
1002     }
1003
1004
1005     //  //////////////////////////////////////////////////
1006     //  /////////////////   ORGS   //////////////////////
1007     //  //////////////////////////////////////////////////
1008
1009     /**
1010      * Returns all organisations.
1011      *
1012      * @return array $aAllOrgs
1013      */
1014     function getOrgs()
1015     {
1016         SGL::logMessage(null, PEAR_LOG_DEBUG);
1017
1018         $query = "
1019             SELECT organisation_id, name
1020             FROM    " . $this->conf['table']['organisation'];
1021         $aAllOrgs = $this->dbh->getAssoc($query);
1022         return $aAllOrgs;
1023     }
1024
1025     /**
1026      * Returns an organisation by org id.
1027      *
1028      * @param integer $orgId
1029      * @return array $aOrg
1030      */
1031     function getOrgById($orgId)
1032     {
1033         SGL::logMessage(null, PEAR_LOG_DEBUG);
1034
1035         $query = "  SELECT  *
1036                     FROM    {$this->conf['table']['organisation']}
1037                     WHERE   organisation_id = " . $orgId;
1038
1039         $aOrg = $this->dbh->getRow($query);
1040         return $aOrg;
1041     }
1042
1043     /**
1044      * Returns all organisations by role id.
1045      *
1046      * @param integer $roleId
1047      * @return array    An array of org ids
1048      */
1049     function getOrgsByRoleId($roleId)
1050     {
1051         SGL::logMessage(null, PEAR_LOG_DEBUG);
1052         $query = "
1053             SELECT  organisation_id
1054             FROM    {$this->conf['table']['organisation']}
1055             WHERE   role_id = " . $roleId;
1056
1057         $aRoleOrgs = $this->dbh->getCol($query);
1058         return $aRoleOrgs;
1059     }
1060 /**
1061      * Returns an organisation name by org id.
1062      *
1063      * @param integer $orgId
1064      * @return string $orgName
1065      */
1066     function getOrgNameById($orgId)
1067     {
1068         SGL::logMessage(null, PEAR_LOG_DEBUG);
1069
1070         $query = "  SELECT  name
1071                     FROM    {$this->conf['table']['organisation']}
1072                     WHERE   organisation_id = " . $orgId;
1073
1074         $orgName = $this->dbh->getOne($query);
1075         return $orgName;
1076     }
1077
1078     /**
1079      * Returns a hash or organisation types.
1080      *
1081      * @return array    An array of org id => names
1082      */
1083     function getOrgTypes()
1084     {
1085         SGL::logMessage(null, PEAR_LOG_DEBUG);
1086
1087         $query = "
1088             SELECT organisation_type_id, name
1089             FROM {$this->conf['table']['organisation_type']}";
1090         $aAllTypes = $this->dbh->getAssoc($query);
1091
1092         //  set the zeroeth element as 'default'
1093         //  done in code rather than default data
1094         //  to simplified optional use of 'org types'
1095         array_unshift($aAllTypes, 'default');
1096         return $aAllTypes;
1097     }
1098
1099
1100     /**
1101      * Determines if a username is unique.
1102      *
1103      * @param string $username
1104      * @return boolean
1105      * @todo get rid of DataObject
1106      */
1107     function isUniqueUsername($username)
1108     {
1109         if (isset($username)) {
1110             $oUser = DB_DataObject::factory($this->conf['table']['user']);
1111             $oUser->whereAdd("username = '$username'");
1112             $numRows = $oUser->find();
1113
1114             //  return false if any rows found
1115             return (boolean)$numRows == 0;
1116         }
1117     }
1118
1119     /**
1120      * Determines if an email is unique.
1121      *
1122      * @param string $email
1123      * @return boolean
1124      * @todo get rid of DataObject
1125      */
1126     function isUniqueEmail($email)
1127     {
1128         if (isset($email)) {
1129             $oUser = DB_DataObject::factory($this->conf['table']['user']);
1130             $oUser->whereAdd("email = '$email'");
1131             $numRows = $oUser->find();
1132
1133             //  return false if any rows found
1134             return (boolean)$numRows == 0;
1135         }
1136     }
1137
1138     /**
1139      * Returns the datetime of last login.
1140      *
1141      * @param integer $userId
1142      * @return string   Datetime of login
1143      */
1144     function getLastLogin($userId = null)
1145     {
1146         $id = (is_null($userId)) ? SGL_Session::getUid() : $userId;
1147         $query = "
1148             SELECT date_time AS last_login
1149             FROM  {$this->conf['table']['login']}
1150             WHERE usr_id = " . $id . '
1151             ORDER BY date_time DESC';
1152
1153         //  grab penultimate record
1154         $res = $this->dbh->limitQuery($query, 1, 1);
1155         $res->fetchInto($login);
1156         return $login;
1157     }
1158
1159     //OrgPreferenceMgr::_updateAll
1160 }
1161 ?>
1162
Note: See TracBrowser for help on using the browser.