phpstan / phpstan-doctrine Goto Github PK
View Code? Open in Web Editor NEWDoctrine extensions for PHPStan
License: MIT License
Doctrine extensions for PHPStan
License: MIT License
Since I updated to the latest version I'm getting this error (but strangely it's only at 1 place in my entire project):
Unable to resolve the template type T in call to method Doctrine\ORM\EntityManager::getRepository()
The line that triggers it:
$repository = $entityManager->getRepository(ApiKeyProjection::class);
Any way i could get rid of such errors? am i missing some configuration step?
43 Call to an undefined method Doctrine\ORM\EntityRepository<x\Entity\Operation>::findFiltered(). 46 Call to an undefined method Doctrine\ORM\EntityRepository<x\Entity\Customer>::findWithFreeFunds(). 71 Call to an undefined method Doctrine\ORM\EntityRepository<x\Entity\BgzDocument>::getFilteredQueryBuilder().
I'm probably misunderstanding the README for this plugin, but I have this:
namespace AquaSafeModel\Repository;
use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
abstract class EntityRepository extends DoctrineEntityRepository implements EntityRepositoryInterface
{
Then I have this
namespace AquaSafeModel\Repository;
use AquaSafeModel\Collection\EntityCollection;
use AquaSafeModel\Entity\Process;
class ProcessRepository extends EntityRepository
{
/** @return Process */
public function find($id, $lockMode = null, $lockVersion = null): ?Process
{
return parent::find($id);
}
But I still get this from PHPStan:
108 Call to an undefined method AquaSafeModel\Entity\BaseEntity::getCompetencies().
I was expecting no output.
Of course, getCompetencies()
exists on Process, not BaseEntity.
For reference, here's my phpstan.neon
:
parameters:
doctrine:
repositoryClass: AquaSafeModel\Repository\EntityRepository
includes:
- vendor/phpstan/phpstan-doctrine/extension.neon
I see in the README that "This extension does not yet support custom repositoryClass specified for each entity class." but I'm thinking that means in the ORM annotations, not my case of subclassing above...
I cannot find a way to satisfy the case
Property App\User::$stats type mapping mismatch: database can contain App\UserStats|null but property expects App\UserStats.
I have the following mapping :
<?php
class User
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var UserStats
*
* @ORM\OneToOne(targetEntity="App\UserStats", mappedBy="user")
*/
protected $stats;
// ... other properties
}
class UserStats
{
/**
* @var User
*
* @ORM\Id
* @ORM\OneToOne(targetEntity="App\User", inversedBy="stats")
*/
private $user;
// ... other properties
}
If I add @ORM\JoinColumn(nullable=false)
on User::$stats
property then Doctrine is broken because JoinColumn
annotation is expected on the owning side of the one to one relationship.
So I'm stuck with this case, because I can't explain to phpstan that my property isn't nullable :/
Property MyEntity::$creationTime type
mapping mismatch: database can contain DateTimeImmutable but property
expects Safe\DateTimeImmutable.
Safe\DateTimeImmutable
extends \DateTimeImmutable
This is a valid notation for getRepository
, but it's not managed.
I have custom Expr class extended from Doctrine\ORM\Query\Expr
I think, PHPStan doesn't know about that class and trigger error
In ExpressionBuilderDynamicReturnTypeExtension.php line 67:
Attempted to call an undefined method named "myCustomMethod" of class "Doctrine\ORM\Query\Expr".
is it because Doctrine\ORM\Query\Expr
harcoded in getClass() method?
How to fix that?
phpstan-doctrine could check if a field's typehint matches Doctrine's metadata.
In the following example, the plugin could emit a warning telling that int
does not match string
:
/**
* @var int
*
* @Column(type="string")
*/
private $var;
In the following examples, the plugin could emit a warning telling that the field is nullable:
/**
* @var int // Should be nullable
*
* @Column(type="integer", nullable=true)
*/
private $var;
/**
* @var Foo // Should be nullable
*
* @OneToOne(targetEntity="Foo")
I'm looking at this primarily as a security feature. Ensuring that prepared statements are used correctly by binding the value or parameter accordingly.
For example:
This is the preferred way of doing a native query:
$sql = <<<SQL
SELECT u.*
FROM `user` AS u
WHERE u.email = :email
SQL;
$em = $this->getEntityManager();
$connection = $em->getConnection();
$statement = $connection->prepare($sql);
$statement->bindValue('email', $email->toString());
$statement->execute();
return $statement->fetchAll();
As opposed to not binding a value:
$sql = <<<SQL
SELECT u.*
FROM `user` AS u
WHERE u.email = {$email->toString()}
SQL;
$em = $this->getEntityManager();
$connection = $em->getConnection();
$statement = $connection->prepare($sql);
$statement->execute();
return $statement->fetchAll();
The same should apply when using the ResultSetMappingBuilder
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata(User::class, 'u');
$query = $this->_em->createNativeQuery($sql, $rsm);
$query->setParameters([
'email' => $email->toString(),
]);
return $query->getResult();
As well as when using the QueryBuilder
:
$qb = $this->createQueryBuilder('u')
->where('u.email = :email')
->setParameter('email', $email->toString())
->getQuery();
return $qb->execute();
This PHP code part is valid:
$user = $this->getDoctrine()->getRepository(User::class)->find(
$this->request->query->get('id')
);
$this->getDoctrine()
return a ManagerRegistry
instance.
But the final $user
does not seems to be typed:
Call to an undefined method object::getUsername().
Using the EntityManagerInterface
directly make things working.
As the title says.
Maybe the package should be split to phpstan-doctrine-collections and phpstan-doctrine-orm?
ObjectManagerFindDynamicReturnTypeExtension
sets the return type of getReference()
and getPartialReference()
to nullable. However, these methods never return null.
With this PHP code:
$qb = $this->invoiceRepository->createQueryBuilder('i')
->select('i, c, ba')
->innerJoin('i.customer', 'c', Expr\Join::WITH, 'c.automaticPaymentMethod = :automatic_payment_method')
->innerJoin('c.bankAccount', 'ba', Expr\Join::WITH, 'ba.activated = :activated AND ba.mandateSigned = :mandateSigned AND ba.mandateSignedDate IS NOT NULL')
foreach ($invoices as $invoice) {
$customer = $invoice->getCustomer();
$bankAccount = $customer->getBankAccount();
$bankAccount->setFirstDebit(true);
$this->persist($bankAccount);
}
;
I'll have this error:
Parameter #1 $object of method Doctrine\Common\Persistence\ObjectManagerDecorator::persist() expects object, AppBundle\Entity\BankAccount|null given.
But this is not true
as innerJoin
will drop customers without a bank account. Am I right?
If I'm right, checking if $bankAccount
in this case is overkill and will never match.
In my project I have multiple objectmanagers.
This currently leads to errors like:
Internal error: The class 'X' was not found in the chain configured namespaces ...
because its using the wrong objectManager (the one returned in object-manager.php
) for some entities.
Hi, is it feasible for the plugin to detect Doctrine's behavior with respect to floats being handled as a string? Example:
/**
* @Entity
*/
class Demo
{
/** @Column(type="decimal", precision=10, scale=2) */
private $price;
/**
* Set price.
*
* @param string $number
*
* @return Demo
*/
public function setPrice($number)
{
$this->price = $number;
return $this;
}
}
$demo = new Demo();
$demo->setPrice(0.0);
Error output: Parameter #1 $number of method Demo::setPrice() expects string, float given
Note: The Doctrine orm: generate-entities console command generates the method with its parameter as string.
Thanks.
As the PoC of #18 seems stalled to resolve custom repository classes based on the mapping, a simpler solution could be implemented in the meantime (even though it is not as good for DX as it requires more work). Instead of configuring a single repository class used by all entities, we could configure a mapping of entity classes to their repositories (the existing option can of course still be kept for the fallback for entities not present in the map):
parameters:
doctrine:
customRepositories:
MyApp\Entity\User: MyApp\Doctrine\UserRepository
MyApp\Entity\Team: MyApp\Doctrine\TeamRepository
repositoryClass: MyApp\Doctrine\BetterEntityRepository
What do you think about that solution ?
Is ODM supported? I guess not. Do you plan to add the support?
In some repositories I have some custom functions named like findOneByX
Example:
class ReviewRepository
{
public function findOneByReviewConfigAndId(...) { }
}
Seems that is not working properly:
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line someClass.php
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
209 Call to method X\ReviewRepository<X\Entity\Review>::findOneByReviewConfigAndId() - entity X\Entity\Review does not have a field named
$reviewConfigAndId.
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hey, I just tried to enable these rules and get this crash:
In Autowiring.php line 190:
Service 'rules.56' (type of PHPStan\Rules\Doctrine\ORM\DqlRule): Service of
type PHPStan\Type\Doctrine\ObjectMetadataResolver needed by $objectMetadat
aResolver in __construct() not found. Did you register it in configuration
file?
analyse [--paths-file PATHS-FILE] [-c|--configuration CONFIGURATION] [-l|--level LEVEL] [--no-progress] [--debug] [-a|--autoload-file AUTOLOAD-FILE] [--error-format ERROR-FORMAT] [--memory-limit MEMORY-LIMIT] [--] [<paths>...]
I have these things in composer.json
"phpstan/phpstan": "0.11.2",
"phpstan/phpstan-doctrine": "0.11.1",
"phpstan/phpstan-mockery": "0.11.0",
"phpstan/phpstan-nette": "0.11.0",
"thecodingmachine/phpstan-safe-rule": "0.1.2"
and dev-master nette.
It should be noted that I don't use ORM but ODM.
Hi,
I'we just noticed that when using 'phpstan-doctrine' extension, there is a weird behaviour
/bug
with findOneBy
methods: doesnt report error on calling non-existing method.
As a proof of concept (not able to share project I work on): https://github.com/msvrtan/phpstan-bug`
When calling a method findOneByUuid
, it doesnt understand it's getting a Customer|null
back but when calling findXOneByUuid
it does: https://travis-ci.com/msvrtan/phpstan-bug/jobs/183766249
I'we also created a PR msvrtan/phpstan-bug#2 that fails https://travis-ci.com/msvrtan/phpstan-bug/builds/103870199 once I remove that Repository does extend EntityRepository...
On the other hand, if I do 'inject' repository as
/* @var \Doctrine\ORM\EntityRepository<\Customer\Customer> */
private $customerRepository;
it does report ...
I know this would be a quick 'fix' to go thru codebase and add those docblocks but it still feels like unexpected behaviour
Hi,
I got an issue (stack trace at the end):
Uncaught PHPStan\ShouldNotHappenException: Please provide the "objectManagerLoader" setting for magic repository Doctrine\ORM\EntityRepository::findOneBy() RepositoryMethodCallRule.php:68
This happens when I have following property and findOneByNumber method using findOneBy method of EntityRepository. The EntityRepository is subclass of Doctrine\ORM\EntityRepository.
/** @var \Kdyby\Doctrine\EntityRepository|\Doctrine\ORM\EntityRepository<Invoice> */
private $repository;
/**
* OrderRepository constructor.
* @param \Kdyby\Doctrine\EntityManager $em
*/
public function __construct(\Kdyby\Doctrine\EntityManager $em)
{
$this->em = $em;
$this->repository = $em->getRepository(Invoice::class);
}
/**
* @param int $number
*
* @return null|Invoice
*/
public function findOneByNumber($number)
{
return $this->repository->findOneBy(['number' => $number]);
}
Stack trace:
#0 C:\Web\Apps\zvz-new\home\libs\vendor\phpstan\phpstan\src\Analyser\Analyser.php(154): PHPStan\Rules\Doctrine\ORM\RepositoryMethodCallRule->processNode(Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\Scope))
#1 C:\Web\Apps\zvz-new\home\libs\vendor\phpstan\phpstan\src\Analyser\NodeScopeResolver.php(1698): PHPStan\Analyser\Analyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\Scope))
#2 C:\Web\Apps\zvz-new\home\libs\vendor\phpstan\phpstan\src\Analyser\NodeScopeResolver.php(1146): PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression(Object(Closure), Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\Scope), Object(PHPSta in C:\Web\Apps\zvz-new\home\libs\vendor\phpstan\phpstan-doctrine\src\Rules\Doctrine\ORM\RepositoryMethodCallRule.php on line 68
I can provide more info if needed.
Thanks!
Hi, on my project the extension works great, except for findOneBy*
methods-like.
I was unable to reproduce the bug within this repository, but I've created a dedicated one that shows the issue:
https://github.com/Slamdunk/phpstan-doctrine-bug
And this is the output of the build:
https://travis-ci.org/Slamdunk/phpstan-doctrine-bug/builds/638002155#L238-L241
I expect the error on findOneByXyz
but not on findOneByUsername
.
I've committed both the composer.json and composer.lock so you can deep down the versions, which are:
When the doctrine plugin is enabled, I get an error with when analysing this code in level 7:
<?php
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
class test
{
/**
* @var test[]&Collection&Selectable
*/
private $items;
/**
* @return test[]&Collection&Selectable
*/
public function getItems(): Collection
{
return $this->items;
}
}
The error:
Method test::getItems() with return type void returns *NEVER* but should not return anything.
I'd like to open new issue here, but it was discussed after closing this issue: #51
Looks like this plugin depends on the doctrine/orm although it definitely is useful for doctrine/odm as also stated in readme (Also supports Doctrine ODM.).
The fact is that it really works well for ODM project and I could delete a few ignore patterns. But I had to add doctrine/orm to my composer.json to make it work. Which is a shame.
I think it would not harm if this package added doctrine/orm as one of its own dependencies.
Is it possible to check Doctrine Annotations or exists some extension for it?
Hi,
I have an abstract class BasicFile
which is used as a Discriminator with Single Table Inheritance.
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/inheritance-mapping.html#single-table-inheritance
<?php
/**
* @ORM\Table(name="files")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"data" = "DataFile"})
*/
abstract class BasicFile {}
And my entity:
<?php
/*
* @ORM\Entity
*/
class DataFile extends BasicFile {}
When I initiate a method on the DataFile
entity, which is not available on the BasicFile
class, i get an error stating the method does not exist.
<?php
$dataFile = new DataFile();
$dataFile->setName('xxx');
Call to an undefined method App\Entity\BasicFile::setName().
Using:
Symfony 5.0.1
doctrine/orm: 2.7.0
phpstan-shim: 0.11.19
phpstan-doctrine: 0.11.6
Hi, this feature request follows #65 (comment) and #65 (comment).
Since Symfony 4.0, it is possible to define Repositories as as Service by extending from ServiceEntityRepository
like this:
<?php
namespace App\Repository\User;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* @method User|null find($id, $lockMode = null, $lockVersion = null)
* @method User|null findOneBy(array $criteria, array $orderBy = null)
* @method User[] findAll()
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, User::class);
}
}
And we can accessing it directly from services constructor or constroller's actions with type hinting:
<?php
namespace App\Controller;
use App\Repository\User\UserRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends AbstractController
{
/**
* @Route("/", name="home")
*/
public function index(UserRepository $userRepository)
{
$user = $userRepository->find(123);
$user->getFooBar();
}
}
But there are some issues.
If we use this phpstan extension, calling whatever method on $user
that does not exist on App\Entity\User
will not fails.
If we don't use it, $userRepository->find*
methods will works correctly (due to @method
annotations, but they are needed for PHPStorm too) and we will see the error Cannot call method getFooBar() on App\Entity\User|null.
As said in the issue, we can use /** @var App\Repository\UserRepository<App\Entity\User> */
to make phpstan works, but:
UserRepository
, phpstan should be able to works with itTo make it work, this extension (or the Symfony extension?) should:
ServiceEntityRepository
In fact, I think it would be better if the repositories detection is part of Symfony extension. Since the Symfony extension can access the Symfony container, we can find services tagged with doctrine.repository_service
and then use them:
What do you think?
Thanks! :)
------ --------------------------------------------------------------
Line Doctrine/Expr/PartialSelect.php
------ --------------------------------------------------------------
Internal error: Class 'parent' not found
Run PHPStan with --debug option and post the stack trace to:
https://github.com/phpstan/phpstan/issues/new
------ --------------------------------------------------------------
PHP Fatal error: Uncaught Error: Class 'parent' not found in /.../vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php:52
Stack trace:
#0 /.../vendor/phpstan/phpstan/src/Analyser/Scope.php(1498): PHPStan\Type\Doctrine\QueryBuilder\Expr\NewExprDynamicReturnTypeExtension->getTypeFromStaticMethodCall(Object(PHPStan\Reflection\Php\PhpMethodReflection), Object(PhpParser\Node\Expr\StaticCall), Object(PHPStan\Analyser\Scope))
#1 /.../vendor/phpstan/phpstan/src/Analyser/Scope.php(372): PHPStan\Analyser\Scope->resolveType(Object(PhpParser\Node\Expr\StaticCall))
#2 /.../vendor/phpstan/phpstan/src/Rules/FunctionCallParametersCheck.php(98): PHPStan\Analyser\Scope->getType(Object(PhpParser\Node\Expr\StaticCall))
#3 /.../vendor/phpstan/phpstan/src/Rules/Methods/CallStaticMethodsRule.php(265): PHPStan\Rules\FunctionCallParamet in /.../vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php on line 52
Is this kind of error handable ?
I want to use phpstan in laravel project with level 0 and need to remove PHPStan\Rules\Methods\CallStaticMethodsRule
, how can I create the same config as level 0, but without this rule?
I tried to copy whole conf/
dir and tried only to remove this rules and pass this config to -c, but I still get exceptions.
Hello,
It seems that query builders built with \Doctrine\ORM\EntityRepository::createQueryBuilder
are not validating DQL, only ones built with \Doctrine\ORM\EntityManagerInterface::createQueryBuilder
.
I'm trying to analyse a Symfony 4 project where all queryBuilder are created within repository classes with $this->createQueryBuilder
.
Am I missing something ?
Thanks
I have this code:
$repository = $this->documentManager->getRepository(Document::class);
assert($repository instanceof \Doctrine\ODM\MongoDB\Repository\DefaultGridFSRepository);
The assert passes but I get this PhpStan error:
Instanceof between
Doctrine\ORM\EntityRepository<MyCompany\ODM\File\Document> and
Doctrine\ODM\MongoDB\Repository\DefaultGridFSRepository will always
evaluate to false.
Note that the document for which I am getting a repository is not a standard document but rather GridFS file document which has some specifics.
The code snippet is taken from here.
PHP Fatal error: Uncaught TypeError: Argument 5 passed to PHPStan\Analyser\Scope::enterClassMethod() must be of the type string or null, boolean given, called in vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php on line 180 and defined in phar://vendor/phpstan/phpstan-shim/phpstan.phar/src/Analyser/Scope.php:1265
Stack trace:
#0 vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php(180): PHPStan\Analyser\Scope->enterClassMethod(Object(PhpParser\Node\Stmt\ClassMethod), Array, NULL, NULL, false, false, false)
#1 vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php(108): PHPStan\Type\Doctrine\QueryBuilder\QueryBuilderMethodDynamicReturnTypeExtension->findQueryBuilderTypesInCalledMetho in phar://vendor/phpstan/phpstan-shim/phpstan.phar/src/Analyser/Scope.php on line 1265`
This:
$dnsDomain = $dnsEntityManager->getRepository('PowerDNSBundle:PowerDNSDomain')->findOneBy([
'ownerId' => $user->getId()
]);
if (!$dnsDomain) {
throw new \RuntimeException("Unable to find DNS domain of user {$user->getUsername()}");
}
$client->request('DELETE', $this->getUrl('api_delete_dns', [
'domain' => $dnsDomain->getId(),
]));
Should work because I check if $dnsDomain
is not null. But I have:
Call to an undefined method object::getId().
Certainly because only the find
method is managed.
Hi,
I used the new version of Symfony 5, and I want to check my code with phpstan 0.12.2 and phpstan-doctrine 0.12.2.
I have many error in this version, for example :
Line Entity/User.php
18 Property App\Entity\User::$id has no typehint specified.
23 Property App\Entity\User::$email has no typehint specified.
28 Property App\Entity\User::$name has no typehint specified.
33 Property App\Entity\User::$password has no typehint specified.
38 Property App\Entity\User::$enable has no typehint specified.
43 Property App\Entity\User::$notification has no typehint specified.
And my Entity
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=500)
*/
private $email;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="string", length=75)
*/
private $password;
/**
* @ORM\Column(type="boolean")
*/
private $enable;
/**
* @ORM\Column(type="boolean")
*/
private $notification = false;
}
I used phpstan/extension-installer (I will try before with file add manually in phpstan.neon /var/www/html/vendor/phpstan/phpstan-doctrine/extension.neon and /var/www/html/vendor/phpstan/phpstan-doctrine/rules.neon)
In the previous version I haven't this error type without @var in my code.
Can you help me ?
Thanks
Hello, although I define an object-manager, the plugin cannot correctly process the entity aliases.
Example:
$entityManager->getRepository('App\Entity\User'); // works
$entityManager->getRepository('Entity:User'); // error unknown class Entity:User
Thanks
I have the following code:
/**
* @param class-string<MyInterface> $entityClass
*/
public function test($entityClass)
{
$entityRepository = $this->entityManager->getRepository($entityClass);
}
This will throw class_exists error as it tries to call class_exists on MyInterface.
Could you please tag a version with the support for PHPStan 0.7? Thanks!
And congrats on the release!
In a nutshell, this PHP class:
use Doctrine\ORM\Decorator\EntityManagerDecorator;
use PowerDNSBundle\Doctrine\ORM\PowerDNSEntityManager;
use PowerDNSBundle\Entity\PowerDNSDomain;
class DnsManager extends EntityManagerDecorator
{
/**
* @var ObjectRepository
*/
private $domainRepository;
public function __construct(PowerDNSEntityManager $wrapped)
{
parent::__construct($wrapped);
$this->domainRepository = $this->getRepository(PowerDNSDomain::class);
}
public function addDomainIfNotExists($name, User $user, $ipV4 = null, $ipV6 = null, $checkDNS = true)
{
$nameCanonical = \idn_to_ascii($name);
$domain = $this->domainRepository->findOneBy(['name' => $nameCanonical]);
if (!$domain) {
$domain = new PowerDNSDomain();
$domain->setName($name);
$domain->setOwnerId($user->getId());
$this->saveDomain($domain, $ipV4, $ipV6, $checkDNS);
}
return $domain;
}
}
Produces:
------ ----------------------------------------------------------------------
Line src/AppBundle/Manager/DnsManager.php
------ ----------------------------------------------------------------------
170 Method AppBundle\Manager\DnsManager::addDomainIfNotExists() should
return PowerDNSBundle\Entity\PowerDNSDomain but returns object.
Replacing the line by $domain = $this->getRepository(PowerDNSDomain::class)->findOneBy(['name' => $nameCanonical]);
directly "solve" the issue.
It seems the property assignation of repositories is not handled by the extension.
There should be a DynamicReturnType for Doctrine\Common\Annotations\Reader
. The getClassAnnotation
, getMethodAnnotation
and getPropertyAnnotation
can only return the requested annotation or null
.
What happens:
If I have a repository with a method findBySomething
and the entity doesn't have the property $something
I get an error about the missing field when I try to use this method.
E.g.
Call to method App\Repository\ThingsRepository<App\Entity\Thing>::findBySomething() - entity App\Entity\Thing does not have a field named $something.
What I expect:
No error as the method is present
If I'm using Phive or the PHPStan shim to install PHPStan, how do I install phpstan-doctrine
which doesn't seem to provide a PHAR and still requires phpstan/phpstan
when installed through Composer?
We are using the ResolveTargetEntityListener of doctrine to allow using interfaces and it allows us to overwrite entities without using mapping superclass behaviour e.g.:
<many-to-one
field="directory"
target-entity="Sulu\Bundle\MyBundle\Model\DirectoryInterface"
inversed-by="translations"
>
<join-column name="directoryNo" referenced-column-name="no" on-delete="CASCADE" nullable="false"/>
</many-to-one>
/**
* @var DirectoryInterface
*/
private $directory;
This ends currently with:
Sulu\Bundle\MyBundle\Model\DirectoryTranslation::$directory type mapping mismatch: property can contain Sulu\Bundle\MyBundle\Model\DirectoryInterface but database expects Sulu\Bundle\MyBundle\Model\Directory.
It would be awesome if it would take the Interface instead of the resolved entity so that phpstan would not error for resolved.
This is for Doctrine ORM 2.7.0
In a Repository with the following:
$query = $em->createQuery('SELECT u FROM ForumUser u WHERE (u.username = :name OR u.username = :name2) AND u.id = :id');
$query->setParameters(array(
'name' => 'Bob',
'name2' => 'Alice',
'id' => 321,
));
$users = $query->getResult();
According to the method, this should be allowed:
* @param ArrayCollection|mixed[] $parameters
But instead, the following error is generated:
Parameter #1 $parameters of method
Doctrine\ORM\AbstractQuery::setParameters() expects
Doctrine\Common\Collections\ArrayCollection&iterable, array<string,
string> given.
In Symfony's Doctrine bridge you 'must' inject Doctrine via the Symfony\Bridge\Doctrine\RegistryInterface
:
/** @var UserRepository */
private $userRepository;
public function __construct(RegistryInterface $registry)
{
$this->userRepository = $registry->getRepository(User::class);
}
This code fails however with:
Property xxx::$userRepository (xxx\UserRepository) does not accept Doctrine\Common\Persistence\ObjectRepository.
Level 5 gives me such warnings: Parameter #4 $condition of method Doctrine\ORM\QueryBuilder::leftJoin() expects string|null, Doctrine\ORM\Query\Expr\Andx given
That happens when you dont use simple string conditions like this ->leftJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
while joining but when using Expr builder instead. QueryBuilder's join functions document that argument as string|null but it also takes Expr
Do you think I should mark this warning as ignored?
I have several errors in the following example, none is detected by phpstan-doctrine currently.
phpstan/phpstan 0.12.4
phpstan/phpstan-doctrine 0.12.8
octrine/annotations v1.8.0
doctrine/orm v2.6.6
/**
* @ORM\Entity(repositoryClass="EmailRepositoryInterface")
* @ORM\InheritanceType("SINGLsdTABLE")
* @ORM\DiscriminatorColumn(namse="email_type", type="string")
* @ORM\DiscriminatorsadMap({
* "default": "Full\NameSpace\Default",
* "device_email": "Full\NameSpace\DeviceEmail"
* })
*/
/**
*
* @ORM\Column(type="sting")
*/
parameters:
autoload_files:
- bootstrap/autoload.php
includes:
- vendor/phpstan/phpstan-doctrine/extension.neon
Are magic methods not supported or is there some configuration option(s) I missed?
$em = $this->managerRegistry->getManager();
$travelDestinationRepository = $em->getRepository(TravelDestination::class);
$childDestinationIdsQueryBuilder = $travelDestinationRepository->getChildrenQueryBuilder($parentDestinationIds);
Line src/AppBundle/ApiPlatform/Doctrine/Orm/Filter/EventLocationFilter.php
99 Call to an undefined method
Doctrine\Common\Persistence\ObjectRepository::getChildrenQueryBuilder()
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.