Completed
Push — master ( 142ca7...5d5121 )
by Leny
06:12
created

WidgetRenderer::renderContainer()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 35
rs 8.5806
cc 4
eloc 22
nc 6
nop 2
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Renderer;
4
5
use Doctrine\Common\Util\ClassUtils;
6
use Doctrine\ORM\EntityManager;
7
use Symfony\Component\DependencyInjection\Container;
8
use Victoire\Bundle\BusinessEntityBundle\Exception\MissingBusinessEntityInstanceException;
9
use Victoire\Bundle\BusinessEntityBundle\Helper\BusinessEntityHelper;
10
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage;
11
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
12
use Victoire\Bundle\CoreBundle\DataCollector\VictoireCollector;
13
use Victoire\Bundle\CoreBundle\Entity\View;
14
use Victoire\Bundle\CoreBundle\Event\WidgetRenderEvent;
15
use Victoire\Bundle\CoreBundle\VictoireCmsEvents;
16
use Victoire\Bundle\WidgetBundle\Cache\WidgetCache;
17
use Victoire\Bundle\WidgetBundle\Entity\Widget;
18
use Victoire\Bundle\WidgetBundle\Helper\WidgetHelper;
19
use Victoire\Bundle\WidgetMapBundle\Entity\Slot;
20
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
21
22
class WidgetRenderer
23
{
24
    private $container;
25
    /**
26
     * @var WidgetCache
27
     */
28
    private $widgetCache;
29
    /**
30
     * @var WidgetHelper
31
     */
32
    private $widgetHelper;
33
    /**
34
     * @var VictoireCollector
35
     */
36
    private $victoireCollector;
37
38
    /**
39
     * WidgetRenderer constructor.
40
     *
41
     * @param Container    $container
42
     * @param WidgetCache  $widgetCache
43
     * @param WidgetHelper $widgetHelper
44
     *
45
     * @internal param Client $redis
46
     */
47
    public function __construct(Container $container, WidgetCache $widgetCache, WidgetHelper $widgetHelper, VictoireCollector $victoireCollector)
48
    {
49
        $this->container = $container;
50
        $this->widgetCache = $widgetCache;
51
        $this->widgetHelper = $widgetHelper;
52
        $this->victoireCollector = $victoireCollector;
53
    }
54
55
    /**
56
     * render the Widget.
57
     *
58
     * @param Widget $widget
59
     * @param View   $view
60
     *
61
     * @return widget show
62
     */
63
    public function render(Widget $widget, View $view)
64
    {
65
        //the mode of display of the widget
66
        $mode = $widget->getMode();
67
68
        //if entity is given and it's not the object, retrieve it and set the entity for the widget
69
        if ($mode == Widget::MODE_BUSINESS_ENTITY && $view instanceof BusinessPage) {
70
            $widget->setEntity($view->getBusinessEntity());
71
        } elseif ($view instanceof BusinessTemplate) {
72
            //We'll try to find a sample entity to mock the widget behavior
73
            /** @var EntityManager $entityManager */
74
            $entityManager = $this->container->get('doctrine.orm.entity_manager');
75
            /** @var BusinessEntityHelper $businessEntityHelper */
76
            $businessEntityHelper = $this->container->get('victoire_core.helper.business_entity_helper');
77
            $businessEntity = $businessEntityHelper->findById($view->getBusinessEntityId());
78
            $queryBuilder = $entityManager->getRepository($businessEntity->getClass())->createQueryBuilder('c');
79
            if (null === $mock = $queryBuilder->setMaxResults(1)->getQuery()->getOneOrNullResult()) {
80
                throw new MissingBusinessEntityInstanceException($businessEntity->getClass());
81
            }
82
            $widget->setEntity($mock);
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
        //the template displayed is in the widget bundle (with the potential theme)
92
        $showView = 'show'.ucfirst($widget->getTheme());
93
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName($showView, $widget);
94
95
        return $templating->render($templateName, $parameters);
96
    }
97
98
    /**
99
     * render a widget.
100
     *
101
     * @param Widget $widget
102
     * @param View   $view
103
     *
104
     * @return string
105
     */
106
    public function renderContainer(Widget $widget, View $view)
107
    {
108
        $dispatcher = $this->container->get('event_dispatcher');
109
110
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_PRE_RENDER, new WidgetRenderEvent($widget));
111
112
        $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view);
113
114
        $directive = '';
115
        if ($this->container->get('security.context')->isGranted('ROLE_VICTOIRE')) {
116
            $directive = 'widget';
117
        }
118
119
        $id = 'vic-widget-'.$widget->getId().'-container';
120
121
        $html = sprintf('<div %s widget-map="%s" id="%s" class="vic-widget-container" data-id="%s">', $directive, $widgetMap->getId(), $id, $widget->getId());
122
123
        if ($this->widgetHelper->isCacheEnabled($widget)) {
124
            $content = $this->widgetCache->fetch($widget);
125
            if (null === $content) {
126
                $content = $this->render($widget, $view);
127
                $this->widgetCache->save($widget, $content);
128
            } else {
129
                $this->victoireCollector->addCachedWidget($widget);
130
            }
131
        } else {
132
            $content = $this->render($widget, $view);
133
        }
134
        $html .= $content;
135
        $html .= '</div>'; //close container
136
137
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_POST_RENDER, new WidgetRenderEvent($widget, $html));
138
139
        return $html;
