| eZ component: MvcTools, Design |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| :Revision: $Rev$ |
| :Date: $Date$ |
| :Status: Draft |
| |
| .. contents:: |
| |
| Scope |
| ===== |
| |
| The scope of this document is to describe the initial design of a component |
| that provides classes to implement a MVC_ architecture for a web application. |
| |
| .. _MVC: http://en.wikipedia.org/wiki/Model-view-controller |
| |
| Design overview |
| =============== |
| |
| Because of the variety of protocols and formats that a modern PHP application |
| should handle, this MVC implementation will provide an abstraction for input |
| and output of controllers. Besides that, a few tieins will be provided. |
| |
| Some of the classes of this component are ezcMvcRequest and ezcMvcResult, |
| which represent the abstract request object for a controller and the abstract |
| result object that the controller returns. |
| |
| Beside these abstraction classes a collection of interfaces and classes will |
| be provided for routing, request-parsing, view-handling and response-writing. |
| This will allow the user of this component to build his own MVC_ on basis of |
| the components building blocks and to adjust it to his needs. |
| |
| Very basic implementations of these interfaces will be shipped with the |
| component, that can be used for very basic applications and are mainly meant |
| as reference implementations. In future tie-ins with other eZ Components might |
| be provided, that ship with more advanced implementations. |
| |
| Layers |
| ====== |
| |
| The component is divided into 4 layers: |
| |
| The request parsing layer is represented by the ezcMvcRequestParser |
| interface. An instance of a class implementing this interface is responsible |
| for parsing an incoming request and creating an instance of ezcMvcRequest from |
| it. This object will encapsulate the complete request data, independent from |
| the protocol and format used for the request. It will also contain raw |
| protocol data. |
| |
| The routing layer, represented by the ezcMvcRouter abstract class, is in charge of |
| selecting the correct controller to handle the request, based on the |
| ezcMvcRequest object it received. |
| |
| Controllers represent the third layer. At this level: Classes process the |
| request, based on the ezcMvcRequest object they received, and select the data |
| to be used to create a response. Controllers only accept an instance of |
| ezcMvcRequest as input and are responsible for returning an instance of |
| ezcMvcResult, encapsulating all data necessary to render the response. |
| |
| View handling is the final layer, which is based on the incoming |
| ezcMvcRequest object and the ezcMvcResult object created by the controllers. |
| The view handler is created through the ezcMvcDispatcherConfiguration and is |
| responsible for creating the actual response body. This response body in |
| combination with the result headers are fed to the a class implementing the |
| ezcResponseWriter interface. |
| |
| Filters reside between different layers. Filtering in the ezcMvcRequest object |
| can for example re-encode all the different input variables in a different |
| character set. Filtering on the result object that comes from the |
| controller's action could for example convert currencies and filtering in the |
| response could minimize CSS, gzip content and re-encode to an output character |
| set. |
| |
| Classes |
| ======= |
| |
| ezcMvcRequestFilter |
| ------------------- |
| |
| Provides an interface for request filters. Request filters can be used to |
| modify the request data before it is used by the controller. They are run in |
| the runRequestFilters() method of the ezcMvcController interface. This method |
| should be called in the run() method of the controller, before the actual |
| logic is applied: |
| |
| .. include:: request-filter.php |
| :literal: |
| |
| ezcMvcResultFilter |
| ------------------ |
| |
| Provides an interface for result filters. Filters that implement this |
| interface can be run after a controller have run their action. They are run in |
| the runResultFilters() method of the ezcMvcController interface. This method |
| should be called in the run() method of the controller, after the actual |
| logic is applied on the result object: |
| |
| .. include:: result-filter.php |
| :literal: |
| |
| ezcMvcResponseFilter |
| -------------------- |
| |
| Provides an interface for response filters. Response filters are run after the |
| response writer created protocol-dependent headers from the abstract headers |
| as returned by the controller action. This can modify the final output stream |
| and protocol-dependent headers. They are run in the runResponseFilters method |
| of the ezcMvcResponseWriter interface: |
| |
| .. include:: response-filter.php |
| :literal: |
| |
| ezcMvcResponse |
| -------------- |
| |
| A struct that encapsulates the body and headers that form a response, used |
| internally in the response writer to allow response filters being run: |
| |
| .. include:: response.php |
| :literal: |
| |
| ezcMvcRequestParser |
| -------------------- |
| |
| The ezcMvcRequestParser interface has to be implemented by classes that will |
| parse a request and create an ezcMvcRequest object. |
| |
| .. include:: request-parser.php |
| :literal: |
| |
| |
| ezcMvcRequest |
| ------------- |
| |
| An instance of this class encapsulates a client-request, containing both data |
| that has been abstracted from the request protocol and format, as well as |
| protocol specific data through the raw property. The latter should not be |
| used, but is provided for extra flexibility. An object of this class is |
| generated by a class that implements the ezcMvcRequestParser interface. |
| |
| An example of a HTTP request: |
| |
| .. include:: http-request.php |
| :literal: |
| |
| An example of a mail request: |
| |
| .. include:: mail-request.php |
| :literal: |
| |
| The class definition itself: |
| |
| .. include:: request.php |
| :literal: |
| |
| |
| ezcMvcRequestAuthentication |
| --------------------------- |
| |
| Encapsulate the client authentication informations in a protocol abstract |
| way: |
| |
| .. include:: request-authentication.php |
| :literal: |
| |
| ezcMvcRequestAccept |
| -------------------- |
| |
| Encapsulate the client content informations in a protocol abstract way: |
| |
| .. include:: request-accept.php |
| :literal: |
| |
| ezcMvcRequestFile |
| ----------------- |
| |
| Encapsulate the files informations in a protocol abstract way: |
| |
| .. include:: request-file.php |
| :literal: |
| |
| ezcMvcRequestUserAgent |
| ---------------------- |
| |
| Encapsulate the client agent informations in a protocol abstract way: |
| |
| .. include:: request-user-agent.php |
| :literal: |
| |
| ezcMvcRawRequest |
| ---------------- |
| |
| Encapsulates the raw request data, must be inherited by protocol-specific |
| classes. Filters can add their own data to this struct in the filterData |
| array: |
| |
| .. include:: request-raw.php |
| :literal: |
| |
| This class will be sub-classed by (for example) the following classes: |
| |
| ezcMvcMailRawRequest |
| ^^^^^^^^^^^^^^^^^^^^ |
| |
| This class encapsulates the parsed e-mail structure: |
| |
| .. include:: request-raw-mail.php |
| :literal: |
| |
| |
| ezcMvcHttpRawRequest |
| ^^^^^^^^^^^^^^^^^^^^ |
| |
| This class encapsulates a raw HTTP request: |
| |
| .. include:: request-raw-http.php |
| :literal: |
| |
| |
| ezcMvcRouter |
| ------------ |
| |
| There will be a few supplied routers, below an example of the |
| router: |
| |
| .. include:: regexp-router.php |
| :literal: |
| |
| ezcMvcController |
| ---------------- |
| |
| This interface must be implemented by every controller. This is the only |
| interface that is only meant for user implementations and for that no basic |
| implementation will be shipped with the component. |
| |
| Assuming that action-selection should be done within the controller itself, |
| it should have a public method: createResult(); The returned result |
| can be either a ezcMvcResult object, or an ezcMvcInternalRedirect object. The |
| latter can be used by the dispatcher to restart the routing and controller |
| parts of the request as you can see in the example dispatcher implementation |
| below: |
| |
| .. include:: controller.php |
| :literal: |
| |
| ezcMvcResult |
| ------------ |
| |
| This object encapsulates the result of a controller, abstracting from the |
| actual response protocol. The output object will be modeled similar to the |
| input variant, described above. There is only one result object returned by |
| the controller, containing both the abstract headers and abstract result. |
| |
| An example of "crafting" a result to produce HTTP response headers in an |
| abstract way is shown below: |
| |
| .. include:: http-result.php |
| :literal: |
| |
| ezcMvcView |
| ---------- |
| |
| This abstract class has to be inherited by classes that handle rendering one |
| ezcMvcResult object into one specific format, that will be part of the |
| response. The view is created by the createViewHandler method of the |
| ezcMvcDispatcherConfiguration. The view returns an ezcMvcResponse object that |
| contains the protocol-abstract headers and the rendered result. The dispatcher |
| then feeds this to a result writer. The views can include other views by using |
| zones. |
| |
| There will be a few supplied view handlers, below an example of things |
| interact: |
| |
| .. include:: template-view-handler.php |
| :literal: |
| |
| ezcMvcResponseWriter |
| -------------------- |
| |
| Takes the result from the controller action, and the body string from the view |
| to handle sending the full response to the client. The interface looks like: |
| |
| .. include:: response-writer.php |
| :literal: |
| |
| ezcMvcDispatcher |
| ---------------- |
| |
| A dispatcher can be used to encapsulate the process from the request |
| parsing to making the response. |
| |
| All dispatchers supplied by eZ Components should implement this interface, |
| asserting that the same configuration object can be used for each: |
| |
| .. include:: dispatcher.php |
| :literal: |
| |
| ezcMvcDispatcherConfiguration |
| ----------------------------- |
| |
| Configuring a dispatcher is done by implementing the following interface: |
| |
| .. include:: dispatcher-configuration.php |
| :literal: |
| |
| |
| Example Dispatcher |
| ================== |
| |
| .. include:: example-dispatcher.php |
| :literal: |
| |
| |
| Example dispatcher usage: |
| |
| .. include:: dispatcher-usage.php |
| :literal: |
| |
| Special considerations |
| ====================== |
| |
| Shipping of example-implementations |
| ----------------------------------- |
| |
| The section `Design overview`_ states that very basic implementations of the |
| provided interfaces should be shipped with the component. It must be decided |
| if these implementations should be part of the components source code itself |
| or should deal as documentation (and therefore reside in the docs/ directory |
| instead of src/). |
| |
| The first iteration of this component will provide the following example |
| implementations: |
| |
| - HTTP request parser (ezcMvcHttpRequestParser), that builds a request |
| object from a HTTP request. |
| - Router like jetfuel/rails (ezcMvcRailsRouter) |
| (http://code.google.com/p/jetfuel/source/browse/branches/0.3.1/examples/blog/settings/routes.php). |
| - Router based on regular expressions (ezcMvcRegexpRouter). |
| - View handler using PHP (ezcMvcPhpView). |
| - View handler using the Template component (ezcMvcTemplateView). |
| - View handler outputting JSON (ezcMvcJsonView). |
| - Example dispatcher for HTTP. |
| - Example dispatcher for CLI applications. |
| - Example controller. |
| - Example model with PersistentObject and service interface. |
| - Authentication request filter (ezcMvcAuthenticationFilter). |
| - Navigation result filter (ezcMvcNavigationFilter) that adds navigation to |
| pages. |
| - Character encoding response filter (ezcMvcCharacterEncodingFilter). |
| |
| Following iterations will add the following examples: |
| |
| - Mail request parser (ezcMvcMailRequestParser), that builds a request |
| object from an e-mail message. |
| - Jabber request parser (ezcMvcJabberRequestParser), that builds a request |
| object from a jabber message. |
| - Router based on the Url component. |
| - Router based on the Tree component. |
| - View handler outputting feeds through the Feed component (ezcMvcFeedView). |
| - View handler outputting XML (ezcMvcXmlView). |
| - View handler that uses Translations into the ezcMvcTemplateView. |
| - GZIP response filter (ezcMvcGzipFilter). |
| |
| |
| |
| .. |
| Local Variables: |
| mode: rst |
| fill-column: 78 |
| End: |
| vim: et syn=rst tw=78 |