Zend Framework: Zend_Form_Generator Component Proposal
| Proposed Component Name | Zend_Form_Generator |
|---|---|
| Developer Notes | http://framework.zend.com/wiki/display/ZFDEV/Zend_Form_Generator |
| Proposers | Oscar Reales |
| Zend Liaison | TBD |
| Revision | 1.0 - 1 January 2008: Initial Draft. (wiki revision: 5) |
Table of Contents
1. Overview
Zend_Form_Generator is a set of class that will automagically generates forms based in the table metainformation obtained trhoug the describeTable() method of the Zend_Db_Adapter (not exactly the metadata as its actually returned, but a "normalized" metadata array based on it) more on this later.
The goal is to generate simple forms that fits to a single table structure and also more complex forms that fits to a multi-table relationships entities.
Generated Forms will generate fields according to the column metainformation. Default Filters, Validators will be added to each field depending on this info.
Generated Form will be translatable and located using Zend_Translate and Zend_Locate
2. References
3. Component Requirements, Constraints, and Acceptance Criteria
- This component will generate forms according to the table metadata information.
- This component will generate "one-table" forms.
- This component will generate "multi-table related" forms.
- This component will generate the right type of field depending on the metainformation for every column. For instance, a PRIMARY col will generate a "hidden" field, an ENUM or a SET column will generate a SELECT or MULTICHECKBOX fields with the available options, a varchar(40) will generate a input-text while a LONGTEXT will generate a "textarea"....etc.
- This component will add to each field the adequate standard validators and filters, based on the metainformation of every single column.
- This component will generate a "normalizedMetadata" array that will be an array based on the metadata returned by the describeTable() method, but with some enhacements. For instance, depending on the type of COL (INT, BIGINT, TYNYTEXT, ENUM, etc...) there is another information that we already knows but that are not included in the "_metadata". For instance: MAX and MIN possible values, Possible Values when the cols is an ENUM, LENGTH in every columns, including that ones that returns this value empty, etc... All this information is important to "normalized" to be sure that every columns has the same information. And secondly because based on this "normalized" information, there are a few validators and filters that we can automagically include.
- This component will allow to choose what columns will be included in the form and wich ones don“t.
- This component will be "FOREIGN KEY" friendly, generating a field with values from another table when required.
- This component will works practically without coding being neccesary, but will allow a 100% customisation of the final form: adding-removing default validators, filters, etc. In order to maintain "encapsulation" all this customisation will be facilitated in the own model tier. I mean: A Zend_Db_Table_Row can define its own "form-representation". In this way, we centralised forms in the model tier. The same form can be used along several projects with the obvious advantages.
- Generated Form will use Translator to be "multilang".
4. Dependencies on Other Framework Components
- Zend_Db_Table
- Zend_Db_Table_Row
- Zend_Db_Adapter
- Zend_Form
- Zend_Filter
- Zemd_Validator
5. Theory of Operation
Zend_Form_Generator is a Factory. the factory method will receive obligatory 2 params: a FormName and a "metadata" array (with a normalized structure). Normally this metadata array will be "automagically" generated based on Table info, but, it could be manually generated or using other piece of code to generate. The key is that this array of metadata will has a known structure, and everything required to generate the form will be passed in this array.
Normally we will invoque this Factory from a Method in our Zend_Db_Table_Row instances (model). For instance, having a table "Users" with name, surname and email columns, we will have a Zend_Db_Table_Row fitting that columns structure. Lets say a UserRow class. A method getForm() in that class will invoque the factory. Will be the Row the responsible of passing the right formName and the right metadata to the Zend_Form_Generator, and it will return the form generated to the "controller - view" tier.
In some cases we want to have 2 different forms for the same model. For instance, an UserRow Form could be different if is going to be renderer in a Public Site, than if it is going to be Renderer in an Admin Area. Some fields could be ignored for public while be editable for Administrators. With this approach, we can have a method getForm() and another getFormForAdmin() methods. Basically both do the same thing, but the "metadata" array passed to the factory, and the name will be different.
NORMALIZING METADATA
The metadata returned by the Zend_Db_Adapter::describeTable method is a good starting point to autogenerate a form, but it is not enough. There is some important information that is missed or not rightly presented as it is returned by the adapter. For instance, there are some columns that return a value for the LENGTH, but there are other columns-adapter that keep this info empty. VARCHAR(10) is a good example. We know the DATATYPE and also the LENGTH (10), but in the returned array, LENGTH is empty. Other example, ENUM(true,false). There is a lot of info we can get from this, that is not rightly mapped in the metadata info. It is an ENUM datatype col, but also I know that can have only 2 values, and also we can know which two values they are, and also we know the maximum length of the field, etc.... all that information is important to be normalized, so Zend_Form_Generator can take decissions on it, and add the right filter, validators or generate the right kind of field. In this last example, Zend_Form_Generator could generate 2 radio fields, one per each possible value. In case that possible values will be higher than 3 elements, could generate a SELECT.
For this reason, it is purposed to re-code the Zend_Db_Adapters to return a normalised metadata. Each adapter can return also information about MIN and MAX values depending on each database and each type of col. For instance, in MySQL, for a tinyint cold, we can know the next:
IF(UNSIGNED)
MIN value = 0
MAX value = 255
IF(!UNSIGNED)
MIN value = -128
MAX value = 127
This kind of info is the one that will be added in the "normalizedMEtadata" and the responsible of it will be the Zend_Db_Adapter. It will imply to rewrite the "describeTable" in the actual Adapters, but it will be quite useful.
6. Milestones / Tasks
- Milestone 1: Write Pruposal and Explain Theory of Operation
- Milestone 2: Include some samples and User Cases
- Milestone 3: Include the first Class Skeleton
- Milestone 4: Open a discussion, and see how can fits with this other proposal
- Milestone 5: Depending on discussion opened, try to unify efforts, and become to a unified proposal
7. Class Index
- Zend_Form_Generator
8. Use Cases
| UC-01 |
|---|
... (see good use cases book)
9. Class Skeletons
ZF Home Page
Code Browser
Wiki Dashboard