Doctrine OrderBy a PHP Function - symfony

I have an entity city that has an address attribute and a PHP function calculate($addess) that takes the city attribute address and returns a number.
I m trying to use the return of the function calculate() to order my cities. is it possible with Doctrine DQL? How can I do it?
Thanks in advance for any guidance
public function calculate($address)
{
//...
return $number;
}
I don't know if that exists but this is what I'm trying to do:
$qb
->select('u')
->from('City', 'u')
->orderBy(calculate($address), 'ASC')
;
Address needs to be a City attribute.

I don't know what calculate() logic does but couldn't you give it to your class as parameter? Than add adress_number to yor DB and mapping and simply orderBy this parameter:
$qb->select('u')
->from('City', 'u')
->orderBy('u.adressNumber', 'ASC');
Hope this helps. :)

Related

how i select some value equal array in Doctrine "createQueryBuilder"

can you help me with this code
There are several columns in the database, one of which is a role, user role value looks like this:
["ROLE_ADMIN"]
how can I get all users who have this role?
public function findUserWithRolle(){
$qb=$this->createQueryBuilder('R');
$qb->select('R.username')
->where('R.roles=["ROLE_ADMIN"]');
return $qb->getQuery()->getResult();
}
If use "direct LIKE-approach" you could get them like:
public function findUserWithRolle(string $role = 'ROLE_ADMIN'){
$qb=$this->createQueryBuilder('R');
$qb->select('R.username')
->andWhere('R.roles LIKE :role')
->setParameter('role', '%'.$role.'%');
return $qb->getQuery()->getResult();
}
Note: There are possible some pitfalls. With "LIKE-approach". But for your case enough.

How can i get current user's id to use it in a dql statement?

I know that this question was asked by many but no one was answered even :
This reponse.
is not a good reponse for how do i get current user's id into a dql statement in Repository.
i see so much talking about it's not logic or it's a bad choice so what 's the good one to use the current user's id like a param into a dql statement or QueryBuilder and this what i do but doesn't work :
My Controller :
public function GetGroupsByStudentAction()
{
$em=$this->getDoctrine()->getManager();
$modeles=$em->getRepository("AcmeMyBundle:GroupMatiere")
->findGroupByStudent();
return($this->render("AcmeMyBundle:GroupMatiere:list.html.twig",array("modeles"=>$modeles)));
}
public function ConnectedUserIdAction()
{ $user = $this->container->get('security.token_bag')->getToken()->getUser();
return $user->getId();
}
MyServices :
<service id="serviceGroupe" class="Acme\MyBundle\Controller\GroupMatiereController"/>
MyRepository :
public function findGroupByStudent()
{
// $currentid = i dont know how i call the methode from the service;
$query=$this->getEntityManager()
->createQuery("SELECT m from AcmeMyBundle:GroupMatiere m WHERE m.idGroupe=?1")
->setParameter(1, $currentid);
return $query->getResult();
}
That's work if i choose for the $currentid=1; But i need connected user id .
Thanks For Help and any other suggestion to change the logic i will be happy !
Define your repository method like this:
public function findGroupByStudent($student)
{
$query=$this->getEntityManager()
->createQuery("SELECT m from AcmeMyBundle:GroupMatiere m WHERE m.idGroupe=?1")
->setParameter(1, $student->getId());
return $query->getResult();
}
And then in the controller pass the Student entity that belongs to the currently logged in user, e.g.:
$modeles=$em->getRepository("AcmeMyBundle:GroupMatiere")
->findGroupByStudent($this->getUser()->getStudent());

Symfony2 simple query: can't fetch an object, only array

