Some modules provide many tokens that are not included explicitly in their hook_token_list() for reasons of brevity. For example, Date module provides ~30 tokens that relate to each date field, and (would) provide the same 30 tokens for the optional TO-date part of that field. Instead they provide a wildcard-style result in the list to-???? and a description of how to use this.

This works fine, apart from when use of the tokens are explicitly validated, and the existing wildcard support only allows for numeric-suffix wildcards.

This feature request is to extend the wildcard support in token validation to support -* -? and -???? style wildcards.

Related issue: #376008: Can't use "to-" date tokens in pathauto

Comments

lyricnz’s picture

Status: Active » Needs review
StatusFileSize
new819 bytes

Here's a patch that performs this validation. Realising that running preg_match() across all the tokens is inefficient, the code is only invoked if there are invalid tokens after normal validation.

Status: Needs review » Needs work

The last submitted patch, token_wildcard_validation-1147452.patch, failed testing.

lyricnz’s picture

StatusFileSize
new751 bytes

Update patch for flattened token structure.

lyricnz’s picture

Status: Needs work » Needs review

Can add tests if approach is approved by maintainer.

Go, bot, go.

lyricnz’s picture

StatusFileSize
new4.42 KB

Change to require characters in the wildcard part of the token, not just the right prefix. Added test cases for both validation, and token-value

dave reid’s picture

I'm not sure why this logic can't go inside the existing 'wildcard' check in token_get_invalid_tokens_by_context(). I don't think it makes sense to run a preg_match() on each token twice. Let's set the standard for a wildcard token that it should be [-_](N|\?) and not -????.

dave reid’s picture

Status: Needs review » Needs work
dave reid’s picture

Also, I backported the assertTokens() function from token.test in Drupal 7 so you can use 'tokenname' => NULL to test for un-generated tokens.

lyricnz’s picture

StatusFileSize
new1.89 KB

The current code loops across each of the tokens found in the input string (small number), and checks if they're in the list of available tokens (big number) - using isset() or a single preg_match() for the _N wildcard. This is very efficient.

However, in order to check an input-token against a wildcard available-token, we need to

  • find the wildcard tokens in the list of available tokens
  • match these against the list of tokens from the input string

So, the extra loop is actually around the *available* tokens, not the list of tokens being validated (probably not clear from the patch). By putting it below the existing loop:

  • we don't do ANY extra work unless there are actually tokens not found by the current code
  • only the input-tokens that are previously unmatched are checked

Here's just the token.module patch with a bit more context.

lyricnz’s picture

Status: Needs work » Needs review
StatusFileSize
new3.88 KB

Updated patch to use new assertTokens() functionality.

dave reid’s picture

This is what I was thinking. There's no need to add another loop with two possible preg calls per loop. With this, we enforce the following standard with wildcard tokens:

You must list your token in hook_token_list as token-name[-_][N?]. Ideally I'd like it to be just '?' rather than both 'N' and '?', but I know location.module already uses -N.

Other changes
1. I have no interest in encouraging and supporting -* as a wildcard token suffix.
2. The test validating the tokens output things is kinda pointless as that code doesn't touch validation at all. There's nothing really new being tested, so I left it out.

lyricnz’s picture

Status: Needs review » Reviewed & tested by the community

OK, works for me. Once this is applied, I'll submit a patch for Date module.

PS: the first line of token_test_exit() generates a warning for me. What's that function?

function token_test_exit() {
  debug($debug);
  if ($debug = variable_get('token_page_tokens', array())) {
lyricnz’s picture

My only thought about -? vs -* is that '?' kindof implies a single letter/number, whereas * makes it clear that there could be quite a bit of stuff after the * (such as provided by date module). This may just be my geek/regex interpretation of that, of course.

lyricnz’s picture

Status: Reviewed & tested by the community » Needs work

Actually, the regex in your patch

elseif (preg_match('/^(.*[_-])([^-_])+$/', $token, $matches)) {

only supports having ONE word-part (as delimited by _-) after the wildcard, which really limits what a module can use the wildcard for. Are you sure?

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new3.67 KB

Yes it is intentional. We are severely limited in the custom/wildcard token API we can provide in D6 without affecting performance. Anything that really wants to do this right should be using D7, which has much better custom token support.

lyricnz’s picture

Your call, of course - but I disagree with "Anything that really wants to do this right should be using D7". Of course D7 has better token support, but most sites are still D6, and have no realistic chance of upgrading or being implemented in D7 (so many contrib modules not updated, in particular).

dave reid’s picture

So looking back on this, I see now that we used to use token-name-???? in token.module's node tokens a while back. So if other modules picked up on that as the 'standard', then we should support that too.

The problem is that with support date token's crazy rules is that I don't think I ever saw an issue in this queue to ask about 'hey we have this crazy wildcard token, how can it be best supported?'.

This patch adds support for token-name-???? wildcard syntax.

lyricnz’s picture

Regarding your comment on performance - that's exactly why I put the code in a second loop, that is only applied if there are tokens that are still invalid after primary checking.

dave reid’s picture

Same thing, this code only executes if the isset($valid_tokens[$token]) condition fails, and the token is invalid. lyricnz does #17 look good to you?

lyricnz’s picture

Status: Needs review » Reviewed & tested by the community

It's fine, but doesn't solve my original problem: "proper" wildcard support.

dave reid’s picture

Status: Reviewed & tested by the community » Fixed

Committed #17 to Git: http://drupalcode.org/project/token.git/commit/66bd549.

If there is any other *concrete* use case that we need to support, please give specific examples of what module provides the tokens, and example token names so that we can investigate further. Date.module tokens are now fully supported.

lyricnz’s picture

Thanks. I've updated the patch for Date module to not create multi-word elements in the wildcard part of the tokens.

http://drupal.org/node/593840#comment-4457364

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.