Passed
Pull Request — master (#1)
by Peter
07:07
created

ArrayHelper   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
dl 0
loc 159
rs 10
c 1
b 0
f 0
wmc 30

6 Methods

Rating   Name   Duplication   Size   Complexity  
A mergeAttributes() 0 18 6
A toQuery() 0 12 3
A toAttributes() 0 19 5
A unsafeMergeAttributes() 0 11 3
B formatAttribute() 0 35 11
A toStyles() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Html\Helper;
6
7
class ArrayHelper
8
{
9
    protected const ERROR_INVALID_ATTRIBUTES = 'invalid attributes (array of string[] and null items)';
10
11
    /**
12
     * @param array $styles
13
     *
14
     * @return string
15
     */
16
    public static function toStyles(array $styles): string
17
    {
18
        $tmp = [];
19
        foreach ($styles as $k => $v) {
20
            $tmp[] = sprintf('%s: %s', $k, $v);
21
        }
22
23
        return implode('; ', $tmp);
24
    }
25
26
    /**
27
     * @param array  $attributes
28
     * @param string $prefix string to prepend if the result is not empty
29
     *
30
     * @return string
31
     */
32
    public static function toAttributes(array $attributes, string $prefix = ' '): string
33
    {
34
        $tmp = [];
35
        foreach ($attributes as $k => $v) {
36
            if (null === $v) {
37
                $tmp[] = (string)$k;
38
                continue;
39
            }
40
41
            $v = is_array($v) ? implode(' ', $v) : $v;
42
43
            $tmp[] = sprintf('%s="%s"', $k, $v);
44
        }
45
46
        if (empty($tmp)) {
47
            return '';
48
        }
49
50
        return $prefix . implode(' ', $tmp);
51
    }
52
53
    /**
54
     * Merges two sets of attributes, but without filtering out duplicates of any sort
55
     * (Developed to be used in factories before Component creation)
56
     *
57
     * @return array
58
     */
59
    public static function unsafeMergeAttributes(array $existing, array $new): array
60
    {
61
        foreach ($new as $key => $value) {
62
            if (!isset($existing[$key])) {
63
                $existing[$key] = $value;
64
            } else {
65
                $existing[$key] = array_merge((array)$existing[$key], (array)$new[$key]);
66
            }
67
        }
68
69
        return $existing;
70
    }
71
72
    /**
73
     * @param array $existing
74
     * @param array $new
75
     * @param bool  $safe if true, $existing will be formatted, which is of course slower.
76
     *                    should only be false if $existing is already formatted
77
     *
78
     * @return array
79
     */
80
    public static function mergeAttributes(array $existing, array $new, bool $safe = true): array
81
    {
82
        if ($safe) {
83
            foreach ($existing as $key => $value) {
84
                $existing[$key] = static::formatAttribute($value);
85
            }
86
        }
87
88
        foreach ($new as $key => $value) {
89
            $existingValue = isset($existing[$key]) ? $existing[$key] : [];
90
            $newValue      = static::formatAttribute($value);
91
92
            if ($newValue !== null) {
93
                $existing[$key] = array_merge($existingValue, $newValue);
94
            }
95
        }
96
97
        return $existing;
98
    }
99
100
    /**
101
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
102
     * @SuppressWarnings(PHPMD.NPathComplexity)
103
     *
104
     * Formats an attribute so that it's either null or an array of strings where:
105
     *  - keys and values are the same
106
     *  - keys (or values) must not have spaces
107
     *
108
     * @param $value
109
     *
110
     * @return array|null
111
     */
112
    public static function formatAttribute($value): ?array
113
    {
114
        static $realEmpty = [null, '', false];
115
116
        if (in_array($value, $realEmpty, true)) {
117
            return null;
118
        }
119
120
        if (!is_scalar($value) && !is_array($value)) {
121
            throw new \InvalidArgumentException(static::ERROR_INVALID_ATTRIBUTES);
122
        }
123
124
        if (is_scalar($value)) {
125
            $value = [(string)$value];
126
        }
127
128
        if (count($value) === 1 && in_array(current($value), $realEmpty, true)) {
129
            return null;
130
        }
131
132
        $newValue = [];
133
        foreach ($value as $v) {
134
            if (!is_scalar($v)) {
135
                throw new \InvalidArgumentException(static::ERROR_INVALID_ATTRIBUTES);
136
            }
137
138
            foreach (explode(' ', (string)$v) as $w) {
139
                if ('' === $w) {
140
                    continue;
141
                }
142
                $newValue[$w] = $w;
143
            }
144
        }
145
146
        return $newValue;
147
    }
148
149
    /**
150
     * @param array $parts
151
     *
152
     * @return string
153
     */
154
    public static function toQuery(array $parts): string
155
    {
156
        if (empty($parts)) {
157
            return '';
158
        }
159
160
        $tmp = [];
161
        foreach ($parts as $k => $v) {
162
            $tmp[] = sprintf('%s=%s', $k, urlencode($v));
163
        }
164
165
        return '?' . implode('&', $tmp);
166
    }
167
}
168