Despite what reported in the project page, the code still replaces only two different tokens: user, and global token.

The version 6.x-1.x version has the following code:

/**
 * Helper function for preg_replace_callback to generate the html for each token filter
 */
function token_filter_replacetoken($matches) {  
  global $user;
  $type  = $matches[1];
  $token = $matches[2];
  switch ($type) {
    case 'user' :
      $object = $user;
      break;
    case 'global':
    default:
      $object = NULL;
      break;
    } 
  $output = token_replace($token, $type, $object = NULL, $leading = '', $trailing = '');
  return $output;
}

If I would use something like [token node xyz], the code will execute a call like token_replace('xyz', 'node', NULL, '', '').

Comments

obrigado’s picture

I don't think this will ever work with node tokens, since there's no way to get the NID / context inside hook_filter()

I'm looking into doing this with hook_nodeapi() instead.

See:

http://drupal.org/node/106249

And in D7...
http://drupal.org/node/8000
http://drupal.org/node/226963

obrigado’s picture

StatusFileSize
new2.12 KB

Here's a version using the view phase of hook_nodeapi instead of hook_filter... this lets you drop node tokens into the body field — particularly handy with CCK fields. Not thoroughly tested, use at your own risk.

Slight difference in syntax... takes just a plain old token and figures out the type afterwards.

Using the uglier preg_match_all() instead of the callback to avoid passing the node object into global scope.

If more people want this, maybe we can create a project or figure out a way to merge with Token Filter.

mudd’s picture

Subscribe...

I'd like to get FCKeditor file uploader/browser to recognize user and node tokens such that UserFilesPath is strictly user partitioned. AND I'm making heavy use of Filefiled (a CCK module) and Filefield_paths.

My setting for Filefield's upload path is "blah/[user-name]/[filefiled_name-title]/[title]", which results in a nicely organized file system based on user and node title (I have parent and child nodes too, and these folders are nested)

In the admin settings for FCKeditor then, would Token Filter allow me to use global/user/node/filefield tokens in the various settings for path etc?

pvhee’s picture

Status: Active » Closed (won't fix)

Token Filter replaces tokens in user, global and custom contexts (provided by other modules using hook_token_values). It indeed does not do it for node context, because it needs to know the current node object. Any patches welcome!

obrigado’s picture

phvee: I posted a different approach to this module above (http://drupal.org/node/474424#comment-1645070) ... this adds support for node tokens, but it shares very little code with the original module, so I did not think a patch was appropriate.

I believe the only way we can get access to the node object without resorting to shenanigans like global variables or javascript is to use the node API hook instead of the filter hook.

pvhee’s picture

That's indeed a very different approach, and I also don't immediately see a different approach than using globals to pass on the node variable to the filter. I will add this to the info page of the module, referring to this issue.

mitylite’s picture

Just chiming in that this would be a useful feature for my site if it ever came to fruition.

Also, the module posted in comment #2 is not compatible with drupal 6.14.

dleong’s picture

subscribing

nedjo’s picture

Even if we pass the node to the filter, it gets there too late. It's a chicken and egg problem--we are altering a field (via filtering), but we want to have all fields for the node already altered so the tokens will be correctly populated.

Filtering is done at the 'prepare' stage of nodeapi, but we can't be sure that all fields are correctly rendered at that stage--some may be reworked later, at the 'view' nodeapi stage. And if we cache a fully rendered node from the view op, the filter will get the previous viewed node, not the current one.

nedjo’s picture

StatusFileSize
new2.47 KB

The only workaround I can think of is:

* Give token_filter a high weight to run after other nodeapi 'view' implementations.
* In nodeapi 'view', load iterate through each cck field as well as the body field
* For each cck field, determine the format, and determine if the format includes the token_filter filter.
* If it does, iterate through the values of the field and run the token filter on it, sending the fully built node as an arg.
* Rewrite the existing filter processing to use a cached node.

Here's a very rough beginning of a patch. Missing parts are marked with // ....

avpaderno’s picture

Title: Drupal 6 version still handles only user, and global token » Code doesn't verify the value entered by the user, and calls toek_replace() with the wrong arguments
Status: Closed (won't fix) » Active

This issue report has been misunderstood because the title I gave it.

I checked the module and it still is using this code:

/**
* Helper function for preg_replace_callback to generate the html for each token filter
*/
function token_filter_replacetoken($matches) {  
  global $user;
  $type  = $matches[1];
  $token = $matches[2];
  switch ($type) {
    case 'user' :
      $object = $user;
      break;
    case 'global':
    default:
      $object = NULL;
      break;
    } 
  $output = token_replace($token, $type, $object = NULL, $leading = '', $trailing = '');
  return $output;
}

The user could enter [token node title], and the code would call token_replace() passing 'node' for $type, and NULL for $object. Modules that implement tokens don't verify if the object passed is null, and this causes access to not defined properties (as the variable is null).

The second problem is that despite the switch statement, the code always passes NULL for $object. This is evident because the line calling the function assign NULL to $object, and because assignment statements return the assigned value, that is also the value given to the parameter passed to the function.
This happens because the function definition has been copied, and used to call the function. What the function call is also doing is to define two variables ($leading, and $trailing), which are solely used to pass the default parameter to the function.
The correct function call is $output = token_replace($token, $type, $object).

I am marking this report as active because what I reported has not been fixed, yet.

nedjo’s picture

Moved the draft patch for passing node context to #696380: Pass node context to filters.

avpaderno’s picture

Title: Code doesn't verify the value entered by the user, and calls toek_replace() with the wrong arguments » Code doesn't verify the value entered by the user, and calls token_replace() with the wrong arguments
dwightaspinwall’s picture

Component: Documentation » Code
Status: Active » Needs review
StatusFileSize
new2.84 KB

This patch prohibits any token type but global and user to be evaluated. It also adds help text for the filter using hook_filter_tips(), and also makes reference to the Tokenize Request Parameters module, which works with this module.

avpaderno’s picture

Status: Needs review » Needs work

t()-placeholders for URLs are like @url, not !url.
The rest of the patch seems fine.

dwightaspinwall’s picture

Help me understand why I'd want to run check_plain() on the url rather than pass it through to t() unchanged?

dave reid’s picture

Because that's the standard set by core.

dwightaspinwall’s picture

Status: Needs work » Needs review
StatusFileSize
new2.84 KB

Revised patch in #14 to include check_plain()ed URL per #15.

ralf.strobel’s picture

Hi. Maybe I don't understand the problem right, but what speaks against taking the current node from the URL?

At least that would work for the typical case of printing contextual tokens.

  if ( arg(0) == 'node' && is_numeric(arg(1)) && empty(arg(2)) ){
      $node = menu_get_object();
  }
joachim’s picture

StatusFileSize
new967 bytes

Patch at #18 has far too many changes... unrelated changes kill kittens! ;)

This looks to me like all that is needed for this fix. Since the regex now only lets through global or user, we don't need a 'default' case further down AFAICT.

To test this, try entering a bogus token like '[token trousers gromit]'. Without the patch, this gets garbled to just '[gromit]'. With the patch, this remains untouched.

darvanen’s picture

Issue summary: View changes
Status: Needs review » Closed (outdated)

Drupal 6 version is no longer supported. Please reopen this if you find it is relevant to Drupal 7 or 8.