Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
62.35% covered (warning)
62.35%
53 / 85
57.14% covered (warning)
57.14%
8 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
Useraccount
62.35% covered (warning)
62.35%
53 / 85
57.14% covered (warning)
57.14%
8 / 14
54.73
0.00% covered (danger)
0.00%
0 / 1
 getEntityMapping
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
1
 addConditionLoginName
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addConditionUserId
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addConditionPassword
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addConditionXauthKey
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addConditionRoleLevel
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 addConditionSearch
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 reverseEntityMapping
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
6
 postProcess
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 addConditionDepartmentIds
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 addConditionDepartmentIdsAndSearch
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 addConditionExcludeSuperusers
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 addOrderByName
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addConditionWorkstationAccess
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace BO\Zmsdb\Query;
4
5use BO\Slim\Application as App;
6
7class Useraccount extends Base implements MappingInterface
8{
9    /**
10     * @var String TABLE mysql table reference
11     */
12    const TABLE = 'nutzer';
13    const TABLE_ASSIGNMENT = 'nutzerzuordnung';
14
15    const QUERY_READ_ID_BY_USERNAME = '
16        SELECT user.`NutzerID` AS id
17        FROM ' . self::TABLE . ' user
18        WHERE
19            user.`Name`=?
20    ';
21
22    const QUERY_WRITE_ASSIGNED_DEPARTMENTS = '
23        REPLACE INTO
24            ' . self::TABLE_ASSIGNMENT . '
25        SET
26            nutzerid=?,
27            behoerdenid=?
28    ';
29
30    const QUERY_DELETE_ASSIGNED_DEPARTMENTS = '
31        DELETE FROM
32            ' . self::TABLE_ASSIGNMENT . '
33        WHERE
34            nutzerid=?
35        ORDER BY behoerdenid
36    ';
37
38    const QUERY_READ_SUPERUSER_DEPARTMENTS = '
39        SELECT behoerde.`BehoerdenID` AS id
40        FROM ' . Department::TABLE . '
41        ORDER BY behoerde.Name
42    ';
43
44    const QUERY_READ_ASSIGNED_DEPARTMENTS = '
45        SELECT userAssignment.`behoerdenid` AS id
46        FROM ' . self::TABLE_ASSIGNMENT . ' userAssignment
47        LEFT JOIN ' . self::TABLE . ' useraccount ON useraccount.Name = :useraccountName
48        WHERE
49            useraccount.`NutzerID` = userAssignment.`nutzerid`
50        ORDER BY userAssignment.`behoerdenid`
51    ';
52
53    const QUERY_READ_ASSIGNED_DEPARTMENTS_FOR_ALL = '
54        SELECT useraccount.Name as useraccountName,
55            userAssignment.`behoerdenid` AS id
56        FROM ' . self::TABLE_ASSIGNMENT . ' userAssignment
57        LEFT JOIN ' . self::TABLE . ' useraccount ON useraccount.NutzerID = userAssignment.nutzerid
58        WHERE
59            useraccount.Name IN (:useraccountNames)
60        ORDER BY useraccount.Name, userAssignment.`behoerdenid`
61    ';
62
63    public function getEntityMapping()
64    {
65        return [
66            'id' => 'useraccount.Name',
67            'password' => 'useraccount.Passworthash',
68            'lastLogin' => 'useraccount.lastUpdate',
69            'rights__superuser' => self::expression('`useraccount`.`Berechtigung` = 90'),
70            'rights__organisation' => self::expression('`useraccount`.`Berechtigung` >= 70'),
71            'rights__department' => self::expression('`useraccount`.`Berechtigung` >= 50'),
72            'rights__cluster' => self::expression('`useraccount`.`Berechtigung` >= 40'),
73            'rights__useraccount' => self::expression('`useraccount`.`Berechtigung` >= 40'),
74            'rights__scope' => self::expression('`useraccount`.`Berechtigung` >= 30'),
75            'rights__departmentStats' => self::expression('`useraccount`.`Berechtigung` >= 25'),
76            'rights__availability' => self::expression('`useraccount`.`Berechtigung` >= 20'),
77            'rights__ticketprinter' => self::expression('`useraccount`.`Berechtigung` >= 15'),
78            'rights__sms' => self::expression('`useraccount`.`Berechtigung` >= 10'),
79            'rights__audit' => self::expression('`useraccount`.`Berechtigung` = 5 OR `useraccount`.`Berechtigung` = 90'),
80            'rights__basic' => self::expression('`useraccount`.`Berechtigung` >= 0'),
81        ];
82    }
83
84    public function addConditionLoginName($loginName)
85    {
86        $this->query->where('useraccount.Name', '=', $loginName);
87        return $this;
88    }
89
90    public function addConditionUserId($userId)
91    {
92        $this->query->where('useraccount.NutzerID', '=', $userId);
93        return $this;
94    }
95
96    public function addConditionPassword($password)
97    {
98        $this->query->where('useraccount.Passworthash', '=', $password);
99        return $this;
100    }
101
102    public function addConditionXauthKey($xAuthKey)
103    {
104        $this->query->where('useraccount.SessionID', '=', $xAuthKey);
105        $this->query->where('useraccount.SessionExpiry', '>', date('Y-m-d H:i:s', time() - App::SESSION_DURATION));
106        return $this;
107    }
108
109    public function addConditionRoleLevel($roleLevel)
110    {
111        $this->query->where('useraccount.Berechtigung', '=', $roleLevel);
112        return $this;
113    }
114
115    public function addConditionSearch($queryString, $orWhere = false)
116    {
117        $condition = function (\BO\Zmsdb\Query\Builder\ConditionBuilder $query) use ($queryString) {
118            $queryString = trim($queryString);
119            $query->orWith('useraccount.NutzerID', 'LIKE', "%$queryString%");
120            $query->orWith('useraccount.Name', 'LIKE', "%$queryString%");
121        };
122        if ($orWhere) {
123            $this->query->orWhere($condition);
124        } else {
125            $this->query->where($condition);
126        }
127        return $this;
128    }
129
130    public function reverseEntityMapping(\BO\Zmsentities\Useraccount $entity)
131    {
132        $data = array();
133        $data['Name'] = $entity->id;
134        $data['Passworthash'] = (isset($entity->password)) ? $entity->password : null;
135        $data['Berechtigung'] = $entity->getRightsLevel();
136        $data['BehoerdenID'] = 0;
137        if (!$entity->isSuperUser() && isset($entity->departments) && 0 < $entity->departments->count()) {
138            $data['BehoerdenID'] = $entity->departments->getFirst()->id;
139        }
140        //default values because of strict mode
141        $data['notrufinitiierung'] = 0;
142        $data['notrufantwort'] = 0;
143
144        $data = array_filter($data, function ($value) {
145            return ($value !== null && $value !== false);
146        });
147        return $data;
148    }
149
150    public function postProcess($data)
151    {
152        $data[$this->getPrefixed("lastLogin")] = ('0000-00-00' != $data[$this->getPrefixed("lastLogin")]) ?
153            strtotime($data[$this->getPrefixed("lastLogin")]) :
154            null;
155        return $data;
156    }
157
158    public function addConditionDepartmentIds(array $departmentIds)
159    {
160        $this->setDistinctSelect();
161        $this->innerJoin(
162            new Alias(static::TABLE_ASSIGNMENT, 'useraccount_department'),
163            'useraccount.NutzerID',
164            '=',
165            'useraccount_department.nutzerid'
166        );
167        $this->query->where('useraccount_department.behoerdenid', 'IN', $departmentIds);
168        return $this;
169    }
170
171    public function addConditionDepartmentIdsAndSearch(array $departmentIds, $queryString = null, $orWhere = false): self
172    {
173        $this->addConditionDepartmentIds($departmentIds);
174
175        if ($queryString) {
176            $this->addConditionSearch($queryString, $orWhere);
177        }
178
179        return $this;
180    }
181
182    public function addConditionExcludeSuperusers(): self
183    {
184        $this->query->where('useraccount.Berechtigung', '!=', 90);
185        return $this;
186    }
187
188    public function addOrderByName(): self
189    {
190        $this->query->orderBy('useraccount.Name', 'ASC');
191        return $this;
192    }
193
194    /**
195     * @SuppressWarnings(UnusedFormalParameter)
196     */
197    public function addConditionWorkstationAccess($workstationUserId, array $workstationDepartmentIds, $isWorkstationSuperuser = false): self
198    {
199        // Superusers can access all useraccounts, no filtering needed
200        if ($isWorkstationSuperuser) {
201            return $this;
202        }
203
204        // Always exclude superusers for non-superuser workstation users
205        $this->query->where('useraccount.Berechtigung', '!=', 90);
206
207        // If no departments, only exclude superusers (already done above)
208        if (empty($workstationDepartmentIds)) {
209            return $this;
210        }
211
212        // Ensure we have a join to nutzerzuordnung for target useraccounts
213        $this->setDistinctSelect();
214        $this->innerJoin(
215            new Alias(static::TABLE_ASSIGNMENT, 'useraccount_department'),
216            'useraccount.NutzerID',
217            '=',
218            'useraccount_department.nutzerid'
219        );
220
221        // Target useraccount must share at least one department with workstation user
222        $this->query->where('useraccount_department.behoerdenid', 'IN', $workstationDepartmentIds);
223
224        return $this;
225    }
226}