Completed
Push — master ( 234c86...6fa286 )
by Banciu N. Cristian Mihai
36:05
created

DotPathTrait::segmentsToKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BinaryCube\DotArray;
4
5
/**
6
 * DotPathTrait
7
 *
8
 * @package BinaryCube\DotArray
9
 * @author  Banciu N. Cristian Mihai <[email protected]>
10
 * @license https://github.com/binary-cube/dot-array/blob/master/LICENSE <MIT License>
11
 * @link    https://github.com/binary-cube/dot-array
12
 */
13
trait DotPathTrait
14
{
15
16
    /**
17
     * Internal Dot Path Config.
18
     *
19
     * @var array
20
     */
21
    protected static $dotPathConfig = [
22
        'template'  => '#(?|(?|[<token-start>](.*?)[<token-end>])|(.*?))(?:$|\.+)#i',
23
        'wrapKey'   => '{{%s}}',
24
        'wildcards' => [
25
            '<token-start>' => ['\'', '\"', '\[', '\(', '\{'],
26
            '<token-end>'   => ['\'', '\"', '\]', '\)', '\}'],
27
        ],
28
    ];
29
30
    /**
31
     * The cached pattern that allow to match the JSON paths that use the dot notation.
32
     *
33
     * Allowed tokens for more complex paths: '', "", [], (), {}
34
     * Examples:
35
     *
36
     * - foo.bar
37
     * - foo.'bar'
38
     * - foo."bar"
39
     * - foo.[bar]
40
     * - foo.(bar)
41
     * - foo.{bar}
42
     *
43
     * Or more complex:
44
     * - foo.{bar}.[component].{version.1.0}
45
     *
46
     * @var string
47
     */
48
    protected static $dotPathPattern;
49
50
51
    /**
52
     * Getting the dot path pattern.
53
     *
54
     * @return string
55
     */
56
    protected static function dotPathPattern()
57
    {
58
        if (empty(self::$dotPathPattern)) {
59
            $path = self::$dotPathConfig['template'];
60
61
            foreach (self::$dotPathConfig['wildcards'] as $wildcard => $tokens) {
62
                $path = \str_replace($wildcard, \implode('', $tokens), $path);
63
            }
64
65
            self::$dotPathPattern = $path;
66
        }
67
68
        return self::$dotPathPattern;
69
    }
70
71
72
    /**
73
     * Converts dot string path to segments.
74
     *
75
     * @param string $path
76
     *
77
     * @return array
78
     */
79
    protected static function pathToSegments($path)
80
    {
81
        $path     = \trim($path, " \t\n\r\0\x0B\.");
82
        $segments = [];
83
        $matches  = [];
84
85
        if (\mb_strlen($path, 'UTF-8') === 0) {
86
            return [];
87
        }
88
89
        \preg_match_all(static::dotPathPattern(), $path, $matches);
90
91
        if (!empty($matches[1])) {
92
            $matches = $matches[1];
93
94
            $segments = \array_filter(
95
                $matches,
96
                function ($match) {
97
                    return (\mb_strlen($match, 'UTF-8') > 0);
98
                }
99
            );
100
        }
101
102
        unset($path, $matches);
103
104
        return $segments;
105
    }
106
107
108
    /**
109
     * Wrap a given string into special characters.
110
     *
111
     * @param string $key
112
     *
113
     * @return string
114
     */
115
    protected static function wrapSegmentKey($key)
116
    {
117
        return vsprintf(static::$dotPathConfig['wrapKey'], [$key]);
118
    }
119
120
121
    /**
122
     * @param array $segments
123
     *
124
     * @return string
125
     */
126
    protected static function segmentsToKey(array $segments)
127
    {
128
        return (
129
            \implode(
130
                '',
131
                \array_map(
132
                    [static::class, 'wrapSegmentKey'],
133
                    $segments
134
                )
135
            )
136
        );
137
    }
138
139
140
    /**
141
     * Flatten the internal array using the dot delimiter,
142
     * also the keys are wrapped inside {{key}} (2 x curly braces).
143
     *
144
     * @param array  $items
145
     * @param string $prepend
146
     *
147
     * @return array
148
     */
149
    protected static function flatten(array $items, $prepend = '')
150
    {
151
        $flatten = [];
152
153
        foreach ($items as $key => $value) {
154
            $wrapKey = static::wrapSegmentKey($key);
155
156
            if (\is_array($value) && !empty($value)) {
157
                $flatten = array_merge(
158
                    $flatten,
159
                    static::flatten(
160
                        $value,
161
                        ($prepend . $wrapKey . '.')
162
                    )
163
                );
164
165
                continue;
166
            }
167
168
            $flatten[$prepend . $wrapKey] = $value;
169
        }
170
171
        return $flatten;
172
    }
173
174
175
}
176