Example #1
0
 /**
  * @BeforeScenario
  */
 public function purgeAndInitializeDatabase()
 {
     $purger = new PHPCRPurger($this->documentManager);
     $purger->purge();
     $this->documentManager->clear();
     $this->initializerManager->initialize();
 }
 /**
  * @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++;
     }
 }
 /**
  * Constructor
  *
  * @param SessionInterface         $session
  * @param DocumentManagerInterface $dm
  */
 public function __construct(SessionInterface $session = null, DocumentManagerInterface $dm = null)
 {
     if (!$session && $dm) {
         $session = $dm->getPhpcrSession();
     }
     parent::__construct($session);
     $this->dm = $dm;
 }
 protected function initPhpcr(DocumentManagerInterface $documentManager)
 {
     $session = $documentManager->getPhpcrSession();
     $rootNode = $session->getRootNode();
     if ($rootNode->hasNode('test')) {
         $rootNode->getNode('test')->remove();
     }
     $rootNode->addNode('test');
 }
Example #5
0
 /**
  * {@inheritdoc}
  */
 public function getDataSource(array $configuration, Parameters $parameters)
 {
     if (!array_key_exists('class', $configuration)) {
         throw new \InvalidArgumentException('"class" must be configured.');
     }
     $repository = $this->documentManager->getRepository($configuration['class']);
     $queryBuilder = $repository->createQueryBuilder(self::QB_SOURCE_ALIAS);
     return new DataSource($queryBuilder);
 }
Example #6
0
 function it_should_clean_the_name(ResourceControllerEvent $event, DocumentManagerInterface $documentManager, ClassMetadata $metadata)
 {
     $document = new \stdClass();
     $event->getSubject()->willReturn($document);
     $documentManager->getClassMetadata('stdClass')->willReturn($metadata);
     $metadata->nodename = 'foobar';
     $metadata->getFieldValue($document, 'foobar')->willReturn('Hello//Foo');
     $metadata->setFieldValue($document, 'foobar', 'Hello  Foo')->shouldBeCalled();
     $this->onEvent($event);
 }
 private function expandClassName(DocumentManagerInterface $dm, $className = null)
 {
     if (null === $className) {
         return null;
     }
     if (false !== strstr($className, ':')) {
         $className = $dm->getClassMetadata($className)->getName();
     }
     return $className;
 }
 /**
  * Create a new repository instance for a document class.
  *
  * @param DocumentManagerInterface  $dm             The DocumentManager instance.
  * @param string                    $documentName   The name of the document.
  *
  * @return \Doctrine\Common\Persistence\ObjectRepository
  */
 protected function createRepository(DocumentManagerInterface $dm, $documentName)
 {
     $metadata = $dm->getClassMetadata($documentName);
     $repositoryClassName = $metadata->customRepositoryClassName;
     if ($repositoryClassName === null) {
         $configuration = $dm->getConfiguration();
         $repositoryClassName = $configuration->getDefaultRepositoryClassName();
     }
     return new $repositoryClassName($dm, $metadata);
 }
