Completed
Push — 2.0-dev ( 392f22...81b595 )
by Michael
04:39 queued 02:38
created

Cache::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
cc 3
eloc 4
nc 2
nop 1
crap 3
1
<?php
2
/**
3
 * Part of the Joomla Framework Cache Package
4
 *
5
 * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
6
 * @license    GNU General Public License version 2 or later; see LICENSE
7
 */
8
9
namespace Joomla\Cache;
10
11
use Joomla\Cache\Exception\InvalidArgumentException;
12
use Joomla\Cache\Item\HasExpirationDateInterface;
13
use Psr\Cache\CacheItemInterface;
14
use Psr\Cache\CacheItemPoolInterface;
15
16
/**
17
 * Joomla! Caching Class
18
 *
19
 * @since  1.0
20
 */
21
abstract class Cache implements CacheItemPoolInterface
22
{
23
	/**
24
	 * The options for the cache object.
25
	 *
26
	 * @var    array|\ArrayAccess
27
	 * @since  1.0
28
	 */
29
	protected $options;
30
31
	/**
32
	 * The deferred items to store
33
	 *
34
	 * @var    array
35
	 * @since  1.0
36
	 */
37
	private $deferred = [];
38
39
	/**
40
	 * Constructor.
41
	 *
42
	 * @param   array|\ArrayAccess  $options  An options array, or an object that implements \ArrayAccess
43
	 *
44
	 * @since   1.0
45
	 * @throws  \RuntimeException
46
	 */
47 8
	public function __construct($options = [])
48
	{
49 8
		if (!($options instanceof \ArrayAccess || is_array($options)))
50 8
		{
51 4
			throw new InvalidArgumentException(sprintf('%s requires an options array or an object that implements \\ArrayAccess', __CLASS__));
52
		}
53
54 8
		$this->options = $options;
55 8
	}
56
57
	/**
58
	 * Returns a traversable set of cache items.
59
	 *
60
	 * @param   array  $keys  A list of keys that can obtained in a single operation.
61
	 *
62
	 * @return  CacheItemInterface[]  An associative array of CacheItemInterface objects keyed on the cache key.
63
	 *
64
	 * @since   1.0
65
	 */
66 3
	public function getItems(array $keys = [])
67
	{
68 3
		$result = [];
69
70 3
		foreach ($keys as $key)
71
		{
72 3
			$result[$key] = $this->getItem($key);
73 3
		}
74
75 3
		return $result;
76
	}
77
78
	/**
79
	 * Get an option from the Cache instance.
80
	 *
81
	 * @param   string  $key  The name of the option to get.
82
	 *
83
	 * @return  mixed  The option value.
84
	 *
85
	 * @since   1.0
86
	 */
87 4
	public function getOption($key)
88
	{
89 4
		return isset($this->options[$key]) ? $this->options[$key] : null;
90
	}
91
92
	/**
93
	 * Removes the item from the pool.
94
	 *
95
	 * @param   string  $key  The key for which to delete
96
	 *
97
	 * @return  boolean
98
	 *
99
	 * @since   1.0
100
	 */
101
	abstract public function deleteItem($key);
102
103
	/**
104
	 * Removes multiple items from the pool.
105
	 *
106
	 * @param   array  $keys  An array of keys that should be removed from the pool.
107
	 *
108
	 * @return  boolean
109
	 *
110
	 * @since   1.0
111
	 */
112 5
	public function deleteItems(array $keys)
113
	{
114 5
		$result = true;
115
116 5
		foreach ($keys as $key)
117
		{
118 5
			if (!$this->deleteItem($key))
119 5
			{
120
				$result = false;
121
			}
122 5
		}
123
124 5
		return $result;
125
	}
126
127
	/**
128
	 * Set an option for the Cache instance.
129
	 *
130
	 * @param   string  $key    The name of the option to set.
131
	 * @param   mixed   $value  The option value to set.
132
	 *
133
	 * @return  $this
134
	 *
135
	 * @since   1.0
136
	 */
137 4
	public function setOption($key, $value)
138
	{
139 4
		$this->options[$key] = $value;
140
141 4
		return $this;
142
	}
143
144
	/**
145
	 * Sets a cache item to be persisted later.
146
	 *
147
	 * @param   CacheItemInterface  $item  The cache item to save.
148
	 *
149
	 * @return  $this
150
	 *
151
	 * @since   __DEPLOY_VERSION__
152
	 */
153
	public function saveDeferred(CacheItemInterface $item)
154
	{
155
		$this->deferred[$item->getKey()] = $item;
156
157
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Joomla\Cache\Cache) is incompatible with the return type declared by the interface Psr\Cache\CacheItemPoolInterface::saveDeferred of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
158
	}
159
160
	/**
161
	 * Persists any deferred cache items.
162
	 *
163
	 * @return  boolean
164
	 *
165
	 * @since   __DEPLOY_VERSION__
166
	 */
167
	public function commit()
168
	{
169
		$result = true;
170
171
		foreach ($this->deferred as $key => $deferred)
172
		{
173
			$saveResult = $this->save($deferred);
174
175
			if (true === $saveResult)
176
			{
177
				unset($this->deferred[$key]);
178
			}
179
180
			$result = $result && $saveResult;
181
		}
182
183
		return $result;
184
	}
185
186
	/**
187
	 * Converts a DateTime object from the cache item to the expiry time in seconds from the present
188
	 *
189
	 * @param   HasExpirationDateInterface $item The cache item
190
	 *
191
	 * @return  integer  The time in seconds until expiry
192
	 *
193
	 * @since   __DEPLOY_VERSION__
194
	 */
195
	protected function convertItemExpiryToSeconds(HasExpirationDateInterface $item)
196
	{
197
		$itemExpiry   = $item->getExpiration();
198
		$itemTimezone = $itemExpiry->getTimezone();
199
		$now          = new \DateTime('now', $itemTimezone);
200
		$interval     = $now->diff($itemExpiry);
201
202
		return (int) $interval->format('%s');
203
	}
204
}
205