How to use Association field in Symfony EasyAdmin 4 - symfony

When I use:
public function configureFields(string $pageName): iterable
{
return [
AssociationField::new('XYZ')
];
}`
I get error "Object of class App\Entity\XYZ could not be converted to string"
When I add ->autocomplete() to the AssociationField::new('XYZ'), then it works, but on save it displays error "Expected argument of type "?string", "App\Entity\XYZ" given at property path "XYZ".
Whats the CORRECT way to use this field with many to one relation? Symfony Easy Admin documentation https://symfony.com/doc/current/EasyAdminBundle/fields/AssociationField.html doesn't help at all.

Your entity App\Entity\XYZ will be converted to a string in your association field (which is a standard symfony entity type). Otherwise there is no way to set a label in your entity select.
It will try to convert it using the __toString method, so you need to add it in your entity.
For example:
/**
* #ORM\Entity(repositoryClass=XyzRepository::class)
*/
class Xyz
{
public function __toString(){
return $this->name; //or anything else
}
EasyAdmin should be able to guess the entity class, so you don't have to specify it like you would for a simple EntityType.

Related

Symfony - Circular reference error in ManyToOne relationships

I am using Symfony 5 and doctrine. I have two entities with ManyToOne relationships (Product and ProductImage). Each product can have multiple images and the product entity has getProductImages() method to fetch its product images.
But when I use this method in controller response like this:
return $this->json($product->getProductImages());
I get the following error:
A circular reference has been detected when serializing the object of class "App\Entity\Product"
Do you have any idea how can I solve it?
$this->json() uses a serializer to convert the ProductImage into json. When the serializer tries to serialize the ProductImage it finds the reference to its Product and tries to serialize that too. Then when it serializes the Product it finds the reference back to the ProductImage, which causes the error.
If you do not need the Product information in your json, the solution is to define a serialization group and skip the serialization of the Product property that is causing the error.
Add a use statement to your ProductImage class:
use Symfony\Component\Serializer\Annotation\Groups;
Add a group to the properties you want to serialize, but skip the Product property:
/**
* #Groups("main")
*/
private $id;
/**
* #Groups("main")
*/
private $filename;
And in your controller specify the group to use in $this->json():
return $this->json(
$product->getProductImages(),
200,
[],
[
'groups' => ['main']
]
);

A "__toString()" method was not found on the objects of type "Admin\UserBundle\Entity\Extension" passed to the choice field

I installed easyAdmin Bundle(symfony2) then :
I combined it with fosUserBundle.
I add an entity "extension".
So i created a user but when i tried to edit the account in the
dashboard i get this error :
A "__toString()" method was not found on the objects of type "Admin\UserBundle\Entity\Extension" passed to the choice field
So can anyone help me?
Sorry for the following question, but what about adding a __toString() method?
In your Extension:
public function __toString()
{
return $this->fieldYouWantToDisplayAsChoice;
}
For example, if your Extension has a property username, you can use return
$this->username, and the choice field will be populated with the username property of each user.
See magic __toString.

add a variable session in entity?

i create an entity "Products".
in this entity, i get the price like
public function getPrice()
{
return $this->price;
}
Indeed, i would like to add in this method a session variable for convert currency like this :
public function getPrix()
{
$devise = $this->session->get('CurencyToConvert');
$json = json_decode(file_get_contents('http://api.fixer.io/latest?symbols='.$devise));
$rates = $json->rates->CHF;
return $this->prix * $rates;
}
but i think this is the wrong solution.
i don't know how to do to get an automatic conversion when i get the price!!
do I create a service for my checkout and a twig filter for my views?
thank you
The Products class is a POPO (Playing Old PHP Object) it's really required to keep it simple which means this class must have only attributes like price and getters and setters for those attributes,
You can create a service to handle Currency conversion, and you can also inject it into a twig filter so you gonna have one piece of code implementing this functionality

Sonata Admin - how to set the menu.label attribute?

According to the Sonata source code, the last node in the breadcrumb is rendered this way:
# standard_layout.html.twig #
<li class="active"><span>{{ menu.label }}</span></li>
In my setup, when opening a given Admin subclass, the last node simply becomes a raw string according to the entity handled by the Admin:
Dashboard / Entity List / Acme\SomeBundle\Entity\Stuff:000000001d74ac0a00007ff2930a326f
How can I set the value of menu.label to get something more appropriate? I have tried, in my Admin subclass, to override the following:
protected function configureTabMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null) {
$this->configureSideMenu($menu, $action, $childAdmin);
}
protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null) {
$menu->setLabel("Some nice label");
$menu->setName("Some nice name");
}
However, this does not change anything, even though I have verified that the methods above are called during runtime.
Finally found a good (and somewhat obvious) solution to this.
The Sonata Admin class uses an internal toString($object) method in order to get a label string for the entity it is handling. Thus, the key is to implement the __toString() method of the entity in question:
public function __toString() {
return "test";
}
The best way is to configure the $classnameLabel variable in the Admin Class :
class fooAdmin extends Admin
{
protected $classnameLabel = 'Custom Label';
}
But it have the same issue (weird name with entity path) doing it, even if it is working fine on all the others pages.
Apparently, the Sonata way of solving this is show here:
Quote:
While it’s very friendly of the SonataAdminBundle to notify the admin of a successful creation, the classname and some sort of hash aren’t really nice to read. This is the default string representation of an object in the SonataAdminBundle. You can change it by defining a toString() (note: no underscore prefix) method in the Admin class. This receives the object to transform to a string as the first parameter:
Source: https://sonata-project.org/bundles/admin/master/doc/getting_started/the_form_view.html#creating-a-blog-post

Doctrine2 criteria filtering can't find property

I'm filtering an entity in Symfony2 that has an association with a "start_date" property. This is the value in the DB and it has a Doctrine-generated getter of getStartDate. Inside the filter method, I use an expression of
Criteria::expr()->gt('start_date', $now)
but that fails with an error about accessing a protected property. If I change the criteria to
Criteria::expr()->gt('startDate', $now)
it fails again but this time with an error about not having that property on the object. Which is correct? I shouldn't need to add a separate getting for just the criteria filtering.
Correct is first case:
Criteria::expr()->gt('start_date', $now)
Is getter public? Try to make this property public. Is error still display in this case?
Also try to add next getters for test:
public function start_date(){};
public function getStart_date(){};
You must to correct your code to this:
/**
* #ORM\Column(type="datetime", name="start_date")
*/
protected $startDate;
public function getStartDate() {
return $this->startDate;
}
and then use:
Criteria::expr()->gt('startDate', $now)
Symfony need to call your proprties in camelCase style, then camelCase getters will be work

Resources