[TYPO3-ect] Draft: Specification of Dispatch and Action Controller Framework

Michael Scharkow mscharkow at gmx.net
Fri Mar 24 10:18:47 CET 2006


Elmar Hinz wrote:
> Hello Typonics,
> 
> this is the conception of the controller framework I am currently
> working on. It is an extension of the action controller proposed by
> Michael Scharkow.

Hi Elmar,

thanks for the great job in writing this. I can hardly wait for the 
implementation.

> Switching
> 
> The first step every controller does, is to switch the incomming
> request to an appropriate controller subpart that is programmed for
> the requierements of the request. It is typically indicated by
> parameters that are send with the request, wich subpart should be run.
> The subpart and the parameters are called action.

In TYPO3, this is done via a tt_content record on a page that calls an 
extension class (currently of pi_base inheritance). I find this still a 
very good way to connect content with plugins. It also manages caching.

> The Action Controller
> 
> The action controller is steered by the parameter action and calls a
> method of the same name with the suffix "Action". If the parameter
> value is "sendPdf" the method "sendPdfAction" is called to handle the
> request.
> 
> If no action is send, the action "defaultAction" is called. You can
> set an other name for the default action like "indexAction".
> If an unknown action is called the action "unknownAction" is called.
> By default this action sends the header 404. You could alter the
> action to give back an informational text or to throw an error.
> You can overwrite the default names of the action parameter, the
> action suffix, the default action and the unknown Action.

I agree to this but have a few comments:

1. Why append Action to every class method? I prefer less typing...
2. Is it more elegant to set $this->defaultAction = 'index' (some people 
would probably even add a setter-method for this), or leave this by 
convention to the index method that *can* call any other method anyway:

function index() {
	return $this->listLatestNews();
}

> The DispatchController
> 
> The dispatch controller is steered by the parameter controller and
> calls an ation controller class of an matching name. If the parameter
> value is "edit" the class tx_myext_controllers_edit is called to
> handle the request.

Let's say we keep the one content type->one plugin class paradigm in 
TYPO3 FE, so that

class.tx_myextension_pi1_controller is called per default. This 
controller can have exposed methods index() and foo(). If you need to 
split the controller up (because it gets too large), you create 
class.tx_myextension_pi_controller_edit in the controllers dir, and the 
controller class checks for this subcontroller class like it checks for 
methods. If it exists, than the subcontroller is instanciated with a 
reference to the current environment (we need to talk about the 
environment soon), and its main() method is returned.

I still expect this kind of recursion to be very rare!

> You can add new action controllers in extensions. If the parameter
> "plusExt__edit" (double underscore) is given then the class
> tx_plusExt_controllers_edit is called. It is a shortcut for
> "plusExt_controllers_edit" which would also work. If an controller
> stays in the "irregular" extension directoy abc/xyz the parameter has
> to be "plusExt_abc_xyz_edit". If the controller stays in the extension
> main directory the parameter is "plusExt_edit" (single underscore).

While I do like the implicity of using naming conventions for these 
hooks, I have a few concerns about security because you *could* call any 
class with an external (unchecked) parameter.

I propose to instead use an action registration like with XClasses or 
Hooks in TYPO3 used today. With this, you explicitly link a certain 
controller action to a controller class.

$actionRegister['tx_myextension_pi1_controller']['edit'] = 
'tx_anotherext_controller_edit']

This is still as flexible, keeps the list of exposed actions tight and 
secure, enables dynamic overrides of certain actions without inheritance.

So what the basic controller dispatching method does for action foo is:

1. Check if a class for foo is registered in the action register and if 
yes call it

2. Check if a controller class controller_foo exists in the controllers 
dir and if yes call it

3. Check if an exposed method foo() exists and call it

4. Call notFound action

Note that the order of 2 and 3 could be reversed for performance reasons 
but would result in less "magic" if you just want to replace the foo() 
method with a larger foo class.

Greetings,
Michael



More information about the TYPO3-team-extension-coordination mailing list