Different Symfony projects, one database. How should we handle the entities? - php

We have different symfony4 projects (readonly APIs) which uses the same database.
In every project we use, for example, the User Entity and the Groups Entity.
So, if we change the database (eg. add a new field), we have to change all the entities in all our projects. How can we solve this problem?
Should we create a Entity Bundle and install it with composer to every project? Or is there another solution?

Usually the best approach for implementing reusable code is to create bundles. That way you can easily reuse them and update them.

Related

Symyfony 3.4 - How to move entitiy to other database

I am running a Symfony 3.4 based web service using Doctrine to manage and persist the different data entities.
Now I am trying to implement a method which transfers older, abandoned user accounts to another database which acts as archive.
Regarding to the Symfony docs it should be no problem to configure Doctrine to manage different database connections and entity managers.
However I do not completely understand the process on how to setup this use case:
Assume the Symfony project has different data entities DataEntity1, DataEntity2, etc. and different infrastructure entities Infrastructure1, etc..
How to tell Doctrine to initialize the archive DB with the data entities only?
How to move the entities between the DBs? Is loading them from entity manager 1 and persisting them in entity manger 2 the correct way?
Is there any best practice on how to do this?
If I understand your question correctly, you should use the prefix option for the mapping configuration.
prefix
A common namespace prefix that all entities of this mapping share.
This prefix should never conflict with prefixes of other defined
mappings otherwise some of your entities cannot be found by Doctrine.
This option defaults to the bundle namespace + Entity, for example for
an application bundle called AcmeHelloBundle prefix would be
Acme\HelloBundle\Entity.
Have a look at https://symfony.com/doc/3.4/reference/configuration/doctrine.html it shoul help you.
To move the entities between the two DBs, you should have two entity managers and use the correct one to persist olders accounts.
Hope this helps.

Symfony2 architecture

I am developing an app with Symfony2 that has 3 main parts called frontoffice, backoffice, admin. I was thinking to create three separate bundles: FrontOfficeBundle, BackOfficeBundle, AdminBundle but Symfony's docs says, each bundle should not have any relation with each other. Entity is already a shared property and probably some models. I could create a SharedBundle but it does not make sense. I remember when I created an app 2 years go when I had like 15 bundles and all connected each other and I know from experience that it's a nightmare.
Should I have just one bundle AppBundle and logic split in the folders, eg. Controller/Admin; Controller/FrontOffice, Controller/BackOffice?
What's the best approach?
It's all about SRP and DRY
It doesn't hurt to create a bundle, so make a separate bundle for stuff you need in multiple bundles, e.g. I tend to create an EntityBundle which contains entities and their repositories (as service).
Of course you can just use a single AppBundle too but please don't put your logic into the controllers -> create reusable services! Inject the services you need into your controller (which should themselves be services too).
Alternatives to base Controller Methods
No such thing as best approach.
However, instead of grouping by class type (Controller,Command,Form,Templates) within a directory, I like to create a single "component" directory for each request action. So I would have
Action
FrontOffice
BackOffics
Admin
User
UserController.php
UserFormType.php
UserTemplate.html.twig
Grouping files in this fashion really cuts down on figuring out where the various files live. Is it the "best" approach? Nope. But it works for me.

Application structure in Symfony 2

