When attempting to display a second level Web Links group, i.e. picked from the breadcrumb, the following notice is thrown:
Notice: Undefined offset: 0 in weblinks_get_tree() (line 1131 of /var/www/html/cm7/sites/all/modules/weblinks/weblinks.module).
The notice is thrown when checking the current term for a parent term:
$new_tree[$tid] = $term;
$new_tree[$tid]->children = array();
if (isset($term->parents)) {
if ($term->parents[0] != 0) {
foreach ($term->parents as $parent) {
if (isset($new_tree[$parent])) {
$new_tree[$parent]->children[] = $tid;
}
}
}
}
Either the if statement 'if ($term->parents[0] != 0)' has to be safeguarded or the logic needs to be changed not assuming offset '0' to be first element of array $new_tree.
Comments
Comment #1
GStegemann commentedI think safeguarding the 'if' statement is the correct fix. Patch uploaded.
Comment #2
GStegemann commentedComment #4
GStegemann commented1: 2197719_1.undefined_offset_0_in_weblinks_get_tree.patch queued for re-testing.
Comment #5
jonathan1055 commentedDo you mean a nested group, ie one taxonomy vocab within another? Or is it a term which has another term as parent?
Comment #6
GStegemann commentedSecond case: a term which has another term as parent. But in Web Links terminology spoken: nested 'groups'.
Assuming you have the following you have selected a nested weblinks the breadcrumb may look like the following:
Web Links» Automatisierungstechnik | FactoryLink | AuthorisierungThen, when you click on the weblinks next to the left from the last one the notice is thrown.
Comment #7
jonathan1055 commentedThanks for the explanation. Interesting, I could not replicate this error. I started with the default empty weblinks group, added a term and a weblink in it. Then added another term as a subgroup, and added a link. Both items in the breadcrumb have the form /weblinks/n where n is the group vid. Neither of the links created the error. I even added a sub-sub-group and that still did not produce the error. Obviously I am doing something different to you. I think we need to know exactly how to replicate, so that we are sure we fix it in the correct way.
Comment #8
GStegemann commentedI can reproduce the error all the time. I have attached two screen shots showing the used Web Links vocabulary and when the PHP notice is thrown.
To reproduce the error the just attempt to view the "middle" group, here url /weblinks/256. Then the if statetment 'if ($term->parents[0] != 0) {' throws the notice because there is no offset '0' in the array $term-parents. In that context the set offset is 256, the term id of the "middle" group. I think that is also the reason why the "first" term in this array is checked to be non zero.
However, the links within this group will be displayed correctly.
Comment #9
jonathan1055 commentedYes, that is what I had, and did not get the error. Obviously there is a problem, as shown by your screenshots, but for the benefit of our understanding, I'd like to know what is going on before we simply remove the e-notice.
My taxonomy looks like

I added the following code to a hook_form_alter to display the term id and parent in the table
Then on viewing a link in the third group, to display the breadcrumbs, I have

