Completed
Push — 2.0-dev ( d70707...e50301 )
by Michael
02:57
created

Cache   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 63.04%

Importance

Changes 10
Bugs 2 Features 1
Metric Value
wmc 17
c 10
b 2
f 1
lcom 2
cbo 3
dl 0
loc 184
ccs 29
cts 46
cp 0.6304
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getItems() 0 11 2
A getOption() 0 4 2
deleteItem() 0 1 ?
A deleteItems() 0 14 3
A setOption() 0 6 1
A saveDeferred() 0 6 1
A commit() 0 18 4
A convertItemExpiryToSeconds() 0 9 1
A __construct() 0 9 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
15
/**
16
 * Joomla! Caching Class
17
 *
18
 * @since  1.0
19
 */
20
abstract class Cache implements CacheItemPoolInterface
21
{
22
	/**
23
	 * The options for the cache object.
24
	 *
25
	 * @var    array|\ArrayAccess
26
	 * @since  1.0
27
	 */
28
	protected $options;
29
30
	/**
31
	 * The deferred items to store
32
	 *
33
	 * @var    array
34
	 * @since  1.0
35
	 */
36
	private $deferred = [];
37
38
	/**
39
	 * Constructor.
40
	 *
41
	 * @param   array|\ArrayAccess  $options  An options array, or an object that implements \ArrayAccess
42
	 *
43
	 * @since   1.0
44
	 * @throws  \RuntimeException
45
	 */
46 58
	public function __construct($options = [])
47
	{
48 58
		if (!($options instanceof \ArrayAccess || is_array($options)))
49 58
		{
50
			throw new InvalidArgumentException(sprintf('%s requires an options array or an object that implements \\ArrayAccess', __CLASS__));
51
		}
52
53 58
		$this->options = $options;
54 58
	}
55
56
	/**
57
	 * Returns a traversable set of cache items.
58
	 *
59
	 * @param   array  $keys  A list of keys that can obtained in a single operation.
60
	 *
61
	 * @return  CacheItemInterface[]  An associative array of CacheItemInterface objects keyed on the cache key.
62
	 *
63
	 * @since   1.0
64
	 */
65 4
	public function getItems(array $keys = [])
66
	{
67 4
		$result = [];
68
69 4
		foreach ($keys as $key)
70
		{
71 4
			$result[$key] = $this->getItem($key);
72 4
		}
73
74 4
		return $result;
75
	}
76
77
	/**
78
	 * Get an option from the Cache instance.
79
	 *
80
	 * @param   string  $key  The name of the option to get.
81
	 *
82
	 * @return  mixed  The option value.
83
	 *
84
	 * @since   1.0
85
	 */
86 12
	public function getOption($key)
87
	{
88 12
		return isset($this->options[$key]) ? $this->options[$key] : null;
89
	}
90
91
	/**
92
	 * Removes the item from the pool.
93
	 *
94
	 * @param   string  $key  The key for which to delete
95
	 *
96
	 * @return  boolean
97
	 *
98
	 * @since   1.0
99
	 */
100
	abstract public function deleteItem($key);
101
102
	/**
103
	 * Removes multiple items from the pool.
104
	 *
105
	 * @param   array  $keys  An array of keys that should be removed from the pool.
106
	 *
107
	 * @return  boolean
108
	 *
109
	 * @since   1.0
110
	 */
111 6
	public function deleteItems(array $keys)
112
	{
113 6
		$result = true;
114
115 6
		foreach ($keys as $key)
116
		{
117 6
			if (!$this->deleteItem($key))
118 6
			{
119
				$result = false;
120
			}
121 6
		}
122
123 6
		return $result;
124
	}
125
126
	/**
127
	 * Set an option for the Cache instance.
128
	 *
129
	 * @param   string  $key    The name of the option to set.
130
	 * @param   mixed   $value  The option value to set.
131
	 *
132
	 * @return  $this
133
	 *
134
	 * @since   1.0
135
	 */
136 6
	public function setOption($key, $value)
137
	{
138 6
		$this->options[$key] = $value;
139
140 6
		return $this;
141
	}
142
143
	/**
144
	 * Sets a cache item to be persisted later.
145
	 *
146
	 * @param   CacheItemInterface  $item  The cache item to save.
147
	 *
148
	 * @return  $this
149
	 *
150
	 * @since   __DEPLOY_VERSION__
151
	 */
152
	public function saveDeferred(CacheItemInterface $item)
153
	{
154
		$this->deferred[$item->getKey()] = $item;
155
156
		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...
157
	}
158
159
	/**
160
	 * Persists any deferred cache items.
161
	 *
162
	 * @return  boolean
163
	 *
164
	 * @since   __DEPLOY_VERSION__
165
	 */
166
	public function commit()
167
	{
168
		$result = true;
169
170
		foreach ($this->deferred as $key => $deferred)
171
		{
172
			$saveResult = $this->save($deferred);
173
174
			if (true === $saveResult)
175
			{
176
				unset($this->deferred[$key]);
177
			}
178
179
			$result = $result && $saveResult;
180
		}
181
182
		return $result;
183
	}
184
185
	/**
186
	 * Converts a DateTime object from the cache item to the expiry time in seconds from the present
187
	 *
188
	 * @param   HasExpirationDateInterface  $item  The cache item
189
	 *
190
	 * @return  integer  The time in seconds until expiry
191
	 *
192
	 * @since   __DEPLOY_VERSION__
193
	 */
194 2
	protected function convertItemExpiryToSeconds(HasExpirationDateInterface $item)
195
	{
196 2
		$itemExpiry   = $item->getExpiration();
197 2
		$itemTimezone = $itemExpiry->getTimezone();
198 2
		$now          = new \DateTime('now', $itemTimezone);
199 2
		$interval     = $now->diff($itemExpiry);
200
201 2
		return (int) $interval->format('%s');
202
	}
203
}
204