phpstan-doctrine icon indicating copy to clipboard operation
phpstan-doctrine copied to clipboard

Use DTO in a query builder

Open asispts opened this issue 1 year ago • 7 comments

Can the following code work without manually defining the return type, i.e adding /** @var UserDto[] */?

final class Repository
{
    public function __construct(
        private EntityManagerInterface $em
    ) {
    }

    /**
     * @return UserDto[]
     */
    public function findAll(): array
    {
        $qb = $this->em->createQueryBuilder()
            ->select(\sprintf('NEW %s(u.id, u.email)', UserDto::class))
            ->from(User::class, 'u')
            ->getQuery();

        /** @var UserDto[] */
        return $qb->getResult();
    }

    public function findByEmail(string $email): ?UserDto
    {
        $qb = $this->em->createQueryBuilder()
            ->select(\sprintf('NEW %s(u.id, u.email)', UserDto::class))
            ->from(User::class, 'u')
            ->where('u.email = :email')
            ->setParameter('email', $email)
            ->getQuery();

        /** @var UserDto|null */
        return $qb->getOneOrNullResult();
    }
}

asispts avatar Mar 22 '24 10:03 asispts

This should work fine. Have you configured objectManagerLoader (see README)?

ondrejmirtes avatar Mar 22 '24 10:03 ondrejmirtes

Readme states that NEW should work. Are you suggesting it does not?

Most DQL features are supported, including GROUP BY, DISTINCT, all flavors of JOIN, arithmetic expressions, functions, aggregations, NEW, etc.

janedbal avatar Mar 22 '24 10:03 janedbal

Yeah, I've added tests/object-manager.php. I still got an error

Method Repository::findByEmail() should return UserDto|null but returns mixed.

The first method should have no issue.

asispts avatar Mar 22 '24 10:03 asispts

Are you on latest versions of PHPStan and phpstan-doctrine?

ondrejmirtes avatar Mar 22 '24 11:03 ondrejmirtes

Yeah, tested on the latest version

phpstan: 1.10.64
phpstan-doctrine: 1.3.64

asispts avatar Mar 22 '24 11:03 asispts

There are many test cases for this scenario starting on this line https://github.com/phpstan/phpstan-doctrine/blob/0871900872abde0d93e4bbd8c681a9985bcd927e/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php#L942

I guess you might have to reproduce your issue either in tests here (probably in QueryBuilderGetQueryDynamicReturnTypeExtensionTest), or in a separate repository.

ondrejmirtes avatar Mar 22 '24 11:03 ondrejmirtes

I'll try that

asispts avatar Mar 22 '24 14:03 asispts