<?php
namespace App\Controller;
use App\Constant\BandTypeConstant;
use App\Constant\UtilsConstant;
use App\Entity\FileAction;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use App\Services\SeoManager;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Constant\ActionPointOfViewConstant;
use App\Constant\ActionStatusConstant;
use App\Constant\AjaxLoadingLimitConstant;
use App\Constant\BandMemberRoleConstant;
use App\Constant\EventParticipationConstant;
use App\Constant\InvitationStatusConstant;
use App\Constant\ShareActionConstant;
use App\Entity\EventAction;
use App\Entity\EventParticipation;
use App\Entity\Invitation;
use App\Entity\Share;
use App\Entity\User;
use App\Entity\Band;
use App\Entity\Action;
use Symfony\Contracts\Translation\TranslatorInterface;
const ACTIONS = 'actions';
const ACTION_SHOW_VIEW = 'Action/show.html.twig';
const POINT_OF_VIEW = 'pointOfView';
class ActionController extends WhiplayController
{
/**
* Show custom news feed linked to current user subscriptions
*
* @param Request $request
* @param SeoManager $seoManager
* @return Response
*/
public function subscriptions(Request $request, SeoManager $seoManager): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
$seoManager
->setTitleAndDescription('action.subscriptions.seo.title','action.subscriptions.seo.description')
->setOgTitleAndDescription('action.subscriptions.seo.og_title', 'action.subscriptions.seo.og_description')
->useLogo();
$this->getDoctrine()
->getRepository(Action::class)
->addViewsOnSubscriptionsPublications($currentUser);
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getSubscriptionsPublications($currentUser, 0, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
$invitations = $this
->getDoctrine()
->getRepository(Invitation::class)
->findBy(array('email' => $currentUser->getEmail(), 'status' => InvitationStatusConstant::WAITING));
return $this->render(ACTION_SHOW_VIEW, array(
ACTIONS => $actions,
'invitations' => $invitations,
'profileUser' => $currentUser,
));
}
/**
* Show private news feed for band in studio
*
* @param Request $request
* @param Band $band
* @param SeoManager $seoManager
* @return Response
*/
public function band(Request $request, Band $band, SeoManager $seoManager): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
if ($band->getType() === BandTypeConstant::USER_COLLABORATION) {
return $this->ajaxForward($request, 'whiplay_home');
}
$seoManager
->setTitleAndDescription(
'action.band.seo.title',
'action.band.seo.description',
['band_name' => htmlspecialchars($band->getName())]
)
->setOgTitleAndDescription(
'action.band.seo.title',
'action.band.seo.description',
['band_name' => htmlspecialchars($band->getName())]
)
->useLogo();
$isInBand = $currentUser->isInBand($band);
$pointOfView = $isInBand ? ActionPointOfViewConstant::INTERNAL : ActionPointOfViewConstant::EXTERNAL;
$this
->getDoctrine()
->getRepository(Action::class)
->addViewsOnBandNews($band, $currentUser, $pointOfView);
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getAllForBand($band, $pointOfView, 0, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
return $this->render(ACTION_SHOW_VIEW, array(
ACTIONS => $actions,
POINT_OF_VIEW => $pointOfView,
'band' => $band,
));
}
/**
* Show specified user news feed
*
* @param Request $request
* @param User $user
* @param SeoManager $seoManager
* @return Response
*/
public function user(Request $request, User $user, SeoManager $seoManager): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
$seoManager
->setTitleAndDescription(
'action.user.seo.title',
'action.user.seo.description',
['user_name' => htmlspecialchars($user->getUsername())]
)
->setOgTitleAndDescription(
'action.user.seo.title',
'action.user.seo.description',
['user_name' => htmlspecialchars($user->getUsername())]
)
->useLogo();
$pointOfView = ($currentUser === $user) ? ActionPointOfViewConstant::INTERNAL : ActionPointOfViewConstant::EXTERNAL;
$this
->getDoctrine()
->getRepository(Action::class)
->addViewsOnUserNews($user, $currentUser, $pointOfView);
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getAllForUser($user, $pointOfView, 0, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
return $this->render(ACTION_SHOW_VIEW, array(
ACTIONS => $actions,
POINT_OF_VIEW => $pointOfView,
'profileUser' => $user,
));
}
/**
* Api method to fetch news feed actions from id (for subscriptions, user or band depends on get parameters)
* lastId get parameter define from which id actions will be fetched
* bandId get parameter will be fetching actions linked to this band id
* userId get parameter will be fetching actions linked to this user id
*
* @param Request $request
* @return Response
*/
public function api(Request $request): Response
{
if (!$request->isXmlHttpRequest()) {
return new Response('Bad request', Response::HTTP_BAD_REQUEST);
}
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return new JsonResponse(["error" => true, "message" => "Forbidden"], Response::HTTP_FORBIDDEN);
}
$lastId = $request->get('lastId') ? $request->get('lastId') : 999999999;
$bandId = $request->get('bandId');
$band = is_numeric($bandId) ? $this
->getDoctrine()
->getRepository(Band::class)
->find($bandId) : null;
$userId = $request->get('userId');
$user = is_numeric($userId) ? $this
->getDoctrine()
->getRepository(User::class)
->find($userId) : null;
if ($band instanceof Band) {
$pointOfView = $currentUser->isInBand($band) ? ActionPointOfViewConstant::INTERNAL : ActionPointOfViewConstant::EXTERNAL;
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getAllForBand($band, $pointOfView, $lastId, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
} else if ($user instanceof User) {
$pointOfView = ($currentUser === $user) ? ActionPointOfViewConstant::INTERNAL : ActionPointOfViewConstant::EXTERNAL;
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getAllForUser($user, $pointOfView, $lastId, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
} else {
$pointOfView = ActionPointOfViewConstant::INTERNAL;
$actions = $this
->getDoctrine()
->getRepository(Action::class)
->getSubscriptionsPublications($currentUser, $lastId, AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER);
}
$response = array();
if (count($actions) < AjaxLoadingLimitConstant::NEWS_FEED_LIMIT_NUMBER) {
$response['noMore'] = true;
}
$response[ACTIONS] = array();
foreach($actions as $action) {
$actionInfos = array();
$actionInfos['id'] = $action->getId();
$actionInfos['view'] = $this->render('Action/news_part/item.html.twig', array(
'action' => $action,
POINT_OF_VIEW => $pointOfView,
))->getContent();
$response[ACTIONS][] = $actionInfos;
}
return new JsonResponse($response, Response::HTTP_OK);
}
/**
* Change file action status to public if it's private and private if it's public
*
* @param Request $request
* @param FileAction $action
* @return Response
*/
public function changeFileActionStatus(Request $request, FileAction $action): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
if ($currentUser->IsInBand($action->getFile()->getBand(), BandMemberRoleConstant::LEADER)) {
$em = $this->getDoctrine()->getManager();
if ($action->getStatus() === ActionStatusConstant::STATUS_PUBLIC) {
$action->setStatus(ActionStatusConstant::STATUS_PRIVATE);
} else {
$action->setStatus(ActionStatusConstant::STATUS_PUBLIC);
}
$em->persist($action);
$em->flush();
}
return $this->ajaxForwardToReferer($request, 'whiplay_action_subscriptions');
}
/**
* Share an action from news feed
*
* @param Request $request
* @param Action $action
* @param TranslatorInterface $translator
* @return Response
*/
public function share(Request $request, Action $action, TranslatorInterface $translator): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
$action = $action instanceof Share ? $action->getBaseAction() : $action;
if ($action->getStatus() === ActionStatusConstant::STATUS_PUBLIC) {
$em = $this->getDoctrine()->getManager();
$newShare = new Share();
$newShare->setBaseAction($action);
$newShare->setUser($currentUser);
$newShare->setCreatedAt(new DateTime());
$newShare->setAction(ShareActionConstant::SHARE);
$newShare->setStatus(ActionStatusConstant::STATUS_PUBLIC);
$em->persist($newShare);
$em->flush();
$this->addFlash(
'notice',
$translator->trans('action.share.completed')
);
}
return $this->ajaxForwardToReferer($request, 'whiplay_action_user', array('id' => $currentUser->getId()));
}
/**
* Show event detail page
*
* @param Request $request
* @param EventAction $eventAction
* @return Response
*/
public function showEvent(Request $request, EventAction $eventAction): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
if ($eventAction->getStatus() == ActionStatusConstant::STATUS_PRIVATE && !$currentUser->isInBand($eventAction->getBand())) {
return $this->ajaxForward($request, 'whiplay_action_band', array('id' => $eventAction->getBand()->getId()));
}
return $this->render('Action/event_show.html.twig', array(
'eventAction' => $eventAction
));
}
/**
* Action share deletion
*
* @param Request $request
* @param EntityManagerInterface $em
* @param Share $share
* @return Response
*/
public function deleteShare(Request $request, EntityManagerInterface $em, Share $share): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
return $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
}
if ($share->getUser()->getId() !== $currentUser->getId()) {
return $this->ajaxForward($request, 'whiplay_home');
}
$em->remove($share);
$em->flush();
return $this->ajaxForwardToReferer($request, 'whiplay_action_user', array('id' => $currentUser->getId()));
}
/**
* Set participation at $eventAction event to $action value for current user
*
* @param Request $request
* @param EventAction $eventAction
* @param string $action
* @param TranslatorInterface $translator
* @return Response
*/
public function participate(Request $request, EventAction $eventAction, string $action, TranslatorInterface $translator): Response
{
$errorResponse = null;
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!($currentUser instanceof User)) {
$errorResponse = $this->ajaxForward($request, UtilsConstant::LOGIN_ROUTE);
} else if (!in_array($action, EventParticipationConstant::getValues()) || (
$eventAction->getStatus() == ActionStatusConstant::STATUS_PRIVATE &&
!$currentUser->isInBand($eventAction->getBand())
)) {
$errorResponse = $this->ajaxForward($request, 'whiplay_action_band', array('id' => $eventAction->getId()));
} else if ($eventAction->isOver()) {
$errorResponse = $this->ajaxForwardToReferer($request, 'whiplay_event_show', array('id' => $eventAction->getId()));
}
if ($errorResponse instanceof Response) {
return $errorResponse;
}
$em = $this->getDoctrine()->getManager();
$EventParticipation = $this
->getDoctrine()
->getRepository(EventParticipation::class)
->findBy([
'user' => $currentUser->getId(),
'event' => $eventAction,
]);
if ($EventParticipation) {
$EventParticipation = $EventParticipation[0];
$EventParticipation->setAction($action);
$EventParticipation->setCreatedAt(new DateTime());
} else {
$EventParticipation = new EventParticipation();
$EventParticipation->setDescription('');
$EventParticipation->setAction($action);
$EventParticipation->setCreatedAt(new DateTime());
$EventParticipation->setUser($currentUser);
$EventParticipation->setStatus(ActionStatusConstant::STATUS_PUBLIC);
$EventParticipation->setEvent($eventAction);
}
$em->persist($EventParticipation);
$em->flush();
$this->addFlash(
'notice',
$translator->trans('event.notice.participation_saved')
);
return $this->ajaxForwardToReferer($request, 'whiplay_event_show', array('id' => $eventAction->getId()));
}
}