Skip to content

Commit

Permalink
added support for hard and weak referrers
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Stark committed Aug 26, 2011
1 parent 42c24a3 commit 5fb699f
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 57 deletions.
4 changes: 2 additions & 2 deletions lib/Doctrine/ODM/PHPCR/DocumentManager.php
Expand Up @@ -326,9 +326,9 @@ public function getChildren($document, $filter = null)
* @param string|array $name optional name to match on referrers names
* @return a collection of referrer documents
*/
public function getReferrers($document, $name = null)
public function getReferrers($document, $type = "all", $name = null)
{
return $this->unitOfWork->getReferrers($document, $name);
return $this->unitOfWork->getReferrers($document, $type, $name);
}

/**
Expand Down
Expand Up @@ -95,6 +95,7 @@ class Children extends Annotation
class Referrers extends Annotation
{
public $filterName = null;
public $referenceType = "all";
}

final class EmbeddedDocument extends Annotation {}
Expand Down
11 changes: 10 additions & 1 deletion lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataInfo.php
Expand Up @@ -527,11 +527,20 @@ public function mapChildren(array $mapping)

public function mapReferrers(array $mapping)
{
$mapping = $this->validateAndCompleteFieldMapping($mapping, false);
$mapping = $this->validateAndCompleteReferrersMapping($mapping, false);
$mapping['name'] = $mapping['fieldName'];
$this->referrersMappings[$mapping['fieldName']] = $mapping;
}

protected function validateAndCompleteReferrersMapping($mapping)
{
$mapping = $this->validateAndCompleteFieldMapping($mapping, false);
if (!isset($mapping['referenceType']) && in_array($mapping['referenceType'], array("all", "weak", "hard"))) {
throw new MappingException("You have to specify a 'referenceType' for the '" . $this->name . "' association which must be 'all', 'weak' or 'hard'.");
}
return $mapping;
}

protected function validateAndCompleteFieldMapping($mapping, $isField = true)
{
if (!isset($mapping['fieldName'])) {
Expand Down
15 changes: 15 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Proxy/ReferenceProxyFactory.php
Expand Up @@ -174,6 +174,21 @@ private function getUnsetAttributes(ClassMetadata $class)
$attributes .= ", ";
}

foreach ($class->referrersMappings as $field) {
$attributes .= '$this->'.$field["fieldName"];
$attributes .= ", ";
}

foreach ($class->childrenMappings as $field) {
$attributes .= '$this->'.$field["fieldName"];
$attributes .= ", ";
}

foreach ($class->childMappings as $field) {
$attributes .= '$this->'.$field["fieldName"];
$attributes .= ", ";
}

$attributes = substr($attributes, 0, -2);

return "unset(".$attributes.");";
Expand Down
5 changes: 3 additions & 2 deletions lib/Doctrine/ODM/PHPCR/ReferrersCollection.php
Expand Up @@ -15,17 +15,18 @@ class ReferrersCollection extends PersistentCollection
private $dm;
private $name;

public function __construct($document, DocumentManager $dm, $name= null)
public function __construct($document, DocumentManager $dm, $type = "all", $name = null)
{
$this->document = $document;
$this->dm = $dm;
$this->type = $type;
$this->name = $name;
}

protected function load()
{
if (null === $this->col) {
$this->col = $this->dm->getReferrers($this->document, $this->name);
$this->col = $this->dm->getReferrers($this->document, $this->type, $this->name);
}
}
}
34 changes: 27 additions & 7 deletions lib/Doctrine/ODM/PHPCR/UnitOfWork.php
Expand Up @@ -238,8 +238,10 @@ public function createDocument($documentName, $node, array &$hints = array())
}
}

$session = $this->dm->getPhpcrSession();
$refNodes = $session->getNodesByIdentifier($refNodeUUIDs);
if (count($refNodeUUIDs) > 0) {
$session = $this->dm->getPhpcrSession();
$refNodes = $session->getNodesByIdentifier($refNodeUUIDs);
}

// initialize inverse side collections
foreach ($class->associationsMappings as $assocName => $assocOptions) {
Expand Down Expand Up @@ -340,7 +342,7 @@ public function createDocument($documentName, $node, array &$hints = array())
}

foreach ($class->referrersMappings as $mapping) {
$documentState[$mapping['fieldName']] = new ReferrersCollection($document, $this->dm, $mapping['filterName']);
$documentState[$mapping['fieldName']] = new ReferrersCollection($document, $this->dm, $mapping['referenceType'], $mapping['filterName']);
}

if (isset($documentName) && $this->validateDocumentName && !($document instanceof $documentName)) {
Expand Down Expand Up @@ -1159,16 +1161,34 @@ public function getChildren($document, $filter = null)
* @param string|array $name optional name to match on referrers names
* @return a collection of referrer documents
*/
public function getReferrers($document, $name = null)
public function getReferrers($document, $type = "all", $name = null)
{
$oid = spl_object_hash($document);
$node = $this->nodesMap[$oid];
$referrerProperties = $node->getReferences($name);

$referrerDocuments = array();
foreach ($referrerProperties as $name => $referrerProperty) {
$referrerPropertiesW = array();
$referrerPropertiesH = array();

if ($type === "all") {
$referrerPropertiesW = $node->getWeakReferences($name);
$referrerPropertiesH = $node->getReferences($name);
} elseif ($type === "weak") {
$referrerPropertiesW = $node->getWeakReferences($name);
} elseif ($type === "hard") {
$referrerPropertiesH = $node->getReferences($name);
}

foreach ($referrerPropertiesW as $referrerProperty) {
$referrerNode = $referrerProperty->getParent();
$referrerDocuments[$name] = $this->createDocument(null, $referrerNode);
$referrerDocuments[] = $this->createDocument(null, $referrerNode);
}

foreach ($referrerPropertiesH as $referrerProperty) {
$referrerNode = $referrerProperty->getParent();
$referrerDocuments[] = $this->createDocument(null, $referrerNode);
}

return new ArrayCollection($referrerDocuments);
}

Expand Down
58 changes: 57 additions & 1 deletion tests/Doctrine/Tests/ODM/PHPCR/Functional/ChildTest.php
Expand Up @@ -236,8 +236,33 @@ public function testModificationAfterPersist()
$this->assertNotNull($parent->child);
$this->assertEquals('Changed', $parent->child->name);
}
}