140
    }
141
142
    /**
143
     * prepare a widget to be rendered asynchronously.
144
     *
145
     * @param int $widgetId
146
     *
147
     * @return string
148
     */
149
    public function prepareAsynchronousRender($widgetId)
150
    {
151
        $ngControllerName = 'widget'.$widgetId.'AsynchronousLoadCtrl';
152
        $ngDirectives = sprintf('ng-controller="WidgetAsynchronousLoadController as %s" class="vic-widget" ng-init="%s.init(%d)" ng-bind-html="html"', $ngControllerName, $ngControllerName, $widgetId);
153
        $html = sprintf('<div class="vic-widget-container vic-widget-asynchronous" data-id="%d" %s></div>', $widgetId, $ngDirectives);
154
155
        return $html;
156
    }
157
158
    /**
159
     * render widget unlink action.
160
     *
161
     * @param int  $widgetId
162
     * @param View $view
163
     *
164
     * @return string
165
     */
166
    public function renderUnlinkActionByWidgetId($widgetId, $view)
167
    {
168
        return $this->container->get('templating')->render(
169
            'VictoireCoreBundle:Widget:widgetUnlinkAction.html.twig',
170
            [
171
                'widgetId' => $widgetId,
172
                'view'     => $view,
173
            ]
174
        );
175
    }
176
177
    /**
178
     * Compute slot options.
179
     *
180
     * @param Slot  $slotId
181
     * @param array $options
182
     *
183
     * @return string
184
     */
185
    public function computeOptions($slotId, $options = [])
186
    {
187
        $slots = $this->container->getParameter('victoire_core.slots');
188
189
        $availableWidgets = $this->container->getParameter('victoire_core.widgets');
190
        $widgets = [];
191
192
        //If the slot is declared in config
193
        if (!empty($slots[$slotId]) && !empty($slots[$slotId]['widgets'])) {
194
            //parse declared widgets
195
            $slotWidgets = array_keys($slots[$slotId]['widgets']);
196
        } elseif (!empty($options['availableWidgets'])) {
197
            $slotWidgets = $options['availableWidgets'];
198
        } else {
199
            //parse all widgets
200
            $slotWidgets = array_keys($availableWidgets);
201
        }
202
203
        foreach ($slotWidgets as $slotWidget) {
204
            $widgetParams = $availableWidgets[$slotWidget];
205
            $widgets[$slotWidget]['params'] = $widgetParams;
206
        }
207
        $slots[$slotId]['availableWidgets'] = $widgets;
208
        if (isset($options['max'])) {
209
            $slots[$slotId]['max'] = $options['max'];
210
        }
211
212
        return $slots[$slotId];
213
    }
214
215
    /**
216
     * Get the extra classes for the css.
217
     *
218
     * @return string The classes
219
     */
220
    public function getExtraCssClass(Widget $widget)
221
    {
222
        $cssClass = 'vic-widget-'.strtolower($this->container->get('victoire_widget.widget_helper')->getWidgetName($widget));
223
224
        return $cssClass;
225
    }
226
}
227