Clone object of Doctrine Entity with relations

Sometimes you need create copy of entity. What if entity have children? What if their children have children? We’ve got interesting task to deep clone.

Imaging you have related entities:

  1. Form
  2. Section
  3. Field

Form have some sections, sections can have a lot of fields.

Now we need to clone Form entity with careness about all relations.

I have solution with overriding __clone() PHP magic method.
Let’s add function clone to every your entity from Form to Field.
(Form->Section->Field).

Such __clone() method in root parent object Form:

/**
* Clone
*/
public function __clone()
{
  if ($this->id) {
    $this->setId(null);
    $sections = $this->getSections();
    $sectionsArray = new ArrayCollection();
    foreach ($sections as $section) {
      /** @var Section $section */
      $sectionClone = clone $section;
      $sectionClone->setForm($this);
      $sectionsArray->add($sectionClone);
    }
    $this->sections = $sectionsArray;
  }
}

 

This __clone() method in Section entity.

/**
* Clone
*/
public function __clone()
{
  if ($this->id) {
    $this->setId(null);
    $fields = $this->getFields();
    $fieldsArray = new ArrayCollection();
    if ($fields) {
      foreach ($fields as $field) {
        /** @var Field $fieldClone */
        $fieldClone = clone $field;
        $fieldClone->setSection($this);
        $fieldsArray->add($fieldClone);
      }
      $this->fields = $fieldsArray;
    }
  }
}

 

And simple __clone() method for last child entity (Field).

/**
* Clone
*/
public function __clone()
  {
    if ($this->id) {
    $this->setId(null);
  }
}

 

So, let’s $form is object of doctrine entity, then for copying of it just type in your code something very close to this:

$formClone = clone $form;
$this->em->persist($formClone);
$this->em->flush();

Bingo! 🙂