/**
  * @param ResourceControllerEvent $event
  */
 public function onEvent(ResourceControllerEvent $event)
 {
     $document = $event->getSubject();
     $metadata = $this->documentManager->getClassMetadata(get_class($document));
     if ($metadata->idGenerator !== ClassMetadata::GENERATOR_TYPE_PARENT) {
         throw new \RuntimeException(sprintf('Document of class "%s" must be using the GENERATOR_TYPE_PARENT identificatio strategy (value %s), it is current using "%s" (this may be an automatic configuration: be sure to map both the `nodename` and the `parentDocument`).', get_class($document), ClassMetadata::GENERATOR_TYPE_PARENT, $metadata->idGenerator));
     }
     // NOTE: that the PHPCR-ODM requires these two fields to be set when
     //       when the GENERATOR_TYPE_PARENT "ID" strategy is used.
     $nameField = $metadata->nodename;
     $parentField = $metadata->parentMapping;
     $parentDocument = $metadata->getFieldValue($document, $parentField);
     $phpcrNode = $this->documentManager->getNodeForDocument($parentDocument);
     $parentPath = $phpcrNode->getPath();
     $baseCandidateName = $metadata->getFieldValue($document, $nameField);
     $candidateName = $baseCandidateName;
     $index = 1;
     while (true) {
         $candidatePath = sprintf('%s/%s', $parentPath, $candidateName);
         $existing = $this->documentManager->find(null, $candidatePath);
         // if the existing document is the document we are updating, then thats great.
         if ($existing === $document) {
             return;
         }
         if (null === $existing) {
             $metadata->setFieldValue($document, $nameField, $candidateName);
             return;
         }
         $candidateName = sprintf('%s-%d', $baseCandidateName, $index);
         $index++;
     }
 }
 /**
  * @param object                       $document           The document to convert
  * @param TranslationStrategyInterface $previousStrategy   Translation strategy to remove fields from old location
  * @param ClassMetadata                $previousMeta       Metadata for old translation strategy
  * @param TranslationStrategyInterface $currentStrategy    Translation strategy to save new translations
  * @param ClassMetadata                $currentMeta        Metadata for new translation strategy
  * @param array                        $fields             The fields to handle
  * @param array                        $locales            Target locales to copy translations to.
  * @param bool                         $partialUntranslate Whether we are only a subset of fields back to untranslated
  */
 private function convertDocument($document, TranslationStrategyInterface $previousStrategy, ClassMetadata $previousMeta, TranslationStrategyInterface $currentStrategy, ClassMetadata $currentMeta, array $fields, array $locales, $partialUntranslate)
 {
     $node = $this->dm->getNodeForDocument($document);
     $data = array();
     foreach ($fields as $field) {
         $data[$field] = $currentMeta->getFieldValue($document, $field);
     }
     if ($currentStrategy instanceof NonTranslatedStrategy) {
         $currentStrategy->saveTranslation($data, $node, $currentMeta, null);
     } else {
         foreach ($locales as $locale) {
             $currentStrategy->saveTranslation($data, $node, $currentMeta, $locale);
         }
     }
     if ($partialUntranslate && $previousStrategy instanceof ChildTranslationStrategy) {
         // the child translation strategy would remove the whole child node
         foreach ($previousStrategy->getLocalesFor($document, $node, $previousMeta) as $locale) {
             $translation = $node->getNode(Translation::LOCALE_NAMESPACE . ':' . $locale);
             foreach ($fields as $field) {
                 $translation->setProperty($previousMeta->mappings[$field]['property'], null);
             }
         }
     } else {
         $previousStrategy->removeAllTranslations($document, $node, $previousMeta);
     }
 }
 function it_should_auto_increment_the_name_if_a_conflict_exists(DocumentManagerInterface $documentManager, ResourceControllerEvent $event, ClassMetadata $metadata, NodeInterface $node)
 {
     $document = new \stdClass();
     $parentDocument = new \stdClass();
     $existingDocument = new \stdClass();
     $event->getSubject()->willReturn($document);
     $documentManager->getClassMetadata('stdClass')->willReturn($metadata);
     $metadata->idGenerator = ClassMetadata::GENERATOR_TYPE_PARENT;
     $metadata->nodename = 'title';
     $metadata->parentMapping = 'parent';
     $metadata->getFieldValue($document, 'parent')->willReturn($parentDocument);
     $documentManager->getNodeForDocument($parentDocument)->willReturn($node);
     $node->getPath()->willReturn('/path/to');
     $metadata->getFieldValue($document, 'title')->willReturn('Hello World');
     $documentManager->find(null, '/path/to/Hello World')->willReturn($existingDocument);
     $documentManager->find(null, '/path/to/Hello World-1')->willReturn($existingDocument);
     $documentManager->find(null, '/path/to/Hello World-2')->willReturn($existingDocument);
     $documentManager->find(null, '/path/to/Hello World-3')->willReturn(null);
     $metadata->setFieldValue($document, 'title', 'Hello World-3')->shouldBeCalled();
     $this->onEvent($event);
 }
 /**
  * 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);
 }
 /**
  * {@inheritDoc}
  */
 public function getNodeForDocument($document)
 {
     return $this->wrapped->getNodeForDocument($document);
 }