diff --git a/doctrine-phpcr-odm-mapping.xsd b/doctrine-phpcr-odm-mapping.xsd index dd8e960f4..679fdbb31 100644 --- a/doctrine-phpcr-odm-mapping.xsd +++ b/doctrine-phpcr-odm-mapping.xsd @@ -146,6 +146,7 @@ + @@ -173,6 +174,11 @@ + + + + + diff --git a/lib/Doctrine/ODM/PHPCR/.UnitOfWork.php.swl b/lib/Doctrine/ODM/PHPCR/.UnitOfWork.php.swl new file mode 100644 index 000000000..07c797ded Binary files /dev/null and b/lib/Doctrine/ODM/PHPCR/.UnitOfWork.php.swl differ diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Depth.php b/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Depth.php new file mode 100644 index 000000000..1d2907276 --- /dev/null +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Depth.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ODM\PHPCR\Mapping\Annotations; + +use Doctrine\Common\Annotations\Annotation; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class Depth +{ +} diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php index d9e741a15..2a356a076 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php @@ -256,6 +256,13 @@ class ClassMetadata implements ClassMetadataInterface */ public $localeMapping; + /** + * READ-ONLY: Name of the depth property + * + * @var string + */ + public $depthMapping; + /** * READ-ONLY: Name of the version name property of this document * @@ -766,6 +773,13 @@ public function mapLocale(array $mapping, ClassMetadata $inherited = null) $this->localeMapping = $mapping['fieldName']; } + public function mapDepth(array $mapping, ClassMetadata $inherited = null) + { + $mapping['type'] = 'depth'; + $mapping = $this->validateAndCompleteFieldMapping($mapping, $inherited, false, false); + $this->depthMapping = $mapping['fieldName']; + } + public function mapVersionName(array $mapping, ClassMetadata $inherited = null) { $mapping['type'] = 'versionname'; @@ -1117,6 +1131,7 @@ public function hasField($fieldName) || isset($this->inheritedFields[$fieldName]) || $this->identifier === $fieldName || $this->localeMapping === $fieldName + || $this->depthMapping === $fieldName || $this->node === $fieldName || $this->nodename === $fieldName || $this->versionNameField === $fieldName @@ -1198,6 +1213,9 @@ public function getFieldNames() if ($this->localeMapping) { $fields[] = $this->localeMapping; } + if ($this->depthMapping) { + $fields[] = $this->depthMapping; + } if ($this->node) { $fields[] = $this->node; } @@ -1450,6 +1468,10 @@ public function __sleep() $serialized[] = 'localeMapping'; } + if ($this->depthMapping) { + $serialized[] = 'depthMapping'; + } + if ($this->translator) { $serialized[] = 'translator'; } diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php index 355566562..1ce45b056 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php @@ -156,6 +156,9 @@ public function loadMetadataForClass($className, ClassMetadata $metadata) } elseif ($fieldAnnot instanceof ODM\Locale) { $mapping = array_merge($mapping, (array) $fieldAnnot); $metadata->mapLocale($mapping); + } elseif ($fieldAnnot instanceof ODM\Depth) { + $mapping = array_merge($mapping, (array) $fieldAnnot); + $metadata->mapDepth($mapping); } elseif ($fieldAnnot instanceof ODM\VersionName) { $mapping = array_merge($mapping, (array) $fieldAnnot); $metadata->mapVersionName($mapping); diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php index b12dd51e9..a0b15ae04 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php @@ -190,6 +190,10 @@ public function loadMetadataForClass($className, ClassMetadata $class) $class->mapLocale(array('fieldName' => (string) $xmlRoot->locale->attributes()->name)); } + if (isset($xmlRoot->depth)) { + $class->mapDepth(array('fieldName' => (string) $xmlRoot->depth->attributes()->name)); + } + if (isset($xmlRoot->{'mixed-referrers'})) { foreach ($xmlRoot->{'mixed-referrers'} as $mixedReferrers) { $attributes = $mixedReferrers->attributes(); diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php index 613d4fe68..671432984 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php @@ -201,6 +201,9 @@ public function loadMetadataForClass($className, ClassMetadata $class) $class->mapLocale(array('fieldName' => $element['locale'])); } + if (isset($element['depth'])) { + $class->mapDepth(array('fieldName' => $element['depth'])); + } if (isset($element['mixedReferrers'])) { foreach ($element['mixedReferrers'] as $name => $attributes) { diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index ab9a8fde2..388537531 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -543,6 +543,10 @@ public function getOrCreateDocuments($className, $nodes, array &$hints = array() $documentState[$class->parentMapping] = $this->getOrCreateProxyFromNode($node->getParent(), $locale); } + if ($class->depthMapping) { + $documentState[$class->depthMapping] = $node->getDepth(); + } + foreach ($class->childMappings as $fieldName) { $mapping = $class->mappings[$fieldName]; $documentState[$fieldName] = $node->hasNode($mapping['nodeName']) @@ -2703,7 +2707,7 @@ private function executeMoves($documents) $this->session->move($sourcePath, $targetPath); - // update fields nodename and parentMapping if they exist in this type + // update fields nodename, parentMapping and depth if they exist in this type $node = $this->session->getNode($targetPath); // get node from session, document class might not map it if ($class->nodename) { $class->setFieldValue($document, $class->nodename, $node->getName()); @@ -2713,6 +2717,10 @@ private function executeMoves($documents) $class->setFieldValue($document, $class->parentMapping, $this->getOrCreateProxyFromNode($node->getParent(), $this->getCurrentLocale($document, $class))); } + if ($class->depthMapping) { + $class->setFieldValue($document, $class->depthMapping, $node->getDepth()); + } + // update all cached children of the document to reflect the move (path id changes) foreach ($this->documentIds as $childOid => $id) { if (0 !== strpos($id, $sourcePath)) { diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/BasicCrudTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/BasicCrudTest.php index f9d7a5e86..047d7f527 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/BasicCrudTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/BasicCrudTest.php @@ -9,6 +9,7 @@ use PHPCR\Util\UUIDHelper; use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM; +use PHPCR\Util\NodeHelper; /** * @group functional @@ -584,6 +585,23 @@ public function testVersionedDocument() $this->assertEquals($user->numbers, $userNew->numbers); } + public function testDepth() + { + $object = new DepthMappingObject(); + $object->id = '/functional/test'; + $this->dm->persist($object); + $this->dm->flush(); + $this->dm->clear(); + + $object = $this->dm->find(null, '/functional/test'); + $this->assertEquals(2, $object->depth); + + NodeHelper::createPath($this->dm->getPhpcrSession(), '/functional/newtest/foobar'); + $this->dm->move($object, '/functional/newtest/foobar/test'); + $this->dm->flush(); + $this->assertEquals(4, $object->depth); + } + /** * Create a node with a bad name and explicitly persist it without * adding it to any parent's children collection. @@ -762,3 +780,15 @@ class UserWithUuid extends User /** @PHPCRODM\Uuid */ public $uuid; } + +/** + * @PHPCRODM\Document + */ +class DepthMappingObject +{ + /** @PHPCRODM\Id */ + public $id; + + /** @PHPCRODM\Depth */ + public $depth; +} diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Mapping/AnnotationMappingTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Mapping/AnnotationMappingTest.php index d2128983d..61abe6b7a 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Mapping/AnnotationMappingTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Mapping/AnnotationMappingTest.php @@ -211,6 +211,8 @@ class Testclass public $node; /** @PHPCRODM\String */ public $text; + /** @PHPCRODM\Depth */ + public $depth; public $callback_run = 0; /** diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php index 1f5215394..6539b4ca9 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php @@ -319,6 +319,22 @@ public function testParentDocumentMapping($class) $this->assertEquals('parent', $class->parentMapping); } + public function testLoadDepthMapping() + { + $className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\DepthMappingObject'; + return $this->loadMetadataForClassname($className); + } + + /** + * @depends testLoadDepthMapping + * @param ClassMetadata $class + */ + public function testDepthMapping($class) + { + $this->assertTrue(isset($class->depthMapping)); + $this->assertEquals('depth', $class->depthMapping); + } + public function testParentWithPrivatePropertyMapping() { $className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\ParentWithPrivatePropertyObject'; diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/DepthMappingObject.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/DepthMappingObject.php new file mode 100644 index 000000000..ef8507ce3 --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/DepthMappingObject.php @@ -0,0 +1,19 @@ + + + + + + + diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.DepthMappingObject.dcm.yml b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.DepthMappingObject.dcm.yml new file mode 100644 index 000000000..ab13f137f --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.DepthMappingObject.dcm.yml @@ -0,0 +1,3 @@ +Doctrine\Tests\ODM\PHPCR\Mapping\Model\DepthMappingObject: + id: id + depth: depth