lib/form: Bypass sent and submit handling if the form is an API target

refs #9606
This commit is contained in:
Eric Lippmann 2015-08-20 13:10:17 +02:00
parent dcb1502286
commit 71ff4512c3

View File

@ -60,6 +60,17 @@ class Form extends Zend_Form
*/ */
protected $created = false; protected $created = false;
/**
* Whether the form is an API target
*
* When the form is an API target, the form evaluates as submitted if the request method equals the form method.
* That means, that the submit button and form identification are not taken into account. In addition, the CSRF
* counter measure will not be added to the form's elements.
*
* @var bool
*/
protected $isApiTarget = false;
/** /**
* The request associated with this form * The request associated with this form
* *
@ -651,6 +662,29 @@ class Form extends Zend_Form
return $this->useFormAutosubmit; return $this->useFormAutosubmit;
} }
/**
* Get whether the form is an API target
*
* @return bool
*/
public function getIsApiTarget()
{
return $this->isApiTarget;
}
/**
* Set whether the form is an API target
*
* @param bool $isApiTarget
*
* @return $this
*/
public function setIsApiTarget($isApiTarget = true)
{
$this->isApiTarget = (bool) $isApiTarget;
return $this;
}
/** /**
* Create this form * Create this form
* *
@ -951,7 +985,7 @@ class Form extends Zend_Form
if (! $this->tokenDisabled) { if (! $this->tokenDisabled) {
$request = $this->getRequest(); $request = $this->getRequest();
if (! $request->isXmlHttpRequest() if (! $request->isXmlHttpRequest()
&& $request->getIsApiRequest() && ($this->getIsApiTarget() || $request->getIsApiRequest())
) { ) {
return $this; return $this;
} }
@ -1016,17 +1050,26 @@ class Form extends Zend_Form
} }
$formData = $this->getRequestData(); $formData = $this->getRequestData();
if ($this->getUidDisabled() || $this->wasSent($formData)) { if ($this->getIsApiTarget() || $this->getUidDisabled() || $this->wasSent($formData)) {
if (($frameUpload = (bool) $request->getUrl()->shift('_frameUpload', false))) { if (($frameUpload = (bool) $request->getUrl()->shift('_frameUpload', false))) {
$this->getView()->layout()->setLayout('wrapped'); $this->getView()->layout()->setLayout('wrapped');
} }
$this->populate($formData); // Necessary to get isSubmitted() to work $this->populate($formData); // Necessary to get isSubmitted() to work
if (! $this->getSubmitLabel() || $this->isSubmitted()) { if (! $this->getSubmitLabel() || $this->isSubmitted()) {
if ($this->isValid($formData) if ($this->isValid($formData)
&& (($this->onSuccess !== null && false !== call_user_func($this->onSuccess, $this)) && (($this->onSuccess !== null && false !== call_user_func($this->onSuccess, $this))
|| ($this->onSuccess === null && false !== $this->onSuccess()))) { || ($this->onSuccess === null && false !== $this->onSuccess()))
if (! $frameUpload) { ) {
if ($this->getIsApiTarget() || $this->getRequest()->getIsApiRequest()) {
// API targets and API requests will never redirect but immediately respond w/ JSON-encoded
// notifications
$messages = Notification::getInstance()->popMessages();
// @TODO(el): Use ApiResponse class for unified response handling.
$this->getRequest()->sendJson(array(
'status' => 'success',
'message' => array_pop($messages) // @TODO(el): Remove the type from the message
));
} elseif (! $frameUpload) {
$this->getResponse()->redirectAndExit($this->getRedirectUrl()); $this->getResponse()->redirectAndExit($this->getRedirectUrl());
} else { } else {
$this->getView()->layout()->redirectUrl = $this->getRedirectUrl()->getAbsoluteUrl(); $this->getView()->layout()->redirectUrl = $this->getRedirectUrl()->getAbsoluteUrl();
@ -1052,6 +1095,12 @@ class Form extends Zend_Form
*/ */
public function isSubmitted() public function isSubmitted()
{ {
if (strtolower($this->getRequest()->getMethod()) !== $this->getMethod()) {
return false;
}
if ($this->getIsApiTarget()) {
return true;
}
if ($this->getSubmitLabel()) { if ($this->getSubmitLabel()) {
return $this->getElement('btn_submit')->isChecked(); return $this->getElement('btn_submit')->isChecked();
} }