This is steps of how to reveal this issue:
1,Install latest drupal,
2,Install token module
3,Install compound_token module
4,Create a test node which node type is "Article".
5,Change the code in compound_token.module from:
if (!module_exists('token')) {
to:
if (true) {
6,Run test code:
/**
* Implements hook_menu().
*/
function test_menu(){
$items['test'] = array(
'title' => 'Test',
'page callback' => 'test_test_page',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function test_test_page(){
$output = "";
$output .= '123456:';
$node = node_load(1);
$output .= token_replace('[node:nid|user:mail][node:nid][node:title]', array('node' => $node));
return $output;
}
7,Then we will get error message:
Notice: Array to string conversion in token_replace() (line 102 of D:\xampp\htdocs\drupaldev\includes\token.inc).
8,And the result output is:
123456:[node:nid|user:mail]ArrayArray
After a lot debug, i find that hook_tokens_alter() was called before hook_tokens, it is very strange. Maybe compound_token module is the first module that use hook_tokens_alter. The hook_tokens_alter has been called twice,one is before hook_tokens, one is after it.
I have examined my code, and do not find any logic error. My purpose of compound_token module is, after run hook_tokens, If there are still some tokens that not be replaced, If these token following the rule provide by compound_token, then this module replace these tokens.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | hook-tokens-alter-run-before-hook-tokens-1541642.patch | 1.23 KB | g089h515r806 |
Comments
Comment #1
g089h515r806 commentedAfter I move the code:
from function token_generate to function token_replace,Then the code of token_replace is:
After this i get the correct result.
Comment #2
g089h515r806 commentedHere is my code, this is the first patch that i build for drupal core.
Comment #3
dave reidSince this problem only happens with your compound_tokens module installed, I'm inclined to say it's a problem caused by the code in compound_tokens. I strongly believe the problem is that you're calling token_replace() from inside your hook_tokens_alter() function, which then is going to cause another invocation of hook_tokens_alter(). You need to ensure that your token_replace() call will not be recursive.
Comment #4
g089h515r806 commentedThe issue still exist even i remove the code of compound token part:
Comment #5
g089h515r806 commentedDave Reid, Thanks for you review my code.
There is no token_replace in hook_tokens-alter now. Issue still exist, actuall speaking, I have put a lot of print debug in my code yesterday.And find it run twice,one before hook_tokens, one after hook_tokens. I put a print debug after "$replacements += token_generate($type, $tokens, $data, $options);", and found it only run one time. That is why i think this is a bug of drupal core instead of a bug of compoumd_token or token module.
For short code that you read:
Comment #6
g089h515r806 commentedWhen i found compound_token module conflict with token module, usually I need to ask myself if there is a bug in my code first, then if there is a bug in token module, after that maybe i could suspect if there is a bug in drupal core.
I put a lot of print debug code in my code and in token.inc, i put print debug code in drupal core this is because i want to research the token system of drupal core.
When i found this issue, I read the debug message, I found that it is caused by Drupal core.
This is my first patch to drupal core, before i submit this patch, I have test a lot method, such as use
to prevent this issue.
Use :
To let my code run at the last place.
After a lot of these effort, I think this is a bug in drupal core. I am not sure, because maybe i make a mistake in other place.
Comment #6.0
g089h515r806 commentedtypo error fixed
Comment #7
Revathi Manohar commentedHi,
i tested that issue in drupal 7 and i got same isuue after the patch is applied i got answer. i tested to print other token also working fine.output is like 123456:[node:nid|user:mail]8sprint token 8 is my nid,sprint token is node title
Thank you
Comment #8
robindh commented#2 works like a charm!
I was trying to alter the node summary token, but could not get it to work. After a lot of debugging, I finally came to the conclusion that the alter hook went off after hook_tokens. Then I found this issue!
Marking as RTBC, since patch applies cleanly and fixes the issue.
Comment #9
poker10 commentedThanks for the detailed report and patch.
I have gone through steps to reproduce and was not able to simulate it without using compound_token module. I have used vanilla D7.91 with token module installed.
1. Created a new node
2. Run the test code (see issue summary)
The output was:
And no warning message was present. This leads me to the fact that the root cause of this problem should be the compound_token module. If that is the case, it needs to be fixed there.
This is correct -
token_generate()is run separately for each token type. And because the string you have presented ([node:nid|user:mail][node:nid][node:title]) contains only NODE type tokens (see how it is scanned bytoken_scan()), this is correct behavior. If you would use another user token separately (so that thetoken_scan()will discover that USER type token) then the function will run two times. Maybe in this case you will get the correct results without the warning.Something like this:
But I have not experimented with the compound_token module now, because the module seems a bit outdated.
Comment #10
g089h515r806 commentedMy expectation:
1,run hook_tokens first
2,then run hook_tokens_alter
When I write compound_token module, I find the actual is:
1, compound_token_tokens_alter run first (even i remove the code "token_replace() in compound_token_tokens_alter").
2, then run token_tokens
I fix it in a dirty way at last, compound_token is compatible with drupal core and token module.
Steps to reproduce the issue:
Maybe you can write a custom module, that is used to change some token provide by token module, you implement:
mycustom_tokens_alter(){
...
//your logic code run before token_tokens, your code is useless, it is very strange.
}
hook_tokens_alter is not a commonly used hook, after several years later people use it again and find the same issue.