Since: 1.0
Author: Benjamin Eberlei (kontakt@beberlei.de)
Author: Lukas Kahwe Smith (smith@pooteeweet.org)
Author: Jonathan H. Wage (jonwage@gmail.com)
Author: Roman Borschel (roman@code-factory.org)
Author: David Buchmann (david@liip.ch)
Author: Daniel Barsotti (daniel.barsotti@liip.ch)
Inheritance: implements Doctrine\Common\Persistence\Mapping\ClassMetadata
Example #1
0
 /**
  * Assertion shortcut:
  * Check the given $metadata contain a field mapping for $field that contains the $key and having the value $expectedValue.
  * @param $expectedValue The expected value
  * @param \Doctrine\ODM\PHPCR\Mapping\ClassMetadata $metadata The class metadata to test
  * @param $field The name of the field's mapping to test
  * @param $key The key expected to be in the field mapping
  */
 protected function assertFieldMetadataEquals($expectedValue, ClassMetadata $metadata, $field, $key)
 {
     $mapping = $metadata->getFieldMapping($field);
     $this->assertInternalType('array', $mapping);
     $this->assertTrue(array_key_exists($key, $mapping));
     $this->assertEquals($expectedValue, $mapping[$key]);
 }
Example #2
0
 /**
  * @param object $document
  * @param ClassMetadata $cm
  * @param DocumentManager $dm
  * @return string
  */
 public function generate($document, ClassMetadata $cm, DocumentManager $dm)
 {
     $id = $cm->getFieldValue($document, $cm->identifier);
     if (!$id) {
         throw new \RuntimeException('ID could not be determined. Make sure the document has a property with Doctrine\\ODM\\PHPCR\\Mapping\\Annotations\\Id annotation and that the property is set to the path where the document is to be stored.');
     }
     return $id;
 }
 /**
  * Use the identifier field as id and throw exception if not set.
  *
  * {@inheritDoc}
  */
 public function generate($document, ClassMetadata $cm, DocumentManagerInterface $dm, $parent = null)
 {
     $id = $cm->getFieldValue($document, $cm->identifier);
     if (!$id) {
         throw new IdException('ID could not be read from the document instance using the AssignedIdGenerator.');
     }
     return $id;
 }
 public function testLoadMetadataForNonDocumentThrowsException()
 {
     $cm = new ClassMetadata('stdClass');
     $cm->initializeReflection(new RuntimeReflectionService());
     $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache());
     $annotationDriver = new \Doctrine\ODM\PHPCR\Mapping\Driver\AnnotationDriver($reader);
     $this->setExpectedException('Doctrine\\ODM\\PHPCR\\Mapping\\MappingException');
     $annotationDriver->loadMetadataForClass('stdClass', $cm);
 }
Example #5
0
 /**
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\XmlDriver::loadMetadataForClass
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\YamlDriver::loadMetadataForClass
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\AnnotationDriver::loadMetadataForClass
  */
 public function testLoadMapping()
 {
     $className = 'Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\PropertyMappingObj';
     $mappingDriver = $this->loadDriver();
     $class = new ClassMetadata($className);
     $class->initializeReflection(new RuntimeReflectionService());
     $mappingDriver->loadMetadataForClass($className, $class);
     return $class;
 }
 /**
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\XmlDriver::loadMetadataForClass
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\YamlDriver::loadMetadataForClass
  * @covers Doctrine\ODM\PHPCR\Mapping\Driver\AnnotationDriver::loadMetadataForClass
  */
 public function testLoadMapping()
 {
     $className = 'Doctrine\\Tests\\Models\\CMS\\CmsUser';
     $mappingDriver = $this->loadDriver();
     $class = new ClassMetadata($className);
     $class->initializeReflection(new RuntimeReflectionService());
     $mappingDriver->loadMetadataForClass($className, $class);
     return $class;
 }
 private function getFieldName(ClassMetadata $metadata)
 {
     foreach ($metadata->getFieldNames() as $fieldName) {
         $field = $metadata->getFieldMapping($fieldName);
         if ('jcr:lastModified' == $field['property']) {
             return $fieldName;
         }
     }
     return;
 }
