<?php
namespace App\Controller;
use App\Entity\Account;
use App\Entity\Live;
use App\Entity\Planning;
use App\Entity\Program;
use App\Entity\Video;
use App\Entity\VideoReading;
use App\Form\AccountType;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
class FrontController extends AbstractController
{
protected $messages = [];
protected $session;
protected $em;
public function __construct(SessionInterface $session, EntityManagerInterface $entityManager)
{
$this->em = $entityManager;
$this->session = $session;
$this->messages = [
'infos' => [],
'errors' => []
];
}
/**
* @param string $info
*/
protected function addInfo(string $info) : void{
$this->messages['infos'][] = $info;
}
/**
* @param string $error
*/
protected function addError(string $error) : void{
$this->messages['errors'][] = $error;
}
/**
* Display all available videos + live
* path : /
* @param Request $request
* @return Response
*/
public function displayVideos(Request $request): Response
{
// If the user is connected
if ($this->session->get('ce') !== null) {
// Get the planning today's planning
$allPlannings = $this->em->getRepository(Planning::class)
->findAll();
$plannings = [];
$days = [
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'Dimanche',
];
foreach ($allPlannings as $planning){
// check if the days is == today
if(strtolower($planning->getDay()) === strtolower($days[date("l")])){
$plannings[] = $planning;
}
}
// get all programs if planning doenst exist
$programs = $this->em->getRepository(Program::class)
->findAll();
//get active live id
$live = $this->em->getRepository(Live::class)
->findOneBy(["isActive" => true]);
if($live == null) {
$liveId = 0;
} else {
$liveId = $live->getLiveId();
}
// Get all videos from database
// todo : lang selector ?
$videos = $this->em->getRepository(Video::class)
->findBy(['displayed' => '1']);
return $this->render('front/videos.html.twig', [
'messages' => $this->messages,
'ce' => $this->session->get('ce'),
'plannings' => $plannings,
'videos' => $videos,
'live' => $liveId,
'imgPath' => 'img/vignettes/',
'vimeoUrl' => 'https://player.vimeo.com/video/',
'programs' => $programs,
]);
}
else{
return $this->redirectToRoute('signIn');
}
}
/**
* Display the LM video Player
* path: /lesmills-video-player
* @param Request $request
* @return Response
*/
public function displayLMVideos(Request $request): Response
{
// If the user is connected
if ($this->session->get('ce') !== null) {
return $this->render('front/LMVideoPlayer.html.twig', [
'messages' => $this->messages,
'ce' => $this->session->get('ce'),
]);
}
else{
return $this->redirectToRoute('signIn');
}
}
/**
* bad 6f18e73f49
* good 42c241ea77
* Allow the user to sign in with the club access code
* path: /signIn
* @param Request $request
* @return Response
*/
public function signIn(Request $request) : Response
{
// If the user is connected
if ($this->session->get('ce') !== null) {
return $this->redirectToRoute('videos');
}
else{
$account = new Account();
$form = $this->createForm(AccountType::class, $account);
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName()));
if ($form->isSubmitted() && $form->isValid()) {
// set the CE from access code
$account->getCEByCode();
// check the accessCode
// If it doesn't work
if (!$account->isEligible()) {
$this->addError('Le code est erroné, veuillez contacter le référent de votre club pour l\'obtenir');
}
// if it works
else {
$this->session->set('accessCode', $account->getAccessCode());
$this->session->set('ce', $account->getCe());
return $this->redirectToRoute('videos');
}
}
}
return $this->render('front/signIn.html.twig', [
'form' => $form->createView(),
'messages' => $this->messages,
]);
}
}
/**
* Sign out a user
* path: /signOut
* @return RedirectResponse
*/
public function signOut() : RedirectResponse
{
// If the user is connected
if ($this->session->get('ce') === null) {
return $this->redirectToRoute('signIn');
}
else{
$this->session->set('accessCode', null);
$this->session->set('ce', null);
return $this->redirectToRoute('signIn');
}
}
/**
* Display the planning from today to future
* path: /planning
*/
public function displayPlanning() : Response
{
$planningsByDay = [];
// get all Planning objects of date >= today
$plannings = $this->em->getRepository(Planning::class)
->findBy([], ['day' => 'asc', 'hour'=>'asc']);
if(count($plannings) === 0){
$this->addError('Aucun planning disponible actuellement');
}
else{
foreach ($plannings as $planning){
$day = $planning->getDay()->getName();
if(!empty($day) && !array_key_exists($day, $planningsByDay)){
$planningsByDay[$day] = [];
}
$planningsByDay[$day][] = $planning;
}
}
// Display them
return $this->render('front/plannings.html.twig', [
'plannings' => $planningsByDay,
'messages' => $this->messages,
]);
}
/**
* Adds a video view when an user clicks on a video
* path: /addVideoView (POST)
* @param Request $request
* @return JsonResponse
*/
public function AjaxAddVideoView(Request $request) : JsonResponse
{
// get The Video ID from the Ajax
$videoId = $request->request->get('videoId', 0);
$video = $this->em->find(Video::class, (int)$videoId);
$ceCode = $this->session->get('ce');
if($video !== null && $video instanceof Video && !is_null($ceCode)){
// add a new VideoReading
$videoReading = (new VideoReading())
->setCodeCE($ceCode)
->setUserIp($_SERVER['REMOTE_ADDR'])
->setVideo($video)
->setReadingDate(new \DateTime('NOW'));
$this->em->persist($videoReading);
$this->em->flush();
return new JsonResponse('ok');
}
else{
return new JsonResponse('error');
}
}
/**
* Get all videos corresponding to criteria
* @param Request $request
* @return JsonResponse
*/
public function AjaxGetVideos(Request $request): JsonResponse
{
$programId = (int)$request->query->get('programId', 0);
if($programId === 0){
$videos = $this->em->getRepository(Video::class)->findAll();
}
else{
// $program = $this->em->find(Program::class, (int)$programId);
// $videos = $program->getVideos();
$videos = $this->em->getRepository(Video::class)->findBy(['program'=> $programId]);
}
// avoid circular reference exception
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
// $data = $serializer->normalize($videos, 'json', ['groups' => 'lightGroup']);
// return $this->json($data);
$jsonObject = $serializer->serialize($videos, 'json', [
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return $this->json($jsonObject, Response::HTTP_OK, [], [ObjectNormalizer::GROUPS => ['lightGroup']]);
// return new JsonResponse($jsonObject);
}
/**
* Generate a analytics file frome database
* returns the file
* path: /admin-generate-analytics
* @return Response
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function generateAnalyticsCSVExport() : response
{
$rawQuery = '
SELECT vr.code_ce as Code_CE, vr.user_ip as User_IP, v.vimeo_number as Vimeo_number, p.program_name as Programme, vr.reading_date as heure
FROM video_reading vr
INNER JOIN video v
ON vr.video_id = v.id
INNER JOIN video_program vp
ON v.id=vp.video_id
INNER JOIN program p
ON vp.program_id = p.id';
$statement = $this->em->getConnection()->prepare($rawQuery);
$statement->execute();
$results = $statement->fetchAllAssociative();
$newFileName = $this->getParameter('kernel.project_dir') . '/public/files/export_csv/analytics/' . sha1((new \DateTime('now'))->format('Y-m-d H:i:s')) . '.csv';
$data = 'Code CE;User IP;Vimeo number;Program name;Date;' .
"\r\n";
foreach ($results as $result){
$data .=
$result['Code_CE'] . ';' .
$result['User_IP'] . ';' .
$result['Vimeo_number'] . ';' .
$result['Programme'] . ';' .
$result['heure'] . ';' .
"\r\n";
}
file_put_contents($newFileName, $data);
return $this->file($newFileName, 'analytics.csv');
}
/**
* Generate a analytics file frome database
* returns the result as JSON
* path: /webservice-video-analytics
* @param Request $request
* @return JsonResponse
*/
public function generateAnalyticsJson(Request $request) : JsonResponse
{
$token = $request->query->get('API_Token');
$response = new JsonResponse();
if($token === substr(sha1('Planet Fitness'), 0, 50)){
$rawQuery = '
SELECT vr.code_ce as Code_CE, vr.user_ip as User_IP, v.vimeo_number as Vimeo_number, p.program_name as Programme, vr.reading_date as heure
FROM video_reading vr
INNER JOIN video v
ON vr.video_id = v.id
INNER JOIN video_program vp
ON v.id=vp.video_id
INNER JOIN program p
ON vp.program_id = p.id';
try {
$statement = $this->em->getConnection()->prepare($rawQuery);
}
catch (Exception $e) {
$response->setData($e->getMessage());
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
return $response;
}
try {
$statement->execute();
}
catch (\Doctrine\DBAL\Driver\Exception $e) {
$response->setData($e->getMessage());
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
return $response;
}
try {
$results = $statement->fetchAllAssociative();
}
catch (\Doctrine\DBAL\Driver\Exception $e) {
$response->setData($e->getMessage());
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
return $response;
}
$response->setData($results);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(Response::HTTP_OK);
}
else{
$response->setData('You don\'t have the right authorization to see this content');
$response->setStatusCode(Response::HTTP_UNAUTHORIZED);
}
return $response;
}
}