This feature request is a continuation of #315959: content_taxonomy module should "own" its taxonomies, leave taxonomy module vocabularies alone.. I'm aiming for the same outcome here, but I hope I'm using more reasonable methods to accomplish it.
Content_taxonomy fields have a hard time living with taxonomy vocabularies when it comes to node edit forms. The current behavior is to unset the form elements for all taxonomy vocabularies when any field has the 'hide_taxonomy_fields' property set TRUE. This has the undesirable side effect of unsetting terms in vocabularies that have nothing to do with content_taxonomy fields. For new users of content_taxonomy who are trying to learn about the module, this causes data loss when they edit existing nodes that have existing term selections but are of a content type which has content_taxonomy fields. To accommodate content_taxonomy's all-or-nothing methods of avoiding conflicts and collisions, we must create a content_taxonomy field for each vocabulary we want to use on a content type.
I find the module's primary purpose to be:
- To define the nature (or 'type') of a term's relationship to a node. Taxonomy module requires us to imply the nature of these relationships basically at the theme layer.
- To allow a node to have multiple typed relationships with the same node. Taxonomy module supports one type of generic relationship between terms and nodes.
The module also provides other benefits:
- Terms are stored in CCK tables, so CCK can come to bear when the field is used in views. Sorting and grouping are a bit more robust.
- Widgets. Rather than simple select and autocomplete text fields, we can use different configurable widgets than what taxonomy module provides
- Scope. A hierarchical vocabulary can be sliced and diced into separate fields by limiting a field's scope to a particular parent term so that field options come from only that term's children rather than the whole vocabulary.
- This list is not meant to be exhaustive! But there are cool things to do with CCK field permissions and stretching a vocabulary's domain of content types so we can include the a vocabulary on node types not allowed by the core taxonomy.module vocabulary settings.
This patch allows content_taxonomy module to be more delicate and precise in its avoidance of conflicts and collisions when a node is saved. Let me review the major changes.
hide_taxonomy_fields
This property is removed from field options. If content_taxonomy isn't going to unset all taxonomy fields, we will want to allow a node form to have taxonomy.module vocabularies and fields based on a subset of those vocabularies. If you have vocabularies showing up that you don't want on your node form, use taxonomy module's vocabulary edit form to disable that vocabulary for the node type.
_content_taxonomy_array_cleared
The $_content_taxonomy_array_cleared in the presave op of content_taxonomy_field needs to track individual vocabularies that have been cleared rather than just the node whose entire taxonomy term selections have been unset. The variable previously was global when I think it should have been static. This variable needs to be kept because multiple content_taxonomy fields might want to also store values in the term_node table, but the fields are saved sequentially. We don't want a second field instance of a vocabulary to unset the terms saved by the first field instance's presave operation.
$node->taxonomy can also contain term objects not just arrays indexed by vocabulary ID
The CCK field 'presave' operation is called whenever a CCK field is saved. CCK fields can be saved without ever being passed through a node form. Actions in cronjobs for example. Nothing bad happens when you ignore the possibility that terms might be objects, but the database key constraints are violated when taxonomy_node_save tries to insert the same row twice.
content_taxonomy_form_alter
Previously, this function would unset all taxonomy form elements on node forms with content_taxonomy fields. Now this function simply accumulates a list of vocabulary IDs that are used in fields so these form elements can be unset.
_content_taxonomy_taxonomy_unset
This new function takes either the values of $form['taxonomy'] or $node->taxonomy and an array of vocabulary IDs. If the node or form contains any terms from these vocabularies, they are unset because those values are either (a) being presented on the node form in a content_taxonomy field or (b) might be saved into the term_node table when the field is saved. When tags are encountered, the function calls itself again so that tag vocabularies are safely unset when they are used as fields.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | content-taxonomy-careful-unset.patch | 4.64 KB | Anonymous (not verified) |
| content-taxonomy-careful-unset.patch | 4.49 KB | Anonymous (not verified) |
Comments
Comment #1
fractile81 commentedIt's worth mentioning that this is a feature that some of us are looking for. Looking over the patch, I like the approach and believe it would work. I would test it, but can't right now unfortunately.
Are there any other eyes that might want to look into this?
Comment #2
Anonymous (not verified) commentedfactile81, the patch needs to be updated because i did find some problems with it. i'll post an updated patch in a few days. though i'm glad to hear you're interested in this patch.
Comment #3
mh86 commentedHi!
I like the idea of this patch and it does make sense how the unsetting of the taxonomy fields is handled.
As you are saying, there are still some problems. The test cases fail with this patch applied and I'm getting "invalid argument supplied for foreach() on line 422" warnings because of an empty array.
The test scenario, which fails does following: creating a node with content taxonomy fields (with save in term_node) and selecting some terms (works), then updating the node and unselecting all terms. But after the updating, the terms are still in the node->taxonomy array.
The interaction of content taxonomy and the taxonomy module is quite tricky, that's the reason why I allows preferred a simple solution (just hiding the taxonomy fields), but I hope we get this patch working!
Comment #4
Anonymous (not verified) commentedHere's a new patch. I've been running with this feature for about 2 months now on a site in development. The problems described by mh86 are fixed, as well as some others.
When I run the tests, I see 97 failures. However, I see the same failures without my patch, so I think there's something I'm not understanding about how to run tests.
Comment #5
bcn commentedThe patch from #4 applies cleanly to the beta5 (and 6.x-1.x-dev branch). I didn't have a chance to run the test though...
Comment #6
mh86 commentedpatch committed :)
I was making a small change, because there was still a problem with the patch. When I was editing a node and unselecting all terms, the terms where still in the term_node table. The reason was, that in this case the $node->taxonomy array was empty and taxonomy_nodeapi only calls taxonomy_node_save for non-empty $node->taxonomy arrays. taxonomy_node_save is responsible for deleting all previous added terms and inserting new ones.
Now, all test cases pass and I was testing this a bit manually and it's working fine for me.
And thanks to bangpound for the patch!
Comment #7
mh86 commentedfor people interested in the committed code, here a link to the diff: http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/content_tax...
Comment #8
Anonymous (not verified) commentedWhew! That's really great mh86. Thanks for helping me get this working!
Comment #10
vito_a commentedConcerning the fields hiding, I've just posted a small snippet, however it's not a patch, it is to be at other custom module, http://vito.ho.ua/en/content/content-taxonomy-show-default-taxonomy-fiel...