I couldn't find a similar issue and think there might be a serious bug unreported as yet. Would be nice, if a developer could assist.
It's about a kind of addressbook implemented with flags. Users may be flagged as a friend to be remembered for later contact. Each user can see how often he's flagged as a friend, i.e. "You've been added to 30 contact lists". Today a user told me his friend-count dropped from 30 to 5 within a couple of days or maybe just a day... you know how precise such reports are...
I started to investigate and found a huge gap between the actual flag_content and the flag_counts table. The flag_content table still shows 30 flags of this type attached to that user. The flag_counts table tells there are only 5 flags.
We recently deleted a bunch of users, and it is very likely some of them were his "friends". So my best guess is, something went wrong when removing these users. Maybe his flag_counts value was deleted and he found 5 new friends afterwards.
Any ideas?
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | flag_count_wrong_1930320-9.patch | 620 bytes | flocondetoile |
| #3 | flag-1930320-3.patch | 594 bytes | boobaa |
Comments
Comment #1
joachim commentedI would have more expected the flag_counts table to be the one with the higher count, as I seem to remember there's an issue about how that doesn't get handled when users are deleted.
Could you try to reproduce this on a dev copy and report your finding & the steps to take please?
Comment #2
boobaaThis issue looks like a copy of #1931170: The {flag_counts} table got out of sync, which does have some code to get the tables in sync again – anyway, I don't know how to reproduce the bug, either. Repeating here: I have proof-read all the code grepping for all the occurences where
{flag_counts}table gets touched, and found nothing that can yield this result.Comment #3
boobaaI have found the root of the problem. It was suspicious that the
{flag_counts}table had the samecountvalue for two differentfidvalues (but the samecontent_typeandcontent_idvalues). So the bug does not exist if there's only one flag type. What's triggering it? Having a close look on what happens on the site when the bug is triggered (and having a great bunch of related d.o issues in my mind) revealed that the problem arises when deleting a user who does have flagged anything, and there's more than one type of flags. So I had another close look on the code, and found the culprit:hook_user_cancel()(andhook_user_delete(), too) callsflag_user_account_removal(), which starts by a left-joinedSELECTon the related tables, but theONclause contains only two of the three indexes:content_idandcontent_type. In other words,fidis missing from theSELECTofflag_user_account_removal(), which means both (all) the flag types will have the samecountvalues when the function returns. This means the counters will definitely be screwed up: two (all) of the counters will have the same value, which belongs to only one of them.Stepping a bit back shows that the
content_typeindex is not needed at all in theONclause, since a flag type may belong to only onecontent_type, which can be clearly seen from the other parts of code of the affected function.Attached is a patch against today's 7.x-2.x git, which applies to 7.x-2.0 (the latest stable release) with some offset, and has been tested locally with satisfying results.
Comment #4
joachim commentedNice job tracking down the bug! :)
Indeed, if you have multiple flags on the same entity type then this join could produce multiple rows, as there will be multiple rows in flag_counts for a given entity type and id!
> $query->leftJoin('flag_counts', 'c', 'fc.entity_id = c.entity_id AND fc.entity_type = c.entity_type');
This does however need fixing on 3.x first, where the table names are different. If you could reroll this on 3.x that would be super :)
Comment #5
Anonymous (not verified) commentedThank you Boobaa, you're a hero!
It's very likely this patch helps in my scenario. We're using round about 15 different flags of all kinds and the issue occurred right after mass user deletion. The patch looks sound enough to be put to production server. I've no opportunity to test it, but will report in case of any side effects.
Comment #6
Anonymous (not verified) commentedBTW, there should be tests for every code changing flag counts. If one update brings the count out of sync, each subsequent update will result in a wrong count, too. What if the count drops below 1?
A "Refresh all flag counts" option in Flag administration would be great, too. Triggering the code of #1931170: The {flag_counts} table got out of sync.
Comment #7
joachim commentedResetting issue statuses.
Comment #8
enricotersi commentedGreat work!
Comment #9
flocondetoileThanks Boobaa,
Same issue with two flags on the same node. the request called when a user is deleted iterate on the two count of the two flag but with the same fid. And then one of the flag is decrease twice (but on each with a starting value which correspond to the count value of the two flag).
Attached the patch port on 7.x-3.x
Comment #10
socketwench commentedI've tested it against 3.3. There seems to be something wrong in HEAD that's causing the automated tests to fail. Not sure if that's just my system.
Comment #11
stevenx commented#9 works for me
running 7.x-3.2+7-dev
Comment #12
joachim commentedLonger term idea for the flag count system: #2157157: Change {flag_counts} table to be a cache. I'd appreciate the opinions of users of the flag count functionality!
Comment #13
joachim commentedCommitted to 3.x. Thanks everyone!
git commit -m "Issue #1930320 by flocondetoile, Boobaa: Fixed error in flag counts caused when a user is deleted and multiple flags are present on the same entities." --author="boobaa "