Compare commits

...

314 Commits

Author SHA1 Message Date
Grégoire Paris
a8b02fd70f Merge pull request #10054 from greg0ire/sa-fixes 2022-09-22 15:36:43 +02:00
Alexander M. Turek
60adc6b7d9 Fix CS 2022-09-22 12:06:40 +02:00
Alexander M. Turek
c65ff6651c Merge branch '2.13.x-enum-arrayhydration' into 2.13.x
* 2.13.x-enum-arrayhydration:
  Fix ArrayHydration of enums
2022-09-22 12:04:22 +02:00
Alexander M. Turek
5f29fcdea2 Revert "Fix EnumType not being hydrated with HYDRATE_ARRAY (#9995)"
This reverts commit bb3ce7e802.
2022-09-22 12:04:09 +02:00
Grégoire Paris
2b8ac15813 Mark ClassMetadataInfo::sequenceGeneratorDefinition as nullable 2022-09-22 09:12:50 +02:00
Grégoire Paris
6dd07e4c76 Merge pull request #9983 from VincentLanglet/discriminatorColumn
Add phpdoc for ClassMetadataInfo::discriminatorColumn property
2022-09-21 23:17:54 +02:00
Alexander M. Turek
0d043059b9 PHPStan 1.8.5, Psalm 4.27.0 (#10033) 2022-09-18 15:06:51 +02:00
Ilya Shashilov
bb3ce7e802 Fix EnumType not being hydrated with HYDRATE_ARRAY (#9995)
Co-authored-by: Ilya Shashilov <kvushiha@gmail.com>
2022-09-14 14:33:42 +02:00
Tomas
bc7e252f00 Fix ArrayHydration of enums 2022-09-12 17:01:40 +02:00
Carlos Buenosvinos
498da2ff98 "Strange" return lines in documentation of inheritance-mapping.rst (#10027) 2022-09-04 18:16:02 +02:00
Carlos Buenosvinos
73e1e42ab5 More strange break lines in inheritance-mapping.rst (#10028) 2022-09-03 21:40:53 +02:00
Alexander M. Turek
5d11648767 Bump Ubuntu version and shared workflows (#10020) 2022-08-30 21:10:38 +02:00
Alexander M. Turek
0ecac1b255 Fail gracefully if EM could not be constructed in tests (#10008) 2022-08-30 13:40:54 +02:00
Grégoire Paris
b2a4fac40b Merge pull request #10009 from greg0ire/cs-update
Upgrade to doctrine/coding-standard 10.0.0
2022-08-27 20:53:59 +02:00
Grégoire Paris
beeba93a53 Upgrade to doctrine/coding-standard 10.0.0 2022-08-27 19:04:47 +02:00
Alexander M. Turek
4c253f2403 Merge pull request #10006 from derrabus/fix/build
Fix build
2022-08-26 13:07:34 +02:00
Alexander M. Turek
46ec86557e Bump coding standard to 9.0.2 2022-08-26 12:27:20 +02:00
Alexander M. Turek
f287b74470 Fix tests for doctrine/common 3.4 2022-08-26 00:34:50 +02:00
Alexander M. Turek
12d086551e Fix static analysis errors for Collections 1.7 2022-08-26 00:09:37 +02:00
Alberto Acha
5283e1441c Fix type in docs (#9994) 2022-08-16 20:40:01 +02:00
Michael Olšavský
18be6d2218 Improve orphan removal documentation - recommend using cascade=persist (#9848)
* Improve orphanRemoval documentation

* Wording improvement

* Update docs/en/reference/working-with-associations.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2022-08-09 21:39:43 +02:00
Vincent Langlet
2fda625dba Add phpdoc for discriminatorColumn 2022-08-08 22:34:18 +02:00
Alexander M. Turek
35c44a5667 Backport type fixes for EntityListenerResolver (#9977) 2022-08-08 11:00:16 +02:00
Fran Moreno
0215b6b9fb Undeprecate LifecycleEventArgs (#9980)
Deprecating this class means that users using SA tools have to
update their code specifying the ObjectManager implementation.

Instead of this, dedicated classes for each event should be
created before deprecating this class.
2022-08-08 10:59:03 +02:00
Fran Moreno
cc9272f53f Update documentation to not use deprecated method (#9979) 2022-08-08 07:46:05 +00:00
Alexander M. Turek
e3e7f3c209 Update branch metadata (#9971) 2022-08-07 19:56:19 +02:00
Alexander M. Turek
c9870a3d82 Remove calls to deprecated Type::getName() (#9972) 2022-08-07 19:55:23 +02:00
Alexander M. Turek
827cb0c10b Address DBAL 3.4 deprecations (#9969) 2022-08-07 18:11:43 +02:00
Vincent Langlet
4d19c0ea71 Improve phpdoc for ClassMetadataInfo (#9965) 2022-08-07 16:00:01 +00:00
Alexander M. Turek
17cfb944f2 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Fix build (#9964)
  fix: class normalisation test (#9966)
2022-08-07 17:39:22 +02:00
Alexander M. Turek
78d08584f1 Fix build (#9964) 2022-08-07 17:31:32 +02:00
Adrien Foulon
f7e202f3ed fix: class normalisation test (#9966) 2022-08-07 17:07:36 +02:00
Romain Canon
33f4db8405 Support native enum hydration when using NEW operator (#9936)
Using the `NEW` operator with the query builder now properly converts
scalar values to native enums inside data transfer objects.
2022-08-04 00:33:46 +02:00
Alexander M. Turek
fa63a395cc Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Update branch info in README and .doctrine-project.json (#9943)
2022-08-02 22:35:33 +02:00
Alexander M. Turek
2ec2c585b0 Deprecate QueryBuilder APIs exposing its internal state (#9945)
Co-authored-by: Sergei Morozov <morozov@tut.by>
2022-08-01 11:42:24 +02:00
Alexander M. Turek
c8025dc4f8 Update branch info in README and .doctrine-project.json (#9943) 2022-07-31 14:53:31 +02:00
Alexander M. Turek
cd95b2a9e5 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Psalm 4.25.0, PHPStan 1.8.2 (#9941)
  Use a more precise phpdoc for ClassMetadataInfo::versionField than mixed (#9937)
2022-07-28 19:38:58 +02:00
Alexander M. Turek
8bfe20073b Psalm 4.25.0, PHPStan 1.8.2 (#9941) 2022-07-28 19:35:26 +02:00
Grégoire Paris
38a9a1c795 Stop passing event manager to constructor (#9938)
Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-07-28 16:47:04 +00:00
Grégoire Paris
2ebe18a822 Merge pull request #9915 from nicolas-grekas/pub-em 2022-07-28 14:55:34 +02:00
Vincent Langlet
9b37541b3b Use a more precise phpdoc for ClassMetadataInfo::versionField than mixed (#9937) 2022-07-27 23:23:43 +02:00
Nicolas Grekas
518d7f2ef1 Make EntityManager @final and its constructor public 2022-07-27 17:15:40 +02:00
Alexander M. Turek
7684cea8ef Add helper function TreeWalkerAdapter::getMetadataForDqlAlias() (#9932) 2022-07-25 20:54:31 +02:00
Alexander M. Turek
5085dbe94b Merge 2.12.x into 2.13.x (#9931) 2022-07-25 18:49:29 +02:00
Alexander M. Turek
6c64bc6067 Simplify LanguageRecognitionTest (#9930) 2022-07-25 16:14:07 +02:00
Grégoire Paris
f5246bdedd Merge pull request #9927 from rdey/patch-1
GH9335: Fix for bug with objects as foreign keys
2022-07-24 15:21:28 +02:00
Louise Zetterlund
705dc6fbda test/added test for foreign keys with custom id object types 2022-07-22 18:41:35 +02:00
Alexander M. Turek
faedb90ffa Widen types for DiscriminatorMap (#9922)
* Allow integers as keys for DiscriminatorMap

* Widen types for DiscriminatorMap
2022-07-21 10:19:42 +02:00
Grégoire Paris
2da28703e3 Merge pull request #9903 from glaszig/fix/dump-sql
schema tool: remove useless text from --dump-sql output
2022-07-19 23:13:51 +02:00
glaszig
20cec8ed79 schema tool: remove useless text from --dump-sql output
the description and semantics of the `--dump-sql` switch
indicate and sql dump. without that useless line

  The following SQL statements will be executed:

the output can actually be used to generate a plain
dump.sql file that can be fed into sql command-
consuming programs.

resolves #8263 and #7186.
2022-07-19 19:33:48 +00:00
Grégoire Paris
c125a856d0 Merge pull request #9914 from greg0ire/fix-build
Avoid supportsCreateDropDatabase()
2022-07-18 23:00:38 +02:00
Grégoire Paris
d7db596cb4 Avoid supportsCreateDropDatabase()
It has been deprecated.
2022-07-18 22:42:13 +02:00
Grégoire Paris
3a9aa5b8c6 Merge pull request #9910 from doctrine/2.12.x
Merge 2.12.x up into 2.13.x
2022-07-18 21:31:50 +02:00
Grégoire Paris
99d9c46bde Add tests for SQL output feature (#9907)
It is not covered yet, and that makes contributions to these commands
hard.
2022-07-18 21:28:17 +02:00
Grégoire Paris
61d405162f Merge pull request #9906 from franmomu/deprecate_lifecycleevent
Deprecate `LifecycleEventArgs`
2022-07-17 17:35:37 +02:00
Fran Moreno
b0f15e070d Deprecate LifecycleEventArgs
Use LifecycleEventArgs from doctrine/persistence instead.
2022-07-17 12:06:10 +02:00
Grégoire Paris
fbb7e24594 Merge pull request #9895 from greg0ire/avoid-sql-assertions
Avoid SQL assertions
2022-07-14 19:09:32 +02:00
Grégoire Paris
888a4a8eff Avoid SQL assertions
doctrine/dbal is the component responsible for generating the queries.
Let us make the test suite more robust by asserting that things work
from a functional point of view.
2022-07-12 08:01:19 +02:00
Grégoire Paris
48b4f63f61 Merge pull request #9893 from greg0ire/2.13.x
Merge 2.12.x up into 2.13.x
2022-07-10 23:18:39 +02:00
Grégoire Paris
4a62b661a5 Merge remote-tracking branch 'origin/2.12.x' into 2.13.x 2022-07-10 23:07:44 +02:00
Grégoire Paris
ab4844b82a Merge pull request #9892 from greg0ire/address-array-object-type-deprecation
Address array object type deprecation
2022-07-10 23:05:34 +02:00
Grégoire Paris
00989d6671 Remove SerializationModel from generic model set
It contains fields with deprecated types.
2022-07-10 12:23:05 +02:00
Grégoire Paris
7ed0db0621 Document what we test in test method name 2022-07-10 11:23:22 +02:00
Grégoire Paris
d6dcfbd6f7 Use ::class notation 2022-07-10 11:23:21 +02:00
Grégoire Paris
baf6a394a1 Test invalid mapping file with boolean model
SerializationModel has a field with type array, and another with type
object. Both types are deprecated.
2022-07-10 11:22:46 +02:00
Alexander M. Turek
1538d70bb9 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  PHPStan 1.8.0 (#9887)
  Fix typo in AbstractQuery
  ObjectHydrator: defer initialization of potentially empty collections
  Migrate more usages of SchemaTool::createSchema()
  preUpdate: Add restriction that changed field needs to be in computed changeset (#9871)
2022-07-08 13:54:43 +02:00
Alexander M. Turek
291765e879 PHPStan 1.8.0 (#9887) 2022-07-08 13:53:03 +02:00
Grégoire Paris
f79ec43e70 Merge pull request #9880 from CarlSchwan/patch-1
Fix typo in AbstractQuery
2022-07-06 21:07:32 +02:00
Carl Schwan
306b5f9812 Fix typo in AbstractQuery 2022-07-06 14:06:42 +02:00
Grégoire Paris
68405f3e5b Merge pull request #9876 from franmomu/extend_event_manager_args
Change parent classes in some events
2022-07-04 19:21:56 +02:00
Grégoire Paris
83c1ad2f57 Merge pull request #9870 from popov-a-e/GH-9807
[GH-9807] Fix: initialize potentially empty collections at the hydration complete
2022-07-03 22:25:18 +02:00
Alex Popov
79447cbb18 ObjectHydrator: defer initialization of potentially empty collections
If ObjectHydrator faces an empty row to an uninitialized collection,
it initializes it, to prevent it from querying again (DDC-1526).
However, if that row is the first but not the only in the collection,
the next rows will be ignored, as the collection will be considered
"existing", and "existing" collections are only replaced if REFRESH hint
is present. To prevent it, we defer initialization to the end of the
hydration.

Fixes GH-9807
2022-07-03 13:25:34 +04:00
Fran Moreno
eea53397c5 Change parent classes
*FlushEventArgs classes should extend ManagerEventArgs from
doctrine/persistence to be able to use ManagerEventArgs for any
persistance implementation.

OnClearEventArgs should extend from OnClearEventArgs from
doctrine/persistence.
2022-07-02 14:27:36 +02:00
Grégoire Paris
3295ccfa25 Merge pull request #9874 from greg0ire/migrate-to-csfm
Migrate more usages of SchemaTool::createSchema()
2022-07-02 00:11:41 +02:00
Grégoire Paris
b1419ddc6c Migrate more usages of SchemaTool::createSchema()
When I introduced OrmFunctionalTestCase::createSchemaForModels(), I made
several wrong assumptions:
- the call is always wrapped in a try / catch;
- that try / catch is always typed with "Exception".

Because of that, I missed, many, many occurrences of
SchemaTool::createSchema().

I recently noticed that contributors kept using the
SchemaTool::createSchema() and figured not everything had been
migrated.

Migrating some of them did not result in something far better until I
also introduced similar methods for
SchemaTool::getUpdateSchemaSql() and SchemaTool::getSchemaFromMetadata().
2022-07-01 21:45:45 +02:00
Thomas Landauer
0ef08c5dfb preUpdate: Add restriction that changed field needs to be in computed changeset (#9871) 2022-06-28 23:44:23 +02:00
Alexander M. Turek
dc8ddfd3e6 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Psalm 4.24.0, PHPStan 1.7.15 (#9865)
  PHP CodeSniffer 3.7.1, PHPStan 1.7.14 (#9858)
2022-06-28 13:35:26 +02:00
Alexander M. Turek
278bf194ca Psalm 4.24.0, PHPStan 1.7.15 (#9865) 2022-06-28 10:41:20 +02:00
Alexander M. Turek
b9f2488c6c PHP CodeSniffer 3.7.1, PHPStan 1.7.14 (#9858) 2022-06-19 14:48:36 +02:00
Hans Mackowiak
b931a59ebc Deprecate omitting the alias in QueryBuilder (#9765)
… methods update() and delete()

Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-06-17 10:33:11 +02:00
Alexander M. Turek
d15eef9051 Merge release 2.12.3 into 2.13.x (#9853) 2022-06-17 10:22:16 +02:00
Alexander M. Turek
c05e1709e9 Run tests on PHP 8.2 (#9840) 2022-06-16 15:42:23 +02:00
Alexander M. Turek
6e31758c7b PHPStan 1.7.13 (#9844) 2022-06-15 11:11:24 +02:00
Alexander M. Turek
eff540a996 Flip conditional extension of legacy AnnotationDriver class (#9843) 2022-06-13 20:10:37 +02:00
Alexander M. Turek
33d74e2e48 PHP CodeSniffer 3.7 (#9842) 2022-06-13 19:19:15 +02:00
bartholdbos
09ff36cda0 Make Reflection available to ConvertMappingCommand (#9619) 2022-06-13 17:30:08 +02:00
Grégoire Paris
e30426cbc0 Merge pull request #9841 from derrabus/bugfix/dynamic-property
Add missing property declaration
2022-06-12 16:55:59 +02:00
Alexander M. Turek
e9135b86e0 Add missing property declaration 2022-06-12 14:25:39 +02:00
Grégoire Paris
5ccb59fa02 Merge pull request #9839 from morozov/list-tables
Use proper API for introspection of tables
2022-06-11 22:41:41 +02:00
Sergei Morozov
2e927970ca Use proper API for introspection of tables 2022-06-11 12:13:25 -07:00
Grégoire Paris
0366a5796f Merge pull request #9837 from greg0ire/address-getdbplatform-deprecation
Address deprecation of getDatabasePlatform()
2022-06-10 20:14:06 +02:00
Grégoire Paris
93f7e78a14 Address deprecation of getDatabasePlatform() 2022-06-10 19:57:50 +02:00
Grégoire Paris
d99e64c05e Merge pull request #9833 from greg0ire/deprecate-sequence-based-ig 2022-06-10 10:09:33 +02:00
Grégoire Paris
9efeefb913 Merge pull request #9826 from greg0ire/improve-phpdoc-configuration
Improve phpdoc for Configuration
2022-06-09 23:53:12 +02:00
Grégoire Paris
3f8430459c Deprecate reliance on sequence-emulated identity columns
Sequence-based identity values have been deprecated.
2022-06-09 23:46:50 +02:00
Grégoire Paris
5f12b8f7de Remove uneeded rule form baseline 2022-06-09 08:13:54 +02:00
Grégoire Paris
f949b9d212 Improve phpdoc for Configuration 2022-06-09 08:09:41 +02:00
Grégoire Paris
2bc0be6fa9 Merge remote-tracking branch 'origin/2.12.x' into 2.13.x 2022-06-09 07:47:32 +02:00
Grégoire Paris
3dc5581294 Merge pull request #9818 from greg0ire/fix-wrong-type-config
Document missing possible types
2022-06-09 07:23:43 +02:00
Grégoire Paris
7bf2c4c8d1 Merge pull request #9823 from greg0ire/fix-build 2022-06-08 14:39:31 +02:00
Grégoire Paris
c81776ad12 Backport fixes from upstream branch
Not all of 01fb82b497 was ported, only
what is necessary to fix the build.
2022-06-08 13:26:35 +02:00
Grégoire Paris
d9c6f86627 Document missing possible types 2022-06-04 18:16:35 +02:00
Alexander M. Turek
ddede4064c Merge 2.12.x into 2.13.x (#9811) 2022-06-03 13:22:41 +02:00
Alexander M. Turek
67d82cdf72 PHPStan 1.7.9 (#9812) 2022-06-03 13:11:19 +02:00
Alexander M. Turek
744f0b5983 Remove empty test file (#9805) 2022-06-03 07:53:13 +02:00
Grégoire Paris
1d02289481 Merge pull request #9809 from greg0ire/disallow-null-setFirstResult
Deprecate passing null to Query::setFirstResult()
2022-06-03 07:51:04 +02:00
Alexander M. Turek
4bd0f974ab Remove calls to deprecated MockBuilder::setMethods() (#9808) 2022-06-02 23:48:47 +02:00
Grégoire Paris
d0c582ca48 Deprecate passing null to Query::setFirstResult()
The argument is cast to an integer, so the user might as well pass 0
instead, and we can require an integer.
2022-06-02 22:29:01 +02:00
Alexander M. Turek
cc6cc26f18 Rename Abstract*Test to *TestCase (#9806) 2022-06-02 16:33:33 +02:00
wiseguy1394
768e2f3816 Add primary key on temp table (#9770)
* add primary key on temp table;fixes doctrine/orm#9768

* use all ID Columns in primary key
2022-06-02 16:08:22 +02:00
Grégoire Paris
deb5f49413 Merge pull request #9804 from greg0ire/2.13.x
Merge 2.12.x up into 2.13.x
2022-06-02 07:14:42 +02:00
Grégoire Paris
52ce39f595 Merge pull request #9801 from greg0ire/widen-types
Widen types
2022-06-02 07:13:58 +02:00
Grégoire Paris
f84ecb2842 Merge pull request #9794 from VincentLanglet/associationMapping
Add type for AssociationMapping
2022-06-01 23:37:00 +02:00
Grégoire Paris
b2fedaef9e Merge remote-tracking branch 'origin/2.12.x' into 2.13.x 2022-06-01 22:49:10 +02:00
Grégoire Paris
21976471a3 Fix wrong types (#9802) 2022-06-01 22:42:51 +02:00
Grégoire Paris
6fb88e1496 Widen return type
This type is so complex that it is not going to bring much value to the
consumer of this method. Let us widen it to mixed.
2022-06-01 19:56:25 +02:00
Sergei Morozov
3ac5f119aa Merge pull request #9799 from morozov/sqlite-fk
Prep work for enabling support for foreign keys on SQLite
2022-06-01 06:19:47 -07:00
Sergei Morozov
01fb82b497 Prep work for enabling support for foreign keys on SQLite 2022-05-30 18:45:43 -07:00
Alexander M. Turek
4f1072e1ac Add missing import (#9796) 2022-05-31 00:42:03 +02:00
Alexander M. Turek
a559563682 Deprecate calling setters without arguments (#9791) 2022-05-30 20:39:06 +02:00
Vincent Langlet
0f9cc194ae Update baseline 2022-05-29 20:27:26 +02:00
Vincent Langlet
2513a1e2b1 Fix 2022-05-29 20:16:12 +02:00
Vincent Langlet
4230214ced Add type for AssociationMapping 2022-05-29 13:17:04 +02:00
Alexander M. Turek
fb1f258736 Move duplicate fixture into dedicated file (#9789) 2022-05-27 15:08:21 +02:00
olegsuvorkov
aae8b43622 Update IdentifierFlattener.php
Fix for coding-standards / Coding Standards (8.1)
2022-05-27 15:35:23 +03:00
Alexander M. Turek
e66fbc434d MockTreeWalker should be an SqlWalker (#9790) 2022-05-27 00:15:30 +02:00
olegsuvorkov
3f4e9e397a Update IdentifierFlattener.php
Hello, I would like to make a small change.
The need arose when using \Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator in "symfony/doctrine-bridge" composite foreign keys
I'm sure these changes will not hurt performance
and allow other objects to be used as identifiers
2022-05-26 10:46:14 +03:00
Grégoire Paris
0f6f752887 Merge pull request #9777 from greg0ire/improve-phpdoc-abstract-query
Make phpdoc more precise for AbstractQuery
2022-05-24 20:42:40 +02:00
Grégoire Paris
c1dd1cfc2c Make phpdoc more precise 2022-05-24 20:42:10 +02:00
Grégoire Paris
3684d236f6 Deprecate setting fetch mode to random integers 2022-05-24 20:42:08 +02:00
Alexander M. Turek
bba6c696f5 Prepare split of output walkers and tree walkers (#9786) 2022-05-24 18:34:40 +00:00
Alexander M. Turek
e02e6f481b Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  PHPStan 1.7.0 (#9785)
2022-05-24 00:43:35 +02:00
Alexander M. Turek
48e4e333c7 PHPStan 1.7.0 (#9785) 2022-05-24 00:41:57 +02:00
Grégoire Paris
507bc514ce Merge pull request #9784 from greg0ire/deprecate-no-op
Deprecate passing null to Query::setDQL()
2022-05-23 22:31:50 +02:00
Grégoire Paris
1ae5de5409 Deprecate passing null to Query::setDQL()
It is a no-op.
2022-05-23 22:11:16 +02:00
Alexander M. Turek
82508956fe Kill call_user_func(_array) (#9780) 2022-05-23 16:28:32 +02:00
Alexander M. Turek
a131878814 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Fix wrong types for AbstractQuery and child classes (#9774)
  Document callable as possible
  Add use statement (#9769)
2022-05-23 11:29:26 +02:00
Grégoire Paris
1f63389065 Fix wrong types for AbstractQuery and child classes (#9774)
* Remove comment about BC

I do not think we actually want to force our users to build an array
collection when they want to use setParameters().

* Make phpdoc more accurate
2022-05-23 11:26:19 +02:00
Grégoire Paris
359dd4ecfb Merge pull request #9779 from greg0ire/fix-config-phpdoc 2022-05-23 11:18:58 +02:00
Grégoire Paris
a0697c9aff Document callable as possible
Custom string functions can either be a class string or a callable
returning the function.
2022-05-23 11:05:16 +02:00
Grégoire Paris
5601c2ce4b Merge pull request #9775 from greg0ire/no-override
Remove override phpdoc tag
2022-05-23 07:48:01 +02:00
Grégoire Paris
1141fe106f Remove override phpdoc tag
Given how little occurrences there are, signalling method overrides with
this tag is probably not something we do everywhere. Besides, it does
not seem to be standard.

See https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/index.html#tag-reference
2022-05-22 16:28:41 +02:00
Grégoire Paris
8f7701279d Add use statement (#9769)
We are supposed to use the driver from doctrine/persistence, and not the
deprecated one from this package.
2022-05-19 13:16:51 +02:00
Grégoire Paris
779f9c36fa Merge pull request #9766 from greg0ire/non-nullable-arg-ns
Document future argument better
2022-05-18 08:00:17 +02:00
Grégoire Paris
0908f92629 Document future argument better
That argument is always provided, so the tests should provide it and the
commented out argument should reflect the future.
2022-05-17 12:09:31 +02:00
Grégoire Paris
24badd60fb Merge pull request #9761 from greg0ire/fix-phpdoc-ns
Fix phpdoc and tests for NamingStrategy
2022-05-16 22:00:41 +02:00
Sergei Morozov
f2d794f8bc Merge pull request #9762 from morozov/schema-manager-database-platform
Do not call AbstractSchemaManager::getDatabasePlatform()
2022-05-16 08:31:45 -07:00
Sergei Morozov
7311f77dfe Do not call AbstractSchemaManager::getDatabasePlatform() 2022-05-15 19:25:51 -07:00
Grégoire Paris
16afa45abf Make tests more realistic
These tests were using the fact that some arguments of some methods of
the naming strategy interface are optional or nullable for now to avoid
providing some. In practice, these arguments are always provided, and
that should also be the case in tests.
2022-05-14 17:31:45 +02:00
Grégoire Paris
8b4d25e94f Handle self-refencing entities
When computing a foreign key column name, the referenced column name
may be null in the case of a self referencing entity with join columns
defined in the mapping.
2022-05-14 16:56:19 +02:00
Grégoire Paris
70087782e8 Merge pull request #9756 from greg0ire/more-precise-phpdoc-ns
Document types as they are passed
2022-05-12 09:05:51 +02:00
Grégoire Paris
dbc5a818e0 Document types as they are passed
Some arguments have been added afterwards which was a BC break for
implementing classes. I do not think they should have been introduced as
optional.
2022-05-11 21:36:44 +02:00
Alexander M. Turek
31a9c9c49b Update Psalm baseline (#9751) 2022-05-10 16:00:54 +02:00
Alexander M. Turek
125afb8e39 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Omit version number in README (#9749)
2022-05-10 15:08:24 +02:00
Grégoire Paris
45e196eb57 Omit version number in README (#9749) 2022-05-10 09:09:20 +02:00
Grégoire Paris
2c30fe6e5b Merge pull request #9748 from doctrine/2.12.x
Merge 2.12.x up into 2.13.x
2022-05-10 08:21:34 +02:00
Grégoire Paris
6757bdf8c6 Deprecate omitting second argument to joinColumnName() (#9747)
* fix headings

* Deprecate omitting second argument to joinColumnName()
2022-05-10 00:37:44 +02:00
Grégoire Paris
eed20ff4dd Better phpdoc tests (#9746)
* Fix inaccurate and imprecise phpdoc

* Remove extra argument

The method signature does not specify it, and it's always set to null.
It looks like this test and its data provider were copy/pasted from the
previous one.

* Specify what concrete class is passed

This is important as the signature of the concrete classes don't
necessarily match the one of the interface. Here, an extra argument that
is only defined in the classes is used.
2022-05-10 00:32:30 +02:00
Sergei Morozov
636712a928 Merge pull request #9737 from morozov/dbal-4-compatibility
Improve compatibility with DBAL 4 for MySQL, MariaDB and PostgreSQL
2022-05-07 07:42:14 -07:00
Sergei Morozov
0aa91c7140 Pass sequence name to AbstractPlatform::getDropSequenceSQL()
See https://github.com/doctrine/dbal/pull/4797
2022-05-06 19:15:06 -07:00
Sergei Morozov
c2f3831b85 Specify length for string columns
See https://github.com/doctrine/dbal/pull/3586
2022-05-06 19:15:06 -07:00
Sergei Morozov
2af52f6a18 Inherit parent column length regardless of the type
See https://github.com/doctrine/dbal/pull/3586
2022-05-06 19:15:05 -07:00
Sergei Morozov
0a79ddf344 Cast column length to int in XML annotation driver
See https://github.com/doctrine/dbal/pull/3511
2022-05-06 19:15:05 -07:00
Sergei Morozov
165c8bd6dd Do not use AbstractSchemaManager::dropAndCreateTable()
See https://github.com/doctrine/dbal/pull/4933
2022-05-06 19:15:03 -07:00
Alexander M. Turek
07ee555279 Exclude /ci from distribution packages (#9732) 2022-05-06 13:07:36 +02:00
Sergei Morozov
e6bda4afda Merge pull request #9730 from morozov/dbal-4-compatibility
Forward compatibility with DBAL 4
2022-05-05 14:06:25 -07:00
Sergei Morozov
51b4e02873 Obtain database platform from the connection, not from the driver
See https://github.com/doctrine/dbal/pull/4764
2022-05-05 11:30:36 -07:00
Sergei Morozov
1915dcd1e8 Use zero as the default query offset
See https://github.com/doctrine/dbal/pull/3574
2022-05-05 11:30:35 -07:00
Sergei Morozov
480d99b107 Use getStringTypeDeclarationSQL() instead of getVarcharTypeDeclarationSQL()
See https://github.com/doctrine/dbal/pull/3586
2022-05-05 11:30:35 -07:00
Sergei Morozov
c6661caaed Do not extend a type with a different PHP return type
See https://github.com/doctrine/dbal/pull/5043
2022-05-05 11:30:34 -07:00
Sergei Morozov
9e27370f15 Drop and create test database manually
See https://github.com/doctrine/dbal/pull/4933
2022-05-05 11:30:32 -07:00
Sergei Morozov
1a3fbcb145 Lookup type name in the registry
See https://github.com/doctrine/dbal/pull/5208
2022-05-05 09:32:38 -07:00
Sergei Morozov
c950e72628 Do not use null column definition 2022-05-05 09:32:37 -07:00
Alexander M. Turek
05560f260c Merge release 2.12.2 into 2.13.x (#9725) 2022-05-03 02:15:35 +02:00
Alexander M. Turek
8291a7f09b Allow doctrine/deprecations 1.0 (#9723) 2022-05-02 21:10:07 +02:00
Ruud Kamphuis
d7d6b9d2c7 Allow setting column options like charset and collation everywhere (#9655)
This makes it possible to set custom options on the following:
* `JoinTable`
* `JoinColumn`
* `InverseJoinColumn`
2022-05-02 19:01:24 +02:00
Grégoire Paris
26e274e373 Merge pull request #9708 from michnovka/2.12.x-fix-psalm-repository 2022-05-02 15:26:47 +02:00
Alexander M. Turek
a02642e3e6 Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  Psalm 4.23, PHPStan 1.6.3 (#9718)
2022-05-02 11:09:12 +02:00
Alexander M. Turek
5209184a60 Psalm 4.23, PHPStan 1.6.3 (#9718) 2022-05-02 11:07:33 +02:00
Grégoire Paris
b4da0ece41 Merge pull request #9704 from greg0ire/reference-cmi-less-and-less
Reference ClassMetadataInfo less and less
2022-05-01 22:06:19 +02:00
Sergei Morozov
3980d58b80 Merge pull request #9710 from morozov/2.13.x
Merge 2.12.x into 2.13.x
2022-05-01 12:46:13 -07:00
Sergei Morozov
10cbb24649 Merge branch '2.12.x' into 2.13.x 2022-05-01 12:24:28 -07:00
Sergei Morozov
23f54885bc Merge pull request #9706 from morozov/cleanup-test-entity-manager
Remove unused OrmTestCase::getTestEntityManager() parameters
2022-05-01 11:43:07 -07:00
Sergei Morozov
7f29b576d8 Remove some ConnectionMock methods (#9707) 2022-05-01 17:52:10 +02:00
Tomas
a8425a5248 Fix psalm annotation 2022-05-01 16:40:44 +02:00
Pierre B
86ce0e5e35 Update ClassMetadataInfo::table definition (#9703)
Everything except the name key might be undefined when accessing to this public property, for instance in a LoadMetadataEvent

Co-authored-by: Pierre Bourdet <pbourdet@worldia.com>
2022-05-01 09:40:00 +02:00
Sergei Morozov
39fd5f4d46 Remove unused OrmTestCase::getTestEntityManager() parameters 2022-04-30 12:35:05 -07:00
Grégoire Paris
476a02075f Deprecate classes and methods removed in 3.0 2022-04-30 19:47:20 +02:00
Grégoire Paris
98e10906f8 Change class metadata type declarations
There is a guarantee in the call sites that we are only passing
ClassMetadata instances.
2022-04-30 19:47:20 +02:00
Grégoire Paris
7241b4d2e0 Reference constants from ClassMetadata 2022-04-30 19:47:20 +02:00
Grégoire Paris
b8db858784 Deprecate not passing ClassMetadata instances 2022-04-30 19:47:20 +02:00
Thomas Landauer
a9309d748b Add missing use statement (#9699) 2022-04-30 08:04:44 +02:00
Grégoire Paris
fe09af6df1 Merge pull request #9701 from doctrine/2.11.x
2.11.x
2022-04-29 22:45:58 +02:00
Grégoire Paris
ed50e3d967 Merge pull request #9698 from ThomasLandauer/patch-8 2022-04-29 16:33:49 +02:00
Thomas Landauer
1d59e46245 use valid link syntax 2022-04-29 16:25:10 +02:00
Grégoire Paris
d8f3198ef8 Merge pull request #9693 from doctrine/2.12.x
Merge 2.12.x up into 2.13.x
2022-04-29 08:13:20 +02:00
Grégoire Paris
a0a0b0e476 Merge pull request #9692 from greg0ire/reference-cmi-even-less
Use ClassMetadata over ClassMetadataInfo in tests
2022-04-28 23:07:56 +02:00
Grégoire Paris
0078a67786 Use ClassMetadata over ClassMetadataInfo in tests
ClassMetadataInfo is deprecated in favor of ClassMetadata.
2022-04-28 21:40:23 +02:00
Grégoire Paris
38d1124be9 Merge pull request #9691 from greg0ire/reference-cmi-less
Reference ClassMetadaInfo less
2022-04-28 07:58:51 +02:00
Grégoire Paris
e9d3c218ef Remove explanation about inexistent distinction
ClassMetadataInfo used to be useful during entity generation, because it
allowed the entity not to exist. We no longer do entity generation, and
even if we did, the reflection methods have been moved to
ClassMetadataInfo as of 76e4f5a80b .
2022-04-27 23:28:58 +02:00
Grégoire Paris
6d2ca8fe40 Address mapping driver extraction
This documentation must be very old because this is no longer valid as
of e9e36dcf32 . The interface and abstract
file driver have since then been moved to doctrine/common, and the to
doctrine/persistence.
2022-04-27 23:28:43 +02:00
Grégoire Paris
a06011daf3 Refer to ClassMetadata instead of ClassMetadataInfo
Although properties and methods are currently located in
ClassMetadataInfo, it is better to refer to ClassMetadata as the former
is deprecated in favor of the latter.
2022-04-27 23:28:40 +02:00
Alexander M. Turek
825e9641fd Merge branch '2.12.x' into 2.13.x
* 2.12.x:
  PHPStan 1.6.1 (#9688)
  Drop SymfonyStyle[listing] for sqls (#9679)
2022-04-27 09:53:50 +02:00
Alexander M. Turek
0846b8b102 PHPStan 1.6.1 (#9688) 2022-04-26 23:52:07 +02:00
Simon Podlipsky
1dd2b44982 Drop SymfonyStyle[listing] for sqls (#9679)
This was super annoying as UpdateCommand printed sqls prefixed with `*` so it was not possible to copy statements anymore without manually removing those asterisks.

This removes prefixing sqls and makes it consistent with Create and Drop commands.
2022-04-26 15:33:18 +02:00
Alexander M. Turek
5fbe5ebef4 Merge 2.12.x into 2.13.x (#9684) 2022-04-26 11:32:14 +02:00
Alexander M. Turek
d9508e97df Remove dynamic property declarations (#9683) 2022-04-26 11:10:50 +02:00
Alexander M. Turek
534ed9c3c2 PHPStan 1.6.0 (#9682) 2022-04-26 11:01:11 +02:00
Grégoire Paris
f4585b954f Merge pull request #6728 from greg0ire/validate_xml_against_xsd
Validate XML mapping against XSD file
2022-04-25 23:04:26 +02:00
Grégoire Paris
ab3a255440 Validate XML mapping against XSD file
Co-Authored-By: Axel Venet <avenet@wamiz.com>
Co-authored-by: Luís Cobucci <lcobucci@gmail.com>
2022-04-25 22:55:00 +02:00
Grégoire Paris
a552df66a9 Merge pull request #9677 from greg0ire/assert-drivers-are-orm-specific
Document ORM drivers only really load ORM metadata
2022-04-24 20:55:13 +02:00
Grégoire Paris
85238d4d98 Document ORM drivers only really load ORM metadata 2022-04-24 20:05:37 +02:00
Fran Moreno
b7e9dd023c Fix HydrationException::invalidDiscriminatorValue parameter type (#9676) 2022-04-24 19:32:57 +02:00
Fran Moreno
1ac05f5e4e Fix type on ClassMetadata discriminatorMap (#9675) 2022-04-24 17:52:28 +02:00
Alexander M. Turek
2e4a872272 Conditionally extend the old AnnotationDriver class (#9671) 2022-04-22 19:46:03 +02:00
Alexander M. Turek
d550364431 Deprecate the doctrine binary (#9661) 2022-04-19 20:34:28 +02:00
Alexander M. Turek
5b2bf9d74c Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  ScalarColumnHydrator: prevent early-bail on falsy values (#9663)
2022-04-19 11:27:11 +02:00
michnovka
2fe40679f4 Fix enum hydration when fetching partial results (#9657) 2022-04-16 20:49:28 +02:00
Alexander M. Turek
7029965d3a Indicate support for doctrine/persistence 3 (#9656) 2022-04-15 13:00:03 +02:00
michnovka
7e49c70320 Fix tests for enum ID hydration (#9658) 2022-04-13 12:58:20 +02:00
Grégoire Paris
f7fe5ad1bb Merge pull request #9654 from greg0ire/revert-9636
Revert "Use charset/collation from column or table default when creatng relations (#9636)"
2022-04-12 07:19:51 +02:00
Grégoire Paris
035c52ce3c Revert "Use charset/collation from column or table default when creating relations (#9636)"
This reverts commit 03f4468be2.
The inferring process seems fragile and MySQL-specific. The ORM might
not be the correct place to fix this issue (if it needs to be fixed at
all).
2022-04-11 20:26:17 +02:00
michnovka
7e7e38b60e Fix test file/class names (#9649) 2022-04-11 12:15:45 +02:00
Alexander M. Turek
36ab133e62 Leverage generic persistence event classes (#9633) 2022-04-11 11:58:42 +02:00
Alexander M. Turek
e13422ab5e Merge 2.11.x into 2.12.x (#9650)
* Fix composer install in contributing readme

People that contribute know how to use composer.

* Fix static analysis for Persistence 2.5 (#9648)

Co-authored-by: Ruud Kamphuis <ruudk@users.noreply.github.com>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2022-04-10 23:45:04 +02:00
Grégoire Paris
fda79b8e21 Improve exception message (#9646)
In setups where you have many parameters, or do not even realise you are
using an entity, that additional piece of context can be helpful. The
parameter name is not always available where the old exception was
called though.
2022-04-10 23:08:52 +02:00
Alexander M. Turek
5a345b01dc Deprecate console helper (#9641) 2022-04-10 20:59:10 +02:00
Ruud Kamphuis
03f4468be2 Use charset/collation from column or table default when creating relations (#9636)
Fixes #6823
2022-04-10 14:34:21 +02:00
michnovka
a3d82f8e2f Support Enum IDs and search by Enum fields (#9629) 2022-04-09 23:40:41 +02:00
Alexander M. Turek
d9e8e839fe Deprecate custom ObjectRepository implementations (#9533) 2022-04-06 13:51:12 +02:00
Alexander M. Turek
e8472c8f1a Fix types on walkLiteral() and walkLikeExpression() (#9566) 2022-04-06 10:48:54 +02:00
Alexander M. Turek
deaab5133e Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  explicitly use the non-deprecated ORMException
2022-04-05 13:02:01 +02:00
Sander
cffe31fc9d Add support for array of enums (#9497)
* Add support for array of enums

This allows the use of 'array' and 'simple_array' in combination
with the enumType parameter.

* Reference is_array and array_map through a use statement nstead of global fallback

* Return the value of an array of enums correctly

* Add enum array mapping test

* Fix order of use parameters

* Fix return type docblock

* Apply phpcs feedback

* Fix static closure

* Add missing return type to static closure

* Add helper method for enum initialization to reduce code duplication

* Fix CS

* Replace mixed typehints with more specific ones

* Update docblock type hint to allow for array of string/int

* Fix types

* Fix types

Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-04-05 01:29:40 +02:00
Alexander M. Turek
0e9c7533fb Fix types on ResultSetMapping (#9621) 2022-04-04 21:58:25 +02:00
Alexander M. Turek
18d6bc3757 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Remove "Description of" PHPDoc (#9611)
2022-03-31 00:14:34 +02:00
Alexander M. Turek
7c4ae58517 Support enums as default values (#9616) 2022-03-28 22:36:45 +02:00
Alexander M. Turek
05f8fcf836 Skip tests requiring ObjectManagerAware (#9612) 2022-03-28 13:50:45 +00:00
Alexander M. Turek
acff29fddd Update psalm.xml 2022-03-28 10:48:23 +02:00
Alexander M. Turek
58659f6c4f Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  PHPStan 1.5.0 (#9607)
  Remove Sphinx config
  Use correct syntax for external links
  Update XmlExporter.php - Type problem in php8.x (#9589)
  Ignore deprecation from Persistence
  Stands with Ukraine (#9567)
  Use internal links when self-referencing
  Link to docs for the stable version
2022-03-28 10:46:50 +02:00
Grégoire Paris
9952350c64 Merge pull request #9604 from greg0ire/improve-exception-message
Indicate what feature is deprecated
2022-03-24 08:46:03 +01:00
Grégoire Paris
3bc78caba9 Indicate what feature is deprecated 2022-03-23 18:39:33 +01:00
Grégoire Paris
0f1c9ec72a Merge pull request #9603 from greg0ire/int-mask-of 2022-03-22 14:18:14 +01:00
Grégoire Paris
80f65d6f77 Implement int-mask-of where appropriate
With Psalm, you can specify that an integer should be a bitmask of
constants. Doing so allows to make some types more precise.
2022-03-22 14:02:31 +01:00
Grégoire Paris
0f04a82857 Merge pull request #9595 from greg0ire/deprecate-more-ns-aliases
Deprecate more occurrences of namespace aliases
2022-03-20 14:34:16 +01:00
Grégoire Paris
17903346cf Deprecate more occurrences of namespace aliases 2022-03-20 14:26:13 +01:00
Alexander M. Turek
98b468da57 Fix type on SqlWalker::walkPathExpression() (#9565) 2022-03-20 13:42:41 +01:00
Grégoire Paris
bccb4c7bd9 Merge pull request #9592 from greg0ire/fix-persistence-compat
Deprecate or throw on namespace alias usage
2022-03-20 12:26:28 +01:00
Grégoire Paris
dc53628faf Deprecate or throw on namespace alias usage
This feature has been deprecated and removed in doctrine/persistence.
It was already deprecated in doctrine/orm for other APIs.
2022-03-20 11:44:42 +01:00
Grégoire Paris
21f339e6eb Merge pull request #9528 from greg0ire/get-rid-of-persistent-object
Implement forward compatibility with Persistence 3
2022-03-19 13:18:06 +01:00
Grégoire Paris
08de12e962 Merge pull request #9580 from klammbueddel/bug/duplicate-object-in-nested-collections
Add test to reproduce #9579
2022-03-18 22:54:19 +01:00
Grégoire Paris
7c83373f1e Add specific CI jobs for Persistence 3 2022-03-18 22:25:47 +01:00
Grégoire Paris
021164fbe5 throw when attempting to use partial clearing 2022-03-18 22:21:59 +01:00
Grégoire Paris
b2d0c21fe0 Workaround the impossibility of unsetting metadata 2022-03-18 21:49:08 +01:00
Grégoire Paris
7391e2586a Mock ClassMetadata::getName()
It is supposed to return a string.
2022-03-18 21:49:08 +01:00
Grégoire Paris
3532ce9a25 Remove useless calls 2022-03-18 21:49:08 +01:00
Grégoire Paris
2c769acf8c Implement forward compatbility with Persistence 3 2022-03-18 21:49:08 +01:00
Christian Bartels
61cb557b18 Check if association already contains object (#9579) 2022-03-18 11:00:33 +01:00
Grégoire Paris
4471ad9f6b Merge pull request #9587 from greg0ire/implement-colocated-driver 2022-03-16 10:54:06 +01:00
Grégoire Paris
cd57768b08 Implement colocated mapping driver
This allows us to decouple further from doctrine/annotations, and to fix
some static analysis issues.

The assumption being made here is that the abstract class we are no
longer extending is not used in type declarations and instanceof checks.
2022-03-15 12:42:27 +01:00
Alexander M. Turek
b64824addb Leverage MemcachedAdapter::isSupported() (#9578) 2022-03-10 23:37:36 +01:00
Alexander M. Turek
c7104c9471 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Baseline Psalm errors caused by DBAL 3.3.3 (#9577)
  Make sure MemcachedAdapter is supported before tring to use it (#9574)
  Fixing `:doc:` link (#9569)
  Adding PHP attributes (#9555)
  Remove reference to removed class
2022-03-09 17:20:17 +01:00
Alexander M. Turek
bc6c6c9f0c Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Parser: SimpleArithmeticExpression should return ArithmeticTerm (#9557)
2022-03-03 19:55:19 +01:00
Loïc Vernet
89d0a6a67c validate schema command: allow to debug missing schema updates list (#9019) 2022-03-03 18:35:32 +00:00
Alexander M. Turek
1febeaca7f Document tree walker class strings (#9553) 2022-03-01 20:14:46 +01:00
Alexander M. Turek
229dcb082b Use literal types for JOIN_TYPE_* constants (#9552) 2022-03-01 15:10:51 +01:00
Grégoire Paris
3849aed6fb Merge pull request #9549 from derrabus/improvement/leverage-token-type
Leverage Lexer's Token type
2022-02-28 20:56:19 +01:00
Alexander M. Turek
f82db6a894 Leverage Lexer's Token type 2022-02-28 20:27:19 +01:00
Alexander M. Turek
a8a859cf5e Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Update baselines for Lexer 1.2.3 (#9546)
2022-02-28 14:11:53 +01:00
Alexander M. Turek
7be96f64ab Document QueryComponent array shape (#9527) 2022-02-25 00:21:29 +01:00
Grégoire Paris
947935e4c9 Merge pull request #9541 from greg0ire/improve-templating 2022-02-24 20:25:13 +01:00
Grégoire Paris
40af1fcfc6 Improve templating
This is helpful for static analysis
2022-02-24 18:19:30 +01:00
Alexander M. Turek
021444b322 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Fix bug-#9536
2022-02-24 11:24:13 +01:00
Alexander M. Turek
ec7c637cf2 Un-deprecate the current proxy mechanism (#9532) 2022-02-24 11:17:05 +01:00
Grégoire Paris
0a0779c4a9 Remove unused methods 2022-02-22 20:26:18 +01:00
Grégoire Paris
a52d9880cc Merge pull request #9542 from doctrine/2.11.x
Merge 2.11.x up into 2.12.x
2022-02-22 18:11:25 +01:00
Alexander M. Turek
08eaba44ca Fix more types on EntityRepository and FilterCollection (#9525) 2022-02-20 21:09:41 +01:00
Alexander M. Turek
05c35c398f Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Bring `FilterCollection` to a "clean" state after hash computation (#9523)
2022-02-20 14:19:47 +01:00
Alexander M. Turek
dac1875a79 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Make creating test models more straightforward
  Trigger the desired code path
  Fix syntax typo in attributes reference (#9513)
  Constructor-Argument "options" has the same type as the associated property. (#9501)
2022-02-20 11:52:36 +01:00
Alexander M. Turek
5a55772559 Document deprecation of AbstractCollectionPersister helpers (#9512) 2022-02-15 22:54:30 +01:00
Alexander M. Turek
d78fa52ad7 Replace TreeWalkerChainIterator with a generator (#9511) 2022-02-15 13:00:15 +01:00
Alexander M. Turek
4ddaa5fc20 Fix types on caches (#9507) 2022-02-13 22:50:21 +01:00
Alexander M. Turek
d7abcb01bc Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Fix AbstractQuery::setParameter phpdoc (#9504)
2022-02-13 11:02:56 +01:00
Alexander M. Turek
8cff7dcdaf Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Added "false" value to $columnPrefix type declaration. (#9493)
2022-02-09 14:56:45 +01:00
Alexander M. Turek
601728045c Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  PHPStan 1.4.6, Psalm 4.20.0 (#9491)
  Fix `#[DiscriminatorMap]` params (#9487)
  Run tests with stricter error handling (#9482)
2022-02-09 00:51:01 +01:00
Alexander M. Turek
b18cd893be Fix types on QueryBuilder (#9492) 2022-02-09 00:48:36 +01:00
Alexander M. Turek
21390a12b9 Fix types on EntityRepository (#9474) 2022-02-09 00:44:30 +01:00
Alexander M. Turek
182bcbae23 Avoid calling merge() (#9489) 2022-02-09 00:42:49 +01:00
Alexander M. Turek
978f687df9 Modernize strpos() calls (#9480) 2022-02-07 09:34:45 +01:00
Alexander M. Turek
fd1690431f Fix types on persisters (#9466) 2022-02-07 09:26:15 +01:00
Grégoire Paris
3cfcd4ad13 Merge pull request #9479 from derrabus/improvement/useless-catch
Remove useless catches
2022-02-06 16:07:47 +01:00
Alexander M. Turek
69b0b764e3 Rename DoctrineSetup to ORMSetup (#9481) 2022-02-06 15:22:58 +01:00
Alexander M. Turek
e11cef5fca Remove useless catches 2022-02-06 00:20:25 +01:00
Alexander M. Turek
395c02caf4 Deprecate methods removed in 3.0 (#9475) 2022-02-05 22:41:33 +01:00
Alexander M. Turek
0c4e739e94 Merge 2.11.x into 2.12.x (#9473) 2022-02-05 20:15:38 +01:00
Alexander M. Turek
7a72526e47 Skip tests related to PersistentObject if that class is missing (#9472) 2022-02-05 19:31:42 +01:00
Alexander M. Turek
5f882b1cdd Check requirements for metadata drivers (#9459) 2022-02-01 19:19:40 +01:00
Alexander M. Turek
b3d849dd38 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  PDO is not a required extension (#9457)
  Check requirements for metadata drivers (#9452)
  Remove trailing underscore (#9446)
2022-02-01 14:16:15 +01:00
Alexander M. Turek
aa1dd881d8 Support enums in findBy() calls (#9453) 2022-01-31 23:02:58 +01:00
Alexander M. Turek
92d27f2fea Streamline cache creation in tests (#9451) 2022-01-31 21:55:39 +01:00
Alexander M. Turek
f8de44c35f Document the new DoctrineSetup class (#9448) 2022-01-31 08:13:10 +01:00
Alexander M. Turek
f81980e1fa Introduce DoctrineSetup as a replacement for Setup (#9443) 2022-01-30 22:38:57 +00:00
Alexander M. Turek
e9e54d8f65 Merge release 2.11.1 into 2.12.x (#9444) 2022-01-30 23:04:07 +01:00
Alexander M. Turek
04bfdf85de Merge 2.11.x up into 2.12.x (#9441) 2022-01-30 18:06:16 +01:00
Alexander M. Turek
43f67c6164 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Psalm 4.19.0, PHPStan 1.4.3 (#9438)
  Ignore PHPUnit result cache everywhere (#9425)
2022-01-28 23:08:59 +01:00
Alexander M. Turek
f5be4183ce Introduce assertQueryCount (#9423) 2022-01-24 09:39:48 +01:00
Alexander M. Turek
eed031fab0 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Add support for PHP 8.1 enums in embedded classes (#9419)
  Added class-string typehint on $targetEntity (#9415)
  Allow DiscriminatorColumn with length=0 (#9410)
  Move UnderscoreNamingStrategyTest to correct namespace (#9414)
2022-01-24 00:05:44 +01:00
Alexander M. Turek
328f36846e Switch tests to the middleware logging system (#9418) 2022-01-23 23:55:07 +01:00
Alexander M. Turek
f7822c775d Fix types on CacheLogger implementations (#9401) 2022-01-20 00:29:39 +01:00
Sergei Morozov
8c08792f0e Rework some tests that use hardcoded DBAL mocks (#9404) 2022-01-19 17:11:57 +01:00
Alexander M. Turek
026bba23f1 Merge branch '2.11.x' into 2.12.x
* 2.11.x:
  Fix type on loadCacheEntry (#9398)
2022-01-18 23:35:01 +01:00
Alexander M. Turek
4305cb9230 Deprecate MultiGetRegion (#9397) 2022-01-18 22:50:26 +01:00
Alexander M. Turek
2886d0dc92 Merge 2.11.x into 2.12.x (#9394)
* Expose enumType to DBAL to make native DB Enum possible (#9382)

* Accessing private properties and methods from the same class is forbidden (#9311)

Resolves issue https://github.com/doctrine/common/issues/934

Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Fix review issues

* Update baselines for DBAL 3.3 (#9393)

Co-authored-by: Vadim Borodavko <vadim.borodavko@gmail.com>
Co-authored-by: olsavmic <molsavsky1@gmail.com>
2022-01-18 09:45:05 +01:00
Alexander M. Turek
07f1c4e8f8 Merge pull request #9387 from doctrine/2.11.x 2022-01-16 21:39:56 +01:00
Alexander M. Turek
0809a2b671 Support enum cases as parameters (#9373) 2022-01-13 13:11:13 +01:00
960 changed files with 11919 additions and 12189 deletions

View File

@@ -12,21 +12,33 @@
"upcoming": true
},
{
"name": "2.12",
"branchName": "2.12.x",
"slug": "2.12",
"name": "2.14",
"branchName": "2.14.x",
"slug": "2.14",
"upcoming": true
},
{
"name": "2.11",
"branchName": "2.11.x",
"slug": "2.11",
"name": "2.13",
"branchName": "2.13.x",
"slug": "2.13",
"current": true,
"aliases": [
"current",
"stable"
]
},
{
"name": "2.12",
"branchName": "2.12.x",
"slug": "2.12",
"maintained": false
},
{
"name": "2.11",
"branchName": "2.11.x",
"slug": "2.11",
"maintained": false
},
{
"name": "2.10",
"branchName": "2.10.x",

5
.gitattributes vendored
View File

@@ -1,7 +1,8 @@
/.github export-ignore
/ci export-ignore
/docs export-ignore
/tests export-ignore
/tools export-ignore
/docs export-ignore
/.github export-ignore
.doctrine-project.json export-ignore
.gitattributes export-ignore
.gitignore export-ignore

View File

@@ -10,6 +10,4 @@ on:
jobs:
coding-standards:
uses: "doctrine/.github/.github/workflows/coding-standards.yml@1.4.1"
with:
php-version: "8.1"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@2.0.0"

View File

@@ -14,7 +14,7 @@ env:
jobs:
phpunit-smoke-check:
name: "PHPUnit with SQLite"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
strategy:
matrix:
@@ -31,6 +31,8 @@ jobs:
dbal-version: "2.13"
- php-version: "8.1"
dbal-version: "3@dev"
- php-version: "8.2"
dbal-version: "3@dev"
steps:
- name: "Checkout"
@@ -42,7 +44,7 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
extensions: "pdo, pdo_sqlite"
extensions: "apcu, pdo, pdo_sqlite"
coverage: "pcov"
ini-values: "zend.assertions=1"
@@ -52,6 +54,8 @@ jobs:
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--ignore-platform-req=php+"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --coverage-clover=coverage-no-cache.xml"
@@ -72,7 +76,7 @@ jobs:
phpunit-postgres:
name: "PHPUnit with PostgreSQL"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
strategy:
@@ -88,6 +92,9 @@ jobs:
- php-version: "8.0"
dbal-version: "2.13"
postgres-version: "14"
- php-version: "8.2"
dbal-version: "3@dev"
postgres-version: "14"
services:
postgres:
@@ -120,6 +127,8 @@ jobs:
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--ignore-platform-req=php+"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml"
@@ -133,7 +142,7 @@ jobs:
phpunit-mariadb:
name: "PHPUnit with MariaDB"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
strategy:
@@ -152,6 +161,14 @@ jobs:
dbal-version: "2.13"
mariadb-version: "10.6"
extension: "pdo_mysql"
- php-version: "8.2"
dbal-version: "3@dev"
mariadb-version: "10.6"
extension: "pdo_mysql"
- php-version: "8.2"
dbal-version: "3@dev"
mariadb-version: "10.6"
extension: "mysqli"
services:
mariadb:
@@ -186,6 +203,8 @@ jobs:
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--ignore-platform-req=php+"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml"
@@ -199,7 +218,7 @@ jobs:
phpunit-mysql:
name: "PHPUnit with MySQL"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
strategy:
@@ -219,6 +238,14 @@ jobs:
dbal-version: "2.13"
mysql-version: "8.0"
extension: "pdo_mysql"
- php-version: "8.2"
dbal-version: "3@dev"
mysql-version: "8.0"
extension: "mysqli"
- php-version: "8.2"
dbal-version: "3@dev"
mysql-version: "8.0"
extension: "pdo_mysql"
services:
mysql:
@@ -252,6 +279,8 @@ jobs:
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--ignore-platform-req=php+"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage-no-cache.xml"
@@ -272,7 +301,7 @@ jobs:
phpunit-lower-php-versions:
name: "PHPUnit with SQLite"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
strategy:
matrix:
@@ -305,7 +334,7 @@ jobs:
upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
needs:
- "phpunit-smoke-check"
- "phpunit-postgres"

View File

@@ -15,7 +15,7 @@ env:
jobs:
phpbench:
name: "PHPBench"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
strategy:
matrix:

View File

@@ -7,7 +7,7 @@ on:
jobs:
release:
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.4.1"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@2.0.0"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}

View File

@@ -12,7 +12,7 @@ on:
jobs:
static-analysis-phpstan:
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
strategy:
fail-fast: false
@@ -21,7 +21,15 @@ jobs:
- "8.1"
dbal-version:
- "default"
- "2.13"
persistence-version:
- "default"
include:
- php-version: "8.1"
dbal-version: "2.13"
persistence-version: "default"
- php-version: "8.1"
dbal-version: "default"
persistence-version: "2.5"
steps:
- name: "Checkout code"
@@ -37,6 +45,10 @@ jobs:
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Require specific persistence version"
run: "composer require doctrine/persistence ^${{ matrix.persistence-version }} --no-update"
if: "${{ matrix.persistence-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
@@ -44,15 +56,19 @@ jobs:
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse"
if: "${{ matrix.dbal-version == 'default' }}"
if: "${{ matrix.dbal-version == 'default' && matrix.persistence-version == 'default'}}"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse -c phpstan-dbal2.neon"
if: "${{ matrix.dbal-version == '2.13' }}"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse -c phpstan-persistence2.neon"
if: "${{ matrix.dbal-version == 'default' && matrix.persistence-version != 'default'}}"
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"
strategy:
fail-fast: false

View File

@@ -1,11 +1,11 @@
| [3.0.x][3.0] | [2.12.x][2.12] | [2.11.x][2.11] |
| [3.0.x][3.0] | [2.14.x][2.14] | [2.13.x][2.13] |
|:----------------:|:----------------:|:----------:|
| [![Build status][3.0 image]][3.0] | [![Build status][2.12 image]][2.12] | [![Build status][2.11 image]][2.11] |
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.12 coverage image]][2.12 coverage] | [![Coverage Status][2.11 coverage image]][2.11 coverage] |
| [![Build status][3.0 image]][3.0] | [![Build status][2.14 image]][2.14] | [![Build status][2.13 image]][2.13] |
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.14 coverage image]][2.14 coverage] | [![Coverage Status][2.13 coverage image]][2.13 coverage] |
[<h1 align="center">🇺🇦 UKRAINE NEEDS YOUR HELP NOW!</h1>](https://www.doctrine-project.org/stop-war.html)
Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence
Doctrine ORM is an object-relational mapper for PHP 7.1+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
inspired by Hibernate's HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
@@ -22,11 +22,11 @@ without requiring unnecessary code duplication.
[3.0]: https://github.com/doctrine/orm/tree/3.0.x
[3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg
[3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x
[2.12 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.12.x
[2.12]: https://github.com/doctrine/orm/tree/2.12.x
[2.12 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.12.x/graph/badge.svg
[2.12 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.12.x
[2.11 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.11.x
[2.11]: https://github.com/doctrine/orm/tree/2.11.x
[2.11 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.11.x/graph/badge.svg
[2.11 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.11.x
[2.14 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.14.x
[2.14]: https://github.com/doctrine/orm/tree/2.14.x
[2.14 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.14.x/graph/badge.svg
[2.14 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.14.x
[2.13 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.13.x
[2.13]: https://github.com/doctrine/orm/tree/2.13.x
[2.13 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.13.x/graph/badge.svg
[2.13 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.13.x

View File

@@ -1,3 +1,317 @@
# Upgrade to 2.13
## Deprecated `QueryBuilder` methods and constants.
1. The `QueryBuilder::getState()` method has been deprecated as the builder state is an internal concern.
2. Relying on the type of the query being built by using `QueryBuilder::getType()` has been deprecated.
If necessary, track the type of the query being built outside of the builder.
The following `QueryBuilder` constants related to the above methods have been deprecated:
1. `SELECT`,
2. `DELETE`,
3. `UPDATE`,
4. `STATE_DIRTY`,
5. `STATE_CLEAN`.
## Deprecated omitting only the alias argument for `QueryBuilder::update` and `QueryBuilder::delete`
When building an UPDATE or DELETE query and when passing a class/type to the function, the alias argument must not be omitted.
### Before
```php
$qb = $em->createQueryBuilder()
->delete('User u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
### After
```php
$qb = $em->createQueryBuilder()
->delete('User', 'u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
## Deprecated using the `IDENTITY` identifier strategy on platform that do not support identity columns
If identity columns are emulated with sequences on the platform you are using,
you should switch to the `SEQUENCE` strategy.
## Deprecated passing `null` to `Doctrine\ORM\Query::setFirstResult()`
`$query->setFirstResult(null);` is equivalent to `$query->setFirstResult(0)`.
## Deprecated calling setters without arguments
The following methods will require an argument in 3.0. Pass `null` instead of
omitting the argument.
* `Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs::setFoundMetadata()`
* `Doctrine\ORM\AbstractQuery::setHydrationCacheProfile()`
* `Doctrine\ORM\AbstractQuery::setResultCache()`
* `Doctrine\ORM\AbstractQuery::setResultCacheProfile()`
## Deprecated passing invalid fetch modes to `AbstractQuery::setFetchMode()`
Calling `AbstractQuery::setFetchMode()` with anything else than
`Doctrine\ORM\Mapping::FETCH_EAGER` results in
`Doctrine\ORM\Mapping::FETCH_LAZY` being used. Relying on that behavior is
deprecated and will result in an exception in 3.0.
## Deprecated `getEntityManager()` in `Doctrine\ORM\Event\OnClearEventArgs` and `Doctrine\ORM\Event\*FlushEventArgs`
This method has been deprecated in:
* `Doctrine\ORM\Event\OnClearEventArgs`
* `Doctrine\ORM\Event\OnFlushEventArgs`
* `Doctrine\ORM\Event\PostFlushEventArgs`
* `Doctrine\ORM\Event\PreFlushEventArgs`
It will be removed in 3.0. Use `getObjectManager()` instead.
## Prepare split of output walkers and tree walkers
In 3.0, `SqlWalker` and its child classes won't implement the `TreeWalker`
interface anymore. Relying on that inheritance is deprecated.
The following methods of the `TreeWalker` interface have been deprecated:
* `setQueryComponent()`
* `walkSelectClause()`
* `walkFromClause()`
* `walkFunction()`
* `walkOrderByClause()`
* `walkOrderByItem()`
* `walkHavingClause()`
* `walkJoin()`
* `walkSelectExpression()`
* `walkQuantifiedExpression()`
* `walkSubselect()`
* `walkSubselectFromClause()`
* `walkSimpleSelectClause()`
* `walkSimpleSelectExpression()`
* `walkAggregateExpression()`
* `walkGroupByClause()`
* `walkGroupByItem()`
* `walkDeleteClause()`
* `walkUpdateClause()`
* `walkUpdateItem()`
* `walkWhereClause()`
* `walkConditionalExpression()`
* `walkConditionalTerm()`
* `walkConditionalFactor()`
* `walkConditionalPrimary()`
* `walkExistsExpression()`
* `walkCollectionMemberExpression()`
* `walkEmptyCollectionComparisonExpression()`
* `walkNullComparisonExpression()`
* `walkInExpression()`
* `walkInstanceOfExpression()`
* `walkLiteral()`
* `walkBetweenExpression()`
* `walkLikeExpression()`
* `walkStateFieldPathExpression()`
* `walkComparisonExpression()`
* `walkInputParameter()`
* `walkArithmeticExpression()`
* `walkArithmeticTerm()`
* `walkStringPrimary()`
* `walkArithmeticFactor()`
* `walkSimpleArithmeticExpression()`
* `walkPathExpression()`
* `walkResultVariable()`
* `getExecutor()`
The following changes have been made to the abstract `TreeWalkerAdapter` class:
* All implementations of now-deprecated `TreeWalker` methods have been
deprecated as well.
* The method `setQueryComponent()` will become protected in 3.0. Calling it
publicly is deprecated.
* The method `_getQueryComponents()` is deprecated, call `getQueryComponents()`
instead.
On the `TreeWalkerChain` class, all implementations of now-deprecated
`TreeWalker` methods have been deprecated as well. However, `SqlWalker` is
unaffected by those deprecations and will continue to implement all of those
methods.
## Deprecated passing `null` to `Doctrine\ORM\Query::setDQL()`
Doing `$query->setDQL(null);` achieves nothing.
## Deprecated omitting second argument to `NamingStrategy::joinColumnName`
When implementing `NamingStrategy`, it is deprecated to implement
`joinColumnName()` with only one argument.
### Before
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* @param string $propertyName A property name.
*/
public function joinColumnName($propertyName): string
{
// …
}
}
```
### After
For backward-compatibility reasons, the parameter has to be optional, but can
be documented as guaranteed to be a `class-string`.
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* @param string $propertyName A property name.
* @param class-string $className
*/
public function joinColumnName($propertyName, $className = null): string
{
// …
}
}
```
## Deprecated methods related to named queries
The following methods have been deprecated:
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryResultClassMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativQueryResultSetMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativQueryEntityResultMapping()`
## Deprecated classes related to Doctrine 1 and reverse engineering
The following classes have been deprecated:
- `Doctrine\ORM\Tools\ConvertDoctrine1Schema`
- `Doctrine\ORM\Tools\DisconnectedClassMetadataFactory`
## Deprecate `ClassMetadataInfo` usage
It is deprecated to pass `Doctrine\ORM\Mapping\ClassMetadataInfo` instances
that are not also instances of `Doctrine\ORM\ClassMetadata` to the following
methods:
- `Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder::__construct()`
- `Doctrine\ORM\Mapping\Driver\DatabaseDriver::loadMetadataForClass()`
- `Doctrine\ORM\Tools\SchemaValidator::validateClass()`
# Upgrade to 2.12
## Deprecated the `doctrine` binary.
The documentation explains how the console tools can be bootstrapped for
standalone usage.
The method `ConsoleRunner::printCliConfigTemplate()` is deprecated because it
was only useful in the context of the `doctrine` binary.
## Deprecate omitting `$class` argument to `ORMInvalidArgumentException::invalidIdentifierBindingEntity()`
To make it easier to identify understand the cause for that exception, it is
deprecated to omit the class name when calling
`ORMInvalidArgumentException::invalidIdentifierBindingEntity()`.
## Deprecate `Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper`
Using a console helper to provide the ORM's console commands with one or
multiple entity managers had been deprecated with 2.9 already. This leaves
The `EntityManagerHelper` class with no purpose which is why it is now
deprecated too. Applications that still rely on the `em` console helper, can
easily recreate that class in their own codebase.
## Deprecate custom repository classes that don't extend `EntityRepository`
Although undocumented, it is currently possible to configure a custom repository
class that implements `ObjectRepository` but does not extend the
`EntityRepository` base class.
This is now deprecated. Please extend `EntityRepository` instead.
## Deprecated more APIs related to entity namespace aliases
```diff
-$config = $entityManager->getConfiguration();
-$config->addEntityNamespace('CMS', 'My\App\Cms');
+use My\App\Cms\CmsUser;
-$entityManager->getRepository('CMS:CmsUser');
+$entityManager->getRepository(CmsUser::class);
```
## Deprecate `AttributeDriver::getReader()` and `AnnotationDriver::getReader()`
That method was inherited from the abstract `AnnotationDriver` class of
`doctrine/persistence`, and does not seem to serve any purpose.
## Un-deprecate `Doctrine\ORM\Proxy\Proxy`
Because no forward-compatible new proxy solution had been implemented yet, the
current proxy mechanism is not considered deprecated anymore for the time
being. This applies to the following interfaces/classes:
* `Doctrine\ORM\Proxy\Proxy`
* `Doctrine\ORM\Proxy\ProxyFactory`
These methods have been un-deprecated:
* `Doctrine\ORM\Configuration::getAutoGenerateProxyClasses()`
* `Doctrine\ORM\Configuration::getProxyDir()`
* `Doctrine\ORM\Configuration::getProxyNamespace()`
Note that the `Doctrine\ORM\Proxy\Autoloader` remains deprecated and will be removed in 3.0.
## Deprecate helper methods from `AbstractCollectionPersister`
The following protected methods of
`Doctrine\ORM\Cache\Persister\Collection\AbstractCollectionPersister`
are not in use anymore and will be removed.
* `evictCollectionCache()`
* `evictElementCache()`
## Deprecate `Doctrine\ORM\Query\TreeWalkerChainIterator`
This class won't have a replacement.
## Deprecate `OnClearEventArgs::getEntityClass()` and `OnClearEventArgs::clearsAllEntities()`
These methods will be removed in 3.0 along with the ability to partially clear
the entity manager.
## Deprecate `Doctrine\ORM\Configuration::newDefaultAnnotationDriver`
This functionality has been moved to the new `ORMSetup` class. Call
`Doctrine\ORM\ORMSetup::createDefaultAnnotationDriver()` to create
a new annotation driver.
## Deprecate `Doctrine\ORM\Tools\Setup`
In our effort to migrate from Doctrine Cache to PSR-6, the `Setup` class which
accepted a Doctrine Cache instance in each method has been deprecated.
The replacement is `Doctrine\ORM\ORMSetup` which accepts a PSR-6
cache instead.
## Deprecate `Doctrine\ORM\Cache\MultiGetRegion`
The interface will be merged with `Doctrine\ORM\Cache\Region` in 3.0.
# Upgrade to 2.11
## Rename `AbstractIdGenerator::generate()` to `generateId()`

View File

@@ -1,5 +1,15 @@
<?php
fwrite(
STDERR,
'[Warning] The use of this script is discouraged. See'
. ' https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/tools.html#doctrine-console'
. ' for instructions on bootstrapping the console runner.'
. PHP_EOL
);
echo PHP_EOL . PHP_EOL;
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');

View File

@@ -3,6 +3,16 @@
use Symfony\Component\Console\Helper\HelperSet;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
fwrite(
STDERR,
'[Warning] The use of this script is discouraged. See'
. ' https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/tools.html#doctrine-console'
. ' for instructions on bootstrapping the console runner.'
. PHP_EOL
);
echo PHP_EOL . PHP_EOL;
$autoloadFiles = [
__DIR__ . '/../vendor/autoload.php',
__DIR__ . '/../../../autoload.php'

View File

@@ -27,32 +27,34 @@
"doctrine/collections": "^1.5",
"doctrine/common": "^3.0.3",
"doctrine/dbal": "^2.13.1 || ^3.2",
"doctrine/deprecations": "^0.5.3",
"doctrine/deprecations": "^0.5.3 || ^1",
"doctrine/event-manager": "^1.1",
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3",
"doctrine/lexer": "^1.0",
"doctrine/persistence": "^2.2",
"doctrine/lexer": "^1.2.3",
"doctrine/persistence": "^2.4 || ^3",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0",
"symfony/polyfill-php72": "^1.23",
"symfony/polyfill-php80": "^1.15"
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"doctrine/annotations": "^1.13",
"doctrine/coding-standard": "^9.0",
"doctrine/coding-standard": "^9.0.2 || ^10.0",
"phpbench/phpbench": "^0.16.10 || ^1.0",
"phpstan/phpstan": "~1.4.10 || 1.5.0",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
"squizlabs/php_codesniffer": "3.6.2",
"phpstan/phpstan": "~1.4.10 || 1.8.5",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"psr/log": "^1 || ^2 || ^3",
"squizlabs/php_codesniffer": "3.7.1",
"symfony/cache": "^4.4 || ^5.4 || ^6.0",
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"vimeo/psalm": "4.22.0"
"vimeo/psalm": "4.27.0"
},
"conflict": {
"doctrine/annotations": "<1.13 || >= 2.0"
},
"suggest": {
"ext-dom": "Provides support for XSD validation for XML mapping files",
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0",
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},

View File

@@ -47,7 +47,7 @@ appropriate autoloaders.
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
}

View File

@@ -87,12 +87,12 @@ Such an interface could look like this:
* @return \Zend_View_Helper_Interface
*/
public function setView(\Zend_View_Interface $view);
/**
* @return \Zend_View_Interface
*/
public function getView();
/**
* Renders this strategy. This method will be called when the user
* displays the site.
@@ -100,7 +100,7 @@ Such an interface could look like this:
* @return string
*/
public function renderFrontend();
/**
* Renders the backend of this block. This method will be called when
* a user tries to reconfigure this block instance.
@@ -118,21 +118,21 @@ Such an interface could look like this:
* @return array
*/
public function getRequiredPanelTypes();
/**
* Determines whether a Block is able to use a given type or not
* @param string $typeName The typename
* @return boolean
*/
public function canUsePanelType($typeName);
public function setBlockEntity(AbstractBlock $block);
public function getBlockEntity();
}
As you can see, we have a method "setBlockEntity" which ties a potential strategy to an object of type AbstractBlock. This type will simply define the basic behaviour of our blocks and could potentially look something like this:
.. code-block:: php
<?php
@@ -177,7 +177,7 @@ As you can see, we have a method "setBlockEntity" which ties a potential strateg
public function getStrategyClassName() {
return $this->strategyClassName;
}
/**
* Returns the instantiated strategy
*
@@ -186,7 +186,7 @@ As you can see, we have a method "setBlockEntity" which ties a potential strateg
public function getStrategyInstance() {
return $this->strategyInstance;
}
/**
* Sets the strategy this block / panel should work as. Make sure that you've used
* this method before persisting the block!
@@ -213,28 +213,29 @@ This might look like this:
.. code-block:: php
<?php
use \Doctrine\ORM,
\Doctrine\Common;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
/**
* The BlockStrategyEventListener will initialize a strategy after the
* block itself was loaded.
*/
class BlockStrategyEventListener implements Common\EventSubscriber {
class BlockStrategyEventListener implements EventSubscriber {
protected $view;
public function __construct(\Zend_View_Interface $view) {
$this->view = $view;
}
public function getSubscribedEvents() {
return array(ORM\Events::postLoad);
return array(Events::postLoad);
}
public function postLoad(ORM\Event\LifecycleEventArgs $args) {
$blockItem = $args->getEntity();
public function postLoad(LifecycleEventArgs $args) {
$blockItem = $args->getObject();
// Both blocks and panels are instances of Block\AbstractBlock
if ($blockItem instanceof Block\AbstractBlock) {
$strategy = $blockItem->getStrategyClassName();

View File

@@ -12,6 +12,7 @@ steps of configuration.
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
@@ -27,7 +28,7 @@ steps of configuration.
$config = new Configuration;
$config->setMetadataCache($metadataCache);
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
$driverImpl = ORMSetup::createDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCache($queryCache);
$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');
@@ -129,7 +130,9 @@ the ``Doctrine\ORM\Configuration``:
.. code-block:: php
<?php
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
use Doctrine\ORM\ORMSetup;
$driverImpl = ORMSetup::createDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
$config->setMetadataDriverImpl($driverImpl);
The path information to the entities is required for the annotation
@@ -454,18 +457,5 @@ Setting up the Console
----------------------
Doctrine uses the Symfony Console component for generating the command
line interface. You can take a look at the ``vendor/bin/doctrine.php``
script and the ``Doctrine\ORM\Tools\Console\ConsoleRunner`` command
for inspiration how to setup the cli.
In general the required code looks like this:
.. code-block:: php
<?php
$cli = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
Doctrine\ORM\Tools\Console\ConsoleRunner::addCommands($cli);
$cli->run();
line interface. You can take a look at the
:doc:`tools chapter <../reference/tools>` for inspiration how to setup the cli.

View File

@@ -207,6 +207,8 @@ Optional parameters:
- ``comment``: The comment of the column in the schema (might not
be supported by all vendors).
- ``charset``: The charset of the column (only supported by Mysql, PostgreSQL, Sqlite and SQLServer).
- ``collation``: The collation of the column (only supported by Mysql, PostgreSQL, Sqlite and SQLServer).
- ``check``: Adds a check constraint type to the column (might not
@@ -681,6 +683,8 @@ Optional parameters:
"columnDefinition" attribute on :ref:`#[Column] <attrref_column>` also sets
the related ``#[JoinColumn]``'s columnDefinition. This is necessary to
make foreign keys work.
- **options**:
See "options" attribute on :ref:`#[Column] <attrref_column>`.
Example:

View File

@@ -41,8 +41,8 @@ access point to ORM functionality provided by Doctrine.
// bootstrap.php
require_once "vendor/autoload.php";
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
$paths = array("/path/to/entity-files");
$isDevMode = false;
@@ -55,16 +55,21 @@ access point to ORM functionality provided by Doctrine.
'dbname' => 'foo',
);
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$config = ORMSetup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$entityManager = EntityManager::create($dbParams, $config);
.. note::
The ``ORMSetup`` class has been introduced with ORM 2.12. It's predecessor ``Setup`` is deprecated and will
be removed in version 3.0.
Or if you prefer XML:
.. code-block:: php
<?php
$paths = array("/path/to/xml-mappings");
$config = Setup::createXMLMetadataConfiguration($paths, $isDevMode);
$config = ORMSetup::createXMLMetadataConfiguration($paths, $isDevMode);
$entityManager = EntityManager::create($dbParams, $config);
Or if you prefer YAML:
@@ -73,7 +78,7 @@ Or if you prefer YAML:
<?php
$paths = array("/path/to/yml-mappings");
$config = Setup::createYAMLMetadataConfiguration($paths, $isDevMode);
$config = ORMSetup::createYAMLMetadataConfiguration($paths, $isDevMode);
$entityManager = EntityManager::create($dbParams, $config);
.. note::
@@ -83,13 +88,18 @@ Or if you prefer YAML:
"symfony/yaml": "*"
Inside the ``Setup`` methods several assumptions are made:
Inside the ``ORMSetup`` 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 true caching is done in memory with the ``ArrayAdapter``. Proxy objects are recreated on every request.
- If ``$isDevMode`` is false, check for Caches in the order APCu, Redis (127.0.0.1:6379), Memcache (127.0.0.1:11211) 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.
.. note::
In order to have ``ORMSetup`` configure the cache automatically, the library ``symfony/cache``
has to be installed as a dependency.
If you want to configure Doctrine in more detail, take a look at the :doc:`Advanced Configuration <reference/advanced-configuration>` section.
.. note::
@@ -101,26 +111,6 @@ Setting up the Commandline Tool
-------------------------------
Doctrine ships with a number of command line tools that are very helpful
during development. You can call this command from the Composer binary
directory:
.. code-block:: sh
$ php vendor/bin/doctrine
You need to register your applications EntityManager to the console tool
to make use of the tasks by creating a ``cli-config.php`` file with the
following content:
.. code-block:: php
<?php
use Doctrine\ORM\Tools\Console\ConsoleRunner;
// replace with file to your own project bootstrap
require_once 'bootstrap.php';
// replace with mechanism to retrieve EntityManager in your app
$entityManager = GetEntityManager();
return ConsoleRunner::createHelperSet($entityManager);
during development. In order to make use of them, create an executable PHP
script in your project as described in the
:doc:`tools chapter <../reference/tools>`.

View File

@@ -79,7 +79,9 @@ array of events it should be subscribed to.
.. code-block:: php
<?php
class TestEventSubscriber implements \Doctrine\Common\EventSubscriber
use Doctrine\Common\EventSubscriber;
class TestEventSubscriber implements EventSubscriber
{
public $preFooInvoked = false;
@@ -211,9 +213,8 @@ specific to a particular entity class's lifecycle.
.. code-block:: attribute
<?php
use Doctrine\DBAL\Types\Types;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\LifecycleEventArgs;
#[Entity]
#[HasLifecycleCallbacks]
@@ -245,7 +246,6 @@ specific to a particular entity class's lifecycle.
.. code-block:: annotation
<?php
use Doctrine\Persistence\Event\LifecycleEventArgs;
/**
@@ -504,7 +504,6 @@ result in an infinite loop.
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreFlushEventArgs;
class PreFlushExampleListener
@@ -542,7 +541,7 @@ mentioned sets. See this example:
{
public function onFlush(OnFlushEventArgs $eventArgs)
{
$em = $eventArgs->getEntityManager();
$em = $eventArgs->getObjectManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityInsertions() as $entity) {
@@ -590,7 +589,6 @@ This event is not a lifecycle callback.
.. code-block:: php
<?php
use Doctrine\ORM\Event\PostFlushEventArgs;
class PostFlushExampleListener
@@ -615,7 +613,7 @@ Changes to associations of the updated entity are never allowed in
this event, since Doctrine cannot guarantee to correctly handle
referential integrity at this point of the flush operation. This
event has a powerful feature however, it is executed with a
`_PreUpdateEventArgs`_ instance, which contains a reference to the
`PreUpdateEventArgs`_ instance, which contains a reference to the
computed change-set of this entity.
This means you have access to all the fields that have changed for
@@ -637,6 +635,8 @@ A simple example for this event looks like:
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreUpdateEventArgs;
class NeverAliceOnlyBobListener
{
public function preUpdate(PreUpdateEventArgs $eventArgs)
@@ -644,6 +644,9 @@ A simple example for this event looks like:
if ($eventArgs->getEntity() instanceof User) {
if ($eventArgs->hasChangedField('name') && $eventArgs->getNewValue('name') == 'Alice') {
$eventArgs->setNewValue('name', 'Bob');
// The following will only work if `status` is already present in the computed changeset.
// Otherwise it will throw an InvalidArgumentException:
$eventArgs->setNewValue('status', 'active');
}
}
}
@@ -656,6 +659,8 @@ lifecycle callback when there are expensive validations to call:
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreUpdateEventArgs;
class ValidCreditCardListener
{
public function preUpdate(PreUpdateEventArgs $eventArgs)
@@ -751,7 +756,7 @@ An entity listener is a lifecycle listener class used for an entity.
.. configuration-block::
.. code-block:: attribute
<?php
namespace MyProject\Entity;
use App\EventListener\UserListener;
@@ -807,6 +812,8 @@ An ``Entity Listener`` could be any class, by default it should be a class with
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreUpdateEventArgs;
class UserListener
{
public function preUpdate(User $user, PreUpdateEventArgs $event)
@@ -823,6 +830,10 @@ you need to map the listener method using the event type mapping:
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\Persistence\Event\LifecycleEventArgs;
class UserListener
{
/** @PrePersist */
@@ -907,6 +918,8 @@ Specifying an entity listener instance :
.. code-block:: php
<?php
use Doctrine\ORM\Event\PreUpdateEventArgs;
// User.php
/** @Entity @EntityListeners({"UserListener"}) */
@@ -933,12 +946,14 @@ Specifying an entity listener instance :
$listener = $container->get('user_listener');
$em->getConfiguration()->getEntityListenerResolver()->register($listener);
Implementing your own resolver :
Implementing your own resolver:
.. code-block:: php
<?php
class MyEntityListenerResolver extends \Doctrine\ORM\Mapping\DefaultEntityListenerResolver
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
class MyEntityListenerResolver extends DefaultEntityListenerResolver
{
public function __construct($container)
{
@@ -972,13 +987,15 @@ This event is not a lifecycle callback.
.. code-block:: php
<?php
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(Doctrine\ORM\Events::loadClassMetadata, $test);
class TestEventListener
{
public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs)
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
$fieldMapping = array(
@@ -1011,13 +1028,16 @@ instance and class metadata.
.. code-block:: php
<?php
use Doctrine\ORM\Tools\ToolEvents;
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(\Doctrine\ORM\Tools\ToolEvents::postGenerateSchemaTable, $test);
$evm->addEventListener(ToolEvents::postGenerateSchemaTable, $test);
class TestEventListener
{
public function postGenerateSchemaTable(\Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs $eventArgs)
public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
$schema = $eventArgs->getSchema();
@@ -1035,13 +1055,16 @@ and the EntityManager.
.. code-block:: php
<?php
use Doctrine\ORM\Tools\ToolEvents;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(\Doctrine\ORM\Tools\ToolEvents::postGenerateSchema, $test);
$evm->addEventListener(ToolEvents::postGenerateSchema, $test);
class TestEventListener
{
public function postGenerateSchema(\Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs $eventArgs)
public function postGenerateSchema(GenerateSchemaEventArgs $eventArgs)
{
$schema = $eventArgs->getSchema();
$em = $eventArgs->getEntityManager();

View File

@@ -178,9 +178,9 @@ relationships involving types that employ this mapping strategy are
very performing.
There is a general performance consideration with Single Table
Inheritance: If the target-entity of a many-to-one or one-to-one
association is an STI entity, it is preferable for performance reasons that it
be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
Inheritance: If the target-entity of a many-to-one or one-to-one
association is an STI entity, it is preferable for performance reasons that it
be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
Otherwise Doctrine *CANNOT* create proxy instances
of this entity and will *ALWAYS* load the entity eagerly.
@@ -284,9 +284,9 @@ themselves on access of any subtype fields, so accessing fields of
subtypes after such a query is not safe.
There is a general performance consideration with Class Table
Inheritance: If the target-entity of a many-to-one or one-to-one
association is a CTI entity, it is preferable for performance reasons that it
be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
Inheritance: If the target-entity of a many-to-one or one-to-one
association is a CTI entity, it is preferable for performance reasons that it
be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
Otherwise Doctrine *CANNOT* create proxy instances
of this entity and will *ALWAYS* load the entity eagerly.

View File

@@ -55,51 +55,66 @@ Implementing Metadata Drivers
In addition to the included metadata drivers you can very easily
implement your own. All you need to do is define a class which
implements the ``Driver`` interface:
implements the ``MappingDriver`` interface:
.. code-block:: php
<?php
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
interface Driver
declare(strict_types=1);
namespace Doctrine\Persistence\Mapping\Driver;
use Doctrine\Persistence\Mapping\ClassMetadata;
/**
* Contract for metadata drivers.
*/
interface MappingDriver
{
/**
* Loads the metadata for the specified class into the provided container.
*
* @param string $className
* @param ClassMetadataInfo $metadata
*
* @psalm-param class-string<T> $className
* @psalm-param ClassMetadata<T> $metadata
*
* @return void
*
* @template T of object
*/
function loadMetadataForClass($className, ClassMetadataInfo $metadata);
public function loadMetadataForClass(string $className, ClassMetadata $metadata);
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array The names of all mapped classes known to this driver.
*/
function getAllClassNames();
/**
* Whether the class with the specified name should have its metadata loaded.
* This is only the case if it is either mapped as an Entity or a
* MappedSuperclass.
*
* @param string $className
* @return boolean
* @return array<int, string> The names of all mapped classes known to this driver.
* @psalm-return list<class-string>
*/
function isTransient($className);
public function getAllClassNames();
/**
* Returns whether the class with the specified name should have its metadata loaded.
* This is only the case if it is either mapped as an Entity or a MappedSuperclass.
*
* @psalm-param class-string $className
*
* @return bool
*/
public function isTransient(string $className);
}
If you want to write a metadata driver to parse information from
some file format we've made your life a little easier by providing
the ``AbstractFileDriver`` implementation for you to extend from:
the ``FileDriver`` implementation for you to extend from:
.. code-block:: php
<?php
class MyMetadataDriver extends AbstractFileDriver
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\FileDriver;
class MyMetadataDriver extends FileDriver
{
/**
* {@inheritdoc}
@@ -109,11 +124,11 @@ the ``AbstractFileDriver`` implementation for you to extend from:
/**
* {@inheritdoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
$data = $this->_loadMappingFile($file);
// populate ClassMetadataInfo instance from $data
// populate ClassMetadata instance from $data
}
/**
@@ -127,13 +142,12 @@ the ``AbstractFileDriver`` implementation for you to extend from:
.. note::
When using the ``AbstractFileDriver`` it requires that you
only have one entity defined per file and the file named after the
class described inside where namespace separators are replaced by
periods. So if you have an entity named ``Entities\User`` and you
wanted to write a mapping file for your driver above you would need
to name the file ``Entities.User.dcm.ext`` for it to be
recognized.
When using the ``FileDriver`` it requires that you only have one
entity defined per file and the file named after the class described
inside where namespace separators are replaced by periods. So if you
have an entity named ``Entities\User`` and you wanted to write a
mapping file for your driver above you would need to name the file
``Entities.User.dcm.ext`` for it to be recognized.
Now you can use your ``MyMetadataDriver`` implementation by setting
@@ -156,14 +170,6 @@ entity when needed.
You have all the methods you need to manually specify the mapping
information instead of using some mapping file to populate it from.
The base ``ClassMetadataInfo`` class is responsible for only data
storage and is not meant for runtime use. It does not require that
the class actually exists yet so it is useful for describing some
entity before it exists and using that information to generate for
example the entities themselves. The class ``ClassMetadata``
extends ``ClassMetadataInfo`` and adds some functionality required
for runtime usage and requires that the PHP class is present and
can be autoloaded.
You can read more about the API of the ``ClassMetadata`` classes in
the PHP Mapping chapter.

View File

@@ -96,6 +96,8 @@ For this you just need to use the ``StaticPHPDriver``:
.. code-block:: php
<?php
use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver;
$driver = new StaticPHPDriver('/path/to/entities');
$em->getConfiguration()->setMetadataDriverImpl($driver);
@@ -185,13 +187,12 @@ It also has several methods that create builders (which are necessary for advanc
- ``createManyToMany($name, $targetEntity)`` returns an ``ManyToManyAssociationBuilder`` instance
- ``createOneToMany($name, $targetEntity)`` returns an ``OneToManyAssociationBuilder`` instance
ClassMetadataInfo API
---------------------
ClassMetadata API
-----------------
The ``ClassMetadataInfo`` class is the base data object for storing
the mapping metadata for a single entity. It contains all the
getters and setters you need populate and retrieve information for
an entity.
The ``ClassMetadata`` class is the data object for storing the mapping
metadata for a single entity. It contains all the getters and setters
you need populate and retrieve information for an entity.
General Setters
~~~~~~~~~~~~~~~
@@ -309,13 +310,11 @@ Lifecycle Callback Getters
- ``hasLifecycleCallbacks($lifecycleEvent)``
- ``getLifecycleCallbacks($event)``
ClassMetadata API
-----------------
Runtime reflection methods
~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``ClassMetadata`` class extends ``ClassMetadataInfo`` and adds
the runtime functionality required by Doctrine. It adds a few extra
methods related to runtime reflection for working with the entities
themselves.
These are methods related to runtime reflection for working with the
entities themselves.
- ``getReflectionClass()``

View File

@@ -268,7 +268,7 @@ Doctrine\DBAL\ParameterType::* or a DBAL Type name for conversion.
use Doctrine\DBAL\Types\Types;
// prevents attempt to load metadata for date time class, improving performance
$qb->setParameter('date', new \DateTimeImmutable(), Types::DATE_IMMUTABLE)
$qb->setParameter('date', new \DateTimeImmutable(), Types::DATETIME_IMMUTABLE)
If you've got several parameters to bind to your query, you can
also use setParameters() instead of setParameter() with the

View File

@@ -7,24 +7,10 @@ Doctrine Console
The Doctrine Console is a Command Line Interface tool for simplifying common
administration tasks during the development of a project that uses ORM.
Take a look at the :doc:`Installation and Configuration <configuration>`
chapter for more information how to setup the console command.
For the following examples, we will set up the CLI as ``bin/doctrine``.
Display Help Information
~~~~~~~~~~~~~~~~~~~~~~~~
Type ``php vendor/bin/doctrine`` on the command line and you should see an
overview of the available commands or use the --help flag to get
information on the available commands. If you want to know more
about the use of generate entities for example, you can call:
.. code-block:: php
$> php vendor/bin/doctrine orm:generate-entities --help
Configuration
~~~~~~~~~~~~~
Setting Up the Console
~~~~~~~~~~~~~~~~~~~~~~
Whenever the ``doctrine`` command line tool is invoked, it can
access all Commands that were registered by a developer. There is no
@@ -34,25 +20,33 @@ Doctrine DBAL and ORM. If you want to use additional commands you
have to register them yourself.
All the commands of the Doctrine Console require access to the
``EntityManager``. You have to inject it into the console application with
``ConsoleRunner::createHelperSet``. Whenever you invoke the Doctrine
binary, it searches the current directory for the file ``cli-config.php``.
This file contains the project-specific configuration.
``EntityManager``. You have to inject it into the console application.
Here is an example of a the project-specific ``cli-config.php``:
Here is an example of a the project-specific ``bin/doctrine`` binary.
.. code-block:: php
#!/usr/bin/env php
<?php
use Doctrine\ORM\Tools\Console\ConsoleRunner;
// replace this with the path to your own project bootstrap file.
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
// replace with path to your own project bootstrap file
require_once 'bootstrap.php';
// replace with mechanism to retrieve EntityManager in your app
$entityManager = GetEntityManager();
return ConsoleRunner::createHelperSet($entityManager);
$commands = [
// If you want to add your own custom console commands,
// you can do so here.
];
ConsoleRunner::run(
new SingleManagerProvider($entityManager),
$commands
);
.. note::
@@ -60,6 +54,18 @@ Here is an example of a the project-specific ``cli-config.php``:
and use their facilities to access the Doctrine EntityManager and
Connection Resources.
Display Help Information
~~~~~~~~~~~~~~~~~~~~~~~~
Type ``php bin/doctrine`` on the command line and you should see an
overview of the available commands or use the ``--help`` flag to get
information on the available commands. If you want to know more
about the use of generate entities for example, you can call:
::
$> php bin/doctrine orm:generate-entities --help
Command Overview
~~~~~~~~~~~~~~~~
@@ -143,7 +149,7 @@ When using the SchemaTool class directly, create your schema using
the ``createSchema()`` method. First create an instance of the
``SchemaTool`` and pass it an instance of the ``EntityManager``
that you want to use to create the schema. This method receives an
array of ``ClassMetadataInfo`` instances.
array of ``ClassMetadata`` instances.
.. code-block:: php
@@ -174,8 +180,8 @@ tables of the current model to clean up with orphaned tables.
You can also use database introspection to update your schema
easily with the ``updateSchema()`` method. It will compare your
existing database schema to the passed array of
``ClassMetadataInfo`` instances.
existing database schema to the passed array of ``ClassMetadata``
instances.
.. code-block:: php
@@ -189,38 +195,35 @@ To create the schema use the ``create`` command:
.. code-block:: php
$ php doctrine orm:schema-tool:create
$ php bin/doctrine orm:schema-tool:create
To drop the schema use the ``drop`` command:
.. code-block:: php
$ php doctrine orm:schema-tool:drop
$ php bin/doctrine orm:schema-tool:drop
If you want to drop and then recreate the schema then use both
options:
.. code-block:: php
$ php doctrine orm:schema-tool:drop
$ php doctrine orm:schema-tool:create
$ php bin/doctrine orm:schema-tool:drop
$ php bin/doctrine orm:schema-tool:create
As you would think, if you want to update your schema use the
``update`` command:
.. code-block:: php
$ php doctrine orm:schema-tool:update
$ php bin/doctrine orm:schema-tool:update
All of the above commands also accept a ``--dump-sql`` option that
will output the SQL for the ran operation.
.. code-block:: php
$ php doctrine orm:schema-tool:create --dump-sql
Before using the orm:schema-tool commands, remember to configure
your cli-config.php properly.
$ php bin/doctrine orm:schema-tool:create --dump-sql
Entity Generation
-----------------
@@ -229,9 +232,9 @@ Generate entity classes and method stubs from your mapping information.
.. code-block:: php
$ php doctrine orm:generate-entities
$ php doctrine orm:generate-entities --update-entities
$ php doctrine orm:generate-entities --regenerate-entities
$ php bin/doctrine orm:generate-entities
$ php bin/doctrine orm:generate-entities --update-entities
$ php bin/doctrine orm:generate-entities --regenerate-entities
This command is not suited for constant usage. It is a little helper and does
not support all the mapping edge cases very well. You still have to put work
@@ -316,14 +319,14 @@ convert to and the path to generate it:
.. code-block:: php
$ php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
$ php bin/doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
Reverse Engineering
-------------------
You can use the ``DatabaseDriver`` to reverse engineer a database
to an array of ``ClassMetadataInfo`` instances and generate YAML,
XML, etc. from them.
You can use the ``DatabaseDriver`` to reverse engineer a database to an
array of ``ClassMetadata`` instances and generate YAML, XML, etc. from
them.
.. note::
@@ -366,7 +369,7 @@ You can also reverse engineer a database using the
.. code-block:: php
$ php doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml
$ php bin/doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml
.. note::
@@ -393,6 +396,11 @@ You can either use the Doctrine Command Line Tool:
doctrine orm:validate-schema
If the validation fails, you can change the verbosity level to
check the detected errors:
doctrine orm:validate-schema -v
Or you can trigger the validation manually:
.. code-block:: php

View File

@@ -37,7 +37,7 @@ information about its type and if it's the owning or inverse side.
{
/** @Id @GeneratedValue @Column(type="string") */
private $id;
/**
* Bidirectional - Many users have Many favorite comments (OWNING SIDE)
*
@@ -45,7 +45,7 @@ information about its type and if it's the owning or inverse side.
* @JoinTable(name="user_favorite_comments")
*/
private $favorites;
/**
* Unidirectional - Many users have marked many comments as read
*
@@ -53,14 +53,14 @@ information about its type and if it's the owning or inverse side.
* @JoinTable(name="user_read_comments")
*/
private $commentsRead;
/**
* Bidirectional - One-To-Many (INVERSE SIDE)
*
* @OneToMany(targetEntity="Comment", mappedBy="author")
*/
private $commentsAuthored;
/**
* Unidirectional - Many-To-One
*
@@ -68,20 +68,20 @@ information about its type and if it's the owning or inverse side.
*/
private $firstComment;
}
/** @Entity */
class Comment
{
/** @Id @GeneratedValue @Column(type="string") */
private $id;
/**
* Bidirectional - Many comments are favorited by many users (INVERSE SIDE)
*
* @ManyToMany(targetEntity="User", mappedBy="favorites")
*/
private $userFavorites;
/**
* Bidirectional - Many Comments are authored by one user (OWNING SIDE)
*
@@ -100,19 +100,19 @@ definitions omitted):
firstComment_id VARCHAR(255) DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Comment (
id VARCHAR(255) NOT NULL,
author_id VARCHAR(255) DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE user_favorite_comments (
user_id VARCHAR(255) NOT NULL,
favorite_comment_id VARCHAR(255) NOT NULL,
PRIMARY KEY(user_id, favorite_comment_id)
) ENGINE = InnoDB;
CREATE TABLE user_read_comments (
user_id VARCHAR(255) NOT NULL,
comment_id VARCHAR(255) NOT NULL,
@@ -135,7 +135,7 @@ relations of the ``User``:
public function getReadComments() {
return $this->commentsRead;
}
public function setFirstComment(Comment $c) {
$this->firstComment = $c;
}
@@ -148,17 +148,17 @@ The interaction code would then look like in the following snippet
<?php
$user = $em->find('User', $userId);
// unidirectional many to many
$comment = $em->find('Comment', $readCommentId);
$user->getReadComments()->add($comment);
$em->flush();
// unidirectional many to one
$myFirstComment = new Comment();
$user->setFirstComment($myFirstComment);
$em->persist($myFirstComment);
$em->flush();
@@ -171,40 +171,40 @@ fields on both sides:
class User
{
// ..
public function getAuthoredComments() {
return $this->commentsAuthored;
}
public function getFavoriteComments() {
return $this->favorites;
}
}
class Comment
{
// ...
public function getUserFavorites() {
return $this->userFavorites;
}
public function setAuthor(User $author = null) {
$this->author = $author;
}
}
// Many-to-Many
$user->getFavorites()->add($favoriteComment);
$favoriteComment->getUserFavorites()->add($user);
$em->flush();
// Many-To-One / One-To-Many Bidirectional
$newComment = new Comment();
$user->getAuthoredComments()->add($newComment);
$newComment->setAuthor($user);
$em->persist($newComment);
$em->flush();
@@ -225,10 +225,10 @@ element. Here are some examples:
// Remove by Elements
$user->getComments()->removeElement($comment);
$comment->setAuthor(null);
$user->getFavorites()->removeElement($comment);
$comment->getUserFavorites()->removeElement($user);
// Remove by Key
$user->getComments()->remove($ithComment);
$comment->setAuthor(null);
@@ -240,7 +240,7 @@ Notice how both sides of the bidirectional association are always
updated. Unidirectional associations are consequently simpler to
handle.
Also note that if you use type-hinting in your methods, you will
Also note that if you use type-hinting in your methods, you will
have to specify a nullable type, i.e. ``setAddress(?Address $address)``,
otherwise ``setAddress(null)`` will fail to remove the association.
Another way to deal with this is to provide a special method, like
@@ -271,8 +271,8 @@ entities that have been re-added to the collection.
Say you clear a collection of tags by calling
``$post->getTags()->clear();`` and then call
``$post->getTags()->add($tag)``. This will not recognize the tag having
already been added previously and will consequently issue two separate database
``$post->getTags()->add($tag)``. This will not recognize the tag having
already been added previously and will consequently issue two separate database
calls.
Association Management Methods
@@ -296,7 +296,7 @@ example that encapsulate much of the association management code:
// Collections implement ArrayAccess
$this->commentsRead[] = $comment;
}
public function addComment(Comment $comment) {
if (count($this->commentsAuthored) == 0) {
$this->setFirstComment($comment);
@@ -304,30 +304,30 @@ example that encapsulate much of the association management code:
$this->comments[] = $comment;
$comment->setAuthor($this);
}
private function setFirstComment(Comment $c) {
$this->firstComment = $c;
}
public function addFavorite(Comment $comment) {
$this->favorites->add($comment);
$comment->addUserFavorite($this);
}
public function removeFavorite(Comment $comment) {
$this->favorites->removeElement($comment);
$comment->removeUserFavorite($this);
}
}
class Comment
{
// ..
public function addUserFavorite(User $user) {
$this->userFavorites[] = $user;
}
public function removeUserFavorite(User $user) {
$this->userFavorites->removeElement($user);
}
@@ -373,7 +373,7 @@ as your preferences.
Synchronizing Bidirectional Collections
---------------------------------------
In the case of Many-To-Many associations you as the developer have the
In the case of Many-To-Many associations you as the developer have the
responsibility of keeping the collections on the owning and inverse side
in sync when you apply changes to them. Doctrine can only
guarantee a consistent state for the hydration, not for your client
@@ -387,7 +387,7 @@ can show the possible caveats you can encounter:
<?php
$user->getFavorites()->add($favoriteComment);
// not calling $favoriteComment->getUserFavorites()->add($user);
$user->getFavorites()->contains($favoriteComment); // TRUE
$favoriteComment->getUserFavorites()->contains($user); // FALSE
@@ -422,7 +422,7 @@ comment might look like in your controller (without ``cascade: persist``):
$user = new User();
$myFirstComment = new Comment();
$user->addComment($myFirstComment);
$em->persist($user);
$em->persist($myFirstComment); // required, if `cascade: persist` is not set
$em->flush();
@@ -480,7 +480,7 @@ If you then set up the cascading to the ``User#commentsAuthored`` property...
<?php
$user = new User();
$user->comment('Lorem ipsum', new DateTime());
$em->persist($user);
$em->flush();
@@ -559,6 +559,13 @@ OrphanRemoval works with one-to-one, one-to-many and many-to-many associations.
If you neglect this assumption your entities will get deleted by Doctrine even if
you assigned the orphaned entity to another one.
.. note::
``orphanRemoval=true`` option should be used in combination with ``cascade=["persist"]`` option
as the child entity, that is manually persisted, will not be deleted automatically by Doctrine
when a collection is still an instance of ArrayCollection (before first flush / hydration).
This is a Doctrine limitation since ArrayCollection does not have access to a UnitOfWork.
As a better example consider an Addressbook application where you have Contacts, Addresses
and StandingData:
@@ -578,10 +585,10 @@ and StandingData:
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @OneToOne(targetEntity="StandingData", orphanRemoval=true) */
/** @OneToOne(targetEntity="StandingData", cascade={"persist"}, orphanRemoval=true) */
private $standingData;
/** @OneToMany(targetEntity="Address", mappedBy="contact", orphanRemoval=true) */
/** @OneToMany(targetEntity="Address", mappedBy="contact", cascade={"persist"}, orphanRemoval=true) */
private $addresses;
public function __construct()
@@ -612,10 +619,10 @@ Now two examples of what happens when you remove the references:
$em->flush();
In this case you have not only changed the ``Contact`` entity itself but
you have also removed the references for standing data and as well as one
address reference. When flush is called not only are the references removed
but both the old standing data and the one address entity are also deleted
In this case you have not only changed the ``Contact`` entity itself but
you have also removed the references for standing data and as well as one
address reference. When flush is called not only are the references removed
but both the old standing data and the one address entity are also deleted
from the database.
.. _filtering-collections:

View File

@@ -137,8 +137,8 @@ step:
<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
require_once "vendor/autoload.php";
@@ -147,10 +147,10 @@ step:
$proxyDir = null;
$cache = null;
$useSimpleAnnotationReader = false;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, $proxyDir, $cache, $useSimpleAnnotationReader);
// or if you prefer yaml or XML
// $config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
// $config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
$config = ORMSetup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, $proxyDir, $cache, $useSimpleAnnotationReader);
// or if you prefer YAML or XML
// $config = ORMSetup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
// $config = ORMSetup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
// database configuration parameters
$conn = array(
@@ -173,7 +173,7 @@ The ``require_once`` statement sets up the class autoloading for Doctrine and
its dependencies using Composer's autoloader.
The second block consists of the instantiation of the ORM
``Configuration`` object using the Setup helper. It assumes a bunch
``Configuration`` object using the ``ORMSetup`` helper. It assumes a bunch
of defaults that you don't have to bother about for now. You can
read up on the configuration details in the
:doc:`reference chapter on configuration <../reference/configuration>`.
@@ -191,22 +191,35 @@ Generating the Database Schema
Doctrine has a command-line interface that allows you to access the SchemaTool,
a component that can generate a relational database schema based entirely on the
defined entity classes and their metadata. For this tool to work, a
``cli-config.php`` file must exist in the project root directory:
defined entity classes and their metadata. For this tool to work, you need to
create an executable console script as described in the
:doc:`tools chapter <../reference/tools>`.
If you created the ``bootstrap.php`` file as described in the previous section,
that script could look like this:
.. code-block:: php
#!/usr/bin/env php
<?php
// cli-config.php
require_once "bootstrap.php";
// bin/doctrine
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
Now call the Doctrine command-line tool:
// Adjust this path to your actual bootstrap.php
require __DIR__ . 'path/to/your/bootstrap.php';
ConsoleRunner::run(
new SingleManagerProvider($entityManager)
);
In the following examples, we will assume that this script has been created as
``bin/doctrine``.
::
$ vendor/bin/doctrine orm:schema-tool:create
$ php bin/doctrine orm:schema-tool:create
Since we haven't added any entity metadata in ``src`` yet, you'll see a message
stating "No Metadata Classes to process." In the next section, we'll create a
@@ -218,14 +231,14 @@ You can easily recreate the database using the following commands:
::
$ vendor/bin/doctrine orm:schema-tool:drop --force
$ vendor/bin/doctrine orm:schema-tool:create
$ php bin/doctrine orm:schema-tool:drop --force
$ php bin/doctrine orm:schema-tool:create
Or you can use the update functionality:
::
$ vendor/bin/doctrine orm:schema-tool:update --force
$ php bin/doctrine orm:schema-tool:update --force
The updating of databases uses a diff algorithm for a given
database schema. This is a cornerstone of the ``Doctrine\DBAL`` package,
@@ -571,7 +584,7 @@ let's update the database schema:
::
$ vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
$ php bin/doctrine orm:schema-tool:update --force --dump-sql
Specifying both flags ``--force`` and ``--dump-sql`` will cause the DDL
statements to be executed and then printed to the screen.
@@ -1268,7 +1281,7 @@ class that holds the owning sides.
Update your database schema by running:
::
$ vendor/bin/doctrine orm:schema-tool:update --force
$ php bin/doctrine orm:schema-tool:update --force
Implementing more Requirements

View File

@@ -4,11 +4,13 @@ declare(strict_types=1);
namespace Doctrine\ORM;
use BackedEnum;
use Countable;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Result;
use Doctrine\Deprecations\Deprecation;
@@ -30,10 +32,13 @@ use function array_map;
use function array_shift;
use function assert;
use function count;
use function func_num_args;
use function in_array;
use function is_array;
use function is_numeric;
use function is_object;
use function is_scalar;
use function is_string;
use function iterator_count;
use function iterator_to_array;
use function ksort;
@@ -193,9 +198,7 @@ abstract class AbstractQuery
return $this;
}
/**
* @return bool TRUE if the query results are enable for second level cache, FALSE otherwise.
*/
/** @return bool TRUE if the query results are enabled for second level cache, FALSE otherwise. */
public function isCacheable()
{
return $this->cacheable;
@@ -223,17 +226,13 @@ abstract class AbstractQuery
return $this->cacheRegion;
}
/**
* @return bool TRUE if the query cache and second level cache are enabled, FALSE otherwise.
*/
/** @return bool TRUE if the query cache and second level cache are enabled, FALSE otherwise. */
protected function isCacheEnabled()
{
return $this->cacheable && $this->hasCache;
}
/**
* @return int
*/
/** @return int */
public function getLifetime()
{
return $this->lifetime;
@@ -280,7 +279,7 @@ abstract class AbstractQuery
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
*
* @return string SQL query
* @return list<string>|string SQL query
*/
abstract public function getSQL();
@@ -322,7 +321,7 @@ abstract class AbstractQuery
/**
* Gets a query parameter.
*
* @param mixed $key The key (index or name) of the bound parameter.
* @param int|string $key The key (index or name) of the bound parameter.
*
* @return Parameter|null The value of the bound parameter, or NULL if not available.
*/
@@ -351,7 +350,6 @@ abstract class AbstractQuery
*/
public function setParameters($parameters)
{
// BC compatibility with 2.3-
if (is_array($parameters)) {
/** @psalm-var ArrayCollection<int, Parameter> $parameterCollection */
$parameterCollection = new ArrayCollection();
@@ -399,8 +397,7 @@ abstract class AbstractQuery
*
* @param mixed $value
*
* @return mixed[]|string|int|float|bool
* @psalm-return array|scalar
* @return mixed
*
* @throws ORMInvalidArgumentException
*/
@@ -424,15 +421,20 @@ abstract class AbstractQuery
return $value->name;
}
if ($value instanceof BackedEnum) {
return $value->value;
}
if (! is_object($value)) {
return $value;
}
try {
$class = ClassUtils::getClass($value);
$value = $this->_em->getUnitOfWork()->getSingleIdentifierValue($value);
if ($value === null) {
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity($class);
}
} catch (MappingException | ORMMappingException $e) {
/* Silence any mapping exceptions. These can occur if the object in
@@ -540,6 +542,15 @@ abstract class AbstractQuery
public function setHydrationCacheProfile(?QueryCacheProfile $profile = null)
{
if ($profile === null) {
if (func_num_args() < 1) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9791',
'Calling %s without arguments is deprecated, pass null instead.',
__METHOD__
);
}
$this->_hydrationCacheProfile = null;
return $this;
@@ -565,9 +576,7 @@ abstract class AbstractQuery
return $this;
}
/**
* @return QueryCacheProfile|null
*/
/** @return QueryCacheProfile|null */
public function getHydrationCacheProfile()
{
return $this->_hydrationCacheProfile;
@@ -584,6 +593,15 @@ abstract class AbstractQuery
public function setResultCacheProfile(?QueryCacheProfile $profile = null)
{
if ($profile === null) {
if (func_num_args() < 1) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9791',
'Calling %s without arguments is deprecated, pass null instead.',
__METHOD__
);
}
$this->_queryCacheProfile = null;
return $this;
@@ -638,6 +656,15 @@ abstract class AbstractQuery
public function setResultCache(?CacheItemPoolInterface $resultCache = null)
{
if ($resultCache === null) {
if (func_num_args() < 1) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9791',
'Calling %s without arguments is deprecated, pass null instead.',
__METHOD__
);
}
if ($this->_queryCacheProfile) {
$this->_queryCacheProfile = new QueryCacheProfile($this->_queryCacheProfile->getLifetime(), $this->_queryCacheProfile->getCacheKey());
}
@@ -799,9 +826,7 @@ abstract class AbstractQuery
return $this->_expireResultCache;
}
/**
* @return QueryCacheProfile|null
*/
/** @return QueryCacheProfile|null */
public function getQueryCacheProfile()
{
return $this->_queryCacheProfile;
@@ -810,17 +835,22 @@ abstract class AbstractQuery
/**
* Change the default fetch mode of an association for this query.
*
* $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
*
* @param string $class
* @param string $assocName
* @param int $fetchMode
* @param class-string $class
* @param string $assocName
* @param int $fetchMode
* @psalm-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
*
* @return $this
*/
public function setFetchMode($class, $assocName, $fetchMode)
{
if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
if (! in_array($fetchMode, [Mapping\ClassMetadata::FETCH_EAGER, Mapping\ClassMetadata::FETCH_LAZY], true)) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9777',
'Calling %s() with something else than ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY is deprecated.',
__METHOD__
);
$fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
}
@@ -1295,7 +1325,8 @@ abstract class AbstractQuery
$parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
}
$sql = $this->getSQL();
$sql = $this->getSQL();
assert(is_string($sql));
$queryCacheProfile = $this->getHydrationCacheProfile();
$hints = $this->getHints();
$hints['hydrationMode'] = $this->getHydrationMode();
@@ -1367,7 +1398,8 @@ abstract class AbstractQuery
*/
protected function getHash()
{
$query = $this->getSQL();
$query = $this->getSQL();
assert(is_string($query));
$hints = $this->getHints();
$params = array_map(function (Parameter $parameter) {
$value = $parameter->getValue();

View File

@@ -141,6 +141,8 @@ interface Cache
* Evicts all cached query results under the given name, or default query cache if the region name is NULL.
*
* @param string|null $regionName The cache name associated to the queries being cached.
*
* @return void
*/
public function evictQueryRegion($regionName = null);

View File

@@ -10,20 +10,26 @@ namespace Doctrine\ORM\Cache;
class AssociationCacheEntry implements CacheEntry
{
/**
* The entity identifier
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string, mixed> The entity identifier
* @var array<string, mixed>
*/
public $identifier;
/**
* The entity class name
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The entity class name
* @var string
* @psalm-var class-string
*/
public $class;
/**
* @param string $class The entity class.
* @param array<string, mixed> $identifier The entity identifier.
* @psalm-param class-string $class
*/
public function __construct($class, array $identifier)
{

View File

@@ -23,41 +23,31 @@ class CacheConfiguration
/** @var QueryCacheValidator|null */
private $queryValidator;
/**
* @return CacheFactory|null
*/
/** @return CacheFactory|null */
public function getCacheFactory()
{
return $this->cacheFactory;
}
/**
* @return void
*/
/** @return void */
public function setCacheFactory(CacheFactory $factory)
{
$this->cacheFactory = $factory;
}
/**
* @return CacheLogger|null
*/
/** @return CacheLogger|null */
public function getCacheLogger()
{
return $this->cacheLogger;
}
/**
* @return void
*/
/** @return void */
public function setCacheLogger(CacheLogger $logger)
{
$this->cacheLogger = $logger;
}
/**
* @return RegionsConfiguration
*/
/** @return RegionsConfiguration */
public function getRegionsConfiguration()
{
if ($this->regionsConfig === null) {
@@ -67,17 +57,13 @@ class CacheConfiguration
return $this->regionsConfig;
}
/**
* @return void
*/
/** @return void */
public function setRegionsConfiguration(RegionsConfiguration $regionsConfig)
{
$this->regionsConfig = $regionsConfig;
}
/**
* @return QueryCacheValidator
*/
/** @return QueryCacheValidator */
public function getQueryValidator()
{
if ($this->queryValidator === null) {
@@ -89,9 +75,7 @@ class CacheConfiguration
return $this->queryValidator;
}
/**
* @return void
*/
/** @return void */
public function setQueryValidator(QueryCacheValidator $validator)
{
$this->queryValidator = $validator;

View File

@@ -25,6 +25,8 @@ class CacheException extends ORMException
}
/**
* @deprecated This method is not used anymore.
*
* @param string $entityName
*
* @return CacheException
@@ -45,6 +47,8 @@ class CacheException extends ORMException
}
/**
* @deprecated This method is not used anymore.
*
* @param string $entityName
* @param string $field
*

View File

@@ -31,9 +31,7 @@ interface CacheFactory
/**
* Build a collection persister for the given relation mapping.
*
* @param EntityManagerInterface $em The entity manager.
* @param CollectionPersister $persister The collection persister that will be cached.
* @param mixed[] $mapping The association mapping.
* @param mixed[] $mapping The association mapping.
*
* @return CachedCollectionPersister
*/
@@ -42,8 +40,7 @@ interface CacheFactory
/**
* Build a query cache based on the given region name
*
* @param EntityManagerInterface $em The Entity manager.
* @param string $regionName The region name.
* @param string|null $regionName The region name.
*
* @return QueryCache The built query cache.
*/
@@ -52,9 +49,6 @@ interface CacheFactory
/**
* Build an entity hydrator
*
* @param EntityManagerInterface $em The Entity manager.
* @param ClassMetadata $metadata The entity metadata.
*
* @return EntityHydrator The built entity hydrator.
*/
public function buildEntityHydrator(EntityManagerInterface $em, ClassMetadata $metadata);
@@ -62,8 +56,7 @@ interface CacheFactory
/**
* Build a collection hydrator
*
* @param EntityManagerInterface $em The Entity manager.
* @param mixed[] $mapping The association mapping.
* @param mixed[] $mapping The association mapping.
*
* @return CollectionHydrator The built collection hydrator.
*/

View File

@@ -11,8 +11,10 @@ namespace Doctrine\ORM\Cache;
abstract class CacheKey
{
/**
* Unique identifier
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string Unique identifier
* @var string
*/
public $hash;
}

View File

@@ -10,14 +10,14 @@ namespace Doctrine\ORM\Cache;
class CollectionCacheEntry implements CacheEntry
{
/**
* The list of entity identifiers hold by the collection
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var CacheKey[] The list of entity identifiers hold by the collection
* @var CacheKey[]
*/
public $identifiers;
/**
* @param CacheKey[] $identifiers List of entity identifiers hold by the collection
*/
/** @param CacheKey[] $identifiers List of entity identifiers hold by the collection */
public function __construct(array $identifiers)
{
$this->identifiers = $identifiers;

View File

@@ -15,20 +15,27 @@ use function strtolower;
class CollectionCacheKey extends CacheKey
{
/**
* The owner entity identifier
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string, mixed> The owner entity identifier
* @var array<string, mixed>
*/
public $ownerIdentifier;
/**
* The owner entity class
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The owner entity class
* @var string
* @psalm-var class-string
*/
public $entityClass;
/**
* The association name
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The association name
* @var string
*/
public $association;
@@ -36,6 +43,7 @@ class CollectionCacheKey extends CacheKey
* @param string $entityClass The entity class.
* @param string $association The field name that represents the association.
* @param array<string, mixed> $ownerIdentifier The identifier of the owning entity.
* @psalm-param class-string $entityClass
*/
public function __construct($entityClass, $association, array $ownerIdentifier)
{

View File

@@ -14,21 +14,12 @@ use Doctrine\ORM\PersistentCollection;
interface CollectionHydrator
{
/**
* @param ClassMetadata $metadata The entity metadata.
* @param CollectionCacheKey $key The cached collection key.
* @param array|mixed[]|Collection $collection The collection.
*
* @return CollectionCacheEntry
*/
public function buildCacheEntry(ClassMetadata $metadata, CollectionCacheKey $key, $collection);
/**
* @param ClassMetadata $metadata The owning entity metadata.
* @param CollectionCacheKey $key The cached collection key.
* @param CollectionCacheEntry $entry The cached collection entry.
* @param PersistentCollection $collection The collection to load the cache into.
*
* @return mixed[]|null
*/
/** @return mixed[]|null */
public function loadCacheEntry(ClassMetadata $metadata, CollectionCacheKey $key, CollectionCacheEntry $entry, PersistentCollection $collection);
}

View File

@@ -29,7 +29,10 @@ class DefaultCache implements Cache
/** @var CacheFactory */
private $cacheFactory;
/** @var QueryCache[] */
/**
* @var QueryCache[]
* @psalm-var array<string, QueryCache>
*/
private $queryCaches = [];
/** @var QueryCache|null */
@@ -259,10 +262,7 @@ class DefaultCache implements Cache
return $this->queryCaches[$regionName];
}
/**
* @param ClassMetadata $metadata The entity metadata.
* @param mixed $identifier The entity identifier.
*/
/** @param mixed $identifier The entity identifier. */
private function buildEntityCacheKey(ClassMetadata $metadata, $identifier): EntityCacheKey
{
if (! is_array($identifier)) {
@@ -272,11 +272,7 @@ class DefaultCache implements Cache
return new EntityCacheKey($metadata->rootEntityName, $identifier);
}
/**
* @param ClassMetadata $metadata The entity metadata.
* @param string $association The field name that represents the association.
* @param mixed $ownerIdentifier The identifier of the owning entity.
*/
/** @param mixed $ownerIdentifier The identifier of the owning entity. */
private function buildCollectionCacheKey(
ClassMetadata $metadata,
string $association,
@@ -290,18 +286,20 @@ class DefaultCache implements Cache
}
/**
* @param ClassMetadata $metadata The entity metadata.
* @param mixed $identifier The entity identifier.
* @param mixed $identifier The entity identifier.
*
* @return array<string, mixed>
*/
private function toIdentifierArray(ClassMetadata $metadata, $identifier): array
{
if (is_object($identifier) && $this->em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($identifier))) {
$identifier = $this->uow->getSingleIdentifierValue($identifier);
if (is_object($identifier)) {
$class = ClassUtils::getClass($identifier);
if ($this->em->getMetadataFactory()->hasMetadataFor($class)) {
$identifier = $this->uow->getSingleIdentifierValue($identifier);
if ($identifier === null) {
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
if ($identifier === null) {
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity($class);
}
}
}

View File

@@ -49,9 +49,7 @@ class DefaultCacheFactory implements CacheFactory
/** @var string|null */
private $fileLockRegionDirectory;
/**
* @param CacheItemPoolInterface $cacheItemPool
*/
/** @param CacheItemPoolInterface $cacheItemPool */
public function __construct(RegionsConfiguration $cacheConfig, $cacheItemPool)
{
if ($cacheItemPool instanceof LegacyCache) {
@@ -89,25 +87,19 @@ class DefaultCacheFactory implements CacheFactory
$this->fileLockRegionDirectory = (string) $fileLockRegionDirectory;
}
/**
* @return string
*/
/** @return string */
public function getFileLockRegionDirectory()
{
return $this->fileLockRegionDirectory;
}
/**
* @return void
*/
/** @return void */
public function setRegion(Region $region)
{
$this->regions[$region->getName()] = $region;
}
/**
* @return void
*/
/** @return void */
public function setTimestampRegion(TimestampRegion $region)
{
$this->timestampRegion = $region;

View File

@@ -27,9 +27,7 @@ class DefaultCollectionHydrator implements CollectionHydrator
/** @var array<string,mixed> */
private static $hints = [Query::HINT_CACHE_ENABLED => true];
/**
* @param EntityManagerInterface $em The entity manager.
*/
/** @param EntityManagerInterface $em The entity manager. */
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;

View File

@@ -12,6 +12,7 @@ use Doctrine\ORM\UnitOfWork;
use Doctrine\ORM\Utility\IdentifierFlattener;
use function array_merge;
use function assert;
use function is_array;
use function is_object;
use function reset;
@@ -37,9 +38,7 @@ class DefaultEntityHydrator implements EntityHydrator
/** @var array<string,mixed> */
private static $hints = [Query::HINT_CACHE_ENABLED => true];
/**
* @param EntityManagerInterface $em The entity manager.
*/
/** @param EntityManagerInterface $em The entity manager. */
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
@@ -57,6 +56,7 @@ class DefaultEntityHydrator implements EntityHydrator
if ($metadata->requiresFetchAfterChange) {
if ($metadata->isVersioned) {
assert($metadata->versionField !== null);
$data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField);
}

View File

@@ -384,7 +384,8 @@ class DefaultQueryCache implements QueryCache
/**
* @param object $entity
*
* @return array<object>|object
* @return mixed[]|object|null
* @psalm-return list<mixed>|object|null
*/
private function getAssociationValue(
ResultSetMapping $rsm,
@@ -411,10 +412,11 @@ class DefaultQueryCache implements QueryCache
}
/**
* @param mixed $value
* @param array<mixed> $path
* @param mixed $value
* @psalm-param array<array-key, array{field: string, class: string}> $path
*
* @return mixed
* @return mixed[]|object|null
* @psalm-return list<mixed>|object|null
*/
private function getAssociationPathValue($value, array $path)
{

View File

@@ -14,14 +14,18 @@ use function array_map;
class EntityCacheEntry implements CacheEntry
{
/**
* The entity map data
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string,mixed> The entity map data
* @var array<string,mixed>
*/
public $data;
/**
* The entity class name
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The entity class name
* @var string
* @psalm-var class-string
*/
public $class;

View File

@@ -15,20 +15,26 @@ use function strtolower;
class EntityCacheKey extends CacheKey
{
/**
* The entity identifier
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string, mixed> The entity identifier
* @var array<string, mixed>
*/
public $identifier;
/**
* The entity class name
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The entity class name
* @var string
* @psalm-var class-string
*/
public $entityClass;
/**
* @param string $entityClass The entity class name. In a inheritance hierarchy it should always be the root entity class.
* @param array<string, mixed> $identifier The entity identifier
* @psalm-param class-string $entityClass
*/
public function __construct($entityClass, array $identifier)
{

View File

@@ -4,9 +4,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
/**
* @deprecated
*/
/** @deprecated */
final class InvalidResultCacheDriver extends CacheException
{
public static function create(): self

View File

@@ -21,9 +21,7 @@ class Lock
$this->time = $time ?: time();
}
/**
* @return Lock
*/
/** @return Lock */
public static function createLockRead()
{
return new self(uniqid((string) time(), true));

View File

@@ -18,6 +18,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param EntityCacheKey $key The cache key of the entity.
*
* @return void
*/
public function entityCachePut($regionName, EntityCacheKey $key);
@@ -26,6 +28,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param EntityCacheKey $key The cache key of the entity.
*
* @return void
*/
public function entityCacheHit($regionName, EntityCacheKey $key);
@@ -34,6 +38,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param EntityCacheKey $key The cache key of the entity.
*
* @return void
*/
public function entityCacheMiss($regionName, EntityCacheKey $key);
@@ -42,6 +48,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param CollectionCacheKey $key The cache key of the collection.
*
* @return void
*/
public function collectionCachePut($regionName, CollectionCacheKey $key);
@@ -50,6 +58,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param CollectionCacheKey $key The cache key of the collection.
*
* @return void
*/
public function collectionCacheHit($regionName, CollectionCacheKey $key);
@@ -58,6 +68,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param CollectionCacheKey $key The cache key of the collection.
*
* @return void
*/
public function collectionCacheMiss($regionName, CollectionCacheKey $key);
@@ -66,6 +78,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param QueryCacheKey $key The cache key of the query.
*
* @return void
*/
public function queryCachePut($regionName, QueryCacheKey $key);
@@ -74,6 +88,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param QueryCacheKey $key The cache key of the query.
*
* @return void
*/
public function queryCacheHit($regionName, QueryCacheKey $key);
@@ -82,6 +98,8 @@ interface CacheLogger
*
* @param string $regionName The name of the cache region.
* @param QueryCacheKey $key The cache key of the query.
*
* @return void
*/
public function queryCacheMiss($regionName, QueryCacheKey $key);
}

View File

@@ -10,7 +10,7 @@ use Doctrine\ORM\Cache\QueryCacheKey;
class CacheLoggerChain implements CacheLogger
{
/** @var array<CacheLogger> */
/** @var array<string, CacheLogger> */
private $loggers = [];
/**
@@ -33,9 +33,7 @@ class CacheLoggerChain implements CacheLogger
return $this->loggers[$name] ?? null;
}
/**
* @return array<CacheLogger>
*/
/** @return array<string, CacheLogger> */
public function getLoggers()
{
return $this->loggers;

View File

@@ -15,13 +15,13 @@ use function array_sum;
*/
class StatisticsCacheLogger implements CacheLogger
{
/** @var int[] */
/** @var array<string, int> */
private $cacheMissCountMap = [];
/** @var int[] */
/** @var array<string, int> */
private $cacheHitCountMap = [];
/** @var int[] */
/** @var array<string, int> */
private $cachePutCountMap = [];
/**
@@ -29,9 +29,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function collectionCacheMiss($regionName, CollectionCacheKey $key)
{
$this->cacheMissCountMap[$regionName] = isset($this->cacheMissCountMap[$regionName])
? $this->cacheMissCountMap[$regionName] + 1
: 1;
$this->cacheMissCountMap[$regionName]
= ($this->cacheMissCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -39,9 +38,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function collectionCacheHit($regionName, CollectionCacheKey $key)
{
$this->cacheHitCountMap[$regionName] = isset($this->cacheHitCountMap[$regionName])
? $this->cacheHitCountMap[$regionName] + 1
: 1;
$this->cacheHitCountMap[$regionName]
= ($this->cacheHitCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -49,9 +47,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function collectionCachePut($regionName, CollectionCacheKey $key)
{
$this->cachePutCountMap[$regionName] = isset($this->cachePutCountMap[$regionName])
? $this->cachePutCountMap[$regionName] + 1
: 1;
$this->cachePutCountMap[$regionName]
= ($this->cachePutCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -59,9 +56,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function entityCacheMiss($regionName, EntityCacheKey $key)
{
$this->cacheMissCountMap[$regionName] = isset($this->cacheMissCountMap[$regionName])
? $this->cacheMissCountMap[$regionName] + 1
: 1;
$this->cacheMissCountMap[$regionName]
= ($this->cacheMissCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -69,9 +65,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function entityCacheHit($regionName, EntityCacheKey $key)
{
$this->cacheHitCountMap[$regionName] = isset($this->cacheHitCountMap[$regionName])
? $this->cacheHitCountMap[$regionName] + 1
: 1;
$this->cacheHitCountMap[$regionName]
= ($this->cacheHitCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -79,9 +74,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function entityCachePut($regionName, EntityCacheKey $key)
{
$this->cachePutCountMap[$regionName] = isset($this->cachePutCountMap[$regionName])
? $this->cachePutCountMap[$regionName] + 1
: 1;
$this->cachePutCountMap[$regionName]
= ($this->cachePutCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -89,9 +83,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function queryCacheHit($regionName, QueryCacheKey $key)
{
$this->cacheHitCountMap[$regionName] = isset($this->cacheHitCountMap[$regionName])
? $this->cacheHitCountMap[$regionName] + 1
: 1;
$this->cacheHitCountMap[$regionName]
= ($this->cacheHitCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -99,9 +92,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function queryCacheMiss($regionName, QueryCacheKey $key)
{
$this->cacheMissCountMap[$regionName] = isset($this->cacheMissCountMap[$regionName])
? $this->cacheMissCountMap[$regionName] + 1
: 1;
$this->cacheMissCountMap[$regionName]
= ($this->cacheMissCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -109,9 +101,8 @@ class StatisticsCacheLogger implements CacheLogger
*/
public function queryCachePut($regionName, QueryCacheKey $key)
{
$this->cachePutCountMap[$regionName] = isset($this->cachePutCountMap[$regionName])
? $this->cachePutCountMap[$regionName] + 1
: 1;
$this->cachePutCountMap[$regionName]
= ($this->cachePutCountMap[$regionName] ?? 0) + 1;
}
/**
@@ -150,25 +141,19 @@ class StatisticsCacheLogger implements CacheLogger
return $this->cachePutCountMap[$regionName] ?? 0;
}
/**
* @return array<string, int>
*/
/** @return array<string, int> */
public function getRegionsMiss()
{
return $this->cacheMissCountMap;
}
/**
* @return array<string, int>
*/
/** @return array<string, int> */
public function getRegionsHit()
{
return $this->cacheHitCountMap;
}
/**
* @return array<string, int>
*/
/** @return array<string, int> */
public function getRegionsPut()
{
return $this->cachePutCountMap;

View File

@@ -8,6 +8,8 @@ namespace Doctrine\ORM\Cache;
* Defines a region that supports multi-get reading.
*
* With one method call we can get multiple items.
*
* @deprecated Implement {@see Region} instead.
*/
interface MultiGetRegion
{

View File

@@ -13,11 +13,15 @@ interface CachedPersister
{
/**
* Perform whatever processing is encapsulated here after completion of the transaction.
*
* @return void
*/
public function afterTransactionComplete();
/**
* Perform whatever processing is encapsulated here after completion of the rolled-back.
*
* @return void
*/
public function afterTransactionRolledBack();

View File

@@ -7,6 +7,7 @@ namespace Doctrine\ORM\Cache\Persister\Collection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Cache\CollectionCacheKey;
use Doctrine\ORM\Cache\CollectionHydrator;
use Doctrine\ORM\Cache\EntityCacheKey;
@@ -108,7 +109,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
}
/**
* @return object[]|null
* {@inheritdoc}
*/
public function loadCollectionCache(PersistentCollection $collection, CollectionCacheKey $key)
{
@@ -224,10 +225,18 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
/**
* Clears cache entries related to the current collection
*
* @deprecated This method is not used anymore.
*
* @return void
*/
protected function evictCollectionCache(PersistentCollection $collection)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9512',
'The method %s() is deprecated and will be removed without replacement.'
);
$key = new CollectionCacheKey(
$this->sourceEntity->rootEntityName,
$this->association['fieldName'],
@@ -242,13 +251,22 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
}
/**
* @deprecated This method is not used anymore.
*
* @param string $targetEntity
* @param object $element
* @psalm-param class-string $targetEntity
*
* @return void
*/
protected function evictElementCache($targetEntity, $element)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9512',
'The method %s() is deprecated and will be removed without replacement.'
);
$targetPersister = $this->uow->getEntityPersister($targetEntity);
assert($targetPersister instanceof CachedEntityPersister);
$targetRegion = $targetPersister->getCacheRegion();

View File

@@ -16,27 +16,23 @@ use Doctrine\ORM\Persisters\Collection\CollectionPersister;
*/
interface CachedCollectionPersister extends CachedPersister, CollectionPersister
{
/**
* @return ClassMetadata
*/
/** @return ClassMetadata */
public function getSourceEntityMetadata();
/**
* @return ClassMetadata
*/
/** @return ClassMetadata */
public function getTargetEntityMetadata();
/**
* Loads a collection from cache
*
* @return PersistentCollection|null
* @return mixed[]|null
*/
public function loadCollectionCache(PersistentCollection $collection, CollectionCacheKey $key);
/**
* Stores a collection into cache
*
* @param array|mixed[]|Collection $elements
* @param mixed[]|Collection $elements
*
* @return void
*/

View File

@@ -14,12 +14,7 @@ use function spl_object_id;
class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
{
/**
* @param CollectionPersister $persister The collection persister that will be cached.
* @param ConcurrentRegion $region The collection region.
* @param EntityManagerInterface $em The entity manager.
* @param mixed[] $association The association mapping.
*/
/** @param mixed[] $association The association mapping. */
public function __construct(CollectionPersister $persister, ConcurrentRegion $region, EntityManagerInterface $em, array $association)
{
parent::__construct($persister, $region, $em, $association);

View File

@@ -177,9 +177,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
return $this->region;
}
/**
* @return EntityHydrator
*/
/** @return EntityHydrator */
public function getEntityHydrator()
{
return $this->hydrator;
@@ -207,9 +205,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
return $cached;
}
/**
* @param object $entity
*/
/** @param object $entity */
private function storeJoinedAssociations($entity): void
{
if ($this->joinedAssociations === null) {
@@ -251,8 +247,8 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
* @param string $query
* @param string[]|Criteria $criteria
* @param string[] $orderBy
* @param int $limit
* @param int $offset
* @param int|null $limit
* @param int|null $offset
*
* @return string
*/

View File

@@ -14,9 +14,7 @@ use Doctrine\ORM\Persisters\Entity\EntityPersister;
*/
interface CachedEntityPersister extends CachedPersister, EntityPersister
{
/**
* @return EntityHydrator
*/
/** @return EntityHydrator */
public function getEntityHydrator();
/**

View File

@@ -82,9 +82,7 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister
$this->queuedCache['update'][] = $entity;
}
/**
* @param object $entity
*/
/** @param object $entity */
private function updateCache($entity, bool $isChanged): bool
{
$class = $this->metadataFactory->getMetadataFor(get_class($entity));

View File

@@ -15,12 +15,6 @@ use Doctrine\ORM\Persisters\Entity\EntityPersister;
*/
class ReadWriteCachedEntityPersister extends AbstractEntityPersister
{
/**
* @param EntityPersister $persister The entity persister to cache.
* @param ConcurrentRegion $region The entity cache region.
* @param EntityManagerInterface $em The entity manager.
* @param ClassMetadata $class The entity metadata.
*/
public function __construct(EntityPersister $persister, ConcurrentRegion $region, EntityManagerInterface $em, ClassMetadata $class)
{
parent::__construct($persister, $region, $em, $class);

View File

@@ -12,9 +12,7 @@ use Doctrine\ORM\Query\ResultSetMapping;
*/
interface QueryCache
{
/**
* @return bool
*/
/** @return bool */
public function clear();
/**
@@ -32,8 +30,6 @@ interface QueryCache
*/
public function get(QueryCacheKey $key, ResultSetMapping $rsm, array $hints = []);
/**
* @return Region
*/
/** @return Region */
public function getRegion();
}

View File

@@ -12,20 +12,24 @@ use function microtime;
class QueryCacheEntry implements CacheEntry
{
/**
* List of entity identifiers
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string, mixed> List of entity identifiers
* @var array<string, mixed>
*/
public $result;
/**
* Time creation of this cache entry
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var float Time creation of this cache entry
* @var float
*/
public $time;
/**
* @param array<string, mixed> $result
* @param float $time
* @param float|null $time
*/
public function __construct($result, $time = null)
{

View File

@@ -12,8 +12,10 @@ use Doctrine\ORM\Cache;
class QueryCacheKey extends CacheKey
{
/**
* Cache key lifetime
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var int Cache key lifetime
* @var int
*/
public $lifetime;
@@ -32,9 +34,7 @@ class QueryCacheKey extends CacheKey
*/
public $timestampKey;
/**
* @psalm-param Cache::MODE_* $cacheMode
*/
/** @psalm-param Cache::MODE_* $cacheMode */
public function __construct(
string $cacheId,
int $lifetime = 0,

View File

@@ -31,9 +31,7 @@ use function strtr;
*/
class DefaultRegion implements Region
{
/**
* @internal since 2.11, this constant will be private in 3.0.
*/
/** @internal since 2.11, this constant will be private in 3.0. */
public const REGION_KEY_SEPARATOR = '_';
private const REGION_PREFIX = 'DC2_REGION_';
@@ -61,9 +59,7 @@ class DefaultRegion implements Region
/** @var CacheItemPoolInterface */
private $cacheItemPool;
/**
* @param CacheItemPoolInterface $cacheItemPool
*/
/** @param CacheItemPoolInterface $cacheItemPool */
public function __construct(string $name, $cacheItemPool, int $lifetime = 0)
{
if ($cacheItemPool instanceof LegacyCache) {

View File

@@ -103,17 +103,13 @@ class FileLockRegion implements ConcurrentRegion
return $this->directory . DIRECTORY_SEPARATOR . $key->hash . '.' . self::LOCK_EXTENSION;
}
/**
* @return string|false
*/
/** @return string|false */
private function getLockContent(string $filename)
{
return @file_get_contents($filename);
}
/**
* @return int|false
*/
/** @return int|false */
private function getLockTime(string $filename)
{
return @fileatime($filename);

View File

@@ -31,9 +31,7 @@ class RegionsConfiguration
$this->defaultLockLifetime = (int) $defaultLockLifetime;
}
/**
* @return int
*/
/** @return int */
public function getDefaultLifetime()
{
return $this->defaultLifetime;
@@ -49,9 +47,7 @@ class RegionsConfiguration
$this->defaultLifetime = (int) $defaultLifetime;
}
/**
* @return int
*/
/** @return int */
public function getDefaultLockLifetime()
{
return $this->defaultLockLifetime;

View File

@@ -17,9 +17,7 @@ class TimestampCacheEntry implements CacheEntry
*/
public $time;
/**
* @param float $time
*/
/** @param float|null $time */
public function __construct($time = null)
{
$this->time = $time ? (float) $time : microtime(true);

View File

@@ -9,9 +9,7 @@ namespace Doctrine\ORM\Cache;
*/
class TimestampCacheKey extends CacheKey
{
/**
* @param string $space Result cache id
*/
/** @param string $space Result cache id */
public function __construct($space)
{
$this->hash = (string) $space;

View File

@@ -10,9 +10,9 @@ namespace Doctrine\ORM\Cache;
interface TimestampRegion extends Region
{
/**
* Update an specific key into the cache region.
* Update a specific key into the cache region.
*
* @param CacheKey $key The key of the item to update the timestamp.
* @return void
*
* @throws LockException Indicates a problem accessing the region.
*/

View File

@@ -12,6 +12,7 @@ use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\Cache as CacheDriver;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Common\Persistence\PersistentObject;
use Doctrine\Common\Proxy\AbstractProxyFactory;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Cache\CacheConfiguration;
@@ -23,6 +24,7 @@ use Doctrine\ORM\Cache\Exception\QueryCacheUsesNonPersistentCache;
use Doctrine\ORM\Exception\InvalidEntityRepository;
use Doctrine\ORM\Exception\NamedNativeQueryNotFound;
use Doctrine\ORM\Exception\NamedQueryNotFound;
use Doctrine\ORM\Exception\NotSupported;
use Doctrine\ORM\Exception\ProxyClassesAlwaysRegenerating;
use Doctrine\ORM\Exception\UnknownEntityNamespace;
use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
@@ -34,6 +36,9 @@ use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Mapping\EntityListenerResolver;
use Doctrine\ORM\Mapping\NamingStrategy;
use Doctrine\ORM\Mapping\QuoteStrategy;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Filter\SQLFilter;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
use Doctrine\ORM\Repository\RepositoryFactory;
@@ -41,9 +46,9 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\ObjectRepository;
use LogicException;
use Psr\Cache\CacheItemPoolInterface;
use ReflectionClass;
use function class_exists;
use function is_a;
use function method_exists;
use function sprintf;
use function strtolower;
@@ -54,6 +59,8 @@ use function trim;
* It combines all configuration options from DBAL & ORM.
*
* Internal note: When adding a new configuration option just write a getter/setter pair.
*
* @psalm-import-type AutogenerateMode from ProxyFactory
*/
class Configuration extends \Doctrine\DBAL\Configuration
{
@@ -75,10 +82,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the directory where Doctrine generates any necessary proxy class files.
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
*
* @see https://github.com/Ocramius/ProxyManager
*
* @return string|null
*/
public function getProxyDir()
@@ -89,11 +92,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the strategy for automatically generating proxy classes.
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
*
* @see https://github.com/Ocramius/ProxyManager
*
* @return int Possible values are constants of Doctrine\Common\Proxy\AbstractProxyFactory.
* @psalm-return AutogenerateMode
*/
public function getAutoGenerateProxyClasses()
{
@@ -104,6 +104,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Sets the strategy for automatically generating proxy classes.
*
* @param bool|int $autoGenerate Possible values are constants of Doctrine\Common\Proxy\AbstractProxyFactory.
* @psalm-param bool|AutogenerateMode $autoGenerate
* True is converted to AUTOGENERATE_ALWAYS, false to AUTOGENERATE_NEVER.
*
* @return void
@@ -116,10 +117,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the namespace where proxy classes reside.
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
*
* @see https://github.com/Ocramius/ProxyManager
*
* @return string|null
*/
public function getProxyNamespace()
@@ -156,6 +153,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Adds a new default annotation driver with a correctly configured annotation reader. If $useSimpleAnnotationReader
* is true, the notation `@Entity` will work, otherwise, the notation `@ORM\Entity` will be supported.
*
* @deprecated Use {@see ORMSetup::createDefaultAnnotationDriver()} instead.
*
* @param string|string[] $paths
* @param bool $useSimpleAnnotationReader
* @psalm-param string|list<string> $paths
@@ -164,6 +163,14 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function newDefaultAnnotationDriver($paths = [], $useSimpleAnnotationReader = true)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9443',
'%s is deprecated, call %s::createDefaultAnnotationDriver() instead.',
__METHOD__,
ORMSetup::class
);
if (! class_exists(AnnotationReader::class)) {
throw new LogicException(sprintf(
'The annotation metadata driver cannot be enabled because the "doctrine/annotations" library'
@@ -193,6 +200,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
}
/**
* @deprecated No replacement planned.
*
* Adds a namespace under a certain alias.
*
* @param string $alias
@@ -202,6 +211,21 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function addEntityNamespace($alias, $namespace)
{
if (class_exists(PersistentObject::class)) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/8818',
'Short namespace aliases such as "%s" are deprecated and will be removed in Doctrine ORM 3.0.',
$alias
);
} else {
NotSupported::createForPersistence3(sprintf(
'Using short namespace alias "%s" by calling %s',
$alias,
__METHOD__
));
}
$this->_attributes['entityNamespaces'][$alias] = $namespace;
}
@@ -548,7 +572,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
throw QueryCacheUsesNonPersistentCache::fromDriver($queryCacheImpl);
}
if ($this->getAutoGenerateProxyClasses()) {
if ($this->getAutoGenerateProxyClasses() !== AbstractProxyFactory::AUTOGENERATE_NEVER) {
throw ProxyClassesAlwaysRegenerating::create();
}
@@ -570,8 +594,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* DQL function names are case-insensitive.
*
* @param string $name Function name.
* @param string|callable $className Class name or a callable that returns the function.
* @param string $name Function name.
* @param class-string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -585,8 +610,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
*
* @return string|null
* @psalm-return ?class-string
* @return string|callable|null
* @psalm-return class-string<FunctionNode>|callable(string):FunctionNode|null
*/
public function getCustomStringFunction($name)
{
@@ -603,7 +628,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* Any previously added string functions are discarded.
*
* @psalm-param array<string, class-string> $functions The map of custom
* @psalm-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions The map of custom
* DQL string functions.
*
* @return void
@@ -622,8 +647,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* DQL function names are case-insensitive.
*
* @param string $name Function name.
* @param string|callable $className Class name or a callable that returns the function.
* @param string $name Function name.
* @param class-string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -637,8 +663,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
*
* @return string|null
* @psalm-return ?class-string
* @return string|callable|null
* @psalm-return class-string|callable|null
*/
public function getCustomNumericFunction($name)
{
@@ -676,7 +702,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name Function name.
* @param string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string|callable $className
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -690,8 +716,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
*
* @return string|null
* @psalm-return ?class-string $name
* @return string|callable|null
* @psalm-return class-string|callable|null $name
*/
public function getCustomDatetimeFunction($name)
{
@@ -709,7 +735,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Any previously added date/time functions are discarded.
*
* @param array $functions The map of custom DQL date/time functions.
* @psalm-param array<string, string> $functions
* @psalm-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions
*
* @return void
*/
@@ -794,6 +820,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name The name of the filter.
* @param string $className The class name of the filter.
* @psalm-param class-string<SQLFilter> $className
*
* @return void
*/
@@ -809,7 +836,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return string|null The class name of the filter, or null if it is not
* defined.
* @psalm-return ?class-string
* @psalm-return class-string<SQLFilter>|null
*/
public function getFilterClassName($name)
{
@@ -820,6 +847,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Sets default repository class.
*
* @param string $className
* @psalm-param class-string<EntityRepository> $className
*
* @return void
*
@@ -827,12 +855,20 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setDefaultRepositoryClassName($className)
{
$reflectionClass = new ReflectionClass($className);
if (! $reflectionClass->implementsInterface(ObjectRepository::class)) {
if (! class_exists($className) || ! is_a($className, ObjectRepository::class, true)) {
throw InvalidEntityRepository::fromClassName($className);
}
if (! is_a($className, EntityRepository::class, true)) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9533',
'Configuring %s as default repository class is deprecated because it does not extend %s.',
$className,
EntityRepository::class
);
}
$this->_attributes['defaultRepositoryClassName'] = $className;
}
@@ -840,7 +876,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Get default repository class.
*
* @return string
* @psalm-return class-string
* @psalm-return class-string<EntityRepository>
*/
public function getDefaultRepositoryClassName()
{
@@ -939,9 +975,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
return $this->_attributes['repositoryFactory'] ?? new DefaultRepositoryFactory();
}
/**
* @return bool
*/
/** @return bool */
public function isSecondLevelCacheEnabled()
{
return $this->_attributes['isSecondLevelCacheEnabled'] ?? false;
@@ -957,17 +991,13 @@ class Configuration extends \Doctrine\DBAL\Configuration
$this->_attributes['isSecondLevelCacheEnabled'] = (bool) $flag;
}
/**
* @return void
*/
/** @return void */
public function setSecondLevelCacheConfiguration(CacheConfiguration $cacheConfig)
{
$this->_attributes['secondLevelCacheConfiguration'] = $cacheConfig;
}
/**
* @return CacheConfiguration|null
*/
/** @return CacheConfiguration|null */
public function getSecondLevelCacheConfiguration()
{
if (! isset($this->_attributes['secondLevelCacheConfiguration']) && $this->isSecondLevelCacheEnabled()) {

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Decorator;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ObjectManagerDecorator;
@@ -43,6 +44,28 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
return $this->wrapped->getExpressionBuilder();
}
/**
* {@inheritdoc}
*
* @psalm-param class-string<T> $className
*
* @psalm-return EntityRepository<T>
*
* @template T of object
*/
public function getRepository($className)
{
return $this->wrapped->getRepository($className);
}
/**
* {@inheritdoc}
*/
public function getClassMetadata($className)
{
return $this->wrapped->getClassMetadata($className);
}
/**
* {@inheritdoc}
*/

View File

@@ -4,9 +4,11 @@ declare(strict_types=1);
namespace Doctrine\ORM;
use BackedEnum;
use BadMethodCallException;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\EventManager;
use Doctrine\Common\Persistence\PersistentObject;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
@@ -17,6 +19,7 @@ use Doctrine\ORM\Exception\InvalidHydrationMode;
use Doctrine\ORM\Exception\MismatchedEventManager;
use Doctrine\ORM\Exception\MissingIdentifierField;
use Doctrine\ORM\Exception\MissingMappingDriverImplementation;
use Doctrine\ORM\Exception\NotSupported;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\Exception\UnrecognizedIdentifierFields;
use Doctrine\ORM\Mapping\ClassMetadata;
@@ -32,7 +35,7 @@ use InvalidArgumentException;
use Throwable;
use function array_keys;
use function call_user_func;
use function class_exists;
use function get_debug_type;
use function gettype;
use function is_array;
@@ -41,6 +44,7 @@ use function is_object;
use function is_string;
use function ltrim;
use function sprintf;
use function strpos;
/**
* The EntityManager is the central access point to ORM functionality.
@@ -66,8 +70,10 @@ use function sprintf;
* is not a valid extension point for the EntityManager. Instead you
* should take a look at the {@see \Doctrine\ORM\Decorator\EntityManagerDecorator}
* and wrap your entity manager in a decorator.
*
* @final
*/
/* final */class EntityManager implements EntityManagerInterface
class EntityManager implements EntityManagerInterface
{
/**
* The used Configuration.
@@ -150,11 +156,15 @@ use function sprintf;
* Creates a new EntityManager that operates on the given database connection
* and uses the given Configuration and EventManager implementations.
*/
protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
public function __construct(Connection $conn, Configuration $config)
{
if (! $config->getMetadataDriverImpl()) {
throw MissingMappingDriverImplementation::create();
}
$this->conn = $conn;
$this->config = $config;
$this->eventManager = $eventManager;
$this->eventManager = $conn->getEventManager();
$metadataFactoryClassName = $config->getClassMetadataFactoryName();
@@ -237,7 +247,7 @@ use function sprintf;
$this->conn->beginTransaction();
try {
$return = call_user_func($func, $this);
$return = $func($this);
$this->flush();
$this->conn->commit();
@@ -433,11 +443,14 @@ use function sprintf;
}
foreach ($id as $i => $value) {
if (is_object($value) && $this->metadataFactory->hasMetadataFor(ClassUtils::getClass($value))) {
$id[$i] = $this->unitOfWork->getSingleIdentifierValue($value);
if (is_object($value)) {
$className = ClassUtils::getClass($value);
if ($this->metadataFactory->hasMetadataFor($className)) {
$id[$i] = $this->unitOfWork->getSingleIdentifierValue($value);
if ($id[$i] === null) {
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
if ($id[$i] === null) {
throw ORMInvalidArgumentException::invalidIdentifierBindingEntity($className);
}
}
}
}
@@ -449,7 +462,12 @@ use function sprintf;
throw MissingIdentifierField::fromFieldAndClass($identifier, $class->name);
}
$sortedId[$identifier] = $id[$identifier];
if ($id[$identifier] instanceof BackedEnum) {
$sortedId[$identifier] = $id[$identifier]->value;
} else {
$sortedId[$identifier] = $id[$identifier];
}
unset($id[$identifier]);
}
@@ -783,7 +801,35 @@ use function sprintf;
*/
public function getRepository($entityName)
{
return $this->repositoryFactory->getRepository($this, $entityName);
if (strpos($entityName, ':') !== false) {
if (class_exists(PersistentObject::class)) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/8818',
'Short namespace aliases such as "%s" are deprecated and will be removed in Doctrine ORM 3.0.',
$entityName
);
} else {
NotSupported::createForPersistence3(sprintf(
'Using short namespace alias "%s" when calling %s',
$entityName,
__METHOD__
));
}
}
$repository = $this->repositoryFactory->getRepository($this, $entityName);
if (! $repository instanceof EntityRepository) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9533',
'Not returning an instance of %s from %s::getRepository() is deprecated and will cause a TypeError on 3.0.',
EntityRepository::class,
get_debug_type($this->repositoryFactory)
);
}
return $repository;
}
/**
@@ -918,13 +964,9 @@ use function sprintf;
*/
public static function create($connection, Configuration $config, ?EventManager $eventManager = null)
{
if (! $config->getMetadataDriverImpl()) {
throw MissingMappingDriverImplementation::create();
}
$connection = static::createConnection($connection, $config, $eventManager);
return new EntityManager($connection, $config, $connection->getEventManager());
return new EntityManager($connection, $config);
}
/**

View File

@@ -5,22 +5,25 @@ declare(strict_types=1);
namespace Doctrine\ORM;
use BadMethodCallException;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\AbstractLazyCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Doctrine\Common\Persistence\PersistentObject;
use Doctrine\DBAL\LockMode;
use Doctrine\Deprecations\Deprecation;
use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\InflectorFactory;
use Doctrine\ORM\Exception\NotSupported;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\Repository\Exception\InvalidMagicMethodCall;
use Doctrine\Persistence\ObjectRepository;
use function array_slice;
use function class_exists;
use function lcfirst;
use function sprintf;
use function strpos;
use function str_starts_with;
use function substr;
/**
@@ -36,22 +39,34 @@ use function substr;
*/
class EntityRepository implements ObjectRepository, Selectable
{
/** @var string */
/**
* @internal This property will be private in 3.0, call {@see getEntityName()} instead.
*
* @var string
* @psalm-var class-string<T>
*/
protected $_entityName;
/** @var EntityManagerInterface */
/**
* @internal This property will be private in 3.0, call {@see getEntityManager()} instead.
*
* @var EntityManagerInterface
*/
protected $_em;
/** @var ClassMetadata */
/**
* @internal This property will be private in 3.0, call {@see getClassMetadata()} instead.
*
* @var ClassMetadata
* @psalm-var ClassMetadata<T>
*/
protected $_class;
/** @var Inflector */
/** @var Inflector|null */
private static $inflector;
/**
* Initializes a new <tt>EntityRepository</tt>.
*/
public function __construct(EntityManagerInterface $em, Mapping\ClassMetadata $class)
/** @psalm-param ClassMetadata<T> $class */
public function __construct(EntityManagerInterface $em, ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
@@ -61,8 +76,8 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Creates a new QueryBuilder instance that is prepopulated for this entity name.
*
* @param string $alias
* @param string $indexBy The index for the from.
* @param string $alias
* @param string|null $indexBy The index for the from.
*
* @return QueryBuilder
*/
@@ -154,6 +169,13 @@ class EntityRepository implements ObjectRepository, Selectable
__METHOD__
);
if (! class_exists(PersistentObject::class)) {
throw NotSupported::createForPersistence3(sprintf(
'Partial clearing of entities for class %s',
$this->_class->rootEntityName
));
}
$this->_em->clear($this->_class->rootEntityName);
}
@@ -246,15 +268,15 @@ class EntityRepository implements ObjectRepository, Selectable
*/
public function __call($method, $arguments)
{
if (strpos($method, 'findBy') === 0) {
if (str_starts_with($method, 'findBy')) {
return $this->resolveMagicCall('findBy', substr($method, 6), $arguments);
}
if (strpos($method, 'findOneBy') === 0) {
if (str_starts_with($method, 'findOneBy')) {
return $this->resolveMagicCall('findOneBy', substr($method, 9), $arguments);
}
if (strpos($method, 'countBy') === 0) {
if (str_starts_with($method, 'countBy')) {
return $this->resolveMagicCall('count', substr($method, 7), $arguments);
}
@@ -267,6 +289,7 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* @return string
* @psalm-return class-string<T>
*/
protected function getEntityName()
{
@@ -274,23 +297,22 @@ class EntityRepository implements ObjectRepository, Selectable
}
/**
* @return string
* {@inheritdoc}
*/
public function getClassName()
{
return $this->getEntityName();
}
/**
* @return EntityManagerInterface
*/
/** @return EntityManagerInterface */
protected function getEntityManager()
{
return $this->_em;
}
/**
* @return Mapping\ClassMetadata
* @return ClassMetadata
* @psalm-return ClassMetadata<T>
*/
protected function getClassMetadata()
{
@@ -301,8 +323,8 @@ class EntityRepository implements ObjectRepository, Selectable
* Select all elements from a selectable that match the expression and
* return a new collection containing these elements.
*
* @return LazyCriteriaCollection
* @psalm-return Collection<int, T>
* @return AbstractLazyCollection
* @psalm-return AbstractLazyCollection<int, T>&Selectable<int, T>
*/
public function matching(Criteria $criteria)
{

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
@@ -11,27 +12,59 @@ use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
* Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
* of entities.
*
* @link www.doctrine-project.org
* @extends BaseLifecycleEventArgs<EntityManagerInterface>
*/
class LifecycleEventArgs extends BaseLifecycleEventArgs
{
/** @param object $object */
public function __construct($object, EntityManagerInterface $objectManager)
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'The %s class is deprecated and will be removed in ORM 3.0. Use %s instead.',
self::class,
BaseLifecycleEventArgs::class
);
parent::__construct($object, $objectManager);
}
/**
* Retrieves associated Entity.
*
* @deprecated 2.13. Use {@see getObject} instead.
*
* @return object
*/
public function getEntity()
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObject();
}
/**
* Retrieves associated EntityManager.
*
* @deprecated 2.13. Use {@see getObjectManager} instead.
*
* @return EntityManagerInterface
*/
public function getEntityManager()
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObjectManager();
}
}

View File

@@ -30,9 +30,6 @@ class ListenersInvoker
*/
private $eventManager;
/**
* Initializes a new ListenersInvoker instance.
*/
public function __construct(EntityManagerInterface $em)
{
$this->eventManager = $em->getEventManager();
@@ -46,6 +43,7 @@ class ListenersInvoker
* @param string $eventName The entity lifecycle event.
*
* @return int Bitmask of subscribed event systems.
* @psalm-return int-mask-of<self::INVOKE_*>
*/
public function getSubscribedSystems(ClassMetadata $metadata, $eventName)
{
@@ -74,6 +72,7 @@ class ListenersInvoker
* @param object $entity The Entity on which the event occurred.
* @param EventArgs $event The Event args.
* @param int $invoke Bitmask to invoke listeners.
* @psalm-param int-mask-of<self::INVOKE_*> $invoke
*
* @return void
*/

View File

@@ -11,8 +11,7 @@ use Doctrine\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetada
/**
* Class that holds event arguments for a loadMetadata event.
*
* @method __construct(ClassMetadata $classMetadata, EntityManagerInterface $objectManager)
* @method ClassMetadata getClassMetadata()
* @extends BaseLoadClassMetadataEventArgs<ClassMetadata<object>, EntityManagerInterface>
*/
class LoadClassMetadataEventArgs extends BaseLoadClassMetadataEventArgs
{

View File

@@ -4,15 +4,21 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\ManagerEventArgs;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\ObjectManager;
use function func_num_args;
/**
* Class that holds event arguments for a `onClassMetadataNotFound` event.
*
* This object is mutable by design, allowing callbacks having access to it to set the
* found metadata in it, and therefore "cancelling" a `onClassMetadataNotFound` event
*
* @extends ManagerEventArgs<EntityManagerInterface>
*/
class OnClassMetadataNotFoundEventArgs extends ManagerEventArgs
{
@@ -23,7 +29,8 @@ class OnClassMetadataNotFoundEventArgs extends ManagerEventArgs
private $foundMetadata;
/**
* @param string $className
* @param string $className
* @param EntityManagerInterface $objectManager
*/
public function __construct($className, ObjectManager $objectManager)
{
@@ -32,17 +39,22 @@ class OnClassMetadataNotFoundEventArgs extends ManagerEventArgs
parent::__construct($objectManager);
}
/**
* @return void
*/
/** @return void */
public function setFoundMetadata(?ClassMetadata $classMetadata = null)
{
if (func_num_args() < 1) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9791',
'Calling %s without arguments is deprecated, pass null instead.',
__METHOD__
);
}
$this->foundMetadata = $classMetadata;
}
/**
* @return ClassMetadata|null
*/
/** @return ClassMetadata|null */
public function getFoundMetadata()
{
return $this->foundMetadata;

View File

@@ -4,44 +4,54 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\OnClearEventArgs as BaseOnClearEventArgs;
/**
* Provides event arguments for the onClear event.
*
* @link www.doctrine-project.org
*
* @extends BaseOnClearEventArgs<EntityManagerInterface>
*/
class OnClearEventArgs extends EventArgs
class OnClearEventArgs extends BaseOnClearEventArgs
{
/** @var EntityManagerInterface */
private $em;
/** @var string|null */
private $entityClass;
/**
* @param string|null $entityClass Optional entity class.
*/
/** @param string|null $entityClass Optional entity class. */
public function __construct(EntityManagerInterface $em, $entityClass = null)
{
$this->em = $em;
parent::__construct($em);
$this->entityClass = $entityClass;
}
/**
* Retrieves associated EntityManager.
*
* @deprecated 2.13. Use {@see getObjectManager} instead.
*
* @return EntityManagerInterface
*/
public function getEntityManager()
{
return $this->em;
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObjectManager();
}
/**
* Name of the entity class that is cleared, or empty if all are cleared.
*
* @deprecated Clearing the entity manager partially is deprecated. This method will be removed in 3.0.
*
* @return string|null
*/
public function getEntityClass()
@@ -52,6 +62,8 @@ class OnClearEventArgs extends EventArgs
/**
* Checks if event clears all entities.
*
* @deprecated Clearing the entity manager partially is deprecated. This method will be removed in 3.0.
*
* @return bool
*/
public function clearsAllEntities()

View File

@@ -4,31 +4,35 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\ManagerEventArgs;
/**
* Provides event arguments for the preFlush event.
*
* @link www.doctrine-project.org
*
* @extends ManagerEventArgs<EntityManagerInterface>
*/
class OnFlushEventArgs extends EventArgs
class OnFlushEventArgs extends ManagerEventArgs
{
/** @var EntityManagerInterface */
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Retrieve associated EntityManager.
*
* @deprecated 2.13. Use {@see getObjectManager} instead.
*
* @return EntityManagerInterface
*/
public function getEntityManager()
{
return $this->em;
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObjectManager();
}
}

View File

@@ -4,31 +4,35 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\ManagerEventArgs;
/**
* Provides event arguments for the postFlush event.
*
* @link www.doctrine-project.org
*
* @extends ManagerEventArgs<EntityManagerInterface>
*/
class PostFlushEventArgs extends EventArgs
class PostFlushEventArgs extends ManagerEventArgs
{
/** @var EntityManagerInterface */
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Retrieves associated EntityManager.
*
* @deprecated 2.13. Use {@see getObjectManager} instead.
*
* @return EntityManagerInterface
*/
public function getEntityManager()
{
return $this->em;
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObjectManager();
}
}

View File

@@ -4,29 +4,33 @@ declare(strict_types=1);
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\ManagerEventArgs;
/**
* Provides event arguments for the preFlush event.
*
* @link www.doctrine-project.com
*
* @extends ManagerEventArgs<EntityManagerInterface>
*/
class PreFlushEventArgs extends EventArgs
class PreFlushEventArgs extends ManagerEventArgs
{
/** @var EntityManagerInterface */
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* @deprecated 2.13. Use {@see getObjectManager} instead.
*
* @return EntityManagerInterface
*/
public function getEntityManager()
{
return $this->em;
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/9875',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getObjectManager() instead.',
__METHOD__
);
return $this->getObjectManager();
}
}

View File

@@ -108,7 +108,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
throw new InvalidArgumentException(sprintf(
'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
$field,
get_debug_type($this->getEntity())
get_debug_type($this->getObject())
));
}
}

View File

@@ -8,9 +8,7 @@ use function get_debug_type;
final class EntityMissingAssignedId extends ORMException
{
/**
* @param object $entity
*/
/** @param object $entity */
public static function forField($entity, string $field): self
{
return new self('Entity of type ' . get_debug_type($entity) . " is missing an assigned ID for field '" . $field . "'. " .

View File

@@ -4,14 +4,14 @@ declare(strict_types=1);
namespace Doctrine\ORM\Exception;
use Doctrine\Persistence\ObjectRepository;
use Doctrine\ORM\EntityRepository;
final class InvalidEntityRepository extends ORMException implements ConfigurationException
{
public static function fromClassName(string $className): self
{
return new self(
"Invalid repository class '" . $className . "'. It must be a " . ObjectRepository::class . '.'
"Invalid repository class '" . $className . "'. It must be a " . EntityRepository::class . '.'
);
}
}

View File

@@ -11,9 +11,7 @@ final class MultipleSelectorsFoundException extends ORMException
{
public const MULTIPLE_SELECTORS_FOUND_EXCEPTION = 'Multiple selectors found: %s. Please select only one.';
/**
* @param string[] $selectors
*/
/** @param string[] $selectors */
public static function create(array $selectors): self
{
return new self(

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Doctrine\ORM\Exception;
use function sprintf;
final class NotSupported extends ORMException
{
public static function create(): self
@@ -11,8 +13,29 @@ final class NotSupported extends ORMException
return new self('This behaviour is (currently) not supported by Doctrine 2');
}
public static function createForDbal3(): self
public static function createForDbal3(string $context): self
{
return new self('Feature was deprecated in doctrine/dbal 2.x and is not supported by installed doctrine/dbal:3.x, please see the doctrine/deprecations logs for new alternative approaches.');
return new self(sprintf(
<<<'EXCEPTION'
Context: %s
Problem: Feature was deprecated in doctrine/dbal 2.x and is not supported by installed doctrine/dbal:3.x
Solution: See the doctrine/deprecations logs for new alternative approaches.
EXCEPTION
,
$context
));
}
public static function createForPersistence3(string $context): self
{
return new self(sprintf(
<<<'EXCEPTION'
Context: %s
Problem: Feature was deprecated in doctrine/persistence 2.x and is not supported by installed doctrine/persistence:3.x
Solution: See the doctrine/deprecations logs for new alternative approaches.
EXCEPTION
,
$context
));
}
}

View File

@@ -6,6 +6,7 @@ namespace Doctrine\ORM\Exception;
use function sprintf;
/** @deprecated No replacement planned. */
final class UnknownEntityNamespace extends ORMException implements ConfigurationException
{
public static function fromNamespaceAlias(string $entityNamespaceAlias): self

View File

@@ -9,9 +9,7 @@ use function sprintf;
final class UnrecognizedIdentifierFields extends ORMException implements ManagerException
{
/**
* @param string[] $fieldNames
*/
/** @param string[] $fieldNames */
public static function fromClassAndFieldNames(string $className, array $fieldNames): self
{
return new self(sprintf(

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Id;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
/**
@@ -27,6 +28,15 @@ class BigIntegerIdentityGenerator extends AbstractIdGenerator
*/
public function __construct($sequenceName = null)
{
if ($sequenceName !== null) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/8850',
'Passing a sequence name to the IdentityGenerator is deprecated in favor of using %s. $sequenceName will be removed in ORM 3.0',
SequenceGenerator::class
);
}
$this->sequenceName = $sequenceName;
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Id;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\EntityManagerInterface;
/**
@@ -27,6 +28,15 @@ class IdentityGenerator extends AbstractIdGenerator
*/
public function __construct($sequenceName = null)
{
if ($sequenceName !== null) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/8850',
'Passing a sequence name to the IdentityGenerator is deprecated in favor of using %s. $sequenceName will be removed in ORM 3.0',
SequenceGenerator::class
);
}
$this->sequenceName = $sequenceName;
}

View File

@@ -62,7 +62,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
$connection->ensureConnectedToPrimary();
}
$this->_nextValue = (int) $connection->executeQuery($sql)->fetchOne();
$this->_nextValue = (int) $connection->fetchOne($sql);
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
}
@@ -99,9 +99,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
return serialize($this->__serialize());
}
/**
* @return array<string, mixed>
*/
/** @return array<string, mixed> */
public function __serialize(): array
{
return [
@@ -122,9 +120,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
$this->__unserialize(unserialize($serialized));
}
/**
* @param array<string, mixed> $data
*/
/** @param array<string, mixed> $data */
public function __unserialize(array $data): void
{
$this->_sequenceName = $data['sequenceName'];

View File

@@ -11,6 +11,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\NotSupported;
use function method_exists;
use function sprintf;
/**
* Represents an ID generator that uses the database UUID expression
@@ -29,7 +30,10 @@ class UuidGenerator extends AbstractIdGenerator
);
if (! method_exists(AbstractPlatform::class, 'getGuidExpression')) {
throw NotSupported::createForDbal3();
throw NotSupported::createForDbal3(sprintf(
'Using the database to generate a UUID through %s',
self::class
));
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Doctrine\ORM\Internal\Hydration;
use BackedEnum;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\ForwardCompatibility\Result as ForwardCompatibilityResult;
use Doctrine\DBAL\Platforms\AbstractPlatform;
@@ -27,6 +28,7 @@ use function count;
use function end;
use function get_debug_type;
use function in_array;
use function is_array;
use function sprintf;
/**
@@ -421,6 +423,10 @@ abstract class AbstractHydrator
$type = $cacheKeyInfo['type'];
$value = $type->convertToPHPValue($value, $this->_platform);
if ($value !== null && isset($cacheKeyInfo['enumType'])) {
$value = $this->buildEnum($value, $cacheKeyInfo['enumType']);
}
$rowData['newObjects'][$objIndex]['class'] = $cacheKeyInfo['class'];
$rowData['newObjects'][$objIndex]['args'][$argIndex] = $value;
break;
@@ -429,7 +435,12 @@ abstract class AbstractHydrator
$type = $cacheKeyInfo['type'];
$value = $type->convertToPHPValue($value, $this->_platform);
if ($value !== null && isset($cacheKeyInfo['enumType'])) {
$value = $this->buildEnum($value, $cacheKeyInfo['enumType']);
}
$rowData['scalars'][$fieldName] = $value;
break;
//case (isset($cacheKeyInfo['isMetaColumn'])):
@@ -453,6 +464,10 @@ abstract class AbstractHydrator
break;
}
if ($value !== null && isset($cacheKeyInfo['enumType'])) {
$value = $this->buildEnum($value, $cacheKeyInfo['enumType']);
}
$rowData['data'][$dqlAlias][$fieldName] = $type
? $type->convertToPHPValue($value, $this->_platform)
: $value;
@@ -536,6 +551,7 @@ abstract class AbstractHydrator
'fieldName' => $fieldName,
'type' => Type::getType($fieldMapping['type']),
'dqlAlias' => $ownerMap,
'enumType' => $this->_rsm->enumMappings[$key] ?? null,
];
// the current discriminator value must be saved in order to disambiguate fields hydration,
@@ -565,6 +581,7 @@ abstract class AbstractHydrator
'argIndex' => $mapping['argIndex'],
'objIndex' => $mapping['objIndex'],
'class' => new ReflectionClass($mapping['className']),
'enumType' => $this->_rsm->enumMappings[$key] ?? null,
];
case isset($this->_rsm->scalarMappings[$key], $this->_hints[LimitSubqueryWalker::FORCE_DBAL_TYPE_CONVERSION]):
@@ -572,6 +589,7 @@ abstract class AbstractHydrator
'fieldName' => $this->_rsm->scalarMappings[$key],
'type' => Type::getType($this->_rsm->typeMappings[$key]),
'dqlAlias' => '',
'enumType' => $this->_rsm->enumMappings[$key] ?? null,
];
case isset($this->_rsm->scalarMappings[$key]):
@@ -579,6 +597,7 @@ abstract class AbstractHydrator
'isScalar' => true,
'fieldName' => $this->_rsm->scalarMappings[$key],
'type' => Type::getType($this->_rsm->typeMappings[$key]),
'enumType' => $this->_rsm->enumMappings[$key] ?? null,
];
case isset($this->_rsm->metaMappings[$key]):
@@ -671,4 +690,21 @@ abstract class AbstractHydrator
$this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
}
/**
* @param mixed $value
* @param class-string<BackedEnum> $enumType
*
* @return BackedEnum|array<BackedEnum>
*/
private function buildEnum($value, string $enumType)
{
if (is_array($value)) {
return array_map(static function ($value) use ($enumType): BackedEnum {
return $enumType::from($value);
}, $value);
}
return $enumType::from($value);
}
}

View File

@@ -11,9 +11,7 @@ use function sprintf;
class HydrationException extends ORMException
{
/**
* @return HydrationException
*/
/** @return HydrationException */
public static function nonUniqueResult()
{
return new self('The result returned by the query was not unique.');
@@ -83,18 +81,17 @@ class HydrationException extends ORMException
}
/**
* @param string $discrValue
* @param string[] $discrMap
* @psalm-param array<string, string> $discrMap
* @param string $discrValue
* @param list<int|string> $discrValues
*
* @return HydrationException
*/
public static function invalidDiscriminatorValue($discrValue, $discrMap)
public static function invalidDiscriminatorValue($discrValue, $discrValues)
{
return new self(sprintf(
'The discriminator value "%s" is invalid. It must be one of "%s".',
$discrValue,
implode('", "', $discrMap)
implode('", "', $discrValues)
));
}
}

View File

@@ -27,9 +27,7 @@ class IterableResult implements Iterator
/** @var mixed[]|null */
private $_current = null;
/**
* @param AbstractHydrator $hydrator
*/
/** @param AbstractHydrator $hydrator */
public function __construct($hydrator)
{
$this->_hydrator = $hydrator;
@@ -65,27 +63,21 @@ class IterableResult implements Iterator
return $this->_current;
}
/**
* @return mixed
*/
/** @return mixed */
#[ReturnTypeWillChange]
public function current()
{
return $this->_current;
}
/**
* @return int
*/
/** @return int */
#[ReturnTypeWillChange]
public function key()
{
return $this->_key;
}
/**
* @return bool
*/
/** @return bool */
#[ReturnTypeWillChange]
public function valid()
{

View File

@@ -44,6 +44,9 @@ class ObjectHydrator extends AbstractHydrator
/** @var mixed[] */
private $initializedCollections = [];
/** @var array<string, PersistentCollection> */
private $uninitializedCollections = [];
/** @var mixed[] */
private $existingCollections = [];
@@ -112,10 +115,11 @@ class ObjectHydrator extends AbstractHydrator
parent::cleanup();
$this->identifierMap =
$this->initializedCollections =
$this->existingCollections =
$this->resultPointers = [];
$this->identifierMap =
$this->initializedCollections =
$this->uninitializedCollections =
$this->existingCollections =
$this->resultPointers = [];
if ($eagerLoad) {
$this->_uow->triggerEagerLoads();
@@ -126,10 +130,11 @@ class ObjectHydrator extends AbstractHydrator
protected function cleanupAfterRowIteration(): void
{
$this->identifierMap =
$this->initializedCollections =
$this->existingCollections =
$this->resultPointers = [];
$this->identifierMap =
$this->initializedCollections =
$this->uninitializedCollections =
$this->existingCollections =
$this->resultPointers = [];
}
/**
@@ -148,6 +153,12 @@ class ObjectHydrator extends AbstractHydrator
$coll->takeSnapshot();
}
foreach ($this->uninitializedCollections as $coll) {
if (! $coll->isInitialized()) {
$coll->setInitialized(true);
}
}
return $result;
}
@@ -394,8 +405,11 @@ class ObjectHydrator extends AbstractHydrator
$reflFieldValue->hydrateSet($indexValue, $element);
$this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
} else {
$reflFieldValue->hydrateAdd($element);
$reflFieldValue->last();
if (! $reflFieldValue->contains($element)) {
$reflFieldValue->hydrateAdd($element);
$reflFieldValue->last();
}
$this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key();
}
@@ -408,8 +422,8 @@ class ObjectHydrator extends AbstractHydrator
}
} elseif (! $reflFieldValue) {
$this->initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
} elseif ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) {
$reflFieldValue->setInitialized(true);
} elseif ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false && ! isset($this->uninitializedCollections[$oid . $relationField])) {
$this->uninitializedCollections[$oid . $relationField] = $reflFieldValue;
}
} else {
// PATH B: Single-valued association

View File

@@ -13,9 +13,7 @@ use function method_exists;
use function strtolower;
use function strtoupper;
/**
* @internal
*/
/** @internal */
trait SQLResultCasing
{
private function getSQLResultCasing(AbstractPlatform $platform, string $column): string

View File

@@ -11,11 +11,18 @@ use Doctrine\Common\Collections\Selectable;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use ReturnTypeWillChange;
use function assert;
/**
* A lazy collection that allows a fast count when using criteria object
* Once count gets executed once without collection being initialized, result
* is cached and returned on subsequent calls until collection gets loaded,
* then returning the number of loaded results.
*
* @template TKey of array-key
* @template TValue of object
* @extends AbstractLazyCollection<TKey, TValue>
* @implements Selectable<TKey, TValue>
*/
class LazyCriteriaCollection extends AbstractLazyCollection implements Selectable
{
@@ -72,6 +79,7 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl
* Do an optimized search of an element
*
* @param object $element
* @psalm-param TValue $element
*
* @return bool
*/
@@ -90,6 +98,7 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl
public function matching(Criteria $criteria)
{
$this->initialize();
assert($this->collection instanceof Selectable);
return $this->collection->matching($criteria);
}

View File

@@ -25,9 +25,7 @@ final class AssociationOverrides implements Annotation
*/
public $overrides = [];
/**
* @param array<AssociationOverride>|AssociationOverride $overrides
*/
/** @param array<AssociationOverride>|AssociationOverride $overrides */
public function __construct($overrides)
{
if (! is_array($overrides)) {

View File

@@ -25,9 +25,7 @@ final class AttributeOverrides implements Annotation
*/
public $overrides = [];
/**
* @param array<AttributeOverride>|AttributeOverride $overrides
*/
/** @param array<AttributeOverride>|AttributeOverride $overrides */
public function __construct($overrides)
{
if (! is_array($overrides)) {

View File

@@ -56,9 +56,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadeAll()
{
$this->mapping['cascade'] = ['ALL'];
@@ -66,9 +64,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadePersist()
{
$this->mapping['cascade'][] = 'persist';
@@ -76,9 +72,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadeRemove()
{
$this->mapping['cascade'][] = 'remove';
@@ -86,9 +80,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadeMerge()
{
$this->mapping['cascade'][] = 'merge';
@@ -96,9 +88,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadeDetach()
{
$this->mapping['cascade'][] = 'detach';
@@ -106,9 +96,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function cascadeRefresh()
{
$this->mapping['cascade'][] = 'refresh';
@@ -116,9 +104,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function fetchExtraLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EXTRA_LAZY;
@@ -126,9 +112,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function fetchEager()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EAGER;
@@ -136,9 +120,7 @@ class AssociationBuilder
return $this;
}
/**
* @return $this
*/
/** @return $this */
public function fetchLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_LAZY;

View File

@@ -4,9 +4,12 @@ declare(strict_types=1);
namespace Doctrine\ORM\Mapping\Builder;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use function get_class;
/**
* Builder Object for ClassMetadata
*
@@ -19,12 +22,21 @@ class ClassMetadataBuilder
public function __construct(ClassMetadataInfo $cm)
{
if (! $cm instanceof ClassMetadata) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/249',
'Passing an instance of %s to %s is deprecated, please pass a ClassMetadata instance instead.',
get_class($cm),
__METHOD__,
ClassMetadata::class
);
}
$this->cm = $cm;
}
/**
* @return ClassMetadataInfo
*/
/** @return ClassMetadataInfo */
public function getClassMetadata()
{
return $this->cm;

View File

@@ -17,9 +17,7 @@ class EmbeddedBuilder
/** @var mixed[] */
private $mapping;
/**
* @param mixed[] $mapping
*/
/** @param mixed[] $mapping */
public function __construct(ClassMetadataBuilder $builder, array $mapping)
{
$this->builder = $builder;

View File

@@ -31,9 +31,7 @@ class FieldBuilder
/** @var string|null */
private $customIdGenerator;
/**
* @param mixed[] $mapping
*/
/** @param mixed[] $mapping */
public function __construct(ClassMetadataBuilder $builder, array $mapping)
{
$this->builder = $builder;

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