Object 创建自己的操作以克隆/复制带有嵌套子元素的TYPO3 8.7 extbase对象
我在TYPO3 8.7中构建了基于extbased的TYPO3扩展。它是一个后端模块。在控制器中,我编写自己的操作来克隆对象。 在本例中,我希望克隆/复制对象“Campaign”,并使用修改后的标题保护它,如将“copy”文本添加到标题中。 但是新对象也应该有自己的新子元素,这些子元素必须是精确的副本。 当调用该操作时,我只得到对象的一个副本,但没有child。有没有一个例子或最佳案例来处理这项任务?我没有发现,甚至我发现了一些关于同一主题的问题和答案,但是旧版本。我希望到目前为止,有一个更直接的解决方案。谢谢你给我的每一个提示,让我找到正确的想法,也许还有一个最新版本的例子。这是我的控制器。如何实现所有子元素的递归复制(有些子元素也有子元素)Object 创建自己的操作以克隆/复制带有嵌套子元素的TYPO3 8.7 extbase对象,object,controller,typo3,extbase,typo3-8.x,Object,Controller,Typo3,Extbase,Typo3 8.x,我在TYPO3 8.7中构建了基于extbased的TYPO3扩展。它是一个后端模块。在控制器中,我编写自己的操作来克隆对象。 在本例中,我希望克隆/复制对象“Campaign”,并使用修改后的标题保护它,如将“copy”文本添加到标题中。 但是新对象也应该有自己的新子元素,这些子元素必须是精确的副本。 当调用该操作时,我只得到对象的一个副本,但没有child。有没有一个例子或最佳案例来处理这项任务?我没有发现,甚至我发现了一些关于同一主题的问题和答案,但是旧版本。我希望到目前为止,有一个更直接
有一种方法从不同的角度处理这个用例,即不带标识的请求参数值自动放入新对象中,然后可以持久化。这基本上是克隆原始对象。这是您需要做的:
编辑
视图,其中有一个单独的提交按钮来调用您的克隆
操作initializeCloneAction()
,并通过$this->request->getArguments()
获取原始请求参数unset($arguments[]['''uu identity'])代码>,如果希望复制而不是共享引用,请对对象具有的每个关系执行相同的操作
$this->request->setArguments($arguments)
再次存储原始请求参数initializeCloneAction()
的外观:
public函数initializeCloneAction()
{
$arguments=$this->request->getArguments();
取消(
$arguments['campaign']['uu identity'],
$arguments['campaign']['SingleRelationship'][''标识'],
);
foreach(数组_键($arguments['campaign']['multiRelation'])为$i){
未设置($arguments['campaign']['multiRelation'][$i][''uu identity']);
}
$this->request->setArguments($arguments);
//现在我们有了新对象,允许创建对象
$this->arguments->getArgument('campaign')->getPropertyMappingConfiguration()
->setTypeConverterOption(PersistentObjectConverter::类,PersistentObjectConverter::配置\允许创建\允许,true)
->allowCreationForSubProperty('singleRelation')
->getConfigurationFor('multiRelation')
->allowCreationForSubProperty('*');
}
现在,如果您使用克隆
操作提交表单,您的克隆
操作将获得一个完全填充的新对象,您可以像往常一样将其存储在存储库中。您的cloneAction()
将非常简单:
public function cloneAction(活动$Campaign)
{
$this->activationrepository->add($campaign);
$this->addFlashMessage('活动复制成功!');
$this->redirect('list');
}
有一种方法可以从不同的角度处理这个用例,即不带标识的请求参数值自动放入新对象中,然后可以持久化。这基本上是克隆原始对象。这是您需要做的:
编辑
视图,其中有一个单独的提交按钮来调用您的克隆
操作initializeCloneAction()
,并通过$this->request->getArguments()
获取原始请求参数unset($arguments[]['''uu identity'])代码>,如果希望复制而不是共享引用,请对对象具有的每个关系执行相同的操作
$this->request->setArguments($arguments)
再次存储原始请求参数initializeCloneAction()
的外观:
public函数initializeCloneAction()
{
$arguments=$this->request->getArguments();
取消(
$arguments['campaign']['uu identity'],
$arguments['campaign']['SingleRelationship'][''标识'],
);
foreach(数组_键($arguments['campaign']['multiRelation'])为$i){
未设置($arguments['campaign']['multiRelation'][$i][''uu identity']);
}
$this->request->setArguments($arguments);
//现在我们有了新对象,允许创建对象
$this->arguments->getArgument('campaign')->getPropertyMappingConfiguration()
->setTypeConverterOption(PersistentObjectConverter::类,PersistentObjectConverter::配置\允许创建\允许,true)
->allowCreationForSubProperty('singleRelation')
->getConfigurationFor('multiRelation')
->allowCreationForSubProperty('*');
}
现在,如果您使用克隆
操作提交表单,您的克隆
操作将获得一个完全填充的新对象,您可以像往常一样将其存储在存储库中。您的cloneAction()
将非常简单:
public function cloneAction(活动$Campaign)
{
$this->activationrepository->add($campaign);
$this->addFlashMessage('活动复制成功!');
$this->redirect('list');
}
我知道这个问题很久以前就得到了回答。但我想提供我的解决方案来创建一个深度
/**
* action clone
* @param \ABC\Copytest\Domain\Model\Campaign $campaign
* @return void
* @var \ABC\Copytest\Domain\Model\Campaign $newCampaign
*/
public function cloneAction(\ABC\Copytest\Domain\Model\Campaign $campaign) {
$newCampaign = $this->objectManager->get("ABC\Copytest\Domain\Model\Campaign");
$properties = $campaign->_getProperties();
unset($properties['uid']);
foreach ($properties as $key => $value) {
$newCampaign->_setProperty($key, $value);
}
$newCampaign->_setProperty('title', $properties['title']. ' COPY');
$this->campaignRepository->add($newCampaign);
$this->addFlashMessage('Clone was created', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::OK);
$this->redirect('list');
}
private function deepcopy($object)
{
$clone = $this->objectManager->get(get_class($object));
$properties = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($object);
foreach ($properties as $propertyName => $propertyValue) {
if ($propertyValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectStorage) {
$v = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\ObjectStorage::class);
foreach($propertyValue as $subObject) {
$subClone = $this->deepcopy($subObject);
$v->attach($subClone);
}
} else {
$v = $propertyValue;
}
if ($v !== null) {
\TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($clone, $propertyName, $v);
}
}
return $clone;
}
if ($propertyValue instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
$objectStorage = $propertyValue->_loadRealInstance();
}
private function deepcopy($object)
{
$clone = $this->objectManager->get(get_class($object));
$properties = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($object);
foreach ($properties as $propertyName => $propertyValue) {
if ($propertyValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectStorage) {
$objectStorage = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\ObjectStorage::class);
foreach ($propertyValue as $subObject) {
$subClone = $this->deepcopy($subObject);
$objectStorage->attach($subClone);
}
} elseif ($propertyValue instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
$objectStorage = $propertyValue->_loadRealInstance();
} else {
$objectStorage = $propertyValue;
}
if ($objectStorage !== null) {
\TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($clone, $propertyName, $objectStorage);
}
}
return $clone;
}