mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cccb2e2fdf | ||
|
|
18138d895e | ||
|
|
fa2b52c974 | ||
|
|
5bf814032f | ||
|
|
02a4e4099d | ||
|
|
12a70bbefb | ||
|
|
5a4ddb2870 | ||
|
|
68fa55f310 | ||
|
|
0b0c3e7e58 | ||
|
|
92434f91c7 | ||
|
|
6414ad4cbb | ||
|
|
7b24275346 | ||
|
|
ed1a576305 | ||
|
|
8b6fe52f74 | ||
|
|
15ec77fa79 | ||
|
|
32cd2106d0 | ||
|
|
cac2acae07 | ||
|
|
146b465ec1 | ||
|
|
5aba762a33 | ||
|
|
77b7107d05 | ||
|
|
a663dda869 | ||
|
|
db14f0fa89 | ||
|
|
9a74ae6280 | ||
|
|
32eb38ebd9 | ||
|
|
2dde65c4ba | ||
|
|
176fbedc69 | ||
|
|
1b15af44b6 | ||
|
|
8336420a26 | ||
|
|
a6b7569d7a | ||
|
|
9e37c788ef | ||
|
|
ca0a6bbf71 | ||
|
|
a3da3d78d4 | ||
|
|
e1c2d2e65d | ||
|
|
6f194eeabf | ||
|
|
16cbc16998 | ||
|
|
5e6608b48e | ||
|
|
94bc137526 | ||
|
|
276a0f55ee | ||
|
|
dbaf99f3d9 | ||
|
|
97411f5567 | ||
|
|
641330baa6 | ||
|
|
35e680cd3f | ||
|
|
705d88eaba | ||
|
|
3271d8f6e2 | ||
|
|
3622381f8c | ||
|
|
f2729b0610 | ||
|
|
cd44547573 |
11
UPGRADE.md
11
UPGRADE.md
@@ -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_.
|
||||
|
||||
@@ -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.1",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^4.4 || ^5.2",
|
||||
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
||||
"vimeo/psalm": "4.10.0"
|
||||
"vimeo/psalm": "4.15.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/annotations": "<1.13 || >= 2.0"
|
||||
|
||||
@@ -4,7 +4,7 @@ Advanced field value conversion using custom mapping types
|
||||
.. sectionauthor:: Jan Sorgalla <jsorgalla@googlemail.com>
|
||||
|
||||
When creating entities, you sometimes have the need to transform field values
|
||||
before they are saved to the database. In Doctrine you can use Custom Mapping
|
||||
before they are saved to the database. In Doctrine you can use Custom Mapping
|
||||
Types to solve this (see: :ref:`reference-basic-mapping-custom-mapping-types`).
|
||||
|
||||
There are several ways to achieve this: converting the value inside the Type
|
||||
@@ -15,7 +15,7 @@ type `Point <https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html>`_.
|
||||
|
||||
The ``Point`` type is part of the `Spatial extension <https://dev.mysql.com/doc/refman/8.0/en/spatial-extensions.html>`_
|
||||
of MySQL and enables you to store a single location in a coordinate space by
|
||||
using x and y coordinates. You can use the Point type to store a
|
||||
using x and y coordinates. You can use the Point type to store a
|
||||
longitude/latitude pair to represent a geographic location.
|
||||
|
||||
The entity
|
||||
@@ -29,9 +29,9 @@ The entity class:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
namespace Geo\Entity;
|
||||
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
@@ -84,7 +84,7 @@ The entity class:
|
||||
}
|
||||
}
|
||||
|
||||
We use the custom type ``point`` in the ``@Column`` docblock annotation of the
|
||||
We use the custom type ``point`` in the ``@Column`` docblock annotation of the
|
||||
``$point`` field. We will create this custom mapping type in the next chapter.
|
||||
|
||||
The point class:
|
||||
@@ -92,7 +92,7 @@ The point class:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
namespace Geo\ValueObject;
|
||||
|
||||
class Point
|
||||
@@ -196,7 +196,7 @@ The format of the string representation format is called
|
||||
`Well-known text (WKT) <https://en.wikipedia.org/wiki/Well-known_text>`_.
|
||||
The advantage of this format is, that it is both human readable and parsable by MySQL.
|
||||
|
||||
Internally, MySQL stores geometry values in a binary format that is not
|
||||
Internally, MySQL stores geometry values in a binary format that is not
|
||||
identical to the WKT format. So, we need to let MySQL transform the WKT
|
||||
representation into its internal format.
|
||||
|
||||
@@ -210,13 +210,13 @@ which convert WKT strings to and from the internal format of MySQL.
|
||||
|
||||
.. note::
|
||||
|
||||
When using DQL queries, the ``convertToPHPValueSQL`` and
|
||||
When using DQL queries, the ``convertToPHPValueSQL`` and
|
||||
``convertToDatabaseValueSQL`` methods only apply to identification variables
|
||||
and path expressions in SELECT clauses. Expressions in WHERE clauses are
|
||||
and path expressions in SELECT clauses. Expressions in WHERE clauses are
|
||||
**not** wrapped!
|
||||
|
||||
If you want to use Point values in WHERE clauses, you have to implement a
|
||||
:doc:`user defined function <dql-user-defined-functions>` for
|
||||
:doc:`user defined function <dql-user-defined-functions>` for
|
||||
``PointFromText``.
|
||||
|
||||
Example usage
|
||||
@@ -252,5 +252,5 @@ Example usage
|
||||
$query = $em->createQuery("SELECT l FROM Geo\Entity\Location l WHERE l.address = '1600 Amphitheatre Parkway, Mountain View, CA'");
|
||||
$location = $query->getSingleResult();
|
||||
|
||||
/* @var Geo\ValueObject\Point */
|
||||
/** @var Geo\ValueObject\Point */
|
||||
$point = $location->getPoint();
|
||||
|
||||
@@ -88,7 +88,7 @@ API would look for this use-case:
|
||||
$pageNum = 1;
|
||||
$query = $em->createQuery($dql);
|
||||
$query->setFirstResult( ($pageNum-1) * 20)->setMaxResults(20);
|
||||
|
||||
|
||||
$totalResults = Paginate::count($query);
|
||||
$results = $query->getResult();
|
||||
|
||||
@@ -101,12 +101,12 @@ The ``Paginate::count(Query $query)`` looks like:
|
||||
{
|
||||
static public function count(Query $query)
|
||||
{
|
||||
/* @var $countQuery Query */
|
||||
/** @var Query $countQuery */
|
||||
$countQuery = clone $query;
|
||||
|
||||
|
||||
$countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\CountSqlWalker'));
|
||||
$countQuery->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
|
||||
return $countQuery->getSingleScalarResult();
|
||||
}
|
||||
}
|
||||
@@ -137,13 +137,13 @@ implementation is:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$pathExpression = new PathExpression(
|
||||
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
|
||||
$parent['metadata']->getSingleIdentifierFieldName()
|
||||
);
|
||||
$pathExpression->type = PathExpression::TYPE_STATE_FIELD;
|
||||
|
||||
|
||||
$AST->selectClause->selectExpressions = array(
|
||||
new SelectExpression(
|
||||
new AggregateExpression('count', $pathExpression, true), null
|
||||
@@ -196,7 +196,7 @@ modify the generation of the SELECT clause, adding the
|
||||
public function walkSelectClause($selectClause)
|
||||
{
|
||||
$sql = parent::walkSelectClause($selectClause);
|
||||
|
||||
|
||||
if ($this->getQuery()->getHint('mysqlWalker.sqlNoCache') === true) {
|
||||
if ($selectClause->isDistinct) {
|
||||
$sql = str_replace('SELECT DISTINCT', 'SELECT DISTINCT SQL_NO_CACHE', $sql);
|
||||
@@ -204,7 +204,7 @@ modify the generation of the SELECT clause, adding the
|
||||
$sql = str_replace('SELECT', 'SELECT SQL_NO_CACHE', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ configuration:
|
||||
$config->addCustomStringFunction($name, $class);
|
||||
$config->addCustomNumericFunction($name, $class);
|
||||
$config->addCustomDatetimeFunction($name, $class);
|
||||
|
||||
|
||||
$em = EntityManager::create($dbParams, $config);
|
||||
|
||||
The ``$name`` is the name the function will be referred to in the
|
||||
@@ -96,7 +96,7 @@ discuss it step by step:
|
||||
// (1)
|
||||
public $firstDateExpression = null;
|
||||
public $secondDateExpression = null;
|
||||
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER); // (2)
|
||||
@@ -106,7 +106,7 @@ discuss it step by step:
|
||||
$this->secondDateExpression = $parser->ArithmeticPrimary(); // (6)
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
|
||||
}
|
||||
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'DATEDIFF(' .
|
||||
@@ -180,28 +180,28 @@ I'll skip the blah and show the code for this function:
|
||||
public $firstDateExpression = null;
|
||||
public $intervalExpression = null;
|
||||
public $unit = null;
|
||||
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
|
||||
$this->firstDateExpression = $parser->ArithmeticPrimary();
|
||||
|
||||
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
|
||||
|
||||
$this->intervalExpression = $parser->ArithmeticPrimary();
|
||||
|
||||
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
|
||||
/* @var $lexer Lexer */
|
||||
|
||||
/** @var Lexer $lexer */
|
||||
$lexer = $parser->getLexer();
|
||||
$this->unit = $lexer->token['value'];
|
||||
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'DATE_ADD(' .
|
||||
|
||||
@@ -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
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ inside the instance variables PHP DocBlock comment. Any value hold
|
||||
inside this variable will be saved to and loaded from the database
|
||||
as part of the lifecycle of the instance variables entity-class.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **type**: Name of the DBAL Type which does the conversion between PHP
|
||||
and Database representation.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **name**: By default the property name is used for the database
|
||||
column name also, however the ``name`` attribute allows you to
|
||||
@@ -165,7 +165,7 @@ Examples:
|
||||
~~~~~~~~
|
||||
Add caching strategy to a root entity or a collection.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **usage**: One of ``READ_ONLY``, ``READ_WRITE`` or ``NONSTRICT_READ_WRITE``, By default this is ``READ_ONLY``.
|
||||
- **region**: An specific region name
|
||||
@@ -210,7 +210,7 @@ Example:
|
||||
|
||||
This attribute allows you to specify a user-provided class to generate identifiers. This attribute only works when both :ref:`#[Id] <attrref_id>` and :ref:`#[GeneratedValue(strategy: "CUSTOM")] <attrref_generatedvalue>` are specified.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **class**: name of the class which should extend Doctrine\ORM\Id\AbstractIdGenerator
|
||||
|
||||
@@ -244,13 +244,13 @@ actually instantiated as.
|
||||
If this attribute is not specified, the discriminator column defaults
|
||||
to a string column of length 255 called ``dtype``.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **name**: The column name of the discriminator. This name is also
|
||||
used during Array hydration as key to specify the class-name.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **type**: By default this is string.
|
||||
@@ -319,7 +319,7 @@ attribute to establish the relationship between the two classes.
|
||||
The embedded attribute is required on an entity's member variable,
|
||||
in order to specify that it is an embedded class.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **class**: The embeddable class
|
||||
|
||||
@@ -331,7 +331,7 @@ Required attributes:
|
||||
Required attribute to mark a PHP class as an entity. Doctrine manages
|
||||
the persistence of all classes marked as entities.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **repositoryClass**: Specifies the FQCN of a subclass of the
|
||||
``EntityRepository``. Use of repositories for entities is encouraged to keep
|
||||
@@ -368,7 +368,7 @@ conjunction with #[Id].
|
||||
If this attribute is not specified with ``#[Id]`` the ``NONE`` strategy is
|
||||
used as default.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **strategy**: Set the name of the identifier generation strategy.
|
||||
Valid values are ``AUTO``, ``SEQUENCE``, ``IDENTITY``, ``UUID``
|
||||
@@ -424,14 +424,14 @@ Attribute is used on the entity-class level. It provides a hint to the SchemaToo
|
||||
generate a database index on the specified table columns. It only
|
||||
has meaning in the ``SchemaTool`` schema generation context.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the Index
|
||||
- **fields**: Array of fields. Exactly one of **fields, columns** is required.
|
||||
- **columns**: Array of columns. Exactly one of **fields, columns** is required.
|
||||
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **options**: Array of platform specific options:
|
||||
|
||||
@@ -548,7 +548,7 @@ The ``#[InverseJoinColumn]`` is the same as ``#[JoinColumn]`` and is used in the
|
||||
of a ``#[ManyToMany]`` attribute declaration to specifiy the details of the join table's
|
||||
column information used for the join to the inverse entity.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **name**: Column name that holds the foreign key identifier for
|
||||
this relation. In the context of ``#[JoinTable]`` it specifies the column
|
||||
@@ -623,14 +623,14 @@ Example:
|
||||
Defines that the annotated instance variable holds a reference that
|
||||
describes a many-to-one relationship between two entities.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
@@ -659,14 +659,14 @@ additional, optional attribute that has reasonable default
|
||||
configuration values using the table and names of the two related
|
||||
entities.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **mappedBy**: This option specifies the property name on the
|
||||
@@ -720,7 +720,7 @@ The ``#[MappedSuperclass]`` attribute cannot be used in conjunction with
|
||||
``#[Entity]``. See the Inheritance Mapping section for
|
||||
:doc:`more details on the restrictions of mapped superclasses <inheritance-mapping>`.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **repositoryClass**: Specifies the FQCN of a subclass of the EntityRepository.
|
||||
That will be inherited for all subclasses of that Mapped Superclass.
|
||||
@@ -756,13 +756,13 @@ be specified. When no
|
||||
:ref:`#[JoinColumn] <attrref_joincolumn>` is specified it defaults to using the target entity table and
|
||||
primary key column names and the current naming strategy to determine a name for the join column.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
- **fetch**: One of LAZY or EAGER
|
||||
@@ -786,13 +786,13 @@ Example:
|
||||
#[OneToMany]
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
- **orphanRemoval**: Boolean that specifies if orphans, inverse
|
||||
@@ -916,11 +916,11 @@ For use with ``#[GeneratedValue(strategy: "SEQUENCE")]`` this
|
||||
attribute allows to specify details about the sequence, such as
|
||||
the increment size and initial values of the sequence.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **sequenceName**: Name of the sequence
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **allocationSize**: Increment the sequence by the allocation size
|
||||
when its fetched. A value larger than 1 allows optimization for
|
||||
@@ -954,11 +954,11 @@ placed on the entity-class level and is optional. If it is
|
||||
not specified the table name will default to the entity's
|
||||
unqualified classname.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the table
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **schema**: Name of the schema the table lies in.
|
||||
|
||||
@@ -985,12 +985,12 @@ generate a database unique constraint on the specified table
|
||||
columns. It only has meaning in the SchemaTool schema generation
|
||||
context.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the Index
|
||||
- **columns**: Array of columns.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **options**: Array of platform specific options:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -127,45 +127,46 @@ 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`
|
||||
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`
|
||||
see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`
|
||||
|
||||
Events Overview
|
||||
---------------
|
||||
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| Event | Dispatched by | Lifecycle |
|
||||
| | | Callback |
|
||||
+=============================+=======================+===========+
|
||||
| ``preRemove`` | ``$em->remove()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``postRemove`` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``prePersist`` | ``$em->persist()`` | Yes |
|
||||
| | on *initial* persist | |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``postPersist`` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``preUpdate`` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``postUpdate`` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``postLoad`` | Loading from database | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``loadClassMetadata`` | Loading of mapping | No |
|
||||
| | metadata | |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``onClassMetadataNotFound`` | ``MappingException`` | No |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``preFlush`` | ``$em->flush()`` | Yes |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``onFlush`` | ``$em->flush()`` | No |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``postFlush`` | ``$em->flush()`` | No |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
| ``onClear`` | ``$em->clear()`` | No |
|
||||
+-----------------------------+-----------------------+-----------+
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| Event | Dispatched by | Lifecycle | Passed |
|
||||
| | | Callback | Argument |
|
||||
+=================================================================+=======================+===========+=====================================+
|
||||
| :ref:`preRemove<reference-events-pre-remove>` | ``$em->remove()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postRemove<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`prePersist<reference-events-pre-persist>` | ``$em->persist()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
| | on *initial* persist | | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postPersist<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`preUpdate<reference-events-pre-update>` | ``$em->flush()`` | Yes | `_PreUpdateEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postUpdate<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postLoad<reference-events-post-load>` | Loading from database | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`loadClassMetadata<reference-events-load-class-metadata>` | Loading of mapping | No | `_LoadClassMetadataEventArgs` |
|
||||
| | metadata | | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| ``onClassMetadataNotFound`` | ``MappingException`` | No | `_OnClassMetadataNotFoundEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`preFlush<reference-events-pre-flush>` | ``$em->flush()`` | Yes | `_PreFlushEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`onFlush<reference-events-on-flush>` | ``$em->flush()`` | No | `_OnFlushEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postFlush<reference-events-post-flush>` | ``$em->flush()`` | No | `_PostFlushEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| ``onClear`` | ``$em->clear()`` | No | `_OnClearEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
|
||||
Naming convention
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@@ -254,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:
|
||||
|
||||
@@ -297,135 +289,109 @@ 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
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
/**
|
||||
* @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: Types::STRING, length: 255)]
|
||||
public $value;
|
||||
|
||||
#[PrePersist]
|
||||
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
#[PrePersist]
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
#[PreUpdate]
|
||||
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
|
||||
{
|
||||
$this->value = 'changed from preUpdate callback!';
|
||||
}
|
||||
}
|
||||
.. code-block:: annotation
|
||||
|
||||
<?php
|
||||
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @HasLifecycleCallbacks
|
||||
*/
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
/** @Column(type="string", length=255) */
|
||||
public $value;
|
||||
|
||||
/** @PrePersist */
|
||||
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/** @PrePersist */
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
/** @PreUpdate */
|
||||
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
|
||||
{
|
||||
$this->value = 'changed from preUpdate 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="preUpdate" method="doStuffOnPreUpdate"/>
|
||||
</lifecycle-callbacks>
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
.. code-block:: yaml
|
||||
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
# ...
|
||||
value:
|
||||
type: string(255)
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||
preUpdate: [ doStuffOnPreUpdate ]
|
||||
|
||||
Lifecycle Callbacks Event Argument
|
||||
----------------------------------
|
||||
@@ -462,7 +428,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
|
||||
@@ -531,8 +497,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);
|
||||
@@ -543,7 +511,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:
|
||||
@@ -563,6 +533,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
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -588,6 +560,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
|
||||
~~~~~~~~~
|
||||
@@ -600,6 +574,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
|
||||
~~~~~~~~
|
||||
|
||||
@@ -622,6 +598,8 @@ result in infinite loop.
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-on-flush:
|
||||
|
||||
onFlush
|
||||
~~~~~~~
|
||||
|
||||
@@ -685,6 +663,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
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -705,6 +685,8 @@ postFlush
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-pre-update:
|
||||
|
||||
preUpdate
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -789,6 +771,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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -798,6 +782,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
|
||||
~~~~~~~~
|
||||
|
||||
@@ -814,7 +800,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;
|
||||
@@ -1010,6 +1008,8 @@ Implementing your own resolver :
|
||||
$configurations->setEntityListenerResolver(new MyEntityListenerResolver);
|
||||
EntityManager::create(.., $configurations, ..);
|
||||
|
||||
.. _reference-events-load-class-metadata:
|
||||
|
||||
Load ClassMetadata Event
|
||||
------------------------
|
||||
|
||||
@@ -1090,3 +1090,12 @@ and the EntityManager.
|
||||
$em = $eventArgs->getEntityManager();
|
||||
}
|
||||
}
|
||||
|
||||
.. _LifecycleEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/LifecycleEventArgs.php
|
||||
.. _PreUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php
|
||||
.. _PreFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreFlushEventArgs.php
|
||||
.. _PostFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostFlushEventArgs.php
|
||||
.. _OnFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnFlushEventArgs.php
|
||||
.. _OnClearEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClearEventArgs.php
|
||||
.. _LoadClassMetadataEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php
|
||||
.. _OnClassMetadataNotFoundEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClassMetadataNotFoundEventArgs.php
|
||||
|
||||
@@ -31,31 +31,31 @@ Each cache region resides in a specific cache namespace and has its own lifetime
|
||||
Notice that when caching collection and queries only identifiers are stored.
|
||||
The entity values will be stored in its own region
|
||||
|
||||
Something like below for an entity region :
|
||||
Something like below for an entity region:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
[
|
||||
'region_name:entity_1_hash' => ['id'=> 1, 'name' => 'FooBar', 'associationName'=>null],
|
||||
'region_name:entity_2_hash' => ['id'=> 2, 'name' => 'Foo', 'associationName'=>['id'=>11]],
|
||||
'region_name:entity_3_hash' => ['id'=> 3, 'name' => 'Bar', 'associationName'=>['id'=>22]]
|
||||
'region_name:entity_1_hash' => ['id' => 1, 'name' => 'FooBar', 'associationName' => null],
|
||||
'region_name:entity_2_hash' => ['id' => 2, 'name' => 'Foo', 'associationName' => ['id' => 11]],
|
||||
'region_name:entity_3_hash' => ['id' => 3, 'name' => 'Bar', 'associationName' => ['id' => 22]]
|
||||
];
|
||||
|
||||
|
||||
If the entity holds a collection that also needs to be cached.
|
||||
An collection region could look something like :
|
||||
An collection region could look something like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
[
|
||||
'region_name:entity_1_coll_assoc_name_hash' => ['ownerId'=> 1, 'list' => [1, 2, 3]],
|
||||
'region_name:entity_2_coll_assoc_name_hash' => ['ownerId'=> 2, 'list' => [2, 3]],
|
||||
'region_name:entity_3_coll_assoc_name_hash' => ['ownerId'=> 3, 'list' => [2, 4]]
|
||||
'region_name:entity_1_coll_assoc_name_hash' => ['ownerId' => 1, 'list' => [1, 2, 3]],
|
||||
'region_name:entity_2_coll_assoc_name_hash' => ['ownerId' => 2, 'list' => [2, 3]],
|
||||
'region_name:entity_3_coll_assoc_name_hash' => ['ownerId' => 3, 'list' => [2, 4]]
|
||||
];
|
||||
|
||||
A query region might be something like :
|
||||
A query region might be something like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -93,8 +93,6 @@ Cache region
|
||||
``Doctrine\ORM\Cache\Region`` defines a contract for accessing a particular
|
||||
cache region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Region.html>`_.
|
||||
|
||||
Concurrent cache region
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -105,8 +103,6 @@ If you want to use an ``READ_WRITE`` cache, you should consider providing your o
|
||||
|
||||
``Doctrine\ORM\Cache\ConcurrentRegion`` defines a contract for concurrently managed data region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/ConcurrentRegion.html>`_.
|
||||
|
||||
Timestamp region
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -114,8 +110,6 @@ Timestamp region
|
||||
|
||||
Tracks the timestamps of the most recent updates to particular entity.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/TimestampRegion.html>`_.
|
||||
|
||||
.. _reference-second-level-cache-mode:
|
||||
|
||||
Caching mode
|
||||
@@ -132,7 +126,7 @@ Caching mode
|
||||
|
||||
* Read Write Cache doesn’t employ any locks but can do reads, inserts, updates and deletes.
|
||||
* Good if the application needs to update data rarely.
|
||||
|
||||
|
||||
|
||||
* ``READ_WRITE``
|
||||
|
||||
@@ -147,21 +141,21 @@ Built-in cached persisters
|
||||
|
||||
Cached persisters are responsible to access cache regions.
|
||||
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| Cache Usage | Persister |
|
||||
+=======================+===========================================================================================+
|
||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadOnlyCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadWriteCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\NonStrictReadWriteCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadOnlyCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadWriteCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\NonStrictReadWriteCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| Cache Usage | Persister |
|
||||
+=======================+==========================================================================================+
|
||||
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Entity\ReadOnlyCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\NonStrictReadWriteCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Collection\ReadOnlyCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\ReadWriteCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\NonStrictReadWriteCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
@@ -172,7 +166,7 @@ Enable Second Level Cache
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To enable the second-level-cache, you should provide a cache factory.
|
||||
``\Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
|
||||
``Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -196,7 +190,7 @@ Cache Factory
|
||||
|
||||
Cache Factory is the main point of extension.
|
||||
|
||||
It allows you to provide a specific implementation of the following components :
|
||||
It allows you to provide a specific implementation of the following components:
|
||||
|
||||
``QueryCache``
|
||||
stores and retrieves query cache results.
|
||||
@@ -209,8 +203,6 @@ It allows you to provide a specific implementation of the following components :
|
||||
``CollectionHydrator``
|
||||
transforms collections into cache entries and cache entries into collections
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/DefaultCacheFactory.html>`_.
|
||||
|
||||
Region Lifetime
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -234,12 +226,12 @@ Cache Log
|
||||
~~~~~~~~~
|
||||
By providing a cache logger you should be able to get information about all cache operations such as hits, misses and puts.
|
||||
|
||||
``\Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
|
||||
``Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $config \Doctrine\ORM\Configuration */
|
||||
/** @var \Doctrine\ORM\Configuration $config */
|
||||
$logger = new \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger();
|
||||
|
||||
// Cache logger
|
||||
@@ -269,12 +261,9 @@ By providing a cache logger you should be able to get information about all cach
|
||||
$logger->getMissCount();
|
||||
|
||||
If you want to get more information you should implement
|
||||
``\Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
|
||||
``Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
|
||||
all the information you want.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Logging/CacheLogger.html>`_.
|
||||
|
||||
|
||||
Entity cache definition
|
||||
-----------------------
|
||||
* Entity cache configuration allows you to define the caching strategy and region for an entity.
|
||||
@@ -330,8 +319,8 @@ level cache region.
|
||||
Country:
|
||||
type: entity
|
||||
cache:
|
||||
usage : READ_ONLY
|
||||
region : my_entity_region
|
||||
usage: READ_ONLY
|
||||
region: my_entity_region
|
||||
id:
|
||||
id:
|
||||
type: integer
|
||||
@@ -401,7 +390,7 @@ It caches the primary keys of association and cache each element will be cached
|
||||
</id>
|
||||
|
||||
<field name="name" type="string" column="name"/>
|
||||
|
||||
|
||||
<many-to-one field="country" target-entity="Country">
|
||||
<cache usage="NONSTRICT_READ_WRITE" />
|
||||
|
||||
@@ -421,7 +410,7 @@ It caches the primary keys of association and cache each element will be cached
|
||||
State:
|
||||
type: entity
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
id:
|
||||
id:
|
||||
type: integer
|
||||
@@ -439,17 +428,18 @@ It caches the primary keys of association and cache each element will be cached
|
||||
country_id:
|
||||
referencedColumnName: id
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
|
||||
oneToMany:
|
||||
cities:
|
||||
targetEntity:City
|
||||
mappedBy: state
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
|
||||
.. note::
|
||||
|
||||
> Note: for this to work, the target entity must also be marked as cacheable.
|
||||
for this to work, the target entity must also be marked as cacheable.
|
||||
|
||||
Cache usage
|
||||
~~~~~~~~~~~
|
||||
@@ -466,8 +456,8 @@ Basic entity cache
|
||||
|
||||
$country1 = $em->find('Country', 1); // Retrieve item from cache
|
||||
|
||||
$country1->setName("New Name");
|
||||
|
||||
$country1->setName('New Name');
|
||||
|
||||
$em->flush(); // Hit database to update the row and update cache
|
||||
|
||||
$em->clear(); // Clear entity manager
|
||||
@@ -492,7 +482,7 @@ Association cache
|
||||
$state = $em->find('State', 1);
|
||||
|
||||
// Hit database to update the row and update cache entry
|
||||
$state->setName("New Name");
|
||||
$state->setName('New Name');
|
||||
$em->persist($state);
|
||||
$em->flush();
|
||||
|
||||
@@ -543,14 +533,14 @@ The query cache stores the results of the query but as identifiers, entity value
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $em \Doctrine\ORM\EntityManager */
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
|
||||
// Execute database query, store query cache and entity cache
|
||||
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
$em->clear()
|
||||
$em->clear();
|
||||
|
||||
// Check if query result is valid and load entities from cache
|
||||
$result2 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
@@ -570,10 +560,10 @@ The Cache Mode controls how a particular query interacts with the second-level c
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $em \Doctrine\ORM\EntityManager */
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
// Will refresh the query cache and all entities the cache as it reads from the database.
|
||||
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
->setCacheMode(Cache::MODE_GET)
|
||||
->setCacheMode(\Doctrine\ORM\Cache::MODE_GET)
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
@@ -597,7 +587,7 @@ Execute the ``UPDATE`` and invalidate ``all cache entries`` using ``Query::HINT_
|
||||
<?php
|
||||
// Execute and invalidate
|
||||
$this->_em->createQuery("UPDATE Entity\Country u SET u.name = 'unknown' WHERE u.id = 1")
|
||||
->setHint(Query::HINT_CACHE_EVICT, true)
|
||||
->setHint(\Doctrine\ORM\Query::HINT_CACHE_EVICT, true)
|
||||
->execute();
|
||||
|
||||
|
||||
@@ -659,7 +649,7 @@ However, you can use the cache API to check / invalidate cache entries.
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $cache \Doctrine\ORM\Cache */
|
||||
/** @var \Doctrine\ORM\Cache $cache */
|
||||
$cache = $em->getCache();
|
||||
|
||||
$cache->containsEntity('Entity\State', 1) // Check if the cache exists
|
||||
@@ -704,19 +694,19 @@ For performance reasons the cache API does not extract from composite primary ke
|
||||
}
|
||||
|
||||
// Supported
|
||||
/* @var $article Article */
|
||||
/** @var Article $article */
|
||||
$article = $em->find('Article', 1);
|
||||
|
||||
// Supported
|
||||
/* @var $article Article */
|
||||
/** @var Article $article */
|
||||
$article = $em->find('Article', $article);
|
||||
|
||||
// Supported
|
||||
$id = array('source' => 1, 'target' => 2);
|
||||
$id = ['source' => 1, 'target' => 2];
|
||||
$reference = $em->find('Reference', $id);
|
||||
|
||||
// NOT Supported
|
||||
$id = array('source' => new Article(1), 'target' => new Article(2));
|
||||
$id = ['source' => new Article(1), 'target' => new Article(2)];
|
||||
$reference = $em->find('Reference', $id);
|
||||
|
||||
Distributed environments
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
</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" />
|
||||
@@ -353,7 +353,7 @@
|
||||
<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="columns" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="fields" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="flags" type="xs:string" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
@@ -402,7 +402,7 @@
|
||||
</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" />
|
||||
@@ -497,6 +497,12 @@
|
||||
</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"/>
|
||||
@@ -612,7 +618,7 @@
|
||||
<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" />
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -330,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
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Serializable;
|
||||
|
||||
@@ -54,11 +55,14 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
|
||||
{
|
||||
if ($this->_maxValue === null || $this->_nextValue === $this->_maxValue) {
|
||||
// Allocate new values
|
||||
$conn = $em->getConnection();
|
||||
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
|
||||
$connection = $em->getConnection();
|
||||
$sql = $connection->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
|
||||
|
||||
// Using `query` to force usage of the master server in MasterSlaveConnection
|
||||
$this->_nextValue = (int) $conn->executeQuery($sql)->fetchOne();
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$this->_nextValue = (int) $connection->executeQuery($sql)->fetchOne();
|
||||
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
@@ -39,9 +40,13 @@ class UuidGenerator extends AbstractIdGenerator
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
$conn = $em->getConnection();
|
||||
$sql = 'SELECT ' . $conn->getDatabasePlatform()->getGuidExpression();
|
||||
$connection = $em->getConnection();
|
||||
$sql = 'SELECT ' . $connection->getDatabasePlatform()->getGuidExpression();
|
||||
|
||||
return $conn->executeQuery($sql)->fetchOne();
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
return $connection->executeQuery($sql)->fetchOne();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\AST\DeleteStatement;
|
||||
@@ -49,6 +50,10 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
|
||||
$platform = $conn->getDatabasePlatform();
|
||||
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
|
||||
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
|
||||
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
|
||||
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\AST\UpdateStatement;
|
||||
@@ -55,6 +56,10 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
|
||||
$platform = $conn->getDatabasePlatform();
|
||||
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
|
||||
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$updateClause = $AST->updateClause;
|
||||
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
|
||||
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
@@ -37,6 +38,10 @@ class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor
|
||||
*/
|
||||
public function execute(Connection $conn, array $params, array $types)
|
||||
{
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
return $conn->executeStatement($this->_sqlStatements, $params, $types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ abstract class SQLFilter
|
||||
* Gets the SQL query part to add to a query.
|
||||
*
|
||||
* @param string $targetTableAlias
|
||||
* @psalm-param ClassMetadata<object> $targetEntity
|
||||
*
|
||||
* @return string The constraint SQL if there is available, empty string otherwise.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -239,7 +239,7 @@ class SchemaValidator
|
||||
}
|
||||
}
|
||||
|
||||
if (! $class->isInheritanceTypeNone() && ! $class->isRootEntity() && ! $class->reflClass->isAbstract() && ! $class->isMappedSuperclass && array_search($class->name, $class->discriminatorMap, true) === false) {
|
||||
if (! $class->isInheritanceTypeNone() && ! $class->isRootEntity() && ! $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.';
|
||||
|
||||
@@ -9,6 +9,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\Proxy\Proxy;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Doctrine\ORM\Cache\Persister\CachedPersister;
|
||||
@@ -338,6 +339,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*/
|
||||
public function commit($entity = null)
|
||||
{
|
||||
$connection = $this->em->getConnection();
|
||||
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
// Raise preFlush
|
||||
if ($this->evm->hasListeners(Events::preFlush)) {
|
||||
$this->evm->dispatchEvent(Events::preFlush, new PreFlushEventArgs($this->em));
|
||||
|
||||
@@ -100,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
|
||||
@@ -180,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
|
||||
@@ -235,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
|
||||
@@ -417,7 +437,12 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Negated boolean expression is always false\\.$#"
|
||||
count: 2
|
||||
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
|
||||
|
||||
-
|
||||
@@ -525,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
|
||||
@@ -561,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
|
||||
|
||||
-
|
||||
@@ -765,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
|
||||
@@ -960,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
|
||||
@@ -1115,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
|
||||
@@ -1380,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\\.$#"
|
||||
@@ -1422,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\\.$#"
|
||||
@@ -1476,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
|
||||
@@ -1982,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
|
||||
|
||||
@@ -2021,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
|
||||
@@ -2062,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
|
||||
|
||||
@@ -2096,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
|
||||
@@ -2106,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
|
||||
@@ -2116,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
|
||||
@@ -2126,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
|
||||
@@ -2161,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
|
||||
|
||||
11
phpstan.neon
11
phpstan.neon
@@ -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\.$/'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.10.0@916b098b008f6de4543892b1e0651c1c3b92cbfa">
|
||||
<files psalm-version="v4.15.0@a1b5e489e6fcebe40cb804793d964e99fc347820">
|
||||
<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>
|
||||
@@ -518,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">
|
||||
@@ -604,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">
|
||||
@@ -777,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>
|
||||
@@ -821,12 +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="2">
|
||||
<code>$class->reflClass</code>
|
||||
<code>! $definition</code>
|
||||
<code>$definition</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidArrayOffset occurrences="1">
|
||||
@@ -869,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>
|
||||
@@ -890,7 +887,8 @@
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>$subClass->table</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$parent->idGenerator</code>
|
||||
<code>$parent->idGenerator</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="17">
|
||||
@@ -921,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">
|
||||
@@ -936,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>
|
||||
@@ -967,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>
|
||||
@@ -987,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>
|
||||
@@ -1013,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>
|
||||
@@ -1036,26 +1043,19 @@
|
||||
<code>$this->table</code>
|
||||
<code>$this->table</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCast occurrences="1">
|
||||
<code>array_values</code>
|
||||
</RedundantCast>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<code>$className !== null</code>
|
||||
<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>
|
||||
@@ -1084,6 +1084,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>
|
||||
@@ -1104,9 +1108,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>
|
||||
@@ -1121,10 +1130,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>
|
||||
@@ -1173,6 +1178,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>
|
||||
@@ -1189,10 +1198,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">
|
||||
@@ -1287,11 +1294,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>
|
||||
@@ -1583,16 +1586,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>
|
||||
@@ -1627,7 +1621,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>
|
||||
@@ -1853,9 +1849,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>
|
||||
@@ -1896,11 +1889,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>
|
||||
@@ -2196,6 +2184,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getLowerExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2225,6 +2216,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>
|
||||
@@ -2263,6 +2257,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getUpperExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2629,16 +2626,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>
|
||||
@@ -2843,27 +2833,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">
|
||||
@@ -2934,10 +2933,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>
|
||||
@@ -3300,13 +3301,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">
|
||||
@@ -3337,9 +3334,6 @@
|
||||
<code>new ClassMetadataExporter()</code>
|
||||
<code>new EntityGenerator()</code>
|
||||
</DeprecatedClass>
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>int</code>
|
||||
</InvalidNullableReturnType>
|
||||
<MissingReturnType occurrences="1">
|
||||
<code>configure</code>
|
||||
</MissingReturnType>
|
||||
@@ -3479,10 +3473,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>
|
||||
@@ -3508,12 +3500,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>
|
||||
@@ -3588,6 +3581,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">
|
||||
@@ -3614,10 +3611,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>
|
||||
@@ -3654,6 +3653,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>
|
||||
@@ -3707,7 +3710,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">
|
||||
@@ -3719,12 +3723,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">
|
||||
@@ -3752,6 +3760,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>
|
||||
|
||||
11
psalm.xml
11
psalm.xml
@@ -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>
|
||||
@@ -83,6 +87,13 @@
|
||||
<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
|
||||
*/
|
||||
|
||||
@@ -239,9 +239,7 @@ class SecondLevelCacheManyToOneTest extends SecondLevelCacheAbstractTest
|
||||
self::assertFalse($this->cache->containsEntity(Action::class, $action3->name));
|
||||
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
/**
|
||||
* @var $entity Token
|
||||
*/
|
||||
|
||||
$entity = $this->_em->find(Token::class, $token->token);
|
||||
|
||||
self::assertInstanceOf(Token::class, $entity);
|
||||
|
||||
217
tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php
Normal file
217
tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php
Normal file
@@ -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`',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`',
|
||||
]
|
||||
);
|
||||
@@ -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>
|
||||
@@ -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,17 +225,6 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,35 +256,6 @@ 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
|
||||
*/
|
||||
|
||||
@@ -58,23 +58,12 @@ abstract class OrmTestCase extends DoctrineTestCase
|
||||
/** @var Cache|null */
|
||||
protected $secondLevelCacheDriverImpl = null;
|
||||
|
||||
/**
|
||||
* @param mixed $alias
|
||||
*/
|
||||
protected function createAnnotationDriver(array $paths = [], $alias = null): AnnotationDriver
|
||||
protected function createAnnotationDriver(array $paths = []): AnnotationDriver
|
||||
{
|
||||
// Register the ORM Annotations in the AnnotationRegistry
|
||||
$reader = new Annotations\AnnotationReader();
|
||||
|
||||
if (class_exists(Annotations\PsrCachedReader::class)) {
|
||||
$reader = new Annotations\PsrCachedReader($reader, new ArrayAdapter());
|
||||
} else {
|
||||
$reader = new Annotations\CachedReader($reader, DoctrineProvider::wrap(new ArrayAdapter()));
|
||||
}
|
||||
|
||||
Annotations\AnnotationRegistry::registerFile(__DIR__ . '/../../../lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
|
||||
|
||||
return new AnnotationDriver($reader, (array) $paths);
|
||||
return new AnnotationDriver(
|
||||
new Annotations\PsrCachedReader(new Annotations\AnnotationReader(), new ArrayAdapter()),
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user