Completed
Push — master ( 7b108e...bec163 )
by Paul
11s
created

WidgetFormBuilder::renderNewQuantumForms()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 12
rs 9.2
cc 4
eloc 7
nc 3
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
                'slot'   => $widget->getWidgetMap()->getSlot(),
73
                'view'   => $this->container->get('victoire_core.current_view')->getCurrentView(),
74
                'form'   => $form->createView(),
75
                'id'     => $widget->getId(),
76
                'entity' => $entity,
77
            ]
78
        );
79
    }
80
81
    /**
82
     * Generates new forms for each available business entities.
83
     *
84
     * @param string           $slot
85
     * @param View             $view
86
     * @param Widget           $widget
87
     * @param BusinessEntity[] $classes
88
     * @param int              $position
89
     * @param null             $parentWidgetMap
90
     * @param int              $position
91
     *
92
     * @throws \Exception
93
     *
94
     * @return \Symfony\Component\Form\Form[]
95
     */
96
    public function renderNewWidgetForms($slot, View $view, Widget $widget, $classes, $position, $parentWidgetMap, $quantum)
97
    {
98
        //the static form
99
        $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...
100
        $forms['static']['main'] = $this->renderNewForm($this->buildForm($widget, $view, null, null, Widget::MODE_STATIC, $slot, $position, $parentWidgetMap, $quantum), $widget, $slot, $view, null);
101
102
        // Build each form relative to business entities
103
        foreach ($classes as $businessEntity) {
104
            //get the forms for the business entity (entity/query/businessEntity)
105
            $entityForms = $this->buildEntityForms($widget, $view, $businessEntity->getId(), $businessEntity->getClass(), $position, $parentWidgetMap, $slot, $quantum);
106
107
            //the list of forms
108
            $forms[$businessEntity->getId()] = [];
109
110
            //foreach of the entity form
111
            foreach ($entityForms as $formMode => $entityForm) {
112
                //we add the form
113
                $forms[$businessEntity->getId()][$formMode] = $this->renderNewForm($entityForm, $widget, $slot, $view, $businessEntity->getId());
114
            }
115
        }
116
117
        return $forms;
118
    }
119
120
    /**
121
     * Generates new forms for each available business entities.
122
     *
123
     * @param string           $slot
124
     * @param View             $view
125
     * @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...
126
     * @param BusinessEntity[] $classes
127
     * @param int              $position
128
     *
129
     * @throws \Exception
130
     *
131
     * @return Form[]
132
     */
133
    public function renderNewQuantumForms($slot, View $view, $widgets, $activeWidget, $classes, $position = null, $parentWidgetMap = null, $quantum = null)
134
    {
135
        $forms = [];
136
        foreach ($widgets as $key => $widget) {
137
            $forms[$key] = $this->renderNewWidgetForms($slot, $view, $widget, $classes, $position, $parentWidgetMap, $quantum ?: $key);
138
            if ($widget === $activeWidget) {
139
                $forms[$key]['active'] = true;
140
            }
141
        }
142
143
        return $forms;
144
    }
145
146
    /**
147
     * @param Widget $widget
148
     * @param View   $view
149
     * @param string $businessEntityId
150
     * @param string $namespace
151
     * @param int    $position
152
     * @param string $slot
153
     *
154
     * @return array
155
     */
156
    protected function buildEntityForms($widget, View $view, $businessEntityId = null, $namespace = null, $position = null, $parentWidgetMap = null, $slot = null, $quantum = null)
157
    {
158
        $forms = [];
159
160
        //get the entity form
161
        $entityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_ENTITY, $slot, $position, $parentWidgetMap, $quantum);
162
        $forms[Widget::MODE_ENTITY] = $entityForm;
163
164
        //get the query form
165
        $queryForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_QUERY, $slot, $position, $parentWidgetMap, $quantum);
166
        $forms[Widget::MODE_QUERY] = $queryForm;
167
168
        //get the query form
169
        $businessEntityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_BUSINESS_ENTITY, $slot, $position, $parentWidgetMap, $quantum);
170
        $forms[Widget::MODE_BUSINESS_ENTITY] = $businessEntityForm;
171
172
        return $forms;
173
    }
174
175
    /**
176
     * create a form with given widget.
177
     *
178
     * @param Widget $widget
179
     * @param View   $view
180
     * @param string $businessEntityId
181
     * @param string $namespace
182
     * @param string $formMode
183
     * @param int    $position
184
     *
185
     * @throws \Exception
186
     *
187
     * @return Form
188
     */
189
    public function buildWidgetForm(Widget $widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $position = null, $parentWidgetMap = null, $slotId = null, $quantum = null)
190
    {
191
        $router = $this->container->get('router');
192
193
        //test parameters
194
        if ($businessEntityId !== null) {
195
            if ($namespace === null) {
196
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
197
            }
198
            if (in_array($formMode, [Widget::MODE_STATIC, null])) {
199
                throw new \Exception('The formMode cannot be null or static if the businessEntityId is given');
200
            }
201
        }
202
203
        $container = $this->container;
204
        $formFactory = $container->get('form.factory');
205
206
        //are we updating or creating the widget?
207
        if ($widget->getId() === null) {
208
            $viewReference = $view->getReference();
209
            $actionParams = [
210
                'viewReference'      => $viewReference->getId(),
211
                'slot'               => $slotId,
212
                'type'               => $widget->getType(), // @todo: use the config
213
                'position'           => $position,
214
                'parentWidgetMap'    => $parentWidgetMap,
215
                'quantum'            => $quantum,
216
            ];
217
            $action = 'victoire_core_widget_create';
218
            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...
219
                $actionParams['businessEntityId'] = $businessEntityId;
220
                $actionParams['mode'] = $formMode;
221
            } else {
222
                $action = 'victoire_core_widget_create_static';
223
            }
224
            $formUrl = $router->generate($action, $actionParams);
225
        } else {
226
            $viewReference = $this->container->get('victoire_core.current_view')->getCurrentView()->getReference();
227
            $formUrl = $router->generate('victoire_core_widget_update',
228
                [
229
                    'id'               => $widget->getId(),
230
                    'viewReference'    => $viewReference->getId(),
231
                    'businessEntityId' => $businessEntityId,
232
                    'mode'             => $formMode,
233
                    'quantum'          => $quantum,
234
                ]
235
            );
236
        }
