Sonata Admin Bundle listbox sort order - php

I have 2 entities one referenced to another with many to one relation. For example, User and City.
I need listbox with Cities in User edit page to be sorted by Name, not by Id.
How can I do it?

In your Entity, you can specify the ordering .
Example :
<?php
/**
* #ManyToMany(targetEntity="Group")
* #OrderBy({"name" = "ASC"})
*/
private $groups;

Related

Nested composite foreign keys as ID in Doctrine

We are developing an online store in Symfony 5 and Doctrine 2 where multiple customers (called participants in this case) can participate in the same order item and share the cost. The following simplified class diagram demonstrates the domain model:
The pure object model works fine in unit tests, but you obviously need to persist the data to a database, which is why we need to introduce IDs.
Order, Product and Participant are entities with their own ID. In an ideal world, OrderItem and OrderItemParticipation would not need their own ID but be identified by the related entities they belong to, meaning their ID would be a composite foreign key.
So, an OrderItem would by identified by the composite key of Order.id and Product.id, which is pretty much exactly the same as given in this example from the Doctrine 2 documentation: https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/tutorials/composite-primary-keys.html#use-case-3-join-table-with-metadata.
Since OrderItemParticipation relates to OrderItem, which uses a composite key itself, it would need to use a nested composite key consisting of Order.id, Product.id and Participant.id.
Unfortunately, Doctrine 2 doesn't seem to be able to work with nested composite keys as ID. I get this error
Column name id referenced for relation from
App\Entity\OrderItemParticipation towards App\Entity\OrderItem does
not exist.
when I try to generate a migration with the following mapping:
/** #ORM\Entity */
class OrderItem {
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity=Order::class, inversedBy="items")
*/
private Order $order;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity=Product::class)
*/
private Product $product;
// ...
}
/** #ORM\Entity */
class OrderItemParticipation {
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity=OrderItem::class, inversedBy="participations")
*/
private OrderItem $orderItem;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity=Participant::class)
*/
private Participant $participant;
// ...
}
So it seems that Doctrine is fine with my ID mapping in OrderItem, but it struggles when it gets to OrderItemParticipation. Is there a way to make Doctrine work with the given domain model? Is it maybe just an issue with the auto-generation of the migration, so if I had already manually set up the database, Doctrine might work with the given mapping? Or is the nested composite key ID approach too complicated for Doctrine?

How can I create a relation between entities twice

I am trying to create some sort of Inventory:
(The following Code is obviously not complete)
class User
{
/**
* #ORM\ManyToMany(targetEntity="Item", fetch="EAGER")
* #ORM\JoinTable(name="character_inventory_mm",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="item_id", referencedColumnName="id")}
* )
*/
private $inventory;
//etc
}
My Problem is that a User can have the same Item twice or even more often.
Is there a way to tell Doctrine not to create unique keys on those Relations or do I have to create some sort of mapping entity?
Something like:
* #ORM\ManyToMany(targetEntity="Item", fetch="EAGER", indexBy="NULL")
I have looked up doctrines joinTable and joinColumns and ManytoMany Documentation but I did not find a way to "fix" my Issue.
Thanks
That would need an unique key to differentiate multiple items connected to the same user.
Just create UserItems entity with a primary key and correspoding OneToMany and ManyToOne relations.

Reference Many sonata admin Bundle

In my project I'm using two documents : User and Quizz. In fact I have Unidirectional relation between this two documents ( the user references one or more Quizzs).
In my Back end I'm using Sonata mongoDb Amin Bundle, And when i'm creating a User I want to add a Quizz to this User. It appears in the form, I add the Quizz , the quizz is created but there is no reference in the User Document.
User Document :
/**
* #var ArrayCollection
* #MongoDB\ReferenceMany(targetDocument="\ATS\QuizzBundle\Document\Quizz", cascade={"all"})
*/
protected $quizz = array();
And here is the UserAdmin :
->add('quizz', 'sonata_type_collection',array('by_reference' => false),
array('admin_code' => 'sonata.admin.quizz')) ;
I'm wondering where is the origin of this problem, any one can help please? thank you

Doctrine - Custom form field based on query

I have 2 linked entities: User and Acess. I want my doctrine User entity to have a field that informs me if the user has acesses or not.
I can't do a simple OneToMany relationship between the two tables, because there is thousands of acesses and it would be too costly to get thousands of records from the database once I only need to know if there is any.
What I would want is a field linked to a native query like:
select * from accesses where user = <whatever> limit 1
More specifically, something like:
/**
* USer
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User {
/**
* #ORM\Column(name="user_id", type="bigint", nullable=false)
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=300, nullable=false)
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\Query="select exists (select id_acesses from accesses where user = "$id" limit 1)"
*/
private $hasAcesses;
}
Is this possible ? is there another way to do this ?
Edit:
based on #Otanaught answer below, I have done some tests:
Using a OneToMany relation with EXTRA_LAZY fetch:
user-getAccesses()->isEmpty() selected the whole collection
user-getAccesses()->count() used count(*) in the database which took 243ms to return
for comparasion my query above who did what I want took 12ms in average with peeks of 2ms or even 1ms.
Maybe the good folks at doctrine could implement this at isEmpty for extra lazy queries ?
Thanx #Otanaught
Doctrine does not provide an annotation that allows you to specify a query for a property of an entity (Annotation reference). You could create a custom method in your repository to implement the check. Did you measure how costly the relation would be? With correct relations and indexes this should be a none issue, because doctrine lazy loads the relation? Check the doctrine documentation about extra lazy collections.

Multiple account-types?

I'm currently using Symfony2 and doctrine. and I'm working on a "create-account" page. There will be 2 different kinds of accounts avaliable on the page, one for normal-usersand one for companies.
I've got an entity (table) called Account this table contains the username, passwordand saltcolumns.
If a company logs in I want to have the company information from a company-table and if a normal-userlogs in I want the information from the user-table.
I've been thinking about having a column named usertype which tells me what type it is, then if the usertype is a company retrieve the company-information-entity and if it's a userretrieve the user-information-entity (corresponding to the id of the account).
Is this a good way to solve this problem? or should I have 2 different tables? AccountUser and AccountCompany?
If you have many columns in Company table that don't exist in the User table and vice versa the best way to solve your problem is to use class-table inheritance which will create three tables: Account, User, Company. User and Company must be subclasses of Account entity.
According to link above you should have code like this:
namespace MyProject\Model;
/**
* #Entity
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="usertype", type="string")
* #DiscriminatorMap({"user" = "User", "company" = "Company"})
*/
class Account
{
// ...
}
/** #Entity */
class User extends Account
{
// ...
}
/** #Entity */
class Company extends Account
{
// ...
}

Categories