This project is read-only.

Searching for an event triggered on ContentItemCreate when all parts are filled with data BUT not stored in DB

Topics: Customizing Orchard, General, Troubleshooting, Writing modules
Aug 21, 2013 at 5:00 PM
Edited Aug 21, 2013 at 7:29 PM
In systems as SalesForces and MS CRM (certainly many others I don't know or forget) , the Pre Create Event is triggered before data are stored in DB but with all the data filled with value to store.
(The post Create Event is triggered with values stored and a copy of values before store).
That's an easy way to do last minute adaptations and checking for errors.

In Orchard, the OnCreating event is triggered on a part basis in the processing order, so all parts are not filled with values when you enter some events.
The OnCreating event for a Part should be triggered after all parts in the ContentItem are filled with data and after base error checking.

This event is useless when one of the parts needs to use data from its siders parts in the contentItem.

Is there a way to do what I am looking for.

I opened an issue here
Aug 21, 2013 at 9:32 PM
Found a partial solution using Request Form but useless when trying to deal with fields, especially media library picker fields.
Aug 22, 2013 at 8:10 AM
Edited Aug 22, 2013 at 8:10 AM
I believe this was fixed, so that when you handle the Created event, the parts have data that come from the database.

However, if you need the posted data, the parts won't be updated until the Updated event, because first all of the drivers must be triggered to do their work. I don't think this is an issue, but by design.
I'm curious though what the use case is to have to access form values in the Created event.
Aug 22, 2013 at 8:22 AM
Edited Aug 22, 2013 at 8:23 AM
My problem is more in the Creating than in the created, I cited Created to be complete.
And I can't find a solution in Orchard to have an action triggered before database insert but after all data in parts, I am not a programing newbie and know the concept of 'by design' :), and also of improving design :)
To answer your question, accessing form values in an after trigger could be useful to trigger a workflow, let's take the case of an order were some pre event has changed something, you can't trigger the workflow before being sure that it is the final modification, so you need to trigger it in the post event.
Aug 22, 2013 at 8:35 AM
Edited Aug 22, 2013 at 8:40 AM
Part of the problem seems to be a kind of 'atomic transaction level' of operation fixed on ContentPart rather than ContentItem: Orchard stores some parts of a contentItem before all the others get their data.

Process being:
0) for each part in contentitem
1) collect part data
2) trigger creating event
3) save part
4) trigger created

Should be better to have an 'atomic level' on the contentItem and a phasing as this
1) collect all data in parts
2) Trigger creating event
3) Save all parts
4) Trigger created event

NB I use the term of transaction level without any relation with orchard actual transactions (?)
Aug 22, 2013 at 8:43 AM
Edited Aug 22, 2013 at 8:45 AM
One solution could be a 'system part' which is always the last to be interpreted, so all the others would have get their data, but this turn around is not perfect and I don't know how to force a part to be the last in the process ?
Or better a flag saying, this part is the last in the contentItem, in order to be able to apply on several kind of custom parts.
Aug 22, 2013 at 8:46 AM
Edited Aug 22, 2013 at 8:48 AM
Ok, but even if you could access the posted data through the content item in the Creating event, that would mean the content item needs to be loaded and then immediately updated with the form values. But that means the content item is changed at that point, and these changes will be persisted at the end of the HTTP request, unless you cancel the transaction. But the Created event is not intended to handle updating the content item with form values. The created event may be triggered from anywhere else in the pipeline, even when there's no post back. That's why we have the UpdateEditor method, triggering UpdateShapeEditor something on the content handlers.
What you maybe could do yourself is clone the created content item in memory, detached from the current transaction (if that's even possible), perform an UpdateEditor on it, and pass that clone to a workflow (to use your example).
But perhaps I misunderstood what you're saying so I may be completely missing the point.

Edit: you could new up a content item, and not Create it, so it will not be persisted at the end if you don't want to.
Aug 22, 2013 at 9:10 AM
Edited Aug 22, 2013 at 9:15 AM
The problem is not the form value, I took this as a turn around, I need to catch every creation with internal .New, with post back, form, and any other if there are.
Cloning something is not a solution as I need to act on each occurence which will be saved...and too complicated.

This clearly appears to me as a weakness in Orchard data processing.

As it appears that separating the contentitem store process in phases seems totally impracticable, the only option left is to have a dedicated part able to be saved in last position ? May be simply inserting it in last position in the content item as it seems Orchards respects the order parts are inserted in a contentitem (very fragile)
Aug 22, 2013 at 9:29 AM
I'm afraid I'm not seeing the issue, what you're exactly saying or trying to achieve. But that's me.
Perhaps you could create a fork, implement your envisioned changes, and demo it on one of the weekly meetings?
Unless somebody else sees your point and has a better answer.
Aug 22, 2013 at 9:42 AM
Thanks for trying, I must certainly provide more details...but reading all this thread and what I explained provides a clear view of the Orchard problem I am raising.
Sep 12, 2013 at 5:00 PM
I am now using the 'Updated' event which is the first one where all the parts from the contentitem have received their data, but I must use a flag in my part to trap the first updated event associated with the creating of the contentitem.
It would be nice to have Orchard providing automatically this flag from the Create process flow.
I would also be nice to have access to the Controller ModelState from the UpdateContext.