Passed
Push — master ( 6af461...005087 )
by Esteban De La Fuente
04:26
created

Arr::ensureArrayAtPath()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 8
c 0
b 0
f 0
nc 6
nop 2
dl 0
loc 20
ccs 9
cts 9
cp 1
crap 5
rs 9.6111
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\Helper;
26
27
use Illuminate\Support\Arr as IlluminateArr;
28
29
/**
30
 * Clase para trabajar con arreglos.
31
 */
32
class Arr extends IlluminateArr
33
{
34
    /**
35
     * Une dos arreglos recursivamente manteniendo solo una clave.
36
     *
37
     * @param array $array1 El primer arreglo.
38
     * @param array $array2 El segundo arreglo.
39
     * @return array El arreglo resultante de la unión.
40
     */
41 7
    public static function mergeRecursiveDistinct(
42
        array $array1,
43
        array $array2
44
    ): array {
45 7
        $merged = $array1;
46 7
        foreach ($array2 as $key => &$value) {
47
            if (
48 5
                is_array($value)
49 5
                && isset($merged[$key])
50 5
                && is_array($merged[$key])
51
            ) {
52 2
                $merged[$key] = self::mergeRecursiveDistinct(
53 2
                    $merged[$key],
54 2
                    $value
55 2
                );
56
            } else {
57 5
                $merged[$key] = $value;
58
            }
59
        }
60 7
        return $merged;
61
    }
62
63
    /**
64
     * Casta recursivamente y de manera automática los datos de un arreglo.
65
     *
66
     * Aplica las siguientes reglas a los valores que sean strings:
67
     *
68
     *   - Limpia los strings con trim().
69
     *   - Un string que representa un decimal es casteado como float.
70
     *   - Un string que representa un entero es casteado como int.
71
     *   - Un string vacío puede ser alterado con otro valor (por defecto se
72
     *     deja igual sin alterar).
73
     *
74
     * @param array $array Arreglo que se castearán sus strings según reglas.
75
     * @param mixed $emptyValue Valor que se asignará a strings vacíos.
76
     * @return array Arrego modificado.
77
     */
78 3
    public static function autoCastRecursive(array &$array, mixed $emptyValue = ''): array
79
    {
80 3
        array_walk_recursive($array, function (&$value, $key, $emptyValue) {
81 3
            if (is_string($value)) {
82 2
                $value = trim($value);
83 2
                if (is_numeric($value)) {
84 1
                    if ($value == (int) $value) {
85 1
                        $value = (int) $value;
86
                    } else {
87 1
                        $value = (float) $value;
88
                    }
89 2
                } elseif ($value === '') {
90 2
                    $value = $emptyValue;
91
                }
92
            }
93 3
        }, $emptyValue);
94
95 3
        return $array;
96
    }
97
98
    /**
99
     * Agrega el ID (índice del arreglo) a los datos del arreglo de dicho
100
     * índice.
101
     *
102
     * Esto hará que el ID esté tanto el índice como en los datos del índice.
103
     *
104
     * @param array<int|string,array> $data
105
     * @param string $idAttribute
106
     * @return array
107
     */
108 8
    public static function addIdAttribute(array $data, string $idAttribute): array
109
    {
110 8
        return array_combine(
111 8
            array_keys($data),
112 8
            array_map(
113 8
                fn ($id, $item) => array_merge(
114 8
                    [$idAttribute => $id],
115 8
                    $item
116 8
                ),
117 8
                array_keys($data),
118 8
                array_values($data)
119 8
            )
120 8
        );
121
    }
122
123
    /**
124
     * Convierte el último nivel de un array, accedido por notación de puntos,
125
     * en un arreglo con índice 0 si aún no es un arreglo con índice 0.
126
     *
127
     * @param array &$array Arreglo de entrada a procesar.
128
     * @param string $path Notación de puntos para navegar en el array.
129
     */
130 5
    public static function ensureArrayAtPath(array &$array, string $path): void
131
    {
132
        // Dividir la notación de puntos en niveles.
133 5
        $keys = explode('.', $path);
134 5
        $current = &$array;
135
136 5
        foreach ($keys as $key) {
137
            // Si el nivel actual no existe, crear un arreglo vacío.
138 5
            if (!isset($current[$key]) || !is_array($current[$key])) {
139 1
                $current[$key] = [];
140
            }
141
142
            // Bajar al siguiente nivel.
143 5
            $current = &$current[$key];
144
        }
145
146
        // Si el último nivel no tiene un índice 0, convertir su valor a un
147
        // arreglo.
148 5
        if (!isset($current[0])) {
149 4
            $current = [$current];
150
        }
151
    }
152
}
153