Closed (fixed)
Project:
Drupal core
Version:
7.x-dev
Component:
taxonomy.module
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
7 Aug 2010 at 22:17 UTC
Updated:
3 Jan 2014 at 01:42 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
dave reidSimple patch.
Comment #2
yched commentedTrue. However :
The patch ensures that the $vocabulary object, built from submitted form values and passed from taxonomy_form_vocabulary_submit() to
taxonomy_vocabulary_save() and down to hook_taxonomy_vocabulary_update(), has an ->old_machine_name property.
This only works for form-based updates, and doesn't catch vocabs updated through direct API calls to taxonomy_vocabulary_save().
taxonomy_vocabulary_save() should retrieve the current machine name of the vocab based on the incoming vid (which, unfortunately, is still the official id key for vocabs in D7), and if the current machine name is different than the incoming one, set $vocab->old_machine_name.
Which, on a related note, reveals that the call to field_attach_rename_bundle(), currently made by taxonomy_form_vocabulary_submit(), should be moved out of the form workflow and into the taxonomy_vocabulary_save() API function.
Comment #3
yched commentedRaising to 'major'. An API call breaking Field API and Pathauto is serious.
Comment #4
dave reidRevised patch that loads in the old machine name if the vocab is being updated. Also moves the logic for field_attach_rename_bundle() to work the same as node type saving.
Comment #5
dave reidComment #7
dave reidGrr, copy/paste error.
Comment #8
yched commentedLooks good - but do we still need this hunk ?
Powered by Dreditor.
Powered by Dreditor.
Comment #9
dave reidIt saves us a db query when updates are made through the UI, and it's in-line with how the node type form works, so I'd say it's best to leave it in.
Comment #10
yched commentedAgreed.
RTBC after the bot comes green.
Comment #11
sunPlease revert. We don't use type hinting for objects. There's a very lengthy discussion about this in another Drupal core issue.
Powered by Dreditor.
Comment #12
dave reidUm no. Lots of functions in core would disagree with you. Take a look at nearly every single file.inc function. And it's not documented in the coding standards that we shouldn't use type hinting for objects.
Comment #13
sunSee #595084: Rollback type hinting for $node
Comment #14
dave reidFine, I won't fight something that was not documented outside of an closed issue.
Comment #15
sunThe first condition on $vocabulary->old_machine_name seems to be needless, as the code that is added right in front of this already makes sure that $vocabulary->old_machine_name is set.
Powered by Dreditor.
Comment #16
dave reidOh good catch. Revised patch for review.
Comment #17
sunThanks!
Comment #18
sunAlthough badly needed, this is D8 material according to the rules (I had to learn today).
Comment #19
dave reidSince this falls under a major bug report, I would be willing to say this would be ok for a 7.1 release since there are no API changes ...
Comment #20
dave reidNote that I'm perfectly willing to even set this to postponed until after 7.0 release, but since this is an actual non-API-changing bug report, I'm marking this back to 7.x.
Comment #21
yched commentedDefinitely for D7, of course.
I would also argue that a bug that blocks modules like Pathauto or XML sitemap qualifies as 'critical', but well.
+ crosslinking from #881530: Exportability of vocabularies is ruined by taxonomy field's 'allowed values' setting, since the bug here more generally prevents storing vocab-related data based on machine name rather than vid, which is another important point on the road to vocab exportability.
Comment #22
fagoThis issue perfectly demonstrates why we need #651240: Allow modules to react to changes to an entity.
Ouch. But probably the best we can do without a generic solution now.
Comment #23
catchThat query in taxonomy_vocabulary_save() is ugly has hell, I can see why this is needed though. There are some notes on better entity update APIs in http://groups.drupal.org/node/62633 for anyone who's interested.
But
Er, no. That also proves we need tests for this.
Comment #24
alex_b commentedI think we should move towards not allowing changes to machine names, just as you would never bother to change a node id.
After working for quite a long time with systems that don't allow you to change machine names (Views etc.) I find that it's just not needed.
What's worse, the infrastructure we need as a community to allow for machine names to change is busy and brittle at best: how many D 6 modules out there are not implementing hook_node_type() where they should?
Comment #25
dave reidPlease don't hijack the issue. Let's just fix the bug.
Comment #26
yched commentedIn case it's not obvioius (took me 30 seconds...), what catch is referring to in #23 is :
'node' should be 'taxonomy_term', of course. So yes, tests needed. Will try give it a shot later today.
Comment #27
yched commentedUpdated patch with test.
+ now that taxo_term $field definitions refer to vocabs by machine_name rather than by vid (after #881530: Exportability of vocabularies is ruined by taxonomy field's 'allowed values' setting), we also need to update them when a machine name is changed. Nothing new here, nodereference fields have done the same for years when a node type name changes.
Also added a test for that other part.
Comment #29
alex_b commented#25: Agreed. This is a bug, image style names and node types can change and have a way of letting other modules know, taxonomy doesn't. This patch follows the general pattern of node. Permanent machine names is a conversation for another issue.
Dug into the failing tests, could not figure out what causes the reported notices:
It appears that when a machine name changes, calls to the field API from taxonomy_taxonomy_vocabulary_update() don't find the field instances they are looking for field_info_instances() >> _field_info_collate_fields().
Comment #30
yched commentedFixes the failures.
For those interested : those failures were actually a non-related bug in the dummy 'field storage backend' implemented in field_test.module - more specifically, its implementation of hook_field_attach_delete_bundle() had an incorrect signature.
It was only triggered by the patch as a side effect of enabling field_test.module in TaxonomyVocabularyUnitTest::setUp(). Some of the tests in this class (not those touched by the patch) delete some vocabs, which calls field_attach_delete_bundle() and its associated hook, which triggers the bug. Did not happen so far because until now those tests ran with field_test.module disabled.
I'm surprised that no existing test has caught this so far. There are definitely existing tests triggering a field_attach_delete_bundle() while field_test.module is on... I'm looking into this, just to be sure.
Anyway - as far as this patch is concerned, this should be ready..
Comment #31
yched commentedBetter fix for the broken field_test_field_attach_delete_bundle().
Comment #32
alex_b commentedyched: thanks for detailing the hook_field_attach_delete_bundle() bug.
This is RTBC now.
I am setting the priority critical because without this patch, any changes to a vocabulary machine name will result in taxonomy term reference fields breaking. (Reproduce by adding taxonomy field to content type, create node with terms, change vocab name, edit and save node).
Comment #33
dave reidYay for fixing hidden bugs! Test coverage looks good and so do all the comments. However,
Shouldn't we be implementing hook_field_attach_rename_bundle() in taxonomy.module rather than hook_taxonomy_vocabulary_update()?
Powered by Dreditor.
Comment #34
dave reidYay for fixing hidden bugs! Test coverage looks good and so do all the comments. However,
Shouldn't we be implementing hook_field_attach_rename_bundle() in taxonomy.module rather than hook_taxonomy_vocabulary_update()?
Powered by Dreditor.
Comment #35
alex_b commentedGood catch. We should. Will post shortly.
Comment #36
alex_b commentedUse hook_field_attach_rename_bundle() instead of hook_taxonomy_vocabulary_update().
Comment #37
webchickHow on earth did that mistake pass tests? Sounds like we need expanded test coverage for renaming machine names?
Comment #38
dave reid...that's exactly what we're working on?
Comment #40
webchickWhat I mean is that #34 identifies some blatantly wrong code in the patch. And yet #31 passes testbot. This should not happen.
Comment #41
dave reidNeeds to check if $entity_type == 'taxonomy_term'.
Powered by Dreditor.
Comment #42
webchickOk, nevermind. I had interpreted #34 as saying "you made a typo" when it was instead saying "there is a more optimal hook into which you can place that code."
Carry on. ;)
Comment #43
alex_b commentedFixed according to #41
Comment #44
yched commentedArguable, I'd say. Both hooks will be fired sequentially anyway, so the difference is mainly esthetic. Personally, I tend to think that the more specific hook_taxonomy_vocabulary_update() is exactly what we want, and that hook_field_attach_rename_bundle() is more obscure here.
+ hook_field_attach_rename_bundle() is invoked more "frequently" (e.g node type change) and means more useless no-op function calls. Rare anyway, so not really important in practice, but makes more sense as a pattern IMO.
So I personnally favor #31 over #43, but either way, both are RTBC.
Comment #45
dries commentedWill this actually trigger? In the code about we call it with 'taxonomy_term' instead of 'taxonomy_term_reference'. Need to look at it more but figured I'd report this. I apologize if I overlooked something.
Comment #46
alex_b commentedYes, it will: taxonomy_term_reference is the field type provided by taxonomy module (see taxonomy_field_info()).
Comment #47
catchLooks fine to me now.
Comment #48
yched commentedJust so that it doesn't get lost - from my #44 : "I personnally favor #31 over #43, but either way, both are RTBC."
See #44 for explanations.
Comment #49
webchickUpon reviewing this issue, I agree with yched. We know the extra semantics to add to this event (we're updating a *vocabulary* rather than some sort of generic bundle), so let's use it. And looks like Dries's concern was addressed above.
However, #31 doesn't apply anymore. Could we get a quick re-roll?
Comment #50
dave reidI don't understand. The code in the hook is responding to a bundle being renamed, hence using the field hook. If the code is in hook_taxonomy_vocabulary_update() it runs no matter if a vocabulary's machine name has changed or not.
?
Comment #51
catchYeah in this case the rename bundle hook is the more targeted one, vocabulary update and bundle rename are two distinct events. The only thing that could justify putting this in hook_taxonomy_vocabulary_update() would be if we moved the field_attach_rename_bundle() logic there too, but that would break the current pattern of having field_attach_*() calls directly in CRUD functions. So I think this should go in as is.
Comment #52
webchickHm. Ok. I can see that perspective.
However, #42 doesn't apply either. :P
Comment #53
catchComment #54
dave reidLooks like it's only the whitespace changes that didn't apply. Marking as RTBC as long as the bot confirms.
Comment #55
webchickGreat!
Committed to HEAD. Thanks, everyone. Another critical bites the dust. :)
Comment #56
yched commentedSorry for being picky, but I realized the correct reason why I felt that using hook_field_attach_rename_bundle() over hook_taxonomy_vocabulary_update() is off.
A vocab machine name change only triggers hook_field_attach_rename_bundle() because it so happens that taxo terms are fieldable entities, and that the bundles are the vocab machine names.
This has nothing to do with the fact that there exists a 'term reference' field type, and that its $field definitions store a vocab machine name, which need to be updated when the name changes - the fact that this name is also the name of a bundle for fieldable terms is incidental.
That's a job for hook_taxonomy_vocabulary_update(). Doing it in hook_field_attach_rename_bundle() works too, but that's pure luck. X being a fieldable entity and the existence of an 'X reference' field type are two completely decorrelated facts.
Attached patch reverts to hook_taxonomy_vocabulary_update(), as in #31.
Comment #57
catchThat's a good argument, and not a picky one.
Comment #58
webchickOkie doke then.
Committed #56 to HEAD. Thanks!