Doctrine extensions for PHPStan

Overview

Doctrine extensions for PHPStan

Build Latest Stable Version License

This extension provides following features:

  • DQL validation for parse errors, unknown entity classes and unknown persistent fields. QueryBuilder validation is also supported.
  • Recognizes magic findBy*, findOneBy* and countBy* methods on EntityRepository.
  • Validates entity fields in repository findBy, findBy*, findOneBy, findOneBy*, count and countBy* method calls.
  • Interprets EntityRepository<MyEntity> correctly in phpDocs for further type inference of methods called on the repository.
  • Provides correct return for Doctrine\ORM\EntityManager::getRepository().
  • Provides correct return type for Doctrine\ORM\EntityManager::find, getReference and getPartialReference when Foo::class entity class name is provided as the first argument
  • Adds missing matching method on Doctrine\Common\Collections\Collection. This can be turned off by setting parameters.doctrine.allCollectionsSelectable to false.
  • Also supports Doctrine ODM.
  • Analysis of discrepancies between entity column types and property field types.

Installation

To use this extension, require it in Composer:

composer require --dev phpstan/phpstan-doctrine

If you also install phpstan/extension-installer then you're all set!

Manual installation

If you don't want to use phpstan/extension-installer, include extension.neon in your project's PHPStan config:

includes:
    - vendor/phpstan/phpstan-doctrine/extension.neon

If you're interested in DQL/QueryBuilder validation, include also rules.neon (you will also need to provide the objectManagerLoader, see below):

includes:
    - vendor/phpstan/phpstan-doctrine/rules.neon

Configuration

If your repositories have a common base class, you can configure it in your phpstan.neon and PHPStan will see additional methods you define in it:

parameters:
	doctrine:
		ormRepositoryClass: MyApp\Doctrine\BetterEntityRepository
		odmRepositoryClass: MyApp\Doctrine\BetterDocumentRepository

You can opt in for more advanced analysis by providing the object manager from your own application. This will enable DQL validation:

parameters:
	doctrine:
		objectManagerLoader: tests/object-manager.php

Example for Symfony 4:

// tests/object-manager.php

use App\Kernel;

require __DIR__ . '/../config/bootstrap.php';
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$kernel->boot();
return $kernel->getContainer()->get('doctrine')->getManager();

Example for Symfony 5:

// tests/object-manager.php

use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;

require __DIR__ . '/../vendor/autoload.php';

(new Dotenv())->bootEnv(__DIR__ . '/../.env');

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$kernel->boot();
return $kernel->getContainer()->get('doctrine')->getManager();

Custom types

If your application uses custom Doctrine types, you can write your own type descriptors to analyse them properly. Type descriptors implement the interface PHPStan\Type\Doctrine\Descriptors\DoctrineTypeDescriptor which looks like this:

<?php

public function getType(): string;

public function getWritableToPropertyType(): Type;

public function getWritableToDatabaseType(): Type;
  • The getType() method simply returns the class name of the custom type.
  • The getWritableToPropertyType() method returns the PHPStan type that the custom type will write into the entity's property field. Basically it is the return type of the custom type's convertToPHPValue() method.
  • The getWritableToDatabaseType() method returns the PHPStan type that can be written from the entity's property field into the custom type. Again, basically it's the allowed type for the custom type's convertToDatabaseValue()'s first argument.

Generally, at least for most of Doctrine's native types, these last two methods will return the same type, but it is not always the case. One example would be the datetime type, which allows you to set any \DateTimeInterface into to property field, but will always contain the \DateTime type when loaded from the database.

Nullable types

Type descriptors don't have to deal with nullable types, as these are transparently added/removed from the descriptor's types as needed. Therefore you don't have to return the union type of your custom type and NullType from the descriptor's methods, even if your custom type allows null.

ReflectionDescriptor

If your custom type's convertToPHPValue() and convertToDatabaseValue() methods have proper typehints, you don't have to write your own descriptor for it. The PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor can analyse the typehints and do the rest for you.

Registering type descriptors

When you write a custom type descriptor, you have to let PHPStan know about it. Add something like this into your phpstan.neon:

services:
	-
		class: MyCustomTypeDescriptor
		tags: [phpstan.doctrine.typeDescriptor]

	# in case you are using the ReflectionDescriptor
	-
		factory: PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor('MyApp\MyCustomTypeName')
		tags: [phpstan.doctrine.typeDescriptor]
