Completed
Pull Request — master (#375)
by Paul
06:22
created

WidgetFormBuilder::renderNewQuantumForms()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 3
eloc 7
nc 3
nop 7
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Builder;
4
5
use Doctrine\Common\Util\ClassUtils;
6
use Symfony\Component\DependencyInjection\Container;
7
use Symfony\Component\Form\Form;
8
use Victoire\Bundle\BusinessEntityBundle\Entity\BusinessEntity;
9
use Victoire\Bundle\CoreBundle\Entity\View;
10
use Victoire\Bundle\CoreBundle\Event\WidgetBuildFormEvent;
11
use Victoire\Bundle\CoreBundle\VictoireCmsEvents;
12
use Victoire\Bundle\WidgetBundle\Entity\Widget;
13
use Victoire\Bundle\WidgetBundle\Event\WidgetFormCreateEvent;
14
use Victoire\Bundle\WidgetBundle\Event\WidgetFormEvents;
15
use Victoire\Bundle\WidgetBundle\Form\WidgetOptionsContainer;
16
17
class WidgetFormBuilder
18
{
19
    private $container;
20
21
    public function __construct(Container $container)
22
    {
23
        $this->container = $container;
24
    }
25
26
    /**
27
     * create form new for a widget.
28
     *
29
     * @param Form   $form
30
     * @param Widget $widget
31
     * @param string $slot
32
     * @param View   $view
33
     * @param string $entity
34
     *
35
     * @return string
36
     */
37
    public function renderNewForm($form, $widget, $slot, View $view, $entity = null)
38
    {
39
        //the template displayed is in the widget bundle
40
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName('new', $widget);
41
42
        return $this->container->get('templating')->render(
43
            $templateName,
44
            [
45
                'widget' => $widget,
46
                'form'   => $form->createView(),
47
                'slot'   => $slot,
48
                'entity' => $entity,
49
                'view'   => $view,
50
            ]
51
        );
52
    }
53
54
    /**
55
     * render Widget form.
56
     *
57
     * @param Form   $form
58
     * @param Widget $widget
59
     * @param object $entity
60
     *
61
     * @return form
62
     */
63
    public function renderForm(Form $form, Widget $widget, $entity = null)
64
    {
65
        //the template displayed is in the widget bundle
66
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName('edit', $widget);
67
68
        return $this->container->get('templating')->render(
69
            $templateName,
70
            [
71
                'widget' => $widget,
72
                'view'   => $this->container->get('victoire_core.current_view')->getCurrentView(),
73
                'form'   => $form->createView(),
74
                'id'     => $widget->getId(),
75
                'entity' => $entity,
76
            ]
77
        );
78
    }
79
80
    /**
81
     * Generates new forms for each available business entities.
82
     *
83
     * @param string           $slot
84
     * @param View             $view
85
     * @param Widget           $widget
86
     * @param BusinessEntity[] $classes
87
     * @param int              $position
88
     *
89
     * @throws \Exception
90
     *
91
     * @return Form[]
92
     */
93
    public function renderNewWidgetForms($slot, View $view, Widget $widget, $classes, $position = null, $parentWidgetMap = null)
94
    {
95
        //the static form
96
        $forms['static'] = [];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$forms was never initialized. Although not strictly required by PHP, it is generally a good practice to add $forms = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
97
        $forms['static']['main'] = $this->renderNewForm($this->buildForm($widget, $view, null, null, Widget::MODE_STATIC, $slot, $position, $parentWidgetMap), $widget, $slot, $view, null);
98
99
        // Build each form relative to business entities
100
        foreach ($classes as $businessEntity) {
101
            //get the forms for the business entity (entity/query/businessEntity)
102
            $entityForms = $this->buildEntityForms($widget, $view, $businessEntity->getId(), $businessEntity->getClass(), $position, $parentWidgetMap, $slot);
103
104
            //the list of forms
105
            $forms[$businessEntity->getId()] = [];
106
107
            //foreach of the entity form
108
            foreach ($entityForms as $formMode => $entityForm) {
109
                //we add the form
110
                $forms[$businessEntity->getId()][$formMode] = $this->renderNewForm($entityForm, $widget, $slot, $view, $businessEntity->getId());
111
            }
112
        }
113
114
        return $forms;
115
    }
116
    /**
117
     * Generates new forms for each available business entities.
118
     *
119
     * @param string           $slot
120
     * @param View             $view
121
     * @param Widget           $widget
0 ignored issues
show
Documentation introduced by
There is no parameter named $widget. Did you maybe mean $widgets?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
122
     * @param BusinessEntity[] $classes
123
     * @param int              $position
124
     *
125
     * @throws \Exception
126
     *
127
     * @return Form[]
128
     */
129
    public function renderNewQuantumForms($slot, View $view, $widgets, $activeWidget, $classes, $position = null, $parentWidgetMap = null)
130
    {
131
        $forms = [];
132
        foreach ($widgets as $key => $widget) {
133
            $forms[$key] = $this->renderNewWidgetForms($slot, $view, $widget, $classes, $position, $parentWidgetMap);
134
            if ($widget === $activeWidget) {
135
                $forms[$key]['active'] = true;
136
            }
137
        }
138
139
        return $forms;
140
    }
141
142
    /**
143
     * @param Widget $widget
144
     * @param View   $view
145
     * @param string $businessEntityId
146
     * @param string $namespace
147
     * @param int    $position
148
     * @param string $slot
149
     *
150
     * @return array
151
     */
152
    protected function buildEntityForms($widget, View $view, $businessEntityId = null, $namespace = null, $position = null, $parentWidgetMap = null, $slot = null)
153
    {
154
        $forms = [];
155
156
        //get the entity form
157
        $entityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_ENTITY, $slot, $position, $parentWidgetMap);
158
        $forms[Widget::MODE_ENTITY] = $entityForm;
159
160
        //get the query form
161
        $queryForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_QUERY, $slot, $position, $parentWidgetMap);
162
        $forms[Widget::MODE_QUERY] = $queryForm;
163
164
        //get the query form
165
        $businessEntityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_BUSINESS_ENTITY, $slot, $position, $parentWidgetMap);
