Skip to content

Commit

Permalink
Apply review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
alcaeus committed Sep 27, 2017
1 parent c2cc628 commit fbfc8ce
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 53 deletions.
4 changes: 2 additions & 2 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,7 @@ Optional attributes:
-
storeAs - Indicates how to store the reference. ``id`` stores the identifier,
``ref`` an embedded object containing the ``id`` field and (optionally) a
discriminator. ``dbRef`` and ``dbRefWithDb`` store a `DBRef`_ object. They
discriminator. ``dbRef`` and ``dbRefWithDb`` store a `DBRef`_ object and
are deprecated in favor of ``ref``. Note that ``id`` references are not
compatible with the discriminators.
-
Expand Down Expand Up @@ -1297,7 +1297,7 @@ Optional attributes:
-
storeAs - Indicates how to store the reference. ``id`` stores the identifier,
``ref`` an embedded object containing the ``id`` field and (optionally) a
discriminator. ``dbRef`` and ``dbRefWithDb`` store a `DBRef`_ object. They
discriminator. ``dbRef`` and ``dbRefWithDb`` store a `DBRef`_ object and
are deprecated in favor of ``ref``. Note that ``id`` references are not
compatible with the discriminators.
-
Expand Down
27 changes: 18 additions & 9 deletions lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -703,25 +703,34 @@ public function createReference($document, array $referenceMapping)


case ClassMetadataInfo::REFERENCE_STORE_AS_REF:
$dbRef = ['id' => $class->getDatabaseIdentifierValue($id)];
$reference = ['id' => $class->getDatabaseIdentifierValue($id)];
break;

default:
$dbRef = [
case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF:
$reference = [
'$ref' => $class->getCollection(),
'$id' => $class->getDatabaseIdentifierValue($id),
];
if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB) {
$dbRef['$db'] = $this->getDocumentDatabase($class->name)->getName();
}
break;

case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB:
$reference = [
'$ref' => $class->getCollection(),
'$id' => $class->getDatabaseIdentifierValue($id),
'$db' => $this->getDocumentDatabase($class->name)->getName(),
];
break;

default:
throw new \InvalidArgumentException("Reference type {$storeAs} is invalid.");
}

/* If the class has a discriminator (field and value), use it. A child
* class that is not defined in the discriminator map may only have a
* discriminator field and no value, so default to the full class name.
*/
if (isset($class->discriminatorField)) {
$dbRef[$class->discriminatorField] = isset($class->discriminatorValue)
$reference[$class->discriminatorField] = isset($class->discriminatorValue)
? $class->discriminatorValue
: $class->name;
}
Expand All @@ -745,10 +754,10 @@ public function createReference($document, array $referenceMapping)
$discriminatorValue = $class->name;
}

$dbRef[$discriminatorField] = $discriminatorValue;
$reference[$discriminatorField] = $discriminatorValue;
}

return $dbRef;
return $reference;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ public function __construct($documentName)

