Passed
Pull Request — master (#1)
by Harry
02:11
created

Config::getGroupPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 7
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of graze/sprout.
4
 *
5
 * Copyright (c) 2017 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/sprout/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/sprout
12
 */
13
14
namespace Graze\Sprout;
15
16
use Graze\ConfigValidation\ConfigValidatorInterface;
17
use Graze\ConfigValidation\Validate;
18
use Graze\Sprout\Config\ConnectionConfig;
19
use Graze\Sprout\Config\GroupConfig;
20
use Graze\Sprout\Config\SchemaConfig;
21
use Graze\Sprout\Config\SchemaConfigInterface;
22
use InvalidArgumentException;
23
use Respect\Validation\Validator as v;
24
use Symfony\Component\Yaml\Parser;
25
26
/**
27
 * Config contains all the configuration required for this application
28
 */
29
class Config
30
{
31
    const DEFAULT_GROUP       = 'core';
32
    const DEFAULT_PATH        = '/seed';
33
    const DEFAULT_CONFIG_PATH = 'config/sprout.yml';
34
    const DEFAULT_PROCESSES   = 10;
35
36
    const CONFIG_DEFAULT_GROUP                  = 'defaults.group';
37
    const CONFIG_DEFAULT_PATH                   = 'defaults.path';
38
    const CONFIG_DEFAULT_SIMULTANEOUS_PROCESSES = 'defaults.simultaneousProcesses';
39
40
    const CONFIG_SCHEMAS = 'schemas';
41
42
    const CONFIG_GROUPS = 'groups';
43
44
    /** @var array */
45
    private $config;
46
47
    /** @var ConfigValidatorInterface */
48
    private $validator;
49
50
    public function __construct()
51
    {
52
        $this->validator =
53
            Validate::arr(false)
54
                    ->optional(static::CONFIG_DEFAULT_GROUP, v::stringType()->alnum('_'), static::DEFAULT_GROUP)
55
                    ->optional(static::CONFIG_DEFAULT_PATH, v::stringType()->directory(), static::DEFAULT_PATH)
56
                    ->optional(static::CONFIG_DEFAULT_SIMULTANEOUS_PROCESSES, v::intVal(), static::DEFAULT_PROCESSES)
57
                    ->optional(
58
                        static::CONFIG_GROUPS,
59
                        v::arrayVal()->each(
60
                            GroupConfig::getValidator()
61
                                       ->getValidator()
62
                        )
63
                    )
64
                    ->required(
65
                        static::CONFIG_SCHEMAS,
66
                        v::arrayVal()->length(1, null)->each(
67
                            SchemaConfig::getValidator()
68
                                        ->getValidator()
69
                        )
70
                    );
71
    }
72
73
    /**
74
     * Parse the config file provided in the constructor.
75
     *
76
     * @param string $path
77
     *
78
     * @return $this
79
     * @throws \Graze\ConfigValidation\Exceptions\ConfigValidationFailedException
80
     */
81
    public function parse(string $path): Config
0 ignored issues
show
Coding Style introduced by
Unknown type hint "string" found for $path
Loading history...
82
    {
83
        if (!file_exists($path)) {
84
            throw new \RuntimeException(sprintf('The supplied path %s does not exist', $path));
85
        }
86
87
        $parser = new Parser();
88
        $fileConfig = $parser->parse(file_get_contents($path));
89
90
        $config = $this->validator->validate($fileConfig);
91
92
        // populates the schema / connection.dbname properties for each defined schema if not set
93
        $schemas = $config['schemas'];
94
        foreach ($schemas as $schema => $value) {
95
            $value = SchemaConfig::getValidator()->validate($value);
96
            $value['connection'] = ConnectionConfig::getValidator()->validate($value['connection']);
97
98
            if (is_null($value['schema'])) {
99
                $config['schemas'][$schema]['schema'] = $schema;
100
            }
101
            if (is_null($value['connection']['dbName'])) {
102
                $config['schemas'][$schema]['connection']['dbName'] = $schema;
103
            }
104
            $config['schemas'][$schema] = new SchemaConfig($config['schemas'][$schema]);
105
        }
106
107
        $this->config = $config;
108
109
        return $this;
110
    }
111
112
    /**
113
     * Get an element from the configuration
114
     *
115
     * @param string     $keyPath A dot separated identifier describing the name of the key to retrieve.
116
     *                            `get('defaults.path', '/some/path')` will return `$config['defaults']['path']` or
117
     *                            `'/some/path'` if it doesn't exist
118
     * @param mixed|null $default The default value to use if the field does not exist or is null. Note
119
     *
120
     * @return mixed the value of an item
121
     */
122
    public function get(string $keyPath, $default = null)
0 ignored issues
show
Coding Style introduced by
Unknown type hint "string" found for $keyPath
Loading history...
123
    {
124
        $paths = explode('.', $keyPath);
125
        $cur = $this->config;
126
        $trail = '';
127
        foreach ($paths as $path) {
128
            $trail .= '.' . $path;
129
            if (!isset($cur[$path]) || is_null($cur[$path])) {
130
                return $default;
131
            }
132
            $cur = $cur[$path];
133
        }
134
        return $cur;
135
    }
136
137
    /**
138
     * @param string $schema
139
     *
140
     * @return SchemaConfigInterface
141
     */
142
    public function getSchemaConfiguration(string $schema): SchemaConfigInterface
0 ignored issues
show
Coding Style introduced by
Unknown type hint "string" found for $schema
Loading history...
143
    {
144
        $value = $this->get("schemas.{$schema}");
145
        if (is_null($value)) {
146
            throw new InvalidArgumentException("no schema: {$schema} found in configuration");
147
        }
148
        return $value;
149
    }
150
151
    /**
152
     * Get the path for a specific schema
153
     *
154
     * @param SchemaConfigInterface $schema The schema configuration
155
     * @param string|null           $group  The group. If none supplied, uses the default
156
     *
157
     * @return string
158
     */
159
    public function getSchemaPath(SchemaConfigInterface $schema, string $group = null): string
160
    {
161
        $group = $group ?: $this->get("defaults.group");
162
        return sprintf('%s/%s/', $this->getGroupPath($group), $schema->getDirName());
0 ignored issues
show
Bug introduced by
It seems like $group can also be of type null; however, parameter $group of Graze\Sprout\Config::getGroupPath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
        return sprintf('%s/%s/', $this->getGroupPath(/** @scrutinizer ignore-type */ $group), $schema->getDirName());
Loading history...
163
    }
164
165
    /**
166
     * @param string $group
167
     *
168
     * @return string
169
     */
170
    public function getGroupPath(string $group): string
0 ignored issues
show
Coding Style introduced by
Unknown type hint "string" found for $group
Loading history...
171
    {
172
        $configGroup = $this->get("groups.{$group}");
173
        if (!is_null($configGroup)) {
174
            return $configGroup['path'];
175
        } else {
176
            return sprintf('%s/%s/', $this->get(static::CONFIG_DEFAULT_PATH), $group);
177
        }
178
    }
179
}
180