Passed
Pull Request — master (#38)
by Douglas
06:30
created

ConfigurationBuilder::setOnDiskConfiguration()   C

Complexity

Conditions 7
Paths 11

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 8.3806

Importance

Changes 0
Metric Value
cc 7
eloc 23
nc 11
nop 1
dl 0
loc 40
ccs 16
cts 23
cp 0.6957
crap 8.3806
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the AntiMattr MongoDB Migrations Library, a library by Matthew Fitzgerald.
7
 *
8
 * (c) 2014 Matthew Fitzgerald
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace AntiMattr\MongoDB\Migrations\Configuration;
15
16
use AntiMattr\MongoDB\Migrations\OutputWriter;
17
use Doctrine\MongoDB\Connection;
18
use Symfony\Component\Yaml\Yaml;
19
20
/**
21
 * @author Douglas Reith <[email protected]>
22
 */
23
class ConfigurationBuilder
24
{
25
    /**
26
     * @var \Doctrine\MongoDB\Connection
27
     */
28
    private $connection;
29
30
    /**
31
     * @var OutputWriter
32
     */
33
    private $outputWriter;
34
35
    /**
36
     * @var array
37
     */
38
    private $configParams;
39
40 3
    private function __construct()
41
    {
42 3
        $this->configParams = [
43
            'name' => null,
44
            'database' => null,
45
            'collection_name' => null,
46
            'migrations_namespace' => null,
47
            'migrations_directory' => null,
48
            'migrations_script_directory' => null,
49
            'migrations' => [],
50
        ];
51 3
    }
52
53
    /**
54
     * @return ConfigurationBuilder
55
     */
56 3
    public static function create(): ConfigurationBuilder
57
    {
58 3
        return new static();
59
    }
60
61
    /**
62
     * @param Connection $connection
63
     *
64
     * @return ConfigurationBuilder
65
     */
66 3
    public function setConnection(Connection $connection): ConfigurationBuilder
67
    {
68 3
        $this->connection = $connection;
69
70 3
        return $this;
71
    }
72
73
    /**
74
     * @param OutputWriter $outputWriter
75
     *
76
     * @return ConfigurationBuilder
77
     */
78 3
    public function setOutputWriter(OutputWriter $outputWriter): ConfigurationBuilder
79
    {
80 3
        $this->outputWriter = $outputWriter;
81
82 3
        return $this;
83
    }
84
85
    /**
86
     * @param string|null $configFile
87
     *
88
     * @return ConfigurationBuilder
89
     */
90 3
    public function setOnDiskConfiguration(?string $configFile = null): ConfigurationBuilder
91
    {
92 3
        $this->configFile = $configFile;
0 ignored issues
show
Bug Best Practice introduced by
The property configFile does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
93
94 3
        if ($this->configFile) {
95 2
            if (file_exists($path = getcwd() . '/' . $this->configFile)) {
96
                $configFile = $path;
0 ignored issues
show
Unused Code introduced by
The assignment to $configFile is dead and can be removed.
Loading history...
97
            }
98
99 2
            if (!file_exists($this->configFile)) {
100
                throw new \InvalidArgumentException('The specified config file is not a valid file.');
101
            }
102
103 2
            $info = pathinfo($this->configFile);
104
105 2
            $fileExt = strtolower($info['extension']);
106
107 2
            switch ($fileExt) {
108 2
                case 'xml':
109 1
                    $diskConfig = $this->loadXmlFile($this->configFile);
110 1
                    break;
111
112 1
                case 'yml':
113
                case 'yaml':
114 1
                    $diskConfig = Yaml::parse(file_get_contents($this->configFile));
115 1
                    break;
116
117
                default:
118
                    throw new \InvalidArgumentException(
119
                        sprintf(
120
                            'The specified config file should end in .xml or .yml/.yaml. Unrecognized extension [%s]',
121
                            $fileExt
122
                        )
123
                    );
124
            }
125
126 2
            $this->configParams = array_merge($this->configParams, $diskConfig);
127
        }
128
129 3
        return $this;
130
    }
131
132
    /**
133
     * @return Configuration
134
     */
135 3
    public function build(): Configuration
136
    {
137 3
        $config = new Configuration($this->connection, $this->outputWriter);
138
139 3
        $migrationsDirectory = $this->getDirectoryRelativeToFile(
140 3
            $this->configFile,
141 3
            $this->configParams['migrations_directory']
142
        );
143
144 3
        $scriptsDirectory = $this->getDirectoryRelativeToFile(
145 3
            $this->configFile,
146 3
            $this->configParams['migrations_script_directory']
147
        );
148
149 3
        $config->setName($this->configParams['name'])
150 3
            ->setFile($this->configFile)
151 3
            ->setMigrationsDatabaseName($this->configParams['database'])
152 3
            ->setMigrationsCollectionName($this->configParams['collection_name'])
153 3
            ->setMigrationsNamespace($this->configParams['migrations_namespace'])
154 3
            ->setMigrationsDirectory($migrationsDirectory)
155 3
            ->setMigrationsScriptDirectory($scriptsDirectory);
156
157 3
        $config->registerMigrationsFromDirectory($migrationsDirectory);
158
159 3
        foreach ($this->configParams['migrations'] as $migration) {
160
            $config->registerMigration(
161
                $migration['version'],
162
                $migration['class']
163
            );
164
        }
165
166 3
        return $config;
167
    }
168
169
    /**
170
     * @param string $configFile
171
     *
172
     * @return array
173
     */
174 1
    private function loadXmlFile(string $configFile): array
175
    {
176 1
        $xml = simplexml_load_file($configFile);
177 1
        $configArr = [];
178
179 1
        if (isset($xml->name)) {
180 1
            $configArr['name'] = (string) $xml->name;
181
        }
182
183 1
        if (isset($xml->database['name'])) {
184 1
            $configArr['database'] = (string) $xml->database['name'];
185
        }
186
187 1
        if (isset($xml->collection['name'])) {
188 1
            $configArr['collection_name'] = (string) $xml->collection['name'];
189
        }
190
191 1
        if (isset($xml->{'migrations-namespace'})) {
192 1
            $configArr['migrations_namespace'] = (string) $xml->{'migrations-namespace'};
193
        }
194
195 1
        if (isset($xml->{'migrations-directory'})) {
196 1
            $configArr['migrations_directory'] = (string) $xml->{'migrations-directory'};
197
        }
198
199 1
        if (isset($xml->{'migrations-script-directory'})) {
200 1
            $configArr['migrations_script_directory'] = (string) $xml->{'migrations-script-directory'};
201
        }
202
203 1
        if (isset($xml->migrations->migration)) {
204
            foreach ($xml->migrations->migration as $migration) {
205
                $configArr['migrations'][] = [
206
                    'version' => $migration['version'],
207
                    'class' => $migration['class'],
208
                ];
209
            }
210
        }
211
212 1
        return $configArr;
213
    }
214
215
    /**
216
     * Get the path to the directory relative to the config file.
217
     *
218
     * @param string      $configFile
219
     * @param string|null $directory
220
     *
221
     * @return string|null
222
     */
223 3
    protected function getDirectoryRelativeToFile(string $configFile, ?string $directory = null): ?string
224
    {
225 3
        if (!$directory) {
226 1
            return null;
227
        }
228
229 2
        $path = realpath(dirname($configFile) . '/' . $directory);
230
231 2
        if (false !== $path) {
232
            return $path;
233
        }
234
235 2
        return $directory;
236
    }
237
}
238