2

I'm making a clone action in sonata admin--following the recommendations of Sonata docs:

<?php // src/Acme/DemoBundle/Controller/CRUDController.php

namespace Acme\DemoBundle\Controller;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;

class CRUDController extends Controller
{
public function cloneAction()
{
    $id = $this->get('request')->get($this->admin->getIdParameter());

    $object = $this->admin->getObject($id);

    if (!$object) {
        throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
    }

    $clonedObject = clone $object;
    $clonedObject->setName($object->getName()." (Clone)");

    $this->admin->create($clonedObject);

    $this->addFlash('sonata_flash_success', 'Cloned successfully');

    return new RedirectResponse($this->admin->generateUrl('list'));
}
}

after setting an id on the $clonedobject I get a DBAL exception. primary keys with same id not allowed--

I've tried setting a unique id

no id with the hope that auto increment in my schema would force ++

thanks for your help

sjt003
  • 2,407
  • 5
  • 24
  • 39

2 Answers2

2

Geert is right, setting the id to null is the way to go with Doctrine.

However, rather than having to implement a setId method in your object, you may as well override the __clone method as follows:

public function __clone()
{
    parent::__clone();
    $this->id = null;
    $this->name .= " (Clone)";
}

See How to re-save the entity as another row in Doctrine 2

Community
  • 1
  • 1
Hugo Briand
  • 1,683
  • 20
  • 27
  • would one use `parent::__clone()`? – sjt003 May 13 '14 at 20:51
  • Well we do not have the inheritance scheme here but there might be some. In that case, better be sure (and your were right about the syntax, my mistake). Moreover, we want all fields to be copied as well, we simply need to set the id to null. – Hugo Briand May 14 '14 at 10:23
1

I think the easy solution is to set your id to null and doctrine will generate an id for you while creating the cloned object...

$clonedObject = clone $object;
$clonedObject->setId(NULL);
$clonedObject->setName($object->getName()." (Clone)");
Geert Wille
  • 1,656
  • 13
  • 18
  • AUTO in entity $id annotation defers to the db increment setting. Tried your method. Id cannot be null while MySQL is set to auto increment and annotation is set to AUTO. I've hacked this by doing a prePersist and setting the properties of the new $clonedObject equal to $object. This is not really the way I want to go with it though. I'll post when I have something more concrete and less hacky. I appreciate your answer! – sjt003 May 06 '14 at 16:23
  • I've used it myself and it works as expected... If the value of the id is null then doctrine will generate a new entity and fill the id up with the auto increment value. (depending on your annotation settings of course) So I don't really get what your issue is... – Geert Wille May 06 '14 at 16:29
  • When I set the $id as null or otherwise the $clonedObject retains the $object id , providing me sql error for inserting duplicate ids – sjt003 May 06 '14 at 16:38
  • are you sure you did provide a setter for id if you used my example? It's not normal that if you do set it to null that it retains the id... – Geert Wille May 06 '14 at 16:42
  • I'm sure I tried your example. It was one of the first things I tried. It seemed to be the most natural solution, and the easiest, but I got the same error. If I don't use create action I can replicate the clone action, but I have to set all the properties. – sjt003 May 06 '14 at 16:48