Completed
Pull Request — master (#325)
by Paul
09:55
created

WidgetController::updatePositionAction()   B

Complexity

Conditions 3
Paths 19

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 27
rs 8.8571
cc 3
eloc 17
nc 19
nop 2
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Controller;
4
5
use Victoire\Bundle\CoreBundle\Controller\VictoireAlertifyControllerTrait;
6
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
7
use Exception;
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
10
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
11
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
16
use Victoire\Bundle\ViewReferenceBundle\ViewReference\ViewReference;
17
use Victoire\Bundle\WidgetBundle\Entity\Widget;
18
19
/**
20
 * Widget Controller.
21
 */
22
class WidgetController extends Controller
23
{
24
    use VictoireAlertifyControllerTrait;
25
26
    /**
27
     * Show a widget.
28
     *
29
     * @param Request $request
30
     * @param Widget  $widget
31
     * @param int     $viewReferenceId
32
     *
33
     * @Route("/victoire-dcms-public/widget/show/{id}/{viewReferenceId}", name="victoire_core_widget_show", options={"expose"=true})
34
     * @Template()
35
     * @ParamConverter("id", class="VictoireWidgetBundle:Widget")
36
     *
37
     * @throws Exception
38
     *
39
     * @return Response
40
     */
41
    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...
42
    {
43
        //the response is for the ajax.js from the AppVentus Ajax Bundle
44
        try {
45
            $view = $this->container->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
46
            $this->container->get('victoire_core.current_view')->setCurrentView($view);
47
            $response = new JsonResponse([
48
                    'html'    => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
49
                    'update'  => 'vic-widget-'.$widget->getId().'-container',
50
                    'success' => false,
51
                ]
52
            );
53
        } catch (Exception $ex) {
54
            $response = $this->getJsonReponseFromException($ex);
55
        }
56
57
        return $response;
58
    }
59
60
    /**
61
     * API widgets function.
62
     *
63
     * @param string $widgetIds       the widget ids to fetch in json
64
     * @param int    $viewReferenceId
65
     *
66
     * @Route("/victoire-dcms-public/api/widgets/{widgetIds}/{viewReferenceId}", name="victoire_core_widget_apiWidgets", options={"expose"=true})
67
     *
68
     * @return JsonResponse
69
     */
70
    public function apiWidgetsAction($widgetIds, $viewReferenceId)
71
    {
72
        $view = $this->container->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
73
        $response = [];
74
        $widgets = $this->get('doctrine.orm.entity_manager')->getRepository('VictoireWidgetBundle:Widget')
75
            ->findBy(['id' => json_decode($widgetIds)]);
76
77
        foreach ($widgets as $widget) {
78
            $response[$widget->getId()] = $this->get('victoire_widget.widget_renderer')->render($widget, $view);
79
        }
80
81
        return new JsonResponse($response);
82
    }
83
84
    /**
85
     * New Widget.
86
     *
87
     * @param string $type          The type of the widget we edit
88
     * @param int    $viewReference The view reference where attach the widget
89
     * @param string $slot          The slot where attach the widget
90
     *
91
     * @return JsonResponse
92
     *
93
     * @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})
94
     * @Template()
95
     */
96
    public function newAction($type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null)
97
    {
98
        try {
99
            $view = $this->getViewByReferenceId($viewReference);
100
101 View Code Duplication
            if (!$reference = $this->container->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...
102
                ->getOneReferenceByParameters(['id' => $viewReference])) {
103
                $reference = new ViewReference($viewReference);
104
            }
105
            $view->setReference($reference);
106
107
            $response = new JsonResponse(
108
                $this->get('victoire_widget.widget_manager')->newWidget(Widget::MODE_STATIC, $type, $slot, $view, $position, $parentWidgetMap)
109
            );
110
111
        } catch (Exception $ex) {
112
            $response = $this->getJsonReponseFromException($ex);
113
        }
114
115
        return $response;
116
    }
117
118
    /**
119
     * Create a widget.
120
     * This action needs 2 routes to handle the presence or not of "businessEntityId" and 'parentWidgetMap'
121
     * that are both integers but "businessEntityId" present only in !static mode
122
     *
123
     * @param string $type             The type of the widget we edit
124
     * @param int    $viewReference    The view reference where attach the widget
125
     * @param string $slot             The slot where attach the widget
126
     * @param string $businessEntityId The BusinessEntity::id (can be null if the submitted form is in static mode)
127
     *
128
     * @return JsonResponse
129
     * @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"})
130
     * @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"})
131
     * @Template()
132
     */
133
    public function createAction($mode, $type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null, $businessEntityId = null)
134
    {
135
        try {
136
            //services
137
            $view = $this->getViewByReferenceId($viewReference);
138
139
            $isNewPage = $view->getId() === null ? true : false;
140
141 View Code Duplication
            if (!$reference = $this->container->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...
142
                ->getOneReferenceByParameters(['id' => $viewReference])) {
143
                $reference = new ViewReference($viewReference);
144
            }
145
146
            $view->setReference($reference);
147
            $this->get('victoire_core.current_view')->setCurrentView($view);
148
149
            $this->congrat($this->get('translator')->trans('victoire.success.message', [], 'victoire'));
150
            $response = $this->get('widget_manager')->createWidget($mode, $type, $slot, $view, $businessEntityId, $position, $parentWidgetMap);
151
152
            if ($isNewPage) {
153
                $response = new JsonResponse([
154
                    'success'  => true,
155
                    'redirect' => $this->generateUrl(
156
                        'victoire_core_page_show',
157
                        [
158
                            'url' => $reference->getUrl(),
159
                        ]
160
                    ),
161
                ]);
162
            } else {
163
                $response = new JsonResponse($response);
164
            }
165
        } catch (Exception $ex) {
166
            $response = $this->getJsonReponseFromException($ex);
167
        }
168
169
        return $response;
170
    }
171
172
    /**
173
     * Edit a widget.
174
     *
175
     * @param Widget $widget           The widget to edit
176
     * @param int    $viewReference    The current view
177
     * @param string $businessEntityId The BusinessEntity::id (can be null if the submitted form is in static mode)
178
     *
179
     * @return JsonResponse
180
     *
181
     * @Route("/victoire-dcms/widget/edit/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_edit", options={"expose"=true})
182
     * @Route("/victoire-dcms/widget/update/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_update", defaults={"businessEntityId": null})
183
     * @Template()
184
     */
185
    public function editAction(Widget $widget, $viewReference, $mode = Widget::MODE_STATIC, $businessEntityId = null)
186
    {
187
        $view = $this->getViewByReferenceId($viewReference);
188
        $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager'));
189
        $widgetView = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view)->getView();
190
        $this->get('victoire_widget_map.widget_data_warmer')->warm($this->getDoctrine()->getManager(), $view);
191
192
        if ($view instanceof BusinessTemplate && !$reference = $this->container->get('victoire_view_reference.repository')
193
            ->getOneReferenceByParameters(['viewId' => $view->getId()])) {
194
            $reference = new ViewReference($viewReference);
195
            $widgetView->setReference($reference);
196
        }
197
        $widget->setCurrentView($widgetView);
198
        $this->get('victoire_core.current_view')->setCurrentView($view);
199
        try {
200
            $response = new JsonResponse(
201
                $this->get('widget_manager')->editWidget(
202
                    $this->get('request'),
203
                    $widget,
204
                    $view,
205
                    $businessEntityId,
206
                    $mode
207
                )
208
            );
209
210
            $this->congrat($this->get('translator')->trans('victoire.success.message', [], 'victoire'));
211
        } catch (Exception $ex) {
212
            $response = $this->getJsonReponseFromException($ex);
213
        }
214
215
        return $response;
216
    }
217
218
    /**
219
     * Stylize a widget.
220
     *
221
     * @param Widget $widget        The widget to stylize
222
     * @param int    $viewReference The current view
223
     *
224
     * @return JsonResponse
225
     *
226
     * @Route("/victoire-dcms/widget/stylize/{id}/{viewReference}", name="victoire_core_widget_stylize", options={"expose"=true})
227
     * @Template()
228
     */
229
    public function stylizeAction(Request $request, Widget $widget, $viewReference)
230
    {
231
        $view = $this->getViewByReferenceId($viewReference);
232
        $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager'));
233
        $widgetView = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view)->getView();
234
235
        $widgetViewReference = $this->container->get('victoire_view_reference.repository')
236
            ->getOneReferenceByParameters(['viewId' => $view->getId()]);
237
238
        $widgetView->setReference($widgetViewReference);
239
        $this->get('victoire_core.current_view')->setCurrentView($view);
240
        try {
241
            $form = $this->container->get('form.factory')->create('victoire_widget_style_type', $widget, [
242
                    'method' => 'POST',
243
                    'action' => $this->generateUrl(
244
                        'victoire_core_widget_stylize',
245
                        [
246
                            'id'            => $widget->getId(),
247
                            'viewReference' => $viewReference,
248
                        ]
249
                    ),
250
                ]
251
            );
252
            $form->handleRequest($this->get('request'));
253
254
            if ($request->query->get('novalidate', false) === false && $form->isValid()) {
255
                if ($form->has('deleteBackground') && $form->get('deleteBackground')->getData()) {
256
                    // @todo: dynamic responsive key
257
                    foreach (['', 'XS', 'SM', 'MD', 'LG'] as $key) {
258
                        $widget->{'deleteBackground'.$key}();
259
                    }
260
                }
261
                $this->get('doctrine.orm.entity_manager')->flush();
262
                $params = [
263
                    'view'        => $view,
264
                    'success'     => true,
265
                    'html'        => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
266
                    'widgetId'    => $widget->getId(),
267
                    'viewCssHash' => $view->getCssHash(),
268
                ];
269
            } else {
270
                $template = ($request->query->get('novalidate', false) !== false) ? 'VictoireCoreBundle:Widget/Form/stylize:form.html.twig' : 'VictoireCoreBundle:Widget/Form:stylize.html.twig';
271
                $params = [
272
                    'success'  => false,
273
                    'html'     => $this->get('victoire_core.template_mapper')->render(
274
                        $template,
275
                        [
276
                            'view'   => $view,
277
                            'form'   => $form->createView(),
278
                            'widget' => $widget,
279
                        ]
280
                    ),
281
                ];
282
            }
283
            $response = new JsonResponse($params);
284
        } catch (Exception $ex) {
285
            $response = $this->getJsonReponseFromException($ex);
286
        }
287
288
        return $response;
289
    }
