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
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.7dev - 2012-01-17
38 namespace Galette\Entity
;
40 use Galette\Core\Login
;
42 use Laminas\Db\Sql\Expression
;
50 * @author Johan Cwiklinski <johan@x-tnd.be>
51 * @copyright 2012-2014 The Galette Team
52 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
53 * @link http://galette.tuxfamily.org
54 * @since Available since 0.7dev - 2012-01-17
58 const TABLE
= 'groups';
59 const PK
= 'id_group';
61 const GROUPSUSERS_TABLE
= 'groups_members';
62 const GROUPSMANAGERS_TABLE
= 'groups_managers';
64 const MEMBER_TYPE
= 0;
65 const MANAGER_TYPE
= 1;
69 private $parent_group;
73 private $creation_date;
74 private $count_members;
80 * @param null|int|ResultSet $args Either a ResultSet row or its id for to load
81 * a specific group, or null to just
84 public function __construct($args = null)
86 if ($args == null ||
is_int($args)) {
87 if (is_int($args) && $args > 0) {
90 } elseif (is_object($args)) {
91 $this->loadFromRS($args);
96 * Loads a group from its id
98 * @param int $id the identifiant for the group to load
100 * @return bool true if query succeed, false otherwise
102 public function load($id)
107 $select = $zdb->select(self
::TABLE
);
108 $select->where(array(self
::PK
=> $id));
110 $results = $zdb->execute($select);
112 if ($results->count() > 0) {
113 $this->loadFromRS($results->current());
118 } catch (\Exception
$e) {
120 'Cannot load group form id `' . $id . '` | ' . $e->getMessage(),
128 * Populate object from a resultset row
130 * @param ResultSet $r the resultset row
134 private function loadFromRS($r)
136 $this->id
= $r->id_group
;
137 $this->group_name
= $r->group_name
;
138 $this->creation_date
= $r->creation_date
;
139 if ($r->parent_group
) {
140 $this->parent_group
= new Group((int)$r->parent_group
);
142 $adhpk = Adherent
::PK
;
143 if (isset($r->members
)) {
144 //we're from a list, we just want members count
145 $this->count_members
= $r->members
;
147 //we're probably from a single group, let's load sub entities
148 //$this->loadPersons(self::MEMBER_TYPE);
149 //$this->loadPersons(self::MANAGER_TYPE);
150 //$this->loadSubGroups();
155 * Loads members for the current group
157 * @param int $type Either self::MEMBER_TYPE or self::MANAGER_TYPE
161 private function loadPersons($type)
169 case self
::MEMBER_TYPE
:
170 $join = PREFIX_DB
. self
::GROUPSUSERS_TABLE
;
172 case self
::MANAGER_TYPE
:
173 $join = PREFIX_DB
. self
::GROUPSMANAGERS_TABLE
;
177 $select = $zdb->select(Adherent
::TABLE
, 'a');
180 'g.' . Adherent
::PK
. '=a.' . Adherent
::PK
,
183 'g.' . self
::PK
. ' = ' . $this->id
189 $results = $zdb->execute($select);
191 $adhpk = Adherent
::PK
;
199 foreach ($results as $m) {
200 $members[] = new Adherent($zdb, $m, $deps);
203 if ($type === self
::MEMBER_TYPE
) {
204 $this->members
= $members;
206 $this->managers
= $members;
208 } catch (\Exception
$e) {
210 'Cannot get group persons | ' . $e->getMessage(),
222 private function loadSubGroups()
227 $select = $zdb->select(self
::TABLE
, 'a');
229 if (!$this->login
->isAdmin() && !$this->login
->isStaff()) {
231 array('b' => PREFIX_DB
. self
::GROUPSMANAGERS_TABLE
),
232 'a.' . self
::PK
. '=b.' . self
::PK
,
234 )->where('b.' . Adherent
::PK
. ' = ' . $this->login
->id
);
237 $select->where('parent_group = ' . $this->id
)
238 ->order('group_name ASC');
240 $results = $zdb->execute($select);
243 foreach ($results as $m) {
244 $group = new Group((int)$m->$grppk);
245 $group->setLogin($this->login
);
248 $this->groups
= $groups;
249 } catch (\Exception
$e) {
251 'Cannot get subgroup for group ' . $this->group_name
.
252 ' (' . $this->id
. ')| ' . $e->getMessage(),
259 * Remove specified group
261 * @param boolean $cascade Also remove members and managers
265 public function remove($cascade = false)
268 $transaction = false;
271 if (!$zdb->connection
->inTransaction()) {
272 $zdb->connection
->beginTransaction();
276 if ($cascade === true) {
277 $subgroups = $this->getGroups();
278 if (count($subgroups) > 0) {
280 'Cascading remove ' . $this->group_name
.
281 '. Subgroups, their members and managers will be detached.',
284 foreach ($subgroups as $subgroup) {
285 $subgroup->remove(true);
290 'Cascading remove ' . $this->group_name
.
291 '. Members and managers will be detached.',
296 $delete = $zdb->delete(self
::GROUPSUSERS_TABLE
);
298 self
::PK
. ' = ' . $this->id
300 $zdb->execute($delete);
303 $delete = $zdb->delete(self
::GROUPSMANAGERS_TABLE
);
305 self
::PK
. ' = ' . $this->id
307 $zdb->execute($delete);
310 //delete group itself
311 $delete = $zdb->delete(self
::TABLE
);
313 self
::PK
. ' = ' . $this->id
315 $zdb->execute($delete);
319 $zdb->connection
->commit();
323 } catch (\Exception
$e) {
325 $zdb->connection
->rollBack();
327 if ($e->getCode() == 23000) {
332 'Group "%group" still have members!'
336 $this->isempty
= false;
339 'Unable to delete group ' . $this->group_name
.
340 ' (' . $this->id
. ') |' . $e->getMessage(),
349 * Is group empty? (after first deletion try)
353 public function isEmpty()
355 return $this->isempty
;
359 * Detach a group from its parent
363 public function detach()
368 $update = $zdb->update(self
::TABLE
);
370 array('parent_group' => new Expression('NULL'))
372 self
::PK
. ' = ' . $this->id
375 $edit = $zdb->execute($update);
377 //edit == 0 does not mean there were an error, but that there
378 //were nothing to change
379 if ($edit->count() > 0) {
380 $this->parent_group
= null;
382 _T("Group has been detached from its parent"),
388 } catch (\Exception
$e) {
390 'Something went wrong detaching group `' . $this->group_name
.
391 '` (' . $this->id
. ') from its parent:\'( | ' .
392 $e->getMessage() . "\n" .
393 $e->getTraceAsString(),
396 throw new \
Exception(_T("Unable to detach group :("));
405 public function store()
411 self
::PK
=> $this->id
,
412 'group_name' => $this->group_name
415 if ($this->parent_group
) {
416 $values['parent_group'] = $this->parent_group
->getId();
419 if (!isset($this->id
) ||
$this->id
== '') {
420 //we're inserting a new group
421 unset($values[self
::PK
]);
422 $this->creation_date
= date("Y-m-d H:i:s");
423 $values['creation_date'] = $this->creation_date
;
425 $insert = $zdb->insert(self
::TABLE
);
426 $insert->values($values);
427 $add = $zdb->execute($insert);
428 if ($add->count() > 0) {
429 if ($zdb->isPostgres()) {
430 $this->id
= (int)$zdb->driver
->getLastGeneratedValue(
431 PREFIX_DB
. 'groups_id_seq'
434 $this->id
= (int)$zdb->driver
->getLastGeneratedValue();
444 $hist->add(_T("Fail to add new group."));
445 throw new \
Exception(
446 'An error occurred inserting new group!'
450 //we're editing an existing group
451 $update = $zdb->update(self
::TABLE
);
454 ->where(self
::PK
. '=' . $this->id
);
456 $edit = $zdb->execute($update);
458 //edit == 0 does not mean there were an error, but that there
459 //were nothing to change
460 if ($edit->count() > 0) {
468 /** FIXME: also store members and managers? */
469 } catch (\Exception
$e) {
471 'Something went wrong :\'( | ' . $e->getMessage() . "\n" .
472 $e->getTraceAsString(),
480 * Is current loggedin user manager of the group?
482 * @param Login $login Login instance
486 public function isManager(Login
$login)
488 if ($login->isAdmin() ||
$login->isStaff()) {
489 //admins as well as staff members are managers for all groups!
492 //let's check if current loggedin user is part of group managers
493 foreach ($this->managers
as $manager) {
494 if ($login->login
== $manager->login
) {
508 public function getId()
514 * Get Level of the group
518 public function getLevel()
520 if ($this->parent_group
) {
521 return $this->parent_group
->getLevel()+
1;
527 * Get the full name of the group "foo / bar"
531 public function getFullName()
533 if ($this->parent_group
) {
534 return $this->parent_group
->getFullName().' / '.$this->group_name
;
536 return $this->group_name
;
540 * Get the indented short name of the group " >> bar"
544 public function getIndentName()
546 if (($level = $this->getLevel())) {
547 return str_repeat(" ", 3*$level).'» '.$this->group_name
;
549 return $this->group_name
;
557 public function getName()
559 return $this->group_name
;
567 public function getMembers()
569 if (!is_array($this->members
)) {
570 $this->loadPersons(self
::MEMBER_TYPE
);
572 return $this->members
;
576 * Get groups managers
580 public function getManagers()
582 if (!is_array($this->managers
)) {
583 $this->loadPersons(self
::MANAGER_TYPE
);
585 return $this->managers
;
593 public function getGroups()
595 if (!is_array($this->groups
)) {
596 $this->loadSubGroups();
598 return $this->groups
;
606 public function getParentGroup()
608 return $this->parent_group
;
612 * Get group creation date
614 * @param boolean $formatted Return date formatted, raw if false
618 public function getCreationDate($formatted = true)
620 if ($formatted === true) {
621 $date = new \
DateTime($this->creation_date
);
622 return $date->format(__("Y-m-d"));
624 return $this->creation_date
;
631 * @param boolean $force Force members load, defaults to false
635 public function getMemberCount($force = false)
637 if (isset($this->members
) && is_array($this->members
)) {
638 return count($this->members
);
639 } elseif (isset($this->count_members
)) {
640 return $this->count_members
;
642 if ($force === true) {
643 return count($this->getMembers());
653 * @param string $name Group name
657 public function setName($name)
659 $this->group_name
= $name;
666 * @param array $groups Groups id
670 public function setSubgroups($groups)
672 $this->groups
= $groups;
677 * check if can Set parent group
679 * @param Group $group Parent group
683 public function canSetParentGroup(Group
$group)
686 if ($group->getId() == $this->getId()) {
689 } while ($group = $group->getParentGroup());
697 * @param int $id Parent group identifier
701 public function setParentGroup($id)
703 $group = new Group((int)$id);
705 if (!$this->canSetParentGroup($group)) {
706 //does not seem to work :/
707 throw new \
Exception(
709 _T('Group `%1$s` cannot be set as parent!'),
715 $this->parent_group
= $group;
722 * @param Adherent[] $members Members list
726 public function setMembers($members)
731 $zdb->connection
->beginTransaction();
733 //first, remove current groups members
734 $delete = $zdb->delete(self
::GROUPSUSERS_TABLE
);
736 self
::PK
. ' = ' . $this->id
738 $zdb->execute($delete);
741 'Group members has been removed for `' . $this->group_name
.
742 '`, we can now store new ones.',
746 $insert = $zdb->insert(self
::GROUPSUSERS_TABLE
);
749 self
::PK
=> ':group',
750 Adherent
::PK
=> ':adh'
754 $stmt = $zdb->sql
->prepareStatementForSqlObject($insert);
756 if (is_array($members)) {
757 foreach ($members as $m) {
758 $result = $stmt->execute(
760 self
::PK
=> $this->id
,
761 Adherent
::PK
=> $m->id
767 'Member `' . $m->sname
. '` attached to group `' .
768 $this->group_name
. '`.',
773 'An error occurred trying to attach member `' .
774 $m->sname
. '` to group `' . $this->group_name
.
775 '` (' . $this->id
. ').',
778 throw new \
Exception(
779 'Unable to attach `' . $m->sname
. '` ' .
780 'to ' . $this->group_name
. '(' . $this->id
. ')'
786 $zdb->connection
->commit();
789 'Group members updated successfully.',
794 } catch (\Exception
$e) {
795 $zdb->connection
->rollBack();
798 $messages[] = $e->getMessage();
799 } while ($e = $e->getPrevious());
801 'Unable to attach members to group `' . $this->group_name
.
802 '` (' . $this->id
. ')|' . implode("\n", $messages),
812 * @param Adherent[] $members Managers list
816 public function setManagers($members)
821 $zdb->connection
->beginTransaction();
823 //first, remove current groups managers
824 $delete = $zdb->delete(self
::GROUPSMANAGERS_TABLE
);
826 self
::PK
. ' = ' . $this->id
828 $zdb->execute($delete);
831 'Group managers has been removed for `' . $this->group_name
.
832 '`, we can now store new ones.',
836 $insert = $zdb->insert(self
::GROUPSMANAGERS_TABLE
);
839 self
::PK
=> ':group',
840 Adherent
::PK
=> ':adh'
844 $stmt = $zdb->sql
->prepareStatementForSqlObject($insert);
846 if (is_array($members)) {
847 foreach ($members as $m) {
848 $result = $stmt->execute(
850 Group
::PK
=> $this->id
,
851 Adherent
::PK
=> $m->id
857 'Manager `' . $m->sname
. '` attached to group `' .
858 $this->group_name
. '`.',
863 'An error occurred trying to attach manager `' .
864 $m->sname
. '` to group `' . $this->group_name
.
865 '` (' . $this->id
. ').',
868 throw new \
Exception(
869 'Unable to attach `' . $m->sname
. '` ' .
870 'to ' . $this->group_name
. '(' . $this->id
. ')'
876 $zdb->connection
->commit();
879 'Groups managers updated successfully.',
884 } catch (\Exception
$e) {
885 $zdb->connection
->rollBack();
888 $messages[] = $e->getMessage();
889 } while ($e = $e->getPrevious());
891 'Unable to attach managers to group `' . $this->group_name
.
892 '` (' . $this->id
. ')|' . implode("\n", $messages),
902 * @param Login $login Login instance
906 public function setLogin(Login
$login)
908 $this->login
= $login;