Passed
Push — master ( 08b227...0445a5 )
by Alexis
01:51 queued 10s
created

DefaultController   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 10
dl 0
loc 164
ccs 68
cts 68
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A indexAction() 0 29 2
A getVariables() 0 18 2
A getTweetsVars() 0 26 2
A getLastTweetIdFromCookie() 0 8 2
A createCookie() 0 14 1
A resetCookieAction() 0 13 1
A deleteLessThanAction() 0 23 2
1
<?php
2
3
namespace AlexisLefebvre\Bundle\AsyncTweetsBundle\Controller;
4
5
use AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity\Tweet;
6
use AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity\TweetRepository;
7
use Doctrine\ORM\EntityManagerInterface;
8
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseController;
9
use Symfony\Component\HttpFoundation\Cookie;
10
use Symfony\Component\HttpFoundation\RedirectResponse;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\HttpFoundation\Session\Session;
14
15
// Compatibility layer for Symfony 3.4
16
if (!class_exists('Symfony\Bundle\FrameworkBundle\Controller\Controller')) {
17
    class_alias('Symfony\Bundle\FrameworkBundle\Controller\Controller', 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController');
18
}
19
20
class DefaultController extends BaseController
21
{
22
    /** @var EntityManagerInterface */
23
    private $entityManager;
24
25
    /** @var TweetRepository */
26
    private $tweetRepository;
27
28 7
    public function __construct(EntityManagerInterface $entityManager)
29
    {
30 7
        $this->entityManager = $entityManager;
31 7
    }
32
33 7
    public function indexAction(Request $request, ?int $firstTweetId): Response
34
    {
35
        /** @var TweetRepository $tweetRepository */
36 7
        $tweetRepository = $this->entityManager
37 7
            ->getRepository(Tweet::class);
38
39 7
        $this->tweetRepository = $tweetRepository;
40
41 7
        $tweets = $this->tweetRepository
42 7
            ->getWithUsersAndMedias($firstTweetId);
43
44 7
        $variables = $this->getVariables($request, $tweets, $firstTweetId);
45
46 7
        $response = $this->render(
47 7
            '@AsyncTweets/Default/index.html.twig',
48
            [
49 7
                'tweets' => $tweets,
50 7
                'vars'   => $variables,
51
            ]
52
        );
53
54 7
        if (!is_null($variables['cookie'])) {
55
            /** @var Cookie $cookie */
56 6
            $cookie = $variables['cookie'];
57 6
            $response->headers->setCookie($cookie);
58
        }
59
60 7
        return $response;
61
    }
62
63
    /**
64
     * @param array<Tweet> $tweets
65
     *
66
     * @return array<Cookie|int|string|null>
67
     */
68 7
    private function getVariables(Request $request, array $tweets, ?int $firstTweetId): array
69
    {
70
        $vars = [
71 7
            'first'    => $firstTweetId,
72
            'previous' => null,
73
            'next'     => null,
74 7
            'number'   => 0,
75 7
            'cookieId' => $this->getLastTweetIdFromCookie($request),
76
            // No cookie by default
77
            'cookie' => null,
78
        ];
79
80 7
        if (count($tweets) > 0) {
81 6
            $vars = $this->getTweetsVars($tweets, $vars);
82
        }
83
84 7
        return $vars;
85
    }
86
87
    /**
88
     * If a Tweet is displayed, fetch data from repository.
89
     *
90
     * @param array<Tweet>                  $tweets
91
     * @param array<Cookie|int|string|null> $vars
92
     *
93
     * @return array<Cookie|int|string|null>
94
     */
95 6
    private function getTweetsVars(array $tweets, array $vars): array
96
    {
97
        /** @var int $firstTweetId */
98 6
        $firstTweetId = $tweets[0]->getId();
99
100 6
        $vars['previous'] = $this->tweetRepository
101 6
            ->getPreviousTweetId($firstTweetId);
102 6
        $vars['next'] = $this->tweetRepository
103 6
            ->getNextTweetId($firstTweetId);
104
105
        // Only update the cookie if the last Tweet Id is bigger than
106
        //  the one in the cookie
107 6
        if ($firstTweetId > $vars['cookieId']) {
108 6
            $vars['cookie'] = $this->createCookie($firstTweetId);
109 6
            $vars['cookieId'] = $firstTweetId;
110
        }
111
112
        /** @var int */
113 6
        $cookieId = $vars['cookieId'];
114 6
        $vars['number'] = $this->tweetRepository
115 6
            ->countPendingTweets($cookieId);
116
117 6
        $vars['first'] = $firstTweetId;
118
119 6
        return $vars;
120
    }
121
122 7
    private function getLastTweetIdFromCookie(Request $request): ?int
123
    {
124 7
        if ($request->cookies->has('lastTweetId')) {
125 4
            return (int) $request->cookies->get('lastTweetId');
126
        }
127
128 7
        return null;
129
    }
130
131 6
    private function createCookie(int $firstTweetId): Cookie
132
    {
133 6
        $nextYear = new \DateTime('now');
134 6
        $nextYear->add(new \DateInterval('P1Y'));
135
136
        // Set last Tweet Id
137 6
        $cookie = new Cookie(
138 6
            'lastTweetId',
139 6
            (string) $firstTweetId,
140 6
            $nextYear->format('U')
141
        );
142
143 6
        return $cookie;
144
    }
145
146 1
    public function resetCookieAction(): RedirectResponse
147
    {
148
        /* @see http://www.craftitonline.com/2011/07/symfony2-how-to-set-a-cookie/ */
149 1
        $response = new RedirectResponse(
150 1
            $this->generateUrl('asynctweets_homepage')
151
        );
152
153
        // Reset last Tweet Id
154 1
        $cookie = new Cookie('lastTweetId', null);
155 1
        $response->headers->setCookie($cookie);
156
157 1
        return $response;
158
    }
159
160 2
    public function deleteLessThanAction(Request $request): RedirectResponse
161
    {
162 2
        $lastTweetId = $this->getLastTweetIdFromCookie($request);
163
164 2
        if (!is_null($lastTweetId)) {
165
            /** @var TweetRepository $tweetRepository */
166 2
            $tweetRepository = $this->entityManager
167 2
                ->getRepository(Tweet::class);
168
169
            $count = $tweetRepository
170 2
                ->deleteAndHideTweetsLessThanId($lastTweetId);
171
172
            /** @var Session<int> $session */
0 ignored issues
show
Documentation introduced by
The doc-type Session<int> could not be parsed: Expected "|" or "end of type", but got "<" at position 7. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
173 2
            $session = $this->get('session');
174
175 2
            $session->getFlashBag()->add(
176 2
                'message',
177 2
                sprintf('%s tweets deleted.', $count)
178
            );
179
        }
180
181 2
        return $this->redirect($this->generateUrl('asynctweets_homepage'));
182
    }
183
}
184