290
291
    /**
292
     * Delete a Widget.
293
     *
294
     * @param Widget $widget        The widget to delete
295
     * @param int    $viewReference The current view
296
     *
297
     * @return JsonResponse response
298
     * @Route("/victoire-dcms/widget/delete/{id}/{viewReference}", name="victoire_core_widget_delete", defaults={"_format": "json"})
299
     * @Template()
300
     */
301
    public function deleteAction(Widget $widget, $viewReference)
302
    {
303
        $view = $this->getViewByReferenceId($viewReference);
304
        try {
305
            $widgetId = $widget->getId();
306
            $this->get('widget_manager')->deleteWidget($widget, $view);
307
308
            return new JsonResponse([
309
                    'success'  => true,
310
                    'message'  => $this->get('translator')->trans('victoire_widget.delete.success', [], 'victoire'),
311
                    'widgetId' => $widgetId,
312
                ]
313
            );
314
        } catch (Exception $ex) {
315
            return $this->getJsonReponseFromException($ex);
316
        }
317
    }
318
319
    /**
320
     * Unlink a Widget by id
321
     * -> used to unlink an invalid widget after a bad widget unplug.
322
     *
323
     * @param int $id            The widgetId to unlink
324
     * @param int $viewReference The current viewReference
325
     *
326
     * @return JsonResponse response
327
     * @Route("/victoire-dcms/widget/unlink/{id}/{viewReference}", name="victoire_core_widget_unlink", defaults={"_format": "json"}, options={"expose"=true})
328
     * @Template()
329
     */
