From 3f0f3b6ae60ac514b8ac890db996e40e65795b0b Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Sun, 7 Oct 2018 00:27:54 +0200
Subject: [PATCH 1/4] friendica-5847 Console Cache List command doesn't work

- Added $prefix to all CacheDriver
- Moved hostname magic to CacheDriver
- Added test for getAllKeys()
---
 src/Core/Cache.php                            | 13 ++---
 src/Core/Cache/AbstractCacheDriver.php        | 49 ++++++++++++++++++-
 src/Core/Cache/ArrayCache.php                 |  4 +-
 src/Core/Cache/DatabaseCacheDriver.php        | 18 +++++--
 src/Core/Cache/ICacheDriver.php               |  4 +-
 src/Core/Cache/MemcacheCacheDriver.php        |  6 ++-
 src/Core/Cache/MemcachedCacheDriver.php       | 14 +++++-
 src/Core/Cache/RedisCacheDriver.php           | 12 ++++-
 src/Core/Console/Cache.php                    |  2 +-
 tests/src/Core/Cache/ArrayCacheDriverTest.php |  5 --
 tests/src/Core/Cache/CacheTest.php            | 32 ++++++++++++
 .../Core/Cache/DatabaseCacheDriverTest.php    |  5 --
 .../Core/Cache/MemcacheCacheDriverTest.php    |  5 --
 .../Core/Cache/MemcachedCacheDriverTest.php   |  5 --
 tests/src/Core/Cache/RedisCacheDriverTest.php |  5 --
 15 files changed, 131 insertions(+), 48 deletions(-)

diff --git a/src/Core/Cache.php b/src/Core/Cache.php
index ea7807031f..7b9f6edd2c 100644
--- a/src/Core/Cache.php
+++ b/src/Core/Cache.php
@@ -51,20 +51,15 @@ class Cache extends \Friendica\BaseObject
 	/**
 	 * @brief Returns all the cache keys sorted alphabetically
 	 *
+	 * @param string $prefix Prefix of the keys (optional)
+	 *
 	 * @return array|null Null if the driver doesn't support this feature
 	 */
