Symfony - Doctrine createQueryBuilder from json_array - symfony

Crete custom query in Symfony 4 and I use createQueryBuilder().
My entity have column price_ranges type type="json_array"
This data I store in this column
{
"from": "10.10.2010",
"to": "10.20.2010",
"pricePerNight": 100,
"minStay": 7
}
Want to query data by pricePerNight key in price_ranges column.
I create function but I have the following error:
[Semantical Error] line 0, col 41 near 'price_ranges': Error: Class App\Entity\House has no field or association named price_ranges
Here is my function. Where am I wrong?
public function findDataByPriceRange()
{
$qb = $this->createQueryBuilder('u');
$qb->select('u')
->where('u.price_ranges LIKE :price_ranges')
->setParameter('pricePerNight', 100);
return $qb->getQuery()->getResult();
}
After I edit my function:
public function findVillasByPriceRange()
{
$qb = $this->createQueryBuilder('u');
$qb->select('u')
->where('u.priceRanges LIKE :priceRanges')
->setParameter('pricePerNight', 100);
return $qb->getQuery()->getResult();
}
I get this error:
Invalid parameter: token pricePerNight is not defined in the query.

You need to use the same parameter name in where() and setParameter() like this
->where('u.priceRanges LIKE :parameterName')
->setParameter('parameterName', 100);

Related

Symfony - How to use LIKE with COALESCE in a Doctrine request?

I have some trouble with LIKE and COALESCE in a Doctrine request (not 100% sure that the trouble is there).
I would like to search inside a database with a filter that match only if exist, and only with a part of the value (for example find 'abc' with the filter set to 'ab').
This request works fine :
public function findUsers($entreprise, $filtres)
{
$filtre_name = $filtres['name'];
return $this->createQueryBuilder('users')
->where('users.entreprise = :entreprise')
->andWhere('users.name = COALESCE(:filtre_name, users.name)')
->setParameter('entreprise', $entreprise)
->setParameter('filtre_name', $filtre_name)
->orderBy('users.name', 'ASC')
->getQuery()
->getResult();
}
It return all the users of the company "entreprise" where "filtre_name" match (if not null) with "name" in the database. (If "filtre_name" is null, then the where match for all the database thanks to COALESCE).
I would like now to do the same thing but with "LIKE" instead of "=" because for now the name has to match perfectly and I would like a match for "abc" with only "ab" inside the filter for example.
public function findUsers($entreprise, $filtres)
{
$filtre_name = $filtres['name'];
return $this->createQueryBuilder('users')
->where('users.entreprise = :entreprise')
->andWhere('users.name LIKE COALESCE(:filtre_name, users.name)')
->setParameter('entreprise', $entreprise)
->setParameter('filtre_name', '%'.$filtre_name.'%')
->orderBy('users.name', 'ASC')
->getQuery()
->getResult();
}
The result is an error : "Warning: Undefined property: Doctrine\ORM\Query\AST\CoalesceExpression::$type".
I have find a solution. I build my queryBuilder with parameter only if they are not Null. So I remove COALESCE and now I can use LIKE.
public function findUsers($entreprise, $filtres)
{
$filtre_nom = $filtres['nom'];
$filtre_gestionnaire = $filtres['gestionnaire'];
$qb = $this ->createQueryBuilder('users');
$qb ->where('users.entreprise = :entreprise')
->setParameter('entreprise', $entreprise);
if ($filtre_nom != Null) {
$qb ->andWhere('users.nom LIKE :filtre_nom')
->setParameter('filtre_nom', '%'.$filtre_nom.'%');
}
if ($filtre_gestionnaire != Null) {
$qb ->andWhere('users.gestionnaire LIKE :filtre_gestionnaire')
->setParameter('filtre_gestionnaire', '%'.$filtre_gestionnaire.'%');
}
$qb->addorderBy('users.nom', 'ASC');
return $qb ->getQuery()
->getResult();
}

Symfony 6 - fetch certain fields

In my table I have: 'id, message, user(from User::class, foreign key) etc...'
How can I select specific fields ? I would like fetch only message and username, how can I do ?
I tried this
public function getNameAndMessage()
{
return $this->createQueryBuilder('c')
->select('c.message, c.user.username')
->orderBy('c.id', 'ASC')
->setFirstResult(5)
->getQuery()
->getResult()
;
}
But an error appear: [Semantical Error] line 0, col 25 near 'username FROM': Error: Class App\Entity\Comment has no field or association named user.username
Someone can help me please
To access the properties of the User entity, you must join it to your query like this:
public function getNameAndMessage(){
return $this->createQueryBuilder('c')
->select('c.message, u.username')
->leftJoin('c.user','u')
->orderBy('c.id', 'ASC')
->getQuery()
->getResult();
}

