Doctrine Configuration (doctrine.yaml) when creating modules in symfony - php

I have created multiple modules folder inside my symfony project. Therefore each Entity and it's Repository class are kept in their own module folder instead keeping them in default src/Entity folder like this.
src
- Post
- Persistence
- Entity
- Post.php
- Repository
- PostRepository.php
- PostComment
- Persistence
- Entity
- PostComment.php
- Repository
- PostCommentRepository.php
Now to make this work in conig/doctrine.yaml, I had to create multiple entity_managers like this
orm:
entity_managers:
vouchers:
mappings:
Post:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Modules/Post/Persistence/Entity'
prefix: 'App\Modules\Post\Persistence\Entity'
alias: Post
PostComment:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Modules/PostComment/Persistence/Entity'
prefix: 'App\Modules\PostComment\Persistence\Entity'
alias: PostComment
This works however as you noticed, this makes me create new entity manager line in the doctrine.yaml configuration file every time I add new entity. There are going to more than 100 tables and I don't feel this is a right way to do it even though it works.
Question: Is there a way to make this dynamic so that I don't need to repeat myself?
More or less, I was hoping it would support regex like this but of-course this does not work.
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
dir: '%kernel.project_dir%/src/Modules/*/Persistence/Entity'
prefix: 'App\Modules\*\Persistence\Entity'
alias: App

Related

MappingException - The class 'generalBundle\Entity\xxx' was not found in the chain configured namespaces xxx - Upgrade to symfony flex

I have a project in Symfony 3.4 and I am configuring flex, to later go to version 4.4.
I have already managed to modify the project folder structure, and it is trying to map, but the problem is that with the old configuration it does not work.
These are my bundles (I have kept the same structure here):
> SRC
> H360 (the place of my bundles)
> comercialBundle
> jasperBundle
> generalBundle
> ...
And this is my orm config (i tried setting 'generalbundle'):
orm:
default_entity_manager: default
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
connection: default
auto_mapping: true
mappings:
generalBundle:
type: annotation
prefix: 'H360\generalBundle'
dir: '%kernel.project_dir%/src/H360/generalBundle/Entity'
is_bundle: false
translatable:
type: annotation
alias: Gedmo
prefix: Gedmo\Translatable\Entity
# make sure vendor library location is correct
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
is_bundle: false
And the error is: "The class 'generalBundle\Entity\GenParametros' was not found in the chain configured namespaces H360\generalBundle, Gedmo\Translatable\Entity"
Any ideas?
Your Prefix is H360\generalBundle but you seem to use generalBundle\Entity\GenParametros to import the entity. Change it to H360\generalBundle\Entity\GenParametros or change the prefix to generalBundle.

Read replica database connection never used, goes back to default

I'm following the documentation here https://symfony.com/doc/current/reference/configuration/doctrine.html about setting up alternative database connections for the purpose of read replication. For reference I'm using AWS Aurora PostgreSQL with end points for primary and read only.
I've set the this for my doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
read:
url: '%env(resolve:READ_URL)%'
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
dql:
datetime_functions:
date_trunc: App\DoctrineExtensions\DateTrunc
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
read:
connection: read
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: false
dql:
datetime_functions:
date_trunc: App\DoctrineExtensions\DateTrunc
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
auto_generate_proxy_classes: true
And calling the read only orm as:
$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);
as an example.
If I call this it still goes to the default database. If I misname it Symfony throws an exception as expected so I can confirm the config is being picked up and loading correctly.
How is my config or call incorrect that it's still requesting from the default database connection or is there any better way to define read replicas for the data connection? I haven't found any current documentation for it.
According to this:
One entity can be managed by more than one entity manager. This
however results in unexpected behavior when extending from
ServiceEntityRepository in your custom repository. The
ServiceEntityRepository always uses the configured entity manager for
that entity. In order to fix this situation, extend EntityRepository
instead and no longer rely on autowiring:
So you should make sure your repository extends EntityRepository instead of ServiceEntityRepository.
Then you should now always fetch this repository using ManagerRegistry::getRepository().
So basically this would work since $this->getDoctrine() return an instance of ManagerRegistry.
$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);
The downside is you will not be able to use autowiring for the repository itself.
So this would not work unless you pass that repository manually.
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

Symfony 4: Reusable code in "src"

