Basic Zend post workflow issue - zend-framework

I am new to this these technologies, so might not be asking to do this the easiest way, but: I want to create a form and ask for an ID value. Once submit is pressed, I want to take that ID, make an external XML call and then show the XML data. I am stuck on if I can do this in a single url:https://plesk.local:8443/modules/example/index.php/index/form. I would like to have both the form and the list data on the same page, so I can update the ID, press submit and see the new data...over and over...
I am trying to modify the basic "Example1" that Plesk includes. I can modify it and test it, but stuck on exactly how POST works. Ideally I want to have $this->view->form to have both a pm_Form_Simple and pm_View_List_Simple on the same $form view (if this makes sense).
So looking for help on
1) Can I use the same URL and handle the POST/GET from it
2) Can I have both a form and simple list on the same page?
thx!!!!!
Here is the sample controller:
<?php
class IndexController extends pm_Controller_Action
{
public function init()
{
parent::init();
// Init title for all actions
$this->view->pageTitle = 'Example Module';
// Init tabs for all actions
$this->view->tabs = array(
array(
'title' => 'Form',
'action' => 'form',
),
array(
'title' => 'List',
'action' => 'list',
),
);
}
public function indexAction()
{
// Default action will be formAction
$this->_forward('form');
}
public function formAction()
{
// Init form here
$form = new pm_Form_Simple();
$form->addElement('text', 'exampleText', array(
'label' => 'Example Text',
'value' => pm_Settings::get('exampleText'),
'required' => true,
'validators' => array(
array('NotEmpty', true),
),
));
$form->addControlButtons(array(
'cancelLink' => pm_Context::getModulesListUrl(),
));
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
// Form proccessing here
pm_Settings::set('exampleText', $form->getValue('exampleText'));
$this->_status->addMessage('info', 'Data was successfully saved.');
$this->_helper->json(array('redirect' => pm_Context::getBaseUrl()));
}
# NEW - start
if (0)
{
# I want to be back here after the POST
# Want to show the list here after I take the POST parameter and do an external XML call...
$list = $this->_getListRandom();
$this->view->list = $list;
}
# NEW - end
$this->view->form = $form;
}
public function listAction()
{
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
public function listDataAction()
{
$list = $this->_getListRandom();
// Json data from pm_View_List_Simple
$this->_helper->json($list->fetchData());
}
private function _getListRandom()
{
$data = array();
#$iconPath = pm_Context::getBaseUrl() . 'images/icon_16.gif';
for ($i = 0; $i < 15; $i++) {
$data[] = array(
'column-1' => '' . (string)rand() . '',
'column-2' => (string)rand(),
);
}
$list = new pm_View_List_Simple($this->view, $this->_request);
$list->setData($data);
$list->setColumns(array(
'column-1' => array(
'title' => 'Random with link',
'noEscape' => true,
),
'column-2' => array(
'title' => 'Random with image',
'noEscape' => true,
),
));
// Take into account listDataAction corresponds to the URL /list-data/
$list->setDataUrl(array('action' => 'list-data'));
return $list;
}
}

Yes
Yes
I'm not expirienced in zend, so it just try, I suggest to replace formAction() with following code:
public function formAction()
{
// Init form here
$form = new pm_Form_Simple();
$form->addElement('text', 'exampleText', array(
'label' => 'Example Text',
'value' => pm_Settings::get('exampleText'),
'required' => true,
'validators' => array(
array('NotEmpty', true),
),
));
$form->addControlButtons(array(
'cancelLink' => pm_Context::getModulesListUrl(),
));
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
// Form proccessing here
pm_Settings::set('exampleText', $form->getValue('exampleText'));
$this->_status->addMessage('info', 'Data was successfully saved.');
$list = $this->_getListRandom();
$this->view->list = $list;
$this->view->form = $form;
// Redirects happens on next string, maybe you need to add something to getBaseUrl()
$this->_helper->json(array('redirect' => pm_Context::getBaseUrl()));
}
$this->view->form = $form;
}

Related

How to create multiple form submit buttons with alternate routes in ZF2

