From: Antti <an...@di...> - 2006-10-07 00:54:02
|
(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 |