I'm trying to update a Symfony 3.4 application to Symfony 4. On my current applications I always share a local AdminBundle folder inside src. I know Symfony 4 recommends to be "bundle-less" now. But this AdminBundle is the base for most of my projects, and sometimes I make some updates to it that can be deployed to all my projects just pushing to the repository.
I tried to move by AdminBundle inside src but obviously that's not working. Could anyone detail the recipe or configuration needed to make this Bundle work under Symfony 4 in a generic way?
If this is not possible what's the best way to create a reusable code in symfony 4?
I'm currently using a similiar approach:
I've got a "CoreBundle" for shared Services, Entites, Subscribers etc under "src".
In order to make this usable i had to edit the following:
config/maker.yaml -> to use make:entity and create under CoreBundle
maker:
root_namespace: 'App\CoreBundle'
config/packages/doctrine.yaml modify -> to get the Entities from CoreBundle
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/CoreBundle/Entity'
prefix: 'App\CoreBundle\Entity'
alias: App
config/services.yaml add -> to import all SymfonyLike Classes
###> CoreBundle ###
App\CoreBundle\:
resource: '../src/CoreBundle/*'
exclude: '../src/CoreBundle/{DependencyInjection,Entity,Model,Migrations,Tests}'
App\CoreBundle\Controller\:
resource: '../src/CoreBundle/Controller'
tags: ['controller.service_arguments']
###< CoreBundle ###
config/* add -> where i wanted to import a separate config file
imports:
- { resource: '../../src/CoreBundle/Resources/config/*.yaml' }

Can I organize Doctrine YAML mappings in subfolders?

I have custom mapping settings in my Symfony3 project for Doctrine entities like this:
MyModel:
type: yml
dir: %kernel.root_dir%/../src/AppBundle/Resources/config/doctrine/MyModel
prefix: MyProject\MyModel\Model
is_bundle: false
Let's assume I have an entity MyProject\MyModel\Model\SubNamespace\MyEntity. Now, I have to put its yml mapping in %kernel.root_dir%/../src/AppBundle/Resources/config/doctrine/MyModel/SubNamespace.MyEntity.orm.yml, and it works fine.
Can I configure Doctrine to be able to organize mapping files in subfolders instead of file names being a concatenation of parts of namespace after prefix?
In this case if would be %kernel.root_dir%/../src/AppBundle/Resources/config/doctrine/MyModel/SubNamespace/MyEntity.orm.yml
The reason is that mapping directory is growing and it's getting hard to find any particular file inside.
Of course, it's not a solution to make a configuration for every subfolder. ;-)
Looking at the source code, there's nothing to handle subfolders. But then the trick could be to add each folder in a different "mapping", as far I know those don't have to stick to your Symfony bundles:
doctrine:
# ...
orm:
# ...
mappings:
AcmeBundleFoo:
type: yml
dir: AcmeBundle/Resources/doctrine/Foo
AcmeBundleBar:
type: yml
is_prefix: false # you are free to let Symfony guess it or to be explicit
dir: AcmeBundle/Resources/doctrine/Bar
A little verbose, but it should work given yout folder structure is src/AcmeBundle/Resources indeed.
yes it's in conf files :
doctrine:
dbal:
driver: "%database_driver%"
#etc
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: false //default was true
mappings:
MySuperBundleName:
type: yml
dir: Resources/somewhereElse/doctrine // your specific directory

How do I change symfony 2 doctrine mapper to use my custom directory instead of my Entity Directory under the bundle

I use doctrine in my symfony 2.3 application. I want to use a folder structure like
/MyBundleName/User/User.php
for my Entities.
Question:
Is there anyway that I can explicitly map doctrine ORM directly to use an explicit directory instead of defaulting to the Entity Directory of my Bundle?
I would like to keep all related files in their respective directory such as ProductProvider in
/MyBundleName/Product/ProductProvider.php
Any help would be greatly appreciated.
Just to follow up a bit on #Imanol's correct answer, it is possible to have your entities in multiple directories under one entity manager:
doctrine:
orm:
default_entity_manager: default
auto_generate_proxy_classes: %kernel.debug%
entity_managers:
default:
connection: default
mappings:
test01:
connection: test01
mappings:
product:
type: yml
dir: %kernel.root_dir%/../src/Cerad/Bundle/Test01Bundle/Product
prefix: Cerad\Bundle\Test01Bundle\Product
alias: Product
is_bundle: false
user:
type: yml
dir: %kernel.root_dir%/../src/Cerad/Bundle/Test01Bundle/User
prefix: Cerad\Bundle\Test01Bundle\User
alias: User
is_bundle: false
Don't worry about the is_bundle: false entries. The entities can still live in a bundle. Doctrine does not care. And in case you are wondering, the alias parameter lets you do things like:
$repo = $em->getRepository("Product:Product");
you can tell Doctrine the directory where is your entities
doctrine:
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: false
mappings:
name:
type: php
dir: %kernel.root_dir%/../src/Company/CartoDBBundle/Tests/CartoDB/Entity
Here you have the full documentation Doctrine configuration
I made a similar question a few days ago, there you can read the full answer Cedar gave me
Similar post
I've spent some time trying to figure out the simplest case. This is how I made it work:
doctrine:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
mappings:
AppBundle:
mapping: true
type: annotation
dir: Model
alias: AppBundle
prefix: 'AppBundle\Model'
is_bundle: true
I simply wanted to store my entities in a directory called 'Model' inside my bundle, instead of the default 'Entity'.

Categories