Example #8
0
 private function unrestrictChildClass(string $class, ClassMetadata $metadata)
 {
     if (!$class) {
         return;
     }
     if (!($childClasses = $metadata->getChildClasses())) {
         return;
     }
     $childClasses[] = $class;
     $metadata->setChildClasses($childClasses);
 }
 /**
  * Create the guesser for this test.
  *
  * @return GuesserInterface
  */
 protected function createGuesser()
 {
     $this->registry = $this->getMockBuilder('\\Doctrine\\Bundle\\PHPCRBundle\\ManagerRegistry')->disableOriginalConstructor()->getMock();
     $this->manager = $this->getMockBuilder('\\Doctrine\\ODM\\PHPCR\\DocumentManager')->disableOriginalConstructor()->getMock();
     $this->metadata = $this->getMockBuilder('\\Doctrine\\ODM\\PHPCR\\Mapping\\ClassMetadata')->disableOriginalConstructor()->getMock();
     $this->registry->expects($this->any())->method('getManagerForClass')->with($this->equalTo('Symfony\\Cmf\\Bundle\\SeoBundle\\Tests\\Unit\\Sitemap\\LastModifiedGuesserTest'))->will($this->returnValue($this->manager));
     $this->manager->expects($this->any())->method('getClassMetadata')->with($this->equalTo('Symfony\\Cmf\\Bundle\\SeoBundle\\Tests\\Unit\\Sitemap\\LastModifiedGuesserTest'))->will($this->returnValue($this->metadata));
     $this->metadata->expects($this->any())->method('getMixins')->will($this->returnValue(array('mix:lastModified')));
     $this->metadata->expects($this->any())->method('getFieldNames')->will($this->returnValue(array('lastModified')));
     $this->metadata->expects($this->any())->method('getFieldMapping')->with($this->equalTo('lastModified'))->will($this->returnValue(array('property' => 'jcr:lastModified')));
     $this->metadata->expects($this->any())->method('getFieldValue')->with($this->equalTo($this), $this->equalTo('lastModified'))->will($this->returnValue(new \DateTime('2016-07-06', new \DateTimeZone('Europe/Berlin'))));
     return new LastModifiedGuesser($this->registry);
 }
 /**
  * Verify that no exception results from a correctly-mapped set
  * of documents.
  */
 public function testCheckNodeTypeMappingsWithoutDuplicate()
 {
     $metadataA = new ClassMetadata('Doctrine\\PHPCR\\Models\\ClassA');
     $metadataA->setNodeType('nt:unstructured');
     $metadataB = new ClassMetadata('Doctrine\\PHPCR\\Models\\ClassB');
     $metadataB->setNodeType('custom:type');
     $metadataB->setUniqueNodeType(true);
     $metadataC = new ClassMetadata('Doctrine\\PHPCR\\Models\\ClassC');
     $metadataA->setNodeType('nt:unstructured');
     $documentManager = $this->configureDocumentManager(array($metadataA, $metadataB, $metadataC));
     $uniqueNodeTypeHelper = new UniqueNodeTypeHelper();
     $uniqueNodeTypeHelper->checkNodeTypeMappings($documentManager);
 }
 /**
  * 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 #12
0
 /**
  * @param object $document
  * @param ClassMetadata $cm
  * @param DocumentManager $dm
  * @return string
  */
 public function generate($document, ClassMetadata $cm, DocumentManager $dm)
 {
     $parent = $cm->getFieldValue($document, $cm->parentMapping);
     $name = $cm->getFieldValue($document, $cm->nodename);
     $id = $cm->getFieldValue($document, $cm->identifier);
     if ((empty($parent) || empty($name)) && empty($id)) {
         throw new \RuntimeException('ID could not be determined. Make sure the document has a property with Doctrine\\ODM\\PHPCR\\Mapping\\Annotations\\ParentDocument and Doctrine\\ODM\\PHPCR\\Mapping\\Annotations\\Nodename annotation and that the property is set to the path where the document is to be stored.');
     }
     // use assigned ID by default
     if (!$parent || empty($name)) {
         return $id;
     }
     // determine ID based on the path and the node name
     $id = $dm->getUnitOfWork()->getDocumentId($parent);
     if (!$id) {
         throw new \RuntimeException('Parent ID could not be determined. Make sure to persist the parent document before persisting this document.');
     }
     return $id . '/' . $name;
 }
