Completed
Push — master ( a13290...ae4efa )
by Song
30s
created

EmbeddedForm::setParentWidgetForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Form;
4
5
use Encore\Admin\Form;
6
use Encore\Admin\Widgets\Form as WidgetForm;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Collection;
9
10
/**
11
 * Class EmbeddedForm.
12
 *
13
 * @method Field\Text           text($column, $label = '')
14
 * @method Field\Checkbox       checkbox($column, $label = '')
15
 * @method Field\Radio          radio($column, $label = '')
16
 * @method Field\Select         select($column, $label = '')
17
 * @method Field\MultipleSelect multipleSelect($column, $label = '')
18
 * @method Field\Textarea       textarea($column, $label = '')
19
 * @method Field\Hidden         hidden($column, $label = '')
20
 * @method Field\Id             id($column, $label = '')
21
 * @method Field\Ip             ip($column, $label = '')
22
 * @method Field\Url            url($column, $label = '')
23
 * @method Field\Color          color($column, $label = '')
24
 * @method Field\Email          email($column, $label = '')
25
 * @method Field\Mobile         mobile($column, $label = '')
26
 * @method Field\Slider         slider($column, $label = '')
27
 * @method Field\Map            map($latitude, $longitude, $label = '')
28
 * @method Field\Editor         editor($column, $label = '')
29
 * @method Field\File           file($column, $label = '')
30
 * @method Field\Image          image($column, $label = '')
31
 * @method Field\Date           date($column, $label = '')
32
 * @method Field\Datetime       datetime($column, $label = '')
33
 * @method Field\Time           time($column, $label = '')
34
 * @method Field\Year           year($column, $label = '')
35
 * @method Field\Month          month($column, $label = '')
36
 * @method Field\DateRange      dateRange($start, $end, $label = '')
37
 * @method Field\DateTimeRange  datetimeRange($start, $end, $label = '')
38
 * @method Field\TimeRange      timeRange($start, $end, $label = '')
39
 * @method Field\Number         number($column, $label = '')
40
 * @method Field\Currency       currency($column, $label = '')
41
 * @method Field\HasMany        hasMany($relationName, $callback)
42
 * @method Field\SwitchField    switch($column, $label = '')
43
 * @method Field\Display        display($column, $label = '')
44
 * @method Field\Rate           rate($column, $label = '')
45
 * @method Field\Divide         divider()
46
 * @method Field\Password       password($column, $label = '')
47
 * @method Field\Decimal        decimal($column, $label = '')
48
 * @method Field\Html           html($html, $label = '')
49
 * @method Field\Tags           tags($column, $label = '')
50
 * @method Field\Icon           icon($column, $label = '')
51
 * @method Field\Embeds         embeds($column, $label = '')
52
 */
