Passed
Push — master ( 9013bb...125cf1 )
by Kirill
03:56
created

InputBag::all()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Http\Request;
13
14
use Spiral\Http\Exception\DotNotFoundException;
15
use Spiral\Http\Exception\InputException;
16
17
/**
18
 * Generic data accessor, used to read properties of active request. Input bags provide ability to
19
 * isolate request parts using given prefix.
20
 */
21
class InputBag implements \Countable, \IteratorAggregate, \ArrayAccess
22
{
23
    /** @var array */
24
    private $data = [];
25
26
    /** @var string */
27
    private $prefix = '';
28
29
    /**
30
     * @param array  $data
31
     * @param string $prefix
32
     */
33
    public function __construct(array $data, string $prefix = '')
34
    {
35
        $this->data = $data;
36
        $this->prefix = $prefix;
37
    }
38
39
    /**
40
     * @return array
41
     */
42
    public function __debugInfo()
43
    {
44
        return $this->all();
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function count(): int
51
    {
52
        return count($this->all());
53
    }
54
55
    /**
56
     * @return array
57
     */
58
    public function all(): array
59
    {
60
        try {
61
            return $this->dotGet('');
62
        } catch (DotNotFoundException $e) {
63
            return [];
64
        }
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function getIterator(): \Traversable
71
    {
72
        return new \ArrayIterator($this->all());
73
    }
74
75
    /**
76
     * Fetch only specified keys from property values. Missed values can be filled with defined
77
     * filler. Only one variable layer can be fetched (no dot notation).
78
     *
79
     * @param array $keys
80
     * @param bool  $fill Fill missing key with filler value.
81
     * @param mixed $filler
82
     * @return array
83
     */
84
    public function fetch(array $keys, bool $fill = false, $filler = null)
85
    {
86
        $result = array_intersect_key($this->all(), array_flip($keys));
87
        ;
88
        if (!$fill) {
89
            return $result;
90
        }
91
92
        return $result + array_fill_keys($keys, $filler);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function offsetExists($offset)
99
    {
100
        return $this->has($offset);
101
    }
102
103
    /**
104
     * Check if field presented (can be empty) by it's name. Dot notation allowed.
105
     *
106
     * @param string $name
107
     * @return bool
108
     */
109
    public function has(string $name): bool
110
    {
111
        try {
112
            $this->dotGet($name);
113
        } catch (DotNotFoundException $e) {
114
            return false;
115
        }
116
117
        return true;
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    public function offsetGet($offset)
124
    {
125
        return $this->get($offset);
126
    }
127
128
    /**
129
     * Get property or return default value. Dot notation allowed.
130
     *
131
     * @param string $name
132
     * @param mixed  $default
133
     * @return mixed
134
     */
135
    public function get(string $name, $default = null)
136
    {
137
        try {
138
            return $this->dotGet($name);
139
        } catch (DotNotFoundException $e) {
140
            return $default;
141
        }
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     *
147
     * @throws InputException
148
     */
149
    public function offsetSet($offset, $value): void
150
    {
151
        throw new InputException('InputBag is immutable');
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     *
157
     * @throws InputException
158
     */
159
    public function offsetUnset($offset): void
160
    {
161
        throw new InputException('InputBag is immutable');
162
    }
163
164
    /**
165
     * Get element using dot notation.
166
     *
167
     * @param string $name
168
     * @return mixed|null
169
     *
170
     * @throws DotNotFoundException
171
     */
172
    private function dotGet(string $name)
173
    {
174
        $data = $this->data;
175
176
        //Generating path relative to a given name and prefix
177
        $path = (!empty($this->prefix) ? $this->prefix . '.' : '') . $name;
178
        if (empty($path)) {
179
            return $data;
180
        }
181
182
        $path = explode('.', rtrim($path, '.'));
183
184
        foreach ($path as $step) {
185
            if (!is_array($data) || !array_key_exists($step, $data)) {
186
                throw new DotNotFoundException("Unable to find requested element '{$name}'");
187
            }
188
189
            $data = &$data[$step];
190
        }
191
192
        return $data;
193
    }
194
}
195