Aside from not having to add 35 "set a data value" actions just to populate an entity with 35 properties/fields, it would also be very useful in terms of reducing multiple integrity checks. This action would allow you to change multiple properties/fields for an already existing entity in a single action. I guess the condition to check an entity's bundle type would be required in order for a particular entity to be available to this new modify action.
The basis for this feature request comes from discussion in #1322682: Many conditions may result in memory crashes?
fago suggests the following as a potential methodology:
select the entity and the properties in a first step and get forms for all properties then.
Comment | File | Size | Author |
---|---|---|---|
#55 | 1421368-55.patch | 10.6 KB | shubham.prakash |
#45 | rules-modify-entity-action-1421368-44.patch | 11.23 KB | acrazyanimal |
#37 | rules-modify-entity-action-1421368-37.patch | 11.19 KB | acrazyanimal |
#36 | rules-modify-entity-action-1421368-36.patch | 9.51 KB | krlucas |
#35 | rules-modify-entity-action-1421368-35.patch | 9.83 KB | krlucas |
Comments
Comment #1
fagoYep, I think that would be a very useful action in many situations. I'd work on it if I'd find the time :/ Still I'm happy to provide directions if anyone wants to take care of it.
Comment #2
AndrzejG CreditAttribution: AndrzejG commentedSomething similar to Components/Rule or Rule Set? They accept as many variables as required.
Recently I added one to my Rules requiring 256 MB memory. Now 512 sometimes crashes. It seems memory hunger increases exponentially or even faster.
Comment #3
acrazyanimal CreditAttribution: acrazyanimal commented@fago: If you have some time to provide some directions I would be happy to start on this. I get how to define rule actions, but the parts that I would find difficult would be the loading of the entity's fields and respective form "setter" elements... and all that jazz.
I can see two potential workflows for this action:
1. first configuration form for the action would be to select the entity you want to modify. Once chosen and "continue" is clicked, all the available fields and properties we know about the entity are loaded. I'm guessing in this case it would mean that all of the current values for every element would have to be loaded and saved regardless of whether you wanted to only modify a couple of the fields or all of them.
2. the first configuration form for the action would have the same entity selector field, then potentially some ajax to load all the properties and fields as checkboxes to select the ones you want to set. Once everything is chosen and you click continue, the next configuration form would have all those fields loaded for you to set.
Note: I would also want to make this action available even if you have just created the entity in the action before this one.
Comment #4
bojanz CreditAttribution: bojanz commentedVBO has an action like this, so maybe it can be used for inspiration.
(uses entity metadata for properties, just like rules)
Comment #5
acrazyanimal CreditAttribution: acrazyanimal commented@bojanz I've been looking through the views interface for views based on several different entity types including content and when I add the vbo field I haven't come across a "modify entity" action yet. Is it more specific? Can you point me at how to enable such an operation.
I've been browsing through the modify.action.inc file and this seems like the code you are referring to, but I can't figure out how to test it out?
cheers.
Comment #6
bojanz CreditAttribution: bojanz commentedYou should definitely be seeing "Modify entity values" in the VBO field settings (Views UI) for any entity type, including Content.
Retry as admin (if you weren't before), maybe it's a permission issue? And make sure you have the latest -dev (but then you say you found the modify.action.inc file, so it sounds like it is the latest...)
Comment #7
acrazyanimal CreditAttribution: acrazyanimal commentedWeird, I have the latest dev release of views 3.x and am logged in as the site admin, but only see the following in the operations dropdown:
The view is just a simple content based view of 'article' type with title and status fields for display in a table.
Comment #8
bojanz CreditAttribution: bojanz commentedYou need to have the very latest VBO -dev.
Comment #9
acrazyanimal CreditAttribution: acrazyanimal commentedI thought I had the latest dev, but turns out I did not. I see it now. Thanks.
Comment #10
fagoI think that's the way it should work. Thus, we need a "properties" parameter which is just used to determine which properties we are setting. The general workflow for implementing such an action is to
1. implement action_info_alter() to alter in new parameters depending on already settings, i.e. alter in parameters for properties that should be changed.
2. implement action_form_alter() to implement the form-workflow using #ajax and multiple steps. Forms for added-in properties will be automatically generated once the form is reloaded and your alter-info adds in the properties.
An similar example working the same way is the existing 'entity_create' action.
Comment #11
acrazyanimal CreditAttribution: acrazyanimal commentedgreat thanks for the input all. I should actually start working on this tomorrow.
Comment #12
acrazyanimal CreditAttribution: acrazyanimal commented@fago: is there a simple way that I can make a parameter (an array or list) that is displayed as a series of checkboxes? That is the roadblock that I am running into at the moment. I'm just not sure how to display the field options.
Comment #13
fagoYou can define a list-parameter using an options list. I think it's going to be a multiple-select by default though. Still you can alter it using the form_alter callback.
Comment #14
acrazyanimal CreditAttribution: acrazyanimal commentedRight on, that seems to work. I'll see where I can get from here.
Comment #15
acrazyanimal CreditAttribution: acrazyanimal commentedOk here is my initial patch against the latest 7.x-2.x dev branch in git. It works well from what I've tested, but haven't tested in enough scenarios to be certain. Hoping the community will help out. The new action is called 'update entity' and I didn't bother overriding the property selection as checkboxes, because I rather like the select box as it is.
Areas of concern:
1. Not sure if the entity is validated for me or not to make sure we are infact dealing with a proper entity before updating. I think it is, but am relying on
->applyDataSelector
to determine this.2. Not sure if I should check access for particular fields before allowing them to be changed? I am most certainly not doing this at the moment.
3. I disabled ajax from the entity selection widget as it didn't seem to work and consequently not everything appears in the first step or two automatically without pressing a button. Not really an issue, but thought I'd mention it in case you know a work around.
Note: you can go backwards and ultimately change the entity you're updating, but you must first deselect all properties from the listbox, choose your new entity to update, and click the reload button. Consequence of 3rd area of concern above.
In the process of adding this functionality I noticed a few other issues that I'll post as separate issues and upload patches for.
cheers.
Comment #16
acrazyanimal CreditAttribution: acrazyanimal commentedComment #17
acrazyanimal CreditAttribution: acrazyanimal commentedAnyone else what to help test out this baby?
Comment #18
AndrzejG CreditAttribution: AndrzejG commentedMaybe in a few days. Or rather nights..
Comment #20
acrazyanimal CreditAttribution: acrazyanimal commentedLooks like I forgot to add a condition to the access callback for the rule. Its in there now and should pass the tests.
Comment #21
fagoThanks! Here is a review:
It's fine to rely upon really getting an entity.
We should implement an _access callback to incorporate those checks, just as the data_set action does.
Let's better just read our "properties" variable.
Let's come up with a better parameter name. What about just "properties" ? Also, let's fix the label to talk about modifying properties not parameters.
Then, we should use the type 'list' and just define the parameter as usually in hook_rules_action_info() with a constant label like just "Properties".
I think we should add a validation callback that checks that each selected property exists and is writable (has a 'setter callback' set).
That way Rules is going to show errors if a modified property goes away afterwards.
Let's call the action "entity_modify" and "Modify an entity". I think that should better communicate you can use the action for newly created entities too.
Also, there is some whitespace in the empty line.
'data' should be called 'entity' as that's the usual variable name for entities.
Let's say "The entity which should be modified."
Take care of the coding style.
Trailing whitespaces.
Comment #22
acrazyanimal CreditAttribution: acrazyanimal commentedTook me a while to get back to this, but here is an updated version with the changes you recommended fago. I added access checking to it, but I'd like to get your opinion on it. I had problems with the following at least with integration in the ECK module; which could very well just be an issue in the ECK module, but am wondering if other modules may have a similar issue if they may not necessarily use the entity_access hook.
The problem I saw with ECK is simply that $access is always false for all properties so the property list will be empty for all ECK defined entities. If I comment out
(FALSE !== $access) &&
then all the properties show up for the ECK entities. However, it seemed to work flawlessly for user and node entities.Anyway it would be good to get some further feedback. Also, I'm reconsidering the dropdown for properties and making them individual checkboxes since the ajax is somewhat annoying and disorienting with a dropdown.
cheers.
Comment #23
acrazyanimal CreditAttribution: acrazyanimal commentedComment #24
Nick Fedchik CreditAttribution: Nick Fedchik commentedI use VBO operation "Modify entity values (views_bulk_operations_modify_action)".
Well, it's possible to mass add references from some entities (nodes) to one entity.
But impossible to do mass unlink operation.
I hope this patch helps to solve such tasks?
Is it any progress?
Comment #25
acrazyanimal CreditAttribution: acrazyanimal commented@Nick Fedchik: The intention of this new 'modify entity' action is not to mass update lots of entities at the same time, but to be able to modify multiple fields/properties on a single entity rather then having to update them individually using multiple 'set data value' actions. However, you can already use rules to mass update lots of entities in many different ways. You could use the load entity by field value action to load a list of entities and then add a loop to the rule to loop over the entities and perform whatever actions you want on them. In your case load all the entities that are linked to a specific other entity, loop over them, and either use the 'data set value' or this new 'modify entity' action to change the 'link' ... or unlink it as you say. You could also use VBO to pass entities to a rules component that takes in the entities you want to modify and performs the necessary actions on them individually.
Please note that this is not the issue, or queue, to be discussing your particular problem with VBO.
cheers.
Comment #26
bojanz CreditAttribution: bojanz commentedPlus, there's even an open VBO issue for what Nick is describing: #1421656: Extend the "modify entity values" action to add a delete mode for multiple-value properties and fields. So, anyone interested in that can go there and make it happen.
Comment #27
Nick Fedchik CreditAttribution: Nick Fedchik commentedSorry that I miss by my question and thanks for answers - I take a look on that solutions.
Comment #28
acrazyanimal CreditAttribution: acrazyanimal commentedOk I think I have the access stuff nailed down now. This patch includes some changes that assume its okay to modify entities and entity properties that do not have an 'access callback' defined.
Comment #29
acrazyanimal CreditAttribution: acrazyanimal commentedJust tested a little more and it seems with this newer version that includes any updates in the last couple months for rules, I'm now getting an ajax error where I never had one before.
So it seems the form api cannot find the
rules_action_type_form_submit_rebuild
callback function anymore. It works for other actions using this function like 'schedule' action in rules scheduler, but not for the modify entity action. It fails after you select an entity to update and click continue. I have been racking my brain all day but cannot for the life of me figure out how to ensure the callback function can be found.Anyone have suggestions to where I'm going wrong?
After applying the latest patch above you can find the submit callback (
rules_action_type_form_submit_rebuild
) for 'modify entity' on line 333. Here is a snippet of the ajax error:Comment #30
acrazyanimal CreditAttribution: acrazyanimal commentedI'm still having this issue and stuck on it. Hmm, maybe I'll try catching someone on IRC.
Comment #31
acrazyanimal CreditAttribution: acrazyanimal commentedOk so I tried rebuilding the registry for the site and all works perfectly fine. Weird. I have no idea what stopped it from working, but it seems to be just fine.
Anyway if anyone gets around to it, its all ready for review again.
Comment #32
mitchell CreditAttribution: mitchell commentedI tested #28 and can't get past
Fatal error: Call to undefined function rules_action_type_form_submit_rebuild() in .../includes/form.inc on line 1443
, either. So, changing this back to 'needs work'.--
Marked #1721298: Action "Attach Fields" as a duplicate. The intended use case of #1472752: Add an "entity is of bundle" condition might also be covered here. Note from #1240364: Create a new entity: Ease populating custom fields, an important use case to cover in the docs will be loading entities from reference fields and modifying them. Also, raising priority based on the number of duplicate issues.
Comment #33
mitchell CreditAttribution: mitchell commented>
form_alter
&rebuild
See, #1681510: Add plugin factory to UI!
Comment #34
krlucas CreditAttribution: krlucas commentedI applied the patch in #28 and also had the problem with "Fatal error: Call to undefined function rules_action_type_form_submit_rebuild() in .../includes/form.inc on line 1443", even after rebuilding the registry. However I was able to get around the issue by changing:
+ '#submit' => array('rules_action_type_form_submit_rebuild'),
to
+ '#submit' => array('rules_form_submit_rebuild'),
rules_action_type_form_submit_rebuild is in data.eval.inc, not entity.*.inc so it would make sense (to me) that it's not in scope. It just calls rules_form_submit_rebuild then sets $form_state['parameter_mode'] = array(); I don't know if that's needed for this form?
After fixing that I created a Rules component using WSClient module to retrieve a data structure, create a new entity (a node), and modify the entity.
When I tried to assign a property of the data structure that was (in this case) empty to a property of the entity, the whole Entity Modify action failed with a Rules Exception 'The variable or parameter %name is empty.' When I used a Set data action with the empty data property, I get no error.
I tried with my own custom data structure (in a custom module) and also had the same problem when trying to assign NULL values. I'm not sure if this is a problem with how I/WSClient are initializing our data structures or if this patch should prevent an exception in this case.
I'd love help continue with this patch but need a bit of guidance.
Comment #35
krlucas CreditAttribution: krlucas commentedHere's the patch from #28 with the minor change I mention in #34.
Comment #36
krlucas CreditAttribution: krlucas commentedI added an "allow null" to the property info alter callback for the action and that did the trick. I've been using this all day on a project for mapping and importing stuff and so far so good.
Right now, my only complaint is the UI is unwieldy especially with entities with a lot of fields. My current thought would be to get rid of the multi-select in favor of an "Add Another" and "Remove" field buttons.
Comment #37
acrazyanimal CreditAttribution: acrazyanimal commentedOk I think that I have my final version of this patch ready to be committed. Here are the changes that I have made to make it better and work properly:
.
FYI: The patch is also git aware. To commit
git am
can be used.Comment #38
krlucas CreditAttribution: krlucas commentedI have applied the patch and it's working well. The UI improvements are great.
However, some fields have "sub-fields". For instance Addressfield which is required by Drupal Commerce. You can't assign the individual address components using "Modify Entity" the way you can with "Set a Data Value".
Comment #39
acrazyanimal CreditAttribution: acrazyanimal commented@krlucas: Yes you could assign an address field to an address field, but not its sub components. Just like you wouldn't be able to set individual members of a list field. You would only be able to set a list to a list. Thats just the way these things work. In both those cases you would do a set data value like you mentioned or add a value to a list.
Comment #40
krlucas CreditAttribution: krlucas commented@acrazyanimal I understand what you are saying about assigning lists to lists but this seems a little different to me. I'm specifically talking about Fields that describe their underlying property info through the API.
When I use "set a data value", and use the data selector input with an AddressField it reveals:
billing-profile:address:country
or
billing-profile:address:thoroughfare
or
billing-profile:address:[whatever]
as assign-able options.
Unlike a list type which is a numerically indexed collection, AddressField has named components and somehow has provided the data selector in Rules with enough information to show the components.
If I chose "Modify an Entity", chose "billing-profile", why couldn't
address:country
address:thoroughfare
address:whatever
be available as checkboxes in your new UI? I don't even know if you can create an entity-less field data structure with Rules so just having "address" might not be helpful.
Not to be too obsessed with Addressfield or complex fields in general--it could be a future enhancement. I'm willing to mark as tested and reviewed if you think handling complex Fields is outside the scope of this patch.
Comment #41
krlucas CreditAttribution: krlucas commentedIn #37 the throw of RulesEvaluationException in rules_action_entity_modify references $settings['entity:select'] which is not defined in that context.
Comment #42
acrazyanimal CreditAttribution: acrazyanimal commented@krlucas: can you provide a little more feedback as to how you produced the exception you're seeing? I don't fully understand what you mean by:
What context? Or is that the error message you see?
Regardless if you could explain how to reproduce the error it would really help. thx.
Also, as for your feedback in #40, I understand what you're saying and I agree that would be totally awesome, but perhaps would be best suited for a later enhancement. It would require really reworking the UI and would make it super complex. As far as I know you cannot create an entity-less field but you could at least copy the value(s) from one entity to another. That is where I have found it most useful.
For a multi-value field like an address field I would think you should at least be able to switch to direct input method to fill out the individual fields? no?
Comment #43
acrazyanimal CreditAttribution: acrazyanimal commentedHmmm ... just checked out modifying an entity with an address field and no, you cannot use the direct data input method. The option doesn't even show up. Too bad. :(
Comment #44
krlucas CreditAttribution: krlucas commented@acrazyanimal sorry for being vague.
On line 153 of the patched version of entity.eval.inc the variable $settings is referenced but is never defined in the function:
This results in unhelpful exception messages like 'Unable to modify the "whatever" property for "": '.
Regarding multi-columned fields, I don't think the UI would change much at all. Just instead of having one checkbox for an "field_my_addressfield" instance you'd have a checkbox for field_my_addressfield:country, field_my_addressfield:city, field_my_addressfield:state, etc... But, anyway, better to get this RTBC first.
Comment #45
acrazyanimal CreditAttribution: acrazyanimal commentedFound another issue with the checkboxes wanting a default value. Fixed that an what @krlucas mentions in 44.
Comment #46
rudy2342 CreditAttribution: rudy2342 commented#45: rules-modify-entity-action-1421368-44.patch queued for re-testing.
Comment #46.0
rudy2342 CreditAttribution: rudy2342 commentedForgot to remove some pasted in text.
Comment #47
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedthis seems, well, brilliant.
can I export the "modify entity" action as part of a feature?
Comment #48
TR CreditAttribution: TR commentedPatch in #45 still applies.
This issue still needs reviews!
Comment #49
sano CreditAttribution: sano commentedApplied #45 patch and tested the action. The only issue I encountered is with "body" field, which expects type "Field_item_textsummary". I do not know how to provide it "from scratch" (as opposed to copying it from existing entity). A workaround is to use "Set a data value" action just for this field, because that action accepts text as an input (does not force use of "Field_item_textsummary").
Comment #50
TR CreditAttribution: TR commentedComment #51
delacosta456 CreditAttribution: delacosta456 commented# very nice ... i love this idea
please when will it be RTBC ?
Thanks
Comment #52
TR CreditAttribution: TR commented@delacosta456: First, we've only had one review, #49, and that pointed out a problem. Someone needs to look at that problem and address it. You could also provide a review yourself - what did you test, did it work, were there any problems, etc. Second, I just triggered a re-test on the patch from #45 and you can see it no longer applies. It needs to be re-rolled to apply to the current development version of Rules. Third, the css needs to be fixed to include RTL styles. We finally got all the other css fixed in Rules after many years (see #2759199: RTL Rules Components tab), so I'm not about to go and break it again. Fourth, there are no test cases!
Regardless, these are all fairly easy things to do, but if no one in the community is willing to put in even a small amount of work to get these done then that indicates to me this isn't a priority. Introducing new features can be tricky when you have 300,000 users - there is a possibility of breaking sites - so I need to see that some care and attention has been put into this.
Comment #53
delacosta456 CreditAttribution: delacosta456 commentedhi @TR ok many thanks on my own side i will try it and see what happen's
Comment #54
TR CreditAttribution: TR commentedComment #55
shubham.prakash CreditAttribution: shubham.prakash at OpenSense Labs commentedComment #56
delacosta456 CreditAttribution: delacosta456 commentedhi
i just try for some days patch #55
the patch applied correctly on latest D7. on top of with distro Panoply 7.x-1.71 is built .(php 7.1.30 +mysql 5.7)
The strange behavior i am getting while testing is that for an Event of "After saving node" action "Modify an entity" doesn't list the title field .
Thanks
Comment #57
sano CreditAttribution: sano commentedIf the a value for the "published status" param is provided, the action will always set it to "Published", regardless of the value specified. I used the Data selector to specify the value.