Example #9
0
 /**
  * @param ResourceControllerEvent $event
  */
 public function onEvent(ResourceControllerEvent $event)
 {
     $document = $event->getSubject();
     $metadata = $this->documentManager->getClassMetadata(get_class($document));
     if (null === ($nameField = $metadata->nodename)) {
         throw new \RuntimeException(sprintf('In order to use the node name filter on "%s" it is necessary to map a field as the "nodename"', get_class($document)));
     }
     $name = $metadata->getFieldValue($document, $nameField);
     $name = preg_replace('/\\/|:|\\[|\\]|\\||\\*/', $this->replacementCharacter, $name);
     $metadata->setFieldValue($document, $nameField, $name);
 }
 public function update(DocumentManagerInterface $documentManager, $document)
 {
     $metadataFactory = $documentManager->getMetadataFactory();
     $classFqn = ClassUtils::getRealClass(get_class($document));
     // PHPCR-ODM will throw an exception if the document is not mapped.
     $odmMetadata = $metadataFactory->getMetadataFor($classFqn);
     if (null === ($ctMetadata = $this->metadataFactory->getMetadataForClass($classFqn))) {
         return;
     }
     $this->doUpdate($metadataFactory, $odmMetadata, $ctMetadata, $document);
 }
 protected function buildName($document, ClassMetadata $class, DocumentManagerInterface $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;
 }
 /**
  * Check each mapped PHPCR-ODM document for the given document manager,
  * throwing an exception if any document is set to use a unique node
  * type but the node type is re-used. Returns an array of debug information.
  *
  * @param DocumentManagerInterface $documentManager The document manager to check mappings for.
  *
  * @return array
  *
  * @throws MappingException
  */
 public function checkNodeTypeMappings(DocumentManagerInterface $documentManager)
 {
     $knownNodeTypes = array();
     $debugInformation = array();
     $allMetadata = $documentManager->getMetadataFactory()->getAllMetadata();
     foreach ($allMetadata as $classMetadata) {
         if ($classMetadata->hasUniqueNodeType() && isset($knownNodeTypes[$classMetadata->getNodeType()])) {
             throw new MappingException(sprintf('The class "%s" is mapped with uniqueNodeType set to true, but the node type "%s" is used by "%s" as well.', $classMetadata->name, $classMetadata->getNodeType(), $knownNodeTypes[$classMetadata->getNodeType()]));
         }
         $knownNodeTypes[$classMetadata->getNodeType()] = $classMetadata->name;
         $debugInformation[$classMetadata->name] = array('unique_node_type' => $classMetadata->hasUniqueNodeType(), 'node_type' => $classMetadata->getNodeType());
     }
     return $debugInformation;
 }
 /**
  * @inheritDoc
  */
 public function saveTranslation(array $data, NodeInterface $node, ClassMetadata $metadata, $locale)
 {
     foreach ($data as $field => $propValue) {
         $mapping = $metadata->mappings[$field];
         $propName = $mapping['property'];
         if ($mapping['multivalue'] && $propValue) {
             $propValue = (array) $propValue;
             if (isset($mapping['assoc'])) {
                 $propValue = $this->dm->getUnitOfWork()->processAssoc($node, $mapping, $propValue);
             }
         }
         $node->setProperty($propName, $propValue);
     }
 }
 /**
  * Use a repository that implements RepositoryIdGenerator 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;
     }
     $repository = $dm->getRepository($class->name);
     if (!$repository instanceof RepositoryIdInterface) {
         throw new IdException("ID could not be determined. Make sure the that the Repository '" . ClassUtils::getClass($repository) . "' implements RepositoryIdInterface");
     }
     $id = $repository->generateId($document, $parent);
     if (!$id) {
         throw new IdException("ID could not be determined. Repository was unable to generate an ID");
     }
     return $id;
 }
Example #15
0
 /**
  * Executes the query and returns the result based on the hydration mode.
  *
  * @param array $parameters    Parameters, alternative to calling setParameters.
  * @param int   $hydrationMode Processing mode to be used during the hydration
  *                             process. One of the Query::HYDRATE_* constants.
  *
  * @return mixed A Collection for HYDRATE_DOCUMENT, \PHPCR\Query\QueryResultInterface for HYDRATE_PHPCR
  *
  * @throws QueryException If $hydrationMode is not known.
  */
 public function execute($parameters = null, $hydrationMode = null)
 {
     if (!empty($parameters)) {
         $this->setParameters($parameters);
     }
     if (null !== $hydrationMode) {
         $this->setHydrationMode($hydrationMode);
     }
     if (null !== $this->maxResults) {
         $this->query->setLimit($this->maxResults);
     }
     if (null !== $this->firstResult) {
         $this->query->setOffset($this->firstResult);
     }
     foreach ($this->parameters as $key => $value) {
         $this->query->bindValue($key, $value);
     }
     switch ($this->hydrationMode) {
         case self::HYDRATE_PHPCR:
             $data = $this->query->execute();
             break;
         case self::HYDRATE_DOCUMENT:
             $data = $this->dm->getDocumentsByPhpcrQuery($this->query, $this->documentClass, $this->primaryAlias);
             break;
         default:
             throw QueryException::hydrationModeNotKnown($this->hydrationMode);
     }
     if (is_array($data)) {
         $data = new ArrayCollection($data);
     }
     return $data;
 }