330
    public function unlinkAction($id, $viewReference)
331
    {
332
        $view = $this->getViewByReferenceId($viewReference);
333
        try {
334
            $this->get('victoire_widget.widget_helper')->deleteById($id);
335
            $this->get('doctrine.orm.entity_manager')->flush();
336
337
            if ($view instanceof Template) {
338
                $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...
339
            } elseif ($view instanceof BusinessTemplate) {
340
                $redirect = $this->generateUrl('victoire_business_template_show', ['id' => $view->getId()]);
341
            } else {
342
                $viewReference = $this->container->get('victoire_view_reference.repository')
343
                    ->getOneReferenceByParameters(['viewId' => $view->getId()]);
344
345
                $redirect = $this->generateUrl('victoire_core_page_show', [
346
                        'url' => $viewReference->getUrl(),
347
                    ]);
348
            }
349
350
            return new JsonResponse([
351
                    'success'  => true,
352
                    'redirect' => $redirect,
353
                ]);
354
        } catch (Exception $ex) {
355
            return $this->getJsonReponseFromException($ex);
356
        }
357
    }
358
359
    /**
360
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
361
     *
362
     * @param int $viewReference The current viewReference
363
     *
364
     * @return JsonResponse
365
     * @Route("/victoire-dcms/widget/updatePosition/{viewReference}", name="victoire_core_widget_update_position", options={"expose"=true})
366
     */
