Compare commits

...

65 Commits
2.8.3 ... 2.8.5

Author SHA1 Message Date
Grégoire Paris
a6577b89a2 Merge pull request #8701 from jderusse/symfony6
Allow Symfony 6.0
2021-05-20 07:58:49 +02:00
Jérémy Derussé
0ca87566a9 Allow Symfony 6.0 2021-05-20 07:48:21 +02:00
Grégoire Paris
5d01f94a36 Merge pull request #8699 from greg0ire/fix-psalm
Fix some static analysis issues
2021-05-20 07:43:12 +02:00
Grégoire Paris
3d02b02636 Update static analysis baseline files
These issues were not introduced with new code, but with upgrades.
2021-05-20 00:03:39 +02:00
Grégoire Paris
6de321cb09 Address Psalm issues introduced by persistence 2021-05-20 00:03:39 +02:00
Grégoire Paris
535bc92dc8 Merge pull request #8700 from deguif/fix-undefined-offset
Fix undefined index
2021-05-18 12:20:38 +02:00
François-Xavier de Guillebon
ebb5d03f7a Fix undefined offset 2021-05-18 10:00:19 +02:00
Grégoire Paris
8e13369621 Merge pull request #8698 from deguif/cache-deprecation
Fix cache deprecation
2021-05-17 22:15:13 +02:00
François-Xavier de Guillebon
8eff4b775a Fix cache deprecation 2021-05-17 21:33:52 +02:00
tweet9ra
3a194ad699 SimpleObjectHydrator: skip unsuit custom type before converting it (#8566)
When using inheritance, it is possible to map the same column to properties of
different child classes. This can result in the same column being selecting several
times with different aliases in one SQL query, and only one aliased field needs
to be hydrated per row.
We now check that such an aliased value is mapped to the class we are hydrated
before attempting to convert it as it might result in an error when using a custom
type that does not get the expected data to initialize php value.

Co-authored-by: Sergey Naumov <s.naumov@lamoda.ru>
2021-05-15 09:37:16 +02:00
Grégoire Paris
4ccc4e19fc Merge pull request #8600 from VincentLanglet/computeChangeset
Remove internal tag from computeChangeSet
2021-05-05 19:27:39 +02:00
Grégoire Paris
c25b822217 Merge pull request #8673 from Seldaek/patch-1
Add hint for ->iterate() deprecation
2021-05-05 13:31:30 +02:00
Jordi Boggiano
c3dcc5af91 Add hint for ->iterate() deprecation 2021-05-05 10:31:33 +02:00
Alexandr Li
d141f27875 ConvertDoctrine1Schema: Fix Doctrine 1 notnull field import (#8649)
* ConvertDoctrine1Schema: Fix Doctrine 1 `notnull` field import

* cs fix

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-05-01 13:56:41 +02:00
Grégoire Paris
8555fc1d34 Merge pull request #8659 from greg0ire/make-tests-independent
Make tests independent
2021-04-29 09:07:26 +02:00
Grégoire Paris
850d57827f Make tests independent
It seems like IdentityMapTest cannot be run on its own when the second
level cache is enabled (with ENABLE_SECOND_LEVEL_CACHE=1).
It does work when running the whole test suite because
ExtraLazyCollectionTest disables part of that cache in its setUp()
method.
In this patch, we restore the class metadata as it was before running
setUp() and put the test in IdentityMapTest inside the group that is
excluded when running with ENABLE_SECOND_LEVEL_CACHE=1 on the CI.
2021-04-28 14:12:31 +02:00
Grégoire Paris
9a48450481 Merge pull request #7608 from mavroprovato/patch-1
Avoid unnecessary flush after processing first row
2021-04-24 14:23:09 +02:00
Kostas Kokkoros
cff8b96dd6 Avoid unnecessary flush after processing first row
The code as is needlessly flushes after just one row is updated or
removed. It makes more sense to update after ``$batchSize`` elements are
updated or removed, just as it is in the insert case.
2021-04-24 13:01:33 +02:00
Grégoire Paris
996c1c74b3 Merge pull request #8644 from greg0ire/more-accurate-return-type
Describe return types more accurately
2021-04-22 22:31:05 +02:00
Grégoire Paris
48612e6dc6 Merge pull request #8641 from Jean85/remove-deprecated-proxy-usage
Replace deprecated Proxy usages with parent interface to reduce baseline
2021-04-19 23:37:22 +02:00
Grégoire Paris
eb860a704e Change incorrect DBAL return types 2021-04-19 19:27:00 +02:00
Grégoire Paris
51ffcb4891 Describe return types more accurately
This fixes an SA regression introduced when using stricter types in
SchemaTool.

Fixes #8642
2021-04-19 19:09:10 +02:00
Alessandro Lai
9ea0769d78 Replace deprecated Proxy usages with parent interface to reduce baseline 2021-04-19 10:43:49 +02:00
Grégoire Paris
06fadcdd8c Merge pull request #8630 from Jean85/reduce-baseline
Reduce baseline
2021-04-18 18:50:59 +02:00
Alessandro Lai
7c56aa2141 Reduce baseline with a nullable return where needed 2021-04-18 18:39:20 +02:00
Alessandro Lai
4cdcb5f760 Reduce baseline for AbstractCollectionPersister 2021-04-18 18:39:20 +02:00
Alessandro Lai
b542b36e45 Remove baseline for DefaultCacheFactory 2021-04-18 18:39:20 +02:00
Alessandro Lai
e5a7a13e1e Remove single baseline rule from DefaultCache 2021-04-18 18:39:20 +02:00
Alessandro Lai
8336dd3779 Remove baseline for AbstractQuery 2021-04-18 18:39:14 +02:00
Grégoire Paris
a959a474fd Merge pull request #8636 from greg0ire/update-gitattributes
Update ignore rules to reflect current situation
2021-04-18 17:56:47 +02:00
Grégoire Paris
5ee71c54d4 Update ignore rules to reflect current situation
We no longer use Travis, we do not use git submodules as far as I know,
and we now use baseline files as well as project metadata.
2021-04-18 10:49:48 +02:00
Grégoire Paris
da3a9fa361 Merge pull request #8634 from orklah/static-upgrade
upgrade static tools
2021-04-17 15:41:51 +02:00
orklah
4fd81d26ff upgrade static tools 2021-04-17 13:12:35 +02:00
Grégoire Paris
e2e9f8fa97 Merge pull request #8627 from greg0ire/add-baselines
Add baseline files for static analyzers
2021-04-16 19:04:04 +02:00
Grégoire Paris
f7249ec709 Declare return type
This helps SA tools figure out that it is fine to call count on the
return value of that method.
As a side-effect, using $metadata->name is not really an option since it
is not part of the ClassMetadata interface.
2021-04-16 13:14:54 +02:00
Grégoire Paris
87dbcca454 Add baseline files for static analyzers
There are many CS and SA-related changes in the ORM as we pursue better
code quality, and easier contributions. These often involve huge
changes, which can be hard to review and inevitably lead to some
regressions. I know some of those could have been avoided if we were
using stricter levels for PHPStan and Psalm.

By adding baselines, we ensure new code is at level 5 for both tools,
which should allow us to catch the most interesting issues.
2021-04-16 09:23:11 +02:00
Grégoire Paris
305e0d6664 Merge pull request #8617 from greg0ire/cs9
Upgrade to doctrine/coding-standard 9
2021-04-13 18:48:12 +02:00
Grégoire Paris
199be94e6d Upgrade to doctrine/coding-standard 9 2021-04-13 09:00:33 +02:00
Grégoire Paris
fa588af3b1 Merge pull request #8604 from janatjak/2.8.x
Fix psalm param typehint for OneToManyAssociationBuilder::setOrderBy method
2021-04-09 12:57:12 +02:00
Grégoire Paris
d4741720fa Merge pull request #8605 from greg0ire/fix-phpdoc-lsp-violations 2021-04-09 11:59:28 +02:00
Grégoire Paris
343385d060 Pin squizlabs/php_codesniffer
We are referencing rules in phpcs.xml.dist, and may experience
unexpected BC-breaks because of that when they get renamed.
2021-04-09 09:27:44 +02:00
Grégoire Paris
6d04dced03 Address sniff rename
This sniff seems to have been renamed or split in the latest version of
phpcs.
2021-04-09 09:19:10 +02:00
Grégoire Paris
22fa3a8556 Document actual return types
Some executors may return integers, for instance executors that only
execute update or delete statements.
Also, in case an integer is not returned, what's actually returned is a
Doctrine\DBAL\Driver\ResultStatement, and not a Doctrine\DBAL\Driver\Statement
2021-04-09 08:52:56 +02:00
Jakub Janata
eb05756dc3 Fix psalm param typehint for OneToManyAssociationBuilder::setOrderBy method 2021-04-08 22:52:50 +02:00
Grégoire Paris
5bb7e20708 Merge pull request #8602 from NicoHaase/fix-8599
Adjusted return type annotation for getOriginalEntityData
2021-04-07 23:22:19 +02:00
Nico Haase
a9076313c7 Adjusted return type 2021-04-07 21:06:58 +02:00
Grégoire Paris
2a87821b28 Merge pull request #8552 from acoulton/maint-phpunit-upgrade 2021-04-07 15:33:06 +02:00
acoulton
da5877d60c Only polyfill older phpunit methods when required 2021-04-07 12:08:55 +01:00
Andrew Coulton
67dfe8e1af Simplify mock building calls
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-07 11:07:35 +01:00
Vincent Langlet
2dfe51b396 Remove internal tag 2021-04-07 11:41:34 +02:00
Grégoire Paris
5ac036de02 Merge pull request #8594 from greg0ire/make-sure-test-is-run 2021-04-06 17:47:17 +02:00
Grégoire Paris
23e1fd8ad6 Drop assertion about not being an instance of proxy
We do not want to enforce it as it is an internal details that seems to
vary from environment to environment.
2021-04-06 14:55:25 +02:00
Grégoire Paris
a588555ecd Merge pull request #8586 from KartaviK/patch-3
Additional psalm param typehint for orderBy argument in findBy method
2021-04-05 20:38:36 +02:00
Grégoire Paris
501057da83 Ensure test is suffixed with Test 2021-04-05 14:42:17 +02:00
Grégoire Paris
7de84537f6 Merge pull request #8591 from DmitriiBezborodnikov/case_insensive_parenthesis
Return case insensitive check
2021-04-05 14:40:51 +02:00
Grégoire Paris
97f8325dad Make sure tests are suffixed with Test
They will not be taken into account when running vendor/bin/phpunit
otherwise.
2021-04-05 14:32:40 +02:00
Grégoire Paris
0ebd7052d7 Drop create table at shutdown
It makes tests more isolated from each other: another test relying on
some tables including some of the ones created here may fail creating
the tables it needs because they already exist.
2021-04-05 14:03:49 +02:00
Dmitrii Bezborodnikov
5d73378b92 Return case insensitive check 2021-04-05 14:03:49 +02:00
Grégoire Paris
10572ec441 Merge pull request #8590 from VincentLanglet/patch-2
Fix phpdoc of ClassMetadataInfo::getIdentifierValues
2021-04-04 23:47:09 +02:00
Vincent Langlet
76278d801d Fix phpdoc 2021-04-04 21:19:54 +02:00
Roman Varkuta
ca80830b26 Describe $orderBy parameter as a hash
A list of string is incorrect, it actually looks like this:
['someField' => 'DESC', 'someOtherField' => 'ASC'…]`
2021-04-03 12:45:24 +02:00
Grégoire Paris
bcb4889a2c Merge pull request #8583 from greg0ire/sync-static-analysis-workflows
Synchronize static analysis jobs with upstream
2021-04-02 08:58:50 +02:00
Grégoire Paris
961da8b0cc Synchronize static analysis jobs with upstream 2021-04-01 23:32:04 +02:00
acoulton
1f4e6ebeeb Add a forward-compatibility wrapper for phpunit8 assertions
While doctrine still supports php7.2 the test cases need to run
under phpunit8 as well. However some assertion methods produce
deprecation warnings in the test output with phpunit >= 9.

This commit adds a thin forward compatiblity wrapper for the
new assertion method names so that they can be used with both
supported phpunit versions.
2021-03-18 11:25:18 +00:00
acoulton
a94db4f5c0 Fix remaining warnings from the phpunit9 upgrade
Some tests were still using deprecated assertion and mocking methods,
resulting in a long list of warnings in the phpunit output.

This commit resolves all the warnings:

* Fixes a couple of test names in `@depends` tags (presumably these
  tests were renamed at some point for coding standards).

* Changes how mocks are configured when asserting the same method
  is called multiple times with a sequence of arguments / sequence
  of return values. The old `->at` expectation is deprecated because
  it can be brittle and give unreliable results. Some of this
  mocking could probably still be refactored further, but my focus
  was on solving the deprecation with the existing setup.

* Removes one use of prophecy for mocking, in favour of using
  phpunit mock objects. Prophecy now requires an extra composer
  dependency and a trait which seems overkill given it was only
  used in one place.

* Updates to the new names for assertFileExists and assertRegExp
  (and their `not` versions) - these are functionally equivalent.

* Replaces the last few references to old PHPUnit_Framework_XXX
  classes with their namespaced equivalent. These were mostly in
  comments, or in native php `assert()` statements that were sanity
  checking mocked object types. These asserts are probably redundant
  (and are clearly not running in CI since the classes they referenced
  no longer exist).
2021-03-18 10:51:43 +00:00
106 changed files with 3595 additions and 604 deletions

5
.gitattributes vendored
View File

@@ -2,10 +2,9 @@
/tools export-ignore
/docs export-ignore
/.github export-ignore
.doctrine-project.json export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.gitmodules export-ignore
.travis.yml export-ignore
build.properties export-ignore
build.properties.dev export-ignore
build.xml export-ignore
@@ -15,4 +14,6 @@ run-all.sh export-ignore
phpcs.xml.dist export-ignore
phpbench.json export-ignore
phpstan.neon export-ignore
phpstan-baseline.neon export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore

View File

@@ -1,12 +1,18 @@
name: Static Analysis
name: "Static Analysis"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
jobs:
static-analysis-phpstan:
name: "PHPStan"
runs-on: "ubuntu-latest"
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-20.04"
strategy:
matrix:
@@ -22,17 +28,18 @@ jobs:
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: cs2pr
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "highest"
- name: "Run a static analysis with phpstan/phpstan"
run: "php vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
run: "vendor/bin/phpstan analyse"
static-analysis-psalm:
name: "Psalm"
runs-on: "ubuntu-latest"
name: "Static Analysis with Psalm"
runs-on: "ubuntu-20.04"
strategy:
matrix:
@@ -51,6 +58,8 @@ jobs:
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "highest"
- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"

View File

@@ -28,15 +28,16 @@
"doctrine/inflector": "^1.4|^2.0",
"doctrine/instantiator": "^1.3",
"doctrine/lexer": "^1.0",
"doctrine/persistence": "^2.0",
"symfony/console": "^3.0|^4.0|^5.0"
"doctrine/persistence": "^2.2",
"symfony/console": "^3.0|^4.0|^5.0|^6.0"
},
"require-dev": {
"doctrine/coding-standard": "^8.0",
"phpstan/phpstan": "^0.12.18",
"doctrine/coding-standard": "^9.0",
"phpstan/phpstan": "^0.12.83",
"phpunit/phpunit": "^8.5|^9.4",
"symfony/yaml": "^3.4|^4.0|^5.0",
"vimeo/psalm": "4.1.1"
"squizlabs/php_codesniffer": "3.6.0",
"symfony/yaml": "^3.4|^4.0|^5.0|^6.0",
"vimeo/psalm": "4.7.0"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"

View File

@@ -89,11 +89,11 @@ with the batching strategy that was already used for bulk inserts:
foreach ($q->toIterable() as $user) {
$user->increaseCredit();
$user->calculateNewBonuses();
++$i;
if (($i % $batchSize) === 0) {
$em->flush(); // Executes all updates.
$em->clear(); // Detaches all objects from Doctrine!
}
++$i;
}
$em->flush();
@@ -147,11 +147,11 @@ The following example shows how to do this:
$q = $em->createQuery('select u from MyProject\Model\User u');
foreach($q->toIterable() as $row) {
$em->remove($row);
++$i;
if (($i % $batchSize) === 0) {
$em->flush(); // Executes all deletions.
$em->clear(); // Detaches all objects from Doctrine!
}
++$i;
}
$em->flush();

View File

@@ -24,7 +24,7 @@ use Countable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\ORM\Cache\Logging\CacheLogger;
use Doctrine\ORM\Cache\QueryCacheKey;
use Doctrine\ORM\Cache\TimestampCacheKey;
@@ -123,7 +123,7 @@ abstract class AbstractQuery
*/
protected $_hydrationMode = self::HYDRATE_OBJECT;
/** @var QueryCacheProfile */
/** @var QueryCacheProfile|null */
protected $_queryCacheProfile;
/**
@@ -289,7 +289,7 @@ abstract class AbstractQuery
/**
* Retrieves the associated EntityManager of this Query instance.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
@@ -346,10 +346,9 @@ abstract class AbstractQuery
* Sets a collection of query parameters.
*
* @param ArrayCollection|mixed[] $parameters
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
*
* @return static This query instance.
*
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
*/
public function setParameters($parameters)
{
@@ -402,10 +401,9 @@ abstract class AbstractQuery
* @param mixed $value
*
* @return mixed[]|string|int|float|bool
* @psalm-return array|scalar
*
* @throws ORMInvalidArgumentException
*
* @psalm-return array|scalar
*/
public function processParameterValue($value)
{
@@ -593,6 +591,7 @@ abstract class AbstractQuery
*/
public function setResultCacheDriver($resultCacheDriver = null)
{
/** @phpstan-ignore-next-line */
if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
throw ORMException::invalidResultCacheDriver();
}
@@ -723,7 +722,7 @@ abstract class AbstractQuery
}
/**
* @return QueryCacheProfile
* @return QueryCacheProfile|null
*/
public function getQueryCacheProfile()
{
@@ -949,7 +948,7 @@ abstract class AbstractQuery
* Executes the query and returns an IterableResult that can be used to incrementally
* iterate over the result.
*
* @deprecated
* @deprecated 2.8 Use {@see toIterable} instead. See https://github.com/doctrine/orm/issues/8463
*
* @param ArrayCollection|mixed[]|null $parameters The query parameters.
* @param string|int|null $hydrationMode The hydration mode to use.
@@ -981,8 +980,8 @@ abstract class AbstractQuery
* Executes the query and returns an iterable that can be used to incrementally
* iterate over the result.
*
* @param ArrayCollection|mixed[] $parameters The query parameters.
* @param string|int|null $hydrationMode The hydration mode to use.
* @param ArrayCollection|array|mixed[] $parameters The query parameters.
* @param string|int|null $hydrationMode The hydration mode to use.
*
* @return iterable<mixed>
*/
@@ -1045,7 +1044,7 @@ abstract class AbstractQuery
$this->setParameters($parameters);
}
$setCacheEntry = static function (): void {
$setCacheEntry = static function ($data): void {
};
if ($this->_hydrationCacheProfile !== null) {
@@ -1203,7 +1202,9 @@ abstract class AbstractQuery
/**
* Executes the query and returns a the resulting Statement object.
*
* @return Statement The executed database statement that holds the results.
* @return ResultStatement|int The executed database statement that holds
* the results, or an integer indicating how
* many rows were affected.
*/
abstract protected function _doExecute();

View File

@@ -30,9 +30,9 @@ use Doctrine\ORM\PersistentCollection;
interface CollectionHydrator
{
/**
* @param ClassMetadata $metadata The entity metadata.
* @param CollectionCacheKey $key The cached collection key.
* @param mixed[]|Collection $collection The collection.
* @param ClassMetadata $metadata The entity metadata.
* @param CollectionCacheKey $key The cached collection key.
* @param array|mixed[]|Collection $collection The collection.
*
* @return CollectionCacheEntry
*/

View File

@@ -48,7 +48,7 @@ class DefaultCache implements Cache
/** @var QueryCache[] */
private $queryCaches = [];
/** @var QueryCache */
/** @var QueryCache|null */
private $defaultQueryCache;
public function __construct(EntityManagerInterface $em)

View File

@@ -111,6 +111,10 @@ class DefaultCacheFactory implements CacheFactory
}
if ($usage === ClassMetadata::CACHE_USAGE_READ_WRITE) {
if (! $region instanceof ConcurrentRegion) {
throw new InvalidArgumentException(sprintf('Unable to use access strategy type of [%s] without a ConcurrentRegion', $usage));
}
return new ReadWriteCachedEntityPersister($persister, $region, $em, $metadata);
}
@@ -134,6 +138,10 @@ class DefaultCacheFactory implements CacheFactory
}
if ($usage === ClassMetadata::CACHE_USAGE_READ_WRITE) {
if (! $region instanceof ConcurrentRegion) {
throw new InvalidArgumentException(sprintf('Unable to use access strategy type of [%s] without a ConcurrentRegion', $usage));
}
return new ReadWriteCachedCollectionPersister($persister, $region, $em, $mapping);
}
@@ -201,7 +209,7 @@ class DefaultCacheFactory implements CacheFactory
}
$directory = $this->fileLockRegionDirectory . DIRECTORY_SEPARATOR . $cache['region'];
$region = new FileLockRegion($region, $directory, $this->regionsConfig->getLockLifetime($cache['region']));
$region = new FileLockRegion($region, $directory, (string) $this->regionsConfig->getLockLifetime($cache['region']));
}
return $this->regions[$cache['region']] = $region;

View File

@@ -345,7 +345,6 @@ class DefaultQueryCache implements QueryCache
* @param mixed $assocValue
*
* @return mixed[]|null
*
* @psalm-return array{targetEntity: string, type: mixed, list?: array[], identifier?: array}|null
*/
private function storeAssociationCache(QueryCacheKey $key, array $assoc, $assocValue)

View File

@@ -40,12 +40,14 @@ class EntityCacheEntry implements CacheEntry
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
*
* @var string The entity class name
* @psalm-var class-string
*/
public $class;
/**
* @param string $class The entity class.
* @param array<string,mixed> $data The entity data.
* @psalm-param class-string $class
*/
public function __construct($class, array $data)
{

View File

@@ -72,7 +72,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
/** @var CollectionHydrator */
protected $hydrator;
/** @var CacheLogger */
/** @var CacheLogger|null */
protected $cacheLogger;
/**

View File

@@ -52,7 +52,7 @@ interface CachedCollectionPersister extends CachedPersister, CollectionPersister
/**
* Stores a collection into cache
*
* @param mixed[]|Collection $elements
* @param array|mixed[]|Collection $elements
*
* @return void
*/

View File

@@ -75,7 +75,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
/** @var Cache */
protected $cache;
/** @var CacheLogger */
/** @var CacheLogger|null */
protected $cacheLogger;
/** @var string */

View File

@@ -63,8 +63,8 @@ class FileLockRegion implements ConcurrentRegion
private $lockLifetime;
/**
* @param string $directory
* @param string $lockLifetime
* @param string $directory
* @param numeric-string $lockLifetime
*
* @throws InvalidArgumentException
*/

View File

@@ -151,10 +151,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* is true, the notation `@Entity` will work, otherwise, the notation `@ORM\Entity` will be supported.
*
* @param bool $useSimpleAnnotationReader
* @psalm-param string|list<string> $paths
*
* @return AnnotationDriver
*
* @psalm-param string|list<string> $paths
*/
public function newDefaultAnnotationDriver($paths = [], $useSimpleAnnotationReader = true)
{
@@ -209,9 +208,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the entity alias map.
*
* @return void
*
* @psalm-param array<string, string> $entityNamespaces
*
* @return void
*/
public function setEntityNamespaces(array $entityNamespaces)
{
@@ -350,13 +349,13 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name The name of the query.
*
* @throws ORMException
*
* @psalm-return array{string, ResultSetMapping} A tuple with the first
* element being the SQL
* string and the second
* element being the
* ResultSetMapping.
*
* @throws ORMException
*/
public function getNamedNativeQuery($name)
{
@@ -426,7 +425,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $name
*
* @return string|null
*
* @psalm-return ?class-string
*/
public function getCustomStringFunction($name)
@@ -444,10 +442,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* Any previously added string functions are discarded.
*
* @return void
*
* @psalm-param array<string, class-string> $functions The map of custom
* DQL string functions.
*
* @return void
*/
public function setCustomStringFunctions(array $functions)
{
@@ -479,7 +477,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $name
*
* @return string|null
*
* @psalm-return ?class-string
*/
public function getCustomNumericFunction($name)
@@ -497,10 +494,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* Any previously added numeric functions are discarded.
*
* @return void
*
* @psalm-param array<string, class-string> $functions The map of custom
* DQL numeric functions.
*
* @return void
*/
public function setCustomNumericFunctions(array $functions)
{
@@ -518,10 +515,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name Function name.
* @param string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string|callable $className
*
* @return void
*
* @psalm-param class-string|callable $className
*/
public function addCustomDatetimeFunction($name, $className)
{
@@ -534,7 +530,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $name
*
* @return string|null
*
* @psalm-return ?class-string $name
*/
public function getCustomDatetimeFunction($name)
@@ -553,10 +548,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Any previously added date/time functions are discarded.
*
* @param array $functions The map of custom DQL date/time functions.
* @psalm-param array<string, string> $functions
*
* @return void
*
* @psalm-param array<string, string> $functions
*/
public function setCustomDatetimeFunctions(array $functions)
{
@@ -587,7 +581,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $modeName The hydration mode name.
*
* @return string|null The hydrator class name.
*
* @psalm-return ?class-string
*/
public function getCustomHydrationMode($modeName)
@@ -599,10 +592,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Adds a custom hydration mode.
*
* @param string $modeName The hydration mode name.
* @psalm-param class-string $hydrator The hydrator class name.
*
* @return void
*
* @psalm-param class-string $hydrator The hydrator class name.
*/
public function addCustomHydrationMode($modeName, $hydrator)
{
@@ -613,10 +605,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Sets a class metadata factory.
*
* @param string $cmfName
* @psalm-param class-string $cmfName
*
* @return void
*
* @psalm-param class-string $cmfName
*/
public function setClassMetadataFactoryName($cmfName)
{
@@ -625,7 +616,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* @return string
*
* @psalm-return class-string
*/
public function getClassMetadataFactoryName()
@@ -655,7 +645,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return string|null The class name of the filter, or null if it is not
* defined.
*
* @psalm-return ?class-string
*/
public function getFilterClassName($name)
@@ -687,7 +676,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Get default repository class.
*
* @return string
*
* @psalm-return class-string
*/
public function getDefaultRepositoryClassName()

View File

@@ -21,6 +21,7 @@
namespace Doctrine\ORM;
use BadMethodCallException;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\EventManager;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\Connection;
@@ -47,6 +48,7 @@ use function is_callable;
use function is_object;
use function is_string;
use function ltrim;
use function method_exists;
use function sprintf;
use function trigger_error;
@@ -166,7 +168,14 @@ use const E_USER_DEPRECATED;
$this->metadataFactory = new $metadataFactoryClassName();
$this->metadataFactory->setEntityManager($this);
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
$metadataCache = $this->config->getMetadataCacheImpl();
if ($metadataCache !== null) {
if (method_exists($this->metadataFactory, 'setCache')) {
$this->metadataFactory->setCache(CacheAdapter::wrap($metadataCache));
} else {
$this->metadataFactory->setCacheDriver($metadataCache);
}
}
$this->repositoryFactory = $config->getRepositoryFactory();
$this->unitOfWork = new UnitOfWork($this);
@@ -284,9 +293,7 @@ use const E_USER_DEPRECATED;
*
* Internal note: Performance-sensitive method.
*
* @param string $className
*
* @return ClassMetadata
* {@inheritDoc}
*/
public function getClassMetadata($className)
{
@@ -386,8 +393,10 @@ use const E_USER_DEPRECATED;
* during the search.
* @param int|null $lockVersion The version of the entity to find when using
* optimistic locking.
* @psalm-param class-string<T> $className
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
*
* @throws OptimisticLockException
* @throws ORMInvalidArgumentException
@@ -395,8 +404,6 @@ use const E_USER_DEPRECATED;
* @throws ORMException
*
* @template T
* @psalm-param class-string<T> $className
* @psalm-return ?T
*/
public function find($className, $id, $lockMode = null, $lockVersion = null)
{
@@ -746,12 +753,12 @@ use const E_USER_DEPRECATED;
* Gets the repository for an entity class.
*
* @param string $entityName The name of the entity.
* @psalm-param class-string<T> $entityName
*
* @return ObjectRepository|EntityRepository The repository class.
* @psalm-return EntityRepository<T>
*
* @template T
* @psalm-param class-string<T> $entityName
* @psalm-return EntityRepository<T>
*/
public function getRepository($entityName)
{

View File

@@ -34,7 +34,7 @@ use Doctrine\Persistence\ObjectManager;
/**
* EntityManager interface
*
* @method Mapping\ClassMetadata getClassMetadata($className)
* @method Mapping\ClassMetadataFactory getMetadataFactory()
*/
interface EntityManagerInterface extends ObjectManager
{
@@ -155,14 +155,14 @@ interface EntityManagerInterface extends ObjectManager
*
* @param string $entityName The name of the entity type.
* @param mixed $id The entity identifier.
* @psalm-param class-string<T> $entityName
*
* @return object|null The entity reference.
* @psalm-return ?T
*
* @throws ORMException
*
* @template T
* @psalm-param class-string<T> $entityName
* @psalm-return ?T
*/
public function getReference($entityName, $id);
@@ -305,4 +305,16 @@ interface EntityManagerInterface extends ObjectManager
* @return bool True, if the EM has a filter collection.
*/
public function hasFilters();
/**
* {@inheritDoc}
*
* @psalm-param string|class-string<T> $className
*
* @return Mapping\ClassMetadata
* @psalm-return Mapping\ClassMetadata<T>
*
* @template T of object
*/
public function getClassMetadata($className);
}

View File

@@ -160,7 +160,6 @@ class EntityRepository implements ObjectRepository, Selectable
* @param int|null $lockVersion The lock version.
*
* @return object|null The entity instance or NULL if the entity can not be found.
*
* @psalm-return ?T
*/
public function find($id, $lockMode = null, $lockVersion = null)
@@ -183,9 +182,9 @@ class EntityRepository implements ObjectRepository, Selectable
*
* @param int|null $limit
* @param int|null $offset
*
* @psalm-param array<string, mixed> $criteria
* @psalm-param list<string>|null $orderBy
* @psalm-param array<string, string>|null $orderBy
*
* @psalm-return list<T> The objects.
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
@@ -198,10 +197,10 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Finds a single entity by a set of criteria.
*
* @return object|null The entity instance or NULL if the entity can not be found.
*
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
*/
public function findOneBy(array $criteria, ?array $orderBy = null)
@@ -214,9 +213,10 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Counts entities by a set of criteria.
*
* @psalm-param array<string, mixed> $criteria
*
* @return int The cardinality of the objects that match the given criteria.
*
* @psalm-param array<string, mixed> $criteria
* @todo Add this method to `ObjectRepository` interface in the next major release
*/
public function count(array $criteria)
@@ -228,13 +228,12 @@ class EntityRepository implements ObjectRepository, Selectable
* Adds support for magic method calls.
*
* @param string $method
* @psalm-param list<mixed> $arguments
*
* @return mixed The returned value from the resolved method.
*
* @throws ORMException
* @throws BadMethodCallException If the method called is invalid.
*
* @psalm-param list<mixed> $arguments
*/
public function __call($method, $arguments)
{
@@ -307,12 +306,11 @@ class EntityRepository implements ObjectRepository, Selectable
*
* @param string $method The method to call
* @param string $by The property name used as condition
* @psalm-param list<mixed> $arguments The arguments to pass at method call
*
* @return mixed
*
* @throws ORMException If the method called is invalid or the requested field/association does not exist.
*
* @psalm-param list<mixed> $arguments The arguments to pass at method call
*/
private function resolveMagicCall(string $method, string $by, array $arguments)
{

View File

@@ -123,10 +123,9 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
* @psalm-param array<string, mixed> $hints
*
* @return IterableResult
*
* @psalm-param array<string, mixed> $hints
*/
public function iterate($stmt, $resultSetMapping, array $hints = [])
{
@@ -151,9 +150,9 @@ abstract class AbstractHydrator
/**
* Initiates a row-by-row hydration.
*
* @return iterable<mixed>
*
* @psalm-param array<string, mixed> $hints
*
* @return iterable<mixed>
*/
public function toIterable(ResultStatement $stmt, ResultSetMapping $resultSetMapping, array $hints = []): iterable
{
@@ -195,10 +194,9 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
* @psalm-param array<string, string> $hints
*
* @return mixed[]
*
* @psalm-param array<string, string> $hints
*/
public function hydrateAll($stmt, $resultSetMapping, array $hints = [])
{
@@ -322,14 +320,13 @@ abstract class AbstractHydrator
* the values applied. Scalar values are kept in a specific key 'scalars'.
*
* @param mixed[] $data SQL Result Row.
* @psalm-param array<string, string> $id Dql-Alias => ID-Hash.
* @psalm-param array<string, bool> $nonemptyComponents Does this DQL-Alias has at least one non NULL value?
*
* @return array<string, array<string, mixed>> An array with all the fields
* (name => value) of the data
* row, grouped by their
* component alias.
*
* @psalm-param array<string, string> $id Dql-Alias => ID-Hash.
* @psalm-param array<string, bool> $nonemptyComponents Does this DQL-Alias has at least one non NULL value?
* @psalm-return array{
* data: array<array-key, array>,
* newObjects?: array<array-key, array{
@@ -415,6 +412,7 @@ abstract class AbstractHydrator
* of elements as before.
*
* @psalm-param array<string, mixed> $data
*
* @psalm-return array<string, mixed> The processed row.
*/
protected function gatherScalarRowData(&$data)

View File

@@ -100,10 +100,9 @@ class HydrationException extends ORMException
/**
* @param string $discrValue
* @psalm-param array<string, string> $discrMap
*
* @return HydrationException
*
* @psalm-param array<string, string> $discrMap
*/
public static function invalidDiscriminatorValue($discrValue, $discrMap)
{

View File

@@ -21,9 +21,9 @@
namespace Doctrine\ORM\Internal\Hydration;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\ORM\Query;
use Doctrine\ORM\UnitOfWork;
use PDO;
@@ -223,12 +223,11 @@ class ObjectHydrator extends AbstractHydrator
* Gets an entity instance.
*
* @param string $dqlAlias The DQL alias of the entity's class.
* @psalm-param array<string, mixed> $data The instance data.
*
* @return object The entity.
*
* @throws HydrationException
*
* @psalm-param array<string, mixed> $data The instance data.
*/
private function getEntity(array $data, $dqlAlias)
{
@@ -274,10 +273,9 @@ class ObjectHydrator extends AbstractHydrator
/**
* @param string $className
* @psalm-param array<string, mixed> $data
*
* @return mixed
*
* @psalm-param array<string, mixed> $data
*/
private function getEntityFromIdentityMap($className, array $data)
{
@@ -433,7 +431,7 @@ class ObjectHydrator extends AbstractHydrator
// PATH B: Single-valued association
$reflFieldValue = $reflField->getValue($parentObject);
if (! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && ! $reflFieldValue->__isInitialized__)) {
if (! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && ! $reflFieldValue->__isInitialized())) {
// we only need to take action if this value is null,
// we refresh the entity or its an uninitialized proxy.
if (isset($nonemptyComponents[$dqlAlias])) {

View File

@@ -133,6 +133,11 @@ class SimpleObjectHydrator extends AbstractHydrator
continue;
}
// If we have inheritance in resultset, make sure the field belongs to the correct class
if (isset($cacheKeyInfo['discriminatorValues']) && ! in_array((string) $discrColumnValue, $cacheKeyInfo['discriminatorValues'], true)) {
continue;
}
// Check if value is null before conversion (because some types convert null to something else)
$valueIsNull = $value === null;
@@ -146,11 +151,6 @@ class SimpleObjectHydrator extends AbstractHydrator
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
if (! isset($data[$fieldName]) || ! $valueIsNull) {
// If we have inheritance in resultset, make sure the field belongs to the correct class
if (isset($cacheKeyInfo['discriminatorValues']) && ! in_array((string) $discrColumnValue, $cacheKeyInfo['discriminatorValues'], true)) {
continue;
}
$data[$fieldName] = $value;
}
}

View File

@@ -138,10 +138,9 @@ class ClassMetadataBuilder
* Adds Index.
*
* @param string $name
* @psalm-param list<string> $columns
*
* @return static
*
* @psalm-param list<string> $columns
*/
public function addIndex(array $columns, $name)
{
@@ -158,10 +157,9 @@ class ClassMetadataBuilder
* Adds Unique Constraint.
*
* @param string $name
* @psalm-param list<string> $columns
*
* @return static
*
* @psalm-param list<string> $columns
*/
public function addUniqueConstraint(array $columns, $name)
{
@@ -299,10 +297,9 @@ class ClassMetadataBuilder
*
* @param string $name
* @param string $type
* @psalm-param array<string, mixed> $mapping
*
* @return static
*
* @psalm-param array<string, mixed> $mapping
*/
public function addField($name, $type, array $mapping = [])
{

View File

@@ -28,9 +28,9 @@ namespace Doctrine\ORM\Mapping\Builder;
class OneToManyAssociationBuilder extends AssociationBuilder
{
/**
* @return static
* @psalm-param array<string, string> $fieldNames
*
* @psalm-param list<string> $fieldNames
* @return static
*/
public function setOrderBy(array $fieldNames)
{

View File

@@ -24,6 +24,8 @@ namespace Doctrine\ORM\Mapping;
* {@inheritDoc}
*
* @todo remove or rename ClassMetadataInfo to ClassMetadata
* @template T of object
* @template-extends ClassMetadataInfo<T>
*/
class ClassMetadata extends ClassMetadataInfo
{

View File

@@ -54,6 +54,10 @@ use function strtolower;
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
* metadata mapping information of a class which describes how a class should be mapped
* to a relational database.
*
* @method ClassMetadata[] getAllMetadata()
* @method ClassMetadata[] getLoadedMetadata()
* @method ClassMetadata getMetadataFor($className)
*/
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
@@ -745,6 +749,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
*/
protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
{
/** @psalm-var class-string */
return $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}

View File

@@ -72,6 +72,9 @@ use function trim;
* 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
*
* @template T of object
* @template-implements ClassMetadata<T>
*/
class ClassMetadataInfo implements ClassMetadata
{
@@ -235,6 +238,7 @@ class ClassMetadataInfo implements ClassMetadata
* READ-ONLY: The name of the entity class.
*
* @var string
* @psalm-var class-string<T>
*/
public $name;
@@ -704,7 +708,6 @@ class ClassMetadataInfo implements ClassMetadata
* Gets the ReflectionProperties of the mapped class.
*
* @return ReflectionProperty[]|null[] An array of ReflectionProperty instances.
*
* @psalm-return array<ReflectionProperty|null>
*/
public function getReflectionProperties()
@@ -748,7 +751,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* @param object $entity
*
* @return array<string|int, mixed>
* @return array<string, mixed>
*/
public function getIdentifierValues($entity)
{
@@ -780,10 +783,10 @@ class ClassMetadataInfo implements ClassMetadata
* Populates the entity identifier of an entity.
*
* @param object $entity
* @psalm-param array<string, mixed> $id
*
* @return void
*
* @psalm-param array<string, mixed> $id
* @todo Rename to assignIdentifier()
*/
public function setIdentifierValues($entity, array $id)
@@ -1102,9 +1105,9 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
* @return void
*
* @psalm-param array{usage?: mixed, region?: mixed} $cache
*
* @return void
*/
public function enableCache(array $cache)
{
@@ -1121,10 +1124,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @param string $fieldName
* @psalm-param array{usage?: mixed, region?: mixed} $cache
*
* @return void
*
* @psalm-param array{usage?: mixed, region?: mixed} $cache
*/
public function enableAssociationCache($fieldName, array $cache)
{
@@ -1134,10 +1136,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @param string $fieldName
* @param array $cache
* @psalm-param array{usage?: mixed, region?: mixed} $cache
*
* @return mixed[]
*
* @psalm-param array{usage?: mixed, region?: mixed} $cache
* @psalm-return array{usage: mixed, region: mixed}
*/
public function getAssociationCacheDefaults($fieldName, array $cache)
@@ -1264,9 +1265,9 @@ class ClassMetadataInfo implements ClassMetadata
*
* @param string $fieldName The field name.
*
* @throws MappingException
*
* @psalm-return array<string, mixed> The field mapping.
*
* @throws MappingException
*/
public function getFieldMapping($fieldName)
{
@@ -1285,9 +1286,9 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $fieldName The field name that represents the association in
* the object model.
*
* @throws MappingException
*
* @psalm-return array<string, mixed> The mapping.
*
* @throws MappingException
*/
public function getAssociationMapping($fieldName)
{
@@ -1358,9 +1359,9 @@ class ClassMetadataInfo implements ClassMetadata
*
* @param string $queryName The query name.
*
* @throws MappingException
*
* @psalm-return array<string, mixed>
*
* @throws MappingException
*/
public function getNamedNativeQuery($queryName)
{
@@ -1388,9 +1389,9 @@ class ClassMetadataInfo implements ClassMetadata
*
* @param string $name The result set mapping name.
*
* @throws MappingException
*
* @psalm-return array<string, mixed>
*
* @throws MappingException
*/
public function getSqlResultSetMapping($name)
{
@@ -1414,11 +1415,11 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes the given field mapping.
*
* @psalm-param array<string, mixed> $mapping The field mapping to validate & complete.
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping The field mapping to validate & complete.
*/
protected function _validateAndCompleteFieldMapping(array &$mapping)
{
@@ -1479,11 +1480,9 @@ class ClassMetadataInfo implements ClassMetadata
* Validates & completes the basic mapping information that is common to all
* association mappings (one-to-one, many-ot-one, one-to-many, many-to-many).
*
* @return mixed[] The updated mapping.
*
* @throws MappingException If something is wrong with the mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping.
*
* @return mixed[] The updated mapping.
* @psalm-return array{
* mappedBy: mixed,
* inversedBy: mixed,
@@ -1500,6 +1499,8 @@ class ClassMetadataInfo implements ClassMetadata
* isCascadeDetach: bool,
* ?orphanRemoval: bool
* }
*
* @throws MappingException If something is wrong with the mapping.
*/
protected function _validateAndCompleteAssociationMapping(array $mapping)
{
@@ -1617,13 +1618,13 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a one-to-one association mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
*
* @return mixed[] The validated & completed mapping.
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool, isCascadeRemove: bool}
*
* @throws RuntimeException
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool, isCascadeRemove: bool}
*/
protected function _validateAndCompleteOneToOneMapping(array $mapping)
{
@@ -1707,12 +1708,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a one-to-many association mapping.
*
* @return mixed[] The validated and completed mapping.
*
* @throws MappingException
* @throws InvalidArgumentException
*
* @psalm-param array<string, mixed> $mapping The mapping to validate and complete.
*
* @return mixed[] The validated and completed mapping.
* @psalm-return array{
* mappedBy: mixed,
* inversedBy: mixed,
@@ -1729,6 +1727,9 @@ class ClassMetadataInfo implements ClassMetadata
* isCascadeDetach: bool,
* orphanRemoval: bool
* }
*
* @throws MappingException
* @throws InvalidArgumentException
*/
protected function _validateAndCompleteOneToManyMapping(array $mapping)
{
@@ -1750,12 +1751,12 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a many-to-many association mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
*
* @return mixed[] The validated & completed mapping.
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool}
*
* @throws InvalidArgumentException
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool}
*/
protected function _validateAndCompleteManyToManyMapping(array $mapping)
{
@@ -1901,9 +1902,9 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the mapped identifier/primary key fields of this class.
* Mainly used by the ClassMetadataFactory to assign inherited identifiers.
*
* @return void
*
* @psalm-param list<mixed> $identifier
*
* @return void
*/
public function setIdentifier(array $identifier)
{
@@ -1930,9 +1931,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets an array containing all the column names.
*
* @return mixed[]
*
* @psalm-param list<string>|null $fieldNames
*
* @return mixed[]
* @psalm-return list<string>
*/
public function getColumnNames(?array $fieldNames = null)
@@ -2151,9 +2152,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Sets the mapped subclasses of this class.
*
* @return void
*
* @psalm-param list<string> $subclasses The names of all mapped subclasses.
*
* @return void
*/
public function setSubclasses(array $subclasses)
{
@@ -2167,9 +2168,9 @@ class ClassMetadataInfo implements ClassMetadata
* Assumes that the class names in the passed array are in the order:
* directParent -> directParentParent -> directParentParentParent ... -> root.
*
* @return void
*
* @psalm-param list<class-string> $classNames
*
* @return void
*/
public function setParentClasses(array $classNames)
{
@@ -2202,12 +2203,11 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the association to override association mapping of property for an entity relationship.
*
* @param string $fieldName
* @psalm-param array<string, mixed> $overrideMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $overrideMapping
*/
public function setAssociationOverride($fieldName, array $overrideMapping)
{
@@ -2268,12 +2268,11 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the override for a mapped field.
*
* @param string $fieldName
* @psalm-param array<string, mixed> $overrideMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $overrideMapping
*/
public function setAttributeOverride($fieldName, array $overrideMapping)
{
@@ -2381,9 +2380,9 @@ class ClassMetadataInfo implements ClassMetadata
*
* If a key is omitted, the current value is kept.
*
* @return void
*
* @psalm-param array<string, mixed> $table The table description.
*
* @return void
*/
public function setPrimaryTable(array $table)
{
@@ -2440,11 +2439,11 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a mapped field to the class.
*
* @psalm-param array<string, mixed> $mapping The field mapping.
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping The field mapping.
*/
public function mapField(array $mapping)
{
@@ -2459,11 +2458,11 @@ class ClassMetadataInfo implements ClassMetadata
* Adds an association mapping without completing/validating it.
* This is mainly used to add inherited association mappings to derived classes.
*
* @psalm-param array<string, mixed> $mapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping
*/
public function addInheritedAssociationMapping(array $mapping/*, $owningClassName = null*/)
{
@@ -2479,9 +2478,9 @@ class ClassMetadataInfo implements ClassMetadata
* Adds a field mapping without completing/validating it.
* This is mainly used to add inherited field mappings to derived classes.
*
* @return void
*
* @psalm-param array<string, mixed> $fieldMapping
*
* @return void
*/
public function addInheritedFieldMapping(array $fieldMapping)
{
@@ -2494,11 +2493,11 @@ class ClassMetadataInfo implements ClassMetadata
* INTERNAL:
* Adds a named query to this class.
*
* @psalm-param array<string, mixed> $queryMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $queryMapping
*/
public function addNamedQuery(array $queryMapping)
{
@@ -2529,11 +2528,11 @@ class ClassMetadataInfo implements ClassMetadata
* INTERNAL:
* Adds a named native query to this class.
*
* @psalm-param array<string, mixed> $queryMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $queryMapping
*/
public function addNamedNativeQuery(array $queryMapping)
{
@@ -2572,11 +2571,11 @@ class ClassMetadataInfo implements ClassMetadata
* INTERNAL:
* Adds a sql result set mapping to this class.
*
* @psalm-param array<string, mixed> $resultMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $resultMapping
*/
public function addSqlResultSetMapping(array $resultMapping)
{
@@ -2646,9 +2645,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a one-to-many mapping.
*
* @return void
*
* @psalm-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
public function mapOneToMany(array $mapping)
{
@@ -2662,9 +2661,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a many-to-one mapping.
*
* @return void
*
* @psalm-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
public function mapManyToOne(array $mapping)
{
@@ -2679,9 +2678,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a many-to-many mapping.
*
* @return void
*
* @psalm-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
public function mapManyToMany(array $mapping)
{
@@ -2695,11 +2694,11 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Stores the association mapping.
*
* @psalm-param array<string, mixed> $assocMapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $assocMapping
*/
protected function _storeAssociationMapping(array $assocMapping)
{
@@ -2714,10 +2713,9 @@ class ClassMetadataInfo implements ClassMetadata
* Registers a custom repository class for the entity class.
*
* @param string $repositoryClassName The class name of the custom mapper.
* @psalm-param class-string $repositoryClassName
*
* @return void
*
* @psalm-param class-string $repositoryClassName
*/
public function setCustomRepositoryClass($repositoryClassName)
{
@@ -2787,9 +2785,9 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the lifecycle callbacks for entities of this class.
* Any previously registered callbacks are overwritten.
*
* @return void
*
* @psalm-param array<string, list<string>> $callbacks
*
* @return void
*/
public function setLifecycleCallbacks(array $callbacks)
{
@@ -2834,11 +2832,11 @@ class ClassMetadataInfo implements ClassMetadata
*
* @see getDiscriminatorColumn()
*
* @psalm-param array<string, mixed> $columnDef
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $columnDef
*/
public function setDiscriminatorColumn($columnDef)
{
@@ -2871,9 +2869,9 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the discriminator values used by this class.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
*
* @return void
*
* @psalm-param array<string, class-string> $map
*
* @return void
*/
public function setDiscriminatorMap(array $map)
{
@@ -2886,12 +2884,11 @@ class ClassMetadataInfo implements ClassMetadata
* Adds one entry of the discriminator map with a new class and corresponding name.
*
* @param string $name
* @psalm-param class-string $className
*
* @return void
*
* @throws MappingException
*
* @psalm-param class-string $className
*/
public function addDiscriminatorMapClass($name, $className)
{
@@ -3071,9 +3068,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Sets definition.
*
* @return void
*
* @psalm-param array<string, string> $definition
*
* @return void
*/
public function setCustomGeneratorDefinition(array $definition)
{
@@ -3093,11 +3090,11 @@ class ClassMetadataInfo implements ClassMetadata
* )
* </code>
*
* @psalm-param array<string, string> $definition
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, string> $definition
*/
public function setSequenceGeneratorDefinition(array $definition)
{
@@ -3125,11 +3122,11 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the version field mapping used for versioning. Sets the default
* value to use depending on the column type.
*
* @psalm-param array<string, mixed> $mapping The version field mapping array.
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping The version field mapping array.
*/
public function setVersionMapping(array &$mapping)
{
@@ -3346,10 +3343,9 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @param string|null $className
* @psalm-param ?class-string $className
*
* @return string|null null if the input value is null
*
* @psalm-param ?class-string $className
*/
public function fullyQualifiedClassName($className)
{
@@ -3381,11 +3377,11 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Map Embedded Class
*
* @psalm-param array<string, mixed> $mapping
*
* @return void
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $mapping
*/
public function mapEmbedded(array $mapping)
{

View File

@@ -488,7 +488,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
/**
* @param mixed[] $joinColumns
*
* @psalm-param array<string, mixed> $mapping
*/
private function loadRelationShipMapping(
@@ -665,7 +664,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
* Parse the given JoinColumn as array
*
* @return mixed[]
*
* @psalm-return array{
* name: string,
* unique: bool,
@@ -693,7 +691,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
* @param string $fieldName
*
* @return mixed[]
*
* @psalm-return array{
* fieldName: string,
* type: mixed,

View File

@@ -145,10 +145,10 @@ class DatabaseDriver implements MappingDriver
/**
* Sets tables manually instead of relying on the reverse engineering capabilities of SchemaManager.
*
* @return void
*
* @psalm-param list<Table> $entityTables
* @psalm-param list<Table> $manyToManyTables
*
* @return void
*/
public function setTables($entityTables, $manyToManyTables)
{
@@ -498,7 +498,6 @@ class DatabaseDriver implements MappingDriver
* Retrieve schema table definition foreign keys.
*
* @return ForeignKeyConstraint[]
*
* @psalm-return array<string, ForeignKeyConstraint>
*/
private function getTableForeignKeys(Table $table)

View File

@@ -714,7 +714,6 @@ class XmlDriver extends FileDriver
* @param SimpleXMLElement $joinColumnElement The XML element.
*
* @return mixed[] The mapping array.
*
* @psalm-return array{
* name: string,
* referencedColumnName: string,
@@ -754,7 +753,6 @@ class XmlDriver extends FileDriver
* Parses the given field as array.
*
* @return mixed[]
*
* @psalm-return array{
* fieldName: string,
* type?: string,
@@ -822,7 +820,6 @@ class XmlDriver extends FileDriver
* Parse / Normalize the cache configuration
*
* @return mixed[]
*
* @psalm-return array{usage: mixed, region: string|null}
*/
private function cacheToArray(SimpleXMLElement $cacheMapping)
@@ -850,7 +847,6 @@ class XmlDriver extends FileDriver
* @param SimpleXMLElement $cascadeElement The cascade element.
*
* @return string[] The list of cascade options.
*
* @psalm-return list<string>
*/
private function getCascadeMappings(SimpleXMLElement $cascadeElement)
@@ -879,16 +875,19 @@ class XmlDriver extends FileDriver
if (isset($xmlElement->entity)) {
foreach ($xmlElement->entity as $entityElement) {
/** @psalm-var class-string */
$entityName = (string) $entityElement['name'];
$result[$entityName] = $entityElement;
}
} elseif (isset($xmlElement->{'mapped-superclass'})) {
foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) {
/** @psalm-var class-string */
$className = (string) $mappedSuperClass['name'];
$result[$className] = $mappedSuperClass;
}
} elseif (isset($xmlElement->embeddable)) {
foreach ($xmlElement->embeddable as $embeddableElement) {
/** @psalm-var class-string */
$embeddableName = (string) $embeddableElement['name'];
$result[$embeddableName] = $embeddableElement;
}

View File

@@ -689,8 +689,6 @@ class YamlDriver extends FileDriver
* Constructs a joinColumn mapping array based on the information
* found in the given join column element.
*
* @return mixed[] The mapping array.
*
* @psalm-param array{
* referencedColumnName?: mixed,
* name?: mixed,
@@ -700,6 +698,8 @@ class YamlDriver extends FileDriver
* onDelete?: mixed,
* columnDefinition?: mixed
* } $joinColumnElement The array join column element.
*
* @return mixed[] The mapping array.
* @psalm-return array{
* referencedColumnName?: string,
* name?: string,
@@ -747,8 +747,6 @@ class YamlDriver extends FileDriver
/**
* Parses the given column as array.
*
* @return mixed[]
*
* @psalm-param array{
* type?: string,
* column?: string,
@@ -760,6 +758,8 @@ class YamlDriver extends FileDriver
* version?: mixed,
* columnDefinition?: mixed
* }|null $column
*
* @return mixed[]
* @psalm-return array{
* fieldName: string,
* type?: string,
@@ -832,10 +832,9 @@ class YamlDriver extends FileDriver
* Parse / Normalize the cache configuration
*
* @param mixed[] $cacheMapping
* @psalm-param array{usage: mixed, region: (string|null)} $cacheMapping
*
* @return mixed[]
*
* @psalm-param array{usage: mixed, region: (string|null)} $cacheMapping
* @psalm-return array{usage: mixed, region: (string|null)}
*/
private function cacheToArray($cacheMapping)

View File

@@ -51,10 +51,9 @@ final class ReflectionPropertiesGetter
/**
* @param string $className
* @psalm-param class-string $className
*
* @return ReflectionProperty[] indexed by property internal name
*
* @psalm-param class-string $className
*/
public function getProperties($className)
{
@@ -77,9 +76,9 @@ final class ReflectionPropertiesGetter
/**
* @param string $className
* @psalm-param class-string $className
*
* @return ReflectionClass[]
*
* @psalm-return list<ReflectionClass>
*/
private function getHierarchyClasses($className): array
@@ -104,7 +103,6 @@ final class ReflectionPropertiesGetter
/**
* @return ReflectionProperty[]
*
* @psalm-return array<string, ReflectionProperty>
*/
private function getClassProperties(ReflectionClass $reflectionClass): array

View File

@@ -123,10 +123,9 @@ class ORMInvalidArgumentException extends InvalidArgumentException
/**
* @param object $entry
* @psalm-param array<string, string> $associationMapping
*
* @return ORMInvalidArgumentException
*
* @psalm-param array<string, string> $associationMapping
*/
public static function newEntityFoundThroughRelationship(array $associationMapping, $entry)
{
@@ -135,10 +134,9 @@ class ORMInvalidArgumentException extends InvalidArgumentException
/**
* @param object $entry
* @psalm-param array<string, string> $assoc
*
* @return ORMInvalidArgumentException
*
* @psalm-param array<string, string> $assoc
*/
public static function detachedEntityFoundThroughRelationship(array $assoc, $entry)
{

View File

@@ -111,7 +111,6 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
*
* @param EntityManagerInterface $em The EntityManager the collection will be associated with.
* @param ClassMetadata $class The class descriptor of the entity type of this collection.
*
* @psalm-param Collection<TKey, T> $collection The collection elements.
*/
public function __construct(EntityManagerInterface $em, $class, Collection $collection)
@@ -128,10 +127,9 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
* describes the association between the owner and the elements of the collection.
*
* @param object $entity
* @psalm-param array<string, mixed> $assoc
*
* @return void
*
* @psalm-param array<string, mixed> $assoc
*/
public function setOwner($entity, array $assoc)
{
@@ -605,7 +603,6 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
* with circular references. This solution seems simpler and works well.
*
* @return string[]
*
* @psalm-return array{0: string, 1: string}
*/
public function __sleep(): array

View File

@@ -298,11 +298,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
* have to join in the actual entities table leading to additional
* JOIN.
*
* @psalm-param array<string, mixed> $mapping Array containing mapping information.
*
* @return string[] ordered tuple:
* - JOIN condition to add to the SQL
* - WHERE condition to add to the SQL
*
* @psalm-param array<string, mixed> $mapping Array containing mapping information.
* @psalm-return array{0: string, 1: string}
*/
public function getFilterSql($mapping)
@@ -350,9 +350,9 @@ class ManyToManyPersister extends AbstractCollectionPersister
/**
* Generate ON condition
*
* @return string[]
*
* @psalm-param array<string, mixed> $mapping
*
* @return string[]
* @psalm-return list<string>
*/
protected function getOnConditionSQL($mapping)
@@ -429,7 +429,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
*
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
* of types for bound parameters
*
* @psalm-return array{0: string, 1: list<string>}
*/
protected function getDeleteRowSQL(PersistentCollection $collection)
@@ -477,7 +476,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
*
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
* of types for bound parameters
*
* @psalm-return array{0: string, 1: list<string>}
*/
protected function getInsertRowSQL(PersistentCollection $collection)
@@ -529,7 +527,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @param object $element
*
* @return mixed[]
*
* @psalm-return list<mixed>
*/
private function collectJoinTableColumnParameters(PersistentCollection $collection, $element)
@@ -577,7 +574,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
* - where clauses to be added for filtering
* - parameters to be bound for filtering
* - types of the parameters to be bound for filtering
*
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
*/
private function getJoinTableRestrictionsWithKey(PersistentCollection $collection, $key, $addFilters)
@@ -663,7 +659,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
* - where clauses to be added for filtering
* - parameters to be bound for filtering
* - types of the parameters to be bound for filtering
*
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
*/
private function getJoinTableRestrictions(PersistentCollection $collection, $element, $addFilters)

View File

@@ -24,9 +24,9 @@ use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\Comparison;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\ResultStatement as DriverStatement;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Statement;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
@@ -362,7 +362,6 @@ class BasicEntityPersister implements EntityPersister
* @param mixed[] $id
*
* @return int[]|null[]|string[]
*
* @psalm-return list<(int|string|null)>
*/
private function extractIdentifierTypes(array $id, ClassMetadata $versionedClass): array
@@ -611,7 +610,6 @@ class BasicEntityPersister implements EntityPersister
* @param object $entity The entity for which to prepare the data.
*
* @return mixed[][] The prepared data.
*
* @psalm-return array<string, array<array-key, mixed|null>>
*/
protected function prepareUpdateData($entity)
@@ -703,7 +701,6 @@ class BasicEntityPersister implements EntityPersister
* @param object $entity The entity for which to prepare the data.
*
* @return mixed[][] The prepared data for the tables to update.
*
* @psalm-return array<string, mixed[]>
*/
protected function prepareInsertData($entity)
@@ -922,8 +919,8 @@ class BasicEntityPersister implements EntityPersister
/**
* Loads an array of entities from a given DBAL statement.
*
* @param mixed[] $assoc
* @param Statement $stmt
* @param mixed[] $assoc
* @param DriverStatement $stmt
*
* @return mixed[]
*/
@@ -944,7 +941,7 @@ class BasicEntityPersister implements EntityPersister
* Hydrates a collection from a given DBAL statement.
*
* @param mixed[] $assoc
* @param Statement $stmt
* @param DriverStatement $stmt
* @param PersistentCollection $coll
*
* @return mixed[]
@@ -976,11 +973,11 @@ class BasicEntityPersister implements EntityPersister
}
/**
* @return \Doctrine\DBAL\Driver\Statement
* @psalm-param array<string, mixed> $assoc
*
* @return DriverStatement
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $assoc
*/
private function getManyToManyStatement(
array $assoc,
@@ -1140,9 +1137,9 @@ class BasicEntityPersister implements EntityPersister
/**
* Gets the ORDER BY SQL snippet for ordered collections.
*
* @throws ORMException
*
* @psalm-param array<string, string> $orderBy
*
* @throws ORMException
*/
final protected function getOrderBySQL(array $orderBy, string $baseTableAlias): string
{
@@ -1350,9 +1347,9 @@ class BasicEntityPersister implements EntityPersister
* Gets the SQL join fragment used when selecting entities from a
* many-to-many association.
*
* @return string
*
* @psalm-param array<string, mixed> $manyToMany
*
* @return string
*/
protected function getSelectManyToManyJoinSQL(array $manyToMany)
{
@@ -1431,7 +1428,6 @@ class BasicEntityPersister implements EntityPersister
* columns placed in the INSERT statements used by the persister.
*
* @return string[] The list of columns.
*
* @psalm-return list<string>
*/
protected function getInsertColumnList()
@@ -1661,13 +1657,12 @@ class BasicEntityPersister implements EntityPersister
* Builds the left-hand-side of a where condition statement.
*
* @param string $field
* @psalm-param array<string, mixed>|null $assoc
*
* @return string[]
* @psalm-return list<string>
*
* @throws ORMException
*
* @psalm-param array<string, mixed>|null $assoc
* @psalm-return list<string>
*/
private function getSelectConditionStatementColumnSQL($field, $assoc = null)
{
@@ -1729,10 +1724,10 @@ class BasicEntityPersister implements EntityPersister
* Subclasses are supposed to override this method if they intend to change
* or alter the criteria by which entities are selected.
*
* @return string
*
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, mixed>|null $assoc
*
* @return string
*/
protected function getSelectConditionSQL(array $criteria, $assoc = null)
{
@@ -1773,10 +1768,9 @@ class BasicEntityPersister implements EntityPersister
* @param object $sourceEntity
* @param int|null $offset
* @param int|null $limit
*
* @return Statement
*
* @psalm-param array<string, mixed> $assoc
*
* @return DriverStatement
*/
private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
{
@@ -1855,7 +1849,6 @@ class BasicEntityPersister implements EntityPersister
* - class to which the field belongs to
*
* @return mixed[][]
*
* @psalm-return array{0: array, 1: list<mixed>}
*/
private function expandToManyParameters($criteria)
@@ -1882,10 +1875,9 @@ class BasicEntityPersister implements EntityPersister
* @param mixed $value
*
* @return int[]|null[]|string[]
* @psalm-return list<(int|string|null)>
*
* @throws QueryException
*
* @psalm-return list<(int|string|null)>
*/
private function getTypes($field, $value, ClassMetadata $class)
{
@@ -2020,9 +2012,9 @@ class BasicEntityPersister implements EntityPersister
/**
* Generates the appropriate join SQL for the given join column.
*
* @return string LEFT JOIN if one of the columns is nullable, INNER JOIN otherwise.
*
* @psalm-param array<array<string, mixed>> $joinColumns The join columns definition of an association.
*
* @return string LEFT JOIN if one of the columns is nullable, INNER JOIN otherwise.
*/
protected function getJoinSQLForJoinColumns($joinColumns)
{

View File

@@ -106,10 +106,9 @@ interface EntityPersister
* @param string $field
* @param mixed $value
* @param string|null $comparison
* @psalm-param array<string, mixed>|null $assoc
*
* @return string
*
* @psalm-param array<string, mixed>|null $assoc
*/
public function getSelectConditionStatementSQL($field, $value, $assoc = null, $comparison = null);
@@ -192,9 +191,6 @@ interface EntityPersister
* or NULL if no specific lock mode should be used
* for loading the entity.
* @param int|null $limit Limit number of results.
*
* @return object|null The loaded and managed entity instance or NULL if the entity can not be found.
*
* @psalm-param array<string, mixed> $hints Hints for entity creation.
* @psalm-param array<string, mixed> $criteria The criteria by which
* to load the entity.
@@ -203,6 +199,9 @@ interface EntityPersister
* load to another entity,
* if any.
* @psalm-param array<string, string>|null $orderBy Criteria to order by.
*
* @return object|null The loaded and managed entity instance or NULL if the entity can not be found.
*
* @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
*/
public function load(
@@ -219,10 +218,10 @@ interface EntityPersister
* Loads an entity by identifier.
*
* @param object|null $entity The entity to load the data into. If not specified, a new entity is created.
*
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
*
* @psalm-param array<string, mixed> $identifier The entity identifier.
*
* @return object|null The loaded and managed entity instance or NULL if the entity can not be found.
*
* @todo Check parameters
*/
public function loadById(array $identifier, $entity = null);
@@ -232,15 +231,14 @@ interface EntityPersister
* association from another entity.
*
* @param object $sourceEntity The entity that owns the association (not necessarily the "owning side").
*
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
*
* @throws MappingException
*
* @psalm-param array<string, mixed> $identifier The identifier of the entity to load. Must be provided if
* the association to load represents the owning side, otherwise
* the identifier is derived from the $sourceEntity.
* @psalm-param array<string, mixed> $assoc The association to load.
*
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
*
* @throws MappingException
*/
public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = []);
@@ -251,12 +249,11 @@ interface EntityPersister
* @param int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
* or NULL if no specific lock mode should be used
* for refreshing the managed entity.
*
* @return void
*
* @psalm-param array<string, mixed> $id The identifier of the entity as an
* associative array from column or
* field names to values.
*
* @return void
*/
public function refresh(array $id, $entity, $lockMode = null);
@@ -272,9 +269,8 @@ interface EntityPersister
*
* @param int|null $limit
* @param int|null $offset
*
* @psalm-param list<string>|null $orderBy
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
* @psalm-param array<string, mixed> $criteria
*/
public function loadAll(array $criteria = [], ?array $orderBy = null, $limit = null, $offset = null);
@@ -284,10 +280,9 @@ interface EntityPersister
* @param object $sourceEntity
* @param int|null $offset
* @param int|null $limit
* @psalm-param array<string, mixed> $assoc
*
* @return mixed[]
*
* @psalm-param array<string, mixed> $assoc
*/
public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null);
@@ -296,10 +291,9 @@ interface EntityPersister
*
* @param object $sourceEntity The entity that owns the collection.
* @param PersistentCollection $collection The collection to fill.
* @psalm-param array<string, mixed> $assoc The association mapping of the association being loaded.
*
* @return mixed[]
*
* @psalm-param array<string, mixed> $assoc The association mapping of the association being loaded.
*/
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection);
@@ -308,10 +302,9 @@ interface EntityPersister
*
* @param object $sourceEntity
* @param PersistentCollection $collection The collection to load/fill.
* @psalm-param array<string, mixed> $assoc
*
* @return mixed
*
* @psalm-param array<string, mixed> $assoc
*/
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection);
@@ -319,10 +312,9 @@ interface EntityPersister
* Locks all rows of this entity matching the given criteria with the specified pessimistic lock mode.
*
* @param int $lockMode One of the Doctrine\DBAL\LockMode::* constants.
* @psalm-param array<string, mixed> $criteria
*
* @return void
*
* @psalm-param array<string, mixed> $criteria
*/
public function lock(array $criteria, $lockMode);
@@ -332,10 +324,9 @@ interface EntityPersister
* @param object $sourceEntity
* @param int|null $offset
* @param int|null $limit
* @psalm-param array<string, mixed> $assoc
*
* @return mixed[]
*
* @psalm-param array<string, mixed> $assoc
*/
public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null);

View File

@@ -83,7 +83,6 @@ class SqlValueVisitor extends ExpressionVisitor
* Returns the Parameters and Types necessary for matching the last visited expression.
*
* @return mixed[][]
*
* @psalm-return array{0: array, 1: array}
*/
public function getParamsAndTypes()

View File

@@ -110,10 +110,9 @@ class ProxyFactory extends AbstractProxyFactory
* Creates a closure capable of initializing a proxy
*
* @return Closure
* @psalm-return Closure(BaseProxy ): void
*
* @throws EntityNotFoundException
*
* @psalm-return Closure(BaseProxy ): void
*/
private function createInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister)
{
@@ -163,10 +162,9 @@ class ProxyFactory extends AbstractProxyFactory
* Creates a closure capable of finalizing state a cloned proxy
*
* @return Closure
* @psalm-return Closure(BaseProxy ): void
*
* @throws EntityNotFoundException
*
* @psalm-return Closure(BaseProxy ): void
*/
private function createCloner(ClassMetadata $classMetadata, EntityPersister $entityPersister)
{

View File

@@ -374,10 +374,9 @@ final class Query extends AbstractQuery
* @param Parameter[] $paramMappings
*
* @return mixed[][]
* @psalm-return array{0: list<mixed>, 1: array}
*
* @throws Query\QueryException
*
* @psalm-return array{0: list<mixed>, 1: array}
*/
private function processParameterMappings(array $paramMappings): array
{
@@ -426,7 +425,6 @@ final class Query extends AbstractQuery
/**
* @return mixed[] tuple of (value, type)
*
* @psalm-return array{0: mixed, 1: mixed}
*/
private function resolveParameterValue(Parameter $parameter): array

View File

@@ -22,7 +22,7 @@ namespace Doctrine\ORM\Query\Exec;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Types\Type;
/**
@@ -72,12 +72,11 @@ abstract class AbstractSqlExecutor
* Executes all sql statements.
*
* @param Connection $conn The database connection that is used to execute the queries.
*
* @return Statement
*
* @psalm-param array<int, mixed>|array<string, mixed> $params The parameters.
* @psalm-param array<int, int|string|Type|null>|
* array<string, int|string|Type|null> $types The parameter types.
*
* @return ResultStatement|int
*/
abstract public function execute(Connection $conn, array $params, array $types);
}

View File

@@ -21,6 +21,7 @@
namespace Doctrine\ORM\Query\Exec;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\ORM\Query\AST\SelectStatement;
use Doctrine\ORM\Query\SqlWalker;
@@ -38,6 +39,8 @@ class SingleSelectExecutor extends AbstractSqlExecutor
/**
* {@inheritDoc}
*
* @return ResultStatement
*/
public function execute(Connection $conn, array $params, array $types)
{

View File

@@ -60,9 +60,9 @@ abstract class Base
}
/**
* @return static
*
* @psalm-param list<string|object> $args
*
* @return static
*/
public function addMultiple($args = [])
{

View File

@@ -63,7 +63,7 @@ class Composite extends Base
}
// Fixes DDC-1237: User may have added a where item containing nested expression (with "OR" or "AND")
if (preg_match('/\s(OR|AND)\s/', $queryPart)) {
if (preg_match('/\s(OR|AND)\s/i', $queryPart)) {
return $this->preSeparator . $queryPart . $this->postSeparator;
}

View File

@@ -39,7 +39,6 @@ class Func
* Creates a function, with the given argument.
*
* @param string $name
*
* @psalm-param list<mixed> $arguments
*/
public function __construct($name, $arguments)

View File

@@ -20,7 +20,7 @@
namespace Doctrine\ORM\Query;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\AST\AggregateExpression;
@@ -190,7 +190,7 @@ class Parser
/**
* The EntityManager.
*
* @var EntityManager
* @var EntityManagerInterface
*/
private $em;
@@ -261,9 +261,9 @@ class Parser
/**
* Adds a custom tree walker for modifying the AST.
*
* @return void
*
* @psalm-param class-string $className
*
* @return void
*/
public function addCustomTreeWalker($className)
{
@@ -293,7 +293,7 @@ class Parser
/**
* Gets the EntityManager used by the parser.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{
@@ -491,12 +491,11 @@ class Parser
* Generates a new syntax error.
*
* @param string $expected Expected string.
* @psalm-param array<string, mixed>|null $token Got token.
*
* @return void
*
* @throws QueryException
*
* @psalm-param array<string, mixed>|null $token Got token.
*/
public function syntaxError($expected = '', $token = null)
{
@@ -517,12 +516,11 @@ class Parser
* Generates a new semantical error.
*
* @param string $message Optional message.
* @psalm-param array<string, mixed>|null $token Optional token.
*
* @return void
*
* @throws QueryException
*
* @psalm-param array<string, mixed>|null $token Optional token.
*/
public function semanticalError($message = '', $token = null)
{
@@ -613,9 +611,9 @@ class Parser
/**
* Checks whether the given token type indicates an aggregate function.
*
* @return bool TRUE if the token type is an aggregate function, FALSE otherwise.
*
* @psalm-param Lexer::T_* $tokenType
*
* @return bool TRUE if the token type is an aggregate function, FALSE otherwise.
*/
private function isAggregateFunction(int $tokenType): bool
{

View File

@@ -165,9 +165,9 @@ class QueryException extends ORMException
}
/**
* @return QueryException
*
* @psalm-param array<string, string> $assoc
*
* @return QueryException
*/
public static function iterateWithFetchJoinCollectionNotAllowed($assoc)
{
@@ -190,9 +190,9 @@ class QueryException extends ORMException
}
/**
* @return QueryException
*
* @psalm-param array<string, string> $assoc
*
* @return QueryException
*/
public static function overwritingJoinConditionsNotYetSupported($assoc)
{
@@ -215,9 +215,9 @@ class QueryException extends ORMException
}
/**
* @return QueryException
*
* @psalm-param array<string, string> $assoc
*
* @return QueryException
*/
public static function iterateWithFetchJoinNotAllowed($assoc)
{

View File

@@ -87,10 +87,9 @@ class ResultSetMappingBuilder extends ResultSetMapping
* @param string $class The class name of the root entity.
* @param string $alias The unique alias to use for the root entity.
* @param int|null $renameMode One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM).
* @psalm-param array<string, string> $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
*
* @return void
*
* @psalm-param array<string, string> $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
*/
public function addRootEntityFromClassMetadata($class, $alias, $renamedColumns = [], $renameMode = null)
{
@@ -110,10 +109,9 @@ class ResultSetMappingBuilder extends ResultSetMapping
* @param string $relation The association field that connects the parent entity result
* with the joined entity result.
* @param int|null $renameMode One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM).
* @psalm-param array<string, string> $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
*
* @return void
*
* @psalm-param array<string, string> $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
*/
public function addJoinedEntityFromClassMetadata($class, $alias, $parentAlias, $relation, $renamedColumns = [], $renameMode = null)
{
@@ -129,12 +127,11 @@ class ResultSetMappingBuilder extends ResultSetMapping
*
* @param string $class
* @param string $alias
* @psalm-param array<string, string> $columnAliasMap
*
* @return void
*
* @throws InvalidArgumentException
*
* @psalm-param array<string, string> $columnAliasMap
*/
protected function addAllClassFields($class, $alias, $columnAliasMap = [])
{
@@ -199,10 +196,9 @@ class ResultSetMappingBuilder extends ResultSetMapping
*
* @param string $columnName
* @param int $mode
* @psalm-param array<string, string> $customRenameColumns
*
* @return string
*
* @psalm-param array<string, string> $customRenameColumns
*/
private function getColumnAlias($columnName, $mode, array $customRenameColumns)
{
@@ -225,10 +221,9 @@ class ResultSetMappingBuilder extends ResultSetMapping
*
* @param string $className
* @param int $mode
* @psalm-param array<string, string> $customRenameColumns
*
* @return string[]
*
* @psalm-param array<string, string> $customRenameColumns
* @psalm-return array<array-key, string>
*/
private function getColumnAliasMap($className, $mode, array $customRenameColumns)
@@ -430,9 +425,9 @@ class ResultSetMappingBuilder extends ResultSetMapping
* Works only for all the entity results. The select parts for scalar
* expressions have to be written manually.
*
* @return string
*
* @psalm-param array<string, string> $tableAliases
*
* @return string
*/
public function generateSelectClause($tableAliases = [])
{

View File

@@ -25,7 +25,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Mapping\QuoteStrategy;
@@ -107,7 +107,7 @@ class SqlWalker implements TreeWalker
/** @var ParserResult */
private $parserResult;
/** @var EntityManager */
/** @var EntityManagerInterface */
private $em;
/** @var Connection */
@@ -228,7 +228,7 @@ class SqlWalker implements TreeWalker
/**
* Gets the EntityManager used by the walker.
*
* @return EntityManager
* @return EntityManagerInterface
*/
public function getEntityManager()
{

View File

@@ -41,7 +41,6 @@ interface TreeWalker
* Returns internal queryComponents array.
*
* @return array<string, array<string, mixed>>
*
* @psalm-return array<string, array{
* metadata: ClassMetadata,
* parent: string,

View File

@@ -56,7 +56,6 @@ class TreeWalkerChainIterator implements Iterator, ArrayAccess
/**
* @return string|false
*
* @psalm-return class-string<TreeWalker>|false
*/
public function rewind()

View File

@@ -455,7 +455,6 @@ class QueryBuilder
* </code>
*
* @return mixed[]
*
* @psalm-return list<mixed>
*/
public function getRootAliases()
@@ -491,7 +490,6 @@ class QueryBuilder
* </code>
*
* @return mixed[]
*
* @psalm-return list<mixed>
*/
public function getAllAliases()
@@ -512,7 +510,6 @@ class QueryBuilder
* </code>
*
* @return mixed[]
*
* @psalm-return list<mixed>
*/
public function getRootEntities()
@@ -695,10 +692,9 @@ class QueryBuilder
*
* @param string $dqlPartName The DQL part name.
* @param bool $append Whether to append (true) or replace (false).
* @psalm-param string|object|list<string>|array{join: array<int|string, object>} $dqlPart An Expr object.
*
* @return self
*
* @psalm-param string|object|list<string>|array{join: array<int|string, object>} $dqlPart An Expr object.
*/
public function add($dqlPartName, $dqlPart, $append = false)
{
@@ -1469,9 +1465,9 @@ class QueryBuilder
/**
* Resets DQL parts.
*
* @return self
*
* @psalm-param list<string>|null $parts
*
* @return self
*/
public function resetDQLParts($parts = null)
{

View File

@@ -149,6 +149,7 @@ EOT
* Return all mapped entity class names
*
* @return string[]
* @psalm-return class-string[]
*/
private function getMappedEntities(EntityManagerInterface $entityManager): array
{
@@ -253,7 +254,6 @@ EOT
* @param mixed $value A Value to show
*
* @return string[]
*
* @psalm-return array{0: string, 1: string}
*/
private function formatField($label, $value): array
@@ -268,9 +268,9 @@ EOT
/**
* Format the association mappings
*
* @return string[][]
*
* @psalm-param array<string, array<string, mixed>> $propertyMappings
*
* @return string[][]
* @psalm-return list<array{0: string, 1: string}>
*/
private function formatMappings(array $propertyMappings): array
@@ -291,9 +291,9 @@ EOT
/**
* Format the entity listeners
*
* @return string[]
*
* @psalm-param list<object> $entityListeners
*
* @return string[]
* @psalm-return array{0: string, 1: string}
*/
private function formatEntityListeners(array $entityListeners): array

View File

@@ -26,6 +26,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata;
use FilterIterator;
use RuntimeException;
use function assert;
use function count;
use function iterator_to_array;
use function preg_match;
@@ -79,7 +80,7 @@ class MetadataFilter extends FilterIterator implements Countable
$metadata = $it->current();
foreach ($this->filter as $filter) {
$pregResult = preg_match('/' . $filter . '/', $metadata->name);
$pregResult = preg_match('/' . $filter . '/', $metadata->getName());
if ($pregResult === false) {
throw new RuntimeException(
@@ -95,6 +96,18 @@ class MetadataFilter extends FilterIterator implements Countable
return false;
}
/**
* @return ArrayIterator<int, ClassMetadata>
*/
public function getInnerIterator()
{
$innerIterator = parent::getInnerIterator();
assert($innerIterator instanceof ArrayIterator);
return $innerIterator;
}
/**
* @return int
*/

View File

@@ -71,7 +71,6 @@ class ConvertDoctrine1Schema
* Doctrine 1 schema.
*
* @return ClassMetadataInfo[] An array of ClassMetadataInfo instances
*
* @psalm-return list<ClassMetadataInfo>
*/
public function getMetadata()
@@ -203,7 +202,9 @@ class ConvertDoctrine1Schema
throw ToolsException::couldNotMapDoctrine1Type($column['type']);
}
$fieldMapping = [];
$fieldMapping = [
'nullable' => ! ($column['notnull'] ?? true), // Doctrine 1 columns are nullable by default
];
if (isset($column['primary'])) {
$fieldMapping['id'] = true;
@@ -217,7 +218,7 @@ class ConvertDoctrine1Schema
$fieldMapping['length'] = $column['length'];
}
$allowed = ['precision', 'scale', 'unique', 'options', 'notnull', 'version'];
$allowed = ['precision', 'scale', 'unique', 'options', 'version'];
foreach ($column as $key => $value) {
if (in_array($key, $allowed)) {

View File

@@ -384,10 +384,9 @@ public function __construct(<params>)
* Generates and writes entity classes for the given array of ClassMetadataInfo instances.
*
* @param string $outputDirectory
* @psalm-param list<ClassMetadataInfo> $metadatas
*
* @return void
*
* @psalm-param list<ClassMetadataInfo> $metadatas
*/
public function generate(array $metadatas, $outputDirectory)
{
@@ -539,12 +538,11 @@ public function __construct(<params>)
* Sets the class fields visibility for the entity (can either be private or protected).
*
* @param string $visibility
* @psalm-param self::FIELD_VISIBLE_*
*
* @return void
*
* @throws InvalidArgumentException
*
* @psalm-param self::FIELD_VISIBLE_*
*/
public function setFieldVisibility($visibility)
{
@@ -946,10 +944,9 @@ public function __construct(<params>)
/**
* @return ReflectionClass[]
* @psalm-return array<trait-string, ReflectionClass>
*
* @throws ReflectionException
*
* @psalm-return array<trait-string, ReflectionClass>
*/
protected function getTraits(ClassMetadataInfo $metadata)
{
@@ -1115,10 +1112,9 @@ public function __construct(<params>)
/**
* @param string $constraintName
* @psalm-param array<string, array<string, mixed>> $constraints
*
* @return string
*
* @psalm-param array<string, array<string, mixed>> $constraints
*/
protected function generateTableConstraints($constraintName, array $constraints)
{
@@ -1286,9 +1282,9 @@ public function __construct(<params>)
}
/**
* @return bool
*
* @psalm-param array<string, mixed> $associationMapping
*
* @return bool
*/
protected function isAssociationIsNullable(array $associationMapping)
{
@@ -1490,9 +1486,9 @@ public function __construct(<params>)
}
/**
* @return string
*
* @psalm-param array<string, mixed> $joinColumn
*
* @return string
*/
protected function generateJoinColumnAnnotation(array $joinColumn)
{
@@ -1812,9 +1808,9 @@ public function __construct(<params>)
}
/**
* @return string
*
* @psalm-param array<string, mixed> $embeddedClass
*
* @return string
*/
protected function generateEmbeddedPropertyDocBlock(array $embeddedClass)
{

View File

@@ -88,9 +88,9 @@ abstract class AbstractExporter
/**
* Sets the array of ClassMetadata instances to export.
*
* @return void
*
* @psalm-param list<ClassMetadata> $metadata
*
* @return void
*/
public function setMetadata(array $metadata)
{
@@ -187,10 +187,9 @@ abstract class AbstractExporter
/**
* @param int $type
* @psalm-param ClassMetadataInfo::INHERITANCE_TYPE_* $type
*
* @return string
*
* @psalm-param ClassMetadataInfo::INHERITANCE_TYPE_* $type
*/
protected function _getInheritanceTypeString($type)
{
@@ -211,10 +210,9 @@ abstract class AbstractExporter
/**
* @param int $mode
* @psalm-param ClassMetadataInfo::FETCH_* $mode
*
* @return string
*
* @psalm-param ClassMetadataInfo::FETCH_* $mode
*/
protected function _getFetchModeString($mode)
{
@@ -232,10 +230,9 @@ abstract class AbstractExporter
/**
* @param int $policy
* @psalm-param ClassMetadataInfo::CHANGETRACKING_* $policy
*
* @return string
*
* @psalm-param ClassMetadataInfo::CHANGETRACKING_* $policy
*/
protected function _getChangeTrackingPolicyString($policy)
{
@@ -253,10 +250,9 @@ abstract class AbstractExporter
/**
* @param int $type
* @psalm-param ClassMetadataInfo::GENERATOR_TYPE_* $type
*
* @return string
*
* @psalm-param ClassMetadataInfo::GENERATOR_TYPE_* $type
*/
protected function _getIdGeneratorTypeString($type)
{

View File

@@ -197,7 +197,6 @@ class PhpExporter extends AbstractExporter
/**
* @return string[]
*
* @psalm-return list<string>
*/
private function processEntityListeners(ClassMetadataInfo $metadata): array

View File

@@ -245,6 +245,7 @@ class YamlExporter extends AbstractExporter
/**
* @psalm-param array<string, mixed> $array
*
* @psalm-return array<string, mixed>&array{entityListeners: array<class-string, array<string, array{string}>>}
*/
private function processEntityListeners(ClassMetadataInfo $metadata, array $array): array
@@ -265,6 +266,7 @@ class YamlExporter extends AbstractExporter
/**
* @psalm-param array{entityListeners: array<class-string, array<string, array{string}>>} $array
* @psalm-param list<array{class: class-string, method: string}> $entityListenerConfig
*
* @psalm-return array{entityListeners: array<class-string, array<string, array{string}>>}
*/
private function processEntityListenerConfig(

View File

@@ -26,7 +26,7 @@ use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\QuoteStrategy;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Query;
@@ -81,7 +81,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
/** @var int */
private $maxResults;
/** @var EntityManager */
/** @var EntityManagerInterface */
private $em;
/**
@@ -514,7 +514,6 @@ class LimitSubqueryOutputWalker extends SqlWalker
/**
* @return array-key[]
*
* @psalm-return array<array-key, array-key>
*/
private function getSQLIdentifier(SelectStatement $AST)

View File

@@ -58,10 +58,9 @@ class ResolveTargetEntityListener implements EventSubscriber
*
* @param string $originalEntity
* @param string $newEntity
* @psalm-param array<string, mixed> $mapping
*
* @return void
*
* @psalm-param array<string, mixed> $mapping
*/
public function addResolveTargetEntity($originalEntity, $newEntity, array $mapping)
{

View File

@@ -87,11 +87,11 @@ class SchemaTool
/**
* Creates the database schema for the given array of ClassMetadata instances.
*
* @psalm-param list<ClassMetadata> $classes
*
* @return void
*
* @throws ToolsException
*
* @psalm-param list<ClassMetadata> $classes
*/
public function createSchema(array $classes)
{
@@ -111,9 +111,9 @@ class SchemaTool
* Gets the list of DDL statements that are required to create the database schema for
* the given list of ClassMetadata instances.
*
* @return string[] The SQL statements needed to create the schema for the classes.
*
* @psalm-param list<ClassMetadata> $classes
*
* @return string[] The SQL statements needed to create the schema for the classes.
*/
public function getCreateSchemaSql(array $classes)
{
@@ -140,11 +140,11 @@ class SchemaTool
/**
* Creates a Schema instance from a given set of metadata classes.
*
* @psalm-param list<ClassMetadata> $classes
*
* @return Schema
*
* @throws ORMException
*
* @psalm-param list<ClassMetadata> $classes
*/
public function getSchemaFromMetadata(array $classes)
{
@@ -431,7 +431,6 @@ class SchemaTool
* Creates a column definition as required by the DBAL from an ORM field mapping definition.
*
* @param ClassMetadata $class The class that owns the field mapping.
*
* @psalm-param array<string, mixed> $mapping The field mapping.
*/
private function gatherColumn(
@@ -500,13 +499,13 @@ class SchemaTool
* Gathers the SQL for properly setting up the relations of the given class.
* This includes the SQL for foreign key constraints and join tables.
*
* @throws ORMException
*
* @psalm-param array<string, array{
* foreignTableName: string,
* foreignColumns: list<string>
* }> $addedFks
* @psalm-param array<string, bool> $blacklistedFks
*
* @throws ORMException
*/
private function gatherRelationsSql(
ClassMetadata $class,
@@ -614,8 +613,6 @@ class SchemaTool
/**
* Gathers columns and fk constraints that are required for one part of relationship.
*
* @throws ORMException
*
* @psalm-param array<string, mixed> $joinColumns
* @psalm-param array<string, mixed> $mapping
* @psalm-param list<string> $primaryKeyColumns
@@ -624,6 +621,8 @@ class SchemaTool
* foreignColumns: list<string>
* }> $addedFks
* @psalm-param array<string,bool> $blacklistedFks
*
* @throws ORMException
*/
private function gatherRelationJoinColumns(
array $joinColumns,
@@ -763,9 +762,9 @@ class SchemaTool
* In any way when an exception is thrown it is suppressed since drop was
* issued for all classes of the schema and some probably just don't exist.
*
* @return void
*
* @psalm-param list<ClassMetadata> $classes
*
* @return void
*/
public function dropSchema(array $classes)
{
@@ -815,9 +814,9 @@ class SchemaTool
/**
* Gets SQL to drop the tables defined by the passed classes.
*
* @return string[]
*
* @psalm-param list<ClassMetadata> $classes
*
* @return string[]
*/
public function getDropSchemaSQL(array $classes)
{

View File

@@ -80,7 +80,6 @@ class SchemaValidator
* Validates a single class of the current.
*
* @return string[]
*
* @psalm-return list<string>
*/
public function validateClass(ClassMetadataInfo $class)

View File

@@ -24,6 +24,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\EventManager;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\Cache\Persister\CachedPersister;
use Doctrine\ORM\Event\LifecycleEventArgs;
@@ -45,7 +46,6 @@ use Doctrine\ORM\Persisters\Entity\BasicEntityPersister;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use Doctrine\ORM\Persisters\Entity\JoinedSubclassPersister;
use Doctrine\ORM\Persisters\Entity\SingleTablePersister;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\ORM\Utility\IdentifierFlattener;
use Doctrine\Persistence\Mapping\RuntimeReflectionService;
use Doctrine\Persistence\NotifyPropertyChanged;
@@ -298,7 +298,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Map of Entity Class-Names and corresponding IDs that should eager loaded when requested.
*
* @psalm-var array<string, array<string, mixed>>
* @psalm-var array<class-string, array<string, mixed>>
*/
private $eagerLoadingEntities = [];
@@ -558,7 +558,7 @@ class UnitOfWork implements PropertyChangedListener
}
// Ignore uninitialized proxy objects
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
if ($entity instanceof Proxy && ! $entity->__isInitialized()) {
return;
}
@@ -629,8 +629,6 @@ class UnitOfWork implements PropertyChangedListener
* If a PersistentCollection has been de-referenced in a fully MANAGED entity,
* then this collection is marked for deletion.
*
* @internal Don't call from the outside.
*
* @param ClassMetadata $class The class descriptor of the entity.
* @param object $entity The entity for which to compute the changes.
*
@@ -865,7 +863,7 @@ class UnitOfWork implements PropertyChangedListener
foreach ($entitiesToProcess as $entity) {
// Ignore uninitialized proxy objects
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
if ($entity instanceof Proxy && ! $entity->__isInitialized()) {
continue;
}
@@ -883,15 +881,14 @@ class UnitOfWork implements PropertyChangedListener
* Computes the changes of an association.
*
* @param mixed $value The value of the association.
* @psalm-param array<string, mixed> $assoc The association mapping.
*
* @throws ORMInvalidArgumentException
* @throws ORMException
*
* @psalm-param array<string, mixed> $assoc The association mapping.
*/
private function computeAssociationChanges(array $assoc, $value): void
{
if ($value instanceof Proxy && ! $value->__isInitialized__) {
if ($value instanceof Proxy && ! $value->__isInitialized()) {
return;
}
@@ -1412,10 +1409,10 @@ class UnitOfWork implements PropertyChangedListener
* Extra updates for entities are stored as (entity, changeset) tuples.
*
* @param object $entity The entity for which to schedule an extra update.
* @psalm-param array<string, array{mixed, mixed}> $changeset The changeset of the entity (what to update).
*
* @return void
*
* @psalm-param array<string, array{mixed, mixed}> $changeset The changeset of the entity (what to update).
* @ignore
*/
public function scheduleExtraUpdate($entity, array $changeset)
@@ -1772,11 +1769,10 @@ class UnitOfWork implements PropertyChangedListener
* the already visited entities to prevent infinite recursions.
*
* @param object $entity The entity to persist.
* @psalm-param array<string, object> $visited The already visited entities.
*
* @throws ORMInvalidArgumentException
* @throws UnexpectedValueException
*
* @psalm-param array<string, object> $visited The already visited entities.
*/
private function doPersist(object $entity, array &$visited): void
{
@@ -1858,11 +1854,10 @@ class UnitOfWork implements PropertyChangedListener
* the already visited entities to prevent infinite recursions.
*
* @param object $entity The entity to delete.
* @psalm-param array<string, object> $visited The map of the already visited entities.
*
* @throws ORMInvalidArgumentException If the instance is a detached entity.
* @throws UnexpectedValueException
*
* @psalm-param array<string, object> $visited The map of the already visited entities.
*/
private function doRemove($entity, array &$visited): void
{
@@ -1932,6 +1927,7 @@ class UnitOfWork implements PropertyChangedListener
* Executes a merge operation on an entity.
*
* @param string[] $assoc
* @psalm-param array<string, object> $visited
*
* @return object The managed copy of the entity.
*
@@ -1939,8 +1935,6 @@ class UnitOfWork implements PropertyChangedListener
* attribute and the version check against the managed copy fails.
* @throws ORMInvalidArgumentException If the entity instance is NEW.
* @throws EntityNotFoundException if an assigned identifier is used in the entity, but none is provided.
*
* @psalm-param array<string, object> $visited
*/
private function doMerge(
object $entity,
@@ -2186,10 +2180,9 @@ class UnitOfWork implements PropertyChangedListener
* Executes a refresh operation on an entity.
*
* @param object $entity The entity to refresh.
* @psalm-param array<string, object> $visited The already visited entities during cascades.
*
* @throws ORMInvalidArgumentException If the entity is not MANAGED.
*
* @psalm-param array<string, object> $visited The already visited entities during cascades.
*/
private function doRefresh(object $entity, array &$visited): void
{
@@ -2417,7 +2410,7 @@ class UnitOfWork implements PropertyChangedListener
$entitiesToCascade = [];
foreach ($associationMappings as $assoc) {
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
if ($entity instanceof Proxy && ! $entity->__isInitialized()) {
$entity->__load();
}
@@ -2474,7 +2467,7 @@ class UnitOfWork implements PropertyChangedListener
return;
}
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
if ($entity instanceof Proxy && ! $entity->__isInitialized()) {
$entity->__load();
}
@@ -2637,10 +2630,11 @@ class UnitOfWork implements PropertyChangedListener
*
* @param string $className The name of the entity class.
* @param mixed[] $data The data for the entity.
* @psalm-param class-string $className
* @psalm-param array<string, mixed> $hints Any hints to account for during reconstitution/lookup of the entity.
*
* @return object The managed entity instance.
*
* @psalm-param array<string, mixed> $hints Any hints to account for during reconstitution/lookup of the entity.
* @ignore
* @todo Rename: getOrCreateEntity
*/
@@ -2818,7 +2812,7 @@ class UnitOfWork implements PropertyChangedListener
isset($hints[self::HINT_DEFEREAGERLOAD]) &&
! $targetClass->isIdentifierComposite &&
$newValue instanceof Proxy &&
$newValue->__isInitialized__ === false
$newValue->__isInitialized() === false
) {
$this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
}
@@ -2989,7 +2983,7 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity
*
* @psalm-return array<string, array<string, mixed>>
* @psalm-return array<string, mixed>
*/
public function getOriginalEntityData($entity)
{
@@ -3170,9 +3164,9 @@ class UnitOfWork implements PropertyChangedListener
/**
* Gets a collection persister for a collection-valued association.
*
* @return CollectionPersister
*
* @psalm-param array<string, mixed> $association
*
* @return CollectionPersister
*/
public function getCollectionPersister(array $association)
{

View File

@@ -19,7 +19,6 @@ final class HierarchyDiscriminatorResolver
* it extracts all the discriminators from the child classes and returns them
*
* @return null[]
*
* @psalm-return array<array-key, null>
*/
public static function resolveDiscriminatorsForClass(

View File

@@ -140,18 +140,10 @@
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedProperty">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.Classes.UnusedPrivateElements.WriteOnlyProperty">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
@@ -195,13 +187,6 @@
<exclude-pattern>tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod">
<!-- https://github.com/slevomat/coding-standard/issues/1094 -->
<exclude-pattern>lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php</exclude-pattern>
<exclude-pattern>lib/Doctrine/ORM/Mapping/Reflection/ReflectionPropertiesGetter.php</exclude-pattern>
<exclude-pattern>lib/Doctrine/ORM/Tools/EntityGenerator.php</exclude-pattern>
</rule>
<rule ref="Squiz.Commenting.FunctionComment.WrongStyle">
<!-- https://github.com/squizlabs/PHP_CodeSniffer/issues/1961 -->
<exclude-pattern>tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php</exclude-pattern>
@@ -252,7 +237,7 @@
<exclude-pattern>tests/Doctrine/Tests/DbalFunctionalTestCase.php</exclude-pattern>
<exclude-pattern>tests/Doctrine/Tests/OrmFunctionalTestCase.php</exclude-pattern>
</rule>
<rule ref="Squiz.NamingConventions.ValidVariableName.NotCamelCaps">
<rule ref="Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps">
<!-- accessing public property __isInitialized__ of a proxy -->
<exclude-pattern>lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php</exclude-pattern>
<exclude-pattern>lib/Doctrine/ORM/UnitOfWork.php</exclude-pattern>

2252
phpstan-baseline.neon Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,11 @@
includes:
- phpstan-baseline.neon
parameters:
level: 1
level: 5
paths:
- %currentWorkingDirectory%/lib
earlyTerminatingMethodCalls:
Doctrine\ORM\Query\Parser:
- syntaxError
phpVersion: 70200

541
psalm-baseline.xml Normal file
View File

@@ -0,0 +1,541 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.7.0@d4377c0baf3ffbf0b1ec6998e8d1be2a40971005">
<file src="lib/Doctrine/ORM/AbstractQuery.php">
<FalsableReturnStatement occurrences="1">
<code>! $filteredParameters-&gt;isEmpty() ? $filteredParameters-&gt;first() : null</code>
</FalsableReturnStatement>
<InvalidNullableReturnType occurrences="3">
<code>\Doctrine\Common\Cache\Cache</code>
<code>int</code>
<code>string</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="4">
<code>$this-&gt;_em-&gt;getConfiguration()-&gt;getResultCacheImpl()</code>
<code>$this-&gt;_queryCacheProfile ? $this-&gt;_queryCacheProfile-&gt;getCacheKey() : null</code>
<code>$this-&gt;_queryCacheProfile-&gt;getResultCacheDriver()</code>
<code>$this-&gt;cacheMode</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Cache/DefaultCacheFactory.php">
<InvalidNullableReturnType occurrences="1">
<code>string</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="1">
<code>$this-&gt;fileLockRegionDirectory</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php">
<InvalidNullableReturnType occurrences="1">
<code>loadCacheEntry</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="1">
<code>null</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php">
<UndefinedInterfaceMethod occurrences="1">
<code>getCacheRegion</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Cache/DefaultQueryCache.php">
<UndefinedInterfaceMethod occurrences="5">
<code>getCacheRegion</code>
<code>resolveAssociationEntries</code>
<code>resolveAssociationEntries</code>
<code>storeEntityCache</code>
<code>storeEntityCache</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php">
<UndefinedInterfaceMethod occurrences="2">
<code>lock</code>
<code>lock</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php">
<UndefinedInterfaceMethod occurrences="9">
<code>getCacheRegion</code>
<code>getCacheRegion</code>
<code>getCacheRegion</code>
<code>getCacheRegion</code>
<code>loadCollectionCache</code>
<code>loadCollectionCache</code>
<code>storeCollectionCache</code>
<code>storeCollectionCache</code>
<code>storeEntityCache</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php">
<UndefinedInterfaceMethod occurrences="2">
<code>lock</code>
<code>lock</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Cache/Region/FileLockRegion.php">
<InvalidNullableReturnType occurrences="1">
<code>lock</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="2">
<code>null</code>
<code>null</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/EntityManager.php">
<InvalidReturnStatement occurrences="7">
<code>$entity</code>
<code>$entity</code>
<code>$entity</code>
<code>$entity instanceof $class-&gt;name ? $entity : null</code>
<code>$persister-&gt;load($sortedId, null, null, [], $lockMode)</code>
<code>$persister-&gt;loadById($sortedId)</code>
<code>$this-&gt;metadataFactory-&gt;getMetadataFor($className)</code>
</InvalidReturnStatement>
<InvalidReturnType occurrences="3">
<code>?T</code>
<code>getClassMetadata</code>
<code>getReference</code>
</InvalidReturnType>
</file>
<file src="lib/Doctrine/ORM/EntityRepository.php">
<InvalidReturnStatement occurrences="3">
<code>$persister-&gt;load($criteria, null, null, [], null, 1, $orderBy)</code>
<code>$this-&gt;_em-&gt;find($this-&gt;_entityName, $id, $lockMode, $lockVersion)</code>
<code>new LazyCriteriaCollection($persister, $criteria)</code>
</InvalidReturnStatement>
<InvalidReturnType occurrences="3">
<code>?T</code>
<code>?T</code>
<code>Collection&lt;int, T&gt;</code>
</InvalidReturnType>
<MoreSpecificImplementedParamType occurrences="2">
<code>$criteria</code>
<code>$criteria</code>
</MoreSpecificImplementedParamType>
</file>
<file src="lib/Doctrine/ORM/Id/TableGenerator.php">
<UndefinedMethod occurrences="2">
<code>getTableHiLoCurrentValSql</code>
<code>getTableHiLoUpdateNextValSql</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Internal/Hydration/IterableResult.php">
<InvalidPropertyAssignmentValue occurrences="1">
<code>$this-&gt;next()</code>
</InvalidPropertyAssignmentValue>
</file>
<file src="lib/Doctrine/ORM/LazyCriteriaCollection.php">
<MoreSpecificImplementedParamType occurrences="1">
<code>$element</code>
</MoreSpecificImplementedParamType>
<UndefinedInterfaceMethod occurrences="1">
<code>matching</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php">
<UndefinedInterfaceMethod occurrences="17">
<code>inlineEmbeddable</code>
<code>isInheritanceTypeNone</code>
<code>isInheritanceTypeSingleTable</code>
<code>isRootEntity</code>
<code>setChangeTrackingPolicy</code>
<code>setCustomGeneratorDefinition</code>
<code>setCustomRepositoryClass</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorMap</code>
<code>setIdGeneratorType</code>
<code>setIdentifier</code>
<code>setInheritanceType</code>
<code>setLifecycleCallbacks</code>
<code>setParentClasses</code>
<code>setPrimaryTable</code>
<code>setVersionField</code>
<code>setVersioned</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php">
<InvalidNullableReturnType occurrences="2">
<code>ReflectionProperty</code>
<code>ReflectionProperty</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="2">
<code>$this-&gt;reflFields[$name]</code>
<code>$this-&gt;reflFields[$this-&gt;identifier[0]]</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php">
<InvalidArrayAccess occurrences="4">
<code>$value[0]</code>
<code>$value[0]</code>
<code>$value[1]</code>
<code>$value[1]</code>
</InvalidArrayAccess>
<UndefinedInterfaceMethod occurrences="32">
<code>addEntityListener</code>
<code>addLifecycleCallback</code>
<code>addNamedNativeQuery</code>
<code>addNamedQuery</code>
<code>addSqlResultSetMapping</code>
<code>enableCache</code>
<code>fullyQualifiedClassName</code>
<code>getAssociationCacheDefaults</code>
<code>isInheritedAssociation</code>
<code>isInheritedEmbeddedClass</code>
<code>isInheritedField</code>
<code>mapEmbedded</code>
<code>mapField</code>
<code>mapManyToMany</code>
<code>mapManyToOne</code>
<code>mapOneToMany</code>
<code>mapOneToOne</code>
<code>markReadOnly</code>
<code>setAssociationOverride</code>
<code>setAttributeOverride</code>
<code>setChangeTrackingPolicy</code>
<code>setCustomGeneratorDefinition</code>
<code>setCustomRepositoryClass</code>
<code>setCustomRepositoryClass</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorMap</code>
<code>setIdGeneratorType</code>
<code>setInheritanceType</code>
<code>setPrimaryTable</code>
<code>setSequenceGeneratorDefinition</code>
<code>setVersionMapping</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php">
<UndefinedInterfaceMethod occurrences="1">
<code>mapManyToMany</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php">
<UndefinedInterfaceMethod occurrences="34">
<code>addEntityListener</code>
<code>addLifecycleCallback</code>
<code>addNamedNativeQuery</code>
<code>addNamedQuery</code>
<code>addSqlResultSetMapping</code>
<code>enableCache</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>mapEmbedded</code>
<code>mapField</code>
<code>mapField</code>
<code>mapField</code>
<code>mapManyToMany</code>
<code>mapManyToOne</code>
<code>mapOneToMany</code>
<code>mapOneToOne</code>
<code>markReadOnly</code>
<code>setAssociationOverride</code>
<code>setAttributeOverride</code>
<code>setChangeTrackingPolicy</code>
<code>setCustomGeneratorDefinition</code>
<code>setCustomRepositoryClass</code>
<code>setCustomRepositoryClass</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorMap</code>
<code>setIdGeneratorType</code>
<code>setInheritanceType</code>
<code>setPrimaryTable</code>
<code>setSequenceGeneratorDefinition</code>
<code>setVersionMapping</code>
<code>setVersionMapping</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php">
<UndefinedInterfaceMethod occurrences="43">
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>$element</code>
<code>addEntityListener</code>
<code>addLifecycleCallback</code>
<code>addNamedNativeQuery</code>
<code>addNamedQuery</code>
<code>addSqlResultSetMapping</code>
<code>enableCache</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>getAssociationCacheDefaults</code>
<code>mapEmbedded</code>
<code>mapField</code>
<code>mapField</code>
<code>mapManyToMany</code>
<code>mapManyToOne</code>
<code>mapOneToMany</code>
<code>mapOneToOne</code>
<code>markReadOnly</code>
<code>setAssociationOverride</code>
<code>setAttributeOverride</code>
<code>setChangeTrackingPolicy</code>
<code>setCustomGeneratorDefinition</code>
<code>setCustomRepositoryClass</code>
<code>setCustomRepositoryClass</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorColumn</code>
<code>setDiscriminatorMap</code>
<code>setIdGeneratorType</code>
<code>setIdGeneratorType</code>
<code>setInheritanceType</code>
<code>setPrimaryTable</code>
<code>setSequenceGeneratorDefinition</code>
<code>setVersionMapping</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/NativeQuery.php">
<LessSpecificImplementedReturnType occurrences="1">
<code>mixed</code>
</LessSpecificImplementedReturnType>
</file>
<file src="lib/Doctrine/ORM/PersistentCollection.php">
<InvalidReturnStatement occurrences="5">
<code>$persister-&gt;slice($this, $offset, $length)</code>
<code>$this-&gt;collection</code>
<code>new ArrayCollection($persister-&gt;loadCriteria($this, $criteria))</code>
<code>parent::slice($offset, $length)</code>
</InvalidReturnStatement>
<InvalidReturnType occurrences="2">
<code>Collection&lt;TKey, T&gt;</code>
<code>array&lt;TKey,T&gt;</code>
</InvalidReturnType>
<UndefinedInterfaceMethod occurrences="1">
<code>matching</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php">
<FalsableReturnStatement occurrences="1">
<code>$this-&gt;conn-&gt;fetchColumn($sql, $params, 0, $types)</code>
</FalsableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php">
<InvalidArgument occurrences="1">
<code>$hints</code>
</InvalidArgument>
<InvalidNullableReturnType occurrences="1">
<code>loadOneToOneEntity</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="2">
<code>$targetEntity</code>
<code>$targetEntity</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Proxy/ProxyFactory.php">
<InvalidArgument occurrences="1">
<code>$classMetadata-&gt;getReflectionProperties()</code>
</InvalidArgument>
<UndefinedInterfaceMethod occurrences="1">
<code>__wakeup</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Doctrine/ORM/Query.php">
<InvalidArgument occurrences="2">
<code>$paramMappings</code>
<code>$sqlPositions</code>
</InvalidArgument>
<LessSpecificImplementedReturnType occurrences="1">
<code>mixed</code>
</LessSpecificImplementedReturnType>
<MoreSpecificImplementedParamType occurrences="1">
<code>$hydrationMode</code>
</MoreSpecificImplementedParamType>
<UndefinedMethod occurrences="1">
<code>$sqlPositions</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php">
<UndefinedPropertyFetch occurrences="1">
<code>$this-&gt;unit-&gt;value</code>
</UndefinedPropertyFetch>
</file>
<file src="lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php">
<UndefinedPropertyFetch occurrences="1">
<code>$this-&gt;unit-&gt;value</code>
</UndefinedPropertyFetch>
</file>
<file src="lib/Doctrine/ORM/Query/AST/IndexBy.php">
<InvalidNullableReturnType occurrences="1">
<code>dispatch</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="1">
<code>$sqlWalker-&gt;walkIndexBy($this)</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Query/AST/JoinClassPathExpression.php">
<UndefinedMethod occurrences="1">
<code>walkJoinPathExpression</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php">
<UndefinedMethod occurrences="1">
<code>walkJoinVariableDeclaration</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php">
<UndefinedMethod occurrences="1">
<code>walkWhenClauseExpression</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Query/AST/WhenClause.php">
<UndefinedMethod occurrences="1">
<code>walkWhenClauseExpression</code>
</UndefinedMethod>
</file>
<file src="lib/Doctrine/ORM/Query/Parser.php">
<InvalidArrayOffset occurrences="2">
<code>$this-&gt;identVariableExpressions[$dqlAlias]</code>
<code>$this-&gt;queryComponents[$dqlAlias]</code>
</InvalidArrayOffset>
<InvalidNullableReturnType occurrences="5">
<code>FunctionNode</code>
<code>FunctionNode</code>
<code>Literal</code>
<code>SelectStatement|UpdateStatement|DeleteStatement</code>
<code>string</code>
</InvalidNullableReturnType>
<InvalidPropertyAssignmentValue occurrences="1">
<code>$this-&gt;identVariableExpressions</code>
</InvalidPropertyAssignmentValue>
<InvalidReturnStatement occurrences="1">
<code>$primary</code>
</InvalidReturnStatement>
<InvalidReturnType occurrences="1">
<code>ArithmeticFactor</code>
</InvalidReturnType>
<NullFunctionCall occurrences="3">
<code>call_user_func($functionClass, $functionName)</code>
<code>call_user_func($functionClass, $functionName)</code>
<code>call_user_func($functionClass, $functionName)</code>
</NullFunctionCall>
<NullableReturnStatement occurrences="10">
<code>$aliasIdentVariable</code>
<code>$factors[0]</code>
<code>$identVariable</code>
<code>$resultVariable</code>
<code>$resultVariable</code>
<code>$statement</code>
<code>$terms[0]</code>
<code>$this-&gt;lexer-&gt;token['value']</code>
<code>$this-&gt;lexer-&gt;token['value']</code>
<code>null</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php">
<InvalidNullableReturnType occurrences="1">
<code>string</code>
</InvalidNullableReturnType>
</file>
<file src="lib/Doctrine/ORM/Query/SqlWalker.php">
<InvalidArgument occurrences="1">
<code>$selectedClass['class']-&gt;name</code>
</InvalidArgument>
<InvalidArrayOffset occurrences="1">
<code>$this-&gt;selectedClasses[$joinedDqlAlias]</code>
</InvalidArrayOffset>
<InvalidNullableReturnType occurrences="1">
<code>walkConditionalPrimary</code>
</InvalidNullableReturnType>
<InvalidPropertyAssignmentValue occurrences="9">
<code>$this-&gt;scalarFields</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
<code>$this-&gt;scalarResultAliasMap</code>
</InvalidPropertyAssignmentValue>
</file>
<file src="lib/Doctrine/ORM/Query/TreeWalkerChain.php">
<InvalidArgument occurrences="1">
<code>$walkerClass</code>
</InvalidArgument>
<NullArgument occurrences="1">
<code>$this-&gt;_walkers</code>
</NullArgument>
</file>
<file src="lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php">
<InvalidPropertyAssignmentValue occurrences="2">
<code>$this-&gt;walkers</code>
<code>$this-&gt;walkers</code>
</InvalidPropertyAssignmentValue>
</file>
<file src="lib/Doctrine/ORM/QueryBuilder.php">
<FalsableReturnStatement occurrences="1">
<code>! $filteredParameters-&gt;isEmpty() ? $filteredParameters-&gt;first() : null</code>
</FalsableReturnStatement>
<InvalidNullableReturnType occurrences="1">
<code>int</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="1">
<code>$this-&gt;cacheMode</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php">
<InvalidNullableReturnType occurrences="1">
<code>execute</code>
</InvalidNullableReturnType>
</file>
<file src="lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php">
<InvalidArgument occurrences="1">
<code>$metadata-&gt;entityListeners</code>
</InvalidArgument>
</file>
<file src="lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php">
<InvalidNullableReturnType occurrences="1">
<code>execute</code>
</InvalidNullableReturnType>
<NullableReturnStatement occurrences="1">
<code>$this-&gt;executeSchemaCommand($input, $output, new SchemaTool($em), $metadatas, $ui)</code>
</NullableReturnStatement>
</file>
<file src="lib/Doctrine/ORM/Tools/EntityGenerator.php">
<InvalidArgument occurrences="1">
<code>array_values($replacements)</code>
</InvalidArgument>
</file>
<file src="lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php">
<InvalidNullableReturnType occurrences="1">
<code>string</code>
</InvalidNullableReturnType>
</file>
<file src="lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php">
<MoreSpecificImplementedParamType occurrences="1">
<code>$query</code>
</MoreSpecificImplementedParamType>
</file>
<file src="lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php">
<MoreSpecificImplementedParamType occurrences="1">
<code>$query</code>
</MoreSpecificImplementedParamType>
</file>
<file src="lib/Doctrine/ORM/UnitOfWork.php">
<InvalidNullableReturnType occurrences="1">
<code>object</code>
</InvalidNullableReturnType>
<InvalidPropertyAssignmentValue occurrences="2">
<code>$this-&gt;entityChangeSets</code>
<code>$this-&gt;entityChangeSets</code>
</InvalidPropertyAssignmentValue>
<NullableReturnStatement occurrences="1">
<code>$this-&gt;identityMap[$rootClassName][$idHash]</code>
</NullableReturnStatement>
<UndefinedInterfaceMethod occurrences="3">
<code>getMapping</code>
<code>getMapping</code>
<code>takeSnapshot</code>
</UndefinedInterfaceMethod>
</file>
</files>

View File

@@ -1,10 +1,11 @@
<?xml version="1.0"?>
<psalm
errorLevel="7"
errorLevel="5"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="lib/Doctrine/ORM" />

View File

@@ -4,12 +4,11 @@ declare(strict_types=1);
namespace Doctrine\Performance\LazyLoading;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Performance\Mock\NonProxyLoadingEntityManager;
use Doctrine\Tests\Models\CMS\CmsEmployee;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DbalTypes;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\JsonType;
use Exception;
class GH8565EmployeePayloadType extends JsonType
{
public const NAME = 'GH8565EmployeePayloadType';
public function convertToPHPValue($value, AbstractPlatform $platform): string
{
if (! isset($value['GH8565EmployeePayloadRequiredField'])) {
throw new Exception('GH8565EmployeePayloadType cannot be initialized without required field');
}
return $value['GH8565EmployeePayloadRequiredField'];
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DbalTypes;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\JsonType;
class GH8565ManagerPayloadType extends JsonType
{
public const NAME = 'GH8565ManagerPayloadType';
public function convertToPHPValue($value, AbstractPlatform $platform): string
{
return $value;
}
}

View File

@@ -4,11 +4,9 @@ declare(strict_types=1);
namespace Doctrine\Tests;
use PHPUnit\Framework\TestCase;
/**
* Base testcase class for all Doctrine testcases.
*/
abstract class DoctrineTestCase extends TestCase
abstract class DoctrineTestCase extends PolyfillableTestCase
{
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Models\GH8565;
use Doctrine\Tests\DbalTypes\GH8565EmployeePayloadType;
/**
* @Entity
* @Table(name="gh8565_employees")
*/
class GH8565Employee extends GH8565Person
{
/**
* @Column(type="GH8565EmployeePayloadType", nullable=false)
* @var GH8565EmployeePayloadType
*/
public $type;
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Models\GH8565;
use Doctrine\Tests\DbalTypes\GH8565ManagerPayloadType;
/**
* @Entity
* @Table(name="gh8565_managers")
*/
class GH8565Manager extends GH8565Person
{
/**
* @Column(type="GH8565ManagerPayloadType", nullable=false)
* @var GH8565ManagerPayloadType
*/
public $type;
}

View File

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Models\GH8565;
/**
* @Entity
* @Table(name="gh8565_persons")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({
* "person" = "GH8565Person",
* "manager" = "GH8565Manager",
* "employee" = "GH8565Employee"
* })
*/
class GH8565Person
{
/**
* @var int
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
public $id;
}

View File

@@ -11,6 +11,7 @@ use Doctrine\ORM\Cache\Logging\CacheLoggerChain;
use Doctrine\ORM\Cache\QueryCacheKey;
use Doctrine\Tests\DoctrineTestCase;
use Doctrine\Tests\Models\Cache\State;
use PHPUnit\Framework\MockObject\MockObject;
/**
* @group DDC-2183
@@ -20,7 +21,7 @@ class CacheLoggerChainTest extends DoctrineTestCase
/** @var CacheLoggerChain */
private $logger;
/** @var PHPUnit_Framework_MockObject_MockObject|CacheLogger */
/** @var MockObject|CacheLogger */
private $mock;
protected function setUp(): void

View File

@@ -88,7 +88,7 @@ class FileLockRegionTest extends AbstractRegionTest
$this->assertNull($this->region->get($key));
$this->assertTrue($this->region->unlock($key, $lock));
$this->assertFileNotExists($file);
$this->assertFileDoesNotExist($file);
}
public function testLockWithExistingLock(): void
@@ -183,7 +183,7 @@ class FileLockRegionTest extends AbstractRegionTest
$this->assertFalse($this->region->contains($key));
$this->assertTrue($this->region->evict($key));
$this->assertFalse($this->region->contains($key));
$this->assertFileNotExists($file);
$this->assertFileDoesNotExist($file);
}
public function testLockedEvictAll(): void
@@ -215,8 +215,8 @@ class FileLockRegionTest extends AbstractRegionTest
$this->assertTrue($this->region->evictAll());
$this->assertFileNotExists($file1);
$this->assertFileNotExists($file2);
$this->assertFileDoesNotExist($file1);
$this->assertFileDoesNotExist($file2);
$this->assertFalse($this->region->contains($key1));
$this->assertFalse($this->region->contains($key2));
@@ -243,7 +243,7 @@ class FileLockRegionTest extends AbstractRegionTest
// outdated lock should be removed
$this->assertTrue($this->region->contains($key));
$this->assertNotNull($this->region->get($key));
$this->assertFileNotExists($file);
$this->assertFileDoesNotExist($file);
}
/**

View File

@@ -8,8 +8,8 @@ use Doctrine\ORM\Decorator\EntityManagerDecorator;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\VerifyDeprecations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use ReflectionClass;
use ReflectionMethod;
@@ -35,7 +35,7 @@ class EntityManagerDecoratorTest extends TestCase
'lock',
];
/** @var EntityManagerInterface|PHPUnit_Framework_MockObject_MockObject */
/** @var EntityManagerInterface|MockObject */
private $wrapped;
/** @before */

View File

@@ -9,7 +9,6 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\PersistentCollection;
use Doctrine\Tests\IterableTester;
use Doctrine\Tests\OrmFunctionalTestCase;
use Exception;
use function assert;
use function count;
@@ -23,19 +22,25 @@ class AdvancedAssociationTest extends OrmFunctionalTestCase
protected function setUp(): void
{
parent::setUp();
try {
$this->_schemaTool->createSchema(
[
$this->_em->getClassMetadata(Phrase::class),
$this->_em->getClassMetadata(PhraseType::class),
$this->_em->getClassMetadata(Definition::class),
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Type::class),
]
);
} catch (Exception $e) {
// Swallow all exceptions. We do not test the schema tool here.
}
$this->_schemaTool->createSchema([
$this->_em->getClassMetadata(Phrase::class),
$this->_em->getClassMetadata(PhraseType::class),
$this->_em->getClassMetadata(Definition::class),
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Type::class),
]);
}
protected function tearDown(): void
{
parent::tearDown();
$this->_schemaTool->dropSchema([
$this->_em->getClassMetadata(Phrase::class),
$this->_em->getClassMetadata(PhraseType::class),
$this->_em->getClassMetadata(Definition::class),
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Type::class),
]);
}
public function testIssue(): void

View File

@@ -6,9 +6,7 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\Tests\OrmFunctionalTestCase;
use Exception;
use function count;
use function get_class;
@@ -16,23 +14,28 @@ use function get_class;
/**
* Functional tests for the Class Table Inheritance mapping strategy.
*/
class ClassTableInheritanceTest2 extends OrmFunctionalTestCase
class ClassTableInheritanceSecondTest extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
try {
$this->_schemaTool->createSchema(
[
$this->_em->getClassMetadata(CTIParent::class),
$this->_em->getClassMetadata(CTIChild::class),
$this->_em->getClassMetadata(CTIRelated::class),
$this->_em->getClassMetadata(CTIRelated2::class),
]
);
} catch (Exception $ignored) {
// Swallow all exceptions. We do not test the schema tool here.
}
$this->_schemaTool->createSchema([
$this->_em->getClassMetadata(CTIParent::class),
$this->_em->getClassMetadata(CTIChild::class),
$this->_em->getClassMetadata(CTIRelated::class),
$this->_em->getClassMetadata(CTIRelated2::class),
]);
}
protected function tearDown(): void
{
parent::tearDown();
$this->_schemaTool->dropSchema([
$this->_em->getClassMetadata(CTIParent::class),
$this->_em->getClassMetadata(CTIChild::class),
$this->_em->getClassMetadata(CTIRelated::class),
$this->_em->getClassMetadata(CTIRelated2::class),
]);
}
public function testOneToOneAssocToBaseTypeBidirectional(): void
@@ -55,7 +58,6 @@ class ClassTableInheritanceTest2 extends OrmFunctionalTestCase
$this->assertInstanceOf(CTIRelated::class, $related2);
$this->assertInstanceOf(CTIChild::class, $related2->getCTIParent());
$this->assertNotInstanceOf(Proxy::class, $related2->getCTIParent());
$this->assertEquals('hello', $related2->getCTIParent()->getData());
$this->assertSame($related2, $related2->getCTIParent()->getRelated());

View File

@@ -67,9 +67,13 @@ class ExtraLazyCollectionTest extends OrmFunctionalTestCase
$class->associationMappings['phonenumbers']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
$class->associationMappings['phonenumbers']['indexBy'] = 'phonenumber';
unset($class->associationMappings['phonenumbers']['cache']);
unset($class->associationMappings['articles']['cache']);
unset($class->associationMappings['users']['cache']);
foreach (['phonenumbers', 'articles', 'users'] as $field) {
if (isset($class->associationMappings[$field]['cache'])) {
$this->previousCacheConfig[$field] = $class->associationMappings[$field]['cache'];
}
unset($class->associationMappings[$field]['cache']);
}
$class = $this->_em->getClassMetadata(CmsGroup::class);
$class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
@@ -87,6 +91,13 @@ class ExtraLazyCollectionTest extends OrmFunctionalTestCase
$class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
$class->associationMappings['phonenumbers']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
foreach (['phonenumbers', 'articles', 'users'] as $field) {
if (isset($this->previousCacheConfig[$field])) {
$class->associationMappings[$field]['cache'] = $this->previousCacheConfig[$field];
unset($this->previousCacheConfig[$field]);
}
}
unset($class->associationMappings['groups']['indexBy']);
unset($class->associationMappings['articles']['indexBy']);
unset($class->associationMappings['phonenumbers']['indexBy']);

View File

@@ -208,6 +208,9 @@ class IdentityMapTest extends OrmFunctionalTestCase
$this->assertEquals(4, count($user3->getPhonenumbers()));
}
/**
* @group non-cacheable
*/
public function testCollectionValuedAssociationIdentityMapBehaviorWithRefresh(): void
{
$user = new CmsUser();

View File

@@ -6,7 +6,7 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\OrmFunctionalTestCase;
class QueryBuilderParenthesis extends OrmFunctionalTestCase
class QueryBuilderParenthesisTest extends OrmFunctionalTestCase
{
protected function setUp(): void
{
@@ -36,6 +36,7 @@ class QueryBuilderParenthesis extends OrmFunctionalTestCase
$queryBuilder->select('o')->from(QueryBuilderParenthesisEntity::class, 'o');
$queryBuilder->andWhere('o.property3 = :value3')->setParameter('value3', 'x');
$queryBuilder->andWhere('o.property1 = :value1 OR o.property2 = :value2');
$queryBuilder->andWhere('o.property1 = :value1 or o.property2 = :value2');
$queryBuilder->setParameter('value1', 'x');
$queryBuilder->setParameter('value2', 'x');
@@ -46,7 +47,7 @@ class QueryBuilderParenthesis extends OrmFunctionalTestCase
$dql = $query->getDQL();
$this->assertSame(
'SELECT o FROM ' . QueryBuilderParenthesisEntity::class . ' o WHERE o.property3 = :value3 AND (o.property1 = :value1 OR o.property2 = :value2)',
'SELECT o FROM ' . QueryBuilderParenthesisEntity::class . ' o WHERE o.property3 = :value3 AND (o.property1 = :value1 OR o.property2 = :value2) AND (o.property1 = :value1 or o.property2 = :value2)',
$dql
);
}

View File

@@ -59,7 +59,7 @@ class QueryCacheTest extends OrmFunctionalTestCase
/**
* @param <type> $query
*
* @depends testQueryCache_DependsOnHints
* @depends testQueryCacheDependsOnHints
*/
public function testQueryCacheDependsOnFirstResult($query): void
{
@@ -76,7 +76,7 @@ class QueryCacheTest extends OrmFunctionalTestCase
/**
* @param <type> $query
*
* @depends testQueryCache_DependsOnHints
* @depends testQueryCacheDependsOnHints
*/
public function testQueryCacheDependsOnMaxResults($query): void
{
@@ -92,7 +92,7 @@ class QueryCacheTest extends OrmFunctionalTestCase
/**
* @param <type> $query
*
* @depends testQueryCache_DependsOnHints
* @depends testQueryCacheDependsOnHints
*/
public function testQueryCacheDependsOnHydrationMode($query): void
{
@@ -146,11 +146,16 @@ class QueryCacheTest extends OrmFunctionalTestCase
->setMethods(['doFetch', 'doContains', 'doSave', 'doDelete', 'doFlush', 'doGetStats'])
->getMock();
$cache->expects($this->at(0))->method('doFetch')->will($this->returnValue(1));
$cache->expects($this->at(1))
->method('doFetch')
->with($this->isType('string'))
->will($this->returnValue($parserResultMock));
$cache->expects($this->exactly(2))
->method('doFetch')
->withConsecutive(
[$this->isType('string')],
[$this->isType('string')]
)
->willReturnOnConsecutiveCalls(
$this->returnValue(1),
$this->returnValue($parserResultMock)
);
$cache->expects($this->never())
->method('doSave');

View File

@@ -55,7 +55,7 @@ class DDC1452Test extends OrmFunctionalTestCase
$results = $this->_em->createQuery($dql)->setMaxResults(1)->getResult();
$this->assertSame($results[0], $results[0]->entitiesB[0]->entityAFrom);
$this->assertFalse($results[0]->entitiesB[0]->entityATo instanceof Proxy);
$this->assertNotInstanceOf(Proxy::class, $results[0]->entitiesB[0]->entityATo);
$this->assertInstanceOf(Collection::class, $results[0]->entitiesB[0]->entityATo->getEntitiesB());
}
@@ -83,12 +83,12 @@ class DDC1452Test extends OrmFunctionalTestCase
$data = $this->_em->createQuery($dql)->getResult();
$this->_em->clear();
$this->assertFalse($data[0]->user instanceof Proxy);
$this->assertNotInstanceOf(Proxy::class, $data[0]->user);
$dql = 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.address a';
$data = $this->_em->createQuery($dql)->getResult();
$this->assertFalse($data[0]->address instanceof Proxy);
$this->assertNotInstanceOf(Proxy::class, $data[0]->address);
}
}

View File

@@ -55,8 +55,9 @@ class DDC1884Test extends OrmFunctionalTestCase
}
/**
* @psalm-var class-string<Car> $class
* @psalm-return array{Car, Car, Car, Car}
*
* @psalm-var class-string<Car> $class
*/
private function createCars(string $class): array
{
@@ -85,8 +86,9 @@ class DDC1884Test extends OrmFunctionalTestCase
}
/**
* @psalm-var class-string<Driver> $class
* @psalm-return array{Driver, Driver}
*
* @psalm-var class-string<Driver> $class
*/
private function createDrivers(string $class): array
{

View File

@@ -11,8 +11,8 @@ use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use function assert;
@@ -34,7 +34,7 @@ class DDC2359Test extends TestCase
$metadataFactory = $this->getMockBuilder(ClassMetadataFactory::class)
->setMethods(['newClassMetadataInstance', 'wakeupReflection'])
->getMock();
assert($metadataFactory instanceof ClassMetadataFactory || $metadataFactory instanceof PHPUnit_Framework_MockObject_MockObject);
assert($metadataFactory instanceof ClassMetadataFactory || $metadataFactory instanceof MockObject);
$configuration = $this->getMockBuilder(Configuration::class)
->setMethods(['getMetadataDriverImpl'])

View File

@@ -5,30 +5,34 @@ declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Tests\OrmFunctionalTestCase;
use Exception;
use function assert;
/**
* Functional tests for the Single Table Inheritance mapping strategy.
*/
class AdvancedAssociationTest extends OrmFunctionalTestCase
class DDC69Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
try {
$this->_schemaTool->createSchema(
[
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Relation::class),
$this->_em->getClassMetadata(RelationType::class),
]
);
} catch (Exception $e) {
// Swallow all exceptions. We do not test the schema tool here.
}
$this->_schemaTool->createSchema([
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Relation::class),
$this->_em->getClassMetadata(RelationType::class),
]);
}
protected function tearDown(): void
{
parent::tearDown();
$this->_schemaTool->dropSchema([
$this->_em->getClassMetadata(Lemma::class),
$this->_em->getClassMetadata(Relation::class),
$this->_em->getClassMetadata(RelationType::class),
]);
}
public function testIssue(): void
@@ -124,9 +128,8 @@ class Lemma
*/
private $lemma;
/**
* @var kateglo\application\utilities\collections\ArrayCollection
* @var Collection<int, Relation>
* @OneToMany(targetEntity="Relation", mappedBy="parent", cascade={"persist"})
*/
private $relations;
@@ -167,7 +170,10 @@ class Lemma
}
}
public function getRelations(): kateglo\application\utilities\collections\ArrayCollection
/**
* @psalm-return Collection<int, Relation>
*/
public function getRelations(): Collection
{
return $this->relations;
}
@@ -288,7 +294,7 @@ class RelationType
private $abbreviation;
/**
* @var kateglo\application\utilities\collections\ArrayCollection
* @var Collection<int, Relation>
* @OneToMany(targetEntity="Relation", mappedBy="type", cascade={"persist"})
*/
private $relations;
@@ -338,7 +344,10 @@ class RelationType
}
}
public function getRelations(): kateglo\application\utilities\collections\ArrayCollection
/**
* @psalm-return Collection<int, Relation>
*/
public function getRelations(): Collection
{
return $this->relations;
}

View File

@@ -36,7 +36,7 @@ class GH6464Test extends OrmFunctionalTestCase
->innerJoin(GH6464Author::class, 'a', 'WITH', 'p.authorId = a.id')
->getQuery();
$this->assertNotRegExp(
$this->assertDoesNotMatchRegularExpression(
'/INNER JOIN \w+ \w+ INNER JOIN/',
$query->getSQL(),
'As of GH-6464, every INNER JOIN should have an ON clause, which is missing here'

View File

@@ -26,7 +26,7 @@ final class GH8061Test extends OrmTestCase
$entityManager = $this->getTestEntityManager();
$query = $entityManager->createQuery($dql);
self::assertRegExp('/SELECT DatabaseFunction\(\w+\.field\) AS /', $query->getSQL());
self::assertMatchesRegularExpression('/SELECT DatabaseFunction\(\w+\.field\) AS /', $query->getSQL());
}
}

View File

@@ -13,7 +13,7 @@ use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit\Framework\MockObject\MockObject;
use function iterator_to_array;
@@ -22,13 +22,13 @@ use function iterator_to_array;
*/
class AbstractHydratorTest extends OrmFunctionalTestCase
{
/** @var EventManager|PHPUnit_Framework_MockObject_MockObject */
/** @var EventManager|MockObject */
private $mockEventManager;
/** @var Statement|PHPUnit_Framework_MockObject_MockObject */
/** @var Statement|MockObject */
private $mockStatement;
/** @var ResultSetMapping|PHPUnit_Framework_MockObject_MockObject */
/** @var ResultSetMapping|MockObject */
private $mockResultMapping;
/** @var AbstractHydrator */

View File

@@ -4,11 +4,17 @@ declare(strict_types=1);
namespace Doctrine\Tests\ORM\Hydration;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\DbalTypes\GH8565EmployeePayloadType;
use Doctrine\Tests\DbalTypes\GH8565ManagerPayloadType;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\Company\CompanyPerson;
use Doctrine\Tests\Models\GH8565\GH8565Employee;
use Doctrine\Tests\Models\GH8565\GH8565Manager;
use Doctrine\Tests\Models\GH8565\GH8565Person;
use Doctrine\Tests\Models\Issue5989\Issue5989Employee;
use Doctrine\Tests\Models\Issue5989\Issue5989Manager;
use Doctrine\Tests\Models\Issue5989\Issue5989Person;
@@ -122,4 +128,36 @@ class SimpleObjectHydratorTest extends HydrationTestCase
$result = $hydrator->hydrateAll($stmt, $rsm);
$this->assertEquals($result[0], $expectedEntity);
}
public function testWrongValuesShouldNotBeConvertedToPhpValue(): void
{
DBALType::addType(GH8565EmployeePayloadType::NAME, GH8565EmployeePayloadType::class);
DBALType::addType(GH8565ManagerPayloadType::NAME, GH8565ManagerPayloadType::class);
$rsm = new ResultSetMapping();
$rsm->addEntityResult(GH8565Person::class, 'p');
$rsm->addFieldResult('p', 'p__id', 'id');
$rsm->addFieldResult('p', 'm__type', 'type', GH8565Manager::class);
$rsm->addFieldResult('p', 'e__type', 'type', GH8565Employee::class);
$rsm->addMetaResult('p', 'discr', 'discr', false, 'string');
$rsm->setDiscriminatorColumn('p', 'type');
$resultSet = [
[
'p__id' => '1',
'm__type' => 'type field',
'e__type' => 'type field',
'e__tags' => null,
'discr' => 'manager',
],
];
$expectedEntity = new GH8565Manager();
$expectedEntity->id = 1;
$expectedEntity->type = 'type field';
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new SimpleObjectHydrator($this->entityManager);
$result = $hydrator->hydrateAll($stmt, $rsm);
$this->assertEquals($result[0], $expectedEntity);
}
}

View File

@@ -28,8 +28,8 @@ use Doctrine\ORM\Events;
use Doctrine\ORM\Internal\HydrationCompleteHandler;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use stdClass;
use function assert;
@@ -42,10 +42,10 @@ use function in_array;
*/
class HydrationCompleteHandlerTest extends TestCase
{
/** @var ListenersInvoker|PHPUnit_Framework_MockObject_MockObject */
/** @var ListenersInvoker|MockObject */
private $listenersInvoker;
/** @var EntityManagerInterface|PHPUnit_Framework_MockObject_MockObject */
/** @var EntityManagerInterface|MockObject */
private $entityManager;
/** @var HydrationCompleteHandler */

View File

@@ -8,8 +8,8 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\LazyCriteriaCollection;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use stdClass;
/**
@@ -17,7 +17,7 @@ use stdClass;
*/
class LazyCriteriaCollectionTest extends TestCase
{
/** @var EntityPersister|PHPUnit_Framework_MockObject_MockObject */
/** @var EntityPersister|MockObject */
private $persister;
/** @var Criteria */

View File

@@ -141,14 +141,18 @@ class ClassMetadataFactoryTest extends OrmTestCase
{
$cmf = new ClassMetadataFactory();
$driver = $this->createMock(MappingDriver::class);
$driver->expects($this->at(0))
->method('isTransient')
->with($this->equalTo(CmsUser::class))
->will($this->returnValue(true));
$driver->expects($this->at(1))
->method('isTransient')
->with($this->equalTo(CmsArticle::class))
->will($this->returnValue(false));
$driver->expects($this->exactly(2))
->method('isTransient')
->withConsecutive(
[CmsUser::class],
[CmsArticle::class]
)
->willReturnMap(
[
[CmsUser::class, true],
[CmsArticle::class, false],
]
);
$em = $this->createEntityManager($driver);
@@ -163,14 +167,18 @@ class ClassMetadataFactoryTest extends OrmTestCase
{
$cmf = new ClassMetadataFactory();
$driver = $this->createMock(MappingDriver::class);
$driver->expects($this->at(0))
->method('isTransient')
->with($this->equalTo(CmsUser::class))
->will($this->returnValue(true));
$driver->expects($this->at(1))
->method('isTransient')
->with($this->equalTo(CmsArticle::class))
->will($this->returnValue(false));
$driver->expects($this->exactly(2))
->method('isTransient')
->withConsecutive(
[CmsUser::class],
[CmsArticle::class]
)
->willReturnMap(
[
[CmsUser::class, true],
[CmsArticle::class, false],
]
);
$em = $this->createEntityManager($driver);
$em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
@@ -501,6 +509,7 @@ class ClassMetadataFactoryTestSubject extends ClassMetadataFactory
/**
* @psalm-param class-string<object> $className
*
* @override
*/
protected function newClassMetadataInstance($className): ClassMetadata

View File

@@ -9,8 +9,8 @@ use Doctrine\Persistence\Mapping\ReflectionService;
use Doctrine\Persistence\Mapping\RuntimeReflectionService;
use Doctrine\Tests\Models\Reflection\ClassWithMixedProperties;
use Doctrine\Tests\Models\Reflection\ParentClass;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use ReflectionClass;
use function assert;
@@ -95,7 +95,7 @@ class ReflectionPropertiesGetterTest extends TestCase
public function testPropertyGetterWillSkipPropertiesNotRetrievedByTheRuntimeReflectionService(): void
{
$reflectionService = $this->createMock(ReflectionService::class);
assert($reflectionService instanceof ReflectionService || $reflectionService instanceof PHPUnit_Framework_MockObject_MockObject);
assert($reflectionService instanceof ReflectionService || $reflectionService instanceof MockObject);
$reflectionService
->expects($this->exactly(2))
@@ -118,7 +118,7 @@ class ReflectionPropertiesGetterTest extends TestCase
public function testPropertyGetterWillSkipClassesNotRetrievedByTheRuntimeReflectionService(): void
{
$reflectionService = $this->createMock(ReflectionService::class);
assert($reflectionService instanceof ReflectionService || $reflectionService instanceof PHPUnit_Framework_MockObject_MockObject);
assert($reflectionService instanceof ReflectionService || $reflectionService instanceof MockObject);
$reflectionService
->expects($this->once())

View File

@@ -13,7 +13,7 @@ use Doctrine\Tests\Mocks\EntityManagerMock;
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
use Doctrine\Tests\OrmTestCase;
use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit\Framework\MockObject\MockObject;
use stdClass;
use function array_keys;
@@ -153,7 +153,7 @@ class PersistentCollectionTest extends OrmTestCase
public function testWillKeepNewItemsInDirtyCollectionAfterInitialization(): void
{
$unitOfWork = $this->createMock(UnitOfWork::class);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof PHPUnit_Framework_MockObject_MockObject);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof MockObject);
$this->_emMock->setUnitOfWork($unitOfWork);
@@ -188,7 +188,7 @@ class PersistentCollectionTest extends OrmTestCase
public function testWillDeDuplicateNewItemsThatWerePreviouslyPersistedInDirtyCollectionAfterInitialization(): void
{
$unitOfWork = $this->createMock(UnitOfWork::class);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof PHPUnit_Framework_MockObject_MockObject);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof MockObject);
$this->_emMock->setUnitOfWork($unitOfWork);
@@ -232,7 +232,7 @@ class PersistentCollectionTest extends OrmTestCase
public function testWillNotMarkCollectionAsDirtyAfterInitializationIfNoElementsWereAdded(): void
{
$unitOfWork = $this->createMock(UnitOfWork::class);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof PHPUnit_Framework_MockObject_MockObject);
assert($unitOfWork instanceof UnitOfWork || $unitOfWork instanceof MockObject);
$this->_emMock->setUnitOfWork($unitOfWork);

View File

@@ -10,8 +10,8 @@ use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
use Doctrine\Tests\Models\DDC753\DDC753DefaultRepository;
use Doctrine\Tests\Models\DDC869\DDC869PaymentRepository;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use function assert;
@@ -22,10 +22,10 @@ use function assert;
*/
class DefaultRepositoryFactoryTest extends TestCase
{
/** @var EntityManagerInterface|PHPUnit_Framework_MockObject_MockObject */
/** @var EntityManagerInterface|MockObject */
private $entityManager;
/** @var Configuration|PHPUnit_Framework_MockObject_MockObject */
/** @var Configuration|MockObject */
private $configuration;
/** @var DefaultRepositoryFactory */
@@ -108,14 +108,14 @@ class DefaultRepositoryFactoryTest extends TestCase
}
/**
* @return PHPUnit_Framework_MockObject_MockObject|ClassMetadata
* @return MockObject|ClassMetadata
*
* @private
*/
public function buildClassMetadata(string $className)
{
$metadata = $this->createMock(ClassMetadata::class);
assert($metadata instanceof ClassMetadata || $metadata instanceof PHPUnit_Framework_MockObject_MockObject);
assert($metadata instanceof ClassMetadata || $metadata instanceof MockObject);
$metadata->expects($this->any())->method('getName')->will($this->returnValue($className));
@@ -125,7 +125,7 @@ class DefaultRepositoryFactoryTest extends TestCase
}
/**
* @return EntityManagerInterface|PHPUnit_Framework_MockObject_MockObject
* @return EntityManagerInterface|MockObject
*/
private function createEntityManager(): EntityManagerInterface
{

Some files were not shown because too many files have changed in this diff Show More