<?php
namespace App\Controller\Api;
use App\Controller\Response;
use App\Entity\ScheduledNotifications;
use App\Entity\UserNotifications;
use App\Entity\UserViewedNotifications;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/api/notifications", name="api_notifications_")
*/
class NotificationsController extends AbstractController
{
use \App\Controller\Request;
use Response;
const MAX_NOTIFICATION_COUNT = 5;
/**
* @Route("/mark_as_read", name="mark_as_read", methods={"POST"})
*/
public function markAsReadAction(Request $request, EntityManagerInterface $em)
{
$user = $this->getUser(); // TOKEN
# get Request json
$content = $request->getContent();
# parse JSON to Array
$data = \json_decode($content, true);
if (!empty($user->getId()) && !empty($data['notification_id'])) {
$view = $em->getRepository(UserViewedNotifications::class)->findOneUserNotification(
$user->getId(),
$data['notification_id']
);
if (!$view) {
$view = new UserViewedNotifications();
$view->setUserId($user->getId());
$view->setNotificationId($data['notification_id']);
$view->setCreatedAt(new \DateTime());
}
$em->persist($view);
$em->flush();
return $this->jsonResponse();
}
return $this->errorJsonResponse();
}
/**
* @Route("/user/{id}", name="user", methods={"GET"})
*/
public function userNotificationsAction($id, Request $request, EntityManagerInterface $em)
{
$user = $this->getUser(); // TOKEN
$lang = $this->getQueryLang($request);
$lang = (strtolower($lang) == 'en' ? 'En' : '');
$qb = $em->createQueryBuilder();
$qb->select(
[
'sn.id',
'sn.notificationTitle' . $lang . ' as notificationTitle',
'sn.notificationPreview' . $lang . ' as notificationPreview',
'sn.scheduledAt',
'uwn.createdAt as viewed_at',
]
);
$qb->from(ScheduledNotifications::class, 'sn');
$qb->leftJoin(
UserViewedNotifications::class,
'uwn',
'WITH',
'sn.id = uwn.notificationId AND uwn.userId = :user'
);
$qb->andWhere('sn.removedAt IS NULL AND sn.runnedAt IS NOT NULL');
if (!$user->hasValidSubscription()) {
$qb->andWhere('sn.pro_users = 0');
}
$qb->setParameter('user', $user->getId());
$qb->orderBy('sn.runnedAt', 'DESC');
$qb->setMaxResults(NotificationsController::MAX_NOTIFICATION_COUNT);
$notifications = $qb->getQuery()->getArrayResult();
if (count($notifications) > 0) {
foreach ($notifications as &$notification) {
$notification['notificationPreview'] = $this->removeLastWord($notification['notificationPreview']) . '...';
}
}
return $this->jsonResponse(['data' => $notifications]);
}
/**
* @Route("/view/{id}", name="view", methods={"GET"})
*/
public function viewNotificationAction($id, Request $request, EntityManagerInterface $em)
{
$lang = $this->getQueryLang($request);
$lang = (strtolower($lang) == 'en' ? 'En' : '');
$notification = $em->createQueryBuilder()
->select(
[
'sn.id',
'sn.notificationTitle' . $lang . ' as notificationTitle',
'sn.notificationBody' . $lang . ' as notificationBody',
'sn.notificationPreview' . $lang . ' as notificationPreview',
'sn.forwardTo',
'sn.scheduledAt',
]
)
->from(ScheduledNotifications::class, 'sn')
->where('sn.id = :id AND sn.removedAt IS NULL AND sn.runnedAt IS NOT NULL')
->setParameter('id', $id)
->orderBy('sn.runnedAt', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult(Query::HYDRATE_ARRAY);
return $this->jsonResponse(['data' => $notification]);
}
/**
* @Route("/unread/{id}", name="unread", methods={"GET"})
*/
public function unreadNotificationsAction($id, Request $request, EntityManagerInterface $em)
{
$user = $this->getUser(); // TOKEN
$count = $em->getRepository(ScheduledNotifications::class)->createQueryBuilder('sn')
->select('count(sn.id)')
->leftJoin(
UserViewedNotifications::class,
'uwn',
'WITH',
'sn.id = uwn.notificationId AND uwn.userId = :user'
)
->setParameter('user', $user->getId())
->where('sn.removedAt IS NULL AND sn.runnedAt IS NOT NULL AND uwn.id IS NULL')
->getQuery()
->getSingleScalarResult();
$objective = $em->getRepository(UserNotifications::class)
->createQueryBuilder('un')
->select('count(un.id)')
->where('un.userId = :user AND un.seenAt IS NULL ')
->setParameter('user', $user->getId())
->getQuery()
->getSingleScalarResult();
$count = min(intval($count), NotificationsController::MAX_NOTIFICATION_COUNT);
return $this->jsonResponse(['data' => intval($count), 'objective' => intval($objective)]);
}
/*
* +---------------------------------------------------+
* | OBJECTIVES |
* +---------------------------------------------------+
*/
/**
* @Route("/objective/user/{id}", name="objective_user", methods={"GET"})
*/
public function objectiveNotificationsAction($id, Request $request, EntityManagerInterface $em)
{
$user = $this->getUser();
$notifications = $em->createQueryBuilder()
->select(['on.id', 'on.notificationTitle', 'on.notificationPreview', 'on.seenAt', 'on.createdAt'])
->from(UserNotifications::class, 'on')
->where('on.userId = :user')
->setParameter('user', $user->getId())
->orderBy('on.id', 'DESC')
->getQuery()
->getArrayResult();
if (count($notifications) > 0) {
foreach ($notifications as &$notification) {
$notification['notificationPreview'] = $this->removeLastWord($notification['notificationPreview']) . '...';
}
}
return $this->jsonResponse(['data' => $notifications]);
}
/**
* @Route("/objective/mark_as_read", name="objective_mark_as_read", methods={"POST"})
*/
public function markAsReadObjectiveNotificationAction(Request $request, EntityManagerInterface $em)
{
$user = $this->getUser();
# get Request json
$content = $request->getContent();
# parse JSON to Array
$data = \json_decode($content, true);
if (!empty($data['notification_id'])) {
$notification = $em->createQueryBuilder()
->select('on')
->from(UserNotifications::class, 'on')
->where('on.userId = :user AND on.id = :notification')
->setParameter('user', $user->getId())
->setParameter('notification', $data['notification_id'])
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if ($notification) {
$notification->setSeenAt(new \DateTime());
$em->persist($notification);
$em->flush();
}
return $this->jsonResponse([]);
}
return $this->errorJsonResponse([]);
}
/**
* @Route("/objective/view/{id}", name="objective_view", methods={"GET"})
*/
public function viewObjectNotificationAction($id, Request $request, EntityManagerInterface $em)
{
$notification = $em->createQueryBuilder()
->select('on')
->from(UserNotifications::class, 'on')
->where('on.id = :id')
->setParameter('id', $id)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult(Query::HYDRATE_ARRAY);
return $this->jsonResponse(['data' => $notification]);
}
private function removeLastWord($string)
{
$words = explode(" ", $string);
array_splice($words, -1);
return implode(" ", $words);
}
}