Store   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 26
c 1
b 0
f 0
dl 0
loc 146
ccs 22
cts 22
cp 1
rs 10
wmc 14

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getAll() 0 3 2
A keyValueContains() 0 5 2
A keyExists() 0 3 1
A get() 0 26 4
A reset() 0 3 1
A keyIsClass() 0 5 1
A set() 0 3 1
A __construct() 0 3 2
1
<?php namespace Chekote\NounStore;
2
3
use Illuminate\Support\Arr;
4
use InvalidArgumentException;
5
6
class Store
7
{
8
    protected Key $keyService;
9
10
    protected array $nouns;
11
12
    /**
13
     * @param Key|null $keyService the key service to use for parsing and building keys
14
     * @codeCoverageIgnore
15
     */
16
    public function __construct(Key $keyService = null)
17
    {
18
        $this->keyService = $keyService ?: Key::getInstance();
19
    }
20
21
    /**
22
     * Removes all entries from the store.
23
     *
24
     * @return void
25
     */
26
    public function reset(): void
27
    {
28 1
        $this->nouns = [];
29
    }
30 1
31 1
    /**
32
     * Retrieves a value for the specified key.
33
     *
34
     * Each key is actually a collection. If you do not specify which item in the collection you want,
35
     * the method will return the most recent entry. You can optionally specify the entry you want by
36
     * using the plain english 1st, 2nd, 3rd etc in the $key param. For example:
37
     *
38
     * Retrieve the most recent entry "Thing" collection:
39
     *   retrieve("Thing")
40
     *
41
     * Retrieve the 1st entry in the "Thing" collection:
42
     *   retrieve("1st Thing")
43
     *
44
     * Retrieve the 3rd entry in the "Thing" collection:
45
     *   retrieve("3rd Thing")
46
     *
47
     * @see    Key::build()
48
     * @see    Key::parseNoun()
49
     * @param  string                   $key The key to retrieve the value for. Supports nth notation.
50
     * @throws InvalidArgumentException if the key syntax is invalid.
51
     * @return mixed                    The value, or null if no value exists for the specified key/index combination.
52
     */
53
    public function get(string $key): mixed
54
    {
55
        $i = 0;
56
57
        return array_reduce(
58
            $this->keyService->parse($key),
59
            static function ($carry, $item) use (&$i) {
60
                list($noun, $index) = $item;
61
62
                $carry = data_get($carry, $noun);
63
64
                try {
65
                    // Was a specific index requested?
66
                    if ($index !== null) {
67 5
                        // Yes, fetch the specific index
68
                        return data_get($carry, $index);
69 5
                    } else {
70
                        // No, return the noun itself, or the latest noun if this is the
71 4
                        // first component of the key, and the noun is a collection
72 1
                        return $i === 0 && Arr::accessible($carry) ? end($carry) : $carry;
0 ignored issues
show
Bug introduced by
It seems like $carry can also be of type null; however, parameter $array of end() does only seem to accept array|object, maybe add an additional type check? ( Ignorable by Annotation )

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

72
                        return $i === 0 && Arr::accessible($carry) ? end(/** @scrutinizer ignore-type */ $carry) : $carry;
Loading history...
73
                    }
74
                } finally {
75 3
                    ++$i;
76
                }
77
            },
78
            $this->nouns
79
        );
80
    }
81
82
    /**
83
     * Retrieves all values for the specified key.
84
     *
85 2
     * @param  string $key The key to retrieve the values for. Does not support nth notation.
86
     * @return array  The values, or an empty array if no value exists for the specified key.
87 2
     */
88 1
    public function getAll(string $key): array
89
    {
90
        return isset($this->nouns[$key]) ? $this->nouns[$key] : [];
91 1
    }
92
93
    /**
94
     * Determines if a value has been stored for the specified key.
95
     *
96
     * @see    Key::build()
97
     * @see    Key::parseNoun()
98
     * @param  string                   $key The key to check. Supports nth notation.
99
     * @throws InvalidArgumentException if the key syntax is invalid.
100
     * @return bool                     True if the a value has been stored, false if not.
101
     */
102
    public function keyExists(string $key): bool
103
    {
104 5
        return $this->get($key) !== null;
105
    }
106 5
107
    /**
108 4
     * Asserts that the key's value contains the specified string.
109
     *
110
     * @see    Key::build()
111
     * @see    Key::parseNoun()
112
     * @param  string                   $key   The key to check.
113
     * @param  string                   $value The value expected to be contained within the key's value.
114
     * @throws InvalidArgumentException if the key syntax is invalid.
115
     * @return bool                     True if the key's value contains the specified string, false if not.
116
     */
117
    public function keyValueContains(string $key, string $value): bool
118
    {
119
        $actual = $this->get($key);
120
121
        return is_string($actual) && strpos($actual, $value) !== false;
122 4
    }
123
124 4
    /**
125
     * Stores a value for the specified key.
126 3
     *
127
     * The specified value is added to the top of the "stack" for the specified key.
128 3
     *
129
     * @param string $key   The key to store the value under. Does not support nth notation.
130
     * @param mixed  $value The value to store.
131
     */
132
    public function set(string $key, mixed $value): void
133
    {
134
        $this->nouns[$key][] = $value;
135
    }
136
137 2
    /**
138
     * Asserts that the key's value contains the specified class instance.
139 2
     *
140 2
     * @see    Key::build()
141
     * @see    Key::parseNoun()
142
     * @param  string                   $key   The key to check.
143
     * @param  class-string             $class The class instance expected to be contained within the key's value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
144
     * @throws InvalidArgumentException if the key syntax is invalid.
145
     * @return bool                     True if the key's value contains the specified class instance, false if not.
146
     */
147
    public function keyIsClass(string $key, string $class): bool
148
    {
149
        $actual = $this->get($key);
150
151
        return $actual instanceof $class;
152
    }
153
}
154