The following query in Symfony2.6 works with getArrayResult(); BUT doesn't work with getResult(); or getOneOrNullResult();. This means that I can't fetch an object but only an array.
If I use this query, all I get is a white/blank page (not even the symfony debug toolbar). Note that in my twig template I just do a {{ dump() }} of the query result.
The table structure is easy (it's a list of books read by the users):
id, user, book, status, vote, review
(user, book and status are foreign keys)
public function selectOneRecordBy2Ids($user_id, $book_id)
{
/* #var $qb QueryBuilder */
$qb = $this->createQueryBuilder('l');
$qb->select('l');
$qb = $qb->Where($qb->expr()->eq('l.user', ':first'));
$qb = $qb->andWhere($qb->expr()->eq('l.book', ':second'));
$qb = $qb->setParameters(array('first' => $user_id, 'second' => $book_id));
return $qb->getQuery()->getOneOrNullResult();
}
I've noticed a few bad practices here, so let me correct them:
public function selectOneRecordBy2Ids(User $user, Book $book)
{
/* #var $qb QueryBuilder */
$qb = $this->createQueryBuilder('l');
$qb
->andWhere($qb->expr()->eq('l.user', ':first'))
->andWhere($qb->expr()->eq('l.book', ':second'))
->setParameters(array('first' => $user, 'second' => $book));
return $qb->getQuery()->getResult();
}
Select is not necessary if you work only with one entity and you don't fetch any relations. QB returns $this so you can chain the method calls.
Try to use entities as parameters instead of primitive types (if it is possible). If not, then you have to use primitive types as primitives in QB. In this case you'll need a few joins:
->select('l')
->join('l.user', 'u')
->join('l.book', 'b')
->andWhere($qb->expr()->eq('u.id', ':first'))
->andWhere($qb->expr()->eq('b.id', ':second'))
->setParameters(array('first' => $user_id, 'second' => $book_id));
If you want to fetch only one record, then you may have to limit the results by setting the max results:
->setMaxResults(1)
I hope this helps and solves your original problem as well.
getOneOrNullResult() does not return the record, but tells you if any record in database is found, or not.
You might want to use getSingleResult()

Symfony2 & Doctrine2: Custom Entity Repository Query to Retrieve Single Result if Joined Table has No Associated Rows

I have two entities/tables, one for Counties and one for Cities. A particular county has a OneToMany relationship to cities and I am trying to make a custom query in the Entity Repository to query a County based on it's ID and return that County and the Cities corresponding to it.
My query currently seems to work great if the county has cities assigned, but if it does not have any cities yet, Doctrine gives me a "Unable to find County entity. " Exception.
I believe there is a logical error in my query, but I am having a hard time re-writing it to return solely the County by ID if no cities are associated with it.
My Query:
class CountyRepository extends EntityRepository
{
public function findOneByIdJoinedToCities($id)
{
$qb = $this->createQueryBuilder('c')
->addSelect('p')
->join('c.cities', 'p')
->where('p.county = :id')
->setParameter('id', $id)
;
$query = $qb->getQuery();
try {
return $query->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $e){
return null;
}
}
}
How could I change the above code to still give back a single result for County if no Cities have been assigned to it yet?
Thanks for the help!
Basic SQL question: use a left join. eg:
$qb = $this->createQueryBuilder('c')
->addSelect('p')
->leftJoin('c.cities', 'p')
// ^^^^^^^^
->where('p.county = :id')
->setParameter('id', $id)
;

How to use wildcards in createQueryBuilder?

In my repository class i use:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.tags LIKE %bipolar%')
->addOrderBy('c.id');
return $qb->getQuery()
->getResult();
}
But unfortunately this doesn't work.. Anybody knows how this can work? Or do I have to build a custom query without the QueryBuilder?
Thanks!
Searching based on a single parameter:
I think it should go:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.tags LIKE :tag')
->addOrderBy('c.id')
->setParameter('tag', $tag);
return $qb->getQuery()->getResult();
}
But I think that it is discouraged to do a LIKE as part of a where using the query builder so you should do:
$qb = $this->createQueryBuilder('c');
$qb->select('c')
->where($qb->expr()->like('c.tags', '?1'))
->addOrderBy('c.id')
->setParameter(1, $tag);
return $qb->getQuery()->getResult();
Check out the docs for more information, there is an example of a like expression in the section entitled Helper Methods
I should also point out that I used a different convention in each example for passing a parameter into a query, the first used a named parameter :tag which is set by setParameter('tag', $value) the second is just a numbered parameter ?1, you could have just as easily have used a named parameter in the second example if you wished to as well.
Searching with an array of parameters:
You also asked about doing an array of likes. Here it is with an OR expression but if you wanted to search for all tags you could change it to an AND.
In order to make a "LIKE array" you just have to build up the expression on its own.
$qb = $this->createQueryBuilder('c');
$orExpr = $qb->expr()->orX();
for ($i = 0; $i < count($tags); $i++) {
$orExpr->add($qb->expr->like('c.tags', "?$i"));
// You may have to set params later in a loop after $orExpr has been
// added to the queryBuilder.
$qb->setParameter($i, $tags[$i]);
}
$qb->select('c')->where($orExpr)->addOrderBy('c.id');
return $qb->getQuery()->getResult();
If you don't want to substitute your query with variables but use a static string you have to put the string in apostrophes.
You have to use apostrophes instead of quotes! Otherwise the Doctrine2 Lexer will throw an Exception.
So in your case Mike you can use:
'c.tags LIKE \'%bipolar%\''
or
"c.tags like '%bipolar%'"
I don't know much about Symfony, but based on what I know about PHP and MySQL, I imagine you mean 'c.tags LIKE "%bipolar%"'. You likely need quotation marks around %bipolar%.
simply:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where( $qb->expr()->like('c.tags', ':tags') )
->addOrderBy('c.id');
$qb->setParameter('tags', '%' . $tag . '%' );
return $qb->getQuery()->getResult();
}

Resources