-	public static function getAllKeys()
+	public static function getAllKeys($prefix = null)
 	{
 		$time = microtime(true);
 
-		$return = self::getDriver()->getAllKeys();
-
-		// Keys are prefixed with the node hostname, let's remove it
-		array_walk($return, function (&$value) {
-			$value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
-		});
-
-		sort($return);
+		$return = self::getDriver()->getAllKeys($prefix);
 
 		self::getApp()->save_timestamp($time, 'cache');
 
diff --git a/src/Core/Cache/AbstractCacheDriver.php b/src/Core/Cache/AbstractCacheDriver.php
index 15b822dc3b..e694b9c314 100644
--- a/src/Core/Cache/AbstractCacheDriver.php
+++ b/src/Core/Cache/AbstractCacheDriver.php
@@ -17,8 +17,55 @@ abstract class AbstractCacheDriver extends BaseObject
 	 * @param string $key	The original key
 	 * @return string		The cache key used for the cache
 	 */
-	protected function getCacheKey($key) {
+	protected function getCacheKey($key)
+	{
 		// We fetch with the hostname as key to avoid problems with other applications
 		return self::getApp()->get_hostname() . ":" . $key;
 	}
+
+	/**
+	 * @param array $keys   A list of cached keys
+	 * @return array        A list of original keys
+	 */
+	protected function getOriginalKeys($keys)
+	{
+		if (empty($keys)) {
+			return [];
+		} else {
+			// Keys are prefixed with the node hostname, let's remove it
+			array_walk($keys, function (&$value) {
+				$value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
+			});
+
+			sort($keys);
+
+			return $keys;
+		}
+	}
+
+	/**
+	 * Filters a list for a given prefix
+	 *
+	 * @param array $list the list
+	 * @param string|null $prefix the prefix
+	 *
+	 * @return array the filtered list
+	 */
+	protected function filterPrefix($list, $prefix = null)
+	{
+		if (empty($prefix)) {
+			return array_keys($list);
+		} else {
+			$result = [];
+
+			foreach (array_keys($list) as $key) {
+				if (strpos($key, $prefix) === 0) {
+					array_push($result, $key);
+				}
+			}
+
+			return $result;
+		}
+
+	}
 }
diff --git a/src/Core/Cache/ArrayCache.php b/src/Core/Cache/ArrayCache.php
index 47c9c16680..0d314fadb7 100644
--- a/src/Core/Cache/ArrayCache.php
+++ b/src/Core/Cache/ArrayCache.php
@@ -22,9 +22,9 @@ class ArrayCache extends AbstractCacheDriver implements IMemoryCacheDriver
 	/**
 	 * (@inheritdoc)
 	 */
-	public function getAllKeys()
+	public function getAllKeys($prefix = null)
 	{
-		return array_keys($this->cachedData);
+		return $this->filterPrefix($this->cachedData, $prefix);
 	}
 
 	/**
diff --git a/src/Core/Cache/DatabaseCacheDriver.php b/src/Core/Cache/DatabaseCacheDriver.php
index 74dfe3991e..9966457467 100644
--- a/src/Core/Cache/DatabaseCacheDriver.php
+++ b/src/Core/Cache/DatabaseCacheDriver.php
@@ -16,11 +16,23 @@ class DatabaseCacheDriver extends AbstractCacheDriver implements ICacheDriver
 	/**
 	 * (@inheritdoc)
 	 */
-	public function getAllKeys()
+	public function getAllKeys($prefix = null)
 	{
-		$stmt = DBA::select('cache', ['k'], ['`expires` >= ?', DateTimeFormat::utcNow()]);
+		if (empty($prefix)) {
+			$where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+		} else {
+			$where = ['`expires` >= ? AND k LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+		}
 
-		return DBA::toArray($stmt);
+		$stmt = DBA::select('cache', ['k'], $where);
+
+		$list = [];
+		while ($key = DBA::fetch($stmt)) {
+			array_push($list, $key['k']);
+		}
+		DBA::close($stmt);
+
+		return $list;
 	}
 
 	/**
diff --git a/src/Core/Cache/ICacheDriver.php b/src/Core/Cache/ICacheDriver.php
index b77aa03c16..0a206559cc 100644
--- a/src/Core/Cache/ICacheDriver.php
+++ b/src/Core/Cache/ICacheDriver.php
@@ -14,9 +14,11 @@ interface ICacheDriver
 	/**
 	 * Lists all cache keys
 	 *
+	 * @param string prefix optional a prefix to search
+	 *
 	 * @return array|null Null if it isn't supported by the cache driver
 	 */
-	public function getAllKeys();
+	public function getAllKeys($prefix = null);
 
 	/**
 	 * Fetches cached data according to the key
diff --git a/src/Core/Cache/MemcacheCacheDriver.php b/src/Core/Cache/MemcacheCacheDriver.php
index 207225b1a2..f31e21d14e 100644
--- a/src/Core/Cache/MemcacheCacheDriver.php
+++ b/src/Core/Cache/MemcacheCacheDriver.php
@@ -43,7 +43,7 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
 	/**
 	 * (@inheritdoc)
 	 */
-	public function getAllKeys()
+	public function getAllKeys($prefix = null)
 	{
 		$list = [];
 		$allSlabs = $this->memcache->getExtendedStats('slabs');
@@ -59,7 +59,9 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
 			}
 		}
 
-		return $list;
+		$list = $this->getOriginalKeys($list);
+
+		return $this->filterPrefix($list, $prefix);
 	}
 
 	/**
diff --git a/src/Core/Cache/MemcachedCacheDriver.php b/src/Core/Cache/MemcachedCacheDriver.php
index c1d08f3321..82df98f13b 100644
--- a/src/Core/Cache/MemcachedCacheDriver.php
+++ b/src/Core/Cache/MemcachedCacheDriver.php
@@ -5,6 +5,7 @@ namespace Friendica\Core\Cache;
 use Friendica\Core\Cache;
 
 use Exception;
+use Friendica\Network\HTTPException\InternalServerErrorException;
 use Memcached;
 
 /**
@@ -40,6 +41,9 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 
 		$this->memcached = new Memcached();
 
+
+		$this->memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, false);
+
 		array_walk($memcached_hosts, function (&$value) {
 			if (is_string($value)) {
 				$value = array_map('trim', explode(',', $value));
@@ -56,9 +60,15 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 	/**
 	 * (@inheritdoc)
 	 */
-	public function getAllKeys()
+	public function getAllKeys($prefix = null)
 	{
-		return $this->memcached->getAllKeys();
+		// Doesn't work because of https://github.com/php-memcached-dev/php-memcached/issues/367
+		// returns everytime an empty array
+		throw new InternalServerErrorException('getAllKeys for Memcached not supported yet');
+
+		$list = $this->getOriginalKeys($this->memcached->getAllKeys());
+
+		return $this->filterPrefix($list, $prefix);
 	}
 
 	/**
diff --git a/src/Core/Cache/RedisCacheDriver.php b/src/Core/Cache/RedisCacheDriver.php
index f9d00fde21..fcbfab548a 100644
--- a/src/Core/Cache/RedisCacheDriver.php
+++ b/src/Core/Cache/RedisCacheDriver.php
@@ -41,9 +41,17 @@ class RedisCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
 	/**
 	 * (@inheritdoc)
 	 */
-	public function getAllKeys()
+	public function getAllKeys($prefix = null)
 	{
-		return null;
+		if (empty($prefix)) {
+			$search = '*';
+		} else {
+			$search = $prefix . '*';
+		}
+
+		$list = $this->redis->keys($this->getCacheKey($search));
+
+		return $this->getOriginalKeys($list);
 	}
 
 	/**
diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php
index 2d3508894a..0dfef43f35 100644
--- a/src/Core/Console/Cache.php
+++ b/src/Core/Console/Cache.php
@@ -105,7 +105,7 @@ HELP;
 	private function executeList()
 	{
 		$prefix = $this->getArgument(1);
-		$keys = Core\Cache::getAllKeys();
+		$keys = Core\Cache::getAllKeys($prefix);
 
 		if (empty($prefix)) {
 			$this->out('Listing all cache keys:');
diff --git a/tests/src/Core/Cache/ArrayCacheDriverTest.php b/tests/src/Core/Cache/ArrayCacheDriverTest.php
index 0cad6e9c7f..6863d149ff 100644
--- a/tests/src/Core/Cache/ArrayCacheDriverTest.php
+++ b/tests/src/Core/Cache/ArrayCacheDriverTest.php
@@ -7,11 +7,6 @@ use Friendica\Core\Cache\ArrayCache;
 
 class ArrayCacheDriverTest extends MemoryCacheTest
 {
-	/**
-	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
-	 */
-	private $cache;
-
 	protected function getInstance()
 	{
 		$this->cache = new ArrayCache();
diff --git a/tests/src/Core/Cache/CacheTest.php b/tests/src/Core/Cache/CacheTest.php
index 5c56c2072f..86bf5e7f01 100644
--- a/tests/src/Core/Cache/CacheTest.php
+++ b/tests/src/Core/Cache/CacheTest.php
@@ -2,6 +2,7 @@
 
 namespace Friendica\Test\src\Core\Cache;
 
+use Friendica\Core\Cache\MemcachedCacheDriver;
 use Friendica\Core\Config;
 use Friendica\Test\DatabaseTest;
 use Friendica\Util\DateTimeFormat;
@@ -13,6 +14,12 @@ abstract class CacheTest extends DatabaseTest
 	 */
 	protected $instance;
 
+	/**
+	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
+	 */
+	protected $cache;
+
+
 	abstract protected function getInstance();
 
 	protected function setUp()
@@ -29,6 +36,8 @@ abstract class CacheTest extends DatabaseTest
 		Config::set('system', 'throttle_limit_week', 100);
 		Config::set('system', 'throttle_limit_month', 100);
 		Config::set('system', 'theme', 'system_theme');
+
+		$this->instance->clear(false);
 	}
 
 	/**
@@ -177,4 +186,27 @@ abstract class CacheTest extends DatabaseTest
 		$received = $this->instance->get('objVal');
 		$this->assertEquals($value, $received, 'Value type changed from ' . gettype($value) . ' to ' . gettype($received));
 	}
+
+	/**
+	 * @small
+	 */
+	public function testGetAllKeys() {
+		if ($this->cache instanceof MemcachedCacheDriver) {
+			$this->markTestSkipped('Memcached doesn\'t support getAllKeys anymore');
+		}
+
+		$this->assertTrue($this->instance->set('value1', 'test'));
+		$this->assertTrue($this->instance->set('value2', 'test'));
+		$this->assertTrue($this->instance->set('test_value3', 'test'));
+
+		$list = $this->instance->getAllKeys();
+
+		$this->assertContains('value1', $list);
+		$this->assertContains('value2', $list);
+		$this->assertContains('test_value3', $list);
+
+		$list = $this->instance->getAllKeys('test');
+
+		$this->assertContains('test_value3', $list);
+	}
 }
