diff --git a/CHANGELOG.md b/CHANGELOG.md index a50bd2ba3..e8f94fa2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Changelog ========= +dev-master +---------- + +* **2016-06-08** [Feature] Allow children of a document to be restricted to a + certain class or forbidden. + 1.3.1 ----- diff --git a/composer.json b/composer.json index cc1a88a46..cc0febc01 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "bin": ["bin/phpcrodm", "bin/phpcrodm.php"], "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/doctrine-phpcr-odm-mapping.xsd b/doctrine-phpcr-odm-mapping.xsd index cd09ee34a..adaff795a 100644 --- a/doctrine-phpcr-odm-mapping.xsd +++ b/doctrine-phpcr-odm-mapping.xsd @@ -44,6 +44,10 @@ + + + + @@ -138,6 +142,7 @@ --> + @@ -159,6 +164,7 @@ + diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Document.php b/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Document.php index 2540184cd..be201e070 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Document.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Document.php @@ -66,4 +66,14 @@ class Document * @var boolean */ public $uniqueNodeType; + + /** + * @var array + */ + public $childClasses = array(); + + /** + * @var boolean + */ + public $isLeaf; } diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php index 7e34bb29f..631061631 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php @@ -31,6 +31,7 @@ use Doctrine\Common\ClassLoader; use Doctrine\Instantiator\Instantiator; use Doctrine\Instantiator\InstantiatorInterface; +use Doctrine\ODM\PHPCR\Exception\OutOfBoundsException; /** * Metadata class @@ -328,6 +329,23 @@ class ClassMetadata implements ClassMetadataInterface */ public $parentClasses = array(); + /** + * READ-ONLY: Child class restrictions. + * + * If empty then any classes are permitted. + * + * @var array + */ + public $childClasses = array(); + + /** + * READ-ONLY: If the document should be act as a leaf-node and therefore + * not be allowed children. + * + * @var boolean + */ + public $isLeaf = false; + /** * The inherited fields of this class * @@ -453,6 +471,57 @@ public function validateIdentifier() } } + /** + * Validate that childClasses is empty if isLeaf is true. + * + * @throws MappingException if there is a conflict between isLeaf and childClasses. + */ + public function validateChildClasses() + { + if (count($this->childClasses) > 0 && $this->isLeaf) { + throw new MappingException(sprintf( + 'Cannot map a document as a leaf and define child classes for "%s"', + $this->name + )); + } + } + + /** + * Assert that the given class FQN can be a child of the document this + * metadata represents. + * + * @param string $classFqn + * @throws OutOfBoundsException + */ + public function assertValidChildClass(ClassMetadata $class) + { + if ($this->isLeaf()) { + throw new OutOfBoundsException(sprintf( + 'Document "%s" has been mapped as a leaf. It cannot have children', + $this->name + )); + } + + $childClasses = $this->getChildClasses(); + + if (0 === count($childClasses)) { + return; + } + + foreach ($childClasses as $childClass) { + if ($class->name === $childClass || $class->reflClass->isSubclassOf($childClass)) { + return; + } + } + + throw new OutOfBoundsException(sprintf( + 'Document "%s" does not allow children of type "%s". Allowed child classes "%s"', + $this->name, + $class->name, + implode('", "', $childClasses) + )); + } + /** * Validate whether this class needs to be referenceable. * @@ -1123,6 +1192,49 @@ public function getParentClasses() return $this->parentClasses; } + /** + * Return the class names or interfaces that children of this document must + * be an instance of. + * + * @return string[] + */ + public function getChildClasses() + { + return $this->childClasses; + } + + /** + * Set the class names or interfaces that children of this document must be + * instance of. + * + * @param string[] $childClasses + */ + public function setChildClasses(array $childClasses) + { + $this->childClasses = $childClasses; + } + + /** + * Return true if this is designated as a leaf node. + * + * @return bool + */ + public function isLeaf() + { + return $this->isLeaf; + } + + /** + * Set if this document should act as a leaf node. + * + * @param bool $isLeaf + */ + public function setIsLeaf($isLeaf) + { + $this->isLeaf = $isLeaf; + } + + /** * Checks whether the class will generate an id via the repository. * diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataFactory.php index 5928341dd..1fd1c62ae 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataFactory.php @@ -256,6 +256,7 @@ protected function validateRuntimeMetadata($class, $parent) $class->validateIdentifier(); $class->validateReferenceable(); $class->validateReferences(); + $class->validateChildClasses(); $class->validateLifecycleCallbacks($this->getReflectionService()); $class->validateTranslatables(); diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php index 14635cb39..67264a94b 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php @@ -111,6 +111,12 @@ public function loadMetadataForClass($className, ClassMetadata $metadata) $metadata->setTranslator($documentAnnot->translator); } + if (array() !== $documentAnnot->childClasses) { + $metadata->setChildClasses($documentAnnot->childClasses); + } + + $metadata->setIsLeaf($documentAnnot->isLeaf); + foreach ($reflClass->getProperties() as $property) { if ($metadata->isInheritedField($property->name) && $metadata->name !== $property->getDeclaringClass()->getName() diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php index 2e7d98950..687ffdce5 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php @@ -83,6 +83,18 @@ public function loadMetadataForClass($className, ClassMetadata $class) $class->setUniqueNodeType((bool) $xmlRoot['uniqueNodeType']); } + if (isset($xmlRoot['is-leaf'])) { + if (!in_array($value = $xmlRoot['is-leaf'], array('true', 'false'))) { + throw new MappingException(sprintf( + 'Value of is-leaf must be "true" or "false", got "%s" for class "%s"', + $value, $className + )); + } + + $class->setIsLeaf($value == 'true' ? true : false); + } + + if (isset($xmlRoot->mixins)) { $mixins = array(); foreach ($xmlRoot->mixins->mixin as $mixin) { @@ -259,6 +271,14 @@ public function loadMetadataForClass($className, ClassMetadata $class) $class->mapField($mapping); } + if (isset($xmlRoot->{'child-class'})) { + $childClasses = array(); + foreach ($xmlRoot->{'child-class'} as $requiredClass) { + $childClasses[] = $requiredClass['name']; + } + $class->setChildClasses($childClasses); + } + $class->validateClassMapping(); } diff --git a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php index c55c34eaf..ac493f96b 100644 --- a/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php @@ -255,6 +255,14 @@ public function loadMetadataForClass($className, ClassMetadata $class) } } + if (isset($element['child_classes'])) { + $class->setChildClasses($element['child_classes']); + } + + if (isset($element['is_leaf'])) { + $class->setIsLeaf($element['is_leaf']); + } + $class->validateClassMapping(); } diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index 880b63428..4a0f9691c 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -54,6 +54,7 @@ use PHPCR\Util\PathHelper; use PHPCR\Util\NodeHelper; use Jackalope\Session as JackalopeSession; +use Doctrine\ODM\PHPCR\Exception\OutOfBoundsException; /** * Unit of work class @@ -2332,6 +2333,8 @@ private function executeInserts($documents) } $parentNode = $this->session->getNode(PathHelper::getParentPath($id)); + $this->validateChildClass($parentNode, $class); + $nodename = PathHelper::getNodeName($id); $node = $parentNode->addNode($nodename, $class->nodeType); if ($class->node) { @@ -2731,6 +2734,9 @@ private function executeMoves($documents) ); } + $parentNode = $this->session->getNode(PathHelper::getParentPath($targetPath)); + $this->validateChildClass($parentNode, $class); + $this->session->move($sourcePath, $targetPath); // update fields nodename, parentMapping and depth if they exist in this type @@ -3968,4 +3974,23 @@ public function invokeGlobalEvent($eventName, EventArgs $event) $this->eventManager->dispatchEvent($eventName, $event); } } + + /** + * 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); + } } diff --git a/tests/Doctrine/Tests/Models/CMS/CmsArticleFolder.php b/tests/Doctrine/Tests/Models/CMS/CmsArticleFolder.php new file mode 100644 index 000000000..0cee22bef --- /dev/null +++ b/tests/Doctrine/Tests/Models/CMS/CmsArticleFolder.php @@ -0,0 +1,22 @@ +assertSame($child->parent, $parent); $this->assertSame('parent', $parent->nodename); } + + /** + * @expectedException Doctrine\ODM\PHPCR\Exception\OutOfBoundsException + * @expectedExceptionMessage Document "Doctrine\Tests\Models\CMS\CmsArticleFolder" does not allow children of type "Doctrine\Tests\Models\CMS\CmsGroup". Allowed child classes "Doctrine\Tests\Models\CMS\CmsArticle" + */ + public function testRequiredClassesInvalidChildren() + { + $articleFolder = new CmsArticleFolder(); + $articleFolder->id = '/functional/articles'; + + $article = new CmsGroup(); + $article->id = '/functional/articles/address'; + $article->name = 'invalid-child'; + + $this->dm->persist($articleFolder); + $this->dm->persist($article); + $this->dm->flush(); + } + + public function testRequiredClassesValidChildren() + { + $articleFolder = new CmsArticleFolder(); + $articleFolder->id = '/functional/articles'; + + $article = new CmsArticle(); + $article->id = '/functional/articles/article'; + $article->topic = 'greetings'; + $article->text = 'Hello World'; + + $this->dm->persist($articleFolder); + $this->dm->persist($article); + $this->dm->flush(); + } + + /** + * @expectedException Doctrine\ODM\PHPCR\Exception\OutOfBoundsException + * @expectedExceptionMessage Document "Doctrine\Tests\Models\CMS\CmsArticleFolder" does not allow children of type "Doctrine\Tests\Models\CMS\CmsGroup". Allowed child classes "Doctrine\Tests\Models\CMS\CmsArticle" + */ + public function testRequiredClassesInvalidUpdate() + { + $articleFolder = new CmsArticleFolder(); + $articleFolder->id = '/functional/articles'; + + $article = new CmsGroup(); + $article->id = '/functional/address'; + $article->name = 'invalid-child'; + + $this->dm->persist($articleFolder); + $this->dm->persist($article); + $this->dm->flush(); + + $this->dm->move($article, '/functional/articles/address'); + $this->dm->flush(); + } + + public function testRequiredClassesAddToChildrenValid() + { + $post = new CmsBlogPost(); + $post->name = 'hello'; + + $postFolder = new CmsBlogFolder(); + $postFolder->id = '/functional/posts'; + $postFolder->posts = new ArrayCollection(array( + $post + )); + + $this->dm->persist($postFolder); + $this->dm->flush(); + } + + /** + * @expectedException Doctrine\ODM\PHPCR\Exception\OutOfBoundsException + * @expectedExceptionMessage Document "Doctrine\Tests\Models\CMS\CmsBlogFolder" does not allow children of type "Doctrine\Tests\Models\CMS\CmsBlogInvalidChild". Allowed child classes "Doctrine\Tests\Models\CMS\CmsBlogPost" + */ + public function testRequiredClassesAddToChildrenInvalid() + { + $post = new CmsBlogInvalidChild(); + $post->name = 'hello'; + + $postFolder = new CmsBlogFolder(); + $postFolder->id = '/functional/posts'; + $postFolder->posts = new ArrayCollection(array( + $post + )); + + $this->dm->persist($postFolder); + $this->dm->flush(); + } + + /** + * @expectedException Doctrine\ODM\PHPCR\Exception\OutOfBoundsException + * @expectedExceptionMessage Document "Doctrine\Tests\Models\CMS\CmsBlogFolder" does not allow children of type "Doctrine\Tests\Models\CMS\CmsBlogInvalidChild". Allowed child classes "Doctrine\Tests\Models\CMS\CmsBlogPost" + */ + public function testRequiredClassesAddToChildrenInvalidOnUpdate() + { + $post = new CmsBlogPost(); + $post->name = 'hello'; + + $postFolder = new CmsBlogFolder(); + $postFolder->id = '/functional/posts'; + $postFolder->posts = new ArrayCollection(array( + $post + )); + + $this->dm->persist($postFolder); + $this->dm->flush(); + $this->dm->clear(); + + $postFolder = $this->dm->find(null, '/functional/posts'); + + $post = new CmsBlogInvalidChild(); + $post->name = 'wolrd'; + $postFolder->posts->add($post); + + $this->dm->persist($postFolder); + $this->dm->flush(); + $this->dm->clear(); + } } diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php index f3a5d6bc6..745f5daf5 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php @@ -798,4 +798,36 @@ public function testUuidMappingNonReferenceable() return $this->loadMetadataForClassname($className); } + + public function testLoadChildClassesMapping() + { + $className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\ChildClassesObject'; + + return $this->loadMetadataForClassname($className); + } + + /** + * @depends testLoadChildClassesMapping + * @param ClassMetadata $class + */ + public function testChildClassesMapping($class) + { + $this->assertEquals(array('stdClass'), $class->getChildClasses()); + } + + public function testLoadIsLeafMapping() + { + $className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\IsLeafObject'; + + return $this->loadMetadataForClassname($className); + } + + /** + * @depends testLoadIsLeafMapping + * @param ClassMetadata $class + */ + public function testIsLeafMapping($class) + { + $this->assertTrue($class->isLeaf()); + } } diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataFactoryTest.php index 813ad3666..a0aee72cd 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataFactoryTest.php @@ -144,6 +144,15 @@ public function testValidateTranslatableNoStrategy() $this->getMetadataFor('Doctrine\Tests\ODM\PHPCR\Mapping\Model\TranslatorMappingObjectNoStrategy'); } + /** + * @expectedException \Doctrine\ODM\PHPCR\Mapping\MappingException + * @expectedExceptionMessage Cannot map a document as a leaf and define child classes for "Doctrine\Tests\ODM\PHPCR\Mapping\Model\ChildClassesAndLeafObject" + */ + public function testValidateChildClassesIfLeafConflict() + { + $this->getMetadataFor('Doctrine\Tests\ODM\PHPCR\Mapping\Model\ChildClassesAndLeafObject'); + } + public function testValidateTranslatable() { $this->getMetadataFor('Doctrine\Tests\ODM\PHPCR\Mapping\Model\TranslatorMappingObject'); diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataTest.php index 64a4b44a5..f64170789 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataTest.php @@ -42,8 +42,8 @@ public function testIsValidNodename(ClassMetadata $cm) $this->assertInstanceOf('PHPCR\RepositoryException', $cm->isValidNodename(':')); $this->assertInstanceOf('PHPCR\RepositoryException', $cm->isValidNodename('x/y')); - $this->assertNull($cm->isValidNodename('a:b')); - $this->assertNull($cm->isValidNodename('b')); + $cm->isValidNodename('a:b'); + $cm->isValidNodename('b'); } /** @@ -324,6 +324,88 @@ public function testClassMetadataInstanceSerializationTranslationProperties($cm) $this->assertTrue(in_array('translatedField', $cm->translatableFields)); $this->assertEquals('locale', $cm->localeMapping); } + + /** + * It should throw an exception if given a child class FQN when the + * metadata is for a leaf. + * + * @expectedException \Doctrine\ODM\PHPCR\Exception\OutOfBoundsException + * @expectedExceptionMessage has been mapped as a leaf + */ + public function testAssertValidChildClassesIsLeaf() + { + $cm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Person'); + $childCm = new ClassMetadata('stdClass'); + $cm->setIsLeaf(true); + $cm->assertValidChildClass($childCm); + } + + /** + * It should return early if the mapped child classes value is an empty array (i.e. any child classes are permitted). + */ + public function testAssertValidChildClassesEmpty() + { + $cm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Person'); + $childCm = new ClassMetadata('stdClass'); + $cm->setChildClasses(array()); + $cm->assertValidChildClass($childCm); + } + + /** + * It should return early if the given class is an allowed child class. + */ + public function testAssertValidChildClassesAllowed() + { + $cm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Person'); + $cm->setChildClasses(array('stdClass')); + $childCm = new ClassMetadata('stdClass'); + $childCm->initializeReflection(new RuntimeReflectionService()); + $cm->assertValidChildClass($childCm); + } + + /** + * It should return early if the given class is an instance of an allowed class. + */ + public function testAssertValidChildClassInstance() + { + $cm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Person'); + $cm->initializeReflection(new RuntimeReflectionService()); + $childCm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Customer'); + $childCm->initializeReflection(new RuntimeReflectionService()); + $cm->setChildClasses(array('Doctrine\Tests\ODM\PHPCR\Mapping\Person')); + $result = $cm->assertValidChildClass($childCm); + $this->assertNull($result); + } + + /** + * It should return early if the given class implements an allowed interface. + */ + public function testAssertValidChildClassInterface() + { + $cm = new ClassMetadata('Doctrine\Tests\ODM\PHPCR\Mapping\Person'); + $cm->initializeReflection(new RuntimeReflectionService()); + $childCm = new ClassMetadata('ArrayAccess'); + $childCm->initializeReflection(new RuntimeReflectionService()); + $cm->setChildClasses(array('ArrayAccess')); + $result = $cm->assertValidChildClass($childCm); + $this->assertNull($result); + } + + /** + * 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); + } } class Customer extends Person diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/ChildClassesAndLeafObject.php b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/ChildClassesAndLeafObject.php new file mode 100644 index 000000000..5748a1e89 --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/ChildClassesAndLeafObject.php @@ -0,0 +1,18 @@ + + + + + + + diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/xml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.xml b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/xml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.xml new file mode 100644 index 000000000..142cc7cfc --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/xml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.ChildClassesObject.dcm.yml b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.ChildClassesObject.dcm.yml new file mode 100644 index 000000000..fce4a1275 --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.ChildClassesObject.dcm.yml @@ -0,0 +1,5 @@ +Doctrine\Tests\ODM\PHPCR\Mapping\Model\ChildClassesObject: + id: id + child_classes: [ "stdClass" ] + is_leaf: false + diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.yml b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.yml new file mode 100644 index 000000000..1a05f773c --- /dev/null +++ b/tests/Doctrine/Tests/ODM/PHPCR/Mapping/Model/yml/Doctrine.Tests.ODM.PHPCR.Mapping.Model.IsLeafObject.dcm.yml @@ -0,0 +1,4 @@ +Doctrine\Tests\ODM\PHPCR\Mapping\Model\IsLeafObject: + id: id + is_leaf: true + diff --git a/tests/Doctrine/Tests/ODM/PHPCR/UnitOfWorkTest.php b/tests/Doctrine/Tests/ODM/PHPCR/UnitOfWorkTest.php index ee64b2b84..f8b5f2eed 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/UnitOfWorkTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/UnitOfWorkTest.php @@ -16,17 +16,34 @@ */ class UnitOfWorkTest extends PHPCRTestCase { - /** @var DocumentManager */ + /** + * @var DocumentManager + */ private $dm; - /** @var UnitOfWork */ + + /** + * @var UnitOfWork + */ private $uow; - /** @var Factory */ + + /** + * @var Factory + */ private $factory; - /** @var \PHPCR\SessionInterface */ + + /** + * @var \PHPCR\SessionInterface + */ private $session; - /** @var \Jackalope\ObjectManager */ + + /** + * @var \Jackalope\ObjectManager + */ private $objectManager; - /** @var string */ + + /** + * @var string + */ private $type; public function setUp()