WidgetRenderer::computeOptions()   B
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 12
nop 2
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\ORMBusinessEntityBundle\Entity\ORMBusinessEntity;
15
use Victoire\Bundle\WidgetBundle\Cache\WidgetCache;
16
use Victoire\Bundle\WidgetBundle\Entity\Widget;
17
use Victoire\Bundle\WidgetBundle\Helper\WidgetHelper;
18
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
19
20
class WidgetRenderer
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
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->getEntity());
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 ($view->getBusinessEntity()->getType() === ORMBusinessEntity::TYPE) {
81
                if ($mock = $this->bepHelper->getEntitiesAllowedQueryBuilder($view, $entityManager)->setMaxResults(1)->getQuery()->getOneOrNullResult()) {
82
                    $widget->setEntity($mock);
83
                }
84
            }
85
        }
86
87
        //the templating service
88
        $templating = $this->container->get('templating');
89
90
        //the content of the widget
91
92
        $parameters = $this->container->get('victoire_widget.widget_content_resolver')->getWidgetContent($widget);
93
        /*
94
         * In some cases, for example, WidgetRender in BusinessEntity mode with magic variables {{entity.id}} transformed
95
         * into the real business entity id, then if in the rendered action, we need to flush, it would persist the
96
         * modified widget which really uncomfortable ;)
97
         */
98
        if ($widget->getMode() == Widget::MODE_BUSINESS_ENTITY) {
99
            $this->container->get('doctrine.orm.entity_manager')->refresh($widget);
100
        }
101
102
        //the template displayed is in the widget bundle (with the potential theme)
103
        $showView = 'show'.ucfirst($widget->getTheme());
104
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName($showView, $widget);
105
106
        return $templating->render($templateName, $parameters);
107
    }
108
109
    /**
110
     * render a widget.
111
     *
112
     * @param Widget $widget
113
     * @param View   $view
114
     *
115
     * @return string
116
     */
117
    public function renderContainer(Widget $widget, View $view)
118
    {
119
        $dispatcher = $this->container->get('event_dispatcher');
120
121
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_PRE_RENDER, new WidgetRenderEvent($widget));
122
123
        $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view);
124
125
        $directive = '';
126
        if ($this->container->get('security.authorization_checker')->isGranted('ROLE_VICTOIRE')) {
127
            $directive = 'widget';
128
        }
129
130
        $id = 'vic-widget-'.$widget->getId().'-container';
131
132
        $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...
133
134
        if ($this->widgetHelper->isCacheEnabled($widget)) {
135
            $content = $this->widgetCache->fetch($widget);
136
            if (null === $content) {
137
                $content = $this->render($widget, $view);
138
                $this->widgetCache->save($widget, $content);
139
            } else {
140
                $this->victoireCollector->addCachedWidget($widget);
141
            }
142
        } else {
143
            $content = $this->render($widget, $view);
144
        }
145
        $html .= $content;
146
        $html .= '</div>'; //close container
147
148
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_POST_RENDER, new WidgetRenderEvent($widget, $html));
149
150
        return $html;
151
    }
152
153
    /**
154
     * prepare a widget to be rendered asynchronously.
155
     *
156
     * @param int $widgetId
157
     *
158
     * @return string
159
     */
160
    public function prepareAsynchronousRender($widgetId)
161
    {
162
        $ngControllerName = 'widget'.$widgetId.'AsynchronousLoadCtrl';
163
        $ngDirectives = sprintf('ng-controller="WidgetAsynchronousLoadController as %s" class="vic-widget" ng-init="%s.init(%d)" ng-bind-html="html"', $ngControllerName, $ngControllerName, $widgetId);
164
        $html = sprintf('<div class="vic-widget-container vic-widget-asynchronous" data-id="%d" %s></div>', $widgetId, $ngDirectives);
165
166
        return $html;
167
    }
168
169
    /**
170
     * render widget unlink action.
171
     *
172
     * @param int  $widgetId
173
     * @param View $view
174
     *
175
     * @return string
176
     */
177
    public function renderUnlinkActionByWidgetId($widgetId, $view)
178
    {
179
        return $this->container->get('templating')->render(
180
            'VictoireCoreBundle:Widget:widgetUnlinkAction.html.twig',
181
            [
182
                'widgetId' => $widgetId,
183
                'view'     => $view,
184
            ]
185
        );
186
    }
187
188
    /**
189
     * Compute slot options.
190
     *
191
     * @param int   $slotId
192
     * @param array $options
193
     *
194
     * @return string
195
     */
196
    public function computeOptions($slotId, $options = [])
197
    {
198
        $slots = $this->container->getParameter('victoire_core.slots');
199
200
        $availableWidgets = $this->container->getParameter('victoire_core.widgets');
201
        $widgets = [];
202
203
        //If the slot is declared in config
204
        if (!empty($slots[$slotId]) && !empty($slots[$slotId]['widgets'])) {
205
            //parse declared widgets
206
            $slotWidgets = array_keys($slots[$slotId]['widgets']);
207
        } elseif (!empty($options['availableWidgets'])) {
208
            $slotWidgets = $options['availableWidgets'];
209
        } else {
210
            //parse all widgets
211
            $slotWidgets = array_keys($availableWidgets);
212
        }
213
214
        foreach ($slotWidgets as $slotWidget) {
215
            $widgetParams = $availableWidgets[$slotWidget];
216
            $widgets[$slotWidget]['params'] = $widgetParams;
217
        }
218
        $slots[$slotId]['availableWidgets'] = $widgets;
219
        if (isset($options['max'])) {
220
            $slots[$slotId]['max'] = $options['max'];
221
        }
222
223
        return $slots[$slotId];
224
    }
225
226
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$widget" missing
Loading history...
227
     * Get the extra classes for the css.
228
     *
229
     * @return string The classes
230
     */
231
    public function getExtraCssClass(Widget $widget)
232
    {
233
        $cssClass = 'v-widget--'.strtolower($this->container->get('victoire_widget.widget_helper')->getWidgetName($widget));
234
235
        return $cssClass;
236
    }
237
}
238