I have an array of collection named $configurations
. This array matches of my Entity Configuration.php
connected to Product.php
as a ManyToMany
. Now I have another entity named WorkType.php
which is connected too to Configuration.php
by a ManyToMany
.
The goal is to recover the product who has O/Null
or Many
configurations for the current work type.
By default I have a product without configurations, but user could choose by checkboxes a O/Null
or One
or Many
configurations available for a work type.
So I created this queryBuilder in my ProductRepository.php
:
public function getProductByManyConfig($slug, $configurations)
{
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$queryBuilder->select('p')
->from('MyBundle', 'p')
->join('p.workType', 'wt', 'WITH', 'wt.id = p.workType')
->leftJoin('p.configurations','c');
$queryBuilder->add('where', $queryBuilder->expr()->in('c', ':c'))
->andWhere('wt.slug = :slug')
->setParameters(array('slug'=> $slug, 'c'=> $configurations));
return $queryBuilder->getQuery()
->getResult();
}
It works, but the proble is that it returns me all product matching with the array of configurations I pass to the query.
For example if the array have the id
1 and 2 of Configuration.php
, the query returns me the products matching with configuration.id = 1 , configuration.id = 2 and configuration.id =1 and 2 .
So I have 3 conditions to achieve, I need only one; eg only the product which containing all the configuration.id !
I only need to return the only one product containing the ids
of Configuration.php
passed into the array for the current WorkType.php
!
This is my controller code:
$vars = array(); //containing all values I need for recover configurations properties
$em = $this->getDoctrine()->getManager();
$var = array_values($vars);
$configurations = $this->getDoctrine()->getRepository('MyBundle:Configuration')->findByName($var);
foreach ($configurations as $conf) {
$name = $conf->getName();
}
$slug = "the_right_database_correspondence";
$arrayProbuctConfig = $this->getDoctrine()->getRepository('MyBundle:Product')->getProductByManyConfig($slug, $configurations);
// return of the view
As the choice of configurations could change, I need to create this dynamic method. How can I return the good result ?
I had the same problem with Doctrine2 recently and I came with that answer.
If you want all Product
entities that are linked with all the configurations, you need to add a where
condition for every configuration.
Considering your $configurations
variable is an array of Configuration
entities
$queryBuilder->select('p')
->from('MyBundle', 'p')
->join('p.workType', 'wt', 'WITH', 'wt.id = p.workType')
->leftJoin('p.configurations','c');
$queryBuilder->where('wt.slug = :slug')->setParameter('slug', $slug);
$nbConfs = count($configurations);
for($i = 0; $i < count($configurations); $i++){
$queryBuilder->andWhere(":conf{$i} MEMBER OF p.configurations")->setParameter("conf{$i}", $configurations[$i]);
}
$queryBuilder
->having('COUNT(c.id) =:some_count')
->setParameter('some_count', $nbConfs);
I had to use a for
loop to create different tokens (the string preceded by :
), otherwise Doctrine doesn't add them to its internal collection of parameters.
Edit : Query modified to consider the case where you pass no configurations and want to get Product
s that has no relations to Configuration
s.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.