diff --git a/includes/token.inc b/includes/token.inc index c31f9e6..63481f7 100644 --- a/includes/token.inc +++ b/includes/token.inc @@ -17,7 +17,7 @@ * * Tokens follow the form: [$type:$name], where $type is a general class of * tokens like 'node', 'user', or 'comment' and $name is the name of a given - * placeholder. For example, [node:title]. + * placeholder. For example, [node:title] or [node:created:since]. * * In addition to raw text containing placeholders, modules may pass in an array * of objects to be used when performing the replacement. The objects should be @@ -103,9 +103,16 @@ function token_replace($text, array $data = array(), array $options = array()) { * An associative array of discovered tokens, grouped by type. */ function token_scan($text) { - // Matches tokens with the following pattern: [$type:$token] - // $type and $token may not contain white spaces. - preg_match_all('/\[([^\s\]:]*):([^\s\]]*)\]/', $text, $matches); + // Matches tokens with the following pattern: [$type:$name] + // $type and $name may not contain [ ] or whitespace characters. + // $type may not contain : characters, but $name may. + preg_match_all('/ + \[ # [ - pattern start + ([^\s\[\]:]*) # match $type not containing whitespace : [ or ] + : # : - separator + ([^\s\[\]]*) # match $name not containing whitespace [ or ] + \] # ] - pattern end + /x', $text, $matches); $types = $matches[1]; $tokens = $matches[2]; diff --git a/modules/system/system.test b/modules/system/system.test index 3045569..60f5d2c 100644 --- a/modules/system/system.test +++ b/modules/system/system.test @@ -1577,9 +1577,10 @@ class TokenReplaceTestCase extends DrupalWebTestCase { $result = token_replace($source, array('node' => $node), array('language' => $language, 'clear' => TRUE)); $result = $this->assertFalse(strcmp($target, $result), 'Valid tokens replaced while invalid tokens cleared out.'); - // Test without using the clear parameter (non-existant token untouched). + // Test without using the clear parameter (non-existent token untouched). $target .= '[user:name]'; $target .= '[bogus:token]'; + $result = token_replace($source, array('node' => $node), array('language' => $language)); $this->assertFalse(strcmp($target, $result), 'Valid tokens replaced while invalid tokens ignored.'); @@ -1596,6 +1597,35 @@ class TokenReplaceTestCase extends DrupalWebTestCase { } /** + * Test whether token-replacement works in various contexts. + */ + function testSystemTokenRecognition() { + global $language; + $source = $target = ''; + + // Generate prefixes and suffixes for the token context. + $tests = array( + array('prefix' => 'this is the ', 'suffix' => ' site'), + array('prefix' => 'this is the', 'suffix' => 'site'), + array('prefix' => '[', 'suffix' => ']'), + array('prefix' => '', 'suffix' => ']]]'), + array('prefix' => '[[[', 'suffix' => ''), + array('prefix' => ':[:', 'suffix' => '--]'), + array('prefix' => '-[-', 'suffix' => ':]:'), + array('prefix' => '[:', 'suffix' => ']'), + array('prefix' => '[site:', 'suffix' => ':name]'), + array('prefix' => '[site:', 'suffix' => ']'), + ); + foreach ($tests as $test) { + $source .= $test['prefix'] . '[site:name]' . $test['suffix']; + $target .= $test['prefix'] . 'Drupal' . $test['suffix']; + } + + $result = token_replace($source, array(), array('language' => $language)); + $this->assertFalse(strcmp($target, $result), 'Token recognized within a string context.'); + } + + /** * Tests the generation of all system site information tokens. */ function testSystemSiteTokenReplacement() {