3 namespace Rapsys\AirBundle\Controller
;
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
;
14 use Rapsys\AirBundle\Entity\Location
;
15 use Rapsys\AirBundle\Entity\Snippet
;
16 use Rapsys\AirBundle\Entity\User
;
18 class SnippetController
extends DefaultController
{
22 * Persist snippet in database
24 * @param Request $request The request instance
26 * @return Response The rendered view or redirection
28 * @throws \RuntimeException When user has not at least guest role
30 public function add(Request
$request) {
32 if (!$this->checker
->isGranted('ROLE_GUEST')) {
34 throw $this->createAccessDeniedException($this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Guest')]));
37 //Create SnippetType form
38 $form = $this->container
->get('form.factory')->createNamed(
40 'snipped_'.$request->getLocale().'_'.$request->get('location'),
42 'Rapsys\AirBundle\Form\SnippetType',
48 'action' => $this->generateUrl('rapsysair_snippet_add', ['location' => $request->get('location')]),
49 //Set the form attribute
54 //Refill the fields in case of invalid form
55 $form->handleRequest($request);
57 //Prevent creating snippet for other user unless admin
58 if ($form->get('user')->getData() !== $this->getUser()) {
60 if (!$this->checker
->isGranted('ROLE_ADMIN')) {
62 throw $this->createAccessDeniedException($this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Admin')]));
67 if (!$form->isSubmitted() || !$form->isValid()) {
69 $section = $this->translator
->trans('Snippet add');
72 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
75 return $this->render('@RapsysAir/snippet/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
79 $doctrine = $this->getDoctrine();
82 $manager = $doctrine->getManager();
85 $snippet = $form->getData();
88 $snippet->setCreated(new \
DateTime('now'));
91 $snippet->setUpdated(new \
DateTime('now'));
94 $manager->persist($snippet);
96 //Flush to get the ids
100 $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()]));
102 //Extract and process referer
103 if ($referer = $request->headers
->get('referer')) {
104 //Create referer request instance
105 $req = Request
::create($referer);
108 $path = $req->getPathInfo();
110 //Get referer query string
111 $query = $req->getQueryString();
114 $path = str_replace($request->getScriptName(), '', $path);
116 //Try with referer path
119 $oldContext = $this->router
->getContext();
121 //Force clean context
122 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
123 $this->router
->setContext(new RequestContext());
125 //Retrieve route matching path
126 $route = $this->router
->match($path);
129 $this->router
->setContext($oldContext);
135 $name = $route['_route'];
137 //Remove route and controller from route defaults
138 unset($route['_route'], $route['_controller']);
140 //Check if snippet view route
141 if ($name == 'rapsysair_user_view' && !empty($route['id'])) {
143 $route['id'] = $snippet->getUser()->getId();
147 $route['snippet'] = $snippet->getId();
151 return $this->redirectToRoute($name, $route);
153 } catch(MethodNotAllowedException
|ResourceNotFoundException
$e) {
154 //Unset referer to fallback to default route
159 //Redirect to cleanup the form
160 return $this->redirectToRoute('rapsysair', ['snippet' => $snippet->getId()]);
166 * Persist snippet in database
168 * @param Request $request The request instance
170 * @return Response The rendered view or redirection
172 * @throws \RuntimeException When user has not at least guest role
174 public function edit(Request
$request, $id) {
176 if (!$this->checker
->isGranted('ROLE_GUEST')) {
178 throw $this->createAccessDeniedException($this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Guest')]));
182 $doctrine = $this->getDoctrine();
185 if (empty($snippet = $doctrine->getRepository(Snippet
::class)->findOneById($id))) {
186 throw $this->createNotFoundException($this->translator
->trans('Unable to find snippet: %id%', ['%id%' => $id]));
189 //Create SnippetType form
190 $form = $this->container
->get('form.factory')->createNamed(
192 'snipped_'.$request->getLocale().'_'.$snippet->getLocation()->getId(),
194 'Rapsys\AirBundle\Form\SnippetType',
200 'action' => $this->generateUrl('rapsysair_snippet_edit', ['id' => $id]),
201 //Set the form attribute
206 //Refill the fields in case of invalid form
207 $form->handleRequest($request);
209 //Prevent creating snippet for other user unless admin
210 if ($form->get('user')->getData() !== $this->getUser()) {
212 if (!$this->checker
->isGranted('ROLE_ADMIN')) {
214 throw $this->createAccessDeniedException($this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Admin')]));
218 //Handle invalid form
219 if (!$form->isSubmitted() || !$form->isValid()) {
221 $section = $this->translator
->trans('Snippet %id%', ['%id%' => $id]);
224 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
227 return $this->render('@RapsysAir/snippet/edit.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
231 //TODO: add delete button ???
232 if ($image = $form->get('image')->getData()) {
234 #$public = $this->container->get('kernel')->getBundle('RapsysAirBundle')->getPath().'/Resources/public';
235 #$public = $this->container->get('kernel')->locateResource('@RapsysAirBundle/Resources/public');
236 $public = $this->getPublicPath();
238 //Create imagick object
239 $imagick = new \
Imagick();
242 $imagick->readImage($image->getRealPath());
245 //XXX: uploaded path location/<userId>/<locationId>.png and session image location/<userId>/<locationId>/<sessionId>.jpeg
246 //XXX: default path location/default.png and session location/default/<sessionId>.jpeg
247 $destination = $public.'/location/'.$snippet->getUser()->getId().'/'.$snippet->getLocation()->getId().'.png';
249 //Check target directory
250 if (!is_dir($dir = dirname($destination))) {
251 //Create filesystem object
252 $filesystem = new Filesystem();
256 //XXX: set as 0775, symfony umask (0022) will reduce rights (0755)
257 $filesystem->mkdir($dir, 0775);
258 } catch (IOExceptionInterface
$e) {
260 throw new \
Exception(sprintf('Output directory "%s" do not exists and unable to create it', $dir), 0, $e);
265 if (!$imagick->writeImage($destination)) {
267 throw new \
Exception(sprintf('Unable to write image "%s"', $destination));
272 $manager = $doctrine->getManager();
275 $snippet->setUpdated(new \
DateTime('now'));
278 $manager->persist($snippet);
280 //Flush to get the ids
284 $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()]));
286 //Extract and process referer
287 if ($referer = $request->headers
->get('referer')) {
288 //Create referer request instance
289 $req = Request
::create($referer);
292 $path = $req->getPathInfo();
294 //Get referer query string
295 $query = $req->getQueryString();
298 $path = str_replace($request->getScriptName(), '', $path);
300 //Try with referer path
303 $oldContext = $this->router
->getContext();
305 //Force clean context
306 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
307 $this->router
->setContext(new RequestContext());
309 //Retrieve route matching path
310 $route = $this->router
->match($path);
313 $this->router
->setContext($oldContext);
319 $name = $route['_route'];
321 //Remove route and controller from route defaults
322 unset($route['_route'], $route['_controller']);
324 //Check if snippet view route
325 if ($name == 'rapsysair_user_view' && !empty($route['id'])) {
327 $route['id'] = $snippet->getUser()->getId();
331 $route['snippet'] = $snippet->getId();
335 return $this->redirectToRoute($name, $route);
337 } catch(MethodNotAllowedException
|ResourceNotFoundException
$e) {
338 //Unset referer to fallback to default route
343 //Redirect to cleanup the form
344 return $this->redirectToRoute('rapsysair', ['snippet' => $snippet->getId()]);