Completed
Push — develop ( e185ca...3573a2 )
by Bradley
01:56
created

SettingBase::cacheEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php namespace Cornford\Setter;
2
3
use Cornford\Setter\Exceptions\SettingArgumentException;
4
use DateTime;
5
use Illuminate\Database\DatabaseManager as Query;
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 integer|datetime|boolean
57
	 */
58
	protected $cacheExpiry;
59
60
	/**
61
	 * Construct Setter
62
	 *
63
	 * @param Query      $database
64
	 * @param Repository $config
65
	 * @param Cache      $cache
66
	 * @param array      $options
67
	 *
68
	 * @throws SettingArgumentException
69
	 */
70
	public function __construct(Query $database, Repository $config, Cache $cache, array $options = [])
71
	{
72
		$this->database = $database;
0 ignored issues
show
Bug introduced by
The property database does not seem to exist. Did you mean databaseInstance?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
73
		$this->config = $config;
74
		$this->cache = $cache;
75
76
		if (!isset($options['cache'])) {
77
			throw new SettingArgumentException('Cache is required in boolean format.');
78
		}
79
		
80
		if (!isset($options['tag'])) {
81
			throw new SettingArgumentException('Tag is required in string format.');
82
		}
83
84
		if (!isset($options['expiry'])) {
85
			throw new SettingArgumentException('Expiry is required in boolean, integer or DateTime format.');
86
		}
87
88
		$this->setCacheEnabled(isset($options['cache']) ? $options['cache'] : self::CACHE_ENABLED);
89
		$this->setCacheTag(isset($options['tag']) ? $options['tag'] : self::CACHE_TAG);
90
		$this->setCacheExpiry(isset($options['expiry']) ? $options['expiry'] : self::CACHE_EXPIRY);
91
	}
92
93
	/**
94
	 * Set caching enabled status.
95
	 *
96
	 * @param boolean $value
97
	 *
98
	 * @throws SettingArgumentException
99
	 *
100
	 * @return void
101
	 */
102
	protected function setCacheEnabled($value)
103
	{
104
		if (!is_bool($value)) {
105
			throw new SettingArgumentException('Cache enabled is required in boolean format.');
106
		}
107
108
		$this->cacheEnabled = $value;
109
	}
110
111
	/**
112
	 * Get the caching enabled status.
113
	 *
114
	 * @return boolean
115
	 */
116
	protected function getCacheEnabled()
117
	{
118
		return $this->cacheEnabled;
119
	}
120
121
	/**
122
	 * Cache enabled?
123
	 *
124
	 * @return boolean
125
	 */
126
	public function cacheEnabled()
127
	{
128
		return ($this->getCacheEnabled() === true);
129
	}
130
131
	/**
132
	 * Set the cache tag
133
	 *
134
	 * @param string $value
135
	 *
136
	 * @throws SettingArgumentException
137
	 *
138
	 * @return void
139
	 */
140
	public function setCacheTag($value)
141
	{
142
		if (!is_string($value)) {
143
			throw new SettingArgumentException('Cache tag is required in string format.');
144
		}
145
146
		$this->cacheTag = $value;
147
	}
148
149
	/**
150
	 * Get the cache tag
151
	 *
152
	 * @return string
153
	 */
154
	public function getCacheTag()
155
	{
156
		return $this->cacheTag;
157
	}
158
159
	/**
160
	 * Set the cache expiry
161
	 *
162
	 * @param boolean|integer|DateTime $value
163
	 *
164
	 * @throws SettingArgumentException
165
	 *
166
	 * @return void
167
	 */