367
    public function updatePositionAction(Request $request, $viewReference)
368
    {
369
        $view = $this->getViewByReferenceId($viewReference);
370
        try {
371
            //the sorted order for the widgets
372
            $sortedWidget = $request->get('sorted');
373
            $em = $this->get('doctrine.orm.entity_manager');
374
            if (!$view->getId()) {
375
                //This view does not have an id, so it's a non persisted BEP. To keep this new order, well have to persist it.
376
                $em->persist($view);
377
                $em->flush();
378
            }
379
            $this->get('victoire_widget_map.builder')->build($view);
380
            //recompute the order for the widgets
381
            $this->get('victoire_widget_map.manager')->move($view, $sortedWidget);
382
            $em->flush();
383
384
            $this->get('victoire_widget_map.builder')->build($view);
385
            $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
386
387
            $response = new JsonResponse(['success' => true, 'availablePositions' => $availablePositions]);
388
        } catch (Exception $ex) {
389
            $response = $this->getJsonReponseFromException($ex);
390
        }
391
392
        return $response;
393
    }
394
395
    /**
396
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
397
     *
398
     * @param int $viewReference The current viewReference
399
     *
400
     * @return JsonResponse
401
     * @Route("/victoire-dcms/widget/get-available-positions/{viewReference}", name="victoire_core_widget_get_available_positions", options={"expose"=true})
402
     */
403
    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...
404
    {
405
        $view = $this->getViewByReferenceId($viewReference);
406
407
        $this->get('victoire_widget_map.builder')->build($view);
408
        $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
409
410
        return new JsonResponse($availablePositions);
411
    }
412
413
    /**
414
     * Get the json response by the exception and the current user.
415
     *
416
     * @param Exception $ex
417
     *
418
     * @return JsonResponse
419
     */
420
    protected function getJsonReponseFromException(Exception $ex)
421
    {
422
        //services
423
        $securityContext = $this->get('security.context');
424
        $logger = $this->get('logger');
425
426
        //can we see the debug
427
        $isDebugAllowed = $securityContext->isGranted('ROLE_VICTOIRE_PAGE_DEBUG');
428
429
        //whatever is the exception, we log it
430
        $logger->error($ex->getMessage());
431
        $logger->error($ex->getTraceAsString());
432
433
        if ($isDebugAllowed) {
434
            throw $ex;
435
        } else {
436
            //translate the message
437
            $translator = $this->get('translator');
438
439
            //get the translated message
440
            $message = $translator->trans('error_occured', [], 'victoire');
441
442
            $response = new JsonResponse(
443
                [
444
                    'success' => false,
445
                    'message' => $message,
446
                ]
447
            );
448
        }
449
450
        return $response;
451
    }
452
453
    /**
454
     * @param int $referenceId
455
     */
456
    protected function getViewByReferenceId($referenceId)
457
    {
458
        return $this->get('victoire_page.page_helper')->findPageByParameters(['id' => $referenceId]);
459
    }
460
}
461