The D7 implementation 'DataSet' has 2 groups of use-cases:
EntityMetadataWrapper
- Set a property on an entity (title, publication date, author-id, ...)
- Set an entity-reference field (target_id)
- Set other fields (complex fields) like Date, Url, ...
In D8 all those action are 'field' actions.
non EntityMetadataWrapper
- Replace passed in $data with passed in $value.
I don't see the when this is useful. This behaviour is activated as a fall-through and probably a mis-configuration.
The actual modification function in D7:
/**
* Action: Modify data.
*/
function rules_action_data_set($wrapper, $value, $settings, $state, $element) {
if ($wrapper instanceof EntityMetadataWrapper) {
try {
// Update the value first then save changes, if possible.
$wrapper->set($value);
}
catch (EntityMetadataWrapperException $e) {
throw new RulesEvaluationException('Unable to modify data "@selector": ' . $e->getMessage(), array('@selector' => $settings['data:select']));
}
// Save changes if a property of a variable has been changed.
if (strpos($element->settings['data:select'], ':') !== FALSE) {
$info = $wrapper->info();
// We always have to save the changes in the parent entity. E.g. when the
// node author is changed, we don't want to save the author but the node.
$state->saveChanges(implode(':', explode(':', $settings['data:select'], -1)), $info['parent']);
}
}
else {
// A not wrapped variable (e.g. a number) is being updated. Just overwrite
// the variable with the new value.
return array('data' => $value);
}
}
@d7
As you can see the action->execute() function trusts on the EntityMetadataWrapper to catch errors.
If non EntityMetadataWrapper object is passed in (as $data), you can simply change it to any other value/type and it will be returned.
@d8
Maybe we should rename this action to "SetField" instead of "SetData". It is the main use-case and doesn't confuse anyone.
The UI-part (with data-selector) then should take care of proper input and, before saving with the wrapper,
As addition in action->execute() we could test proper input before saving with the wrapper.
We try to use TypedDataManager, so then we will have 2 use-cases:
- TypedDataManager / Entities/ Fields
- Primitives (if ever used)
Today I tried to make test coverage, but did not implement anything with TypedDataManager.
If someone can help me with a test to mock an Entity/TypedDataManager setting that would be appreciated.
As in Drupal 7 via the entitymetadatawrapper, in D8 using the typedatamanager we should be able to manipulate any structured data. That may be fields on entities but can also be other data structures.
Did you check TypedDataTest yet? It is quite extensive.
OK, decided to commit the current port to be able to use this action elsewhere.
Assigning to fago for some guidance what else we could possibly need for this action and what we should do about the "allow null" config that does not exist in D8 as far as I can see.
data_set was ported and committed 2 years ago in #14.
What further needs to be done? Perhaps "Needs work" is a better status here. Or perhaps this should be marked as fixed and another issue opened if there is still a problem with it.
Comments
Comment #1
dasjoComment #2
dasjoComment #3
miklComment #4
miklOk, this one requires specialist knowledge:
I made the basic port here, but the aforementioned parts are missing:
https://github.com/mikl/rules/commit/dd6d16d7da2a62ea4bcf6fea605505b26d6...
Comment #5
ndf commentedI'll give it a shot
Comment #6
ndf commentedPR: https://github.com/fago/rules/pull/176
Not ready for reviewing, but added a DataSetTest and a summary function.
Comment #7
ndf commentedThe D7 implementation 'DataSet' has 2 groups of use-cases:
EntityMetadataWrapper
- Set a property on an entity (title, publication date, author-id, ...)
- Set an entity-reference field (target_id)
- Set other fields (complex fields) like Date, Url, ...
In D8 all those action are 'field' actions.
non EntityMetadataWrapper
- Replace passed in $data with passed in $value.
I don't see the when this is useful. This behaviour is activated as a fall-through and probably a mis-configuration.
The actual modification function in D7:
@d7
As you can see the action->execute() function trusts on the EntityMetadataWrapper to catch errors.
If non EntityMetadataWrapper object is passed in (as $data), you can simply change it to any other value/type and it will be returned.
@d8
Maybe we should rename this action to "SetField" instead of "SetData". It is the main use-case and doesn't confuse anyone.
The UI-part (with data-selector) then should take care of proper input and, before saving with the wrapper,
As addition in action->execute() we could test proper input before saving with the wrapper.
Comment #8
ndf commentedTalked with fubi:
We try to use TypedDataManager, so then we will have 2 use-cases:
- TypedDataManager / Entities/ Fields
- Primitives (if ever used)
Today I tried to make test coverage, but did not implement anything with TypedDataManager.
If someone can help me with a test to mock an Entity/TypedDataManager setting that would be appreciated.
Comment #9
dasjoHi nielsdefeyter,
thanks for starting on this one.
As in Drupal 7 via the entitymetadatawrapper, in D8 using the typedatamanager we should be able to manipulate any structured data. That may be fields on entities but can also be other data structures.
Did you check
TypedDataTestyet? It is quite extensive.Comment #10
dasjoI'm unassigning this for now, feel free to pick it up whenever you have time to work on it.
Cheers, dasjo
Comment #11
ndf commentedHi dasjo, unassigned it better yes.
I'll try to make some time for it the next weeks.
Comment #12
klausiI'm going to look into this.
Comment #13
klausiNew pull request is at https://github.com/fago/rules/pull/202 , work in progress.
Comment #15
klausiOK, decided to commit the current port to be able to use this action elsewhere.
Assigning to fago for some guidance what else we could possibly need for this action and what we should do about the "allow null" config that does not exist in D8 as far as I can see.
Comment #16
tr commenteddata_set was ported and committed 2 years ago in #14.
What further needs to be done? Perhaps "Needs work" is a better status here. Or perhaps this should be marked as fixed and another issue opened if there is still a problem with it.
Comment #17
tr commented