The hook-documentation for the taxonomy module in taxonomy.api.php is not consistent. The earliest examples stem from the removal of synonyms (see: #314870: UNSTABLE-4 blocker: Add api.php for every core module, #567572: Remove taxonomy synonyms since Field API is better) from core in Drupal 7. During subsequent updates, documentation for more hooks were added. However later examples do not blend in well with the original docs because they illustrate the hooks based on other (hypothetical) cases (#764726: hook_taxonomy_term_presave() is missing, #835046: hook_taxonomy_vocabulary_presave() is missing, #949576: Missing hook_entity_view() and hook_entity_view_alter()).
The original docs however have two problems:
- The presence of the old synonym-code can lead to confusion among users (see e.g. #1538430: D6 -> D7 unused taxonomy tables should be dropped).
- The synonym-code mentions variables (not used anywhere outside
taxonomy.api.php). As a consequence the old code affects #1775842: [meta] Convert all variables to state and/or config systems
I propose that the examples for the following functions should be rewritten in order to remove references to old synonym-tables and variables.
hook_taxonomy_vocabulary_loadhook_taxonomy_vocabulary_inserthook_taxonomy_vocabulary_updatehook_taxonomy_vocabulary_predeletehook_taxonomy_vocabulary_deletehook_taxonomy_term_inserthook_taxonomy_term_updatehook_taxonomy_term_predeletehook_taxonomy_term_delete
hook_taxonomy_term_load could serve as an example.
Comments
Comment #1
cameron tod commentedThese hooks aren't used anywhere in core, so I had to make up my own dubious examples. Hope they are ok.
Comment #2
cameron tod commentedComment #3
znerol commentedAdd tag and move to documentation project.
The examples are still not to coherent but frankly I'm not able to come up with a more realistic use-case touching all of the hooks. Let's see if we get input from the docs team.
Comment #4
Gaelan commentedInitial patch.
EDIT: Whoops! I got this task and forgot to read the issue. Gaelan--
Comment #6
jhodgdonThanks for the patches!
So... It is kind of important that the sample function bodies in hook documentation follow the Drupal coding standards. I noticed a couple of things in hook_taxonomy_vocabulary_insert() (they apply to other functions in the patch too):
- Normally we use single quotes instead of double quotes for strings (unless the string itself contains apostrophes/single quotes).
- We don't normally split watchdog() calls into multiple lines.
Elsewhere in the patch, I noticed:
- The word "translator" is misspelled several times.
- The term delete hook body is not valid (it references vocabulary not terms). Also the vocabulary create hook body references term not vocabulary.
- I think each sample function body could be improved by starting it with a code comment explaining what the sample body does. For instance "// A term has changed, so notify translators." etc.
- I like some of the examples, but I'm not too excited about:
-- The "paper trail" examples. Can we come up with something better?
-- The vocabulary load one that multiplies all the weights by 10 (what for?)
-- The ones that set a value for "foo", without explaining what it would do... and will that even work? Where is this "foo" field/property defined?
Comment #7
orb commentedWe are working now with this issue during Code Sprint UA.
Comment #8
orb commentedFix:
1. Change examples
2. fix Drupal coding standards
Comment #9
berdirThis is not PHP :)
This should be ==
fluent method calls should be on separate lines, indented by two spaces like this:
This is not necessary, no need to use db_select() here.
tid, not vid.
Term is a NG entity now, so this should be $term->description->isEmpty(). I would also suggest to use something else, description will soon become a field.
id() was correct, ->tid is an object now.
Comment #10
orb commentedFixed
Comment #11
orb commentedsorry, replaced by LF
Comment #12
cameron tod commentedThanks for your help on this.
Is this example accurate, given that it doesn't return anything, and that $vocabularies is not passed by reference?
A vid is an int, I don't think it can be a string, so this could be a confusing example.
Same reference/return question as hook_taxonomy_vocabulary_load().
Comment #13
berdir@cam8001: Those cases are fine. vid is a machine name, not an int, it's a config entity. And the objects are by reference, that's how load hooks work. The only thing that I'm not sure about is if we invoke load hooks for config entities at all. If not then we should simply delete that hook documentation.
->fields( should be on the next line, indented by two spaces, the array keys by 4.
I wouldn't touch things line at all, it's fine to be longer.
Same here.
Comment #14
andypostNo! It's a string (machine name)
See
comment_node_load()as working example, we have this all over coreComment #15
orb commentedFix indents
Comment #16
andypostexecute should have 2 spaces indent like db_delete()
Comment #17
orb commentedfix indent
Comment #18
podarokhttps://drupal.org/coding-standards#array
Arrays should be ended with comma
Comment #19
orb commentedFixed - comma.
Comment #20
orb commentedneeds review
Comment #21
podarok#19 looks good for me
if bot happy - RTBC
Comment #22
jhodgdonShouldn't this example use db_select() and condition() rather than db_query?
And in the Term section, one example changed:
But then the next couple of examples do things like:
So the first change implies to me that id() is bad to use, but then the next example uses it? I don't think both of them can be correct.
Comment #23
berdirtid/id() are correct. $record is a database result row, which is a stdClass without methods. $term is a Term object with an id() method. That $record is currently using ->id() was a search & replace bug when terms were converted.
And our current standard is AFAIK still to use db_query() unless there is a reason to use db_select(), e.g. some dynamic parts. As I said above, that line should probably not be touched at all, but I have no strong opinion on that, so back to you for now :)
Comment #24
jhodgdonWell, how come most of the example hook function bodies use db_select() and this one uses db_query()? If this logic applies to one example, it should apply to all. Can't we keep them consistent?
I also personally find db_select() a lot easier to read/parse than a bare SQL query with placeholders, so my preference would be to use db_select() in the examples for clarity, even if our coding standards recommend db_query().
Comment #25
jhodgdonAnyway... Let's either use a db_query() for both vocabulary and term load examples, or use db_select for both. You are right that our documentation says to use db_query() if performance is an issue:
https://drupal.org/node/310075
But the queries in the examples for vocabulary load and term load are nearly identical. One is using db_query, and the other is using db_select. They can't both be the right thing to do. Let's make them the same.
Comment #26
orb commented1. Change db_select
2. Change replaced $vocabulary->vid of $vocabulary->id()
Comment #27
andypostI think it's ready to go
Comment #28
jhodgdonUm... I thought in this case we were supposed to use the id() method and not ->vid?
Comment #29
orb commentedFixed
Comment #30
berdirIt's the same, but agreed that id() is better here.
Comment #31
jhodgdonThanks! I'll get this one committed soon. Consistent docs++
Comment #32
jhodgdonThanks all! Committed to 8.x.
I think we could use a backport of this to 7.x? It would need a bit of work because taxonomy/vocabulary are not classes in D7.
Comment #33
andypostShould be the same except
->id()becomevidComment #34
berdirand vid would actually be an integer, so you might want to use ->machine_name for the conceptually same check there.
Comment #35
jhodgdonComment #36
orb commentedComment #37
orb commentedported to Drupal 7
Comment #38
andypostD7 have no
hook_taxonomy_vocabulary_create()Comment #39
jhodgdonUm... in the term_update and vocabulary_update hooks, shouldn't we be updating a record rather than inserting a new one? It seems like the tid/vid is probably the primary key, so we'd either need to delete the previous record before inserting, or use db_update() rather than db_insert()?
We did that in the 8.x patch too... guess we need to go back and fix it there?
Comment #40
orb commentedComment #41
orb commentedFix for Drupal 8
Comment #42
jhodgdonThanks! Looks good to me; anyone else want to give it a quick look?
Comment #43
sergeypavlenko commentedThank you. Good code!
Comment #44
alexpottCommitted 025aa2a and pushed to 8.x. Thanks!
Back to 7.x
Comment #45
orb commentedComment #46
orb commentedPort Drupal7
Comment #47
jhodgdonThanks orb! That looks like the right patch for D7, and I'll get it committed shortly.
Comment #48
jhodgdonCommitted to 7.x. Thanks again everyone!