private static function setNulls($entity, array $metadata, IModel $model, array &$pre)
{
foreach ($metadata as $propertyMeta) {
$type = $propertyMeta->relationship->type;
$name = $propertyMeta->name;
$reverseRepository = $model->getRepository($propertyMeta->relationship->repository);
$reverseProperty = $propertyMeta->relationship->property ? $reverseRepository->getEntityMetadata()->getProperty($propertyMeta->relationship->property) : null;
if ($type === Relationship::MANY_HAS_MANY) {
/** @var ManyHasMany $property */
$property = $entity->getProperty($name);
$pre[] = $property;
if ($reverseProperty !== null) {
foreach ($property as $reverseEntity) {
$pre[] = $reverseEntity->getProperty($reverseProperty->name);
}
}
$entity->setValue($name, []);
} elseif ($type === Relationship::MANY_HAS_ONE || $type === Relationship::ONE_HAS_ONE && $propertyMeta->relationship->isMain) {
/** @var ManyHasOne|OneHasOne $property */
$property = $entity->getProperty($name);
if ($reverseProperty !== null && $entity->hasValue($name)) {
$pre[] = $entity->getValue($name)->getProperty($reverseProperty->name);
}
$property->set(null, true);
} else {
// $type === Relationship::ONE_HAS_MANY or
// $type === Relationship::ONE_HAS_ONE && !$isMain
if (!$entity->hasValue($name) || $reverseProperty === null) {
continue;
}
if ($reverseProperty->isNullable) {
if ($type === Relationship::ONE_HAS_MANY) {
foreach ($entity->getValue($name) as $subValue) {
$pre[] = $subValue;
}
$entity->setValue($name, []);
} else {
$pre[] = $entity->getValue($name);
$entity->getProperty($name)->set(null, true);
}
} else {
if ($type === Relationship::ONE_HAS_MANY && $entity->getValue($name)->count() === 0) {
continue;
}
$entityClass = get_class($entity);
$reverseEntityClass = $propertyMeta->relationship->entity;
$primaryValue = $entity->getValue('id');
$primaryValue = is_array($primaryValue) ? '[' . implode(', ', $primaryValue) . ']' : $primaryValue;
throw new InvalidStateException("Cannot remove {$entityClass}::\$id={$primaryValue} because {$reverseEntityClass}::\${$reverseProperty->name} cannot be a null.");
}
}
}
}