Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
8 / 8 |
CRAP | |
98.39% |
61 / 62 |
DefaultController | |
100.00% |
1 / 1 |
|
100.00% |
8 / 8 |
13 | |
100.00% |
60 / 60 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
indexAction | |
100.00% |
1 / 1 |
2 | |
100.00% |
14 / 14 |
|||
getVariables | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
getTweetsVars | |
100.00% |
1 / 1 |
2 | |
100.00% |
13 / 13 |
|||
getLastTweetIdFromCookie | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
createCookie | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
resetCookieAction | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
deleteLessThanAction | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
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 | public function __construct(EntityManagerInterface $entityManager) |
29 | { |
30 | $this->entityManager = $entityManager; |
31 | } |
32 | |
33 | public function indexAction(Request $request, ?int $firstTweetId): Response |
34 | { |
35 | /** @var TweetRepository $tweetRepository */ |
36 | $tweetRepository = $this->entityManager |
37 | ->getRepository(Tweet::class); |
38 | |
39 | $this->tweetRepository = $tweetRepository; |
40 | |
41 | $tweets = $this->tweetRepository |
42 | ->getWithUsersAndMedias($firstTweetId); |
43 | |
44 | $variables = $this->getVariables($request, $tweets, $firstTweetId); |
45 | |
46 | $response = $this->render( |
47 | '@AsyncTweets/Default/index.html.twig', |
48 | [ |
49 | 'tweets' => $tweets, |
50 | 'vars' => $variables, |
51 | ] |
52 | ); |
53 | |
54 | if (!is_null($variables['cookie'])) { |
55 | /** @var Cookie $cookie */ |
56 | $cookie = $variables['cookie']; |
57 | $response->headers->setCookie($cookie); |
58 | } |
59 | |
60 | return $response; |
61 | } |
62 | |
63 | /** |
64 | * @param array<Tweet> $tweets |
65 | * |
66 | * @return array<Cookie|int|string|null> |
67 | */ |
68 | private function getVariables(Request $request, array $tweets, ?int $firstTweetId): array |
69 | { |
70 | $vars = [ |
71 | 'first' => $firstTweetId, |
72 | 'previous' => null, |
73 | 'next' => null, |
74 | 'number' => 0, |
75 | 'cookieId' => $this->getLastTweetIdFromCookie($request), |
76 | // No cookie by default |
77 | 'cookie' => null, |
78 | ]; |
79 | |
80 | if (count($tweets) > 0) { |
81 | $vars = $this->getTweetsVars($tweets, $vars); |
82 | } |
83 | |
84 | 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 | private function getTweetsVars(array $tweets, array $vars): array |
96 | { |
97 | /** @var int $firstTweetId */ |
98 | $firstTweetId = $tweets[0]->getId(); |
99 | |
100 | $vars['previous'] = $this->tweetRepository |
101 | ->getPreviousTweetId($firstTweetId); |
102 | $vars['next'] = $this->tweetRepository |
103 | ->getNextTweetId($firstTweetId); |
104 | |
105 | // Only update the cookie if the last Tweet Id is bigger than |
106 | // the one in the cookie |
107 | if ($firstTweetId > $vars['cookieId']) { |
108 | $vars['cookie'] = $this->createCookie($firstTweetId); |
109 | $vars['cookieId'] = $firstTweetId; |
110 | } |
111 | |
112 | /** @var int */ |
113 | $cookieId = $vars['cookieId']; |
114 | $vars['number'] = $this->tweetRepository |
115 | ->countPendingTweets($cookieId); |
116 | |
117 | $vars['first'] = $firstTweetId; |
118 | |
119 | return $vars; |
120 | } |
121 | |
122 | private function getLastTweetIdFromCookie(Request $request): ?int |
123 | { |
124 | if ($request->cookies->has('lastTweetId')) { |
125 | return (int) $request->cookies->get('lastTweetId'); |
126 | } |
127 | |
128 | return null; |
129 | } |
130 | |
131 | private function createCookie(int $firstTweetId): Cookie |
132 | { |
133 | $nextYear = new \DateTime('now'); |
134 | $nextYear->add(new \DateInterval('P1Y')); |
135 | |
136 | // Set last Tweet Id |
137 | $cookie = new Cookie( |
138 | 'lastTweetId', |
139 | (string) $firstTweetId, |
140 | $nextYear->format('U') |
141 | ); |
142 | |
143 | return $cookie; |
144 | } |
145 | |
146 | public function resetCookieAction(): RedirectResponse |
147 | { |
148 | /* @see http://www.craftitonline.com/2011/07/symfony2-how-to-set-a-cookie/ */ |
149 | $response = new RedirectResponse( |
150 | $this->generateUrl('asynctweets_homepage') |
151 | ); |
152 | |
153 | // Reset last Tweet Id |
154 | $cookie = new Cookie('lastTweetId', null); |
155 | $response->headers->setCookie($cookie); |
156 | |
157 | return $response; |
158 | } |
159 | |
160 | public function deleteLessThanAction(Request $request): RedirectResponse |
161 | { |
162 | $lastTweetId = $this->getLastTweetIdFromCookie($request); |
163 | |
164 | if (!is_null($lastTweetId)) { |
165 | /** @var TweetRepository $tweetRepository */ |
166 | $tweetRepository = $this->entityManager |
167 | ->getRepository(Tweet::class); |
168 | |
169 | $count = $tweetRepository |
170 | ->deleteAndHideTweetsLessThanId($lastTweetId); |
171 | |
172 | /** @var Session<int> $session */ |
173 | $session = $this->get('session'); |
174 | |
175 | $session->getFlashBag()->add( |
176 | 'message', |
177 | sprintf('%s tweets deleted.', $count) |
178 | ); |
179 | } |
180 | |
181 | return $this->redirect($this->generateUrl('asynctweets_homepage')); |
182 | } |
183 | } |