Completed
Pull Request — master (#325)
by Paul
09:55
created

WidgetFormBuilder::callBuildFormSwitchParameters()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 20
rs 9.4285
cc 3
eloc 9
nc 3
nop 6
1
<?php
2
3
namespace Victoire\Bundle\WidgetBundle\Builder;
4
5
use Symfony\Component\DependencyInjection\Container;
6
use Symfony\Component\Form\Form;
7
use Victoire\Bundle\BusinessEntityBundle\Entity\BusinessEntity;
8
use Victoire\Bundle\CoreBundle\Entity\View;
9
use Victoire\Bundle\CoreBundle\Event\WidgetBuildFormEvent;
10
use Victoire\Bundle\CoreBundle\VictoireCmsEvents;
11
use Victoire\Bundle\WidgetBundle\Entity\Widget;
12
13
class WidgetFormBuilder
14
{
15
    private $container;
16
17
    public function __construct(Container $container)
18
    {
19
        $this->container = $container;
20
    }
21
22
    /**
23
     * create form new for a widget.
24
     *
25
     * @param Form   $form
26
     * @param Widget $widget
27
     * @param string $slot
28
     * @param View   $view
29
     * @param string $entity
30
     *
31
     * @return string
32
     */
33
    public function renderNewForm($form, $widget, $slot, View $view, $entity = null)
34
    {
35
        //the template displayed is in the widget bundle
36
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName('new', $widget);
37
38
        return $this->container->get('victoire_templating')->render(
39
            $templateName,
40
            [
41
                'widget' => $widget,
42
                'form'   => $form->createView(),
43
                'slot'   => $slot,
44
                'entity' => $entity,
45
                'view'   => $view,
46
            ]
47
        );
48
    }
49
50
    /**
51
     * render Widget form.
52
     *
53
     * @param Form   $form
54
     * @param Widget $widget
55
     * @param object $entity
56
     *
57
     * @return form
58
     */
59
    public function renderForm(Form $form, Widget $widget, $entity = null)
60
    {
61
        //the template displayed is in the widget bundle
62
        $templateName = $this->container->get('victoire_widget.widget_helper')->getTemplateName('edit', $widget);
63
64
        return $this->container->get('victoire_templating')->render(
65
            $templateName,
66
            [
67
                'widget' => $widget,
68
                'view'   => $this->container->get('victoire_core.current_view')->getCurrentView(),
69
                'form'   => $form->createView(),
70
                'id'     => $widget->getId(),
71
                'entity' => $entity,
72
            ]
73
        );
74
    }
75
76
    /**
77
     * Generates new forms for each available business entities.
78
     *
79
     * @param string           $slot
80
     * @param View             $view
81
     * @param Widget           $widget
82
     * @param BusinessEntity[] $classes
83
     * @param int              $position
84
     *
85
     * @throws \Exception
86
     *
87
     * @return Form[]
88
     */
89
    public function renderNewWidgetForms($slot, View $view, Widget $widget, $classes, $position = null, $parentWidgetMap = null)
90
    {
91
        //the static form
92
        $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...
93
        $forms['static']['main'] = $this->renderNewForm($this->buildForm($widget, $view, null, null, Widget::MODE_STATIC, $slot, $position, $parentWidgetMap), $widget, $slot, $view, null);
94
95
        // Build each form relative to business entities
96
        foreach ($classes as $businessEntity) {
97
            //get the forms for the business entity (entity/query/businessEntity)
98
            $entityForms = $this->buildEntityForms($widget, $view, $businessEntity->getId(), $businessEntity->getClass(), $position, $parentWidgetMap, $slot);
99
100
            //the list of forms
101
            $forms[$businessEntity->getId()] = [];
102
103
            //foreach of the entity form
104
            foreach ($entityForms as $formMode => $entityForm) {
105
                //we add the form
106
                $forms[$businessEntity->getId()][$formMode] = $this->renderNewForm($entityForm, $widget, $slot, $view, $businessEntity->getId());
107
            }
108
        }
109
110
        return $forms;
111
    }
112
113
    /**
114
     * @param Widget $widget
115
     * @param View   $view
116
     * @param string $businessEntityId
117
     * @param string $namespace
118
     * @param integer $position
119
     * @param string $slot
120
     *
121
     * @return array
122
     */
123
    protected function buildEntityForms($widget, View $view, $businessEntityId = null, $namespace = null, $position = null, $parentWidgetMap = null, $slot = null)
124
    {
125
        $forms = [];
126
127
        //get the entity form
128
        $entityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_ENTITY, $slot, $position, $parentWidgetMap);
129
        $forms[Widget::MODE_ENTITY] = $entityForm;
130
131
        //get the query form
132
        $queryForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_QUERY, $slot, $position, $parentWidgetMap);
133
        $forms[Widget::MODE_QUERY] = $queryForm;
134
135
        //get the query form
136
        $businessEntityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_BUSINESS_ENTITY, $slot, $position, $parentWidgetMap);
137
        $forms[Widget::MODE_BUSINESS_ENTITY] = $businessEntityForm;
138
139
        return $forms;
140
    }
141
142
    /**
143
     * create a form with given widget.
144
     *
145
     * @param Widget $widget
146
     * @param View   $view
147
     * @param string $businessEntityId
148
     * @param string $namespace
149
     * @param string $formMode
150
     * @param int    $position
151
     *
152
     * @throws \Exception
153
     *
154
     * @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...
155
     */
