Passed
Push — master ( 6fb22a...49a409 )
by Esteban De La Fuente
03:21
created

Repository::createEntity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 6
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\Package\Prime\Component\Entity\Repository;
26
27
use Derafu\Lib\Core\Foundation\Contract\FactoryInterface;
28
use Derafu\Lib\Core\Helper\Factory;
29
use Derafu\Lib\Core\Package\Prime\Component\Entity\Contract\RepositoryInterface;
30
use Derafu\Lib\Core\Support\Store\Repository as StoreRepository;
31
use LogicException;
32
use Symfony\Component\Yaml\Yaml;
33
34
/**
35
 * Clase para repositorios de entidades.
36
 *
37
 * Proporciona métodos estándar para acceder y buscar entidades desde una fuente
38
 * de datos.
39
 */
40
class Repository extends StoreRepository implements RepositoryInterface
41
{
42
    /**
43
     * {@inheritdoc}
44
     */
45
    protected string $entityClass;
46
47
    /**
48
     * Nombre por defecto del índice del nombre cuando los datos de la entidad
49
     * no están normalizados y se debe crear el atributo.
50
     *
51
     * @var string
52
     */
53
    protected string $normalizationName = 'name';
54
55
    /**
56
     * Instancia de la fábrica de las entidades del repositorio.
57
     *
58
     * Esta fábrica no es obligatoria, se puede pasar la clase directamente.
59
     *
60
     * Solo es necesaria la fábrica si se desea algún tipo de personalización.
61
     *
62
     * @var FactoryInterface|null
63
     */
64
    protected ?FactoryInterface $factory = null;
65
66
    /**
67
     * Constructor del repositorio.
68
     *
69
     * @param string $entityClass
70
     * @param string|string $source
71
     */
72
    public function __construct(
73
        string $entityClass,
74
        string|array $source,
75
        ?string $normalizationName = null,
76
        ?FactoryInterface $factory = null
77
    ) {
78
        $this->entityClass = $entityClass;
79
        $this->factory = $factory;
80
81
        if (!is_array($source)) {
0 ignored issues
show
introduced by
The condition is_array($source) is always true.
Loading history...
82
            $source = $this->loadSource($source);
83
        }
84
85
        $source = $this->normalizeData($source, $normalizationName);
86
87
        parent::__construct($source);
88
    }
89
90
    /**
91
     * Carga el archivo de datos desde diferentes formatos de archivo.
92
     *
93
     * @param string $source
94
     * @return array
95
     */
96
    protected function loadSource(string $source): array
97
    {
98
        $extension = strtolower(pathinfo($source, PATHINFO_EXTENSION));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($source, Derafu...ory\PATHINFO_EXTENSION) can also be of type array; however, parameter $string of strtolower() 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

98
        $extension = strtolower(/** @scrutinizer ignore-type */ pathinfo($source, PATHINFO_EXTENSION));
Loading history...
99
100
        switch ($extension) {
101
            case 'php':
102
                $data = require $source;
103
                break;
104
            case 'json':
105
                $data = json_decode(file_get_contents($source), true);
106
                break;
107
            case 'yaml':
108
                $data = Yaml::parseFile(file_get_contents($source));
109
                break;
110
            default:
111
                throw new LogicException(sprintf(
112
                    'Formato de archivo %s de %s no soportado para la carga de repositorios.',
113
                    $extension,
114
                    basename($source)
115
                ));
116
        }
117
118
        if (!is_array($data)) {
119
            throw new LogicException(sprintf(
120
                'Los datos del repositorio de %s usando el origen %s no ha podido ser convertido a un arreglo válido para ser cargado en el repositorio.',
121
                $this->entityClass,
122
                $source
123
            ));
124
        }
125
126
        return $data;
127
    }
128
129
    /**
130
     * Normaliza los datos en caso que sea un arreglo de valores y no un arreglo
131
     * de arreglos.
132
     *
133
     * @param array $data
134
     * @return array
135
     */
136
    protected function normalizeData(array $data, ?string $normalizationName): array
137
    {
138
        $normalizationName = $normalizationName ?? $this->normalizationName;
139
140
        return array_map(function ($entity) use ($normalizationName) {
141
            if (!is_array($entity)) {
142
                return [
143
                    $normalizationName => $entity,
144
                ];
145
            }
146
            return $entity;
147
        }, $data);
148
    }
149
150
    /**
151
     * Crea una entidad a partir de los datos.
152
     *
153
     * @param array $data Datos que se asignarán a la entidad.
154
     * @return object Instancia de la entidad con los datos cargados.
155
     */
156
    protected function createEntity(array $data): object
157
    {
158
        if (isset($this->factory)) {
159
            return $this->factory->create($data);
0 ignored issues
show
Bug introduced by
The method create() does not exist on null. ( Ignorable by Annotation )

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

159
            return $this->factory->/** @scrutinizer ignore-call */ create($data);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
160
        }
161
162
        return Factory::create($data, $this->entityClass);
163
    }
164
}
165