Friday, November 09, 2007

Zend Framework and HTML_QuickForm_Controller for Multiple Page Forms

For generating generic forms in Zend Framework,
zend_controller and HTML_QuickForm integration is shown at:

http://blog.case.edu/gps10/2006/03/17/using_zend_framework_smarty_and_quickform_to_quickly_deploy_php_applications


In addition to using html_quickform in zend framework, I wanted multiple page forms via HTML_QuickForm_Controller.

(yes, I can implement multi-page forms in zend_controller but this pear package has already done it for me so why not use it?).

I got a tip on setting attributes from
http://news.php.net/php.pear.general/28170




I did get it to work, but I wouldn't say I understand it...

Two things need changing:

-set 'action' attribute in 2 places

-Set action to current page url without the get parameters




It works, but it's pretty slow. Comparing it to the 'raw' version that runs outside zend framework (on the same machine), the zend framework version takes twice (from 2x to 2.5x) the time to respond. The slow Windows file system is likely to blame (see http://www.nabble.com/RE%3A-ZF-performance-advice-p13268859s16154.html ), but I don't know how much speed-up I can get on a linux box. It would be great to get some performance numbers from http://www.nabble.com/Re%3A-ZF-performance-advice-p13185506s16154.html

11/18/07 Update: I just saw this post: http://www.nabble.com/RE%3A-ZF-performance-advice-p13285168s16154.html which makes me more comfortable with this approach on a server class computer and OS.




I used the wizard.php example from html_quickform_controller examples.

The sample code is available for download at:

http://www.nabble.com/Zend-Framework-and-HTML_QuickForm_Controller-for-Multiple-Page-Forms-p13679900s16154.html

and is shown here (the embedded pre tag and php tag need adjusting):








< ? php /** * testing html_quickform_controller with zend framework * * based on wizard.php example from html_quickform_controller * * @author Dennis Fogg */ /** *********************************************************************** * qf controller for zend framework mvc * * *********************************************************************** */ class qfController extends Zend_Controller_Action { /** * html_quickform_controller test * * based on: http://blog.case.edu/gps10/2006/03/17/using_zend_framework_smarty_and_quickform_to_quickly_deploy_php_applications * * * i need a separate controller here because just making it * an action * failed when i tried it. * i think it's because of the extra classes read in. * */ /** * strip out get parameters from a url * * @param unknown_type $url * @return unknown */ public static function strip_get_params($url) { $pos = strpos($url, '?'); $sub = substr($url, 0, $pos); //print "$sub"; return $sub; } public function MultiplePageAction() { set_include_path( get_include_path() ); /** * Example 2 for HTML_QuickForm_Controller: Wizard * * @version CVS: $Id: wizard.php,v 1.3 2007/05/18 09:34:18 avb Exp $ * @author Alexey Borzov
* @ignore
*/

require_once 'Controller.php';

// Load some default action handlers
require_once 'Action/Next.php';
require_once 'Action/Back.php';
require_once 'Action/Jump.php';
require_once 'Action/Display.php';

// Start the session, form-page values will be kept there
session_start();


$wizard =& new HTML_QuickForm_Controller('Wizard');



// zf: replace these
/*$wizard->addPage(new PageFirst('page1'));
$wizard->addPage(new PageSecond('page2'));
$wizard->addPage(new PageThird('page3'));*/


/**
* zf: changes
* assign using =& instead of = for the new
* i don't know why, but not using it causes problems even though i'm in php5
*
*/
$a_page =& new PageFirst('page1');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);

$a_page =& new PageSecond('page2');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);

$a_page =& new PageThird('page3');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);






// We actually add these handlers here for the sake of example
// They can be automatically loaded and added by the controller
$wizard->addAction('display', new HTML_QuickForm_Action_Display());
$wizard->addAction('next', new HTML_QuickForm_Action_Next());
$wizard->addAction('back', new HTML_QuickForm_Action_Back());
$wizard->addAction('jump', new HTML_QuickForm_Action_Jump());

// This is the action we should always define ourselves
$wizard->addAction('process', new ActionProcess());

$wizard->run();



}

}



class PageFirst extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 1 of 3');

$radio[] = &$this->createElement('radio', null, null, 'Yes', 'Y');
$radio[] = &$this->createElement('radio', null, null, 'No', 'N');
$this->addGroup($radio, 'iradYesNo', 'Are you absolutely sure?');

$this->addElement('submit', $this->getButtonName('next'), 'Next >>');

$this->addRule('iradYesNo', 'Check Yes or No', 'required');

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));
}
}

class PageSecond extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 2 of 3');

$name['last'] = &$this->createElement('text', 'last', null, array('size' => 30));
$name['first'] = &$this->createElement('text', 'first', null, array('size' => 20));
$this->addGroup($name, 'name', 'Name (last, first):', ', ');

$prevnext[] =& $this->createElement('submit', $this->getButtonName('back'), '<<>createElement('submit', $this->getButtonName('next'), 'Next >>');
$this->addGroup($prevnext, null, '', ' ', false);

$this->addGroupRule('name', array('last' => array(array('Last name is required', 'required'))));

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));

}
}

class PageThird extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 3 of 3');

$this->addElement('textarea', 'itxaTest', 'Parting words:', array('rows' => 5, 'cols' => 40));

$prevnext[] =& $this->createElement('submit', $this->getButtonName('back'), '<<>createElement('submit', $this->getButtonName('next'), 'Finish');
$this->addGroup($prevnext, null, '', ' ', false);

$this->addRule('itxaTest', 'Say something!', 'required');

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));

}
}



class ActionProcess extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
echo "Submit successful!
\n<>\n";
var_dump($page->controller->exportValues());
echo "\n\n";

// zf: destroy session
$_SESSION = array();
session_destroy();
}
}


About Me

I'm a web dude and this is my geek blog. There should be lots of content ... if I'm working hard ...