Controller, Processors and Processor resolvers
Stubbles contains an unique front controller that does all necessary actions for processing a request by delegating the real work to processors. While the front controller does the general process handling (establishing request, session and response instances) a processor contains the logic how to process a specific request. The front controller itself uses processor resolvers to determine which processor is responsible for processing a request. The following article explains how these three components work together and can be used to build MVC applications on top of them.
The front controller
The front controller is used to keep the index.php small and clean. The most simple index.php could look like this:
<?php require '../config/php/config.php'; require stubConfig::getLibPath() . '/stubbles.php'; stubClassLoader::load('net::stubbles::util::stubGeneralInitializer', 'net::stubbles::websites::stubDefaultWebsiteInitializer', 'net::stubbles::websites::stubFrontController' ); $controller = new stubFrontController(new stubDefaultWebsiteInitializer(new stubGeneralInitializer())); $controller->process(); ?>
What we do here is very simple: include the config file, load Stubbles, then load some classes, instantiate the controller and run it.
The front controller takes one argument: a website initializer that is able to initialize the registry (see Using and configuring the registry), provides an initializer to load the interceptors (see Intercepting the processing of requests), and a method to create a processor resolver. For the purpose of the first two check the mentioned documentations, the last one will be described further down.
When the front controller is instantiated it will also create instances of stubRequest, stubSession and stubResponse which will be handed to the processor resolver and the processor later on. By default the controller will create an instance of stubWebRequest and stubPHPSession. This can be customized to any other class implementing the stubRequest respectively the stubSession interface by setting the values net.stubbles.ipo.request.class and net.stubbles.ipo.session.class in the registry to full qualified class names of the classes to use instead. The stubResponse instance can not be configured this way, but the processor itself can change the instance of this class later on.
In the process() method all preinterceptors are called, then the processor itself, and afterwards all postinterceptors. If in one of those steps the request is cancelled only the response will be send. This means, if a preinterceptor cancels the request, the response will be send immediately and neither the subsequent preinterceptors, the processor nor any postinterceptor will be called. If the processor itself cancels the request, no postinterceptor will be called.
The purpose of the processor resolver factory
As the name says, the main purpose of a processor resolver factory is to create a processor resolver. Stubbles delivers the stubProcessorResolverXJConfFactory as a default processor resolver factory, but you can create your own by implementing the stubProcessorResolverFactory interface.
Configuring the stubProcessorResolverXJConfFactory
When using the stubProcessorResolverXJConfFactory it can be configured in config/xml/processors.xml. By default Stubbles offers the following configuration tags:
- defaultResolver stands for the stubDefaultProcessorResolver. It has an required attribute default which should set the processor that is to be returned if the processor request variable is not set or contains an invalid value.
- The defaultResolver contains processor tags which stand for the processor that should be returned. The processor tag has three attributes:
- name describes on which value of the processor request variable this processor will be used.
- type contains the full qualified classname of the processor to use.
- interceptorDescriptor describes the interceptor configuration to use for this processor.
- pageFactoryClass contains the full qualified class name of the page factory to be injected into the processor if the processor implements the net::stubbles::websites::processors::stubPageBasedProcessor interface. See Purpose of the page factory for more informations about page factories.
- The defaultResolver contains processor tags which stand for the processor that should be returned. The processor tag has three attributes:
- simpleResolver stands for the stubSimpleProcessorResolver which can be configured with only one processor via the processor attribute, which should contain the full qualified classname of the processor to use.
For an example utilizing the default resolver see processor configuration in examples/config/xml/processors.xml.
Processor resolvers
A processor resolver is responsible for analysing the request and to create the processor that is able to process the request. Stubbles offers two implementations: a stubSimpleProcessorResolver and a stubDefaultProcessorResolver. While the stubSimpleProcessorResolver will always return the same processor, the stubDefaultProcessorResolver can be configured to create processors dependent on the processor variable of the request.
Of course you can implement you own processor resolver. It needs to implement the stubProcessorResolver interface, but you can ease this with extending the stubAbstractProcessorResolver.
Processors
Finally, the processor will do the real work in processing the request. With the processor the type of the view is chosen. On instantiation the processor will get the request, session, response and page factory instances (its the task of a processor resolver to create the processor and to supply these instances to it). The front controller will get the configured processor from the processor resolver and ask it for the interceptor descriptor. This descriptor decides which configuration the interceptor initializer should use to create the pre- and postinterceptors (see above). Finally, after calling all preinterceptors, the front controller calls the process() method of the processor, where the processor can now do any work it needs to do to fulfill the request. After this the front controller gets the response back from the processor via its getResponse() method. The processor may just return the response instance it received in the constructor, but it may return any other response instance.
Default processors in Stubbles
Stubbles delivers several processors for different tasks:
- stubXMLProcessor to build XML/XSL driven websites
- stubMemphisProcessor to build websites similarly as in the ucuo framework, see Memphis view engine
- stubJsonRpcProcessor to answer JSON/RPC requests.
Create your own processor
If you are missing a processor that suits your needs you can create your own by implementing the stubProcessor interface. The stubAbstractProcessor already delivers a default implementation that just needs to be extended.
