mirror of
https://github.com/doctrine/orm.git
synced 2026-04-24 23:18:13 +02:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b24275346 | |||
| ed1a576305 | |||
| 15ec77fa79 | |||
| cac2acae07 | |||
| 146b465ec1 | |||
| 5aba762a33 | |||
| a663dda869 | |||
| db14f0fa89 | |||
| 9a74ae6280 | |||
| 32eb38ebd9 | |||
| 176fbedc69 | |||
| 1b15af44b6 | |||
| 8336420a26 | |||
| a6b7569d7a | |||
| 9e37c788ef | |||
| ca0a6bbf71 | |||
| a3da3d78d4 | |||
| e1c2d2e65d | |||
| 6f194eeabf | |||
| 16cbc16998 | |||
| 5e6608b48e | |||
| 94bc137526 | |||
| 276a0f55ee | |||
| dbaf99f3d9 | |||
| 97411f5567 | |||
| 641330baa6 | |||
| 35e680cd3f | |||
| 705d88eaba | |||
| 3271d8f6e2 | |||
| 3622381f8c | |||
| f2729b0610 | |||
| cd44547573 | |||
| 81d472f6f9 | |||
| d458968cee | |||
| 5eb01da0a0 | |||
| 5aaf361139 | |||
| 6a8dcbc392 | |||
| 12babcc1c2 | |||
| 416aa1d2d7 | |||
| 8e16bb4ddc | |||
| e1dee439bb | |||
| e313d012ae | |||
| dede619b9e | |||
| 142cfb39fc | |||
| 53d41a456a | |||
| 95b34ca940 | |||
| 3eaf76eebd | |||
| 5c12d36be3 | |||
| 1ee68eb318 | |||
| 705c7f0a4b | |||
| 8c5e49efc0 | |||
| 483e09cf1c | |||
| bbb68d0072 | |||
| f346379c7b | |||
| b1c31e1aac | |||
| 02b6f9c335 | |||
| d14d9919c7 | |||
| bd79e3d383 | |||
| 10f72417c9 | |||
| 87ad869a8a | |||
| bc4659b73c | |||
| 4eab6536c3 | |||
| 1571c8a781 | |||
| 20a65cbe32 |
+12
-6
@@ -12,21 +12,27 @@
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.10",
|
||||
"branchName": "2.10.x",
|
||||
"slug": "2.10",
|
||||
"name": "2.11",
|
||||
"branchName": "2.11.x",
|
||||
"slug": "2.11",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.9",
|
||||
"branchName": "2.9.x",
|
||||
"slug": "2.9",
|
||||
"name": "2.10",
|
||||
"branchName": "2.10.x",
|
||||
"slug": "2.10",
|
||||
"current": true,
|
||||
"aliases": [
|
||||
"current",
|
||||
"stable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "2.9",
|
||||
"branchName": "2.9.x",
|
||||
"slug": "2.9",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.8",
|
||||
"branchName": "2.8.x",
|
||||
|
||||
@@ -10,30 +10,6 @@ on:
|
||||
|
||||
jobs:
|
||||
coding-standards:
|
||||
name: "Coding Standards"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
tools: "cs2pr"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v1"
|
||||
with:
|
||||
dependency-versions: "highest"
|
||||
|
||||
# https://github.com/doctrine/.github/issues/3
|
||||
- name: "Run PHP_CodeSniffer"
|
||||
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
|
||||
uses: "doctrine/.github/.github/workflows/coding-standards.yml@1.1.1"
|
||||
with:
|
||||
php-version: "7.4"
|
||||
|
||||
@@ -4,13 +4,9 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
tag-ignore:
|
||||
- "*"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
tag-ignore:
|
||||
- "*"
|
||||
|
||||
env:
|
||||
fail-fast: true
|
||||
|
||||
@@ -7,46 +7,10 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: "Git tag, release & create merge-up PR"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Release"
|
||||
# revert to v1 when
|
||||
# https://github.com/laminas/automatic-releases/issues/166 is fixed
|
||||
uses: "docker://ghcr.io/laminas/automatic-releases:1.11.1"
|
||||
with:
|
||||
args: "laminas:automatic-releases:release"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
"SHELL_VERBOSITY": "3"
|
||||
|
||||
- name: "Create Merge-Up Pull Request"
|
||||
# revert to v1 when
|
||||
# https://github.com/laminas/automatic-releases/issues/166 is fixed
|
||||
uses: "docker://ghcr.io/laminas/automatic-releases:1.11.1"
|
||||
with:
|
||||
args: "laminas:automatic-releases:create-merge-up-pull-request"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
|
||||
- name: "Create new milestones"
|
||||
# revert to v1 when
|
||||
# https://github.com/laminas/automatic-releases/issues/166 is fixed
|
||||
uses: "docker://ghcr.io/laminas/automatic-releases:1.11.1"
|
||||
with:
|
||||
args: "laminas:automatic-releases:create-milestones"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.1.1"
|
||||
secrets:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
|
||||
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| [3.0.x][3.0] | [2.10.x][2.10] | [2.9.x][2.9] |
|
||||
| [3.0.x][3.0] | [2.11.x][2.11] | [2.10.x][2.10] |
|
||||
|:----------------:|:----------------:|:----------:|
|
||||
| [![Build status][3.0 image]][3.0] | [![Build status][2.10 image]][2.10] | [![Build status][2.9 image]][2.9] |
|
||||
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.10 coverage image]][2.10 coverage] | [![Coverage Status][2.9 coverage image]][2.9 coverage] |
|
||||
| [![Build status][3.0 image]][3.0] | [![Build status][2.11 image]][2.11] | [![Build status][2.10 image]][2.10] |
|
||||
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.11 coverage image]][2.11 coverage] | [![Coverage Status][2.10 coverage image]][2.10 coverage] |
|
||||
|
||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence
|
||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||
@@ -20,11 +20,11 @@ without requiring unnecessary code duplication.
|
||||
[3.0]: https://github.com/doctrine/orm/tree/3.0.x
|
||||
[3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg
|
||||
[3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x
|
||||
[2.9 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.9.x
|
||||
[2.9]: https://github.com/doctrine/orm/tree/2.9.x
|
||||
[2.9 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.9.x/graph/badge.svg
|
||||
[2.9 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.9.x
|
||||
[2.10 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.10.x
|
||||
[2.10]: https://github.com/doctrine/orm/tree/2.10.x
|
||||
[2.10 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.10.x/graph/badge.svg
|
||||
[2.10 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.10.x
|
||||
[2.11 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.11.x
|
||||
[2.11]: https://github.com/doctrine/orm/tree/2.11.x
|
||||
[2.11 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.11.x/graph/badge.svg
|
||||
[2.11 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.11.x
|
||||
|
||||
+10
-7
@@ -1,5 +1,12 @@
|
||||
# Upgrade to 2.10
|
||||
|
||||
## BC Break: `UnitOfWork` now relies on SPL object IDs, not hashes
|
||||
|
||||
When calling the following methods, you are now supposed to use the result of
|
||||
`spl_object_id()`, and not `spl_object_hash()`:
|
||||
- `UnitOfWork::clearEntityChangeSet()`
|
||||
- `UnitOfWork::setOriginalEntityProperty()`
|
||||
|
||||
## BC Break: Removed `TABLE` id generator strategy
|
||||
|
||||
The implementation was unfinished for 14 years.
|
||||
@@ -9,10 +16,6 @@ It is now deprecated to rely on:
|
||||
- `Doctrine\ORM\Mapping\ClassMetadata::$tableGeneratorDefinition`;
|
||||
- or `Doctrine\ORM\Mapping\ClassMetadata::isIdGeneratorTable()`.
|
||||
|
||||
## BC Break: Removed possibility to extend the doctrine mapping xml schema with anything
|
||||
|
||||
If you want to extend it now you have to provide your own validation schema.
|
||||
|
||||
## New method `Doctrine\ORM\EntityManagerInterface#wrapInTransaction($func)`
|
||||
|
||||
Works the same as `Doctrine\ORM\EntityManagerInterface#transactional()` but returns any value returned from `$func` closure rather than just _non-empty value returned from the closure or true_.
|
||||
@@ -108,10 +111,10 @@ now always cleared regardless of the cache adapter being used.
|
||||
Method `Doctrine\ORM\UnitOfWork#commit()` can throw an OptimisticLockException when a commit silently fails and returns false
|
||||
since `Doctrine\DBAL\Connection#commit()` signature changed from returning void to boolean
|
||||
|
||||
## Deprecated: `Doctrine\ORM\AbstractQuery#iterator()`
|
||||
## Deprecated: `Doctrine\ORM\AbstractQuery#iterate()`
|
||||
|
||||
The method `Doctrine\ORM\AbstractQuery#iterator()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
|
||||
Note that `toIterable()` yields results of the query, unlike `iterator()` which yielded each result wrapped into an array.
|
||||
The method `Doctrine\ORM\AbstractQuery#iterate()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
|
||||
Note that `toIterable()` yields results of the query, unlike `iterate()` which yielded each result wrapped into an array.
|
||||
|
||||
# Upgrade to 2.7
|
||||
|
||||
|
||||
+3
-3
@@ -39,12 +39,12 @@
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/coding-standard": "^9.0",
|
||||
"phpbench/phpbench": "^0.16.10 || ^1.0",
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan": "1.2.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
|
||||
"squizlabs/php_codesniffer": "3.6.0",
|
||||
"squizlabs/php_codesniffer": "3.6.1",
|
||||
"symfony/cache": "^4.4 || ^5.2",
|
||||
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
||||
"vimeo/psalm": "4.10.0"
|
||||
"vimeo/psalm": "4.13.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/annotations": "<1.13 || >= 2.0"
|
||||
|
||||
@@ -33,8 +33,8 @@ the DQL parser:
|
||||
is only ever one of them. We implemented the default SqlWalker
|
||||
implementation for it.
|
||||
- A tree walker. There can be many tree walkers, they cannot
|
||||
generate the sql, however they can modify the AST before its
|
||||
rendered to sql.
|
||||
generate the SQL, however they can modify the AST before its
|
||||
rendered to SQL.
|
||||
|
||||
Now this is all awfully technical, so let me come to some use-cases
|
||||
fast to keep you motivated. Using walker implementation you can for
|
||||
@@ -50,7 +50,7 @@ example:
|
||||
- Modify the Output walker to pretty print the SQL for debugging
|
||||
purposes.
|
||||
|
||||
In this cookbook-entry I will show examples on the first two
|
||||
In this cookbook-entry I will show examples of the first two
|
||||
points. There are probably much more use-cases.
|
||||
|
||||
Generic count query for pagination
|
||||
@@ -64,7 +64,7 @@ like:
|
||||
|
||||
SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
|
||||
|
||||
Now in this query the blog post is the root entity, meaning its the
|
||||
Now in this query the blog post is the root entity, meaning it's the
|
||||
one that is hydrated directly from the query and returned as an
|
||||
array of blog posts. In contrast the comment and author are loaded
|
||||
for deeper use in the object tree.
|
||||
@@ -79,7 +79,7 @@ query for pagination would look like:
|
||||
SELECT count(DISTINCT p.id) FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
|
||||
|
||||
Now you could go and write each of these queries by hand, or you
|
||||
can use a tree walker to modify the AST for you. Lets see how the
|
||||
can use a tree walker to modify the AST for you. Let's see how the
|
||||
API would look for this use-case:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -16,7 +16,6 @@ Doctrine ORM don't panic. You can get help from different sources:
|
||||
- The `Doctrine Mailing List <https://groups.google.com/group/doctrine-user>`_
|
||||
- Slack chat room `#orm <https://www.doctrine-project.org/slack>`_
|
||||
- Report a bug on `GitHub <https://github.com/doctrine/orm/issues>`_.
|
||||
- On `Twitter <https://twitter.com/search/%23doctrine2>`_ with ``#doctrine2``
|
||||
- On `StackOverflow <https://stackoverflow.com/questions/tagged/doctrine-orm>`_
|
||||
|
||||
If you need more structure over the different topics you can browse the :doc:`table
|
||||
|
||||
@@ -184,6 +184,8 @@ in well defined units of work. Work with your objects and modify
|
||||
them as usual and when you're done call ``EntityManager#flush()``
|
||||
to make your changes persistent.
|
||||
|
||||
.. _unit-of-work:
|
||||
|
||||
The Unit of Work
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ The following example sets up such a unidirectional one-to-many association:
|
||||
// ...
|
||||
|
||||
/**
|
||||
* Many User have Many Phonenumbers.
|
||||
* Many Users have Many Phonenumbers.
|
||||
* @ManyToMany(targetEntity="Phonenumber")
|
||||
* @JoinTable(name="users_phonenumbers",
|
||||
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
|
||||
|
||||
@@ -85,9 +85,9 @@ Or if you prefer YAML:
|
||||
|
||||
Inside the ``Setup`` methods several assumptions are made:
|
||||
|
||||
- If `$isDevMode` is true caching is done in memory with the ``ArrayCache``. Proxy objects are recreated on every request.
|
||||
- If `$isDevMode` is false, check for Caches in the order APC, Xcache, Memcache (127.0.0.1:11211), Redis (127.0.0.1:6379) unless `$cache` is passed as fourth argument.
|
||||
- If `$isDevMode` is false, set then proxy classes have to be explicitly created through the command line.
|
||||
- If ``$isDevMode`` is true caching is done in memory with the ``ArrayCache``. Proxy objects are recreated on every request.
|
||||
- If ``$isDevMode`` is false, check for Caches in the order APC, Xcache, Memcache (127.0.0.1:11211), Redis (127.0.0.1:6379) unless `$cache` is passed as fourth argument.
|
||||
- If ``$isDevMode`` is false, set then proxy classes have to be explicitly created through the command line.
|
||||
- If third argument `$proxyDir` is not set, use the systems temporary directory.
|
||||
|
||||
If you want to configure Doctrine in more detail, take a look at the :doc:`Advanced Configuration <reference/advanced-configuration>` section.
|
||||
|
||||
+173
-129
@@ -121,6 +121,53 @@ Now you can test the ``$eventSubscriber`` instance to see if the
|
||||
echo 'pre foo invoked!';
|
||||
}
|
||||
|
||||
Registering Events
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are two ways to register an event:
|
||||
|
||||
* *All events* can be registered by calling ``$eventManager->addEventListener()``
|
||||
or ``eventManager->addEventSubscriber()``, see
|
||||
:ref:`Listening and subscribing to Lifecycle Events<listening-and-subscribing-to-lifecycle-events>`
|
||||
* *Lifecycle Callbacks* can also be registered in the entity mapping (annotation, attribute, etc.),
|
||||
see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`
|
||||
|
||||
Events Overview
|
||||
---------------
|
||||
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| Event | Dispatched by | Lifecycle |
|
||||
| | | Callback |
|
||||
+=================================================================+=======================+===========+
|
||||
| :ref:`preRemove<reference-events-pre-remove>` | ``$em->remove()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`postRemove<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`prePersist<reference-events-pre-persist>` | ``$em->persist()`` | Yes |
|
||||
| | on *initial* persist | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`postPersist<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`preUpdate<reference-events-pre-update>` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`postUpdate<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`postLoad<reference-events-post-load>` | Loading from database | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`loadClassMetadata<reference-events-load-class-metadata>` | Loading of mapping | No |
|
||||
| | metadata | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| ``onClassMetadataNotFound`` | ``MappingException`` | No |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`preFlush<reference-events-pre-flush>` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`onFlush<reference-events-on-flush>` | ``$em->flush()`` | No |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| :ref:`postFlush<reference-events-post-flush>` | ``$em->flush()`` | No |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
| ``onClear`` | ``$em->clear()`` | No |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+
|
||||
|
||||
Naming convention
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -208,15 +255,6 @@ events during the life-time of their registered entities.
|
||||
cascade remove relations. In this case, you should load yourself the proxy in
|
||||
the associated pre event.
|
||||
|
||||
You can access the Event constants from the ``Events`` class in the
|
||||
ORM package.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Events;
|
||||
echo Events::preUpdate;
|
||||
|
||||
These can be hooked into by two different types of event
|
||||
listeners:
|
||||
|
||||
@@ -237,6 +275,7 @@ The ``EventArgs`` instance received by the listener gives access to the entity,
|
||||
:ref:`reference-events-implementing-listeners` section very carefully
|
||||
to understand which operations are allowed in which lifecycle event.
|
||||
|
||||
.. _lifecycle-callbacks:
|
||||
|
||||
Lifecycle Callbacks
|
||||
-------------------
|
||||
@@ -250,135 +289,104 @@ specific to a particular entity class's lifecycle.
|
||||
|
||||
.. note::
|
||||
|
||||
Note that Licecycle Callbacks are not supported for Embeddables.
|
||||
Lifecycle Callbacks are not supported for :doc:`Embeddables </tutorials/embeddables>`.
|
||||
|
||||
.. code-block:: php
|
||||
.. configuration-block::
|
||||
|
||||
<?php
|
||||
.. code-block:: attribute
|
||||
|
||||
/** @Entity @HasLifecycleCallbacks */
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=255)
|
||||
* #[Entity]
|
||||
* #[HasLifecycleCallbacks]
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/** @Column(name="created_at", type="string", length=255) */
|
||||
private $createdAt;
|
||||
|
||||
/** @PrePersist */
|
||||
public function doStuffOnPrePersist()
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/** @PrePersist */
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
/** @PostPersist */
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
$this->value = 'changed from postPersist callback!';
|
||||
}
|
||||
|
||||
/** @PostLoad */
|
||||
public function doStuffOnPostLoad()
|
||||
{
|
||||
$this->value = 'changed from postLoad callback!';
|
||||
}
|
||||
|
||||
/** @PreUpdate */
|
||||
public function doStuffOnPreUpdate()
|
||||
{
|
||||
$this->value = 'changed from preUpdate callback!';
|
||||
}
|
||||
}
|
||||
|
||||
Note that the methods set as lifecycle callbacks need to be public and,
|
||||
when using these annotations, you have to apply the
|
||||
``@HasLifecycleCallbacks`` marker annotation on the entity class.
|
||||
|
||||
If you want to register lifecycle callbacks from YAML or XML you
|
||||
can do it with the following.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
# ...
|
||||
name:
|
||||
type: string(50)
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||
postPersist: [ doStuffOnPostPersist ]
|
||||
|
||||
In YAML the ``key`` of the lifecycleCallbacks entry is the event that you
|
||||
are triggering on and the value is the method (or methods) to call. The allowed
|
||||
event types are the ones listed in the previous Lifecycle Events section.
|
||||
|
||||
XML would look something like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<entity name="User">
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="postPersist" method="doStuffOnPostPersist"/>
|
||||
</lifecycle-callbacks>
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
In XML the ``type`` of the lifecycle-callback entry is the event that you
|
||||
are triggering on and the ``method`` is the method to call. The allowed event
|
||||
types are the ones listed in the previous Lifecycle Events section.
|
||||
|
||||
When using YAML or XML you need to remember to create public methods to match the
|
||||
callback names you defined. E.g. in these examples ``doStuffOnPrePersist()``,
|
||||
``doOtherStuffOnPrePersist()`` and ``doStuffOnPostPersist()`` methods need to be
|
||||
defined on your ``User`` model.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// ...
|
||||
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
|
||||
public function doStuffOnPrePersist()
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function doOtherStuffOnPrePersist()
|
||||
#[Column(type: 'string', length: 255)]
|
||||
public $value;
|
||||
|
||||
#[PrePersist]
|
||||
public function doStuffOnPrePersist()
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
#[PrePersist]
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
#[PostLoad]
|
||||
public function doStuffOnPostLoad()
|
||||
{
|
||||
$this->value = 'changed from postLoad callback!';
|
||||
}
|
||||
}
|
||||
.. code-block:: annotation
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @HasLifecycleCallbacks
|
||||
*/
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
/** @Column(type="string", length=255) */
|
||||
public $value;
|
||||
|
||||
/** @PrePersist */
|
||||
public function doStuffOnPrePersist()
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/** @PrePersist */
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
/** @PostLoad */
|
||||
public function doStuffOnPostLoad()
|
||||
{
|
||||
$this->value = 'changed from postLoad callback!';
|
||||
}
|
||||
}
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
<entity name="User">
|
||||
<!-- ... -->
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="postLoad" method="doStuffOnPostLoad"/>
|
||||
</lifecycle-callbacks>
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
.. code-block:: yaml
|
||||
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
# ...
|
||||
value:
|
||||
type: string(255)
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||
postLoad: [ doStuffOnPostLoad ]
|
||||
|
||||
Lifecycle Callbacks Event Argument
|
||||
----------------------------------
|
||||
@@ -403,6 +411,8 @@ With the additional argument you have access to the
|
||||
}
|
||||
}
|
||||
|
||||
.. _listening-and-subscribing-to-lifecycle-events:
|
||||
|
||||
Listening and subscribing to Lifecycle Events
|
||||
---------------------------------------------
|
||||
|
||||
@@ -413,7 +423,7 @@ behaviors across different entity classes.
|
||||
|
||||
Note that they require much more detailed knowledge about the inner
|
||||
workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please
|
||||
read the :ref:`reference-events-implementing-listeners` section
|
||||
read the :ref:`Implementing Event Listeners<reference-events-implementing-listeners>` section
|
||||
carefully if you are trying to write your own listener.
|
||||
|
||||
For event subscribers, there are no surprises. They declare the
|
||||
@@ -482,8 +492,10 @@ EventManager that is passed to the EntityManager factory:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
$eventManager = new EventManager();
|
||||
$eventManager->addEventListener(array(Events::preUpdate), new MyEventListener());
|
||||
$eventManager->addEventListener([Events::preUpdate], new MyEventListener());
|
||||
$eventManager->addEventSubscriber(new MyEventSubscriber());
|
||||
|
||||
$entityManager = EntityManager::create($dbOpts, $config, $eventManager);
|
||||
@@ -494,7 +506,9 @@ EntityManager was created:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$entityManager->getEventManager()->addEventListener(array(Events::preUpdate), new MyEventListener());
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
$entityManager->getEventManager()->addEventListener([Events::preUpdate], new MyEventListener());
|
||||
$entityManager->getEventManager()->addEventSubscriber(new MyEventSubscriber());
|
||||
|
||||
.. _reference-events-implementing-listeners:
|
||||
@@ -514,6 +528,8 @@ the restrictions apply as well, with the additional restriction
|
||||
that (prior to version 2.4) you do not have access to the
|
||||
``EntityManager`` or ``UnitOfWork`` APIs inside these events.
|
||||
|
||||
.. _reference-events-pre-persist:
|
||||
|
||||
prePersist
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -539,6 +555,8 @@ The following restrictions apply to ``prePersist``:
|
||||
- Doctrine will not recognize changes made to relations in a prePersist
|
||||
event. This includes modifications to
|
||||
collections such as additions, removals or replacement.
|
||||
|
||||
.. _reference-events-pre-remove:
|
||||
|
||||
preRemove
|
||||
~~~~~~~~~
|
||||
@@ -551,6 +569,8 @@ There are no restrictions to what methods can be called inside the
|
||||
``preRemove`` event, except when the remove method itself was
|
||||
called during a flush operation.
|
||||
|
||||
.. _reference-events-pre-flush:
|
||||
|
||||
preFlush
|
||||
~~~~~~~~
|
||||
|
||||
@@ -573,6 +593,8 @@ result in infinite loop.
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-on-flush:
|
||||
|
||||
onFlush
|
||||
~~~~~~~
|
||||
|
||||
@@ -636,6 +658,8 @@ The following restrictions apply to the onFlush event:
|
||||
affected entity. This can be done by calling
|
||||
``$unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity)``.
|
||||
|
||||
.. _reference-events-post-flush:
|
||||
|
||||
postFlush
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -656,6 +680,8 @@ postFlush
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-pre-update:
|
||||
|
||||
preUpdate
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -740,6 +766,8 @@ Restrictions for this event:
|
||||
API are strongly discouraged and don't work as expected outside the
|
||||
flush operation.
|
||||
|
||||
.. _reference-events-post-update-remove-persist:
|
||||
|
||||
postUpdate, postRemove, postPersist
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -749,6 +777,8 @@ database, but you can use these events to alter non-persistable items,
|
||||
like non-mapped fields, logging or even associated classes that are
|
||||
not directly mapped by Doctrine.
|
||||
|
||||
.. _reference-events-post-load:
|
||||
|
||||
postLoad
|
||||
~~~~~~~~
|
||||
|
||||
@@ -765,7 +795,19 @@ An entity listener is a lifecycle listener class used for an entity.
|
||||
|
||||
.. configuration-block::
|
||||
|
||||
.. code-block:: php
|
||||
.. code-block:: attribute
|
||||
|
||||
<?php
|
||||
namespace MyProject\Entity;
|
||||
use App\EventListener\UserListener;
|
||||
|
||||
#[Entity]
|
||||
#[EntityListeners([UserListener::class])]
|
||||
class User
|
||||
{
|
||||
// ....
|
||||
}
|
||||
.. code-block:: annotation
|
||||
|
||||
<?php
|
||||
namespace MyProject\Entity;
|
||||
@@ -961,6 +1003,8 @@ Implementing your own resolver :
|
||||
$configurations->setEntityListenerResolver(new MyEntityListenerResolver);
|
||||
EntityManager::create(.., $configurations, ..);
|
||||
|
||||
.. _reference-events-load-class-metadata:
|
||||
|
||||
Load ClassMetadata Event
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ easily using a combination of ``count`` and ``slice``.
|
||||
``removeElement`` directly issued DELETE queries to the database from
|
||||
version 2.4.0 to 2.7.0. This circumvents the flush operation and might run
|
||||
outside a transactional boundary if you don't create one yourself. We
|
||||
consider this a critical bug in the assumptio of how the ORM works and
|
||||
consider this a critical bug in the assumption of how the ORM works and
|
||||
reverted ``removeElement`` EXTRA_LAZY behavior in 2.7.1.
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ that directory with the following contents:
|
||||
|
||||
{
|
||||
"require": {
|
||||
"doctrine/orm": "^2.6.2",
|
||||
"doctrine/orm": "^2.10.2",
|
||||
"doctrine/dbal": "^3.1.1",
|
||||
"symfony/yaml": "2.*",
|
||||
"symfony/cache": "^5.3"
|
||||
},
|
||||
@@ -112,6 +113,14 @@ Add the following directories:
|
||||
.. note::
|
||||
The YAML driver is deprecated and will be removed in version 3.0.
|
||||
It is strongly recommended to switch to one of the other mappings.
|
||||
.. note::
|
||||
It is strongly recommended that you require ``doctrine/dbal`` in your
|
||||
``composer.json`` as well, because using the ORM means mapping objects
|
||||
and their fields to database tables and their columns, and that
|
||||
requires mentioning so-called types that are defined in ``doctrine/dbal``
|
||||
in your application. Having an explicit requirement means you control
|
||||
when the upgrade to the next major version happens, so that you can
|
||||
do the necessary changes in your application beforehand.
|
||||
|
||||
Obtaining the EntityManager
|
||||
---------------------------
|
||||
@@ -642,7 +651,7 @@ Let's continue by creating a script to display the name of a product based on it
|
||||
echo sprintf("-%s\n", $product->getName());
|
||||
|
||||
Next we'll update a product's name, given its id. This simple example will
|
||||
help demonstrate Doctrine's implementation of the UnitOfWork pattern. Doctrine
|
||||
help demonstrate Doctrine's implementation of the :ref:`UnitOfWork pattern <unit-of-work>`. Doctrine
|
||||
keeps track of all the entities that were retrieved from the Entity Manager,
|
||||
and can detect when any of those entities' properties have been modified.
|
||||
As a result, rather than needing to call ``persist($entity)`` for each individual
|
||||
@@ -1334,7 +1343,7 @@ call this script as follows:
|
||||
php create_bug.php 1 1 1
|
||||
|
||||
See how simple it is to relate a Bug, Reporter, Engineer and Products?
|
||||
Also recall that thanks to the UnitOfWork pattern, Doctrine will detect
|
||||
Also recall that thanks to the :ref:`UnitOfWork pattern <unit-of-work>`, Doctrine will detect
|
||||
these relations and update all of the modified entities in the database
|
||||
automatically when ``flush()`` is called.
|
||||
|
||||
|
||||
+84
-3
@@ -18,13 +18,17 @@
|
||||
<xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="entity" type="orm:entity" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="embeddable" type="orm:embeddable" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:complexType name="emptyType">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="cascade-type">
|
||||
@@ -35,7 +39,9 @@
|
||||
<xs:element name="cascade-remove" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:element name="cascade-refresh" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:element name="cascade-detach" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="lifecycle-callback-type">
|
||||
@@ -61,15 +67,19 @@
|
||||
|
||||
<xs:complexType name="lifecycle-callback">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="type" type="orm:lifecycle-callback-type" use="required" />
|
||||
<xs:attribute name="method" type="xs:NMTOKEN" use="required" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="lifecycle-callbacks">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="named-query">
|
||||
@@ -88,6 +98,7 @@
|
||||
<xs:complexType name="named-native-query">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="query" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="result-class" type="orm:fqcn" />
|
||||
@@ -97,12 +108,14 @@
|
||||
<xs:complexType name="named-native-queries">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="named-native-query" type="orm:named-native-query" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="entity-listener">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="class" type="orm:fqcn"/>
|
||||
</xs:complexType>
|
||||
@@ -135,7 +148,9 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="entity-result" type="orm:entity-result"/>
|
||||
<xs:element name="column-result" type="orm:column-result"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
@@ -173,6 +188,7 @@
|
||||
<xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="association-overrides" type="orm:association-overrides" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="attribute-overrides" type="orm:attribute-overrides" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="table" type="orm:tablename" />
|
||||
@@ -181,6 +197,7 @@
|
||||
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
|
||||
<xs:attribute name="change-tracking-policy" type="orm:change-tracking-policy" />
|
||||
<xs:attribute name="read-only" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="tablename" id="tablename">
|
||||
@@ -193,21 +210,27 @@
|
||||
<xs:complexType name="option" mixed="true">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="option" type="orm:option"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="options">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="option" type="orm:option" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="mapped-superclass" >
|
||||
<xs:complexContent>
|
||||
<xs:extension base="orm:entity">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
@@ -216,6 +239,7 @@
|
||||
<xs:complexContent>
|
||||
<xs:extension base="orm:entity">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
@@ -267,10 +291,11 @@
|
||||
<xs:complexType name="field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="false" />
|
||||
@@ -278,6 +303,7 @@
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:attribute name="precision" type="xs:integer" use="optional" />
|
||||
<xs:attribute name="scale" type="xs:integer" use="optional" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="embedded">
|
||||
@@ -292,62 +318,78 @@
|
||||
|
||||
<xs:complexType name="discriminator-column">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="field-name" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="unique-constraint">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="fields" type="xs:string" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="unique-constraints">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="unique-constraint" type="orm:unique-constraint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="index">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="required"/>
|
||||
<xs:attribute name="fields" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="flags" type="xs:string" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="indexes">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="index" type="orm:index" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="discriminator-mapping">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
|
||||
<xs:attribute name="class" type="orm:fqcn" use="required"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="discriminator-map">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="discriminator-mapping" type="orm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="id">
|
||||
@@ -356,25 +398,30 @@
|
||||
<xs:element name="sequence-generator" type="orm:sequence-generator" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="custom-id-generator" type="orm:custom-id-generator" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="association-key" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="sequence-generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="sequence-name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="allocation-size" type="xs:integer" use="optional" default="1" />
|
||||
<xs:attribute name="initial-value" type="xs:integer" use="optional" default="1" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="custom-id-generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="class" type="orm:fqcn" use="required" />
|
||||
</xs:complexType>
|
||||
@@ -389,11 +436,14 @@
|
||||
<xs:complexType name="inverse-join-columns">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-column">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional" />
|
||||
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
|
||||
@@ -401,34 +451,43 @@
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="true" />
|
||||
<xs:attribute name="on-delete" type="orm:fk-action" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-columns">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-table">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-columns" type="orm:join-columns" />
|
||||
<xs:element name="inverse-join-columns" type="orm:join-columns" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="schema" type="xs:NMTOKEN" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="order-by">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="order-by-field" type="orm:order-by-field" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="order-by-field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="order-by-direction">
|
||||
@@ -438,12 +497,19 @@
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="columntoken" id="columntoken">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:pattern value="[-._:A-Za-z0-9`]+" id="columntoken.pattern"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:complexType name="many-to-many">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="cache" type="orm:cache" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
|
||||
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" use="required" />
|
||||
@@ -452,6 +518,7 @@
|
||||
<xs:attribute name="index-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="one-to-many">
|
||||
@@ -459,6 +526,7 @@
|
||||
<xs:element name="cache" type="orm:cache" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" use="required" />
|
||||
@@ -466,6 +534,7 @@
|
||||
<xs:attribute name="index-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="many-to-one">
|
||||
@@ -475,12 +544,15 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="join-column" type="orm:join-column"/>
|
||||
<xs:element name="join-columns" type="orm:join-columns"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" />
|
||||
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="one-to-one">
|
||||
@@ -490,7 +562,9 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="join-column" type="orm:join-column"/>
|
||||
<xs:element name="join-columns" type="orm:join-columns"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" />
|
||||
@@ -498,11 +572,13 @@
|
||||
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="association-overrides">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="association-override" type="orm:association-override" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
@@ -511,6 +587,7 @@
|
||||
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
|
||||
<xs:element name="join-columns" type="orm:join-columns" minOccurs="0" />
|
||||
<xs:element name="inversed-by" type="orm:inversed-by-override" minOccurs="0" maxOccurs="1" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" use="optional" />
|
||||
@@ -523,12 +600,14 @@
|
||||
<xs:complexType name="attribute-overrides">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="attribute-override" type="orm:attribute-override" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="attribute-override">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="field" type="orm:attribute-override-field" minOccurs="1" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
</xs:complexType>
|
||||
@@ -536,9 +615,10 @@
|
||||
<xs:complexType name="attribute-override-field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="false" />
|
||||
@@ -546,6 +626,7 @@
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:attribute name="precision" type="xs:integer" use="optional" />
|
||||
<xs:attribute name="scale" type="xs:integer" use="optional" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
|
||||
@@ -1253,7 +1253,8 @@ abstract class AbstractQuery
|
||||
* Will return the configured id if it exists otherwise a hash will be
|
||||
* automatically generated for you.
|
||||
*
|
||||
* @return array<string, string> ($key, $hash)
|
||||
* @return string[] ($key, $hash)
|
||||
* @psalm-return array{string, string} ($key, $hash)
|
||||
*/
|
||||
protected function getHydrationCacheId()
|
||||
{
|
||||
|
||||
@@ -357,9 +357,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$cached = $queryCache->put($queryKey, $rsm, [$result]);
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
if ($result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||
}
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||
|
||||
if ($cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);
|
||||
|
||||
@@ -5,9 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Cache\Persister\Entity;
|
||||
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\ORM\Cache\CacheException;
|
||||
use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyEntity;
|
||||
use Doctrine\ORM\Utility\StaticClassNameConverter;
|
||||
|
||||
/**
|
||||
* Specific read-only region entity persister
|
||||
|
||||
@@ -19,6 +19,7 @@ use Doctrine\Persistence\ObjectManager;
|
||||
* EntityManager interface
|
||||
*
|
||||
* @method Mapping\ClassMetadataFactory getMetadataFactory()
|
||||
* @method mixed wrapInTransaction(callable $func)
|
||||
*/
|
||||
interface EntityManagerInterface extends ObjectManager
|
||||
{
|
||||
@@ -329,11 +330,9 @@ interface EntityManagerInterface extends ObjectManager
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-param string|class-string<T> $className
|
||||
* @phpstan-param string $className
|
||||
*
|
||||
* @return Mapping\ClassMetadata
|
||||
* @psalm-return Mapping\ClassMetadata<T>
|
||||
* @phpstan-return Mapping\ClassMetadata<object>
|
||||
*
|
||||
* @psalm-template T of object
|
||||
*/
|
||||
|
||||
@@ -142,7 +142,7 @@ abstract class AbstractHydrator
|
||||
* @param Result|ResultStatement $stmt
|
||||
* @psalm-param array<string, mixed> $hints
|
||||
*
|
||||
* @return Generator<int, mixed>
|
||||
* @return Generator<array-key, mixed>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
@@ -194,9 +194,12 @@ abstract class AbstractHydrator
|
||||
$this->hydrateRowData($row, $result);
|
||||
|
||||
$this->cleanupAfterRowIteration();
|
||||
|
||||
if (count($result) === 1) {
|
||||
yield end($result);
|
||||
if (count($resultSetMapping->indexByMap) === 0) {
|
||||
yield end($result);
|
||||
} else {
|
||||
yield from $result;
|
||||
}
|
||||
} else {
|
||||
yield $result;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
|
||||
// We need to find the correct entity class name if we have inheritance in resultset
|
||||
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
|
||||
$discrColumnName = $this->getSQLResultCasing($this->_platform, $this->class->discriminatorColumn['name']);
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $this->getSQLResultCasing($this->_platform, $discrColumn['name']);
|
||||
|
||||
// Find mapped discriminator column from the result set.
|
||||
$metaMappingDiscrColumnName = array_search($discrColumnName, $this->resultSetMapping()->metaMappings, true);
|
||||
|
||||
@@ -184,9 +184,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
$class->setPrimaryTable($parent->table);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$this->addInheritedIndexes($class, $parent);
|
||||
}
|
||||
$this->addInheritedIndexes($class, $parent);
|
||||
|
||||
if ($parent->cache) {
|
||||
$class->cache = $parent->cache;
|
||||
@@ -276,7 +274,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
} else {
|
||||
assert($parent instanceof ClassMetadataInfo); // https://github.com/doctrine/orm/issues/8746
|
||||
if (
|
||||
(! $class->reflClass || ! $class->reflClass->isAbstract())
|
||||
! $class->reflClass->isAbstract()
|
||||
&& ! in_array($class->name, $class->discriminatorMap, true)
|
||||
) {
|
||||
throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
|
||||
|
||||
@@ -20,6 +20,7 @@ use Doctrine\ORM\Id\AbstractIdGenerator;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\ReflectionService;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use ReflectionClass;
|
||||
use ReflectionNamedType;
|
||||
use ReflectionProperty;
|
||||
@@ -69,6 +70,26 @@ use const PHP_VERSION_ID;
|
||||
*
|
||||
* @template-covariant T of object
|
||||
* @template-implements ClassMetadata<T>
|
||||
* @psalm-type FieldMapping = array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* length?: int,
|
||||
* id?: bool,
|
||||
* nullable?: bool,
|
||||
* columnDefinition?: string,
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* unique?: string,
|
||||
* inherited?: class-string,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* quoted?: bool,
|
||||
* requireSQLConversion?: bool,
|
||||
* declared?: class-string,
|
||||
* declaredField?: string,
|
||||
* options?: array<string, mixed>
|
||||
* }
|
||||
*/
|
||||
class ClassMetadataInfo implements ClassMetadata
|
||||
{
|
||||
@@ -426,25 +447,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* Whether a unique constraint should be generated for the column.
|
||||
*
|
||||
* @var mixed[]
|
||||
* @psalm-var array<string, array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* length?: int,
|
||||
* id?: bool,
|
||||
* nullable?: bool,
|
||||
* columnDefinition?: string,
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* unique?: string,
|
||||
* inherited?: class-string,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* quoted?: bool,
|
||||
* requireSQLConversion?: bool,
|
||||
* declaredField?: string,
|
||||
* options: array<mixed>
|
||||
* }>
|
||||
* @psalm-var array<string, FieldMapping>
|
||||
*/
|
||||
public $fieldMappings = [];
|
||||
|
||||
@@ -495,7 +498,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* READ-ONLY: The definition of the discriminator column used in JOINED and SINGLE_TABLE
|
||||
* inheritance mappings.
|
||||
*
|
||||
* @psalm-var array<string, mixed>
|
||||
* @psalm-var array<string, mixed>|null
|
||||
*/
|
||||
public $discriminatorColumn;
|
||||
|
||||
@@ -509,7 +512,14 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* uniqueConstraints => array
|
||||
*
|
||||
* @var mixed[]
|
||||
* @psalm-var array{name: string, schema: string, indexes: array, uniqueConstraints: array}
|
||||
* @psalm-var array{
|
||||
* name: string,
|
||||
* schema: string,
|
||||
* indexes: array,
|
||||
* uniqueConstraints: array,
|
||||
* options: array<string, mixed>,
|
||||
* quoted?: bool
|
||||
* }
|
||||
*/
|
||||
public $table;
|
||||
|
||||
@@ -665,7 +675,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* The ReflectionClass instance of the mapped class.
|
||||
*
|
||||
* @var ReflectionClass
|
||||
* @var ReflectionClass|null
|
||||
*/
|
||||
public $reflClass;
|
||||
|
||||
@@ -1276,18 +1286,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* @param string $fieldName The field name.
|
||||
*
|
||||
* @return mixed[] The field mapping.
|
||||
* @psalm-return array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* inherited?: class-string,
|
||||
* nullable?: bool,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* scale?: int,
|
||||
* precision?: int,
|
||||
* length?: int
|
||||
* }
|
||||
* @psalm-return FieldMapping
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -3090,6 +3089,18 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
final public function getDiscriminatorColumn(): array
|
||||
{
|
||||
if ($this->discriminatorColumn === null) {
|
||||
throw new LogicException('The discriminator column was not set.');
|
||||
}
|
||||
|
||||
return $this->discriminatorColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the discriminator values used by this class.
|
||||
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
|
||||
|
||||
@@ -15,26 +15,26 @@ use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final class Column implements Annotation
|
||||
{
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
public $name;
|
||||
|
||||
/** @var mixed */
|
||||
public $type;
|
||||
|
||||
/** @var int */
|
||||
/** @var int|null */
|
||||
public $length;
|
||||
|
||||
/**
|
||||
* The precision for a decimal (exact numeric) column (Applies only for decimal column).
|
||||
*
|
||||
* @var int
|
||||
* @var int|null
|
||||
*/
|
||||
public $precision = 0;
|
||||
|
||||
/**
|
||||
* The scale for a decimal (exact numeric) column (Applies only for decimal column).
|
||||
*
|
||||
* @var int
|
||||
* @var int|null
|
||||
*/
|
||||
public $scale = 0;
|
||||
|
||||
@@ -47,7 +47,7 @@ final class Column implements Annotation
|
||||
/** @var array<string,mixed> */
|
||||
public $options = [];
|
||||
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
public $columnDefinition;
|
||||
|
||||
/**
|
||||
|
||||
@@ -249,7 +249,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$field = $this->quoteStrategy->getColumnName($name, $targetClass, $this->platform);
|
||||
$whereClauses[] = sprintf('te.%s %s ?', $field, $operator);
|
||||
$params[] = $value;
|
||||
$paramTypes[] = PersisterHelper::getTypeOfColumn($field, $targetClass, $this->em);
|
||||
$paramTypes[] = PersisterHelper::getTypeOfField($name, $targetClass, $this->em)[0];
|
||||
}
|
||||
|
||||
$tableName = $this->quoteStrategy->getTableName($targetClass, $this->platform);
|
||||
|
||||
@@ -24,7 +24,7 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
|
||||
$data = parent::prepareInsertData($entity);
|
||||
|
||||
// Populate the discriminator column
|
||||
$discColumn = $this->class->discriminatorColumn;
|
||||
$discColumn = $this->class->getDiscriminatorColumn();
|
||||
$this->columnTypes[$discColumn['name']] = $discColumn['type'];
|
||||
$data[$this->getDiscriminatorColumnTableName()][$discColumn['name']] = $this->class->discriminatorValue;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ use Doctrine\ORM\Utility\PersisterHelper;
|
||||
|
||||
use function array_combine;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* The joined subclass persister maps a single entity instance to several tables in the
|
||||
@@ -412,14 +411,15 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
}
|
||||
|
||||
$columnList = [];
|
||||
$discrColumn = $this->class->discriminatorColumn['name'];
|
||||
$discrColumnType = $this->class->discriminatorColumn['type'];
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $discrColumn['name'];
|
||||
$discrColumnType = $discrColumn['type'];
|
||||
$baseTableAlias = $this->getSQLTableAlias($this->class->name);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumn);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumnName);
|
||||
|
||||
$this->currentPersisterContext->rsm->addEntityResult($this->class->name, 'r');
|
||||
$this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
|
||||
|
||||
// Add regular columns
|
||||
foreach ($this->class->fieldMappings as $fieldName => $mapping) {
|
||||
@@ -457,7 +457,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
? $baseTableAlias
|
||||
: $this->getSQLTableAlias($this->class->rootEntityName);
|
||||
|
||||
$columnList[] = $tableAlias . '.' . $discrColumn;
|
||||
$columnList[] = $tableAlias . '.' . $discrColumnName;
|
||||
|
||||
// sub tables
|
||||
foreach ($this->class->subClasses as $subClassName) {
|
||||
@@ -540,7 +540,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
|
||||
// Add discriminator column if it is the topmost class.
|
||||
if ($this->class->name === $this->class->rootEntityName) {
|
||||
$columns[] = $this->class->discriminatorColumn['name'];
|
||||
$columns[] = $this->class->getDiscriminatorColumn()['name'];
|
||||
}
|
||||
|
||||
return $columns;
|
||||
|
||||
@@ -44,16 +44,17 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$rootClass = $this->em->getClassMetadata($this->class->rootEntityName);
|
||||
$tableAlias = $this->getSQLTableAlias($rootClass->name);
|
||||
|
||||
// Append discriminator column
|
||||
$discrColumn = $this->class->discriminatorColumn['name'];
|
||||
$discrColumnType = $this->class->discriminatorColumn['type'];
|
||||
// Append discriminator column
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $discrColumn['name'];
|
||||
$discrColumnType = $discrColumn['type'];
|
||||
|
||||
$columnList[] = $tableAlias . '.' . $discrColumn;
|
||||
$columnList[] = $tableAlias . '.' . $discrColumnName;
|
||||
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumn);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumnName);
|
||||
|
||||
$this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
|
||||
|
||||
// Append subclass columns
|
||||
foreach ($this->class->subClasses as $subClassName) {
|
||||
@@ -100,7 +101,7 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$columns = parent::getInsertColumnList();
|
||||
|
||||
// Add discriminator column to the INSERT SQL
|
||||
$columns[] = $this->class->discriminatorColumn['name'];
|
||||
$columns[] = $this->class->getDiscriminatorColumn()['name'];
|
||||
|
||||
return $columns;
|
||||
}
|
||||
@@ -158,11 +159,12 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$values[] = $this->conn->quote($discrValues[$subclassName]);
|
||||
}
|
||||
|
||||
$discColumnName = $this->class->getDiscriminatorColumn()['name'];
|
||||
|
||||
$values = implode(', ', $values);
|
||||
$discColumn = $this->class->discriminatorColumn['name'];
|
||||
$tableAlias = $this->getSQLTableAlias($this->class->name);
|
||||
|
||||
return $tableAlias . '.' . $discColumn . ' IN (' . $values . ')';
|
||||
return $tableAlias . '.' . $discColumnName . ' IN (' . $values . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -649,6 +649,10 @@ final class Query extends AbstractQuery
|
||||
*/
|
||||
public function setFirstResult($firstResult): self
|
||||
{
|
||||
if ($firstResult !== null) {
|
||||
$firstResult = (int) $firstResult;
|
||||
}
|
||||
|
||||
$this->firstResult = $firstResult;
|
||||
$this->_state = self::STATE_DIRTY;
|
||||
|
||||
@@ -675,6 +679,10 @@ final class Query extends AbstractQuery
|
||||
*/
|
||||
public function setMaxResults($maxResults): self
|
||||
{
|
||||
if ($maxResults !== null) {
|
||||
$maxResults = (int) $maxResults;
|
||||
}
|
||||
|
||||
$this->maxResults = $maxResults;
|
||||
$this->_state = self::STATE_DIRTY;
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ class Parser
|
||||
*/
|
||||
private $customOutputWalker;
|
||||
|
||||
/** @psalm-var list<AST\SelectExpression> */
|
||||
/** @psalm-var array<string, AST\SelectExpression> */
|
||||
private $identVariableExpressions = [];
|
||||
|
||||
/**
|
||||
|
||||
@@ -369,7 +369,7 @@ class ResultSetMappingBuilder extends ResultSetMapping
|
||||
{
|
||||
if (isset($entityMapping['discriminatorColumn']) && $entityMapping['discriminatorColumn']) {
|
||||
$discriminatorColumn = $entityMapping['discriminatorColumn'];
|
||||
$discriminatorType = $classMetadata->discriminatorColumn['type'];
|
||||
$discriminatorType = $classMetadata->getDiscriminatorColumn()['type'];
|
||||
|
||||
$this->setDiscriminatorColumn($alias, $discriminatorColumn);
|
||||
$this->addMetaResult($alias, $discriminatorColumn, $discriminatorColumn, false, $discriminatorType);
|
||||
|
||||
@@ -465,7 +465,7 @@ class SqlWalker implements TreeWalker
|
||||
? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.'
|
||||
: '';
|
||||
|
||||
$sqlParts[] = $sqlTableAlias . $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
|
||||
$sqlParts[] = $sqlTableAlias . $class->getDiscriminatorColumn()['name'] . ' IN (' . implode(', ', $values) . ')';
|
||||
}
|
||||
|
||||
$sql = implode(' AND ', $sqlParts);
|
||||
@@ -739,7 +739,7 @@ class SqlWalker implements TreeWalker
|
||||
// Add discriminator columns to SQL
|
||||
$rootClass = $this->em->getClassMetadata($class->rootEntityName);
|
||||
$tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias);
|
||||
$discrColumn = $rootClass->discriminatorColumn;
|
||||
$discrColumn = $rootClass->getDiscriminatorColumn();
|
||||
$columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
|
||||
|
||||
$sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
|
||||
@@ -2091,7 +2091,7 @@ class SqlWalker implements TreeWalker
|
||||
$sql .= $this->getSQLTableAlias($discrClass->getTableName(), $dqlAlias) . '.';
|
||||
}
|
||||
|
||||
$sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
|
||||
$sql .= $class->getDiscriminatorColumn()['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
|
||||
$sql .= $this->getChildDiscriminatorsFromClassMetadata($discrClass, $instanceOfExpr);
|
||||
|
||||
return $sql;
|
||||
|
||||
@@ -627,6 +627,10 @@ class QueryBuilder
|
||||
*/
|
||||
public function setFirstResult($firstResult)
|
||||
{
|
||||
if ($firstResult !== null) {
|
||||
$firstResult = (int) $firstResult;
|
||||
}
|
||||
|
||||
$this->_firstResult = $firstResult;
|
||||
|
||||
return $this;
|
||||
@@ -652,6 +656,10 @@ class QueryBuilder
|
||||
*/
|
||||
public function setMaxResults($maxResults)
|
||||
{
|
||||
if ($maxResults !== null) {
|
||||
$maxResults = (int) $maxResults;
|
||||
}
|
||||
|
||||
$this->_maxResults = $maxResults;
|
||||
|
||||
return $this;
|
||||
|
||||
@@ -151,7 +151,7 @@ EOT
|
||||
if (empty($metadata)) {
|
||||
$ui->success('No Metadata Classes to process.');
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($metadata as $class) {
|
||||
|
||||
@@ -1140,7 +1140,11 @@ public function __construct(<params>)
|
||||
return '';
|
||||
}
|
||||
|
||||
$discrColumn = $metadata->discriminatorColumn;
|
||||
$discrColumn = $metadata->discriminatorColumn;
|
||||
if ($discrColumn === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$columnDefinition = 'name="' . $discrColumn['name']
|
||||
. '", type="' . $discrColumn['type']
|
||||
. '", length=' . $discrColumn['length'];
|
||||
|
||||
@@ -31,7 +31,7 @@ use const DIRECTORY_SEPARATOR;
|
||||
*/
|
||||
class EntityRepositoryGenerator
|
||||
{
|
||||
/** @psalm-var class-string */
|
||||
/** @psalm-var class-string|null */
|
||||
private $repositoryName;
|
||||
|
||||
/** @var string */
|
||||
|
||||
@@ -239,7 +239,7 @@ class SchemaValidator
|
||||
}
|
||||
}
|
||||
|
||||
if (! $class->isInheritanceTypeNone() && ! $class->isRootEntity() && ! $class->isMappedSuperclass && array_search($class->name, $class->discriminatorMap, true) === false) {
|
||||
if (! $class->isInheritanceTypeNone() && ! $class->isRootEntity() && ! $class->reflClass->isAbstract() && ! $class->isMappedSuperclass && array_search($class->name, $class->discriminatorMap, true) === false) {
|
||||
$ce[] = "Entity class '" . $class->name . "' is part of inheritance hierarchy, but is " .
|
||||
"not mapped in the root entity '" . $class->rootEntityName . "' discriminator map. " .
|
||||
'All subclasses must be listed in the discriminator map.';
|
||||
|
||||
+189
-39
@@ -85,11 +85,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$entry of method Doctrine\\\\ORM\\\\Cache\\\\EntityHydrator\\:\\:loadCacheEntry\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheEntry, Doctrine\\\\ORM\\\\Cache\\\\CacheEntry given\\.$#"
|
||||
count: 1
|
||||
@@ -105,6 +100,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type Doctrine\\\\Common\\\\Cache\\\\Cache\\|Doctrine\\\\Common\\\\Cache\\\\MultiGetCache of property Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultMultiGetRegion\\:\\:\\$cache is not covariant with PHPDoc type Doctrine\\\\Common\\\\Cache\\\\Cache of overridden property Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultRegion\\:\\:\\$cache\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Region/DefaultMultiGetRegion.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultRegion\\:\\:getCache\\(\\) should return Doctrine\\\\Common\\\\Cache\\\\CacheProvider but returns Doctrine\\\\Common\\\\Cache\\\\Cache\\.$#"
|
||||
count: 1
|
||||
@@ -185,6 +185,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/EntityManager.php
|
||||
|
||||
-
|
||||
message: "#^Template type T of method Doctrine\\\\ORM\\\\EntityManagerInterface\\:\\:getClassMetadata\\(\\) is not referenced in a parameter\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/EntityManagerInterface.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\EntityRepository\\:\\:findOneBy\\(\\) should return T\\|null but returns object\\|null\\.$#"
|
||||
count: 1
|
||||
@@ -240,6 +245,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/LazyCriteriaCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$cache\\.$#"
|
||||
count: 2
|
||||
@@ -412,7 +427,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
@@ -422,7 +437,12 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Negated boolean expression is always false\\.$#"
|
||||
count: 3
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes'\\|'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
@@ -530,21 +550,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\('name' \\=\\> string, 'schema' \\=\\> string, 'indexes' \\=\\> array, 'uniqueConstraints' \\=\\> array\\)\\) does not accept key 'options'\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\('name' \\=\\> string, 'schema' \\=\\> string, 'indexes' \\=\\> array, 'uniqueConstraints' \\=\\> array\\)\\) does not accept key 'quoted'\\.$#"
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\<string, array\\|string\\>\\) does not accept true\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method ReflectionProperty\\:\\:getType\\(\\)\\.$#"
|
||||
count: 3
|
||||
@@ -566,13 +571,13 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$type of static method Doctrine\\\\ORM\\\\Mapping\\\\MappingException\\:\\:invalidInheritanceType\\(\\) expects string, int given\\.$#"
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} on left side of \\?\\? always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
count: 2
|
||||
message: "#^Parameter \\#2 \\$type of static method Doctrine\\\\ORM\\\\Mapping\\\\MappingException\\:\\:invalidInheritanceType\\(\\) expects string, int given\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
@@ -770,6 +775,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string, int\\> of property Doctrine\\\\ORM\\\\Mapping\\\\Driver\\\\AttributeDriver\\:\\:\\$entityAnnotationClasses is not covariant with PHPDoc type array\\<class\\-string, bool\\|int\\> of overridden property Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\AnnotationDriver\\:\\:\\$entityAnnotationClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo&Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -965,6 +975,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'version' on \\*NEVER\\* in isset\\(\\) always exists and is always null\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1120,6 +1135,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'usage' on array\\{usage\\: string, region\\?\\: string\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1385,15 +1405,30 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Andx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Andx.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Orx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Orx.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Select\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Select.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Query\\\\FilterCollection\\:\\:\\$em \\(Doctrine\\\\ORM\\\\EntityManager\\) does not accept Doctrine\\\\ORM\\\\EntityManagerInterface\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/FilterCollection.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\<int, Doctrine\\\\ORM\\\\Query\\\\AST\\\\SelectExpression\\>\\) does not accept key non\\-empty\\-string\\.$#"
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Query\\\\FilterCollection\\:\\:\\$filterHash is never written, only read\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
path: lib/Doctrine/ORM/Query/FilterCollection.php
|
||||
|
||||
-
|
||||
message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
|
||||
@@ -1427,14 +1462,19 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
count: 1
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
-
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 4
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
message: "#^Offset 'columns' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'entities' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$class of static method Doctrine\\\\ORM\\\\Utility\\\\PersisterHelper\\:\\:getTypeOfColumn\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo given\\.$#"
|
||||
@@ -1481,6 +1521,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'resultVariable' on array\\{metadata\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, parent\\: string, relation\\: array, map\\: mixed, nestingLevel\\: int, token\\: array\\} in isset\\(\\) does not exist\\.$#"
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset string on array\\<int, array\\{class\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, dqlAlias\\: string, resultAlias\\: string\\}\\> in isset\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$entity of static method Doctrine\\\\ORM\\\\OptimisticLockException\\:\\:lockFailed\\(\\) expects object, class\\-string\\<object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1987,7 +2037,7 @@ parameters:
|
||||
path: lib/Doctrine/ORM/QueryBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\>&nonEmpty given\\.$#"
|
||||
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, non\\-empty\\-array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\> given\\.$#"
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/QueryBuilder.php
|
||||
|
||||
@@ -2026,11 +2076,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\Tools\\\\Console\\\\Command\\\\ConvertMappingCommand\\:\\:execute\\(\\) should return int but empty return statement found\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:setMetadata\\(\\) expects array\\<int, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata\\>, array\\<Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -2067,7 +2112,47 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
message: "#^Offset 'allocationSize' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'initialValue' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'name' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'sequenceName' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
@@ -2101,6 +2186,36 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'name' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'version' on array\\{type\\: string, fieldName\\: string, columnName\\?\\: string, length\\?\\: int, id\\?\\: bool, nullable\\?\\: bool, columnDefinition\\?\\: string, precision\\?\\: int, \\.\\.\\.\\} in isset\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$policy of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:_getChangeTrackingPolicyString\\(\\) expects 1\\|2\\|3, int given\\.$#"
|
||||
count: 1
|
||||
@@ -2111,6 +2226,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Right side of && is always true\\.$#"
|
||||
count: 2
|
||||
@@ -2121,6 +2241,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$table \\(array\\<string, array\\|bool\\|string\\>\\) on left side of \\?\\? is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Return type \\(void\\) of method Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\CountWalker\\:\\:walkSelectStatement\\(\\) should be compatible with return type \\(string\\) of method Doctrine\\\\ORM\\\\Query\\\\TreeWalker\\:\\:walkSelectStatement\\(\\)$#"
|
||||
count: 1
|
||||
@@ -2131,6 +2261,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'parent' on array\\{metadata\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, parent\\: string, relation\\: array, map\\: mixed, nestingLevel\\: int, token\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php
|
||||
|
||||
-
|
||||
message: "#^Return type \\(void\\) of method Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\LimitSubqueryWalker\\:\\:walkSelectStatement\\(\\) should be compatible with return type \\(string\\) of method Doctrine\\\\ORM\\\\Query\\\\TreeWalker\\:\\:walkSelectStatement\\(\\)$#"
|
||||
count: 1
|
||||
@@ -2166,6 +2301,21 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"&\" between string and 3 results in an error\\.$#"
|
||||
count: 1
|
||||
|
||||
+1
-10
@@ -21,7 +21,7 @@ parameters:
|
||||
message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/SQLResultCasing.php
|
||||
-
|
||||
message: '/^Parameter \$stmt of method .* has invalid typehint type Doctrine\\DBAL\\Driver\\ResultStatement\.$/'
|
||||
message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
|
||||
-
|
||||
message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/'
|
||||
@@ -30,15 +30,6 @@ parameters:
|
||||
message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
|
||||
|
||||
# Forward compatibility for DBAL 3.2
|
||||
- '/^Call to an undefined method Doctrine\\DBAL\\Cache\\QueryCacheProfile::[gs]etResultCache\(\)\.$/'
|
||||
-
|
||||
message: '/^Call to an undefined static method Doctrine\\DBAL\\Configuration::[gs]etResultCache\(\)\.$/'
|
||||
path: lib/Doctrine/ORM/Configuration.php
|
||||
-
|
||||
message: '/^Parameter #3 \$resultCache of class Doctrine\\DBAL\\Cache\\QueryCacheProfile constructor/'
|
||||
path: lib/Doctrine/ORM/AbstractQuery.php
|
||||
|
||||
# False positive
|
||||
-
|
||||
message: '/^Variable \$offset in isset\(\) always exists and is not nullable\.$/'
|
||||
|
||||
+119
-129
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.10.0@916b098b008f6de4543892b1e0651c1c3b92cbfa">
|
||||
<files psalm-version="4.13.1@5cf660f63b548ccd4a56f62d916ee4d6028e01a3">
|
||||
<file src="lib/Doctrine/ORM/AbstractQuery.php">
|
||||
<DeprecatedClass occurrences="1">
|
||||
<code>IterableResult</code>
|
||||
@@ -7,9 +7,6 @@
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>iterate</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>$resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<FalsableReturnStatement occurrences="1">
|
||||
<code>! $filteredParameters->isEmpty() ? $filteredParameters->first() : null</code>
|
||||
</FalsableReturnStatement>
|
||||
@@ -273,8 +270,7 @@
|
||||
<code>getCacheFactory</code>
|
||||
<code>getTimestampRegion</code>
|
||||
</PossiblyNullReference>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$result</code>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>assert($metadata instanceof ClassMetadata)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="9">
|
||||
@@ -503,10 +499,9 @@
|
||||
<code>$entityName</code>
|
||||
<code>$entityName</code>
|
||||
</ParamNameMismatch>
|
||||
<PossiblyNullArgument occurrences="3">
|
||||
<PossiblyNullArgument occurrences="2">
|
||||
<code>$config->getProxyDir()</code>
|
||||
<code>$config->getProxyNamespace()</code>
|
||||
<code>$entity</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullReference occurrences="2">
|
||||
<code>createCache</code>
|
||||
@@ -520,15 +515,16 @@
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>new $metadataFactoryClassName()</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCondition occurrences="1">
|
||||
<RedundantCondition occurrences="2">
|
||||
<code>is_object($connection)</code>
|
||||
<code>is_object($connection)</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->filterCollection !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<TypeDoesNotContainType occurrences="2">
|
||||
<code>$connection instanceof Connection</code>
|
||||
<code>': "' . $connection . '"'</code>
|
||||
<code>gettype($connection)</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/EntityManagerInterface.php">
|
||||
@@ -606,9 +602,6 @@
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="1">
|
||||
<code>$sequenceName</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<code>(string) $em->getConnection()->lastInsertId($this->sequenceName)</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Id/TableGenerator.php">
|
||||
<PossiblyFalseOperand occurrences="3">
|
||||
@@ -779,9 +772,7 @@
|
||||
</RedundantCastGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/ClassMetadata.php">
|
||||
<PropertyNotSetInConstructor occurrences="8">
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
<PropertyNotSetInConstructor occurrences="6">
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
@@ -823,13 +814,13 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>ClassMetadata::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<DeprecatedMethod occurrences="3">
|
||||
<code>addNamedNativeQuery</code>
|
||||
<code>addNamedQuery</code>
|
||||
<code>getName</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>! $class->reflClass</code>
|
||||
<code>$class->reflClass</code>
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $definition</code>
|
||||
<code>$definition</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidArrayOffset occurrences="1">
|
||||
@@ -872,6 +863,9 @@
|
||||
<code>$parent->table</code>
|
||||
<code>$parent->versionField</code>
|
||||
</NoInterfaceProperties>
|
||||
<PossiblyInvalidArrayAssignment occurrences="1">
|
||||
<code>$subClass->table[$indexType][$indexName]</code>
|
||||
</PossiblyInvalidArrayAssignment>
|
||||
<PossiblyInvalidIterator occurrences="1">
|
||||
<code>$parentClass->table[$indexType]</code>
|
||||
</PossiblyInvalidIterator>
|
||||
@@ -894,7 +888,7 @@
|
||||
<code>$subClass->table</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$parent</code>
|
||||
<code>$parent->idGenerator</code>
|
||||
<code>$parent->idGenerator</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="17">
|
||||
@@ -925,13 +919,17 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>self::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>canEmulateSchemas</code>
|
||||
</DeprecatedMethod>
|
||||
<DeprecatedProperty occurrences="4">
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
</DeprecatedProperty>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $this->table</code>
|
||||
<code>$this->table</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidDocblock occurrences="4">
|
||||
@@ -940,9 +938,10 @@
|
||||
<code>protected function _validateAndCompleteOneToOneMapping(array $mapping)</code>
|
||||
<code>public $inheritanceType = self::INHERITANCE_TYPE_NONE;</code>
|
||||
</InvalidDocblock>
|
||||
<InvalidNullableReturnType occurrences="2">
|
||||
<InvalidNullableReturnType occurrences="3">
|
||||
<code>ReflectionProperty</code>
|
||||
<code>ReflectionProperty</code>
|
||||
<code>getReflectionClass</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$definition</code>
|
||||
@@ -971,7 +970,8 @@
|
||||
<MoreSpecificReturnType occurrences="1">
|
||||
<code>array{usage: int, region: string|null}</code>
|
||||
</MoreSpecificReturnType>
|
||||
<NullableReturnStatement occurrences="2">
|
||||
<NullableReturnStatement occurrences="3">
|
||||
<code>$this->reflClass</code>
|
||||
<code>$this->reflFields[$name]</code>
|
||||
<code>$this->reflFields[$this->identifier[0]]</code>
|
||||
</NullableReturnStatement>
|
||||
@@ -991,12 +991,17 @@
|
||||
<code>$queryMapping['resultClass']</code>
|
||||
<code>$reflService->getAccessibleProperty($mapping['originalClass'], $mapping['originalField'])</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="3">
|
||||
<code>$reflService->getClass($this->name)</code>
|
||||
<code>$reflService->getClass($this->name)</code>
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="1">
|
||||
<code>null</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
<PossiblyNullReference occurrences="6">
|
||||
<PossiblyNullPropertyFetch occurrences="2">
|
||||
<code>$embeddable->reflClass->name</code>
|
||||
<code>$this->reflClass->name</code>
|
||||
</PossiblyNullPropertyFetch>
|
||||
<PossiblyNullReference occurrences="9">
|
||||
<code>getProperty</code>
|
||||
<code>getProperty</code>
|
||||
<code>getProperty</code>
|
||||
<code>getValue</code>
|
||||
<code>getValue</code>
|
||||
<code>getValue</code>
|
||||
@@ -1017,12 +1022,10 @@
|
||||
<code>$this->fieldMappings[$idProperty]['columnName']</code>
|
||||
<code>$this->fieldMappings[$idProperty]['columnName']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
<PropertyNotSetInConstructor occurrences="8">
|
||||
<code>$discriminatorColumn</code>
|
||||
<PropertyNotSetInConstructor occurrences="6">
|
||||
<code>$idGenerator</code>
|
||||
<code>$isVersioned</code>
|
||||
<code>$namespace</code>
|
||||
<code>$reflClass</code>
|
||||
<code>$sequenceGeneratorDefinition</code>
|
||||
<code>$table</code>
|
||||
<code>$tableGeneratorDefinition</code>
|
||||
@@ -1045,21 +1048,11 @@
|
||||
<code>$mapping !== false</code>
|
||||
<code>$mapping !== false</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<RedundantPropertyInitializationCheck occurrences="1"/>
|
||||
<TooManyArguments occurrences="2">
|
||||
<code>joinColumnName</code>
|
||||
<code>joinColumnName</code>
|
||||
</TooManyArguments>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/Column.php">
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="5">
|
||||
<code>$columnDefinition</code>
|
||||
<code>$length</code>
|
||||
<code>$name</code>
|
||||
<code>$precision</code>
|
||||
<code>$scale</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/ColumnResult.php">
|
||||
<MissingConstructor occurrences="1">
|
||||
<code>$name</code>
|
||||
@@ -1088,6 +1081,10 @@
|
||||
</PossiblyFalseOperand>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php">
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<code>canEmulateSchemas</code>
|
||||
<code>canEmulateSchemas</code>
|
||||
</DeprecatedMethod>
|
||||
<MissingClosureParamType occurrences="1">
|
||||
<code>$joinColumn</code>
|
||||
</MissingClosureParamType>
|
||||
@@ -1108,9 +1105,14 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$metadata</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $class</code>
|
||||
<code>$class</code>
|
||||
</DocblockTypeContradiction>
|
||||
<LessSpecificReturnStatement occurrences="1">
|
||||
<code>$mapping</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType occurrences="1"/>
|
||||
<NoInterfaceProperties occurrences="5">
|
||||
<code>$metadata->inheritanceType</code>
|
||||
<code>$metadata->isEmbeddedClass</code>
|
||||
@@ -1125,10 +1127,6 @@
|
||||
<code>$primaryTable['indexes']</code>
|
||||
<code>$primaryTable['uniqueConstraints']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>isset($column->columnDefinition)</code>
|
||||
<code>isset($column->name)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="32">
|
||||
<code>addEntityListener</code>
|
||||
<code>addLifecycleCallback</code>
|
||||
@@ -1177,6 +1175,10 @@
|
||||
<code>$value[1]</code>
|
||||
<code>$value[1]</code>
|
||||
</InvalidArrayAccess>
|
||||
<LessSpecificReturnStatement occurrences="1">
|
||||
<code>$mapping</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType occurrences="1"/>
|
||||
<NonInvariantDocblockPropertyType occurrences="1">
|
||||
<code>$entityAnnotationClasses</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
@@ -1193,10 +1195,8 @@
|
||||
<code>assert($method instanceof ReflectionMethod)</code>
|
||||
<code>assert($property instanceof ReflectionProperty)</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>assert($cacheAttribute instanceof Mapping\Cache)</code>
|
||||
<code>isset($column->columnDefinition)</code>
|
||||
<code>isset($column->name)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php">
|
||||
@@ -1291,11 +1291,7 @@
|
||||
<code>$indexXml->options</code>
|
||||
<code>$uniqueXml->options</code>
|
||||
</PossiblyInvalidPropertyFetch>
|
||||
<RedundantCast occurrences="1">
|
||||
<code>(string) $attributes->name</code>
|
||||
</RedundantCast>
|
||||
<RedundantCondition occurrences="20">
|
||||
<code>isset($attributes->name)</code>
|
||||
<RedundantCondition occurrences="19">
|
||||
<code>isset($xmlRoot->cache)</code>
|
||||
<code>isset($xmlRoot->embedded)</code>
|
||||
<code>isset($xmlRoot->field)</code>
|
||||
@@ -1587,16 +1583,7 @@
|
||||
<InvalidDocblock occurrences="1">
|
||||
<code>final class PersistentCollection extends AbstractLazyCollection implements Selectable</code>
|
||||
</InvalidDocblock>
|
||||
<InvalidReturnStatement occurrences="5">
|
||||
<code>$persister->slice($this, $offset, $length)</code>
|
||||
<code>$this->collection</code>
|
||||
<code>new ArrayCollection($persister->loadCriteria($this, $criteria))</code>
|
||||
<code>parent::slice($offset, $length)</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType occurrences="2">
|
||||
<code>Collection<TKey, T></code>
|
||||
<code>array<TKey,T></code>
|
||||
</InvalidReturnType>
|
||||
<InvalidReturnStatement occurrences="1"/>
|
||||
<MissingParamType occurrences="2">
|
||||
<code>$key</code>
|
||||
<code>$offset</code>
|
||||
@@ -1631,7 +1618,9 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$backRefFieldName</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<RedundantConditionGivenDocblockType occurrences="5">
|
||||
<code>$this->em</code>
|
||||
<code>$this->em</code>
|
||||
<code>is_object($this->collection)</code>
|
||||
<code>is_object($value) && $this->em</code>
|
||||
<code>is_object($value) && $this->em</code>
|
||||
@@ -1857,9 +1846,6 @@
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>$this->currentPersisterContext->sqlTableAliases</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>($comparison === Comparison::EQ || $comparison === Comparison::IS) && $value === null</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->insertSql !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -1900,11 +1886,6 @@
|
||||
<code>$columnList</code>
|
||||
</PossiblyUndefinedVariable>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Persisters/SqlValueVisitor.php">
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>($operator === Comparison::EQ || $operator === Comparison::IS) && $value === null</code>
|
||||
</RedundantCondition>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Proxy/ProxyFactory.php">
|
||||
<ArgumentTypeCoercion occurrences="2">
|
||||
<code>$classMetadata</code>
|
||||
@@ -1973,9 +1954,6 @@
|
||||
<code>$queryCacheTTL</code>
|
||||
<code>Query</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<code>(int) $timeToLive</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="4">
|
||||
<code>$dqlQuery !== null</code>
|
||||
<code>$rsm !== null</code>
|
||||
@@ -2203,6 +2181,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getLowerExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2232,6 +2213,9 @@
|
||||
</PropertyNotSetInConstructor>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php">
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getSqrtExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$simpleArithmeticExpression</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2270,6 +2254,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getUpperExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2636,16 +2623,9 @@
|
||||
<code>call_user_func($functionClass, $functionName)</code>
|
||||
<code>call_user_func($functionClass, $functionName)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidArrayOffset occurrences="2">
|
||||
<code>$this->identVariableExpressions[$dqlAlias]</code>
|
||||
<code>$this->queryComponents[$dqlAlias]</code>
|
||||
</InvalidArrayOffset>
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>SelectStatement|UpdateStatement|DeleteStatement</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$this->identVariableExpressions</code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<InvalidReturnStatement occurrences="9">
|
||||
<code>$primary</code>
|
||||
<code>$this->CollectionMemberExpression()</code>
|
||||
@@ -2850,27 +2830,36 @@
|
||||
<code>$renameMode</code>
|
||||
<code>$renameMode</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<PossiblyNullPropertyFetch occurrences="1">
|
||||
<code>$classMetadata->reflClass->name</code>
|
||||
</PossiblyNullPropertyFetch>
|
||||
<PossiblyNullReference occurrences="3">
|
||||
<code>getShortName</code>
|
||||
<code>getShortName</code>
|
||||
<code>getShortName</code>
|
||||
</PossiblyNullReference>
|
||||
<PossiblyUndefinedArrayOffset occurrences="1">
|
||||
<code>$class->fieldMappings[$this->fieldMappings[$columnName]]['columnName']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Query/SqlWalker.php">
|
||||
<DocblockTypeContradiction occurrences="10">
|
||||
<code>! ($factor instanceof AST\ConditionalFactor)</code>
|
||||
<code>$condExpr instanceof AST\ConditionalExpression</code>
|
||||
<code>$condTerm instanceof AST\ConditionalTerm</code>
|
||||
<code>$simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression</code>
|
||||
<DocblockTypeContradiction occurrences="8">
|
||||
<code>$likeExpr->stringPattern instanceof AST\Functions\FunctionNode</code>
|
||||
<code>$likeExpr->stringPattern instanceof AST\PathExpression</code>
|
||||
<code>$this->queryComponents[$dqlAlias]['relation'] === null</code>
|
||||
<code>''</code>
|
||||
<code>is_numeric($leftExpr) ? $leftExpr : $this->conn->quote($leftExpr)</code>
|
||||
<code>is_numeric($rightExpr) ? $rightExpr : $this->conn->quote($rightExpr)</code>
|
||||
<code>is_numeric($leftExpr)</code>
|
||||
<code>is_numeric($rightExpr)</code>
|
||||
<code>is_string($expression)</code>
|
||||
<code>is_string($stringExpr)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<ImplicitToStringCast occurrences="1">
|
||||
<code>$expr</code>
|
||||
</ImplicitToStringCast>
|
||||
<InvalidArgument occurrences="1">
|
||||
<InvalidArgument occurrences="4">
|
||||
<code>$condExpr</code>
|
||||
<code>$condTerm</code>
|
||||
<code>$factor</code>
|
||||
<code>$selectedClass['class']->name</code>
|
||||
</InvalidArgument>
|
||||
<InvalidArrayOffset occurrences="1">
|
||||
@@ -2941,10 +2930,12 @@
|
||||
<code>$this->queryComponents</code>
|
||||
<code>$this->selectedClasses</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantConditionGivenDocblockType occurrences="5">
|
||||
<RedundantConditionGivenDocblockType occurrences="7">
|
||||
<code>$leftExpr instanceof AST\Node</code>
|
||||
<code>$likeExpr->stringPattern instanceof AST\InputParameter</code>
|
||||
<code>$rightExpr instanceof AST\Node</code>
|
||||
<code>$this->conn->quote($leftExpr)</code>
|
||||
<code>$this->conn->quote($rightExpr)</code>
|
||||
<code>$whereClause !== null</code>
|
||||
<code>($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -3239,10 +3230,9 @@
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->cacheMode</code>
|
||||
</NullableReturnStatement>
|
||||
<PossiblyFalseArgument occurrences="3">
|
||||
<PossiblyFalseArgument occurrences="2">
|
||||
<code>$spacePos</code>
|
||||
<code>$spacePos</code>
|
||||
<code>strpos($join, '.')</code>
|
||||
</PossiblyFalseArgument>
|
||||
<PossiblyFalseOperand occurrences="2">
|
||||
<code>$spacePos</code>
|
||||
@@ -3258,13 +3248,6 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$_dql</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="5">
|
||||
<code>(bool) $cacheable</code>
|
||||
<code>(bool) $flag</code>
|
||||
<code>(int) $cacheMode</code>
|
||||
<code>(int) $lifetime</code>
|
||||
<code>(string) $cacheRegion</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->_dql !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -3315,13 +3298,9 @@
|
||||
<MissingReturnType occurrences="1">
|
||||
<code>configure</code>
|
||||
</MissingReturnType>
|
||||
<PossiblyNullArgument occurrences="2">
|
||||
<code>$cacheDriver</code>
|
||||
<PossiblyNullArgument occurrences="1">
|
||||
<code>$cacheDriver</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>deleteAll</code>
|
||||
</PossiblyNullReference>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php">
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
@@ -3352,9 +3331,6 @@
|
||||
<code>new ClassMetadataExporter()</code>
|
||||
<code>new EntityGenerator()</code>
|
||||
</DeprecatedClass>
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>int</code>
|
||||
</InvalidNullableReturnType>
|
||||
<MissingReturnType occurrences="1">
|
||||
<code>configure</code>
|
||||
</MissingReturnType>
|
||||
@@ -3494,10 +3470,8 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>ClassMetadataInfo::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>$metadata->reflClass !== null</code>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>class_exists($metadata->name)</code>
|
||||
<code>new ReflectionClass($metadata->name)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidDocblock occurrences="1">
|
||||
<code>public function setFieldVisibility($visibility)</code>
|
||||
@@ -3523,12 +3497,13 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$classToExtend</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<RedundantCastGivenDocblockType occurrences="2">
|
||||
<code>(array) $metadata->table['options']</code>
|
||||
<code>(bool) $embeddablesImmutable</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<code>$metadata->reflClass</code>
|
||||
<code>$metadata->reflClass !== null</code>
|
||||
<code>$metadata->sequenceGeneratorDefinition</code>
|
||||
<code>$metadata->sequenceGeneratorDefinition</code>
|
||||
<code>isset($metadata->lifecycleCallbacks)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
@@ -3538,15 +3513,9 @@
|
||||
<code>$fullClassName</code>
|
||||
<code>$fullClassName</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>EntityRepository::class</code>
|
||||
</DocblockTypeContradiction>
|
||||
<PossiblyFalseOperand occurrences="1">
|
||||
<code>strrpos($fullClassName, '\\')</code>
|
||||
</PossiblyFalseOperand>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$repositoryName</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>$repositoryName</code>
|
||||
</PropertyTypeCoercion>
|
||||
@@ -3609,6 +3578,10 @@
|
||||
<NonInvariantDocblockPropertyType occurrences="1">
|
||||
<code>$_extension</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$metadata->table</code>
|
||||
<code>$metadata->table</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php">
|
||||
<ArgumentTypeCoercion occurrences="3">
|
||||
@@ -3635,10 +3608,12 @@
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>addAttribute</code>
|
||||
</PossiblyNullReference>
|
||||
<RedundantCondition occurrences="1">
|
||||
<RedundantCondition occurrences="2">
|
||||
<code>$field['associationKey']</code>
|
||||
<code>isset($field['associationKey']) && $field['associationKey']</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$sequenceDefinition</code>
|
||||
<code>isset($metadata->lifecycleCallbacks)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
@@ -3675,6 +3650,10 @@
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php">
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<code>getCountExpression</code>
|
||||
<code>getCountExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<MoreSpecificImplementedParamType occurrences="1">
|
||||
<code>$query</code>
|
||||
</MoreSpecificImplementedParamType>
|
||||
@@ -3728,7 +3707,8 @@
|
||||
</PropertyNotSetInConstructor>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalFactor</code>
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalPrimary</code>
|
||||
</DocblockTypeContradiction>
|
||||
<ImplementedReturnTypeMismatch occurrences="1">
|
||||
@@ -3740,12 +3720,16 @@
|
||||
<PossiblyInvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$AST->whereClause->conditionalExpression</code>
|
||||
</PossiblyInvalidPropertyAssignmentValue>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalExpression</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="1"/>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/SchemaTool.php">
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DeprecatedMethod occurrences="3">
|
||||
<code>canEmulateSchemas</code>
|
||||
<code>compare</code>
|
||||
<code>setExplicitForeignKeyIndexes</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $definingClass</code>
|
||||
<code>$definingClass</code>
|
||||
</DocblockTypeContradiction>
|
||||
<MissingClosureParamType occurrences="1">
|
||||
@@ -3773,6 +3757,11 @@
|
||||
<code>$indexName</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/SchemaValidator.php">
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>isAbstract</code>
|
||||
</PossiblyNullReference>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Setup.php">
|
||||
<DeprecatedClass occurrences="3">
|
||||
<code>new ClassLoader('Doctrine', $directory)</code>
|
||||
@@ -3877,7 +3866,8 @@
|
||||
<code>setValue</code>
|
||||
<code>setValue</code>
|
||||
</PossiblyNullReference>
|
||||
<PossiblyUndefinedMethod occurrences="3">
|
||||
<PossiblyUndefinedMethod occurrences="4">
|
||||
<code>addPropertyChangedListener</code>
|
||||
<code>unwrap</code>
|
||||
<code>unwrap</code>
|
||||
<code>unwrap</code>
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
<!-- We're calling the deprecated method for BC here. -->
|
||||
<file name="lib/Doctrine/ORM/Internal/SQLResultCasing.php"/>
|
||||
<!-- We need to keep the calls for DBAL 2.13 compatibility. -->
|
||||
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::getResultCacheDriver"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::setResultCacheDriver"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Configuration::getResultCacheImpl"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Configuration::setResultCacheImpl"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Connection::getSchemaManager"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getGuidExpression"/>
|
||||
</errorLevel>
|
||||
@@ -76,6 +80,20 @@
|
||||
<file name="lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php"/>
|
||||
</errorLevel>
|
||||
</NullArgument>
|
||||
<RedundantCastGivenDocblockType>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Can be removed once the "getMaxResults" methods of those classes have native parameter types -->
|
||||
<file name="lib/Doctrine/ORM/Query.php"/>
|
||||
<file name="lib/Doctrine/ORM/QueryBuilder.php"/>
|
||||
</errorLevel>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<!-- Workaround for https://github.com/vimeo/psalm/issues/7026 -->
|
||||
<ReservedWord>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="lib"/>
|
||||
<directory name="tests"/>
|
||||
</errorLevel>
|
||||
</ReservedWord>
|
||||
<TypeDoesNotContainType>
|
||||
<errorLevel type="suppress">
|
||||
<file name="lib/Doctrine/ORM/Internal/SQLResultCasing.php"/>
|
||||
|
||||
@@ -17,16 +17,14 @@ abstract class GetMetadata
|
||||
{
|
||||
/**
|
||||
* @param string|object $class
|
||||
* @phpstan-param class-string|object $class
|
||||
* @psalm-param class-string|object $class
|
||||
*/
|
||||
abstract public function getEntityManager($class): EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* @psalm-param class-string<TObject> $class
|
||||
* @phpstan-param class-string $class
|
||||
*
|
||||
* @psalm-return ClassMetadata<TObject>
|
||||
* @phpstan-return ClassMetadata<object>
|
||||
*
|
||||
* @psalm-template TObject of object
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\IterableTester;
|
||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||
use Doctrine\Tests\Models\CMS\CmsArticle;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
@@ -68,4 +69,48 @@ final class QueryIterableTest extends OrmFunctionalTestCase
|
||||
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
|
||||
public function testIndexByQueryWithOneResult(): void
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->name = 'Antonio J.';
|
||||
$user->username = 'ajgarlag';
|
||||
$user->status = 'developer';
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$query = $this->_em->createQuery('SELECT u FROM ' . CmsUser::class . ' u INDEX BY u.username');
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
|
||||
public function testIndexByQueryWithMultipleResults(): void
|
||||
{
|
||||
$article1 = new CmsArticle();
|
||||
$article1->topic = 'Doctrine 2';
|
||||
$article1->text = 'This is an introduction to Doctrine 2.';
|
||||
|
||||
$article2 = new CmsArticle();
|
||||
$article2->topic = 'Symfony 2';
|
||||
$article2->text = 'This is an introduction to Symfony 2.';
|
||||
|
||||
$article3 = new CmsArticle();
|
||||
$article3->topic = 'Laminas';
|
||||
$article3->text = 'This is an introduction to Laminas.';
|
||||
|
||||
$article4 = new CmsArticle();
|
||||
$article4->topic = 'CodeIgniter';
|
||||
$article4->text = 'This is an introduction to CodeIgniter.';
|
||||
|
||||
$this->_em->persist($article1);
|
||||
$this->_em->persist($article2);
|
||||
$this->_em->persist($article3);
|
||||
$this->_em->persist($article4);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('select a from ' . CmsArticle::class . ' a INDEX BY a.topic');
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\GeneratedValue;
|
||||
use Doctrine\ORM\Mapping\Id;
|
||||
use Doctrine\ORM\Mapping\ManyToMany;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group GH-9109
|
||||
*/
|
||||
class GH9109Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH9109User::class),
|
||||
$this->_em->getClassMetadata(GH9109Product::class),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->_schemaTool->dropSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH9109User::class),
|
||||
$this->_em->getClassMetadata(GH9109Product::class),
|
||||
]
|
||||
);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testIssue(): void
|
||||
{
|
||||
$userFirstName = 'GH9109Test';
|
||||
$userLastName = 'UserGH9109';
|
||||
$productTitle = 'Test product';
|
||||
|
||||
$userRepository = $this->_em->getRepository(GH9109User::class);
|
||||
|
||||
$user = new GH9109User();
|
||||
$user->setFirstName($userFirstName);
|
||||
$user->setLastName($userLastName);
|
||||
|
||||
$product = new GH9109Product();
|
||||
$product->setTitle($productTitle);
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$product->addBuyer($user);
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$persistedProduct = $this->_em->find(GH9109Product::class, $product->getId());
|
||||
|
||||
// assert Product was persisted
|
||||
self::assertInstanceOf(GH9109Product::class, $persistedProduct);
|
||||
self::assertEquals($productTitle, $persistedProduct->getTitle());
|
||||
|
||||
// assert Product has a Buyer
|
||||
$count = $persistedProduct->getBuyers()->count();
|
||||
self::assertEquals(1, $count);
|
||||
|
||||
// assert NOT QUOTED will WORK with findOneBy
|
||||
$user = $userRepository->findOneBy(['lastName' => $userLastName]);
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userLastName, $user->getLastName());
|
||||
|
||||
// assert NOT QUOTED will WORK with Criteria
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where($criteria->expr()->eq('lastName', $userLastName));
|
||||
$user = $persistedProduct->getBuyers()->matching($criteria)->first();
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userLastName, $user->getLastName());
|
||||
|
||||
// assert QUOTED will WORK with findOneBy
|
||||
$user = $userRepository->findOneBy(['firstName' => $userFirstName]);
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userFirstName, $user->getFirstName());
|
||||
|
||||
// assert QUOTED will WORK with Criteria
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where($criteria->expr()->eq('firstName', $userFirstName));
|
||||
$user = $persistedProduct->getBuyers()->matching($criteria)->first();
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userFirstName, $user->getFirstName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH9109Product
|
||||
{
|
||||
/**
|
||||
* @var int $id
|
||||
* @Column(name="`id`", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string $title
|
||||
* @Column(name="`title`", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var Collection|GH9109User[]
|
||||
* @psalm-var Collection<int, GH9109User>
|
||||
* @ManyToMany(targetEntity="GH9109User")
|
||||
*/
|
||||
private $buyers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->buyers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return Collection<int, GH9109User>
|
||||
*/
|
||||
public function getBuyers(): Collection
|
||||
{
|
||||
return $this->buyers;
|
||||
}
|
||||
|
||||
public function addBuyer(GH9109User $buyer): void
|
||||
{
|
||||
$this->buyers[] = $buyer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH9109User
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @Column(name="`id`", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @Column(name="`first_name`", type="string")
|
||||
*/
|
||||
private $firstName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @Column(name="last_name", type="string")
|
||||
*/
|
||||
private $lastName;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getFirstName(): string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName(string $firstName): void
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
}
|
||||
|
||||
public function getLastName(): string
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function setLastName(string $lastName): void
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
}
|
||||
}
|
||||
@@ -1119,6 +1119,13 @@ abstract class AbstractMappingDriverTest extends OrmTestCase
|
||||
$class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
|
||||
self::assertEquals('dtype', $class->discriminatorColumn['name']);
|
||||
}
|
||||
|
||||
public function testReservedWordInTableColumn(): void
|
||||
{
|
||||
$metadata = $this->createClassMetadata(ReservedWordInTableColumn::class);
|
||||
|
||||
self::assertSame('count', $metadata->getFieldMapping('count')['columnName']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1774,3 +1781,42 @@ class SingleTableEntityIncompleteDiscriminatorColumnMappingSub1 extends SingleTa
|
||||
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub2 extends SingleTableEntityIncompleteDiscriminatorColumnMapping
|
||||
{
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
#[ORM\Entity]
|
||||
class ReservedWordInTableColumn
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
#[ORM\Id, ORM\Column(type: 'integer'), ORM\GeneratedValue(strategy: 'NONE')]
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
* @Column(name="`count`", type="integer")
|
||||
*/
|
||||
#[ORM\Column(name: '`count`', type: 'integer')]
|
||||
public $count;
|
||||
|
||||
public static function loadMetadata(ClassMetadataInfo $metadata): void
|
||||
{
|
||||
$metadata->mapField(
|
||||
[
|
||||
'id' => true,
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer',
|
||||
]
|
||||
);
|
||||
$metadata->mapField(
|
||||
[
|
||||
'fieldName' => 'count',
|
||||
'type' => 'integer',
|
||||
'columnName' => '`count`',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$metadata->mapField(
|
||||
[
|
||||
'id' => true,
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer',
|
||||
]
|
||||
);
|
||||
$metadata->mapField(
|
||||
[
|
||||
'fieldName' => 'count',
|
||||
'type' => 'integer',
|
||||
'columnName' => '`count`',
|
||||
]
|
||||
);
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\ReservedWordInTableColumn">
|
||||
|
||||
<id name="id" type="integer" column="id">
|
||||
<generator strategy="NONE"/>
|
||||
</id>
|
||||
|
||||
<field name="count" column="`count`" type="integer"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
Doctrine\Tests\ORM\Mapping\ReservedWordInTableColumn:
|
||||
type: entity
|
||||
id:
|
||||
id:
|
||||
generator:
|
||||
strategy: NONE
|
||||
fields:
|
||||
count:
|
||||
type: integer
|
||||
column: '`count`'
|
||||
@@ -76,7 +76,7 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
parent::assertEquals(
|
||||
$sqlToBeConfirmed,
|
||||
$sqlGenerated,
|
||||
sprintf('"%s" is not equal of "%s"', $sqlGenerated, $sqlToBeConfirmed)
|
||||
sprintf('"%s" is not equal to "%s"', $sqlGenerated, $sqlToBeConfirmed)
|
||||
);
|
||||
|
||||
$query->free();
|
||||
@@ -2116,26 +2116,6 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
'SELECT CONCAT(c0_.id, c0_.name, c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform(new PostgreSQL94Platform());
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
||||
"SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE c0_.name || c0_.status || 's' = ?"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
|
||||
'SELECT c0_.id || c0_.name || c0_.status AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform(new SQLServer2012Platform());
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
||||
"SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE (c0_.name + c0_.status + 's') = ?"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
|
||||
'SELECT (c0_.id + c0_.name + c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform($orgPlatform);
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,17 @@ class SchemaValidatorTest extends OrmTestCase
|
||||
|
||||
$this->assertEquals([], $ce);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 9095
|
||||
*/
|
||||
public function testAbstractChildClassNotPresentInDiscriminator(): void
|
||||
{
|
||||
$class1 = $this->em->getClassMetadata(Issue9095AbstractChild::class);
|
||||
$ce = $this->validator->validateClass($class1);
|
||||
|
||||
$this->assertEquals([], $ce);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,6 +267,35 @@ class ChildEntity extends MappedSuperclassEntity
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("SINGLE_TABLE")
|
||||
* @DiscriminatorMap({"child" = Issue9095Child::class})
|
||||
*/
|
||||
abstract class Issue9095Parent
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @Id
|
||||
* @Column
|
||||
*/
|
||||
protected $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
abstract class Issue9095AbstractChild extends Issue9095Parent
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class Issue9095Child extends Issue9095AbstractChild
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user