/** * 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]); }
/** * @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); }
/** * @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; }
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; }
/** * @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; }
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); }
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); } } }
/** * 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); }
/** * 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); }
/** * 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()); }
/** * 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); }
/** * @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; }
/** * @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); } } } }
/** * @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')); }
/** * 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; }
/** * 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); } } }
/** * 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); } }