Passed
Push — master ( d4f916...00f97a )
by Esteban De La Fuente
04:27
created

DataFormatter::createDataInstance()   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
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
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\Package\Prime\Component\Template\Service;
26
27
use Derafu\Lib\Core\Package\Prime\Component\Template\Contract\DataFormatterInterface;
28
use Derafu\Lib\Core\Package\Prime\Component\Template\Contract\DataHandlerInterface;
29
use Derafu\Lib\Core\Package\Prime\Component\Template\Contract\DataInterface;
30
use Derafu\Lib\Core\Package\Prime\Component\Template\Entity\Data;
31
use Derafu\Lib\Core\Support\Store\Contract\RepositoryInterface;
32
33
/**
34
 * Servicio de formateo de datos.
35
 *
36
 * Permite recibir un valor y formatearlo según un mapa de handlers predefinido
37
 * mediante su identificador.
38
 */
39
class DataFormatter implements DataFormatterInterface
40
{
41
    /**
42
     * Mapeo de identificadores a la forma que se usará para darle formato a los
43
     * valores asociados al identificador.
44
     *
45
     * @var array<string,string|array|callable|DataHandlerInterface|RepositoryInterface>
46
     */
47
    private array $handlers;
48
49
    /**
50
     * Handler por defecto de los formatos.
51
     *
52
     * @var DataHandlerInterface
53
     */
54
    private DataHandlerInterface $handler;
55
56
    /**
57
     * Constructor del servicio.
58
     *
59
     * @param array $handlers
60
     */
61 3
    public function __construct(array $handlers = [])
62
    {
63 3
        $this->setHandlers($handlers);
64 3
        $this->handler = new DataHandler();
65
    }
66
67
    /**
68
     * @inheritDoc
69
     */
70 3
    public function setHandlers(array $handlers): static
71
    {
72 3
        $this->handlers = $handlers;
73
74 3
        return $this;
75
    }
76
77
    /**
78
     * @inheritDoc
79
     */
80
    public function getHandlers(): array
81
    {
82
        return $this->handlers;
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88 3
    public function addHandler(
89
        string $id,
90
        string|array|callable|DataHandlerInterface|RepositoryInterface $handler
91
    ): static {
92 3
        $this->handlers[$id] = $handler;
93
94 3
        return $this;
95
    }
96
97
    /**
98
     * @inheritDoc
99
     */
100
    public function getHandler(string $id): string|array|callable|DataHandlerInterface|RepositoryInterface|null
101
    {
102
        return $this->handlers[$id] ?? null;
103
    }
104
105
    /**
106
     * @inheritDoc
107
     */
108 2
    public function format(string $id, mixed $value): string
109
    {
110
        // Si no hay handler exacto revisar si el ID tiene partes.
111 2
        if (!isset($this->handlers[$id])) {
112
            // Si el ID tiene partes se busca si la primera parte está definida
113
            // como handler.
114
            if (str_contains($id, '.')) {
115
                // Separar en handler e ID y si existe el formato se usa.
116
                [$handler, $id] = explode('.', $id, 2);
117
                if (isset($this->handlers[$handler])) {
118
                    return $this->handle($handler, $id, $value);
119
                }
120
            }
121
        }
122
        // El ID es el formato.
123
        else {
124 2
            return $this->handle($id, $id, $value);
125
        }
126
127
        // Buscar si hay un handler genérico (comodín).
128
        if (!isset($this->handlers['*'])) {
129
            return $this->handle('*', $id, $value);
130
        }
131
132
        // Si no hay handler para manejar se retorna como string el valor
133
        // original que se pasó casteado a string (lo que podría fallar).
134
        return (string) $value;
135
    }
136
137
    /**
138
     * Maneja el formateao de los datos según cierto handler.
139
     *
140
     * @param string $name Nombre del handler registrado que se debe utilizar.
141
     * @param string $id Identificador pasado del formato.
142
     * @param mixed $value Valor a formatear.
143
     * @return string Valor formateado.
144
     */
145 2
    private function handle(string $name, string $id, mixed $value): string
146
    {
147 2
        $handler = $this->handlers[$name];
148 2
        $data = $this->createDataInstance($id, $value);
149
150 2
        if ($handler instanceof DataHandlerInterface) {
151
            $handler->handle($data);
152
        } else {
153 2
            $this->handler->handle($data);
154
        }
155
156 2
        return $data->getFormatted();
157
    }
158
159
    /**
160
     * Crea una instancia de los datos que se requiere formatear.
161
     *
162
     * @param string $id
163
     * @param mixed $value
164
     * @return DataInterface
165
     */
166 2
    protected function createDataInstance(string $id, mixed $value): DataInterface
167
    {
168 2
        return new Data($id, $value);
169
    }
170
}
171