| 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 |