Find element in array data using createQueryBuilder - php

I have a table ( shops) in witch I store data like this: ["bsd1234","qwe9876"] in a field named products and I want to get the shops objects that contain a given product using createQueryBuilder().
It should look like this, but I can't find the solution:
public function findByProducts($value)
{
return $this->createQueryBuilder('s')
->andWhere('s.products = :val')
->setParameter('val', $value)
->orderBy('s.id', 'ASC')
->getQuery()
->getResult()
;
}
Can you help mw with that?

Related

Sorting the most relation with Doctrine

Sorting the most relation with Doctrine?
Relation
#[ORM\ManyToOne(inversedBy: 'users')]
#[ORM\JoinColumn(nullable: false)]
private ?University $university = null;
My repository code ( Doesn't sort correctly )
public function sortPopularChats(): array
{
return $this->createQueryBuilder('u')
->orderBy('u.university', 'DESC')
->groupBy('u.university')
->setMaxResults(5)
->getQuery()
->getResult()
;
}
My user table
|id|university_id|
|1|100610385|...
|2|106952005|...
|5|100610385|...
|11|108410557|...
|6|100610385|...
|7|106952005|...
|4|100610385|...
|9|106952005|...
|10|100610385|...
Sorting should be like this
100610385
106952005
108410557
...
...
You need a count expression in order to be able to use it as the ordering field, but doing that it'll return a ScalarResult, with both the count and the object. To prevent that, you can use the HIDDEN keyword (scroll down or search for it) so only the University entities are returned:
public function sortPopularChats(): array
{
return $this->createQueryBuilder('e')
->leftJoin('e.university', 'u')
->addSelect('u, count(u) AS HIDDEN uniCount')
->orderBy('uniCount', 'ASC')
->groupBy('u.id')
->setMaxResults(5)
->getQuery()
->getResult()
;
}

Doctrine delete the oldest entry

I have one MongoDb document with 3 fields message, author, sendAt, i have created a query builder to count all DB entries on this document and if there is more than 20 entries, I'm trying to delete the oldest one.
sendAt is the current dateTime when the message is send ("sendAt" : ISODate("2016-01-21T08:53:00Z"))
I have an unfinished query builder
public function deleteOldestMessage()
{
return $this->createQueryBuilder()
->delete('m')
->from('Messages', 'm')
->where('m.sendAt = ')
->execute();
}
But i really don't know what i should add on the where condition.
I should maybe order DESC the sendAt field and delete the first on the list ?
How can I tell the query builder to delete the oldest one ?
Thanks,
You need first to select the oldest one then you can delete it like this :
$qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'DESC');
$messages = $qb->getResult();
thene
if(count($messages) >= 20){
//get the first element of array which is the oldest one
$lastMessage = current($messages);
$em->remove($lastMessage);
}
You can try something like:
$qb = $em->createQueryBuilder();
$messages = $qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'ASC')
->getQuery()
->getResult()
;
// You will receive array where in the top will be the oldest message.
if (count($messages) > 20) {
// And in your desired case, you can remove just one oldest message.
$messageToDelete = array_shift($messages);
$em->remove($lastMessage);
$em->flush();
}
You use sql query builder options instead of mongodb.
return $this->createQueryBuilder()
->remove()
->sort('sendAt', 'asc')
->getQuery()
->getSingleResult()
->execute();

Get first column result in Doctrine 2

I want to get only the list of values ​​in the first column of the query.
$types = $em->getRepository('MyBundle:Notice')
->createQueryBuilder('n')
->select('n.type')
->groupBy('n.type')
->getQuery()
->getResult();
exho json_encode($types);
Result
[{"type":"foo"},{"type":"bar"},{"type":"baz"}]
I want to get a result
["foo","bar","baz"]
Of course, I can manually sort out the data and get the result I needed.
foreach ($types as $key => $type) {
$types[$key] = $type['type'];
}
But I want to use the standard method, if any. Unfortunately, I did not find such a method in the documentation. Maybe I'm bad looking)

Symfony 2 finding blog posts for multiple users

