Passed
Push — master ( 5e3680...55a26e )
by Esteban De La Fuente
04:47
created

AbstractApplication::getService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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\Abstract;
26
27
use Derafu\Lib\Core\Foundation\Configuration;
28
use Derafu\Lib\Core\Foundation\Contract\ApplicationInterface;
29
use Derafu\Lib\Core\Foundation\Contract\ConfigurationInterface;
30
use Derafu\Lib\Core\Foundation\Contract\KernelInterface;
31
use Derafu\Lib\Core\Foundation\Contract\PackageInterface;
32
use LogicException;
33
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
34
35
/**
36
 * Clase base para la clase principal de la aplicación.
37
 */
38
abstract class AbstractApplication implements ApplicationInterface
39
{
40
    /**
41
     * Instancia del núcleo de la aplicación.
42
     *
43
     * @var KernelInterface
44
     */
45
    private KernelInterface $kernel;
46
47
    /**
48
     * Instancia de la clase para el patrón singleton.
49
     *
50
     * @var self
51
     */
52
    private static self $instance;
53
54
    /**
55
     * Constructor de la aplicación.
56
     *
57
     * Debe ser privado para respetar el patrón singleton.
58
     *
59
     * @param string|array|null $config Configuración de la aplicación.
60
     * Puede ser la clase que implementa la configuración, una ruta al archivo
61
     * de configuración o un arreglo con la configuración.
62
     */
63 17
    private function __construct(string|array|null $config)
64
    {
65 17
        $this->initialize($config);
66
    }
67
68
    /**
69
     * Inicializa la aplicación.
70
     *
71
     * @param string|array|null $config
72
     */
73 17
    protected function initialize(string|array|null $config)
74
    {
75
        // Cargar configuración.
76 17
        $configuration = $this->resolveConfiguration($config);
77
78
        // Iniciar el kernel.
79 17
        $kernelClass = $configuration->getKernelClass();
80 17
        $this->kernel = new $kernelClass($configuration);
81
    }
82
83
    /**
84
     * Resuelve y carga la configuración de la aplicación.
85
     *
86
     * @param string|array|null $config
87
     * @return ConfigurationInterface
88
     */
89 17
    protected function resolveConfiguration(
90
        string|array|null $config
91
    ): ConfigurationInterface {
92 17
        if ($config === null) {
0 ignored issues
show
introduced by
The condition $config === null is always false.
Loading history...
93 12
            return new Configuration();
94
        }
95
96 5
        if (is_array($config)) {
0 ignored issues
show
introduced by
The condition is_array($config) is always true.
Loading history...
97
            return new Configuration($config);
98
        }
99
100 5
        if (class_exists($config)) {
101
            return new $config();
102
        }
103
104 5
        return new Configuration($config);
105
    }
106
107
    /**
108
     * {@inheritDoc}
109
     */
110
    public function path(?string $path = null): string
111
    {
112
        return $this->kernel->getConfiguration()->resolvePath($path);
113
    }
114
115
    /**
116
     * {@inheritDoc}
117
     */
118
    public function config(string $name, mixed $default = null): mixed
119
    {
120
        return $this->kernel->getConfiguration()->get($name, $default);
121
    }
122
123
    /**
124
     * {@inheritDoc}
125
     */
126
    public function hasPackage(string $package): bool
127
    {
128
        $servicesPrefix = $this->kernel->getConfiguration()->getServicesPrefix();
129
        $service = $servicesPrefix . $package;
130
131
        return $this->kernel->getContainer()->has($service);
132
    }
133
134
    /**
135
     * {@inheritDoc}
136
     */
137 8
    public function getPackage(string $package): PackageInterface
138
    {
139 8
        $servicesPrefix = $this->kernel->getConfiguration()->getServicesPrefix();
140 8
        $service = $servicesPrefix . $package;
141
142
        try {
143 8
            $instance = $this->kernel->getContainer()->get($service);
144
        } catch (ServiceNotFoundException $e) {
145
            $instance = null;
146
        }
147
148 8
        if (!$instance instanceof PackageInterface) {
149
            throw new LogicException(sprintf(
150
                'El paquete %s no existe en la aplicación.',
151
                $package
152
            ));
153
        }
154
155 8
        $config = $this->kernel->getConfiguration()->getPackageConfiguration(
156 8
            $package
157 8
        );
158 8
        $instance->setConfiguration($config);
159
160 8
        return $instance;
161
    }
162
163
    /**
164
     * {@inheritDoc}
165
     */
166 1
    public function getPackages(): array
167
    {
168 1
        $packages = [];
169 1
        $ids = $this->kernel->getContainer()->findTaggedServiceIds('package');
170 1
        $servicesPrefix = $this->kernel->getConfiguration()->getServicesPrefix();
171 1
        foreach ($ids as $id => $tags) {
172 1
            $packages[str_replace($servicesPrefix, '', $id)] =
173 1
                $this->kernel->getContainer()->get($id)
174 1
            ;
175
        }
176
177 1
        return $packages;
178
    }
179
180
    /**
181
     * {@inheritDoc}
182
     */
183
    public function hasService(string $service): bool
184
    {
185
        return $this->kernel->getContainer()->has($service);
186
    }
187
188
    /**
189
     * {@inheritDoc}
190
     */
191 9
    public function getService(string $service): object
192
    {
193 9
        return $this->kernel->getContainer()->get($service);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->kernel->ge...tainer()->get($service) could return the type null which is incompatible with the type-hinted return object. Consider adding an additional type-check to rule them out.
Loading history...
194
    }
195
196
    /**
197
     * {@inheritDoc}
198
     */
199 17
    public static function getInstance(string|array|null $config = null): static
200
    {
201 17
        if (!isset(self::$instance)) {
202 17
            $class = static::class;
203 17
            self::$instance = new $class($config);
204
        }
205
206 17
        assert(self::$instance instanceof static);
207
208 17
        return self::$instance;
209
    }
210
}
211