Completed
Push — 1.x ( 0f5ece...c9692e )
by Asao
36:16
created

AbstractData::ifExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 3
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
        list($key, $next) = each($levels);
154
        // an array
155
        if (Accessor::has($inputs, $key)) {
156
            return $this->recurseGet($next, Accessor::get($inputs, $key));
157
        }
158
        return null;
159
    }
160
161
    /**
162
     * returns new Data object populated with its data[$key].
163
     *
164
     * @param string $key
165
     * @return static
166
     */
167
    public function extractKey($key)
168
    {
169
        $self       = clone($this);
170
        $self->data = Accessor::get($this->data, $key) ?: [];
171
        return $self;
172
    }
173
174
    /**
175
     * Retrieve an external iterator
176
     *
177
     * @return Traversable
178
     */
179
    public function getIterator()
180
    {
181
        $data = $this->data;
182
        foreach ($this->data as $key => $val) {
183
            $data[$key] = $this->extractKey($key);
184
        }
185
        return new \ArrayIterator($data);
186
    }
187
188
    /**
189
     * @param mixed $offset
190
     * @return bool
191
     */
192
    public function offsetExists($offset)
193
    {
194
        return array_key_exists($offset, $this->data);
195
    }
196
197
    /**
198
     * @param mixed
199
     * @return mixed
200
     */
201
    public function offsetGet($offset)
202
    {
203
        return $this->get($offset);
204
    }
205
206
    /**
207
     * @param mixed $offset
208
     * @param mixed $value
209
     * @return void
210
     */
211
    public function offsetSet($offset, $value)
212
    {
213
        $this->data[$offset] = $value;
214
    }
215
216
    /**
217
     * @param mixed $offset
218
     * @return void
219
     */
220
    public function offsetUnset($offset)
221
    {
222
        if ($this->offsetExists($offset)) {
223
            unset($this->data[$offset]);
224
        }
225
    }
226
227
}
228