|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the Zikula package. |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright Zikula Foundation - http://zikula.org/ |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Zikula\GroupsModule\Controller; |
|
13
|
|
|
|
|
14
|
|
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
|
15
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
16
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
17
|
|
|
use Symfony\Component\HttpFoundation\RedirectResponse; |
|
18
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
|
19
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; |
|
20
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; |
|
21
|
|
|
use Zikula\Core\Controller\AbstractController; |
|
22
|
|
|
use Zikula\Core\Event\GenericEvent; |
|
23
|
|
|
use Zikula\Core\Response\PlainResponse; |
|
24
|
|
|
use Zikula\GroupsModule\Entity\GroupEntity; |
|
25
|
|
|
use Zikula\GroupsModule\GroupEvents; |
|
26
|
|
|
use Zikula\GroupsModule\Helper\CommonHelper; |
|
27
|
|
|
use Zikula\ThemeModule\Engine\Annotation\Theme; |
|
28
|
|
|
use Zikula\UsersModule\Constant as UsersConstant; |
|
29
|
|
|
use Zikula\UsersModule\Entity\UserEntity; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @Route("/membership") |
|
33
|
|
|
* |
|
34
|
|
|
* Administrative controllers for the groups module |
|
35
|
|
|
*/ |
|
36
|
|
|
class MembershipController extends AbstractController |
|
37
|
|
|
{ |
|
38
|
|
|
/** |
|
39
|
|
|
* @Route("/list/{gid}/{letter}/{startNum}", requirements={"gid" = "^[1-9]\d*$", "letter" = "[a-zA-Z]|\*", "startNum" = "\d+"}) |
|
40
|
|
|
* @Method("GET") |
|
41
|
|
|
* @Template |
|
42
|
|
|
* |
|
43
|
|
|
* Display all members of a group to a user |
|
44
|
|
|
* |
|
45
|
|
|
* @param GroupEntity $group |
|
46
|
|
|
* @param string $letter the letter from the alpha filter |
|
47
|
|
|
* @param integer $startNum the start item number for the pager |
|
48
|
|
|
* @return array |
|
49
|
|
|
*/ |
|
50
|
|
|
public function listAction(GroupEntity $group, $letter = '*', $startNum = 0) |
|
51
|
|
|
{ |
|
52
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::memberslist', '::', ACCESS_OVERVIEW)) { |
|
53
|
|
|
throw new AccessDeniedException(); |
|
54
|
|
|
} |
|
55
|
|
|
$groupsCommon = new CommonHelper($this->getTranslator()); |
|
56
|
|
|
$inactiveLimit = $this->get('zikula_extensions_module.api.variable')->getSystemVar('secinactivemins'); |
|
57
|
|
|
$dateTime = new \DateTime(); |
|
58
|
|
|
$dateTime->modify('-' . $inactiveLimit . 'minutes'); |
|
59
|
|
|
|
|
60
|
|
|
return [ |
|
61
|
|
|
'group' => $group, |
|
62
|
|
|
'groupTypes' => $groupsCommon->gtypeLabels(), |
|
63
|
|
|
'states' => $groupsCommon->stateLabels(), |
|
64
|
|
|
'usersOnline' => $this->get('zikula_users_module.user_session_repository')->getUsersSince($dateTime), |
|
65
|
|
|
'pager' => [ |
|
66
|
|
|
'amountOfItems' => $group->getUsers()->count(), |
|
67
|
|
|
'itemsPerPage' => $this->getVar('itemsperpage', 25) |
|
68
|
|
|
], |
|
69
|
|
|
]; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* @Route("/admin/list/{gid}/{letter}/{startNum}", requirements={"gid" = "^[1-9]\d*$", "letter" = "[a-zA-Z]|\*", "startNum" = "\d+"}) |
|
74
|
|
|
* @Method("GET") |
|
75
|
|
|
* @Theme("admin") |
|
76
|
|
|
* @Template |
|
77
|
|
|
* |
|
78
|
|
|
* Display all members of a group to an admin |
|
79
|
|
|
* |
|
80
|
|
|
* @param GroupEntity $group |
|
81
|
|
|
* @param string $letter the letter from the alpha filter |
|
82
|
|
|
* @param integer $startNum the start item number for the pager |
|
83
|
|
|
* @return array |
|
84
|
|
|
*/ |
|
85
|
|
|
public function adminListAction(GroupEntity $group, $letter = '*', $startNum = 0) |
|
86
|
|
|
{ |
|
87
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::', $group->getGid() . '::', ACCESS_EDIT)) { |
|
88
|
|
|
throw new AccessDeniedException(); |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
return [ |
|
92
|
|
|
'group' => $group, |
|
93
|
|
|
'pager' => [ |
|
94
|
|
|
'amountOfItems' => $group->getUsers()->count(), |
|
95
|
|
|
'itemsPerPage' => $this->getVar('itemsperpage', 25) |
|
96
|
|
|
], |
|
97
|
|
|
'csrfToken' => $this->get('zikula_core.common.csrf_token_handler')->generate() |
|
98
|
|
|
]; |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
/** |
|
102
|
|
|
* @Route("/admin/add/{uid}/{gid}/{csrfToken}", requirements={"gid" = "^[1-9]\d*$", "uid" = "^[1-9]\d*$"}) |
|
103
|
|
|
* |
|
104
|
|
|
* Add user to a group. |
|
105
|
|
|
* |
|
106
|
|
|
* @param UserEntity $userEntity |
|
107
|
|
|
* @param GroupEntity $group |
|
108
|
|
|
* @param $csrfToken |
|
109
|
|
|
* @return RedirectResponse |
|
110
|
|
|
*/ |
|
111
|
|
|
public function addAction(UserEntity $userEntity, GroupEntity $group, $csrfToken) |
|
112
|
|
|
{ |
|
113
|
|
|
$this->get('zikula_core.common.csrf_token_handler')->validate($csrfToken); |
|
114
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::', $group->getGid() . '::', ACCESS_EDIT)) { |
|
115
|
|
|
throw new AccessDeniedException(); |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
if ($userEntity->getGroups()->contains($group)) { |
|
119
|
|
|
$this->addFlash('warning', $this->__('The selected user is already a member of this group.')); |
|
120
|
|
View Code Duplication |
} else { |
|
|
|
|
|
|
121
|
|
|
$userEntity->addGroup($group); |
|
122
|
|
|
$this->get('doctrine')->getManager()->flush(); |
|
123
|
|
|
$this->addFlash('status', $this->__('Done! The user was added to the group.')); |
|
124
|
|
|
// Let other modules know that we have updated a group. |
|
125
|
|
|
$addUserEvent = new GenericEvent(['gid' => $group->getGid(), 'uid' => $userEntity->getUid()]); |
|
126
|
|
|
$this->get('event_dispatcher')->dispatch(GroupEvents::GROUP_ADD_USER, $addUserEvent); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
return $this->redirectToRoute('zikulagroupsmodule_membership_adminlist', ['gid' => $group->getGid()]); |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
/** |
|
133
|
|
|
* Process request by the current user to join a group |
|
134
|
|
|
* @Route("/join/{gid}", requirements={"gid" = "^[1-9]\d*$"}) |
|
135
|
|
|
* @param GroupEntity $group |
|
136
|
|
|
* @return RedirectResponse |
|
137
|
|
|
*/ |
|
138
|
|
|
public function joinAction(GroupEntity $group) |
|
139
|
|
|
{ |
|
140
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::', '::', ACCESS_OVERVIEW)) { |
|
141
|
|
|
throw new AccessDeniedException(); |
|
142
|
|
|
} |
|
143
|
|
|
$currentUserApi = $this->get('zikula_users_module.current_user'); |
|
144
|
|
|
if (!$currentUserApi->isLoggedIn()) { |
|
145
|
|
|
throw new AccessDeniedException($this->__('Sorry! You must register for a user account on this site before you can join a group.')); |
|
146
|
|
|
} |
|
147
|
|
|
/** @var UserEntity $userEntity */ |
|
148
|
|
|
$userEntity = $this->get('zikula_users_module.user_repository')->find($currentUserApi->get('uid')); |
|
149
|
|
|
$groupTypeIsPrivate = $group->getGtype() == CommonHelper::GTYPE_PRIVATE; |
|
150
|
|
|
$groupTypeIsCore = $group->getGtype() == CommonHelper::GTYPE_CORE; |
|
151
|
|
|
$groupStateIsClosed = $group->getState() == CommonHelper::STATE_CLOSED; |
|
152
|
|
|
$groupCountIsLimit = $group->getNbumax() > 0 && $group->getUsers()->count() > $group->getNbumax(); |
|
153
|
|
|
$alreadyGroupMember = $group->getUsers()->contains($userEntity); |
|
154
|
|
|
if ($groupTypeIsPrivate || $groupTypeIsCore || $groupStateIsClosed || $groupCountIsLimit || $alreadyGroupMember) { |
|
155
|
|
|
$this->addFlash('error', $this->getSpecificGroupMessage($groupTypeIsPrivate, $groupTypeIsCore, $groupStateIsClosed, $groupCountIsLimit, $alreadyGroupMember)); |
|
156
|
|
View Code Duplication |
} else { |
|
|
|
|
|
|
157
|
|
|
$userEntity->addGroup($group); |
|
158
|
|
|
$this->get('doctrine')->getManager()->flush(); |
|
159
|
|
|
$this->addFlash('success', $this->__f('Joined the "%group" group', ['%group' => $group->getName()])); |
|
160
|
|
|
// Let other modules know that we have updated a group. |
|
161
|
|
|
$addUserEvent = new GenericEvent(['gid' => $group->getGid(), 'uid' => $userEntity->getUid()]); |
|
162
|
|
|
$this->get('event_dispatcher')->dispatch(GroupEvents::GROUP_ADD_USER, $addUserEvent); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
return $this->redirectToRoute('zikulagroupsmodule_group_list'); |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* @Route("/admin/remove/{gid}/{uid}", requirements={"gid" = "^[1-9]\d*$", "uid" = "^[1-9]\d*$"}) |
|
170
|
|
|
* @Theme("admin") |
|
171
|
|
|
* @Template |
|
172
|
|
|
* |
|
173
|
|
|
* Remove a user from a group. |
|
174
|
|
|
* |
|
175
|
|
|
* @param Request $request |
|
176
|
|
|
* @param int $gid |
|
177
|
|
|
* @param int $uid |
|
178
|
|
|
* @return mixed Response|void symfony response object if confirmation isn't provided, void otherwise |
|
179
|
|
|
*/ |
|
180
|
|
|
public function removeAction(Request $request, $gid = 0, $uid = 0) |
|
181
|
|
|
{ |
|
182
|
|
|
if ($request->isMethod('POST')) { |
|
183
|
|
|
$postVars = $request->request->get('zikulagroupsmodule_removeuser'); |
|
184
|
|
|
$gid = isset($postVars['gid']) ? $postVars['gid'] : 0; |
|
185
|
|
|
$uid = isset($postVars['uid']) ? $postVars['uid'] : 0; |
|
186
|
|
|
} |
|
187
|
|
|
if ($gid < 1 || $uid < 1) { |
|
188
|
|
|
throw new \InvalidArgumentException($this->__('Invalid Group ID or User ID.')); |
|
189
|
|
|
} |
|
190
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::', $gid.'::', ACCESS_EDIT)) { |
|
191
|
|
|
throw new AccessDeniedException(); |
|
192
|
|
|
} |
|
193
|
|
|
$group = $this->get('zikula_groups_module.group_repository')->find($gid); |
|
194
|
|
|
if (!$group) { |
|
195
|
|
|
throw new \InvalidArgumentException($this->__('Invalid Group ID.')); |
|
196
|
|
|
} |
|
197
|
|
|
$user = $this->get('zikula_users_module.user_repository')->find($uid); |
|
198
|
|
|
if (!$user) { |
|
199
|
|
|
throw new \InvalidArgumentException($this->__('Invalid User ID.')); |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
$form = $this->createForm('Zikula\GroupsModule\Form\Type\RemoveUserType', [ |
|
203
|
|
|
'gid' => $gid, |
|
204
|
|
|
'uid' => $uid |
|
205
|
|
|
], [ |
|
206
|
|
|
'translator' => $this->get('translator.default') |
|
207
|
|
|
]); |
|
208
|
|
|
|
|
209
|
|
|
if ($form->handleRequest($request)->isValid()) { |
|
210
|
|
View Code Duplication |
if ($form->get('remove')->isClicked()) { |
|
|
|
|
|
|
211
|
|
|
$user->removeGroup($group); |
|
212
|
|
|
$this->get('doctrine')->getManager()->flush(); |
|
213
|
|
|
$this->addFlash('status', $this->__('Done! The user was removed from the group.')); |
|
214
|
|
|
$removeUserEvent = new GenericEvent(null, ['gid' => $gid, 'uid' => $uid]); |
|
215
|
|
|
$this->get('event_dispatcher')->dispatch(GroupEvents::GROUP_REMOVE_USER, $removeUserEvent); |
|
216
|
|
|
} |
|
217
|
|
|
if ($form->get('cancel')->isClicked()) { |
|
218
|
|
|
$this->addFlash('status', $this->__('Operation cancelled.')); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
return $this->redirectToRoute('zikulagroupsmodule_membership_adminlist', ['gid' => $group->getGid()]); |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
return [ |
|
225
|
|
|
'form' => $form->createView(), |
|
226
|
|
|
'group' => $group, |
|
227
|
|
|
'uname' => $user->getUname() |
|
228
|
|
|
]; |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
/** |
|
232
|
|
|
* Process request by current user to leave a group |
|
233
|
|
|
* @Route("/leave/{gid}", requirements={"gid" = "^[1-9]\d*$"}) |
|
234
|
|
|
* @param GroupEntity $group |
|
235
|
|
|
* @return RedirectResponse |
|
236
|
|
|
*/ |
|
237
|
|
|
public function leaveAction(GroupEntity $group) |
|
238
|
|
|
{ |
|
239
|
|
|
if (!$this->hasPermission('ZikulaGroupsModule::', '::', ACCESS_OVERVIEW)) { |
|
240
|
|
|
throw new AccessDeniedException(); |
|
241
|
|
|
} |
|
242
|
|
|
$currentUserApi = $this->get('zikula_users_module.current_user'); |
|
243
|
|
|
if (!$currentUserApi->isLoggedIn()) { |
|
244
|
|
|
throw new AccessDeniedException($this->__('Sorry! You must be logged in before you can leave a group.')); |
|
245
|
|
|
} |
|
246
|
|
|
/** @var UserEntity $userEntity */ |
|
247
|
|
|
$userEntity = $this->get('zikula_users_module.user_repository')->find($currentUserApi->get('uid')); |
|
248
|
|
|
$userEntity->removeGroup($group); |
|
249
|
|
|
$this->get('doctrine')->getManager()->flush(); |
|
250
|
|
|
$this->addFlash('success', $this->__f('Left the "%group" group', ['%group' => $group->getName()])); |
|
251
|
|
|
// Let other modules know that we have updated a group. |
|
252
|
|
|
$removeUserEvent = new GenericEvent(['gid' => $group->getGid(), 'uid' => $userEntity->getUid()]); |
|
253
|
|
|
$this->get('event_dispatcher')->dispatch(GroupEvents::GROUP_REMOVE_USER, $removeUserEvent); |
|
254
|
|
|
|
|
255
|
|
|
return $this->redirectToRoute('zikulagroupsmodule_group_list'); |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
/** |
|
259
|
|
|
* Called from UsersModule/Resources/public/js/Zikula.Users.Admin.View.js |
|
260
|
|
|
* to populate a username search |
|
261
|
|
|
* |
|
262
|
|
|
* @Route("/admin/getusersbyfragmentastable", options={"expose"=true}) |
|
263
|
|
|
* @Method("POST") |
|
264
|
|
|
* @param Request $request |
|
265
|
|
|
* @return Response |
|
266
|
|
|
*/ |
|
267
|
|
|
public function getUsersByFragmentAsTableAction(Request $request) |
|
268
|
|
|
{ |
|
269
|
|
|
if (!$this->hasPermission('ZikulaGroupsodule', '::', ACCESS_EDIT)) { |
|
270
|
|
|
return new PlainResponse(''); |
|
271
|
|
|
} |
|
272
|
|
|
$fragment = $request->request->get('fragment'); |
|
273
|
|
|
$filter = [ |
|
274
|
|
|
'activated' => ['operator' => 'notIn', 'operand' => [ |
|
275
|
|
|
UsersConstant::ACTIVATED_PENDING_REG, |
|
276
|
|
|
UsersConstant::ACTIVATED_PENDING_DELETE |
|
277
|
|
|
]], |
|
278
|
|
|
'uname' => ['operator' => 'like', 'operand' => "$fragment%"] |
|
|
|
|
|
|
279
|
|
|
]; |
|
280
|
|
|
$users = $this->get('zikula_users_module.user_repository')->query($filter); |
|
281
|
|
|
|
|
282
|
|
|
return $this->render('@ZikulaGroupsModule/Membership/userlist.html.twig', [ |
|
283
|
|
|
'users' => $users, |
|
284
|
|
|
'gid' => $request->get('gid'), |
|
285
|
|
|
'csrfToken' => $request->get('csrfToken') |
|
286
|
|
|
], new PlainResponse()); |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
private function getSpecificGroupMessage($groupTypeIsPrivate, $groupTypeIsCore, $groupStateIsClosed, $groupCountIsLimit, $alreadyGroupMember) |
|
290
|
|
|
{ |
|
291
|
|
|
$messages = []; |
|
292
|
|
|
$messages[] = $this->__('Sorry!, You cannot apply to join the requested group'); |
|
293
|
|
|
if ($groupTypeIsPrivate) { |
|
294
|
|
|
$messages[] = $this->__('This group is a private group'); |
|
295
|
|
|
} |
|
296
|
|
|
if ($groupTypeIsCore) { |
|
297
|
|
|
$messages[] = $this->__('This group is a core-only group'); |
|
298
|
|
|
} |
|
299
|
|
|
if ($groupStateIsClosed) { |
|
300
|
|
|
$messages[] = $this->__('This group is closed.'); |
|
301
|
|
|
} |
|
302
|
|
|
if ($groupCountIsLimit) { |
|
303
|
|
|
$messages[] = $this->__('This group is has reached its membership limit.'); |
|
304
|
|
|
} |
|
305
|
|
|
if ($alreadyGroupMember) { |
|
306
|
|
|
$messages[] = $this->__('You are already a member of this group.'); |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
return implode('<br>', $messages); |
|
310
|
|
|
} |
|
311
|
|
|
} |
|
312
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.