diff --git a/token.module b/token.module index 0fea16d..457920c 100644 --- a/token.module +++ b/token.module @@ -250,6 +250,12 @@ function token_replace($text, $type = 'global', $object = NULL, $leading = TOKEN * Text with tokens replaced. */ function token_replace_multiple($text, $types = array('global' => NULL), $leading = TOKEN_PREFIX, $trailing = TOKEN_SUFFIX, $options = array(), $flush = FALSE) { + // If there are no tokens to replace, just return the text. + $text_tokens = token_scan($text, $leading, $trailing); + if (empty($text_tokens)) { + return $text; + } + $full = new stdClass(); $full->tokens = $full->values = array(); @@ -266,7 +272,7 @@ function token_replace_multiple($text, $types = array('global' => NULL), $leadin // Support clearing out tokens that would not be replaced. if (!empty($options['clear'])) { - foreach (token_scan($text) as $token) { + foreach ($text_tokens as $token) { if (!in_array($token, $full->tokens)) { $full->tokens[] = $token; $full->values[] = ''; @@ -334,6 +340,13 @@ function token_get_values($type = 'global', $object = NULL, $flush = FALSE, $opt $tokens = array(); } + // Allow simple resets of the static values. + if ($type === 'reset') { + $tokens = array(); + $running = FALSE; + return; + } + // Neutralize options that do not affect token replacement. $serialized_options = $options; unset($serialized_options['clear']); @@ -677,7 +690,7 @@ function token_scan($text, $leading = TOKEN_PREFIX, $trailing = TOKEN_SUFFIX) { // Matches tokens with the following pattern: [$token] $leading = preg_quote($leading, '/'); $trailing = preg_quote($trailing, '/'); - preg_match_all("/{$leading}([^\s]+?){$trailing}/", $text, $matches); + preg_match_all("/{$leading}([^\s{$leading}{$trailing}]+){$trailing}/x", $text, $matches); return $matches[1]; } diff --git a/token.test b/token.test index cc9dec8..0de269c 100644 --- a/token.test +++ b/token.test @@ -14,6 +14,9 @@ class TokenTestHelper extends DrupalWebTestCase { $modules[] = 'token'; $modules[] = 'token_test'; parent::setUp($modules); + + // Clear the token static cache. + token_get_values('reset'); } function assertToken($type, $object, $token, $expected, array $options = array()) { @@ -234,6 +237,26 @@ class TokenUnitTestCase extends TokenTestHelper { ); $this->assertTokens('global', NULL, $tokens, array('foo' => 'bar')); } + + /** + * Test the token_scan() function. + */ + function testTokenScan() { + $tests = array( + array('text' => 'Test [foo] [bar] test.', 'tokens' => array('foo', 'bar')), + array('text' => 'Test [foo] [] test.', 'tokens' => array('foo')), + array('text' => 'Test [foo][] test.', 'tokens' => array('foo')), + array('text' => 'Test [foo][bar] test.', 'tokens' => array('foo', 'bar')), + array('text' => 'Test %foo %bar test.', 'tokens' => array('foo', 'bar'), 'leading' => '%', 'trailing' => ''), + array('text' => 'Test %foo % test.', 'tokens' => array('foo'), 'leading' => '%', 'trailing' => ''), + array('text' => 'Test %foo% test.', 'tokens' => array('foo'), 'leading' => '%', 'trailing' => ''), + array('text' => 'Test %foo%bar test.', 'tokens' => array('foo', 'bar'), 'leading' => '%', 'trailing' => ''), + ); + foreach ($tests as $test) { + $test += array('leading' => TOKEN_PREFIX, 'trailing' => TOKEN_SUFFIX); + $this->assertEqual(token_scan($test['text'], $test['leading'], $test['trailing']), $test['tokens']); + } + } } class TokenNodeTestCase extends TokenTestHelper {