File: README.md
Doctrine Bundle
Doctrine DBAL & ORM Bundle for the Symfony Framework.
What is Doctrine?
The Doctrine Project is the home of a selected set of PHP libraries primarily focused on providing persistence
services and related functionality. Its prize projects are a Object Relational Mapper and the Database Abstraction
Layer it is built on top of. You can read more about the projects below or view a list of all projects.
Object relational mapper (ORM) for PHP that 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 Hibernates HQL. This provides developers with a powerful
alternative to SQL that maintains flexibility without requiring unnecessary code duplication.
DBAL is a powerful database abstraction layer with many features for database schema introspection,
schema management and PDO abstraction.
Documentation
The documentation is rendered on the symfony.com website.
The source of the documentation is available in the docs folder.
File: composer.json
{
"name": "doctrine/doctrine-bundle",
"description": "Symfony DoctrineBundle",
"license": "MIT",
"type": "symfony-bundle",
"keywords": [
"DBAL",
"ORM",
"Database",
"Persistence"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]"
},
{
"name": "Benjamin Eberlei",
"email": "[email protected]"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
},
{
"name": "Doctrine Project",
"homepage": "https://www.doctrine-project.org/"
}
],
"homepage": "https://www.doctrine-project.org",
"require": {
"php": "^8.4",
"ext-mbstring": "",
"doctrine/dbal": "^4.0",
"doctrine/deprecations": "^1.0",
"doctrine/persistence": "^4",
"doctrine/sql-formatter": "^1.0.1",
"symfony/cache": "^6.4 || ^7.0 || ^8.0",
"symfony/config": "^6.4 || ^7.0 || ^8.0",
"symfony/console": "^6.4 || ^7.0 || ^8.0",
"symfony/dependency-injection": "^6.4 || ^7.0 || ^8.0",
"symfony/doctrine-bridge": "^6.4.3 || ^7.0.3 || ^8.0",
"symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/service-contracts": "^3"
},
"require-dev": {
"doctrine/coding-standard": "^14",
"doctrine/orm": "^3.4.4",
"phpstan/phpstan": "^2.1.13",
"phpstan/phpstan-phpunit": "2.0.3",
"phpstan/phpstan-strict-rules": "^2",
"phpstan/phpstan-symfony": "^2.0.9",
"phpunit/phpunit": "^12.3.10",
"psr/log": "^3.0",
"symfony/doctrine-messenger": "^6.4 || ^7.0 || ^8.0",
"symfony/expression-language": "^6.4 || ^7.0 || ^8.0",
"symfony/http-kernel": "^6.4 || ^7.0 || ^8.0",
"symfony/lock": "^6.4 || ^7.0 || ^8.0",
"symfony/messenger": "^6.4 || ^7.0 || ^8.0",
"symfony/property-info": "^6.4 || ^7.0 || ^8.0",
"symfony/runtime": "^6.4 || ^7.0 || ^8.0",
"symfony/security-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/stopwatch": "^6.4 || ^7.0 || ^8.0",
"symfony/string": "^6.4 || ^7.0 || ^8.0",
"symfony/twig-bridge": "^6.4 || ^7.0 || ^8.0",
"symfony/validator": "^6.4 || ^7.0 || ^8.0",
"symfony/web-profiler-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/yaml": "^6.4 || ^7.0 || ^8.0",
"twig/twig": "^3.21.1 || ^4"
},
"conflict": {
"doctrine/orm": "<3.0 || >=4.0",
"twig/twig": "<3.0.4 || >=5"
},
"suggest": {
"ext-pdo": "",
"doctrine/orm": "The Doctrine ORM integration is optional in the bundle.",
"symfony/web-profiler-bundle": "To use the data collector."
},
"minimum-stability": "dev",
"autoload": {
"psr-4": {
"Doctrine\Bundle\DoctrineBundle\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Doctrine\Bundle\DoctrineBundle\Tests\": "tests",
"Fixtures\": "tests/DependencyInjection/Fixtures"
}
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"symfony/flex": true,
"symfony/runtime": false
},
"sort-packages": true
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
}
}
}
File: SECURITY.md
Security
If you find a Security bug in Doctrine, please follow our
Security reporting guidelines.
Security vulnerabilities should be reported to [email protected]
and not posted on the GitHub issue tracker of the project.
File: UPGRADE-2.10.md
UPGRADE FROM 2.9 to 2.10
Configuration
Preparing for a new `report_fields_where_declared` mapping driver mode
Doctrine ORM 2.16+ makes a change to how the annotations and attribute mapping drivers report fields inherited from parent classes. For details, see https://github.com/doctrine/orm/pull/10455. It will trigger a deprecation notice unless the new mode is activated. In ORM 3.0, the new mode will be the only one.
The new mode does not should not make a difference for regular, valid use cases, but may lead to MappingExceptions for users with certain configurations that were not meant to be supported by the ORM in the first place. To avoid surprising users (even when their configuration is invalid) during a 2.16 minor version upgrade, the transition to this new mode was implemented as an opt-in. This way, you can try and deal with the change any time you see fit.
In version 2.10+ of this bundle, a new configuration setting report_fields_where_declared was added at the entity manager configuration level. Set it to true to switch the mapping driver for the corresponding entity manager to the new mode. It is only relevant for mapping configurations using attributes or annotations.
Unless you set it to true, Doctrine ORM will emit deprecation messages mentioning this new setting.
Preparing for the XSD validation for XML drivers
Doctrine ORM 2.14+ adds support for validating the XSD of XML mapping files. In ORM 3.0, this validation will be mandatory.
As the ecosystem is known to rely on custom elements in the XML mapping files that are forbidden when validating the XSD (for instance when using gedmo/doctrine-extensions), this validation is opt-in thanks to a validate_xml_mapping setting at the entity manager configuration level.
Unless you set it to true, Doctrine ORM will emit deprecation messages mentioning the XSD validation.
Deprecations
Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterfacehas been deprecated. Use the#[AsDoctrineListener]attribute instead.
File: UPGRADE-2.12.md
UPGRADE FROM 2.11 to 2.12
Configuration
Controller resolver auto mapping default configuration will be changed
The default value of doctrine.orm.controller_resolver.auto_mapping will be changed from true to false in 3.0.
Auto mapping uses any route parameter that matches with a field name of the Entity to resolve as criteria in a find by query.
If you are relying on this functionality, you will need to configure it explicitly to silence the deprecation notice.
File: UPGRADE-2.13.md
UPGRADE FROM 2.12 to 2.13
Configuration
Controller resolver auto mapping deprecated
The controller resolver auto mapping functionality has been deprecated with Symfony 7.1, and is replaced with explicit mapped route parameters. Enabling the auto mapper by default using this bundle is now deprecated as well.
Auto mapping uses any route parameter that matches with a field name of the Entity to resolve as criteria in a find by query.
If you are relying on this functionality, you can update your code to use explicit mapped route parameters instead.
File: UPGRADE-2.17.md
UPGRADE FROM 2.16 to 2.17
DoctrineExtension
Minor breaking change:Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension no
longer extendsSymfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension.
Configuration
The `doctrine.orm.entity_managers.some_em.report_fields_where_declared` configuration option is deprecated
This option is a no-op when using doctrine/orm 3 and has been conditionally
deprecated. You should stop using it as soon as you upgrade to Doctrine ORM 3.
The `doctrine.dbal.connections.some_connection.disable_type_comments` configuration option is deprecated
This option is a no-op when using doctrine/dbal 4 and has been conditionally
deprecated. You should stop using it as soon as you upgrade to Doctrine DBAL 4.
The `doctrine.dbal.connections.some_connection.use_savepoints` configuration option is deprecated
This option is a no-op when using doctrine/dbal 4 and has been conditionally
deprecated. You should stop using it as soon as you upgrade to Doctrine DBAL 4.
ConnectionFactory::createConnection() signature change
The signature of ConnectionFactory::createConnection() will change with
version 3.0 of the bundle.
As soon as you upgrade to Doctrine DBAL 4, you should use stop passing an event
manager argument.
- $connectionFactory->createConnection($params, $config, $eventManager, $mappingTypes)
+ $connectionFactory->createConnection($params, $config, $mappingTypes)As a small breaking change, it is no longer fully possible to use named
arguments with that method until 3.0.
File: UPGRADE-2.18.md
UPGRADE FROM 2.17 to 2.18
DoctrineOrmMappingsPass
The `DoctrineOrmMappingsPass::createYamlMappingDriver()` method is deprecated
This method is deprecated with no replacement planned and will be removed in
DoctrineBundle 3.0.
The `DoctrineOrmMappingsPass::createAnnotationMappingDriver()` method is deprecated
This method is deprecated with no replacement planned and will be removed in
DoctrineBundle 3.0.
File: UPGRADE-2.19.md
UPGRADE FROM 2.18 to 2.19
Configuration
BC Break: Native return type on Twig extension
A native return type array has been added toDoctrine\Bundle\DoctrineBundle\Twig\DoctrineExtension. That class is not
meant to be extended, but if a downstream project did that, the return type
needs to be added there as well.
Proxy-related configuration settings are conditionally deprecated
When using PHP 8.4 or higher in combination with Doctrine ORM 3.4 or
higher, the following configuration settings are deprecated:
auto_generate_proxy_classesproxy_namespaceproxy_dir
Instead, they should be unset, and enable_native_lazy_objects should
be set to true.
File: UPGRADE-3.0.md
UPGRADE FROM 2.x to 3.0
Compatibility
Configuring caching options to use services backed by doctrine/cache is no
longer supported. Migrate to PSR-6 services instead.
The minimum required PHP version is now 8.4.
Support for the following major versions of the following packages has been dropped:
doctrine/dbal3doctrine/persistence3doctrine/orm2psr/log1 and 2twig/twig2
More details below
Support for `doctrine/orm` 2 is dropped
This makes DisconnectedMetadataFactory redundant, as it relies on code
available only in doctrine/orm 2. It has been removed, as well asClassMetadataConnection.
Support for the YML and annotation metadata drivers has been dropped.
Doctrine\Bundle\DoctrineBundle\Repository\LazyServiceEntityRepository has
been removed without replacement.
Commands
All command classes in the Doctrine\Bundle\DoctrineBundle\Command\Proxy
namespace have been removed. Use the original commands provided by Doctrine
DBAL and ORM directly.
doctrine:query:sql has been removed. Use dbal:run-sql instead. All other
commands use the original command classes directly.
doctrine:mapping:convert and doctrine:ensure-production-settings have been
removed and do not have replacements.
Doctrine\Bundle\DoctrineBundle\Command\ImportMappingCommand has been removed
and does not have a replacement.
Configuration
no-op configuration options removed
The following configuration options are no-ops when using doctrine/orm 3 and
have been removed:
doctrine.orm.entity_managers.some_em.report_fields_where_declareddoctrine.orm.enable_lazy_ghost_objects
Also, the 3 following options were no-ops when enabling native lazy objects
and have been removed as well:
doctrine.orm.auto_generate_proxy_classesdoctrine.orm.proxy_dirdoctrine.orm.proxy_namespace
The `doctrine.dbal.default_table_options.collate` default table option is removed
Use doctrine.dbal.default_table_options.collation instead.
The `doctrine.dbal.override_url` option is removed
There is no replacement for this option.
The `doctrine.dbal.types.some_custom_type.commented` option is removed
The commented option for custom types is no longer supported and has been
removed.
The `doctrine.dbal.connection.some_connection.disable_type_comments` option is removed
The disable_type_comments option for connections is no longer supported and has
been removed.
The `doctrine.dbal.connection.some_connection.platform_service` option is removed
The platform_service option for connections is no longer supported and has
been removed.
The `doctrine.dbal.connection.some_connection.keep_slave` and `doctrine.dbal.connection.some_connection.slaves` option is removed
doctrine.dbal.connection.some_connection.slaves becomesdoctrine.dbal.connection.some_connection.replicas.
The `doctrine.dbal.connection.some_connection.use_savepoints` option is removed
The use_savepoints option for connections is no longer supported and
has been removed.
Controller resolver auto mapping can no longer be configured
The doctrine.orm.controller_resolver.auto_mapping option now only accepts false as value, to disallow the usage of the controller resolver auto mapping feature by default. The configuration option will be fully removed in 4.0.
Auto mapping used any route parameter that matches with a field name of the Entity to resolve as criteria in a find by query. This method has been deprecated in Symfony 7.1 and is replaced with mapped route parameters.
If you were relying on this functionality, you will need to update your code to use explicit mapped route parameters instead.
URL overrides are no longer allowed
When using the doctrine.dbal.url configuration option, you can no longer
specify other configuration options that would conflict with it, such asdbname, host, etc.
Service class parameters removed
The following service class parameters have been removed:
doctrine.classdoctrine.data_collector.classdoctrine.dbal.configuration.classdoctrine.dbal.connection.event_manager.classdoctrine.dbal.connection_factory.classdoctrine.orm.configuration.classdoctrine.orm.entity_listener_resolver.classdoctrine.orm.entity_manager.classdoctrine.orm.listeners.attach_entity_listeners.classdoctrine.orm.listeners.resolve_target_entity.classdoctrine.orm.manager_configurator.classdoctrine.orm.metadata.attribute.classdoctrine.orm.metadata.driver_chain.classdoctrine.orm.metadata.php.classdoctrine.orm.metadata.staticphp.classdoctrine.orm.metadata.xml.classdoctrine.orm.naming_strategy.default.classdoctrine.orm.naming_strategy.underscore.classdoctrine.orm.quote_strategy.ansi.classdoctrine.orm.quote_strategy.default.classdoctrine.orm.second_level_cache.cache_configuration.classdoctrine.orm.second_level_cache.default_cache_factory.classdoctrine.orm.second_level_cache.default_region.classdoctrine.orm.second_level_cache.filelock_region.classdoctrine.orm.second_level_cache.logger_chain.classdoctrine.orm.second_level_cache.logger_statistics.classdoctrine.orm.second_level_cache.regions_configuration.classdoctrine.orm.security.user.provider.classdoctrine.orm.typed_field_mapper.default.classdoctrine.orm.validator.unique.classdoctrine.orm.validator_initializer.classform.type_guesser.doctrine.class
If your application was relying on these parameters, you should update your
service definitions to use the class names directly instead of parameter
references.
ConnectionFactory::createConnection() signature change
The signature of ConnectionFactory::createConnection() changed.
You should use stop passing an event manager argument.
- $connectionFactory->createConnection($params, $config, $eventManager, $mappingTypes)
+ $connectionFactory->createConnection($params, $config, $mappingTypes)DependencyInjection namespace becomes internal
The Doctrine\Bundle\DoctrineBundle\DependencyInjection namespace is now
considered internal, and all classes inside it are marked as final, except forDoctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineORMMappingsPass.
Don't reference any classes from this namespace directly, except the one
mentioned earlier.
`Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventListenerInterface` has been removed
Use the #[Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener]
attribute instead.
`Doctrine\Bundle\DoctrineBundle\Dbal\BlacklistSchemaAssetsFilter` has been removed
Implement your own include/exclude mechanism instead.
Type declarations
Native type declarations have been added to all constants, properties, and
methods.
Twig filters
The Twig filter doctrine_pretty_query has been removed.
File: UPGRADE-3.1.md
UPGRADE FROM 3.0 to 3.1
Configuration
The doctrine.orm.controller_resolver.auto_mapping only accepts false
as value since 3.0 and supplying the value explicitly is now marked as
deprecated.
The doctrine.orm.entity_managers.some_em.enable_native_lazy_objects
configuration option is deprecated and will be removed in DoctrineBundle 4.0,
as native lazy objects are now always enabled.
File: UPGRADE-3.2.md
UPGRADE FROM 3.1 to 3.2
DoctrineOrmMappingsPass
The $aliasMap argument of the DoctrineOrmMappingsPass class and methods
is removed. Namespace aliases are no longer supported in Doctrine.
File: .doctrine-project.json
{
"active": true,
"name": "Doctrine Bundle",
"shortName": "DoctrineBundle",
"slug": "doctrine-bundle",
"versions": [
{
"name": "4.0",
"branchName": "4.0.x",
"slug": "latest",
"upcoming": true
},
{
"name": "3.4",
"branchName": "3.4.x",
"slug": "3.4",
"upcoming": true
},
{
"name": "3.3",
"branchName": "3.3.x",
"slug": "3.3",
"current": true
},
{
"name": "3.2",
"slug": "3.2",
"maintained": false
},
{
"name": "3.1",
"slug": "3.1",
"maintained": false
},
{
"name": "3.0",
"slug": "3.0",
"maintained": false
},
{
"name": "2.19",
"branchName": "2.19.x",
"slug": "2.19",
"maintained": true
},
{
"name": "2.18",
"slug": "2.18",
"maintained": false
},
{
"name": "2.16",
"slug": "2.16",
"maintained": false
},
{
"name": "2.15",
"slug": "2.15",
"maintained": false
},
{
"name": "2.14",
"slug": "2.14",
"maintained": false
},
{
"name": "2.13",
"slug": "2.13",
"maintained": false
},
{
"name": "2.12",
"slug": "2.12",
"maintained": false
},
{
"name": "2.11",
"slug": "2.11",
"maintained": false
},
{
"name": "2.10",
"slug": "2.10",
"maintained": false
},
{
"name": "2.7",
"slug": "2.7",
"maintained": false
},
{
"name": "2.6",
"slug": "2.6",
"maintained": false
},
{
"name": "2.0",
"slug": "2.0",
"maintained": false
},
{
"name": "1.12",
"slug": "1.12",
"maintained": false
}
]
}
File: .symfony.bundle.yaml
branches:
- "2.6.x"
- "2.7.x"
- "2.10.x"
- "2.11.x"
- "2.12.x"
- "2.13.x"
- "2.14.x"
- "2.15.x"
- "2.16.x"
- "2.18.x"
- "2.19.x"
- "3.0.x"
- "3.1.x"
- "3.2.x"
- "3.3.x"
- "4.0.x"
maintained_branches:
- "2.18.x"
- "2.19.x"
- "3.2.x"
- "3.3.x"
- "4.0.x"
doc_dir: "docs/en/"
current_branch: "3.2.x"
dev_branch: "3.3.x"
File: docs/composer.json
{
"require-dev": {
"doctrine/docs-builder": "^1.0"
},
"config": {
"sort-packages": true
}
}
File: docs/en/custom-id-generators.rst
Custom ID Generators
Custom ID generators are classes that allow implementing custom logic to generate
identifiers for your entities. They extend Doctrine\ORM\Id\AbstractIdGenerator
and implement the custom logic in the generate(EntityManager $em, $entity)
method. Before Doctrine bundle 2.3, custom ID generators were always created
without any constructor arguments.
Starting with Doctrine bundle 2.3, the CustomIdGenerator attribute can be
used to reference any services tagged with the doctrine.id_generator tag.
If you enable autoconfiguration (which is the default most of the time), Symfony
will add this tag for you automatically if you implement your own id-generators.
When using Symfony's Doctrine bridge and Uid component 5.3 or higher, two services
are provided: doctrine.ulid_generator to generate ULIDs, anddoctrine.uuid_generator to generate UUIDs.
.. code-block:: php
<?php
// User.php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class User
{
#[ORM\Id]
#[ORM\Column(type: 'uuid')]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator('doctrine.uuid_generator')]
private $id;
// ....
}See also
https://www.doctrine-project.org/projects/doctrine-orm/en/3.3/reference/attributes-reference.html#attrref_customidgenerator
for more info about custom ID generators.
File: docs/en/dbal-type.rst
DBAL Types
Custom DBAL types can be registered using the AsDbalType attribute. This
attribute allows you to define a name for your custom type directly in the class
definition. If the name is not provided, the class name will be used as the default.
To register a custom DBAL type, create a class that extendsDoctrine\DBAL\Types\Type and add the #[AsDbalType] attribute to it:
.. code-block:: php
namespace App\Doctrine\Type;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDbalType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
#[AsDbalType(name: 'money')]
class MoneyType extends Type
{
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getDecimalTypeDeclarationSQL($column);
}
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
{
return $value;
}
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): mixed
{
return $value;
}
}When using the AsDbalType attribute, the type will be automatically
registered with Doctrine.
Manual Registration
Alternatively, you can register custom types in your configuration:
.. configuration-block::
.. code-block:: yaml
# config/packages/doctrine.yaml
doctrine:
dbal:
types:
money: App\Doctrine\Type\MoneyType
.. code-block:: xml
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:doctrine="http://symfony.com/schema/dic/doctrine"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/doctrine
http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">
<doctrine:config>
<doctrine:dbal>
<doctrine:type name="money">App\Doctrine\Type\MoneyType</doctrine:type>
</doctrine:dbal>
</doctrine:config>
</container>
.. code-block:: php
// config/packages/doctrine.php
use App\Doctrine\Type\MoneyType;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('doctrine', [
'dbal' => [
'types' => [
'money' => MoneyType::class,
],
],
]);
};File: docs/en/doctrine-console.rst
Doctrine Console
Some Doctrine packages such as doctrine/dbal and doctrine/orm
provide useful console commands to interact with your database and your
entities:
Doctrine DBAL Commands <https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/cli-tools.html#cli-tools>_Doctrine ORM Commands <https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/tools.html#doctrine-console>_
This bundle automatically registers those commands, but it renames them
in the process so as to group them under the doctrine: namespace.
Note that the bundle also provide some additional commands that are not
part of the aforementioned packages.
Command Name Mapping
The following table shows the mapping between the original Doctrine command
names and the names used by this bundle:
+--------------------------------------------+---------------------------------------+
| Bundle Command Name | Original Doctrine Command Name |
+============================================+=======================================+
| doctrine:cache:clear-metadata | orm:clear-cache:metadata |
+--------------------------------------------+---------------------------------------+
| doctrine:cache:clear-query | orm:clear-cache:query |
+--------------------------------------------+---------------------------------------+
| doctrine:cache:clear-result | orm:clear-cache:result |
+--------------------------------------------+---------------------------------------+
| doctrine:cache:clear-collection-region | orm:clear-cache:region:collection |
+--------------------------------------------+---------------------------------------+
| doctrine:cache:clear-entity-region | orm:clear-cache:region:entity |
+--------------------------------------------+---------------------------------------+
| doctrine:cache:clear-query-region | orm:clear-cache:region:query |
+--------------------------------------------+---------------------------------------+
| doctrine:schema:create | orm:schema-tool:create |
+--------------------------------------------+---------------------------------------+
| doctrine:schema:drop | orm:schema-tool:drop |
+--------------------------------------------+---------------------------------------+
| doctrine:schema:update | orm:schema-tool:update |
+--------------------------------------------+---------------------------------------+
| doctrine:mapping:info | orm:info |
+--------------------------------------------+---------------------------------------+
| doctrine:mapping:describe | orm:mapping:describe |
+--------------------------------------------+---------------------------------------+
| doctrine:query:dql | orm:run-dql |
+--------------------------------------------+---------------------------------------+
| doctrine:schema:validate | orm:validate-schema |
+--------------------------------------------+---------------------------------------+
Additionally, the bundle provides the following commands:
doctrine:database:createdoctrine:database:drop
To get a list of all available Doctrine commands, run:
.. code-block:: console
php bin/console list doctrineIt is possible to get help on any specific command. For example,
to get help on the doctrine:schema:update command, run:
.. code-block:: console
php bin/console doctrine:schema:update --helpFile: docs/en/entity-listeners.rst
Entity Listeners
Entity listeners that are services must be registered with the entity listener
resolver. On top of the attribute in the entity class, you have to tag the
service with doctrine.orm.entity_listener for it to be automatically added
to the resolver. Use the (optional) entity_manager attribute to specify
which entity manager it should be registered with.
Full example:
.. code-block:: php
<?php
// User.php
use Doctrine\ORM\Mapping as ORM;
use App\UserListener;
#[ORM\Entity]
#[ORM\EntityListeners([UserListener::class])]
class User
{
// ....
}.. configuration-block::
.. code-block:: yaml
services:
App\UserListener:
tags:
# Minimal configuration below
- { name: doctrine.orm.entity_listener }
# Or, optionally, you can give the entity manager name as below
#- { name: doctrine.orm.entity_listener, entity_manager: custom }
.. code-block:: php
// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use App\UserListener;
return static function (ContainerConfigurator $configurator) {
$services = $configurator->services();
// Minimal configuration below
$services->set(UserListener::class)
->tag('doctrine.orm.entity_listener')
;
// Or, optionally, you can give the entity manager name as below
// $services->set(UserListener::class)
// ->tag('doctrine.orm.entity_listener', ['entity_manager' => 'custom'])
// ;
};Starting with doctrine/orm 2.5 and Doctrine bundle 1.5.2, instead of registering
the entity listener on the entity, you can declare all options from the service
definition:
.. configuration-block::
.. code-block:: yaml
services:
App\UserListener:
tags:
-
name: doctrine.orm.entity_listener
event: preUpdate
entity: App\Entity\User
# entity_manager attribute is optional
entity_manager: custom
# method attribute is optional
method: validateEmail
.. code-block:: php
// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use App\UserListener;
return static function (ContainerConfigurator $configurator) {
$services = $configurator->services();
$services->set(UserListener::class)
->tag('doctrine.orm.entity_listener', [
'event' => 'preUpdate',
'entity' => 'App\Entity\User',
// entity_manager attribute is optional
'entity_manager' => 'custom',
// method attribute is optional
'method' => 'validateEmail',
])
;
};The event attribute is required if the entity listener is not registered on
the entity. If you don't specify the method attribute, it falls back on the
subscribed event name.
Starting with Doctrine bundle 1.12, if this method does not exist but if your entity listener is invokable, it falls
back on the __invoke() method.
See also
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#entity-listeners
for more info on entity listeners and the resolver required by Symfony.
File: docs/en/event-listeners.rst
Event Listeners
In opposite to :doc:Entity Listeners </entity-listeners>, Event listeners
are services that listen for all entities in your application.
See https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#implementing-event-listeners
for more info on event listeners.
To register a service to act as an event listener you have to tag it with thedoctrine.event_listener tag:
Starting with Doctrine bundle 2.8, you can use the AsDoctrineListener
attribute to tag the service.
.. configuration-block::
.. code-block:: php-attributes
// src/App/EventListener/SearchIndexer.php
namespace App\EventListener;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
#[AsDoctrineListener('postPersist'/*, 500, 'default'*/)]
class SearchIndexer
{
public function postPersist(LifecycleEventArgs $event): void
{
// ...
}
}
.. code-block:: yaml
# config/services.yaml
services:
# ...
App\EventListener\SearchIndexer:
tags:
-
name: 'doctrine.event_listener'
# this is the only required option for the lifecycle listener tag
event: 'postPersist'
# listeners can define their priority in case multiple subscribers or listeners are associated
# to the same event (default priority = 0; higher numbers = listener is run earlier)
priority: 500
# you can also restrict listeners to a specific Doctrine connection
connection: 'default'
.. code-block:: php
// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use App\EventListener\SearchIndexer;
return static function (ContainerConfigurator $configurator) {
$services = $configurator->services();
// listeners are applied by default to all Doctrine connections
$services->set(SearchIndexer::class)
->tag('doctrine.event_listener', [
// this is the only required option for the lifecycle listener tag
'event' => 'postPersist',
// listeners can define their priority in case multiple subscribers or listeners are associated
// to the same event (default priority = 0; higher numbers = listener is run earlier)
'priority' => 500,
// you can also restrict listeners to a specific Doctrine connection
'connection' => 'default',
])
;
};File: docs/en/index.rst
DoctrineBundle
Integrates Doctrine's ORM and DBAL projects into Symfony applications. It provides
configuration options, console commands and even a web debug toolbar collector.
.. toctree::
installation
doctrine-console
dbal-type
entity-listeners
event-listeners
custom-id-generators
middlewares
configurationFile: docs/en/installation.rst
Installation
Step 1: Download the Bundle
Open a command console, enter your project directory and execute the following
command to download the latest stable version of this bundle:
.. code-block:: bash
$ composer require doctrine/doctrine-bundleThis command requires you to have Composer installed globally, as explained
in the installation chapter_ of the Composer documentation.
Step 2: Enable the Bundle
Your bundle should be automatically enabled by Flex.
In case you don't use Flex, you'll need to manually enable the bundle by
adding the following line in the config/bundles.php file of your project::
<?php
// config/bundles.php
return [
// ...
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
// ...
];If you don't have a config/bundles.php file in your project, chances are that
you're using an older Symfony version. In this case, you should have anapp/AppKernel.php file instead. Edit such file::
<?php
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
// ...
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
];
// ...
}
// ...
}.. _installation chapter: https://getcomposer.org/doc/00-intro.md
File: docs/en/middlewares.rst
Middlewares
Doctrine DBAL supports middlewares. According to the DBAL documentation_:
"A middleware sits in the middle between the wrapper components and the driver"They allow to decorate the following DBAL classes:
Doctrine\DBAL\DriverDoctrine\DBAL\Driver\ConnectionDoctrine\DBAL\Driver\StatementDoctrine\DBAL\Driver\Result
Symfony, for instance, uses a middleware to harvest the queries executed
by the current page and make them available in the profiler.
.. _DBAL documentation: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/architecture.html#middlewares
You can also create your own middleware. This is an example of a (very)
simple middleware that prevents database connections with the root user.
The first step is to create the middleware:
.. code-block:: php
<?php
namespace App\Middleware;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Middleware;
class PreventRootConnectionMiddleware implements Middleware
{
public function wrap(Driver $driver): Driver
{
return new PreventRootConnectionDriver($driver);
}
}As you can see in the wrap method, the principle of a middleware is
to decorate Doctrine objects with your own objects bearing the logic you
need. Now, the connect method of the driver must be decorated inPreventRootConnectionDriver to prevent connections with the root user:
.. code-block:: php
<?php
namespace App\Middleware;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
use SensitiveParameter;
final class PreventRootConnectionDriver extends AbstractDriverMiddleware
{
public function connect(array $params): Connection
{
if (isset($params['user']) && $params['user'] === 'root') {
throw new \LogicException('Connecting to the database with the root user is not allowed.');
}
return parent::connect($params);
}
}That's all! Connection with the root user is not possible anymore. Note
that connect is not the only method you can decorate in a Connection.
But thanks to the AbstractDriverMiddleware default implementation,
you only need to decorate the methods for which you want to add some logic.
Too see a more advanced example with a decoration of the Statement class,
you can look at the middleware implementation starting in the classSymfony\Bridge\Doctrine\Middleware\Debug\Middleware of the
Doctrine Bridge. Decorating the Result class follows the same principle.
The middleware we've just created applies by default to all the connections.
If your application has several dbal connections, you can limit the middleware
scope to a subset of connections thanks to the AsMiddleware PHP attribute.
Let's limit our middleware to a connection named legacy:
.. code-block:: php
<?php
namespace App\Middleware;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsMiddleware;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Middleware;
#[AsMiddleware(connections: ['legacy'])]
class PreventRootConnectionMiddleware implements Middleware
{
public function wrap(Driver $driver): Driver
{
return new PreventRootConnectionDriver($driver);
}
}If you register multiple middlewares in your application, they will be executed
in the order they were registered. If some middleware needs to be executed
before another, you can set priority through the AsMiddleware PHP attribute.
This priority can be any integer, positive or negative. The higher the priority,
the earlier the middleware is executed. If no priority is defined, the priority
is considered 0. Let's make sure our middleware is the first middleware
executed, so that we don't set up debugging or logging if the connection will
be prevented:
.. code-block:: php
<?php
namespace App\Middleware;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsMiddleware;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Middleware;
#[AsMiddleware(priority: 10)]
class PreventRootConnectionMiddleware implements Middleware
{
public function wrap(Driver $driver): Driver
{
return new PreventRootConnectionDriver($driver);
}
}priority and connections can be used together to restrict a middleware
to a specific connection while changing its priority.
All the examples presented above assume autoconfigure is enabled.
If autoconfigure is disabled, the doctrine.middleware tag must be
added to the middleware. This tag supports a connections attribute to
limit the scope of the middleware and a priority attribute to change
the execution order of the registered middlewares.
.. note::
Middlewares have been introduced in version 3.2 of ``doctrine/dbal``
and at least the 2.6 version of ``doctrine/doctrine-bundle`` is needed
to integrate them in Symfony as shown above.File: tests/DependencyInjection/Fixtures/config/yml/dbal_auto_commit.yml
doctrine:
dbal:
auto_commit: false
File: tests/DependencyInjection/Fixtures/config/yml/dbal_collect_schema_errors_disable.yml
doctrine:
dbal:
default_connection: mysql
connections:
profile_without_schema_validator:
logging: false
profiling: true
profiling_collect_schema_errors: false
File: tests/DependencyInjection/Fixtures/config/yml/dbal_collect_schema_errors_disable_no_profiling.yml
doctrine:
dbal:
default_connection: mysql
connections:
profile_without_schema_validator_no_profiling:
logging: false
profiling: false
profiling_collect_schema_errors: false
File: tests/DependencyInjection/Fixtures/config/yml/dbal_collect_schema_errors_enable.yml
doctrine:
dbal:
default_connection: mysql
connections:
profile_with_schema_validator:
logging: false
profiling: true
profiling_collect_schema_errors: true
File: tests/DependencyInjection/Fixtures/config/yml/dbal_dbname_suffix.yml
doctrine:
dbal:
url: 'mysql://root:password@database:3306/main?serverVersion=mariadb-12.1.1'
dbname_suffix: _test
File: tests/DependencyInjection/Fixtures/config/yml/dbal_driver_schemes.yml
doctrine:
dbal:
url: 'mysql://root:password@database:3306/main?serverVersion=mariadb-12.1.1'
driver_schemes:
postgresql: pgsql
my-scheme: my_driver
File: tests/DependencyInjection/Fixtures/config/yml/dbal_logging.yml
doctrine:
dbal:
default_connection: mysql
connections:
log:
logging: true
profiling: false
profile:
logging: false
profiling: true
profile_with_backtrace:
logging: false
profiling: true
profiling_collect_backtrace: true
backtrace_without_profile:
logging: false
profiling: false
profiling_collect_backtrace: true
both:
logging: true
profiling: true
profile_without_schema_validator:
logging: false
profiling: true
profiling_collect_schema_errors: true
File: tests/DependencyInjection/Fixtures/config/yml/dbal_oracle_connectstring.yml
doctrine:
dbal:
connectstring: scott@sales-server:1521/sales.us.example.com
File: tests/DependencyInjection/Fixtures/config/yml/dbal_oracle_instancename.yml
doctrine:
dbal:
instancename: mySuperInstance
File: tests/DependencyInjection/Fixtures/config/yml/dbal_result_cache.yml
doctrine:
dbal:
default_connection: connection_with_cache
connections:
connection_with_cache:
result_cache: example.cache
connection_without_cache: ~
File: tests/DependencyInjection/Fixtures/config/yml/dbal_schema_filter.yml
doctrine:
dbal:
default_connection: connection1
connections:
connection1:
schema_filter: ^(?!t_)
server_version: 9.4.0
connection2:
server_version: 9.4.0
connection3:
server_version: 9.4.0
File: tests/DependencyInjection/Fixtures/config/yml/dbal_schema_manager_factory.yml
doctrine:
dbal:
default_connection: custom_schema_manager_factory
connections:
default_schema_manager_factory: ~
custom_schema_manager_factory:
schema_manager_factory: custom_factory
File: tests/DependencyInjection/Fixtures/config/yml/dbal_service_multiple_connections.yml
doctrine:
dbal:
default_connection: mysql
connections:
mysql:
dbname: mysql_db
user: mysql_user
password: mysql_s3cr3t
unix_socket: /path/to/mysqld.sock
sqlite:
driver: pdo_sqlite
dbname: sqlite_db
user: sqlite_user
password: sqlite_s3cr3t
path: /tmp/db.sqlite
memory: true
options:
userDefinedFunctions:
asin:
callback: 'asin'
numArgs: 1
arbitraryValue: foo
oci:
driver: oci8
dbname: oracle_db
user: oracle_user
password: oracle_s3cr3t
servicename: oracle_service
service: true
pooled: true
charset: utf8
ibmdb2:
driver: ibm_db2
dbname: ibmdb2_db
user: ibmdb2_user
password: ibmdb2_s3cr3t
protocol: TCPIP
pgsql:
driver: pdo_pgsql
dbname: pgsql_schema
user: pgsql_user
password: pgsql_s3cr3t
default_dbname: pgsql_db
sslmode: require
sslrootcert: postgresql-ca.pem
sslcert: postgresql-cert.pem
sslkey: postgresql-key.pem
sslcrl: postgresql.crl
charset: utf8
sqlanywhere:
driver: sqlanywhere
host: localhost
port: 2683
server: sqlanywhere_server
dbname: sqlanywhere_db
user: sqlanywhere_user
password: sqlanywhere_s3cr3t
persistent: true
charset: utf8
File: tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_connection.yml
doctrine:
dbal:
dbname: mysql_db
user: mysql_user
password: mysql_s3cr3t
unix_socket: /path/to/mysqld.sock
server_version: 9.4.0
File: tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_primary_replica_connection.yml
doctrine:
dbal:
dbname: mysql_db
user: mysql_user
password: mysql_s3cr3t
unix_socket: /path/to/mysqld.sock
keep_replica: true
default_table_options:
engine: InnoDB
options:
!php/const PDO::ATTR_STRINGIFY_FETCHES: 1
replicas:
replica1:
user: replica_user
dbname: replica_db
password: replica_s3cr3t
unix_socket: /path/to/mysqld_replica.sock
File: tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml
doctrine:
dbal:
default_connection: default
types:
test: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType
connections:
default: ~
File: tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
entity_managers:
default:
entity_listeners:
ExternalBundles\Entities\FooEntity:
MyBundles\Listeners\FooEntityListener:
prePersist:
postPersist: [postPersist]
postLoad: [postLoadHandler]
ExternalBundles\Entities\BarEntity:
MyBundles\Listeners\BarEntityListener:
prePersist: [prePersist, prePersistHandler]
MyBundles\Listeners\LogDeleteEntityListener:
postDelete: [postDelete]File: tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener_tag.yml
services:
entity_listener1:
class: EntityListener1
tags:
- { name: doctrine.orm.entity_listener, entity: My/Entity1, event: postLoad }
entity_listener2:
class: EntityListener2
tags:
- { name: doctrine.orm.entity_listener, entity_manager: em2, entity: My/Entity2, event: preFlush, method: preFlushHandler }
invokable_entity_listener:
class: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener
tags:
- { name: doctrine.orm.entity_listener, entity: My/Entity1, event: loadClassMetadata }
- { name: doctrine.orm.entity_listener, entity: My/Entity1, event: postPersist }
grand_parent_entity_listener:
class: GrandParentEntityListener
parent_entity_listener:
parent: grand_parent_entity_listener
class: ParentEntityListener
children_entity_listener:
parent: parent_entity_listener
tags:
- { name: doctrine.orm.entity_listener, entity: My/Entity3, event: postLoad, priority: 1 }doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
em2:File: tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listeners_two_connections.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
foobar:
dbname: foobar
orm:
default_entity_manager: em1
entity_managers:
em1:
connection: default
em2:
connection: foobarFile: tests/DependencyInjection/Fixtures/config/yml/orm_attach_lazy_entity_listener.yml
services:
custom_entity_listener_resolver:
class: Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver
arguments:
- '@service_container'
entity_listener1:
class: EntityListener1
tags:
- { name: doctrine.orm.entity_listener, lazy: true }
entity_listener2:
class: EntityListener2
tags:
- { name: doctrine.orm.entity_listener, entity_manager: em2, lazy: true }
entity_listener3:
class: EntityListener3
tags:
- { name: doctrine.orm.entity_listener, lazy: false }
entity_listener4:
class: EntityListener4
tags:
- { name: doctrine.orm.entity_listener }doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
em2:
entity_listener_resolver: custom_entity_listener_resolverFile: tests/DependencyInjection/Fixtures/config/yml/orm_caches.yml
services:
cache.psr6:
class: Symfony\Component\Cache\Adapter\ArrayAdapter
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
server_version: 9.4.0
orm:
default_entity_manager: metadata_cache_none
entity_managers:
metadata_cache_none: ~
metadata_cache_pool:
metadata_cache_driver:
type: pool
pool: cache.psr6
metadata_cache_service_psr6:
metadata_cache_driver:
type: service
id: cache.psr6
query_cache_pool:
query_cache_driver:
type: pool
pool: cache.psr6
query_cache_service_psr6:
query_cache_driver:
type: service
id: cache.psr6
result_cache_pool:
result_cache_driver:
type: pool
pool: cache.psr6
result_cache_service_psr6:
result_cache_driver:
type: service
id: cache.psr6
second_level_cache_pool:
second_level_cache:
enabled: true
region_cache_driver:
type: pool
pool: cache.psr6
second_level_cache_service_psr6:
second_level_cache:
enabled: true
region_cache_driver:
type: service
id: cache.psr6File: tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_abstract.yml
services:
entity_listener:
abstract: true
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener }
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:File: tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_custom_resolver.yml
services:
custom_entity_listener_resolver:
class: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\CustomEntityListenerServiceResolver
public: false
entity_listener:
class: EntityListener
public: false
tags:
- { name: doctrine.orm.entity_listener }doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
entity_listener_resolver: custom_entity_listener_resolverFile: tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_lazy_private.yml
services:
entity_listener:
public: false
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener, lazy: true }
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:File: tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_lazy_resolver_without_interface.yml
services:
custom_resolver:
class: Doctrine\ORM\Mapping\DefaultEntityListenerResolver
entity_listener:
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener, lazy: true }doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
entity_listener_resolver: custom_resolverFile: tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_resolver.yml
services:
entity_listener_resolver:
class: Doctrine\ORM\Mapping\DefaultEntityListenerResolver
entity_listener1:
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener }
entity_listener2:
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener, entity_manager: em2 }doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
em2:
entity_listener_resolver: entity_listener_resolverFile: tests/DependencyInjection/Fixtures/config/yml/orm_fetch_mode_subselect_batch_size.yml
doctrine:
dbal:
default_connection: default
orm:
fetch_mode_subselect_batch_size: 10000File: tests/DependencyInjection/Fixtures/config/yml/orm_filters.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
server_version: 9.4.0
orm:
filters:
soft_delete:
class: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter
enabled: true
myFilter:
class: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter
enabled: true
parameters:
myParameter: myValue
mySecondParameter: mySecondValueFile: tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
entity_managers:
default:
mappings:
XmlBundle: ~
dql:
string_functions:
test_string: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction
numeric_functions:
test_numeric: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction
datetime_functions:
test_datetime: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunctionFile: tests/DependencyInjection/Fixtures/config/yml/orm_hydration_mode.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
entity_managers:
default:
hydrators:
test_hydrator: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator
mappings:
XmlBundle: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_identity_generation_preferences.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
mappings:
XmlBundle: ~
identity_generation_preferences:
Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
em2:
mappings:
XmlBundle: ~
identity_generation_preferences:
Doctrine\DBAL\Platforms\PostgreSQLPlatform: sequenceFile: tests/DependencyInjection/Fixtures/config/yml/orm_multiple_em_bundle_mappings.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em2
entity_managers:
em1:
mappings:
AttributesBundle:
type: attribute
em2:
validate_xml_mapping: true
mappings:
XmlBundle:
dir: Resources/config/doctrine
alias: xml
manual:
type: xml
prefix: Fixtures\Bundles\XmlBundle
dir: "%kernel.root_dir%/tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine"
alias: TestAliasFile: tests/DependencyInjection/Fixtures/config/yml/orm_namingstrategy.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
mappings:
XmlBundle: ~
naming_strategy: doctrine.orm.naming_strategy.default
em2:
mappings:
XmlBundle: ~
naming_strategy: doctrine.orm.naming_strategy.underscoreFile: tests/DependencyInjection/Fixtures/config/yml/orm_native_lazy_objects_default.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
server_version: 9.4.0
orm: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_native_lazy_objects_disable.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
server_version: 9.4.0
orm:
enable_native_lazy_objects: falseFile: tests/DependencyInjection/Fixtures/config/yml/orm_native_lazy_objects_enable.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
server_version: 9.4.0
orm:
enable_native_lazy_objects: trueFile: tests/DependencyInjection/Fixtures/config/yml/orm_quotestrategy.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: em1
entity_managers:
em1:
mappings:
XmlBundle: ~
quote_strategy: doctrine.orm.quote_strategy.default
em2:
mappings:
XmlBundle: ~
quote_strategy: doctrine.orm.quote_strategy.ansiFile: tests/DependencyInjection/Fixtures/config/yml/orm_repository_factory.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
repository_factory: repository_factoryservices:
repository_factory:
class: Doctrine\Bundle\DoctrineBundle\Repository\RepositoryFactory
File: tests/DependencyInjection/Fixtures/config/yml/orm_resolve_target_entity.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
resolve_target_entities:
Symfony\Component\Security\Core\User\UserInterface: MyUserClassFile: tests/DependencyInjection/Fixtures/config/yml/orm_schema_ignore_classes.yml
doctrine:
dbal:
default_connection: default
orm:
entity_managers:
em1:
schema_ignore_classes:
- Class\A
- Class\BFile: tests/DependencyInjection/Fixtures/config/yml/orm_second_level_cache.yml
services:
my_service_region_driver:
class: Symfony\Component\Cache\Adapter\ArrayAdapter
my_service_logger1:
class: Doctrine\ORM\Cache\Logging\StatisticsCacheLogger
my_service_logger2:
class: Doctrine\ORM\Cache\Logging\StatisticsCacheLogger
my_service_region:
class: Doctrine\ORM\Cache\Region\DefaultRegion
arguments: ["my_service_region", "@my_service_region_driver", 3600]
my_factory_config:
class: Doctrine\ORM\Cache\CacheConfiguration
my_factory_driver:
class: Symfony\Component\Cache\Adapter\ArrayAdapter
my_factory:
class: Doctrine\ORM\Cache\DefaultCacheFactory
arguments: ["@my_factory_config", "@my_factory_driver"]doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
entity_managers:
custom_slc_factory:
second_level_cache:
factory: "my_factory"
default:
second_level_cache:
log_enabled: true
enabled: true
region_cache_driver: ~
loggers:
my_service_logger1 :
service: "my_service_logger1"
my_service_logger2 :
service: "my_service_logger1"
regions:
my_service_region:
type: service
service : "my_service_region"
my_query_region:
lifetime: 300
cache_driver: ~
type: filelock
lock_path: "%kernel.cache_dir%/doctrine/orm/slc/filelock"
my_entity_region:
lifetime: 600
cache_driver: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml
doctrine:
dbal:
default_connection: conn1
connections:
conn1:
driver: pdo_sqlite
dbname: sqlite_db
user: sqlite_user
password: sqlite_s3cr3t
memory: true
conn2:
driver: pdo_sqlite
dbname: sqlite_db
user: sqlite_user
password: sqlite_s3cr3t
memory: true
orm:
default_entity_manager: em2
entity_managers:
em1:
connection: conn1
mappings:
XmlBundle: ~
em2:
connection: conn2
mappings:
XmlBundle: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: default
mappings:
XmlBundle: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager_without_dbname.yml
doctrine:
dbal:
default_connection: default
connections:
default:
orm:
default_entity_manager: default
mappings:
XmlBundle: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_service_single_entity_manager.yml
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_sqlite
dbname: sqlite_db
user: sqlite_user
password: sqlite_s3cr3t
memory: true
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
default_repository_class: Acme\Doctrine\Repository
mappings:
XmlBundle: ~File: tests/DependencyInjection/Fixtures/config/yml/orm_single_em_bundle_mappings.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
validate_xml_mapping: true
mappings:
AttributesBundle:
type: attribute
XmlBundle:
dir: Resources/config/doctrine
alias: xml
manual:
type: xml
prefix: Fixtures\Bundles\XmlBundle
dir: "%kernel.root_dir%/tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine"
alias: TestAliasFile: tests/DependencyInjection/Fixtures/config/yml/orm_single_em_default_table_options.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
default_table_options:
charset: utf8mb4
collation: utf8mb4_unicode_ci
engine: InnoDB
orm:
mappings:
AttributesBundle: ~
XmlBundle:
dir: Resources/config/doctrine
alias: xml
manual:
type: xml
prefix: Fixtures\Bundles\XmlBundle
dir: "%kernel.root_dir%/tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine"
alias: TestAliasFile: tests/DependencyInjection/Fixtures/config/yml/orm_single_em_dql_functions.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
dql:
string_functions:
test_string: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunctionFile: tests/DependencyInjection/Fixtures/config/yml/orm_typedfieldmapper.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: db
orm:
default_entity_manager: default
entity_managers:
default:
mappings:
XmlBundle: ~
typed_field_mapper: doctrine.orm.typed_field_mapper.defaultFile: tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_default_tables_session.yml
doctrine:
dbal:
default_connection: connection1
connections:
connection1:
schema_filter: ^(?!t_)
connection2: []
connection3: []
services:
well_known_filter:
alias: 'doctrine.dbal.well_known_schema_asset_filter'
public: true
symfony.session:
class: 'Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler'File: tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_overridden_tables_session.yml
doctrine:
dbal:
default_connection: connection1
connections:
connection1:
schema_filter: ^(?!t_)
connection2: []
connection3: []
services:
well_known_filter:
alias: 'doctrine.dbal.well_known_schema_asset_filter'
public: true
symfony.session:
class: 'Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler'
arguments:
- ~
- db_table: app_sessionFile: .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:- "CI"
target-branch: "2.18.x"
groups:
doctrine:
patterns:- "doctrine/*"
- "CI"
File: .github/FUNDING.yml
patreon: phpdoctrine
tidelift: packagist/doctrine%2Fdoctrine-bundle
custom: https://www.doctrine-project.org/sponsorship.html
File: .github/stale.yml
onlyLabels: ['Status: Waiting feedback']
daysUntilStale: 14
daysUntilClose: 7
staleLabel: 'Stale'
exemptProjects: true
exemptMilestones: true
markComment: >
This issue is still waiting on feedback. Please provide the information requested above to allow us to continue working on this ticket.
This issue will be closed after 7 days. You can still provide us with the necessary information to continue working on this issue, and we will reopen the ticket for you. Thanks!
File: .github/workflows/coding-standards.yml
name: "Coding Standards"
on:
pull_request:
branches:
- ".x"
paths:
- .github/workflows/coding-standards.yml
- config/*
- composer.*
- phpcs.xml.dist
- src/**
- tests/**
push:
branches:
- ".x"
paths:
- .github/workflows/coding-standards.yml
- config/*
- composer.*
- phpcs.xml.dist
- src/**
- tests/**
jobs:
coding-standards:
name: "Coding Standards"
uses: "doctrine/.github/.github/workflows/[email protected]"
with:
composer-options: "--prefer-dist --prefer-stable"
File: .github/workflows/composer-lint.yml
name: "Composer Lint"
on:
pull_request:
branches:
- ".x"
paths:
- .github/workflows/composer-lint.yml
- "composer.json"
push:
branches:
- ".x"
paths:
- .github/workflows/composer-lint.yml
- "composer.json"
jobs:
composer-lint:
name: "Composer Lint"
uses: "doctrine/.github/.github/workflows/[email protected]"
File: .github/workflows/continuous-integration.yml
name: "CI: PHPUnit"
on:
pull_request:
branches:
- ".x"
paths:
- .github/workflows/continuous-integration.yml
- config/*
- composer.*
- phpunit.xml.dist
- src/**
- templates/**
- tests/**
push:
branches:
- ".x"
paths:
- .github/workflows/continuous-integration.yml
- config/*
- composer.*
- phpunit.xml.dist
- src/**
- templates/**
- tests/**
jobs:
phpunit:
name: >
${{ format('PHP {0} - Sf {1} - deps {2} - stab. {3}',
matrix.php-version || 'Ø',
matrix.symfony-require || 'Ø',
matrix.dependencies || 'Ø',
matrix.stability || 'Ø'
) }}
${{ matrix.remove-orm && ' - remove ORM' }}
${{ matrix.remove-doctrine-messenger && ' - remove Messenger' }}
runs-on: "ubuntu-latest"
env:
SYMFONY_REQUIRE: ${{matrix.symfony-require}}
SYMFONY_DEPRECATIONS_HELPER: weak
strategy:
fail-fast: false
matrix:
php-version:
- "8.4"
dependencies:
- "highest"
stability:
- "stable"
symfony-require:
- ""
remove-orm:
- false
remove-doctrine-messenger:
- false
include:
# Tests the lowest set of dependencies
- dependencies: "lowest"
stability: "stable"
php-version: "8.4"
# Test legacy LTS
- symfony-require: "6.4.*"
dependencies: "highest"
php-version: "8.5"
# Test LTS
- symfony-require: "7.4.*"
dependencies: "highest"
php-version: "8.5"
# Test non-LTS
- symfony-require: "8.0.*"
dependencies: "highest"
php-version: "8.5"
# DBAL only without ORM
- php-version: "8.5"
dependencies: "highest"
stability: "stable"
remove-orm: true
# No Messenger integration
- php-version: "8.5"
dependencies: "highest"
stability: "stable"
remove-doctrine-messenger: true
# Bleeding edge
- php-version: "8.5"
dependencies: "highest"
stability: "dev"
steps:
- name: "Checkout"
uses: "actions/checkout@v7"
with:
fetch-depth: 2
- name: "Install PHP with PCOV"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-file: "development"
extensions: "pdo_sqlite"
tools: "flex"
- name: "Enforce using stable dependencies"
run: "composer config minimum-stability stable"
if: "${{ matrix.stability == 'stable' }}"
- name: "Remove doctrine/orm"
run: "composer remove doctrine/orm --dev --no-update"
if: "${{ matrix.remove-orm }}"
- name: "Remove symfony/doctrine-messenger"
run: "composer remove symfony/doctrine-messenger --dev --no-update"
if: "${{ matrix.remove-doctrine-messenger }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v4"
with:
dependency-versions: "${{ matrix.dependencies }}"
composer-options: "--prefer-dist"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v7"
with:
name: "phpunit-${{ matrix.php-version }}-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}.coverage"
path: "coverage.xml" upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-latest"
# Only run on PRs from forks or PRs from branches that do not match *.x
if: "github.event.pull_request.head.repo.full_name != github.repository || !contains(github.event.pull_request.head.ref, '.x')"
needs:
- "phpunit"
steps:
- name: "Checkout"
uses: "actions/checkout@v7"
with:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v8"
with:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v7"
with:
directory: reports
env:
CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"File: .github/workflows/documentation.yml
name: "Documentation"
on:
pull_request:
branches:
- ".x"
paths:
- ".github/workflows/documentation.yml"
- "docs/**"
push:
branches:
- ".x"
paths:
- ".github/workflows/documentation.yml"
- "docs/**"
jobs:
documentation:
name: "Documentation"
uses: "doctrine/.github/.github/workflows/[email protected]"
File: .github/workflows/release-on-milestone-closed.yml
name: "Automatic Releases"
on:
milestone:
types:
- "closed"
jobs:
release:
name: "Git tag, release & create merge-up PR"
uses: "doctrine/.github/.github/workflows/[email protected]"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
File: .github/workflows/static-analysis.yml
name: "Static Analysis"
on:
pull_request:
branches:
- ".x"
paths:
- .github/workflows/static-analysis.yml
- config/*
- composer.*
- phpstan.neon.dist
- src/**
- tests/**
push:
branches:
- ".x"
paths:
- .github/workflows/static-analysis.yml
- config/*
- composer.*
- phpstan.neon.dist
- src/**
- tests/**
jobs:
static-analysis:
name: "PHPStan"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout code"
uses: "actions/checkout@v5"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.4"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
- name: "Warm up Symfony cache"
run: "php tests/console-application.php"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse -v"File: .github/workflows/test-dev-stability.yml
name: "Dev dependencies stability check"
on:
schedule:
- cron: "0 0 * * 0"
jobs:
phpunit:
name: "PHPUnit"
runs-on: "ubuntu-latest"
env:
SYMFONY_REQUIRE: ${{matrix.symfony-require}}
strategy:
fail-fast: false
matrix:
php-version:
- "8.4"
dependencies:
- "highest"
stability:
- "dev"
symfony-require:
- ""
- "6.*"
steps:
- name: "Checkout"
uses: "actions/checkout@v7"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
ini-file: "development"
extensions: "pdo_sqlite"
tools: "flex"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v4"
with:
dependency-versions: "${{ matrix.dependencies }}"
composer-options: "--prefer-dist"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit"File: .github/workflows/website-schema.yml
name: "Website config validation"
on:
pull_request:
branches:
- ".x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"
push:
branches:
- ".x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"
jobs:
json-validate:
name: "Validate JSON schema"
uses: "doctrine/.github/.github/workflows/[email protected]"