Duplicating extbase repository object
Asked Answered
S

4

5

In my extbase/fluid project,in addition to standard actions such as create,delete,list etc, I want to create a duplicate of a model class object which are stored in a repository. Using findall(), all objects are displayed in a list and corresponding actions such as delete,edit are displayed next to each. For duplicating an object, I have created a duplicate action in the corresponding controller and here is the code:

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

Seems straitforward enough but no new object is added to the repository and I am not getting an error.I have checked the documentation and there is no explicit method available for duplicating.

Seventeenth answered 17/9, 2012 at 16:16 Comment(0)
L
3

Note : When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.

Alternative you can use reflection to create a (deep) copy of your object.

    $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. 
Leatherleaf answered 26/9, 2012 at 10:41 Comment(0)
A
4

For those who may concern:

You don't need to call the reflection-api at this point. You only need to implement a method called e.g. resetUid() in your model like this:

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

then you can use the magic clone method to clone the object in your controller. after that you have to call the new resetUid() method and then you are able to persist the new object with the old properties.

Avaavadavat answered 12/6, 2014 at 14:45 Comment(0)
L
3

Note : When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.

Alternative you can use reflection to create a (deep) copy of your object.

    $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. 
Leatherleaf answered 26/9, 2012 at 10:41 Comment(0)
C
3

For me, the Solution "Clone $Object and resetUid() in the Modell" does not work .. maybe this solution had worked in older TYPO3 Versions but in 7.6. LTS it throws an exception

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

so maybe someone can find my solution helpful as it is much less code than the other reflection Solution: (and you do not have to think about to set all single properties .. )

Given: an Object called $registrant with all Data. Wanted Result: a copy of that Object with same Data, but new 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 ) ;

}
Commix answered 30/11, 2016 at 18:28 Comment(0)
A
0

I think the add command ignores objects that already exist.

You could try to clone the object and then add the clone to the repository $copy_of_object = clone $object;. Or maybe create a new Object with all the same properties.

Arium answered 22/9, 2012 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.