I am trying to flag a node in code, and then set the flagging field values.
One method is to use $flag->flag followed by flag_get_entity_flags() with a foreach to iterate through all the results, find the flag id you just created, load it with entity_load, set the field value, wrap it with entity_metadata_wrapper, and then save it.
Another method would be to create the flagging with entity_create, wrap it with entity_metadata_wrapper, and then set the field value directly. It's much cleaner this way. However, entity_create() is returning 0 when I try to create a flagging, and I'm not sure what's going on. Is there something incorrect in my $flag_settings?
$flag_settings = array(
'fid' => 1,
'entity_type' => 'node',
'entity_id' => 4646,
'uid' => 1,
'sid' => 0,
);
$flag = entity_create('flagging', $flag_settings);
// at this point, $flag equal 0 because entity_create fails.
$flag_wrapper = entity_metadata_wrapper('flagging', $flag);
$flag_wrapper->field_myfield = 'myvalue';
//fails because entity_create failed, not sure if EMW works for flaggings
Comment | File | Size | Author |
---|---|---|---|
#13 | flag-entity_create_callback-2162393-13.patch | 1.55 KB | micromegas |
Comments
Comment #1
micromegas CreditAttribution: micromegas commentedComment #2
micromegas CreditAttribution: micromegas commentedremoved EMW info, since I confirmed that flags are working with EMW. Still can't get entity_create to work, however.
Comment #3
joachim CreditAttribution: joachim commentedentity_create() returns FALSE for a flagging entity because:
- the flagging entity type has no creation callback defined
- the flagging entity type is not using a controller that implements the entity API interface
(see http://drupalcontrib.org/api/drupal/contributions!entity!entity.module/f...)
I've already made the decision that we shouldn't add a dependency on Entity API, so that leaves us with the create callback. I'd be fine with that being added, since if Entity API isn't present, nothing will mind.
If you feel like tackling a patch, it should be fine to crib from EntityAPIController::create(). There's not much involved.
What you shouldn't do with the $flagging entity is use entity_save() on it, because that will bypass the flagging API.
You should instead do:
That will take the $flagging as the starting point for the new flagging.
If you can get that to work, could you update https://drupal.org/node/1748148#write-flagging-fields, since, as you say, it's a cleaner approach than performing the flagging then having to go hunting for it.
Comment #4
micromegas CreditAttribution: micromegas commentedI see; the correct workflow would be create the flag with entity_create(), pass it to the flag->flag() method to save it, then change the field values, and then use entity_save()/EMW->save()... hence the need for an entity_create() callback.
Comment #5
joachim CreditAttribution: joachim commentedYou shouldn't use entity_save().
The workflow should be:
The call to $flag->flag() saves the flagging entities as part of the process.
Comment #6
micromegas CreditAttribution: micromegas commentedIsn't entity_metadata_wrapper/entity_save() needed to set/save the flagging field values, after the initial flagging entity is created and saved?
So, in other words, don't use entity_save to create the flag; only use it to save field values on a flag that was already created/saved with $flag->flag. Is this correct? Or is there some way to save field values directly with $flag->flag?
I've got a simple entity_create() callback working and I'll post the patch when it's finished.
Comment #7
joachim CreditAttribution: joachim commentedThe flag API takes care of saving the flagging, which in turn saves the field values.
This code works for me:
Having an entity_create callback would only change the ' $flagging = (object) $values;' line, which isn't much, but it does contribute towards a consistent DX which is a good thing.
Comment #8
joachim CreditAttribution: joachim commentedBTW, https://drupal.org/node/1748148#write-flagging-fields will need updating after this.
Comment #9
micromegas CreditAttribution: micromegas commentedAdded patch for entity_create() callback. Note that it also allows you to specify an fid to keep it consistent with other entity_create() callbacks.
Comment #10
joachim CreditAttribution: joachim commentedThanks for the patch. I like the approach of allowing either the flag name or the fid.
Just a few things that need a tidy-up:
It's either an object or an array, not both ;) I'd say instead 'An unsaved Flagging object containing the property values.' There's a missing full stop too.
isset() is easier to read than array_key_exists(); it's also marginally quicker.
Comments need to be written as full sentences. This needs a capital and a full stop.
Also, I'm not entirely sure when it comes to referencing methods, but $flag::flag() seems a bit of a mixed case to me. flag_flag::flag() identifies the class; $flag->flag() is an example of the typical variable you'd have. I'm ok with whichever you think it clearer.
Comment #11
micromegas CreditAttribution: micromegas commentedAttached patch: fixed comment weirdness and changed to isset().
Comment #13
micromegas CreditAttribution: micromegas commentedPatch was wonky, made a new one.
Comment #14
shabana.navas CreditAttribution: shabana.navas commentedThe patch works perfectly. My example:
I now have a record in field_something for this flagging entity type.
Comment #15
joachim CreditAttribution: joachim commentedThat's great.
I've fixed the whitespace and tweaked the comments a bit to say that this is an Entity API callback
git commit -m "Issue #2162393 by micromegas: Added support for entity_create() to flaggings." --author="micromegas "
Comment #16
micromegas CreditAttribution: micromegas commentedUpdated https://drupal.org/node/1748148.
Comment #17
joachim CreditAttribution: joachim commentedThat's super, thanks!