UPDATE: I just updated Phorm to version 1.0. Lot’s of bug fixes and validation has been completely redesigned. I’ll be posting a tutorial in a bit so sit tight. Thanks.
Phorm is a form generation and validation module for Kohana. I wrote Phorm because I wanted to automate and simplify the generation and validation process in Kohana. Here is the end result. Phorm is released under a beerware license.
Quick list of Phorm’s features:
- Easy for noobs and pros alike
- Built upon Kohana’s Form and Validation classes
- Support for select multiple elements
- Wash and wax your car, take your girl on a date
- Automatically re-populates form data on validation errors
- Auto error message support
- Keeps controllers nice and clean - free from view data.
- Just joking about the car part. But it will still take your girl on a date - logs errors.
- Smart directory layout
- Highly configurable
- Dead simple
Tutorial
First let’s go over the configuration options available.
Configuration
- autoload errors - prepend form template with error template when there are validation errors. Bypasses the need to use $object->get_html_errors( ) or phorm::error_display( ).
- add form name - adds form name to elements. For instance element name would be transformed from name=”myForm[myElement]” and id=”myForm_myElement”. This options does not apply to select multiple elements as they can not be wrapped with [].
- controller sub-folder - use the controller name as a sub-folder for rules and forms. So if controller name is myForms_Controller, path would be $rules_folder$/myforms/$controller_method$.php.
- rules folder - put rules files here
- forms folder - find forms here, must be within a ‘views’ folder
- error class - add class to elements with errors, can be set to FALSE
- label error class - add label error class to labels that are for elements with errors, can be set to FALSE
- error css folder - where to find css files for error template sets
- error folder - folder where to find error template sets
- error template - default error template to use, this can be changed at runtime.
- errors as labels - wrap element names in error messages with a label tag so that they can be clickable and focus on invalid element.
- blank passwords - blank passwords on validation errors.
/**
* If form has errors autoload error template. This bypasses the need to add
* in your form views. Automatically loaded with
* $PHORM_OBJECT->fetch() in controller. Added to string just before form.
*
* DEFAULT: TRUE
*/
$config['autoload_errors'] = TRUE;
/**
* Add form name to element name and element id. i.e. form name = myForm,
* element name = myElement. If TRUE myElement name will be
* name = myForm[myElement] and id = myForm_myElement
*
* DEFAULT: TRUE
*/
$config['add_form_name'] = TRUE;
/**
* Use controller name as a sub-folder. Applies to rules and forms.
*
* DEFAULT: TRUE
*/
$config['controller_sub_folder'] = TRUE;
/**
* Folder where rules reside. Rules can be loaded manually using
* $phormObject->rules('myRules'). Rules will be loaded from
* rules_folder/($controller_sub_folder/)myRules.php. If rules are not set
* manually an attempt to autoload will be made.
* Use APPPATH instead of MODPATH to specify application folders.
*
* DEFAULT: MODPATH.'phorm/rules/';
*/
$config['rules_folder'] = MODPATH.'phorm/rules/';
/**
* Folder where your form stubs reside. Must be within a 'views' folder.
* Forms can be loaded manually using $phormObject->form('myForm').
* Forms will be loaded from forms_folder/($controller_sub_folder/)myForm.php.
* If form is not set manually an attempt to autoload will be made.
* Use APPPATH instead of MODPATH to specify application folders.
*
* DEFAULT: 'forms/';
*/
$config['forms_folder'] = 'forms/';
/**
* Specify class(es) to be attached to elements that do not validate.
* i.e. $config['error_class'] = 'class1 class2 class3';
* FALSE can be specified.
*
* DEFAULT: 'phorm_error';
*/
$config['error_class'] = 'phorm_error';
/**
* Specify error class(es) to be added to labels for invalid elements.
* i.e. $config['label_error_class'] = 'class1 class2 class3';
*
* Default = FALSE
*/
$config['label_error_class'] = FALSE;
/**
* Error css file to load. Set to FALSE to skip using a css file. If config
* option is set to FALSE css will not be automatically loaded.
*
* DEFAULT: MODPATH.'/phorm/media/'
*/
$config['error_css_folder'] = MODPATH.'/phorm/media/';
/**
* Default error template folder. Must be within a 'views' folder thanks to
* Kohana's cascading file system. Thanks Kohana!
*
* DEFAULT: 'errors/';
*/
$config['error_folder'] = 'errors/';
/**
* Default error template (Applies to stub too. Appends _stub to stub
* template name.)
*
* DEFAULT: 'phorm_error';
*/
$config['error_template'] = 'phorm_error';
/**
* Wrap error strings with label tags to make them clickable and give
* elements focus. This is applied to error_stub.
*
* DEFAULT: TRUE
*/
$config['errors_as_labels'] = TRUE;
/**
* Empty password values on validation error
*
* DEFAULT: TRUE
*/
$config['blank_passwords'] = TRUE;
Demo Controller
myController.php
Url: http://localhost/phorm/demo
class Phorm_Controller extends Template_Controller
{
public function demo()
{
$form = PhormLib::factory();
$form->name('myForm');
if ($form->validate())
{
$this->template->yield = 'Valid';
} else
{
$data = $form->fetch();
$this->template->yield = $data;
}
}
}
Init PhormLib via PhormLib::factory(). Then add your options. If no rules are set PhormLib will attempt to autoload files. It will take the calling function name as a starting point. So in the above file it will look for a rules file name demo.php. This autoload feature applies to rules and forms. Rules and forms directories can be changed in ‘phorm/config/phorm.php’. Use the following class methods to override default settings. PhormLIb methods must be called with object->method().
Methods in PhormLib
- factory( ) Returns PhormLib instance.
- name(’myForm’) Sets form name. Required if you want to wrap element names in myForm[myElement] format. No default value.
- rules(’myRules’) Set rules file. Pass file name without extension. Must reside within rules folder in configuration. Default value is the name of calling function. For this example it would be ‘demo’.
- form(’myFormName’) Specify form template to use. Must reside within forms folder specified in configuration. Default value is the name of calling function. For this example it would be ‘demo’.
- lang(’myLangFile’) Set lang file. Must reside within an i18n folder. Default is ‘phorm’.
- data($data_array) Pass data array to be used in validation. Default is $_POST.
- validate(name, form, rules , data, lang) Validate form data against rules. Parameters may be passed. Returns TRUE if form is valid, FALSE otherwise.
- errors(’element_name’) If element is set then return error message for that specific element. If error is null hen return an array of error message strings.
- get_errors_html(’myErrorTemplate’) Specify error template. Default error template is ‘phorm_error’. Must reside within error folder specified in config.
- valid( ) Returns boolean. Is form valid? Must be run after validate( ).
- fetch( ) Returns form data that has been validated and filtered and inserted into the form template. Used for displaying form templates after errors have been detected. Returns html. Available after validate( ).
- values(’element_name’) If element name is specified returns value for that element. If no element is specified returns an array of all form values. Values have been validated and filtered. Available after validate( ).
- is_valid(’element_name’) Use this method to determine if an individual element is valid. No default value. Available after validate( ).
- submitted( ) Returns an array of form values NOT run through validation or filters.
Demo View
views/forms/demo.php
<div id="myForm">
<?= phorm::wrap('all', '', '<br />') ?>
<?= phorm::open(NULL, array('name' => 'myForm')) ?>
<?= phorm::input('first_name') ?>
<?= phorm::multiple('myMultiple', $options, $selected) ?>
<?= phorm::submit('mySub', 'submit') ?>
<?= phorm::close() ?>
</div>
Methods in phorm
Many of the methods used in Kohana’s form class are available in phorm and take the same parameters. Key difference between phorm and form is that phorm validates and re-populates form data automatically. phorm also adds support for select multiples through the method multiple( ). phorm methods are static and can be accessed through phorm::method().
- open( )
- open_multipart( )
- input( )
- hidden( )
- password( )
- upload( )
- textarea( )
- dropdown( )
- checkbox( )
- radio( )
- submit( )
- button( )
- label( )
- attributes( )
- open_fieldset( )
- close_fieldset( )
- legend( )
- multiple( ) Accepts the same parameters as dropdown( ) but adds support for validation. If you use multiple make sure to close your form with close( ).
- close( ) Close form tag. Also flushes support info for any multiples in the form.
- errors(’element_name’) If element is set then return error message for that specific element. If error is null hen return an array of error message strings.
- error_count( ) Returns number of errors.
- is_valid(’element_name’) Use this method to determine if an individual element is valid. No default value. Available after validate( ).
- error_display(’myErrorTemplate’) Specify error template. Default error template is ‘phorm_error’. Must reside within error folder specified in config.
- error_stub( ) Call error stub. Prints individual error messages using stub as a template.
- values(’element_name’) If element name is specified returns value for that element. If no element is specified returns an array of all form values. Values have been validated and filtered. Available after validate( ).
- valid( ) Returns boolean. Is form valid? Must be run after validate( ).
- submitted( ) Returns an array of form values NOT run through validation or filters.
- wrap( $element_name(s), ‘prefix’, ’suffix’) First parameter is element name (s) and can either be a string of a single element or an array of element names. Use ‘all’ to to wrap all elements except open, open_multipart, hidden, close, close_multipart, open_fieldset, close_fieldset. Prefix and suffix can either be a string or html. To wrap a specific element use their method names. For instance to wrap only input, textarea and button tags use:
phorm::wrap(array('input', 'textarea', 'button'), '', '');
// will output
<br />
<input type="text" name="blah" />
<br />
// same applies to textarea and button
Rules and Filters
Rules and filters are written a little different from Kohana but it’s the same affect. The default rules file for our tutorial would be demo.php and it resides in MODPATH.’/phorm/rules/’. Rules folder can be changed in config.
demo.php
$pre['all'] = array('trim');
$post['first_name'] = array('ucfirst');
$rule['first_name'] = array('required', 'length[3, 15]');
Let’s explain the rules file. Prior to validation all values will be trimmed and all characters will be changed to lowercase. After validation only first name will have it’s first letter capitalized. There is one rule that applies to the element first_name. First name is required and must be between 3 and 15 characters long. Refer to Kohana’s Validation documentation for more info on filters and rules which are available.
Error Handling
Error messages consist of 4 parts: error template, error stub, error css and an error message language file. Don’t worry all these can be set automagically or if you a control freak, manually. The default error template is phorm_error.php. Stub, phorm_error_stub.php. Css phorm_error.css. When specifying error template set, you can use $object->get_errors_html(’phorm_error’) in your controller or phorm::error_display(’phorm_error’) in your view. Css and error template folder can be changed in config.
One more time. So to use an error template set of ‘admin_errors’ you would first call the necessary method, $object->get_errors_html(’admin_errors’) then make sure the appropriate files are available in their respective folders, main template: admin_errors.php, stub: admin_errors_stub.php, css: admin_errors.css.
phorm_error.php
<div id="phorm_errors">
<?
$msg = (phorm::error_count() == 1)
? 'There is <strong>1</strong> error,'
: 'There are <strong>'.phorm::error_count(). '</strong> errors,';
$msg .= ' please correct.';
?>
<p id="phorm_error_count"><?= $msg ?></p>
<ol>
<?= phorm::error_stub() ?>
</ol>
</div>
Make sure to call phorm::error_stub( ) to specify where the stub should print individual error messages.
phorm_error_stub.php
<li>$error$</li>
Use $error$ where you want the error message to be displayed.
error.css
#phorm_errors {
width: 50%;
border: 1px solid #DC143C;
background: #FFD0D7;
margin: 25px auto;
padding: 5px 20px;
font-size: 0.8em;
color: #222;
}
#phorm_errors label {
cursor: pointer;
text-decoration: underline;
}
#phorm_errors label:hover {
text-decoration: none;
}
#phorm_errors li {
margin: 5px 0;
}
#phorm_error_count {
font-size: 1.2em;
}
.phorm_error {
background: #FFD0D7;
border-top: 1px solid #DC143C;
border-left: 1px solid #DC143C;
border-right: 1px solid #888;
border-bottom: 1px solid #888;
}
Default css file for phorm_error. Add your css for this error set here. You can set error css to FALSE in config.
Lang file: phorm.php
$lang = array
(
'required' => '$element$ is required.',
'length' => '$element$ must be $length$ character(s) in length.',
'length_range' => '$element$ must be between $low$ and $high$ characters long.',
'depends_on' => '$element$ is dependent on $depends_on$.',
'matches' => '$element$ does not match $matches$.',
'chars' => '$element$ must contain one of following characters: $chars$.',
'email' => '$element$ is not a valid email address.',
'email_rfc' => '$element$ is not a valid rfc822 email address.',
'email_domain' => '$element$ does not have a valid MX record.',
'url' => '$element$ is not a valid url.',
'ip' => '$element$ is not a valid ip address.',
'credit_card' => '$element$ is not a valid $credit_card$ credit card.',
'phone' => '$element$ must be $phone$ digits in length.',
'alpha_numeric' => '$element$ must consist of alphanumeric characters only.',
'alpha_dash' => '$element$ must consist of alphanumeric and dash characters only.',
'digit' => '$element$ must consist of only digits.',
'numeric' => '$element$ must consist of numeric characters only.',
);
I hate writing error messages and I was surprised to see that Kohana’s Validation class expects you to write and error message for EVERY single element. Whew! That’s too much work. So I wrote my own methods to create and parse default error messages. If you notice the key for the message is the rule type and the string uses placeholders $name$ to replace with specific values. Element names are cleaned and capitalized and underscores are removed. When rules consist of multiple options, i.e. depends_on[element1, element2, element3] options are added to error string.
You can edit these defaults as you wish, just leave the keys intact. You can roll your own lang file with $object->lang(’myLang’) however you will have to Kohana’s lang scheme. Refer to Kohana’s Validation documentation for more info.
Okay so that’s the rules and filters. If you want to see the default error messages in action load up http://mydevserver/phorm in developement mode. Leave elements blank and click submit. There are a bunch of config options availabe in Phorm so let’s go over them.
Conclusion
Hopefully you find Phorm easy to use but powerful enough to handle big jobs. Since Phorm is released under a beerware license you can do whatever you wish with the code. Trash it, use it without credit, take credit for it, tell your boss my code ruined your project - whatever; just promise to use and improve. Any comments or suggestions you may have to improve the performance of Phorm are welcomed. You can also fork the github repo. Thanks!
29/12/2008 at 5:36 am Permalink
use this http://blog.transphorm.com/auto-form-auto-modeler-form-generation-for-kohana