Taxonomy index: when joining nodes check if node revisions needs to be considered?
This was a question asked on an earlier issue regarding porting to D7. It needs a discussion here to resolve it.
In Drupal7 the taxonomy_index table links terms (tid) to nodes (nid). In Drupal6 the equivalent table was term_node and this contained the node id (nid), version id (vid) and term id (tid).
It appears that because the revision id is not in taxonomy_index then this data must refer to the latest node revision only, and is maintained to match the the nodes current terms. Now that taxonomies are added as fields the field_revision_* tables store the history of term changes if they were needed.
The taxonomy_index table is used three times in weblinks.module: weblinks_term_node_count(), weblinks_node_load() and _weblinks_get_query(), each time linking to the node table. It is also used once in weblinks.user.inc weblinks_user_form(), where it only links to taxonomy_term_data.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | 2417699_22.taxonomy_index_table.patch | 6.21 KB | jonathan1055 |
Comments
Comment #1
gstegemann commentedI would say yes. In D7 there is no way to map a revision of a node to a term.
One more thing needs to be considered: unpublished nodes are not kept in the taxonomy_index table. Therefore when Web Links Checker unpublishes a node it has to be removed from this table as well, and vice versa.
And third: the taxonomy_index table can be disabled on a site through variable 'taxonomy_maintain_index_table'. In other words when the variable 'taxonomy_maintain_index_table' exists and is set to FALSE we cannot rely on this table to retrieve node to term information.
Comment #2
jonathan1055 commentedThanks for this background info.
Hopefully we do not have to do this manually - if we use node_save() for the updating as discussed in #2415693: Weblinks Checker should update node_revision table then Taxonomy module should take care of this. We can check this after implementing node_save()
If if the variable is set to FALSE are you saying we should not use the table? I guess, then, that this requires each of the four uses of the table to be examined to see what alternatives there are for this scenario. I thought this issue was going to be simple and quick to close ...
Comment #3
jonathan1055 commentedThe variable 'taxonomy_maintain_index_table' is only used in taxonomy.module and field.api.php. Reading the comments in the header for taxonomy_field_presave() the variable defaults to TRUE and there is no admin config for this, it can only be set to FALSE by a custom module or maybe some contrib modules which would be fairly niche and specific. If this is the case then the site builder would know what they are doing, and they have a site which is not common. With this in mind, looking at our usages of the table:
Hence for Weblinks 7.x-1.0 we need to return sensible results when the taxonomy_index table is not being maintained, but we can leave the implementation of alternative methods of term retrieval until after our 1.0 release, and then only when requested by our users - there may be not a single site which is both using Weblinks and has taxonomy_index table disabled.
Comment #4
gstegemann commentedYes. See also #962664: Taxonomy Index for unpublished entities.
I agree with your implementation proposals.
Sure. Unless someone is running a site with a specific field storage engine.
Comment #5
jonathan1055 commentedAs expected, now that we are using node_save() when Weblinks Checker unpublishes a bad link the taxonomy_index table is automatically maintained (ie the rows are removed). When the url is good again and Checker republishes the node, the rows are added back into the taxonomy_index table. So that's good.
The four places where changes are required to check if we can use the the taxonomy_index table are:
Then this got me thinking ... If we can use table field_data_taxonomy_weblinks when taxonomy_index is not to be trusted, why can't we use it all the time? This would save the added complexity of checking, and avoid duplicating some code.
I have addresses each of the issues above, and made four separate patches - named accordingly. This is so you can test each change separately if you wish, or you can apply all four together as they do not clash. Once you've had time to look at the code, try it and have some thoughts then I will make a proper clean patch to test.
Jonathan
Comment #6
gstegemann commentedSee my answers below:
Very simple. I didn't know better at the time when I started to port Web Links to D7. And in the early stages of the work the taxonomy field did not exist.
The property $node->taxonomy is used in the D6 version to assign a term to a Web Links node. There was no other way to accomplish this. In an earlier issue we discussed already to remove the property $node->taxonomy at a later time since it is basically obsolete now. To be consistent taxonomy information should be now taken from ->taxonomy_weblinks or table field_data_taxonomy_weblinks as you already proposed.
I will review and test your patches.
Comment #7
jonathan1055 commentedThanks for the background. I hope you realise that when I make these questions there is no implied criticism or anything like that. I just ask the questions, and you always have good answers. :-)
Comment #8
gstegemann commentedYes. Your questions are OK.
Comment #9
jonathan1055 commentedI had a search but could not find the issue you mention, but anyway from what you say, that is good we can drop ->taxonomy. It will also be useful to make it consistent by using field_data_taxonomy_weblinks in all cases.
Would you like me to make a single clean patch based on this? The single debug patches are still useful if you want to see what I did and how the code developed.
Comment #10
gstegemann commentedYes. Thanks.
Comment #11
jonathan1055 commentedHere is a clean patch for 1, 3 and 4.
For item 2 I have created a separate issue #2449127: Remove $node->taxonomy and replace all usages with $node->taxonomy_weblinks
Comment #12
gstegemann commentedMany thanks. Good idea to create a separate issue for item 2.
My first comments:
Is that a good idea to change the status text strings? How about already existing translations?
The field $node->moderate may exists when a moderation contributed module is installed and enabled like Modr8.
Generally: shouldn't there be checks whether the field/table field_data_taxonomy_weblinks really exists? I.e. when no Web Links vocabulary is used?
Comment #13
jonathan1055 commentedThanks for the review
a. Yes, maybe you are right. Those strings are ok to remain without a capital letter.
b. So you are saying that just using
$query = db_select('node', 'n');other contrib module can add extra fields to the node table? I'll take a look at Modr8 as that sounds interesting.c. Yes you are are right we do need to check. In particular when a minimal installation is used without Taxonomy module. I had that on my list to check but forgot to mention it. There may even be some php5 warnings to fix.
Comment #14
jonathan1055 commentedModr8 actually changes the core node table by adding a 'moderate' field. I didn't know that was allowed, or at least I thought it was against good practice. I don't see why we should give extra importance to this particular contrib module and display the ->moderate field when there could be any number of fields added to the node table which "might be useful". I propose we drop it, but I'm ready to be persuaded if you have a strong view on this.
With Taxonomy module not enabled the changes to weblinks.module and weblinks.user.inc are all OK, as they will only be called when we are doing group work, which in turn means that the Taxonomy and Field modules must be available. Before installing Web Links I could not find a way to disable the 'field' core module. Is it possible? It says that it is required by 'Drupal' and there also seems to be a reciprocal requirement between 'Field' and 'Field SQL storage' which means that neither can be disabled. Is this due to some deep config setting?
Here is a patch with these things tidied up.
Comment #15
gstegemann commentedRegarding the ->moderate field: I think we should keep the code for the ->moderate field. It is there since I can remember. And node moderation is something which might be used on some sites, e.g. Web Links nodes added by regular website users which will be reviewed by the sites administrator before become published to the public.
Regarding module checks: no, the 'field' core module cannot be disabled. It is definitely required by Drupal. So every thing seems to be taken care of.
Comment #16
gstegemann commentedI have tested the patch. It works for me.
But some comments needs to be corrected:
The table name 'taxonomy_index' should changed to 'field_data_taxonomy_weblinks'.
Have you thought about the ->moderate field?
Comment #17
jonathan1055 commentedOK we'll continue to add the 'moderate' field, although the Modr8 module does not have a full 7.x version yet. They have 500 installs of 7.x-dev and 1,700 at 6.x I think there are more widely used moderation modules such as Workbench Moderation which has 19,000 installs at 7.x. What would be really nice is if we could implement a hook or alter function allowing other modules to add their own entries to this table. Then Modr8 could add text and/or links, or any custom module could include extras. We could also add links on behalf of other modules if they are installed.
One question on coding style and your preference:
query->fields('n', array('nid', ...))fails if it specifies a field which does not exist. So to include the optional 'moderate' field we either load all fields from the node table (which is against best practice as we only need six out of the fourteen fields, therefore doing more db work that necessary), or we do a conditionalif module_exists('modr8')which adds complexity and an extra bit of processing. I think in this situation the difference in page serve time is going to be negligible, but I'd like to hear your view on this.Comment #18
gstegemann commentedRegarding the ->moderate field: I just picked Modr8 as an example. There might be other moderation modules using the method to add fields. Yes, a hook or alter function would be a better approach to support extras for other modules.
Your question: I think it is acceptable to query all fields here. A conditional would be difficult to maintain as we do not know which modules provide which extra fields now and in the future.
Comment #19
nancydruThe "moderate" flag was standard in the node table before 7.x. Given that Core has removed it, I would not support it at all, unless you want to stick in some kind of hook or query tag to allow other modules to do whatever they need done. I don't recall why WL needs to pay any attention to it.
If you want to do a "query all fields", then it would be faster to do a
db_queryrather thandb_select.Comment #20
jonathan1055 commentedThanks for the background Nancy. I'd like to drop it too, now that it is not in Core. It was only a text value after all, not an active link for the user to click. We could look at making the table properly customisable at a later date, after out 7.x release.
Thanks for the tip about db_query in preference to db_select, that's a useful reminder (I think I had read it, but forgotten)
Comment #21
gstegemann commentedJust to remind to some history of Web Links moderation please see #2089139: Typos in $node->promoted and $node->moderated, #289437: filter/refine and #316087: Collecting weblinks.
As the moderation concept of Modr8 might be not as flexible as compared to other modules like Workbench Moderation (based on node revisions) I think now as well it is OK to remove the ->moderate field.
Comment #22
jonathan1055 commentedThanks Gerhard for finding those past issues - one was even started by me, I'd forgotten that.
I'm pleased we all agree. Here is an updated patch.
Comment #23
gstegemann commentedYes, already a long time ago.
OK. I've tested the patch. Works for me. Thanks.
Comment #25
jonathan1055 commentedThank you both for all your input and help.