Completed
Pull Request — master (#325)
by Paul
08:12 queued 49s
created

WidgetFormBuilder::buildWidgetForm()   C

Complexity

Conditions 7
Paths 14

Size

Total Lines 73
Code Lines 49

Duplication

Lines 8
Ratio 10.96 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 8
loc 73
rs 6.6896
cc 7
eloc 49
nc 14
nop 8

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 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, $widgetReference = 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, $widgetReference), $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, $widgetReference, $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
     *
119
     * @return array
120
     */
121
    protected function buildEntityForms($widget, View $view, $businessEntityId = null, $namespace = null, $position = null, $widgetReference = null, $slot = null)
122
    {
123
        $forms = [];
124
125
        //get the entity form
126
        $entityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_ENTITY, $slot, $position, $widgetReference);
127
        $forms[Widget::MODE_ENTITY] = $entityForm;
128
129
        //get the query form
130
        $queryForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_QUERY, $slot, $position, $widgetReference);
131
        $forms[Widget::MODE_QUERY] = $queryForm;
132
133
        //get the query form
134
        $businessEntityForm = $this->buildForm($widget, $view, $businessEntityId, $namespace, Widget::MODE_BUSINESS_ENTITY, $slot, $position, $widgetReference);
135
        $forms[Widget::MODE_BUSINESS_ENTITY] = $businessEntityForm;
136
137
        return $forms;
138
    }
139
140
    /**
141
     * create a form with given widget.
142
     *
143
     * @param Widget $widget
144
     * @param View   $view
145
     * @param string $businessEntityId
146
     * @param string $namespace
147
     * @param string $formMode
148
     * @param int    $position
149
     *
150
     * @throws \Exception
151
     *
152
     * @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...
153
     */
154
    public function buildWidgetForm(Widget $widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $position = null, $widgetReference = null, $slotId = null)
155
    {
156
        $router = $this->container->get('router');
157
158
        //test parameters
159 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...
160
            if ($namespace === null) {
161
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
162
            }
163
            if ($formMode === null) {
164
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
165
            }
166
        }
167
168
        $container = $this->container;
169
        $formFactory = $container->get('form.factory');
170
171
        $formAlias = 'victoire_widget_form_'.strtolower($this->container->get('victoire_widget.widget_helper')->getWidgetName($widget));
172
        $filters = [];
173
        if ($this->container->has('victoire_core.filter_chain')) {
174
            $filters = $this->container->get('victoire_core.filter_chain')->getFilters();
175
        }
176
177
        //are we updating or creating the widget?
178
        if ($widget->getId() === null) {
179
            $viewReference = $view->getReference();
180
            $params = [
181
                'viewReference'      => $viewReference->getId(),
182
                'slot'               => $slotId,
183
                'type'               => $widget->getType(), // @todo: use the config
184
                'position'           => $position,
185
                'widgetMapReference' => $widgetReference,
186
            ];
187
            $action = 'victoire_core_widget_create';
188
            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...
189
                $params['businessEntityId'] = $businessEntityId;
190
                $params['mode'] = $formMode;
191
            } else {
192
                $action = 'victoire_core_widget_create_static';
193
            }
194
            $formUrl = $router->generate($action, $params);
195
        } else {
196
            $viewReference = $widget->getCurrentView()->getReference();
197
            $formUrl = $router->generate('victoire_core_widget_update',
198
                [
199
                    'id'               => $widget->getId(),
200
                    'viewReference'    => $viewReference->getId(),
201
                    'businessEntityId' => $businessEntityId,
202
                    'mode'             => $formMode,
203
                ]
204
            );
205
        }
206
        $params = [
207
            'businessEntityId' => $businessEntityId,
208
            'namespace'        => $namespace,
209
            'mode'             => $formMode,
210
            'action'           => $formUrl,
211
            'method'           => 'POST',
212
            'filters'          => $filters,
213
        ];
214
215
        /** @var Form $mockForm Get the base form to get the name */
216
        $mockForm = $formFactory->create($formAlias, $widget, $params);
217
        //Prefix base name with form mode to avoid to have unique form fields ids
218
        $form = $formFactory->createNamed(
219
            sprintf('%s_%s_%s', $businessEntityId, $formMode, $mockForm->getName()),
220
            $formAlias,
221
            $widget,
222
            $params
223
        );
224
225
        return $form;
226
    }
227
228
    /**
229
     * create a form with given widget.
230
     *
231
     * @param Widget $widget           the widget
232
     * @param View   $view             the page
233
     * @param string $businessEntityId the entity class
234
     * @param string $namespace        the namespace
235
     * @param string $formMode         the form mode
236
     * @param int    $position
237
     *
238
     * @throws \Exception
239
     *
240
     * @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...
241
     */
242
    public function buildForm($widget, View $view, $businessEntityId = null, $namespace = null, $formMode = Widget::MODE_STATIC, $slotId = null, $position = null, $widgetReference = null)
243
    {
244
        //test parameters
245 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...
246
            if ($namespace === null) {
247
                throw new \Exception('The namespace is mandatory if the businessEntityId is given');
248
            }
249
            if ($formMode === null) {
250
                throw new \Exception('The formMode is mandatory if the businessEntityId is given');
251
            }
252
        }
253
254
        $form = $this->buildWidgetForm($widget, $view, $businessEntityId, $namespace, $formMode, $position, $widgetReference, $slotId);
255
256
        //send event
257
        $dispatcher = $this->container->get('event_dispatcher');
258
        $dispatcher->dispatch(VictoireCmsEvents::WIDGET_BUILD_FORM, new WidgetBuildFormEvent($widget, $form));
259
260
        return $form;
261
    }
262
263
    /**
264
     * Call the build form with selected parameter switch the parameters
265
     * The call is not the same if an entity is provided or not.
266
     *
267
     * @param Widget $widget
268
     * @param View   $view
269
     * @param string $businessEntityId
270
     * @param int    $position
271
     *
272
     * @throws \Exception
273
     *
274
     * @return \Symfony\Component\Form\Form
275
     */
276
    public function callBuildFormSwitchParameters(Widget $widget, $view, $businessEntityId, $position, $widgetReference, $slotId)
277
    {
278
        $entityClass = null;
279
        //if there is an entity
280
        if ($businessEntityId) {
281
            //get the businessClasses for the widget
282
            $classes = $this->container->get('victoire_core.helper.business_entity_helper')->getBusinessClassesForWidget($widget);
283
284
            //test the result
285
            if (!isset($classes[$businessEntityId])) {
286
                throw new \Exception('The entity '.$businessEntityId.' was not found int the business classes.');
287
            }
288
            //get the class of the entity name
289
            $entityClass = $classes[$businessEntityId]->getClass();
290
        }
291
292
        $form = $this->buildForm($widget, $view, $businessEntityId, $entityClass, $widget->getMode(), $slotId, $position, $widgetReference);
293
294
        return $form;
295
    }
296
}
297