156
    public function buildWidgetForm(Widget $widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $position = null, $parentWidgetMap = null, $slotId = null)
157
    {
158
        $router = $this->container->get('router');
159
160
        //test parameters
161 View Code Duplication
        if ($businessEntityId !== null) {
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...
162
            if ($namespace === null) {
163
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
164
            }
165
            if ($formMode === null) {
166
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
167
            }
168
        }
169
170
        $container = $this->container;
171
        $formFactory = $container->get('form.factory');
172
173
        $formAlias = 'victoire_widget_form_'.strtolower($this->container->get('victoire_widget.widget_helper')->getWidgetName($widget));
174
        $filters = [];
175
        if ($this->container->has('victoire_core.filter_chain')) {
176
            $filters = $this->container->get('victoire_core.filter_chain')->getFilters();
177
        }
178
179
        //are we updating or creating the widget?
180
        if ($widget->getId() === null) {
181
            $viewReference = $view->getReference();
182
            $params = [
183
                'viewReference'      => $viewReference->getId(),
184
                'slot'               => $slotId,
185
                'type'               => $widget->getType(), // @todo: use the config
186
                'position'           => $position,
187
                'parentWidgetMap' => $parentWidgetMap,
188
            ];
189
            $action = 'victoire_core_widget_create';
190
            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...
191
                $params['businessEntityId'] = $businessEntityId;
192
                $params['mode'] = $formMode;
193
            } else {
194
                $action = 'victoire_core_widget_create_static';
195
            }
196
            $formUrl = $router->generate($action, $params);
197
        } else {
198
            $viewReference = $widget->getCurrentView()->getReference();
199
            $formUrl = $router->generate('victoire_core_widget_update',
200
                [
201
                    'id'               => $widget->getId(),
202
                    'viewReference'    => $viewReference->getId(),
203
                    'businessEntityId' => $businessEntityId,
204
                    'mode'             => $formMode,
205
                ]
206
            );
207
        }
208
        $params = [
209
            'businessEntityId' => $businessEntityId,
210
            'namespace'        => $namespace,
211
            'mode'             => $formMode,
212
            'action'           => $formUrl,
213
            'method'           => 'POST',
214
            'filters'          => $filters,
215
        ];
216
217
        /** @var Form $mockForm Get the base form to get the name */
218
        $mockForm = $formFactory->create($formAlias, $widget, $params);
219
        //Prefix base name with form mode to avoid to have unique form fields ids
220
        $form = $formFactory->createNamed(
221
            sprintf('%s_%s_%s', $businessEntityId, $formMode, $mockForm->getName()),
222
            $formAlias,
223
            $widget,
224
            $params
225
        );
226
227
        return $form;
228
    }
229
230
    /**
231
     * create a form with given widget.
232
     *
233
     * @param Widget $widget           the widget
234
     * @param View   $view             the page
235
     * @param string $businessEntityId the entity class
236
     * @param string $namespace        the namespace
237
     * @param string $formMode         the form mode
238
     * @param int    $position
239
     *
240
     * @throws \Exception
241
     *
242
     * @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...
243
     */
244
    public function buildForm($widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $slotId = null, $position = null, $parentWidgetMap = null)
245
    {
246
        //test parameters
247 View Code Duplication
        if ($businessEntityId !== null) {
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...
248
            if ($namespace === null) {
249
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
250
            }
251
            if ($formMode === null) {
252
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
253
            }
254
        }
255
256
        $form = $this->buildWidgetForm($widget, $view, $businessEntityId, $namespace, $formMode, $position, $parentWidgetMap, $slotId);
257
258
        //send event
259
        $dispatcher = $this->container->get('event_dispatcher');
260
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_BUILD_FORM, new WidgetBuildFormEvent($widget, $form));
261
262
        return $form;
263
    }
264
265
    /**
266
     * Call the build form with selected parameter switch the parameters
267
     * The call is not the same if an entity is provided or not.
268
     *
269
     * @param Widget $widget
270
     * @param View   $view
271
     * @param string $businessEntityId
272
     * @param int    $position
273
     * @param string $slotId
274
     *
275
     * @throws \Exception
276
     *
277
     * @return \Symfony\Component\Form\Form
278
     */
279
    public function callBuildFormSwitchParameters(Widget $widget, $view, $businessEntityId, $position, $parentWidgetMap, $slotId)
280
    {
281
        $entityClass = null;
282
        //if there is an entity
283
        if ($businessEntityId) {
284
            //get the businessClasses for the widget
285
            $classes = $this->container->get('victoire_core.helper.business_entity_helper')->getBusinessClassesForWidget($widget);
286
287
            //test the result
288
            if (!isset($classes[$businessEntityId])) {
289
                throw new \Exception('The entity '.$businessEntityId.' was not found int the business classes.');
290
            }
291
            //get the class of the entity name
292
            $entityClass = $classes[$businessEntityId]->getClass();
293
        }
294
295
        $form = $this->buildForm($widget, $view, $businessEntityId, $entityClass, $widget->getMode(), $slotId, $position, $parentWidgetMap);
296
297
        return $form;
298
    }
299
}
300