/**
* Helper method to get reference id of ref* type references
* @param array $reference
* @param mixed $reference
* @param string $storeAs
* @return mixed
* @internal
Expand Down
38 changes: 23 additions & 15 deletions lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -1420,31 +1420,39 @@ private function getWriteOptions(array $options = array())
*/
private function prepareReference($fieldName, $value, array $mapping, $inNewObj)
{
$dbRef = $this->dm->createReference($value, $mapping);
$reference = $this->dm->createReference($value, $mapping);
if ($inNewObj || $mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
return [[$fieldName, $dbRef]];
return [[$fieldName, $reference]];
}

if ($mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_REF) {
$keys = ['id' => true];
} else {
$keys = ['$ref' => true, '$id' => true, '$db' => true];
switch ($mapping['storeAs']) {
case ClassMetadataInfo::REFERENCE_STORE_AS_REF:
$keys = ['id' => true];
break;

if ($mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
unset($keys['$db']);
}
case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF:
case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB:
$keys = ['$ref' => true, '$id' => true, '$db' => true];

if (isset($mapping['targetDocument'])) {
unset($keys['$ref'], $keys['$db']);
}
if ($mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
unset($keys['$db']);
}

if (isset($mapping['targetDocument'])) {
unset($keys['$ref'], $keys['$db']);
}
break;

default:
throw new \InvalidArgumentException("Reference type {$mapping['storeAs']} is invalid.");
}

if ($mapping['type'] === 'many') {
return [[$fieldName, ['$elemMatch' => array_intersect_key($dbRef, $keys)]]];
return [[$fieldName, ['$elemMatch' => array_intersect_key($reference, $keys)]]];
} else {
return array_map(
function ($key) use ($dbRef, $fieldName) {
return [$fieldName . '.' . $key, $dbRef[$key]];
function ($key) use ($reference, $fieldName) {
return [$fieldName . '.' . $key, $reference[$key]];
},
array_keys($keys)
);
Expand Down
64 changes: 40 additions & 24 deletions lib/Doctrine/ODM/MongoDB/Query/Expr.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,21 @@ public function references($document)
{
if ($this->currentField) {
$mapping = $this->getReferenceMapping();
$dbRef = $this->dm->createReference($document, $mapping);
$reference = $this->dm->createReference($document, $mapping);
$storeAs = array_key_exists('storeAs', $mapping) ? $mapping['storeAs'] : null;

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
$this->query[$mapping['name']] = $dbRef;
} else {
if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_REF) {
switch ($storeAs) {
case ClassMetadataInfo::REFERENCE_STORE_AS_ID:
$this->query[$mapping['name']] = $reference;
return $this;
break;

case ClassMetadataInfo::REFERENCE_STORE_AS_REF:
$keys = ['id' => true];
} else {
break;

case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF:
case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB:
$keys = ['$ref' => true, '$id' => true, '$db' => true];

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
Expand All @@ -91,17 +97,19 @@ public function references($document)
if (isset($mapping['targetDocument'])) {
unset($keys['$ref'], $keys['$db']);
}
}
break;

foreach ($keys as $key => $value) {
$this->query[$mapping['name'] . '.' . $key] = $dbRef[$key];
}
default:
throw new \InvalidArgumentException("Reference type {$storeAs} is invalid.");
}

foreach ($keys as $key => $value) {
$this->query[$mapping['name'] . '.' . $key] = $reference[$key];
}
} else {
@trigger_error('Calling ' . __METHOD__ . ' without a current field set will no longer be possible in ODM 2.0.', E_USER_DEPRECATED);

$dbRef = $this->dm->createReference($document);
$this->query = $dbRef;
$this->query = $this->dm->createDBRef($document);
}

return $this;
Expand All @@ -117,15 +125,21 @@ public function includesReferenceTo($document)
{
if ($this->currentField) {
$mapping = $this->getReferenceMapping();
$dbRef = $this->dm->createReference($document, $mapping);
$reference = $this->dm->createReference($document, $mapping);
$storeAs = array_key_exists('storeAs', $mapping) ? $mapping['storeAs'] : null;

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
$this->query[$mapping['name']] = $dbRef;
} else {
if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_REF) {
switch ($storeAs) {
case ClassMetadataInfo::REFERENCE_STORE_AS_ID:
$this->query[$mapping['name']] = $reference;
return $this;
break;

case ClassMetadataInfo::REFERENCE_STORE_AS_REF:
$keys = ['id' => true];
} else {
break;

case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF:
case ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB:
$keys = ['$ref' => true, '$id' => true, '$db' => true];

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
Expand All @@ -135,17 +149,19 @@ public function includesReferenceTo($document)
if (isset($mapping['targetDocument'])) {
unset($keys['$ref'], $keys['$db']);
}
}
break;

foreach ($keys as $key => $value) {
$this->query[$mapping['name']]['$elemMatch'][$key] = $dbRef[$key];
}
default:
throw new \InvalidArgumentException("Reference type {$storeAs} is invalid.");
}

foreach ($keys as $key => $value) {
$this->query[$mapping['name']]['$elemMatch'][$key] = $reference[$key];
}
} else {
@trigger_error('Calling ' . __METHOD__ . ' without a current field set will no longer be possible in ODM 2.0.', E_USER_DEPRECATED);

$dbRef = $this->dm->createReference($document);
$this->query['$elemMatch'] = $dbRef;
$this->query['$elemMatch'] = $this->dm->createDBRef($document);
}

return $this;
Expand Down
4 changes: 2 additions & 2 deletions tests/Doctrine/ODM/MongoDB/Tests/Query/ExprTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public function testReferencesUsesMinimalKeys()
->will($this->returnValue($expected));
$class->expects($this->once())
->method('getFieldMapping')
->will($this->returnValue(array('targetDocument' => 'Foo', 'name' => 'foo')));
->will($this->returnValue(array('targetDocument' => 'Foo', 'name' => 'foo', 'storeAs' => ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB)));

$expr = new Expr($dm);
$expr->setClassMetadata($class);
Expand Down Expand Up @@ -239,7 +239,7 @@ public function testReferencesUsesAllKeys()
->will($this->returnValue($expected));
$class->expects($this->once())
->method('getFieldMapping')
->will($this->returnValue(array('name' => 'foo')));
->will($this->returnValue(array('name' => 'foo', 'storeAs' => ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB)));

$expr = new Expr($dm);
$expr->setClassMetadata($class);
Expand Down

0 comments on commit fbfc8ce

Please sign in to comment.