How to use LIKE clause in DQL? - symfony

I'm trying to create a query using the LIKE clause in Doctrine Query Language.
My query is as following:
public function findByName($keyword){
$em = $this->getEntityManager();
$consulta = $em->createQuery('SELECT o FROM AppBundle:Items o WHERE o.name LIKE :keyword');
$consulta->setParameter('keyword', '%'.$keyword.'%');
return $consulta->getResult();
}
I'm getting the next errors:
Notice: Trying to access array offset on value of type null
While if I do the same query but instead of LIKE i simply use =, the query executes correctly and I get the results. What could I be doing wrong here?
Thanks for the help.
Debug info:
object(Doctrine\ORM\Query)#901 (24) {
["_state":"Doctrine\ORM\Query":private]=> int(2)
["_parsedTypes":"Doctrine\ORM\Query":private]=> array(0) { }
["_dql":"Doctrine\ORM\Query":private]=> string(57) "SELECT o FROM
AppBundle:Coche o WHERE o.modelo = :keyword"
["_parserResult":"Doctrine\ORM\Query":private]=> NULL
["_firstResult":"Doctrine\ORM\Query":private]=> NULL
["_maxResults":"Doctrine\ORM\Query":private]=> NULL
["_queryCache":"Doctrine\ORM\Query":private]=> NULL
["_expireQueryCache":"Doctrine\ORM\Query":private]=> bool(false)
["_queryCacheTTL":"Doctrine\ORM\Query":private]=> NULL
["_useQueryCache":"Doctrine\ORM\Query":private]=> bool(true)
["parameters":protected]=>
object(Doctrine\Common\Collections\ArrayCollection)#946 (1) {
["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
array(1) { [0]=> object(Doctrine\ORM\Query\Parameter)#913 (3) {
["name":"Doctrine\ORM\Query\Parameter":private]=> string(7) "keyword"
["value":"Doctrine\ORM\Query\Parameter":private]=> int(1)
["type":"Doctrine\ORM\Query\Parameter":private]=> string(7) "integer"
} } } ["_resultSetMapping":protected]=> NULL ["_em":protected]=>
object(Doctrine\ORM\EntityManager)#740 (11) {
["config":"Doctrine\ORM\EntityManager":private]=>
object(Doctrine\ORM\Configuration)#564 (1) {
["_attributes":protected]=> array(14) { ["entityNamespaces"]=>
array(1) { ["AppBundle"]=> string(16) "AppBundle\Entity" }
["metadataCacheImpl"]=> object(Doctrine\Common\Cache\ArrayCache)#566
(6) { ["data":"Doctrine\Common\Cache\ArrayCache":private]=> array(0) {
} ["hitsCount":"Doctrine\Common\Cache\ArrayCache":private]=> int(0)
["missesCount":"Doctrine\Common\Cache\ArrayCache":private]=> int(0)
["upTime":"Doctrine\Common\Cache\ArrayCache":private]=>
int(1598445780)
["namespace":"Doctrine\Common\Cache\CacheProvider":private]=>
string(79)
"sf_orm_default_061d80f6e71229c042b639f23634872f7045193d957ba060c640bf0458feeae2"
["namespaceVersion":"Doctrine\Common\Cache\CacheProvider":private]=>
NULL } ["queryCacheImpl"]=>
public function LikeExpression()
{
$stringExpr = $this->StringExpression();
$not = false;
if ($this->lexer->isNextToken(Lexer::T_NOT)) {
$this->match(Lexer::T_NOT);
$not = true;
}
$this->match(Lexer::T_LIKE);
if ($this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
$this->match(Lexer::T_INPUT_PARAMETER);
$stringPattern = new AST\InputParameter($this->lexer->token['value']);
} else {
$stringPattern = $this->StringPrimary();
}
$escapeChar = null;
//////// Highlighted error area//////////
if ($this->lexer->lookahead['type'] === Lexer::T_ESCAPE) {
$this->match(Lexer::T_ESCAPE);
$this->match(Lexer::T_STRING);
$escapeChar = new AST\Literal(AST\Literal::STRING, $this->lexer->token['value']);
}
////////////////////////////////////////
$likeExpr = new AST\LikeExpression($stringExpr, $stringPattern, $escapeChar);
$likeExpr->not = $not;
return $likeExpr;
}

Related

getUnitChangeSet doesn't work correct with json

My method:
public function getUpdatedColumns(Shop $shop): array
{
$uow = $this->entityManager->getUnitOfWork();
$uow->computeChangeSets();
return $uow->getEntityChangeSet($shop);
}
What I get is this:
array(1) {
["mailConfig"]=>
array(2) {
[0]=>
string(25) "{"transport": "sendgrid"}"
[1]=>
string(24) "{"transport":"sendgrid"}"
}
}
and because of this whitespace, getEntityChangeSet returns result when the field is not actually updated. Is there a workaround when we are working with JSON ? The database field is JSON as well if that matters.

Javacc grammar not working with optional tokens

I have a DFM (is a Delphi source file, like JSON, to define form component layouts) parser created with javaCC.
My grammar (.jj file) define this:
private DfmObject dfmObject():
{
DfmObject res = new DfmObject();
DfmProperty prop;
DfmObject obj;
Token tName;
Token tType;
}
{
<OBJECT>
(tName = <IDENTIFIER> { res.setName(tName.image); } <COLON>)?
tType = <IDENTIFIER> { res.setType(tType.image); }
<ENDLINE>
( prop = property() { res.addProperty(prop); } )*
( obj = dfmObject() { res.addChild(obj); } (<ENDLINE>)*)*
<END>
{ return res; }
}
This is for parsing 2 types of object definitions:
object name: Type
end
as so
object Type
end
So, the name : is optional.
But, when I try to parse this second DFM, I always get this error:
Exception in thread "main" eu.kaszkowiak.jdfm.parser.ParseException: Encountered " <ENDLINE> "\r\n"" at line 1, column 12.
Was expecting:
":" ...
What I'm doing wrong?
A solution/workaround is, to make optional the : Type part and switch between the name and type values when the type == null.
See the grammar implementation:
private DfmObject dfmObject():
{
DfmObject res = new DfmObject();
DfmProperty prop;
DfmObject obj;
Token tName;
Token tType;
}
{
(
<OBJECT>
(
tName = <IDENTIFIER> { res.setName(tName.image); }
)
( <COLON> tType = <IDENTIFIER> { res.setType(tType.image); } )?
<ENDLINE>
)
( prop = property() { res.addProperty(prop); } )*
( obj = dfmObject() { res.addChild(obj); } (<ENDLINE>)*)*
<END>
{
if (res.getType() == null) {
res.setType(res.getName());
res.setName(null);
}
return res;
}
}

Symfony2 - Invalid parameter number

I have this error:
Invalid parameter number: number of bound variables does not match
number of tokens
When I'm trying to get getAllOrders() in my Repository:
public function allOrdersQB()
{
return $this->createQueryBuilder('o')
->andWhere('o.state != :canceled')
->andWhere('o.state != :receipt_complete')
->setParameters(array(
'receipt_complete' => 'receipt_complete',
'canceled' => 'canceled',
));
}
public function getAllOrders()
{
return $this->allOrdersQB()
->andWhere('o.stateCorp = :stateCorp')
->setParameters(array(
'stateCorp' => 0,
))
->getQuery()->getResult();
}
I don't understand because I have set all the parameters.
What did I do wrong?
The setParameters method reset all previous parameters, so you could use the simple setParameter call (see in the source code here), as example:
public function allOrdersQB()
{
return $this->createQueryBuilder('o')
->andWhere('o.state != :canceled')
->andWhere('o.state != :receipt_complete')
->setParameter('receipt_complete', 'receipt_complete')
->setParameter('canceled', 'canceled')
}
public function getAllOrders()
{
return $this->allOrdersQB()
->andWhere('o.stateCorp = :stateCorp')
->setParameter('stateCorp', 0)
->getQuery()->getResult();
}
Hope this help

phpunit InvalidArgumentException: The current node list is empty

Running a test which has this line:
$authorizeForm = $crawler->selectButton('Authorize')->form();
outputs this error:
There was 1 error:
1) Citiqa\ApiBundle\Tests\Controller\SecurityControllerTest::testLoginAndAuthorize
InvalidArgumentException: The current node list is empty.
/home/oris/src/citiqa-api/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php:648
/home/oris/src/citiqa-api/src/Citiqa/ApiBundle/Tests/Controller/SecurityControllerTest.php:28
I've taken a look at Crawler.php and saw the problematic function:
public function form(array $values = null, $method = null)
{
//var_dump($this);
if (!count($this)) {
throw new \InvalidArgumentException('The current node list is empty.');
}
$form = new Form($this->getNode(0), $this->uri, $method);
if (null !== $values) {
$form->setValues($values);
}
return $form;
}
$this is in this case the crawler object which extends \SplObjectStorage which implements the Countable interface, so we should be fine. I've tried to var_dump($this); on form() and I see this:
object(Symfony\Component\DomCrawler\Crawler)#1354 (2) {
["uri":"Symfony\Component\DomCrawler\Crawler":private]=>
string(37) "https://localhost/oauth/v2/auth_login"
["storage":"SplObjectStorage":private]=>
array(1) {
["0000000075b694bd000000002b32afe0"]=>
array(2) {
["obj"]=>
object(DOMElement)#529 (18) {
["tagName"]=>
string(6) "button"
["schemaTypeInfo"]=>
NULL
["nodeName"]=>
string(6) "button"
["nodeValue"]=>
string(5) "login"
["nodeType"]=>
int(1)
["parentNode"]=>
string(22) "(object value omitted)"
["childNodes"]=>
string(22) "(object value omitted)"
["firstChild"]=>
string(22) "(object value omitted)"
["lastChild"]=>
string(22) "(object value omitted)"
["previousSibling"]=>
string(22) "(object value omitted)"
["nextSibling"]=>
string(22) "(object value omitted)"
["attributes"]=>
string(22) "(object value omitted)"
["ownerDocument"]=>
string(22) "(object value omitted)"
["namespaceURI"]=>
NULL
["prefix"]=>
string(0) ""
["localName"]=>
string(6) "button"
["baseURI"]=>
NULL
["textContent"]=>
string(5) "login"
}
["inf"]=>
NULL
}
}
}
object(Symfony\Component\DomCrawler\Crawler)#1852 (2) {
["uri":"Symfony\Component\DomCrawler\Crawler":private]=>
string(155) "https://localhost/oauth/v2/auth?client_id=1_5ndcb2XXXXX&redirect_uri=http%3A%2F%2Fwww.google.com&response_type=token"
["storage":"SplObjectStorage":private]=>
array(0) {
}
}
phpunit version is 3.6.10
Funny thing is, this test is completing successfully on another machine, with a different phpunit version (3.7.21). could this be a version / error reporting level issue?

