/** * {@inheritDoc} * * @TODO This mehtod needs to be refactored. */ public function merge(PropertyMetadata $propertyMetadata, MergeContext $context) { $innerType = $propertyMetadata->innerType; $reflectionProperty = $propertyMetadata->reflection; if (!$innerType) { throw new MergeException('You must provide an inner type.'); } $reflectionClass = new \ReflectionClass($innerType); $innerClassMetadata = $context->getGraphWalker()->getMetadataFactory()->getMetadataForClass($innerType); $objectIdentifier = $innerClassMetadata->objectIdentifier; if ($objectIdentifier === null) { throw new MergeException('You must provide at least one identifier field.'); } $sourceCollection = $reflectionProperty->getValue($context->getMergeFrom()); $targetCollection = $reflectionProperty->getValue($context->getMergeTo()); if (!$sourceCollection instanceof \Traversable && !is_array($sourceCollection)) { return; } if (!$targetCollection instanceof \Traversable && !is_array($targetCollection)) { return; } $collectedValues = array('missing' => array(), 'removed' => array()); foreach ($sourceCollection as $sourceItem) { foreach ($targetCollection as $targetItem) { if ($this->isMergeable($objectIdentifier, $reflectionClass, $sourceItem, $targetItem)) { $context->getGraphWalker()->accept($sourceItem, $targetItem); continue 2; } } array_push($collectedValues['missing'], $sourceItem); } $this->applyCollectionMergeStrategy($propertyMetadata, $collectedValues, $context); }
/** * Merges an object property. * * @param PropertyMetadata $property Metadata of the property * @param MergeContext $context The current mergingcontext */ public function mergeObject(PropertyMetadata $property, MergeContext $context) { $reflectionProperty = $property->reflection; $leftValue = $context->getPropertyAccessor()->getValue($reflectionProperty, $context->getMergeFrom()); $rightValue = $context->getPropertyAccessor()->getValue($reflectionProperty, $context->getMergeTo()); if (null === $rightValue) { $context->getPropertyAccessor()->setValue($reflectionProperty, $context->getMergeTo(), $leftValue); } else { $context->getGraphWalker()->accept($leftValue, $rightValue); } }