public function testChildOfReference()
{
$referrerTestObj = new ChildReferrerTestObj();
$referrerTestObj->id = "/functional/referrerTestObj";
$referrerTestObj->name = "referrerTestObj";

$refererenceableTestObj = new ChildReferenceableTestObj();
$refererenceableTestObj->id = "/functional/referenceableTestObj";
$refererenceableTestObj->name = "referenceableTestObj";
$referrerTestObj->reference = $refererenceableTestObj;

$this->dm->persist($referrerTestObj);

$ChildTestObj = new ChildTestObj();
$ChildTestObj->id = "/functional/referenceableTestObj/test";
$ChildTestObj->name= "childTestObj";

$this->dm->persist($ChildTestObj);
$this->dm->flush();
$this->dm->clear();

$referrer = $this->dm->find(null, "/functional/referrerTestObj");

$this->assertEquals($referrer->reference->aChild->name, "childTestObj");
}
}

/**
* @PHPCRODM\Document(alias="childTestObj")
Expand All @@ -251,6 +276,7 @@ class ChildChildTestObj
/** @PHPCRODM\String */
public $name;
}

/**
* @PHPCRODM\Document(alias="testObj")
*/
Expand All @@ -265,3 +291,33 @@ class ChildTestObj
/** @PHPCRODM\Child(name="test") */
public $child;
}

/**
* @PHPCRODM\Document(alias="ChildReferrerTestObj")
*/
class ChildReferrerTestObj
{
/** @PHPCRODM\Id */
public $id;

/** @PHPCRODM\String */
public $name;

/** @PHPCRODM\ReferenceOne(targetDocument="ChildReferenceableTestObj") */
public $reference;
}

/**
* @PHPCRODM\Document(alias="ChildReferenceableTestObj", referenceable="true")
*/
class ChildReferenceableTestObj
{
/** @PHPCRODM\Id */
public $id;

/** @PHPCRODM\String */
public $name;

/** @PHPCRODM\Child(name="test") */
public $aChild;
}
58 changes: 58 additions & 0 deletions tests/Doctrine/Tests/ODM/PHPCR/Functional/ChildrenTest.php
Expand Up @@ -76,6 +76,34 @@ public function testAnnotation()
$this->assertEquals(1, count($parent->aChildren));
$this->assertEquals(4, count($parent->allChildren));
}

public function testChildrenOfReference()
{
$referrerTestObj = new ChildrenReferrerTestObj();
$referrerTestObj->id = "/functional/referrerTestObj";
$referrerTestObj->name = "referrerTestObj";

$refererenceableTestObj = new ChildrenReferenceableTestObj();
$refererenceableTestObj->id = "/functional/referenceableTestObj";
$refererenceableTestObj->name = "referenceableTestObj";
$referrerTestObj->reference = $refererenceableTestObj;

$this->dm->persist($referrerTestObj);

$ChildrenTestObj = new ChildrenTestObj();
$ChildrenTestObj->id = "/functional/referenceableTestObj/childrenTestObj";
$ChildrenTestObj->name= "childrenTestObj";

$this->dm->persist($ChildrenTestObj);
$this->dm->flush();
$this->dm->clear();

$referrer = $this->dm->find(null, "/functional/referrerTestObj");

$this->assertEquals(count($referrer->reference->allChildren), 1);
$this->assertEquals($referrer->reference->allChildren->first()->name, "childrenTestObj");

}
}

/**
Expand All @@ -95,3 +123,33 @@ class ChildrenTestObj
/** @PHPCRODM\Children */
public $allChildren;
}

/**
* @PHPCRODM\Document(alias="Referrer")
*/
class ChildrenReferrerTestObj
{
/** @PHPCRODM\Id */
public $id;

/** @PHPCRODM\String */
public $name;

/** @PHPCRODM\ReferenceOne(targetDocument="ChildrenReferenceableTestObj") */
public $reference;
}

/**
* @PHPCRODM\Document(alias="ChildrenReferenceableTestObj", referenceable="true")
*/
class ChildrenReferenceableTestObj
{
/** @PHPCRODM\Id */
public $id;

/** @PHPCRODM\String */
public $name;

/** @PHPCRODM\Children */
public $allChildren;
}

0 comments on commit 5fb699f

Please sign in to comment.