[Agavi-Users] Nested Actions: Validation, Slots and the FPF

17 views
Skip to first unread message

Michal Charemza

unread,
Feb 18, 2009, 2:36:27 AM2/18/09
to Agavi Users Mailing List
I'm having trouble getting validation and the Form Population Filter
(FPF) to work as I expect, when the action that processes the form is
called as a slot within another action. I wonder if just my
understanding of what is going on is wrong. I have some general
questions:

- What is the data 'flow' of input (say, from the actual $_POST
variable), through validation and into an action (where it ends up as
the AgaviRequestDataHolder).

- What is the data 'flow' of input through validation and into an
action called within another action. Is the validation from the
*outer* action also applied?

- How are these 'flows' different if there is a validation error?

- At which stage does the FPF get its data? At what stage do the
validation errors get passed to the FPF?

Sorry if I'm being a bit vague with the word 'flow', I'm not sure what
would be a better word.

Michal.


_______________________________________________
users mailing list
us...@lists.agavi.org
http://lists.agavi.org/mailman/listinfo/users

Michal Charemza

unread,
Feb 19, 2009, 10:55:09 AM2/19/09
to Agavi Users Mailing List
Ok, maybe I should be specific with my issue. It is a very similar
issue to one I posted previously about (although it is now with
different outer/inner actions, hence I suspect my understanding is
off...)

I have a form that is output in the view of an action, which is itself
called as a slot (and so called 'within', if that's the right word,
another action). In the Error view of the inner action I now have the
following code:

$vm = $this->container->getValidationManager();
$errors = $vm->getErrors();
$this->setAttribute('errors', $errors);

I can manually output the errors in the template, using $t['errors'].
*However* I would prefer to use the FPF. The FPF seems to work in
other forms in the app, but not this one. Somehow the errors are 'in'
the validation manager, but they don't get to the FPF. Any suggestions?

Sorry if I'm being a bit pushy with this issue, but it is slightly
driving me crazy...

Michal.

Felix Gilcher

unread,
Feb 20, 2009, 6:39:05 AM2/20/09
to Agavi Users Mailing List
Hi Michal,

I do understand your problem, but that's not answered as quickly as
the other questions, so I need a little time to whip up a sample and
give you a proper answer. I might have a little time to spare this
weekend, so just be a little patient, you'll get your answer.

cheers

felix

Michal

unread,
Feb 20, 2009, 6:53:11 AM2/20/09
to Agavi Users Mailing List
Thanks! Sorry if I was being a bit impatient... I know it might make
me look a bit ungrateful (on other lists it annoys me when I see other
be impatient, and then I go and do the same thing myself...)

Michal.

Felix Gilcher

unread,
Feb 20, 2009, 7:42:28 AM2/20/09
to Agavi Users Mailing List
Hey,

I didn't want to imply that you were pushing things - I just wanted to
say that we've read your mail and are working on getting you a proper
response :)

cheers

felix

David Zülke

unread,
Feb 20, 2009, 11:43:04 AM2/20/09
to Agavi Users Mailing List
Hi Mihal,

FPF has several modes of operation. In the usual configuration, it
scans the result document on POST requests and looks for forms where
the "action" matches the current URL. It then re-fills this form using
data from the current request (using the global request data object),
and looks at the *initial* execution container's validation report
object for errors during validation.
It can be configured at runtime to work on specific forms (like by ID,
or by specific URLs), skip certain fields, populate forms using data
you define etc.

Anyway, one major issue with your approach is that you seem to be
POSTing to the "post" action, relying on the fact that it loads a slot
for the comments which then creates the comment in that special case.
That's really, really wrong from a logical point of view, and it also
violates the principles of HTTP, not to mention proper separation of
concerns.
What you should do is post to an "AddComment" action or so, and, on
success, *redirect* back to the post page. On error, you would
*forward* back to the post page (which contains a slot for the
comments form again).
However, that won't solve your problem - the validation report is in
the AddComment action's execution container, so FPF will not see the
validation errors.

