Antti Vähäkotamäki
2006-10-07 00:53:58 UTC
(Note: This is a long mail. You might want to start with my request for
comments/approval at the two last paragraphs to decide if you want to read
the rest)
In the last post to this mailing list, about half a year ago I tried to
propose the notion of Action Environments. I still think they would be a nice
thing and in this post I will try to touch on how it would fit in to the
execution chain. So this post is mainly about the Controller class and how it
would control the action execution.
Currently Controller has been used mainly for handling how the content
returned from the Action is sent to the requesting user. Controller however
is in such a position in the request chain that it would be the correct place
to do things also before the Action is executed.
The obivous example for this is XMLRPC where the code which is to be executed
is specified in the xml body of the content. Controller is the suitable place
for parsing this XML and assigning the correct task to be executed along with
the parameters.
I however think that Controller should do even more. I think that Controller
should be the part responsible for what parameters the Action object deals
with and pretty much everything that the action sees of it's environment or
changes in it's environment.
In principle the Controller should control everything that the programmer
might want to change if she was executing the Action manually. So some of the
things now done in Actions execute method (like task resolving and additional
assigning) should be done in the Controller before Actions execution.
The easiest way I see this could be handled is that the Controller is
responsible for setting up the (usually passthrough) Environment for the
Action.
I think that this would make it adequately possible to isolate the Action from
the real Request, but I think that the issue of Action parameters should be
looked at more closely. Currently we have quite a lot of ways to set
parameters for an Action: Parameters fetched from Request (both POST
parameters and GET parameters), parameters parsed using url_additional,
parameters parsed from content (for example xmlrpc), parameters passed in to
the Action's execute call and parameters received from action configuration.
In addition to this there might be some defaults for the parameters and the
programmer might want to change some of the values during execution.
I think that it would be nice if there would be only one set of named
parameters to work with (even if in the background there were many) and all
these different ways to assign parameters would be assigned an order
according to which they would automatically override the previously set
values.
I would suggest that the order (latter overrides former):
1. default parameters for tasks (action)
2. url_additional (controller)
3. GET parameters (controller)
4. POST parameters (controller)
5. content parameters (controller)
6. parameters from action configuration (action.ini)
7. parameters passed to execute (action)
8. parameters assigned during execution (action)
How would these work in practice with Environments?
8. parameters assigned during execution:
$self->param( param => $value );
7. parameters passed to execute:
As currently, moved to action parameters at the beginning of execute.
6. parameters from action configuration:
As currently, first to properties and then to params at the beginning of
execute.
5. content parameters
Controller parses content and sets the parameters to environment:
$environment->param( param => $value );
4. POST parameters
Parsed as currently but already existing GET values are overridden, not
appended as a list. Stored in Request. Default Environment's param call
queries Request for the parameter if no other value is set.
3. GET parameters
Parsed as currently. Stored in Request. Default Environment's param call
queries Request for the parameter if no other value is set.
2. url_additional
Controller parses URL and sets the parameters to environment (after request
is already attached to the environment):
$environment->param_default( param => $value );
1. default parameters for tasks
In the beginning of the task, programmer would place:
$self->param_default( param => value );
For this purpose we should extend ParamContainer to have param_exists and
param_default functions which would tell if some param is touched and sets a
param value only if it is not touched. With them Action and Environment param
calls would (effectively) be something like:
Action param {
if ( $self->param_exists( $param ) {
return $self->param( $param );
}
else {
return $self->env->param( $param );
}
}
Environment param {
if ( $self->param_exists( $param ) {
return $self->param( $param );
}
else {
return $self->request->param( $param );
}
}
I think that all this could be put into the system pretty much so that it
would still retain backwards compatibility. All I can think of which would
break it would be the POST & GET parameters ith the same name combining to an
array (which I have myself always concidered a bug anyway ;))
In addition to this I would like to change the current Action behaviour in
such a way that consecutive Actions executions with the same object would
always have the same starting parameters regardless what happens in steps 7.
and 8.. One way to do this would be to always start the action execute with
an empty set of parameters before appending parameters in steps 6. and 7.
This however might break some existing code that creates an action, sets some
parameters and then launches it. I think a nice way to achieve this kind of
pre-parameterizing could be to set the parameters to the Environment and if
backwards compatibility is needed, Action could place parameters assigned to
it staright to the environment if it is not currently inside the execute
call. Full backwards compatibility can however not be guaranteed in case of
old code reusing the same Action instance multiple times and expecting that
changes to params done inside execute to be available in the next execute -
but I don't think many (of those millions of OI2 developers ;)) use Actions
like that.
Now I would be grateful if somebody discussed/approved my ideas before I start
implementing them. To summarize they are the following:
* An Environment object for Actions through which Action can get all external
data.
* All parameters accessible through one param interface, using defined
override sequence.
* URL additional parameters appended to Environment params in Controller
instead of Action params in Action execute.
* Action params are cleared in the beginning of Action's execute.
- Antti
comments/approval at the two last paragraphs to decide if you want to read
the rest)
In the last post to this mailing list, about half a year ago I tried to
propose the notion of Action Environments. I still think they would be a nice
thing and in this post I will try to touch on how it would fit in to the
execution chain. So this post is mainly about the Controller class and how it
would control the action execution.
Currently Controller has been used mainly for handling how the content
returned from the Action is sent to the requesting user. Controller however
is in such a position in the request chain that it would be the correct place
to do things also before the Action is executed.
The obivous example for this is XMLRPC where the code which is to be executed
is specified in the xml body of the content. Controller is the suitable place
for parsing this XML and assigning the correct task to be executed along with
the parameters.
I however think that Controller should do even more. I think that Controller
should be the part responsible for what parameters the Action object deals
with and pretty much everything that the action sees of it's environment or
changes in it's environment.
In principle the Controller should control everything that the programmer
might want to change if she was executing the Action manually. So some of the
things now done in Actions execute method (like task resolving and additional
assigning) should be done in the Controller before Actions execution.
The easiest way I see this could be handled is that the Controller is
responsible for setting up the (usually passthrough) Environment for the
Action.
I think that this would make it adequately possible to isolate the Action from
the real Request, but I think that the issue of Action parameters should be
looked at more closely. Currently we have quite a lot of ways to set
parameters for an Action: Parameters fetched from Request (both POST
parameters and GET parameters), parameters parsed using url_additional,
parameters parsed from content (for example xmlrpc), parameters passed in to
the Action's execute call and parameters received from action configuration.
In addition to this there might be some defaults for the parameters and the
programmer might want to change some of the values during execution.
I think that it would be nice if there would be only one set of named
parameters to work with (even if in the background there were many) and all
these different ways to assign parameters would be assigned an order
according to which they would automatically override the previously set
values.
I would suggest that the order (latter overrides former):
1. default parameters for tasks (action)
2. url_additional (controller)
3. GET parameters (controller)
4. POST parameters (controller)
5. content parameters (controller)
6. parameters from action configuration (action.ini)
7. parameters passed to execute (action)
8. parameters assigned during execution (action)
How would these work in practice with Environments?
8. parameters assigned during execution:
$self->param( param => $value );
7. parameters passed to execute:
As currently, moved to action parameters at the beginning of execute.
6. parameters from action configuration:
As currently, first to properties and then to params at the beginning of
execute.
5. content parameters
Controller parses content and sets the parameters to environment:
$environment->param( param => $value );
4. POST parameters
Parsed as currently but already existing GET values are overridden, not
appended as a list. Stored in Request. Default Environment's param call
queries Request for the parameter if no other value is set.
3. GET parameters
Parsed as currently. Stored in Request. Default Environment's param call
queries Request for the parameter if no other value is set.
2. url_additional
Controller parses URL and sets the parameters to environment (after request
is already attached to the environment):
$environment->param_default( param => $value );
1. default parameters for tasks
In the beginning of the task, programmer would place:
$self->param_default( param => value );
For this purpose we should extend ParamContainer to have param_exists and
param_default functions which would tell if some param is touched and sets a
param value only if it is not touched. With them Action and Environment param
calls would (effectively) be something like:
Action param {
if ( $self->param_exists( $param ) {
return $self->param( $param );
}
else {
return $self->env->param( $param );
}
}
Environment param {
if ( $self->param_exists( $param ) {
return $self->param( $param );
}
else {
return $self->request->param( $param );
}
}
I think that all this could be put into the system pretty much so that it
would still retain backwards compatibility. All I can think of which would
break it would be the POST & GET parameters ith the same name combining to an
array (which I have myself always concidered a bug anyway ;))
In addition to this I would like to change the current Action behaviour in
such a way that consecutive Actions executions with the same object would
always have the same starting parameters regardless what happens in steps 7.
and 8.. One way to do this would be to always start the action execute with
an empty set of parameters before appending parameters in steps 6. and 7.
This however might break some existing code that creates an action, sets some
parameters and then launches it. I think a nice way to achieve this kind of
pre-parameterizing could be to set the parameters to the Environment and if
backwards compatibility is needed, Action could place parameters assigned to
it staright to the environment if it is not currently inside the execute
call. Full backwards compatibility can however not be guaranteed in case of
old code reusing the same Action instance multiple times and expecting that
changes to params done inside execute to be available in the next execute -
but I don't think many (of those millions of OI2 developers ;)) use Actions
like that.
Now I would be grateful if somebody discussed/approved my ideas before I start
implementing them. To summarize they are the following:
* An Environment object for Actions through which Action can get all external
data.
* All parameters accessible through one param interface, using defined
override sequence.
* URL additional parameters appended to Environment params in Controller
instead of Action params in Action execute.
* Action params are cleared in the beginning of Action's execute.
- Antti