Completed
Push — master ( 2c86a7...690ed0 )
by
unknown
36:26 queued 28:50
created

WidgetRenderer   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 19
lcom 1
cbo 11
dl 0
loc 213
rs 10
c 1
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
B render() 0 35 5
B renderContainer() 0 35 4
A prepareAsynchronousRender() 0 8 1
A renderUnlinkActionByWidgetId() 0 10 1
B computeOptions() 0 29 6
A getExtraCssClass() 0 6 1
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Renderer;
4
5
use Doctrine\ORM\EntityManager;
6
use Symfony\Component\DependencyInjection\Container;
7
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage;
8
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
9
use Victoire\Bundle\BusinessPageBundle\Helper\BusinessPageHelper;
10
use Victoire\Bundle\CoreBundle\DataCollector\VictoireCollector;
11
use Victoire\Bundle\CoreBundle\Entity\View;
12
use Victoire\Bundle\CoreBundle\Event\WidgetRenderEvent;
13
use Victoire\Bundle\CoreBundle\VictoireCmsEvents;
14
use Victoire\Bundle\WidgetBundle\Cache\WidgetCache;
15
use Victoire\Bundle\WidgetBundle\Entity\Widget;
16
use Victoire\Bundle\WidgetBundle\Helper\WidgetHelper;
17
use Victoire\Bundle\WidgetMapBundle\Entity\Slot;
18
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
19
20
class WidgetRenderer
21
{
22
    private $container;
23
    /**
24
     * @var WidgetCache
25
     */
26
    private $widgetCache;
27
    /**
28
     * @var WidgetHelper
29
     */
30
    private $widgetHelper;
31
    /**
32
     * @var VictoireCollector
33
     */
34
    private $victoireCollector;
35
    /**
36
     * @var BusinessPageHelper
37
     */
38
    private $bepHelper;
39
40
    /**
41
     * WidgetRenderer constructor.
42
     *
43
     * @param Container          $container
44
     * @param WidgetCache        $widgetCache
45
     * @param WidgetHelper       $widgetHelper
46
     * @param VictoireCollector  $victoireCollector
47
     * @param BusinessPageHelper $bepHelper
48
     *
49
     * @internal param Client $redis
50
     */
51
    public function __construct(Container $container, WidgetCache $widgetCache, WidgetHelper $widgetHelper, VictoireCollector $victoireCollector, BusinessPageHelper $bepHelper)
52
    {
53
        $this->container = $container;
54
        $this->widgetCache = $widgetCache;
55
        $this->widgetHelper = $widgetHelper;
56
        $this->victoireCollector = $victoireCollector;
57
        $this->bepHelper = $bepHelper;
58
    }
59
60
    /**
61
     * render the Widget.
62
     *
63
     * @param Widget $widget
64
     * @param View   $view
65
     *
66
     * @return widget show
67
     */
68
    public function render(Widget $widget, View $view)
69
    {
70
        //the mode of display of the widget
71
        $mode = $widget->getMode();
72
73
        //if entity is given and it's not the object, retrieve it and set the entity for the widget
74
        if ($mode == Widget::MODE_BUSINESS_ENTITY && $view instanceof BusinessPage) {
75
            $widget->setEntity($view->getBusinessEntity());
76
        } elseif ($view instanceof BusinessTemplate) {
77
            //We'll try to find a sample entity to mock the widget behavior
78
            /** @var EntityManager $entityManager */
79
            $entityManager = $this->container->get('doctrine.orm.entity_manager');
80
            if ($mock = $this->bepHelper->getEntitiesAllowedQueryBuilder($view, $entityManager)->setMaxResults(1)->getQuery()->getOneOrNullResult()) {
81
                $widget->setEntity($mock);
82
            }
83
        }
84
85
        //the templating service
86
        $templating = $this->container->get('templating');
87
88
        //the content of the widget
89
        $parameters = $this->container->get('victoire_widget.widget_content_resolver')->getWidgetContent($widget);
90
        /*
91
         * In some cases, for example, WidgetRender in BusinessEntity mode with magic variables {{entity.id}} transformed
92
         * into the real business entity id, then if in the rendered action, we need to flush, it would persist the
93
         * modified widget which really uncomfortable ;)
94
         */
95
        $this->container->get('doctrine.orm.entity_manager')->refresh($widget);
96
97
        //the template displayed is in the widget bundle (with the potential theme)
98
        $showView = 'show'.ucfirst($widget->getTheme());
99
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName($showView, $widget);
100
101
        return $templating->render($templateName, $parameters);
102
    }
103
104
    /**
105
     * render a widget.
106
     *
107
     * @param Widget $widget
108
     * @param View   $view
109
     *
110
     * @return string
111
     */
112
    public function renderContainer(Widget $widget, View $view)
113
    {
114
        $dispatcher = $this->container->get('event_dispatcher');
115
116
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_PRE_RENDER, new WidgetRenderEvent($widget));
117
118
        $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view);