That's quite unfortunate, and I'm mildly surprised that nobody has
come up with this issue so far. Anyway, in 1.0-HEAD, you have the
ability to specify an explicit validation report object for FPF to use
instead of the current container's (http://trac.agavi.org/ticket/
1050). That should solve your problem. So in your AddCommentErrorView,
you'd do something like:
$this->getContext()->getRequest()-
>setAttribute('validation_report', $this->getContainer()-
>getValidationManager()->getReport(),
'org.agavi.filter.FormPopulationFilter');
return $this->createForwardContainer('Module', 'ViewPost');

Hope that helps,

- David

David Zülke

unread,
Feb 20, 2009, 11:47:54 AM2/20/09
to Agavi Users Mailing List
On 18.02.2009, at 08:36, Michal Charemza wrote:

> I'm having trouble getting validation and the Form Population Filter
> (FPF) to work as I expect, when the action that processes the form is
> called as a slot within another action. I wonder if just my
> understanding of what is going on is wrong. I have some general
> questions:

You shouldn't do that under any circumstance; my other mail explains
that.


> - What is the data 'flow' of input (say, from the actual $_POST
> variable), through validation and into an action (where it ends up as
> the AgaviRequestDataHolder).

Uhm... yes? :p That's how it works. On startup, the framework
populates the "global" request data object you don't have access to in
actions and views. Every container receives a copy of this.


> - What is the data 'flow' of input through validation and into an
> action called within another action. Is the validation from the
> *outer* action also applied?

No. Each action (slot or not) must validate separately. Note that
containers may be given "arguments" to work with, which are merged
into the request data. A container's request data is, after creation,
simply a copy if the global request data object.
If an action is "simple" (AgaviAction::isSimple()), then there won't
be any request data, only explicitly given arguments. Those don't have
to be validated (validation is not performed for simple actions, and
no filters are run, and no security checks are performed, and the
action isn't run - only the view).


> - How are these 'flows' different if there is a validation error?

They aren't.


> - At which stage does the FPF get its data? At what stage do the
> validation errors get passed to the FPF?

FPF grabs its validation report data from the container that was used
to run the initial request. The data to populate the form with, on the
other hand, comes from the global request data object.

Michal

unread,
Feb 20, 2009, 1:20:44 PM2/20/09
to Agavi Users Mailing List
On Fri, Feb 20, 2009 at 4:43 PM, David Zülke
<david....@bitextender.com> wrote:
> Anyway, one major issue with your approach is that you seem to be POSTing to
> the "post" action, relying on the fact that it loads a slot for the comments
> which then creates the comment in that special case. That's really, really
> wrong from a logical point of view, and it also violates the principles of
> HTTP, not to mention proper separation of concerns.
I do now, finally, see that this is a bad idea. Although perhaps I'm
not clear about the principles of HTTP argument...

> What you should do is post to an "AddComment" action or so, and, on success,
> *redirect* back to the post page. On error, you would *forward* back to the
> post page (which contains a slot for the comments form again).

I think I am finally getting you...So I should have a route that
routes only to the AddComment action. However, I'm thinking that the
URL for the AddComment action should actually be the same as the
ShowPost action. This is because, in case of errors, I would expect to
stay at the same page, and not move anywhere else.

So, I could have a hidden value in the form, say "isCommentSubmision".
Would it be possible (and also would it be an ok solution) to route
based on this value as a POST variable? How would this be done? But is
this a bad idea?

> However, that won't solve your problem - the validation report is in the
> AddComment action's execution container, so FPF will not see the validation
> errors.
>
> That's quite unfortunate, and I'm mildly surprised that nobody has come up
> with this issue so far. Anyway, in 1.0-HEAD, you have the ability to specify
> an explicit validation report object for FPF to use instead of the current

> container's (http://trac.agavi.org/ticket/1050). That should solve your


> problem. So in your AddCommentErrorView, you'd do something like:
> $this->getContext()->getRequest()->setAttribute('validation_report',
> $this->getContainer()->getValidationManager()->getReport(),
> 'org.agavi.filter.FormPopulationFilter');
> return $this->createForwardContainer('Module', 'ViewPost');

Thanks: I will try this,

Thanks again,

Reply all
Reply to author
Forward
0 new messages