Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Unflagg for an entity or a user and add tests for that, ensuring that when a user is deleted the flags are also deleted.
This is actually quite likely to happen right now because flag_entity_delete() is not implemented. But if when it will be, I think making sure that this doesn't fail hard is important.
Comment | File | Size | Author |
---|---|---|---|
#76 | interdiff_2501575_66-76.txt | 996 bytes | socketwench |
#76 | avoid_fatal_error_when-2501575-76.patch | 9.23 KB | socketwench |
| |||
#67 | interdiff-avoid_fatal_error_when-2501575-62-66.txt | 3.64 KB | edurenye |
#67 | avoid_fatal_error_when-2501575-66.patch | 9.21 KB | edurenye |
| |||
#64 | avoid_fatal_error_when-2501575-64.patch.txt | 8.7 KB | martin107 |
Comments
Comment #1
Anonymous (not verified) CreditAttribution: Anonymous at FFW commentedComment #2
joachim CreditAttribution: joachim commentedIf the flaggable entity is missing, we should probably still remove the flagging.
Though then that would mean we'd have a call to flagging->delete() which bypasses the API, which I can't help but think sets a bad example :/
Comment #3
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedTests added.
Comment #5
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedJust call
$node1->id()
or$node2->id()
.$this->clickLink(t('Flag this item'));
Comment #6
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone.
Comment #9
BerdirWe should still try to delete the flagging. So an else that just does $flagging->delete().
And the test should make sure that we are deleting them in the end. You could also add a check to confirm that they haven't been deleted already before the user is deleted, but that would then fail in the follow-up that's suggested below. But that's ok too, file the issue and add a @todo to it.
Contrary to what @mbo said, let's not change this here. It makes the patch a lot bigger due to completely unrelated changes. Let's keep them all without t().
I'd even suggest to not rename $node to $node1 but just add $node2.
Note that the test is only failing as expected and providing the necessary test coverage because flag_entity_delete() is not implemented at all. So we should have a follow-up issue to do so. If that is implemented then we should be fine with this too since it shouldn't happen anymore.
Comment #10
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedI think it's ok now, I made those changes.
Comment #11
BerdirI'm confused about this.. you pass in the first node and only count flags for that node ID. So why does that return 2?
$count_flags is unused now and the method needs documentation.
Comment #12
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedI has asserting bad the tests, I have to compare no check if it's true, now the tests are ok.
Comment #13
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedOne
debug()
left. :)Comment #14
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedYes, I forgot to remove, sorry.
Comment #15
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedThere is 96.86% similarity between these 2 blocks so I would suggest to create a helper method (in
flag.module
) and call it twice as it was before withunflag()
method.Won't change the status, as this is only a suggestion.
Comment #16
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedHere is your suggestion applied.
Comment #17
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedLooks nice. :)
Just small changes.
PhpStorm is saying this is not used.
I would rename this to
flag_unflag()
(reads strange, but first word in the method name should be module name).And then change this
flag_unflag($account)
. Second param is null by default.Possibly add
/** @var \Drupal\flag\FlaggingInterface $flagging */
above this line.Comment #18
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone all those changes.
Comment #19
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedI think this should be like before.
And
/** @var \Drupal\flag\FlaggingInterface $flagging */
one line above this one. :)Other than that, looks good.
Comment #20
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone.
Comment #21
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedLooks nice. :)
Comment #22
BerdirSeems like this should rather be a method on the flag service, which already has unflag(), so we should add some alternative method there? unflagAll() maybe?
Comment #23
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedMoved to service.
Comment #24
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedQue?
And:
Create the issue, add a @todo, update the issue summary (that one would be really helpful).
Comment #25
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedMoved the tests to a todo.
Comment #26
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedCreate the issue, revert the removal of the test which will fail in the future, update the issue summary (that one would be really helpful).
Comment #27
socketwench CreditAttribution: socketwench commentedWe don't need to call service(), since this is now a just a FlagService method. We can just use $this. ^_^
I was wondering why we even need unflagAll() when we have reset(), and then I saw the different parameter lists. We should add some @see directives to FlagInterface::unflagAll() and FlagInterface::reset() to reduce confusion elsewhere.
Comment #28
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedCreated the issue, added again the tests, added the correct @todo, removed service, added @see tags and edited the summary.
Comment #29
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedThis comment still doesn't make any sense.
Comment #30
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone, I hope.
Comment #31
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedBetter.
Comment #32
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedHooray! Looks good to go.
Comment #35
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedRebased.
Comment #36
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedWrong file.
Comment #38
juanse254 CreditAttribution: juanse254 at MD Systems GmbH commentedRebase Needed.
Comment #40
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedRebased.
Comment #42
juanse254 CreditAttribution: juanse254 at MD Systems GmbH commentedSome nitpicking and good to go
Unrelated empty line
improve the comment.
Comment #43
juanse254 CreditAttribution: juanse254 at MD Systems GmbH commentedComment #44
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone.
Comment #46
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedUnrelated failing test.
Comment #48
juanse254 CreditAttribution: juanse254 at MD Systems GmbH commentedOkay tests are good, setting to RTBC.
Comment #49
joachim CreditAttribution: joachim commentedSorry I've not given this any attention. I've been aware of people working on this one.
I think unflagAll() is a good addition. Though reading this patch, I was thinking about how (IIRC) we don't yet take care of deleting flaggings when a flag is deleted. Which let me to thinking that when we tackle that, unflagAll() would acquire an extra $flag parameter. Which then makes reset() a bit pointless really -- reset() is just a special case of unflagAll() where we only specify the $flag parameter. The 'reset' part becomes legacy terminology from previous version of Flag. But that can be dealt with in a clean-up issue later.
The patch does have a few things that need fixing:
That looks like unrelated cleanup.
This shouldn't be changed. The @var type declaration is an interface. See standard proposal: https://www.drupal.org/node/2305593.
We're in the service here! It's $this ;)
This needs a comment to explain that we're working around the potential situation where the flagging is already gone. Also, it should be mentioned that the unflag event won't get fired. Basically, if we get here, it's because our data is broken and we're trying to do our best to clean it up.
Say 'flaggings', not 'flags' here.
remove()?
Hmmmmyeah this test class is a bit of a dumping ground for random bits. I really do appreciate the tests though :)
'Flag the nodes.'
Is there a reason we're not using the count service? I suppose tests should query the DB directly. Should this go in the base test class maybe?
Comment doesn't fit here.
Comment #50
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone everything.
In the point 9, I don't have any method in count service to count the flags of a user over an entity, if we have to add it there, then maybe it should be done in a follow up?
The other solution of moving it to base test, means that FlagSimpleTest has to extend base test, or maybe as now most of the things we are testing are in services maybe we should move the tests to that other test class?
Comment #51
socketwench CreditAttribution: socketwench commentedVerified everything appears to be fixed.
We should create a follow up and add it to the count service if it sounds like it has value. That can be done in another issue.
Comment #52
joachim CreditAttribution: joachim commentedArgh, needs a reroll, sorry. My fault for taking too long to get round to committing this.
Comment #53
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedRebased.
Comment #54
BerdirThe description of this could be a bit better. What it basically does is filter on that, if provided. So it should say (optional) and something like If provided, unflags flaggings done to this entity/by this account.
Also, what happens if neither is provided? Delete everything? Is that supported? (There are actually use cases, for example to be able to uninstall flag. Core has default validations that you can't avoid that prevent you from uninstalling a module that has remaining content entities). Should probably be mentioned.
I don't think @see supports a description? What about making this an inline documentation that references that. Combined with the above.
* I actually find "Unflag all flags" quite confusing, the flagging vs flag terminology is tricky. reset() uses "Remove all flagged entities", which is better, but what we actually remove is the flagging, not the entity, so that's kind of confusing too. "Removes all flaggings" might be simpler and clearer? Then we could unify those two descriptions.
Leaving at needs review, lets wait for feedback from @joachim/@socketwench before making changes.
Comment #55
joachim CreditAttribution: joachim commentedYup, I agree with all those points.
> I don't think @see supports a description? What about making this an inline documentation that references that. Combined with the above.
Yup. Also, don't say reset() as that's a core PHP function!
> * I actually find "Unflag all flags" quite confusing, the flagging vs flag terminology is tricky. reset() uses "Remove all flagged entities", which is better, but what we actually remove is the flagging, not the entity, so that's kind of confusing too. "Removes all flaggings" might be simpler and clearer? Then we could unify those two descriptions.
Yup. "Remove all flaggings made with this flag / on this entity" is the clearest.
Comment #56
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedRebased and applied those changes.
I deleted the @see as FlagServiceInterface doesn't define the reset() anymore.
Comment #57
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedEverything looks good except this comment is missing:
Comment #58
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedAdded this comments and changed the short description to "Remove all flaggings from an entity / made by an account."
I think has more sense as this method never removes for a flag, always remove on all the flags just depending on the entity or account.
Comment #59
LKS90 CreditAttribution: LKS90 at MD Systems GmbH commentedI think the comments should be correct and explanatory now, good to go!
Comment #61
joachim CreditAttribution: joachim commentedSorry to knock this back another time :(
There's a few things in unflagAll() that don't quite make sense to me.
Leave this in please -- it's there for commented-out code.
If $entity is specified, the it's the $flaggable, isn't it? So you don't need to keep loading it.
... and if $account wasn't given, you're passing a NULL in here!
While we're rerolling... could this be $node1 and $node2? Or $node and $node_to_delete?
And also $node_id is a bug waiting to happen now :/
This isn't quite right -- it counts flaggings, not flags.
countFlaggings? or getFlaggingCount?
Comment #62
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone all those points, also deleted flag count service that I'm loading and not using, I think was result of one rebase.
Comment #63
BerdirAs @joachim said, I think the $account behavior is not quite correct yet. This documents that NULL = all users. but unflag() is for the current user if it is NULL. So if have no user, you need to pass the user from $flagging to it.
Comment #64
martin107 CreditAttribution: martin107 commentedI think we can refactor flag_user_account_removal() some more- It is the procedural way of sharing common functionality between hooks.
I have moved the logic into the FlagService::userFlagRemoval()
There is still work todo ... so I am just making this change in isolation ... I want to keep the interdiff simple and easy to follow.
I have had a little review and this look like a good change.
It is out of scope but I am going to mention it here just in case it raises things for others.
I was manually going through the steps to both cancel and delete looking to see if anything caused problems
Using /admin/people to delete a account gives these options.
Disable the account and keep its content.
Disable the account and unpublish its content.
Delete the account and make its content belong to the Anonymous user.
Delete the account and its content.
We need a way for the admin to choose to respond in ways that don't delete in every case.
There is nothing wrong with anonymous users flagging content - I will file an issue for that.
Comment #65
Berdir@martin107: I think that .patch.txt file should just be .patch?
Comment #66
martin107 CreditAttribution: martin107 commentedNuts ....so much for simple and easy to follow :(
Comment #67
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedSorry for add the interdiff with the patch 62, but I could not apply the patch 64 so I added those changes manually.
I fixed the comment 63.
Comment #68
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedSorry for deliting your file from the file list, but I didn't want to do that, drupal.org did that when I Saved my comment, and your post was already posted :( And I don't have any option tho make it appear again, I don't like how it works when more than one are publishing at the same time.
And we discused with @Berdir that we should create a followup to remove the flags in predelete instead of in delete, so we have to implement flag_user_predelete
Comment #69
martin107 CreditAttribution: martin107 commentedThe merging of patches looks good to me.I can see another problem .. with FlagService not the last patchI am going to create a new side issue but I should talk about it here because if we cannot resolve this independently then it makes the approach taken here bad.The issue is between\Drupal\user\UserInterface
\Drupal\Core\Session\AccountInterface;AccountInterface is the larger superset containing all of UserInterface.The patch introduces UserInterface as an ugly ducking method parameter to FlagService - all other methods use AccountInterface.Regarding the flow of a UserInterface variable flowing into the serviceflag_user_delete() -> FlagService::userFlagRemoval() -> FlagService::unFlagAll() -> FlagService::getFlagging/FlagService::unflag()So I think we need to make some flag and flagging calls work with the more limited UserInterface.Anyway I will create the issue tomorrow.Comment #70
BerdirNo, it's the other way round. UserInterface extends AccountInterface. A user entity is always an account, but an account can also be something else, like the session object/object for the anonymous user.
So, it is perfectly valid to pass a UserInterface into a method that accepts AccountInterface.
Comment #71
martin107 CreditAttribution: martin107 commentedHangs head in shame.... to make up for my mistake.
Here is a fix to ugly duckling problem ...now all FlagServices use the AccountInterface.
Comment #72
BerdirI actually think it was correct before.
UserInterface was correct.
We are calling two things here, and we pass it both to the first and the second argument. The first expects an EntityInterface.
UserInterface extends from EntityInterface and AccountInterface, and is therefore the only correct type hint.
Comment #73
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedThen, no need to set it to needs work, the previous patch was just fine.
Not related with this issue:
I know why my comment deleted your file, because both of the patches had the same name, This is a bug of drupal.org site, not sure where to report it, the files maybe need some kind of unic id.
Comment #74
BerdirRight. RTBC'ing the patch in #67.
This and #2562971: Flag bookmark view is broken are the two patches that I have still applied in our install profile, would love to get rid of them.
Comment #75
socketwench CreditAttribution: socketwench commented#67 no longer applies
Comment #76
socketwench CreditAttribution: socketwench commentedComment #78
socketwench CreditAttribution: socketwench commentedSince the conflicts were only comment changes from another issue, there's no need to re-review. Committing.
Thanks everyone!