]> Raphaƫl G. Git Repositories - airbundle/blob - Controller/SnippetController.php
Use checker member for isGranted call
[airbundle] / Controller / SnippetController.php
1 <?php
2
3 namespace Rapsys\AirBundle\Controller;
4
5 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
6 use Symfony\Component\Filesystem\Filesystem;
7 use Symfony\Component\HttpFoundation\File\Exception\FileException;
8 use Symfony\Component\HttpFoundation\Request;
9 use Symfony\Component\HttpFoundation\Response;
10 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
11 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
12 use Symfony\Component\Routing\RequestContext;
13
14 use Rapsys\AirBundle\Entity\Location;
15 use Rapsys\AirBundle\Entity\Snippet;
16 use Rapsys\AirBundle\Entity\User;
17
18 class SnippetController extends DefaultController {
19 /**
20 * Add snippet
21 *
22 * @desc Persist snippet in database
23 *
24 * @param Request $request The request instance
25 *
26 * @return Response The rendered view or redirection
27 *
28 * @throws \RuntimeException When user has not at least guest role
29 */
30 public function add(Request $request) {
31 //Prevent non-guest to access here
32 $this->denyAccessUnlessGranted('ROLE_GUEST', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Guest')]));
33
34 //Create SnippetType form
35 $form = $this->container->get('form.factory')->createNamed(
36 //Set name
37 'snipped_'.$request->getLocale().'_'.$request->get('location'),
38 //Set type
39 'Rapsys\AirBundle\Form\SnippetType',
40 //Set data
41 null,
42 //Set options
43 [
44 //Set the action
45 'action' => $this->generateUrl('rapsys_air_snippet_add', ['location' => $request->get('location')]),
46 //Set the form attribute
47 'attr' => []
48 ]
49 );
50
51 //Refill the fields in case of invalid form
52 $form->handleRequest($request);
53
54 //Prevent creating snippet for other user unless admin
55 if ($form->get('user')->getData() !== $this->getUser()) {
56 //Prevent non-admin to access here
57 $this->denyAccessUnlessGranted('ROLE_ADMIN', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Admin')]));
58 }
59
60 //Handle invalid form
61 if (!$form->isSubmitted() || !$form->isValid()) {
62 //Set section
63 $section = $this->translator->trans('Snippet add');
64
65 //Set title
66 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
67
68 //Render the view
69 return $this->render('@RapsysAir/snippet/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+$this->context);
70 }
71
72 //Get doctrine
73 $doctrine = $this->getDoctrine();
74
75 //Get manager
76 $manager = $doctrine->getManager();
77
78 //Get snippet
79 $snippet = $form->getData();
80
81 //Set created
82 $snippet->setCreated(new \DateTime('now'));
83
84 //Set updated
85 $snippet->setUpdated(new \DateTime('now'));
86
87 //Queue snippet save
88 $manager->persist($snippet);
89
90 //Flush to get the ids
91 $manager->flush();
92
93 //Add notice
94 $this->addFlash('notice', $this->translator->trans('Snippet in %locale% %location% for %user% created', ['%locale%' => $snippet->getLocale(), '%location%' => $this->translator->trans('at '.$snippet->getLocation()), '%user%' => $snippet->getUser()]));
95
96 //Extract and process referer
97 if ($referer = $request->headers->get('referer')) {
98 //Create referer request instance
99 $req = Request::create($referer);
100
101 //Get referer path
102 $path = $req->getPathInfo();
103
104 //Get referer query string
105 $query = $req->getQueryString();
106
107 //Remove script name
108 $path = str_replace($request->getScriptName(), '', $path);
109
110 //Try with referer path
111 try {
112 //Save old context
113 $oldContext = $this->router->getContext();
114
115 //Force clean context
116 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
117 $this->router->setContext(new RequestContext());
118
119 //Retrieve route matching path
120 $route = $this->router->match($path);
121
122 //Reset context
123 $this->router->setContext($oldContext);
124
125 //Clear old context
126 unset($oldContext);
127
128 //Extract name
129 $name = $route['_route'];
130
131 //Remove route and controller from route defaults
132 unset($route['_route'], $route['_controller']);
133
134 //Check if snippet view route
135 if ($name == 'rapsys_air_user_view' && !empty($route['id'])) {
136 //Replace id
137 $route['id'] = $snippet->getUser()->getId();
138 //Other routes
139 } else {
140 //Set snippet
141 $route['snippet'] = $snippet->getId();
142 }
143
144 //Generate url
145 return $this->redirectToRoute($name, $route);
146 //No route matched
147 } catch(MethodNotAllowedException|ResourceNotFoundException $e) {
148 //Unset referer to fallback to default route
149 unset($referer);
150 }
151 }
152
153 //Redirect to cleanup the form
154 return $this->redirectToRoute('rapsys_air', ['snippet' => $snippet->getId()]);
155 }
156
157 /**
158 * Edit snippet
159 *
160 * @desc Persist snippet in database
161 *
162 * @param Request $request The request instance
163 *
164 * @return Response The rendered view or redirection
165 *
166 * @throws \RuntimeException When user has not at least guest role
167 */
168 public function edit(Request $request, $id) {
169 //Prevent non-guest to access here
170 $this->denyAccessUnlessGranted('ROLE_GUEST', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Guest')]));
171
172 //Get doctrine
173 $doctrine = $this->getDoctrine();
174
175 //Get snippet
176 if (empty($snippet = $doctrine->getRepository(Snippet::class)->findOneById($id))) {
177 throw $this->createNotFoundException($this->translator->trans('Unable to find snippet: %id%', ['%id%' => $id]));
178 }
179
180 //Create SnippetType form
181 $form = $this->container->get('form.factory')->createNamed(
182 //Set name
183 'snipped_'.$request->getLocale().'_'.$snippet->getLocation()->getId(),
184 //Set type
185 'Rapsys\AirBundle\Form\SnippetType',
186 //Set data
187 $snippet,
188 //Set options
189 [
190 //Set the action
191 'action' => $this->generateUrl('rapsys_air_snippet_edit', ['id' => $id]),
192 //Set the form attribute
193 'attr' => []
194 ]
195 );
196
197 //Refill the fields in case of invalid form
198 $form->handleRequest($request);
199
200 //Prevent creating snippet for other user unless admin
201 if ($form->get('user')->getData() !== $this->getUser()) {
202 //Prevent non-admin to access here
203 $this->denyAccessUnlessGranted('ROLE_ADMIN', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Admin')]));
204 }
205
206 //Handle invalid form
207 if (!$form->isSubmitted() || !$form->isValid()) {
208 //Set section
209 $section = $this->translator->trans('Snippet %id%', ['%id%' => $id]);
210
211 //Set title
212 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
213
214 //Render the view
215 return $this->render('@RapsysAir/snippet/edit.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'form' => $form->createView()]+$this->context);
216 }
217
218 //With image
219 //TODO: add delete button ???
220 if ($image = $form->get('image')->getData()) {
221 //Get public path
222 #$public = $this->container->get('kernel')->getBundle('RapsysAirBundle')->getPath().'/Resources/public';
223 #$public = $this->container->get('kernel')->locateResource('@RapsysAirBundle/Resources/public');
224 $public = $this->getPublicPath();
225
226 //Create imagick object
227 $imagick = new \Imagick();
228
229 //Read image
230 $imagick->readImage($image->getRealPath());
231
232 //Set destination
233 //XXX: uploaded path location/<userId>/<locationId>.png and session image location/<userId>/<locationId>/<sessionId>.jpeg
234 //XXX: default path location/default.png and session location/default/<sessionId>.jpeg
235 $destination = $public.'/location/'.$snippet->getUser()->getId().'/'.$snippet->getLocation()->getId().'.png';
236
237 //Check target directory
238 if (!is_dir($dir = dirname($destination))) {
239 //Create filesystem object
240 $filesystem = new Filesystem();
241
242 try {
243 //Create dir
244 //XXX: set as 0775, symfony umask (0022) will reduce rights (0755)
245 $filesystem->mkdir($dir, 0775);
246 } catch (IOExceptionInterface $e) {
247 //Throw error
248 throw new \Exception(sprintf('Output directory "%s" do not exists and unable to create it', $dir), 0, $e);
249 }
250 }
251
252 //Save image
253 if (!$imagick->writeImage($destination)) {
254 //Throw error
255 throw new \Exception(sprintf('Unable to write image "%s"', $destination));
256 }
257 }
258
259 //Get manager
260 $manager = $doctrine->getManager();
261
262 //Set updated
263 $snippet->setUpdated(new \DateTime('now'));
264
265 //Queue snippet save
266 $manager->persist($snippet);
267
268 //Flush to get the ids
269 $manager->flush();
270
271 //Add notice
272 $this->addFlash('notice', $this->translator->trans('Snippet %id% in %locale% %location% for %user% updated', ['%id%' => $id, '%locale%' => $snippet->getLocale(), '%location%' => $this->translator->trans('at '.$snippet->getLocation()), '%user%' => $snippet->getUser()]));
273
274 //Extract and process referer
275 if ($referer = $request->headers->get('referer')) {
276 //Create referer request instance
277 $req = Request::create($referer);
278
279 //Get referer path
280 $path = $req->getPathInfo();
281
282 //Get referer query string
283 $query = $req->getQueryString();
284
285 //Remove script name
286 $path = str_replace($request->getScriptName(), '', $path);
287
288 //Try with referer path
289 try {
290 //Save old context
291 $oldContext = $this->router->getContext();
292
293 //Force clean context
294 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
295 $this->router->setContext(new RequestContext());
296
297 //Retrieve route matching path
298 $route = $this->router->match($path);
299
300 //Reset context
301 $this->router->setContext($oldContext);
302
303 //Clear old context
304 unset($oldContext);
305
306 //Extract name
307 $name = $route['_route'];
308
309 //Remove route and controller from route defaults
310 unset($route['_route'], $route['_controller']);
311
312 //Check if snippet view route
313 if ($name == 'rapsys_air_user_view' && !empty($route['id'])) {
314 //Replace id
315 $route['id'] = $snippet->getUser()->getId();
316 //Other routes
317 } else {
318 //Set snippet
319 $route['snippet'] = $snippet->getId();
320 }
321
322 //Generate url
323 return $this->redirectToRoute($name, $route);
324 //No route matched
325 } catch(MethodNotAllowedException|ResourceNotFoundException $e) {
326 //Unset referer to fallback to default route
327 unset($referer);
328 }
329 }
330
331 //Redirect to cleanup the form
332 return $this->redirectToRoute('rapsys_air', ['snippet' => $snippet->getId()]);
333 }
334 }