How to sum the contents of a document field with symfony query builder?

I am just trying to get the total value of one of the fields of my documents but it's not working. What am I missing?
#ProductRepository
public function countTotalValue()
{
return $this->createQueryBuilder('a')
->select('SUM(a.price)')
->getQuery()
->getSingleScalarResult()
;
}
I discovered it!
public function countTotalValue()
{
$array = $this->createQueryBuilder()
->select('price')
->hydrate(false)
->getQuery()
->execute()
->toArray()
;
$array = array_column($array, 'price');
return (array_sum($array));
}
It was returning a complex array, I had to stripe it before make the sum.

Get custom getter property into QueryBuilder object?

I have the following QueryBuilder snippet working as expected:
$restaurants = $qb->select('r.id, r.name, r.addressGpsLat, r.addressGpsLng, r.addressZip, r.addressCity')
->from('BackendBundle:Restaurant', 'r')
->orderBy('r.name', 'ASC');
In our Restaurant entity we calculate ratings based on a relation, which looks like this:
public function getRating()
{
$rating = 0;
$votes = count($this->votes);
foreach ($this->votes as $vote) {
$rating += $vote->getRating();
}
if ($votes == 0) {
return null;
}
return number_format(($rating / $votes), 2, ',', '.');
}
So my question: is there a way I get the result of the getRating() property into my QueryBuilder object? We need it to be a seperate attribute in our JSON response. E.g. { …, "rating":2.2, …}
Any advice on this? Thanks!

how to access annotation of an property(class,mappedBy,inversedBy)

Good morning,
Is it exist an function where I pass an entity and the propertyName and return me the mappedBy,inversedBy and absoluteClassName of an Entity.
The goal is to use the __call to create automatic getteur/setteur and addFucntion bidirectionnal.
I don't want to use generates Entities I want all getteur,setteur and add Function use __call.
But i can"t do an addBirectionnal if i don't know if the relation is many to many or one to many and if i don't know the name of the mappedBy.
my code:
public function __get($p){
return $this->$p;
}
public function __set($p,$v){
$this->$p = $v;
return $this;
}
public function __call($name,$arguments){
if(substr($name,1,3)=='et')
$name2 = substr(3);
if($name[0] == 'g'){
return $this->$name2;
}else{//substr($name,0,1) == 's'
$this->$name2 = $arguments[0];
/*for a one to one*/
/*$mappedByName= getmappedByOrInversedBy(get_class($name),$name2);
if($mappedByName){
$this->$name->$mappedByName = $this;/
}*/
return $this;
}
}
}
I need getmappedByOrInversedBy, thanks.
edit: I try this
public function test(){
$str = "AppBundle\Entity\Group";
$mapping = new \Doctrine\ORM\Mapping\ClassMetadataInfo($str);
$d = $mapping->getAssociationMappedByTargetField('trad');
var_dump($d);
return $this->render('default/index.html.twig', array(
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..'),
));
}
class Group
{
...
/**
* #ORM\OneToOne(targetEntity="Traduction",inversedBy="grp")
*/
protected $trad;
}
Result : Undefined index: trad
The ClassMetadataInfo is what you are looking for.
Creates an instance with the entityName :
$mapping = new \Doctrine\ORM\Mapping\ClassMetadataInfo($entityNamespaceOrAlias);
Then, get the informations you want :
Get all association names: $mapping->getAssociationNames();
Get the join column of an association:
$mapping->getSingleAssociationJoinColumnName($fieldName);
Get the mappedBy column of an association:
$mapping->getAssociationMappedByTargetField($fieldName);
...
Look at the class to know which method you can access.
Hopes it's what you expect.
EDIT
As you can access the EntityManager (i.e. from a controller), use :
$em = $this->getDoctrine()->getManager();
$metadata = $em->getClassMetadata('AppBundle:Group');
To be sure there is no problem with your entity namespace, try :
print $metadata->getTableName();
To retrieve the associations of the entity, use :
$metadata->getAssociationNames();
And to get the mapping informations of an existing association, use :
$metadata->getAssociationMapping($fieldName);
And to get all the association mappings of your entity, use:
$metadata->getAssociationMappings();

Resources