Completed
Pull Request — master (#375)
by Paul
06:11
created

WidgetController::newAction()   B

Complexity

Conditions 3
Paths 11

Size

Total Lines 29
Code Lines 20

Duplication

Lines 4
Ratio 13.79 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
c 4
b 1
f 1
dl 4
loc 29
rs 8.8571
cc 3
eloc 20
nc 11
nop 5
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Controller;
4
5
use Exception;
6
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
7
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
9
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
10
use Symfony\Component\HttpFoundation\JsonResponse;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
14
use Victoire\Bundle\CoreBundle\Controller\VictoireAlertifyControllerTrait;
15
use Victoire\Bundle\ViewReferenceBundle\ViewReference\ViewReference;
16
use Victoire\Bundle\WidgetBundle\Entity\Widget;
17
use Victoire\Bundle\WidgetBundle\Form\WidgetStyleType;
18
use Victoire\Bundle\WidgetMapBundle\Exception\WidgetMapNotFoundException;
19
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
20
21
/**
22
 * Widget Controller.
23
 */
24
class WidgetController extends Controller
25
{
26
    use VictoireAlertifyControllerTrait;
27
28
    /**
29
     * Show a widget.
30
     *
31
     * @param Request $request
32
     * @param Widget  $widget
33
     * @param int     $viewReferenceId
34
     *
35
     * @Route("/victoire-dcms-public/widget/show/{id}/{viewReferenceId}", name="victoire_core_widget_show", options={"expose"=true})
36
     * @Template()
37
     * @ParamConverter("id", class="VictoireWidgetBundle:Widget")
38
     *
39
     * @throws Exception
40
     *
41
     * @return Response
42
     */
43
    public function showAction(Request $request, Widget $widget, $viewReferenceId)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
    {
45
        //the response is for the ajax.js from the AppVentus Ajax Bundle
46
        try {
47
            $view = $this->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
48
            $this->get('victoire_core.current_view')->setCurrentView($view);
49
            $response = new JsonResponse([
50
                    'html'    => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
51
                    'update'  => 'vic-widget-'.$widget->getId().'-container',
52
                    'success' => true,
53
                ]
54
            );
55
        } catch (Exception $ex) {
56
            $response = $this->getJsonReponseFromException($ex);
57
        }
58
59
        return $response;
60
    }
61
62
    /**
63
     * API widgets function.
64
     *
65
     * @param string $widgetIds       the widget ids to fetch in json
66
     * @param int    $viewReferenceId
67
     *
68
     * @Route("/victoire-dcms-public/api/widgets/{widgetIds}/{viewReferenceId}", name="victoire_core_widget_apiWidgets", options={"expose"=true})
69
     *
70
     * @return JsonResponse
71
     */
72
    public function apiWidgetsAction($widgetIds, $viewReferenceId)
73
    {
74
        $view = $this->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
75
        $response = [];
76
        $widgets = $this->get('doctrine.orm.entity_manager')->getRepository('VictoireWidgetBundle:Widget')
77
            ->findBy(['id' => json_decode($widgetIds)]);
78
79
        foreach ($widgets as $widget) {
80
            $response[$widget->getId()] = $this->get('victoire_widget.widget_renderer')->render($widget, $view);
81
        }
82
83
        return new JsonResponse($response);
84
    }
85
86
    /**
87
     * New Widget.
88
     *
89
     * @param string $type          The type of the widget we edit
90
     * @param int    $viewReference The view reference where attach the widget
91
     * @param string $slot          The slot where attach the widget
92
     *
93
     * @return JsonResponse
94
     *
95
     * @Route("/victoire-dcms/widget/new-quantum-item/{type}/{viewReference}/{slot}/{position}/{parentWidgetMap}", name="victoire_core_widget_new_quantum_item", defaults={"slot":null, "position":null, "parentWidgetMap":null}, options={"expose"=true})
96
     * @Route("/victoire-dcms/widget/new/{type}/{viewReference}/{slot}/{position}/{parentWidgetMap}", name="victoire_core_widget_new", defaults={"slot":null, "position":null, "parentWidgetMap":null}, options={"expose"=true})
97
     */
98
    public function newAction($type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null)
99
    {
100
        try {
101
            $view = $this->getViewByReferenceId($viewReference);
102
103 View Code Duplication
            if (!$reference = $this->get('victoire_view_reference.repository')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
                ->getOneReferenceByParameters(['id' => $viewReference])) {
105
                $reference = new ViewReference($viewReference);
106
            }
107
            $view->setReference($reference);
108
            $widgetData = $this->get('victoire_widget.widget_manager')->newWidget(
109
                Widget::MODE_STATIC,
110
                $type,
111
                $slot,
112
                $view,
113
                $position,
114
                $parentWidgetMap
115
            );
116
117
            $response = new JsonResponse([
118
                'success' => true,
119
                'html' => $widgetData['html']
120
            ]);
121
        } catch (Exception $ex) {
122
            $response = $this->getJsonReponseFromException($ex);
123
        }
124
125
        return $response;
126
    }
127
128
    /**
129
     * Create a widget.
130
     * This action needs 2 routes to handle the presence or not of "businessEntityId" and 'parentWidgetMap'
131
     * that are both integers but "businessEntityId" present only in !static mode.
132
     *
133
     * @param string $type             The type of the widget we edit
134
     * @param int    $viewReference    The view reference where attach the widget
135
     * @param string $slot             The slot where attach the widget
136
     * @param string $businessEntityId The BusinessEntity::id (can be null if the submitted form is in static mode)
137
     *
138
     * @return JsonResponse
139
     * @Route("/victoire-dcms/widget/create/static/{type}/{viewReference}/{slot}/{position}/{parentWidgetMap}", name="victoire_core_widget_create_static", defaults={"mode":"static", "slot":null, "businessEntityId":null, "position":null, "parentWidgetMap":null, "_format": "json"})
140
     * @Route("/victoire-dcms/widget/create/{mode}/{type}/{viewReference}/{slot}/{businessEntityId}/{position}/{parentWidgetMap}", name="victoire_core_widget_create", defaults={"slot":null, "businessEntityId":null, "position":null, "parentWidgetMap":null, "_format": "json"})
141
     * @Template()
142
     */
143
    public function createAction($mode, $type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null, $businessEntityId = null)
144
    {
145
        try {
146
            //services
147
            $view = $this->getViewByReferenceId($viewReference);
148
149
            $isNewPage = $view->getId() === null ? true : false;
150
151 View Code Duplication
            if (!$reference = $this->get('victoire_view_reference.repository')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
                ->getOneReferenceByParameters(['id' => $viewReference])) {
153
                $reference = new ViewReference($viewReference);
154
            }
155
156
            $view->setReference($reference);
157
            $this->get('victoire_core.current_view')->setCurrentView($view);
158
159
            $this->congrat($this->get('translator')->trans('victoire.success.message', [], 'victoire'));
160
            $response = $this->get('widget_manager')->createWidget($mode, $type, $slot, $view, $businessEntityId, $position, $parentWidgetMap);
161
162
            if ($isNewPage) {
163
                $response = new JsonResponse([
164
                    'success'  => true,
165
                    'redirect' => $this->generateUrl(
166
                        'victoire_core_page_show',
167
                        [
168
                            'url' => $reference->getUrl(),
169
                        ]
170
                    ),
171
                ]);
172
            } else {
173
                $response = new JsonResponse($response);
174
            }
175
        } catch (Exception $ex) {
176
            $response = $this->getJsonReponseFromException($ex);
177
        }
178
179
        return $response;
180
    }
181
182
    /**
183
     * Edit a widget.
184
     *
185
     * @param Widget $widget           The widget to edit
186
     * @param int    $viewReference    The current view
187
     * @param string $businessEntityId The BusinessEntity::id (can be null if the submitted form is in static mode)
188
     *
189
     * @return JsonResponse
190
     *
191
     * @Route("/victoire-dcms/widget/edit/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_edit", options={"expose"=true})
192
     * @Route("/victoire-dcms/widget/update/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_update", defaults={"businessEntityId": null})
193
     * @Template()
194
     */
195
    public function editAction(Widget $widget, $viewReference, $mode = Widget::MODE_STATIC, $businessEntityId = null)
196
    {
197
        $view = $this->getViewByReferenceId($viewReference);
198
        $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager'));
199
        $this->get('victoire_widget_map.widget_data_warmer')->warm($this->getDoctrine()->getManager(), $view);
200
201
        if ($view instanceof BusinessTemplate && !$reference = $this->get('victoire_view_reference.repository')
202
            ->getOneReferenceByParameters(['viewId' => $view->getId()])) {
203
            $reference = new ViewReference($viewReference);
204
            $view->setReference($reference);
205
        }
206
        $this->get('victoire_core.current_view')->setCurrentView($view);
207
        try {
208
            $response = new JsonResponse(
209
                $this->get('widget_manager')->editWidget(
210
                    $this->get('request'),
211
                    $widget,
212
                    $view,
213
                    $businessEntityId,
214
                    $mode
215
                )
216
            );
217
218
            $this->congrat($this->get('translator')->trans('victoire.success.message', [], 'victoire'));
219
        } catch (Exception $ex) {
220
            $response = $this->getJsonReponseFromException($ex);
221
        }
222
223
        return $response;
224
    }
225
226
    /**
227
     * Stylize a widget.
228
     *
229
     * @param Widget $widget        The widget to stylize
230
     * @param int    $viewReference The current view
231
     *
232
     * @return JsonResponse
233
     *
234
     * @Route("/victoire-dcms/widget/stylize/{id}/{viewReference}", name="victoire_core_widget_stylize", options={"expose"=true})
235
     * @Template()
236
     */
237
    public function stylizeAction(Request $request, Widget $widget, $viewReference)
238
    {
239
        $view = $this->getViewByReferenceId($viewReference);
240
        $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager'));
241
242
        try {
243
            $widgetView = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view)->getView();
244
        } catch (WidgetMapNotFoundException $e) {
245
            return new JsonResponse([
246
                'success' => false,
247
                'message' => $e->getMessage(),
248
            ]);
249
        }
250
251
        if (!$view instanceof \Victoire\Bundle\TemplateBundle\Entity\Template) {
252
            $widgetViewReference = $this->get('victoire_view_reference.repository')
253
                ->getOneReferenceByParameters(['viewId' => $view->getId()]);
254
            $widgetView->setReference($widgetViewReference);
255
        }
256
257
        $this->get('victoire_core.current_view')->setCurrentView($view);
258
        try {
259
260
            if ($request->getMethod() === 'POST') {
261
262
                $form = $this->get('form.factory')->create(WidgetStyleType::class, $widget, [
263
                        'method' => 'POST',
264
                        'action' => $this->generateUrl(
265
                            'victoire_core_widget_stylize',
266
                            [
267
                                'id'            => $widget->getId(),
268
                                'viewReference' => $viewReference,
269
                            ]
270
                        ),
271
                    ]
272
                );
273
274
                $form->handleRequest($this->get('request'));
275
                if ($request->query->get('novalidate', false) === false && $form->isValid()) {
276
                    if ($form->has('deleteBackground') && $form->get('deleteBackground')->getData()) {
277
                        // @todo: dynamic responsive key
278
                        foreach (['', 'XS', 'SM', 'MD', 'LG'] as $key) {
279
                            $widget->{'deleteBackground'.$key}();
280
                        }
281
                    }
282
                    $this->get('doctrine.orm.entity_manager')->flush();
283
                    $params = [
284
                        'view'        => $view,
285
                        'success'     => true,
286
                        'html'        => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
287
                        'widgetId'    => $widget->getId(),
288
                        'viewCssHash' => $view->getCssHash(),
289
                    ];
290
291
                } else {
292
                    $template = ($request->query->get('novalidate', false) !== false) ? 'VictoireCoreBundle:Widget/Form/stylize:form.html.twig' : 'VictoireCoreBundle:Widget/Form:stylize.html.twig';
293
                    $params = [
294
                        'success'  => !$form->isSubmitted(),
295
                        'html'     => $this->get('templating')->render(
296
                            $template,
297
                            [
298
                                'view'   => $view,
299
                                'form'   => $form->createView(),
300
                                'widget' => $widget,
301
                            ]
302
                        ),
303
                    ];
304
                }
305
            } else {
306
307
                $widgets = $widget->getWidgetMap()->getWidgets();
308
                $forms = [];
309
                foreach ($widgets as $widget) {
0 ignored issues
show
Bug introduced by
The expression $widgets of type object<Victoire\Bundle\W...etBundle\Entity\Widget> is not traversable.
Loading history...
310
                    $forms[] = $this->get('form.factory')->create(WidgetStyleType::class, $widget, [
311
                            'method' => 'POST',
312
                            'action' => $this->generateUrl(
313
                                'victoire_core_widget_stylize',
314
                                [
315
                                    'id'            => $widget->getId(),
316
                                    'viewReference' => $viewReference,
317
                                ]
318
                            ),
319
                        ]
320
                    )->createView();
321
                };
322
                $params = [
323
                    'html' => $this->get('templating')->render(
324
                        'VictoireCoreBundle:Widget/Form:stylize.html.twig',
325
                        [
326
                            'view'   => $view,
327
                            'forms'   => $forms,
328
                            'widget' => $widget,
329
                            'widgets' => $widgets,
330
                        ]
331
                    ),
332
                ];
333
334
            }
335
336
            $response = new JsonResponse($params);
337
        } catch (Exception $ex) {
338
            $response = $this->getJsonReponseFromException($ex);
339
        }
340
341
        return $response;
342
    }
343
344
    /**
345
     * Delete a Widget.
346
     *
347
     * @param Widget $widget        The widget to delete
348
     * @param int    $viewReference The current view
349
     *
350
     * @return JsonResponse response
351
     * @Route("/victoire-dcms/widget/delete/{id}/{viewReference}", name="victoire_core_widget_delete", defaults={"_format": "json"})
352
     * @Template()
353
     */
354 View Code Duplication
    public function deleteAction(Widget $widget, $viewReference)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
355
    {
356
        $view = $this->getViewByReferenceId($viewReference);
357
        try {
358
            $widgetId = $widget->getId();
359
            $this->get('widget_manager')->deleteWidget($widget, $view);
360
361
            return new JsonResponse([
362
                    'success'  => true,
363
                    'message'  => $this->get('translator')->trans('victoire_widget.delete.success', [], 'victoire'),
364
                    'widgetId' => $widgetId,
365
                ]
366
            );
367
        } catch (Exception $ex) {
368
            return $this->getJsonReponseFromException($ex);
369
        }
370
    }
371
    /**
372
     * Delete a Widget quantum.
373
     *
374
     * @param Widget $widget        The widget to delete
375
     * @param int    $viewReference The current view
376
     *
377
     * @return JsonResponse response
378
     * @Route("/victoire-dcms/widget/delete/quantum/{id}/{viewReference}", name="victoire_core_widget_delete_bulk", defaults={"_format": "json"})
379
     * @Template()
380
     */
381 View Code Duplication
    public function deleteBulkAction(Widget $widget, $viewReference)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
382
    {
383
        $view = $this->getViewByReferenceId($viewReference);
384
        try {
385
            $widgets = $widget->getWidgetMap()->getWidgets();
386
387
            foreach ($widgets as $widget) {
0 ignored issues
show
Bug introduced by
The expression $widgets of type object<Victoire\Bundle\W...etBundle\Entity\Widget> is not traversable.
Loading history...
388
                $this->get('widget_manager')->deleteWidget($widget, $view);
389
            }
390
391
            return new JsonResponse([
392
                    'success'  => true,
393
                    'message'  => $this->get('translator')->trans('victoire_widget.delete.success', [], 'victoire'),
394
                ]
395
            );
396
        } catch (Exception $ex) {
397
            return $this->getJsonReponseFromException($ex);
398
        }
399
    }
400
401
    /**
402
     * Unlink a Widget by id
403
     * -> used to unlink an invalid widget after a bad widget unplug.
404
     *
405
     * @param int $id            The widgetId to unlink
406
     * @param int $viewReference The current viewReference
407
     *
408
     * @return JsonResponse response
409
     * @Route("/victoire-dcms/widget/unlink/{id}/{viewReference}", name="victoire_core_widget_unlink", defaults={"_format": "json"}, options={"expose"=true})
410
     * @Template()
411
     */
412
    public function unlinkAction($id, $viewReference)
413
    {
414
        $view = $this->getViewByReferenceId($viewReference);
415
        try {
416
            $this->get('victoire_widget.widget_helper')->deleteById($id);
417
            $this->get('doctrine.orm.entity_manager')->flush();
418
419
            if ($view instanceof Template) {
420
                $redirect = $this->generateUrl('victoire_template_show', ['slug' => $view->getSlug()]);
0 ignored issues
show
Bug introduced by
The method getSlug() does not seem to exist on object<Sensio\Bundle\Fra...Configuration\Template>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
421
            } elseif ($view instanceof BusinessTemplate) {
422
                $redirect = $this->generateUrl('victoire_business_template_show', ['id' => $view->getId()]);
423
            } else {
424
                $viewReference = $this->get('victoire_view_reference.repository')
425
                    ->getOneReferenceByParameters(['viewId' => $view->getId()]);
426
427
                $redirect = $this->generateUrl('victoire_core_page_show', [
428
                        'url' => $viewReference->getUrl(),
429
                    ]);
430
            }
431
432
            return new JsonResponse([
433
                    'success'  => true,
434
                    'redirect' => $redirect,
435
                ]);
436
        } catch (Exception $ex) {
437
            return $this->getJsonReponseFromException($ex);
438
        }
439
    }
440
441
442
    /**
443
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
444
     *
445
     * @param int $viewReference The current viewReference
446
     *
447
     * @return JsonResponse
448
     * @Route("/victoire-dcms/widget/updatePosition/{viewReference}", name="victoire_core_widget_update_position", options={"expose"=true})
449
     */
450
    public function updatePositionAction(Request $request, $viewReference)
451
    {
452
        $view = $this->getViewByReferenceId($viewReference);
453
        try {
454
            //the sorted order for the widgets
455
            $sortedWidget = $request->get('sorted');
456
            $em = $this->get('doctrine.orm.entity_manager');
457
            if (!$view->getId()) {
458
                //This view does not have an id, so it's a non persisted BEP. To keep this new order, well have to persist it.
459
                $em->persist($view);
460
                $em->flush();
461
            }
462
            $this->get('victoire_widget_map.builder')->build($view);
463
            //recompute the order for the widgets
464
            $this->get('victoire_widget_map.manager')->move($view, $sortedWidget);
465
            $em->flush();
466
467
            $this->get('victoire_widget_map.builder')->build($view);
468
            $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
469
470
            $response = new JsonResponse(['success' => true, 'availablePositions' => $availablePositions]);
471
        } catch (Exception $ex) {
472
            $response = $this->getJsonReponseFromException($ex);
473
        }
474
475
        return $response;
476
    }
477
478
    /**
479
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
480
     *
481
     * @param int $viewReference The current viewReference
482
     *
483
     * @return JsonResponse
484
     * @Route("/victoire-dcms/widget/get-available-positions/{viewReference}", name="victoire_core_widget_get_available_positions", options={"expose"=true})
485
     */
486
    public function getAvailablePositionsAction(Request $request, $viewReference)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
487
    {
488
        $view = $this->getViewByReferenceId($viewReference);
489
490
        $this->get('victoire_widget_map.builder')->build($view);
491
        $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
492
493
        return new JsonResponse($availablePositions);
494
    }
495
496
    /**
497
     * Get the json response by the exception and the current user.
498
     *
499
     * @param Exception $ex
500
     *
501
     * @return JsonResponse
502
     */
503
    protected function getJsonReponseFromException(Exception $ex)
504
    {
505
        //services
506
        $securityContext = $this->get('security.context');
507
        $logger = $this->get('logger');
508
509
        //can we see the debug
510
        $isDebugAllowed = $securityContext->isGranted('ROLE_VICTOIRE_PAGE_DEBUG');
511
512
        //whatever is the exception, we log it
513
        $logger->error($ex->getMessage());
514
        $logger->error($ex->getTraceAsString());
515
516
        if ($isDebugAllowed) {
517
            throw $ex;
518
        } else {
519
            //translate the message
520
            $translator = $this->get('translator');
521
522
            //get the translated message
523
            $message = $translator->trans('error_occured', [], 'victoire');
524
525
            $response = new JsonResponse(
526
                [
527
                    'success' => false,
528
                    'message' => $message,
529
                ]
530
            );
531
        }
532
533
        return $response;
534
    }
535
536
    /**
537
     * @param int $referenceId
538
     */
539
    protected function getViewByReferenceId($referenceId)
540
    {
541
        return $this->get('victoire_page.page_helper')->findPageByParameters(['id' => $referenceId]);
542
    }
543
}
544