Example #16
0
 /**
  * {@inheritDoc}
  */
 protected function walkSourceDocument(SourceDocument $node)
 {
     $alias = $node->getAlias();
     $documentFqn = $node->getDocumentFqn();
     // cache the metadata for this document
     /** @var $meta ClassMetadata */
     $meta = $this->mdf->getMetadataFor($documentFqn);
     if (null === $meta->getName()) {
         throw new \RuntimeException(sprintf('%s is not a mapped document', $documentFqn));
     }
     $this->aliasMetadata[$alias] = $meta;
     if ($this->locale && $meta->translator) {
         $this->translator[$alias] = $this->dm->getTranslationStrategy($meta->translator);
     }
     $nodeType = $meta->getNodeType();
     // make sure we add the phpcr:{class,classparents} constraints
     // unless the document has a unique type; From is dispatched first,
     // so these will always be the primary constraints.
     if (!$meta->hasUniqueNodeType()) {
         $this->sourceDocumentNodes[$alias] = $node;
     }
     // get the PHPCR Alias
     $alias = $this->qomf->selector($alias, $nodeType);
     return $alias;
 }
 /**
  * Just make one field of a document untranslated again
  */
 public function testPartialUntranslateChild()
 {
     $article = new ChildTranslationArticle();
     $article->id = '/functional/convert';
     $article->topic = 'Some interesting subject';
     $article->setText('Lorem ipsum...');
     $this->dm->persist($article);
     $this->dm->flush();
     $this->dm->clear();
     $class = 'Doctrine\\Tests\\Models\\Translation\\ChildTranslationArticle';
     $field = 'author';
     $node = $this->node->getNode('convert');
     $node->getNode('phpcr_locale:en')->setProperty($field, 'Move to untranslated');
     $this->session->save();
     $this->assertFalse($this->converter->convert($class, array('en'), array($field)));
     $this->session->save();
     $this->dm->clear();
     $this->dm = $this->createDocumentManager();
     $this->dm->setLocaleChooserStrategy(new LocaleChooser($this->localePrefs, 'en'));
     $this->assertTrue($node->hasProperty($field), 'new property was not created');
     $this->assertTrue($node->hasNode('phpcr_locale:en'), 'lost translation');
     $this->assertFalse($node->getNode('phpcr_locale:en')->hasProperty($field), 'old property was not removed');
     $article = $this->dm->find(null, '/functional/convert');
     $this->assertInstanceof($class, $article);
     $this->assertEquals('Move to untranslated', $article->author);
     $this->assertEquals('Lorem ipsum...', $article->getText());
     $this->dm->clear();
     $article = $this->dm->find(null, '/functional/convert');
     $this->assertInstanceof($class, $article);
     $this->assertEquals('Move to untranslated', $article->author);
     $this->assertEquals('Lorem ipsum...', $article->getText());
 }
 /**
  * @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);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function build(MetadataInterface $metadata, FormBuilderInterface $formBuilder, array $options)
 {
     $classMetadata = $this->documentManager->getClassMetadata($metadata->getClass('model'));
     // the field mappings should only contain standard value mappings
     foreach ($classMetadata->fieldMappings as $fieldName) {
         if ($fieldName === $classMetadata->uuidFieldName) {
             continue;
         }
         if ($fieldName === $classMetadata->nodename) {
             continue;
         }
         $options = [];
         $mapping = $classMetadata->mappings[$fieldName];
         if ($mapping['nullable'] === false) {
             $options['required'] = true;
         }
         $formBuilder->add($fieldName, null, $options);
     }
 }
Example #20
0
 private function resolveParent($document, ClassMetadata $metadata)
 {
     if (!($parentField = $metadata->parentMapping)) {
         throw new \RuntimeException(sprintf('A default parent path has been specified, but no parent mapping has been applied to document "%s"', get_class($document)));
     }
     if (false === $this->force) {
         $actualParent = $metadata->getFieldValue($document, $parentField);
         if ($actualParent) {
             return;
         }
     }
     $parentDocument = $this->documentManager->find(null, $this->parentPath);
     if (true === $this->autocreate && null === $parentDocument) {
         NodeHelper::createPath($this->documentManager->getPhpcrSession(), $this->parentPath);
         $parentDocument = $this->documentManager->find(null, $this->parentPath);
     }
     if (null === $parentDocument) {
         throw new \RuntimeException(sprintf('Document at default parent path "%s" does not exist. `autocreate` was set to "%s"', $this->parentPath, $this->autocreate ? 'true' : 'false'));
     }
     $metadata->setFieldValue($document, $parentField, $parentDocument);
 }
Example #21
0
 /**
  * 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);
 }
Example #22
0
 private function getVersionedNodePath($document)
 {
     $path = $this->getDocumentId($document);
     $metadata = $this->dm->getClassMetadata(get_class($document));
     if (!$metadata->versionable) {
         throw new InvalidArgumentException(sprintf("The document at path '%s' is not versionable", $path));
     }
     $node = $this->session->getNode($path);
     $mixin = $metadata->versionable === 'simple' ? 'mix:simpleVersionable' : 'mix:versionable';
     if (!$node->isNodeType($mixin)) {
         $node->addMixin($mixin);
     }
     return $path;
 }
Example #23
0
 /**
  * @param NodeInterface[] $nodes
  */
 public function prefetch(DocumentManagerInterface $dm, $nodes, $locale = null)
 {
     if (!count($nodes)) {
         return;
     }
     $uuids = array();
     $paths = array();
     $documentClassMapper = $dm->getConfiguration()->getDocumentClassMapper();
     foreach ($nodes as $node) {
         $className = $documentClassMapper->getClassName($dm, $node);
         $class = $dm->getClassMetadata($className);
         if (!$locale && $class->translator) {
             $locale = $dm->getLocaleChooserStrategy()->getLocale();
         }
         $uuids = array_merge($uuids, $this->collectPrefetchReferences($class, $node));
         $paths = array_merge($paths, $this->collectPrefetchHierarchy($class, $node, $locale));
     }
     if (count($uuids)) {
         $node->getSession()->getNodesByIdentifier($uuids);
     }
     if (count($paths)) {
         $node->getSession()->getNodes($paths);
     }
 }
 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);
 }
 function it_should_return_early_if_force_is_false_and_subject_already_has_a_parent(ResourceControllerEvent $event, ClassMetadata $documentMetadata, DocumentManagerInterface $documentManager)
 {
     $subjectDocument = new \stdClass();
     $event->getSubject()->willReturn($subjectDocument);
     $documentManager->getClassMetadata(\stdClass::class)->willReturn($documentMetadata);
     $documentMetadata->parentMapping = 'parent';
     $documentMetadata->getFieldValue($subjectDocument, 'parent')->willReturn(new \stdClass());
     $documentManager->find(null, '/path/to')->shouldNotBeCalled();
     $this->onPreCreate($event);
 }
 /**
  * {@inheritDoc}
  */
 public function transactional($callback)
 {
     return $this->wrapped->transactional($callback);
 }
 /**
  * Initializes a new ListenersInvoker instance.
  *
  * @param DocumentManagerInterface $dm
  */
 public function __construct(DocumentManagerInterface $dm)
 {
     $this->eventManager = $dm->getEventManager();
     $this->dm = $dm;
 }
Example #28
0
 /**
  * If the parent node has child restrictions, ensure that the given
  * class name is within them.
  *
  * @param NodeInterface $parentNode
  * @param string $classFqn
  */
 private function validateChildClass(NodeInterface $parentNode, ClassMetadata $class)
 {
     $parentClass = $this->documentClassMapper->getClassName($this->dm, $parentNode);
     if (null === $parentClass) {
         return;
     }
     $metadata = $this->dm->getClassMetadata($parentClass);
     $metadata->assertValidChildClass($class);
 }
 /**
  * {@inheritDoc}
  */
 public function getNodeForDocument($document)
 {
     return $this->wrapped->getNodeForDocument($document);
 }
Example #30
0
 function it_creates_data_source_via_doctrine_phpcrodm_query_builder(DocumentManagerInterface $documentManager, DocumentRepository $documentRepository, QueryBuilder $queryBuilder, Parameters $parameters)
 {
     $documentManager->getRepository('App:Book')->willReturn($documentRepository);
     $documentRepository->createQueryBuilder('o')->willReturn($queryBuilder);
     $this->getDataSource(['class' => 'App:Book'], $parameters)->shouldHaveType(DataSource::class);
 }