Passed
Push — master ( 00f97a...f17640 )
by Esteban De La Fuente
04:35
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\Support\Store\Contract\RepositoryInterface;
30
31
/**
32
 * Servicio de formateo de datos.
33
 *
34
 * Permite recibir un valor y formatearlo según un mapa de handlers predefinido
35
 * mediante su identificador.
36
 */
37
class DataFormatter implements DataFormatterInterface
38
{
39
    /**
40
     * Mapeo de identificadores a la forma que se usará para darle formato a los
41
     * valores asociados al identificador.
42
     *
43
     * @var array<string,string|array|callable|DataHandlerInterface|RepositoryInterface>
44
     */
45
    private array $handlers;
46
47
    /**
48
     * Handler por defecto de los formatos.
49
     *
50
     * @var DataHandlerInterface
51
     */
52
    private DataHandlerInterface $handler;
53
54
    /**
55
     * Constructor del servicio.
56
     *
57
     * @param array $handlers Mapa de handlers para los formatos.
58
     * @param DataHandlerInterface|null $handler Handler por defecto a usar.
59
     */
60 3
    public function __construct(
61
        array $handlers = [],
62
        DataHandlerInterface $handler = null
63
    ) {
64 3
        $this->setHandlers($handlers);
65 3
        $this->handler = $handler ?? new DataHandler();
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71 3
    public function setHandlers(array $handlers): static
72
    {
73 3
        $this->handlers = $handlers;
74
75 3
        return $this;
76
    }
77
78
    /**
79
     * @inheritDoc
80
     */
81
    public function getHandlers(): array
82
    {
83
        return $this->handlers;
84
    }
85
86
    /**
87
     * @inheritDoc
88
     */
89 3
    public function addHandler(
90
        string $id,
91
        string|array|callable|DataHandlerInterface|RepositoryInterface $handler
92
    ): static {
93 3
        $this->handlers[$id] = $handler;
94
95 3
        return $this;
96
    }
97
98
    /**
99
     * @inheritDoc
100
     */
101
    public function getHandler(string $id): string|array|callable|DataHandlerInterface|RepositoryInterface|null
102
    {
103
        return $this->handlers[$id] ?? null;
104
    }
105
106
    /**
107
     * @inheritDoc
108
     */
109 2
    public function format(string $id, mixed $data): string
110
    {
111
        // Si no hay handler exacto revisar si el ID tiene partes.
112 2
        if (!isset($this->handlers[$id])) {
113
            // Si el ID tiene partes se busca si la primera parte está definida
114
            // como handler.
115
            if (str_contains($id, '.')) {
116
                // Separar en handler e ID y si existe el formato se usa.
117
                [$handler, $id] = explode('.', $id, 2);
118
                if (isset($this->handlers[$handler])) {
119
                    return $this->handle($handler, $id, $data);
120
                }
121
            }
122
        }
123
        // El ID es el formato.
124
        else {
125 2
            return $this->handle($id, $id, $data);
126
        }
127
128
        // Buscar si hay un handler genérico (comodín).
129
        if (isset($this->handlers['*'])) {
130
            return $this->handle('*', $id, $data);
131
        }
132
133
        // Si no hay handler para manejar se retorna como string el valor
134
        // original que se pasó casteado a string (lo que podría fallar).
135
        return (string) $data;
136
    }
137
138
    /**
139
     * Maneja el formateao de los datos según cierto handler.
140
     *
141
     * @param string $name Nombre del handler registrado que se debe utilizar.
142
     * @param string $id Identificador pasado del formato.
143
     * @param mixed $data Datos a formatear.
144
     * @return string Datos formateados.
145
     */
146 2
    private function handle(string $name, string $id, mixed $data): string
147
    {
148 2
        $handler = $this->handlers[$name];
149
150 2
        if ($handler instanceof DataHandlerInterface) {
151
            return $handler->handle($id, $data);
152
        } else {
153 2
            if ($this->handler instanceof DataHandler) {
154 2
                return $this->handler->handle($id, $data, $handler);
0 ignored issues
show
Unused Code introduced by
The call to Derafu\Lib\Core\Package\...dlerInterface::handle() has too many arguments starting with $handler. ( Ignorable by Annotation )

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

154
                return $this->handler->/** @scrutinizer ignore-call */ handle($id, $data, $handler);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
155
            } else {
156
                return $this->handler->handle($id, $data);
157
            }
158
        }
159
    }
160
}
161