Passed
Push — master ( 2635eb...63381f )
by Sébastien
04:45
created

CustomForm::postConfigure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 0
c 0
b 0
f 0
dl 0
loc 2
ccs 1
cts 1
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Bdf\Form\Custom;
4
5
use Bdf\Form\Aggregate\FormBuilder;
6
use Bdf\Form\Aggregate\FormBuilderInterface;
7
use Bdf\Form\Aggregate\FormInterface;
8
use Bdf\Form\Aggregate\View\FormView;
9
use Bdf\Form\Child\ChildInterface;
10
use Bdf\Form\Child\Http\HttpFieldPath;
11
use Bdf\Form\ElementInterface;
12
use Bdf\Form\Error\FormError;
13
use Bdf\Form\RootElementInterface;
14
use Bdf\Form\View\ElementViewInterface;
15
16
/**
17
 * Utility class for simply create a custom form element
18
 *
19
 * <code>
20
 * // Declaration
21
 * class MyForm extends CustomForm
22
 * {
23
 *     public function configure(FormBuilderInterface $builder)
24
 *     {
25
 *         $builder->generates(MyEntity::class);
26
 *         $builder->string('foo')->setter();
27
 *     }
28
 * }
29
 *
30
 * // Usage
31
 * $form = new MyForm(); // Directly instantiate the form
32
 * $form = $this->registry->elementBuilder(MyForm::class)->buildElement(); // Use registry and builder
33
 *
34
 * if (!$form->submit($request->post())->valid()) {
35
 *     return new JsonResponse($form->error()->print(new FormErrorFormat()), 400);
36
 * }
37
 *
38
 * $entity = $form->value();
39
 * $this->service->handle($entity);
40
 *
41
 * return new Response('OK', 200);
42
 * </code>
43
 *
44
 * @todo implements root form interface ?
45
 * @template T
46
 * @implements FormInterface<T>
47
 */
48
abstract class CustomForm implements FormInterface
49
{
50
    /**
51
     * @var FormBuilderInterface
52
     */
53
    private $builder;
54
55
    /**
56
     * The inner form
57
     *
58
     * @var FormInterface<T>|null
59
     */
60
    private $form;
61
62
63
    /**
64
     * CustomForm constructor.
65
     *
66
     * @param FormBuilderInterface|null $builder
67
     */
68 40
    public function __construct(?FormBuilderInterface $builder = null)
69
    {
70 40
        $this->builder = $builder ?: new FormBuilder();
71 40
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 18
    public function offsetGet($offset): ChildInterface
77
    {
78 18
        return $this->form()[$offset];
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 8
    public function offsetExists($offset): bool
85
    {
86 8
        return isset($this->form()[$offset]);
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function offsetSet($offset, $value)
93
    {
94
        $this->form()[$offset] = $value;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function offsetUnset($offset)
101
    {
102
        unset($this->form()[$offset]);
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 1
    public function getIterator()
109
    {
110 1
        return $this->form()->getIterator();
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 25
    public function submit($data): ElementInterface
117
    {
118 25
        $this->submitTarget()->submit($data);
119
120 25
        return $this;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 2
    public function patch($data): ElementInterface
127
    {
128 2
        $this->submitTarget()->patch($data);
129
130 2
        return $this;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136 2
    public function import($entity): ElementInterface
137
    {
138 2
        $this->form()->import($entity);
139
140 2
        return $this;
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 11
    public function value()
147
    {
148 11
        return $this->form()->value();
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 1
    public function httpValue()
155
    {
156 1
        return $this->form()->httpValue();
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162 18
    public function valid(): bool
163
    {
164 18
        return $this->form()->valid();
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170 4
    public function error(?HttpFieldPath $field = null): FormError
171
    {
172 4
        return $this->form()->error($field);
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 3
    public function container(): ?ChildInterface
179
    {
180 3
        return $this->form()->container();
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 6
    public function setContainer(ChildInterface $container): ElementInterface
187
    {
188 6
        $form = clone $this;
189 6
        $form->form = $this->form()->setContainer($container);
190
191 6
        return $form;
192
    }
193
194
    /**
195
     * {@inheritdoc}
196
     */
197 3
    public function root(): RootElementInterface
198
    {
199
        // @todo bad root form ?
200 3
        return $this->form()->root();
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206 1
    public function attach($entity): FormInterface
207
    {
208 1
        $this->form()->attach($entity);
209
210 1
        return $this;
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 4
    public function view(?HttpFieldPath $field = null): ElementViewInterface
217
    {
218 4
        $form = $this->form();
219
        /** @var FormView $view */
220 4
        $view = $form->container() === null
221 4
            ? $form->root()->view($field)
222 4
            : $form->view($field)
223
        ;
224
225 4
        $view->setType(static::class);
226
227 4
        return $view;
228
    }
229
230
    /**
231
     * Configure the form using the builder
232
     *
233
     * @param FormBuilderInterface $builder
234
     */
235
    abstract protected function configure(FormBuilderInterface $builder): void;
236
237
    /**
238
     * Override this method to hook the inner form build
239
     *
240
     * <code>
241
     * class MyForm extends CustomForm
242
     * {
243
     *     public $foo;
244
     *     public function configure(FormBuilderInterface $builder): void
245
     *     {
246
     *         $builder->string('foo');
247
     *     }
248
     *
249
     *     public function postConfigure(FormInterface $form): void
250
     *     {
251
     *         // Get the "foo" children
252
     *         $this->foo = $form['foo'];
253
     *     }
254
     * }
255
     * </code>
256
     *
257
     * @param FormInterface $form The inner form built instance
258
     */
259 38
    public function postConfigure(FormInterface $form): void
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

259
    public function postConfigure(/** @scrutinizer ignore-unused */ FormInterface $form): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
260
    {
261
        // to overrides
262 38
    }
263
264
    /**
265
     * Get (or build) the inner form
266
     *
267
     * @return FormInterface<T>
268
     */
269 39
    final protected function form(): FormInterface
270
    {
271 39
        if ($this->form) {
272 35
            return $this->form;
273
        }
274
275 39
        $this->configure($this->builder);
276
277 39
        $form = $this->form = $this->builder->buildElement();
278 39
        $this->postConfigure($form);
279
280 39
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type Bdf\Form\ElementInterface which includes types incompatible with the type-hinted return Bdf\Form\Aggregate\FormInterface.
Loading history...
281
    }
282
283
    /**
284
     * Get the submit target element
285
     * This element must be used for all submit or patch call
286
     * Handle submit button if the current form is the root element
287
     *
288
     * @return ElementInterface
289
     */
290 27
    final protected function submitTarget(): ElementInterface
291
    {
292 27
        $form = $this->form();
293
294
        // The form is the root form
295 27
        if ($form->container() === null) {
296 25
            return $form->root();
297
        }
298
299 4
        return $form;
300
    }
301
}
302