SettingBase::cacheHas()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php namespace Cornford\Setter;
2
3
use Cornford\Setter\Exceptions\SettingArgumentException;
4
use DateTime;
5
use Illuminate\Database\DatabaseManager;
6
use Illuminate\Config\Repository;
7
use Illuminate\Cache\Repository as Cache;
8
9
abstract class SettingBase {
10
11
	const LOCATION_DATABASE = 'database';
12
	const LOCATION_CACHE = 'cache';
13
14
	const CACHE_ENABLED = true;
15
	const CACHE_TAG = 'setter::';
16
	const CACHE_EXPIRY = true;
17
18
	/**
19
	 * Database
20
	 *
21
	 * @var \Illuminate\Database\DatabaseManager
22
	 */
23
	protected $databaseInstance;
24
25
	/**
26
	 * Config
27
	 *
28
	 * @var \Illuminate\Config\Repository
29
	 */
30
	protected $config;
31
32
	/**
33
	 * Cache
34
	 *
35
	 * @var \Illuminate\Cache\Repository
36
	 */
37
	protected $cache;
38
39
	/**
40
	 * Caching Enabled?
41
	 *
42
	 * @var boolean
43
	 */
44
	protected $cacheEnabled = true;
45
46
	/**
47
	 * Cache Tag
48
	 *
49
	 * @var string
50
	 */
51
	protected $cacheTag;
52
53
	/**
54
	 * Cache
55
	 *
56
	 * @var boolean|integer|DateTime
57
	 */
58
	protected $cacheExpiry;
59
60
	/**
61
	 * Un-cached?
62
	 *
63
	 * @var boolean
64
	 */
65
	protected $uncached = false;
66
67
	/**
68
	 * Construct Setter
69
	 *
70
	 * @param DatabaseManager $database
71
	 * @param Repository      $config
72
	 * @param Cache           $cache
73
	 * @param array           $options
74
	 *
75
	 * @throws SettingArgumentException
76
	 */
77
	public function __construct(DatabaseManager $database, Repository $config, Cache $cache, array $options = [])
78
	{
79
		$this->databaseInstance = $database;
80
		$this->config = $config;
81
		$this->cache = $cache;
82
83
		if (!isset($options['cache'])) {
84
			throw new SettingArgumentException('Cache is required in boolean format.');
85
		}
86
87
		if (!isset($options['tag'])) {
88
			throw new SettingArgumentException('Tag is required in string format.');
89
		}
90
91
		if (!isset($options['expiry'])) {
92
			throw new SettingArgumentException('Expiry is required in boolean, integer or DateTime format.');
93
		}
94
95
		$this->setCacheEnabled(isset($options['cache']) ? $options['cache'] : self::CACHE_ENABLED);
96
		$this->setCacheTag(isset($options['tag']) ? $options['tag'] : self::CACHE_TAG);
97
		$this->setCacheExpiry(isset($options['expiry']) ? $options['expiry'] : self::CACHE_EXPIRY);
98
	}
99
100
	/**
101
	 * Set caching enabled status.
102
	 *
103
	 * @param boolean $value
104
	 *
105
	 * @throws SettingArgumentException
106
	 *
107
	 * @return void
108
	 */
109
	protected function setCacheEnabled($value)
110
	{
111
		if (!is_bool($value)) {
112
			throw new SettingArgumentException('Cache enabled is required in boolean format.');
113
		}
114
115
		$this->cacheEnabled = $value;
116
	}
117
118
	/**
119
	 * Get the caching enabled status.
120
	 *
121
	 * @return boolean
122
	 */
123
	protected function getCacheEnabled()
124
	{
125
		return $this->cacheEnabled;
126
	}
127
128
	/**
129
	 * Cache enabled?
130
	 *
131
	 * @return boolean
132
	 */
133
	public function cacheEnabled()
134
	{
135
		return ($this->getCacheEnabled() === self::CACHE_ENABLED);
136
	}
137
138
	/**
139
	 * Set the cache tag
140
	 *
141
	 * @param string $value
142
	 *
143
	 * @throws SettingArgumentException
144
	 *
145
	 * @return void
146
	 */
147
	public function setCacheTag($value)
148
	{
149
		if (!is_string($value)) {
150
			throw new SettingArgumentException('Cache tag is required in string format.');
151
		}
152
153
		$this->cacheTag = $value;
154
	}
155
156
	/**
157
	 * Get the cache tag
158
	 *
159
	 * @return string
160
	 */
161
	public function getCacheTag()
162
	{
163
		return $this->cacheTag;
164
	}
165
166
	/**
167
	 * Set the cache expiry
168
	 *
169
	 * @param boolean|integer|DateTime $value
170
	 *
171
	 * @throws SettingArgumentException
172
	 *
173
	 * @return void
174
	 */
175
	protected function setCacheExpiry($value)
176
	{
177
		if (!is_bool($value) && !is_integer($value) && !$value instanceof DateTime) {
178
			throw new SettingArgumentException('Expiry is required in boolean, integer or DateTime format.');
179
		}
180
181
		$this->cacheExpiry = $value;
182
	}
183
184
	/**
185
	 * Get the cache tag
186
	 *
187
	 * @return string
188
	 */
189
	protected function getCacheExpiry()
190
	{
191
		return $this->cacheExpiry;
192
	}
193
194
	/**
195
	 * Set the uncached status.
196
	 *
197
	 * @param boolean $value
198
	 *
199
	 * @return void
200
	 */
201
	protected function setUncached($value)
202
	{
203
		$this->uncached = $value;
204
	}
205
206
	/**
207
	 * Get the uncached status.
208
	 *
209
	 * @return boolean
210
	 */
211
	protected function getUncached()
212
	{
213
		return $this->uncached;
214
	}
215
216
	/**
217
	 * Return a key with an attached cache tag
218
	 *
219
	 * @param string $key
220
	 *
221
	 * @return string
222
	 */
223
	protected function attachCacheTag($key)
224
	{
225
		return $this->getCacheTag() . $key;
226
	}
227
228
	/**
229
	 * Check a setting exists in cache
230
	 *
231
	 * @param string $key
232
	 *
233
	 * @return boolean
234
	 */
235
	public function cacheHas($key)
236
	{
237
		return $this->cache->has($this->attachCacheTag($key)) ? true : false;
238
	}
239
240
	/**
241
	 * Forget a cached setting by key
242
	 *
243
	 * @param string $key
244
	 *
245
	 * @return boolean
246
	 */
247
	public function cacheForget($key)
248
	{
249
		$this->cache
250
			->forget($this->attachCacheTag($key));
251
252
		return true;
253
	}
254
255
	/**
256
	 * Clear all cached settings
257
	 *
258
	 * @return boolean
259
	 */
260
	public function cacheClear()
261
	{
262
		$this->cache
263
			->flush();
264
265
		return true;
266
	}
267
268
	/**
269
	 * Check a setting exists in config
270
	 *
271
	 * @param string $key
272
	 *
273
	 * @return boolean
274
	 */
275
	public function configHas($key)
276
	{
277
		return $this->config->has($key) ? true : false;
278
	}
279
280
	/**
281
	 * Arrange results into an associative array
282
	 *
283
	 * @param array  $results
284
	 * @param string $key
285
	 *
286
	 * @return array
287
	 */
288
	protected function arrangeResults($results, $key = null)
289
	{
290
		$return = array();
291
292
		foreach ($results as $path => $value) {
293
			$parts = strpos($path, '.') > 0 ? explode('.', trim(preg_replace('/^' . $key . '/', '', $path), '.')) : array($path);
294
			$target =& $return;
295
296
			foreach ($parts as $part) {
297
				$target =& $target[$part];
298
			}
299
300
			$target = $this->decodeJson($value);
301
		}
302
303
		return $return;
304
	}
305
306
	/**
307
	 * Return result values
308
	 *
309
	 * @param array  $results
310
	 * @param string $key
311
	 *
312
	 * @return string|array
313
	 */
314
	protected function returnResults($results = array(), $key)
315
	{
316
		$items = $this->arrangeResults($results, $key);
317
		$return = $this->combineResults($items, $key);
318
319
		if ((!is_array($this->returnConfig($key)) || count($this->returnConfig($key)) == 0) &&
320
			(array_key_exists($key, $return) || array_key_exists('', $return))
321
			&& count($return) == 1
322
		) {
323
			$return = reset($return);
324
		}
325
326
		if ($this->cacheEnabled()) {
327
			$this->cache->forget($this->attachCacheTag($key));
328
			$this->cache->add($this->attachCacheTag($key), $return, $this->getCacheExpiry());
329
		}
330
331
		return $this->decodeJson($return);
332
	}
333
334
	/**
335
	 * Combine result values from the database and configuration
336
	 *
337
	 * @param array  $results
338
	 * @param string $key
339
	 *
340
	 * @return array
341
	 */
342
	protected function combineResults(array $results = array(), $key)
343
	{
344
		$config = $this->returnConfig($key);
345
346
		if (is_array($config)) {
347
			return array_replace_recursive($config, ((array_key_exists($key, $results) || array_key_exists('', $results)) ? reset($results) : $results));
348
		}
349
350
		return $results;
351
	}
352
353
	/**
354
	 * Re-cache item and its parents
355
	 *
356
	 * @param string $value
357
	 * @param string $key
358
	 *
359
	 * @return void
360
	 */
361
	protected function recacheItem($value, $key)
362
	{
363
		for ($i = 0; $i <= substr_count($key, '.') - 1; $i++) {
364
			$j = $i;
365
			$position = 0;
366
367
			while ($j >= 0) {
368
				$position =+ strpos($key, '.', $position) + 1;
369
				$j--;
370
			}
371
372
			$this->cache
373
				->forget($this->attachCacheTag(rtrim(substr_replace($key, '', $position), '.')));
374
		}
375
376
		$this->cache
377
			->forget($this->attachCacheTag($key));
378
		$this->cache
379
			->add($this->attachCacheTag($key), $value, $this->getCacheExpiry());
380
	}
381
382
	/**
383
	 * Return cache values
384
	 *
385
	 * @param string $key
386
	 *
387
	 * @return string|array
388
	 */
389
	protected function returnCache($key)
390
	{
391
		$value = $this->cache->get($this->attachCacheTag($key));
392
393
		return $this->decodeJson($value);
394
	}
395
396
	/**
397
	 * Return config values
398
	 *
399
	 * @param string $key
400
	 *
401
	 * @return string|array
402
	 */
403
	protected function returnConfig($key)
404
	{
405
		$value = $this->config->get($key);
406
407
		return $this->decodeJson($value);
408
	}
409
410
	/**
411
	 * Is the string Json encoded.
412
	 *
413
	 * @param string $string
414
	 * @return boolean
415
	 */
416
	protected function isJson($string)
417
	{
418
		if (!is_string($string)) {
419
			return false;
420
		}
421
422
		json_decode($string);
423
424
		return (json_last_error() == JSON_ERROR_NONE);
425
	}
426
427
	/**
428
	 * Decode a Json item.
429
	 *
430
	 * @param mixed $value
431
	 *
432
	 * @return mixed
433
	 */
434
	protected function decodeJson($value)
435
	{
436
		if ($this->isJson($value)) {
437
			return ($value === '""' || $value === '' ? '' : json_decode($value));
438
		}
439
440
		return $value;
441
	}
442
443
}
444