At the moment RDF module does not support automated deletion of stored mappings for Content Types and Fields. This would result in inconsistency once the users edit or delete Content Types and fields associated. Thus this functionality should be added to the rdf module.
How to create a content type + mapping using Drush
Having a way to quickly create content types with their RDF mappings is going to be quite useful to test this issue.
These instructions assume you are starting from a vanilla Drupal site with the standard profile installed. It already includes mappings for article, user and the tags taxonomy term bundle. It also assumes you've already deleted the article content type (for example to test this issue). Here is how to recreate the article content type (and if needed its RDF mappings too) using Drush:
- Export your configuration in the staging area: drush config-export staging -y
- It should be missing the article content type YAML file
- copy the original article content type definition YAML file located in the standard profile into your site staging area: cp core/profiles/standard/config/install/node.type.article.yml sites/default/files/config_2T8.../staging/
- optionally also copy the article RDF mapping (rdf.mapping.node.article.yml) if those were deleted (as they should be once the patch is working
- Import all of the config present in the staging area into your site: drush config-import staging -y
- Visit the content type listing page, the article content type should be back!
Comment | File | Size | Author |
---|---|---|---|
#99 | 2303541-99.patch | 16.71 KB | jofitz |
#94 | 2303541-94-interdiff.txt | 1023 bytes | lokapujya |
#94 | 2303541-94.patch | 13.71 KB | lokapujya |
#92 | 2303541-92.patch | 13.72 KB | lokapujya |
#92 | 2303541-92-interdiff.txt | 3.07 KB | lokapujya |
Comments
Comment #1
scor CreditAttribution: scor commentedComment #2
lokapujyaComment #3
scor CreditAttribution: scor commentedComment #4
chrisfromredfinKicking the testbot. This is only a partial implementation, but would like comments and implementation at least looked over if someone has the opportunity. Next stop - implement hook_field_delete_field.
Comment #6
scor CreditAttribution: scor commentedLike we discussed, I would rather try to use rdf_get_mapping() if possible, and then act on that config entity.
Comment #7
chrisfromredfinWhat I didn't like about that was that entity_load, if there is no mapping, returns FALSE. rdf_get_mapping will return me an structured array that will sort of "start me a mapping" if one does not exist. So then I'm testing for some particular structured array rather than a simple "FALSE."
I'd be happy to use rdf_get_mapping, but I feel like we might want ot change the function signature to add a (..., $return_empty = TRUE) or something. Alternatively, we could write "rdf_mapping_exists" but all it would do is call the entity_load.
Other thoughts?
Comment #8
scor CreditAttribution: scor commentedI think you had mentioned during our last sprint: we could also inspect the new empty mapping that rdf_get_mapping() returns, and detect that the mapping doesn't exist. I *think* I've seen the same logic of instantiating a new object in other APIs in core, but I don't remember which one it was (maybe config?).
Comment #9
chrisfromredfin1. I talked to Crell, who broke the tie. He agrees with you that if you can detect the empty case, better off calling the higher-level API over the lower one. I used the ->id property to detect if there was no mapping. So adjusted that code.
2. With help from chx, I was able to get pointed in the write hook direction for when a field instance is removed from an entity. In this case, there doesn't appear to really be a way to DELETE a field's mapping, only to set the mapping to empty. I don't love how this turns out in the yml when I config-export. It's still there, but set to an empty array. Not sure if we need a new function / API change.
Comment #10
chrisfromredfinMostly writing a note to myself here with a status update from the last sprint...
This patch passes tests primarily because it doesn't test its own case, btw. The two functions, combined, break on the first $mapping->save call when deleting an entire bundle (deleting the bundle must also invoke the hook to delete the individual fields, which makes sense).
For some reason that mapping->save() call dies "accessing a non-object" -- will need to fire up the debugger and figure out the timings. Alternatively, the right approach here is probably to use a ->deleteMapping() call (new) rather than mapping->save()ing an empty array into the mapping. That alone might solve the issue.
Comment #11
chrisfromredfinAnd back to NW.
Comment #12
lokapujyaAdded a deleteFieldMapping(). You still have to call save().
Started adding a test for "delete" to the crudTest.php, but maybe testing the automatic deletion of a mapping needs to be a web test (in order to trigger hook_ENTITY_TYPE_delete.)
Comment #13
scor CreditAttribution: scor commentedThis looks great, Jamie!
Why is a web test required to trigger hook_ENTITY_TYPE_delete? Can't you delete the entity_test entity type in a unit test?
Comment #14
Berdir#2260457: Allow config entities to remove dependent configuration keys when dependencies are deleted due to module uninstall is related I think, and the ideas there to generalize deleting/cleaning-up related/dependant config entities when config entities are deleted. Right now, this deletion only happens when a module is uninstalled, and the cleanup there is also just done in that case. But we could possibly extend that to always use that system, instead of building multiple custom solutions.
Looking at RdfMapping::calculateDependencies(), it doesn't expose dependencies on defined fields yet, sounds like we should do that, similar to how EntityDisplayBase is doing it?
Comment #15
lokapujyaLet's try it. Note: we don't actually have a test for it here.
Comment #17
lokapujyaNeed to change the way I get the fields.
Berdir, would we need to wait for #2336727: Use configuration dependencies and onDependencyRemoval to standardise dependency management on configuration entity delete in order to use dependencies? and then implement something in onDependencyRemoval() that would only delete the mapping for just the field and not the whole bundle?
Comment #18
BerdirIf you add the dependencies, then you need to implement onDependencyRemoval() too, or the whole rdf mapping would get dropped when a field is deleted as part of a module uninstallation.
Once you have that, you can either continue with custom code for now or wait (hope? ;)) for the other issue to happen.
Comment #19
lokapujyaAdds a test to #17. Not using dependencies for now. Just want to get the test working. But when I delete() the field, the delete hooks are not triggered.
Comment #21
lokapujyaDelete the instance. Then, the delete hooks get triggered.
Comment #23
lokapujyaPassed locally.
Comment #25
lokapujyaThis hook gets called when I run the test locally and all tests pass. But, on drupal.org, I can't tell if this hook is getting called. Appears not to be since the debug messages on 142/158 are the same.
Comment #26
lokapujyaPutting a debug() in the hook, to see if the hook gets called.
Result: It is not getting called. Reason why is in the next comment.
Comment #28
lokapujya1.) Rerolled due to #2312093: Rename FieldInstanceConfig to FieldConfig.
2.) Removed a debug().
3.) Changed the Assert (post delete) to be more specific.
Comment #29
scor CreditAttribution: scor commentedLooks like we are no longer using DrupalUnitTestBase, so maybe this line could be removed?
any particular reason for using email as opposed to a regular text field? email is probably fine too.
did you intend to leave this debug() here?
I was confused initially when reading this comment. We're deleting the field value from the entity. We're not deleting the field per se yet.
debug()
Shouldn't we also test the bundle deletion? or is that tested elsewhere?
Comment #30
lokapujyaMade some of the changes. Added some comments.
Comment #31
scor CreditAttribution: scor commentedThanks Jamie. I'm happy with those changes. The only thing remaining now it to also test rdf_entity_bundle_delete().
that comment feels a bit out of place. I don't think we need to say that anywhere.
Comment #32
lokapujyaTests automatic removal of the mapping by rdf_entity_bundle_delete().
Comment #33
scor CreditAttribution: scor commentedYou should check that the entire bundle mapping is deleted, not just the particular field.
Comment #34
lokapujyaNot sure why I needed to create the getId() function.
Fixed a bug in calculatedependecies. With calling save() on the rdf_mapping in the field_config_delete hook, and without checking to see if the object is empty, we got a fatal error.
Comment #36
lokapujyaRemove extra line.
Comment #37
lokapujyafix coding standard.
Comment #38
scor CreditAttribution: scor commentedwas there a patch attached with your comments #36 and #37?
Comment #39
lokapujyaNo, those were just statements; todos.
Comment #40
lokapujyaComment #41
suntog CreditAttribution: suntog commentedFixed a merge conflict.
Comment #42
suntog CreditAttribution: suntog commentedcleaned up blank spaces
Comment #45
lokapujyaComment #46
chrisfromredfinI reviewed the code, it all looks good to me. I'm not super familiar with the coding standards for 8, but what I do know of Drupal standards was all there.
I reviewed the behavior in practice -- added/deleted a field, checked the exported config, added a mapping, deleted the field, exported, checked the mapping. Deleted the whole bundle, verified that it was gone.
I ran a the CRUD tests locally--all passed.
FEEDBACK
[1] If I have anything to add, it seems like we're creating a test entity in setUp() and adding one field to it. Then we're removing the field and ensuring there's no mapping on the entity. A more thorough test might be that we add TWO fields to the test entity, then delete just ONE of them, and check the mapping for the whole bundle. This gives us a little bit more test coverage to ensure we're not over-reaching on our delete.
[2] Also, I see that getId() was created for the purpose of a solitary test to call it. Do we really need that? Can't we use ->id like elsewhere, or is it a different kind of ID or something?
Comment #47
lokapujya1.) done.
2.) I guess we don't need getId()
plus, removed comment mentioned in #31
Comment #48
chrisfromredfingetId() (and call to it) is still there... were you leaving it open for more discussion or should it be gone? I vote to lose it, personally.
Comment #49
lokapujyaI think I tried removing it and it seemed to work. But I somehow left out the change.
Comment #50
lokapujyaupdated.
Comment #53
lokapujyaComment #54
Sachini CreditAttribution: Sachini commentedRe - rolling patch to apply cleanly at commit ffea3bb91d on 8.0.x, with improvements for CrudTest.
The function getId() in RdfMapping had to be introduced again as the fields were made protected. see https://www.drupal.org/node/2384531
Comment #55
lokapujyaComment #56
scor CreditAttribution: scor commentedThis should not be changed, it was fixed in #2381921: Clean-up RDF module test members - ensure property definition and use of camelCase naming convention to comply with the coding standards which recommends camelCase instead of under_score notations.
@lokapujya it's best practice to avoid RTBC'ing patches that contain code your wrote :) so that they are reviewed by someone neutral.
Comment #57
Sachini CreditAttribution: Sachini commentedSorry. Here's the patch with 'enitityType' restored.
Comment #58
BerdirIt is very likely that this will no longer be required very soon, see #2416409: Delete dependent config entities that don't implement onDependencyRemoval() when a config entity is deleted. That is completing the working that we started with automatic deletion of config based on dependencies.
I'd suggest to provide a test-only patch, that should still fail, and it will probably pass after the referenced issue landed.
Comment #59
lokapujyaI think we would still need to set up the dependencies in calculateDependencies().
In addition would we need to add the dependencies to existing .yml files? such as:
rdf.mapping.node.article.yml
Comment #60
lokapujyaFirst a reroll, but want to try using calculateDependencies().
Comment #62
lokapujyaJust the test.
Comment #64
lokapujyaStill test only, addressing issues with the tests.
Comment #66
lokapujyaAttempting to set up the correct dependencies.
Comment #68
lokapujyaHere, I am adding a dependence for each of the field Mappings. However, I only want to set the the dependency for the field that is currently being saved. How do I know which field is being saved? Is it even possible?
Since the saving happens here. It is not actually saving the field mapping; it is saving the mappings for all fields of the bundle.
Comment #69
lokapujyaI may need to go back to the custom deleting of field mappings in #57.
Comment #70
lokapujyaTheoretically, by implementing onDependencyRemoval and returning TRUE, the rdf mapping should not get deleted. Instead, I remove the mapping for just the field that is getting deleted. However, it's still not working in my local testing.
Comment #71
lokapujyaEven if I just return True from onDependencyRemoval() and do nothing else, the Mapping for field 2 is still getting deleted.
Comment #73
lokapujyaComment #74
lokapujyaOk, so that fixes the problem. Needed to use $this instead of retrieving the mapping. The remaining 3 are side effects of adding calculateDependencies. No clue yet why.
Comment #76
lokapujyaComment #77
lokapujyaStandardInstallerTest is failing. That sounds like something is could begetting deleted by calculateDependencies() unexpectedly. But the line that I'm editing in this patch seems to cause it.
Comment #79
lokapujyainterdiff for 77. this was a wild guess but didn't fix the problem.
Comment #80
lokapujyaIf I comment this block out, the standardInstall test doesn't fail. I only get the expected fail from the RDF crudtest.
If I comment the inner block, I still get tthe standardInstall test fails.
Comment #81
lokapujya#80 was a lie. Got 3 errors, but they were different errors.
I think I understand what is happening now. CalculateDependencies() actually changes configuration; It adds dependencies to the field mappings. Then the StandardInstallTest diffs the deployed config which doesn't have the dependencies in the RDF Mappings. So, I think what needs to happen is that the RDF Mappings deployed .yml needs to have the dependencies. I suspected this, as mentioned way back in comment #59, but forgot about it.
Comment #82
lokapujyaTest out the theory above.
Comment #84
lokapujyaGood. That last patch fixed the errors that it was supposed to. There is still an issue with the bundle dependency. First of all, the test doesn't properly test to see if the bundle mapping gets removed. Then there are 2 PHPUnit test errors.
Comment #85
lokapujyaUpdate the delete bundle test.
Comment #87
lokapujyaSatisfy the PHPUnit tests.
Comment #88
lokapujyaComment #90
lokapujyaThe remaining fail is from a new test that I added and left out of the interdiff. Here is the interdiff for the new test. This test if for testing the rdf mapping dependency on the bundle. I needed to use an article, because the test case requires having an entity that manages it's bundles using entities. Here is an interdiff that shows the added test.
Comment #91
BerdirI don't see why this is needed or added here. Every entity has an id() method. just use that. It might not be a great name, but there's no need to duplicate that.
This is public and @inheritdoc but never defined anywhere on an interface. Does this really need to be public? If yes, it needs to be added and documented on the interface.
Which is problematic because of BC. I would recommend to avoid this.
not sure if this came up before but why limit it to field_config?
I don't understand this.
You're not supposed to save yourself. The API might just be checking if you could be changed or not.
this test is disabled?
Comment #92
lokapujya1. ok
2. The method can be private.
3. That was copied from EntityDisplayBase. Seems like it's not needed here.
4. Neither do I. It was copied from somewhere.
5. Thanks!
6. Oops.
How do you delete a bundle?
This is what the test is trying, but I'm not sure this is right:
Comment #94
lokapujyaTry a different way of deleting the bundle.
Comment #95
lokapujyaComment #98
lokapujyaThe test is failing on 8.2.x. Something changed since this was written for 8.0.x.
Comment #99
jofitz CreditAttribution: jofitz at ComputerMinds commentedRe-roll.
Comment #109
smustgrave CreditAttribution: smustgrave at Mobomo commentedWith rdf being removed in D10 wondering if this is still an issue?
Comment #110
smustgrave CreditAttribution: smustgrave at Mobomo commentedRDF is moving out of core and into https://www.drupal.org/project/rdf.
To keep the ball moving closing this as outdated since this moved to PNMI. If still a valid bug please reopen under the contrib module.