On clicking the middle link, there is no error and I get the following debug from weblinks_get_tree()
So what we need to find out is how this differs from what you have.
Comment #10
GStegemann commentedHere are my debug results:
and in uploaded weblinks_terms_drupal_debug.txt.
Comment #11
jonathan1055 commentedThanks. I also had a dd() in weblinks_get_tree around line 1120. Can you add it, then click the middle breadcrumb link (or whatever one produces the error) and upload the .txt
Comment #12
GStegemann commentedHere is the output of dd() in weblinks_get_tree, file weblinks_get_tree_drupal_debug.txt.
Comment #13
jonathan1055 commentedThe differences between your array and mine (ignoring rdf which I deleted) is that you have these extra items
In my output, there is no 'parents' key at all for the term clicked on - we only get that for the child terms later in the process. Are we certain that your 'parents' item is actually a weblinks item? Maybe we have a clash of key names here - has one of your other modules created this item?
Comment #14
jonathan1055 commentedHere's a version of weblinks_get_tree with more debug. This should show us what is happening
Comment #15
GStegemann commentedYes, there is another vocabulary called 'Tags', machine name 'vocabulary_2', which also a term 'FactoryLink' with termid '233'.
OK, I have replaced weblinks_get_tree with your debug version and re-run the tests. See uploaded debug file.
Comment #16
jonathan1055 commentedWe never did resolve this. Attached is a replacement for weblinks_get_tree() for the latest 7.x code, with debug using dd() as before. Can you paste this into your clean 7.x weblinks.module and post back the output?
Looking back to #13 I think that the extra 'parents' property you get is created in taxonomy_term_load() so I have added extra debug at that point.
I think that we could be wrong to use isset to protect the
if ($term->parents[0] != 0)line, it might be correct to get the actual key used, or use array_shift or array_keys to get the first value without assuming they key is 0. But until we know where that spurious value comes from we should not simply make the error go away.If neither you nor I can understand the weblinks code, then we must work at it, because if we don't then no one else will be able to follow it either ;-)
Comment #17
GStegemann commentedHere are my first results. Taxonomy is the same as used in earlier tests.
Sure, that might be a key name clash. But how can I discover that?
Comment #18
jonathan1055 commentedThanks for the debug. I will work through it and compare to mine.
To discover the key name clash, maybe you could search your site's codebase for the keywords
metatags, parents, guidwhich you get from taxonomy_term_load(256) and I do not. See what modules it finds, then disable those and re-run the debug to see if we get a different result.Comment #19
GStegemann commentedI found the interfering module. The key name 'parents' is also used by "Taxonomy import/export via XML", https://www.drupal.org/project/taxonomy_xml.
After disabling the module the error has gone.
But who is wrong now? Web Links or Taxonmy XML? Maybe our error is related to #1835898: RDF import not recreating hierarchy.
Comment #20
jonathan1055 commentedAh Ha! Now we know where the extra 'parents' property comes from, it is in taxonomy_xml's hook_taxonomy_term_load. We can solve the problem properly, but first I had to work out what weblinks_get_tree() is doing:
Weblinks_get_tree() gets the tree from supplied $parent id, via $tree = taxonomy_get_tree(_weblinks_get_vocid(), $parent); This will return an array of term objects below the requested $parent id. Each object has a 'parents' property which is the array '0' => term id. If taxonomy module does not exist then we do not have a tree but a simple unclassified list, plus maybe unpublished too.
Next, if the requested $parent is not the top level '0' we add the actual term for $parent into the top of the $tree, shifting the depth down for all items already recovered. The $parent item is extracted via $parent_term = taxonomy_term_load($parent) and this does NOT normally have a 'parents' key. However, module Taxonomy_xml adds a 'parents' key with values 'term' => term, not '0' => term like the lower levels.
Later in weblinks_get_tree we want to create a 'children' array by taking data from the 'parents' property of each term. Weblinks assumes that if 'parents' exist then the (first) key will be '0'. This is true for all the children terms but for the top-level term there is no 'parents'. All fine.
However, when module taxonomy_xml exists, it's own hook_taxonomy_term_load adds a 'parents' property, keyed with the term id, not '0'. So when we try to build the 'children' array we also process it for the top-level term and the code fails because there is no '0' key.
To solve this we could manipulate the returned array to cater for zero and non-zero keys in the parents property. But a much simpler correction is not to call taxonomy_term_load at all, but call taxonomy_get_tree starting from the parent of the requested term. This avoids the fuss of having to insert the parent term at the top and shift all the depths down by one.
Attached is another weblinks_get_tree with the new code in addition to the old, so you can compare the final $tree and we shall see that the error will not be created. Can you test this as before, with taxonomy_xml enabled, and send back the debug.
Comment #21
jonathan1055 commentedI've done some further testing and we do need to keep the original call to taxonomy_term_load(). Otherwise the requested $parent term is not inserted if that is a real top-level term.
So an option (1) would be to simply unset 'parents' from the obejct returned by taxonomy_term_load() so that any hook invocations of this do not the property which the core function does not add. That might be the easiest to understand for code maintainers later.
Another solution (2) would be to code round the extra 'parents' array we were not expecting, and not make assumptions about the keys just look at the values.
I presume that the final structure of the returned tree should be the same as we had in D6, and the same as in D7 if there are no other hook implementations altering it. This means no 'parents' item for the top term returned. If this is the case then option (1) is the best.
I've downloaded taxonomy_xml so I can replicate the problem you get.
Comment #22
jonathan1055 commentedHere is the final debug version (but only if you really want to try it) and a real patch to test. I have added several comments as the original was a little obscure in what it was doing. The actual code changes are:
if ($term->parents[0] != 0)as this can be checked within the foreach loop.I've tested with multiple terms in the hierarchy, single terms, starting at the top level, starting at the lowest level, with and without taxonomy_xml, and running without the taxonomy module. All seems OK. Patch against alpha1+13.
Comment #23
GStegemann commentedMany thanks for your indepth analysis, detailed descriptions and patch.
Sure, I will try to run your latest debug version, maybe tomorrow or on Monday.
Comment #24
GStegemann commentedI've re-tested this issue against the debug version of weblinks_get_tree from comment #22. My results are attached. So far the patch looks OK.
Comment #25
jonathan1055 commentedThat's great. Can you re-enable your Taxonomy_xml module and just try the middle term weblinks/256 as that was the actual original cause of the problem. If that works then I think we've solved it.
Comment #26
GStegemann commentedSorry. Thanks for reminding me to re-run the test with Taxonomy XML enabled. The debug log is attached.
Yes, I agree. The issue is solved now.
Comment #27
GStegemann commentedComment #28
GStegemann commentedI ran a second test, in just supplying a not existing parent ID, like 300. Then several notices are thrown in several functions:
Note: referenced line numbers based on debug version weblinks_get_tree.
Should this case/code be safeguarded as well?
When you attempt the same with an alphanumeric parent ID/group ID, like www.example.com/weblinks/bumper an applicable error message w/o any notices is displayed: 'Invalid group requested (bumper)'.
Comment #30
jonathan1055 commentedI did not see your final comment before I did the commit. But, anyway what we have changed is still fine.
Yes, it might be nicer to protect those warnings. I guess they could be produced if some hard-coded link in a page referred to a web link group which has since been deleted by the admin. I'll look at that.
Comment #31
GStegemann commentedYes, of course.
Thanks for looking into the 'invalid group' issue.
Comment #32
jonathan1055 commentedIt was nice and simple to fix, with no extra function calls, just checking the result returned from taxonomy_term_load(). I tidied up some of the comments which were repeating themselves.
Patch is on top of the commit above, but the -dev release on the front page has not been refreshed yet. However, on https://www.drupal.org/node/870844 it has been refreshed to alpha1+14
Comment #33
GStegemann commentedTested and works.
BTW: I had to apply the patch. The tar file was not up-to-date yet.
Comment #35
jonathan1055 commentedI took the opportunity in this second commit to also fix all of the coder review warnings within _weblinks_get_tree(). I think it is worth doing things like when it's appropriate and when they do not obscure the actual code fix being discussed. Also if the extra changes are kept within the function already being altered then this is unlikely to increase the number of other patches that might have to be re-rolled.
Just for the record, the stats before were:
Stats after:
Thank you for all your testing! It's great to get this issue fixed.
Comment #36
GStegemann commentedRegarding coder reviews: that's OK.
And thank you for sorting this out.