Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Form, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
75 | class Form implements Renderable |
||
76 | { |
||
77 | use HasHooks; |
||
78 | |||
79 | /** |
||
80 | * Remove flag in `has many` form. |
||
81 | */ |
||
82 | const REMOVE_FLAG_NAME = '_remove_'; |
||
83 | |||
84 | /** |
||
85 | * Eloquent model of the form. |
||
86 | * |
||
87 | * @var Model |
||
88 | */ |
||
89 | protected $model; |
||
90 | |||
91 | /** |
||
92 | * @var \Illuminate\Validation\Validator |
||
93 | */ |
||
94 | protected $validator; |
||
95 | |||
96 | /** |
||
97 | * @var Builder |
||
98 | */ |
||
99 | protected $builder; |
||
100 | |||
101 | /** |
||
102 | * Data for save to current model from input. |
||
103 | * |
||
104 | * @var array |
||
105 | */ |
||
106 | protected $updates = []; |
||
107 | |||
108 | /** |
||
109 | * Data for save to model's relations from input. |
||
110 | * |
||
111 | * @var array |
||
112 | */ |
||
113 | protected $relations = []; |
||
114 | |||
115 | /** |
||
116 | * Input data. |
||
117 | * |
||
118 | * @var array |
||
119 | */ |
||
120 | protected $inputs = []; |
||
121 | |||
122 | /** |
||
123 | * @var Layout |
||
124 | */ |
||
125 | protected $layout; |
||
126 | |||
127 | /** |
||
128 | * Available fields. |
||
129 | * |
||
130 | * @var array |
||
131 | */ |
||
132 | public static $availableFields = [ |
||
133 | 'button' => Field\Button::class, |
||
134 | 'checkbox' => Field\Checkbox::class, |
||
135 | 'color' => Field\Color::class, |
||
136 | 'currency' => Field\Currency::class, |
||
137 | 'date' => Field\Date::class, |
||
138 | 'dateRange' => Field\DateRange::class, |
||
139 | 'datetime' => Field\Datetime::class, |
||
140 | 'dateTimeRange' => Field\DatetimeRange::class, |
||
141 | 'datetimeRange' => Field\DatetimeRange::class, |
||
142 | 'decimal' => Field\Decimal::class, |
||
143 | 'display' => Field\Display::class, |
||
144 | 'divider' => Field\Divider::class, |
||
145 | 'embeds' => Field\Embeds::class, |
||
146 | 'email' => Field\Email::class, |
||
147 | 'file' => Field\File::class, |
||
148 | 'hasMany' => Field\HasMany::class, |
||
149 | 'hidden' => Field\Hidden::class, |
||
150 | 'id' => Field\Id::class, |
||
151 | 'image' => Field\Image::class, |
||
152 | 'ip' => Field\Ip::class, |
||
153 | 'mobile' => Field\Mobile::class, |
||
154 | 'month' => Field\Month::class, |
||
155 | 'multipleSelect' => Field\MultipleSelect::class, |
||
156 | 'number' => Field\Number::class, |
||
157 | 'password' => Field\Password::class, |
||
158 | 'radio' => Field\Radio::class, |
||
159 | 'rate' => Field\Rate::class, |
||
160 | 'select' => Field\Select::class, |
||
161 | 'slider' => Field\Slider::class, |
||
162 | 'switch' => Field\SwitchField::class, |
||
163 | 'text' => Field\Text::class, |
||
164 | 'textarea' => Field\Textarea::class, |
||
165 | 'time' => Field\Time::class, |
||
166 | 'timeRange' => Field\TimeRange::class, |
||
167 | 'url' => Field\Url::class, |
||
168 | 'year' => Field\Year::class, |
||
169 | 'html' => Field\Html::class, |
||
170 | 'tags' => Field\Tags::class, |
||
171 | 'icon' => Field\Icon::class, |
||
172 | 'multipleFile' => Field\MultipleFile::class, |
||
173 | 'multipleImage' => Field\MultipleImage::class, |
||
174 | 'captcha' => Field\Captcha::class, |
||
175 | 'listbox' => Field\Listbox::class, |
||
176 | 'table' => Field\Table::class, |
||
177 | 'timezone' => Field\Timezone::class, |
||
178 | 'keyValue' => Field\KeyValue::class, |
||
179 | 'list' => Field\ListField::class, |
||
180 | ]; |
||
181 | |||
182 | /** |
||
183 | * Form field alias. |
||
184 | * |
||
185 | * @var array |
||
186 | */ |
||
187 | public static $fieldAlias = []; |
||
188 | |||
189 | /** |
||
190 | * Ignored saving fields. |
||
191 | * |
||
192 | * @var array |
||
193 | */ |
||
194 | protected $ignored = []; |
||
195 | |||
196 | /** |
||
197 | * Collected field assets. |
||
198 | * |
||
199 | * @var array |
||
200 | */ |
||
201 | protected static $collectedAssets = []; |
||
202 | |||
203 | /** |
||
204 | * @var Form\Tab |
||
205 | */ |
||
206 | protected $tab = null; |
||
207 | |||
208 | /** |
||
209 | * Field rows in form. |
||
210 | * |
||
211 | * @var array |
||
212 | */ |
||
213 | public $rows = []; |
||
214 | |||
215 | /** |
||
216 | * @var bool |
||
217 | */ |
||
218 | protected $isSoftDeletes = false; |
||
219 | |||
220 | /** |
||
221 | * Initialization closure array. |
||
222 | * |
||
223 | * @var []Closure |
||
224 | */ |
||
225 | protected static $initCallbacks; |
||
226 | |||
227 | /** |
||
228 | * Create a new form instance. |
||
229 | * |
||
230 | * @param $model |
||
231 | * @param \Closure $callback |
||
232 | */ |
||
233 | public function __construct($model, Closure $callback = null) |
||
249 | |||
250 | /** |
||
251 | * Initialize with user pre-defined default disables, etc. |
||
252 | * |
||
253 | * @param Closure $callback |
||
254 | */ |
||
255 | public static function init(Closure $callback = null) |
||
259 | |||
260 | /** |
||
261 | * Call the initialization closure array in sequence. |
||
262 | */ |
||
263 | protected function callInitCallbacks() |
||
273 | |||
274 | /** |
||
275 | * @param Field $field |
||
276 | * |
||
277 | * @return $this |
||
278 | */ |
||
279 | public function pushField(Field $field): self |
||
291 | |||
292 | /** |
||
293 | * @return Model |
||
294 | */ |
||
295 | public function model(): Model |
||
299 | |||
300 | /** |
||
301 | * @return Builder |
||
302 | */ |
||
303 | public function builder(): Builder |
||
307 | |||
308 | /** |
||
309 | * Generate a edit form. |
||
310 | * |
||
311 | * @param $id |
||
312 | * |
||
313 | * @return $this |
||
314 | */ |
||
315 | public function edit($id): self |
||
324 | |||
325 | /** |
||
326 | * Use tab to split form. |
||
327 | * |
||
328 | * @param string $title |
||
329 | * @param Closure $content |
||
330 | * @param bool $active |
||
331 | * |
||
332 | * @return $this |
||
333 | */ |
||
334 | public function tab($title, Closure $content, bool $active = false): self |
||
340 | |||
341 | /** |
||
342 | * Get Tab instance. |
||
343 | * |
||
344 | * @return Tab |
||
345 | */ |
||
346 | public function getTab() |
||
350 | |||
351 | /** |
||
352 | * Set Tab instance. |
||
353 | * |
||
354 | * @return Tab |
||
355 | */ |
||
356 | public function setTab(): Tab |
||
364 | |||
365 | /** |
||
366 | * Destroy data entity and remove files. |
||
367 | * |
||
368 | * @param $id |
||
369 | * |
||
370 | * @return mixed |
||
371 | */ |
||
372 | public function destroy($id) |
||
416 | |||
417 | /** |
||
418 | * Remove files in record. |
||
419 | * |
||
420 | * @param Model $model |
||
421 | * @param bool $forceDelete |
||
422 | */ |
||
423 | protected function deleteFiles(Model $model, $forceDelete = false) |
||
440 | |||
441 | /** |
||
442 | * Store a new record. |
||
443 | * |
||
444 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\Http\JsonResponse |
||
445 | */ |
||
446 | public function store() |
||
481 | |||
482 | /** |
||
483 | * @param MessageBag $message |
||
484 | * |
||
485 | * @return $this|\Illuminate\Http\JsonResponse |
||
486 | */ |
||
487 | protected function responseValidationError(MessageBag $message) |
||
499 | |||
500 | /** |
||
501 | * Get ajax response. |
||
502 | * |
||
503 | * @param string $message |
||
504 | * |
||
505 | * @return bool|\Illuminate\Http\JsonResponse |
||
506 | */ |
||
507 | protected function ajaxResponse($message) |
||
521 | |||
522 | /** |
||
523 | * Prepare input data for insert or update. |
||
524 | * |
||
525 | * @param array $data |
||
526 | * |
||
527 | * @return mixed |
||
528 | */ |
||
529 | protected function prepare($data = []) |
||
545 | |||
546 | /** |
||
547 | * Remove ignored fields from input. |
||
548 | * |
||
549 | * @param array $input |
||
550 | * |
||
551 | * @return array |
||
552 | */ |
||
553 | protected function removeIgnoredFields($input): array |
||
559 | |||
560 | /** |
||
561 | * Get inputs for relations. |
||
562 | * |
||
563 | * @param array $inputs |
||
564 | * |
||
565 | * @return array |
||
566 | */ |
||
567 | protected function getRelationInputs($inputs = []): array |
||
586 | |||
587 | /** |
||
588 | * Handle update. |
||
589 | * |
||
590 | * @param int $id |
||
591 | * @param null $data |
||
592 | * |
||
593 | * @return bool|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|mixed|null|Response |
||
594 | */ |
||
595 | public function update($id, $data = null) |
||
652 | |||
653 | /** |
||
654 | * Get RedirectResponse after store. |
||
655 | * |
||
656 | * @return \Illuminate\Http\RedirectResponse |
||
657 | */ |
||
658 | protected function redirectAfterStore() |
||
666 | |||
667 | /** |
||
668 | * Get RedirectResponse after update. |
||
669 | * |
||
670 | * @param mixed $key |
||
671 | * |
||
672 | * @return \Illuminate\Http\RedirectResponse |
||
673 | */ |
||
674 | protected function redirectAfterUpdate($key) |
||
680 | |||
681 | /** |
||
682 | * Get RedirectResponse after data saving. |
||
683 | * |
||
684 | * @param string $resourcesPath |
||
685 | * @param string $key |
||
686 | * |
||
687 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector |
||
688 | */ |
||
689 | protected function redirectAfterSaving($resourcesPath, $key) |
||
708 | |||
709 | /** |
||
710 | * Check if request is from editable. |
||
711 | * |
||
712 | * @param array $input |
||
713 | * |
||
714 | * @return bool |
||
715 | */ |
||
716 | protected function isEditable(array $input = []): bool |
||
720 | |||
721 | /** |
||
722 | * Handle updates for single column. |
||
723 | * |
||
724 | * @param int $id |
||
725 | * @param array $data |
||
726 | * |
||
727 | * @return array|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|Response |
||
728 | */ |
||
729 | protected function handleColumnUpdates($id, $data) |
||
746 | |||
747 | /** |
||
748 | * Handle editable update. |
||
749 | * |
||
750 | * @param array $input |
||
751 | * |
||
752 | * @return array |
||
753 | */ |
||
754 | protected function handleEditable(array $input = []): array |
||
766 | |||
767 | /** |
||
768 | * @param array $input |
||
769 | * |
||
770 | * @return array |
||
771 | */ |
||
772 | protected function handleFileDelete(array $input = []): array |
||
783 | |||
784 | /** |
||
785 | * @param array $input |
||
786 | * |
||
787 | * @return array |
||
788 | */ |
||
789 | protected function handleFileSort(array $input = []): array |
||
809 | |||
810 | /** |
||
811 | * Handle orderable update. |
||
812 | * |
||
813 | * @param int $id |
||
814 | * @param array $input |
||
815 | * |
||
816 | * @return bool |
||
817 | */ |
||
818 | protected function handleOrderable($id, array $input = []) |
||
832 | |||
833 | /** |
||
834 | * Update relation data. |
||
835 | * |
||
836 | * @param array $relationsData |
||
837 | * |
||
838 | * @return void |
||
839 | */ |
||
840 | protected function updateRelation($relationsData) |
||
947 | |||
948 | /** |
||
949 | * Prepare input data for update. |
||
950 | * |
||
951 | * @param array $updates |
||
952 | * @param bool $oneToOneRelation If column is one-to-one relation. |
||
953 | * |
||
954 | * @return array |
||
955 | */ |
||
956 | protected function prepareUpdate(array $updates, $oneToOneRelation = false): array |
||
988 | |||
989 | /** |
||
990 | * @param string|array $columns |
||
991 | * @param bool $containsDot |
||
992 | * |
||
993 | * @return bool |
||
994 | */ |
||
995 | protected function isInvalidColumn($columns, $containsDot = false): bool |
||
1006 | |||
1007 | /** |
||
1008 | * Prepare input data for insert. |
||
1009 | * |
||
1010 | * @param $inserts |
||
1011 | * |
||
1012 | * @return array |
||
1013 | */ |
||
1014 | protected function prepareInsert($inserts): array |
||
1037 | |||
1038 | /** |
||
1039 | * Is input data is has-one relation. |
||
1040 | * |
||
1041 | * @param array $inserts |
||
1042 | * |
||
1043 | * @return bool |
||
1044 | */ |
||
1045 | protected function isHasOneRelation($inserts): bool |
||
1059 | |||
1060 | /** |
||
1061 | * Ignore fields to save. |
||
1062 | * |
||
1063 | * @param string|array $fields |
||
1064 | * |
||
1065 | * @return $this |
||
1066 | */ |
||
1067 | public function ignore($fields): self |
||
1073 | |||
1074 | /** |
||
1075 | * @param array $data |
||
1076 | * @param string|array $columns |
||
1077 | * |
||
1078 | * @return array|mixed |
||
1079 | */ |
||
1080 | View Code Duplication | protected function getDataByColumn($data, $columns) |
|
1098 | |||
1099 | /** |
||
1100 | * Find field object by column. |
||
1101 | * |
||
1102 | * @param $column |
||
1103 | * |
||
1104 | * @return mixed |
||
1105 | */ |
||
1106 | protected function getFieldByColumn($column) |
||
1118 | |||
1119 | /** |
||
1120 | * Set original data for each field. |
||
1121 | * |
||
1122 | * @return void |
||
1123 | */ |
||
1124 | protected function setFieldOriginalValue() |
||
1134 | |||
1135 | /** |
||
1136 | * Set all fields value in form. |
||
1137 | * |
||
1138 | * @param $id |
||
1139 | * |
||
1140 | * @return void |
||
1141 | */ |
||
1142 | protected function setFieldValue($id) |
||
1166 | |||
1167 | /** |
||
1168 | * Add a fieldset to form. |
||
1169 | * |
||
1170 | * @param string $title |
||
1171 | * @param Closure $setCallback |
||
1172 | * |
||
1173 | * @return Field\Fieldset |
||
1174 | */ |
||
1175 | View Code Duplication | public function fieldset(string $title, Closure $setCallback) |
|
1187 | |||
1188 | /** |
||
1189 | * Don't snake case attributes. |
||
1190 | * |
||
1191 | * @param Model $model |
||
1192 | * |
||
1193 | * @return void |
||
1194 | */ |
||
1195 | protected static function doNotSnakeAttributes(Model $model) |
||
1201 | |||
1202 | /** |
||
1203 | * Get validation messages. |
||
1204 | * |
||
1205 | * @param array $input |
||
1206 | * |
||
1207 | * @return MessageBag|bool |
||
1208 | */ |
||
1209 | public function validationMessages($input) |
||
1228 | |||
1229 | /** |
||
1230 | * Merge validation messages from input validators. |
||
1231 | * |
||
1232 | * @param \Illuminate\Validation\Validator[] $validators |
||
1233 | * |
||
1234 | * @return MessageBag |
||
1235 | */ |
||
1236 | protected function mergeValidationMessages($validators): MessageBag |
||
1246 | |||
1247 | /** |
||
1248 | * Get all relations of model from callable. |
||
1249 | * |
||
1250 | * @return array |
||
1251 | */ |
||
1252 | public function getRelations(): array |
||
1279 | |||
1280 | /** |
||
1281 | * Set action for form. |
||
1282 | * |
||
1283 | * @param string $action |
||
1284 | * |
||
1285 | * @return $this |
||
1286 | */ |
||
1287 | public function setAction($action): self |
||
1293 | |||
1294 | /** |
||
1295 | * Set field and label width in current form. |
||
1296 | * |
||
1297 | * @param int $fieldWidth |
||
1298 | * @param int $labelWidth |
||
1299 | * |
||
1300 | * @return $this |
||
1301 | */ |
||
1302 | public function setWidth($fieldWidth = 8, $labelWidth = 2): self |
||
1313 | |||
1314 | /** |
||
1315 | * Set view for form. |
||
1316 | * |
||
1317 | * @param string $view |
||
1318 | * |
||
1319 | * @return $this |
||
1320 | */ |
||
1321 | public function setView($view): self |
||
1327 | |||
1328 | /** |
||
1329 | * Set title for form. |
||
1330 | * |
||
1331 | * @param string $title |
||
1332 | * |
||
1333 | * @return $this |
||
1334 | */ |
||
1335 | public function setTitle($title = ''): self |
||
1341 | |||
1342 | /** |
||
1343 | * Add a row in form. |
||
1344 | * |
||
1345 | * @param Closure $callback |
||
1346 | * |
||
1347 | * @return $this |
||
1348 | */ |
||
1349 | public function row(Closure $callback): self |
||
1355 | |||
1356 | /** |
||
1357 | * Tools setting for form. |
||
1358 | * |
||
1359 | * @param Closure $callback |
||
1360 | */ |
||
1361 | public function tools(Closure $callback) |
||
1365 | |||
1366 | /** |
||
1367 | * @param Closure|null $callback |
||
1368 | * |
||
1369 | * @return Form\Tools |
||
1370 | */ |
||
1371 | View Code Duplication | public function header(Closure $callback = null) |
|
1379 | |||
1380 | /** |
||
1381 | * Indicates if current form page is creating. |
||
1382 | * |
||
1383 | * @return bool |
||
1384 | */ |
||
1385 | public function isCreating(): bool |
||
1389 | |||
1390 | /** |
||
1391 | * Indicates if current form page is editing. |
||
1392 | * |
||
1393 | * @return bool |
||
1394 | */ |
||
1395 | public function isEditing(): bool |
||
1399 | |||
1400 | /** |
||
1401 | * Disable form submit. |
||
1402 | * |
||
1403 | * @param bool $disable |
||
1404 | * |
||
1405 | * @return $this |
||
1406 | * |
||
1407 | * @deprecated |
||
1408 | */ |
||
1409 | public function disableSubmit(bool $disable = true): self |
||
1415 | |||
1416 | /** |
||
1417 | * Disable form reset. |
||
1418 | * |
||
1419 | * @param bool $disable |
||
1420 | * |
||
1421 | * @return $this |
||
1422 | * |
||
1423 | * @deprecated |
||
1424 | */ |
||
1425 | public function disableReset(bool $disable = true): self |
||
1431 | |||
1432 | /** |
||
1433 | * Disable View Checkbox on footer. |
||
1434 | * |
||
1435 | * @param bool $disable |
||
1436 | * |
||
1437 | * @return $this |
||
1438 | */ |
||
1439 | public function disableViewCheck(bool $disable = true): self |
||
1445 | |||
1446 | /** |
||
1447 | * Disable Editing Checkbox on footer. |
||
1448 | * |
||
1449 | * @param bool $disable |
||
1450 | * |
||
1451 | * @return $this |
||
1452 | */ |
||
1453 | public function disableEditingCheck(bool $disable = true): self |
||
1459 | |||
1460 | /** |
||
1461 | * Disable Creating Checkbox on footer. |
||
1462 | * |
||
1463 | * @param bool $disable |
||
1464 | * |
||
1465 | * @return $this |
||
1466 | */ |
||
1467 | public function disableCreatingCheck(bool $disable = true): self |
||
1473 | |||
1474 | /** |
||
1475 | * Footer setting for form. |
||
1476 | * |
||
1477 | * @param Closure $callback |
||
1478 | * |
||
1479 | * @return \Encore\Admin\Form\Footer |
||
1480 | */ |
||
1481 | View Code Duplication | public function footer(Closure $callback = null) |
|
1489 | |||
1490 | /** |
||
1491 | * Get current resource route url. |
||
1492 | * |
||
1493 | * @param int $slice |
||
1494 | * |
||
1495 | * @return string |
||
1496 | */ |
||
1497 | public function resource($slice = -2): string |
||
1507 | |||
1508 | /** |
||
1509 | * Render the form contents. |
||
1510 | * |
||
1511 | * @return string |
||
1512 | */ |
||
1513 | public function render() |
||
1521 | |||
1522 | /** |
||
1523 | * Get or set input data. |
||
1524 | * |
||
1525 | * @param string $key |
||
1526 | * @param null $value |
||
1527 | * |
||
1528 | * @return array|mixed |
||
1529 | */ |
||
1530 | public function input($key, $value = null) |
||
1538 | |||
1539 | /** |
||
1540 | * Register custom field. |
||
1541 | * |
||
1542 | * @param string $abstract |
||
1543 | * @param string $class |
||
1544 | * |
||
1545 | * @return void |
||
1546 | */ |
||
1547 | public static function extend($abstract, $class) |
||
1551 | |||
1552 | /** |
||
1553 | * Set form field alias. |
||
1554 | * |
||
1555 | * @param string $field |
||
1556 | * @param string $alias |
||
1557 | * |
||
1558 | * @return void |
||
1559 | */ |
||
1560 | public static function alias($field, $alias) |
||
1564 | |||
1565 | /** |
||
1566 | * Remove registered field. |
||
1567 | * |
||
1568 | * @param array|string $abstract |
||
1569 | */ |
||
1570 | public static function forget($abstract) |
||
1574 | |||
1575 | /** |
||
1576 | * Find field class. |
||
1577 | * |
||
1578 | * @param string $method |
||
1579 | * |
||
1580 | * @return bool|mixed |
||
1581 | */ |
||
1582 | public static function findFieldClass($method) |
||
1597 | |||
1598 | /** |
||
1599 | * Collect assets required by registered field. |
||
1600 | * |
||
1601 | * @return array |
||
1602 | */ |
||
1603 | public static function collectFieldAssets(): array |
||
1628 | |||
1629 | /** |
||
1630 | * Add a new layout column. |
||
1631 | * |
||
1632 | * @param int $width |
||
1633 | * @param \Closure $closure |
||
1634 | * |
||
1635 | * @return $this |
||
1636 | */ |
||
1637 | View Code Duplication | public function column($width, \Closure $closure): self |
|
1645 | |||
1646 | /** |
||
1647 | * Initialize filter layout. |
||
1648 | */ |
||
1649 | protected function initLayout() |
||
1653 | |||
1654 | /** |
||
1655 | * Getter. |
||
1656 | * |
||
1657 | * @param string $name |
||
1658 | * |
||
1659 | * @return array|mixed |
||
1660 | */ |
||
1661 | public function __get($name) |
||
1665 | |||
1666 | /** |
||
1667 | * Setter. |
||
1668 | * |
||
1669 | * @param string $name |
||
1670 | * @param mixed $value |
||
1671 | * |
||
1672 | * @return array |
||
1673 | */ |
||
1674 | public function __set($name, $value) |
||
1678 | |||
1679 | /** |
||
1680 | * Generate a Field object and add to form builder if Field exists. |
||
1681 | * |
||
1682 | * @param string $method |
||
1683 | * @param array $arguments |
||
1684 | * |
||
1685 | * @return Field |
||
1686 | */ |
||
1687 | public function __call($method, $arguments) |
||
1703 | |||
1704 | /** |
||
1705 | * @return Layout |
||
1706 | */ |
||
1707 | public function getLayout(): Layout |
||
1711 | } |
||
1712 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: