Symfony. Get the last object loaded - symfony

I have a situation where i must use an entity for persistence and associations with many other entities in several forms.
For example :
Entities A,B,C and D
Relation between A (supposing I want to use the entity A with id 10) and B is oneToMany.
How to get the entity A with Id 10 in the controller of the entity B when creating a new entity B ( b->setA(A) )
Knowing that i load the entity A only in one form by search
Or how to use loaded entity A with Id 10 and use it in others controllers
Thanks

In the first controller where entity A is created and therefore you presumably have access to the id:
$this->get('session')->set('entityAId' => $entityA->getId());
In the second controller:
$entityAId = $this->get('session')->get('entityAId');
$em = $this->getDoctrine()->getManager();
$entityA = $em->getRepository('YourBundle:EntityA')->findOneBy(array('id' => $entityAId));
You will need to cater for the scenario where no entity with that id is found and if you haven't used the session before you should read about Symfony Session Management

Related

multiple entitymanager symfony

Before I used only one entity manager to interact with my database.
Everything worked well till I add 2 new entity manager (one entity manager to insert data and one entity manager to select data)
-> I want to make a replication of my database later.
I think, I can solve the problem alone, but I just want to understand why this error appears :
A new entity was found through the relationship 'AppBundle\Entity\Userinterest#user'
that was not configured to cascade persist operations for entity: my_username.
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity
or configure cascade persist this association in the mapping for example
#ManyToOne(..,cascade={"persist"})
I think, I understand the problem :) :
My User from FOSUserBundle is authenticate with the default entity manager.
$userinteret->setUser($this->getUser());
$em = $this->getDoctrine()->getManager();
$em->persist($userinteret);
$em->flush();
Then, I don't know how is stored the token_storage. But because I use the user from the token_storage, I think the probem come from there.
Try with :
// All 3 return the "default" entity manager
$em = $this->getDoctrine()->getManager();
$em = $this->getDoctrine()->getManager('default');
$em = $this->get('doctrine.orm.default_entity_manager');
// Both of these return the "customer" entity manager
$customerEm = $this->getDoctrine()->getManager('customer');
$customerEm = $this->get('doctrine.orm.customer_entity_manager');
How to Work with multiple Entity Managers and Connections

How to make multiple table connections in symfony2 Repository ? Entity?

I have tables like
profile status
Profile.class
id name
1 taro
2 jiro
3 john
Status.class
id profile school date
1 1 highschool 2017-04-01
2 1 juniorhighschool 2013-04-01
3 2 highschool 2017-04-01
Status is added when status changes.
So I normally choose latest status every time I need status.
$ss = $this->em->createQuery(
"SELECT cm FROM UserBundle:Status s where c.profile = :p order by desc")
->setParameters(['p' => $profile])->getResult();
$ss[0] // Latest Status
So now I would like to put this in function.
What I want to do is getting latest status from profile.
I have a few ideas
Put this function in Profile Entity?
put this function in Profile Repository?
put this function in service???
In my opinion it should be the feature of Profile Entity, So I would like to put this in Entity though, access another from an Entity is bad manner.
Is it OK to access another entity from a Profile Repository??
Or should I use service??
You can achieve this with a method in ProfileRepository
<?php
public function getLastStatusByProfile(Profile $profile)
{
// do our query from Profile with a join on Status
}
And please, use a LIMIT 1 on your query, you only need the last result
You cannot put this in an Entity because Entities cannot be injected the Doctrine EntityManager dependency ($this->em).
To perform your "getLatestStatus()" function you need the EntityManager $this->em.
To access the EntityManager you can:
get it from the container in a Command or a Controller (e.g. in a Controller $this->get('doctrine')->getManager();)
inject it into a Service using Dependency Injection configuration files (see http://symfony.com/doc/current/service_container.html#injecting-services-config-into-a-service)
use it in a Repository because Repositories have native access to it
Usually people put functions such as getLatestStatus() in a repository, the repository becomes "the class where we put all DQL queries" and this works quite fine. This is recommanded by the official Documentation (https://symfony.com/doc/current/doctrine/repository.html) "Methods containing your query logic can then be stored in this class."
It is usual in Symfony Applications to have:
Entities having only properties, getters, setters, and some additionnal logical functions (like activate(), disable() ... functions that modify the Entity properties)
Repositories to hold DQL queries with complex logic such as getLatestStatus()
Services to hold other any other functions that read / modify data
Controllers are only gateways to use Services
So one complete example would be:
<?php
class ProfileRepository extends EntityRepository
{
/**
* #param Profile $profile
*
* #return Status
*/
public function getLatestStatus($profile)
{
$qb = $this->getEntityManager()->createQuery(
"SELECT cm FROM UserBundle:Status s where c.profile = :p order by desc")
->setParameters(['p' => $profile])
->getResult();
return $result;
}
}
And do not forget to handle the case where there is no "status" available for this profile. Do you wish to return null, raise an Exception or return a default status ?

Set up non-persistent relation in Doctrine 2

I have an object $user that has a one to many relation with $establishment. I can use:
$user->getEstablishments();
The user can select a stablishment to work on. I have this method that I call in the controller:
$user->setCurrentEstablishment($establishment);
And this one that I call in the view:
$establishment = $user->getCurrentEstablishment();
I want to be able to call:
$user->setCurrentEstablishmentBy Slug($establishment_slug);
where the slug is a string, and let the user object look for the establishment.
Doctrine discourages the practice of accessing the Entity Manager inside the Entity object, but I think that using it in the controller is even worse.
I suspect that some special Doctrine annotation exists that takes care of non persistent relations like this, or some method other than serving the Entity Manager through a service should be used here. Some easy way of referencing other entities from inside the model.
¿Is there any? ¿How could I do that?
There is no Annotation in Doctrine which could convert slug into object.
What can help You is ParamConverter, with it you can automatically convert slug from query into object. But it still must be used in Controller.
Example usage:
/**
* #Route("/some-route/{slug}")
* #ParamConverter("object", class="AppBundle:Establishment", options={"id" = "slug", "repository_method" = "findEstablishmentBySlug"})
*/
public function slugAction(Establishment $object)
{
...
Docs about param converter: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html

Symfony2 findBy method with property from relationship

I'm wondering if it's possible to querying doctrine entities by a property from a relation.
Here is an example :
Entity A fields :
-> title
-> content
-> description
-> date
Entity B fields :
-> title
-> link ( entity b )
-> date
Is it possible to querying Entity B by link->title property such as the following :
$this->getDoctrine()->getManager()->getRepository("acmeAppBundle:EntityB")->findBy(array( "title" => "test", "link.title" => "example" ) );
Currently I'm achieving this with a custom function from Entity B repository, but may be I'm missing something.
You can't use findBy like this. FindBy is only there to fetch very basic things. Generally it's considered as a best practice to use repository calls, because for example, if you here fetch all objects where title is test and then you get from A all B entity, then entity B will be fetched separately, while in a repository call you can use join, so only one query will be sent to your DB.

Automatically add a Join statement in findBy magic method

I'm using Symfony2 / Doctrine2.
I'm trying to override the BaseEntityRepository Class so the magic findBy method automatically adds a JOIN on a "translations" relation. It was easy to do in Symfony 1.4/Doctrine 1, because it was manipulating a Doctrine_Query object, so I simply had to $query->addJoin() and it did the trick.
Unfortunately, in Doctrine 2 you only receive an array of criteria as parameter, and that's where I'm stucked.
I got many entities which have a one-to-many relationship with a translation entity.
For exemple : Section as a one-to-many relationship with SectionTranslation
The goal is to retrieve only the "active" sections (active is in SectionTranslation) when using SectionRepository->findAll(); (or even findBy).
The wanted DQL result is : Select * from Section INNER JOIN SectionTranslation ON Section.id = SectionTranslation.translatable_id WHERE SectionTranslation.locale = $locale AND SectionTranslation.active = 1;
Any idea?
The solution could be adding event listener for particular entity and particular method.

Resources