Comments
  • Support multiple object managers?

    Support multiple object managers?

    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.

    opened by dmaicher 46
  • Support for infering the result type of queries in EntityManager::createQuery()

    Support for infering the result type of queries in EntityManager::createQuery()

    Adds a type parameter TResult on the Doctrine\ORM\Query and Doctrine\ORM\AbstractQuery stubs. This parameter represents the type of the results returned by the getResult() and execute() family of methods, when in HYDRATE_OBJECT mode.

    Also adds a DynamicReturnTypeExtension on EntityManager::createQuery() so that TResult is infered from the query string.

    As the hydration mode influences the return type of the getResult() and execute() family of methods, we can not just declare that these methods return TResult yet. This will require a DynamicReturnTypeExtension (next PR).

    (see issue #221 and the fully functional dev branch with the DynamicReturnTypeExtension)

    opened by arnaud-lb 37
  • Precise getRootAliases return type

    Precise getRootAliases return type

    This allow

    $rootAlias = current($query->getQueryBuilder()->getRootAliases());
    
    $queryBuilder->where($rootAlias . '.statusId IN (:statusIds)')
    
    opened by VincentLanglet 23
  • Fix empty DQL with QueryBuilder::setParameters()

    Fix empty DQL with QueryBuilder::setParameters()

    Since version 0.12.18 I have a weird error:

    QueryBuilder: [Syntax Error] line 0, col -1: Error: Expected IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression, got end of string.
    DQL: SELECT
    

    It is reported in code that uses the QueryBuilder::setParameters() method. I first replaced those calls with several QueryBuilder::setParameter() calls and the errors were not reported anymore, but it was an unsatisfactory solution.

    I noticed that in that version, a new stub was added for the QueryBuilder::setParameters() method so I tried editing it. When replacing @return static with @return self, the errors were not reported anymore. I have no idea why this fixes the issue though so please let me know if there's a better way.

    opened by julienfalque 20
  • Unable to resolve the template type

    Unable to resolve the template type

    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);
    
    opened by enumag 19
  • Discover repository class from `#[Entity]` attribute on PHP 8

    Discover repository class from `#[Entity]` attribute on PHP 8

    By doing it like this, we don't need to instantiate the object manager at all which makes PHPStan run faster and more reliable. Very often I had to manually clear my Symfony cache and re-run PHPStan.

    Unfortunately, BetterReflection doesn't support attributes yet so therefore we need to use native ReflectionClass.

    See https://github.com/phpstan/phpstan/discussions/5863#discussioncomment-1823297

    opened by ruudk 18
  • class-string vs literal-string in QueryBuilder

    class-string vs literal-string in QueryBuilder

    With the recent addition of literal-types to QueryBuilder (https://github.com/phpstan/phpstan-doctrine/pull/327), I'm getting warnings when passing class-string there: Parameter #1 $from of method Doctrine\ORM\QueryBuilder::from() expects literal-string, class-string given

    This is the simplified example to reproduce the issue:

        /**
         * @param class-string $className
         */
        public function getSortable(
            string $className,
        ): ?Sortable
        {
            return $this
                ->entityManager
                ->createQueryBuilder()
                ->select('sortable')
                ->from($className, 'sortable')
                ->getQuery()
                ->getOneOrNullResult();
        }
    

    What is do you think is the correct way to handle this? To me it seems that class-string is more specific type than the literal-string.

    cc @VincentLanglet

    opened by mhujer 16
  • Dynamic return types for some Expr methods - Part 2

    Dynamic return types for some Expr methods - Part 2

    Continuing on from PR 298, for Issue 294.

    I'm starting with:

    • Failing tests, confirming these functions don't return a literal-string when there is no Object Manager.
    • Changed the requirements to phpstan/phpstan:^1.6.
    • Changed selectSingle to selectFromArgs.

    I'll continue this next week, but thought I should upload what I've got so far just incase I'm going in the wrong direction.


    Previous Diff.

    "Implement the logic in stubs with the help of conditional return types"... "The conditional return type for the methods would look like this: @return ($x is literal-string ? literal-string : string)"

    opened by craigfrancis 13
  • Doctrine type mismatch for non nullable doctrine properties

    Doctrine type mismatch for non nullable doctrine properties

    I recently decided to give PHPStan a go, but I'm getting over 1,000 errors for type mismatches on my Doctrine entities, such as:

    type mapping mismatch: property can contain int|null but database expects int

    Perhaps I'm missing something, but I don't believe these should be type mismatches. To provide an example:

    class MyEntity
    {
        /**
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @var int|null
         */
        private $id;
    
        public function getId(): ?int
        {
            return $this->id;
        }
    }
    
    $entity = new MyEntity();
    $entity->getId(); // this can return null if the entity is not yet hydrated
    

    I understand seeing a type mismatch if the property annotation has nullable=true and the docblock does not include null, this makes sense.

    However, there are absolutely times where a property with a NOT NULL constraint on the database column may contain a null value on the entity's property. It seems PHPStan is making the assumption that an entity is always going to be hydrated, but this simply isn't the case. When you create a new entity, all the properties are going to be null regardless of if the database expects those fields to contain NULL values or not.

    opened by patrick-vandy 13
  • [FEATURE] Allow functions chained on execute()

    [FEATURE] Allow functions chained on execute()

    I would like to suggest a rule to have following functions allowed to have fetch(), fetchAll(), fetchColumn() and rowCount() chained after execute() without getting the errors

    Cannot call method fetch() on Doctrine\DBAL\Driver\Statement|int.
    Cannot call method fetchAll() on Doctrine\DBAL\Driver\Statement|int.
    Cannot call method fetchColumn() on Doctrine\DBAL\Driver\Statement|int.
    Cannot call method rowCount() on Doctrine\DBAL\Driver\Statement|int.
    

    The execute() returns int when a count('*') is made instead of a select('*'), therefor with two possible return types PHPStan complains about this.

    Code Example

    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->tableName);
    $queueRec = $queryBuilder
        ->select('*')
        ->from($this->tableName)
        ->where(
            $queryBuilder->expr()->eq('qid', $queryBuilder->createNamedParameter($queueId))
        )
        ->execute()
        ->fetch();
    

    My problem currently, as stated on twitter, I'm quite new to PHPStan and would not know where to start to add this rule.

    If someone can point me into the direction how to implement this, I would happy to have a look at this, and I don't see it as a error with the current implementation of Doctrine select() and count().

    Hope that someone can point me in the right direction.

    opened by tomasnorre 13
  • Buggy static analyse with phpstan/phpstan-doctrine 1.2.6 - 1.2.8

    Buggy static analyse with phpstan/phpstan-doctrine 1.2.6 - 1.2.8

    Version: 1.2.6 to 1.2.8

    Very buggy static analyse - sometimes PHPStan is ok and sometimes reports manz errors

    Example code:

    <?php declare(strict_types = 1);
    
    namespace App\Entities;
    
    use Doctrine\ORM\Mapping as ORM;
    use App\Repositories\CountryRepository;
    
    #[ORM\Entity(repositoryClass: CountryRepository::class)]
    #[ORM\Table(name: 'countries')]
    class Country
    {
    
    	#[ORM\Id]
    	#[ORM\Column(type: 'integer')]
    	#[ORM\GeneratedValue]
    	private int $id;
    
    	#[ORM\Column(type: 'string', nullable: false)]
    	private string $code;
    
    	#[ORM\Column(type: 'string', nullable: false)]
    	private string $country;
    
    	public function getId(): int
    	{
    		return $this->id;
    	}
    
    	public function getCode(): string
    	{
    		return $this->code;
    	}
    
    	public function getCountry(): string
    	{
    		return $this->country;
    	}
    
    	public function setCode(string $code): void
    	{
    		$this->code = $code;
    	}
    
    	public function setCountry(string $country): void
    	{
    		$this->country = $country;
    	}
    
    }
    ?>
    
    <?php declare(strict_types = 1);
    
    namespace App\Repositories;
    
    use App\Entities\Country;
    use App\Model\EntityRepository;
    
    /**
     * @extends EntityRepository<Country>
     */
    final class CountryRepository extends EntityRepository
    {
    
    }
    ?>
    
    <?php declare(strict_types = 1);
    
    namespace App\Model;
    
    use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
    
    /**
     * @template TEntityClass of object
     * @extends  DoctrineEntityRepository<TEntityClass>
     */
    abstract class EntityRepository extends DoctrineEntityRepository
    {
    
    }
    

    tests/object-manager.php

    <?php declare(strict_types = 1);
    
    return App\Bootstrap::boot()
    	->createContainer()
    	->getByType(App\Model\EntityManagerDecorator::class);
    

    phpstan.neon

    parameters:
    	level: 8
    
    	doctrine:
    		repositoryClass: App\Model\EntityRepository
    		objectManagerLoader: tests/object-manager.php
    

    composer packages versions:

    beberlei/doctrineextensions	v1.3.0
    contributte/console v0.9.1
    contributte/di	v0.5.1
    doctrine/annotations	1.13.2
    doctrine/cache	1.12.1
    doctrine/collections	1.6.8
    doctrine/common	3.2.1
    doctrine/dbal	2.13.7
    doctrine/deprecations	v0.5.3
    doctrine/event-manager	1.1.1
    doctrine/inflector	2.0.4
    doctrine/instantiator	1.4.0
    doctrine/lexer	1.2.2
    doctrine/orm	2.11.1
    doctrine/persistence	2.3.0
    latte/latte	v2.10.8
    nette/application	v3.0.8
    nette/bootstrap	v3.0.2
    nette/caching	v3.0.2
    nette/component-model	v3.0.2
    nette/di	v3.0.12
    nette/finder	v2.5.3
    nette/forms	v3.0.7
    nette/http	v3.0.7
    nette/mail	v3.1.8
    nette/neon	v3.3.2
    nette/php-generator	v3.6.5
    nette/robot-loader	v3.4.1
    nette/routing	v3.0.2
    nette/safe-stream	v2.5.0
    nette/security	v3.0.6
    nette/schema	v1.2.2
    nette/tokenizer	v3.1.0
    nette/utils	v3.2.7
    nettrine/annotations	v0.7.0
    nettrine/cache	v0.3.0
    nettrine/dbal	v0.7.0
    nettrine/extensions-beberlei	v0.2.0
    nettrine/orm	v0.8.2
    psr/cache	3.0.0
    psr/container	2.0.2
    symfony/console	v5.4.3
    symfony/deprecation-contracts	v3.0.0
    symfony/polyfill-ctype	v1.24.0
    symfony/polyfill-intl-grapheme	v1.24.0
    symfony/polyfill-intl-normalizer	v1.24.0
    symfony/polyfill-mbstring	v1.24.0
    symfony/polyfill-php72	v1.24.0
    symfony/polyfill-php73	v1.24.0
    symfony/polyfill-php80	v1.24.0
    symfony/service-contracts	v3.0.0
    symfony/string	v6.0.3
    tracy/tracy	v2.7.8
    
    Dev Packages
    nette/tester	v2.4.1
    phpstan/extension-installer	1.1.0
    phpstan/phpstan	1.4.4
    phpstan/phpstan-deprecation-rules	1.0.0
    phpstan/phpstan-doctrine	1.2.8
    phpstan/phpstan-nette	1.0.0
    phpstan/phpstan-strict-rules	1.1.0
    

    Error report:

     ------ ----------------------------------------------------------------------- 
      Line   app/Entities/Country.php                                     
     ------ ----------------------------------------------------------------------- 
      16     Property App\Entities\Country::$id is never written, only    
             read.                                                                  
             💡 See:                                                                 
             https://phpstan.org/developing-extensions/always-read-written-propert  
             ies                                                                    
     ------ ----------------------------------------------------------------------- 
    
    opened by petrparolek 12
  • Error with the return of repositories

    Error with the return of repositories

    Hi,

    I just upgraded from 1.3.29 to 1.3.31, and also doctrine/doctrine-bundle from 2.7.0 to 2.8.2 I have now errors with the repository->findOneBy method which returns now object|null instead of the expected entity or null. I use an objectManagerLoader, I include vendor/phpstan/phpstan-doctrine/extension.neon and vendor/phpstan/phpstan-doctrine/rules.neon. I tried with and without bleedingEdge.

    The errors disappear when I downgrade the StubFilesExtensionLoader->getFiles() method and go back to the

    return 
    [
        $path . '/ORM/QueryBuilder.stub',
        $path . '/EntityRepository.stub',
    ];
    
    

    I saw thatan other issue was created and solved by 1.3.30 but it's still not ok for me.

    opened by rgrassian 1
  • Handle all hydration mode in QueryResultDynamicReturnTypeExtension

    Handle all hydration mode in QueryResultDynamicReturnTypeExtension

    Follow up of https://github.com/phpstan/phpstan-doctrine/pull/404

    Fix SingleScalarResult: to fix

    $eventsCount = $this->entityManager->createQueryBuilder()
    			->select('COUNT(cle.id)')
    			->from(CountryLocalityEvent::class, 'cle')
    			->andWhere('cle.user = ?', $user)
    			->andWhere('cle.expirationTime > ?', DateTimeProvider::now())
    			->getQuery()
    			->getSingleScalarResult();
    
    		return $eventsCount > 0;
    

    Fix ArrayResult: to fix

    $result = $this->entityManager->createQueryBuilder()
    			->select('d.name, d.id')
    			->from(Destination::class, 'd')
    			->addOrderBy('d.name')
    			->getQuery()
    			->getArrayResult();
    
    		$destinations = [];
    		foreach ($result as $item) {
    			$destinations[(string) $item['id']->toString()] = (string) $item['name'];
    		}
    

    For the last issue @ondrejmirtes,

    $query = $this->entityManager->createQueryBuilder()
    			->select('IDENTITY(n.related)')
    			->from(DistrictNeighbour::class, 'n')
    			->andWhere('n.center = ?', $districtId)
    			->getQuery();
    
    		return array_map(static fn (array $row): UuidInterface => $row['related'], $query->getArrayResult());
    

    I wonder if it couldn't be a bug in your codebase.

    • There is a Test for the Identity function checking it's indexed by 1, 2, 3, ... https://github.com/phpstan/phpstan-doctrine/blob/1.3.x/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php#L1394-L1419
    • Expectations are double-checked with the result from a database https://github.com/phpstan/phpstan-doctrine/blob/1.3.x/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php#L215-L233
    opened by VincentLanglet 0
  • #202 Add rule to prevent final constructors in doctrine entities

    #202 Add rule to prevent final constructors in doctrine entities

    This fixes #202.

    • Prevent Doctrine entities from containing private constructors
    • At the same time, don't forbid non-constructor methods in Doctrine entities

    What do you think about that?

    opened by LeoVie 1
  • Collection->contains() returns always-false for freshly created ArrayCollection without defined template type

    Collection->contains() returns always-false for freshly created ArrayCollection without defined template type

    Following error appeared after upgrading from 1.3.14 to 1.3.15. Easily fixable by using array and creating collection later, so I assume this is minor issue.

    /**
     * @return Collection<int, Account>
     */
    public function getAccounts(): Collection
    {
        $accounts = new ArrayCollection();
    
        foreach ($this->users as $user) {
            $account = $user->getAccount();
    
            if (!$accounts->contains($account)) { // error: Negated boolean expression is always true. 
                $accounts->add($account);
            }
        }
    
        return $accounts;
    }
    
    opened by janedbal 4
  • QueryBuilder::select() with multiple arguments not understood

    QueryBuilder::select() with multiple arguments not understood

    I have a method as follows:

    protected function foo(): void {
        $qb = $this->entityManager->createQueryBuilder();
        if (mt_rand(0, 1) === 0) {
            $qb->select('e.f1', 'e.f2');
        }
        else {
            $qb->select('e.f3', 'e.f4');
        }
        \PHPStan\dumpType($qb);
        $qb->select('e.f5', 'e.f6');
    }
    

    I get the following output:

      117    Dumped type: Doctrine\ORM\QueryBuilder|Doctrine\ORM\QueryBuilder
      118    Method Doctrine\ORM\QueryBuilder::select() invoked with 2 parameters, 0-1 required.
    

    I only marginally know how the query builder code works, but I xdebugged it as far as to see that the union is done between two BranchingQueryBuilderType instances and they are not considered equal due to different methods having been called on them. So not collapsing the union seems expected, but then maybe the code that validates the select() call cannot handle unions or something like that.

    I imagine that this is hard to reproduce, since it might depend on the exact Doctrine configuration. Let me know if I should attempt to create a full stand-alone example that triggers the issue.

    Using phpstan/phpstan-doctrine 1.3.12 and phpstan/phpstan 1.8.4.

    opened by jlherren 0
