As a bug-reporting n00b I couldn't find this on here, apologies if I've looked in the wrong place & duplicated! I have created a basic taxonomy tree, just a vocab with with 2 parent terms, and then a 3rd term which I made a shared child of the first 2. When I insert a "Term Reference" field for my vocab into a content type, the select box only shows the child under the first parent, and nothing under the second.
After some poking, it seems that the form gets its allowed values from the function taxonomy_allowed_values which parses a term tree into an array with the key => value pairs of tid => name. This means that it will never hold more than one term with the same tid. To confirm this I modified the code:
foreach ($terms as $term) {
$options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
}
to this:
foreach ($terms as $index => $term) {
$options[$index . $term->tid] = str_repeat('-', $term->depth) . $term->name;
}
Obviously this won't work when the form is submitted, but it demonstrates than when the array items have unique keys then all the terms are displayed correctly. I've not dug deep enough into D7's APIs or into Taxonomy's code to see how easy it would be to implement something to take this into account, but it seems like a huge oversight to me! If there's info / solution somewhere already that I've missed then I'd be really grateful, otherwise I'll try & come up with a patch meself innit.
Comment | File | Size | Author |
---|---|---|---|
#12 | 1061232-12.patch | 972 bytes | jibran |
Comments
Comment #1
Sunlight Studios CreditAttribution: Sunlight Studios commentedComment #2
Sunlight Studios CreditAttribution: Sunlight Studios commentedahem sorry about title changes
Comment #3
sunThe code snippets of the actual error in the logic look like a stupid oversight to me, but I'm not able to understand/confirm the problem description/scenario. Could use some less wordy, more concrete clarification and steps to reproduce.
Comment #4
Sunlight Studios CreditAttribution: Sunlight Studios commentedTo reproduce on 7.x (I've not tried on anything later than 7.8)...
1. Create a vocabulary
2. Add two items, "Parent One" and "Parent Two"
3. Add a third item, "Shared Child" and set this as belonging to the above two parent items.
Now, when you click the "list" tab to view the tree, it rightly displays "Shared Child" as belonging to both parents, a la:
HOWEVER! When you add a "Term Reference" field for this vocabulary to a content type, "Shared Child" will only show up once, under the first parent ONLY, like this:
The form is generated using an array returned by the function taxonomy_allowed_values() function, on line 1452 of taxonomy.module, which looks like this:
It now becomes obvious why it's only showing once, because the $options array is keyed by tid, so any given term can only be listed once, regardless of how many parent terms it should be listed under. Although this does not render the "Term Reference" field unusable (as it's always going to be the same term no matter which one you select) it does result in an inaccurate rendering of the vocabulary's tree.
It may also be worth noting that this behaviour is NOT present on Drupal 6, where the select list correctly shows the shared child term under all of its parents as expected.
Comment #5
emclaughlin CreditAttribution: emclaughlin commentedSince you can't have a term listed twice under the same parent, would the solution be to just add the parent tid to the key?
Comment #7
Sunlight Studios CreditAttribution: Sunlight Studios commentedUnfortunately the array returned by taxonomy_allowed_values is used directly in the form. The tid key is used as the value for the drop-down options, so it needs to be a pure tid when submitting. Changing it to $term->tid . '-' . $term->parent would mean changing the submit handler too - I haven't looked into this so it might be a trivial thing or it might be looooooooooong.
Comment #8
emclaughlin CreditAttribution: emclaughlin commentedDang, okay. The problem with going through and changing the submit handler and all that of everything is, I would think, that you'd then have to find everywhere every function that gets edited is being called and edit those two and so on and so forth until you find an end?
Alternately, the submit handlers aren't necessarily keying by TID, just using the TID so I could investigate that and, if the submit handlers go from array[tid]=>whatever to array[something]=>obj->tid obj->whatever then it would be simple enough to split on the hyphen and make everything work that way.
Really, I'm just talking out loud to myself at this point. So back to taking another stab at this one!
ETA: No. The answer is no to that entire second paragraph. No. Also no to this entire way of solving the issue.
Comment #9
jibranThe bug described in #4 is still the same but now ER is responsible for this code.
Comment #10
amateescu CreditAttribution: amateescu commentedDrupal\taxonomy\Plugin\EntityReferenceSelection\TermSelection
is provided by the Taxonomy module, moving back to the right queue.Comment #11
jibranComment #12
jibranInstead of using composite key why not do this?
Comment #14
Sunlight Studios CreditAttribution: Sunlight Studios commentedThe issue with changing the array structure is that the form relies on it for its output. Also any change to what the form submits means changing the submit handler. A composite key would mean not having to change the way the form outputs its markup, but still requires the submit handler to be changed. I have no idea what sort of knock-on effect this would have, so I've not attempted a fix (plus I originally filed this for D7 & haven't done any development on D8 so things might be different again).
Comment #27
LendudeThis came up as a daily triage target of the Bug Smash Initiative.
Looking at the code
\Drupal\taxonomy\Plugin\EntityReferenceSelection\TermSelection::getReferenceableEntities
it uses loadTree to get all the terms. The data returned doesn't actually contain the data for the parent when dealing with multiple parents, it always returns the last parent id as far as I could tell. So getting this to work might require work deeper down in core.What I'm wondering though is, does it matter that you can't select these in all their possible parents? We aren't storing the parent information, just a term ID, so when loading/editing again, this information is lost anyway right? which would just raise more questions I think.