Test Setup Failed
Push — master ( c91700...65feeb )
by Php Easy Api
03:50
created

ArraySafe::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
4
namespace Resta\Support;
5
6
class ArraySafe implements \JsonSerializable, \ArrayAccess {
7
8
    /**
9
     * @var array
10
     */
11
    private $data;
12
13
    /**
14
     * SafeArray constructor.
15
     *
16
     * @param array $data
17
     */
18
    public function __construct( array $data = [] )
19
    {
20
        $this->data = $data;
21
    }
22
23
    /**
24
     * @param array $target
25
     * @param array $indices
26
     *
27
     * @return array|mixed|null
28
     */
29
    public function safeGet( array $target, $indices )
30
    {
31
        $movingTarget = $target;
32
33
        foreach ( $indices as $index )
34
        {
35
            $isArray = is_array( $movingTarget ) || $movingTarget instanceof ArrayAccess;
0 ignored issues
show
introduced by
The condition is_array($movingTarget) is always true.
Loading history...
Bug introduced by
The type Resta\Support\ArrayAccess was not found. Did you mean ArrayAccess? If so, make sure to prefix the type with \.
Loading history...
36
            if ( ! $isArray || ! isset( $movingTarget[ $index ] ) ) return NULL;
37
38
            $movingTarget = $movingTarget[ $index ];
39
        }
40
41
        return $movingTarget;
42
    }
43
44
    /**
45
     * @param array $keys
46
     *
47
     * @return array|mixed|null
48
     */
49
    public function getKeys( array $keys )
50
    {
51
        return static::safeGet( $this->data, $keys );
0 ignored issues
show
Bug Best Practice introduced by
The method Resta\Support\ArraySafe::safeGet() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        return static::/** @scrutinizer ignore-call */ safeGet( $this->data, $keys );
Loading history...
52
    }
53
54
    /**
55
     * <p>Access nested array index values by providing a dot notation access string.</p>
56
     * <p>Example: $safeArrayGetter->get('customer.paymentInfo.ccToken') ==
57
     * $array['customer']['paymentInfo']['ccToken']</p>
58
     *
59
     * @param $accessString
60
     *
61
     * @return array|mixed|null
62
     */
63
    public function get( $accessString )
64
    {
65
        return $this->getKeys( $this->parseDotNotation( $accessString ) );
66
    }
67
68
    /**
69
     * @param      $propString
70
     * @param      $value
71
     *
72
     * @return $this
73
     */
74
    public function set( $propString, $value )
75
    {
76
        $movingTarget = &$this->data;
77
        $keys         = $this->parseDotNotation( $propString );
78
        $length       = count( $keys );
79
80
        foreach ( $keys as $i => $key )
81
        {
82
            $lastKey = $i === $length - 1;
83
            $isset   = isset( $movingTarget[ $key ] );
84
85
            if ( $isset && ! $lastKey && ! is_array( $movingTarget[ $key ] ) )
86
            {
87
                throw new InvalidArgumentException( sprintf(
0 ignored issues
show
Bug introduced by
The type Resta\Support\InvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
88
                    "Attempted to set/access the property %s like an array, but is of type: %s",
89
                    $key,
90
                    gettype( $movingTarget[ $key ] )
91
                ) );
92
            }
93
94
            if ( ! $isset || ! is_array( $movingTarget[ $key ] ) ) $movingTarget[ $key ] = [];
95
96
            $movingTarget = &$movingTarget[ $key ];
97
        }
98
99
        $movingTarget = $value;
100
101
        return $this;
102
    }
103
104
    /**
105
     * @param $string
106
     *
107
     * @return array
108
     */
109
    protected function parseDotNotation( $string )
110
    {
111
        return explode( '.', strval( $string ) );
112
    }
113
114
    /**
115
     * @return array
116
     */
117
    public function toArray()
118
    {
119
        return $this->data;
120
    }
121
122
    /**
123
     * @param int $options
124
     * @param int $depth
125
     *
126
     * @return string
127
     */
128
    public function toJson( $options = 0, $depth = 512 )
129
    {
130
        return json_encode( $this, $options, $depth );
131
    }
132
133
    /**
134
     * @param array $data
135
     *
136
     * @return static
137
     */
138
    public static function newFromArray( array $data )
139
    {
140
        return new static( $data );
141
    }
142
143
    /**
144
     * @param \stdClass $data
145
     *
146
     * @return static
147
     */
148
    public static function newFromStdObject( \stdClass $data )
149
    {
150
        return new static( json_decode( json_encode( $data ), TRUE ) );
151
    }
152
153
    /**
154
     * Specify data which should be serialized to JSON
155
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
156
     * @return array data which can be serialized by <b>json_encode</b>,
157
     * which is a value of any type other than a resource.
158
     * @since 5.4.0
159
     */
160
    function jsonSerialize()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
161
    {
162
        return $this->toArray();
163
    }
164
165
    /**
166
     * Whether a offset exists
167
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
168
     *
169
     * @param mixed $offset <p>
170
     * An offset to check for.
171
     * </p>
172
     *
173
     * @return boolean true on success or false on failure.
174
     * </p>
175
     * <p>
176
     * The return value will be casted to boolean if non-boolean was returned.
177
     * @since 5.0.0
178
     */
179
    public function offsetExists( $offset )
180
    {
181
        $movingTarget = $this->data;
182
183
        foreach ( $this->parseDotNotation( $offset ) as $i )
184
        {
185
            if ( ! isset( $movingTarget[ $i ] ) ) return FALSE;
186
            $movingTarget = $movingTarget[ $i ];
187
        }
188
189
        return isset( $movingTarget );
190
    }
191
192
    /**
193
     * Offset to retrieve
194
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
195
     *
196
     * @param mixed $offset <p>
197
     * The offset to retrieve.
198
     * </p>
199
     *
200
     * @return mixed Can return all value types.
201
     * @since 5.0.0
202
     */
203
    public function offsetGet( $offset )
204
    {
205
        return $this->get( $offset );
206
    }
207
208
    /**
209
     * Offset to set
210
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
211
     *
212
     * @param mixed $offset <p>
213
     * The offset to assign the value to.
214
     * </p>
215
     * @param mixed $value <p>
216
     * The value to set.
217
     * </p>
218
     *
219
     * @return void
220
     * @since 5.0.0
221
     */
222
    public function offsetSet( $offset, $value )
223
    {
224
        $this->set( $offset, $value );
225
    }
226
227
    /**
228
     * Offset to unset
229
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
230
     *
231
     * @param mixed $offset <p>
232
     * The offset to unset.
233
     * </p>
234
     *
235
     * @return void
236
     * @since 5.0.0
237
     */
238
    public function offsetUnset( $offset )
239
    {
240
        $movingTarget = &$this->data;
241
        $keys         = $this->parseDotNotation( $offset );
242
        $length       = count( $keys );
243
244
        foreach ( $keys as $i => $key )
245
        {
246
            if ( $i === $length - 1 )
247
            {
248
                unset( $movingTarget[ $key ] );
249
            }
250
            else
251
            {
252
                $movingTarget = &$movingTarget[ $key ];
253
            }
254
        }
255
    }
256
257
    /**
258
     * @return string
259
     */
260
    public function __toString()
261
    {
262
        return json_encode( $this );
263
    }
264
}