Example #13
0
 public function setUp()
 {
     if (!class_exists('Jackalope\\Factory', true)) {
         $this->markTestSkipped('The Node needs to be properly mocked/stubbed. Remove dependency to Jackalope');
     }
     $this->factory = new Factory();
     $this->session = $this->getMock('Jackalope\\Session', array(), array($this->factory), '', false);
     $this->objectManager = $this->getMock('Jackalope\\ObjectManager', array(), array($this->factory), '', false);
     $this->type = 'Doctrine\\Tests\\ODM\\PHPCR\\UoWUser';
     $this->dm = DocumentManager::create($this->session);
     $this->uow = new UnitOfWork($this->dm);
     $cmf = $this->dm->getMetadataFactory();
     $metadata = new ClassMetadata($this->type);
     $metadata->initializeReflection($cmf->getReflectionService());
     $metadata->mapId(array('fieldName' => 'id', 'id' => true));
     $metadata->idGenerator = ClassMetadata::GENERATOR_TYPE_ASSIGNED;
     $metadata->mapField(array('fieldName' => 'username', 'type' => 'string'));
     $cmf->setMetadataFor($this->type, $metadata);
 }
 /**
  * @dataProvider provideExpandClassName
  */
 public function testExpandClassName($className, $fqClassName, $isAlias)
 {
     if ($isAlias) {
         $this->dm->expects($this->once())->method('getClassMetadata')->with($className)->will($this->returnValue($this->metadata));
         $this->metadata->expects($this->once())->method('getName')->will($this->returnValue($fqClassName));
     }
     $refl = new \ReflectionClass($this->mapper);
     $method = $refl->getMethod('expandClassName');
     $method->setAccessible(true);
     $res = $method->invoke($this->mapper, $this->dm, $className);
     $this->assertEquals($fqClassName, $res);
 }
Example #15
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);
 }
 private function doUpdate(ClassMetadataFactory $metadataFactory, PhpcrMetadata $odmMetadata, CtMetadata $ctMetadata, $document)
 {
     $documentId = $odmMetadata->getIdentifierValue($document);
     foreach ($odmMetadata->childrenMappings as $childrenField) {
         // if the children field is not managed by the CT component,
         // continue
         if (!isset($ctMetadata->propertyMetadata[$childrenField])) {
             continue;
         }
         $children = $odmMetadata->getFieldValue($document, $childrenField);
         // note that we do not preserve array keys. PHPCR ODM will return a
         // children collection using the PHPCR property names as keys, so
         // we currently have no control over how these keys populated.
         $index = 0;
         foreach ($children as $child) {
             $childMetadata = $metadataFactory->getMetadataFor(ClassUtils::getRealClass(get_class($child)));
             $newId = sprintf('%s/%s', $documentId, $this->encoder->encode($childrenField, $index++));
             $childMetadata->setIdentifierValue($child, $newId);
         }
     }
 }
Example #17
0
 /**
  * Use the name and parent fields to generate the id
  *
  * {@inheritDoc}
  */
 public function generate($document, ClassMetadata $class, DocumentManager $dm, $parent = null)
 {
     if (null === $parent) {
         $parent = $class->parentMapping ? $class->getFieldValue($document, $class->parentMapping) : null;
     }
     $name = $class->nodename ? $class->getFieldValue($document, $class->nodename) : null;
     $id = $class->getFieldValue($document, $class->identifier);
     if (empty($id)) {
         if (empty($name) && empty($parent)) {
             throw IdException::noIdentificationParameters($document, $class->parentMapping, $class->nodename);
         }
         if (empty($parent)) {
             throw IdException::noIdNoParent($document, $class->parentMapping);
         }
         if (empty($name)) {
             throw IdException::noIdNoName($document, $class->nodename);
         }
     }
     // use assigned ID by default
     if (empty($parent) || empty($name)) {
         return $id;
     }
     if ($exception = $class->isValidNodename($name)) {
         throw IdException::illegalName($document, $class->nodename, $name);
     }
     // determine ID based on the path and the node name
     return $this->buildName($document, $class, $dm, $parent, $name);
 }