I am quiet new to the symfony framework and took some lessons and purchased the 'Starting in Symfony2' tutorial from knpuniverse. I want to be sure that I use the correct setup for my application. My question is, How do you call your first central bundle? eg. FrontendBundle? I want to make the next structure in my application:
FrontendBundle
The front where people get a landing site where they can also login
from there, when they login, they get into the next bundle:
CustomerBundle
Backend app where customers get their invoices and pay them and edit their information we stored in the database
And at least:
AdminBundle
Another backend app where I can edit customers, make invoices for customers and edit the app information
Is this the correct way and is FOSUserBundle a good bundle for this kind of application?
Bundles have sense only if they can be used in "multiple projects". I mean: if you write code, make it as a bundle and you can't reuse that bundle (for example because bundles, as you described above, are strictly and logically connected to your project) this three bundle separations is totally useless.
So, final answer (that is also a question) is:
Could you reuse FrontendBundle in other projects?
Could you reuse CustomBundle in other projects?
Could you reuse AdminBundle in other porjects?
If you notice that you can't use any or all of these bundles for other project, maybe this separations isn't good.
Why I say that?
Because if they can't be used in separated ways is likely that they should be used togheter so you should keep them togheter.
So I advice to keep them into a single bundle (YourNameYourBundleNameBundle (in that notation, for example)) and to separate the single "areas":
FrontEnd controllers/entities/views
Custom controllers/entities/views
Admin controllers/entities/views
This problem has been discussed at length already. For application specific code either do a single AppBundle or don't use bundles at all.

Altering table using the Symfony2 Doctrine2 console/generate feature?

What I'm trying to figure out is how to add new fields to a table, using Symfony2 with Doctrine2.
I used this to initially create the Entity:
php app/console doctrine:generate:entity --entity="MyMainBundle:ImagesTable" --fields="title:string(100) file:string(100)"
And I used this to create/update the tables on the database:
php app/console doctrine:schema:update --force
Now if I wanted to add new fields to the ImagesTable entity, is there an easy way to do it using the console, or do I have to manually edit the entity. I am just using 1 entity as an example right now, but in reality, there are many entities I'd be changing; so, there has to be an easier way to do it.
I've been manually editing them to create relationships, so if there is an easier way to do that as well, that'd be great.
I remember this being a lot easier with Symfony1.4 - all I had to do was create the database/tables using phpMyAdmin, and Symfony was able to generate the models with no issues.
I really hope I'm missing something here, because this won't work if I have to manually edit every entity for every change.
Doctrine generator commands are intended to help the developer to quickly prototype an idea. They generally don't produce production ready code, and the code needs to be checked to see if it contains what you want.
You can still create your model in phpmyadmin and use Doctrine reverse engineering tools, but it also doesn't produce production ready code, only intended to use in prototyping.
Creating database/tables beforehand doesn't really work well with Doctrine2, as the underlying relation between tables may not be the same as the relation between objects of your model. The whole point of ORM is to think in classes and letting Doctrine do the rest of the work for you.
Doctrine is not intended to write your entities for you, it gives you tools to build your data model, which you use to code your model in Php.
If you don't like to code your entities by hand (which is what all developers using doctrine does), you may want to have a look at RedbeanPHP, a zero-config ORM framework for PHP. It creates the database tables, columns, indexes on the fly depending on the data model you use.

How do I define an entity which is commonly used several bundles?

I want to create a blogging system in order to practice symfony2,
but currently I get a bit confused when creating entities such as user or blog.
The reason is the following :
User( or Blog) is commonly used in frontend and backend(admin)
(currently I have considered creating FrontendBundle and AdminBundle)
Entity must belong to one bundle.
Currently I have considered the following methods, but what is the best way
in this case, or please tell me if there is another way.
Create bundle named 'BlogCommonBundle' and define User entity as "BlogCommonBundle:User".
Define all controllers under 1 bundle, such as 'BlogBundle', so
frontend/backend(admin) controllers belong to same bundle.
I think creating a BlogBundle and having multiple controllers for frontend and admin functionality is a good way to handle this. Both controllers would make use of the same entities and repositories, and you can easily firewall your admin actions in the security settings of your application. By keeping everything blog related to one bundle, you maintain good code organization.
The same goes for a UserBundle. It's helpful to remind yourself that a bundle should represent a set of like functionality for an application. So if you have code that fetches blog posts, and allows you to create and manage them, they naturally group together in a single bundle.
I asked a similar question here:
How to share a Symfony2 model with several projects
I went with the 'ModelBundle' approach that contains all the entities, forms, repositories, etc. These are all shared with the FrontendBundle and BackendBundle.
So far I'm very happy with this solution.

Categories