Completed
Push — 2.0-dev ( 96e0ca...04c5d6 )
by Michael
02:05
created

Memcached::deleteItems()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 24
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.1502

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
ccs 9
cts 11
cp 0.8182
rs 8.5125
cc 5
eloc 8
nc 4
nop 1
crap 5.1502
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\Adapter;
10
11
use Joomla\Cache\AbstractCacheItemPool;
12
use Joomla\Cache\Exception\RuntimeException;
13
use Joomla\Cache\Item\HasExpirationDateInterface;
14
use Joomla\Cache\Item\Item;
15
use Psr\Cache\CacheItemInterface;
16
17
/**
18
 * Memcached cache driver for the Joomla Framework.
19
 *
20
 * @since  1.0
21
 */
22
class Memcached extends AbstractCacheItemPool
23
{
24
	/**
25
	 * The Memcached driver
26
	 *
27
	 * @var    \Memcached
28
	 * @since  1.0
29
	 */
30
	private $driver;
31
32
	/**
33
	 * Constructor.
34
	 *
35
	 * @param   \Memcached          $memcached  The Memcached driver being used for this pool
36
	 * @param   array|\ArrayAccess  $options    An options array, or an object that implements \ArrayAccess
37
	 *
38
	 * @since   1.0
39
	 * @throws  \RuntimeException
40
	 */
41 12
	public function __construct(\Memcached $memcached, $options = [])
42
	{
43
		// Parent sets up the caching options and checks their type
44 12
		parent::__construct($options);
45
46 12
		$this->driver = $memcached;
47 12
	}
48
49
	/**
50
	 * This will wipe out the entire cache's keys
51
	 *
52
	 * @return  boolean  The result of the clear operation.
53
	 *
54
	 * @since   1.0
55
	 */
56 12
	public function clear()
57
	{
58 12
		return $this->driver->flush();
59
	}
60
61
	/**
62
	 * Method to get a storage entry value from a key.
63
	 *
64
	 * @param   string  $key  The storage entry identifier.
65
	 *
66
	 * @return  CacheItemInterface
67
	 *
68
	 * @since   1.0
69
	 */
70 4 View Code Duplication
	public function getItem($key)
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...
71
	{
72 4
		$value = $this->driver->get($key);
73 4
		$code = $this->driver->getResultCode();
74 4
		$item = new Item($key);
75
76 4
		if ($code === \Memcached::RES_SUCCESS)
77 4
		{
78 3
			$item->set($value);
79 3
		}
80
81 4
		return $item;
82
	}
83
84
	/**
85
	 * Returns a traversable set of cache items.
86
	 *
87
	 * @param   array  $keys  A list of keys that can obtained in a single operation.
88
	 *
89
	 * @return  CacheItemInterface[]  An associative array of CacheItemInterface objects keyed on the cache key.
90
	 *
91
	 * @since   __DEPLOY_VERSION__
92
	 * @throws  RuntimeException
93
	 */
94 1
	public function getItems(array $keys = [])
95
	{
96 1
		$data = $this->driver->getMulti($keys);
97
98 1
		if ($this->driver->getResultCode() !== \Memcached::RES_SUCCESS)
99 1
		{
100
			throw new RuntimeException('Error retrieving data from cache store: ' . $this->driver->getResultMessage());
101
		}
102
103 1
		$result = [];
104
105 1
		foreach ($keys as $key)
106
		{
107 1
			$item = new Item($key);
108
109 1
			if (array_key_exists($key, $data))
110 1
			{
111 1
				$item->set($data[$key]);
112 1
			}
113
114 1
			$result[$key] = $item;
115 1
		}
116
117 1
		return $result;
118
	}
119
120
	/**
121
	 * Method to remove a storage entry for a key.
122
	 *
123
	 * @param   string  $key  The storage entry identifier.
124
	 *
125
	 * @return  boolean
126
	 *
127
	 * @since   1.0
128
	 */
129 1
	public function deleteItem($key)
130
	{
131 1
		if ($this->hasItem($key))
132 1
		{
133 1
			$this->driver->delete($key);
134
135 1
			$rc = $this->driver->getResultCode();
136
137
			// If the item was not successfully removed nor did not exist then raise an error
138 1
			if (($rc !== \Memcached::RES_SUCCESS))
139 1
			{
140
				throw new RuntimeException(sprintf('Unable to remove cache entry for %s. Error message `%s`.', $key, $this->driver->getResultMessage()));
141
			}
142 1
		}
143
144 1
		return true;
145
	}
146
147
	/**
148
	 * Removes multiple items from the pool.
149
	 *
150
	 * @param   array  $keys  An array of keys that should be removed from the pool.
151
	 *
152
	 * @return  boolean
153
	 *
154
	 * @since   __DEPLOY_VERSION__
155
	 */
156 1
	public function deleteItems(array $keys)
157
	{
158
		// HHVM doesn't support deleteMulti
159 1
		if (!method_exists($this->driver, 'deleteMulti'))
160 1
		{
161
			return parent::deleteItems($keys);
162
		}
163
164 1
		$deleted = $this->driver->deleteMulti($keys);
0 ignored issues
show
Bug introduced by
The method deleteMulti() does not exist on Memcached. Did you maybe mean delete()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
165
166 1
		foreach ($deleted as $key => $value)
167
		{
168
			/*
169
			 * The return of deleteMulti is not consistent with the documentation for error cases,
170
			 * so check for an explicit boolean true for successful deletion
171
			 */
172 1
			if ($value !== true && $value !== \Memcached::RES_NOTFOUND)
173 1
			{
174
				return false;
175
			}
176 1
		}
177
178 1
		return true;
179
	}
180
181
	/**
182
	 * Persists a cache item immediately.
183
	 *
184
	 * @param   CacheItemInterface  $item  The cache item to save.
185
	 *
186
	 * @return  boolean
187
	 *
188
	 * @since   __DEPLOY_VERSION__
189
	 */
190 9
	public function save(CacheItemInterface $item)
191
	{
192 9
		if ($item instanceof HasExpirationDateInterface)
193 9
		{
194 1
			$ttl = $this->convertItemExpiryToSeconds($item);
195 1
		}
196
		else
197
		{
198 8
			$ttl = 0;
199
		}
200
201 9
		$this->driver->set($item->getKey(), $item->get(), $ttl);
202
203 9
		return (bool) ($this->driver->getResultCode() == \Memcached::RES_SUCCESS);
204
	}
205
206
	/**
207
	 * Method to determine whether a storage entry has been set for a key.
208
	 *
209
	 * @param   string  $key  The storage entry identifier.
210
	 *
211
	 * @return  boolean
212
	 *
213
	 * @since   1.0
214
	 */
215 4
	public function hasItem($key)
216
	{
217 4
		$this->driver->get($key);
218
219 4
		return ($this->driver->getResultCode() !== \Memcached::RES_NOTFOUND);
220
	}
221
222
	/**
223
	 * Test to see if the CacheItemPoolInterface is available
224
	 *
225
	 * @return  boolean  True on success, false otherwise
226
	 *
227
	 * @since   __DEPLOY_VERSION__
228
	 */
229 12
	public static function isSupported()
230
	{
231
		/*
232
		 * GAE and HHVM have both had instances where Memcached the class was defined but no extension was loaded.
233
		 * If the class is there, we can assume it works.
234
		 */
235 12
		return (class_exists('Memcached'));
236
	}
237
}
238