Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
taxonomy.module
Priority:
Major
Category:
Task
Assigned:
Issue tags:
Reporter:
Created:
5 Dec 2011 at 09:14 UTC
Updated:
29 Jul 2014 at 20:13 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
fagoComment #2
gábor hojtsyNot sure if it should be part of this patch, but it would be great if we can get language supported for terms (taxonomy entities) as well. Same as for nodes, so we can just copy that code hopefully :) That would unify this part of the code / behavior.
Comment #3
xjmI'll try working on this.
Comment #4
xjmYeah, like Dave Reid said in #1361226: Make the file entity a classed object, I think that language handling should be a followup once the base implementation is done. We'll want to make sure we do it consistently for all the entities where it's missing.
Comment #5
gábor hojtsy@xjm: understood, not trying to disturb the conversion process :)
Comment #6
xjmRecategorizing per #1346204-11: [meta] Drupal 8 Entity API improvements.
Comment #7
sunComment #8
berdirxjm, I assume you are not currently working on this one, are you?
Working on an initial patch...
Comment #9
berdirThis one should pass the taxonomy tests, let's see if there are any other test fails... maybe forum.module and stuff like that needs work.
Comment #11
xjmOh, I was actually. =/
Comment #12
berdirSorry, I actually didn't noticed that this issue was assigned to you and when I did I was already half through with the patch..
Next try, fixed some vocabulary and term creations in forum.install, trigger.text and entity_crud_hook_test.test.
Comment #14
berdirFixed forum tests and revert the class enforcements in the hooks after discussing it with fago.
The two remaining fails are during the upgrade, not sure how to fix that:
The error:
ResponseText: Fatal error: Class 'TaxonomyVocabularyController' not found in /home/berdir/Projekte/d8/core/modules/entity/entity.module on line 297
Call Stack:
0.0000 647976 1. {main}() /home/berdir/Projekte/d8/index.php:0
0.0191 4234864 2. menu_execute_active_handler() /home/berdir/Projekte/d8/index.php:21
0.0194 4313312 3. call_user_func_array() /home/berdir/Projekte/d8/core/includes/menu.inc:512
0.0194 4313680 4. system_batch_page() /home/berdir/Projekte/d8/core/includes/menu.inc:512
0.0194 4313680 5. _batch_page() /home/berdir/Projekte/d8/core/modules/system/system.admin.inc:2333
0.0194 4317880 6. _batch_do() /home/berdir/Projekte/d8/core/includes/batch.inc:80
0.0194 4317880 7. _batch_process() /home/berdir/Projekte/d8/core/includes/batch.inc:161
0.0200 4364376 8. call_user_func_array() /home/berdir/Projekte/d8/core/includes/batch.inc:284
0.0200 4364448 9. _simpletest_batch_operation() /home/berdir/Projekte/d8/core/includes/batch.inc:284
0.0286 4973584 10. DrupalTestCase->run() /home/berdir/Projekte/d8/core/modules/simpletest/simpletest.module:177
1.0979 5368760 11. BareUpgradePathTestCase->testBareUpgrade() /home/berdir/Projekte/d8/core/modules/simpletest/drupal_web_test_case.php:520
1.0979 5368760 12. UpgradePathTestCase->performUpgrade() /home/berdir/Projekte/d8/core/modules/simpletest/tests/upgrade/upgrade_bare.test:29
6.9304 9269744 13. DrupalWebTestCase->checkPermissions() /home/berdir/Projekte/d8/core/modules/simpletest/tests/upgrade/upgrade.test:308
6.9304 9270320 14. module_invoke_all() /home/berdir/Projekte/d8/core/modules/simpletest/drupal_web_test_case.php:1190
6.9342 9333176 15. call_user_func_array() /home/berdir/Projekte/d8/core/includes/module.inc:819
6.9342 9333544 16. taxonomy_permission() /home/berdir/Projekte/d8/core/includes/module.inc:819
6.9342 9334616 17. taxonomy_get_vocabularies() /home/berdir/Projekte/d8/core/modules/taxonomy/taxonomy.module:88
6.9342 9335016 18. taxonomy_vocabulary_load_multiple() /home/berdir/Projekte/d8/core/modules/taxonomy/taxonomy.module:664
6.9342 9335168 19. entity_load() /home/berdir/Projekte/d8/core/modules/taxonomy/taxonomy.module:950
6.9342 9335248 20. entity_get_controller() /home/berdir/Projekte/d8/core/modules/entity/entity.module:234
Comment #16
aspilicious commentedOk just a note for myself so I don't forget these notes for final patch reviews
Something wrong with indentation
We need the override statements
Add a newline
all the taxonomy term tests are turned off
-1 days to next Drupal core point release.
Comment #17
berdirUpsie, fixed all points except of the override docblocks, quite a few others will need that as well..
Comment #19
aspilicious commentedFatal error: Class 'TaxonomyVocabularyController' not found
looks like a registry or .info file reloading problem. Berdit told me in irc that it can't be the registry so not reloading the .info is the last on my list of options. Probbably this is not the case but just writing it down.
Added docs for the class functions.
Comment #21
rfayComment #22
David_Rothstein commentedJust skimming through the patch and noticed the following... Why remove all that documentation?
Comment #23
berdirThe properties are now documented on the class itself. Except original (old_machine_name is gone), so we could keep that.
The return should probably be kept, but then we should unify all _save() functions (if we want to keep them). I oriented myself on comment_save() which is probably not a very nice example as there was no @return documentation in D7 either.
Comment #24
sunAttached patch fixes the TaxonomyVocabularyUnitTest test failure. Includes:
- Removed debugging code
- Fixed comments
- Fixed drupal_write_record() to properly support (entity) class instance objects
- Fixed isNew() method to (re)set the ->is_new property, so preSave() and postSave() methods can rely on it.
That said, even with the latter, the isNew() method returns a bogus result. We either need a wasNew() method/property, or need to directly access the $entity->is_new property in preSave()/postSave() (instead of the method).
Comment #26
fagoYep, isNew() for postSave() wouldn't tell TRUE for an insert. Maybe we should pass a boolean to both preSave() postSave() that tells us whether it's an insert or update?
Imo, an entity should always have a single defined data structure and go with that only. If necessary, the form code has to account for matching it.
This should use entity_create().
Let's skip type-hinting until we've resolved #1391694: Use type-hinting for entity-parameters.
Comment #27
sunIncorporated feedback from #26 and fixed upgrade path tests.
To resolve the postSave() problem with isNew(), I've changed the ->isNew() method to only set the ->is_new property once; i.e., once set, it sticks for the duration of ->save(). It is unset at the end. The only "risk" involved there would be some broken code that directly adjusts the ->is_new property during the save operation, but I do not think we want or need to care about such broken code.
Comment #29
sunStale comments everywhere ;)
Was there any particular reason for omitting $format? I've added it in this patch.
Should refer to the actual constants, not their values.
Additionally reverted these removals, as I believe that code that calls into the static resetters expects to have the entity caches cleared, too. We might need to discuss this for all entity types + resetters in a separate issue.
Comment #30
berdirThe resetCache() are already done in the save() and delete() methods, see http://api.drupal.org/api/drupal/core--modules--entity--entity.controlle... and http://api.drupal.org/api/drupal/core--modules--entity--entity.controlle.... So it should be save to delete them IMHO.
Agreed on everything else, note that I've just copied the descriptions from the hook_schema() definition.
Comment #31
sunYes, resetCache() is already invoked within the controller operations. However, those
taxonomy_*_static_reset()functions are not necessarily invoked from within the controller. They are called in tests and possibly from other places as well. It's those other calls that expect a full reset of statics.Comment #32
aspilicious commentedNow it's green time to nitpick. Only found 2 small issues after quick review.
Deletes
Deletes
I see there are other problems with the code alrdy in core. I don't care about those in this issue. Just want to be sure new docs are ok.
Comment #33
sunFixed #32.
Comment #34
berdirMore comments about my own code than a review...
I've just hacked this together to get it working but I really dislike it.
I have no clue why the arguments defaults to an array instead of NULL. Is there a case where we could possibly pass an array into it or is this just very very old code? Should probably be cleaned up. I guess we need some sort of pattern for how to deal with new/edit forms.
I guess we'll see later on if this is a behavior that's worth to be unified..
I did this in preSave() because there was no way to get the isNew() information in postSave() before. As you changed this, it *might* make sense to move it into postSave(), not sure. It happened technically after the insert in the old code but there was no clear separation of pre/post anyway.
I agree with fago that there should be a single, consistent way to define an entity and we should drop support for that weird nested syntax (I think I already dropped the support for $term->parent = 5), I just didn't want to do this without feedback.
Note that I dropped the old_machine_name stuff, in case it wasn't obvious :)
For the record, I *really* like changes like this. It's now obvious what is happening here (creating an entity based on the values) instead of magically creating entities by casting $item/$form_state['values']to an object.
This change might look weird and irrelevant. The problem is that if this check fails then Simpletest tries to generate a message automatically with the whole content of $terms2 and $terms3. This results in a string that is too long to be saved and the test throws an exception. This makes it hard to actually see what's wrong, especially with the testbot. I guess the code never failed when this code was created..
This part could now probably be reverted since the static reset call does call resetCache() too. On the other side, the new code just clears what's necessary.
Comment #35
bojanz commentedThis sounds odd.
I think we should cleanup the signature of taxonomy_form_vocabulary() and remove the hack while we're at it. I see no reason why $vocabulary should default to an array.
Comment #36
catchI'm sure that's very old code. When doing the entity/field conversions in D7 I found all kinds of stuff but there's plenty still in there.
Comment #37
sunIncorporated #34 and #35.
Attached patch is a format-patch for convenience, so you don't need to review the whole she-bang once more.
IMHO, this doesn't belong into the entity class though. It should be part of the form/user input handling, and at maximum, be validated on entity validation level (which does not exist at all yet).
However, leaving this alone for now.
I think the new location in preSave() is correct, as that means that hook implementations get a prepared entity for saving.
I'd like to move further tweaks to $term->parent into a separate issue. These changes are technically irrelevant for this issue and, as API changes, they really deserve an own discussion.
Actually, this concerned me a bit. I don't think the test never failed. The previous size of the taxonomy term stdClass was small enough to fit into an assertion message.
Now, with the entity info and all of the additional data (which is *a lot*), the mere var_export of two term entities broke the test runner in a very very weird way. (An uncaught exception is thrown deep down the line, leading to a fatal error, and what you see in the test result is a huge chunk of triple-escaped string garbage.)
We need to watch out for this and should discuss possible resolution options in a separate issue.
Comment #38
catchpounard mentioned in the main interface patch (but after it was committed), that we should avoid copying the entity info into the classes, I'd agree with that even if it's just for smaller backtraces.
Comment #39
sunAdditionally cleaned up taxonomy_term_form() in the same way.
Providing an interdiff since #33 this time.
Comment #41
sunSorry, test failure caused by recently added taxonomy test code in another core patch.
Comment #42
aspilicious commentedAdded some type hinting as proposed in #1391694: Use type-hinting for entity-parameters
Comment #43
aspilicious commentedpatch...
Comment #45
aspilicious commentedOffcourse that fails! :D Let's try this one...
Comment #46
aspilicious commentedThe array stuff is gone now so should this be type hinted?
Same question
-10 days to next Drupal core point release.
Comment #47
sunCreated spin-off: #1401496: forum_taxonomy_term_delete() completely broken (takes $tid instead of $term entity)
Added type-hinting to all relevant taxonomy functions and hooks.
interdiff is against #41.
Comment #48
aspilicious commentedUnrelated?
Comment #49
sunLooks RTBC to me, anyone bold enough?
This patch contains some entity system and common.inc fixes that will unblock further entification work.
Comment #50
aspilicious commentedYeah this is rtbc, #48 is a minor api.php fix.
Comment #51
David_Rothstein commentedReading through this, it looked very nice, but I caught a couple things:
The previous docs told module authors exactly what they needed to provide if they wanted to save a new term or vocabulary, but the new docs aren't quite there yet.
Minor issue here with the line not wrapping at 80 characters.
I don't understand why this line is being removed? Based on the code comment, it sounds like it's integral to what the test is trying to assert... Anyway, at a minimum the code comment is no longer consistent with what the code is actually doing :)
Comment #52
berdir1. As I understand it are the _save() functions just a temporary BC wrapper (that has already been removed in the user patch because the function would have to be changed anyway). The optional original property should IMHO be documented directly on the Entity class because it's not taxonomy specific. Not sure where information on how to create entities from scratch should live, but I think it's rather pointless to add it to a function that we want to remove anyway.
3. No idea either, pretty sure that line needs to stay.
Comment #53
fagoThe patch looks already great!
Yep, let's re-evaluate this in a follow-up.
Here a review:
I see the following problems with this:
1. This kind of adds a state to the method. If the id-key changes, it needs to fix the public property. However, the property is not part of the interface, so the storage-code cannot know.
Thus, I'd prefer keeping isNew() stateless.
2. This changes the behaviour of isNew() to return TRUE during postSave(). While I'm sure that's intended, I don't think it's correct. The entity is not new any more once it has been saved and a possible sub-sequent save *has* to update it. Yes, there are cases were modules need to be able to re-save upon insert. See related issue #1146244: node_access integrity constraint violation on module_invoke_all('node_' . $op, $node);.
That said, I don't think we should keep the state ("it's an insert) by tracking on the entity, but pass it around explicitly. That's going to be more robust and doesn't rely on the non-obvious (and imho incorrect) assumption that isNew() is TRUE after inserting.
That's not nice as it's going to populate quite some not existing entity properties. I guess fixing all form handling now is out of scope for this patch, we should come back to this though once we've more sophisticated entity form handling...
What's that variable or? Why not just go with $term->name ?
I agree this belongs to the form code (both entities).
Again, let's fix how the entity looks like given a set of properties. Thus,
this should not be optional as the vocabulary isn't. Thus, let's either rely upon it or scratch it.
As it is the bundle-key, it's required for now. But then let's move it to TaxonomyTerm::create() ? I could see it passing in a 'vocabulary' object (alternatively to passing $vid) ala
entity_create('taxonomy_term', array('vocabulary' => $vocabulary)). Then we can initialize 'vid' and the machine name based upon the vocabulary?hm, why isn't that in resetCache()?
I guess it would make sense to move all that retrieval functions into the storage controller at some point + cache reseting into resetCache(). That should be as fine follow-up though.
Agreed. I think those documentation is outdated by entity properties documented at the class though. However, $parent does not seem to be missing there.
Comment #54
sunRebased and re-rolled #47 in http://drupalcode.org/sandbox/sun/1255586.git/shortlog/refs/heads/platfo... against latest HEAD.
Does *not* incorporate any feedback since #47.
Comment #56
gábor hojtsyThere is now also a langcode both on vocabularies and terms. I did not find those coved in the patch on a quick look.
Comment #57
klausiInterdiff is against #54. Does no incorporate feedback since #52.
Comment #58
klausiCreated a branch in sun's platform sandbox and pushed my patch there: http://drupalcode.org/sandbox/sun/1255586.git/shortlog/refs/heads/platfo...
Comment #59
sunI've dissected and merged in all changes by @amateescu and @klausi.
See curent branch for all changes.
(@klausi: Merging in your changes was a bit harder, as your branch wasn't based on platform-taxonomy. Therefore, I've removed that branch. Please create a new branch based on the main one if you'd like to work on this further.)
Looks like only #53 still needs to be incorporated.
Comment #61
sunSorry.
Comment #62
David_Rothstein commentedIn #51 I proposed not having the documentation remain on taxonomy_term_save() itself, but rather moving it elsewhere (probably to the class). However, the current patch still seems to just delete it without adding it back anywhere else.
Comment #63
fagook, worked over the remaining points from my own review from #53
I've implemented that and added a boolean to postSave(). However, I also noted that currently the storage controller assumes $entity->is_new what violates the coupling via the interfaces. Thus I've cleaned the isNew() logic up and introduced EntityInterface::enforceIsNew().
Good suggestion (it's mine ;), but it shows a lack in the current implementation. We do not have a way to populate / initialize entity properties on entity-creation as __construct() is called during load() to. Thus, we currently can do it only on preSave() what sucks as the initialized entity properties are not available between entity creation and save then, what violates the "an entity should always look equal for a given set of properties" assumption.
Thus I've improved entity creation to go over the storage controller by adding a create() method there, which so can be overridden to add custom entity property initializations.
I've moved all static cache reset and the cache_clear_all() call into resetCache(), what properly centralizes cache clears there. I had to add a call to resetCache() during entity insertion though which now allows general caches ("all XY") to be cleared.
I've added a TaxonomyTerm::$parent property + moved the docs over there. I've updated those docs and the code to match (they were not in sync at all) by removing not documented behavior and the docs for not existing behavior. Still, having that kind-of-property is awkward and should probably cleaned up in a follow-up. Anyway, at least the docs now reflect what's there.
Also, the patch previously introduced a property definition for Entity::$original, what I don't think makes sense as it's only there during saves. Additionally, I think we should clean it up to be passed as second parameter in entity CRUD hooks instead of piggy-backing it on the entity object. But that's another issue. Removed that.
I've implemented the changes using properly split commits in sun's platform repository in the
platform-taxonomy-fagobranch. Also, updated patch attached.I don't think there is a cause for doing special language handling for vocabularies. If we decide to go with the default language by default we can do so generally, but no cause for handling vocabularies different. Thus, I've removed that hunk. See #1277776: Add generic field/property getters/setters (with optional language support) for entities
Comment #65
fagoI realized that wasn't added by this patch, thus I reverted those commits to keep that code for now. Let's deal with that in the language-issues.
Also, I fixed the test-fail by converting a recently changed test case to make use entity_create().
Comment #66
amateescu commentedReviewed fago's changes from #63 and they all look very good.
Re: #51 1)
Fixed in the attached patch.
I think we can leave this for a follow-up task. We have three more entity conversions that are waiting for this one to land :)
Comment #67
bojanz commentedOkay, time to get this in, and continue with entity conversions.
The current patch looks good to me, and I see that all feedback so far has been addressed.
Comment #68
catchenforceIsNew is hard to say, what about forceNew()? But that doesn't have the strong link to isNew so not sure... either way can be a follow-up if at all.
Why do we need to do this?
Leaving at RTBC, would be good to get feedback on those, but I'm happy committing this later on anyway.
Comment #69
aspilicious commentedrelated #1495024: Convert the entity system to PSR-0
Comment #70
fago#66 adds great doc improvments, however it also re-introduces the $original variable for vocabularies. As explained prevously I don't think we should add $original as property to the class:
Thus, removed it again for vocabularies and re-rolled the patch.
Comment #71
bojanz commentedSounds good.
Comment #72
Crell commentedRe #68: The database-backed class loader doesn't play nice with Unit tests and, apparently, some functional tests. In order to keep it from exploding due to a missing DB etc. you need to disable it in setUp and re-enable it in shutDown. Arguably we should just push that into the Unit test case base class, but I haven't gotten around to doing so.
I haven't reviewed its usage in this patch to say why it's being done here, since it's a WebTestCase, but I presume it's the same reasoning.
Comment #73
catchThanks folks. We've been badly over thresholds the past week, but currently if you take the RTBC patches against 7.x from the threshold count it's just on the line, so since this gets us towards closing #1368394: Convert all core entities to classed objects which is also over thresholds I've gone ahead and committed/pushed it to 8.x.
This needs a change notification, but we probably want to have just one for the meta issue, going to mark this as needing one but hopefully we can just add a short note to an overview of the changes.
Comment #74
aspilicious commentedI think we alrdy have one: http://drupal.org/node/1400186
Comment #75
fagook, I've updated the existing one over at http://drupal.org/node/1400186 to reflect the recent changes. Please review.
Comment #76
catchThat looks good to me, marking fixed. Thanks!
Comment #77
aspilicious commentedComment #79
xjmRegression: #1550454: Regression: Following taxonomy entity conversion, Taxonomy EFQ causes warnings and notices
Comment #80
xjmSorry; I started to reopen this but then decided it was better to file a followup (since we are several entity conversions past reverting this), but then didn't set the fields back. :P
Comment #80.0
xjmUpdated issue summary.