AbstractData::offsetUnset()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
namespace Tuum\Form\Data;
3
4
use Traversable;
5
6
abstract class AbstractData implements \ArrayAccess, \IteratorAggregate
7
{
8
    /**
9
     * @var array|object
10
     */
11
    protected $data = [];
12
13
    /**
14
     * @var callable|Escape
15
     */
16
    protected $escape;
17
18
    /**
19
     * @ param Message $message
20
     *
21
     * @param array|object  $data
22
     * @param null|callable $escape
23
     */
24
    public function __construct($data = [], $escape = null)
25
    {
26
        $this->data   = $data;
27
        $this->escape = $escape ?: ['Tuum\Form\Data\Escape', 'htmlSafe'];
28
    }
29
30
    /**
31
     * @param array|object  $data
32
     * @param null|callable $escape
33
     * @return static
34
     */
35
    public static function forge($data = [], $escape = null)
36
    {
37
        return new static($data, $escape);
38
    }
39
40
    /**
41
     * accessing data as property. returns escaped value.
42
     *
43
     * @param string $key
44
     * @return mixed
45
     */
46
    public function __get($key)
47
    {
48
        return $this->get($key);
49
    }
50
51
    /**
52
     * get an escaped value.
53
     *
54
     * @param string     $key
55
     * @param null|mixed $default
56
     * @return mixed
57
     */
58
    public function get($key, $default = null)
59
    {
60
        $value  = $this->raw($key, $default);
61
        $escape = $this->escape;
62
        return $escape($value);
63
    }
64
65
    /**
66
     * @param string $name
67
     * @param string|null $value
68
     * @param string $string
69
     * @return string
70
     */
71
    public function ifExists($name, $value, $string)
72
    {
73
        if ($this->exists($name, $value)) {
74
            return $string;
75
        }
76
        return '';
77
    }
78
79
    /**
80
     * @param string $name
81
     * @param string $value
82
     * @return bool
83
     */
84
    public function exists($name, $value = null)
85
    {
86
        $found = $this->raw($name);
87
        if (is_null($found)) {
88
            return false;
89
        }
90
        if (!is_null($value)) {
91
            if (is_array($found)) {
92
                return in_array($value, $found);
93
            }
94
            return (string)$value === (string)$found;
95
        }
96
        return true;
97
    }
98
99
    /**
100
     * get a raw value.
101
     *
102
     * @param string     $key
103
     * @param null|mixed $default
104
     * @return mixed
105
     */
106
    public function raw($key, $default = null)
107
    {
108
        if (strpos($key, '[') === false) {
109
            return Accessor::get($this->data, $key, $default);
110
        }
111
        $found = $this->parseRaw($key);
112
        if (!is_null($found)) {
113
            return $found;
114
        }
115
        return $default;
116
    }
117
118
    /**
119
     * get a raw value for form element array name (with []).
120
     *
121
     * @param string $key
122
     * @return null|mixed
123
     */
124
    private function parseRaw($key)
125
    {
126
        $key = str_replace('[]', '', $key);
127
        parse_str($key, $levels);
128
        if (is_null($levels)) {
129
            return null;
130
        }
131
        $inputs = $this->data;
132
        return $this->recurseGet($levels, $inputs);
133
    }
134
135
    /**
136
     * gets a value from $input array.
137
     *
138
     * returns null if not found. or
139
     * returns an empty space if key is set but has not real value.
140
     *
141
     * @param array $levels
142
     * @param mixed $inputs
143
     * @return mixed
144
     */
145
    private function recurseGet($levels, $inputs)
146
    {
147
        if (!is_array($levels)) {
148
            if (is_null($inputs) || $inputs === false) {
149
                $inputs = '';
150
            }
151
            return $inputs;
152
        }
153
        foreach($levels as $key => $next) {
154
            if (Accessor::has($inputs, $key)) {
155
                return $this->recurseGet($next, Accessor::get($inputs, $key));
156
            }
157
            break;
158
        }
159
        return null;
160
    }
161
162
    /**
163
     * returns new Data object populated with its data[$key].
164
     *
165
     * @param string $key
166
     * @return static
167
     */
168
    public function extractKey($key)
169
    {
170
        $self       = clone($this);
171
        $self->data = Accessor::get($this->data, $key) ?: [];
172
        return $self;
173
    }
174
175
    /**
176
     * Retrieve an external iterator
177
     *
178
     * @return Traversable
179
     */
180
    public function getIterator()
181
    {
182
        $data = $this->data;
183
        foreach ($this->data as $key => $val) {
184
            $data[$key] = $this->extractKey($key);
185
        }
186
        return new \ArrayIterator($data);
187
    }
188
189
    /**
190
     * @param mixed $offset
191
     * @return bool
192
     */
193
    public function offsetExists($offset)
194
    {
195
        return array_key_exists($offset, $this->data);
196
    }
197
198
    /**
199
     * @param mixed
200
     * @return mixed
201
     */
202
    public function offsetGet($offset)
203
    {
204
        return $this->get($offset);
205
    }
206
207
    /**
208
     * @param mixed $offset
209
     * @param mixed $value
210
     * @return void
211
     */
212
    public function offsetSet($offset, $value)
213
    {
214
        $this->data[$offset] = $value;
215
    }
216
217
    /**
218
     * @param mixed $offset
219
     * @return void
220
     */
221
    public function offsetUnset($offset)
222
    {
223
        if ($this->offsetExists($offset)) {
224
            unset($this->data[$offset]);
225
        }
226
    }
227
228
}
229