From 3bb0a16a2dd8087fc85804604b5f77c15e38fa24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20GERVAIS?= Date: Thu, 20 Jun 2019 08:41:41 +0000 Subject: [PATCH] Update redis module to 3.17 --- sites/all/modules/fpfis/redis/.gitignore | 1 + sites/all/modules/fpfis/redis/README.txt | 40 +++++++- .../modules/fpfis/redis/lib/Redis/Cache.php | 5 +- .../fpfis/redis/lib/Redis/CacheCompressed.php | 66 +++++++++++++ .../lib/Redis/Path/AbstractHashLookup.php | 96 +++++++++++++++++++ .../fpfis/redis/lib/Redis/Path/PhpRedis.php | 56 +---------- .../fpfis/redis/lib/Redis/Path/Predis.php | 56 +---------- .../CompressedPhpRedisFixesUnitTestCase.test | 27 ++++++ .../CompressedPhpRedisFlushUnitTestCase.test | 27 ++++++ ...essedPhpRedisShardedFixesUnitTestCase.test | 25 +++++ ...essedPhpRedisShardedFlushUnitTestCase.test | 25 +++++ ...sShardedWithPipelineFixesUnitTestCase.test | 25 +++++ .../Redis/Tests/Cache/FixesUnitTestCase.php | 7 +- .../Redis/Tests/Cache/FlushUnitTestCase.php | 7 +- .../lib/Redis/Tests/Path/PathUnitTestCase.php | 56 +++++++++++ sites/all/modules/fpfis/redis/redis.info | 11 ++- sites/all/modules/fpfis/redis/redis.install | 2 +- sites/all/modules/fpfis/redis/redis.module | 12 +-- sites/all/modules/fpfis/redis/redis.path.inc | 22 +++-- 19 files changed, 440 insertions(+), 126 deletions(-) create mode 100644 sites/all/modules/fpfis/redis/.gitignore create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/CacheCompressed.php create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFixesUnitTestCase.test create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFlushUnitTestCase.test create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFixesUnitTestCase.test create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFlushUnitTestCase.test create mode 100644 sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedWithPipelineFixesUnitTestCase.test diff --git a/sites/all/modules/fpfis/redis/.gitignore b/sites/all/modules/fpfis/redis/.gitignore new file mode 100644 index 000000000..a48738a76 --- /dev/null +++ b/sites/all/modules/fpfis/redis/.gitignore @@ -0,0 +1 @@ +predis diff --git a/sites/all/modules/fpfis/redis/README.txt b/sites/all/modules/fpfis/redis/README.txt index 679203302..37357eb30 100644 --- a/sites/all/modules/fpfis/redis/README.txt +++ b/sites/all/modules/fpfis/redis/README.txt @@ -26,7 +26,7 @@ enabled due to the EVAL command usage. If you can't upgrade you Redis server: - - 3.x release will only officially support Redis server <= 2.6 + - 3.x release will only officially support Redis server <= 2.8 and 3.x nevertheless you may use it with Redis 2.4 if you configure your cache backend to operate in sharding mode. @@ -54,7 +54,7 @@ Quick setup ----------- Here is a simple yet working easy way to setup the module. -This method will Drupal to use Redis for all caches and locks +This method will allow Drupal to use Redis for all caches and locks and path alias cache replacement. $conf['redis_client_interface'] = 'PhpRedis'; // Can be "Predis". @@ -77,6 +77,40 @@ settings for different bins; It's today very stable. Advanced configuration ====================== +Use the compressed cache +------------------------ + +Please note this is for now an experimental feature. As a personnal note +from the module author, it should be safe to use. + +Use this cache class setting to enable compression. This will save usually +about 80% RAM at the cost of some milliseconds server time. + + $conf['cache_default_class'] = 'Redis_CacheCompressed'; + +Additionnaly, you can alter the default size compression threshold, under which +entries will not be compressed (size is in bytes, set 0 to always compress): + + $conf['cache_compression_size_threshold'] = 100; + +You can also change the compression level, which an positive integer between +1 and 9, 1 being the lowest but fastest compression ratio, 9 being the most +aggressive compression but is a lot slower. From testing, setting it to the +lower level (1) gives 80% memory usage decrease, which is more than enough. + + $conf['cache_compression_ratio'] = 5; + +Please note that those settings are global and not on a cache bin basis, you can +already control whenever the compression is to be used or not by selecting a +different cache class on per cache bin basis. + +If you switch from the standard default backend (without compression) to the +compressed cache backend, it will recover transparently uncompressed data and +proceed normally without additional cache eviction, it safe to upgrade. +Donwgrading from compressed data to uncompressed data won't work, but the +cache backend will just give you cache hit miss and it will work seamlessly +too without any danger for the site. + Choose the Redis client library to use -------------------------------------- @@ -84,7 +118,7 @@ Add into your settings.php file: $conf['redis_client_interface'] = 'PhpRedis'; -You can replace 'PhpRedis' with 'Predis', depending on the library you chose. +You can replace 'PhpRedis' with 'Predis', depending on the library you chose. Note that this is optional but recommended. If you don't set this variable the module will proceed to class lookups and attempt to choose the best client diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Cache.php b/sites/all/modules/fpfis/redis/lib/Redis/Cache.php index 0feceb46e..3a1cf48d2 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Cache.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Cache.php @@ -167,6 +167,9 @@ public function getMaxTtl() return $this->maxTtl; } + /** + * {@inheritdoc} + */ public function __construct($bin) { $this->bin = $bin; @@ -288,7 +291,7 @@ public function getLastFlushTime() if (!$this->flushCache) { $this->flushCache = $this->backend->getLastFlushTime(); } - + // At the very first hit, we might not have the timestamps set, thus // we need to create them to avoid our entry being considered as // invalid diff --git a/sites/all/modules/fpfis/redis/lib/Redis/CacheCompressed.php b/sites/all/modules/fpfis/redis/lib/Redis/CacheCompressed.php new file mode 100644 index 000000000..f817cb1ff --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/CacheCompressed.php @@ -0,0 +1,66 @@ +compressionSizeThreshold = (int)variable_get('cache_compression_size_threshold', 100); + if ($this->compressionSizeThreshold < 0) { + trigger_error('cache_compression_size_threshold must be 0 or a positive integer, negative value found, switching back to default 100', E_USER_WARNING); + $this->compressionSizeThreshold = 100; + } + + // Minimum compression level (1) has good ratio in low time. + $this->compressionRatio = (int)variable_get('cache_compression_ratio', 1); + if ($this->compressionRatio < 1 || 9 < $this->compressionRatio) { + trigger_error('cache_compression_ratio must be between 1 and 9, out of bounds value found, switching back to default 1', E_USER_WARNING); + $this->compressionRatio = 1; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntryHash($cid, $data, $expire = CACHE_PERMANENT) + { + $hash = parent::createEntryHash($cid, $data, $expire); + + // Empiric level when compression makes sense. + if (!$this->compressionSizeThreshold || strlen($hash['data']) > $this->compressionSizeThreshold) { + + $hash['data'] = gzcompress($hash['data'], $this->compressionRatio); + $hash['compressed'] = true; + } + + return $hash; + } + + /** + * {@inheritdoc} + */ + protected function expandEntry(array $values, $flushPerm, $flushVolatile) + { + if (!empty($values['data']) && !empty($values['compressed'])) { + // Uncompress, suppress warnings e.g. for broken CRC32. + $values['data'] = @gzuncompress($values['data']); + + // In such cases, void the cache entry. + if ($values['data'] === false) { + return false; + } + } + + return parent::expandEntry($values, $flushPerm, $flushVolatile); + } +} diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Path/AbstractHashLookup.php b/sites/all/modules/fpfis/redis/lib/Redis/Path/AbstractHashLookup.php index d027d848c..4cdf578e8 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Path/AbstractHashLookup.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Path/AbstractHashLookup.php @@ -6,4 +6,100 @@ abstract class Redis_Path_AbstractHashLookup extends Redis_AbstractBackend implements Redis_Path_HashLookupInterface { + /** + * @todo document me + * + * @param string $key + * @param string $hkey + * @param string $hvalue + */ + abstract protected function saveInHash($key, $hkey, $hvalue); + + /** + * @todo document me + * + * @param string $key + * @param string $hkey + * @param string $hvalue + */ + abstract protected function deleteInHash($key, $hkey, $hvalue); + + /** + * @todo document me + * + * @param string $keyPrefix + * @param string $hkey + * @param string $language + */ + abstract protected function lookupInHash($keyPrefix, $hkey, $language = null); + + /** + * Normalize value to avoid duplicate or false negatives + * + * @param string $value + * + * @return string + */ + private function normalize($value) + { + if (null !== $value) { + return strtolower(trim($value)); + } + } + + /** + * {@inheritdoc} + */ + public function saveAlias($source, $alias, $language = null) + { + $alias = $this->normalize($alias); + $source = $this->normalize($source); + + if (null === $language) { + $language = LANGUAGE_NONE; + } + + if (!empty($source)) { + $this->saveInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); + } + if (!empty($alias)) { + $this->saveInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); + } + } + + /** + * {@inheritdoc} + */ + public function deleteAlias($source, $alias, $language = null) + { + $alias = $this->normalize($alias); + $source = $this->normalize($source); + + if (null === $language) { + $language = LANGUAGE_NONE; + } + + $this->deleteInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); + $this->deleteInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); + } + + /** + * {@inheritdoc} + */ + public function lookupAlias($source, $language = null) + { + $source = $this->normalize($source); + + return $this->lookupInHash(self::KEY_ALIAS, $source, $language); + } + + /** + * {@inheritdoc} + */ + public function lookupSource($alias, $language = null) + { + $alias = $this->normalize($alias); + + return $this->lookupInHash(self::KEY_SOURCE, $alias, $language); + } } diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Path/PhpRedis.php b/sites/all/modules/fpfis/redis/lib/Redis/Path/PhpRedis.php index 35ac104ac..46610bcc9 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Path/PhpRedis.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Path/PhpRedis.php @@ -41,23 +41,6 @@ protected function saveInHash($key, $hkey, $hvalue) // Empty value here means that we already got it } - /** - * {@inheritdoc} - */ - public function saveAlias($source, $alias, $language = null) - { - if (null === $language) { - $language = LANGUAGE_NONE; - } - - if (!empty($source)) { - $this->saveInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); - } - if (!empty($alias)) { - $this->saveInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); - } - } - protected function deleteInHash($key, $hkey, $hvalue) { $client = $this->getClient(); @@ -77,29 +60,6 @@ protected function deleteInHash($key, $hkey, $hvalue) } } - /** - * {@inheritdoc} - */ - public function deleteAlias($source, $alias, $language = null) - { - if (null === $language) { - $language = LANGUAGE_NONE; - } - - $this->deleteInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); - $this->deleteInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); - } - - /** - * {@inheritdoc} - */ - public function deleteLanguage($language) - { - $client = $this->getClient(); - $client->del($this->getKey(array(self::KEY_ALIAS, $language))); - $client->del($this->getKey(array(self::KEY_SOURCE, $language))); - } - protected function lookupInHash($keyPrefix, $hkey, $language = null) { $client = $this->getClient(); @@ -117,7 +77,7 @@ protected function lookupInHash($keyPrefix, $hkey, $language = null) if ($doNoneLookup && (!$ret || self::VALUE_NULL === $ret)) { $previous = $ret; $ret = $client->hget($this->getKey(array($keyPrefix, LANGUAGE_NONE)), $hkey); - if (!$ret && $previous) { + if (!$ret || self::VALUE_NULL === $ret) { // Restore null placeholder else we loose conversion to false // and drupal_lookup_path() would attempt saving it once again $ret = $previous; @@ -139,16 +99,10 @@ protected function lookupInHash($keyPrefix, $hkey, $language = null) /** * {@inheritdoc} */ - public function lookupAlias($source, $language = null) - { - return $this->lookupInHash(self::KEY_ALIAS, $source, $language); - } - - /** - * {@inheritdoc} - */ - public function lookupSource($alias, $language = null) + public function deleteLanguage($language) { - return $this->lookupInHash(self::KEY_SOURCE, $alias, $language); + $client = $this->getClient(); + $client->del($this->getKey(array(self::KEY_ALIAS, $language))); + $client->del($this->getKey(array(self::KEY_SOURCE, $language))); } } diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Path/Predis.php b/sites/all/modules/fpfis/redis/lib/Redis/Path/Predis.php index 6065475f7..a0eb74d05 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Path/Predis.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Path/Predis.php @@ -41,23 +41,6 @@ protected function saveInHash($key, $hkey, $hvalue) // Empty value here means that we already got it } - /** - * {@inheritdoc} - */ - public function saveAlias($source, $alias, $language = null) - { - if (null === $language) { - $language = LANGUAGE_NONE; - } - - if (!empty($source)) { - $this->saveInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); - } - if (!empty($alias)) { - $this->saveInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); - } - } - protected function deleteInHash($key, $hkey, $hvalue) { $client = $this->getClient(); @@ -77,29 +60,6 @@ protected function deleteInHash($key, $hkey, $hvalue) } } - /** - * {@inheritdoc} - */ - public function deleteAlias($source, $alias, $language = null) - { - if (null === $language) { - $language = LANGUAGE_NONE; - } - - $this->deleteInHash($this->getKey(array(self::KEY_ALIAS, $language)), $source, $alias); - $this->deleteInHash($this->getKey(array(self::KEY_SOURCE, $language)), $alias, $source); - } - - /** - * {@inheritdoc} - */ - public function deleteLanguage($language) - { - $client = $this->getClient(); - $client->del($this->getKey(array(self::KEY_ALIAS, $language))); - $client->del($this->getKey(array(self::KEY_SOURCE, $language))); - } - protected function lookupInHash($keyPrefix, $hkey, $language = null) { $client = $this->getClient(); @@ -117,7 +77,7 @@ protected function lookupInHash($keyPrefix, $hkey, $language = null) if ($doNoneLookup && (!$ret || self::VALUE_NULL === $ret)) { $previous = $ret; $ret = $client->hget($this->getKey(array($keyPrefix, LANGUAGE_NONE)), $hkey); - if (!$ret && $previous) { + if (!$ret || self::VALUE_NULL === $ret) { // Restore null placeholder else we loose conversion to false // and drupal_lookup_path() would attempt saving it once again $ret = $previous; @@ -139,16 +99,10 @@ protected function lookupInHash($keyPrefix, $hkey, $language = null) /** * {@inheritdoc} */ - public function lookupAlias($source, $language = null) - { - return $this->lookupInHash(self::KEY_ALIAS, $source, $language); - } - - /** - * {@inheritdoc} - */ - public function lookupSource($alias, $language = null) + public function deleteLanguage($language) { - return $this->lookupInHash(self::KEY_SOURCE, $alias, $language); + $client = $this->getClient(); + $client->del($this->getKey(array(self::KEY_ALIAS, $language))); + $client->del($this->getKey(array(self::KEY_SOURCE, $language))); } } diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFixesUnitTestCase.test b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFixesUnitTestCase.test new file mode 100644 index 000000000..5555dbb6d --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFixesUnitTestCase.test @@ -0,0 +1,27 @@ + 'Compressed PhpRedis cache fixes', + 'description' => 'Tests Redis module cache fixes feature.', + 'group' => 'Redis', + ); + } + + protected function createCacheInstance($name = null) + { + return new Redis_CacheCompressed($name); + } + + protected function getClientInterface() + { + return 'PhpRedis'; + } +} \ No newline at end of file diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFlushUnitTestCase.test b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFlushUnitTestCase.test new file mode 100644 index 000000000..f901bf3f0 --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisFlushUnitTestCase.test @@ -0,0 +1,27 @@ + 'Compressed PhpRedis cache flush', + 'description' => 'Tests Redis module cache flush modes feature.', + 'group' => 'Redis', + ); + } + + protected function createCacheInstance($name = null) + { + return new Redis_CacheCompressed($name); + } + + protected function getClientInterface() + { + return 'PhpRedis'; + } +} \ No newline at end of file diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFixesUnitTestCase.test b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFixesUnitTestCase.test new file mode 100644 index 000000000..8369fec18 --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFixesUnitTestCase.test @@ -0,0 +1,25 @@ + 'Compressed PhpRedis cache fixes (S)', + 'description' => 'Tests Redis module cache fixes feature.', + 'group' => 'Redis', + ); + } + + protected function createCacheInstance($name = null) + { + return new Redis_CacheCompressed($name); + } + + protected function getClientInterface() + { + $GLOBALS['conf']['redis_flush_mode'] = Redis_Cache::FLUSH_SHARD; + + return 'PhpRedis'; + } +} \ No newline at end of file diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFlushUnitTestCase.test b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFlushUnitTestCase.test new file mode 100644 index 000000000..e8b973b30 --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedFlushUnitTestCase.test @@ -0,0 +1,25 @@ + 'Compressed PhpRedis cache flush (S)', + 'description' => 'Tests Redis module cache flush modes feature.', + 'group' => 'Redis', + ); + } + + protected function createCacheInstance($name = null) + { + return new Redis_CacheCompressed($name); + } + + protected function getClientInterface() + { + $GLOBALS['conf']['redis_flush_mode'] = Redis_Cache::FLUSH_SHARD; + + return 'PhpRedis'; + } +} \ No newline at end of file diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedWithPipelineFixesUnitTestCase.test b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedWithPipelineFixesUnitTestCase.test new file mode 100644 index 000000000..069944720 --- /dev/null +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/CompressedPhpRedisShardedWithPipelineFixesUnitTestCase.test @@ -0,0 +1,25 @@ + 'Compressed PhpRedis cache fixes (SP)', + 'description' => 'Tests Redis module cache fixes feature.', + 'group' => 'Redis', + ); + } + + protected function createCacheInstance($name = null) + { + return new Redis_CacheCompressed($name); + } + + protected function getClientInterface() + { + $GLOBALS['conf']['redis_flush_mode'] = Redis_Cache::FLUSH_SHARD_WITH_PIPELINING; + + return 'PhpRedis'; + } +} \ No newline at end of file diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FixesUnitTestCase.php b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FixesUnitTestCase.php index 30625bac2..512005167 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FixesUnitTestCase.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FixesUnitTestCase.php @@ -14,6 +14,11 @@ abstract class Redis_Tests_Cache_FixesUnitTestCase extends Redis_Tests_AbstractU */ static private $id = 1; + protected function createCacheInstance($name = null) + { + return new Redis_Cache($name); + } + /** * Get cache backend * @@ -28,7 +33,7 @@ final protected function getBackend($name = null) $name = 'cache' . (self::$id++); } - $backend = new Redis_Cache($name); + $backend = $this->createCacheInstance($name); $this->assert(true, "Redis client is " . ($backend->isSharded() ? '' : "NOT ") . " sharded"); $this->assert(true, "Redis client is " . ($backend->allowTemporaryFlush() ? '' : "NOT ") . " allowed to flush temporary entries"); diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FlushUnitTestCase.php b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FlushUnitTestCase.php index c40b62364..41f519a7d 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FlushUnitTestCase.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Cache/FlushUnitTestCase.php @@ -7,6 +7,11 @@ abstract class Redis_Tests_Cache_FlushUnitTestCase extends Redis_Tests_AbstractU */ static private $id = 1; + protected function createCacheInstance($name = null) + { + return new Redis_Cache($name); + } + /** * Get cache backend * @@ -21,7 +26,7 @@ final protected function getBackend($name = null) $name = 'cache' . (self::$id++); } - $backend = new Redis_Cache($name); + $backend = $this->createCacheInstance($name); $this->assert(true, "Redis client is " . ($backend->isSharded() ? '' : "NOT ") . " sharded"); $this->assert(true, "Redis client is " . ($backend->allowTemporaryFlush() ? '' : "NOT ") . " allowed to flush temporary entries"); diff --git a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Path/PathUnitTestCase.php b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Path/PathUnitTestCase.php index 99fb93da2..91636f059 100644 --- a/sites/all/modules/fpfis/redis/lib/Redis/Tests/Path/PathUnitTestCase.php +++ b/sites/all/modules/fpfis/redis/lib/Redis/Tests/Path/PathUnitTestCase.php @@ -89,4 +89,60 @@ public function testPathLookup() $alias = $backend->lookupAlias('node/4', 'fr'); $this->assertIdentical('node-4', $alias); } + + /** + * Tests https://www.drupal.org/node/2728831 + */ + public function testSomeEdgeCaseFalseNegative() + { + $backend = $this->getBackend(); + + $backend->deleteLanguage('fr'); + $backend->deleteLanguage('und'); + $backend->saveAlias('node/123', 'node-123'); + + // Language lookup should return the language neutral value if no value + $source = $backend->lookupSource('node-123', 'fr'); + $this->assertIdentical($source, 'node/123'); + $source = $backend->lookupAlias('node/123', 'fr'); + $this->assertIdentical($source, 'node-123'); + + // Now, let's consider we have an item we don't know if it exists or + // not, per definition we should not return a strict FALSE but a NULL + // value instead to tell "we don't know anything about this". In a + // very specific use-case, if the language neutral value is a strict + // "not exists" value, it should still return NULL instead of FALSE + // if another language was asked for. + + // Store "value null" for the language neutral entry + $backend->saveAlias('node/456', Redis_Path_HashLookupInterface::VALUE_NULL); + $source = $backend->lookupAlias('node/456'); + $this->assertIdentical(false, $source); + + $source = $backend->lookupAlias('node/456', 'fr'); + $this->assertIdentical(null, $source); + } + + /** + * Tests that lookup is case insensitive + */ + public function testCaseInsensitivePathLookup() + { + $backend = $this->getBackend(); + + $backend->saveAlias('node/1', 'Node-1-FR', 'fr'); + $source = $backend->lookupSource('NODE-1-fr', 'fr'); + $this->assertIdentical('node/1', $source); + $source = $backend->lookupSource('node-1-FR', 'fr'); + $this->assertIdentical('node/1', $source); + $alias = $backend->lookupAlias('node/1', 'fr'); + $this->assertIdentical('node-1-fr', strtolower($alias)); + + // Delete and ensure it does not exist anymore. + $backend->deleteAlias('node/1', 'node-1-FR', 'fr'); + $source = $backend->lookupSource('Node-1-FR', 'fr'); + $this->assertIdentical(null, $source); + $alias = $backend->lookupAlias('node/1', 'fr'); + $this->assertIdentical(null, $source); + } } diff --git a/sites/all/modules/fpfis/redis/redis.info b/sites/all/modules/fpfis/redis/redis.info index 5c8888a13..931f282bd 100644 --- a/sites/all/modules/fpfis/redis/redis.info +++ b/sites/all/modules/fpfis/redis/redis.info @@ -9,6 +9,11 @@ files[] = lib/Redis/Tests/AbstractUnitTestCase.php files[] = lib/Redis/Tests/Admin/VariableTestCase.test files[] = lib/Redis/Tests/Cache/FixesUnitTestCase.php files[] = lib/Redis/Tests/Cache/FlushUnitTestCase.php +files[] = lib/Redis/Tests/Cache/CompressedPhpRedisFixesUnitTestCase.test +files[] = lib/Redis/Tests/Cache/CompressedPhpRedisFlushUnitTestCase.test +files[] = lib/Redis/Tests/Cache/CompressedPhpRedisShardedFixesUnitTestCase.test +files[] = lib/Redis/Tests/Cache/CompressedPhpRedisShardedFlushUnitTestCase.test +files[] = lib/Redis/Tests/Cache/CompressedPhpRedisShardedWithPipelineFixesUnitTestCase.test files[] = lib/Redis/Tests/Cache/PhpRedisFixesUnitTestCase.test files[] = lib/Redis/Tests/Cache/PhpRedisFlushUnitTestCase.test files[] = lib/Redis/Tests/Cache/PhpRedisShardedFixesUnitTestCase.test @@ -31,9 +36,9 @@ files[] = lib/Redis/Tests/Queue/QueueUnitTestCase.php files[] = lib/Redis/Tests/Queue/PhpRedisQueueUnitTestCase.test files[] = lib/Redis/Tests/Queue/PredisQueueUnitTestCase.test -; Information added by Drupal.org packaging script on 2016-04-08 -version = "7.x-3.12" +; Information added by Drupal.org packaging script on 2017-12-22 +version = "7.x-3.17" core = "7.x" project = "redis" -datestamp = "1460130914" +datestamp = "1513939095" diff --git a/sites/all/modules/fpfis/redis/redis.install b/sites/all/modules/fpfis/redis/redis.install index 791888718..b3e606706 100644 --- a/sites/all/modules/fpfis/redis/redis.install +++ b/sites/all/modules/fpfis/redis/redis.install @@ -30,7 +30,7 @@ function redis_requirements($phase) { 'title' => "Redis", 'value' => t("Not connected."), 'severity' => REQUIREMENT_WARNING, - 'description' => t("No Redis client connected, this module is useless thereof. Ensure that you enabled module using it or disable it."), + 'description' => t("No Redis client connected. Please ensure that your Redis connection is working properly. If you are not using a Redis server connection you should disable this module."), ); } diff --git a/sites/all/modules/fpfis/redis/redis.module b/sites/all/modules/fpfis/redis/redis.module index 6ced6df52..fa4816e33 100644 --- a/sites/all/modules/fpfis/redis/redis.module +++ b/sites/all/modules/fpfis/redis/redis.module @@ -39,8 +39,8 @@ function redis_help($path, $arg) { switch ($path) { case 'admin/config/development/performance/redis': $messages = - '

' . t("Redis module is optional if you are using only a cache, lock or session backend. The full API will be automatically loaded and its configuration will live into the settings.php file. If you access to this screen, it's probably because another contrib module needs it as a dependency for using the Redis client. If you didn't enabled such module, you are strongly advised to disable the Redis module on the module page.") . '

' . - '

' . t("While Redis client configuration can be changed through the web, if you are using a cache, lock or session backend they must be set in the settings.php file. Once this done, any modification done using this form will be ignored, and real settings in use will be get at early bootstrap phase, before the configuration system is bootstrapped.") . '

'; + '

' . t("Redis module is optional if you are using only a cache or lock backend. The full API will be automatically loaded and its configuration will live into the settings.php file. If you access to this screen, it's probably because another contrib module needs it as a dependency for using the Redis client. If you didn't enabled such module, you are strongly advised to disable the Redis module on the module page.") . '

' . + '

' . t("While Redis client configuration can be changed through the web, if you are using a cache or lock backend they must be set in the settings.php file. Once this done, any modification done using this form will be ignored, and real settings in use will be get at early bootstrap phase, before the configuration system is bootstrapped.") . '

'; if (Redis_Client::getClient()) { $messages .= '

' . t("Current connected client uses the @name library.", array('@name' => Redis_Client::getClientInterfaceName())) . '

'; } @@ -55,9 +55,9 @@ function redis_help($path, $arg) { */ function phpredis_client_get() { if ('PhpRedis' !== variable_get('redis_client_interface')) { - return Redis_Client::getClient(); + throw new \LogicException("Redis is not configured to use the php-redis client"); } - throw new \LogicException("Redis is not configured to use the php-redis client"); + return Redis_Client::getClient(); } /** @@ -67,7 +67,7 @@ function phpredis_client_get() { */ function predis_client_get() { if ('Predis' !== variable_get('redis_client_interface')) { - return Redis_Client::getClient(); + throw new \LogicException("Redis is not configured to use the Predis client"); } - throw new \LogicException("Redis is not configured to use the Predis client"); + return Redis_Client::getClient(); } diff --git a/sites/all/modules/fpfis/redis/redis.path.inc b/sites/all/modules/fpfis/redis/redis.path.inc index 03abe0a28..73ffa0910 100644 --- a/sites/all/modules/fpfis/redis/redis.path.inc +++ b/sites/all/modules/fpfis/redis/redis.path.inc @@ -85,6 +85,10 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) { return $cache[$path_language][$action][$path]; } + if (!empty($path)) { + $path = strtolower(trim($path)); + } + $ret = null; $hashLookup = redis_path_backend_get(); @@ -117,17 +121,17 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) { // the right language (keeps track of LANGUAGE_NONE or specific language // so that default fallback behavior is the same that core). if ($path_language == LANGUAGE_NONE) { - list ($ret, $path_language) = db_query("SELECT alias, language FROM {url_alias} WHERE source = :source AND language = :language ORDER BY pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT alias, language FROM {url_alias} WHERE source = :source AND language = :language ORDER BY pid DESC", 0, 1, array( ':source' => $path, ':language' => $path_language, ))->fetch(PDO::FETCH_NUM); } else if ($path_language > LANGUAGE_NONE) { - list ($ret, $path_language) = db_query("SELECT alias, language FROM {url_alias} WHERE source = :source AND language IN (:language) ORDER BY language DESC, pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT alias, language FROM {url_alias} WHERE source = :source AND language IN (:language) ORDER BY language DESC, pid DESC", 0, 1, array( ':source' => $path, ':language' => array($path_language, LANGUAGE_NONE), ))->fetch(PDO::FETCH_NUM); } else { - list ($ret, $path_language) = db_query("SELECT alias, language FROM {url_alias} WHERE source = :source AND language IN (:language) ORDER BY language ASC, pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT alias, language FROM {url_alias} WHERE source = :source AND language IN (:language) ORDER BY language ASC, pid DESC", 0, 1, array( ':source' => $path, ':language' => array($path_language, LANGUAGE_NONE), ))->fetch(PDO::FETCH_NUM); @@ -159,17 +163,17 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) { // the right language (keeps track of LANGUAGE_NONE or specific language // so that default fallback behavior is the same that core). if ($path_language == LANGUAGE_NONE) { - list ($ret, $path_language) = db_query("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language = :language ORDER BY pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language = :language ORDER BY pid DESC", 0, 1, array( ':alias' => $path, ':language' => LANGUAGE_NONE, ))->fetch(PDO::FETCH_NUM); } else if ($path_language > LANGUAGE_NONE) { - list ($ret, $path_language) = db_query("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language IN (:language) ORDER BY language DESC, pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language IN (:language) ORDER BY language DESC, pid DESC", 0, 1, array( ':alias' => $path, ':language' => array($path_language, LANGUAGE_NONE), ))->fetch(PDO::FETCH_NUM); } else { - list ($ret, $path_language) = db_query("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language IN (:language) ORDER BY language ASC, pid DESC LIMIT 1", array( + list ($ret, $path_language) = db_query_range("SELECT source, language FROM {url_alias} WHERE alias = :alias AND language IN (:language) ORDER BY language ASC, pid DESC", 0, 1, array( ':alias' => $path, ':language' => array($path_language, LANGUAGE_NONE), ))->fetch(PDO::FETCH_NUM); @@ -177,6 +181,8 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) { // Getting here with a value means we need to cache it if (empty($ret)) { $ret = false; + } else { + $ret = strtolower(trim($ret)); } $hashLookup->saveAlias($ret, $path, $path_language); } @@ -561,8 +567,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) { elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) { // Path is dynamic (ie 'user/%'), so check directly against menu_router table. if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) { - $item['link_path'] = $form_item['link_path']; - $item['link_title'] = $form_item['link_title']; + $item['link_path'] = $item['path']; + $item['link_title'] = $item['title']; $item['external'] = FALSE; $item['options'] = ''; _menu_link_translate($item);