Completed
Pull Request — master (#325)
by Paul
08:28
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\WidgetMapBundle\Helper\WidgetMapHelper;
6
use Exception;
7
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
10
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
11
use Symfony\Component\HttpFoundation\JsonResponse;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\Response;
14
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
15
use Victoire\Bundle\ViewReferenceBundle\ViewReference\ViewReference;
16
use Victoire\Bundle\WidgetBundle\Entity\Widget;
17
18
/**
19
 * Widget Controller.
20
 */
21
class WidgetController extends Controller
22
{
23
    /**
24
     * Show a widget.
25
     *
26
     * @param Request $request
27
     * @param Widget  $widget
28
     * @param int     $viewReferenceId
29
     *
30
     * @Route("/victoire-dcms-public/widget/show/{id}/{viewReferenceId}", name="victoire_core_widget_show", options={"expose"=true})
31
     * @Template()
32
     * @ParamConverter("id", class="VictoireWidgetBundle:Widget")
33
     *
34
     * @throws Exception
35
     *
36
     * @return Response
37
     */
38
    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...
39
    {
40
        //the response is for the ajax.js from the AppVentus Ajax Bundle
41
        try {
42
            $view = $this->container->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
43
            $this->container->get('victoire_core.current_view')->setCurrentView($view);
44
            $response = new JsonResponse([
45
                    'html'    => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
46
                    'update'  => 'vic-widget-'.$widget->getId().'-container',
47
                    'success' => false,
48
                ]
49
            );
50
        } catch (Exception $ex) {
51
            $response = $this->getJsonReponseFromException($ex);
52
        }
53
54
        return $response;
55
    }
56
57
    /**
58
     * API widgets function.
59
     *
60
     * @param string $widgetIds       the widget ids to fetch in json
61
     * @param int    $viewReferenceId
62
     *
63
     * @Route("/victoire-dcms-public/api/widgets/{widgetIds}/{viewReferenceId}", name="victoire_core_widget_apiWidgets", options={"expose"=true})
64
     *
65
     * @return JsonResponse
66
     */
67
    public function apiWidgetsAction($widgetIds, $viewReferenceId)
68
    {
69
        $view = $this->container->get('victoire_page.page_helper')->findPageByParameters(['id' => $viewReferenceId]);
70
        $response = [];
71
        $widgets = $this->get('doctrine.orm.entity_manager')->getRepository('VictoireWidgetBundle:Widget')
72
            ->findBy(['id' => json_decode($widgetIds)]);
73
74
        foreach ($widgets as $widget) {
75
            $response[$widget->getId()] = $this->get('victoire_widget.widget_renderer')->render($widget, $view);
76
        }
77
78
        return new JsonResponse($response);
79
    }
80
81
    /**
82
     * New Widget.
83
     *
84
     * @param string $type              The type of the widget we edit
85
     * @param int    $viewReference     The view reference where attach the widget
86
     * @param string $slot              The slot where attach the widget
87
     *
88
     * @return JsonResponse
89
     *
90
     * @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})
91
     * @Template()
92
     */
93
    public function newAction($type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null)
94
    {
95
        try {
96
            $view = $this->getViewByReferenceId($viewReference);
97
98 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...
99
                ->getOneReferenceByParameters(['id' => $viewReference])) {
100
                $reference = new ViewReference($viewReference);
101
            }
102
            $view->setReference($reference);
103
104
            $response = new JsonResponse(
105
                $this->get('victoire_widget.widget_manager')->newWidget(Widget::MODE_STATIC, $type, $slot, $view, $position, $parentWidgetMap)
106
            );
107
108
        } catch (Exception $ex) {
109
            $response = $this->getJsonReponseFromException($ex);
110
        }
111
112
        return $response;
113
    }
114
115
    /**
116
     * Create a widget.
117
     * This action needs 2 routes to handle the presence or not of "businessEntityId" and 'parentWidgetMap'
118
     * that are both integers but "businessEntityId" present only in !static mode
119
     *
120
     * @param string $type              The type of the widget we edit
121
     * @param int    $viewReference     The view reference where attach the widget
122
     * @param string $slot              The slot where attach the widget
123
     * @param string $businessEntityId  The BusinessEntity::id (can be null if the submitted form is in static mode)
124
     *
125
     * @return JsonResponse
126
     * @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"})
127
     * @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"})
128
     * @Template()
129
     */
130
    public function createAction($mode, $type, $viewReference, $slot = null, $position = null, $parentWidgetMap = null, $businessEntityId = null)
131
    {
132
        try {
133
            //services
134
            $view = $this->getViewByReferenceId($viewReference);
135
136
            $isNewPage = $view->getId() === null ? true : false;
137
138 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...
139
                ->getOneReferenceByParameters(['id' => $viewReference])) {
140
                $reference = new ViewReference($viewReference);
141
            }
142
143
            $view->setReference($reference);
144
            $this->get('victoire_core.current_view')->setCurrentView($view);
145
146
            $response = $this->get('widget_manager')->createWidget($mode, $type, $slot, $view, $businessEntityId, $position, $parentWidgetMap);
147
148
            if ($isNewPage) {
149
                $response = new JsonResponse([
150
                    'success'  => true,
151
                    'redirect' => $this->generateUrl(
152
                        'victoire_core_page_show',
153
                        [
154
                            'url' => $reference->getUrl(),
155
                        ]
156
                    ),
157
                ]);
158
            } else {
159
                $response = new JsonResponse($response);
160
            }
161
        } catch (Exception $ex) {
162
            $response = $this->getJsonReponseFromException($ex);
163
        }
164
165
        return $response;
166
    }
