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 Xml 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 Xml, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
67 | class Xml extends File implements Loader |
||
68 | { |
||
69 | /** |
||
70 | * Config file DOMDocument |
||
71 | * |
||
72 | * @var \DOMDocument |
||
73 | */ |
||
74 | private $document; |
||
75 | |||
76 | /** |
||
77 | * Xpath to navigate the config DOM. |
||
78 | * |
||
79 | * @var \DOMXPath |
||
80 | */ |
||
81 | private $xpath; |
||
82 | |||
83 | /** |
||
84 | * Xml constructor. |
||
85 | * |
||
86 | * @param string $file |
||
87 | * @param \phpbu\App\Configuration\Bootstrapper $bootstrapper |
||
88 | * @throws \phpbu\App\Exception |
||
89 | */ |
||
90 | 19 | public function __construct(string $file, Configuration\Bootstrapper $bootstrapper) |
|
98 | |||
99 | /** |
||
100 | * Return list of adapter configs. |
||
101 | * |
||
102 | * @return array |
||
103 | * @throws \phpbu\App\Exception |
||
104 | */ |
||
105 | 17 | protected function getAdapterConfigs() |
|
123 | |||
124 | /** |
||
125 | * Set the phpbu application settings. |
||
126 | * |
||
127 | * @param \phpbu\App\Configuration $configuration |
||
128 | */ |
||
129 | 17 | public function setAppSettings(Configuration $configuration) |
|
143 | |||
144 | /** |
||
145 | * Set the log configuration. |
||
146 | * |
||
147 | * @param \phpbu\App\Configuration $configuration |
||
148 | * @throws \phpbu\App\Exception |
||
149 | */ |
||
150 | 15 | public function setLoggers(Configuration $configuration) |
|
170 | |||
171 | /** |
||
172 | * Set the backup configurations. |
||
173 | * |
||
174 | * @param \phpbu\App\Configuration $configuration |
||
175 | * @throws \phpbu\App\Exception |
||
176 | */ |
||
177 | 14 | public function setBackups(Configuration $configuration) |
|
183 | |||
184 | /** |
||
185 | * Get the config for a single backup node. |
||
186 | * |
||
187 | * @param \DOMElement $backupNode |
||
188 | * @throws \phpbu\App\Exception |
||
189 | * @return \phpbu\App\Configuration\Backup |
||
190 | */ |
||
191 | 14 | View Code Duplication | private function getBackupConfig(DOMElement $backupNode) |
207 | |||
208 | /** |
||
209 | * Get source configuration. |
||
210 | * |
||
211 | * @param \DOMElement $node |
||
212 | * @return \phpbu\App\Configuration\Backup\Source |
||
213 | * @throws \phpbu\App\Exception |
||
214 | */ |
||
215 | 14 | protected function getSource(DOMElement $node) |
|
230 | |||
231 | /** |
||
232 | * Get Target configuration. |
||
233 | * |
||
234 | * @param \DOMElement $node |
||
235 | * @return \phpbu\App\Configuration\Backup\Target |
||
236 | * @throws \phpbu\App\Exception |
||
237 | */ |
||
238 | 12 | protected function getTarget(DOMElement $node) |
|
256 | |||
257 | /** |
||
258 | * Set backup checks. |
||
259 | * |
||
260 | * @param \phpbu\App\Configuration\Backup $backup |
||
261 | * @param \DOMElement $node |
||
262 | */ |
||
263 | 11 | protected function setChecks(Configuration\Backup $backup, DOMElement $node) |
|
276 | |||
277 | /** |
||
278 | * Set the crypt configuration. |
||
279 | * |
||
280 | * @param \phpbu\App\Configuration\Backup $backup |
||
281 | * @param \DOMElement $node |
||
282 | * @throws \phpbu\App\Exception |
||
283 | */ |
||
284 | 11 | View Code Duplication | protected function setCrypt(Configuration\Backup $backup, DOMElement $node) |
300 | |||
301 | /** |
||
302 | * Set backup sync configurations. |
||
303 | * |
||
304 | * @param \phpbu\App\Configuration\Backup $backup |
||
305 | * @param \DOMElement $node |
||
306 | * @throws \phpbu\App\Exception |
||
307 | */ |
||
308 | 10 | protected function setSyncs(Configuration\Backup $backup, DOMElement $node) |
|
321 | |||
322 | /** |
||
323 | * Set the cleanup configuration. |
||
324 | * |
||
325 | * @param \phpbu\App\Configuration\Backup $backup |
||
326 | * @param \DOMElement $node |
||
327 | * @throws \phpbu\App\Exception |
||
328 | */ |
||
329 | 8 | View Code Duplication | protected function setCleanup(Configuration\Backup $backup, DOMElement $node) |
345 | |||
346 | /** |
||
347 | * Extracts all option tags. |
||
348 | * |
||
349 | * @param \DOMElement $node |
||
350 | * @return array |
||
351 | * @throws \phpbu\App\Exception |
||
352 | */ |
||
353 | 15 | protected function getOptions(DOMElement $node) |
|
364 | |||
365 | /** |
||
366 | * Load the XML-File. |
||
367 | * |
||
368 | * @param string $filename |
||
369 | * @throws \phpbu\App\Exception |
||
370 | * @return \DOMDocument |
||
371 | */ |
||
372 | 19 | private function loadXmlFile($filename) |
|
373 | { |
||
374 | 19 | $contents = $this->loadFile($filename); |
|
375 | 18 | $document = new \DOMDocument; |
|
376 | 18 | $message = ''; |
|
377 | 18 | $internal = libxml_use_internal_errors(true); |
|
378 | 18 | $reporting = error_reporting(0); |
|
379 | |||
380 | 18 | $document->documentURI = $filename; |
|
381 | 18 | $loaded = $document->loadXML($contents); |
|
382 | |||
383 | 18 | foreach (libxml_get_errors() as $error) { |
|
384 | 1 | $message .= "\n" . $error->message; |
|
385 | } |
||
386 | |||
387 | 18 | libxml_use_internal_errors($internal); |
|
388 | 18 | error_reporting($reporting); |
|
389 | |||
390 | 18 | if ($loaded === false || $message !== '') { |
|
391 | 1 | throw new Exception( |
|
392 | 1 | sprintf( |
|
393 | 1 | 'Error loading file "%s".%s', |
|
394 | $filename, |
||
395 | 1 | $message != '' ? "\n" . $message : '' |
|
396 | ) |
||
397 | ); |
||
398 | } |
||
399 | 17 | return $document; |
|
400 | } |
||
401 | |||
402 | /** |
||
403 | * Validate xml configuration against phpbu.xsd schema |
||
404 | * |
||
405 | * @return void |
||
406 | */ |
||
407 | 17 | private function validateConfigurationAgainstSchema() |
|
424 | } |
||
425 |