Passed
Branch master (3daac1)
by Vincent
07:53
created

CustomForm::setContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
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
 */
46
abstract class CustomForm implements FormInterface
47
{
48
    /**
49
     * @var FormBuilderInterface
50
     */
51
    private $builder;
52
53
    /**
54
     * The inner form
55
     *
56
     * @var FormInterface|null
57
     */
58
    private $form;
59
60
61
    /**
62
     * CustomForm constructor.
63
     *
64
     * @param FormBuilderInterface|null $builder
65
     */
66 38
    public function __construct(?FormBuilderInterface $builder = null)
67
    {
68 38
        $this->builder = $builder ?: new FormBuilder();
69 38
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 18
    public function offsetGet($offset): ChildInterface
75
    {
76 18
        return $this->form()[$offset];
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 8
    public function offsetExists($offset): bool
83
    {
84 8
        return isset($this->form()[$offset]);
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function offsetSet($offset, $value)
91
    {
92
        $this->form()[$offset] = $value;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function offsetUnset($offset)
99
    {
100
        unset($this->form()[$offset]);
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 1
    public function getIterator()
107
    {
108 1
        return $this->form()->getIterator();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 23
    public function submit($data): ElementInterface
115
    {
116 23
        $this->submitTarget()->submit($data);
117
118 23
        return $this;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 2
    public function patch($data): ElementInterface
125
    {
126 2
        $this->submitTarget()->patch($data);
127
128 2
        return $this;
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134 2
    public function import($entity): ElementInterface
135
    {
136 2
        $this->form()->import($entity);
137
138 2
        return $this;
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144 11
    public function value()
145
    {
146 11
        return $this->form()->value();
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152 1
    public function httpValue()
153
    {
154 1
        return $this->form()->httpValue();
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 18
    public function valid(): bool
161
    {
162 18
        return $this->form()->valid();
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 3
    public function error(): FormError
169
    {
170 3
        return $this->form()->error();
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176 3
    public function container(): ?ChildInterface
177
    {
178 3
        return $this->form()->container();
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184 6
    public function setContainer(ChildInterface $container): ElementInterface
185
    {
186 6
        $form = clone $this;
187 6
        $form->form = $this->form()->setContainer($container);
188
189 6
        return $form;
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195 3
    public function root(): RootElementInterface
196
    {
197
        // @todo bad root form ?
198 3
        return $this->form()->root();
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204 1
    public function attach($entity): FormInterface
205
    {
206 1
        $this->form()->attach($entity);
207
208 1
        return $this;
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214 3
    public function view(?HttpFieldPath $field = null): ElementViewInterface
215
    {
216 3
        $form = $this->form();
217
        /** @var FormView $view */
218 3
        $view = $form->container() === null
219 3
            ? $form->root()->view($field)
220 3
            : $form->view($field)
221
        ;
222
223 3
        $view->setType(static::class);
224
225 3
        return $view;
226
    }
227
228
    /**
229
     * Configure the form using the builder
230
     *
231
     * @param FormBuilderInterface $builder
232
     */
233
    abstract protected function configure(FormBuilderInterface $builder): void;
234
235
    /**
236
     * Get (or build) the inner form
237
     *
238
     * @return FormInterface
239
     */
240 37
    final protected function form(): FormInterface
241
    {
242 37
        if ($this->form) {
243 34
            return $this->form;
244
        }
245
246 37
        $this->configure($this->builder);
247
248 37
        return $this->form = $this->builder->buildElement();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->form = $th...builder->buildElement() returns the type Bdf\Form\ElementInterface which includes types incompatible with the type-hinted return Bdf\Form\Aggregate\FormInterface.
Loading history...
249
    }
250
251
    /**
252
     * Get the submit target element
253
     * This element must be used for all submit or patch call
254
     * Handle submit button if the current form is the root element
255
     *
256
     * @return ElementInterface
257
     */
258 25
    final protected function submitTarget(): ElementInterface
259
    {
260 25
        $form = $this->form();
261
262
        // The form is the root form
263 25
        if ($form->container() === null) {
264 23
            return $form->root();
265
        }
266
267 4
        return $form;
268
    }
269
}
270