Complex QueryBuilder expresion in createQuery() with Sonata Admin - doctrine-orm

I'm using Symfony 4.2 and Sonata Admin bundle and I'm trying to display a specific list in one of my admin list view.
I want to display the lastest user by group. I created the SQL query and I'm now trying to translate it to QueryBuilder.
SELECT * FROM users
WHERE (created_at, group_id) IN (
SELECT MAX(created_at), group_id
FROM users
GROUP BY group_id)
My createQuery function in my Sonata Admin class :
public function createQuery($context = 'list')
{
$container = $this->getConfigurationPool()->getContainer();
$em = $container->get('doctrine.orm.entity_manager');
$expr = $em->getExpressionBuilder();
$subQuery = $em->createQueryBuilder()
->select('MAX(c.createdAt), c.group')
->from('ApiBundle:Configuration', 'c')
->groupBy('c.group')
->getDQL();
$query = parent::createQuery($context);
$alias = $query->getRootAlias();
$query->where($expr->in('('.$alias.'.createdAt, '.$alias.'.group)', $subQuery));
}
Unfortunately it is not working and I'm not sure it's the right way to do it.
I could make it work with only selecting the createdAt in the in() expression but it's not what I want to have at the end.
Here is the error I got.
[Syntax Error] line 0, col 77: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got ','
How can I make it work using QueryBuilder ?
Thank you.

Related

Doctrine and quoting reserved word of MySql

I have in my Symfony 4.3 project entity named Group and table group in MySql database. Group is a reserved word. I have 3 entities : User, Group, UserGroup. They have relations: User ->OneToMany-> UserGroup and Group -> OneToMany -> UserGroup ( UserGroup has additional attributes, so I can't use ManyToMany relation). When I try to get group names for user with id=1:
$entityManager = $this->getDoctrine()->getManager();
$user = $entityManager->getRepository(User::class)
->find($id);
$groups = $user->getUserGroups();
foreach ($groups as $group) {
$group_name = $group->getGroupId()->getName();
echo $group_name, '<br>';
}
I get error message :
You have an error: An exception occurred while executing 'SELECT t0.id AS id_1, t0.name AS name_2 FROM group t0 WHERE t0.id = ?' with params [1]: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group t0 WHERE t0.id = 1' at line 1 with code: 0
There is a recipe in documentation (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words) how to enable quoting of reserved words:
<?php
use Doctrine\ORM\Mapping\AnsiQuoteStrategy;
$configuration->setQuoteStrategy(new AnsiQuoteStrategy());
I don't understand where I have to use this code - in EntityManager, in Controller? And how I can get $configuration?
I think the better solution is to use ticks in the definition of your entity as mentioned in Doctrine Documentation.
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\GroupRepository")
* #ORM\Table(name="`group`")
*/
class Group
{
// ...
}
Note, that this approach will work only if you are using the default quote strategy. So, delete quote_strategy parameter or set it as doctrine.orm.quote_strategy.default.
# config/packages/doctrine.yml
doctrine:
# ...
orm:
quote_strategy: doctrine.orm.quote_strategy.default

Doctrine Query builder for simple search

Hi I am trying to write a simple search query using QueryBuilder. I have a single table with fields: Name, Description, Code.
Basically I want to check if an entered keyword is in any of the fields.
public function searchProducts( $keyword )
{
$qb = $this->productRepository->createQueryBuilder('u');
$qb->add('where' , 'u.name LIKE :search');
$qb->add('where' , 'u.description LIKE :search');
$qb->add('where' , 'u.code LIKE :search');
$qb->setParameter('search', '%'.$keyword.'%');
}
How do I add the orX context to this?
public function searchProducts( $keyword )
{
$qb = $this->productRepository->createQueryBuilder('u');
$qb->add('where', $qb->expr()->orX(
$qb->expr()->like('u.name', ':search'),
$qb->expr()->like('u.description', ':search'),
$qb->expr()->like('u.code', ':search')
))
$qb->setParameter('search', '%'.$keyword.'%');
}
I think this should work for you.
Additional I'm not sure, but isnt there a select/from missing like this:
$qb->add('select', 'u')
->add('from', 'User u')
I have taken it from the doctrine2 ORM Doc:
Docu

how to write below query in joomla model class using joomla2.5

select es.* from g5ch3_empstatus_objects as es inner join(select
statuscreator,statuscreatorid,max(created)as maxcreated, ustatus from
g5ch3_empstatus_objects where statuscreator='user->name' group by
statuscreator )s on es.statuscreator=s.statuscreator and
es.created=s.maxcreated
How to write this query in Joomla model class am using joomla2.5
I've tried in this way but i get empty result set:
$query = $db->getQuery(true);
$subquery = $db->getQuery(true);
$subquery->select('max(created) as maxcreated')
-> from ('#_empstatus_objects');
$query->select(
'es.id as id,' .
'es.statuscreator,' .
'es.statuscreatorid,' .
'es.created,' .
'es.ustatus'
);
$query->from ('#__empstatus_objects as es'.$subquery.$where)
-> group('statuscreator');
$superadmin = $this->access_superuser($user->id);
if(!$superadmin){
$query->where ('statuscreatorid='.$user->id);
}
Go to http://docs.joomla.org/Accessing_the_database_using_JDatabase/2.5 and take a look at the "Selecting Records from Multiple Tables" section.

What is wrong with doctrine2 query builder - expected literal

I am using Doctrine 2 within ZF2 code and I am trying to write update query.
Code is like this:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->update('Application\Entity\Groups', 'group')
->set('group.state', '?1')
->set('group.modified', '?2')
->where($qb->expr()->eq('group.id', '?3'))
->setParameter(1, \Application\Entity\Groups::STATE_DELETED)
->setParameter(2, $modified)
->setParameter(3, $group_id);
Doctrine2 complains about query. Exact error message is:
(string) [Syntax Error] line 0, col 87: Error: Expected Literal, got 'group'
It seems that keyword group created problems. When I used gr alias instead of group it worked fine.
So, DQL bellow worked:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->update('Application\Entity\Groups', 'gr')
->set('gr.state', ':state')
->set('gr.modified', ':modified')
->where($qb->expr()->eq('gr.id', ':group_id'))
->setParameter('group_id', $group_id)
->setParameter('state', \Application\Entity\Groups::STATE_DELETED)
->setParameter('modified', $modified);

doctrine 2 query builder and join tables

I'm trying to get all comments for each post in my home page
return
$this->createQueryBuilder('c')
->select('c')
->from('Sdz\BlogBundle\Entity\Commentaire' ,'c')
->leftJoin('a.comments' ,'c')->getQuery()->getResult() ;
but I'm getting this error
[Semantical Error] line 0, col 58 near '.comments c,': Error:
Identification Variable a used in join path expression but was not defined before.
PS : The mapping is correct because I can see the page article with its comments.
In case this is still giving you problems, here is your query using the syntax found in the examples in the Doctrine 2.1 documentation.
I'm assuming your query resides in a custom repository method, and that 'a' is an abbreviation for 'Article'.
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb->select(array('a', 'c'))
->from('Sdz\BlogBundle\Entity\Article', 'a')
->leftJoin('a.comments', 'c');
$query = $qb->getQuery();
$results = $query->getResult();
return $results;