Example #18
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 #19
0
 /**
  * Create a Query
  *
  * @param string $statement             the SQL2 statement
  * @param string $language              (see QueryInterface for list of supported types)
  * @param bool   $replaceWithFieldnames if * should be replaced with field names automatically
  *
  * @return Query
  */
 public function createQuery($statement, $language, $options = 0)
 {
     // TODO: refactor this to use the odm query builder
     $qb = $this->dm->createPhpcrQueryBuilder()->setFromQuery($statement, $language);
     if ($options & self::QUERY_REPLACE_WITH_FIELDNAMES) {
         $columns = $qb->getColumns();
         if (1 === count($columns)) {
             $column = reset($columns);
             if ('*' === $column->getColumnName() && null == $column->getPropertyName()) {
                 $qb->setColumns(array());
                 foreach ($this->class->getFieldNames() as $name) {
                     $qb->addSelect('a', $name);
                 }
             }
         }
     }
     $factory = $qb->getQOMFactory();
     $comparison = $factory->comparison($factory->propertyValue('a', 'phpcr:class'), Constants::JCR_OPERATOR_EQUAL_TO, $factory->literal($this->className));
     $qb->andWhere($comparison);
     return new Query($qb->getQuery(), $this->getDocumentManager());
 }
Example #20
0
 /**
  * It should throw an exception if the given class is not allowed.
  *
  * @expectedException \Doctrine\ODM\PHPCR\Exception\OutOfBoundsException
  * @expectedExceptionMessage does not allow children of type "stdClass"
  */
 public function testAssertValidChildClassesNotAllowed()
 {
     $cm = new ClassMetadata('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Person');
     $cm->initializeReflection(new RuntimeReflectionService());
     $childCm = new ClassMetadata('stdClass');
     $childCm->initializeReflection(new RuntimeReflectionService());
     $cm->setChildClasses(array('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Person'));
     $cm->assertValidChildClass($childCm);
 }
Example #21
0
 /**
  * @param ClassMetadata $cm
  * @depends testClassName
  */
 public function testMapAssociationManyToOne($cm)
 {
     $cm->mapManyToOne(array('fieldName' => 'address', 'targetDocument' => 'Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Address'));
     $this->assertTrue(isset($cm->associationsMappings['address']), "No 'address' in associations map.");
     $this->assertEquals(array('fieldName' => 'address', 'targetDocument' => 'Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Address', 'sourceDocument' => 'Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Person', 'type' => ClassMetadata::MANY_TO_ONE), $cm->associationsMappings['address']);
     return $cm;
 }
