]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Repository/Groups.php
Throw errors
[galette.git] / galette / lib / Galette / Repository / Groups.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Groups entity
7 *
8 * PHP version 5
9 *
10 * Copyright © 2011-2014 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Repository
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2011-2014 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7dev - 2011-10-25
35 */
36
37 namespace Galette\Repository;
38
39 use Throwable;
40 use Analog\Analog;
41 use Laminas\Db\Sql\Expression;
42 use Laminas\Db\Sql\Predicate\PredicateSet;
43 use Galette\Entity\Group;
44 use Galette\Entity\Adherent;
45 use Galette\Core\Login;
46 use Galette\Core\Db;
47
48 /**
49 * Groups entitiy
50 *
51 * @category Repository
52 * @name Groups
53 * @package Galette
54 * @author Johan Cwiklinski <johan@x-tnd.be>
55 * @copyright 2011-2014 The Galette Team
56 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
57 * @link http://galette.tuxfamily.org
58 * @since Available since 0.7dev - 2011-10-25
59 */
60 class Groups
61 {
62
63 /**
64 * Constructor
65 *
66 * @param Db $zdb Database instance
67 * @param Login $login Login instance
68 */
69 public function __construct(Db $zdb, Login $login)
70 {
71 $this->zdb = $zdb;
72 $this->login = $login;
73 }
74
75 /**
76 * Get simple groups list (only id and names)
77 *
78 * @param boolean $as_groups Retrieve Group[]
79 *
80 * @return array
81 */
82 public static function getSimpleList($as_groups = false)
83 {
84 global $zdb;
85
86 try {
87 $select = $zdb->select(Group::TABLE);
88 if ($as_groups === false) {
89 $select->columns(
90 array(Group::PK, 'group_name')
91 );
92 }
93 $groups = array();
94 $gpk = Group::PK;
95
96 $results = $zdb->execute($select);
97
98 foreach ($results as $row) {
99 if ($as_groups === false) {
100 $groups[$row->$gpk] = $row->group_name;
101 } else {
102 $groups[$row->$gpk] = new Group($row);
103 }
104 }
105 return $groups;
106 } catch (Throwable $e) {
107 Analog::log(
108 'Cannot list groups (simple) | ' . $e->getMessage(),
109 Analog::WARNING
110 );
111 throw $e;
112 }
113 }
114
115 /**
116 * Get groups list
117 *
118 * @param boolean $full Return full list or root only
119 * @param int $id Group ID to retrieve
120 *
121 * @return Group[]
122 */
123 public function getList($full = true, $id = null)
124 {
125 try {
126 $select = $this->zdb->select(Group::TABLE, 'a');
127 $select->join(
128 array('b' => PREFIX_DB . Group::GROUPSUSERS_TABLE),
129 'a.' . Group::PK . '=b.' . Group::PK,
130 array('members' => new Expression('count(b.' . Group::PK . ')')),
131 $select::JOIN_LEFT
132 );
133
134 if (!$this->login->isAdmin() && !$this->login->isStaff() && $full === true) {
135 $select->join(
136 array('c' => PREFIX_DB . Group::GROUPSMANAGERS_TABLE),
137 'a.' . Group::PK . '=c.' . Group::PK,
138 array()
139 )->where('c.' . Adherent::PK . ' = ' . $this->login->id);
140 }
141
142 if ($full !== true) {
143 $select->where('parent_group IS NULL');
144 }
145
146 if ($id !== null) {
147 $select->where(
148 array(
149 'a.' . Group::PK => $id,
150 'a.parent_group' => $id
151 ),
152 PredicateSet::OP_OR
153 );
154 }
155
156 $select->group('a.' . Group::PK)
157 ->group('a.group_name')
158 ->group('a.creation_date')
159 ->group('a.parent_group')
160 ->order('a.group_name ASC');
161
162 $groups = array();
163
164 $results = $this->zdb->execute($select);
165
166 foreach ($results as $row) {
167 $group = new Group($row);
168 $group->setLogin($this->login);
169 $groups[$group->getFullName()] = $group;
170 }
171 if ($full) { // Order by tree name instead of name
172 ksort($groups);
173 Analog::log(
174 'Groups SORTED: ' . print_r(array_keys($groups), true),
175 Analog::DEBUG
176 );
177 }
178 return $groups;
179 } catch (Throwable $e) {
180 Analog::log(
181 'Cannot list groups | ' . $e->getMessage(),
182 Analog::WARNING
183 );
184 throw $e;
185 }
186 }
187
188 /**
189 * Loads managed groups for specific member
190 *
191 * @param int $id Memebr id
192 * @param boolean $as_group Retrieve Group[] or int[]
193 *
194 * @return array
195 */
196 public static function loadManagedGroups($id, $as_group = true)
197 {
198 return self::loadGroups($id, true, $as_group);
199 }
200
201 /**
202 * Loads groups for specific member
203 *
204 * @param int $id Member id
205 * @param boolean $managed Retrieve managed groups (defaults to false)
206 * @param boolean $as_group Retrieve Group[] or int[]
207 *
208 * @return array
209 */
210 public static function loadGroups($id, $managed = false, $as_group = true)
211 {
212 global $zdb;
213 try {
214 $join_table = ($managed) ?
215 Group::GROUPSMANAGERS_TABLE : Group::GROUPSUSERS_TABLE;
216
217 $select = $zdb->select(Group::TABLE, 'a');
218 $select->join(
219 array(
220 'b' => PREFIX_DB . $join_table
221 ),
222 'a.' . Group::PK . '=b.' . Group::PK,
223 array()
224 )->where(array('b.' . Adherent::PK => $id));
225
226 $results = $zdb->execute($select);
227
228 $groups = array();
229 foreach ($results as $r) {
230 if ($as_group === true) {
231 $groups[] = new Group($r);
232 } else {
233 $gpk = Group::PK;
234 $groups[] = $r->$gpk;
235 }
236 }
237 return $groups;
238 } catch (Throwable $e) {
239 Analog::log(
240 'Cannot load member groups for id `' . $id . '` | ' .
241 $e->getMessage(),
242 Analog::WARNING
243 );
244 throw $e;
245 }
246 }
247
248 /**
249 * Add a member to specified groups
250 *
251 * @param Adherent $adh Member
252 * @param array $groups Groups Groups list. Each entry must contain
253 * the group id, name each value separated
254 * by a pipe.
255 * @param boolean $manager Add member as manager, defaults to false
256 * @param boolean $transaction Does a SQL transaction already exists? Defaults
257 * to false.
258 *
259 * @return boolean
260 */
261 public static function addMemberToGroups($adh, $groups, $manager = false, $transaction = false)
262 {
263 global $zdb;
264 try {
265 if ($transaction === false) {
266 $zdb->connection->beginTransaction();
267 }
268
269 $table = null;
270 if ($manager === true) {
271 $table = Group::GROUPSMANAGERS_TABLE;
272 } else {
273 $table = Group::GROUPSUSERS_TABLE;
274 }
275
276 //first, remove current groups members
277 $delete = $zdb->delete($table);
278 $delete->where(
279 Adherent::PK . ' = ' . $adh->id
280 );
281 $zdb->execute($delete);
282
283 $msg = null;
284 if ($manager === true) {
285 $msg = 'Member `' . $adh->sname . '` has been detached from groups he manages';
286 } else {
287 $msg = 'Member `' . $adh->sname . '` has been detached of its groups';
288 }
289 Analog::log(
290 $msg . ', we can now store new ones.',
291 Analog::INFO
292 );
293
294 //we proceed, if groups has been specified
295 if (is_array($groups)) {
296 $insert = $zdb->insert($table);
297 $insert->values(
298 array(
299 Group::PK => ':group',
300 Adherent::PK => ':adh'
301 )
302 );
303 $stmt = $zdb->sql->prepareStatementForSqlObject($insert);
304
305 foreach ($groups as $group) {
306 list($gid, $gname) = explode('|', $group);
307
308 $result = $stmt->execute(
309 array(
310 'group' => $gid,
311 'adh' => $adh->id
312 )
313 );
314
315 if ($result) {
316 $msg = 'Member `' . $adh->sname . '` attached to group `' .
317 $gname . '` (' . $gid . ')';
318 if ($manager === true) {
319 $msg .= ' as a manager';
320 }
321 Analog::log(
322 $msg,
323 Analog::DEBUG
324 );
325 } else {
326 $msg = 'Unable to attach member `' .
327 $adh->sname . '` (' . $adh->id . ') to group `' .
328 $gname . '` (' . $gid . ').';
329 if ($manager === true) {
330 $msg .= ' as a manager';
331 }
332 Analog::log(
333 $msg,
334 Analog::ERROR
335 );
336 throw new \Exception($msg);
337 }
338 }
339 }
340 if ($transaction === false) {
341 //commit all changes
342 $zdb->connection->commit();
343 }
344 return true;
345 } catch (Throwable $e) {
346 if ($transaction === false) {
347 $zdb->connection->rollBack();
348 }
349 $msg = 'Unable to add member `' . $adh->sname . '` (' . $adh->id .
350 ') to specified groups ' . print_r($groups, true);
351 if ($manager === true) {
352 $msg .= ' as a manager';
353 }
354 do {
355 $messages[] = $e->getMessage();
356 } while ($e = $e->getPrevious());
357 Analog::log(
358 $msg . ' |' . implode("\n", $messages),
359 Analog::ERROR
360 );
361 throw $e;
362 }
363 }
364
365 /**
366 * Remove members from all their groups
367 *
368 * @param array $ids Members ids
369 *
370 * @return void
371 */
372 public static function removeMembersFromGroups(array $ids)
373 {
374 global $zdb;
375
376 try {
377 $del_qry = $zdb->delete(Group::GROUPSUSERS_TABLE);
378 $del_qry->where->in(Adherent::PK, $ids);
379 $zdb->execute($del_qry);
380
381 $del_qry = $zdb->delete(Group::GROUPSMANAGERS_TABLE);
382 $del_qry->where->in(Adherent::PK, $ids);
383 $zdb->execute($del_qry);
384 } catch (Throwable $e) {
385 Analog::log(
386 'Unable to remove member #' . $id . ' from his groups: ' .
387 $e->getMessage(),
388 Analog::ERROR
389 );
390 throw $e;
391 }
392 }
393
394 /**
395 * Remove member from all his groups
396 *
397 * @param int $id Member's id
398 *
399 * @return void
400 */
401 public static function removeMemberFromGroups($id)
402 {
403 self::removeMembersFromGroups([$id]);
404 }
405
406 /**
407 * Check if groupname is unique
408 *
409 * @param Db $zdb Database instance
410 * @param string $name Requested name
411 *
412 * @return boolean
413 */
414 public static function isUnique(Db $zdb, $name)
415 {
416 try {
417 $select = $zdb->select(Group::TABLE);
418 $select->columns(
419 array('group_name')
420 )->where(array('group_name' => $name));
421 $results = $zdb->execute($select);
422 return !($results->count() > 0);
423 } catch (Throwable $e) {
424 Analog::log(
425 'Cannot list groups (simple) | ' . $e->getMessage(),
426 Analog::WARNING
427 );
428 throw $e;
429 }
430 }
431
432 /**
433 * Get managed users id list
434 *
435 * @param array $groups List of managed groups.
436 * If empty, Groups::loadManagedGroups() will be called
437 *
438 * @return array|false
439 */
440 public function getManagerUsers(array $groups = [])
441 {
442 if (!$this->login->isGroupManager()) {
443 return false;
444 }
445 if (!count($groups)) {
446 $groups = self::loadManagedGroups($this->login->id, false);
447 }
448
449 $select = $this->zdb->select(Adherent::TABLE, 'a');
450 $select->columns(
451 [Adherent::PK]
452 )->join(
453 array('b' => PREFIX_DB . Group::GROUPSUSERS_TABLE),
454 'a.' . Adherent::PK . '=b.' . Adherent::PK,
455 []
456 )->where->in('b.' . Group::PK, $groups);
457
458 $results = $this->zdb->execute($select);
459
460 $ids_adh = array();
461 foreach ($results as $r) {
462 $ids_adh[] = $r->id_adh;
463 }
464 return $ids_adh;
465 }
466 }