Symfony 4: Reusable code in "src" - php

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' }

Related

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

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

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.

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

Configuring DoctrineExtensions-Taggable in Symfony fullstack with config.yml

I am having difficulty configuring the Doctrine Extension Taggable provided here:
https://github.com/FabienPennequin/DoctrineExtensions-Taggable
My project is using Symfony 2 Fullstack and my configuration is using yaml while my doctrine entities are using annotation. I installed DoctrineExtensions using composer. Adding "fpn/doctrine-extensions-taggable": "dev-master" to the require section on composer.json and then running composer update. This installed without issue.
I then become lost at this section: https://github.com/FabienPennequin/DoctrineExtensions-Taggable#setup-doctrine
I understand that the metadata is a Doctrine Entity however as previously mentioned I am using yaml for my symfony configuration as well as entity managers. Here is the excerpt from my config.yml file:
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
default_entity_manager: main
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
main:
connection: default
mappings:
VendorMainBundle:
prefix: Vendor\MainBundle\Entity
taggable:
connection: default
mappings:
taggable:
type: xml
prefix: DoctrineExtensions\Taggable\Entity
dir: %kernel.root_dir%/../vendor/fpn/doctrine-extensions-taggable/metadata
However, when I run php app/console doctrine:mapping:info --em=taggable I get the error:
[Exception]
You do not have any mapped Doctrine ORM entities according to the current configuration. If you have entities or mapping files you should check your mapping configuration for errors.
Should the above command show the mappings described in the xml files?
Thereby allowing me to update the schema in the database?
I used this documenation as reference for the config.yml file: http://symfony.com/doc/current/reference/configuration/doctrine.html#mapping-configuration
I also added this under the config.yml in order to setup the TagListener. Is this correct?
services:
taggable:
class: DoctrineExtensions\Taggable\TagListener
EDIT [#Grimv01k]:
The TagListener requires an argument passed that is an instance of the TagManager Object. I created another service to handle that as follows and passed it to the TagListener:
tag.manager:
class: DoctrineExtensions\Taggable\TagManager
tags:
- { name: doctrine.event_subscriber, connection: default }
arguments:
entity.manager: #doctrine.orm.entity_manager
taggable:
class: DoctrineExtensions\Taggable\TagListener
arguments:
manager: #tag.manager
The TagManager requires an argument of the entityManager however by doing so results in error:
[Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
Circular reference detected for service "doctrine.dbal.default_connection", path: "doctrine.dbal.default_connection".
Across the web it's recommended to resolve this error by passing #service_container and in the constructor of the object pull out the entity_manager, however being a vendor I'd prefer not to modify their code. Is there another way?
Just guess: maybe that happens becuse you haven't got tags applied in service, and Doctrine doesn't use this in your complier pass. Try to do it like this:
services:
taggable:
class: DoctrineExtensions\Taggable\TagListener
tags:
- { name: doctrine.event_subscriber, connection: default }

Doctrine2+Symfony2: How to use namespaced Doctrine entities with Symfony2?

I try to use Doctrine in Symfony 2.5 with an XML configuration for the entity mapping.
I have a namespaced class Bar: ACME\TestBundle\Entity\Foo\Bar
As I have many entities they can't all reside in the ACME\TestBundle\Entity namespace, but must be put into sub-namespaces.
Creating the entities is no problem, but I can't figure out where to put the ORM XML configuration files.
I tried Resources/config/doctrine/Foo/Bar.orm.xml, which doesn't find the mapping file:
$ php app/console doctrine:schema:create --dump-sql
No Metadata Classes to process.
I tried Resources/config/doctrine/Bar.orm.xml, which ignores the additional Foo namespace unter Entity, although the full namespace is correctly given in Bar.orm.xml in the name element.
$ php app/console doctrine:schema:create --dump-sql
[Doctrine\Common\Persistence\Mapping\MappingException]
Class 'ACME\TestBundle\Entity\Bar' does not exist
What am I missing? What is the correct place for the XML mapping file to reside for these namespaced classes?
Using #user3749178 suggestion of Foo.Bar.orm.xml works and is the easiest way to solve the problem though all the mapping files end up in one directory.
It's also possible to have individual directories for everything based on:
http://symfony.com/doc/current/reference/configuration/doctrine.html#mapping-configuration
Here is an example configuration:
doctrine:
orm:
default_entity_manager: default
auto_generate_proxy_classes: %kernel.debug%
entity_managers:
default:
connection: default
mappings:
foo1:
prefix: Cerad\Bundle\ProjectGameBundle\Doctrine\Entity\Foo1
type: yml
dir: src/ProjectGameBundle/Doctrine/EntityMapping/Foo1
is_bundle: false
foo2:
prefix: Cerad\Bundle\ProjectGameBundle\Doctrine\Entity\Foo2
type: yml
dir: src/ProjectGameBundle/Doctrine/EntityMapping/Foo2
is_bundle: false
You basically specify one mapping for each directory containing entities.

Categories