Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] @EmbedOne @EmbedMany without targetDocument on 2.0@beta-1 #1961

Closed
Dragonqos opened this issue Feb 19, 2019 · 7 comments
Closed

[Bug] @EmbedOne @EmbedMany without targetDocument on 2.0@beta-1 #1961

Dragonqos opened this issue Feb 19, 2019 · 7 comments
Labels
Milestone

Comments

@Dragonqos
Copy link

Dragonqos commented Feb 19, 2019

Bug Report

Trying to create EmbedOne/EmbedMany Relation with discriminatorMap and discriminatorType only, getting error on Metadata parse:

Q A
BC Break yes/no
Version 2.0.0-beta1

Summary

When we calling $class = $metadata->getAssociationTargetClass($property); from file api-platform/core/src/Bridge/Doctrine/MongoDbOdm/PropertyInfo/DoctrineExtractor.php:69 and targetDocument is not defined method should return NULL instead of STRING, but that action was restricted by type hint in file MongoDB/Mapping/ClassMetadata.php:1743

In ClassMetadata.php line 1743:
  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Return value of Doctrine\ODM\MongoDB\Mapping\ClassMetadata::getAssociationTargetClass() must be of the type string, null returned
Exception trace:
 () at /var/www/channel/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php:1743
 Doctrine\ODM\MongoDB\Mapping\ClassMetadata->getAssociationTargetClass() at /var/www/channel/vendor/api-platform/core/src/Bridge/Doctrine/MongoDbOdm/PropertyInfo/DoctrineExtractor.php:69

Current behavior

public function getAssociationTargetClass($assocName) : string
returns STRING or throw FatalError

How to reproduce

<?php

namespace App\Tests;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
use PHPUnit\Framework\TestCase;

class DiscriminatorTest extends TestCase
{
    public function testGettingMetadataForEmbededWithoutTargetDocument()
    {
        $classMetadata = $this->loadMetadata(EmbedWithoutTargetDocument::class);

        self::assertEquals([
            "fieldName" => "embeddedPhonenumber",
            "type" => "one",
            "embedded" => true,
            "targetDocument" => null,
            "discriminatorField" => "discr",
            "discriminatorMap" => [
                "home" => "App\Tests\HomePhonenumber",
            ],
            "defaultDiscriminatorValue" => null,
            "name" => "embeddedPhonenumber",
            "nullable" => false,
            "options" => [],
            "strategy" => "set",
            "notSaved" => false,
            "value" => null,
            "isCascadeRemove" => true,
            "isCascadePersist" => true,
            "isCascadeRefresh" => true,
            "isCascadeMerge" => true,
            "isCascadeDetach" => true,
            "association" => 3,
            "isOwningSide" => true,
            "isInverseSide" => false
        ], $classMetadata->getFieldMapping('embeddedPhonenumber'));

        self::assertNULL($classMetadata->getAssociationTargetClass('embeddedPhonenumber'));
    }

    protected function loadMetadata($className): ClassMetadata
    {
        $mappingDriver = $this->_loadDriver();
        $class = new ClassMetadata($className);
        $mappingDriver->loadMetadataForClass($className, $class);

        return $class;
    }

    protected function _loadDriver()
    {
        $reader = new AnnotationReader();
        return new AnnotationDriver($reader);
    }
}

/**
 * @ODM\Document
 */
class EmbedWithoutTargetDocument
{
    /** @ODM\Id */
    public $id;

    /** @ODM\EmbedOne( 
      * discriminatorField="discr", 
      * discriminatorMap={"home"=HomePhonenumber::class} ) 
      */
    public $embeddedPhonenumber;
}

/**
 * @ODM\Document
 */
class HomePhonenumber
{
    /** @ODM\Id */
    public $id;

    /** @ODM\Field(type="string") */
    public $number;
}

Expected behavior

public function getAssociationTargetClass($assocName) : ?string
returns STRING or NULL

@malarzm malarzm added the Bug label Feb 19, 2019
@malarzm malarzm added this to the 2.0.0-Beta2 milestone Feb 19, 2019
@malarzm
Copy link
Member

malarzm commented Feb 19, 2019

I believe we could treat the only entry discriminatorMap as it'd be defined as targetClass. @alcaeus thoughts on this?

Offhand, @Dragonqos what's the use case for an embedded document with one entry? Is it being prepared for the future extension?

@Dragonqos
Copy link
Author

One entry in discriminatorMap is just for example for test. My application has at least 5 embedded document.

@alcaeus
Copy link
Member

alcaeus commented Feb 20, 2019

@Dragonqos thanks for providing a test case. You are correct, an association without a target document is perfectly valid, so we should fix the wrong typehint.

@Dragonqos
Copy link
Author

Hope it will be fixed asap)

@Dragonqos
Copy link
Author

Any updates on this?

@malarzm
Copy link
Member

malarzm commented Mar 21, 2019

@Dragonqos I've just submitted #1983 with a fix

alcaeus added a commit that referenced this issue Mar 29, 2019
Allow returning null from getAssociationTargetClass
@alcaeus
Copy link
Member

alcaeus commented Mar 29, 2019

#1983 was merged, closing here. Thanks for bringing this up @Dragonqos!

@alcaeus alcaeus closed this as completed Mar 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants