Completed
Pull Request — master (#177)
by olivier
15:57
created

BadgeCompletionController::indexAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
dl 9
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
namespace Badger\Bundle\GameBundle\Controller;
4
5
use Badger\Bundle\GameBundle\Entity\VotableItem;
6
use Badger\Bundle\GameBundle\Event\BadgeUnlockEvent;
7
use Badger\Bundle\GameBundle\GameEvents;
8
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
9
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
10
use Symfony\Component\HttpFoundation\RedirectResponse;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
15
16
/**
17
 * @author  Adrien Pétremann <[email protected]>
18
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
19
 */
20
class BadgeCompletionController extends Controller
21
{
22
    /**
23
     * Lists all pending badge completions.
24
     *
25
     * @return Response
26
     */
27 View Code Duplication
    public function indexAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
28
    {
29
        $pendingCompletions = $this->get('badger.game.repository.badge_completion')
30
            ->findBy(['pending' => 1]);
31
32
        return $this->render('@Game/claimed-badges/index.html.twig', [
33
            'pendingCompletions' => $pendingCompletions
34
        ]);
35
    }
36
37
    /**
38
     * Reject a badge completion by removing it from the database.
39
     *
40
     * @param string $id
41
     *
42
     * @return RedirectResponse
43
     */
44
    public function rejectAction($id)
45
    {
46
        $pendingCompletion = $this->get('badger.game.repository.badge_completion')
47
            ->findOneBy(['id' => $id, 'pending' => 1]);
48
49
        if (null === $pendingCompletion) {
50
            throw new NotFoundHttpException(sprintf('No pending BadgeCompletion entity with id %s', $id));
51
        }
52
53
        $badgeTitle = $pendingCompletion->getBadge()->getTitle();
54
        $username = $pendingCompletion->getUser()->getUsername();
55
56
        $badgeCompletionRemover = $this->get('badger.game.remover.badge_completion');
57
        $badgeCompletionRemover->remove($pendingCompletion);
58
59
        $event = new BadgeUnlockEvent($pendingCompletion);
60
        $this->get('event_dispatcher')->dispatch(GameEvents::BADGE_HAS_BEEN_REJECTED, $event);
61
62
        $this->addFlash('notice', sprintf(
63
            'Successfully rejected the claimed badge "%s" for %s!',
64
            $badgeTitle,
65
            $username
66
        ));
67
68
        return $this->redirectToRoute('admin_claimed_badge_index');
69
    }
70
71
    /**
72
     * Set the badge as votable.
73
     *
74
     * @param string $id
75
     *
76
     * @return RedirectResponse
77
     */
78
    public function sendToTheCouncilAction($id)
79
    {
80
        $pendingCompletion = $this->get('badger.game.repository.badge_completion')
81
            ->findOneBy(['id' => $id, 'pending' => 1]);
82
83
        if (null === $pendingCompletion) {
84
            throw new NotFoundHttpException(sprintf('No pending BadgeCompletion entity with id %s', $id));
85
        }
86
87
        $votableItem = new VotableItem();
88
        $votableItem->setBadgeCompletion($pendingCompletion);
89
90
        try {
91
            $this->get('badger.game.saver.votable_item')->save($votableItem);
92
        } catch (UniqueConstraintViolationException $e) {
93
            $this->addFlash('warning', sprintf(
94
                'The badge "%s" is already submitted to vote',
95
                $pendingCompletion->getBadge()->getTitle()
96
            ));
97
98
            return $this->redirectToRoute('admin_claimed_badge_index');
99
        }
100
101
        $this->addFlash('notice', sprintf(
102
            'Successfully send the badge "%s" to the people vote! #democracy',
103
            $pendingCompletion->getBadge()->getTitle()
104
        ));
105
106
        return $this->redirectToRoute('admin_claimed_badge_index');
107
    }
108
109
    /**
110
     * Accept a badge completion.
111
     *
112
     * @param string $id
113
     *
114
     * @return RedirectResponse
115
     */
116
    public function acceptAction($id)
117
    {
118
        $pendingCompletion = $this->get('badger.game.repository.badge_completion')
119
            ->findOneBy(['id' => $id, 'pending' => 1]);
120
121
        if (null === $pendingCompletion) {
122
            throw new NotFoundHttpException(sprintf('No pending BadgeCompletion entity with id %s', $id));
123
        }
124
125
        $user = $pendingCompletion->getUser();
126
        $badge = $pendingCompletion->getBadge();
127
128
        $pendingCompletion->setPending(false);
129
        $pendingCompletion->setCompletionDate(new \DateTime());
130
131
        $errors = $this->get('validator')->validate($pendingCompletion);
132
133 View Code Duplication
        if (0 === count($errors)) {
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...
134
            $this->get('badger.game.saver.badge_completion')->save($pendingCompletion);
135
136
            $event = new BadgeUnlockEvent($pendingCompletion);
137
            $this->get('event_dispatcher')->dispatch(GameEvents::USER_UNLOCKED_BADGE, $event);
138
139
            $this->addFlash('notice', sprintf(
140
                '%s successfully unlocked the badge "%s"!',
141
                $user->getUsername(),
142
                $badge->getTitle()
143
            ));
144
        } else {
145
            $this->addFlash('error', (string) $errors);
146
        }
147
148
        return $this->redirectToRoute('admin_claimed_badge_index');
149
    }
150
151
    /**
152
     * Give a badge to a user directly by creating a completed badge completion.
153
     *
154
     * @param Request $request
155
     *
156
     * @return Response
157
     */
158
    public function giveAction(Request $request)
159
    {
160
        $badgeRepository = $this->get('badger.game.repository.badge');
161
162
        if ('POST' === $request->getMethod()) {
163
            $validator = $this->get('validator');
164
165
            $user = $this->get('fos_user.user_manager')->findUserByUsername($request->get('user'));
166
            $badge = $badgeRepository->find($request->get('badge'));
167
168
            $token = new UsernamePasswordToken($user, 'none', 'none', $user->getRoles());
169
            $isUnlockable = $this->get('security.access.public_decision_manager')->decide($token, ['view'], $badge);
170
171 View Code Duplication
            if (!$isUnlockable) {
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...
172
                $this->addFlash(
173
                    'error',
174
                    sprintf('%s does not have access to badge "%s"', $user->getUsername(), $badge->getTitle())
175
                );
176
177
                return $this->redirectToRoute('admin_unlocked_badge_give');
178
            }
179
180
            $badgeCompletion = $this->get('badger.game.repository.badge_completion')
181
                ->findOneBy([
182
                    'user' => $user,
183
                    'badge' => $badge
184
                ]);
185
186
            if (null === $badgeCompletion) {
187
                $badgeCompletion = $this->get('badger.game.badge_completion.factory')->create($user, $badge);
188
            }
189
190 View Code Duplication
            if (!$badgeCompletion->isPending()) {
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...
191
                $this->addFlash(
192
                    'error',
193
                    sprintf('%s already has the badge "%s"', $user->getUsername(), $badge->getTitle())
194
                );
195
196
                return $this->redirectToRoute('admin_unlocked_badge_give');
197
            }
198
199
            $badgeCompletion->setPending(false);
200
            $badgeCompletion->setCompletionDate(new \DateTime());
201
202
            $errors = $validator->validate($badgeCompletion);
203
204 View Code Duplication
            if (0 === count($errors)) {
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...
205
                $this->get('badger.game.saver.badge_completion')->save($badgeCompletion);
206
207
                $event = new BadgeUnlockEvent($badgeCompletion);
208
                $this->get('event_dispatcher')->dispatch(GameEvents::USER_UNLOCKED_BADGE, $event);
209
210
                $this->addFlash('notice', sprintf(
211
                    '%s successfully received the badge "%s"!',
212
                    $user->getUsername(),
213
                    $badge->getTitle()
214
                ));
215
            } else {
216
                $this->addFlash('error', (string) $errors);
217
            }
218
        }
219
220
        $badges = $badgeRepository->findAll();
221
        $usernames = $this->get('badger.user.repository.user')->getAllUsernames();
222
223
        return $this->render('@Game/unlocked-badges/give.html.twig', [
224
            'badges' => json_encode($badges),
225
            'users'  => json_encode($usernames)
226
        ]);
227
    }
228
229
    /**
230
     * Remove a badge from a user by removing the badge completion.
231
     *
232
     * @param Request $request
233
     *
234
     * @return Response
235
     */
236
    public function removeAction(Request $request)
237
    {
238
        $badgeRepository = $this->get('badger.game.repository.badge');
239
240
        if ('POST' === $request->getMethod()) {
241
            $user = $this->container->get('fos_user.user_manager')->findUserByUsername($request->get('user'));
242
            $badge = $badgeRepository->findOneById($request->get('badge'));
243
244
            $badgeCompletion = $this->get('badger.game.repository.badge_completion')
245
                ->findOneBy([
246
                    'user' => $user,
247
                    'badge' => $badge,
248
                    'pending' => false
249
                ]);
250
251 View Code Duplication
            if (null === $badgeCompletion) {
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...
252
                $this->addFlash(
253
                    'error',
254
                    sprintf('%s has no badge named "%s"', $user->getUsername(), $badge->getTitle())
255
                );
256
257
                return $this->redirectToRoute('admin_unlocked_badge_remove');
258
            }
259
260
            $badgeCompletionRemover = $this->get('badger.game.remover.badge_completion');
261
            $badgeCompletionRemover->remove($badgeCompletion);
262
263
            $event = new BadgeUnlockEvent($badgeCompletion);
264
            $this->get('event_dispatcher')->dispatch(GameEvents::BADGE_HAS_BEEN_REMOVED, $event);
265
266
            $this->addFlash('notice', sprintf(
267
                'Successfully removed the badge "%s" to the user "%s"!',
268
                $badge->getTitle(),
269
                $user->getUsername()
270
            ));
271
        }
272
273
        $badges = $badgeRepository->findAll();
274
        $usernames = $this->get('badger.user.repository.user')->getAllUsernames();
275
276
        return $this->render('@Game/unlocked-badges/remove.html.twig', [
277
            'badges' => json_encode($badges),
278
            'users'  => json_encode($usernames)
279
        ]);
280
    }
281
}
282