5

在我的 extbase/fluid 项目中,除了创建、删除、列表等标准操作之外,我还想创建存储在存储库中的模型类对象的副本。使用 findall(),所有对象都显示在列表中,并且相应的操作(例如删除、编辑)显示在每个对象旁边。为了复制一个对象,我在相应的控制器中创建了一个复制动作,代码如下:

public function dupcliateAction(Tx_CcCompanylogin_Domain_Model_MyObject $testObject)
{
 $this->myObjectRepository->add($testObject);
 $this->redirect('list');//Lists the objects again from the repository
}

似乎足够严格,但没有新对象添加到存储库中,我没有收到错误。我检查了文档,没有可用于复制的明确方法。

4

4 回答 4

3

注意:当一个对象被克隆时,PHP 5 将对该对象的所有属性执行一个浅拷贝。任何引用其他变量的属性都将保持引用。

或者,您可以使用反射来创建对象的(深层)副本。

    $productClone = $this->objectManager->create('Tx_Theext_Domain_Model_Product');

// $product = source object
    $productProperties = Tx_Extbase_Reflection_ObjectAccess::getAccessibleProperties($product);
    foreach ($productProperties as $propertyName => $propertyValue) {
        Tx_Extbase_Reflection_ObjectAccess::setProperty($productClone, $propertyName, $propertyValue);
    }

// $productAdditions = ObjectStorage property
    $productAdditions = $product->getProductAddition();
    $newStorage = $this->objectManager->get('Tx_Extbase_Persistence_ObjectStorage');
    foreach ($productAdditions as $productAddition) {
        $productAdditionClone = $this->objectManager->create('Tx_Theext_Domain_Model_ProductAddition');
        $productAdditionProperties = Tx_Extbase_Reflection_ObjectAccess::getAccessibleProperties($productAddition);
        foreach ($productAdditionProperties as $propertyName => $propertyValue) {
            Tx_Extbase_Reflection_ObjectAccess::setProperty($productAdditionClone, $propertyName, $propertyValue);
        }
        $newStorage->attach($productAdditionClone);
    }
    $productClone->setProductAddition($newStorage);
// This have to be repeat for every ObjectStorage property, or write a service. 
于 2012-09-26T10:41:37.157 回答
3

对于那些可能担心的人:

此时您不需要调用反射 API。您只需要在您的模型中实现一个名为例如 resetUid() 的方法,如下所示:

public function resetUid() {
  $this->uid = NULL;
  $this->_setClone(FALSE);
}

然后您可以使用魔术clone方法克隆控制器中的对象。之后,您必须调用新resetUid()方法,然后才能使用旧属性保留新对象。

于 2014-06-12T14:45:14.520 回答
3

对我来说,解决方案“在 Modell 中克隆 $Object 和 resetUid()”不起作用.. 也许这个解决方案在较旧的 TYPO3 版本中有效,但在 7.6 中有效。LTS 它抛出异常

#1222871239: The uid "61" has been modified, that is simply too much. 

所以也许有人会发现我的解决方案很有帮助,因为它的代码比其他反射解决方案少得多:(而且您不必考虑设置所有单个属性..)

给定:一个名为 $registrant 的对象,其中包含所有数据。 想要的结果:该对象的副本具有相同的数据,但新的 Uid ..

/** @var \JVE\JvEvents\Domain\Model\Registrant $newregistrant */

$newregistrant = $this->objectManager->get( "JVE\\JvEvents\\Domain\\Model\\Registrant")  ;

$properties = $registrant->_getProperties() ;
unset($properties['uid']) ;

foreach ($properties as $key => $value ) {
    $newregistrant->_setProperty( $key , $value ) ;

}
于 2016-11-30T18:28:57.513 回答
0

我认为 add 命令会忽略已经存在的对象。

您可以尝试克隆对象,然后将克隆添加到存储库$copy_of_object = clone $object;。或者也许创建一个具有所有相同属性的新对象。

于 2012-09-22T09:30:23.370 回答