Make form creation lazy and implement the new validation mechanism
Form creation must not depend on specific function calls. If a forms' elements are required and missing, create them. Form::isValid() must be able to determine whether a form can be processed or not without to rely on a particular button value. refs #5525
This commit is contained in:
parent
37fd3deb67
commit
78a6175acc
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
namespace Icinga\Web;
|
namespace Icinga\Web;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use Zend_Form;
|
use Zend_Form;
|
||||||
|
use Zend_View_Interface;
|
||||||
use Icinga\Web\Session;
|
use Icinga\Web\Session;
|
||||||
use Icinga\Web\Form\Decorator\HelpText;
|
use Icinga\Web\Form\Decorator\HelpText;
|
||||||
use Icinga\Web\Form\Decorator\ElementWrapper;
|
use Icinga\Web\Form\Decorator\ElementWrapper;
|
||||||
|
@ -15,6 +17,13 @@ use Icinga\Web\Form\InvalidCSRFTokenException;
|
||||||
*/
|
*/
|
||||||
class Form extends Zend_Form
|
class Form extends Zend_Form
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Whether this form has been created
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $created = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The view script to use when rendering this form
|
* The view script to use when rendering this form
|
||||||
*
|
*
|
||||||
|
@ -112,14 +121,34 @@ class Form extends Zend_Form
|
||||||
return $this->tokenElementName;
|
return $this->tokenElementName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create this form
|
||||||
|
*
|
||||||
|
* @param array $formData The data to populate the form with
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function create(array $formData = array())
|
||||||
|
{
|
||||||
|
if (false === $this->created) {
|
||||||
|
$this->addElements($this->createElements($formData));
|
||||||
|
$this->addCsrfToken();
|
||||||
|
$this->created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return the elements to add to this form
|
* Create and return the elements to add to this form
|
||||||
*
|
*
|
||||||
* Intended to be implemented by concrete form classes.
|
* Intended to be implemented by concrete form classes.
|
||||||
*
|
*
|
||||||
|
* @param array $formData The data to populate the elements with
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function createElements()
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
@ -177,6 +206,82 @@ class Form extends Zend_Form
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the elements with the given values
|
||||||
|
*
|
||||||
|
* @param array $defaults The values to populate the elements with
|
||||||
|
*/
|
||||||
|
public function setDefaults(array $defaults)
|
||||||
|
{
|
||||||
|
$this->create($defaults);
|
||||||
|
return parent::setDefaults($defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the given data provides a value for each element of this form
|
||||||
|
*
|
||||||
|
* @param array $formData The data to check
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*
|
||||||
|
* @throws LogicException In case this form has no elements
|
||||||
|
*/
|
||||||
|
public function isComplete(array $formData)
|
||||||
|
{
|
||||||
|
$elements = $this->create($formData)->getElements();
|
||||||
|
if (empty($elements)) {
|
||||||
|
throw new LogicException('Forms without elements cannot be complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
$missingValues = array_diff_key($elements, $formData);
|
||||||
|
return empty($missingValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the given values (possibly incomplete) are valid
|
||||||
|
*
|
||||||
|
* Unlike Zend_Form::isValid() this will not set NULL as value for
|
||||||
|
* an element that is not present in the given data.
|
||||||
|
*
|
||||||
|
* @param array $formData The data to validate
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValidPartial(array $formData)
|
||||||
|
{
|
||||||
|
$this->create($formData);
|
||||||
|
return parent::isValidPartial($formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the given values are complete and valid
|
||||||
|
*
|
||||||
|
* @param array $formData The data to validate
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid($formData)
|
||||||
|
{
|
||||||
|
if ($this->isComplete($formData)) {
|
||||||
|
$this->assertValidCsrfToken($formData);
|
||||||
|
return parent::isValid($formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->isValidPartial($formData); // The form can't be processed but we want to show validation errors though
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all elements of this form
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function clearElements()
|
||||||
|
{
|
||||||
|
$this->created = false;
|
||||||
|
return parent::clearElements();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the default decorators
|
* Load the default decorators
|
||||||
*
|
*
|
||||||
|
@ -204,6 +309,19 @@ class Form extends Zend_Form
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render this form
|
||||||
|
*
|
||||||
|
* @param Zend_View_Interface $view The view context to use
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render(Zend_View_Interface $view = null)
|
||||||
|
{
|
||||||
|
$this->create();
|
||||||
|
return parent::render($view);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new (seed, token) pair
|
* Generate a new (seed, token) pair
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue