3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10 * Copyright © 2012-2014 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
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.
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.
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/>.
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2012-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 - 2012-01-17
37 namespace Galette\Entity
;
39 use Galette\Core\Login
;
41 use Laminas\Db\Sql\Expression
;
49 * @author Johan Cwiklinski <johan@x-tnd.be>
50 * @copyright 2012-2014 The Galette Team
51 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
52 * @link http://galette.tuxfamily.org
53 * @since Available since 0.7dev - 2012-01-17
57 const TABLE
= 'groups';
58 const PK
= 'id_group';
60 const GROUPSUSERS_TABLE
= 'groups_members';
61 const GROUPSMANAGERS_TABLE
= 'groups_managers';
63 const MEMBER_TYPE
= 0;
64 const MANAGER_TYPE
= 1;
68 private $parent_group;
72 private $creation_date;
73 private $count_members;
79 * @param null|int|ResultSet $args Either a ResultSet row or its id for to load
80 * a specific group, or null to just
83 public function __construct($args = null)
85 if ($args == null ||
is_int($args)) {
86 if (is_int($args) && $args > 0) {
89 } elseif (is_object($args)) {
90 $this->loadFromRS($args);
95 * Loads a group from its id
97 * @param int $id the identifiant for the group to load
99 * @return bool true if query succeed, false otherwise
101 public function load($id)
106 $select = $zdb->select(self
::TABLE
);
107 $select->where(array(self
::PK
=> $id));
109 $results = $zdb->execute($select);
111 if ($results->count() > 0) {
112 $this->loadFromRS($results->current());
117 } catch (\Exception
$e) {
119 'Cannot load group form id `' . $id . '` | ' . $e->getMessage(),
127 * Populate object from a resultset row
129 * @param ResultSet $r the resultset row
133 private function loadFromRS($r)
135 $this->id
= $r->id_group
;
136 $this->group_name
= $r->group_name
;
137 $this->creation_date
= $r->creation_date
;
138 if ($r->parent_group
) {
139 $this->parent_group
= new Group((int)$r->parent_group
);
141 $adhpk = Adherent
::PK
;
142 if (isset($r->members
)) {
143 //we're from a list, we just want members count
144 $this->count_members
= $r->members
;
146 //we're probably from a single group, let's load sub entities
147 //$this->loadPersons(self::MEMBER_TYPE);
148 //$this->loadPersons(self::MANAGER_TYPE);
149 //$this->loadSubGroups();
154 * Loads members for the current group
156 * @param int $type Either self::MEMBER_TYPE or self::MANAGER_TYPE
160 private function loadPersons($type)
168 case self
::MEMBER_TYPE
:
169 $join = PREFIX_DB
. self
::GROUPSUSERS_TABLE
;
171 case self
::MANAGER_TYPE
:
172 $join = PREFIX_DB
. self
::GROUPSMANAGERS_TABLE
;
176 $select = $zdb->select(Adherent
::TABLE
, 'a');
179 'g.' . Adherent
::PK
. '=a.' . Adherent
::PK
,
182 'g.' . self
::PK
. ' = ' . $this->id
188 $results = $zdb->execute($select);
190 $adhpk = Adherent
::PK
;
198 foreach ($results as $m) {
199 $members[] = new Adherent($zdb, $m, $deps);
202 if ($type === self
::MEMBER_TYPE
) {
203 $this->members
= $members;
205 $this->managers
= $members;
207 } catch (\Exception
$e) {
209 'Cannot get group persons | ' . $e->getMessage(),
221 private function loadSubGroups()
226 $select = $zdb->select(self
::TABLE
, 'a');
228 if (!$this->login
->isAdmin() && !$this->login
->isStaff()) {
230 array('b' => PREFIX_DB
. self
::GROUPSMANAGERS_TABLE
),
231 'a.' . self
::PK
. '=b.' . self
::PK
,
233 )->where('b.' . Adherent
::PK
. ' = ' . $this->login
->id
);
236 $select->where('parent_group = ' . $this->id
)
237 ->order('group_name ASC');
239 $results = $zdb->execute($select);
242 foreach ($results as $m) {
243 $group = new Group((int)$m->$grppk);
244 $group->setLogin($this->login
);
247 $this->groups
= $groups;
248 } catch (\Exception
$e) {
250 'Cannot get subgroup for group ' . $this->group_name
.
251 ' (' . $this->id
. ')| ' . $e->getMessage(),
258 * Remove specified group
260 * @param boolean $cascade Also remove members and managers
264 public function remove($cascade = false)
267 $transaction = false;
270 if (!$zdb->connection
->inTransaction()) {
271 $zdb->connection
->beginTransaction();
275 if ($cascade === true) {
276 $subgroups = $this->getGroups();
277 if (count($subgroups) > 0) {
279 'Cascading remove ' . $this->group_name
.
280 '. Subgroups, their members and managers will be detached.',
283 foreach ($subgroups as $subgroup) {
284 $subgroup->remove(true);
289 'Cascading remove ' . $this->group_name
.
290 '. Members and managers will be detached.',
295 $delete = $zdb->delete(self
::GROUPSUSERS_TABLE
);
297 self
::PK
. ' = ' . $this->id
299 $zdb->execute($delete);
302 $delete = $zdb->delete(self
::GROUPSMANAGERS_TABLE
);
304 self
::PK
. ' = ' . $this->id
306 $zdb->execute($delete);
309 //delete group itself
310 $delete = $zdb->delete(self
::TABLE
);
312 self
::PK
. ' = ' . $this->id
314 $zdb->execute($delete);
318 $zdb->connection
->commit();
322 } catch (\Exception
$e) {
324 $zdb->connection
->rollBack();
326 if ($e->getCode() == 23000) {
331 'Group "%group" still have members!'
335 $this->isempty
= false;
338 'Unable to delete group ' . $this->group_name
.
339 ' (' . $this->id
. ') |' . $e->getMessage(),
348 * Is group empty? (after first deletion try)
352 public function isEmpty()
354 return $this->isempty
;
358 * Detach a group from its parent
362 public function detach()
367 $update = $zdb->update(self
::TABLE
);
369 array('parent_group' => new Expression('NULL'))
371 self
::PK
. ' = ' . $this->id
374 $edit = $zdb->execute($update);
376 //edit == 0 does not mean there were an error, but that there
377 //were nothing to change
378 if ($edit->count() > 0) {
379 $this->parent_group
= null;
381 _T("Group has been detached from its parent"),
387 } catch (\Exception
$e) {
389 'Something went wrong detaching group `' . $this->group_name
.
390 '` (' . $this->id
. ') from its parent:\'( | ' .
391 $e->getMessage() . "\n" .
392 $e->getTraceAsString(),
395 throw new \
Exception(_T("Unable to detach group :("));
404 public function store()
410 self
::PK
=> $this->id
,
411 'group_name' => $this->group_name
414 if ($this->parent_group
) {
415 $values['parent_group'] = $this->parent_group
->getId();
418 if (!isset($this->id
) ||
$this->id
== '') {
419 //we're inserting a new group
420 unset($values[self
::PK
]);
421 $this->creation_date
= date("Y-m-d H:i:s");
422 $values['creation_date'] = $this->creation_date
;
424 $insert = $zdb->insert(self
::TABLE
);
425 $insert->values($values);
426 $add = $zdb->execute($insert);
427 if ($add->count() > 0) {
428 if ($zdb->isPostgres()) {
429 $this->id
= (int)$zdb->driver
->getLastGeneratedValue(
430 PREFIX_DB
. 'groups_id_seq'
433 $this->id
= (int)$zdb->driver
->getLastGeneratedValue();
443 $hist->add(_T("Fail to add new group."));
444 throw new \
Exception(
445 'An error occurred inserting new group!'
449 //we're editing an existing group
450 $update = $zdb->update(self
::TABLE
);
453 ->where(self
::PK
. '=' . $this->id
);
455 $edit = $zdb->execute($update);
457 //edit == 0 does not mean there were an error, but that there
458 //were nothing to change
459 if ($edit->count() > 0) {
467 /** FIXME: also store members and managers? */
468 } catch (\Exception
$e) {
470 'Something went wrong :\'( | ' . $e->getMessage() . "\n" .
471 $e->getTraceAsString(),
479 * Is current loggedin user manager of the group?
481 * @param Login $login Login instance
485 public function isManager(Login
$login)
487 if ($login->isAdmin() ||
$login->isStaff()) {
488 //admins as well as staff members are managers for all groups!
491 //let's check if current loggedin user is part of group managers
492 foreach ($this->managers
as $manager) {
493 if ($login->login
== $manager->login
) {
507 public function getId()
513 * Get Level of the group
517 public function getLevel()
519 if ($this->parent_group
) {
520 return $this->parent_group
->getLevel() +
1;
526 * Get the full name of the group "foo / bar"
530 public function getFullName()
532 if ($this->parent_group
) {
533 return $this->parent_group
->getFullName() . ' / ' . $this->group_name
;
535 return $this->group_name
;
539 * Get the indented short name of the group " >> bar"
543 public function getIndentName()
545 if (($level = $this->getLevel())) {
546 return str_repeat(" ", 3 * $level) . '» ' . $this->group_name
;
548 return $this->group_name
;
556 public function getName()
558 return $this->group_name
;
566 public function getMembers()
568 if (!is_array($this->members
)) {
569 $this->loadPersons(self
::MEMBER_TYPE
);
571 return $this->members
;
575 * Get groups managers
579 public function getManagers()
581 if (!is_array($this->managers
)) {
582 $this->loadPersons(self
::MANAGER_TYPE
);
584 return $this->managers
;
592 public function getGroups()
594 if (!is_array($this->groups
)) {
595 $this->loadSubGroups();
597 return $this->groups
;
605 public function getParentGroup()
607 return $this->parent_group
;
611 * Get group creation date
613 * @param boolean $formatted Return date formatted, raw if false
617 public function getCreationDate($formatted = true)
619 if ($formatted === true) {
620 $date = new \
DateTime($this->creation_date
);
621 return $date->format(__("Y-m-d"));
623 return $this->creation_date
;
630 * @param boolean $force Force members load, defaults to false
634 public function getMemberCount($force = false)
636 if (isset($this->members
) && is_array($this->members
)) {
637 return count($this->members
);
638 } elseif (isset($this->count_members
)) {
639 return $this->count_members
;
641 if ($force === true) {
642 return count($this->getMembers());
652 * @param string $name Group name
656 public function setName($name)
658 $this->group_name
= $name;
665 * @param array $groups Groups id
669 public function setSubgroups($groups)
671 $this->groups
= $groups;
676 * check if can Set parent group
678 * @param Group $group Parent group
682 public function canSetParentGroup(Group
$group)
685 if ($group->getId() == $this->getId()) {
688 } while ($group = $group->getParentGroup());
696 * @param int $id Parent group identifier
700 public function setParentGroup($id)
702 $group = new Group((int)$id);
704 if (!$this->canSetParentGroup($group)) {
705 //does not seem to work :/
706 throw new \
Exception(
708 _T('Group `%1$s` cannot be set as parent!'),
714 $this->parent_group
= $group;
721 * @param Adherent[] $members Members list
725 public function setMembers($members)
730 $zdb->connection
->beginTransaction();
732 //first, remove current groups members
733 $delete = $zdb->delete(self
::GROUPSUSERS_TABLE
);
735 self
::PK
. ' = ' . $this->id
737 $zdb->execute($delete);
740 'Group members has been removed for `' . $this->group_name
.
741 '`, we can now store new ones.',
745 $insert = $zdb->insert(self
::GROUPSUSERS_TABLE
);
748 self
::PK
=> ':group',
749 Adherent
::PK
=> ':adh'
753 $stmt = $zdb->sql
->prepareStatementForSqlObject($insert);
755 if (is_array($members)) {
756 foreach ($members as $m) {
757 $result = $stmt->execute(
759 self
::PK
=> $this->id
,
760 Adherent
::PK
=> $m->id
766 'Member `' . $m->sname
. '` attached to group `' .
767 $this->group_name
. '`.',
772 'An error occurred trying to attach member `' .
773 $m->sname
. '` to group `' . $this->group_name
.
774 '` (' . $this->id
. ').',
777 throw new \
Exception(
778 'Unable to attach `' . $m->sname
. '` ' .
779 'to ' . $this->group_name
. '(' . $this->id
. ')'
785 $zdb->connection
->commit();
788 'Group members updated successfully.',
793 } catch (\Exception
$e) {
794 $zdb->connection
->rollBack();
797 $messages[] = $e->getMessage();
798 } while ($e = $e->getPrevious());
800 'Unable to attach members to group `' . $this->group_name
.
801 '` (' . $this->id
. ')|' . implode("\n", $messages),
811 * @param Adherent[] $members Managers list
815 public function setManagers($members)
820 $zdb->connection
->beginTransaction();
822 //first, remove current groups managers
823 $delete = $zdb->delete(self
::GROUPSMANAGERS_TABLE
);
825 self
::PK
. ' = ' . $this->id
827 $zdb->execute($delete);
830 'Group managers has been removed for `' . $this->group_name
.
831 '`, we can now store new ones.',
835 $insert = $zdb->insert(self
::GROUPSMANAGERS_TABLE
);
838 self
::PK
=> ':group',
839 Adherent
::PK
=> ':adh'
843 $stmt = $zdb->sql
->prepareStatementForSqlObject($insert);
845 if (is_array($members)) {
846 foreach ($members as $m) {
847 $result = $stmt->execute(
849 Group
::PK
=> $this->id
,
850 Adherent
::PK
=> $m->id
856 'Manager `' . $m->sname
. '` attached to group `' .
857 $this->group_name
. '`.',
862 'An error occurred trying to attach manager `' .
863 $m->sname
. '` to group `' . $this->group_name
.
864 '` (' . $this->id
. ').',
867 throw new \
Exception(
868 'Unable to attach `' . $m->sname
. '` ' .
869 'to ' . $this->group_name
. '(' . $this->id
. ')'
875 $zdb->connection
->commit();
878 'Groups managers updated successfully.',
883 } catch (\Exception
$e) {
884 $zdb->connection
->rollBack();
887 $messages[] = $e->getMessage();
888 } while ($e = $e->getPrevious());
890 'Unable to attach managers to group `' . $this->group_name
.
891 '` (' . $this->id
. ')|' . implode("\n", $messages),
901 * @param Login $login Login instance
905 public function setLogin(Login
$login)
907 $this->login
= $login;