166
        $forms[Widget::MODE_BUSINESS_ENTITY] = $businessEntityForm;
167
168
        return $forms;
169
    }
170
171
    /**
172
     * create a form with given widget.
173
     *
174
     * @param Widget $widget
175
     * @param View   $view
176
     * @param string $businessEntityId
177
     * @param string $namespace
178
     * @param string $formMode
179
     * @param int    $position
180
     *
181
     * @throws \Exception
182
     *
183
     * @return $form
0 ignored issues
show
Documentation introduced by
The doc-type $form could not be parsed: Unknown type name "$form" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
184
     */
185
    public function buildWidgetForm(Widget $widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $position = null, $parentWidgetMap = null, $slotId = null)
186
    {
187
        $router = $this->container->get('router');
188
189
        //test parameters
190
        if ($businessEntityId !== null) {
191
            if ($namespace === null) {
192
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
193
            }
194
            if (in_array($formMode, [Widget::MODE_STATIC, null])) {
195
                throw new \Exception('The formMode cannot be null or static if the businessEntityId is given');
196
            }
197
        }
198
199
        $container = $this->container;
200
        $formFactory = $container->get('form.factory');
201
202
        //are we updating or creating the widget?
203
        if ($widget->getId() === null) {
204
            $viewReference = $view->getReference();
205
            $actionParams = [
206
                'viewReference'      => $viewReference->getId(),
207
                'slot'               => $slotId,
208
                'type'               => $widget->getType(), // @todo: use the config
209
                'position'           => $position,
210
                'parentWidgetMap'    => $parentWidgetMap,
211
            ];
212
            $action = 'victoire_core_widget_create';
213
            if ($businessEntityId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $businessEntityId of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
214
                $actionParams['businessEntityId'] = $businessEntityId;
215
                $actionParams['mode'] = $formMode;
216
            } else {
217
                $action = 'victoire_core_widget_create_static';
218
            }
219
            $formUrl = $router->generate($action, $actionParams);
220
        } else {
221
            $viewReference = $this->container->get('victoire_core.current_view')->getCurrentView()->getReference();
222
            $formUrl = $router->generate('victoire_core_widget_update',
223
                [
224
                    'id'               => $widget->getId(),
225
                    'viewReference'    => $viewReference->getId(),
226
                    'businessEntityId' => $businessEntityId,
227
                    'mode'             => $formMode,
228
                ]
229
            );
230
        }
231
232
        $widgetName = $this->container->get('victoire_widget.widget_helper')->getWidgetName($widget);
233
234
        $widgetFormTypeClass = ClassUtils::getClass(
235
            $this->container->get(
236
                sprintf(
237
                    'victoire.widget.form.%s',
238
                    strtolower($widgetName)
239
                )
240
            )
241
        );
242
243
        $optionsContainer = new WidgetOptionsContainer([
244
            'businessEntityId' => $businessEntityId,
245
            'namespace'        => $namespace,
246
            'mode'             => $formMode,
247
            'action'           => $formUrl,
248
            'method'           => 'POST',
249
            'dataSources'           => $this->container->get('victoire_criteria.chain.data_source_chain'),
250
        ]);
251
252
        $event = new WidgetFormCreateEvent($optionsContainer, $widgetFormTypeClass);
253
        $this->container->get('event_dispatcher')->dispatch(WidgetFormEvents::PRE_CREATE, $event);
254
        $this->container->get('event_dispatcher')->dispatch(WidgetFormEvents::PRE_CREATE.'_'.strtoupper($widgetName), $event);
255
256
        /** @var Form $mockForm Get the base form to get the name */
257
        $mockForm = $formFactory->create($widgetFormTypeClass, $widget, $optionsContainer->getOptions());
258
        //Prefix base name with form mode to avoid to have unique form fields ids
259
        $form = $formFactory->createNamed(
260
            sprintf('%s_%s_%s', $businessEntityId, $formMode, $mockForm->getName()),
261
            $widgetFormTypeClass,
262
            $widget,
263
            $optionsContainer->getOptions()
264
        );
265
266
        return $form;
267
    }
