Total Complexity | 40 |
Total Lines | 198 |
Duplicated Lines | 0 % |
Changes | 7 | ||
Bugs | 0 | Features | 0 |
Complex classes like FieldFactory 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.
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 FieldFactory, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class FieldFactory |
||
14 | { |
||
15 | /** |
||
16 | * Works out what class should be used for the given block’s content |
||
17 | * |
||
18 | * @param $block |
||
19 | * @param $field |
||
20 | * @param $key |
||
21 | * @return \Illuminate\Support\Collection|mixed|Asset|Image|MultiAsset|RichText|Table |
||
22 | */ |
||
23 | public function build($block, $field, $key): mixed |
||
24 | { |
||
25 | $isClassField = $this->classField($block, $field, $key); |
||
26 | |||
27 | if ($isClassField) { |
||
28 | return $isClassField; |
||
29 | } |
||
30 | |||
31 | // single item relations |
||
32 | if (Str::isUuid($field) && ($block->_autoResolveRelations || in_array($key, $block->_resolveRelations, true) || array_key_exists($key, $block->_resolveRelations))) { |
||
33 | |||
34 | if (array_key_exists($key, $block->_resolveRelations)) { |
||
35 | return $block->getRelation(new RequestStory(), $field, $block->_resolveRelations[$key]); |
||
36 | } |
||
37 | |||
38 | return $block->getRelation(new RequestStory(), $field); |
||
39 | } |
||
40 | |||
41 | // complex fields |
||
42 | if (is_array($field) && !empty($field)) { |
||
43 | return $this->arrayField($block, $field, $key); |
||
44 | } |
||
45 | |||
46 | // legacy and string image fields |
||
47 | if ($this->isStringImageField($field)) { |
||
48 | return new Image($field, $block); |
||
49 | } |
||
50 | |||
51 | // strings or anything else - do nothing |
||
52 | return $field; |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * @param $block |
||
57 | * @param $field |
||
58 | * @param $key |
||
59 | * @return mixed |
||
60 | */ |
||
61 | protected function classField($block, $field, $key): mixed |
||
62 | { |
||
63 | // does the Block assign any $_casts? This is key (field) => value (class) |
||
64 | if (array_key_exists($key, $block->getCasts())) { |
||
65 | $casts = $block->getCasts(); |
||
66 | return new $casts[$key]($field, $block); |
||
67 | } |
||
68 | |||
69 | // find Fields specific to this Block matching: BlockNameFieldName |
||
70 | if ($class = $block->getChildClassName('Field', $block->component() . '_' . $key)) { |
||
71 | return new $class($field, $block); |
||
72 | } |
||
73 | |||
74 | // auto-match Field classes |
||
75 | if ($class = $block->getChildClassName('Field', $key)) { |
||
76 | return new $class($field, $block); |
||
77 | } |
||
78 | |||
79 | return false; |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * If given an array field we need more processing to determine the class |
||
84 | * |
||
85 | * @param $block |
||
86 | * @param $field |
||
87 | * @param $key |
||
88 | * @return \Illuminate\Support\Collection|mixed|Asset|Image|MultiAsset|RichText|Table |
||
89 | */ |
||
90 | protected function arrayField($block, $field, $key): mixed |
||
91 | { |
||
92 | // match link fields |
||
93 | if (array_key_exists('linktype', $field)) { |
||
94 | $class = 'Riclep\Storyblok\Fields\\' . Str::studly($field['linktype']) . 'Link'; |
||
95 | |||
96 | return new $class($field, $block); |
||
97 | } |
||
98 | |||
99 | // match rich-text fields |
||
100 | if (array_key_exists('type', $field) && $field['type'] === 'doc') { |
||
101 | return new RichText($field, $block); |
||
102 | } |
||
103 | |||
104 | // match asset fields - detecting raster images |
||
105 | if (array_key_exists('fieldtype', $field) && $field['fieldtype'] === 'asset') { |
||
106 | // legacy and string image fields |
||
107 | if ($this->isStringImageField($field['filename'])) { |
||
108 | return new Image($field, $block); |
||
109 | } |
||
110 | |||
111 | if ($this->isSvgImageField($field['filename'])) { |
||
112 | return new SvgImage($field, $block); |
||
113 | } |
||
114 | |||
115 | return new Asset($field, $block); |
||
116 | } |
||
117 | |||
118 | // match table fields |
||
119 | if (array_key_exists('fieldtype', $field) && $field['fieldtype'] === 'table') { |
||
120 | return new Table($field, $block); |
||
121 | } |
||
122 | |||
123 | if (array_key_exists(0, $field)) { |
||
124 | return $this->relationField($block, $field, $key); |
||
125 | } |
||
126 | |||
127 | // just return the array |
||
128 | return $field; |
||
129 | } |
||
130 | |||
131 | protected function relationField($block, $field, $key) { |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Check if given string is a string image field |
||
189 | * |
||
190 | * @param $filename |
||
191 | * @return boolean |
||
192 | */ |
||
193 | public function isStringImageField($filename): bool |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Check if given string is a string image field |
||
202 | * |
||
203 | * @param $filename |
||
204 | * @return boolean |
||
205 | */ |
||
206 | public function isSvgImageField($filename): bool |
||
211 | } |
||
212 | } |
||
213 |