I have 3 tables: user, user_followers and blog_posts.
Users can follow other users and users are related to blog_post by user_id.
I need to get all blog posts that people I follow have written.
I tried something like:
$followedUsers = $user->getFollowedByMe(); //This one works
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')
->findBy(array('user_id' => $followedUsers));
And I tried a lot more variations but can't figure it out. Maybe someone knows a better way to search by multiple objects not just one.
You can use this kind of code in your BlogRepository.php in example.
public function getBlogPost($userId)
{
return $this
->_em
->createQueryBuilder('p')
->leftJoin('p.user', 'u')
->where('u.id = :id')
->setParameter('id', $userId)
->getQuery()
->getResult();
}
createQueryBuilder('p') will automatically create the select and from (select entity (post ?) from table).
Then, you can use it like this :
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')->getBlogPost($userId);
I can't give you the exact query because we don't have enough informations about your entities. But this way, you can write nice queries to get exactly what you want.
You can do:
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')
->createQueryBuilder('b')
->whereIn('b.user', $followedUsers)
->getQuery()
->getResult();
'user' should be the name of property used to hold the user in the Blogpost object.
So i figured it out (thanx guys for pointing me in the right direction with queryBuilder).
$followedByMe = $user->getFollowedByMe(); //Getting users i follow
$followedIds = $followedByMe
->map(function( $obj ) { //Using map method to create an array of id's for all followers
return $obj->getId(); //Value to put into array (in this case id)
})->toArray(); //Create an array and assign it to $followedIds variable
$qb = $em->getRepository('<BundleHere>:BlogPosts')->createQueryBuilder('b');
$posts = $qb->where($qb->expr()->in('b.user', $followedIds ))
->orWhere('b.user = :my_id')->setParameter('my_id', $user->getId()) //Get my posts too
->getQuery()
->getResult();

Symfony 2 & Doctrine 2 - create a custom findBy() method

I would like create my own method findBy().
I have two entities: Film and Genre. The purpose of this custom findBy() method is :
join the Film entity with the Genre entity, to retrieve all my films
and the associated genres,
keeping the parameters of the basic method which are: $criteria,
$orderBy , $limit and $offset.
Indeed, I use those parameters to make a paging.
Previously I made a custom findAll method with the join between the two entities :
<?php
public function myFindAll()
{
$films = $this->createQueryBuilder('f')
// leftJoin because I need all the genre
->leftJoin('f.genres', 'g')
->addSelect('g.label')
->groupBy('f.id')
->getQuery()
->getArrayResult();
// $genres contains all the genres and the associated movies
return ($films);
}
I don't know how to include the rest of parameters.
How about slice() ?
$genders = $em->getRepository('models\Gender')->findAll()->slice($offset, $lenght);
Also, you can make use of your function like:
public function myFindAll($criteria, $orderBy, $limit, $offset)
{
$films = $this->createQueryBuilder('f')
// leftJoin because I need all the genre
->leftJoin('f.genres', 'g')
->addSelect('g.label')
->groupBy('f.id')
->add('orderBy', "f.{$orderBy} ASC")
->getQuery()
->getArrayResult()
->slice($offset, $limit);
// $films contains all the genres and the associated movies
return ($films);
}
EDIT:
The slice() function acts as pagination function:
$page1 = $films->slice(0, 15); // retrieve films from 0 to 15 position
$page2 = $films->slice(10, 7); // retrieve films from 10 to 17 position
Now, if you want to use some criterias values you can make something like this:
public function myFindAll($criteria, $orderBy, $limit, $offset)
{
$films = $this->createQueryBuilder('f');
foreach($criteria as $column => $value)
$films->where($column, $value);
$films
->leftJoin('f.genres', 'g')
->addSelect('g.label')
->groupBy('f.id')
->add('orderBy', "{$orderBy[0]} {$orderBy[1]}");
->getQuery()
->getArrayResult()
->slice($offset, $limit);
// $genres contains all the genres and the associated movies
return ($films);
}
I am not sure if where function will override the previous conditions, but at least it can lead you to find the correct query
setFirstResult() and setMaxResult()
Also, there is another option that you can use:
public function myFindAll($criteria, $orderBy, $limit, $offset)
{
$films = $this->createQueryBuilder('f');
foreach($criteria as $column => $value)
$films->where($column, $value);
$films
->leftJoin('f.genres', 'g')
->addSelect('g.label')
->groupBy('f.id')
->add('orderBy', "f.{$orderBy[0]} {$orderBy[1]}")
->setFirstResult($offset)
->setMaxResults($limit)
->getQuery()
->getArrayResult();
// $genres contains all the genres and the associated movies
return ($films);
}

Categories