summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2014-04-21 12:53:23 (GMT)
committerNathaniel Catchpole2014-04-21 12:53:23 (GMT)
commit1d8a302aad133d30b3d45313c631e0ca738ca94f (patch)
tree6b1c34dfd803ed4c86f998e1b7910109490d5c00
parent5cc27d94cc9d96847d8d5484ae2063c1ed982920 (diff)
Issue #1211864 by Xano, Taz, Dave Reid: Add caching to \Drupal\Core\Utility\Token::getInfo().
-rw-r--r--core/core.services.yml2
-rw-r--r--core/lib/Drupal/Core/Utility/Token.php52
-rw-r--r--core/tests/Drupal/Tests/Core/Utility/TokenUnitTest.php118
3 files changed, 166 insertions, 6 deletions
diff --git a/core/core.services.yml b/core/core.services.yml
index 3f7c394..c3bb8d2 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -652,7 +652,7 @@ services:
arguments: ['@module_handler']
token:
class: Drupal\Core\Utility\Token
- arguments: ['@module_handler']
+ arguments: ['@module_handler', '@cache.discovery', '@language_manager']
batch.storage:
class: Drupal\Core\Batch\BatchStorage
arguments: ['@database']
diff --git a/core/lib/Drupal/Core/Utility/Token.php b/core/lib/Drupal/Core/Utility/Token.php
index 27a4519..4a1238e 100644
--- a/core/lib/Drupal/Core/Utility/Token.php
+++ b/core/lib/Drupal/Core/Utility/Token.php
@@ -7,7 +7,10 @@
namespace Drupal\Core\Utility;
+use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Language\Language;
+use Drupal\Core\Language\LanguageManagerInterface;
/**
* Drupal placeholder/token replacement system.
@@ -55,9 +58,28 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
class Token {
/**
+ * The tag to cache token info with.
+ */
+ const TOKEN_INFO_CACHE_TAG = 'token_info';
+
+ /**
+ * The token cache.
+ *
+ * @var \Drupal\Core\Cache\CacheBackendInterface
+ */
+ protected $cache;
+
+ /**
+ * The language manager.
+ *
+ * @var \Drupal\Core\Language\LanguageManagerInterface
+ */
+ protected $languageManager;
+
+ /**
* Token definitions.
*
- * @var array|null
+ * @var array[]|null
* An array of token definitions, or NULL when the definitions are not set.
*
* @see self::setInfo()
@@ -74,11 +96,18 @@ class Token {
protected $moduleHandler;
/**
- * Constructor.
+ * Constructs a new class instance.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+ * The module handler.
+ * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+ * The token cache.
+ * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+ * The language manager.
*/
- public function __construct(ModuleHandlerInterface $module_handler) {
+ public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
+ $this->cache = $cache;
+ $this->languageManager = $language_manager;
$this->moduleHandler = $module_handler;
}
@@ -282,8 +311,18 @@ class Token {
*/
public function getInfo() {
if (is_null($this->tokenInfo)) {
- $this->tokenInfo = $this->moduleHandler->invokeAll('token_info');
- $this->moduleHandler->alter('token_info', $this->tokenInfo);
+ $cache_id = 'token_info:' . $this->languageManager->getCurrentLanguage(Language::TYPE_CONTENT)->id;
+ $cache = $this->cache->get($cache_id);
+ if ($cache) {
+ $this->tokenInfo = $cache->data;
+ }
+ else {
+ $this->tokenInfo = $this->moduleHandler->invokeAll('token_info');
+ $this->moduleHandler->alter('token_info', $this->tokenInfo);
+ $this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, array(
+ static::TOKEN_INFO_CACHE_TAG => TRUE,
+ ));
+ }
}
return $this->tokenInfo;
@@ -307,5 +346,8 @@ class Token {
*/
public function resetInfo() {
$this->tokenInfo = NULL;
+ $this->cache->deleteTags(array(
+ static::TOKEN_INFO_CACHE_TAG => TRUE,
+ ));
}
}
diff --git a/core/tests/Drupal/Tests/Core/Utility/TokenUnitTest.php b/core/tests/Drupal/Tests/Core/Utility/TokenUnitTest.php
new file mode 100644
index 0000000..f2d0a2d
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Utility/TokenUnitTest.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Utility\TokenUnitTest.
+ */
+
+namespace Drupal\Tests\Core\Utility;
+
+use Drupal\Core\Language\Language;
+use Drupal\Core\Utility\Token;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Tests\Core\Utility\Token
+ */
+class TokenUnitTest extends UnitTestCase {
+
+ /**
+ * The cache used for testing.
+ *
+ * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $cache;
+
+ /**
+ * The language manager used for testing.
+ *
+ * @var \Drupal\Core\Language\LanguageManager|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $languageManager;
+
+ /**
+ * The module handler service used for testing.
+ *
+ * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $moduleHandler;
+
+ /**
+ * The token service under test.
+ *
+ * @var \Drupal\Core\Utility\Token|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $token;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getInfo() {
+ return array(
+ 'description' => '',
+ 'name' => '\Drupal\Tests\Core\Utility\Token unit test',
+ 'group' => 'System',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ $this->cache = $this->getMock('\Drupal\Core\Cache\CacheBackendInterface');
+
+ $this->languageManager = $this->getMockBuilder('\Drupal\Core\Language\LanguageManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
+
+ $this->token = new Token($this->moduleHandler, $this->cache, $this->languageManager);
+ }
+
+ /**
+ * @covers getInfo
+ */
+ public function testGetInfo() {
+ $token_info = array(
+ 'types' => array(
+ 'foo' => array(
+ 'name' => $this->randomName(),
+ ),
+ ),
+ );
+
+ $language = $this->getMock('\Drupal\Core\Language\Language');
+ $language->id = $this->randomName();
+
+ $this->languageManager->expects($this->once())
+ ->method('getCurrentLanguage')
+ ->with(Language::TYPE_CONTENT)
+ ->will($this->returnValue($language));
+
+ // The persistent cache must only be hit once, after which the info is
+ // cached statically.
+ $this->cache->expects($this->once())
+ ->method('get');
+ $this->cache->expects($this->once())
+ ->method('set')
+ ->with('token_info:' . $language->id, $token_info);
+
+ $this->moduleHandler->expects($this->once())
+ ->method('invokeAll')
+ ->with('token_info')
+ ->will($this->returnValue($token_info));
+ $this->moduleHandler->expects($this->once())
+ ->method('alter')
+ ->with('token_info', $token_info);
+
+ // Get the information for the first time. The cache should be checked, the
+ // hooks invoked, and the info should be set to the cache should.
+ $this->token->getInfo();
+ // Get the information for the second time. The data must be returned from
+ // the static cache, so the persistent cache must not be accessed and the
+ // hooks must not be invoked.
+ $this->token->getInfo();
+ }
+
+}