public function detectRelationshipReferenceChanges()
{
foreach ($this->managedRelationshipReferences as $oid => $reference) {
$entity = $this->entitiesById[$this->entityIds[$oid]];
$reflO = $this->entityManager->getClassMetadataFor(get_class($entity));
foreach ($reference as $field => $info) {
$property = $reflO->getRelationship($field);
$value = $property->getValue($entity);
if ($value instanceof ArrayCollection || $value instanceof AbstractLazyCollection) {
$value = $value->toArray();
}
if (is_array($value)) {
$currentValue = array_map(function ($ref) {
return $this->entitiesById[$this->entityIds[$ref['target']]];
}, $info);
$compare = function ($a, $b) {
if ($a === $b) {
return 0;
}
return $a < $b ? -1 : 1;
};
$added = array_udiff($value, $currentValue, $compare);
$removed = array_udiff($currentValue, $value, $compare);
foreach ($added as $add) {
// Since this is the same property, it should be ok to re-use the first relationship
$this->scheduleRelationshipReferenceForCreate($entity, $add, $info[0]['rel']);
}
foreach ($removed as $remove) {
$this->scheduleRelationshipReferenceForDelete($entity, $remove, $info[0]['rel']);
}
} elseif (is_object($value)) {
$target = $this->entitiesById[$this->entityIds[$info[0]['target']]];
if ($value !== $target) {
$this->scheduleRelationshipReferenceForDelete($entity, $target, $info[0]['rel']);
$this->scheduleRelationshipReferenceForCreate($entity, $value, $info[0]['rel']);
}
} elseif ($value === null) {
foreach ($info as $ref) {
$target = $this->entitiesById[$this->entityIds[$ref['target']]];
$this->scheduleRelationshipReferenceForDelete($entity, $target, $ref['rel']);
}
}
}
}
}