In ZF2, how do you create multiple submit buttons that each lead to different routes? In the Forms and actions chaper of the ZF2 tutorial, a form is created with a single submit button with the label “Go” that processes the input data and returns to the index page (route). Where do we put the pertinent scripts if we wanted four buttons:
Save action: saves user input, route: return to current page
Save and Close action: saves user input, route: return to index (Album)
Clear action: no action, route: return to current page
Close action: no action, route: return to index (Album)
I assume the buttons are created like this:
namespace Album\Form;
class AlbumForm extends Form
{
public function __construct($name = null)
{
// ... //
$this->add(array(
'name' => 'savebutton',
'attributes' => array(
'type' => 'submit',
'value' => 'Save',
'id' => 'savebutton',
),
));
$this->add(array(
'name' => 'save_closebutton',
'attributes' => array(
'type' => 'submit',
'value' => 'Save & Close',
'id' => 'save_closebutton',
),
));
$this->add(array(
'name' => 'clearbutton',
'attributes' => array(
'type' => 'submit',
'value' => 'Clear',
'id' => 'clearbutton',
),
));
$this->add(array(
'name' => 'closebutton',
'attributes' => array(
'type' => 'submit',
'value' => 'Close',
'id' => 'closebutton',
),
));
}
}
This is what the edit action looks like with only one submit button:
// module/Album/src/Album/Controller/AlbumController.php:
//...
// Add content to this method:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('album', array(
'action' => 'add'
));
}
$album = $this->getAlbumTable()->getAlbum($id);
$form = new AlbumForm();
$form->bind($album);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getAlbumTable()->saveAlbum($form->getData());
// Redirect to list of albums
return $this->redirect()->toRoute('album');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
//...
Since pairs of buttons have the same form action and pairs of buttons have the same route, I image we want to add two if statements somewhere here, unless a switch statement is better.
Quick 'n dirty way to do what you need:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('album', array(
'action' => 'add'
));
}
$album = $this->getAlbumTable()->getAlbum($id);
$form = new AlbumForm();
$form->bind($album);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$input = $form->getData();
if (!empty($input['save_closebutton'])) {
return $this->redirect()->toRoute('album', array(
'controller' => 'AlbumController',
'action' => 'index',
));
}
}
}
return array(
'id' => $id,
'form' => $form,
);
}

InputFilter "setRequired" not working for html5 multiple

