We're seeing this PHP Notice "Notice: Trying to get property 'language' of non-object in scheduler_tokens()" on our sites. When you look at
line 34 of modules/contrib/scheduler/scheduler.tokens.inc which is this line of code $language_code = isset($options['language']) ? $options['language']->language : NULL; and $options['language']->language is treating an array a an object which is causing the error.
It seems the fix is simply to change $options['language']->language to $options['language'].
Notice: Trying to get property 'language' of non-object in scheduler_tokens() (line 34 of modules/contrib/scheduler/scheduler.tokens.inc).
scheduler_tokens('site', Array, Array, Array, Object)
call_user_func_array('scheduler_tokens', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('tokens', Array) (Line: 304)
Comments
Comment #2
kamkejj commentedPatch for this change.
Comment #3
kamkejj commentedComment #4
kamkejj commentedComment #5
jasonawant@kamkejj,
I wonder why scheduler_tokens() assumes $options['language'] is an object. Did you see any instances where it was an object and can you share the stack traces or origins?
I wonder if this change breaks other usages.
From hook_tokens documentation ,
And \Drupal\Core\Utility\Token::replace(),
$options['langcode']is intended to be just that, a langcode...not an language object.I imagine something is calling Token::replace() with a language object instead of the langcode. In which case, what breaks with this change? And, do we need to report an issue some where else to correct this usage.
Comment #6
kamkejj commentedHey @jasonwant
The short answer.
When I step debugged I only saw "$options['language']" as an array and not an object which is why I proposed this change. As it iterrerated over "function scheduler_tokens" sometimes "$options" was empty and sometimes it was an array with language as a key and without the language key.
Comment #7
jonathan1055 commentedHi kamkejj and jasonawant,
Thanks for finding and reporting this problem. I looked back using
git blameand that line has not been changed since January 2011!At that time Scheduler 6.x-1.8 was the current release and Scheduler 7.x-1.0 was being finalised. The issue which added scheduler.tokens.inc was #960030: Scheduler token support
I don't know. But according to your helpful research is should always be a string. However, you say that it is
$options['langcode']which has the language code, so we should use that, and not$options['language']?Comment #8
drupal.ninja03 commentedI am on Drupal 8.8.6, PHP 7.2. I am not able to reproduce the error. Can you provide the steps?
Comment #9
jonathan1055 commentedYes, thanks @drupal.ninja03 that is exactly what I was going to ask for. I need to be able to reproduce the problem to prove that the patch fixes it. I am also confused as to the documentaion on \Drupal\Core\Utility\Token::replace() which states that the key is 'langcode' and no mention of key 'language'. So why would the
$options['language']->languageeven be attempted to get evaluated?Comment #10
jonathan1055 commentedBy the way, I will be release Scheduler 8.x-1.3 in a few days, due to needing to fix #3145169: User messages are not displayed after updating to 8.x-1.2 so if we can get a solution here it can be included in the next release.
Comment #11
kamkejj commentedHi @drupal.ninja03 and @jonathan1055
Did some more research and step debugging of our custom code. I think there's still an issue with
$language_code = isset($options['language']) ? $options['language']->language : NULL;in scheduler.tokens.inc, just a slightly different one that's actually the Drupal 7 version. As @drupal.ninja03 pointed out this is code from 2011.I just found custom code that's setting the language key in the array
where the "language" key is the Drupal 7 version of the possible values for $options in hook_tokens(). See https://api.drupal.org/api/drupal/includes%21token.inc/function/token_re...
For Drupal 8 this was changed to "langcode" as we see in an example of the $options array value when debugging the code.
I think
$language_code = isset($options['language']) ? $options['langcode']->language : NULL;should be changed to$language_code = isset($options['langcode']) ? $options['langcode']: NULL;in order to get the language code?As Jason pointed out above in comment #5 that valid values for $options, Drupal 8, are langcode, clear, callback as we can see in the docs at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Utility%2...
If you agree I can either open a new issue with a new patch or post a new patch in this issue. Thoughts?
Thanks
BTW, We are on Drupal 8.8.5.
Comment #12
kamkejj commentedMade a patch anyway that updates
$language_code = isset($options['language']) ? $options['language']->language : NULL;which seems to be the Drupal 7 version to the Drupal 8 version of the possible values for $options.
Drupal 7 docs https://api.drupal.org/api/drupal/includes%21token.inc/function/token_re...
Drupal 8 docs https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Utility%2...
Refer to comment #11 for details. Also hid the previous patch.
Comment #13
jonathan1055 commentedA-ha, that explains my question in #9 "So why would the $options['language']->language even be attempted to get evaluated?" it was your custom code setting the 'language' key when it should now be setting the 'langcode' key.
Your patch #12 is exactly what I was expecting the change to be. But can you give me the steps to reproduce the original error. I have enabled language and language translation, enabled token and token_filter, created content with translations, but still in scheduler_tokens() for $options I only get an empty array, or with key 'clear' but no other keys.
Comment #14
jasonawantHi jonathan1055,
I found custom project code that set the
$options['language']. Once that was removed; I did not find another usage.Regarding the following, I couldn't tell you why. I suspect this was missed during Drupal 8 port as the Drupal 7 usage did specify the language key and language object. See Drupal 7 token_replace docs.
I can not find usage of the following as examples of array key assignment within scheduler itself.
'language' =>$options['language'] =I think the right path forward is to replace the current logic with
Comment #15
jonathan1055 commentedThanks @jasonawant. Yes we all agree on the chnage required. That is what patch #12 had, so was there a reason why you hid that patch and set the status to 'needs work'? If that was an error, just set it to RTBC and I will commit this.
Comment #16
jasonawantWhoops, sorry! My apologies to everyone; I was looking at a stale page!
Comment #18
jonathan1055 commentedThanks @kamkejj and @jasonawant. This will be in Scheduler 8.x-1.3 which I'm going to release tomorrow.
Comment #19
kamkejj commentedThanks @jonathan1055
Just to follow up on steps to reproduce. With at least one other language enabled and a content type set to be translatable. Create a new node or edit an existing translatable node and look at the value of $options['language'].
In our project I always see the langocde key set to "en".
Comment #20
jonathan1055 commented@kamkejj, yes I have done all that, as explained in #13. Your site must have other modules which are using/providing tokens. It is those other modules that we need to look at. Or if it is only your custom module, and not a contrib module that I can download, then I can't really test this. But we agree now what the right change is, and I have committed it.