119
120
        $directive = '';
121
        if ($this->container->get('security.authorization_checker')->isGranted('ROLE_VICTOIRE')) {
122
            $directive = 'widget';
123
        }
124
125
        $id = 'vic-widget-'.$widget->getId().'-container';
126
127
        $html = sprintf('<div %s widget-map="%s" id="%s" class="vic-widget-container" data-id="%s">', $directive, $widgetMap->getId(), $id, $widget->getId());
0 ignored issues
show
Bug introduced by
The method getId does only exist in Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap, but not in Victoire\Bundle\WidgetMa...getMapNotFoundException.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
128
129
        if ($this->widgetHelper->isCacheEnabled($widget)) {
130
            $content = $this->widgetCache->fetch($widget);
131
            if (null === $content) {
132
                $content = $this->render($widget, $view);
133
                $this->widgetCache->save($widget, $content);
134
            } else {
135
                $this->victoireCollector->addCachedWidget($widget);
136
            }
137
        } else {
138
            $content = $this->render($widget, $view);
139
        }
140
        $html .= $content;
141
        $html .= '</div>'; //close container
142
143
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_POST_RENDER, new WidgetRenderEvent($widget, $html));
144
145
        return $html;
146
    }
147
148
    /**
149
     * prepare a widget to be rendered asynchronously.
150
     *
151
     * @param int $widgetId
152
     *
153
     * @return string
154
     */
155
    public function prepareAsynchronousRender($widgetId)
156
    {
157
        $ngControllerName = 'widget'.$widgetId.'AsynchronousLoadCtrl';
158
        $ngDirectives = sprintf('ng-controller="WidgetAsynchronousLoadController as %s" class="vic-widget" ng-init="%s.init(%d)" ng-bind-html="html"', $ngControllerName, $ngControllerName, $widgetId);
159
        $html = sprintf('<div class="vic-widget-container vic-widget-asynchronous" data-id="%d" %s></div>', $widgetId, $ngDirectives);
160
161
        return $html;
162
    }
163
164
    /**
165
     * render widget unlink action.
166
     *
167
     * @param int  $widgetId
168
     * @param View $view
169
     *
170
     * @return string
171
     */
172
    public function renderUnlinkActionByWidgetId($widgetId, $view)
173
    {
174
        return $this->container->get('templating')->render(
175
            'VictoireCoreBundle:Widget:widgetUnlinkAction.html.twig',
176
            [
177
                'widgetId' => $widgetId,
178
                'view'     => $view,
179
            ]
180
        );
181
    }
182
183
    /**
184
     * Compute slot options.
185
     *
186
     * @param Slot  $slotId
187
     * @param array $options
188
     *
189
     * @return string
190
     */
191
    public function computeOptions($slotId, $options = [])
192
    {
193
        $slots = $this->container->getParameter('victoire_core.slots');
194
195
        $availableWidgets = $this->container->getParameter('victoire_core.widgets');
196
        $widgets = [];
197
198
        //If the slot is declared in config
199
        if (!empty($slots[$slotId]) && !empty($slots[$slotId]['widgets'])) {
200
            //parse declared widgets
201
            $slotWidgets = array_keys($slots[$slotId]['widgets']);
202
        } elseif (!empty($options['availableWidgets'])) {
203
            $slotWidgets = $options['availableWidgets'];
204
        } else {
205
            //parse all widgets
206
            $slotWidgets = array_keys($availableWidgets);
207
        }
208
209
        foreach ($slotWidgets as $slotWidget) {
210
            $widgetParams = $availableWidgets[$slotWidget];
211
            $widgets[$slotWidget]['params'] = $widgetParams;
212
        }
213
        $slots[$slotId]['availableWidgets'] = $widgets;
214
        if (isset($options['max'])) {
215
            $slots[$slotId]['max'] = $options['max'];
216
        }
217
218
        return $slots[$slotId];
219
    }
220
221
    /**
222
     * Get the extra classes for the css.
223
     *
224
     * @return string The classes
225
     */
226
    public function getExtraCssClass(Widget $widget)
227
    {
228
        $cssClass = 'vic-widget-'.strtolower($this->container->get('victoire_widget.widget_helper')->getWidgetName($widget));
229
230
        return $cssClass;
231
    }
232
}
233