Config::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

158
        return realpath(sprintf('%s/%s/', $this->getGroupPath(/** @scrutinizer ignore-type */ $group), $schema->getDirName()));
Loading history...
159
    }
160
161
    /**
162
     * @param string $group
163
     *
164
     * @return string
165
     */
166
    public function getGroupPath(string $group): string
167
    {
168
        $configGroup = $this->get("groups.{$group}");
169
        if (!is_null($configGroup)) {
170
            return $configGroup['path'];
171
        } else {
172
            return sprintf('%s/%s/', $this->get(static::CONFIG_DEFAULT_PATH), $group);
173
        }
174
    }
175
}
176