Passed
Pull Request — master (#12)
by Donald
02:34
created

Store::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 1
nop 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php namespace Chekote\NounStore;
2
3
use InvalidArgumentException;
4
use OutOfBoundsException;
5
use RuntimeException;
6
7
class Store
8
{
9
    /** @var array */
10
    protected $nouns;
11
12
    /** @var Key */
13
    protected $keyService;
14
15
    /** @var Assert */
16
    protected $assert;
17
18 37
    public function __construct(Key $keyService = null)
19
    {
20 37
        $this->keyService = $keyService ?: Key::getInstance();
21
22
        // @todo this is temporary. remove once all assert methods are moved to Assert class
23 37
        $this->assert = new Assert($this, $this->keyService);
24 37
    }
25
26
    /**
27
     * Asserts that the key's value contains the specified string.
28
     *
29
     * @param  string                   $key   The key to check. @see self::get() for formatting options.
30
     * @param  string                   $value The value expected to be contained within the key's value.
31
     * @param  int                      $index [optional] The index of the key entry to retrieve. If not specified, the
32
     *                                         method will check the most recent value stored under the key.
33
     * @throws OutOfBoundsException     If a value has not been stored for the specified key.
34
     * @throws InvalidArgumentException if both an $index and $key are provided, but the $key contains an nth value
35
     *                                        that does not match the index.
36
     */
37 10
    public function assertKeyValueContains($key, $value, $index = null)
38
    {
39 10
        list($key, $index) = $this->keyService->parse($key, $index);
40
41 9
        $this->assert->keyExists($key, $index);
42
43 7
        if (!$this->keyValueContains($key, $value, $index)) {
44 2
            throw new RuntimeException(
45 2
                "Entry '" . $this->keyService->build($key, $index) . "' does not contain '$value'"
46
            );
47
        }
48 5
    }
49
50
    /**
51
     * Removes all entries from the store.
52
     *
53
     * @return void
54
     */
55 1
    public function reset()
56
    {
57 1
        $this->nouns = [];
58 1
    }
59
60
    /**
61
     * Retrieves a value for the specified key.
62
     *
63
     * Each key is actually a collection. If you do not specify which item in the collection you want,
64
     * the method will return the most recent entry. You can specify the entry you want by either
65
     * using the plain english 1st, 2nd, 3rd etc in the $key param, or by specifying 0, 1, 2 etc in
66
     * the $index param. For example:
67
     *
68
     * Retrieve the most recent entry "Thing" collection:
69
     *   retrieve("Thing")
70
     *
71
     * Retrieve the 1st entry in the "Thing" collection:
72
     *   retrieve("1st Thing")
73
     *   retrieve("Thing", 0)
74
     *
75
     * Retrieve the 3rd entry in the "Thing" collection:
76
     *   retrieve("3rd Thing")
77
     *   retrieve("Thing", 2)
78
     *
79
     * Please note: The nth value in the string key is indexed from 1. In that "1st" is the first item stored.
80
     * The index parameter is indexed from 0. In that 0 is the first item stored.
81
     *
82
     * Please Note: If you specify both an $index param and an nth in the $key, they must both reference the same index.
83
     * If they do not, the method will throw an InvalidArgumentException.
84
     *
85
     * retrieve("1st Thing", 1);
86
     *
87
     * @param  string                   $key   The key to retrieve the value for. Can be prefixed with an nth descriptor.
88
     * @param  int                      $index [optional] The index of the key entry to retrieve. If not specified, the
89
     *                                         method will return the most recent value stored under the key.
90
     * @throws InvalidArgumentException if both an $index and $key are provided, but the $key contains an nth value
91
     *                                        that does not match the index.
92
     * @return mixed                    The value, or null if no value exists for the specified key/index combination.
93
     */
94 23
    public function get($key, $index = null)
95
    {
96 23
        list($key, $index) = $this->keyService->parse($key, $index);
97
98 22
        if (!$this->keyExists($key, $index)) {
99 5
            return;
100
        }
101
102 17
        return $index !== null ? $this->nouns[$key][$index] : end($this->nouns[$key]);
103
    }
104
105
    /**
106
     * Retrieves all values for the specified key.
107
     *
108
     * @param  string               $key The key to retrieve the values for.
109
     * @throws OutOfBoundsException if the specified $key does not exist in the store.
110
     * @return array                The values.
111
     */
112 2
    public function getAll($key)
113
    {
114 2
        if (!isset($this->nouns[$key])) {
115 1
            throw new OutOfBoundsException("'$key' does not exist in the store");
116
        }
117
118 1
        return $this->nouns[$key];
119
    }
120
121
    /**
122
     * Determines if a value has been stored for the specified key.
123
     *
124
     * @param  string                   $key   The key to check.
125
     * @param  int                      $index [optional] The index of the key entry to check. If not specified, the
126
     *                                         method will ensure that at least one item is stored for the key.
127
     * @throws InvalidArgumentException if both an $index and $key are provided, but the $key contains an nth value
128
     *                                        that does not match the index.
129
     * @return bool                     True if the a value has been stored, false if not.
130
     */
131 29
    public function keyExists($key, $index = null)
132
    {
133 29
        list($key, $index) = $this->keyService->parse($key, $index);
134
135 28
        return $index !== null ? isset($this->nouns[$key][$index]) : isset($this->nouns[$key]);
136
    }
137
138
    /**
139
     * Asserts that the key's value contains the specified string.
140
     *
141
     * @param  string                   $key   The key to check. @see self::get() for formatting options.
142
     * @param  string                   $value The value expected to be contained within the key's value.
143
     * @param  int                      $index [optional] The index of the key entry to retrieve. If not specified, the
144
     *                                         method will check the most recent value stored under the key.
145
     * @throws InvalidArgumentException if both an $index and $key are provided, but the $key contains an nth value
146
     *                                        that does not match the index.
147
     * @return bool                     True if the key's value contains the specified string, false if not.
148
     */
149 17
    public function keyValueContains($key, $value, $index = null)
150
    {
151 17
        list($key, $index) = $this->keyService->parse($key, $index);
152
153 16
        $actual = $this->get($key, $index);
154
155 16
        return is_string($actual) && strpos($actual, $value) !== false;
156
    }
157
158
    /**
159
     * Stores a value for the specified key.
160
     *
161
     * @param string $key   The key to store the value under.
162
     * @param mixed  $value The value to store.
163
     */
164 37
    public function set($key, $value)
165
    {
166 37
        $this->nouns[$key][] = $value;
167 37
    }
168
}
169