Releases(1.3.31)
Owner
PHPStan
PHP Static Analysis Tool - discover bugs in your code without running it!
PHPStan
WordPress extensions for PHPStan ⛏️

WordPress extensions for PHPStan Static analysis for the WordPress ecosystem. PHPStan WordPress Installation Add this package to your project. compose

Viktor Szépe 183 Dec 30, 2022
PHPStan extension to support #[Readonly] constructor properties

icanhazstring/phpstan-readonly-property Support #[Readonly] promoted constructor properties for PHPStan. This library is used to have a full transitio

Andreas Frömer 4 Apr 5, 2022
Analyzes PHPStan baseline files and creates aggregated error trend-reports

Analyzes phpstan baseline files Analyzes PHPStan baseline files and creates aggregated error trend-reports.

Markus Staab 22 Dec 23, 2022
Magento specific extension for phpstan

bitexpert/phpstan-magento This package provides some additional features for PHPStan to make it work for Magento 2 projects. Installation The preferre

bitExpert AG 92 Dec 7, 2022
Sandbox project for the PHPStan workshop

Sandbox project for a PHPStan workshop Installation Requirements Docker Engine Docker Compose Git Bash Getting started Clone this repository (git clon

Matthias Noback 4 Oct 17, 2022
A PHPStan package that supports working with Extbase

PHPStan for Extbase This package provides a couple of stubs and services to make your life easier when working with PHPStan and Extbase. Examples clas

Alexander Schnitzler 7 Dec 10, 2021
Custom PHPStan rules

phpstan-rules Provides additional rules for phpstan/phpstan. Installation Run $ composer require --dev alister/phpstan-rules Usage All of the rules pr

Alister Bulman 1 Nov 4, 2021
The main scope of this extension is to help phpstan to detect the type of object after the Assert\Assertion validation.

PHPStan beberlei/assert extension PHPStan beberlei/assert Description The main scope of this extension is to help phpstan to detect the type of object

PHPStan 33 Jan 2, 2023
PHPStan extension for webmozart/assert

PHPStan webmozart/assert extension PHPStan webmozart/assert Description The main scope of this extension is to help phpstan to detect the type of obje

PHPStan 139 Dec 22, 2022
Various PHPStan rules we found useful in ShipMonk.

ShipMonk PHPStan rules Various rules we found useful in ShipMonk. You may found some of them opinionated, so we recommend picking only those fitting y

ShipMonk R&D 31 Dec 22, 2022
PHPStan extension for sealed classes and interfaces.

Sealed classes with PHPStan This extension adds support for sealed classes and interfaces to PHPStan. Installation To use this extension, require it v

Jiří Pudil 14 Nov 28, 2022
Extension for PHPStan to allow analysis of Drupal code.

phpstan-drupal Extension for PHPStan to allow analysis of Drupal code. Sponsors Would you like to sponsor? Usage When you are using phpstan/extension-

Matt Glaman 154 Jan 2, 2023
Repository containing all the PHPStan rules from the book "Recipes for Decoupling"

PHPStan rules from the book "Recipes for Decoupling" by Matthias Noback In the book "Recipes for Decoupling" we discuss how to decouple from web and C

Matthias Noback 19 Sep 21, 2022
Perform static analysis of Drupal PHP code with phpstan-drupal.

Perform static analysis of Drupal PHP code with PHPStan and PHPStan-Drupal on Drupal using PHP 8. For example: docker run --rm \ -v $(pwd)/example01

Dcycle 0 Dec 10, 2021
Rector upgrades rules for Doctrine

Rector Rules for Doctrine See available Doctrine rules Install This package is already part of rector/rector package, so it works out of the box.

Rector 37 Nov 7, 2022
Support for PHP 8.1 enums in Doctrine.

Doctrine Native Enums This library provides first-class support to PHP Enums, introduced in PHP 8.1, within your Doctrine entities. Installation compo

Beno!t POLASZEK 14 Dec 15, 2022
Pageon Doctrine Data Grid Bundle

Pageon Doctrine Data Grid Bundle A bundle that wraps around the knp paginator bundle and doctrine to generate a data grid from your entity Documentati

null 1 Dec 14, 2021
Immutable value object for IPv4 and IPv6 addresses, including helper methods and Doctrine support.

IP is an immutable value object for (both version 4 and 6) IP addresses. Several helper methods are provided for ranges, broadcast and network address

Darsyn 224 Dec 28, 2022
Spot v2.x DataMapper built on top of Doctrine's Database Abstraction Layer

Spot DataMapper ORM v2.0 Spot v2.x is built on the Doctrine DBAL, and targets PHP 5.4+. The aim of Spot is to be a lightweight DataMapper alternative

Spot ORM 602 Dec 27, 2022