Reputation: 43
I wrote an api with a function that sets notification as read by passing it's id.
But also, there should be an option to pass array of ids there, to mark several at once as read. I should extend function so that it handles the case where $this>data['id'] is an array.
Is this the right way?
My Service:
public function read($id = []){
$notification = $this->getRepository()->findBy([
'id' => $id
]);
if($notification) {
$notification[0]->setRead(new \DateTime());
$this->em->flush();
}
}
My Controller:
public function readAction()
{
$this->requirePostParams(['id']);
$this->get('app')->read(
$this->data['id']
);
return $this->success();
}
Upvotes: 4
Views: 2665
Reputation: 14146
You can indeed pass an array of id
values to \Doctrine\ORM\EntityRepository::findBy()
; e.g:
$notifications = $this->getRepository()->findBy([
'id' => [1, 2, 3] // etc.
]);
However, since findBy()
can return multiple results, it will return an array (or array-like object like Doctrine\ORM\PersistentCollection
). Therefore you should iterate over your result set:
foreach ($notifications as $notification) {
$notification->setRead(new \DateTime());
}
$this->em->flush();
Additionally, it's a matter of taste to some degree but you may want to make your API more explicit and create separate methods for a single action versus a group action; e.g:
public function read(int $id)
{
//in this scenario you are searching for one notification
// only so you can use `findOneBy()` instead
$notification = $this->getRepository()->findOneBy(['id' => $id]);
$notification->setRead(new \DateTime());
$this->em->flush();
}
public function readMany(array $ids)
{
$notification = $this->getRepository()->findBy(['id' => $ids]);
foreach ($notifications as $notification) {
$notification->setRead(new \DateTime());
}
$this->em->flush();
}
As pointed out by @Yoshi, read()
could also be neatly implemented as:
public function read(int $id)
{
$this->readMany([$id]);
}
Hope this helps :)
Upvotes: 4