Symfony2 - Query Builder LIKE null values

I'm trying to build a dynamic query in response to a custom search from users. I have an issue: when I'm building the query, I don't have the results because the SELECT LIKE column comparison doesn't work with NULL values. How can I work around this issue, considering that query is dynamically built? So, users can give values or not to search criteria...
This is my code:
$qb->add('select', 'f')
->add('from', 'Bundle:Object f')
->add('where', $qb->expr()->andx(
$qb->expr()->like('f.c1',':c1'),
$qb->expr()->like('f.c2',':c2'),
$qb->expr()->like('f.c3',':c3')))
->add('orderBy', 'f.nnumCatalogo ASC');
if ($data->getField1() != null) {
$isField1 = true;
}
if ($data->getField2() != null) {
$isField2 = true;
}
if ($data->getField3() != null) {
$isField3 = true;
}
if ($isField1) {
$qb->setParameter('c1', $data->getField1());
} else {
$qb->setParameter('c1', '%');
}
if ($isField2) {
$qb->setParameter('c2', $data->getField2());
} else {
$qb->setParameter('c2', '%');
}
if ($isField3) {
$qb->setParameter('c3', $data->getField3());
} else {
$qb->setParameter('c3', '%');
}
With this code I have no results becuase of NULL values in some columns not selected with LIKE '%' (mysql).
Try this:
$qb->add('select', 'f')->add('from', 'Bundle:Object f');
if ($data->getField1() != null) {
$qb->andWhere('f.c1 like :c1')
->setParameter('c1', $data->getField1());
}
if ($data->getField2() != null) {
$qb->andWhere('f.c2 like :c2')
->setParameter('c2', $data->getField2());
}
if ($data->getField3() != null) {
$qb->andWhere('f.c3 like :c3')
->setParameter('c3', $data->getField3());
}
$qb->add('orderBy', 'f.nnumCatalogo ASC');

Resources