167
168
    /**
169
     * Edit a widget.
170
     *
171
     * @param Widget $widget           The widget to edit
172
     * @param int    $viewReference    The current view
173
     * @param string $businessEntityId The BusinessEntity::id (can be null if the submitted form is in static mode)
174
     *
175
     * @return JsonResponse
176
     *
177
     * @Route("/victoire-dcms/widget/edit/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_edit", options={"expose"=true})
178
     * @Route("/victoire-dcms/widget/update/{id}/{viewReference}/{mode}/{businessEntityId}", name="victoire_core_widget_update", defaults={"businessEntityId": null})
179
     * @Template()
180
     */
181
    public function editAction(Widget $widget, $viewReference, $mode = Widget::MODE_STATIC, $businessEntityId = null)
182
    {
183
        $view = $this->getViewByReferenceId($viewReference);
184
        $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager'));
185
        $widgetView = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view)->getView();
186
        $this->get('victoire_widget_map.widget_data_warmer')->warm($this->getDoctrine()->getManager(), $view);
187
188
        if ($view instanceof BusinessTemplate && !$reference = $this->container->get('victoire_view_reference.repository')
189
            ->getOneReferenceByParameters(['viewId' => $view->getId()])) {
190
            $reference = new ViewReference($viewReference);
191
            $widgetView->setReference($reference);
192
        }
193
        $widget->setCurrentView($widgetView);
194
        $this->get('victoire_core.current_view')->setCurrentView($view);
195
        try {
196
            $response = new JsonResponse(
197
                $this->get('widget_manager')->editWidget(
198
                    $this->get('request'),
199
                    $widget,
200
                    $view,
201
                    $businessEntityId,
202
                    $mode
203
                )
204
            );
205
        } catch (Exception $ex) {
206
            $response = $this->getJsonReponseFromException($ex);
207
        }
208
209
        return $response;
210
    }
211
212
    /**
213
     * Stylize a widget.
214
     *
215
     * @param Widget $widget        The widget to stylize
216
     * @param int    $viewReference The current view
217
     *
218
     * @return JsonResponse
219
     *
220
     * @Route("/victoire-dcms/widget/stylize/{id}/{viewReference}", name="victoire_core_widget_stylize", options={"expose"=true})
221
     * @Template()
222
     */
223
    public function stylizeAction(Request $request, Widget $widget, $viewReference)