I'm having hard time with a weird behaviour of fileinput.
This is my form:
namespace Frontend\Form;
use NW\Form\Form;
use Zend\InputFilter;
use Zend\Form\Element;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
class EnrollStructure extends Form implements ServiceManagerAwareInterface
{
protected $sm;
public function __construct($name=null) {
parent::__construct("frmEnrollStructure");
$this->setAttribute("action", "/registrazione_struttura/submit")
->setAttribute('method', 'post')
->setAttribute("id", "iscrizione_struttura")
->setAttribute("class", "form fullpage");
$this->addInputFilter();
}
public function init()
{
$structureFs = $this->sm->get('Structure\Form\Fieldsets\Structure');
$structureFs->setUseAsBaseFieldset(true);
$structureFs->remove("id")
->remove("creationTime")
->remove("latLon");
$file = new Element\File("images");
$file->setAttribute('multiple', true);
$this->add($structureFs)->add($file);
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Iscriviti',
'id' => 'sbmtEnrollStructure',
'class' => 'submit_btn'
),
));
$this->setValidationGroup(
array(
'structure' =>
array(
'companyname',
'vatNumber',
'addressStreet',
'addressZip',
'addressCity',
'addressRegion',
'fax',
'publicPhone',
'publicEmail',
'website',
'status',
'ownerNotes',
'category',
'subcategory',
"facilities",
"agreeOnPolicy",
"agreeOnPrivacy",
"subscribeNewsletter",
"contact" => array("name", "surname", "email", "role", "phone"),
),
"images"
));
}
/**
* Set service manager
*
* #param ServiceManager $serviceManager
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->sm = $serviceManager;
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('images');
$fileInput->setRequired(true);
$fileInput->getValidatorChain()
->attachByName('filesize', array('max' => "2MB"))
->attachByName('filemimetype', array('mimeType' => 'image/png,image/x-png,image/jpg,image/jpeg'))
->attachByName('fileimagesize', array('maxWidth' => 2048, 'maxHeight' => 2048));
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
Basically, I mainly use a fieldset which contains most of the data I request to the user, plus a File input field.
This is the Fieldset Structure: (most important parts..)
use Zend\Form\Element;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Validator\Identical;
use Zend\Validator\NotEmpty;
use Zend\Validator\Regex;
use Zend\Validator\StringLength;
class Structure extends Fieldset implements InputFilterProviderInterface, ServiceManagerAwareInterface
{
protected $sm;
public function __construct()
{
parent::__construct('structure');
}
public function init()
{
$this->setHydrator(new DoctrineHydrator($this->_entityManager(),'Structure\Entity\Structure'));
$this->setObject($this->sm->getServiceLocator()->get("Structure_Structure"));
$id = new Element\Hidden("id");
$name = new Element\Text("companyname");
$name->setLabel("Ragione Sociale");
...........
}
public function getInputFilterSpecification()
{
return array
(
"id" => array(
"required" => false,
),
"companyname" => array(
"required" => true,
"validators" => array(
array('name' => "NotEmpty", 'options' => array("messages" => array( NotEmpty::IS_EMPTY => "Inserire la ragione sociale")))
),
),
.....
}
}
This is my controller:
public function submitAction()
{
try {
$this->layout("layout/json");
$form = $this->getForm('Frontend\Form\EnrollStructure');
//$form->addInputFilter();
$structure = $this->getServiceLocator()->get("Structure_Structure");
$viewModel = new ViewModel();
$request = $this->getRequest();
if ($request->isPost())
{
$post = array_merge_recursive
(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid())
{
$structure = $form->getObject();
$contact = $structure->getContact();
$this->getServiceLocator()->get('Structure_ContactService')->save($contact);
$files = $request->getFiles()->toArray();
if(isset($files['images']))
{
$count = 3;
foreach($files['images'] as $pos => $file)
{
$fpath = $this->getServiceLocator()->get('RdnUpload\Container')->upload($file);
if(!empty($fpath))
{
if(--$count ==0) break;
$asset = $this->getServiceLocator()->get("Application_AssetService")->fromDisk($fpath, $file['name']);
$this->getServiceLocator()->get("Application_AssetService")->save($asset);
$structure->addImage($asset);
}
}
}
$this->getServiceLocator()->get('Structure_StructureService')->save($structure);
$retCode = RetCode::success(array("iscrizione_struttura!" => array("form_submit_successfull")), true);
}
else
{
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
}
$viewModel->setVariable("retcode", $retCode);
return $viewModel;
}
} catch(Exception $e)
{
throw $e;
}
}
The strange thing is that if i remove from the field "images" the "multiple" attribute everything works fine, causing the form not to validate and i get this message:
[images] => Array
(
[fileUploadFileErrorFileNotFound] => File was not found
)
While, if i set the attribute multiple, and the user does not upload a file i get no error, but the form gets invalidated (this is the reason for this "bad" code in my controller:)
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
I found the problem was caused by the Jquery form plugin, without it it works fine. :( In case somebody needs, I think the correct action code can be found here (I haven't tryied it anyway)
https://github.com/cgmartin/ZF2FileUploadExamples/blob/master/src/ZF2FileUploadExamples/Controller/ProgressExamples.php

How to add both Form and List to $this [Plesk/Zend]

I have some sample code with 2 tabs. One shows a "form" and the other a "list" (Sample 1.5-1), I want to combine them.
I want to show the "form" tab with a "list" view at the bottom (after submit button). I am getting stuck on how to show this.
Inside IndexController, in the ->getRequest->isPost() area, I try to create and fill up the $list (same as the "list" tab example code):
$list=$this->_getListRandom();
$this->view->list = $list;
Then inside of form.phtml, I append:
<h1>My Report Data></h1>
<?php echo $this->list; ?>
I can see the "My Report Data" text in the web page, so I know I am getting to the right area in the code!
But, I get an error from pm_View_Helper_render::renderList() that it must be an instance of pm_View_List_Simple.
I am trying to create both a pm_Form_Simple and pm_View_List_Simple in the same $this, but not
sure if it is allowed or how to do it.
Thanks for any suggestions!
<?php
class IndexController extends pm_Controller_Action
{
public function init()
{
parent::init();
// Init title for all actions
$this->view->pageTitle = 'Example Module';
// Init tabs for all actions
$this->view->tabs = array(
array(
'title' => 'Form',
'action' => 'form',
),
array(
'title' => 'List',
'action' => 'list',
),
);
}
public function indexAction()
{
// Default action will be formAction
$this->_forward('form');
}
public function formAction()
{
// Init form here
$form = new pm_Form_Simple();
$form->addElement('text', 'exampleText', array(
'label' => 'Example Text',
'value' => pm_Settings::get('exampleText'),
'required' => true,
'validators' => array(
array('NotEmpty', true),
),
));
$form->addControlButtons(array(
'cancelLink' => pm_Context::getModulesListUrl(),
));
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
// Form proccessing here
pm_Settings::set('exampleText', $form->getValue('exampleText'));
$this->_status->addMessage('info', 'Data was successfully saved.');
# Create the LIST
$list = $this->_getListRandom();
$this->view->list = $list;
$this->_helper->json(array('redirect' => pm_Context::getBaseUrl()));
}
$this->view->form = $form;
}
public function listAction()
{
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
public function listDataAction()
{
$list = $this->_getListRandom();
// Json data from pm_View_List_Simple
$this->_helper->json($list->fetchData());
}
private function _getListRandom()
{
$data = array();
#$iconPath = pm_Context::getBaseUrl() . 'images/icon_16.gif';
for ($i = 0; $i < 15; $i++) {
$data[] = array(
'column-1' => '' . (string)rand() . '',
'column-2' => (string)rand(),
);
}
$list = new pm_View_List_Simple($this->view, $this->_request);
$list->setData($data);
$list->setColumns(array(
'column-1' => array(
'title' => 'Random with link',
'noEscape' => true,
),
'column-2' => array(
'title' => 'Random with image',
'noEscape' => true,
),
));
// Take into account listDataAction corresponds to the URL /list-data/
$list->setDataUrl(array('action' => 'list-data'));
return $list;
}
}
Please, try https://mega.co.nz/#!NxtyzbyS!JQqFdh7ruESQU_pgmhM6vi8yVFZQRTH-sPDeQcAOFws
Following files are changed:
\example-1.5-2\plib\views\scripts\index\form.phtml:
<?php echo $this->renderTabs($this->tabs); ?>
<?php echo $this->test; ?>
<?php echo $this->form; ?>
<?php echo $this->renderList($this->list); ?>
\example-1.5-2\plib\controllers\IndexController.php:
public function formAction() {
...
...
...
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
and here the result:

$form->isValid says it is invalid, but my form does not show any error message - Zend Framework 2

Im having a problem with the addAction in my CRUD application. On the controller the logic does not pass the $form->isValid() verification but the form does not show any error message.
I tried with this (Thanks Sam):
foreach($form->get('product')->getElements() as $el)
{
echo $el->getName()." = ".$el->getValue()." > ".$el->getMessages()." <br/>";
}
That only show the name and value of the field, but not the error message.
I've tried letting the form totally blank and it fire "Value is required and can't be empty" error messages, but then, i fill each field one by one until i don't get more error messages but the form still invalid.
My form has a Product Fieldset as a base fieldset and a submit button. Inside Product Fieldset i have an ID field, a name field, a price field and a Brand Fieldset. Inside my Brand Fieldset i have a id field. Like this:
ProductForm:
class ProductForm extends Form
{
public function init()
{
// we want to ignore the name passed
parent::__construct('product');
$this->setName('product');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'product',
'type' => 'Administrador\Form\ProductFieldset',
'options' => array(
'use_as_base_fieldset' => true
),
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Add',
'id' => 'submitbutton',
),
));
}
}
ProductFieldset:
class ProductFieldset extends Fieldset implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
function __construct($name = null)
{
parent::__construct('product_fieldset');
$this->setHydrator(new ArraySerializableHydrator());
$this->setObject(new Product());
}
public function init()
{
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array(
'name' => 'name',
'type' => 'Text',
'options' => array(
'label' => 'Name',
),
));
$this->add(array(
'name' => 'price',
'type' => 'Text',
'options' => array(
'label' => 'Price',
),
));
$this->add(array(
'name' => 'brand',
'type' => 'BrandFieldset',
));
}
public function setServiceLocator(ServiceLocatorInterface $sl)
{
$this->serviceLocator = $sl;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
BrandFieldset:
class BrandFieldset extends Fieldset
{
function __construct(BrandTable $brandTable)
{
parent::__construct('brand_fieldset');
//$this->setHydrator(new ClassMethodsHydrator(false))->setObject(new Brand());
$this->setHydrator(new ArraySerializableHydrator());
$this->setObject(new Brand());
$brandSelectOptionsArray = $brandTable->populateSelectBrand();
$this->add(array(
'name' => 'id',
'type' => 'Select',
'options' => array(
'label' => 'Brand',
'empty_option' => 'Please select a brand',
'value_options' => $brandSelectOptionsArray,
),
));
}
}
This is my new Form statement in the addAction:
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Administrador\Form\ProductForm');
Inside my model 'Product' i have the inputFilters, required filter for 'id' field, required filter for 'name' field. And for the Brand field i created other inputFilter and added it to the main inputFilter:
$brandFilter->add($factory->createInput(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
)));
$inputFilter->add($brandFilter, 'brand');
The weird behavior is that my editAction works fine and has the same logic.
Is it there any form of echoing an internal error message from the form, something that helps me to understand WHY the form is not valid.
EDIT 2013-06-01
Here is my full Controller:
class ProductController extends AbstractActionController
{
protected $productTable;
protected $brandTable;
public function indexAction()
{
return new ViewModel(array(
'products' => $this->getProductTable()->fetchAll(),
));
}
public function addAction()
{
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Administrador\Form\ProductForm');
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$product = new Product();
$product->brand = new Brand();
$form->setInputFilter($product->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$product->exchangeArray($form->getData());
$this->getProductTable()->saveProduct($product);
// Redirect to list of products
return $this->redirect()->toRoute('product');
}
}
return new ViewModel(array(
'form' => $form,
));
}
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('product', array(
'action' => 'add'
));
}
// Get the Product with the specified id. An exception is thrown
// if it cannot be found, in which case go to the index page.
try {
$product = $this->getProductTable()->getProduct($id);
}
catch (\Exception $ex) {
return $this->redirect()->toRoute('product', array(
'action' => 'index'
));
}
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Administrador\Form\ProductForm');
$brand = $this->getBrandTable()->getBrand($product->brand);
$product->brand = $brand;
$form->bind($product);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($product->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getProductTable()->saveProduct($form->getData());
// Redirect to list of products
return $this->redirect()->toRoute('product');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
public function deleteAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('product');
}
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->getPost('del', 'No');
if ($del == 'Yes') {
$id = (int) $request->getPost('id');
$this->getProductTable()->deleteProduct($id);
}
// Redirect to list of products
return $this->redirect()->toRoute('product');
}
return array(
'id' => $id,
'product' => $this->getProductTable()->getProduct($id)
);
}
public function getProductTable()
{
if (!$this->productTable) {
$sm = $this->getServiceLocator();
$this->productTable = $sm->get('Administrador\Model\ProductTable');
}
return $this->productTable;
}
public function getBrandTable()
{
if (!$this->brandTable) {
$sm = $this->getServiceLocator();
$this->brandTable = $sm->get('Administrador\Model\BrandTable');
}
return $this->brandTable;
}
}
My case was I passed wrong input filter. isValid returns false, but $form->getMessages() is empty. Form OrderForm had the following:
$form->setInputFilter(new \Application\Form\UserInputFilter($er));
When I changed UserInputFilter to OrderInputFilter it works.
Well, I got the answer :D
This is how the addAction should be:
public function addAction()
{
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Administrador\Form\ProductForm');
$form->get('submit')->setValue('Add');
$product = new Product();
$product->brand = new Brand();
$form->bind($product); // I need to bind the product to the form to pass the isValid() validation
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($product->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$product = $form->getData();
$this->getProductTable()->saveProduct($product);
// Redirect to list of products
return $this->redirect()->toRoute('product');
}
}
return new ViewModel(array(
'form' => $form,
));
}
Apparently i needed to bind and empty product object to the form to be able to pass the isValid() validation. After that i retrieve a product object from the $form->getData().
You can also do: $form->setBindOnValidate(false);

Zend Framework: My form wont render

So I have created a form below with Zend Framework which I'm then going to customise. My first issue is that with the csrf hash security I get an application error. However, when I remove them lines all I get is a blanks screen which is only resolved when I remove the CPATCHA protection. Can anyone explain to me why?
My Form:
class Application_Form_Clips extends Zend_Form
{
public function init()
{
// Set the method for the display form to POST
$this->setMethod('post');
// Add an email element
$this->addElement('text', 'email', array(
'label' => 'Your email address:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
)
));
// Add the comment element
$this->addElement('textarea', 'comment', array(
'label' => 'Please Comment:',
'required' => true,
'validators' => array(
array('validator' => 'StringLength', 'options' => array(0, 20))
)
));
// Add a captcha
$this->addElement('captcha', 'captcha', array(
'label' => 'Please enter the 5 letters displayed below:',
'required' => true,
'captcha' => array(
'captcha' => 'Figlet',
'wordLen' => 5,
'timeout' => 300
)
));
// Add the submit button
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Sign Guestbook',
));
// And finally add some CSRF protection
$this->addElement('hash', 'csrf', array(
'ignore' => true,
));
}
}
My Controller:
class AdminController extends Zend_Controller_Action
{
public function init()
{
// get doctrine and the entity manager
$this->doctrine = Zend_Registry::get('doctrine');
$this->entityManager = $this->doctrine->getEntityManager();
// get the users repository
$this->indexVideos = $this->entityManager->getRepository('\ZC\Entity\Videos');
$this->indexClips = $this->entityManager->getRepository('\ZC\Entity\Clips');
}
public function indexAction()
{
// action body
}
public function clipsAction()
{
// get a form
$form = new Application_Form_Clips();
$this->view->form = $form;
}
public function videosAction()
{
// action body
}
}
My View:
<?php echo $this->form; ?>
Basic error, I hadn't uncommented session.pat in my php.ini