Skip to content

Commit fc9cd8d

Browse files
committed
Issue 573 - fixed getting child nodes of a version of a document
1 parent c6f4647 commit fc9cd8d

File tree

4 files changed

+130
-46
lines changed

4 files changed

+130
-46
lines changed

lib/Doctrine/ODM/PHPCR/UnitOfWork.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ class UnitOfWork
7979
const STATE_REMOVED = 3;
8080
const STATE_DETACHED = 4;
8181

82+
/**
83+
* Used for versions of documents (these are unmodifiable frozen nodes)
84+
*
85+
* @var int
86+
*/
87+
const STATE_FROZEN = 5;
88+
8289
/**
8390
* @var DocumentManager
8491
*/
@@ -799,6 +806,8 @@ private function doScheduleInsert($document, &$visited, $overrideIdGenerator = n
799806
break;
800807
case self::STATE_DETACHED:
801808
throw new InvalidArgumentException('Detached document or new document with already existing id passed to persist(): '.self::objToStr($document, $this->dm));
809+
case self::STATE_FROZEN:
810+
throw new InvalidArgumentException('Document versions cannot be persisted: '.self::objToStr($document, $this->dm));
802811
}
803812

804813
$this->cascadeScheduleInsert($class, $document, $visited);
@@ -2860,7 +2869,7 @@ public function findVersionByName($className, $id, $versionName)
28602869

28612870
$hints = array('versionName' => $versionName, 'ignoreHardReferenceNotFound' => true);
28622871
$frozenDocument = $this->getOrCreateDocument($className, $node, $hints);
2863-
$this->dm->detach($frozenDocument);
2872+
28642873

28652874
$oid = spl_object_hash($frozenDocument);
28662875
$this->documentHistory[$oid] = $history;
@@ -3032,8 +3041,12 @@ public function registerDocument($document, $id)
30323041
$oid = spl_object_hash($document);
30333042
$this->documentIds[$oid] = $id;
30343043
$this->identityMap[$id] = $document;
3035-
$this->setDocumentState($oid, self::STATE_MANAGED);
3044+
3045+
// frozen nodes need another state so they are managed but not included for updates
3046+
$frozen = $this->session->nodeExists($id) && $this->session->getNode($id)->isNodeType('nt:frozenNode');
30363047

3048+
$this->setDocumentState($oid, $frozen ? self::STATE_FROZEN : self::STATE_MANAGED);
3049+
30373050
return $oid;
30383051
}
30393052

tests/Doctrine/Tests/Models/Versioning/FullVersionableArticleWithChildren.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@
99
*/
1010
class FullVersionableArticleWithChildren extends FullVersionableArticle
1111
{
12-
/** @PHPCRODM\Children */
13-
public $childArticles;
14-
15-
public function __construct()
16-
{
17-
$this->childArticles = new ArrayCollection();
18-
}
19-
20-
public function addChildArticle(NonVersionableArticle $a)
21-
{
22-
$this->childArticles->add($a);
23-
}
12+
13+
/**
14+
* @PHPCRODM\Children
15+
*/
16+
public $childArticles;
17+
18+
public function __construct()
19+
{
20+
$this->childArticles = new ArrayCollection();
21+
}
22+
23+
public function addChildArticle(NonVersionableArticle $a)
24+
{
25+
$this->childArticles->add($a);
26+
}
2427
}

tests/Doctrine/Tests/ODM/PHPCR/Functional/Versioning/VersioningTestAbstract.php

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\Tests\Models\Versioning\FullVersionableArticle;
88
use Doctrine\Tests\Models\Versioning\FullVersionableArticleWithChildren;
99
use Doctrine\Tests\Models\Versioning\NonVersionableArticle;
10+
use Doctrine\ODM\PHPCR\UnitOfWork;
1011

