Doctrine where if empty - php

$repository = $this->getEntityManager()->getRepository('App\Entity\HolidayPackages');
$holiday_packages = $repository
->createQueryBuilder('hp')
->addSelect('hpt')
->innerJoin('hp.holiday_packages_translation', 'hpt')
->where('hpt.code = :code')
->setParameter('code', $language_code)
->andWhere('hpt.title LIKE :title')
->setParameter('title', $title . '%');
if (!empty($starting_date)) {
$repository
->andWhere('hp.starting_date = :starting_date')
->setParameter('starting_date', $starting_date);
}
$repository
->setFirstResult($offset)
->setMaxResults($limit)
->getQuery()
->getResult();
I am trying to filter search. How can i check if parameter is empty, don' t add to where query ?
I followed this link : doctrine2 - querybuilder, empty parameters
But i doesn't works for me.
When i try to like that, i got an error :
Undefined method 'setFirstResult'. The method name must start with either findBy or findOneBy!
Thanks in advice..
Update
if i add to command line setFirstResult error change :
Undefined method 'getQuery'. The method name must start with either findBy or findOneBy!
When i used to use pdo, i can like this using bind parameters. But i don't know how to do in Doctrine.

You should keep using $holiday_packages instead of $repository.
$repository = $this->getEntityManager()->getRepository('App\Entity\HolidayPackages');
$holiday_packages = $repository
->createQueryBuilder('hp')
->addSelect('hpt')
->innerJoin('hp.holiday_packages_translation', 'hpt')
->where('hpt.code = :code')
->setParameter('code', $language_code)
->andWhere('hpt.title LIKE :title')
->setParameter('title', $title . '%');
if (!empty($starting_date)) {
$holiday_packages->andWhere('hp.starting_date = :starting_date')
->setParameter('starting_date', $starting_date);
}
$holiday_packages->setFirstResult($offset)
->setMaxResults($limit)
->getQuery()
->getResult();

Related

Symfony - using orWhere() in doctrine query builder

I want to return query result for the words I am searching in a message but just where userOne or userTwo is currently logged in user.
I think I have trouble with defining my query builder right because when testing otherwise logged in user is returned correctly.
I am trying with orWhere() clause but it always returns all results of that word not just for logged in user.
My code:
public function search($word, $user)
{
return $this->getMessageRepository()
->createQueryBuilder('a')
->where('a.message LIKE :message')
->andWhere("a.toUser = $user OR fromUser = $user")
->setParameter('message', '%' . $word. '%')
->setParameter('toUser', $user)
->setParameter('fromUser', $user)
->getQuery()
->getResult();
}
The logic of the where statement should work as expected.
But it seems like you are using incorrect parameter binding.
toUser and fromUser are columns and therefore no need to bind them.
$user is the target user that we want to filter on, thus it should be bound to the query.
An example:
{
return $this->getMessageRepository()
->createQueryBuilder('a')
->where('a.message LIKE :message')
->andWhere("a.toUser = :user OR a.fromUser = :user")
->setParameter('message', '%' . $word. '%')
->setParameter('user', $user)
->getQuery()
->getResult();
}
You need to specify all fields with a prefix a because you create this prefix in createQueryBuilder('a');
If you have more 1 params use setParameters.
And you can OR write in QueryBuilder type -> $builder->expr()->orX.
Your query example:
public function search($word, $user)
{
$builder = $this->createQueryBuilder('a');
return $builder
->where('a.message LIKE :message')
->andWhere($builder->expr()->orX(
$builder->expr()->eq('a.toUser', ':user'),
$builder->expr()->eq('a.fromUser', ':user'),
))
->setParameters([
'message' => '%' . $word . '%',
'user' => $user,
])
->getQuery()
->getResult();
}

How to make a query_builder out of raw sql