268
269
    /**
270
     * create a form with given widget.
271
     *
272
     * @param Widget $widget           the widget
273
     * @param View   $view             the page
274
     * @param string $businessEntityId the entity class
275
     * @param string $namespace        the namespace
276
     * @param string $formMode         the form mode
277
     * @param int    $position
278
     *
279
     * @throws \Exception
280
     *
281
     * @return $form
0 ignored issues
show
Documentation introduced by
The doc-type $form could not be parsed: Unknown type name "$form" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
282
     */
283
    public function buildForm($widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $slotId = null, $position = null, $parentWidgetMap = null)
284
    {
285
        //test parameters
286
        if ($businessEntityId !== null) {
287
            if ($namespace === null) {
288
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
289
            }
290
            if ($formMode === null) {
291
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
292
            }
293
        }
294
295
        $form = $this->buildWidgetForm($widget, $view, $businessEntityId, $namespace, $formMode, $position, $parentWidgetMap, $slotId);
296
297
        //send event
298
        $dispatcher = $this->container->get('event_dispatcher');
299
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_BUILD_FORM, new WidgetBuildFormEvent($widget, $form));
300
301
        return $form;
302
    }
303
304
    /**
305
     * Call the build form with selected parameter switch the parameters
306
     * The call is not the same if an entity is provided or not.
307
     *
308
     * @param Widget $widget
309
     * @param View   $view
310
     * @param string $businessEntityId
311
     * @param int    $position
312
     * @param string $slotId
313
     *
314
     * @throws \Exception
315
     *
316
     * @return \Symfony\Component\Form\Form
317
     */
318
    public function callBuildFormSwitchParameters(Widget $widget, $view, $businessEntityId, $position, $parentWidgetMap, $slotId)
319
    {
320
        $entityClass = null;
321
        //if there is an entity
322
        if ($businessEntityId) {
323
            //get the businessClasses for the widget
324
            $classes = $this->container->get('victoire_core.helper.business_entity_helper')->getBusinessClassesForWidget($widget);
325
326
            //test the result
327
            if (!isset($classes[$businessEntityId])) {
328
                throw new \Exception('The entity '.$businessEntityId.' was not found int the business classes.');
329
            }
330
            //get the class of the entity name
331
            $entityClass = $classes[$businessEntityId]->getClass();
332
        }
333
334
        $form = $this->buildForm($widget, $view, $businessEntityId, $entityClass, $widget->getMode(), $slotId, $position, $parentWidgetMap);
335
336
        return $form;
337
    }
338
}
339