Example #22
0
 /**
  * @param ClassMetadata $class
  * @param object $document
  * @return void
  */
 private function computeChangeSet(ClassMetadata $class, $document)
 {
     if ($document instanceof Proxy && !$document->__isInitialized()) {
         return;
     }
     $actualData = array();
     foreach ($class->reflFields as $fieldName => $reflProperty) {
         $value = $reflProperty->getValue($document);
         if ($class->isCollectionValuedAssociation($fieldName) && $value !== null && !$value instanceof PersistentCollection) {
             if (!$value instanceof Collection) {
                 $value = new MultivaluePropertyCollection(new ArrayCollection($value), true);
                 $this->multivaluePropertyCollections[] = $value;
             }
             $collection = $value;
             $class->reflFields[$fieldName]->setValue($document, $collection);
             $actualData[$fieldName] = $collection;
         } else {
             $actualData[$fieldName] = $value;
         }
     }
     // unset the version info fields if they have values, they are not to be managed by the user in write scenarios.
     if ($class->versionable) {
         unset($actualData[$class->versionNameField]);
         unset($actualData[$class->versionCreatedField]);
     }
     $oid = spl_object_hash($document);
     if (!isset($this->originalData[$oid])) {
         // Document is New and should be inserted
         $this->originalData[$oid] = $actualData;
         $this->documentChangesets[$oid] = $actualData;
         $this->scheduledInserts[$oid] = $document;
     } else {
         if (isset($this->originalData[$oid][$class->nodename]) && isset($actualData[$class->nodename]) && $this->originalData[$oid][$class->nodename] !== $actualData[$class->nodename]) {
             throw new PHPCRException('The Nodename property is immutable (' . $this->originalData[$oid][$class->nodename] . ' !== ' . $actualData[$class->nodename] . '). Please use DocumentManager::move to rename the document: ' . self::objToStr($document, $this->dm));
         }
         if (isset($this->originalData[$oid][$class->parentMapping]) && isset($actualData[$class->parentMapping]) && $this->originalData[$oid][$class->parentMapping] !== $actualData[$class->parentMapping]) {
             throw new PHPCRException('The ParentDocument property is immutable (' . $class->getIdentifierValue($this->originalData[$oid][$class->parentMapping]) . ' !== ' . $class->getIdentifierValue($actualData[$class->parentMapping]) . '). Please use PHPCR\\Session::move to move the document: ' . self::objToStr($document, $this->dm));
         }
         if (isset($this->originalData[$oid][$class->identifier]) && isset($actualData[$class->identifier]) && $this->originalData[$oid][$class->identifier] !== $actualData[$class->identifier]) {
             throw new PHPCRException('The Id is immutable (' . $this->originalData[$oid][$class->identifier] . ' !== ' . $actualData[$class->identifier] . '). Please use DocumentManager::move to move the document: ' . self::objToStr($document, $this->dm));
         }
         // Document is "fully" MANAGED: it was already fully persisted before
         // and we have a copy of the original data
         $changed = false;
         foreach ($actualData as $fieldName => $fieldValue) {
             if (!isset($class->fieldMappings[$fieldName]) && !isset($class->childMappings[$fieldName]) && !isset($class->associationsMappings[$fieldName]) && !isset($class->referrersMappings[$fieldName]) && !isset($class->parentMapping[$fieldName]) && !isset($class->nodename)) {
                 continue;
             }
             if ($class->isCollectionValuedAssociation($fieldName)) {
                 if (!$fieldValue instanceof PersistentCollection) {
                     // if its not a persistent collection and the original value changed. otherwise it could just be null
                     $changed = true;
                     break;
                 } elseif ($fieldValue->changed()) {
                     $this->visitedCollections[] = $fieldValue;
                     $changed = true;
                     break;
                 }
             } elseif ($this->originalData[$oid][$fieldName] !== $fieldValue) {
                 $changed = true;
                 break;
             } elseif ($fieldValue instanceof ReferenceManyCollection) {
                 if ($fieldValue->changed()) {
                     $changed = true;
                 }
             }
         }
         if (isset($this->documentLocales[$oid]) && $this->documentLocales[$oid]['current'] !== $this->documentLocales[$oid]['original']) {
             $changed = true;
         }
         if ($changed) {
             $this->documentChangesets[$oid] = $actualData;
             $this->scheduledUpdates[$oid] = $document;
         }
     }
     if ($class->parentMapping && isset($actualData[$class->parentMapping])) {
         $parent = $actualData[$class->parentMapping];
         $parentClass = $this->dm->getClassMetadata(get_class($parent));
         $state = $this->getDocumentState($parent);
         if ($state === self::STATE_MANAGED) {
             $this->computeChangeSet($parentClass, $parent);
         }
     }
     $id = $class->getIdentifierValue($document);
     foreach ($class->childMappings as $name => $childMapping) {
         if ($actualData[$name]) {
             if ($this->originalData[$oid][$name] && $this->originalData[$oid][$name] !== $actualData[$name]) {
                 throw new PHPCRException('Cannot move/copy children by assignment as it would be ambiguous. Please use the DocumentManager::move() or PHPCR\\Session::copy() operations for this: ' . self::objToStr($document, $this->dm));
             }
             $this->computeChildChanges($childMapping, $actualData[$name], $id);
         }
     }
     foreach ($class->associationsMappings as $assocName => $assoc) {
         if ($actualData[$assocName]) {
             if (is_array($actualData[$assocName]) || $actualData[$assocName] instanceof Collection) {
                 foreach ($actualData[$assocName] as $ref) {
                     if ($ref !== null) {
                         $this->computeReferenceChanges($ref);
                     }
                 }
             } else {
                 $this->computeReferenceChanges($actualData[$assocName]);
             }
         }
     }
     foreach ($class->referrersMappings as $name => $referrerMapping) {
         if ($this->originalData[$oid][$name]) {
             foreach ($this->originalData[$oid][$name] as $referrer) {
                 $this->computeReferrerChanges($referrer);
             }
         }
     }
 }