I need help to change this code into a query builder in Symfony 5.
$em = $this->getEntityManager();
$query = "SELECT * FROM fizuser where roles::text LIKE :role";
$statement = $em->getConnection()->prepare($query);
$statement->bindValue('role', '%'.$role.'%');
$statement->execute();
$result = $statement->fetchAll();
return $result;
This is what I've tried:
function (UserRepository $er) {
return $er->createQueryBuilder('u')
->where("u.roles :: text like '%a%'");
However, I can't use "::" tag.
You can do it with -
return $this->createQueryBuilder('u')
->andWhere('u.roles LIKE :role')
->setParameter('role', '%'.'a'.'%')
->getQuery()
->getResult();
I'd like to add some details,
the column type in psql is json.
Using this type of query builder gives me error
SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: json ~~ unknown
LINE 1: ...ted AS activated_25 FROM fizuser f0_ WHERE f0_.roles LIKE $1

Prioritize MySQL SELECT/LIKE result in Repository

I want to create a query that values more precise search terms, e.g. search for "Essen" should return Essen currently it returns Evessen as this is a valid value as well.
My current function:
public function findCities($city){
$qb = $this->createQueryBuilder('z');
$qb
->select('z')
->where($qb->expr()->like('z.city', ':city'))
->orderBy('z.code')
->setParameter('city', '%'.$city . '%');
return $qb->getQuery()->getResult();
}
Based on THIS advice I created a repository function:
public function findCities($city){
$qb = $this->createQueryBuilder('z');
$qb
->select('z')
->where($qb->expr()->like('z.city', ':city'))
->orderBy('INSTR(z.city, '.$city.'), z.city')
->setParameter('city', '%'.$city . '%');
return $qb->getQuery()->getResult();
}
Unfortunately it returns [Syntax Error] line 0, col 70: Error: Expected known function, got 'INSTR'
Any other approach (that does NOT return an array, as there is a function that needs heavy altering if the output is an array, I'd like to avoid that) maybe?
There is no INSTR function in DQL, that's why you get this error see docs
instead you can make NativeQuery see docs
something like this
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('City', 'c');
// for every selected field you should do this
$rsm->addFieldResult('c', 'id', 'id');
$rsm->addFieldResult('c', 'name', 'name');
$em = $this->getEntityManager()
->createNativeQuery('
SELECT
id, name
FROM cities WHERE city LIKE '%:city%'
ORDER BY INSTR(city, ':city'), city',
$rsm
)->setParameter('city', $city);
return $em->getResult();

How to fetch class instead of array in Doctrine 2

I am able to fetch my data from database by using this structure:
$user = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Emails')
->find(8081);
When I do that, I am able to get my data like this:
$user->getColumnNameHere();
Basically I am able to use Entity Class.
But if I want to use QueryBuilder instead of find I am only getting associative arrays.
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
$product returnds as array. Is it possible to fetch it withj Entity Managaer Class? If yes, how?
I digg the documentation but it seems not possible or not exist in the doc or I'm just blind :)
Yes you can, usually using:
$repository
->createQueryBuilder('p')
->getQuery()
->execute()
;
This should return you an array of entities.
If you want to get a single entity result, use either getSingleResult or getOneOrNullResult:
$repository
->createQueryBuilder('p')
->getQuery()
->getOneOrNullResult()
;
Warning: These method can potentially throw NonUniqueResultException.
Edit: Ok, so the question was about partial objects: http://docs.doctrine-project.org/en/latest/reference/partial-objects.html
you can get an object instead of array by using "Partial Objects".
here is a tested example with DoctrineORM 2.2.2:
// create query builder
// $em is the EntityManager
$qb = $em->createQueryBuilder();
// specify the fields to fetch (unselected fields will have a null value)
$qb->select ('partial p.{id,pubDate,title,summary}')
->from ('Project\Entity\Post', 'p')
->where ('p.isActive = 1')
->orderBy ('p.pubDate', 'desc');
$q = $qb->getQuery();
$result = $q->getResult();
var_dump($result); // => object
If you wish to return an object from your original query:
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
Remove this line
->select('p.columnNameHere')
As soon as you use select, it will return an array...
getResult() method returns a collection (an array) of entities. Use getSingleResult() if you're going to fetch only one object.
EDIT:
Oh, I just noticed that you want to fetch a single field of a single object. Use getSingleScalarResult() as #Florian suggests.

How to select distinct query using symfony2 doctrine query builder?

I have this symfony code where it retrieves all the categories related to a blog section on my project:
$category = $catrep->createQueryBuilder('cc')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->getQuery();
$categories = $category->getResult();
This works, but the query includes duplicates:
Test Content
Business
Test Content
I want to use the DISTINCT command in my query. The only examples I have seen require me to write raw SQL. I want to avoid this as much as possible as I am trying to keep all of my code the same so they all use the QueryBuilder feature supplied by Symfony2/Doctrine.
I tried adding distinct() to my query like this:
$category = $catrep->createQueryBuilder('cc')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->distinct('cc.categoryid')
->getQuery();
$categories = $category->getResult();
But it results in the following error:
Fatal error: Call to undefined method Doctrine\ORM\QueryBuilder::distinct()
How do I tell symfony to select distinct?
This works:
$category = $catrep->createQueryBuilder('cc')
->select('cc.categoryid')
->where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->distinct()
->getQuery();
$categories = $category->getResult();
Edit for Symfony 3 & 4.
You should use ->groupBy('cc.categoryid') instead of ->distinct()
If you use the "select()" statement, you can do this:
$category = $catrep->createQueryBuilder('cc')
->select('DISTINCT cc.contenttype')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->getQuery();
$categories = $category->getResult();
you could write
select DISTINCT f from t;
as
select f from t group by f;
thing is, I am just currently myself getting into Doctrine, so I cannot give you a real answer. but you could as shown above, simulate a distinct with group by and transform that into Doctrine. if you want add further filtering then use HAVING after group by.
Just open your repository file and add this new function, then call it inside your controller:
public function distinctCategories(){
return $this->createQueryBuilder('cc')
->where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->groupBy('cc.blogarticle')
->getQuery()
->getResult()
;
}
Then within your controller:
public function index(YourRepository $repo)
{
$distinctCategories = $repo->distinctCategories();
return $this->render('your_twig_file.html.twig', [
'distinctCategories' => $distinctCategories
]);
}
Good luck!

Categories