/** * Computes the changes of a child. * * @param array $mapping the mapping data * @param mixed $child the child document. * @param string $parentId the id of the parent document * @param string $nodename the name of the node as specified by the mapping * @param mixed $parent the parent document * * @return object the child instance (if we are replacing a child this can be a different instance than was originally provided) */ private function computeChildChanges($mapping, $child, $parentId, $nodename, $parent = null) { $targetClass = $this->dm->getClassMetadata(get_class($child)); $state = $this->getDocumentState($child); switch ($state) { case self::STATE_NEW: // cascade persist is implicit on children, no check for cascading // check if we have conflicting nodename information on creation. if ($targetClass->nodename) { $assignedName = $targetClass->getFieldValue($child, $targetClass->nodename); if ($assignedName && $assignedName != $nodename) { throw IdException::conflictingChildName($parentId, $mapping['fieldName'], $nodename, $child, $assignedName); } } $childId = $parentId . '/' . $nodename; $targetClass->setIdentifierValue($child, $childId); if ($this->getDocumentById($childId)) { $child = $this->merge($child); } else { $this->persistNew($targetClass, $child, ClassMetadata::GENERATOR_TYPE_ASSIGNED, $parent); } $this->computeChangeSet($targetClass, $child); break; case self::STATE_DETACHED: throw new InvalidArgumentException('A detached document was found through a child relationship during cascading a persist operation: ' . self::objToStr($child, $this->dm)); default: if (PathHelper::getParentPath($this->getDocumentId($child)) !== $parentId) { throw PHPCRException::cannotMoveByAssignment(self::objToStr($child, $this->dm)); } } return $child; }