Example #23
0
 /**
  * @param array         $mapping
  * @param ClassMetadata $inherited  same field of parent document, if any
  * @param bool          $isField    whether this is a field or an association
  * @param string        $phpcrLabel the name for the phpcr thing. usually property,
  *                                  except for child where this is name. referrers
  *                                  use false to not set anything.
  *
  * @return mixed
  *
  * @throws MappingException
  */
 protected function validateAndCompleteFieldMapping(array $mapping, ClassMetadata $inherited = null, $isField = true, $phpcrLabel = 'property')
 {
     if ($inherited) {
         if (!isset($mapping['inherited'])) {
             $this->inheritedFields[$mapping['fieldName']] = $inherited->name;
         }
         if (!isset($mapping['declared'])) {
             $mapping['declared'] = $inherited->name;
         }
         $this->reflFields[$mapping['fieldName']] = $inherited->getReflectionProperty($mapping['fieldName']);
         $this->mappings[$mapping['fieldName']] = $mapping;
         return $mapping;
     }
     if (empty($mapping['fieldName'])) {
         throw new MappingException("Mapping a property requires to specify the field name in '{$this->name}'.");
     }
     if (!is_string($mapping['fieldName'])) {
         throw new MappingException("Field name must be of type string in '{$this->name}'.");
     }
     if (!$this->reflClass->hasProperty($mapping['fieldName'])) {
         throw MappingException::classHasNoField($this->name, $mapping['fieldName']);
     }
     if (empty($mapping['property'])) {
         $mapping['property'] = $mapping['fieldName'];
     }
     if ($phpcrLabel && (!isset($mapping[$phpcrLabel]) || empty($mapping[$phpcrLabel]))) {
         $mapping[$phpcrLabel] = $mapping['fieldName'];
     }
     if ($isField && isset($mapping['assoc'])) {
         $mapping['multivalue'] = true;
         if (empty($mapping['assoc'])) {
             $mapping['assoc'] = $mapping['property'] . 'Keys';
         }
         $mapping['assocNulls'] = $mapping['property'] . 'Nulls';
     }
     if (isset($this->mappings[$mapping['fieldName']])) {
         if (!$isField || empty($mapping['type']) || empty($this->mappings[$mapping['fieldName']]) || $this->mappings[$mapping['fieldName']]['type'] !== $mapping['type']) {
             throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']);
         }
     }
     if (!isset($mapping['type'])) {
         throw MappingException::missingTypeDefinition($this->name, $mapping['fieldName']);
     }
     if ($mapping['type'] === 'int') {
         $mapping['type'] = 'long';
     } elseif ($mapping['type'] === 'float') {
         $mapping['type'] = 'double';
     }
     $reflProp = $this->reflClass->getProperty($mapping['fieldName']);
     $reflProp->setAccessible(true);
     $this->reflFields[$mapping['fieldName']] = $reflProp;
     $this->mappings[$mapping['fieldName']] = $mapping;
     return $mapping;
 }
 /**
  * @depends testLoadReferenceManyMapping
  * @param ClassMetadata $class
  */
 public function testReferenceManyMapping($class)
 {
     $this->assertEquals(2, count($class->referenceMappings));
     $this->assertTrue(isset($class->mappings['referenceManyWeak']));
     $this->assertCount(2, $class->getAssociationNames());
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\myDocument', $class->getAssociationTargetClass('referenceManyWeak'));
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\myDocument', $class->getAssociationTargetClass('referenceManyHard'));
     $referenceManyWeak = $class->mappings['referenceManyWeak'];
     $this->assertEquals('referenceManyWeak', $referenceManyWeak['fieldName']);
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\myDocument', $referenceManyWeak['targetDocument']);
     $this->assertEquals('weak', $referenceManyWeak['strategy']);
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\ReferenceManyMappingObject', $referenceManyWeak['sourceDocument']);
     $this->assertEquals(ClassMetadata::MANY_TO_MANY, $referenceManyWeak['type']);
     $referenceManyHard = $class->mappings['referenceManyHard'];
     $this->assertEquals('referenceManyHard', $referenceManyHard['fieldName']);
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\myDocument', $referenceManyHard['targetDocument']);
     $this->assertEquals('hard', $referenceManyHard['strategy']);
     $this->assertEquals('Doctrine\\Tests\\ODM\\PHPCR\\Mapping\\Model\\ReferenceManyMappingObject', $referenceManyHard['sourceDocument']);
     $this->assertEquals(ClassMetadata::MANY_TO_MANY, $referenceManyHard['type']);
 }
 public function testClassMetadataInstanceSerialization()
 {
     $cm = new ClassMetadata('Doctrine\\Tests\\Models\\CMS\\CmsUser');
     $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService());
     // Test initial state
     $this->assertTrue(count($cm->getReflectionProperties()) == 0);
     $this->assertInstanceOf('ReflectionClass', $cm->reflClass);
     $this->assertEquals('Doctrine\\Tests\\Models\\CMS\\CmsUser', $cm->name);
     $this->assertEquals(array(), $cm->parentClasses);
     $this->assertEquals(0, count($cm->referenceMappings));
     // Customize state
     $cm->setParentClasses(array("UserParent"));
     $cm->setCustomRepositoryClassName("CmsUserRepository");
     $cm->setNodeType('foo:bar');
     $cm->mapManyToOne(array('fieldName' => 'address', 'targetDocument' => 'CmsAddress', 'mappedBy' => 'foo'));
     $this->assertEquals(1, count($cm->referenceMappings));
     $serialized = serialize($cm);
     /** @var ClassMetadata $cm */
     $cm = unserialize($serialized);
     $cm->wakeupReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService());
     // Check state
     $this->assertTrue(count($cm->getReflectionProperties()) > 0);
     $this->assertEquals('Doctrine\\Tests\\Models\\CMS', $cm->namespace);
     $this->assertInstanceOf('ReflectionClass', $cm->reflClass);
     $this->assertEquals('Doctrine\\Tests\\Models\\CMS\\CmsUser', $cm->name);
     $this->assertEquals(array('UserParent'), $cm->parentClasses);
     $this->assertEquals('Doctrine\\Tests\\Models\\CMS\\CmsUserRepository', $cm->customRepositoryClassName);
     $this->assertEquals('foo:bar', $cm->getNodeType());
     $this->assertEquals(ClassMetadata::MANY_TO_ONE, $cm->getTypeOfField('address'));
     $this->assertEquals(1, count($cm->referenceMappings));
     $this->assertTrue($cm->hasAssociation('address'));
     $this->assertEquals('Doctrine\\Tests\\Models\\CMS\\CmsAddress', $cm->getAssociationTargetClass('address'));
 }
Example #26
0
 /**
  * Identify whether a PHPCR property is autocreated or not.
  *
  * @param ClassMetadata $class
  * @param string        $fieldName
  *
  * @return boolean
  */
 private function isAutocreatedProperty(ClassMetadata $class, $fieldName)
 {
     $field = $class->getField($fieldName);
     if ('jcr:uuid' === $field['property']) {
         // jackrabbit at least does not identify this as auto created
         // it is strictly speaking no property
         return true;
     }
     $ntm = $this->session->getWorkspace()->getNodeTypeManager();
     $nodeType = $ntm->getNodeType($class->getNodeType());
     $propertyDefinitions = $nodeType->getPropertyDefinitions();
     foreach ($class->getMixins() as $mixinTypeName) {
         $nodeType = $ntm->getNodeType($mixinTypeName);
         $propertyDefinitions = array_merge($propertyDefinitions, $nodeType->getPropertyDefinitions());
     }
     foreach ($propertyDefinitions as $property) {
         if ($class->mappings[$fieldName]['property'] === $property->getName() && $property->isAutoCreated()) {
             return true;
         }
     }
     return false;
 }
Example #27
0
 /**
  * Set the mapped mixins.
  *
  * @param ClassMetadata $metadata
  * @param NodeInterface $node
  * @param object        $document The document to update autogenerated fields.
  */
 private function setMixins(Mapping\ClassMetadata $metadata, NodeInterface $node, $document)
 {
     $repository = $this->session->getRepository();
     if ($metadata->versionable === 'full') {
         if ($repository->getDescriptor(RepositoryInterface::OPTION_VERSIONING_SUPPORTED)) {
             $node->addMixin('mix:versionable');
         } elseif ($repository->getDescriptor(RepositoryInterface::OPTION_SIMPLE_VERSIONING_SUPPORTED)) {
             $node->addMixin('mix:simpleVersionable');
         }
     } elseif ($metadata->versionable === 'simple' && $repository->getDescriptor(RepositoryInterface::OPTION_SIMPLE_VERSIONING_SUPPORTED)) {
         $node->addMixin('mix:simpleVersionable');
     }
     if (!$node->isNodeType('mix:referenceable') && $metadata->referenceable) {
         $node->addMixin('mix:referenceable');
     }
     // manually set the uuid if it is not present yet, so we can assign it to documents
     if ($node->isNodeType('mix:referenceable') && !$node->hasProperty('jcr:uuid')) {
         $uuid = false;
         $uuidFieldName = $metadata->getUuidFieldName();
         if ($uuidFieldName) {
             $uuid = $metadata->getFieldValue($document, $uuidFieldName);
         }
         if (!$uuid) {
             $uuid = $this->generateUuid();
         }
         $node->setProperty('jcr:uuid', $uuid);
         if ($uuidFieldName && !$metadata->getFieldValue($document, $uuidFieldName)) {
             $metadata->setFieldValue($document, $uuidFieldName, $uuid);
         }
     }
 }
