Created
August 9, 2022 14:13
-
-
Save zim32/5a8e6c7c2127f7e91863543fda05f39b to your computer and use it in GitHub Desktop.
Doctrine trait for handling associations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Zim\Bundle\SymfonyRestHelperBundle\Doctrine; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Doctrine\Common\Collections\Collection; | |
trait ORMSetterTrait | |
{ | |
/** | |
* @param mixed $data Submitted data (Converted by serialized into doctrine entities) | |
* @param string $propertyName Inverse property name | |
* @param string $owningPropertyName Owning property name | |
* @param callable $comparator First argument is submitted item, second argument is existing item | |
* @param boolean $orphanRemoval Pass true, if you need to delete owning entity. Passing true, prevents calling setter on owning side | |
*/ | |
protected function handleOneToMany($data, string $propertyName, string $owningPropertyName, callable $comparator, bool $orphanRemoval = false) | |
{ | |
if (!($data instanceof Collection)) { | |
$data = new ArrayCollection($data); | |
} | |
// handle removing | |
foreach ($this->{$propertyName} as $existing) { | |
if (false === $data->exists(function($key, $val) use ($existing, $comparator) { | |
return $comparator($val, $existing); | |
})) { | |
$this->{$propertyName}->removeElement($existing); | |
$owningSetter = 'set' . ucfirst($owningPropertyName); | |
if (!$orphanRemoval) { | |
$existing->$owningSetter(null); | |
} | |
} | |
} | |
// handle addition | |
foreach ($data as $newItem) { | |
if (false === $this->{$propertyName}->exists(function($key, $item) use ($newItem, $comparator) { | |
return $comparator($newItem, $item); | |
})) { | |
$this->{$propertyName}->add($newItem); | |
$owningSetter = 'set' . ucfirst($owningPropertyName); | |
$newItem->$owningSetter($this); | |
} | |
} | |
} | |
/** | |
* @param mixed $data Submitted data (Converted by serialized into doctrine entities) | |
* @param string $propertyName Inverse property name | |
* @param string $owningPropertyName Owning property name | |
* @param callable $comparator First argument is submitted item, second argument is existing item | |
*/ | |
protected function handleManyToManyInverseSide($data, string $propertyName, string $owningPropertyName, callable $comparator) | |
{ | |
if (!($data instanceof Collection)) { | |
$data = new ArrayCollection($data); | |
} | |
// handle removing | |
foreach ($this->{$propertyName} as $existing) { | |
if (false === $data->exists(function($key, $val) use ($existing, $comparator) { | |
return $comparator($val, $existing); | |
})) { | |
$this->{$propertyName}->removeElement($existing); | |
$owningGetter = 'get' . ucfirst($owningPropertyName); | |
$existing->$owningGetter()->removeElement($this); | |
} | |
} | |
// handle addition | |
foreach ($data as $newItem) { | |
if (false === $this->{$propertyName}->exists(function($key, $item) use ($newItem, $comparator) { | |
return $comparator($newItem, $item); | |
})) { | |
$this->{$propertyName}->add($newItem); | |
$owningGetter = 'get' . ucfirst($owningPropertyName); | |
$newItem->$owningGetter()->add($this); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment