Failed Conditions
Push — master ( 9cb424...0e881e )
by Asmir
02:57 queued 11s
created

XmlFile::extractParameters()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 10.0145

Importance

Changes 0
Metric Value
cc 10
eloc 19
nc 14
nop 2
dl 0
loc 30
ccs 18
cts 19
cp 0.9474
crap 10.0145
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Configuration\Migration;
6
7
use Doctrine\Migrations\Configuration\Configuration;
8
use Doctrine\Migrations\Configuration\Exception\FileNotFound;
9
use Doctrine\Migrations\Configuration\Migration\Exception\XmlNotValid;
10
use Doctrine\Migrations\Tools\BooleanStringFormatter;
11
use DOMDocument;
12
use SimpleXMLElement;
13
use function assert;
14
use function file_exists;
15
use function file_get_contents;
16
use function libxml_clear_errors;
17
use function libxml_use_internal_errors;
18
use function simplexml_load_string;
19
use function strtr;
20
use const DIRECTORY_SEPARATOR;
21
use const LIBXML_NOCDATA;
22
23
final class XmlFile extends ConfigurationFile
24
{
25 10
    public function getConfiguration() : Configuration
26
    {
27 10
        if (! file_exists($this->file)) {
28 1
            throw FileNotFound::new($this->file);
29
        }
30
31 9
        $this->validateXml($this->file);
32
33 6
        $rawXML = file_get_contents($this->file);
34 6
        assert($rawXML !== false);
35
36 6
        $root = simplexml_load_string($rawXML, SimpleXMLElement::class, LIBXML_NOCDATA);
37 6
        assert($root !== false);
38
39 6
        $config = $this->extractParameters($root, true);
40
41 6
        if (isset($config['all_or_nothing'])) {
42 2
            $config['all_or_nothing'] = BooleanStringFormatter::toBoolean(
43 2
                $config['all_or_nothing'],
44 2
                false
45
            );
46
        }
47
48 6
        if (isset($config['migrations_paths'])) {
49 3
            $config['migrations_paths'] = $this->getDirectoriesRelativeToFile(
50 3
                $config['migrations_paths'],
51 3
                $this->file
52
            );
53
        }
54
55 6
        return (new ConfigurationArray($config))->getConfiguration();
56
    }
57
58
    /**
59
     * @return mixed[]
60
     */
61 6
    private function extractParameters(SimpleXMLElement $root, bool $loopOverNodes) : array
62
    {
63 6
        $config = [];
64
65 6
        $itemsToCheck = $loopOverNodes ? $root->children() : $root->attributes();
66
67 6
        if (! ($itemsToCheck instanceof SimpleXMLElement)) {
0 ignored issues
show
introduced by
$itemsToCheck is always a sub-type of SimpleXMLElement.
Loading history...
68
            return $config;
69
        }
70
71 6
        foreach ($itemsToCheck as $node) {
72 6
            $nodeName = strtr($node->getName(), '-', '_');
73 6
            if ($nodeName === 'migrations_paths') {
74 3
                $config['migrations_paths'] = [];
75 3
                foreach ($node->{'path'} as $pathNode) {
76 3
                    $config['migrations_paths'][(string) $pathNode['namespace']] = (string) $pathNode;
77
                }
78 5
            } elseif ($nodeName === 'storage' && $node->{'table-storage'} instanceof SimpleXMLElement) {
79 2
                $config['table_storage'] = $this->extractParameters($node->{'table-storage'}, false);
80 5
            } elseif ($nodeName === 'migrations') {
81 2
                $config['migrations'] = [];
82 2
                foreach ($node->{'migration'} as $pathNode) {
83 2
                    $config['migrations'][] = (string) $pathNode;
84
                }
85
            } else {
86 5
                $config[$nodeName] = (string) $node;
87
            }
88
        }
89
90 6
        return $config;
91
    }
92
93 9
    private function validateXml(string $file) : void
94
    {
95
        try {
96 9
            libxml_use_internal_errors(true);
97
98 9
            $xml = new DOMDocument();
99
100 9
            if ($xml->load($file) === false) {
101 1
                throw XmlNotValid::malformed();
102
            }
103
104 8
            $xsdPath = __DIR__ . DIRECTORY_SEPARATOR . 'XML' . DIRECTORY_SEPARATOR . 'configuration.xsd';
105
106 8
            if ($xml->schemaValidate($xsdPath) === false) {
107 2
                throw XmlNotValid::failedValidation();
108
            }
109 6
        } finally {
110 9
            libxml_clear_errors();
111 9
            libxml_use_internal_errors(false);
112
        }
113 6
    }
114
}
115