diff --git a/tests/src/Core/Cache/DatabaseCacheDriverTest.php b/tests/src/Core/Cache/DatabaseCacheDriverTest.php
index 5df00fc913..3cc4a72ed1 100644
--- a/tests/src/Core/Cache/DatabaseCacheDriverTest.php
+++ b/tests/src/Core/Cache/DatabaseCacheDriverTest.php
@@ -6,11 +6,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
 
 class DatabaseCacheDriverTest extends CacheTest
 {
-	/**
-	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
-	 */
-	private $cache;
-
 	protected function getInstance()
 	{
 		$this->cache = CacheDriverFactory::create('database');
diff --git a/tests/src/Core/Cache/MemcacheCacheDriverTest.php b/tests/src/Core/Cache/MemcacheCacheDriverTest.php
index 62f7440033..db85723af1 100644
--- a/tests/src/Core/Cache/MemcacheCacheDriverTest.php
+++ b/tests/src/Core/Cache/MemcacheCacheDriverTest.php
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcacheCacheDriverTest extends MemoryCacheTest
 {
-	/**
-	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
-	 */
-	private $cache;
-
 	protected function getInstance()
 	{
 		$this->cache = CacheDriverFactory::create('memcache');
diff --git a/tests/src/Core/Cache/MemcachedCacheDriverTest.php b/tests/src/Core/Cache/MemcachedCacheDriverTest.php
index 5a07814a38..fba5c4a958 100644
--- a/tests/src/Core/Cache/MemcachedCacheDriverTest.php
+++ b/tests/src/Core/Cache/MemcachedCacheDriverTest.php
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcachedCacheDriverTest extends MemoryCacheTest
 {
-	/**
-	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
-	 */
-	private $cache;
-
 	protected function getInstance()
 	{
 		$this->cache = CacheDriverFactory::create('memcached');
diff --git a/tests/src/Core/Cache/RedisCacheDriverTest.php b/tests/src/Core/Cache/RedisCacheDriverTest.php
index 460c1184ba..0ee73945b9 100644
--- a/tests/src/Core/Cache/RedisCacheDriverTest.php
+++ b/tests/src/Core/Cache/RedisCacheDriverTest.php
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class RedisCacheDriverTest extends MemoryCacheTest
 {
-	/**
-	 * @var \Friendica\Core\Cache\IMemoryCacheDriver
-	 */
-	private $cache;
-
 	protected function getInstance()
 	{
 		$this->cache = CacheDriverFactory::create('redis');

From 1ec5c6b2840cedbe21e089f4ef4404d22a65031e Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Sun, 7 Oct 2018 10:35:37 +0200
Subject: [PATCH 2/4] friendica-5847 Console Cache List command doesn't work

- filterPrefix => filterArrayKeysByPrefix()
- Logging failed Executions of getAllKeys and get from Memcached
---
 src/Core/Cache/AbstractCacheDriver.php  | 15 ++++++++-------
 src/Core/Cache/ArrayCache.php           |  2 +-
 src/Core/Cache/MemcacheCacheDriver.php  | 10 +++++-----
 src/Core/Cache/MemcachedCacheDriver.php | 22 +++++++++++-----------
 src/Core/Console/Cache.php              |  5 +----
 5 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/src/Core/Cache/AbstractCacheDriver.php b/src/Core/Cache/AbstractCacheDriver.php
index e694b9c314..1cdecf6ceb 100644
--- a/src/Core/Cache/AbstractCacheDriver.php
+++ b/src/Core/Cache/AbstractCacheDriver.php
@@ -44,21 +44,22 @@ abstract class AbstractCacheDriver extends BaseObject
 	}
 
 	/**
-	 * Filters a list for a given prefix
+	 * Filters the keys of an array with a given prefix
+	 * Returns the filtered keys as an new array
 	 *
-	 * @param array $list the list
-	 * @param string|null $prefix the prefix
+	 * @param array $array The array, which should get filtered
+	 * @param string|null $prefix The prefix (if null, all keys will get returned)
 	 *
-	 * @return array the filtered list
+	 * @return array The filtered array with just the keys
 	 */
-	protected function filterPrefix($list, $prefix = null)
+	protected function filterArrayKeysByPrefix($array, $prefix = null)
 	{
 		if (empty($prefix)) {
-			return array_keys($list);
+			return array_keys($array);
 		} else {
 			$result = [];
 
-			foreach (array_keys($list) as $key) {
+			foreach (array_keys($array) as $key) {
 				if (strpos($key, $prefix) === 0) {
 					array_push($result, $key);
 				}
diff --git a/src/Core/Cache/ArrayCache.php b/src/Core/Cache/ArrayCache.php
index 0d314fadb7..a99b05788f 100644
--- a/src/Core/Cache/ArrayCache.php
+++ b/src/Core/Cache/ArrayCache.php
@@ -24,7 +24,7 @@ class ArrayCache extends AbstractCacheDriver implements IMemoryCacheDriver
 	 */
 	public function getAllKeys($prefix = null)
 	{
-		return $this->filterPrefix($this->cachedData, $prefix);
+		return $this->filterArrayKeysByPrefix($this->cachedData, $prefix);
 	}
 
 	/**
diff --git a/src/Core/Cache/MemcacheCacheDriver.php b/src/Core/Cache/MemcacheCacheDriver.php
index f31e21d14e..fd928c6fcc 100644
--- a/src/Core/Cache/MemcacheCacheDriver.php
+++ b/src/Core/Cache/MemcacheCacheDriver.php
@@ -45,23 +45,23 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
 	 */
 	public function getAllKeys($prefix = null)
 	{
-		$list = [];
+		$keys = [];
 		$allSlabs = $this->memcache->getExtendedStats('slabs');
 		foreach ($allSlabs as $slabs) {
 			foreach (array_keys($slabs) as $slabId) {
 				$cachedump = $this->memcache->getExtendedStats('cachedump', (int)$slabId);
-				foreach ($cachedump as $keys => $arrVal) {
+				foreach ($cachedump as $key => $arrVal) {
 					if (!is_array($arrVal)) {
 						continue;
 					}
-					$list = array_merge($list, array_keys($arrVal));
+					$keys = array_merge($keys, array_keys($arrVal));
 				}
 			}
 		}
 
-		$list = $this->getOriginalKeys($list);
+		$keys = $this->getOriginalKeys($keys);
 
-		return $this->filterPrefix($list, $prefix);
+		return $this->filterArrayKeysByPrefix($keys, $prefix);
 	}
 
 	/**
diff --git a/src/Core/Cache/MemcachedCacheDriver.php b/src/Core/Cache/MemcachedCacheDriver.php
index 82df98f13b..a6e1bad950 100644
--- a/src/Core/Cache/MemcachedCacheDriver.php
+++ b/src/Core/Cache/MemcachedCacheDriver.php
@@ -62,13 +62,14 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 	 */
 	public function getAllKeys($prefix = null)
 	{
-		// Doesn't work because of https://github.com/php-memcached-dev/php-memcached/issues/367
-		// returns everytime an empty array
-		throw new InternalServerErrorException('getAllKeys for Memcached not supported yet');
+		$keys = $this->getOriginalKeys($this->memcached->getAllKeys());
 
-		$list = $this->getOriginalKeys($this->memcached->getAllKeys());
-
-		return $this->filterPrefix($list, $prefix);
+		if ($this->memcached->getResultCode() == Memcached::RES_SUCCESS) {
+			return $this->filterArrayKeysByPrefix($keys, $prefix);
+		} else {
+			logger('Memcached \'getAllKeys\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
+			return [];
+		}
 	}
 
 	/**
@@ -76,17 +77,17 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 	 */
 	public function get($key)
 	{
-		$return = null;
 		$cachekey = $this->getCacheKey($key);
 
 		// We fetch with the hostname as key to avoid problems with other applications
 		$value = $this->memcached->get($cachekey);
 
 		if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
-			$return = $value;
+			return $value;
+		} else {
+			logger('Memcached \'get\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
+			return [];
 		}
-
-		return $return;
 	}
 
 	/**
@@ -109,7 +110,6 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 				$value
 			);
 		}
-
 	}
 
 	/**
diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php
index 0dfef43f35..459a27e20b 100644
--- a/src/Core/Console/Cache.php
+++ b/src/Core/Console/Cache.php
@@ -115,10 +115,7 @@ HELP;
 
 		$count = 0;
 		foreach ($keys as $key) {
-			if (empty($prefix) || strpos($key, $prefix) === 0) {
-				$this->out($key);
-				$count++;
-			}
+			$this->out($key);
 		}
 
 		$this->out($count . ' keys found');

From 8491f8660f3afa67bd02f5702fb10bb35c25db21 Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Sun, 7 Oct 2018 10:38:45 +0200
Subject: [PATCH 3/4] Bugfixing Memcached

---
 src/Core/Cache/MemcachedCacheDriver.php | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/Core/Cache/MemcachedCacheDriver.php b/src/Core/Cache/MemcachedCacheDriver.php
index a6e1bad950..62c3892860 100644
--- a/src/Core/Cache/MemcachedCacheDriver.php
+++ b/src/Core/Cache/MemcachedCacheDriver.php
@@ -41,9 +41,6 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 
 		$this->memcached = new Memcached();
 
-
-		$this->memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, false);
-
 		array_walk($memcached_hosts, function (&$value) {
 			if (is_string($value)) {
 				$value = array_map('trim', explode(',', $value));
@@ -68,7 +65,7 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 			return $this->filterArrayKeysByPrefix($keys, $prefix);
 		} else {
 			logger('Memcached \'getAllKeys\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
-			return [];
+			return null;
 		}
 	}
 
@@ -77,17 +74,19 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 	 */
 	public function get($key)
 	{
+		$return = null;
 		$cachekey = $this->getCacheKey($key);
 
 		// We fetch with the hostname as key to avoid problems with other applications
 		$value = $this->memcached->get($cachekey);
 
 		if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
-			return $value;
+			$return = $value;
 		} else {
 			logger('Memcached \'get\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
-			return [];
 		}
+
+		return $return;
 	}
 
 	/**

From 7da6da6666973efce1553237846aca06d497866d Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Sun, 7 Oct 2018 22:14:05 +0200
Subject: [PATCH 4/4] Bugfixings for getAllKeys()

---
 src/Core/Cache.php                      | 2 +-
 src/Core/Cache/DatabaseCacheDriver.php  | 8 ++++----
 src/Core/Cache/ICacheDriver.php         | 2 +-
 src/Core/Cache/MemcachedCacheDriver.php | 2 +-
 src/Core/Console/Cache.php              | 1 +
 5 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/Core/Cache.php b/src/Core/Cache.php
index 7b9f6edd2c..b239af7d60 100644
--- a/src/Core/Cache.php
+++ b/src/Core/Cache.php
@@ -53,7 +53,7 @@ class Cache extends \Friendica\BaseObject
 	 *
 	 * @param string $prefix Prefix of the keys (optional)
 	 *
-	 * @return array|null Null if the driver doesn't support this feature
+	 * @return array Empty if the driver doesn't support this feature
 	 */
 	public static function getAllKeys($prefix = null)
 	{
diff --git a/src/Core/Cache/DatabaseCacheDriver.php b/src/Core/Cache/DatabaseCacheDriver.php
index 9966457467..d90c6e4f18 100644
--- a/src/Core/Cache/DatabaseCacheDriver.php
+++ b/src/Core/Cache/DatabaseCacheDriver.php
@@ -21,18 +21,18 @@ class DatabaseCacheDriver extends AbstractCacheDriver implements ICacheDriver
 		if (empty($prefix)) {
 			$where = ['`expires` >= ?', DateTimeFormat::utcNow()];
 		} else {
-			$where = ['`expires` >= ? AND k LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+			$where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
 		}
 
 		$stmt = DBA::select('cache', ['k'], $where);
 
-		$list = [];
+		$keys = [];
 		while ($key = DBA::fetch($stmt)) {
-			array_push($list, $key['k']);
+			array_push($keys, $key['k']);
 		}
 		DBA::close($stmt);
 
-		return $list;
+		return $keys;
 	}
 
 	/**
diff --git a/src/Core/Cache/ICacheDriver.php b/src/Core/Cache/ICacheDriver.php
index 0a206559cc..2c04c59925 100644
--- a/src/Core/Cache/ICacheDriver.php
+++ b/src/Core/Cache/ICacheDriver.php
@@ -16,7 +16,7 @@ interface ICacheDriver
 	 *
 	 * @param string prefix optional a prefix to search
 	 *
-	 * @return array|null Null if it isn't supported by the cache driver
+	 * @return array Empty if it isn't supported by the cache driver
 	 */
 	public function getAllKeys($prefix = null);
 
diff --git a/src/Core/Cache/MemcachedCacheDriver.php b/src/Core/Cache/MemcachedCacheDriver.php
index 62c3892860..1a6b2a9aef 100644
--- a/src/Core/Cache/MemcachedCacheDriver.php
+++ b/src/Core/Cache/MemcachedCacheDriver.php
@@ -65,7 +65,7 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 			return $this->filterArrayKeysByPrefix($keys, $prefix);
 		} else {
 			logger('Memcached \'getAllKeys\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
-			return null;
+			return [];
 		}
 	}
 
diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php
index 459a27e20b..1d93c3c011 100644
--- a/src/Core/Console/Cache.php
+++ b/src/Core/Console/Cache.php
@@ -116,6 +116,7 @@ HELP;
 		$count = 0;
 		foreach ($keys as $key) {
 			$this->out($key);
+			$count++;
 		}
 
 		$this->out($count . ' keys found');