Skip to content

Custom types are not correctly transformered for embedded documents #2212

Open
@o10g

Description

@o10g

Bug Report

Q A
BC Break no
Version 2.1.1

Summary

Let's say we have User document with embedded document Identities. Some of fields in Identities has to be encrypted in the database. To achieve it, the new type was registered and assigned to the appropriate fields.
In the repository class we need to filter by the encrypted field while in code we have it decrypted.
So query builder is used this way:

$passportNumber = 'FB555555';
$qb = $this->dm->createQueryBuilder(User::class);
$qb->field('identifiers.passportNumber')->equals(new PassportNumber($passportNumber));
$qb->getQuery()->toArray();

But the query doesn't find anything because PassportNumberType::convertToDatabaseValue is never called.

Current behavior

PassportNumber is not encrypted because PassportNumberType::convertToDatabaseValue is never called.
It is never called, because \Doctrine\ODM\MongoDB\Persisters\DocumentPersister::convertToDatabaseValue can't see the field in the class as this line of code $this->class->hasField($fieldName) returns false.

How to reproduce

Here is a small code samples (namespaces, use statement and other unnecessary code is omitted):

/**
 * @MongoDB\Document()
 */
class User
{
    /**
     * @MongoDB\Id
     */
    private $id;

    /**
     * @var Identifiers|null
     * @MongoDB\EmbedOne(targetDocument="App\Document\User\Identities")
     */
    private $identities;
}

/**
 * @MongoDB\EmbeddedDocument
 */
class Identifiers
{
    /**
     * @MongoDB\Field(type="passport_number", name="passport_number")
     */
    private PassportNumber $passportNumber;
}



class PassportNumberType extends Type
{
    public function convertToPHPValue($value): PassportNumber
    {
        return new PassportNumber(str_replace('encrypted_', 'decrypted_', $value));
    }

    public function convertToDatabaseValue($value): string
    {
        /** @var $value PassportNumber */
        return 'encrypted_' . $value->value();
    }
}

class PassportNumber
{
    private ?string $id;

    public function __construct(?string $id)
    {
        $this->id = $id;
    }

    public function value(): ?string
    {
        return $this->id;
    }
}

Expected behavior

The value for the custom type in the embedded documents should be processed in the way it is defined in the custom type definition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions