Symfony2 Criteria filtering OneToMany - symfony

I have an Entity called 'User', which has a OnetoMany relation in a field called 'books'.
I also have an Entity called 'Book' which has many attributes, like, 'title' or 'date'.
There ir another entity called 'Date', which attributes are: 'day', 'month' and 'year'.
I want to filter the books that the user has which are from year 2009.
I am tring to do it like this, using Criteria, but I recieve an error because field date.year does not exist:
$books = $user->getBooks();
$criteria = Criteria::create()
->where(Criteria::expr()->eq("date.year", "2009"));
$books_2009 = $books->matching($criteria);
Any idea of how can I solve it?

$criteria = Criteria::create()
->where(Criteria::expr()->eq("year", "2009"));
This should work. Please let me know.

Related

How can I join two tables without association?

I try to combine two arrays in Symfony that do not have an association field. In documents the field "uuid" is actually the "documentId" in data. Here my approach:
$builder = $this->em->createQueryBuilder();
$result = $builder->select('documents')
->from('App:Documents', 'documents')
->leftJoin('data', 'data')
->andWhere('documents.uuid = data.documentId')
->andWhere('data.fields = :id')
->setParameter('id', 2)
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
But I get the error message that documents has no association data.
You are quite close, but lack a few things.
You need to be more precise with your join and specify which entity is targeted (if there is no relation or inheritance).
// If your entity name is called Data
->leftJoin(Data::class, 'data', 'WITH','data.documentId = documents.uuid')
Let's say you are creating your method from the Documents repository (which by the way should be in singular instead of plural).
Your method would look like this:
$result = $this->createQueryBuilder('documents')
->select('documents as document, data as myData')
->leftJoin(Data::class, 'data', \Doctrine\ORM\Query\Expr\Join::WITH,'data.documentId = documents.uuid')
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
But I think there may be an issue with your schema if there is no relation between two entities that are clearly related.

Symfony2 - related entity contains 'isDefault' property how to use in related entity form

I have 2 related entities, e.g. Book and Publisher (Book has one publisher, publisher has many books).
When editing\adding a Book I want to present a select of the Publishers.
Publishers has a property 'isDefault' on of the Publisher records will be marked as isDefault TRUE.
How do I make use of this in my add/edit form to pre-select the default Publisher?
I would recommend injecting publisherRepository as a service into your form.
And then declare a field something like this:
$builder->add('publishers', 'choice', array(
'choices' => $this->publisherRepository->findAll(),
'data' => $this->publisherRepository->findOneBy(['isDefault' => true]),
));

doctrine join column joined on other entity

I have 3 tables:
Post -> Type -> Category
I need to get the category on the Post entity passing per Type to use this on a filter form
This is possible?
like a join and subjoin
If I understand correctly, you want to be able to filter Post's by Category.
Like with any other field you wish to filter by, you have to add a Form to the filter's FormBuilder. The problem in this case is that the Entity bound to the form doesn't have the property category. It's its property type who does.
Thus, you need to tell the Form how to access the right property. This is achieved by using the property_path option. Here's the documentation for it.
You would do something like this in your filter's Type:
$builder
->add('category', 'entity', array(
'label' => 'Category',
'data_class' => 'Category',
'property_path' => 'type.category',
))
;
The property_path option is very powerful. It will accept any path that the PropertyAccess component does. Read its documentation here.
Multiple joins are possible in doctrine. Please, read this section in doctrine documentation.

Multiple orderby within Criteria

I currently use the Criteria to filter a collection of objects. But when I want to achieve with 2 orderBy fields, only the first is considered. I do not understand.
$events = new Collections\ArrayCollection($results);
$dateFrom = new \DateTime($date);
$dateTo = new \DateTime(date('Y-m-d H:i:s', strtotime($date . ' + 1 day')));
$criteria = Criteria::create()
->where(Criteria::expr()->eq('activity', $activity));
$criteria->orderBy(array(
"time" => "ASC",
"title" => "ASC"
));
How can I make it work with two orderby fields and not only the first ?
Thank you in advance for any answers !
Your code is correct, assuming that $criteria is then applied correctly to the ArrayCollection.
Judging by the names of your fields you're trying to order by, it's possible that title doesn't affect the order because time doesn't repeat among the elements in the collection.
If this isn't the case, please provide more information on the results you're getting and I will update my answer.
Update (in response to additional data provided that has since been deleted):
You are sorting the collection correctly. The problem is that you're then feeding the ArrayCollection into the Paginator, which apparently cannot sort by more than one field.
There's an open issue in Knp's tracker about this: https://github.com/KnpLabs/KnpPaginatorBundle/issues/109.

Symfony - Get Entity Repository with multiple ID's

I have an entity that has multiple keys, how would I go about finding the proper object based on multiple ids?
$product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
It's a little confusing what you're asking here. It sounds as though you have an entity with a compound key (primary key relates to multiple columns) and want to find it based on it's primary key values, yes?
If so, the find method will require an array containing values for each of the fields that make up the key:
$product = $em->getRepository('AcmeStoreBundle:Product')->find(array(
'key1' => 'value1',
'key2' => 'value2'
));
Alternatively, you could use findOneBy method. This would be useful for when the combination of the provided fields are not unique as you're able to provide a second argument to define the ordering.
$product = $em->getRepository('AcmeStoreBundle:Product')->findOneBy(array(
'key1' => 'value1',
'key2' => 'value2'
), array('updated_at' => 'DESC'));
See http://symfony.com/doc/2.0/book/doctrine.html#fetching-objects-from-the-database
$product = $em->getRepository('AcmeStoreBundle:Product')->findBy(
array('key1' => 'value1', 'key2'=>'value2')
);

Resources