/** * @param Property $property * @param $oldValue * @param $newValue * @return AssociatedCollection * @throws RuntimeException */ private function buildAssociationToManyEntitiesChange(Property $property, $oldValue, $newValue) { if (!$this->isTraversableArray($newValue)) { throw new RuntimeException(sprintf("Property \"%s\" is marked as associated with many entities and require new value to be traversable collection.", $property->getName())); } $oldPersistedArray = $this->toPersistedArray($oldValue); $newPersistedArray = []; $changes = []; foreach ($newValue as $newElement) { $this->validateAssociatedEntity($property, $newElement); if (!$this->identifier->isPersisted($newElement)) { $changes[] = new NewEntity($property, $newElement, false); continue; } $identity = $this->identifier->getIdentity($newElement); $newPersistedArray[$identity] = $newElement; if (array_key_exists($identity, $oldPersistedArray)) { $oldElement = $oldPersistedArray[$identity]; $changeSet = $this->buildChanges($oldElement, $newElement); if ($changeSet->count()) { $changes[] = new EditedEntity($property, $changeSet, $oldElement, $newElement); } continue; } $changes[] = new NewEntity($property, $newElement, true); } foreach ($oldPersistedArray as $identity => $oldElement) { if (!array_key_exists($identity, $newPersistedArray)) { $changes[] = new RemovedEntity($property, $oldElement); } } return new AssociatedCollection($property, $oldValue, $newValue, $changes); }
function let(Definition\Repository $definitions, Identifier $identifier) { $definitions->getDefinition(Argument::type(EntityFake::getClassName()))->willReturn($this->createEntityDefinition()); $definitions->getDefinition(Argument::type(AssociatedEntityFake::getClassName()))->willReturn($this->createAssociatedEntityDefinition()); $identifier->isPersisted(Argument::any())->will(function ($args) { return !is_null($args[0]->getId()); }); $identifier->getIdentity(Argument::any())->will(function ($args) { return $args[0]->getId(); }); $this->beConstructedWith($definitions, $identifier); }
/** * @param $entity * @return int * @throws InvalidArgumentException * @throws RuntimeException */ private function getEntityState($entity) { if (!is_object($entity)) { throw new InvalidArgumentException("Only objects can be registered in Unit of Work."); } if (!$this->isRegistered($entity)) { throw new RuntimeException("Object need to be registered first in the Unit of Work."); } if ($this->registry->isRemoved($entity)) { return EntityStates::REMOVED_ENTITY; } if (!$this->identifier->isPersisted($entity)) { return EntityStates::NEW_ENTITY; } if ($this->isChanged($entity)) { return EntityStates::EDITED_ENTITY; } return EntityStates::PERSISTED_ENTITY; }