在我的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
}
看起来很不错,但没有新的对象添加到存储库中,我没有收到错误。我检查了文档,没有明确的方法可用于复制。
答案 0 :(得分: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.
答案 1 :(得分:3)
对于那些可能关心的人:
此时您不需要调用reflection-api。 您只需要实现一个名为的方法,例如你的模型中的resetUid()是这样的:
public function resetUid() {
$this->uid = NULL;
$this->_setClone(FALSE);
}
然后您可以使用魔术clone
方法克隆控制器中的对象。之后,您必须调用新的resetUid()
方法,然后您可以使用旧属性保留新对象。
答案 2 :(得分:3)
对我来说,解决方案" Clone $ Object和resetUid()在Modell"不起作用..也许这个解决方案适用于较旧的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 ) ;
}
答案 3 :(得分:0)
我认为add命令会忽略已经存在的对象。
您可以尝试克隆该对象,然后将该克隆添加到存储库$copy_of_object = clone $object;
。或者也许创建一个具有所有相同属性的新对象。