Completed
Push — 2.0-dev ( d28091...472030 )
by Michael
02:06
created

Memcached   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 212
Duplicated Lines 6.13 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 4
dl 13
loc 212
ccs 46
cts 46
cp 1
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A clear() 0 4 1
A hasItem() 0 6 1
A isSupported() 0 8 1
A getItem() 13 13 2
A getItems() 0 21 4
A deleteItem() 0 17 3
B deleteItems() 0 24 5
A save() 0 15 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
	protected $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
	 */
40 19
	public function __construct(\Memcached $memcached, $options = [])
41
	{
42
		// Parent sets up the caching options and checks their type
43 19
		parent::__construct($options);
44
45 19
		$this->driver = $memcached;
46 19
	}
47
48
	/**
49
	 * This will wipe out the entire cache's keys
50
	 *
51
	 * @return  boolean  True if the pool was successfully cleared. False if there was an error.
52
	 *
53
	 * @since   1.0
54
	 */
55 19
	public function clear()
56
	{
57 19
		return $this->driver->flush();
58
	}
59
60
	/**
61
	 * Returns a Cache Item representing the specified key.
62
	 *
63
	 * @param   string  $key  The key for which to return the corresponding Cache Item.
64
	 *
65
	 * @return  CacheItemInterface  The corresponding Cache Item.
66
	 *
67
	 * @since   __DEPLOY_VERSION__
68
	 */
69 9 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...
70
	{
71 9
		$value = $this->driver->get($key);
72 9
		$code = $this->driver->getResultCode();
73 9
		$item = new Item($key);
74
75 9
		if ($code === \Memcached::RES_SUCCESS)
76
		{
77 7
			$item->set($value);
78
		}
79
80 9
		return $item;
81
	}
82
83
	/**
84
	 * Returns a traversable set of cache items.
85
	 *
86
	 * @param   string[]  $keys  An indexed array of keys of items to retrieve.
87
	 *
88
	 * @return  array  A traversable collection of Cache Items keyed by the cache keys of each item.
89
	 *                 A Cache item will be returned for each key, even if that key is not found.
90
	 *
91
	 * @since   __DEPLOY_VERSION__
92
	 */
93 4
	public function getItems(array $keys = [])
94
	{
95 4
		$data = $this->driver->getMulti($keys);
96
97 4
		$result = [];
98
99 4
		foreach ($keys as $key)
100
		{
101 4
			$item = new Item($key);
102
103
			// On some platforms $data may be a boolean false
104 4
			if (is_array($data) && array_key_exists($key, $data))
105
			{
106 2
				$item->set($data[$key]);
107
			}
108
109 4
			$result[$key] = $item;
110
		}
111
112 4
		return $result;
113
	}
114
115
	/**
116
	 * Removes the item from the pool.
117
	 *
118
	 * @param   string  $key  The key to delete.
119
	 *
120
	 * @return  boolean  True if the item was successfully removed. False if there was an error.
121
	 *
122
	 * @since   __DEPLOY_VERSION__
123
	 * @throws  RuntimeException
124
	 */
125 2
	public function deleteItem($key)
126
	{
127 2
		if ($this->hasItem($key))
128
		{
129 2
			$this->driver->delete($key);
130
131 2
			$rc = $this->driver->getResultCode();
132
133
			// If the item was not successfully removed nor did not exist then raise an error
134 2
			if (($rc !== \Memcached::RES_SUCCESS))
135
			{
136
				throw new RuntimeException(sprintf('Unable to remove cache entry for %s. Error message `%s`.', $key, $this->driver->getResultMessage()));
137
			}
138
		}
139
140 2
		return true;
141
	}
142
143
	/**
144
	 * Removes multiple items from the pool.
145
	 *
146
	 * @param   array  $keys  An array of keys that should be removed from the pool.
147
	 *
148
	 * @return  boolean
149
	 *
150
	 * @since   __DEPLOY_VERSION__
151
	 */
152 2
	public function deleteItems(array $keys)
153
	{
154
		// HHVM doesn't support deleteMulti
155 2
		if (!method_exists($this->driver, 'deleteMulti'))
156
		{
157
			return parent::deleteItems($keys);
158
		}
159
160 2
		$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...
161
162 2
		foreach ($deleted as $key => $value)
163
		{
164
			/*
165
			 * The return of deleteMulti is not consistent with the documentation for error cases,
166
			 * so check for an explicit boolean true for successful deletion
167
			 */
168 2
			if ($value !== true && $value !== \Memcached::RES_NOTFOUND)
169
			{
170 2
				return false;
171
			}
172
		}
173
174 2
		return true;
175
	}
176
177
	/**
178
	 * Persists a cache item immediately.
179
	 *
180
	 * @param   CacheItemInterface  $item  The cache item to save.
181
	 *
182
	 * @return  boolean  True if the item was successfully persisted. False if there was an error.
183
	 *
184
	 * @since   __DEPLOY_VERSION__
185
	 */
186 16
	public function save(CacheItemInterface $item)
187
	{
188 16
		if ($item instanceof HasExpirationDateInterface)
189
		{
190 8
			$ttl = $this->convertItemExpiryToSeconds($item);
191
		}
192
		else
193
		{
194 8
			$ttl = 0;
195
		}
196
197 16
		$this->driver->set($item->getKey(), $item->get(), $ttl);
198
199 16
		return $this->driver->getResultCode() === \Memcached::RES_SUCCESS;
200
	}
201
202
	/**
203
	 * Confirms if the cache contains specified cache item.
204
	 *
205
	 * @param   string  $key  The key for which to check existence.
206
	 *
207
	 * @return  boolean  True if item exists in the cache, false otherwise.
208
	 *
209
	 * @since   1.0
210
	 */
211 6
	public function hasItem($key)
212
	{
213 6
		$this->driver->get($key);
214
215 6
		return $this->driver->getResultCode() !== \Memcached::RES_NOTFOUND;
216
	}
217
218
	/**
219
	 * Test to see if the CacheItemPoolInterface is available
220
	 *
221
	 * @return  boolean  True on success, false otherwise
222
	 *
223
	 * @since   __DEPLOY_VERSION__
224
	 */
225 19
	public static function isSupported(): bool
226
	{
227
		/*
228
		 * GAE and HHVM have both had instances where Memcached the class was defined but no extension was loaded.
229
		 * If the class is there, we can assume it works.
230
		 */
231 19
		return (class_exists('Memcached'));
232
	}
233
}
234