237
238
        $widgetName = $this->container->get('victoire_widget.widget_helper')->getWidgetName($widget);
239
240
        $widgetFormTypeClass = ClassUtils::getClass(
241
            $this->container->get(
242
                sprintf(
243
                    'victoire.widget.form.%s',
244
                    strtolower($widgetName)
245
                )
246
            )
247
        );
248
249
        $optionsContainer = new WidgetOptionsContainer([
250
            'businessEntityId'      => $businessEntityId,
251
            'namespace'             => $namespace,
252
            'mode'                  => $formMode,
253
            'action'                => $formUrl,
254
            'method'                => 'POST',
255
            'dataSources'           => $this->container->get('victoire_criteria.chain.data_source_chain'),
256
        ]);
257
258
        $event = new WidgetFormCreateEvent($optionsContainer, $widgetFormTypeClass);
259
        $this->container->get('event_dispatcher')->dispatch(WidgetFormEvents::PRE_CREATE, $event);
260
        $this->container->get('event_dispatcher')->dispatch(WidgetFormEvents::PRE_CREATE.'_'.strtoupper($widgetName), $event);
261
262
        /** @var Form $mockForm Get the base form to get the name */
263
        $mockForm = $formFactory->create($widgetFormTypeClass, $widget, $optionsContainer->getOptions());
264
        //Prefix base name with form mode to avoid to have unique form fields ids
265
266
        $form = $formFactory->createNamed(
267
            sprintf('%s_%s_%s_%s', $businessEntityId, $this->convertToString($quantum), $formMode, $mockForm->getName()),
268
            $widgetFormTypeClass,
269
            $widget,
270
            $optionsContainer->getOptions()
271
        );
272
273
        return $form;
274
    }
275
276
    /**
277
     * This method converts a number to an alphabetic char.
278
     * If the number is > 26, convert to aa...az...zz...
279
     *
280
     * @param        $number
281
     * @param string $letter
282
     *
283
     * @return string
284
     */
285
    private function convertToString($number, $letter = 'a', $i = 0)
286
    {
287
        while ($i < $number) {
288
            $i++;
289
            $letter++;
290
        }
291
292
        return $letter;
293
    }
294
295
    /**
296
     * create a form with given widget.
297
     *
298
     * @param Widget $widget           the widget
299
     * @param View   $view             the page
300
     * @param string $businessEntityId the entity class
301
     * @param string $namespace        the namespace
302
     * @param string $formMode         the form mode
303
     * @param int    $position
304
     *
305
     * @throws \Exception
306
     *
307
     * @return Form
308
     */
309
    public function buildForm($widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $slotId = null, $position = null, $parentWidgetMap = null, $quantum = null)
310
    {
311
        //test parameters
312
        if ($businessEntityId !== null) {
313
            if ($namespace === null) {
314
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
315
            }
316
            if ($formMode === null) {
317
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
318
            }
319
        }
320
321
        $form = $this->buildWidgetForm($widget, $view, $businessEntityId, $namespace, $formMode, $position, $parentWidgetMap, $slotId, $quantum);
322
323
        //send event
324
        $dispatcher = $this->container->get('event_dispatcher');
325
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_BUILD_FORM, new WidgetBuildFormEvent($widget, $form));
0 ignored issues
show
Documentation introduced by
$form is of type object<Symfony\Component\Form\Form>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
326
327
        return $form;
328
    }
329
330
    /**
331
     * Call the build form with selected parameter switch the parameters
332
     * The call is not the same if an entity is provided or not.
333
     *
334
     * @param Widget $widget
335
     * @param View   $view
336
     * @param string $businessEntityId
337
     * @param int    $position
338
     * @param string $slotId
339
     *
340
     * @throws \Exception
341
     *
342
     * @return \Symfony\Component\Form\Form
343
     */
344
    public function callBuildFormSwitchParameters(Widget $widget, $view, $businessEntityId, $position, $parentWidgetMap, $slotId, $quantum)
345
    {
346
        $entityClass = null;
347
        //if there is an entity
348
        if ($businessEntityId) {
349
            //get the businessClasses for the widget
350
            $classes = $this->container->get('victoire_core.helper.business_entity_helper')->getBusinessClassesForWidget($widget);
351
352
            //test the result
353
            if (!isset($classes[$businessEntityId])) {
354
                throw new \Exception('The entity '.$businessEntityId.' was not found int the business classes.');
355
            }
356
            //get the class of the entity name
357
            $entityClass = $classes[$businessEntityId]->getClass();
358
        }
359
360
        $form = $this->buildForm($widget, $view, $businessEntityId, $entityClass, $widget->getMode(), $slotId, $position, $parentWidgetMap, $quantum);
361
362
        return $form;
363
    }
364
}
365