168 View Code Duplication
	protected function setCacheExpiry($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169
	{
170
		if (!is_bool($value) && !is_integer($value) && !$value instanceof DateTime) {
171
			throw new SettingArgumentException('Expiry is required in boolean, integer or DateTime format.');
172
		}
173
174
		$this->cacheExpiry = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value can also be of type object<DateTime>. However, the property $cacheExpiry is declared as type integer|object<Cornford\Setter\Datetime>|boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
175
	}
176
177
	/**
178
	 * Get the cache tag
179
	 *
180
	 * @return string
181
	 */
182
	protected function getCacheExpiry()
183
	{
184
		return $this->cacheExpiry;
185
	}
186
187
	/**
188
	 * Return a key with an attached cache tag
189
	 *
190
	 * @param string $key
191
	 *
192
	 * @return string
193
	 */
194
	protected function attachCacheTag($key)
195
	{
196
		return $this->getCacheTag() . $key;
197
	}
198
199
	/**
200
	 * Check a setting exists in cache
201
	 *
202
	 * @param string $key
203
	 *
204
	 * @return boolean
205
	 */
206
	public function cacheHas($key)
207
	{
208
		return $this->cache->has($this->attachCacheTag($key)) ? true : false;
209
	}
210
211
	/**
212
	 * Forget a cached setting by key
213
	 *
214
	 * @param string $key
215
	 *
216
	 * @return boolean
217
	 */
218
	public function cacheForget($key)
219
	{
220
		$this->cache
221
			->forget($this->attachCacheTag($key));
222
223
		return true;
224
	}
225
226
	/**
227
	 * Clear all cached settings
228
	 *
229
	 * @return boolean
230
	 */
231
	public function cacheClear()
232
	{
233
		$this->cache
234
			->flush();
235
236
		return true;
237
	}
238
239
	/**
240
	 * Check a setting exists in config
241
	 *
242
	 * @param string $key
243
	 *
244
	 * @return boolean
245
	 */
246
	public function configHas($key)
247
	{
248
		return $this->config->has($key) ? true : false;
249
	}
250
251
	/**
252
	 * Arrange results into an associative array
253
	 *
254
	 * @param array  $results
255
	 * @param string $key
256
	 *
257
	 * @return array
258
	 */
259
	protected function arrangeResults($results, $key = null)
260
	{
261
		$return = array();
262
263
		foreach ($results as $path => $value) {
264
			$parts = strpos($path, '.') > 0 ? explode('.', trim(preg_replace('/^' . $key . '/', '', $path), '.')) : array($path);
265
			$target =& $return;
266
267
			foreach ($parts as $part) {
268
				$target =& $target[$part];
269
			}
270
271
			$target = $this->decodeJson($value);
272
		}
273
274
		return $return;
275
	}
276
277
	/**
278
	 * Return result values
279
	 *
280
	 * @param array  $results
281
	 * @param string $key
282
	 *
283
	 * @return string|array
284
	 */
285
	protected function returnResults($results = array(), $key)
286
	{
287
		$items = $this->arrangeResults($results, $key);
288
		$return = $this->combineResults($items, $key);
289
290
		if ((!is_array($this->returnConfig($key)) || count($this->returnConfig($key)) == 0) &&
291
			(array_key_exists($key, $return) || array_key_exists('', $return))
292
			&& count($return) == 1
293
		) {
294
			$return = reset($return);
295
		}
296
297
		if ($this->cacheEnabled()) {
298
			$this->cache->forget($this->attachCacheTag($key));
299
			$this->cache->add($this->attachCacheTag($key), $return, $this->getCacheExpiry());
300
		}
301
302
		return $this->decodeJson($return);
303
	}
304
305
	/**
306
	 * Combine result values from the database and configuration
307
	 *
308
	 * @param array  $results
309
	 * @param string $key
310
	 *
311
	 * @return array
312
	 */
313
	protected function combineResults(array $results = array(), $key)
314
	{
315
		$config = $this->returnConfig($key);
316
317
		if (is_array($config)) {
318
			return array_replace_recursive($config, $results);
319
		}
320
321
		return $results;
322
	}
323
324
	/**
325
	 * Re-cache item and its parents
326
	 *
327
	 * @param string $value
328
	 * @param string $key
329
	 *
330
	 * @return void
331
	 */
332
	protected function recacheItem($value, $key)
333
	{
334
		for ($i = 0; $i <= substr_count($key, '.') - 1; $i++) {
335
			$j = $i;
336
			$position = 0;
337
338
			while ($j >= 0) {
339
				$position =+ strpos($key, '.', $position) + 1;
340
				$j--;
341
			}
342
343
			$this->cache
344
				->forget($this->attachCacheTag(rtrim(substr_replace($key, '', $position), '.')));
345
		}
346
347
		$this->cache
348
			->forget($this->attachCacheTag($key));
349
		$this->cache
350
			->add($this->attachCacheTag($key), $value, $this->getCacheExpiry());
351
	}
352
353
	/**
354
	 * Return cache values
355
	 *
356
	 * @param string $key
357
	 *
358
	 * @return string|array
359
	 */
360
	protected function returnCache($key)
361
	{
362
		$value = $this->cache->get($this->attachCacheTag($key));
363
364
		return $this->decodeJson($value);
365
	}
366
367
	/**
368
	 * Return config values
369
	 *
370
	 * @param string $key
371
	 *
372
	 * @return string|array
373
	 */
374
	protected function returnConfig($key)
375
	{
376
		$value = $this->config->get($key);
377
378
		return $this->decodeJson($value);
379
	}
380
381
	/**
382
	 * Is the string Json encoded.
383
	 *
384
	 * @param string $string
385
	 * @return boolean
386
	 */
387
	protected function isJson($string)
388
	{
389
		if (!is_string($string)) {
390
			return false;
391
		}
392
393
		json_decode($string);
394
395
		return (json_last_error() == JSON_ERROR_NONE);
396
	}
397
398
	/**
399
	 * Decode a Json item.
400
	 *
401
	 * @param mixed $value
402
	 *
403
	 * @return mixed
404
	 */
405
	protected function decodeJson($value)
406
	{
407
		if ($this->isJson($value)) {
408
			return ($value === '""' || $value === '' ? '' : json_decode($value));
409
		}
410
411
		return $value;
412
	}
413
414
}
415