Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.46% covered (warning)
76.46%
614 / 803
66.67% covered (warning)
66.67%
54 / 81
CRAP
0.00% covered (danger)
0.00%
0 / 1
SeedDMS_Core_User
76.46% covered (warning)
76.46%
614 / 803
66.67% covered (warning)
66.67%
54 / 81
1711.72
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
1
 getInstance
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
8
 getAllInstances
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
7
 __toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDMS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDMS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLogin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLogin
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 getFullName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setFullName
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getPwd
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPwd
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getPwdExpiration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPwdExpiration
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
5
 getEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEmail
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLanguage
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getTheme
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTheme
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getComment
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setComment
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getRole
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRole
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 isAdmin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setAdmin
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 isGuest
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setGuest
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 isUser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isHidden
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHidden
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 isDisabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDisabled
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 addLoginFailure
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 clearLoginFailures
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 getUsedDiskSpace
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getQuota
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setQuota
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 getHomeFolder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHomeFolder
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 __removeFromProcesses
18.52% covered (danger)
18.52%
10 / 54
0.00% covered (danger)
0.00%
0 / 1
861.82
 removeFromProcesses
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
2.09
 __transferDocumentsFolders
68.42% covered (warning)
68.42%
13 / 19
0.00% covered (danger)
0.00%
0 / 1
8.54
 transferDocumentsFolders
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
3.10
 __transferEvents
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
3.21
 transferEvents
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 remove
49.45% covered (danger)
49.45%
45 / 91
0.00% covered (danger)
0.00%
0 / 1
105.73
 joinGroup
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 leaveGroup
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 getGroups
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
5.01
 isMemberOfGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasImage
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
4.02
 getImage
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 setImage
83.33% covered (warning)
83.33%
10 / 12
0.00% covered (danger)
0.00%
0 / 1
4.07
 getDocuments
73.33% covered (warning)
73.33%
11 / 15
0.00% covered (danger)
0.00%
0 / 1
4.30
 getDocumentsLocked
73.33% covered (warning)
73.33%
11 / 15
0.00% covered (danger)
0.00%
0 / 1
4.30
 getDocumentLinks
64.29% covered (warning)
64.29%
9 / 14
0.00% covered (danger)
0.00%
0 / 1
4.73
 getDocumentFiles
69.23% covered (warning)
69.23%
9 / 13
0.00% covered (danger)
0.00%
0 / 1
4.47
 getDocumentContents
66.67% covered (warning)
66.67%
8 / 12
0.00% covered (danger)
0.00%
0 / 1
4.59
 getFolders
92.31% covered (success)
92.31%
12 / 13
0.00% covered (danger)
0.00%
0 / 1
4.01
 getReviewStatus
79.17% covered (warning)
79.17%
38 / 48
0.00% covered (danger)
0.00%
0 / 1
20.93
 getApprovalStatus
80.00% covered (warning)
80.00%
40 / 50
0.00% covered (danger)
0.00%
0 / 1
20.59
 getWorkflowStatus
53.85% covered (warning)
53.85%
14 / 26
0.00% covered (danger)
0.00%
0 / 1
29.62
 getWorkflowsInvolved
70.00% covered (warning)
70.00%
7 / 10
0.00% covered (danger)
0.00%
0 / 1
5.68
 getMandatoryReviewers
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getMandatoryApprovers
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 isMandatoryReviewerOf
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 isMandatoryApproverOf
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 getMandatoryWorkflow
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
 getMandatoryWorkflows
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 setMandatoryReviewer
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
8
 setMandatoryApprover
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
8
 setMandatoryWorkflow
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 setMandatoryWorkflows
71.43% covered (warning)
71.43%
10 / 14
0.00% covered (danger)
0.00%
0 / 1
5.58
 delMandatoryReviewers
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 delMandatoryApprovers
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 delMandatoryWorkflow
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getNotifications
71.43% covered (warning)
71.43%
10 / 14
0.00% covered (danger)
0.00%
0 / 1
5.58
 getKeywordCategories
