Orion PHP  0.11.12
The PHP5.3 framework
form.php
Go to the documentation of this file.
00001 <?php
00002 
00003 
00004 namespace Orion\Core;
00005 
00006 define( "NEWLINE", "\n" );
00007 
00008 /**
00009  * \Orion\Core\Form
00010  * 
00011  * Orion form class.
00012  *
00013  * Form creation helper
00014  *
00015  * @author Thibaut Despoulain
00016  * @license BSD 4-clauses
00017  * @version 0.11.12
00018  */
00019 class Form
00020 {
00021 
00022     /**
00023      * Hidden input type
00024      */
00025     const HIDDEN = 0;
00026     /**
00027      * Text input type
00028      */
00029     const TEXT = 1;
00030     /**
00031      * Passwod input type
00032      */
00033     const PASSWORD = 2;
00034     /**
00035      * Textarea type
00036      */
00037     const TEXTAREA = 3;
00038     /**
00039      * Checkbox input type
00040      */
00041     const CHECKBOX = 4;
00042     /**
00043      * Checkbox list input type
00044      */
00045     const CHECKLIST = 5;
00046     /**
00047      * Radio list input type
00048      */
00049     const RADIOLIST = 6;
00050     /**
00051      * Droplist input type
00052      */
00053     const DROPLIST = 7;
00054     /**
00055      * Image browse type
00056      */
00057     const IMAGE = 8;
00058     /**
00059      * File browse type
00060      */
00061     const FILE = 9;
00062     /**
00063      * Valued list input type
00064      */
00065     const VALUEDLIST = 10;
00066     /**
00067      * Submit input type
00068      */
00069     const SUBMIT = 11;
00070     /**
00071      * Cancel button type
00072      */
00073     const CANCEL = 12;
00074     /**
00075      * Message type
00076      */
00077     const MESSAGE = 13;
00078 
00079     /**
00080      * Model handler
00081      * @var Orion\Core\Model
00082      */
00083     private $model = null;
00084 
00085     /**
00086      * Array of Orion\Core\Form\Field's, used to store form fields as Data Object
00087      * @var array<Orion\Core\Form\Field>
00088      */
00089     private $fields = array( );
00090 
00091     /**
00092      * Ordered array of fields' name.
00093      * It's used to determine fields order in form.
00094      * @var array<int, string>
00095      */
00096     private $indexes = array( );
00097 
00098     /**
00099      * Array of required fields names
00100      * @var string array
00101      */
00102     private $required = array( );
00103 
00104     /**
00105      * Form name
00106      * @var string
00107      */
00108     private $name = null;
00109 
00110     /**
00111      * Action url
00112      * @var string
00113      */
00114     private $action = null;
00115 
00116     /**
00117      * Creates a new form
00118      */
00119     public function __construct( $_name, $_action='#' )
00120     {
00121         $this->fields = array( );
00122         $this->required = array( );
00123         $this->name = $_name;
00124         $this->action = $_action;
00125     }
00126 
00127     /**
00128      * Add a new field to the form.
00129      * These functions can be chained like $form->add(...)->add(...) etc.
00130      * @param Orion\Core\ModelField $field
00131      * @param mixed $value
00132      * @return Orion\Core\Form instance
00133      */
00134     public function &add( $field, $value=null )
00135     {
00136         if ( array_key_exists( $field->getName(), $this->fields ) )
00137             throw new Exception( 'Duplicate field [' . $field->getName() . '] during form creation.', E_WARNING, get_class( $this ) );
00138 
00139         if ( $value != null )
00140             $field->setValue( $value );
00141         $this->fields[ $field->getName() ] = $field;
00142         $this->indexes[ ] = $field->getName();
00143 
00144         return $this;
00145     }
00146 
00147     /**
00148      * Add a new field to the form before given element.
00149      * These functions can be chained like $form->add(...)->add(...) etc.
00150      * @param string Name of the element before which the field will be added.
00151      * @param Orion\Core\Model\Field $field
00152      * @param mixed $value
00153      * @return Orion\Core\Form instance
00154      */
00155     public function &addBefore( $element, $field, $value=null )
00156     {
00157         if ( array_key_exists( $field->getName(), $this->fields ) )
00158             throw new Exception( 'Duplicate field [' . $field->getName() . '] during form creation.', E_WARNING, get_class( $this ) );
00159 
00160         if ( $value != null )
00161             $field->setValue( $value );
00162         $this->fields[ $field->getName() ] = $field;
00163         array_splice( $this->indexes, array_search( $element, $this->indexes ), 0, $field->getName() );
00164 
00165         return $this;
00166     }
00167 
00168     /**
00169      * Add a new field from model to current form.
00170      * Similiar to add() but getting its field object from provided model based on field binding.
00171      * @param string $field
00172      * @param mixed $value
00173      */
00174     public function &addField( $fieldname, $value=null )
00175     {
00176         if ( $this->model == null )
00177             throw new Exception( 'You need to provide a correct Orion\Core\Model before using addField()', E_WARNING, get_class( $this ) );
00178 
00179         if ( array_key_exists( $fieldname, $this->fields ) )
00180             throw new Exception( 'Duplicate field [' . Core\Security::preventInjection( $fieldname ) . '] during form creation.', E_WARNING, get_class( $this ) );
00181 
00182         $model = $this->model;
00183 
00184         if ( !$model::hasField( $fieldname ) )
00185             throw new Exception( 'The field [' . Core\Security::preventInjection( $fieldname ) . '] does not exist in provided model.', E_WARNING, get_class( $this ) );
00186 
00187         $this->fields[ $fieldname ] = $model::getField( $fieldname );
00188         if ( $value != null )
00189             $this->fields[ $fieldname ]->setValue( $value );
00190 
00191         $this->indexes[ ] = $fieldname;
00192 
00193         return $this;
00194     }
00195 
00196     /**
00197      * Removes a registered field
00198      * @param string $fieldname 
00199      * @return Orion\Core\Form instance
00200      */
00201     public function &remove( $fieldname )
00202     {
00203         if ( func_num_args() > 1 )
00204         {
00205             foreach ( func_get_args() as $arg )
00206                 $this->remove( $arg );
00207         }
00208         else
00209         {
00210             if ( !array_key_exists( $fieldname, $this->fields ) )
00211                 throw new Exception( 'Unable to remove field [' . $fieldname . ']. Field does not exist.' );
00212 
00213             unset( $this->fields[ $fieldname ] );
00214             array_splice( $this->indexes, array_search( $fieldname, $this->indexes ), 1 );
00215         }
00216 
00217         return $this;
00218     }
00219 
00220     /**
00221      * Hydrate form fields with values stored in provided object (usually for editing purpose)
00222      * @param Object $object Object to retrives each field values from.
00223      */
00224     public function hydrate( $object )
00225     {
00226         foreach ( array_keys( $this->fields ) as $key )
00227         {
00228             if ( isset( $object->{$key} ) && $object->{$key} != null )
00229                 $this->fields[ $key ]->setValue( stripslashes( $object->{$key} ) );
00230         }
00231     }
00232 
00233     /**
00234      * Prepare this form using provided Model class
00235      * @param String $model
00236      */
00237     public function prepare( $model=null )
00238     {
00239         if ( $model == null && $this->model == null )
00240             throw new Exception( 'You need to provide a model to prepare this form.', E_WARNING, get_class( $this ) );
00241 
00242         if ( $model != null )
00243             $this->model = $model;
00244 
00245         foreach ( $model::getFields() as $field )
00246             $this->add( $field );
00247     }
00248 
00249     /**
00250      * Retreive the HTML version of the form
00251      * @param boolean $XHTML Output (x)HTML if set to TRUE instead of pure HTML
00252      */
00253     public function toHtml( $XHTML=false )
00254     {
00255         $html = '<form id="' . $this->name . '" name="' . $this->name . '" method="post" action="' . $this->action . '"';
00256         if ( $this->isMultipart() )
00257             $html.= ' enctype="multipart/form-data"';
00258         $html .= '>' . NEWLINE;
00259 
00260         foreach ( $this->indexes as $fieldname )
00261         {
00262             $field = $this->fields[ $fieldname ];
00263             if ( !$field->isVisible() )
00264                 continue;
00265             if ( !method_exists( $field, 'toHtml' ) )
00266                 throw new Exception( 'Missing toHtml() method in field [' . $field->getName() . ']', E_USER_ERROR, get_class( $this ) );
00267             $html .= $field->toHtml( $XHTML ) . NEWLINE;
00268         }
00269 
00270         $html .= '</form>' . NEWLINE;
00271 
00272         return $html;
00273     }
00274 
00275     /**
00276      * Bind an Orion\Core\Model to the form
00277      * @param Orion\Core\Model $_model
00278      */
00279     public function setModel( $_model )
00280     {
00281         $this->model = $_model;
00282     }
00283 
00284     /**
00285      * Get bound model
00286      * @return Orion\Core\Model
00287      */
00288     public function getModel()
00289     {
00290         return $this->model;
00291     }
00292 
00293     /**
00294      * Get a field
00295      * @param string $name
00296      * @return \Orion\Form\Field
00297      */
00298     public function &getField( $name )
00299     {
00300         return $this->fields[ $name ];
00301     }
00302 
00303     /**
00304      * Tests if the form requires multipart encoding
00305      * @return Boolean
00306      */
00307     public function isMultipart()
00308     {
00309         foreach ( $this->fields as $field )
00310             if ( $field->isMultipart() )
00311                 return true;
00312         return false;
00313     }
00314 
00315 }
00316 
00317 ?>