TYPO3 流体形式 returns 旧值
TYPO3 Fluid Form returns old values
我 运行 使用具有两个字段 username
和 password
的流体创建表单。当第一个 运行 时,正确的数据被发送到操作。当重新提交不同的数据时,将原始数据而不是新值发送到控制器操作。我该如何解决这个问题?
编辑:我发现包含 user-submitted 表单字段及其值的数组是从请求中获取的,按原样序列化 和存储在名为“__referrer[arguments]
”的隐藏输入字段中的字符串,然后将其与表单一起提交回用户。当用户再次使用新值重新提交表单时,用户没有意识到旧值以序列化字符串的形式存在于表单中,并与新值一起提交。事实证明,如果验证器没有报告错误,这是可以的。在这种情况下,数据只是简单地传递给控制器操作,然后继续处理。但是如果收集到错误,则处理不会发送到控制器操作,而是发送到错误操作。错误操作反序列化旧数据并将该数据(而不是新值)转发到预期的操作控制器。参见 \TYPO3\CMS\Extbase\Mvc\Controller\ActionController::forwardToReferringRequest()
。
编辑:重现步骤;
创建一个带有一个参数的动作,并创建一个带有一个输入元素和一个提交按钮的表单。为元素创建一个验证器。将其设为字符串 属性。当一切都说完之后,首先发送一个 VALID 值并让表单 return。它会毫无错误地返回。而且,如果您查看它的隐藏值,您会发现 __referrer[arguments]
发生了变化。那是因为您以前的值已序列化并且存在。现在提交一个 INVALID 值并检查输入您的操作的值。你会惊呆他们是旧的。
这很奇怪。目前,如果我在 \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::renderHiddenReferrerFields()
方法中禁用 __referrer[arguments]
输入字段的生成,则一切正常。我该如何解决这个问题?请帮忙。
哪里出了问题:
此处:\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::forwardToReferringRequest()
。在此方法中,arguments
是从 __referrer
内部参数而不是提交的值中寻找的。通常,如果发现错误,在arguments
表单变量中只会找到两个元素:controller
控制器名称和action
动作名称。这是因为它们最初是与表单一起提交的,只要验证器发现错误,它们就会不做更改地回收。不会添加任何其他内容。这很好......直到它验证。当它验证时,结果直接发送到动作控制器,而不是通过错误控制器。当流程返回到表单时,提交的对象或参数将被添加到表单并返回给用户。记住它已验证。当您接下来发送一个错误的值时,它会转到错误控制器,但是旧值(已验证)并在 __referrer[arguments]
中被序列化,并被反序列化并转发给您的操作。这就是你如何在你的行动中以旧价值观结束。这是因为它假定变量内部只包含两个值;仅控制器和操作名称。错了。
假设:
表单 post 值处理似乎是在这样的假设下构建的,即一旦表单通过验证,您将不再需要它。
新闻。
您发送的值是从 extbase
参数中寻找的,并在 \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::renderHiddenReferrerFields()
方法中序列化,在呈现给您之前添加到表单中。 TYPO3 所要做的就是跳过你的值,让默认值只被序列化。刚看到函数的文档部分有这个:
/**
* Renders hidden form fields for referrer information about
* the current controller and action.
*
* @return string Hidden fields with referrer information
* @todo filter out referrer information that is equal to the target (e.g. same packageKey)
*/
@todo
部分是新闻。希望它在 next-patch 中完成,因为在许多情况下您想要恢复表单,例如在数据输入中。
解决方案
最简单的解决方案:在您的操作中初始化空参数并将该参数传递给表单。就我而言,我使用 DTO。
范例
public function accountLoginAction(DTO\Account\LoginDTO $accountLogin=null):ResponseInterface
{
if($accountLogin){
$this->repository->logon();
...
} else{
$accountLogin=DTO\Account\LoginDTO::getNewInstance();
}
$this->view->assign('object', $accountLogin);
return $this->response();
}
希望对大家有所帮助。
我 运行 使用具有两个字段 username
和 password
的流体创建表单。当第一个 运行 时,正确的数据被发送到操作。当重新提交不同的数据时,将原始数据而不是新值发送到控制器操作。我该如何解决这个问题?
编辑:我发现包含 user-submitted 表单字段及其值的数组是从请求中获取的,按原样序列化 和存储在名为“__referrer[arguments]
”的隐藏输入字段中的字符串,然后将其与表单一起提交回用户。当用户再次使用新值重新提交表单时,用户没有意识到旧值以序列化字符串的形式存在于表单中,并与新值一起提交。事实证明,如果验证器没有报告错误,这是可以的。在这种情况下,数据只是简单地传递给控制器操作,然后继续处理。但是如果收集到错误,则处理不会发送到控制器操作,而是发送到错误操作。错误操作反序列化旧数据并将该数据(而不是新值)转发到预期的操作控制器。参见 \TYPO3\CMS\Extbase\Mvc\Controller\ActionController::forwardToReferringRequest()
。
编辑:重现步骤;
创建一个带有一个参数的动作,并创建一个带有一个输入元素和一个提交按钮的表单。为元素创建一个验证器。将其设为字符串 属性。当一切都说完之后,首先发送一个 VALID 值并让表单 return。它会毫无错误地返回。而且,如果您查看它的隐藏值,您会发现 __referrer[arguments]
发生了变化。那是因为您以前的值已序列化并且存在。现在提交一个 INVALID 值并检查输入您的操作的值。你会惊呆他们是旧的。
这很奇怪。目前,如果我在 \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::renderHiddenReferrerFields()
方法中禁用 __referrer[arguments]
输入字段的生成,则一切正常。我该如何解决这个问题?请帮忙。
哪里出了问题:
此处:\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::forwardToReferringRequest()
。在此方法中,arguments
是从 __referrer
内部参数而不是提交的值中寻找的。通常,如果发现错误,在arguments
表单变量中只会找到两个元素:controller
控制器名称和action
动作名称。这是因为它们最初是与表单一起提交的,只要验证器发现错误,它们就会不做更改地回收。不会添加任何其他内容。这很好......直到它验证。当它验证时,结果直接发送到动作控制器,而不是通过错误控制器。当流程返回到表单时,提交的对象或参数将被添加到表单并返回给用户。记住它已验证。当您接下来发送一个错误的值时,它会转到错误控制器,但是旧值(已验证)并在 __referrer[arguments]
中被序列化,并被反序列化并转发给您的操作。这就是你如何在你的行动中以旧价值观结束。这是因为它假定变量内部只包含两个值;仅控制器和操作名称。错了。
假设:
表单 post 值处理似乎是在这样的假设下构建的,即一旦表单通过验证,您将不再需要它。
新闻。
您发送的值是从 extbase
参数中寻找的,并在 \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::renderHiddenReferrerFields()
方法中序列化,在呈现给您之前添加到表单中。 TYPO3 所要做的就是跳过你的值,让默认值只被序列化。刚看到函数的文档部分有这个:
/**
* Renders hidden form fields for referrer information about
* the current controller and action.
*
* @return string Hidden fields with referrer information
* @todo filter out referrer information that is equal to the target (e.g. same packageKey)
*/
@todo
部分是新闻。希望它在 next-patch 中完成,因为在许多情况下您想要恢复表单,例如在数据输入中。
解决方案
最简单的解决方案:在您的操作中初始化空参数并将该参数传递给表单。就我而言,我使用 DTO。 范例
public function accountLoginAction(DTO\Account\LoginDTO $accountLogin=null):ResponseInterface
{
if($accountLogin){
$this->repository->logon();
...
} else{
$accountLogin=DTO\Account\LoginDTO::getNewInstance();
}
$this->view->assign('object', $accountLogin);
return $this->response();
}
希望对大家有所帮助。