I have a node flag and all configurations are working fine. I have a field created for the flag to track some additional details related to the flag.
I tried using flagging_save() function to grammatically save new flags based on some logic. It shows a error as
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'entity_id' cannot be null: INSERT INTO {field_data_message_subscribe_email_freq} (entity_type, entity_id, revision_id, bundle, delta, language, message_subscribe_email_freq_value) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6); Array
(
[:db_insert_placeholder_0] => flagging
[:db_insert_placeholder_1] =>
[:db_insert_placeholder_2] =>
[:db_insert_placeholder_3] => email_node
[:db_insert_placeholder_4] => 0
[:db_insert_placeholder_5] => und
[:db_insert_placeholder_6] => email
)
in field_sql_storage_field_storage_write()
If the flag don't have the field then it works fine.
Hth,
Sadashiv.
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | flag_flagging-update-exception-with-field-2541072-3.patch | 1.14 KB | firewaller |
Comments
Comment #1
sadashiv commentedHi,
I tried to debug and found that this happens only if the node is already flagged. i.e. The user has already flagged the content and we try to flag it again using flagging_save.
I checked in code and found that incase the flag already exist then the code invokes flagging_update and in case of new flag it invokes flagging_insert functions.
flagging_update invokes field_attach_presave('flagging', $flagging);
Here the flagging don't have flagging_id set so the entity_id goes as null and the field update/insert fails.
Have fixed it in attached patch.
Thanks,
Sadashiv.
Comment #2
joachim commentedI follow your explanation, but I don't understand how you're missing the flagging ID. If you're passing an existing flagging to flagging_save(), then isn't it your responsibility to have the existing ID set on it?
Comment #3
sadashiv commentedHi,
I don't know whether the flag exist or not so I am trying to create a new flagging so am calling flagging_save without flagging id.
I think the check is already made by the flag function in include/flag/flag_flag.inc file before flagging. So if the flag exists it's calling flagging_update else it call flagging_insert.
When it calls flagging_update it is the modules responsibility to pass the existing_flagging_id and that's what I did in the code.
Steps to replicate this issue.
1) Create a node flag (flag is for page bundle).
2) Create any field for the flag
3) Create a page
4) Flag as the logged in user
5) Now may be some custom module or some import script based on a logic is flagging users where it tries to create a new flagging with the code as
If we don't have fields it works fine.
Hth,
Sadashiv
Comment #4
joachim commented> I don't know whether the flag exist or not so I am trying to create a new flagging so am calling flagging_save without flagging id.
Right, that's the flaw then. If you're using flagging_save(), you're expected to know whether it's a new or an existing flagging, save as if you do node_save().
Comment #5
gokulnk commentedThe API says
So I am assuming that you are passing either the flag_name or flag fid.
Comment #6
joachim commentedYes, you need to ensure the flagging entity has either the flag_name or flag fid. But that's a different thing from the flagging ID.
Comment #7
sadashiv commentedHi,
I am setting flag_name and that's not the problem. The only problem was that I was not checking whether the flag already exists. If I check that it already exists and set the flagging_id then it works. I still think that the flag module can improve some part of it or we can remove some code checking the existing flag.
Thanks,
Sadashiv.
Comment #8
joachim commentedI'm a bit confused about the workflow.
Presumably, if you're working with field data on the flagging, you should load the existing flagging first -- and that will have the flagging ID on it.
Comment #9
sadashiv commentedActually I am using message_subscribe module and as I am introducing it now I want all users of different groups to be subscribed to the group i.e. the group should be flagged by default if the user is a member so I wrote a simple script to load all members of all groups and flag the groups for each member.
As I am installing flag now and a user can be member of the group i.e. single entry in membership table for each user for a particular group I was not checking whether the group is flagged
Then I ran into this error for some reason the few group tried to flag twice for the same user. I checked and found that flag function in flag_flag.inc detects whether the flag exists or not and accordingly calls flagging_insert or flagging_update.
When it calls flagging_update it assumes that the flagging_id is set by the invoking function and in my case it wasn't so it gave me the error. before invoking flagging_update we can set it as we are retrieving it in existing_flag_id so thought of fixing that issue so that if some code don't check whether the content is flagged and invokes the flagging_save and the flag has a field then it won't throw any error but simple update the existing flag.
Hth,
Sadashiv.
Comment #10
heylookalive commentedI've just hit this myself, as said this specific issues crops up when trying to create a new flagging entry when one already exists for that entity ID, flag gets confused, tries to do an update for an entity not yet saved via entity_create.
Comment #11
joachim commentedHmm if you're flagging programmatically, then IIRC it's your responsibility to know whether to do:
or to load the existing flagging entity.
Comment #12
heylookalive commented@joachim yep! my bad :)
Comment #13
firewaller commentedPatch #1 resolved the same issue that was occurring for me.
Comment #14
firewaller commentedActually, the above patch does not address the real issue which is that the flag_confirm() form assumes the "flag" action is always creating a new flagging instance. This is not always the case since the flag_confirm form page is always available regardless of the flagging's status.
Attached is a patch that looks to solve that deeper issue.
Comment #16
firewaller commentedAttached is an updated patch that re-loads the entire flagging entity, which pulls the field values for the confirm form.
Comment #17
joachim commented> This is not always the case since the flag_confirm form page is always available regardless of the flagging's status.
Are you sure about that? My recollection is that once a flagging exists, you get taken to a different form.
Comment #18
firewaller commented@joachim yes, you are correct. But the form is still accessible, which could happen organically if the URL is cached/somebody saves the initial URL.
I understand this is edge case, but the confirm page should not always assume the flagging is new. This simply accounts for that and prevents errors.
Comment #19
ivnishDrupal 7 is EOL. Issue will be closed, but patches are still here