Passed
Push — master ( 457209...f3a6b9 )
by Max
02:29
created

AbstractDictionary::offsetExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EasyDictionary;
6
7
use EasyDictionary\Interfaces\DataProviderInterface;
8
use EasyDictionary\Interfaces\DictionaryInterface;
9
use Psr\SimpleCache\CacheInterface;
10
11
/**
12
 * Class AbstractDictionary
13
 * @package EasyDictionary
14
 */
15
abstract class AbstractDictionary implements DictionaryInterface
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $name = '';
21
22
    /**
23
     * @var DataProviderInterface
24
     */
25
    protected $dataProvider = null;
26
27
    /**
28
     * @var callable
29
     */
30
    protected $view = null;
31
32
    /**
33
     * @var \Psr\SimpleCache\CacheInterface
34
     */
35
    protected $cache = null;
36
37
    /**
38
     * @var int
39
     */
40
    protected $cacheTTL = 0;
41
42
    /**
43
     * @var iterable
44
     */
45
    protected $data = [];
46
47
    /**
48
     * @var array
49
     */
50
    protected $searchFields = [];
51
52
    /**
53
     * @var bool
54
     */
55
    protected $dataLoaded = false;
56
57
    /**
58
     * AbstractDictionary constructor.
59
     * @param string $name
60
     */
61 16
    public function __construct(string $name = '')
62
    {
63 16
        $this->setName($name);
64 16
    }
65
66
    /**
67
     * @param callable|null $view
68
     * @return $this
69
     */
70 3
    public function setDefaultView(callable $view = null)
71
    {
72 3
        $this->view = $view;
73
74 3
        return $this;
75
    }
76
77
    /**
78
     * @return null|DataProviderInterface
79
     */
80 14
    public function getDataProvider(): ?DataProviderInterface
81
    {
82 14
        return $this->dataProvider;
83
    }
84
85
    /**
86
     * @param DataProviderInterface $provider
87
     * @return $this
88
     */
89 15
    public function setDataProvider(DataProviderInterface $provider)
90
    {
91 15
        $this->dataProvider = $provider;
92
93 15
        return $this;
94
    }
95
96
    /**
97
     * @return int
98
     */
99 1
    public function count(): int
100
    {
101 1
        return count($this->getData());
102
    }
103
104
    /**
105
     * @return mixed
106
     */
107 14
    public function getData(): iterable
108
    {
109 14
        if (false === $this->dataLoaded) {
110 14
            $cache = $this->getCache();
111
112 14
            if (is_null($cache)) {
113 12
                $this->data = $this->loadData();
114
            } else {
115 2
                $key = static::class . '_' . $this->getName();
116
117
                try {
118 2
                    if (!($this->data = $cache->get($key, []))) {
119 2
                        $this->data = $this->loadData();
120 2
                        $cache->set($key, $this->data, $this->cacheTTL);
121
                    }
122 1
                } catch (\Psr\SimpleCache\InvalidArgumentException $e) {
123 1
                    $this->data = [];
124
                }
125
            }
126
127 14
            $this->dataLoaded = true;
128
        }
129
130 14
        return $this->data;
131
    }
132
133
    /**
134
     * @return CacheInterface
135
     */
136 14
    public function getCache(): ?CacheInterface
137
    {
138 14
        return $this->cache;
139
    }
140
141
    /**
142
     * @param CacheInterface $cache
143
     * @param int $ttl
144
     * @return $this
145
     */
146 2
    public function setCache(CacheInterface $cache, int $ttl = 3600)
147
    {
148 2
        $this->cache = $cache;
149 2
        $this->cacheTTL = $ttl;
150
151 2
        return $this;
152
    }
153
154
    /**
155
     * @return iterable
156
     */
157
    abstract protected function loadData(): iterable;
158
159
    /**
160
     * @return string
161
     */
162 3
    public function getName(): string
163
    {
164 3
        return $this->name;
165
    }
166
167
    /**
168
     * @param string $name
169
     */
170 16
    public function setName(string $name)
171
    {
172 16
        $this->name = $name;
173 16
    }
174
175
    /**
176
     * @param string $pattern
177
     * @param bool $strict
178
     * @return iterable
179
     */
180 2
    public function search(string $pattern, bool $strict = false): iterable
181
    {
182 2
        $data = [];
183 2
        $searchData = [];
184 2
        $searchFields = array_filter($this->getSearchFields($strict));
185 2
        foreach ($this as $key => $value) {
186 2
            $data[$key] = $value;
187
188 2
            if (is_array($value)) {
189 1
                $searchData[$key] = (string)$key . ' ' .
190 1
                    join(' ', empty($searchFields) ? $value : array_intersect_key($value, $searchFields));
191
            } else {
192 2
                $searchData[$key] = (string)$key . ' ' . (string)$value;
193
            }
194
        }
195
196 2
        return array_intersect_key($data, preg_grep($pattern, $searchData));
197
    }
198
199
    /**
200
     * @param bool $strict
201
     * @return array
202
     */
203 2
    public function getSearchFields(bool $strict = false): array
204
    {
205 2
        return true === $strict ? array_filter($this->searchFields) : $this->searchFields;
206
    }
207
208
    /**
209
     * @param array $searchFields
210
     * @return $this
211
     */
212 3
    public function setSearchFields(array $searchFields)
213
    {
214 3
        $this->searchFields = $searchFields;
215
216 3
        return $this;
217
    }
218
219
    /**
220
     * @param mixed $offset
221
     * @param mixed $value
222
     * @return null|void
223
     */
224 1
    public function offsetSet($offset, $value)
225
    {
226 1
    }
227
228
    /**
229
     * @param mixed $offset
230
     * @return bool
231
     */
232 1
    public function offsetExists($offset)
233
    {
234 1
        $data = $this->getData();
235
236 1
        return isset($data[$offset]);
237
    }
238
239
    /**
240
     * @param mixed $offset
241
     * @return null|void
242
     */
243 1
    public function offsetUnset($offset)
244
    {
245 1
    }
246
247
    /**
248
     * @param mixed $offset
249
     * @return mixed|null
250
     */
251 1
    public function offsetGet($offset)
252
    {
253 1
        $data = $this->getData();
254
255 1
        return $data[$offset] ?? null;
256
    }
257
258
    /**
259
     * @return array
260
     */
261 3
    public function toArray()
262
    {
263 3
        return iterator_to_array($this->getIterator());
264
    }
265
266
    /**
267
     * @return \Iterator
268
     */
269 8
    public function getIterator(): iterable
270
    {
271 8
        $view = $this->getDefaultView();
272
273 8
        if (is_null($view)) {
0 ignored issues
show
introduced by
The condition is_null($view) is always false.
Loading history...
274 7
            foreach ($this->getData() as $key => $item) {
275 7
                yield $key => $item;
276
            }
277
        } else {
278 1
            yield from $this->withView($view);
279
        }
280 8
    }
281
282
    /**
283
     * @return callable|null
284
     */
285 8
    public function getDefaultView(): ?callable
286
    {
287 8
        return $this->view;
288
    }
289
290
    /**
291
     * @param callable $callable
292
     * @return \Generator
293
     */
294 2
    public function withView(callable $callable = null): iterable
295
    {
296 2
        if (is_callable($callable)) {
297 1
            yield from call_user_func($callable, $this->getData());
298
        } else {
299 1
            yield from $this->getIterator();
300
        }
301 2
    }
302
}
303