This is a simple module that can automatically select parent terms in a taxonomy.
For instance, imagine a "Geography" taxonomy having all continents, countries
and cities in a tree structure. Users are then asked to tag a piece of content
with this taxonomy. Suppose a user tags a piece of content with "Berlin".
Using the normal drupal taxonomy system, this would be the only term applied
in our tree. The content would not be able to be found under "Germany" or
"Europe". What this little module does is simply make sure that these parent
terms are also selected at the time a piece of content is saved.
By selecting the "Geography" taxonomy in the module administration screens,
a user can ensure that these parent terms are selected and hierarchical
taxonomies become more powerful.
How it works:
If any vocabularies have lineage set, we check entities when they are
saved to see if they have fields referring to these vocabularies. If so,
we automatically select all parent terms of manually selected terms.
Note that this does not override the maximum number of terms selectable in a
field. If for a given field, content creators are only allowed to select one term,
this module will not be able to set any parent terms in that field.
This module should work with any drupal language / i18n / localization strategy.
This module will only set parents on the terms in the language that was
just changed / edited. That means in a multilingual field with terms selectable
independently for each language, if you change which French taxonomy terms are
selected, only the French terms will be processed to select parents, not the
English terms on the same field. This follows the principle of least surprise.
Configuration can be found at admin/structure/taxonomy/taxonomy_set_lineage or
on the Taxonomy set Lineage tab visible from the taxonomy administration screen.
This module has nothing to do with the Taxonomy Lineage module which allows sorting nodes according to the taxonomy terms on them http://drupal.org/project/lineage
This module differs from the Hierarchical Select and the Taxonomy Term Reference Tree Widget modules in that it does not use a client side javascript widget to show and manipulate hierarchy, but simply automatically populates parent terms. Unlike these modules It does not use the form system at all, and so should work with programatically saved entities.
Project sandbox page:
http://drupal.org/sandbox/yareckon/1744220
Git repo:
git clone --recursive --branch 7.x-1.x http://git.drupal.org/sandbox/yareckon/1744220.git
This project is for D7.
Comments
Comment #1
monymirzaSome conding standards missing here
http://ventral.org/pareview/httpgitdrupalorgsandboxyareckon1744220git
Comment #2
yareckon commentedThanks for the review! I'll add an @file docblock to the .install file.
Can you explain the "missing type" comments? Most core modules do not use them, at least in 7.x.
Comment #3
yareckon commentedI'll upload a version with the types put in there, but would be happy about some feedback about whether they are actually recommended for D7 stuff.
Comment #4
klausiWe are currently quite busy with all the project applications and I can only review projects with a review bonus. Please help me reviewing and I'll take a look at your project right away :-)
Comment #5
Aleksey Zubko commentedHello.
Little, nice and handy module.
Module works stable and I ain't got much troubles with it.
My suggestion is to move hook_menu's page argument implementation (taxonomy_set_lineage_config_form()) to a separate file. So it'll be loaded only on configuration page.
Comment #6
yareckon commentedThanks for the suggestion Drucode, I've implemented that.
Comment #6.0
yareckon commentedadded my first peer review
Comment #6.1
yareckon commentedadding additional review performed.
Comment #7
yareckon commentedAdding review bonus tag based on my manual reviews of other modules. Would love an in depth manual review from someone, or any simple usage review that results in 'reviewed and tested' status. :D Thanks folks!
Comment #8
yareckon commentedsorry, finger got itchy.... someone else should set that status :)
Comment #9
jurcello commentedFunctionality review:
When I go to the settings the first time, I get a the following warning:
Warning: Invalid argument supplied for foreach() in form_type_checkboxes_value() (line 2288 of */includes/form.inc).
This is caused by the default value of 0 on line 22 of the admin file. Change this to array() and the warning is gone:
http://drupalcode.org/sandbox/yareckon/1744220.git/blob/68bde42:/taxonom...
Taxonomy field single value: when I change the taxonomy field of the content type to single values, obviously your module doesn't work. Maybe you can add a warning that the term reference fields should be mutlivalued.
Apart from these findings, the module worked correct.
Code review:
http://drupalcode.org/sandbox/yareckon/1744220.git/blob/68bde42:/taxonom...
You define language_changed, but you don't use it. Either use it, or remove this line.
For the rest it looks ok. Nice little module!
Comment #10
yareckon commentedMany thanks for the careful look through the code! It really helps.
I've set the default value of that variable to an array and removed the unused $language_changed, which was from an earlier strategy to identify changed fields. A new version of the module with you credited is up.
About the warning that single value fields don't benefit from this module: text to that effect is in the Readme and on the module home page. One further possibility would be to warn the user on the field instance configuration page, but this might be overkill with it documented so many other places. What do you think?
Comment #11
jurcello commentedI didn't read the Readme careful enough I think. I agree that a warning on the field instance configuration page is overkill.
Comment #12
tsphethean commentedCouple of comments:
1. The taxonomy_set_lineage_affected_taxonomies variable defaults to NULL in taxonomy_set_lineage_entity_presave() and to array() in taxonomy_set_lineage_config_form(). Ideally this would be consistent in both places.
2. In taxonomy_set_lineage_entity_presave line 39 checks
but $wanted_vocabs may not be an array so should probably check !empty($wanted_vocabs) instead or is_array() of isset.
3. In _taxonomy_set_lineage_vocab_to_instance_field_name(), list is used on the result of entity_extract_ids(), but $id and $vid are never used. Could do:
4. In _taxonomy_set_lineage_activate_parents() you have:
$tidsnew[] .= isset($term['tid']) ? $term['tid'] : NULL;- i don't think you need .= should just be = (should save a few php notices). Same goes for $tidsold a little further down.Other than those minor things, looks a nice little module and can definitely see the use cases.
Nothing that should stop approval, but have you thought about what happens when a parent taxonomy term is removed from the entity - should that remove the child terms too? Might be a nice addition.
Hope this helps.
Comment #12.0
tsphethean commentedadded third review
Comment #13
tsphethean commentedDeleted - duplicate post.
Comment #14
tsphethean commentedDeleted - duplicate post.
Comment #15
yareckon commentedtsphethean, thanks for your detailed look through!
1. & 2) yes, these should be consistent, I didn't catch this when making changes suggested by earlier reviewers! Thank You.
3) gonna have to disagree with you here. A comment on the docs suggests doing it the way I did. Also $entity_ids['bundle'] doesn't exist because it returns an indexed array 0,1,2. I find the way I did it clearer.
http://api.drupal.org/api/drupal/includes!common.inc/function/entity_ext...
4) Yes, wow, thanks. That's *Obviously* a total whiff .= vis = I feel silly. I think I was originally building a string there in an earlier strategy.
5) Interesting... this is generally not a problem, because one is submitting a selected "total state" each time, and I can just work with / decorate what is there. Taxonomy terms are always in fields now, and that means whether programatically or through a form, you have to hand me a complete snapshot of what terms are attached to the entity on save. Then I work with that to select parents. I'd rather stick with that to keep things simple, but maybe I'm not wrapping my head around the complexities.
The reason I check what has changed is NOT to do any cleverness around which terms should be selected automatically vs by hand, it's simply to only change the terms in the language that was just edited. So if you have French and English terms on a node even in the same taxonomy, if you change the French terms, the English ones will stay the same. Which... lead me to now explicitly state this in the readme.
6) bonus... your review lead me to look at the logic for determining what had changed again, and I found a two logic errors. One that could have lead to a term being added twice if it was the parent of more than one term, and one that could have failed to select terms because of how array_diff is order sensitive.
A new version is up that should fix these issues.
Comment #16
tsphethean commentedhi yareckon, no problem - glad it was helpful.
I've looked at the updates you've done and they look good. pareview is reporting all good too from a code standard POV (http://ventral.org/pareview/httpgitdrupalorgsandboxyareckon1744220git)
On the entity_extract_ids issue, that was my mistake on the returned array keys, and its minor style preference in the list vs array key so not something that should stop project approval.
Looks a good module to me, I'm going to mark as RTBC.
Comment #17
klausimanual review:
but that are not major issues, so ...
Thanks for your contribution, yareckon!
I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.
Here are some recommended readings to help with excellent maintainership:
You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!
Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
Thanks to the dedicated reviewer(s) as well.
Comment #18
yareckon commentedWow, thanks for the green light klausi, you made my week! The whole review process has been fairly helpful at improving the module as well. Thanks to everyone that has taken the time to do a manual review.
$tidsnew is used in later iterations of the loop to keep tids from being added more than once. See the !in_array() condition the line before.
Thanks for the other two comments!
W00t!
Comment #19.0
(not verified) commentedUpdated to note translation strategy.
Comment #20
marcoka commentedthere is still no project created yet. or am i blind? i looked at his user profile.
Comment #21
yareckon commentedmarkoka, thanks for the prod. I had never hit the promote button after getting the module into shape. It's "published" now.
Comment #22
marcoka commentedthank you man
https://drupal.org/project/taxonomy_set_lineage