Passed
Push — master ( 737114...d97858 )
by Esteban De La Fuente
04:54
created

Configuration::getPackageConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Derafu: Biblioteca PHP (Núcleo).
7
 * Copyright (C) Derafu <https://www.derafu.org>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de GNU
20
 * junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace Derafu\Lib\Core\Foundation;
26
27
use Composer\InstalledVersions;
28
use Derafu\Lib\Core\Foundation\Contract\ConfigurationInterface;
29
use Derafu\Lib\Core\Support\Store\Contract\DataContainerInterface;
30
use Derafu\Lib\Core\Support\Store\DataContainer;
31
use Symfony\Component\Yaml\Yaml;
32
33
/**
34
 * Configuración de la aplicación.
35
 */
36
class Configuration implements ConfigurationInterface
37
{
38
    /**
39
     * Directorio raíz de la aplicación.
40
     */
41
    private string $projectDir;
42
43
    /**
44
     * Prefijo para las configuraciones de Derafu Lib en el archivo de
45
     * configuración.
46
     *
47
     * Este prefijo no es necesario cambiarlo, pues solo se usa para
48
     * configuraciones internas de la biblioteca y no para las configuraciones
49
     * de "lo que usa" la biblioteca.
50
     *
51
     * @var string
52
     */
53
    protected string $prefix = 'derafu.lib.';
54
55
    /**
56
     * Define un mapa de parámetros (índice) y de qué configuración (valor)
57
     * obtener el valor que se asignará a dicho parámetro.
58
     *
59
     * @var array
60
     */
61
    protected array $parameters = [
62
        'kernel.project_dir' => 'app.project_dir',
63
    ];
64
65
    /**
66
     * Instancia que administra los datos de la configuración.
67
     *
68
     * @var DataContainerInterface
69
     */
70
    private DataContainerInterface $data;
71
72
    /**
73
     * Esquema de la estructura de los datos de la configuración.
74
     *
75
     * @var array
76
     */
77
    protected array $dataSchema = [
78
        'app' => [
79
            'types' => 'array',
80
            'default' => [],
81
            'schema' => [
82
                'project_dir' => [
83
                    'types' => 'string',
84
                ],
85
            ],
86
        ],
87
        'derafu' => [
88
            'types' => 'array',
89
            'default' => [],
90
            'schema' => [
91
                'lib' => [
92
                    'types' => 'array',
93
                    'default' => [],
94
                    'schema' => [
95
                        'services' => [
96
                            'types' => 'array',
97
                            'default' => [],
98
                            'schema' => [
99
                                'prefix' => [
100
                                    'types' => 'string',
101
                                    'default' => 'derafu.lib.',
102
                                ],
103
                                'kernelClass' => [
104
                                    'types' => 'string',
105
                                    'default' => Kernel::class,
106
                                ],
107
                                'serviceRegistryClass' => [
108
                                    'types' => 'string',
109
                                    'default' => ServiceRegistry::class,
110
                                ],
111
                                'compilerPassClass' => [
112
                                    'types' => 'string',
113
                                    'default' => ServiceProcessingCompilerPass::class,
114
                                ],
115
                            ],
116
                        ],
117
                    ],
118
                ],
119
                'packages' => [
120
                    'types' => 'array',
121
                    'default' => [],
122
                ],
123
            ],
124
        ],
125
    ];
126
127
    /**
128
     * Constructor de la configuración.
129
     *
130
     * @param string|array|null $config Archivo de configuración que se debe
131
     * cargar o el arreglo con la configuración.
132
     */
133 17
    public function __construct(string|array|null $config = null)
134
    {
135 17
        $this->load($config, $this->dataSchema);
136 17
        $this->configure();
137
    }
138
139
    /**
140
     * Carga la configuración de la aplicación desde un archivo.
141
     *
142
     * @param string $config
143
     * @return static
144
     */
145 17
    protected function load(string|array|null $config, array $schema): static
146
    {
147 17
        $config = $config ?? $this->resolvePath('config/config.yaml');
148
149 17
        $config = is_array($config)
150
            ? $config
151 17
            : (array) Yaml::parseFile($config)
152 17
        ;
153
154 17
        $this->data = new DataContainer($config, $schema);
155
156 17
        return $this;
157
    }
158
159
    /**
160
     * Realiza las configuraciones de la aplicación según lo que se haya
161
     * cargado como configuración.
162
     *
163
     * @return void
164
     */
165 17
    protected function configure(): void
166
    {
167 17
        if ($this->data->get('app.project_dir') === null) {
168 17
            $this->data->set('app.project_dir', $this->getProjectDir());
169
        }
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     */
175 17
    public function get(string $key, mixed $default = null): mixed
176
    {
177 17
        return $this->data->get($key, $default);
178
    }
179
180
    /**
181
     * {@inheritDoc}
182
     */
183 17
    public function getParameters(): array
184
    {
185 17
        $parameters = [];
186 17
        foreach ($this->parameters as $name => $source) {
187 17
            $value = $this->get($source);
188 17
            if ($value !== null) {
189 17
                $parameters[$name] = $value;
190
            }
191
        }
192
193 17
        return $parameters;
194
    }
195
196
    /**
197
     * {@inheritDoc}
198
     */
199 17
    public function getServicesPrefix(): string
200
    {
201 17
        return $this->get($this->prefix . 'services.prefix');
202
    }
203
204
    /**
205
     * {@inheritDoc}
206
     */
207 17
    public function getKernelClass(): string
208
    {
209 17
        return $this->get($this->prefix . 'services.kernelClass');
210
    }
211
212
    /**
213
     * {@inheritDoc}
214
     */
215 17
    public function getServiceRegistryClass(): string
216
    {
217 17
        return $this->get($this->prefix . 'services.serviceRegistryClass');
218
    }
219
220
    /**
221
     * {@inheritDoc}
222
     */
223 17
    public function getCompilerPassClass(): ?string
224
    {
225 17
        return $this->get($this->prefix . 'services.compilerPassClass');
226
    }
227
228
    /**
229
     * {@inheritDoc}
230
     */
231 17
    protected function getProjectDir(): string
232
    {
233 17
        if (!isset($this->projectDir)) {
234 17
            $vendorDir = InstalledVersions::getRootPackage();
235 17
            $this->projectDir = realpath($vendorDir['install_path']);
236
        }
237
238 17
        return $this->projectDir;
239
    }
240
241
    /**
242
     * {@inheritDoc}
243
     */
244 12
    public function resolvePath(?string $path = null): string
245
    {
246 12
        if (!$path) {
247
            return $this->getProjectDir();
248
        }
249
250 12
        if ($path[0] === '/') {
251
            return $path;
252
        }
253
254 12
        return $this->getProjectDir() . '/' . $path;
255
    }
256
257
    /**
258
     * {@inheritDoc}
259
     */
260 12
    public function getPackageConfiguration(
261
        string $package
262
    ): array|DataContainerInterface {
263 12
        $prefix = explode('.', $this->prefix)[0] . '.';
264 12
        $config = $this->data->get($prefix . 'packages.' . $package);
265
266 12
        return $config ?? [];
267
    }
268
}
269