1112
/**
1213
* @group functional
@@ -342,41 +343,58 @@ public function testDeletedVersionDoesNotExistAnymore($lastVersionName)
342343
{
343344
$this->dm->findVersionByName($this->typeVersion, '/functional/versionTestObj', $lastVersionName);
344345
}
345-
346+
346347
/**
347348
* Try to access the children of a specific version of a document and assert they
348349
* are hydrated properly
349350
*/
350351
public function testUnversionedChildrenOnParentVersion()
351352
{
352-
$versionableArticle = new FullVersionableArticleWithChildren();
353-
$versionableArticle->author = 'mellowplace';
354-
$versionableArticle->topic = 'children test';
355-
$versionableArticle->id = '/functional/children-test';
356-
$versionableArticle->setText('Parent article text');
357-
$this->dm->persist($versionableArticle);
358-
359-
$childArticle = new NonVersionableArticle();
360-
$childArticle->setText("This is the child");
361-
$childArticle->id = '/functional/children-test/child';
362-
$childArticle->author = 'mellowplace';
363-
$childArticle->topic = 'children test - child';
364-
$versionableArticle->addChildArticle($childArticle);
365-
366-
$this->dm->flush();
367-
368-
$this->dm->checkpoint($versionableArticle);
369-
370-
$version = $this->dm->findVersionByName(
371-
'Doctrine\Tests\Models\Versioning\FullVersionableArticleWithChildren',
372-
$versionableArticle->id,
373-
'1.0'
353+
$versionableArticle = new FullVersionableArticleWithChildren();
354+
$versionableArticle->author = 'mellowplace';
355+
$versionableArticle->topic = 'children test';
356+
$versionableArticle->id = '/functional/children-test';
357+
$versionableArticle->setText('Parent article text');
358+
$this->dm->persist($versionableArticle);
359+
360+
$childArticle = new NonVersionableArticle();
361+
$childArticle->setText("This is the child");
362+
$childArticle->id = '/functional/children-test/child';
363+
$childArticle->author = 'mellowplace';
364+
$childArticle->topic = 'children test - child';
365+
$versionableArticle->addChildArticle($childArticle);
366+
367+
// checkin the first version (1.0)
368+
$this->dm->flush();
369+
$this->dm->checkpoint($versionableArticle);
370+
371+
// now modify the child nodes text and checkin the second version (1.1)
372+
$childArticle->setText('modified text');
373+
$this->dm->flush();
374+
$this->dm->checkpoint($versionableArticle);
375+
376+
$firstVersion = $this->dm->findVersionByName(
377+
'Doctrine\Tests\Models\Versioning\FullVersionableArticleWithChildren',
378+
$versionableArticle->id,
379+
'1.0'
380+
);
381+
382+
$secondVersion = $this->dm->findVersionByName(
383+
'Doctrine\Tests\Models\Versioning\FullVersionableArticleWithChildren',
384+
$versionableArticle->id,
385+
'1.1'
374386
);
375-
376-
$this->assertEquals(
377-
"This is the child",
378-
$version->childArticles->first()->getText(),
379-
"The expected child article text is correct"
387+
388+
$this->assertEquals(
389+
'This is the child',
390+
$firstVersion->childArticles->first()->getText(),
391+
'The expected child article text is correct'
392+
);
393+
394+
$this->assertEquals(
395+
'modified text',
396+
$secondVersion->childArticles->first()->getText(),
397+
'The expected, modified, child article text is correct'
380398
);
381399
}
382400
}

tests/Doctrine/Tests/ODM/PHPCR/UnitOfWorkTest.php

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function setUp()
3838

3939
$this->factory = new Factory;
4040
$this->session = $this->getMock('Jackalope\Session', array(), array($this->factory), '', false);
41+
4142
$this->objectManager = $this->getMock('Jackalope\ObjectManager', array(), array($this->factory), '', false);
4243

4344
$this->type = 'Doctrine\Tests\ODM\PHPCR\UoWUser';
@@ -53,20 +54,55 @@ public function setUp()
5354
$cmf->setMetadataFor($this->type, $metadata);
5455
}
5556

56-
protected function createNode($id, $username)
57+
protected function createNode($id, $username, $primaryType = 'rep:root')
5758
{
5859
$repository = $this->getMockBuilder('Jackalope\Repository')->disableOriginalConstructor()->getMock();
5960
$this->session->expects($this->any())
6061
->method('getRepository')
6162
->with()
6263
->will($this->returnValue($repository));
63-
64+
65+
$type = $this->getMockBuilder('Jackalope\NodeType\NodeType')->disableOriginalConstructor()->getMock();
66+
$type->expects($this->any())
67+
->method('getName')
68+
->with()
69+
->will($this->returnValue($primaryType));
70+
71+
$ntm = $this->getMockBuilder('Jackalope\NodeType\NodeTypeManager')->disableOriginalConstructor()->getMock();
72+
$ntm->expects($this->any())
73+
->method('getNodeType')
74+
->with()
75+
->will($this->returnValue($type));
76+
77+
$workspace = $this->getMockBuilder('Jackalope\Workspace')->disableOriginalConstructor()->getMock();
78+
$workspace->expects($this->any())
79+
->method('getNodeTypeManager')
80+
->with()
81+
->will($this->returnValue($ntm));
82+
83+
$this->session->expects($this->any())
84+
->method('getWorkspace')
85+
->with()
86+
->will($this->returnValue($workspace));
87+
88+
$this->session->expects($this->any())
89+
->method('nodeExists')
90+
->with($id)
91+
->will($this->returnValue(true));
92+
6493
$nodeData = array(
65-
"jcr:primaryType" => "rep:root",
94+
"jcr:primaryType" => $primaryType,
6695
"jcr:system" => array(),
6796
'username' => $username,
6897
);
69-
return new Node($this->factory, $nodeData, $id, $this->session, $this->objectManager);
98+
$node = new Node($this->factory, $nodeData, $id, $this->session, $this->objectManager);
99+
100+
$this->session->expects($this->any())
101+
->method('getNode')
102+
->with($id)
103+
->will($this->returnValue($node));
104+
105+
return $node;
70106
}
71107

72108
public function testGetOrCreateDocument()
@@ -161,6 +197,20 @@ public function testUuid()
161197
$uow = new UnitOfWork($dm);
162198
$this->assertEquals('like-a-uuid', $method->invoke($uow));
163199
}
200+
201+
/**
202+
* @author Rob Graham
203+
*
204+
* Test the registering of a version of a document, state should be set to STATE_FROZEN
205+
*/
206+
public function testRegisterDocumentForVersion()
207+
{
208+
// create a node of type frozenNode (which is a version)
209+
$node = $this->createNode('/version/doc', 'foo', 'nt:frozenNode');
210+
$document = $this->uow->getOrCreateDocument($this->type, $node);
211+
$this->uow->registerDocument($document, '/version/doc');
212+
$this->assertEquals(UnitOfWork::STATE_FROZEN, $this->uow->getDocumentState($document), 'A version of a document is frozen as expected');
213+
}
164214
}
165215

166216
class UoWUser

0 commit comments

Comments
 (0)