diff --git a/core/lib/Drupal/Core/Cache/ApcuBackend.php b/core/lib/Drupal/Core/Cache/ApcuBackend.php index 9bac79e..f3e0acc 100644 --- a/core/lib/Drupal/Core/Cache/ApcuBackend.php +++ b/core/lib/Drupal/Core/Cache/ApcuBackend.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; + /** * Stores cache items in the Alternative PHP Cache User Cache (APCu). */ @@ -166,7 +168,7 @@ protected function prepareItem($cache, $allow_invalid) { * {@inheritdoc} */ public function set($cid, $data, $expire = CacheBackendInterface::CACHE_PERMANENT, array $tags = array()) { - Cache::validateTags($tags); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); $tags = array_unique($tags); $cache = new \stdClass(); $cache->cid = $cid; diff --git a/core/lib/Drupal/Core/Cache/Cache.php b/core/lib/Drupal/Core/Cache/Cache.php index 5ad9500..0c66244 100644 --- a/core/lib/Drupal/Core/Cache/Cache.php +++ b/core/lib/Drupal/Core/Cache/Cache.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Drupal\Core\Database\Query\SelectInterface; /** @@ -59,8 +60,9 @@ public static function mergeContexts(array $a = [], array $b = []) { * The merged array of cache tags. */ public static function mergeTags(array $a = [], array $b = []) { + assert(Inspector::assertAllStrings($a) && Inspector::assertAllStrings($b)); + $cache_tags = array_unique(array_merge($a, $b)); - static::validateTags($cache_tags); sort($cache_tags); return $cache_tags; } @@ -99,6 +101,9 @@ public static function mergeMaxAges($a = Cache::PERMANENT, $b = Cache::PERMANENT * @param string[] $tags * An array of cache tags. * + * @deprecated + * Use assert(\Drupal\Component\Assertion\Inspector::assertAllStrings($tags)); + * * @throws \LogicException */ public static function validateTags(array $tags) { diff --git a/core/lib/Drupal/Core/Cache/CacheCollector.php b/core/lib/Drupal/Core/Cache/CacheCollector.php index a6d8ab5..d387a12 100644 --- a/core/lib/Drupal/Core/Cache/CacheCollector.php +++ b/core/lib/Drupal/Core/Cache/CacheCollector.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Drupal\Core\DestructableInterface; use Drupal\Core\Lock\LockBackendInterface; @@ -115,7 +116,7 @@ * (optional) The tags to specify for the cache item. */ public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, array $tags = array()) { - Cache::validateTags($tags); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); $this->cid = $cid; $this->cache = $cache; $this->tags = $tags; diff --git a/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php b/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php index 64a8eb0..c798071 100644 --- a/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php +++ b/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Symfony\Component\DependencyInjection\ContainerAwareTrait; /** @@ -28,7 +29,7 @@ class CacheTagsInvalidator implements CacheTagsInvalidatorInterface { */ public function invalidateTags(array $tags) { // Validate the tags. - Cache::validateTags($tags); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); // Notify all added cache tags invalidators. foreach ($this->invalidators as $invalidator) { diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index 06c5dc2..43608ab 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Drupal\Component\Utility\Crypt; use Drupal\Core\Database\Connection; use Drupal\Core\Database\SchemaObjectExistsException; @@ -199,7 +200,7 @@ protected function doSetMultiple(array $items) { 'tags' => array(), ); - Cache::validateTags($item['tags']); + assert(Inspector::assertAllStrings($item['tags']), 'Cache Tags must be strings.'); $item['tags'] = array_unique($item['tags']); // Sort the cache tags so that they are stored consistently in the DB. sort($item['tags']); diff --git a/core/lib/Drupal/Core/Cache/MemoryBackend.php b/core/lib/Drupal/Core/Cache/MemoryBackend.php index 5c7f928..5aebd7b 100644 --- a/core/lib/Drupal/Core/Cache/MemoryBackend.php +++ b/core/lib/Drupal/Core/Cache/MemoryBackend.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; + /** * Defines a memory cache implementation. * @@ -107,7 +109,7 @@ protected function prepareItem($cache, $allow_invalid) { * Implements Drupal\Core\Cache\CacheBackendInterface::set(). */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - Cache::validateTags($tags); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); $tags = array_unique($tags); // Sort the cache tags so that they are stored consistently in the database. sort($tags); diff --git a/core/lib/Drupal/Core/Cache/PhpBackend.php b/core/lib/Drupal/Core/Cache/PhpBackend.php index 761e394..8f130f7 100644 --- a/core/lib/Drupal/Core/Cache/PhpBackend.php +++ b/core/lib/Drupal/Core/Cache/PhpBackend.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Drupal\Core\PhpStorage\PhpStorageFactory; use Drupal\Component\Utility\Crypt; @@ -148,7 +149,7 @@ protected function prepareItem($cache, $allow_invalid) { * {@inheritdoc} */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - Cache::validateTags($tags); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); $item = (object) array( 'cid' => $cid, 'data' => $data, diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php index 7c8799a..38f2a21 100644 --- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php +++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Plugin; +use Drupal\Component\Assertion\Inspector; use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface; use Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait; use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; @@ -154,7 +155,7 @@ public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInte * definitions should be cleared along with other, related cache entries. */ public function setCacheBackend(CacheBackendInterface $cache_backend, $cache_key, array $cache_tags = array()) { - Cache::validateTags($cache_tags); + assert(Inspector::assertAllStrings($cache_tags), 'Cache Tags must be strings.'); $this->cacheBackend = $cache_backend; $this->cacheKey = $cache_key; $this->cacheTags = $cache_tags; diff --git a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php index cc0d9df..8aaa323 100644 --- a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php +++ b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php @@ -218,13 +218,13 @@ public function testSetGet() { $this->assertEqual('value', $backend->get('TEST8')->data); $this->assertFalse($backend->get('test8')); - // Calling ::set() with invalid cache tags. + // Calling ::set() with invalid cache tags. This should fail an assertion. try { - $backend->set('exception_test', 'value', Cache::PERMANENT, ['node' => [3, 5, 7]]); - $this->fail('::set() was called with invalid cache tags, no exception was thrown.'); + $backend->set('assertion_test', 'value', Cache::PERMANENT, ['node' => [3, 5, 7]]); + $this->fail('::set() was called with invalid cache tags, runtime assertion did not fail.'); } - catch (\LogicException $e) { - $this->pass('::set() was called with invalid cache tags, an exception was thrown.'); + catch (\AssertionError $e) { + $this->pass('::set() was called with invalid cache tags, runtime assertion failed.'); } } @@ -412,7 +412,7 @@ public function testSetMultiple() { $this->assertEqual($cached['cid_5']->data, $items['cid_5']['data'], 'New cache item set correctly.'); - // Calling ::setMultiple() with invalid cache tags. + // Calling ::setMultiple() with invalid cache tags. This should fail an assertion. try { $items = [ 'exception_test_1' => array('data' => 1, 'tags' => []), @@ -420,10 +420,10 @@ public function testSetMultiple() { 'exception_test_3' => array('data' => 3, 'tags' => ['node' => [3, 5, 7]]), ]; $backend->setMultiple($items); - $this->fail('::setMultiple() was called with invalid cache tags, no exception was thrown.'); + $this->fail('::setMultiple() was called with invalid cache tags, runtime assertion did not fail.'); } - catch (\LogicException $e) { - $this->pass('::setMultiple() was called with invalid cache tags, an exception was thrown.'); + catch (\AssertionError $e) { + $this->pass('::setMultiple() was called with invalid cache tags, runtime assertion failed.'); } } diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php index a9ebf6f..01200ce 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBase.php +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php @@ -7,6 +7,7 @@ namespace Drupal\KernelTests; +use Drupal\Component\Assertion\Handle as AssertionHandler; use Drupal\Component\FileCache\ApcuFileCacheBackend; use Drupal\Component\FileCache\FileCache; use Drupal\Component\FileCache\FileCacheFactory; @@ -232,6 +233,7 @@ protected function setUp() { * @internal */ protected function bootEnvironment() { + AssertionHandler::register(); $this->streamWrappers = array(); \Drupal::unsetContainer(); diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheTest.php index c2e61a1..be0e510 100644 --- a/core/tests/Drupal/Tests/Core/Cache/CacheTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/CacheTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\Core\Cache; +use Drupal\Component\Assertion\Inspector; use Drupal\Core\Cache\Cache; use Drupal\Tests\UnitTestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -60,6 +61,32 @@ public function testValidateTags(array $tags, $expected_exception_message) { } /** + * Tests Drupal\Component\Assertion\Inspector::assertAllStrings + * + * Inspector is replacing ::validateTags, so for regression testing it must + * return correctly on the same test data. It returns boolean instead of + * throwing an exception when the tags are invalid, so this is reflected in + * the test below. In practice the Inspector is called from the assert() + * statement which will throw \AssertionError when the tags are invalid. + * + * @covers Drupal\Component\Assertion\Inspector::assertAllStrings + * + * @dataProvider validateTagsProvider + */ + public function testInspectorAssertAllStrings(array $tags, $expected_exception_message) { + // If no exception is expected for ::validateTags then the Inspector should + // return TRUE + if ($expected_exception_message === FALSE) { + $this->assertTrue(Inspector::assertAllStrings($tags)); + } + // Otherwise it returns FALSE. Unlike the function it replaces, it returns + // boolean. + else { + $this->assertFalse(Inspector::assertAllStrings($tags)); + } + } + + /** * Provides a list of pairs of cache tags arrays to be merged. * * @return array