63.64% covered (warning)
63.64%
7 / 11
0.00% covered (danger)
0.00%
0 / 1
4.77
1<?php
2declare(strict_types=1);
3
4/**
5 * Implementation of the user object in the document management system
6 *
7 * @category   DMS
8 * @package    SeedDMS_Core
9 * @license    GPL 2
10 * @version    @version@
11 * @author     Uwe Steinmann <uwe@steinmann.cx>
12 * @copyright  Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
13 *             2010-2024 Uwe Steinmann
14 * @version    Release: @package_version@
15 */
16
17/**
18 * Class to represent a user in the document management system
19 *
20 * @category   DMS
21 * @package    SeedDMS_Core
22 * @author     Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
23 * @copyright  Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
24 *             2010-2024 Uwe Steinmann
25 * @version    Release: @package_version@
26 */
27class SeedDMS_Core_User { /* {{{ */
28    /**
29     * @var integer id of user
30     *
31     * @access protected
32     */
33    protected $_id;
34
35    /**
36     * @var string login name of user
37     *
38     * @access protected
39     */
40    protected $_login;
41
42    /**
43     * @var string password of user as saved in database (md5)
44     *
45     * @access protected
46     */
47    protected $_pwd;
48
49    /**
50     * @var string date when password expires
51     *
52     * @access protected
53     */
54    protected $_pwdExpiration;
55
56    /**
57     * @var string full human readable name of user
58     *
59     * @access protected
60     */
61    protected $_fullName;
62
63    /**
64     * @var string email address of user
65     *
66     * @access protected
67     */
68    protected $_email;
69
70    /**
71     * @var string prefered language of user
72     *      possible values are subdirectories within the language directory
73     *
74     * @access protected
75     */
76    protected $_language;
77
78    /**
79     * @var string preselected theme of user
80     *
81     * @access protected
82     */
83    protected $_theme;
84
85    /**
86     * @var string comment of user
87     *
88     * @access protected
89     */
90    protected $_comment;
91
92    /**
93     * @var string role of user. Can be one of SeedDMS_Core_User::role_user,
94     *      SeedDMS_Core_User::role_admin, SeedDMS_Core_User::role_guest
95     *
96     * @access protected
97     */
98    protected $_role;
99
100    /**
101     * @var boolean true if user shall be hidden
102     *
103     * @access protected
104     */
105    protected $_isHidden;
106
107    /**
108     * @var boolean true if user is disabled
109     *
110     * @access protected
111     */
112    protected $_isDisabled;
113
114    /**
115     * @var int number of login failures
116     *
117     * @access protected
118     */
119    protected $_loginFailures;
120
121    /**
122     * @var SeedDMS_Core_Folder home folder
123     *
124     * @access protected
125     */
126    protected $_homeFolder;
127
128    /**
129     * @var array list of groups
130     *
131     * @access protected
132     */
133    protected $_groups;
134
135    /**
136     * @var SeedDMS_Core_DMS reference to the dms instance this user belongs to
137     *
138     * @access protected
139     */
140    protected $_dms;
141
142    /**
143     * @var int
144     *
145     * @access protected
146     */
147    protected $_quota;
148
149    /**
150     * @var bool
151     *
152     * @access protected
153     */
154    protected $_hasImage;
155
156    const role_user = '0';
157    const role_admin = '1';
158    const role_guest = '2';
159
160    /**
161     * SeedDMS_Core_User constructor.
162     * @param $id
163     * @param $login
164     * @param $pwd
165     * @param $fullName
166     * @param $email
167     * @param $language
168     * @param $theme
169     * @param $comment
170     * @param $role
171     * @param int $isHidden
172     * @param int $isDisabled
173     * @param string $pwdExpiration
174     * @param int $loginFailures
175     * @param int $quota
176     * @param null $homeFolder
177     */
178    public function __construct($id, $login, $pwd, $fullName, $email, $language, $theme, $comment, $role, $isHidden = 0, $isDisabled = 0, $pwdExpiration = '', $loginFailures = 0, $quota = 0, $homeFolder = null) {
179        $this->_id = $id;
180        $this->_login = $login;
181        $this->_pwd = $pwd;
182        $this->_fullName = $fullName;
183        $this->_email = $email;
184        $this->_language = $language;
185        $this->_theme = $theme;
186        $this->_comment = $comment;
187        $this->_role = $role;
188        $this->_isHidden = (bool) $isHidden;
189        $this->_isDisabled = (bool) $isDisabled;
190        $this->_pwdExpiration = $pwdExpiration;
191        $this->_loginFailures = $loginFailures;
192        $this->_quota = $quota;
193        $this->_homeFolder = $homeFolder;
194        $this->_dms = null;
195    }
196
197    /**
198     * Create an instance of a user object
199     *
200     * @param string|integer $id Id, login name, or email of user, depending
201     * on the 3rd parameter.
202     * @param SeedDMS_Core_DMS $dms instance of dms
203     * @param string $by search by [name|email]. If 'name' is passed, the method
204     * will check for the 4th paramater and also filter by email. If this
205     * parameter is left empty, the user will be search by its Id.
206     * @param string $email optional email address if searching for name
207     * @return SeedDMS_Core_User|bool instance of class SeedDMS_Core_User if user was
208     * found, null if user was not found, false in case of error
209     */
210    public static function getInstance($id, $dms, $by = '', $email = '') { /* {{{ */
211        $db = $dms->getDB();
212
213        switch ($by) {
214            case 'name':
215                $queryStr = "SELECT * FROM `tblUsers` WHERE `login` = ".$db->qstr((string) $id);
216                if ($email)
217                    $queryStr .= " AND `email`=".$db->qstr($email);
218                break;
219            case 'email':
220                $queryStr = "SELECT * FROM `tblUsers` WHERE `email` = ".$db->qstr((string) $id);
221                break;
222            default:
223                $queryStr = "SELECT * FROM `tblUsers` WHERE `id` = " . (int) $id;
224        }
225        $resArr = $db->getResultArray($queryStr);
226
227        if (is_bool($resArr) && $resArr == false) return false;
228        if (count($resArr) != 1) return null;
229
230        $resArr = $resArr[0];
231
232        $user = new self((int) $resArr["id"], $resArr["login"], $resArr["pwd"], $resArr["fullName"], $resArr["email"], $resArr["language"], $resArr["theme"], $resArr["comment"], $resArr["role"], $resArr["hidden"], $resArr["disabled"], $resArr["pwdExpiration"], $resArr["loginfailures"], (int) $resArr["quota"], $resArr["homefolder"]);
233        $user->setDMS($dms);
234        return $user;
235    } /* }}} */
236
237    /**
238     * Return all users
239     *
240     * @param $orderby can be `fullname`
241     * @param SeedDMS_Core_DMS $dms
242     * @return SeedDMS_Core_User[]|bool
243     */
244    public static function getAllInstances($orderby, $dms) { /* {{{ */
245        $db = $dms->getDB();
246
247        if ($orderby == 'fullname') {
248            $queryStr = "SELECT * FROM `tblUsers` ORDER BY `fullName`";
249        } else {
250            $queryStr = "SELECT * FROM `tblUsers` ORDER BY `login`";
251        }
252        $resArr = $db->getResultArray($queryStr);
253
254        if (is_bool($resArr) && $resArr == false) {
255            return false;
256        }
257
258        $users = array();
259
260        for ($i = 0; $i < count($resArr); $i++) {
261            /** @var SeedDMS_Core_User $user */
262            $user = new self($resArr[$i]["id"], $resArr[$i]["login"], $resArr[$i]["pwd"], $resArr[$i]["fullName"], $resArr[$i]["email"], (isset($resArr[$i]["language"])?$resArr[$i]["language"]:null), (isset($resArr[$i]["theme"])?$resArr[$i]["theme"]:null), $resArr[$i]["comment"], $resArr[$i]["role"], $resArr[$i]["hidden"], $resArr[$i]["disabled"], $resArr[$i]["pwdExpiration"], $resArr[$i]["loginfailures"], (int) $resArr[$i]["quota"], $resArr[$i]["homefolder"]);
263            $user->setDMS($dms);
264            $users[$i] = $user;
265        }
266
267        return $users;
268    } /* }}} */
269
270    /**
271     * Cast to string
272     *
273     * @return string
274     */
275    public function __toString() { /* {{{ */
276        return $this->_fullName." (".$this->_login.")";
277    } /* }}} */
278
279    /**
280     * Check if this object is of type 'user'.
281     *
282     * @param string $type type of object
283     */
284    public function isType($type) { /* {{{ */
285        return $type == 'user';
286    } /* }}} */
287
288    /**
289     * @param SeedDMS_Core_DMS $dms
290     */
291    public function setDMS($dms) {
292        $this->_dms = $dms;
293    }
294
295    /**
296     * @return SeedDMS_Core_DMS $dms
297     */
298    public function getDMS() {
299        return $this->_dms;
300    }
301
302    /**
303     * Return internal id of user
304     *
305     * @return int
306     */
307    public function getID() { return $this->_id; }
308
309    /**
310     * Return login of user
311     *
312     * @return string
313     */
314    public function getLogin() { return $this->_login; }
315
316    /**
317     * Change login of user
318     *
319     * @param $newLogin new login
320     * @return bool
321     */
322    public function setLogin($newLogin) { /* {{{ */
323        $newLogin = trim($newLogin);
324        if (!$newLogin)
325            return false;
326
327        $db = $this->_dms->getDB();
328
329        $queryStr = "UPDATE `tblUsers` SET `login` =".$db->qstr($newLogin)." WHERE `id` = " . $this->_id;
330        $res = $db->getResult($queryStr);
331        if (!$res)
332            return false;
333
334        $this->_login = $newLogin;
335        return true;
336    } /* }}} */
337
338    /**
339     * Return full name of user
340     *
341     * @return string
342     */
343    public function getFullName() { return $this->_fullName; }
344
345    /**
346     * Set full name of user
347     *
348     * @param $newFullName
349     * @return bool
350     */
351    public function setFullName($newFullName) { /* {{{ */
352        $db = $this->_dms->getDB();
353
354        $queryStr = "UPDATE `tblUsers` SET `fullName` = ".$db->qstr($newFullName)." WHERE `id` = " . $this->_id;
355        $res = $db->getResult($queryStr);
356        if (!$res)
357            return false;
358
359        $this->_fullName = $newFullName;
360        return true;
361    } /* }}} */
362
363    /**
364     * Get encrypted password of user
365     *
366     * @return string
367     */
368    public function getPwd() { return $this->_pwd; }
369
370    /**
371     * Set password of user
372     *
373     * The password must be encrypted before calling this method.
374     *
375     * @param $newPwd new encrypted password
376     * @return bool
377     */
378    public function setPwd($newPwd) { /* {{{ */
379        $db = $this->_dms->getDB();
380
381        $queryStr = "UPDATE `tblUsers` SET `pwd` =".$db->qstr($newPwd)." WHERE `id` = " . $this->_id;
382        $res = $db->getResult($queryStr);
383        if (!$res)
384            return false;
385
386        $this->_pwd = $newPwd;
387        return true;
388    } /* }}} */
389
390    /**
391     * @return string
392     */
393    public function getPwdExpiration() { return $this->_pwdExpiration; }
394
395    /**
396     * @param $newPwdExpiration
397     * @return bool
398     */
399    public function setPwdExpiration($newPwdExpiration) { /* {{{ */
400        $db = $this->_dms->getDB();
401
402        if (trim($newPwdExpiration) == '' || trim($newPwdExpiration) == 'never') {
403            $newPwdExpiration = null;
404            $queryStr = "UPDATE `tblUsers` SET `pwdExpiration` = NULL WHERE `id` = " . $this->_id;
405        } else {
406            if (trim($newPwdExpiration) == 'now')
407                $newPwdExpiration = date('Y-m-d H:i:s');
408            $queryStr = "UPDATE `tblUsers` SET `pwdExpiration` =".$db->qstr($newPwdExpiration)." WHERE `id` = " . $this->_id;
409        }
410        $res = $db->getResult($queryStr);
411        if (!$res)
412            return false;
413
414        $this->_pwdExpiration = $newPwdExpiration;
415        return true;
416    } /* }}} */
417
418    /**
419     * Get email address of user
420     *
421     * @return string
422     */
423    public function getEmail() { return $this->_email; }
424
425    /**
426     * Change email address of user
427     *
428     * @param $newEmail new email address
429     * @return bool
430     */
431    public function setEmail($newEmail) { /* {{{ */
432        $db = $this->_dms->getDB();
433
434        $queryStr = "UPDATE `tblUsers` SET `email` =".$db->qstr(trim($newEmail))." WHERE `id` = " . $this->_id;
435        $res = $db->getResult($queryStr);
436        if (!$res)
437            return false;
438
439        $this->_email = $newEmail;
440        return true;
441    } /* }}} */
442
443    /**
444     * @return string
445     */
446    public function getLanguage() { return $this->_language; }
447
448    /**
449     * @param $newLanguage
450     * @return bool
451     */
452    public function setLanguage($newLanguage) { /* {{{ */
453        $db = $this->_dms->getDB();
454
455        $queryStr = "UPDATE `tblUsers` SET `language` =".$db->qstr(trim($newLanguage))." WHERE `id` = " . $this->_id;
456        $res = $db->getResult($queryStr);
457        if (!$res)
458            return false;
459
460        $this->_language = $newLanguage;
461        return true;
462    } /* }}} */
463
464    /**
465     * @return string
466     */
467    public function getTheme() { return $this->_theme; }
468
469    /**
470     * @param string $newTheme
471     * @return bool
472     */
473    public function setTheme($newTheme) { /* {{{ */
474        $db = $this->_dms->getDB();
475
476        $queryStr = "UPDATE `tblUsers` SET `theme` =".$db->qstr(trim($newTheme))." WHERE `id` = " . $this->_id;
477        $res = $db->getResult($queryStr);
478        if (!$res)
479            return false;
480
481        $this->_theme = $newTheme;
482        return true;
483    } /* }}} */
484
485    /**
486     * Return comment of user
487     *
488     * @return string
489     */
490    public function getComment() { return $this->_comment; }
491
492    /**
493     * Change comment of user
494     *
495     * @param $newComment new comment
496     * @return bool
497     */
498    public function setComment($newComment) { /* {{{ */
499        $db = $this->_dms->getDB();
500
501        $queryStr = "UPDATE `tblUsers` SET `comment` =".$db->qstr(trim($newComment))." WHERE `id` = " . $this->_id;
502        $res = $db->getResult($queryStr);
503        if (!$res)
504            return false;
505
506        $this->_comment = $newComment;
507        return true;
508    } /* }}} */
509
510    /**
511     * @return string
512     */
513    public function getRole() { return $this->_role; }
514
515    /**
516     * @param integer $newrole
517     * @return bool
518     */
519    public function setRole($newrole) { /* {{{ */
520        $db = $this->_dms->getDB();
521        if (!in_array($newrole, array(SeedDMS_Core_User::role_admin, SeedDMS_Core_User::role_guest, SeedDMS_Core_User::role_user), true))
522            return false;
523
524        $queryStr = "UPDATE `tblUsers` SET `role` = " . $newrole . " WHERE `id` = " . $this->_id;
525        if (!$db->getResult($queryStr))
526            return false;
527
528        $this->_role = $newrole;
529        return true;
530    } /* }}} */
531
532    /**
533     * Check, if user is an administrator
534     *
535     * @return bool
536     */
537    public function isAdmin() { return ($this->_role == SeedDMS_Core_User::role_admin); }
538
539    /**
540     * Turn user into a admin
541     *
542     * @return bool
543     */
544    public function setAdmin() { /* {{{ */
545        $db = $this->_dms->getDB();
546
547        $queryStr = "UPDATE `tblUsers` SET `role` = " . SeedDMS_Core_User::role_admin . " WHERE `id` = " . $this->_id;
548        if (!$db->getResult($queryStr))
549            return false;
550
551        $this->_role = SeedDMS_Core_User::role_admin;
552        return true;
553    } /* }}} */
554
555    /**
556     * Check, if user is a guest
557     *
558     * @return bool
559     */
560    public function isGuest() { return ($this->_role == SeedDMS_Core_User::role_guest); }
561
562    /**
563     * Turn user into a guest
564     *
565     * @return bool
566     */
567    public function setGuest() { /* {{{ */
568        $db = $this->_dms->getDB();
569
570        $queryStr = "UPDATE `tblUsers` SET `role` = " . SeedDMS_Core_User::role_guest . " WHERE `id` = " . $this->_id;
571        if (!$db->getResult($queryStr))
572            return false;
573
574        $this->_role = SeedDMS_Core_User::role_guest;
575        return true;
576    } /* }}} */
577
578    /**
579     * Check, if user is a regular user
580     *
581     * @return bool
582     */
583    public function isUser() { return ($this->_role == SeedDMS_Core_User::role_user); }
584
585    /**
586     * Check, if user is hidden
587     *
588     * @return bool
589     */
590    public function isHidden() { return $this->_isHidden; }
591
592    /**
593     * Set user hidden
594     *
595     * @param $isHidden
596     * @return bool
597     */
598    public function setHidden($isHidden) { /* {{{ */
599        $db = $this->_dms->getDB();
600
601        $isHidden = ($isHidden) ? "1" : "0";
602        $queryStr = "UPDATE `tblUsers` SET `hidden` = " . intval($isHidden) . " WHERE `id` = " . $this->_id;
603        if (!$db->getResult($queryStr))
604            return false;
605
606        $this->_isHidden = (bool) $isHidden;
607        return true;
608    }     /* }}} */
609
610    /**
611     * Check, if user is disabled
612     *
613     * @return bool|int
614     */
615    public function isDisabled() { return $this->_isDisabled; }
616
617    /**
618     * Disable user
619     *
620     * @param $isDisabled
621     * @return bool
622     */
623    public function setDisabled($isDisabled) { /* {{{ */
624        $db = $this->_dms->getDB();
625
626        $isDisabled = ($isDisabled) ? "1" : "0";
627        $queryStr = "UPDATE `tblUsers` SET `disabled` = " . intval($isDisabled) . " WHERE `id` = " . $this->_id;
628        if (!$db->getResult($queryStr))
629            return false;
630
631        $this->_isDisabled = (bool) $isDisabled;
632        return true;
633    }     /* }}} */
634
635    /**
636     * @return bool|int
637     */
638    public function addLoginFailure() { /* {{{ */
639        $db = $this->_dms->getDB();
640
641        $this->_loginFailures++;
642        $queryStr = "UPDATE `tblUsers` SET `loginfailures` = " . $this->_loginFailures . " WHERE `id` = " . $this->_id;
643        if (!$db->getResult($queryStr))
644            return false;
645
646        return $this->_loginFailures;
647    } /* }}} */
648
649    /**
650     * @return bool
651     */
652    public function clearLoginFailures() { /* {{{ */
653        $db = $this->_dms->getDB();
654
655        $this->_loginFailures = 0;
656        $queryStr = "UPDATE `tblUsers` SET `loginfailures` = " . $this->_loginFailures . " WHERE `id` = " . $this->_id;
657        if (!$db->getResult($queryStr))
658            return false;
659
660        return true;
661    } /* }}} */
662
663    /**
664     * Calculate the disk space for all documents owned by the user
665     *
666     * This is done by using the internal database field storing the
667     * filesize of a document version.
668     *
669     * @return integer total disk space in Bytes
670     */
671    public function getUsedDiskSpace() { /* {{{ */
672        $db = $this->_dms->getDB();
673
674        $queryStr = "SELECT SUM(`fileSize`) sum FROM `tblDocumentContent` a LEFT JOIN `tblDocuments` b ON a.`document`=b.`id` WHERE b.`owner` = " . $this->_id;
675        $resArr = $db->getResultArray($queryStr);
676        if (is_bool($resArr) && $resArr == false)
677            return false;
678
679        return (int) $resArr[0]['sum'];
680    } /* }}} */
681
682    /**
683     * @return int
684     */
685    public function getQuota() { return $this->_quota; }
686
687    /**
688     * @param integer $quota
689     * @return bool
690     */
691    public function setQuota($quota) { /* {{{ */
692        if (!is_numeric($quota))
693            return false;
694        if ($quota < 0)
695            return false;
696
697        $db = $this->_dms->getDB();
698
699        $quota = intval($quota);
700        $queryStr = "UPDATE `tblUsers` SET `quota` = " . $quota . " WHERE `id` = " . $this->_id;
701        if (!$db->getResult($queryStr))
702            return false;
703
704        $this->_quota = (int) $quota;
705        return true;
706    }     /* }}} */
707
708    /**
709     * @return null|SeedDMS_Core_Folder
710     */
711    public function getHomeFolder() { return $this->_homeFolder; }
712
713    /**
714     * @param integer $homefolder
715     * @return bool
716     */
717    public function setHomeFolder($homefolder) { /* {{{ */
718        $db = $this->_dms->getDB();
719        $homefolder = intval($homefolder);
720
721        $queryStr = "UPDATE `tblUsers` SET `homefolder` = " . ($homefolder ? $homefolder : 'NULL') . " WHERE `id` = " . $this->_id;
722        if (!$db->getResult($queryStr))
723            return false;
724
725        $this->_homeFolder = $homefolder;
726        return true;
727    }     /* }}} */
728
729    /**
730     * Remove user from all processes
731     *
732     * This method adds another log entry to the reviews and approvals
733     * which indicates the user has been deleted from the process. By default it will
734     * do so for each review/approval regardless of its current state unles
735     * the user has been removed already (status=-2). So even
736     * reviews/approvals already processed by the user will be added the log
737     * entry. Only, if the last log entry was a removal already, it will not be
738     * added a second time.
739     *
740     * This removal from processes will also take place for older versions of a document.
741     *
742     * This methode was initialy added to remove a user (which is going to be deleted
743     * afterwards) from all processes he or she is still involved in.
744     *
745     * If a new user is passed, then this user will be added as a new reviewer, approver, etc.
746     * Hence, this method does not replace the old user but actually deletes the old user and
747     * adds a new one. Adding the new reviewer, approver, etc. will also be done for old versions
748     * of a document. The same operation could be archieved by first calling
749     * SeedDMS_Core_DocumentVersion::delIndReviewer() followed by SeedDMS_Core_DocumentVersion::addIndReviewer()
750     * but this would require to do for each version of a document and the operation would not
751     * be in a single transaction.
752     *
753     * A new user is only added if the process (review, approval, etc.) is still in its initial
754     * state (have not been reviewed/approved or rejected). Unlike the removal of the user (see above).
755     *
756     * If a new user is given but has no read access on the document the transfer for that
757     * particular document will be skipped. Not even the removal of the user will take place.
758     *
759     * @param object $user the user doing the removal (needed for entry in
760     *        review and approve log).
761     * @param array $states remove user only from reviews/approvals in one of the states
762     *        e.g. if passing array('review'=>array(0)), the method will operate on
763     *        reviews which has not been touched yet.
764     * @param object $newuser user who takes over the processes
765     * @param array $docs remove only processes from docs with the given document ids
766     * @return boolean true on success or false in case of an error
767     */
768    private function __removeFromProcesses($user, $states = array(), $newuser = null, $docs = null) { /* {{{ */
769        $db = $this->_dms->getDB();
770
771        /* Get a list of all reviews, even those of older document versions */
772        $reviewStatus = $this->getReviewStatus();
773        $db->startTransaction();
774        foreach ($reviewStatus["indstatus"] as $ri) {
775            if (!($doc = $this->_dms->getDocument($ri['documentID'])))
776                continue;
777            if ($docs) {
778                if (!in_array($doc->getID(), $docs))
779                    continue;
780                if (!$doc->isLatestContent($ri['version']))
781                    continue;
782            }
783            if ($newuser && $doc->getAccessMode($newuser) < M_READ)
784                continue;
785            if ($ri['status'] != -2 && (!isset($states['review']) || in_array($ri['status'], $states['review']))) {
786                $queryStr = "INSERT INTO `tblDocumentReviewLog` (`reviewID`, `status`, `comment`, `date`, `userID`) ".
787                    "VALUES ('". $ri["reviewID"] ."', '-2', '".(($newuser && $ri['status'] == 0) ? 'Reviewer replaced by '.$newuser->getLogin() : 'Reviewer removed from process')."', ".$db->getCurrentDatetime().", '". $user->getID() ."')";
788                $res = $db->getResult($queryStr);
789                if (!$res) {
790                    $db->rollbackTransaction();
791                    return false;
792                }
793                /* Only reviews not done already can be transferred to a new user */
794                if ($newuser && $ri['status'] == 0) {
795                    if ($version = $doc->getContentByVersion($ri['version'])) {
796                        $ret = $version->addIndReviewer($newuser, $user);
797                        /* returns -3 if the user is already a reviewer */
798                        if ($ret === false || ($ret < 0 && $ret != -3)) {
799                            $db->rollbackTransaction();
800                            return false;
801                        }
802                    }
803                }
804            }
805        }
806        $db->commitTransaction();
807
808        /* Get a list of all approvals, even those of older document versions */
809        $approvalStatus = $this->getApprovalStatus();
810        $db->startTransaction();
811        foreach ($approvalStatus["indstatus"] as $ai) {
812            if (!($doc = $this->_dms->getDocument($ai['documentID'])))
813                continue;
814            if ($docs) {
815                if (!in_array($doc->getID(), $docs))
816                    continue;
817                if (!$doc->isLatestContent($ai['version']))
818                    continue;
819            }
820            if ($newuser && $doc->getAccessMode($newuser) < M_READ)
821                continue;
822            if ($ai['status'] != -2 && (!isset($states['approval']) || in_array($ai['status'], $states['approval']))) {
823                $queryStr = "INSERT INTO `tblDocumentApproveLog` (`approveID`, `status`, `comment`, `date`, `userID`) ".
824                    "VALUES ('". $ai["approveID"] ."', '-2', '".(($newuser && $ai['status'] == 0)? 'Approver replaced by '.$newuser->getLogin() : 'Approver removed from process')."', ".$db->getCurrentDatetime().", '". $user->getID() ."')";
825                $res = $db->getResult($queryStr);
826                if (!$res) {
827                    $db->rollbackTransaction();
828                    return false;
829                }
830                /* Only approvals not done already can be transferred to a new user */
831                if ($newuser && $ai['status'] == 0) {
832                    if ($version = $doc->getContentByVersion($ai['version'])) {
833                        $ret = $version->addIndReviewer($newuser, $user);
834                        /* returns -3 if the user is already a reviewer */
835                        if ($ret === false || ($ret < 0 && $ret != -3)) {
836                            $db->rollbackTransaction();
837                            return false;
838                        }
839                    }
840                }
841            }
842        }
843        $db->commitTransaction();
844
845        return true;
846    } /* }}} */
847
848    /**
849     * Remove user from all processes
850     *
851     * This includes review, approval and workflow
852     *
853     * @param object $user the user doing the removal (needed for entry in
854     *        review and approve log).
855     * @param array $states remove user only from reviews/approvals in one of the states
856     * @param object $newuser user who takes over the processes
857     * @return boolean true on success or false in case of an error
858     */
859    public function removeFromProcesses($user, $states = array(), $newuser = null, $docs = null) { /* {{{ */
860        $db = $this->_dms->getDB();
861
862        $db->startTransaction();
863        if (!$this->__removeFromProcesses($user, $states, $newuser, $docs)) {
864            $db->rollbackTransaction();
865            return false;
866        }
867        $db->commitTransaction();
868        return true;
869    } /* }}} */
870
871    /**
872     * Transfer documents and folders to another user
873     *
874     * @param object $assignToUser the user who is new owner of folders and
875     *        documents which previously were owned by the delete user.
876     * @return boolean true on success or false in case of an error
877     */
878    private function __transferDocumentsFolders($assignToUser) { /* {{{ */
879        $db = $this->_dms->getDB();
880
881        if (!$assignToUser)
882            return false;
883
884        /* Assign documents of the removed user to the given user */
885        $queryStr = "UPDATE `tblFolders` SET `owner` = " . $assignToUser->getID() . " WHERE `owner` = " . $this->_id;
886        if (!$db->getResult($queryStr)) {
887            return false;
888        }
889
890        $queryStr = "UPDATE `tblDocuments` SET `owner` = " . $assignToUser->getID() . " WHERE `owner` = " . $this->_id;
891        if (!$db->getResult($queryStr)) {
892            return false;
893        }
894
895        $queryStr = "UPDATE `tblDocumentContent` SET `createdBy` = " . $assignToUser->getID() . " WHERE `createdBy` = " . $this->_id;
896        if (!$db->getResult($queryStr)) {
897            return false;
898        }
899
900        // ... but keep public links
901        $queryStr = "UPDATE `tblDocumentLinks` SET `userID` = " . $assignToUser->getID() . " WHERE `userID` = " . $this->_id;
902        if (!$db->getResult($queryStr)) {
903            return false;
904        }
905
906        // set administrator for deleted user's attachments
907        $queryStr = "UPDATE `tblDocumentFiles` SET `userID` = " . $assignToUser->getID() . " WHERE `userID` = " . $this->_id;
908        if (!$db->getResult($queryStr)) {
909            return false;
910        }
911
912        return true;
913    } /* }}} */
914
915    /**
916     * Transfer documents and folders to another user
917     *
918     * @param object $assignToUser the user who is new owner of folders and
919     *        documents which previously were owned by the delete user.
920     * @return boolean true on success or false in case of an error
921     */
922    public function transferDocumentsFolders($assignToUser) { /* {{{ */
923        $db = $this->_dms->getDB();
924
925        if ($assignToUser->getID() == $this->_id)
926            return true;
927
928        $db->startTransaction();
929        if (!$this->__transferDocumentsFolders($assignToUser)) {
930            $db->rollbackTransaction();
931            return false;
932        }
933        $db->commitTransaction();
934        return true;
935    } /* }}} */
936
937    /**
938     * Transfer events to another user
939     *
940     * @param object $assignToUser the user who is new owner of events
941     * @return boolean true on success or false in case of an error
942     */
943    private function __transferEvents($assignToUser) { /* {{{ */
944        $db = $this->_dms->getDB();
945
946        if (!$assignToUser)
947            return false;
948
949        // set new owner of events
950        $queryStr = "UPDATE `tblEvents` SET `userID` = " . $assignToUser->getID() . " WHERE `userID` = " . $this->_id;
951        if (!$db->getResult($queryStr)) {
952            return false;
953        }
954
955        return true;
956    } /* }}} */
957
958    /**
959     * Transfer events to another user
960     *
961     * @param object $assignToUser the user who is new owner of events
962     * @return boolean true on success or false in case of an error
963     */
964    public function transferEvents($assignToUser) { /* {{{ */
965        $db = $this->_dms->getDB();
966
967        if ($assignToUser->getID() == $this->_id)
968            return true;
969
970        $db->startTransaction();
971        if (!$this->__transferEvents($assignToUser)) {
972            $db->rollbackTransaction();
973            return false;
974        }
975        $db->commitTransaction();
976        return true;
977    } /* }}} */
978
979    /**
980     * Remove the user and also remove all its keywords, notifications, etc.
981     * Do not remove folders and documents of the user, but assign them
982     * to a different user.
983     *
984     * @param SeedDMS_Core_User $user the user doing the removal (needed for entry in
985     *        review and approve log).
986     * @param SeedDMS_Core_User $assignToUser the user who is new owner of folders and
987     *        documents which previously were owned by the delete user.
988     * @return boolean true on success or false in case of an error
989     */
990    public function remove($user, $assignToUser = null) { /* {{{ */
991        $db = $this->_dms->getDB();
992
993        /* Records like folders and documents that formely have belonged to
994         * the user will assign to another user. If no such user is set,
995         * the function now returns false and will not use the admin user
996         * anymore.
997         */
998        if (!$assignToUser)
999            return false;
1000            /** @noinspection PhpUnusedLocalVariableInspection */
1001            $assignTo = $assignToUser->getID();
1002
1003        $db->startTransaction();
1004
1005        // delete private keyword lists
1006        $queryStr = "SELECT `tblKeywords`.`id` FROM `tblKeywords`, `tblKeywordCategories` WHERE `tblKeywords`.`category` = `tblKeywordCategories`.`id` AND `tblKeywordCategories`.`owner` = " . $this->_id;
1007        $resultArr = $db->getResultArray($queryStr);
1008        if (count($resultArr) > 0) {
1009            $queryStr = "DELETE FROM `tblKeywords` WHERE ";
1010            for ($i = 0; $i < count($resultArr); $i++) {
1011                $queryStr .= "id = " . $resultArr[$i]["id"];
1012                if ($i + 1 < count($resultArr))
1013                    $queryStr .= " OR ";
1014            }
1015            if (!$db->getResult($queryStr)) {
1016                $db->rollbackTransaction();
1017                return false;
1018            }
1019        }
1020
1021        $queryStr = "DELETE FROM `tblKeywordCategories` WHERE `owner` = " . $this->_id;
1022        if (!$db->getResult($queryStr)) {
1023            $db->rollbackTransaction();
1024            return false;
1025        }
1026
1027        //Benachrichtigungen entfernen
1028        $queryStr = "DELETE FROM `tblNotify` WHERE `userID` = " . $this->_id;
1029        if (!$db->getResult($queryStr)) {
1030            $db->rollbackTransaction();
1031            return false;
1032        }
1033
1034        // Remove private links on documents ...
1035        $queryStr = "DELETE FROM `tblDocumentLinks` WHERE `userID` = " . $this->_id . " AND `public` = 0";
1036        if (!$db->getResult($queryStr)) {
1037            $db->rollbackTransaction();
1038            return false;
1039        }
1040
1041        /* Assign documents, folders, files, public document links of the removed user to the given user */
1042        if (!$this->__transferDocumentsFolders($assignToUser)) {
1043                $db->rollbackTransaction();
1044                return false;
1045        }
1046
1047        // unlock documents locked by the user
1048        $queryStr = "DELETE FROM `tblDocumentLocks` WHERE `userID` = " . $this->_id;
1049        if (!$db->getResult($queryStr)) {
1050            $db->rollbackTransaction();
1051            return false;
1052        }
1053
1054        // Delete user from all groups
1055        $queryStr = "DELETE FROM `tblGroupMembers` WHERE `userID` = " . $this->_id;
1056        if (!$db->getResult($queryStr)) {
1057            $db->rollbackTransaction();
1058            return false;
1059        }
1060
1061        // User aus allen ACLs streichen
1062        $queryStr = "DELETE FROM `tblACLs` WHERE `userID` = " . $this->_id;
1063        if (!$db->getResult($queryStr)) {
1064            $db->rollbackTransaction();
1065            return false;
1066        }
1067
1068        // Delete image of user
1069        $queryStr = "DELETE FROM `tblUserImages` WHERE `userID` = " . $this->_id;
1070        if (!$db->getResult($queryStr)) {
1071            $db->rollbackTransaction();
1072            return false;
1073        }
1074
1075        // Delete entries in password history
1076        $queryStr = "DELETE FROM `tblUserPasswordHistory` WHERE `userID` = " . $this->_id;
1077        if (!$db->getResult($queryStr)) {
1078            $db->rollbackTransaction();
1079            return false;
1080        }
1081
1082        // Delete entries in password request
1083        $queryStr = "DELETE FROM `tblUserPasswordRequest` WHERE `userID` = " . $this->_id;
1084        if (!$db->getResult($queryStr)) {
1085            $db->rollbackTransaction();
1086            return false;
1087        }
1088
1089        // mandatory review/approve
1090        $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `reviewerUserID` = " . $this->_id;
1091        if (!$db->getResult($queryStr)) {
1092            $db->rollbackTransaction();
1093            return false;
1094        }
1095
1096        $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `approverUserID` = " . $this->_id;
1097        if (!$db->getResult($queryStr)) {
1098            $db->rollbackTransaction();
1099            return false;
1100        }
1101
1102        $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id;
1103        if (!$db->getResult($queryStr)) {
1104            $db->rollbackTransaction();
1105            return false;
1106        }
1107
1108        $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id;
1109        if (!$db->getResult($queryStr)) {
1110            $db->rollbackTransaction();
1111            return false;
1112        }
1113
1114        $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id;
1115        if (!$db->getResult($queryStr)) {
1116            $db->rollbackTransaction();
1117            return false;
1118        }
1119
1120        $queryStr = "DELETE FROM `tblWorkflowTransitionUsers` WHERE `userid` = " . $this->_id;
1121        if (!$db->getResult($queryStr)) {
1122            $db->rollbackTransaction();
1123            return false;
1124        }
1125
1126        /* Assign events of the removed user to the given user */
1127        if (!$this->__transferEvents($assignToUser)) {
1128                $db->rollbackTransaction();
1129                return false;
1130        }
1131
1132        // Delete user itself
1133        $queryStr = "DELETE FROM `tblUsers` WHERE `id` = " . $this->_id;
1134        if (!$db->getResult($queryStr)) {
1135            $db->rollbackTransaction();
1136            return false;
1137        }
1138
1139        // TODO : update document status if reviewer/approver has been deleted
1140        // "DELETE FROM `tblDocumentApproveLog` WHERE `userID` = " . $this->_id;
1141        // "DELETE FROM `tblDocumentReviewLog` WHERE `userID` = " . $this->_id;
1142
1143        if (!$this->__removeFromProcesses($user)) {
1144                $db->rollbackTransaction();
1145                return false;
1146        }
1147
1148        $db->commitTransaction();
1149        return true;
1150    } /* }}} */
1151
1152    /**
1153     * Make the user a member of a group
1154     * This function uses {@link SeedDMS_Group::addUser} but checks before if
1155     * the user is already a member of the group.
1156     *
1157     * @param SeedDMS_Core_Group $group group to be the member of
1158     * @return boolean true on success or false in case of an error or the user
1159     *        is already a member of the group
1160     */
1161    public function joinGroup($group) { /* {{{ */
1162        if ($group->isMember($this))
1163            return false;
1164
1165        if (!$group->addUser($this))
1166            return false;
1167
1168        unset($this->_groups);
1169        return true;
1170    } /* }}} */
1171
1172    /**
1173     * Removes the user from a group
1174     * This function uses {@link SeedDMS_Group::removeUser} but checks before if
1175     * the user is a member of the group at all.
1176     *
1177     * @param SeedDMS_Core_Group $group group to leave
1178     * @return boolean true on success or false in case of an error or the user
1179     *        is not a member of the group
1180     */
1181    public function leaveGroup($group) { /* {{{ */
1182        if (!$group->isMember($this))
1183            return false;
1184
1185        if (!$group->removeUser($this))
1186            return false;
1187
1188        unset($this->_groups);
1189        return true;
1190    } /* }}} */
1191
1192    /**
1193     * Get all groups the user is a member of
1194     *
1195     * @return SeedDMS_Core_Group[]|bool list of groups
1196     */
1197    public function getGroups() { /* {{{ */
1198        $db = $this->_dms->getDB();
1199
1200        if (!isset($this->_groups)) {
1201            $queryStr = "SELECT `tblGroups`.*, `tblGroupMembers`.`userID` FROM `tblGroups` ".
1202                "LEFT JOIN `tblGroupMembers` ON `tblGroups`.`id` = `tblGroupMembers`.`groupID` ".
1203                "WHERE `tblGroupMembers`.`userID`='". $this->_id ."'";
1204            $resArr = $db->getResultArray($queryStr);
1205            if (is_bool($resArr) && $resArr == false)
1206                return false;
1207
1208            $this->_groups = array();
1209            $classname = $this->_dms->getClassname('group');
1210            foreach ($resArr as $row) {
1211                /** @var SeedDMS_Core_Group $group */
1212                $group = new $classname((int) $row["id"], $row["name"], $row["comment"]);
1213                $group->setDMS($this->_dms);
1214                array_push($this->_groups, $group);
1215            }
1216        }
1217        return $this->_groups;
1218    } /* }}} */
1219
1220    /**
1221     * Checks if user is member of a given group
1222     *
1223     * @param SeedDMS_Core_Group $group
1224     * @return boolean true if user is member of the given group otherwise false
1225     */
1226    public function isMemberOfGroup($group) { /* {{{ */
1227        return $group->isMember($this);
1228    } /* }}} */
1229
1230    /**
1231     * Check if user has an image in its profile
1232     *
1233     * @return boolean true if user has a picture of itself
1234     */
1235    public function hasImage() { /* {{{ */
1236        if (!isset($this->_hasImage)) {
1237            $db = $this->_dms->getDB();
1238
1239            $queryStr = "SELECT COUNT(*) AS num FROM `tblUserImages` WHERE `userID` = " . $this->_id;
1240            $resArr = $db->getResultArray($queryStr);
1241            if ($resArr === false)
1242                return false;
1243
1244            if ($resArr[0]["num"] == 0)    $this->_hasImage = false;
1245            else $this->_hasImage = true;
1246        }
1247
1248        return $this->_hasImage;
1249    } /* }}} */
1250
1251    /**
1252     * Get the image from the users profile
1253     *
1254     * @return string|null|bool image data as a string or null if no image is set or
1255     * false in case of an error
1256     */
1257    public function getImage() { /* {{{ */
1258        $db = $this->_dms->getDB();
1259
1260        $queryStr = "SELECT * FROM `tblUserImages` WHERE `userID` = " . $this->_id;
1261        $resArr = $db->getResultArray($queryStr);
1262        if ($resArr === false)
1263            return false;
1264
1265        if ($resArr)
1266            return $resArr[0];
1267        else
1268            return null;
1269    } /* }}} */
1270
1271    /**
1272     * @param $tmpfile
1273     * @param $mimeType
1274     * @return bool
1275     */
1276    public function setImage($tmpfile, $mimeType) { /* {{{ */
1277        $db = $this->_dms->getDB();
1278
1279        $fp = fopen($tmpfile, "rb");
1280        if (!$fp) return false;
1281        $content = fread($fp, filesize($tmpfile));
1282        fclose($fp);
1283
1284        if ($this->hasImage()) {
1285            $queryStr = "UPDATE `tblUserImages` SET `image` = '".base64_encode($content)."', `mimeType` = ".$db->qstr($mimeType)." WHERE `userID` = " . $this->_id;
1286        } else {
1287            $queryStr = "INSERT INTO `tblUserImages` (`userID`, `image`, `mimeType`) VALUES (" . $this->_id . ", '".base64_encode($content)."', ".$db->qstr($mimeType).")";
1288        }
1289        if (!$db->getResult($queryStr)) {
1290            return false;
1291        }
1292
1293        $this->_hasImage = true;
1294        return true;
1295    } /* }}} */
1296
1297    /**
1298     * Returns all documents of a given user
1299     * @return SeedDMS_Core_Document[]|bool list of documents
1300     */
1301    public function getDocuments() { /* {{{ */
1302        $db = $this->_dms->getDB();
1303
1304        $queryStr = "SELECT `tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser` ".
1305            "FROM `tblDocuments` ".
1306            "LEFT JOIN `tblDocumentLocks` ON `tblDocuments`.`id`=`tblDocumentLocks`.`document` ".
1307            "WHERE `tblDocuments`.`owner` = " . $this->_id . " ORDER BY `sequence`";
1308
1309        $resArr = $db->getResultArray($queryStr);
1310        if (is_bool($resArr) && !$resArr)
1311            return false;
1312
1313        $documents = array();
1314        $classname = $this->_dms->getClassname('document');
1315        foreach ($resArr as $row) {
1316            /** @var SeedDMS_Core_Document $document */
1317            $document = new $classname((int) $row["id"], $row["name"], $row["comment"], $row["date"], $row["expires"], $row["owner"], $row["folder"], $row["inheritAccess"], $row["defaultAccess"], $row["lockUser"], $row["keywords"], $row["sequence"]);
1318            $document->setDMS($this->_dms);
1319            $documents[] = $document;
1320        }
1321        return $documents;
1322    } /* }}} */
1323
1324    /**
1325     * Returns all documents locked by a given user
1326     *
1327     * @return bool|SeedDMS_Core_Document[] list of documents
1328     */
1329    public function getDocumentsLocked() { /* {{{ */
1330        $db = $this->_dms->getDB();
1331
1332        $queryStr = "SELECT `tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser` ".
1333            "FROM `tblDocumentLocks` LEFT JOIN `tblDocuments` ON `tblDocuments`.`id` = `tblDocumentLocks`.`document` ".
1334            "WHERE `tblDocumentLocks`.`userID` = '".$this->_id."' ".
1335            "ORDER BY `id` DESC";
1336
1337        $resArr = $db->getResultArray($queryStr);
1338        if (is_bool($resArr) && !$resArr)
1339            return false;
1340
1341        $documents = array();
1342        $classname = $this->_dms->getClassname('document');
1343        foreach ($resArr as $row) {
1344            /** @var SeedDMS_Core_Document $document */
1345            $document = new $classname((int) $row["id"], $row["name"], $row["comment"], $row["date"], $row["expires"], $row["owner"], $row["folder"], $row["inheritAccess"], $row["defaultAccess"], $row["lockUser"], $row["keywords"], $row["sequence"]);
1346            $document->setDMS($this->_dms);
1347            $documents[] = $document;
1348        }
1349        return $documents;
1350    } /* }}} */
1351
1352    /**
1353     * Returns all document links of a given user
1354     * @return SeedDMS_Core_DocumentLink[]|bool list of document links
1355     */
1356    public function getDocumentLinks() { /* {{{ */
1357        $db = $this->_dms->getDB();
1358
1359        $queryStr = "SELECT * FROM `tblDocumentLinks` ".
1360            "WHERE `userID` = " . $this->_id;
1361
1362        $resArr = $db->getResultArray($queryStr);
1363        if (is_bool($resArr) && !$resArr)
1364            return false;
1365
1366        $links = array();
1367        $classname = 'SeedDMS_Core_DocumentLink';
1368        foreach ($resArr as $row) {
1369            $document = $this->_dms->getDocument($row["document"]);
1370            $target = $this->_dms->getDocument($row["target"]);
1371            /** @var SeedDMS_Core_Document $document */
1372            $link = new $classname((int) $row["id"], $document, $target, $row["userID"], $row["public"]);
1373            $links[] = $link;
1374        }
1375        return $links;
1376    } /* }}} */
1377
1378    /**
1379     * Returns all document files of a given user
1380     * @return SeedDMS_Core_DocumentFile[]|bool list of document files
1381     */
1382    public function getDocumentFiles() { /* {{{ */
1383        $db = $this->_dms->getDB();
1384
1385        $queryStr = "SELECT * FROM `tblDocumentFiles` ".
1386            "WHERE `userID` = " . $this->_id;
1387
1388        $resArr = $db->getResultArray($queryStr);
1389        if (is_bool($resArr) && !$resArr)
1390            return false;
1391
1392        $files = array();
1393        $classname = 'SeedDMS_Core_DocumentFile';
1394        foreach ($resArr as $row) {
1395            $document = $this->_dms->getDocument($row["document"]);
1396            /** @var SeedDMS_Core_DocumentFile $file */
1397            $file = new $classname((int) $row["id"], $document, $row["userID"], $row["comment"], $row["date"], $row["dir"], $row["fileType"], $row["mimeType"], $row["orgFileName"], $row["name"], $row["version"], $row["public"]);
1398            $files[] = $file;
1399        }
1400        return $files;
1401    } /* }}} */
1402
1403    /**
1404     * Returns all document contents of a given user
1405     * @return SeedDMS_Core_DocumentContent[]|bool list of document contents
1406     */
1407    public function getDocumentContents() { /* {{{ */
1408        $db = $this->_dms->getDB();
1409
1410        $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `createdBy` = " . $this->_id;
1411
1412        $resArr = $db->getResultArray($queryStr);
1413        if (is_bool($resArr) && !$resArr)
1414            return false;
1415
1416        $contents = array();
1417        $classname = $this->_dms->getClassname('documentcontent');
1418        foreach ($resArr as $row) {
1419            $document = $this->_dms->getDocument($row["document"]);
1420            /** @var SeedDMS_Core_DocumentContent $content */
1421            $content = new $classname((int) $row["id"], $document, $row["version"], $row["comment"], $row["date"], $row["createdBy"], $row["dir"], $row["orgFileName"], $row["fileType"], $row["mimeType"], $row['fileSize'], $row['checksum']);
1422            $contents[] = $content;
1423        }
1424        return $contents;
1425    } /* }}} */
1426
1427    /**
1428     * Returns all folders of a given user
1429     * @return SeedDMS_Core_Folder[]|bool list of folders
1430     */
1431    public function getFolders() { /* {{{ */
1432        $db = $this->_dms->getDB();
1433
1434        $queryStr = "SELECT * FROM `tblFolders` ".
1435            "WHERE `owner` = " . $this->_id . " ORDER BY `sequence`";
1436
1437        $resArr = $db->getResultArray($queryStr);
1438        if (is_bool($resArr) && !$resArr)
1439            return false;
1440
1441        $folders = array();
1442        $classname = $this->_dms->getClassname('folder');
1443        foreach ($resArr as $row) {
1444            /** @var SeedDMS_Core_Folder $folder */
1445            $folder = new $classname((int) $row["id"], $row["name"], $row['parent'], $row["comment"], $row["date"], $row["owner"], $row["inheritAccess"], $row["defaultAccess"], $row["sequence"]);
1446            $folder->setDMS($this->_dms);
1447            $folders[] = $folder;
1448        }
1449        return $folders;
1450    } /* }}} */
1451
1452    /**
1453     * Get a list of reviews
1454     *
1455     * This function returns a list of all reviews and their latest log entry
1456     * seperated by individuals and groups. If the document id
1457     * is passed, then only this document will be checked for reviews. The
1458     * same is true for the version of a document which limits the list
1459     * further. If you do not limit on a version it will retrieve the status
1460     * for each version, that includes even older versions which has been superseded
1461     * by a new version.
1462     *
1463     * For a detailed description of the result array see
1464     * {link SeedDMS_Core_User::getApprovalStatus} which does the same for
1465     * approvals.
1466     *
1467     * @param int $documentID optional document id for which to retrieve the
1468     *        reviews
1469     * @param int $version optional version of the document
1470     * @return array|bool list of all reviews
1471     */
1472    public function getReviewStatus($documentID = null, $version = null) { /* {{{ */
1473        $db = $this->_dms->getDB();
1474
1475        if (!$db->createTemporaryTable("ttreviewid", true)) {
1476            return false;
1477        }
1478
1479        $status = array("indstatus" => array(), "grpstatus" => array());
1480
1481        // See if the user is assigned as an individual reviewer.
1482        // Attention: this method didn't use ttreviewid to filter out the latest
1483        // log entry. This was added 2021-09-29 because $group->getReviewStatus()
1484        // does it as well. The check below if the date is larger than the date
1485        // of a previos entry is still required to just take the latest version
1486        // of a document into account.
1487        $queryStr = "SELECT `tblDocumentReviewers`.*, `tblDocumentReviewLog`.`status`, ".
1488            "`tblDocumentReviewLog`.`comment`, `tblDocumentReviewLog`.`date`, ".
1489            "`tblDocumentReviewLog`.`userID` ".
1490            "FROM `tblDocumentReviewers` ".
1491            "LEFT JOIN `tblDocumentReviewLog` USING (`reviewID`) ".
1492            "LEFT JOIN `ttreviewid` on `ttreviewid`.`maxLogID` = `tblDocumentReviewLog`.`reviewLogID` ".
1493            "WHERE `ttreviewid`.`maxLogID`=`tblDocumentReviewLog`.`reviewLogID` ".
1494            ($documentID == null ? "" : "AND `tblDocumentReviewers`.`documentID` = '". (int) $documentID ."' ").
1495            ($version == null ? "" : "AND `tblDocumentReviewers`.`version` = '". (int) $version ."' ").
1496            "AND `tblDocumentReviewers`.`type`='0' ".
1497            "AND `tblDocumentReviewers`.`required`='". $this->_id ."' ".
1498            "ORDER BY `tblDocumentReviewLog`.`reviewLogID` DESC";
1499        $resArr = $db->getResultArray($queryStr);
1500        if (is_bool($resArr) && $resArr === false)
1501            return false;
1502        if (count($resArr)>0) {
1503            foreach ($resArr as $res) {
1504                if (isset($status["indstatus"][$res['documentID']])) {
1505                    if ($status["indstatus"][$res['documentID']]['date'] < $res['date']) {
1506                        $status["indstatus"][$res['documentID']] = $res;
1507                    }
1508                } else {
1509                    $status["indstatus"][$res['documentID']] = $res;
1510                }
1511            }
1512        }
1513
1514        // See if the user is the member of a group that has been assigned to
1515        // review the document version.
1516        $queryStr = "SELECT `tblDocumentReviewers`.*, `tblDocumentReviewLog`.`status`, ".
1517            "`tblDocumentReviewLog`.`comment`, `tblDocumentReviewLog`.`date`, ".
1518            "`tblDocumentReviewLog`.`userID` ".
1519            "FROM `tblDocumentReviewers` ".
1520            "LEFT JOIN `tblDocumentReviewLog` USING (`reviewID`) ".
1521            "LEFT JOIN `ttreviewid` on `ttreviewid`.`maxLogID` = `tblDocumentReviewLog`.`reviewLogID` ".
1522            "LEFT JOIN `tblGroupMembers` ON `tblGroupMembers`.`groupID` = `tblDocumentReviewers`.`required` ".
1523            "WHERE `ttreviewid`.`maxLogID`=`tblDocumentReviewLog`.`reviewLogID` ".
1524            ($documentID == null ? "" : "AND `tblDocumentReviewers`.`documentID` = '". (int) $documentID ."' ").
1525            ($version == null ? "" : "AND `tblDocumentReviewers`.`version` = '". (int) $version ."' ").
1526            "AND `tblDocumentReviewers`.`type`='1' ".
1527            "AND `tblGroupMembers`.`userID`='". $this->_id ."' ".
1528            "ORDER BY `tblDocumentReviewLog`.`reviewLogID` DESC";
1529        $resArr = $db->getResultArray($queryStr);
1530        if (is_bool($resArr) && $resArr === false)
1531            return false;
1532        if (count($resArr)>0) {
1533            foreach ($resArr as $res) {
1534                if (isset($status["grpstatus"][$res['documentID']])) {
1535                    if ($status["grpstatus"][$res['documentID']]['date'] < $res['date']) {
1536                        $status["grpstatus"][$res['documentID']] = $res;
1537                    }
1538                } else {
1539                    $status["grpstatus"][$res['documentID']] = $res;
1540                }
1541            }
1542        }
1543        return $status;
1544    } /* }}} */
1545
1546    /**
1547     * Get a list of approvals
1548     *
1549     * This function returns a list of all approvals and their latest log entry
1550     * seperated by individuals and groups. If the document id
1551     * is passed, then only this document will be checked for approvals. The
1552     * same is true for the version of a document which limits the list
1553     * further. If you do not limit on a version it will retrieve the status
1554     * for each version, that includes even older versions which has been superseded
1555     * by a new version.
1556     *
1557     * The result array has two elements:
1558     * - indstatus: which contains the approvals by individuals (users)
1559     * - grpstatus: which contains the approvals by groups
1560     *
1561     * Each element is itself an array of approvals with the following elements
1562     * (it is a combination of fields from tblDocumentApprovers and tblDocumentApproveLog):
1563     * - approveID: unique id of approval
1564     * - documentID: id of document, that needs to be approved
1565     * - version: version of document, that needs to be approved
1566     * - type: 0 for individual approval, 1 for group approval
1567     * - required: id of user who is required to do the approval
1568     * - status: 0 not approved, ....
1569     * - comment: comment given during approval
1570     * - date: date of approval
1571     * - userID: id of user who has done the approval
1572     *
1573     * @param int $documentID optional document id for which to retrieve the
1574     *        approvals
1575     * @param int $version optional version of the document
1576     * @return array|bool list of all approvals
1577     */
1578    public function getApprovalStatus($documentID = null, $version = null) { /* {{{ */
1579        $db = $this->_dms->getDB();
1580
1581        if (!$db->createTemporaryTable("ttapproveid")) {
1582            return false;
1583        }
1584
1585        $status = array("indstatus" => array(), "grpstatus" => array());
1586
1587        // See if the user is assigned as an individual approver.
1588        // Attention: this method didn't use ttapproveid to filter out the latest
1589        // log entry. This was added 2021-09-29 because $group->getApprovalStatus()
1590        // does it as well. The check below if the date is larger than the date
1591        // of a previos entry is still required to just take the latest version
1592        // of a document into account.
1593        $queryStr =
1594            "SELECT `tblDocumentApprovers`.*, `tblDocumentApproveLog`.`status`, ".
1595            "`tblDocumentApproveLog`.`comment`, `tblDocumentApproveLog`.`date`, ".
1596            "`tblDocumentApproveLog`.`userID` ".
1597            "FROM `tblDocumentApprovers` ".
1598            "LEFT JOIN `tblDocumentApproveLog` USING (`approveID`) ".
1599            "LEFT JOIN `ttapproveid` on `ttapproveid`.`maxLogID` = `tblDocumentApproveLog`.`approveLogID` ".
1600            "WHERE `ttapproveid`.`maxLogID`=`tblDocumentApproveLog`.`approveLogID` ".
1601            ($documentID == null ? "" : "AND `tblDocumentApprovers`.`documentID` = '". (int) $documentID ."' ").
1602            ($version == null ? "" : "AND `tblDocumentApprovers`.`version` = '". (int) $version ."' ").
1603            "AND `tblDocumentApprovers`.`type`='0' ".
1604            "AND `tblDocumentApprovers`.`required`='". $this->_id ."' ".
1605            "ORDER BY `tblDocumentApproveLog`.`approveLogID` DESC";
1606
1607        $resArr = $db->getResultArray($queryStr);
1608        if (is_bool($resArr) && $resArr == false)
1609            return false;
1610        if (count($resArr)>0) {
1611            foreach ($resArr as $res) {
1612                if (isset($status["indstatus"][$res['documentID']])) {
1613                    if ($status["indstatus"][$res['documentID']]['date'] < $res['date']) {
1614                        $status["indstatus"][$res['documentID']] = $res;
1615                    }
1616                } else {
1617                    $status["indstatus"][$res['documentID']] = $res;
1618                }
1619            }
1620        }
1621
1622        // See if the user is the member of a group that has been assigned to
1623        // approve the document version.
1624        $queryStr =
1625            "SELECT `tblDocumentApprovers`.*, `tblDocumentApproveLog`.`status`, ".
1626            "`tblDocumentApproveLog`.`comment`, `tblDocumentApproveLog`.`date`, ".
1627            "`tblDocumentApproveLog`.`userID` ".
1628            "FROM `tblDocumentApprovers` ".
1629            "LEFT JOIN `tblDocumentApproveLog` USING (`approveID`) ".
1630            "LEFT JOIN `ttapproveid` on `ttapproveid`.`maxLogID` = `tblDocumentApproveLog`.`approveLogID` ".
1631            "LEFT JOIN `tblGroupMembers` ON `tblGroupMembers`.`groupID` = `tblDocumentApprovers`.`required` ".
1632            "WHERE `ttapproveid`.`maxLogID`=`tblDocumentApproveLog`.`approveLogID` ".
1633            ($documentID == null ? "" : "AND `tblDocumentApprovers`.`documentID` = '". (int) $documentID ."' ").
1634            ($version == null ? "" : "AND `tblDocumentApprovers`.`version` = '". (int) $version ."' ").
1635            "AND `tblDocumentApprovers`.`type`='1' ".
1636            "AND `tblGroupMembers`.`userID`='". $this->_id ."' ".
1637            "ORDER BY `tblDocumentApproveLog`.`approveLogID` DESC";
1638        $resArr = $db->getResultArray($queryStr);
1639        if (is_bool($resArr) && $resArr == false)
1640            return false;
1641        if (count($resArr)>0) {
1642            foreach ($resArr as $res) {
1643                if (isset($status["grpstatus"][$res['documentID']])) {
1644                    if ($status["grpstatus"][$res['documentID']]['date'] < $res['date']) {
1645                        $status["grpstatus"][$res['documentID']] = $res;
1646                    }
1647                } else {
1648                    $status["grpstatus"][$res['documentID']] = $res;
1649                }
1650            }
1651        }
1652        return $status;
1653    } /* }}} */
1654
1655    /**
1656     * Get a list of documents with a workflow
1657     *
1658     * @param int $documentID optional document id for which to retrieve the
1659     *        reviews
1660     * @param int $version optional version of the document
1661     * @return array|bool list of all workflows
1662     */
1663    public function getWorkflowStatus($documentID = null, $version = null) { /* {{{ */
1664        $db = $this->_dms->getDB();
1665
1666        $queryStr = 'SELECT DISTINCT d.*, c.`userid` FROM `tblWorkflowTransitions` a LEFT JOIN `tblWorkflows` b ON a.`workflow`=b.`id` LEFT JOIN `tblWorkflowTransitionUsers` c ON a.`id`=c.`transition` LEFT JOIN `tblWorkflowDocumentContent` d ON b.`id`=d.`workflow` WHERE d.`document` IS NOT NULL AND a.`state`=d.`state` AND c.`userid`='.$this->_id;
1667        if ($documentID) {
1668            $queryStr .= ' AND d.`document`='.(int) $documentID;
1669            if ($version)
1670                $queryStr .= ' AND d.`version`='.(int) $version;
1671        }
1672        $resArr = $db->getResultArray($queryStr);
1673        if (is_bool($resArr) && $resArr == false)
1674            return false;
1675        $result['u'] = array();
1676        if (count($resArr)>0) {
1677            foreach ($resArr as $res) {
1678                $result['u'][] = $res;
1679            }
1680        }
1681
1682        $queryStr = 'select distinct d.*, c.`groupid` from `tblWorkflowTransitions` a left join `tblWorkflows` b on a.`workflow`=b.`id` left join `tblWorkflowTransitionGroups` c on a.`id`=c.`transition` left join `tblWorkflowDocumentContent` d on b.`id`=d.`workflow` left join `tblGroupMembers` e on c.`groupid` = e.`groupID` where d.`document` is not null and a.`state`=d.`state` and e.`userID`='.$this->_id;
1683        if ($documentID) {
1684            $queryStr .= ' AND d.`document`='.(int) $documentID;
1685            if ($version)
1686                $queryStr .= ' AND d.`version`='.(int) $version;
1687        }
1688        $resArr = $db->getResultArray($queryStr);
1689        if (is_bool($resArr) && $resArr == false)
1690            return false;
1691        $result['g'] = array();
1692        if (count($resArr)>0) {
1693            foreach ($resArr as $res) {
1694                $result['g'][] = $res;
1695            }
1696        }
1697        return $result;
1698    } /* }}} */
1699
1700    /**
1701     * Get a list of workflows this user is involved as in individual
1702     *
1703     * @return array|bool list of all workflows
1704     */
1705    public function getWorkflowsInvolved() { /* {{{ */
1706        $db = $this->_dms->getDB();
1707
1708        $queryStr = 'SELECT DISTINCT b.*, c.`userid` FROM `tblWorkflowTransitions` a LEFT JOIN `tblWorkflows` b ON a.`workflow`=b.`id` LEFT JOIN `tblWorkflowTransitionUsers` c ON a.`id`=c.`transition` WHERE c.`userid`='.$this->_id;
1709        $resArr = $db->getResultArray($queryStr);
1710        if (is_bool($resArr) && $resArr == false)
1711            return false;
1712        $result = array();
1713        if (count($resArr)>0) {
1714            foreach ($resArr as $res) {
1715                $result[] = $this->_dms->getWorkflow((int) $res['id']);
1716            }
1717        }
1718
1719        return $result;
1720    } /* }}} */
1721
1722    /**
1723     * Get a list of mandatory reviewers
1724     * A user which isn't trusted completely may have assigned mandatory
1725     * reviewers (both users and groups).
1726     * Whenever the user inserts a new document the mandatory reviewers are
1727     * filled in as reviewers.
1728     *
1729     * @return array list of arrays with two elements containing the user id
1730     *         (reviewerUserID) and group id (reviewerGroupID) of the reviewer.
1731     */
1732    public function getMandatoryReviewers() { /* {{{ */
1733        $db = $this->_dms->getDB();
1734
1735        $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id;
1736        $resArr = $db->getResultArray($queryStr);
1737
1738        return $resArr;
1739    } /* }}} */
1740
1741    /**
1742     * Get a list of mandatory approvers
1743     * See {link SeedDMS_Core_User::getMandatoryReviewers}
1744     *
1745     * @return array list of arrays with two elements containing the user id
1746     *         (approverUserID) and group id (approverGroupID) of the approver.
1747     */
1748    public function getMandatoryApprovers() { /* {{{ */
1749        $db = $this->_dms->getDB();
1750
1751        $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id;
1752        $resArr = $db->getResultArray($queryStr);
1753
1754        return $resArr;
1755    } /* }}} */
1756
1757    /**
1758     * Get a list of users this user is a mandatory reviewer of
1759     *
1760     * This method is the reverse function of getMandatoryReviewers(). It returns
1761     * those user where the current user is a mandatory reviewer.
1762     *
1763     * @return SeedDMS_Core_User[]|bool list of users where this user is a mandatory reviewer.
1764     */
1765    public function isMandatoryReviewerOf() { /* {{{ */
1766        $db = $this->_dms->getDB();
1767
1768        $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `reviewerUserID` = " . $this->_id;
1769        $resArr = $db->getResultArray($queryStr);
1770        if (is_bool($resArr) && !$resArr) return false;
1771
1772        $users = array();
1773        foreach ($resArr as $res) {
1774            $users[] = self::getInstance($res['userID'], $this->_dms);
1775        }
1776
1777        return $users;
1778    } /* }}} */
1779
1780    /**
1781     * Get a list of users this user is a mandatory approver of
1782     *
1783     * This method is the reverse function of getMandatoryApprovers(). It returns
1784     * those user where the current user is a mandatory approver.
1785     *
1786     * @return SeedDMS_Core_User[]|bool list of users where this user is a mandatory approver.
1787     */
1788    public function isMandatoryApproverOf() { /* {{{ */
1789        $db = $this->_dms->getDB();
1790
1791        $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `approverUserID` = " . $this->_id;
1792        $resArr = $db->getResultArray($queryStr);
1793        if (is_bool($resArr) && !$resArr) return false;
1794
1795        $users = array();
1796        foreach ($resArr as $res) {
1797            $users[] = self::getInstance($res['userID'], $this->_dms);
1798        }
1799
1800        return $users;
1801    } /* }}} */
1802
1803    /**
1804     * Get the mandatory workflow
1805     * A user which isn't trusted completely may have assigned mandatory
1806     * workflow
1807     * Whenever the user inserts a new document the mandatory workflow is
1808     * filled in as the workflow.
1809     *
1810     * @return SeedDMS_Core_Workflow|bool workflow
1811     */
1812    public function getMandatoryWorkflow() { /* {{{ */
1813        $db = $this->_dms->getDB();
1814
1815        $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id;
1816        $resArr = $db->getResultArray($queryStr);
1817        if (is_bool($resArr) && !$resArr) return false;
1818
1819        if (!$resArr)
1820            return null;
1821
1822        $workflow = $this->_dms->getWorkflow($resArr[0]['workflow']);
1823        return $workflow;
1824    } /* }}} */
1825
1826    /**
1827     * Get the mandatory workflows
1828     * A user which isn't trusted completely may have assigned mandatory
1829     * workflow
1830     * Whenever the user inserts a new document the mandatory workflow is
1831     * filled in as the workflow.
1832     *
1833     * @return SeedDMS_Core_Workflow[]|bool workflow
1834     */
1835    public function getMandatoryWorkflows() { /* {{{ */
1836        $db = $this->_dms->getDB();
1837
1838        $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id;
1839        $resArr = $db->getResultArray($queryStr);
1840        if (is_bool($resArr) && !$resArr) return false;
1841
1842        if (!$resArr)
1843            return null;
1844
1845        $workflows = array();
1846        foreach ($resArr as $res) {
1847            $workflows[] = $this->_dms->getWorkflow($res['workflow']);
1848        }
1849        return $workflows;
1850    } /* }}} */
1851
1852    /**
1853     * Set a mandatory reviewer
1854     * This function sets a mandatory reviewer if it isn't already set.
1855     *
1856     * @param integer $id id of reviewer
1857     * @param boolean $isgroup true if $id is a group
1858     * @return boolean true on success, otherwise false
1859     */
1860    public function setMandatoryReviewer($id, $isgroup = false) { /* {{{ */
1861        $db = $this->_dms->getDB();
1862        $id = (int) $id;
1863
1864        if ($isgroup) {
1865            $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id . " AND `reviewerGroupID` = " . $id;
1866            $resArr = $db->getResultArray($queryStr);
1867            if (count($resArr) != 0) return true;
1868
1869            $queryStr = "INSERT INTO `tblMandatoryReviewers` (`userID`, `reviewerGroupID`) VALUES (" . $this->_id . ", " . $id .")";
1870            $resArr = $db->getResult($queryStr);
1871            if (is_bool($resArr) && !$resArr) return false;
1872        } else {
1873            $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id . " AND `reviewerUserID` = " . $id;
1874            $resArr = $db->getResultArray($queryStr);
1875            if (count($resArr) != 0) return true;
1876
1877            $queryStr = "INSERT INTO `tblMandatoryReviewers` (`userID`, `reviewerUserID`) VALUES (" . $this->_id . ", " . $id .")";
1878            $resArr = $db->getResult($queryStr);
1879            if (is_bool($resArr) && !$resArr) return false;
1880        }
1881
1882        return true;
1883    } /* }}} */
1884
1885    /**
1886     * Set a mandatory approver
1887     * This function sets a mandatory approver if it isn't already set.
1888     *
1889     * @param integer $id id of approver
1890     * @param boolean $isgroup true if $id is a group
1891     * @return boolean true on success, otherwise false
1892     */
1893    public function setMandatoryApprover($id, $isgroup = false) { /* {{{ */
1894        $db = $this->_dms->getDB();
1895        $id = (int) $id;
1896
1897        if ($isgroup) {
1898            $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id . " AND `approverGroupID` = " . $id;
1899            $resArr = $db->getResultArray($queryStr);
1900            if (count($resArr) != 0) return true;
1901
1902            $queryStr = "INSERT INTO `tblMandatoryApprovers` (`userID`, `approverGroupID`) VALUES (" . $this->_id . ", " . $id .")";
1903            $resArr = $db->getResult($queryStr);
1904            if (is_bool($resArr) && !$resArr) return false;
1905        } else {
1906            $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id . " AND `approverUserID` = " . $id;
1907            $resArr = $db->getResultArray($queryStr);
1908            if (count($resArr) != 0) return true;
1909
1910            $queryStr = "INSERT INTO `tblMandatoryApprovers` (`userID`, `approverUserID`) VALUES (" . $this->_id . ", " . $id .")";
1911            $resArr = $db->getResult($queryStr);
1912            if (is_bool($resArr) && !$resArr) return false;
1913        }
1914
1915        return true;
1916    } /* }}} */
1917
1918    /**
1919     * Set a mandatory workflow
1920     * This function sets a mandatory workflow if it isn't already set.
1921     *
1922     * @param object $workflow workflow
1923     * @return boolean true on success, otherwise false
1924     */
1925    public function setMandatoryWorkflow($workflow) { /* {{{ */
1926        $db = $this->_dms->getDB();
1927
1928        $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id . " AND `workflow` = " . (int) $workflow->getID();
1929        $resArr = $db->getResultArray($queryStr);
1930        if (count($resArr) != 0) return true;
1931
1932        $queryStr = "INSERT INTO `tblWorkflowMandatoryWorkflow` (`userid`, `workflow`) VALUES (" . $this->_id . ", " . $workflow->getID() .")";
1933        $resArr = $db->getResult($queryStr);
1934        if (is_bool($resArr) && !$resArr) return false;
1935
1936        return true;
1937    } /* }}} */
1938
1939    /**
1940     * Set a mandatory workflows
1941     * This function sets a list of mandatory workflows.
1942     *
1943     * @param SeedDMS_Core_Workflow[] $workflows list of workflow objects
1944     * @return boolean true on success, otherwise false
1945     */
1946    public function setMandatoryWorkflows($workflows) { /* {{{ */
1947        $db = $this->_dms->getDB();
1948
1949        $db->startTransaction();
1950        $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id;
1951        if (!$db->getResult($queryStr)) {
1952            $db->rollbackTransaction();
1953            return false;
1954        }
1955
1956        foreach ($workflows as $workflow) {
1957            $queryStr = "INSERT INTO `tblWorkflowMandatoryWorkflow` (`userid`, `workflow`) VALUES (" . $this->_id . ", " . $workflow->getID() .")";
1958            $resArr = $db->getResult($queryStr);
1959            if (is_bool($resArr) && !$resArr) {
1960                $db->rollbackTransaction();
1961                return false;
1962            }
1963        }
1964
1965        $db->commitTransaction();
1966        return true;
1967    } /* }}} */
1968
1969    /**
1970     * Deletes all mandatory reviewers
1971     *
1972     * @return boolean true on success, otherwise false
1973     */
1974    public function delMandatoryReviewers() { /* {{{ */
1975        $db = $this->_dms->getDB();
1976        $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id;
1977        if (!$db->getResult($queryStr)) return false;
1978        return true;
1979    } /* }}} */
1980
1981    /**
1982     * Deletes all mandatory approvers
1983     *
1984     * @return boolean true on success, otherwise false
1985     */
1986    public function delMandatoryApprovers() { /* {{{ */
1987        $db = $this->_dms->getDB();
1988
1989        $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id;
1990        if (!$db->getResult($queryStr)) return false;
1991        return true;
1992    } /* }}} */
1993
1994    /**
1995     * Deletes the  mandatory workflow
1996     *
1997     * @return boolean true on success, otherwise false
1998     */
1999    public function delMandatoryWorkflow() { /* {{{ */
2000        $db = $this->_dms->getDB();
2001        $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id;
2002        if (!$db->getResult($queryStr)) return false;
2003        return true;
2004    } /* }}} */
2005
2006    /**
2007     * Get all notifications of user
2008     *
2009     * @param integer $type type of item (T_DOCUMENT or T_FOLDER)
2010     * @return SeedDMS_Core_Notification[]|bool array of notifications
2011     */
2012    public function getNotifications($type = 0) { /* {{{ */
2013        $db = $this->_dms->getDB();
2014        $queryStr = "SELECT `tblNotify`.* FROM `tblNotify` ".
2015         "WHERE `tblNotify`.`userID` = ". $this->_id;
2016        if ($type) {
2017            $queryStr .= " AND `tblNotify`.`targetType` = ". (int) $type;
2018        }
2019
2020        $resArr = $db->getResultArray($queryStr);
2021        if (is_bool($resArr) && !$resArr)
2022            return false;
2023
2024        $notifications = array();
2025        foreach ($resArr as $row) {
2026            $not = new SeedDMS_Core_Notification($row["target"], $row["targetType"], $row["userID"], $row["groupID"]);
2027            $not->setDMS($this);
2028            array_push($notifications, $not);
2029        }
2030
2031        return $notifications;
2032    } /* }}} */
2033
2034    /**
2035     * Return list of personal keyword categories
2036     *
2037     * @return SeedDMS_Core_KeywordCategory[]|bool list of categories or false in case of an error
2038     */
2039    public function getKeywordCategories() { /* {{{ */
2040        $db = $this->_dms->getDB();
2041
2042        $queryStr = "SELECT * FROM `tblKeywordCategories` WHERE `owner` = ".$this->_id;
2043
2044        $resArr = $db->getResultArray($queryStr);
2045        if (is_bool($resArr) && !$resArr)
2046            return false;
2047
2048        $categories = array();
2049        foreach ($resArr as $row) {
2050            $cat = new SeedDMS_Core_KeywordCategory((int) $row["id"], $row["owner"], $row["name"]);
2051            $cat->setDMS($this->_dms);
2052            array_push($categories, $cat);
2053        }
2054
2055        return $categories;
2056    } /* }}} */
2057
2058} /* }}} */