| Total Complexity | 56 |
| Total Lines | 216 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like YamlReferenceDumper 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 YamlReferenceDumper, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 28 | class YamlReferenceDumper |
||
| 29 | { |
||
| 30 | private ?string $reference = null; |
||
| 31 | |||
| 32 | public function dump(ConfigurationInterface $configuration): string |
||
| 33 | { |
||
| 34 | return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree()); |
||
| 35 | } |
||
| 36 | |||
| 37 | public function dumpAtPath(ConfigurationInterface $configuration, string $path): string |
||
| 38 | { |
||
| 39 | $rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree(); |
||
| 40 | |||
| 41 | foreach (explode('.', $path) as $step) { |
||
| 42 | if (!$node instanceof ArrayNode) { |
||
| 43 | throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); |
||
| 44 | } |
||
| 45 | |||
| 46 | /** @var NodeInterface[] $children */ |
||
| 47 | $children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren(); |
||
| 48 | |||
| 49 | foreach ($children as $child) { |
||
| 50 | if ($child->getName() === $step) { |
||
| 51 | $node = $child; |
||
| 52 | |||
| 53 | continue 2; |
||
| 54 | } |
||
| 55 | } |
||
| 56 | |||
| 57 | throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); |
||
| 58 | } |
||
| 59 | |||
| 60 | return $this->dumpNode($node); |
||
| 61 | } |
||
| 62 | |||
| 63 | public function dumpNode(NodeInterface $node): string |
||
| 71 | } |
||
| 72 | |||
| 73 | private function writeNode(NodeInterface $node, ?NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = false): void |
||
| 171 | } |
||
| 172 | } |
||
| 173 | } |
||
| 174 | |||
| 175 | /** |
||
| 176 | * Outputs a single config reference line. |
||
| 177 | */ |
||
| 178 | private function writeLine(string $text, int $indent = 0): void |
||
| 179 | { |
||
| 180 | $indent = \strlen($text) + $indent; |
||
| 181 | $format = '%'.$indent.'s'; |
||
| 182 | |||
| 183 | $this->reference .= \sprintf($format, $text)."\n"; |
||
| 184 | } |
||
| 185 | |||
| 186 | private function writeArray(array $array, int $depth, bool $asComment = false): void |
||
| 187 | { |
||
| 188 | $isIndexed = array_is_list($array); |
||
| 189 | |||
| 190 | foreach ($array as $key => $value) { |
||
| 191 | if (\is_array($value)) { |
||
| 192 | $val = ''; |
||
| 193 | } else { |
||
| 194 | $val = $value; |
||
| 195 | } |
||
| 196 | |||
| 197 | $prefix = $asComment ? '# ' : ''; |
||
| 198 | |||
| 199 | if ($isIndexed) { |
||
| 200 | $this->writeLine($prefix.'- '.$val, $depth * 4); |
||
| 201 | } else { |
||
| 202 | $this->writeLine(\sprintf('%s%-20s %s', $prefix, $key.':', $val), $depth * 4); |
||
| 203 | } |
||
| 204 | |||
| 205 | if (\is_array($value)) { |
||
| 206 | $this->writeArray($value, $depth + 1, $asComment); |
||
| 207 | } |
||
| 208 | } |
||
| 209 | } |
||
| 210 | |||
| 211 | private function getPrototypeChildren(PrototypedArrayNode $node): array |
||
| 244 | } |
||
| 245 | } |
||
| 246 |