Completed
Push — master ( ef0404...81c807 )
by Craig
23:17 queued 14:56
created

MembershipController::leaveAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 20
rs 9.4285
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 {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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 {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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%"]
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $fragment instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
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