224
    {
225
        $view = $this->getViewByReferenceId($viewReference);
226
        $widgetView = $widget->getView();
0 ignored issues
show
Deprecated Code introduced by
The method Victoire\Bundle\WidgetBu...ntity\Widget::getView() has been deprecated with message: Get view.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
227
228
        $widgetViewReference = $this->container->get('victoire_view_reference.repository')
229
            ->getOneReferenceByParameters(['viewId' => $view->getId()]);
230
231
        $widgetView->setReference($widgetViewReference);
0 ignored issues
show
Bug introduced by
The method setReference cannot be called on $widgetView (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
232
        $this->get('victoire_core.current_view')->setCurrentView($view);
233
        try {
234
            $form = $this->container->get('form.factory')->create('victoire_widget_style_type', $widget, [
235
                    'method' => 'POST',
236
                    'action' => $this->generateUrl(
237
                        'victoire_core_widget_stylize',
238
                        [
239
                            'id'            => $widget->getId(),
240
                            'viewReference' => $viewReference,
241
                        ]
242
                    ),
243
                ]
244
            );
245
            $form->handleRequest($this->get('request'));
246
247
            if ($request->query->get('novalidate', false) === false && $form->isValid()) {
248
                if ($form->has('deleteBackground') && $form->get('deleteBackground')->getData()) {
249
                    // @todo: dynamic responsive key
250
                    foreach (['', 'XS', 'SM', 'MD', 'LG'] as $key) {
251
                        $widget->{'deleteBackground'.$key}();
252
                    }
253
                }
254
                $this->get('doctrine.orm.entity_manager')->flush();
255
                $params = [
256
                    'view'        => $view,
257
                    'success'     => true,
258
                    'html'        => $this->get('victoire_widget.widget_renderer')->render($widget, $view),
259
                    'widgetId'    => $widget->getId(),
260
                    'viewCssHash' => $view->getCssHash(),
261
                ];
262
            } else {
263
                $template = ($request->query->get('novalidate', false) !== false) ? 'VictoireCoreBundle:Widget/Form/stylize:form.html.twig' : 'VictoireCoreBundle:Widget/Form:stylize.html.twig';
264
                $params = [
265
                    'success'  => false,
266
                    'html'     => $this->get('victoire_core.template_mapper')->render(
267
                        $template,
268
                        [
269
                            'view'   => $view,
270
                            'form'   => $form->createView(),
271
                            'widget' => $widget,
272
                        ]
273
                    ),
274
                ];
275
            }
276
            $response = new JsonResponse($params);
277
        } catch (Exception $ex) {
278
            $response = $this->getJsonReponseFromException($ex);
279
        }
280
281
        return $response;
282
    }
283
284
    /**
285
     * Delete a Widget.
286
     *
287
     * @param Widget $widget        The widget to delete
288
     * @param int    $viewReference The current view
289
     *
290
     * @return JsonResponse response
291
     * @Route("/victoire-dcms/widget/delete/{id}/{viewReference}", name="victoire_core_widget_delete", defaults={"_format": "json"})
292
     * @Template()
293
     */
294
    public function deleteAction(Widget $widget, $viewReference)
295
    {
296
        $view = $this->getViewByReferenceId($viewReference);
297
        try {
298
            $widgetId = $widget->getId();
299
            $this->get('widget_manager')->deleteWidget($widget, $view);
300
301
            return new JsonResponse([
302
                    'success'  => true,
303
                    'message'  => $this->get('translator')->trans('victoire_widget.delete.success', [], 'victoire'),
304
                    'widgetId' => $widgetId,
305
                ]
306
            );
307
        } catch (Exception $ex) {
308
            return $this->getJsonReponseFromException($ex);
309
        }
310
    }
311
312
    /**
313
     * Unlink a Widget by id
314
     * -> used to unlink an invalid widget after a bad widget unplug.
315
     *
316
     * @param int $id            The widgetId to unlink
317
     * @param int $viewReference The current viewReference
318
     *
319
     * @return JsonResponse response
320
     * @Route("/victoire-dcms/widget/unlink/{id}/{viewReference}", name="victoire_core_widget_unlink", defaults={"_format": "json"}, options={"expose"=true})
321
     * @Template()
322
     */
323
    public function unlinkAction($id, $viewReference)
324
    {
325
        $view = $this->getViewByReferenceId($viewReference);
326
        try {
327
            $this->get('victoire_widget.widget_helper')->deleteById($id);
328
            $this->get('doctrine.orm.entity_manager')->flush();
329
330
            if ($view instanceof Template) {
331
                $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...
332
            } elseif ($view instanceof BusinessTemplate) {
333
                $redirect = $this->generateUrl('victoire_business_template_show', ['id' => $view->getId()]);
334
            } else {
335
                $viewReference = $this->container->get('victoire_view_reference.repository')
336
                    ->getOneReferenceByParameters(['viewId' => $view->getId()]);
337
338
                $redirect = $this->generateUrl('victoire_core_page_show', [
339
                        'url' => $viewReference->getUrl(),
340
                    ]);
341
            }
342
343
            return new JsonResponse([
344
                    'success'  => true,
345
                    'redirect' => $redirect,
346
                ]);
347
        } catch (Exception $ex) {
348
            return $this->getJsonReponseFromException($ex);
349
        }
350
    }
351
352
    /**
353
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
354
     *
355
     * @param int $viewReference The current viewReference
356
     *
357
     * @return JsonResponse
358
     * @Route("/victoire-dcms/widget/updatePosition/{viewReference}", name="victoire_core_widget_update_position", options={"expose"=true})
359
     */
360
    public function updatePositionAction(Request $request, $viewReference)
361
    {
362
        $view = $this->getViewByReferenceId($viewReference);
363
        try {
364
            //the sorted order for the widgets
365
            $sortedWidget = $request->get('sorted');
366
            $em = $this->get('doctrine.orm.entity_manager');
367
            if (!$view->getId()) {
368
                //This view does not have an id, so it's a non persisted BEP. To keep this new order, well have to persist it.
369
                $em->persist($view);
370
                $em->flush();
371
            }
372
            $this->get('victoire_widget_map.builder')->build($view);
373
            //recompute the order for the widgets
374
            $this->get('victoire_widget_map.manager')->move($view, $sortedWidget);
375
            $em->flush();
376
377
            $this->get('victoire_widget_map.builder')->build($view);
378
            $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
379
380
            $response = new JsonResponse(['success' => true, 'availablePositions' => $availablePositions]);
381
        } catch (Exception $ex) {
382
            $response = $this->getJsonReponseFromException($ex);
383
        }
384
385
        return $response;
386
    }
387
388
    /**
389
     * Update widget positions accross the view. If moved widget is a Reference, ask to detach the view from template.
390
     *
391
     * @param int $viewReference The current viewReference
392
     *
393
     * @return JsonResponse
394
     * @Route("/victoire-dcms/widget/get-available-positions/{viewReference}", name="victoire_core_widget_get_available_positions", options={"expose"=true})
395
     */
396
    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...
397
    {
398
        $view = $this->getViewByReferenceId($viewReference);
399
400
        $this->get('victoire_widget_map.builder')->build($view);
401
        $availablePositions = $this->get('victoire_widget_map.builder')->getAvailablePosition($view);
402
403
        return new JsonResponse($availablePositions);
404
    }
405
406
    /**
407
     * Get the json response by the exception and the current user.
408
     *
409
     * @param Exception $ex
410
     *
411
     * @return JsonResponse
412
     */
413
    protected function getJsonReponseFromException(Exception $ex)
414
    {
415
        //services
416
        $securityContext = $this->get('security.context');
417
        $logger = $this->get('logger');
418
419
        //can we see the debug
420
        $isDebugAllowed = $securityContext->isGranted('ROLE_VICTOIRE_PAGE_DEBUG');
421
422
        //whatever is the exception, we log it
423
        $logger->error($ex->getMessage());
424
        $logger->error($ex->getTraceAsString());
425
426
        if ($isDebugAllowed) {
427
            throw $ex;
428
        } else {
429
            //translate the message
430
            $translator = $this->get('translator');
431
432
            //get the translated message
433
            $message = $translator->trans('error_occured', [], 'victoire');
434
435
            $response = new JsonResponse(
436
                [
437
                    'success' => false,
438
                    'message' => $message,
439
                ]
440
            );
441
        }
442
443
        return $response;
444
    }
445
446
    /**
447
     * @param int $referenceId
448
     */
449
    protected function getViewByReferenceId($referenceId)
450
    {
451
        return $this->get('victoire_page.page_helper')->findPageByParameters(['id' => $referenceId]);
452
    }
453
}
454