Skip to content

Commit

Permalink
Merge release 2.5.5 into 2.6.x (#2585)
Browse files Browse the repository at this point in the history
* fix: Do not drop/re-create 2dsphere indexes (#2575)

* Validate that targetDocument can be resolved (#2577)

* fix: Validate that targetDocument can be resolved

* refactor: Use exception factory

* fix: Validate that all values in a discriminatorMap can be resolved

* fix: PHPStan errors for intentionally missing class

* fix: psalm/phpunit CI tests

---------

Co-authored-by: buffcode <[email protected]>
Co-authored-by: Andreas Braun <[email protected]>
  • Loading branch information
3 people authored Nov 24, 2023
1 parent 99aa043 commit 66a6f3f
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 56 deletions.
17 changes: 17 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use function enum_exists;
use function extension_loaded;
use function in_array;
use function interface_exists;
use function is_array;
use function is_string;
use function is_subclass_of;
Expand Down Expand Up @@ -2310,6 +2311,22 @@ public function mapField(array $mapping): array
$mapping['discriminatorField'] = self::DEFAULT_DISCRIMINATOR_FIELD;
}

if (isset($mapping['targetDocument']) && ! class_exists($mapping['targetDocument']) && ! interface_exists($mapping['targetDocument'])) {
throw MappingException::invalidTargetDocument(
$mapping['targetDocument'],
$this->name,
$mapping['fieldName'],
);
}

if (isset($mapping['discriminatorMap'])) {
foreach ($mapping['discriminatorMap'] as $value => $class) {
if (! class_exists($class) && ! interface_exists($class)) {
throw MappingException::invalidClassInReferenceDiscriminatorMap($class, $this->name, $mapping['fieldName']);
}
}
}

if (isset($mapping['version'])) {
$mapping['notSaved'] = true;
$this->setVersionMapping($mapping);
Expand Down
10 changes: 10 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public static function invalidClassInDiscriminatorMap(string $className, string
return new self(sprintf("Document class '%s' used in the discriminator map of class '%s' does not exist.", $className, $owningClass));
}

public static function invalidClassInReferenceDiscriminatorMap(string $className, string $owningClass, string $fieldName): self
{
return new self(sprintf("Document class '%s' used in the discriminator map of field '%s' in class '%s' does not exist.", $className, $fieldName, $owningClass));
}

public static function unlistedClassInDiscriminatorMap(string $className): self
{
return new self(sprintf('Document class "%s" is unlisted in the discriminator map.', $className));
Expand All @@ -82,6 +87,11 @@ public static function invalidDiscriminatorValue(string $value, string $owningCl
return new self(sprintf("Discriminator value '%s' used in the declaration of class '%s' does not exist.", $value, $owningClass));
}

public static function invalidTargetDocument(string $targetDocument, string $owningClass, string $owningField): self
{
return new self(sprintf("Target document class '%s' used in field '%s' of class '%s' does not exist.", $targetDocument, $owningField, $owningClass));
}

public static function missingFieldName(string $className): self
{
return new self(sprintf("The Document class '%s' field mapping misses the 'fieldName' attribute.", $className));
Expand Down
1 change: 1 addition & 0 deletions lib/Doctrine/ODM/MongoDB/SchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ final class SchemaManager
'language_override',
'textIndexVersion',
'name',
'2dsphereIndexVersion',
];

public function __construct(protected DocumentManager $dm, protected ClassMetadataFactoryInterface $metadataFactory)
Expand Down
39 changes: 39 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/IndexesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ public function testPartialIndexCreation(): void
self::assertSame(['counter' => ['$gt' => 5]], $indexes[0]['options']['partialFilterExpression']);
self::assertTrue($indexes[0]['options']['unique']);
}

public function testGeoIndexCreation(): void
{
$className = GeoIndexDocument::class;
$this->dm->getSchemaManager()->ensureDocumentIndexes(GeoIndexDocument::class);

$indexes = $this->dm->getSchemaManager()->getDocumentIndexes($className);
self::assertSame(['coordinatesWith2DIndex' => '2d'], $indexes[0]['keys']);
self::assertSame(['coordinatesWithSphereIndex' => '2dsphere'], $indexes[1]['keys']);
}
}

/** @ODM\Document */
Expand Down Expand Up @@ -657,3 +667,32 @@ class DocumentWithIndexInDiscriminatedEmbeds
*/
public $embedded;
}

/**
* @ODM\Document
* @ODM\Index(keys={"coordinatesWith2DIndex"="2d"})
* @ODM\Index(keys={"coordinatesWithSphereIndex"="2dsphere"})
*/
class GeoIndexDocument
{
/**
* @ODM\Id
*
* @var string|null
*/
public $id;

/**
* @ODM\Field(type="hash")
*
* @var array<float>
*/
public $coordinatesWith2DIndex;

/**
* @ODM\Field(type="hash")
*
* @var array<float>
*/
public $coordinatesWithSphereIndex;
}
124 changes: 124 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/TargetDocumentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

declare(strict_types=1);

namespace Doctrine\ODM\MongoDB\Tests\Functional;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\ODM\MongoDB\Mapping\MappingException;
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
use stdClass;

class TargetDocumentTest extends BaseTestCase
{
/** @doesNotPerformAssertions */
public function testMappedSuperClassAsTargetDocument(): void
{
$test = new TargetDocumentTestDocument();
$test->reference = new TargetDocumentTestReference();
$this->dm->persist($test);
$this->dm->persist($test->reference);
$this->dm->flush();
}

public function testTargetDocumentIsResolvable(): void
{
self::expectExceptionObject(
MappingException::invalidTargetDocument(
'Doctrine\ODM\MongoDB\Tests\Functional\SomeInvalidClass',
InvalidTargetDocumentTestDocument::class,
'reference',
),
);

$test = new InvalidTargetDocumentTestDocument();
$test->reference = new stdClass();
$this->dm->persist($test);
}

public function testDiscriminatorTargetIsResolvable(): void
{
self::expectExceptionObject(
MappingException::invalidClassInReferenceDiscriminatorMap(
'Doctrine\ODM\MongoDB\Tests\Functional\SomeInvalidClass',
InvalidDiscriminatorTargetsTestDocument::class,
'reference',
),
);

$test = new InvalidDiscriminatorTargetsTestDocument();
$test->reference = new stdClass();
$this->dm->persist($test);
}
}

/** @ODM\Document */
class TargetDocumentTestDocument
{
/**
* @ODM\Id
*
* @var string|null
*/
public $id;

/**
* @ODM\ReferenceOne(targetDocument=Doctrine\ODM\MongoDB\Tests\Functional\TargetDocumentTestReference::class)
*
* @var TargetDocumentTestReference|null
*/
public $reference;
}

/** @ODM\MappedSuperclass */
abstract class AbstractTargetDocumentTestReference
{
/**
* @ODM\Id
*
* @var string|null
*/
public $id;
}

/** @ODM\Document */
class TargetDocumentTestReference extends AbstractTargetDocumentTestReference
{
}

/** @ODM\Document */
class InvalidTargetDocumentTestDocument
{
/**
* @ODM\Id
*
* @var string|null
*/
public $id;

/**
* @ODM\ReferenceOne(targetDocument="Doctrine\ODM\MongoDB\Tests\Functional\SomeInvalidClass")
*
* @var object|null
*/
public $reference;
}


/** @ODM\Document */
class InvalidDiscriminatorTargetsTestDocument
{
/**
* @ODM\Id
*
* @var string|null
*/
public $id;

/**
* @ODM\ReferenceOne(discriminatorField="referencedClass", discriminatorMap={"Foo"="Doctrine\ODM\MongoDB\Tests\Functional\SomeInvalidClass"})
*
* @var object|null
*/
public $reference;
}
56 changes: 0 additions & 56 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/TestTargetDocument.php

This file was deleted.

6 changes: 6 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,12 @@ public static function dataIsMongoIndexEquivalentToDocumentIndex(): array
'mongoIndex' => ['background' => true],
'documentIndex' => ['options' => ['background' => true]],
],
// 2dsphereIndexVersion index options
'2dsphereIndexVersionOptionsDifferent' => [
'expected' => true,
'mongoIndex' => ['2dsphereIndexVersion' => 3],
'documentIndex' => [],
],
];
}

Expand Down

0 comments on commit 66a6f3f

Please sign in to comment.