protected function buildName($document, ClassMetadata $class, DocumentManager $dm, $parent, $name) { // get the id of the parent document $id = $dm->getUnitOfWork()->getDocumentId($parent); if (!$id) { throw IdException::parentIdCouldNotBeDetermined($document, $class->parentMapping, $parent); } // edge case parent is root if ('/' === $id) { $id = ''; } return $id . '/' . $name; }
/** * Use the parent field together with an auto generated name to generate the id * * {@inheritDoc} */ public function generate($document, ClassMetadata $class, DocumentManagerInterface $dm, $parent = null) { if (null === $parent) { $parent = $class->parentMapping ? $class->getFieldValue($document, $class->parentMapping) : null; } $id = $class->getFieldValue($document, $class->identifier); if (empty($id) && null === $parent) { throw IdException::noIdNoParent($document, $class->parentMapping); } if (empty($parent)) { return $id; } try { $parentNode = $dm->getNodeForDocument($parent); $existingNames = (array) $parentNode->getNodeNames(); } catch (RepositoryException $e) { // this typically happens while cascading persisting documents $existingNames = array(); } $name = NodeHelper::generateAutoNodeName($existingNames, $dm->getPhpcrSession()->getWorkspace()->getNamespaceRegistry()->getNamespaces(), '', ''); return $this->buildName($document, $class, $dm, $parent, $name); }
/** * 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; }