我正在尝试使用CMS 8.7.9创建嵌套表单,以允许前端中的IRRE。 提交此表单时,如果存在指向1:n关系的记录指向返回根对象,则我会看到已提交的表单数据的验证被跳过。
我有这样的域名模型:
class RootObject extends AbstractEntity {
/**
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Vendor\Ext\Domain\Model\Child>
* @cascade remove
*/
protected $children = null;
/**
* @var \Vendor\Ext\Domain\Model\OtherObject
* @validate NotEmpty
*/
protected $otherProperty = null;
...
}
class Child extends AbstractEntity {
/**
* @var \Vendor\Ext\Domain\Model\RootObject
*/
protected $parent = null;
/**
* @var string
*/
protected $title = '';
...
}
由ExtensionBuilder创建的TCA配置,inline
用于1:n关系,passthrough
在子节点上,指向rootObject。
应该可以在一个表单中创建和编辑RootObject
及其子项。我的流体模板看起来像:
<f:form method="post" controller="RootController" action="update" name="rootObject object="{rootObject}">
<f:form.select property="otherProperty"/>
<f:for each="{rootObject.children}" as="child iteration="iter">
<f:form.textfield type="text" property="children.{iter.index}.title"/>
</f:for>
...
</f:form>
当我为RootObject
提交此表单而没有Child
时,$otherProperty
的NotEmpty验证已正确评估,并且我收到相应的验证错误。但是,只要RootObject
在关系中有Child
,就不会评估otherProperty
的验证。
我将其跟踪到\TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator
,其中validate
重置了验证结果。
我不完全理解为什么 - 但是在验证rootObject
extbase调用Child
的验证器时,又会再次调用rootObject
验证重用验证器实例当前正在验证调用树的rootObject
。然后它会覆盖当前的$result
。
用
修补该行- $this->result = new \TYPO3\CMS\Extbase\Error\Result();
+ $this->result = $this->result ?: new \TYPO3\CMS\Extbase\Error\Result();
解决了这个问题。
我是否使用嵌套表单错误,或者这是一个Extbase错误?
修改
有关验证调用树的更多见解:
ConjunctionValidator($rootObject)
来电
GenericObjectValidator($rootObject->children)
来电
CollectionValidator($rootObject->children)
来电
ConjunctionValidator($child)
来电
GenericObjectValidator($child->parent)
来电
与我们开始时相同的ConjunctionValidator
实例。这导致覆盖在下降到验证$rootObject->children
之前生成的验证结果。
答案 0 :(得分:0)
尝试在您的控制器中执行以下操作:
public function initializeUpdateAction()
{
if ($this->arguments->hasArgument('rootObject')) {
$this->arguments->getArgument('rootObject')
->getPropertyMappingConfiguration()
->forProperty('children.*')
->skipProperties('parent');
}
}
初始化操作在您的操作之前和验证之前运行。
首先我们检查一下我们是否有参数。然后我们获取参数rootObject
的属性映射配置,并告诉它不要验证children.*.parent
,因为它已经过验证。
它是未经测试的,并且是从记忆中写出的,但希望它可以帮助你。