Hi Jesse,

sorry, I was really busy an not able to answer or even look at your 
mails the last days.

The second mail was much better than the first one. :-) I think you got 
it. Here are some notes/conclusions regarding both of your mails (I 
guess, you got most of them):

Of course the workflow definition is not defined or even expanded in the 
several actions (as you wrote in the first mail). Mostly you define it 
once (via XML or PHP) and then save it to the database. It's important 
to understand the difference between workflow (definition) and workflow 
execution - similar to the difference of classes and objects in 
object-oriented programming: first you define your workflow and then 
you create/access instances (=executions) of that definition.

Also it's important to note that the workflow execution suspends itself 
if the workflow can not continue any more (and is not ended). This 
could happen in two cases: there is an input node waiting for some 
input variables or a service object where the execute() method 
returns "false". In both cases the workflow is suspended. The execution 
id is the main thing to find and resume() the workflow execution 
later - this needs to be saved in what you call "workpool".

I also want to mention that there is a concept called "variable 
handler". The difference to execution variables: if the workflow is 
resumed (resp. suspended) the variable is loaded (resp. stored) via the 
variable handler's logic. The advantage: if the variable (in your case 
the article object) is updated in between, it is always the actual 
version, you refer to in the workflow. (Also, you do not duplicate the 
article's data.) Another possibility not to duplicate the article could 
be, to have the article object only in the workflow execution but not 
in the "normal" database. Thus the database is only filled with the 
object if it is approved an published. But this depends on your 
scenario (and in the latter case you can access the article only via 
the workflow execution that stores it).

See some few notes below...

Am Dienstag, 2. Oktober 2007 schrieb Jesse Sanford:
> Thomas, After sending that last email I just realized a few things.
>
> First of all lets say that I have the workflow described in that last
> email
> programmatically all defined within an xml file or saved in the
> database tiein.
>
> Let's also say I removed the first input node. Since it wasn't really
> needed
> there is no reason to have it there. If we are creating a new article
> we can
> assume the content has already been created for it.
>
> Now the first node after the start Node should be the input node that
> waits
> for an editors approval (former $input2 node from my last email)
>
> So let's begin again...
>
> I create a new article object and hydrate it with the users input.
> Then I
> would simply load a new copy of that workflow a storage object.
>
> New($articleBody) {
>
> /* instantiate new article object */
>
> $article = new article($articleBody);
>
> /* load workflow from database and instantiate workflow variable */
>
> $db = ezcDBFactory::create( 'mysql://[EMAIL PROTECTED]/test' );
>
> $definition = new ezcWorkflowDatabaseDefinitionStorage( $db );
> $workflow = $definition->loadByName( ' articlePublishing' );
>
> /* Then I would start the workflow */
>
> $execution = new ezcWorkflowDatabaseExecution( $db );
>
> $execution->workflow - $workflow;

Perhaps you want to do something like:

    $execution->setVariable( 'article', $article );

> $id = $execution->start();

or (if the first input node waits for the article):

    $execution->start();
    $execution->resume( array( 'article', $article ) );

> $article->workflowId = $id;
> $article->state = "waiting for approval";
> }

One thing, that seems to be not that nice: you store the execution id in 
the article ($article->workflowId). That's not that nice from an 
object-oriented view as it is not part of the article object. Without 
any good reason it seems to be better if this is stored only in 
the "workpool".

> Then I would end the new() article action. 

Don't forget to store the execution id in the workpool. :-)

> So the execution would 
> presumably
> start then hit the first input node and then wait. I would need to
> store this input $id and a description of this workflow somewhere so
> that the editor could review it correct? Lets just say I store it in
> the new article
> object.

Yes and No. As written above: store the id in the workpool and not in 
the article. First this data is not part of the entity "article". Then: 
it's much easier to find the pending workflows for a user via a 
workpool if there are several objects (not only articles but perhaps 
also forum posts or blog comments, ...). If needed just store some 
metadata in the workpool (e.g. the workflow cares about an article or 
whatever). (Of course there may be a situation where it should be 
appropriate to store the execution id in the article - but I can't 
imagine at the moment for your situation.)

> So the editor logs in. I querry my workpool table and find all the
> $ids for
> workflows that are now waiting for approval.
>
> I pick up that article attached to that $id and show the view for the
> approval screen.
>
> The editor pushes the approve button.
>
> The controller for the article object then fires it's approved action
>
> The approved action resumes the workflow with the "approval variable
> set to
> true (reference the last email for the approval conditional nodes and
> variables)
>
> Approved($article) {
>
> $article->approved = true;
>
> $db = ezcDBFactory::create( 'mysql://[EMAIL PROTECTED]/test' );
> $execution = new ezcWorkflowDatabaseExecution( $db,
> $article->workflowId );
> $execution->resume( array('approval' => true ) );
>
> $article->state = "approved waiting for publish";
>
> }

I do not really get, why you save the state information in two places: 
$article->approved and $article->state. Probably this is redundant 
information... (The same to $article->published below.)

> Then the workflow executes the $approvedNode branch and (any service
> objects
> attached to it correct?) and comes to a stop when it reaches the
> input node
> for publishing (former $input3 in last email)
>
> So now I close the approved action.
>
> Then the editor decides to publish this article so he goes into the
> view for
> the publish screen and clicks the publish button for this article.
>
> The published action on the article fires
>
> Published($article) {
>
> $article->published = true;
>
> $db = ezcDBFactory::create( 'mysql://[EMAIL PROTECTED]/test' );
> $execution = new ezcWorkflowDatabaseExecution( $db,
> $article->workflowId );
> $execution->resume( array('published' => true ) );
>
> $article->state = "published";
>
> }
>
> The workflow execution continues. The $publishedNode branch executes
> (any
> service objects attached to the $publishNode fire) and then the
> workflow moves on to the $merge (see last email) and then goes on to
> the end node thus finishing the workflow (correct?) does the workflow
> finish even though
> only one of the paths had been executed preceding the merge? Does it
> wait
> for anything else before the merge fires it's outNode?

Regarding end nodes: in general, if an end node is reached, the workflow 
is ended - even if there is a branch that is not finished. This is 
because of the implicit ending of the workflow execution if an end node 
is reached.

If I understood you correctly, you have a merge node just before the end 
node. It depends on the merge node, if this activates its out node (the 
end node) e.g. when the first branch comes in or when all branches 
reached the merge node. So it's not the end node that's important here 
but the type of the merging node.

Hope that answered your questions. If not - just ask...

Have a nice day

Thomas


> Thanks again for all your help,
> Jesse
>
> On 9/26/07 9:18 AM, "Thomas Nunninger" <[EMAIL PROTECTED]> wrote:
> > One general note (as this is not the first request regarding
> > workflows to my personal email):
> >
> > Regarding questions about the workflow components (or others),
> > allways write to the eZ Components list. That way you ensure that
> > other people can profit or answer as well. I will allways post to
> > the list as well when answering such mails (unless you convince me,
> > why it's better to keep it private).
> >
> >
> > Hi Jesse,
> >
> >> Hi Thomas, I am sorry to bother you today but I am really
> >> interested in using the ezWorkflow component in a project I am
> >> working on but I am having trouble grasping how to incorporate it
> >> into the MVC architecture. Let's say for instance I have created
> >> CRUD screens for content entry. Lets also say that I have some
> >> semblance of a user acl. Now one workflow I have modeled involves
> >> a writer creating a story and then submitting it to an editor for
> >> review before the editor publishes the story. I know we can model
> >> this with a petri-net or a directed graph very easily. I also
> >> assume this can be created within the ezWorkflow component. My
> >> question is how do I get this to actually influence the
> >> Controllers and Views of the model as it gets written then
> >> approved then published.
> >
> > In general you allways need to take care about the execution ids
> > and which user it belongs to. It could be stored in the session or
>
> database
>
> > or provided via a parameter within the request.
> >
> > Sometimes it could be stored within the relevant data of the
> > covered objects. But if you have a more complex situation, I
> > suggest to use a separate table. Such a table could basically
> > contain a column for user (group), execution id and perhaps some
> > additional information if
>
> needed
>
> > (e.g. action).
> >
> > When a user sends an article for publishing, you insert an entry in
>
> the
>
> > table for the next user (group), the execution id and perhaps the
> > additional information. (What the next user group is, could be
> > defined in a special execution variable and read generally from the
> > workflow execution object.).
> >
> > When the editor looks into his account, you could query the table
> > and present him a list with all pending workflows that needs his
> > interaction. He could select one execution and provide the needed
>
> input
>
> > data to trigger the workflow to the next step. (If the workflow is
> > not finished, you could create a new entry in the table.)
> >
> > It could be pretty handy if you create your own
> > application-specific WorkflowUtils class providing easy handling of
> > starting/triggering workflows or fetching a list of all workflows
> > that need input from a special user. Then you can reuse this
> > functionality in several places of your application.
> >
> > Hope this answered your question. If not: just ask...
> >
> > Have a nice day
> >
> > Thomas
> >
> >> Thanks in advance. Your help is greatly appreciated!
> >>
> >> Jesse Sanford


-- 
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components

Reply via email to