0
respostas

Converter dado da tabela para objeto de valor

Estou com uma dúvida e não consegui encontrar uma solução na documentação do Doctrine. Na aula 4, do curso de PHP e Clean Architecture foi proposto o desafio de implementar um novo repositório usando Doctrine. Criei o arquivo de mapeamento em XML para a entidade Student, como pede na documentação. Até consegui testar a inserção de um aluno. O problema ocorre quando vou listar os alunos, para conferir se foi cadastrado corretamente.

PHP Fatal error:  Uncaught TypeError: Typed property App\Arch\Domain\Student\Student::$email must be an instance of App\Arch\Domain\Email, string used in /home/christianwd/workspace/alura/php-clean-architecture/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionPropertyBase.php:62

Até onde entendi, o erro acima ocorre porque o Doctrine tenta atribuir o valor string em uma propriedade tipada como Email, que é uma classe, um ValueObject. Como posso contornar esse problema, existe alguma maneira de converter o valor para o tipo necessário?

Minha classe Student está assim:

class Student
{
    private Cpf $cpf;
    private string $name;
    private Email $email;
    /**
     * @var Phone[]
     */
    private array $phones;

    private function __construct(
        Cpf $cpf,
        string $name,
        Email $email
    ) {
        $this->cpf = $cpf;
        $this->name = $name;
        $this->email = $email;
    }

    public static function withCpfEmailAndName(string $cpf, string $email, string $name): self
    {
        return new static(
            new Cpf($cpf),
            $name,
            new Email($email)
        );
    }

    public function addPhone(string $ddd, string $number): self
    {
        $this->phones[] = new Phone($ddd, $number);

        return $this;
    }

    public function getCpf(): string
    {
        return (string) $this->cpf;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getEmail(): string
    {
        return (string) $this->email;
    }

    /**
     * @return Phone[]
     */
    public function getPhones(): array
    {
        return $this->phones;
    }
}

O mapeamento em XML ficou assim:

// filename: App.Arch.Domain.Student.Student.dcm
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
                    https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="App\Arch\Domain\Student\Student" table="students">
        <id name="cpf" type="string" length="11"></id>
        <field name="email" type="string" length="60" unique="true" />
        <field name="name" type="string" length="100" />
    </entity>

</doctrine-mapping>