]> Raphaël G. Git Repositories - blogbundle/blob - Controller/KeywordController.php
Add security member
[blogbundle] / Controller / KeywordController.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys BlogBundle package.
5 *
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
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 Rapsys\BlogBundle\Controller;
13
14 use Symfony\Component\HttpFoundation\Request;
15 use Symfony\Component\HttpFoundation\Response;
16
17 use Rapsys\BlogBundle\Entity\Article;
18 use Rapsys\BlogBundle\Entity\Keyword;
19
20 /**
21 * {@inheritdoc}
22 */
23 class KeywordController extends AbstractController {
24 /**
25 * The keyword index
26 *
27 * Display keywords
28 *
29 * @param Request $request The request instance
30 * @return Response The rendered view
31 */
32 public function index(Request $request): Response {
33 //With keywords
34 if ($count = $this->doctrine->getRepository(Keyword::class)->findCountAsInt()) {
35 //Negative page or over page
36 if (($page = (int) $request->get('page', 0)) < 0 || $page > $count / $this->limit) {
37 //Throw 404
38 throw $this->createNotFoundException($this->translator->trans('Unable to find keywords (page: %page%)', ['%page%' => $page]));
39 }
40
41 //Without keywords
42 if (empty($this->context['keywords'] = $this->doctrine->getRepository(Keyword::class)->findAllAsArray($page, $this->limit))) {
43 //Throw 404
44 throw $this->createNotFoundException($this->translator->trans('Unable to find keywords'));
45 }
46
47 //With prev link
48 if ($page > 0) {
49 //Set keywords older
50 $this->context['head']['prev'] = $this->context['keywords_prev'] = $this->generateUrl($request->attributes->get('_route'), ['page' => $page - 1]+$request->attributes->get('_route_params'));
51 }
52
53 //With next link
54 if ($count > ($page + 1) * $this->limit) {
55 //Set keywords newer
56 $this->context['head']['next'] = $this->context['keywords_next'] = $this->generateUrl($request->attributes->get('_route'), ['page' => $page + 1]+$request->attributes->get('_route_params'));
57 }
58
59 //Set modified
60 $this->modified = max(array_map(function ($v) { return $v['modified']; }, $this->context['keywords']));
61 //Without keywords
62 } else {
63 //Set empty keywords
64 $this->context['keywords'] = [];
65
66 //Set empty modified
67 $this->modified = new \DateTime('-1 year');
68 }
69
70 //Create response
71 $response = new Response();
72
73 //With logged user
74 if ($this->checker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
75 //Set last modified
76 $response->setLastModified(new \DateTime('-1 year'));
77
78 //Set as private
79 $response->setPrivate();
80 //Without logged user
81 } else {
82 //Set etag
83 //XXX: only for public to force revalidation by last modified
84 $response->setEtag(md5(serialize($this->context['keywords'])));
85
86 //Set last modified
87 $response->setLastModified($this->modified);
88
89 //Set as public
90 $response->setPublic();
91
92 //Without role and modification
93 if ($response->isNotModified($request)) {
94 //Return 304 response
95 return $response;
96 }
97 }
98
99 //Set keywords
100 $this->context['head']['keywords'] = implode(
101 ', ',
102 //Use closure to extract each unique article keywords sorted
103 (function ($t) {
104 //Return array
105 $r = [];
106
107 //Iterate on keywords
108 foreach($t as $k) {
109 //Set keyword
110 $r[$k['title']] = $k['title'];
111 }
112
113 //Sort array
114 sort($r);
115
116 //Return array
117 return $r;
118 })($this->context['keywords'])
119 );
120
121 //Set title
122 $this->context['title'] = $this->translator->trans('Keywords list');
123
124 //Set description
125 $this->context['description'] = $this->translator->trans('Welcome to raphaël\'s developer diary keyword listing');
126
127 //Render the view
128 return $this->render('@RapsysBlog/keyword/index.html.twig', $this->context, $response);
129 }
130
131 /**
132 * The keyword view
133 *
134 * Display keyword articles
135 *
136 * @param Request $request The request instance
137 * @param integer $id The keyword id
138 * @param ?string $slug The keyword slug
139 * @return Response The rendered view
140 */
141 public function view(Request $request, int $id, ?string $slug): Response {
142 //Without keyword
143 if (empty($this->context['keyword'] = $this->doctrine->getRepository(Keyword::class)->findByIdAsArray($id))) {
144 //Throw 404
145 throw $this->createNotFoundException($this->translator->trans('Unable to find keyword: %id%', ['%id%' => $id]));
146 }
147
148 //With invalid slug
149 if ($slug !== $this->context['keyword']['slug']) {
150 //Redirect on correctly spelled keyword
151 return $this->redirectToRoute('rapsys_blog_keyword_view', ['id' => $this->context['keyword']['id'], 'slug' => $this->context['keyword']['slug']], Response::HTTP_MOVED_PERMANENTLY);
152 }
153
154 //Set modified
155 $this->modified = $this->context['keyword']['modified'];
156
157 //Create response
158 $response = new Response();
159
160 //With logged user
161 if ($this->checker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
162 //Set last modified
163 $response->setLastModified(new \DateTime('-1 year'));
164
165 //Set as private
166 $response->setPrivate();
167 //Without logged user
168 } else {
169 //Set etag
170 //XXX: only for public to force revalidation by last modified
171 $response->setEtag(md5(serialize($this->context['keyword'])));
172
173 //Set last modified
174 $response->setLastModified($this->modified);
175
176 //Set as public
177 $response->setPublic();
178
179 //Without role and modification
180 if ($response->isNotModified($request)) {
181 //Return 304 response
182 return $response;
183 }
184 }
185
186 //Set keywords
187 $this->context['head']['keywords'] = implode(
188 ', ',
189 //Use closure to extract each unique article keywords sorted
190 (function ($t) {
191 //Return array
192 $r = [];
193
194 //Iterate on articles
195 foreach($t as $a) {
196 //Non empty keywords
197 if (!empty($a['keywords'])) {
198 //Iterate on keywords
199 foreach($a['keywords'] as $k) {
200 //Set keyword
201 $r[$k['title']] = $k['title'];
202 }
203 }
204 }
205
206 //Sort array
207 sort($r);
208
209 //Return array
210 return $r;
211 })($this->context['keyword']['articles'])
212 );
213
214 //Set title
215 $this->context['title'] = $this->context['keyword']['title'];
216
217 //Set description
218 $this->context['description'] = $this->context['keyword']['description'];
219
220 //Render the view
221 return $this->render('@RapsysBlog/keyword/view.html.twig', $this->context, $response);
222 }
223 }