]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Repository/Groups.php
98dc350d67bee9c6fe3074b0eb04604a356f4956
[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 * @version SVN: $Id$
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.7dev - 2011-10-25
36 */
37
38 namespace Galette\Repository;
39
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 (\Exception $e) {
107 Analog::log(
108 'Cannot list groups (simple) | ' . $e->getMessage(),
109 Analog::WARNING
110 );
111 }
112 }
113
114 /**
115 * Get groups list
116 *
117 * @param boolean $full Return full list or root only
118 * @param int $id Group ID to retrieve
119 *
120 * @return Group[]
121 */
122 public function getList($full = true, $id = null)
123 {
124 try {
125 $select = $this->zdb->select(Group::TABLE, 'a');
126 $select->join(
127 array('b' => PREFIX_DB . Group::GROUPSUSERS_TABLE),
128 'a.' . Group::PK . '=b.' . Group::PK,
129 array('members' => new Expression('count(b.' . Group::PK . ')')),
130 $select::JOIN_LEFT
131 );
132
133 if (!$this->login->isAdmin() && !$this->login->isStaff() && $full === true) {
134 $select->join(
135 array('c' => PREFIX_DB . Group::GROUPSMANAGERS_TABLE),
136 'a.' . Group::PK . '=c.' . Group::PK,
137 array()
138 )->where('c.' . Adherent::PK . ' = ' . $this->login->id);
139 }
140
141 if ($full !== true) {
142 $select->where('parent_group IS NULL');
143 }
144
145 if ($id !== null) {
146 $select->where(
147 array(
148 'a.' . Group::PK => $id,
149 'a.parent_group' => $id
150 ),
151 PredicateSet::OP_OR
152 );
153 }
154
155 $select->group('a.' . Group::PK)
156 ->group('a.group_name')
157 ->group('a.creation_date')
158 ->group('a.parent_group')
159 ->order('a.group_name ASC');
160
161 $groups = array();
162
163 $results = $this->zdb->execute($select);
164
165 foreach ($results as $row) {
166 $group = new Group($row);
167 $group->setLogin($this->login);
168 $groups[$group->getFullName()] = $group;
169 }
170 if ($full) { // Order by tree name instead of name
171 ksort($groups);
172 Analog::log(
173 'Groups SORTED: ' . print_r(array_keys($groups), true),
174 Analog::DEBUG
175 );
176 }
177 return $groups;
178 } catch (\Exception $e) {
179 Analog::log(
180 'Cannot list groups | ' . $e->getMessage(),
181 Analog::WARNING
182 );
183 }
184 }
185
186 /**
187 * Loads managed groups for specific member
188 *
189 * @param int $id Memebr id
190 * @param boolean $as_group Retrieve Group[] or int[]
191 *
192 * @return array
193 */
194 public static function loadManagedGroups($id, $as_group = true)
195 {
196 return self::loadGroups($id, true, $as_group);
197 }
198
199 /**
200 * Loads groups for specific member
201 *
202 * @param int $id Member id
203 * @param boolean $managed Retrieve managed groups (defaults to false)
204 * @param boolean $as_group Retrieve Group[] or int[]
205 *
206 * @return array
207 */
208 public static function loadGroups($id, $managed = false, $as_group = true)
209 {
210 global $zdb;
211 try {
212 $join_table = ($managed) ?
213 Group::GROUPSMANAGERS_TABLE :
214 Group::GROUPSUSERS_TABLE;
215
216 $select = $zdb->select(Group::TABLE, 'a');
217 $select->join(
218 array(
219 'b' => PREFIX_DB . $join_table
220 ),
221 'a.' . Group::PK . '=b.' . Group::PK,
222 array()
223 )->where(array('b.' . Adherent::PK => $id));
224
225 $results = $zdb->execute($select);
226
227 $groups = array();
228 foreach ($results as $r) {
229 if ($as_group === true) {
230 $groups[] = new Group($r);
231 } else {
232 $gpk = Group::PK;
233 $groups[] = $r->$gpk;
234 }
235 }
236 return $groups;
237 } catch (\Exception $e) {
238 Analog::log(
239 'Cannot load member groups for id `' . $id . '` | ' .
240 $e->getMessage(),
241 Analog::WARNING
242 );
243 return false;
244 }
245 }
246
247 /**
248 * Add a member to specified groups
249 *
250 * @param Adherent $adh Member
251 * @param array $groups Groups Groups list. Each entry must contain
252 * the group id, name each value separated
253 * by a pipe.
254 * @param boolean $manager Add member as manager, defaults to false
255 * @param boolean $transaction Does a SQL transaction already exists? Defaults
256 * to false.
257 *
258 * @return boolean
259 */
260 public static function addMemberToGroups($adh, $groups, $manager = false, $transaction = false)
261 {
262 global $zdb;
263 try {
264 if ($transaction === false) {
265 $zdb->connection->beginTransaction();
266 }
267
268 $table = null;
269 if ($manager === true) {
270 $table = Group::GROUPSMANAGERS_TABLE;
271 } else {
272 $table = Group::GROUPSUSERS_TABLE;
273 }
274
275 //first, remove current groups members
276 $delete = $zdb->delete($table);
277 $delete->where(
278 Adherent::PK . ' = ' . $adh->id
279 );
280 $zdb->execute($delete);
281
282 $msg = null;
283 if ($manager === true) {
284 $msg = 'Member `' . $adh->sname . '` has been detached from groups he manages';
285 } else {
286 $msg = 'Member `' . $adh->sname . '` has been detached of its groups';
287 }
288 Analog::log(
289 $msg . ', we can now store new ones.',
290 Analog::INFO
291 );
292
293 //we proceed, if groups has been specified
294 if (is_array($groups)) {
295 $insert = $zdb->insert($table);
296 $insert->values(
297 array(
298 Group::PK => ':group',
299 Adherent::PK => ':adh'
300 )
301 );
302 $stmt = $zdb->sql->prepareStatementForSqlObject($insert);
303
304 foreach ($groups as $group) {
305 list($gid, $gname) = explode('|', $group);
306
307 $result = $stmt->execute(
308 array(
309 Group::PK => $gid,
310 Adherent::PK => $adh->id
311 )
312 );
313
314 if ($result) {
315 $msg = 'Member `' . $adh->sname . '` attached to group `' .
316 $gname . '` (' . $gid . ')';
317 if ($manager === true) {
318 $msg .= ' as a manager';
319 }
320 Analog::log(
321 $msg,
322 Analog::DEBUG
323 );
324 } else {
325 $msg = 'Unable to attach member `' .
326 $adh->sname . '` (' . $adh->id . ') to group `' .
327 $gname . '` (' . $gid . ').';
328 if ($manager === true) {
329 $msg .= ' as a manager';
330 }
331 Analog::log(
332 $msg,
333 Analog::ERROR
334 );
335 throw new \Exception($msg);
336 }
337 }
338 }
339 if ($transaction === false) {
340 //commit all changes
341 $zdb->connection->commit();
342 }
343 return true;
344 } catch (\Exception $e) {
345 if ($transaction === false) {
346 $zdb->connection->rollBack();
347 }
348 $msg = 'Unable to add member `' . $adh->sname . '` (' . $adh->id .
349 ') to specified groups ' . print_r($groups, true);
350 if ($manager === true) {
351 $msg .= ' as a manager';
352 }
353 do {
354 $messages[] = $e->getMessage();
355 } while ($e = $e->getPrevious());
356 Analog::log(
357 $msg . ' |' . implode("\n", $messages),
358 Analog::ERROR
359 );
360 return false;
361 }
362 }
363
364 /**
365 * Remove members from all their groups
366 *
367 * @param array $ids Members ids
368 *
369 * @return void
370 */
371 public static function removeMembersFromGroups(array $ids)
372 {
373 global $zdb;
374
375 try {
376 $del_qry = $zdb->delete(Group::GROUPSUSERS_TABLE);
377 $del_qry->where->in(Adherent::PK, $ids);
378 $zdb->execute($del_qry);
379
380 $del_qry = $zdb->delete(Group::GROUPSMANAGERS_TABLE);
381 $del_qry->where->in(Adherent::PK, $ids);
382 $zdb->execute($del_qry);
383 } catch (\Exception $e) {
384 Analog::log(
385 'Unable to remove member #' . $id . ' from his groups: ' .
386 $e->getMessage(),
387 Analog::ERROR
388 );
389 throw $e;
390 }
391 }
392
393 /**
394 * Remove member from all his groups
395 *
396 * @param int $id Member's id
397 *
398 * @return void
399 */
400 public static function removeMemberFromGroups($id)
401 {
402 self::removeMembersFromGroups([$id]);
403 }
404
405 /**
406 * Check if groupname is unique
407 *
408 * @param Db $zdb Database instance
409 * @param string $name Requested name
410 *
411 * @return boolean
412 */
413 public static function isUnique(Db $zdb, $name)
414 {
415 try {
416 $select = $zdb->select(Group::TABLE);
417 $select->columns(
418 array('group_name')
419 )->where(array('group_name' => $name));
420 $results = $zdb->execute($select);
421 return !($results->count() > 0);
422 } catch (\Exception $e) {
423 Analog::log(
424 'Cannot list groups (simple) | ' . $e->getMessage(),
425 Analog::WARNING
426 );
427 }
428 }
429
430 /**
431 * Get managed users id list
432 *
433 * @param array $groups List of managed groups.
434 * If empty, Groups::loadManagedGroups() will be called
435 *
436 * @return array|false
437 */
438 public function getManagerUsers(array $groups = [])
439 {
440 if (!$this->login->isGroupManager()) {
441 return false;
442 }
443 if (!count($groups)) {
444 $groups = self::loadManagedGroups($this->login->id, false);
445 }
446
447 $select = $this->zdb->select(Adherent::TABLE, 'a');
448 $select->columns(
449 [Adherent::PK]
450 )->join(
451 array('b' => PREFIX_DB . Group::GROUPSUSERS_TABLE),
452 'a.' . Adherent::PK . '=b.' . Adherent::PK,
453 []
454 )->where->in('b.' . Group::PK, $groups);
455
456 $results = $this->zdb->execute($select);
457
458 $ids_adh = array();
459 foreach ($results as $r) {
460 $ids_adh[] = $r->id_adh;
461 }
462 return $ids_adh;
463 }
464 }