53
class EmbeddedForm
54
{
55
    /**
56
     * @var Form|WidgetForm
57
     */
58
    protected $parent = null;
59
60
    /**
61
     * Fields in form.
62
     *
63
     * @var Collection
64
     */
65
    protected $fields;
66
67
    /**
68
     * Original data for this field.
69
     *
70
     * @var array
71
     */
72
    protected $original = [];
73
74
    /**
75
     * Column name for this form.
76
     *
77
     * @var string
78
     */
79
    protected $column;
80
81
    /**
82
     * EmbeddedForm constructor.
83
     *
84
     * @param string $column
85
     */
86
    public function __construct($column)
87
    {
88
        $this->column = $column;
89
90
        $this->fields = new Collection();
91
    }
92
93
    /**
94
     * Get all fields in current form.
95
     *
96
     * @return Collection
97
     */
98
    public function fields()
99
    {
100
        return $this->fields;
101
    }
102
103
    /**
104
     * Set parent form for this form.
105
     *
106
     * @param Form $parent
107
     *
108
     * @return $this
109
     */
110
    public function setParent(Form $parent)
111
    {
112
        $this->parent = $parent;
113
114
        return $this;
115
    }
116
117
    /**
118
     * Set parent form for this form.
119
     *
120
     * @param WidgetForm $parent
121
     *
122
     * @return $this
123
     */
124
    public function setParentWidgetForm(WidgetForm $parent)
125
    {
126
        $this->parent = $parent;
127
128
        return $this;
129
    }
130
131
    /**
132
     * Set original values for fields.
133
     *
134
     * @param array $data
135
     *
136
     * @return $this
137
     */
138
    public function setOriginal($data)
139
    {
140
        if (empty($data)) {
141
            return $this;
142
        }
143
144
        if (is_string($data)) {
145
            $data = json_decode($data, true);
146
        }
147
148
        $this->original = $data;
149
150
        return $this;
151
    }
152
153
    /**
154
     * Prepare for insert or update.
155
     *
156
     * @param array $input
157
     *
158
     * @return mixed
159
     */
160
    public function prepare($input)
161
    {
162
        foreach ($input as $key => $record) {
163
            $this->setFieldOriginalValue($key);
164
            $input[$key] = $this->prepareValue($key, $record);
165
        }
166
167
        return $input;
168
    }
169
170
    /**
171
     * Do prepare work for each field.
172
     *
173
     * @param string $key
174
     * @param string $record
175
     *
176
     * @return mixed
177
     */
178
    protected function prepareValue($key, $record)
179
    {
180
        $field = $this->fields->first(function (Field $field) use ($key) {
181
            return in_array($key, (array) $field->column());
182
        });
183
184
        if (method_exists($field, 'prepare')) {
185
            return $field->prepare($record);
186
        }
187
188
        return $record;
189
    }
190
191
    /**
192
     * Set original data for each field.
193
     *
194
     * @param string $key
195
     *
196
     * @return void
197
     */
198 View Code Duplication
    protected function setFieldOriginalValue($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
199
    {
200
        if (array_key_exists($key, $this->original)) {
201
            $values = $this->original[$key];
202
203
            $this->fields->each(function (Field $field) use ($values) {
204
                $field->setOriginal($values);
205
            });
206
        }
207
    }
208
209
    /**
210
     * Fill data to all fields in form.
211
     *
212
     * @param array $data
213
     *
214
     * @return $this
215
     */
216
    public function fill(array $data)
217
    {
218
        $this->fields->each(function (Field $field) use ($data) {
219
            $field->fill($data);
220
        });
221
222
        return $this;
223
    }
224
225
    /**
226
     * Format form, set `element name` `error key` and `element class`.
227
     *
228
     * @param Field $field
229
     *
230
     * @return Field
231
     */
232
    protected function formatField(Field $field)
233
    {
234
        $jsonKey = $field->column();
235
236
        $elementName = $elementClass = $errorKey = [];
237
238
        if (is_array($jsonKey)) {
239
            foreach ($jsonKey as $index => $name) {
240
                $elementName[$index] = "{$this->column}[$name]";
241
                $errorKey[$index] = "{$this->column}.$name";
242
                $elementClass[$index] = "{$this->column}_$name";
243
            }
244
        } else {
245
            $elementName = "{$this->column}[$jsonKey]";
246
            $errorKey = "{$this->column}.$jsonKey";
247
            $elementClass = "{$this->column}_$jsonKey";
248
        }
249
250
        $field->setElementName($elementName)
251
            ->setErrorKey($errorKey)
252
            ->setElementClass($elementClass);
253
254
        return $field;
255
    }
256
257
    /**
258
     * Add a field to form.
259
     *
260
     * @param Field $field
261
     *
262
     * @return $this
263
     */
264
    public function pushField(Field $field)
265
    {
266
        $field = $this->formatField($field);
267
268
        $this->fields->push($field);
269
270
        return $this;
271
    }
272
273
    /**
274
     * Add nested-form fields dynamically.
275
     *
276
     * @param string $method
277
     * @param array  $arguments
278
     *
279
     * @return Field|$this
280
     */
281 View Code Duplication
    public function __call($method, $arguments)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
282
    {
283
        if ($className = Form::findFieldClass($method)) {
284
            $column = Arr::get($arguments, 0, '');
285
286
            /** @var Field $field */
287
            $field = new $className($column, array_slice($arguments, 1));
288
289
            if ($this->parent instanceof WidgetForm) {
290
                $field->setWidgetForm($this->parent);
291
            } else {
292
                $field->setForm($this->parent);
293
            }
294
295
            $this->pushField($field);
296
297
            return $field;
298
        }
299
300
        return $this;
301
    }
302
}
303