Object 创建自己的操作以克隆/复制带有嵌套子元素的TYPO3 8.7 extbase对象

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。有没有一个例子或最佳案例来处理这项任务?我没有发现,甚至我发现了一些关于同一主题的问题和答案,但是旧版本。我希望到目前为止,有一个更直接

我在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;
        }