Example #28
0
 /**
  * Generates a closure capable of finalizing a cloned proxy
  *
  * @param \Doctrine\ODM\PHPCR\Mapping\ClassMetadata $classMetadata
  * @param \ReflectionProperty                       $reflectionId
  *
  * @return \Closure
  *
  * @throws \Doctrine\Common\Proxy\Exception\UnexpectedValueException
  */
 private function createCloner(ClassMetadata $classMetadata, ReflectionProperty $reflectionId)
 {
     $className = $classMetadata->getName();
     $documentManager = $this->documentManager;
     return function (Proxy $cloned) use($className, $classMetadata, $documentManager, $reflectionId) {
         if ($cloned->__isInitialized()) {
             return;
         }
         $cloned->__setInitialized(true);
         $cloned->__setInitializer(null);
         $original = $documentManager->find($className, $reflectionId->getValue($cloned));
         if (null === $original) {
             throw new UnexpectedValueException(sprintf('Proxy with ID "%s" could not be loaded', $reflectionId->getValue($cloned)));
         }
         foreach ($classMetadata->getReflectionClass()->getProperties() as $reflectionProperty) {
             $propertyName = $reflectionProperty->getName();
             if ($classMetadata->hasField($propertyName) || $classMetadata->hasAssociation($propertyName)) {
                 $reflectionProperty->setAccessible(true);
                 $reflectionProperty->setValue($cloned, $reflectionProperty->getValue($original));
             }
         }
     };
 }
 /**
  * Validate runtime metadata is correctly defined.
  *
  * @param ClassMetadata $class
  * @param $parent
  * @throws MappingException
  */
 protected function validateRuntimeMetadata($class, $parent)
 {
     if (!$class->reflClass) {
         // only validate if there is a reflection class instance
         return;
     }
     $class->validateIdentifier();
     $class->validateReferences();
     $class->validateLifecycleCallbacks($this->getReflectionService());
     $class->validateTranslatables();
     // verify inheritance
     // TODO
 }
 /**
  * @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);
     }
 }