Passed
Pull Request — 3.0 (#35)
by Rashid
02:10
created

Store::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php namespace Chekote\NounStore;
2
3
use ArrayAccess;
4
use Closure;
5
use InvalidArgumentException;
6
7
class Store
8
{
9
    /** @var Key */
10
    protected $keyService;
11
12
    /** @var array */
13
    protected $nouns;
14
15
    /**
16
     * @param Key $keyService the key service to use for parsing and building keys
17
     * @codeCoverageIgnore
18
     */
19
    public function __construct(Key $keyService = null)
20
    {
21
        $this->keyService = $keyService ?: Key::getInstance();
22
    }
23
24
    /**
25
     * Removes all entries from the store.
26
     *
27
     * @return void
28
     */
29
    public function reset()
30
    {
31
        $this->nouns = [];
32
    }
33
34
    /**
35
     * Retrieves a value for the specified key.
36
     *
37
     * Each key is actually a collection. If you do not specify which item in the collection you want,
38
     * the method will return the most recent entry. You can optionally specify the entry you want by
39
     * using the plain english 1st, 2nd, 3rd etc in the $key param. For example:
40
     *
41
     * Retrieve the most recent entry "Thing" collection:
42
     *   retrieve("Thing")
43
     *
44
     * Retrieve the 1st entry in the "Thing" collection:
45
     *   retrieve("1st Thing")
46
     *
47
     * Retrieve the 3rd entry in the "Thing" collection:
48
     *   retrieve("3rd Thing")
49
     *
50
     * @see    Key::build()
51
     * @see    Key::parse()
52
     * @param  string                   $key The key to retrieve the value for. Supports nth notation.
53
     * @throws InvalidArgumentException if the key syntax is invalid.
54
     * @return mixed                    The value, or null if no value exists for the specified key/index combination.
55
     */
56
    public function get($key)
57
    {
58
        if (!$this->keyExists($key)) {
59
            return;
60
        }
61
62
        list($key, $index) = $this->keyService->parse($key);
63
        if ($this->plainKeyExists($key)) {
64
            return $index !== null ? $this->nouns[$key][$index] : end($this->nouns[$key]);
65
        }
66
67
        // Complex key
68
        list($base_key, $child_keys) = $this->keyService->parseNested($key);
69
        if (!$this->plainKeyExists($base_key)) {
70
            return;
71
        }
72
73
        return $index
74
            ? $this->data_get($this->nouns[$base_key][$index - 1], $child_keys)
75
            : $this->data_get(end($this->nouns[$base_key]), $child_keys);
76
77
    }
78
79
    /**
80
     * Retrieves all values for the specified key.
81
     *
82
     * @param  string $key The key to retrieve the values for. Does not support nth notation.
83
     * @return array  The values, or an empty array if no value exists for the specified key.
84
     */
85
    public function getAll($key)
86
    {
87
        return isset($this->nouns[$key]) ? $this->nouns[$key] : [];
88
    }
89
90
    /**
91
     * Determines if a value has been stored for the specified key.
92
     *
93
     * @see    Key::build()
94
     * @see    Key::parse()
95
     * @param  string                   $key The key to check. Supports nth notation.
96
     * @throws InvalidArgumentException if the key syntax is invalid.
97
     * @return bool                     True if the a value has been stored, false if not.
98
     */
99
    public function keyExists($key)
100
    {
101
        list($key, $index) = $this->keyService->parse($key);
102
        list($base_key, $unused) = $this->keyService->parseNested($key);
103
104
        return $index
105
            ? (isset($this->nouns[$key][$index]) || isset($this->nouns[$key][$index]))
106
            : (isset($this->nouns[$key]) || isset($this->nouns[$base_key]));
107
    }
108
109
    /**
110
     * Determines if a value has been stored for the specified key.
111
     *
112
     * @see    Key::build()
113
     * @see    Key::parse()
114
     * @param  string                   $key The key to check. Supports nth notation.
115
     * @throws InvalidArgumentException if the key syntax is invalid.
116
     * @return bool                     True if the a value has been stored, false if not.
117
     */
118
    public function plainKeyExists($key)
119
    {
120
        list($key, $index) = $this->keyService->parse($key);
121
122
        return $index ? isset($this->nouns[$key][$index]) : isset($this->nouns[$key]);
123
    }
124
125
    /**
126
     * Asserts that the key's value contains the specified string.
127
     *
128
     * @see    Key::build()
129
     * @see    Key::parse()
130
     * @param  string                   $key   The key to check.
131
     * @param  string                   $value The value expected to be contained within the key's value.
132
     * @throws InvalidArgumentException if the key syntax is invalid.
133
     * @return bool                     True if the key's value contains the specified string, false if not.
134
     */
135
    public function keyValueContains($key, $value)
136
    {
137
        $actual = $this->get($key);
138
139
        return is_string($actual) && strpos($actual, $value) !== false;
140
    }
141
142
    /**
143
     * Stores a value for the specified key.
144
     *
145
     * The specified value is added to the top of the "stack" for the specified key.
146
     *
147
     * @param string $key   The key to store the value under. Does not support nth notation.
148
     * @param mixed  $value The value to store.
149
     */
150
    public function set($key, $value)
151
    {
152
        $this->nouns[$key][] = $value;
153
    }
154
155
    /**
156
     * Retrieves a value from a nested array or object using array list.
157
     * (Modified version of data_get() laravel > 5.6).
158
     *
159
     * @param  mixed    $target    The target element
160
     * @param  string[] $key_parts List of nested values
161
     * @param  mixed    $default   If value doesn't exists
162
     * @return mixed
163
     */
164
    public function data_get($target, array $key_parts, $default = null)
165
    {
166
        foreach ($key_parts as $segment) {
167
            if (is_array($target)) {
168
                if (!array_key_exists($segment, $target)) {
169
                    return $this->closureValue($default);
170
                }
171
                $target = $target[$segment];
172
            } elseif ($target instanceof ArrayAccess) {
173
                if (!isset($target[$segment])) {
174
                    return $this->closureValue($default);
175
                }
176
                $target = $target[$segment];
177
            } elseif (is_object($target)) {
178
                if (!isset($target->{$segment})) {
179
                    return $this->closureValue($default);
180
                }
181
                $target = $target->{$segment};
182
            } else {
183
                return $this->closureValue($default);
184
            }
185
        }
186
187
        return $target;
188
    }
189
190
    /**
191
     * Returns value itself or Closure will be executed and return result.
192
     *
193
     * @param  string $value Closure to be evaluated
194
     * @return mixed  Result of the Closure function or $value itself
195
     */
196
    public function closureValue($value)
197
    {
198
        return $value instanceof Closure ? $value() : $value;
0 ignored issues
show
introduced by
$value is never a sub-type of Closure.
Loading history...
199
    }
200
}
201