<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mime\Email;
use Symfony\Component\HttpFoundation\{JsonResponse, Request, Response};
use Symfony\Component\Routing\Annotation\Route;
use App\Utils\Ticketing;
use App\Entity\User;
use App\Entity\Item;
use App\Utils\Functions;
/**
* @Route("/{_locale}", requirements={"_locale": "en|es"})
*/
class UserController extends AbstractController
{
/**
* @var Ticketing
*/
private $ticketing;
/**
* @var Functions
*/
private $functions;
/**
* @var ManagerRegistry
*/
private $doctrine;
/**
* @param Ticketing $ticketing
* @param Functions $functions
* @param ManagerRegistry $doctrine
*/
public function __construct(Ticketing $ticketing, Functions $functions, ManagerRegistry $doctrine)
{
date_default_timezone_set('UTC');
$this->ticketing = $ticketing;
$this->functions = $functions;
$this->doctrine = $doctrine;
}
/**
* @Route("/access", name="access")
*/
public function access(Request $request, ManagerRegistry $doctrine, MailerInterface $mailer): Response
{
if($request->get("format")){
$format = $request->get("format");
} else {
$format = 1;
}
// General function to set discount ref/affId
$this->functions->setDiscount($request);
$entityManager = $doctrine->getManager();
$redirect="";
$statusLogin = "";
$statusPreregister = "";
$emailPreregister = $request->get('email-preregister');
$emailLogin = $request->get('email-login');
$password = $request->get('password');
if($request->get("redirect")){
$redirect=$request->get("redirect");
}
// if($request->isMethod('post')) {
// $checkCaptcha = $this->functions->checkCaptcha($request->get('g-recaptcha-response'));
// if(!$checkCaptcha) {
// return $this->render('user/access.html.twig', [
// 'statusLogin' => 'errorCaptcha',
// 'statusPreregister' => $statusPreregister,
// 'redirect' => $redirect,
// 'format' => $format
// ]);
// }
// }
if($emailLogin){
if($request->get('send-form-log')){
$result = $this->ticketing->curl("users/login", "normal", array("userId"=>$emailLogin, "password"=>$password), "POST");
if($result["code"] != 200){
$statusLogin = "error";
} else{
$session = $request->getSession();
$session->set('userId', $result["userId"]);
if (!empty($result['type']) && $result['type'] === 1) {
$session->set('userType', 1);
$session->set('userEventId', $result['eventId']);
}
if($redirect!=""){
return $this->redirect($redirect);
}
return $this->redirectToRoute('home');
}
}
}
if($emailPreregister){
if($request->get('send-form-pre')){
$result = $this->ticketing->curl("users", "normal", array("userId"=>$emailPreregister), "POST");
if($result["code"] != 201){
$statusPreregister = "error";
} else {
$user = new User();
$user->setUserId($result["userId"]);
$user->setCreatedAt(new \DateTime());
$entityManager->persist($user);
$entityManager->flush();
$email = (new TemplatedEmail())
->from($this->getParameter('mailer_from'))
->to($result["userId"])
->subject('DOW - Registro')
->htmlTemplate('mail/register.html.twig')
->context([
'userId' => $result["userId"],
'registerCode' => $result["registerCode"],
]);
$mailer->send($email);
$statusPreregister = "done";
}
}
}
return $this->render('user/access.html.twig', [
'statusLogin' => $statusLogin,
'statusPreregister' => $statusPreregister,
'redirect' => $redirect,
'format' => $format
]);
}
/**
* @Route("/register/{userId}/{registerCode}", name="register")
*/
public function register(Request $request, ManagerRegistry $doctrine, $userId, $registerCode): Response
{
$em = $doctrine->getManager();
$status = "";
$user = $this->ticketing->curl("users/".$userId, "normal", array(), "GET");
if($user["code"] == 200){
$status = "error";
} else {
if($request->get('send-form')){
$password = $request->get('password');
$name = $request->get('name');
$surname = $request->get('surname');
$alias = $request->get('alias');
$phone = $request->get('phone');
$city = $request->get('city');
$nif = $request->get('nif');
// Birth date
$birth_date = $request->get('birth_date');
$datetime = new \DateTime();
$newDate = $datetime->createFromFormat('Y-m-d', $birth_date);
$objUser = $em->getRepository(User::class)->findOneBy(['user_id' => $userId]);
if (empty($objUser)) {
$objUser = new User();
$objUser->setUserId($userId);
$objUser->setCreatedAt(new \DateTime());
}
// Requiresd
$objUser->setAlias($alias);
$objUser->setPhone($phone);
$objUser->setBirthDate($newDate);
$objUser->setCity($city);
$em->persist($objUser);
$em->flush();
$result = $this->ticketing->curl("users", "normal",
[
"userId" => $userId,
"password" => 'dow-12345678', // Password temporal
"name" => $name,
"surname" => $surname,
"registerCode" => $registerCode,
"alias" => $alias,
"phone" => $phone,
"city" => $city,
"birth_date" => $newDate,
"nif" => $nif,
], "PATCH");
if($result["code"] != 200){
$status = "error";
} else {
$status = "done";
// Email with tickets link
$this->ticketing->curl("send-qr-email", "normal", ["userId" => $userId], "POST");
}
}
}
return $this->render('user/register.html.twig', [
'status' => $status,
'id' => $userId,
'code' => $registerCode
]);
}
/**
* @Route("/logout", name="logout")
*/
public function logout(Request $request): Response
{
$session = $request->getSession();
$session->clear();
return $this->redirectToRoute('home');
}
/**
* @Route("/user-profile", name="userProfile")
*/
public function userProfile(Request $request): Response
{
// General function to set discount ref/affId
$this->functions->setDiscount($request);
$em = $this->doctrine->getManager();
$userId=$this->functions->getUserLogged();
if(!$userId){
$this->addFlash(
'notice',
'Debe iniciar sesión como usuario'
);
return $this->redirectToRoute('access',["redirect" => $this->generateUrl('userProfile')]);
}
$tickets = $this->ticketing->curl("tickets?onSaleByUser=false&user=" . $userId . "&orderBy=event&limit=1000", "normal", [], "GET");
$result = $this->ticketing->curl("users/" . $userId, "normal", [], "GET");
$items_pending = $em->getRepository(Item::class)->search("count", ["web_pending" => TRUE]);
$sents = $this->ticketing->curl("tickets/activity?origin=" . $userId . "&limit=1000&enabled=true&type=transfer", "normal", [], "GET");
$sells = $this->ticketing->curl("tickets?onSaleByUser=true&user=" . $userId . "&limit=1000", "normal", [], "GET");
$sales_history = $this->ticketing->curl("tickets/activity?origin=" . $userId . "&limit=1000&type=sale", "normal", [], "GET");
$wallet_operations = $this->ticketing->curl("wallet-operations?user=".$userId, "normal", [], "GET");
// Separate collections and tickets
$spsCollections = [];
$nftTickets = [];
date_default_timezone_set("Europe/Madrid");
$dateForCollection = date("Y-m-d H:i:s", strtotime('-24 hours'));
foreach($tickets['tickets'] as $ticket) {
if ($dateForCollection > $ticket['event']['dateEvent']) {
$spsCollections[] = $ticket;
} else {
// Automatic activation for tickets
if (!$ticket["active"] && (date("Y-m-d H:i:s") >= $ticket['event']['dateActivation'])) {
// Unblock ticket
if ($ticket['isBlocked'])
$this->ticketing->curl("tickets/" . $ticket['id'], "normal", ["blocked" => "false"], "PATCH");
// Remove tickets on sale in secondary market
if ($ticket['onSaleUser'])
$this->ticketing->curl("sales/" . $ticket['id'], "normal", [], "DELETE");
// get event
$event = $this->ticketing->curl("events/".$ticket["event"]["id"], "normal", [], "GET");
$activation = $this->ticketing->curl("tickets/".$ticket['id']."/activate", "normal", ["latitude" => $event["latitude"], "longitude" => $event["longitude"]], "PATCH");
if ($activation["code"] == "200") {
$ticket['active'] = true;
$ticket['accessCode'] = $activation['accessCode'];
}
}
$nftTickets[] = $ticket;
}
}
$user = $em->getRepository(User::class)->findOneBy(['user_id' => $userId]);
if ($user !== null) {
$userAlias = $user->getAlias();
} else {
$userAlias = '-';
}
// Blacklist from env
$blacklist = explode(',',$_ENV['BLACKLIST']);
return $this->render('user/profile.html.twig', [
'user' => $result,
'tickets' => $nftTickets,
'collections' => $spsCollections,
'items_pending' => $items_pending,
'alias' => $userAlias,
'sents' => $sents["activity"],
'sells' => $sells["tickets"],
'wallet_operations' => $wallet_operations,
'sales_history' => $sales_history["activity"],
'blacklist' => $blacklist
]);
}
/**
* @Route("/extra-content/{ticketId}/{source}", name="extraContent")
*/
public function extraContent(Request $request, $ticketId, $source): Response
{
// General function to set discount ref/affId
$this->functions->setDiscount($request);
$em = $this->doctrine->getManager();
$userId=$this->functions->getUserLogged();
if(!$userId){
$this->addFlash(
'notice',
'Debe iniciar sesión como usuario'
);
return $this->redirectToRoute('access');
}
$ticket = $this->ticketing->curl("tickets/".$ticketId, "normal", [], "GET");
$topMomentActive = !str_contains(strtolower($ticket['name']), 'space top moment') && !$ticket["active"];
if (empty($ticket) || $ticket["code"] != "200" || $ticket["user"]["userId"] != $userId || $topMomentActive){
$this->addFlash(
'notice',
'No se puede acceder al contenido extra'
);
return $this->redirectToRoute('home');
}
if(!array_key_exists("extraContent", $ticket) || !array_key_exists($source, $ticket["extraContent"])){
$this->addFlash(
'notice',
'No se puede acceder al contenido extra'
);
return $this->redirectToRoute('home');
}
$source = $ticket["extraContent"][$source];
// Path to your private key. Be very careful that this file is not accessible
// from the web!
$private_key_filename = \dirname(__DIR__).'/../var/private_key.pem';
$key_pair_id = 'K3HFP4XM97GS7X';
$expires = time() + 86400; // 1 hour
$canned_policy_stream_name = $this->functions->get_canned_policy_stream_name($source, $private_key_filename, $key_pair_id, $expires);
$client_ip = $_SERVER['REMOTE_ADDR'];
$policy =
'{'.
'"Statement":['.
'{'.
'"Resource":"'. $source . '",'.
'"Condition":{'.
'"IpAddress":{"AWS:SourceIp":"' . $client_ip . '/32"},'.
'"DateLessThan":{"AWS:EpochTime":' . $expires . '}'.
'}'.
'}'.
']' .
'}';
$custom_policy_stream_name = $this->functions->get_custom_policy_stream_name($source, $private_key_filename, $key_pair_id, $policy);
//echo urldecode($canned_policy_stream_name);die();
return $this->redirect(urldecode($custom_policy_stream_name));
return $this->render('user/extra-content.html.twig', [
'source' => $source,
'canned_policy_stream_name' => urldecode($canned_policy_stream_name),
'custom_policy_stream_name' => urldecode($custom_policy_stream_name)
]);
}
/**
* @Route("/recover-password", name="recoverPassword")
*/
public function recoverPassword(Request $request, MailerInterface $mailer): Response
{
$status = "";
$email = $request->get('email');
$result = $this->ticketing->curl("users/".$email."/recover/password", "normal", [], "GET");
if($email && $result){
if($result["code"] != 200 || (!array_key_exists('recoverCode', $result) && !array_key_exists('registerCode', $result))){
$status = "error";
} else {
$checkCaptcha = $this->functions->checkCaptcha($request->get('g-recaptcha-response'));
if(!$checkCaptcha) {
return $this->render('user/recover-password.html.twig', [
'status' => 'errorCaptcha'
]);
}
if(array_key_exists('registerCode', $result) && !empty($result['registerCode'])){
$mail = (new TemplatedEmail())
->from($this->getParameter('mailer_from'))
->to($email)
->subject('DOW - Registro')
->htmlTemplate('mail/register.html.twig')
->context([
'userId' => $email,
'registerCode' => $result["registerCode"],
]);
} else {
$mail = (new TemplatedEmail())
->from($this->getParameter('mailer_from'))
->to($email)
->subject('DOW - Recuperar contraseña')
->htmlTemplate('mail/recover-password.html.twig')
->context([
'userId' => $email,
'recoverCode' => $result["recoverCode"],
]);
}
$mailer->send($mail);
$status = "done";
}
}
return $this->render('user/recover-password.html.twig', [
'status'=>$status
]);
}
/**
* @Route("/change-password/{userId}/{recoverCode}", name="changePassword")
*/
public function changePassword(Request $request, $userId, $recoverCode): Response
{
$status = "";
$password = $request->get('password');
$check = $this->ticketing->curl("users/".$userId, "normal", array(), "GET");
if($check["code"] != 200 || !array_key_exists('recoverCode', $check) || $check["recoverCode"]!=$recoverCode){
$status = "error2";
}
else{
if($request->get('send-form')){
$result = $this->ticketing->curl("users/change-password", "normal", array("userId"=>$userId, "password"=>$password, "recoverCode"=>$recoverCode), "PATCH");
if($result["code"] != 200){
$status = "error";
} else {
$status = "done";
}
}
}
return $this->render('user/change-password.html.twig', [
'status' => $status,
'id' => $userId,
'code' => $recoverCode
]);
}
/**
* @Route("/withdrawal", name="withdrawal-request")
*/
public function requestWithdrawal(Request $request, MailerInterface $mailer) {
$wh_token = bin2hex(random_bytes(45));
$data = $request->request->all();
$data['token'] = $wh_token;
$withdraw = $this->ticketing->curl("wallet-operations", "normal", $data, "POST");
if($withdraw["code"] != 201) {
return new JsonResponse([
'status' => false,
'message' => $withdraw['message'],
'data' => []
], 403);
}
$data['operation_id'] = $withdraw['id'];
$email = (new TemplatedEmail())
->from($this->getParameter('mailer_from'))
->to($_ENV['CLIENT_EMAIL'])
->subject('DOW - request withdrawal')
->htmlTemplate('mail/withdrawal-request.html.twig')
->context($data);
$mailer->send($email);
return new JsonResponse([
'status' => true,
'message' => 'La retirada se ha solicitado con éxito.'
]);
}
/**
* @Route("/withdrawal-remove", name="withdrawal-remove")
*/
public function removeWithdrawal(Request $request, MailerInterface $mailer) {
$wh_token = bin2hex(random_bytes(45));
$data = $request->request->all();
$data['token'] = $wh_token;
$withdraw = $this->ticketing->curl("wallet-operations-update/".$data['operation_id'], "normal", $data, "POST");
if($withdraw["code"] != 201) {
return new JsonResponse([
'status' => false,
'message' => $withdraw['message'],
'data' => []
], 403);
}
$email = (new TemplatedEmail())
->from($this->getParameter('mailer_from'))
->to($_ENV['CLIENT_EMAIL'])
->subject('DOW - remove withdrawal')
->htmlTemplate('mail/withdrawal-remove.html.twig')
->context([
'operation_id' => $withdraw['id'],
'account_name' => $withdraw['accountName'],
'account' => $withdraw['account'],
'amount' => $withdraw['amount']
]);
$mailer->send($email);
return new JsonResponse([
'status' => true,
'message' => 'La retirada se ha anulado con éxito.'
]);
}
/**
* @Route("/anonymous-user-profile/{token}", name="anonymousUserProfile")
*/
public function anonymousUserProfile(Request $request, $token): Response
{
$userId = $this->functions->getUserLogged();
if ($userId)
return $this->redirectToRoute('userProfile');
// General function to set discount ref/affId
$this->functions->setDiscount($request);
$em = $this->doctrine->getManager();
$userId = $this->functions->decrypt($token);
$anyUser = '/false';
$result = $this->ticketing->curl("users/".$userId.$anyUser, "normal", [], "GET");
if($result['enabled']){
$this->addFlash(
'notice',
'Debe iniciar sesión como usuario'
);
return $this->redirectToRoute('access',["redirect" => $this->generateUrl('userProfile')]);
}
$tickets = $this->ticketing->curl("tickets?onSaleByUser=false&user=".$userId."&orderBy=event&limit=1000", "normal", [], "GET");
$items_pending = $em->getRepository(Item::class)->search("count",["web_pending" => TRUE]);
// Separate collections and tickets
$spsCollections = [];
$nftTickets = [];
date_default_timezone_set("Europe/Madrid");
foreach($tickets['tickets'] as $ticket) {
if (date("Y-m-d") > $ticket['event']['dateEvent']) {
$spsCollections[] = $ticket;
} else {
// Automatic activation for tickets
if (!$ticket["active"] && (date("Y-m-d H:i:s") >= $ticket['event']['dateActivation'])
&& (date("Y-m-d") == date("Y-m-d", strtotime($ticket['event']['dateEvent']))) ) {
// get event
$event = $this->ticketing->curl("events/".$ticket["event"]["id"], "normal", [], "GET");
$activation = $this->ticketing->curl("tickets/".$ticket['id']."/activate", "normal", ["latitude" => $event["latitude"], "longitude" => $event["longitude"]], "PATCH");
if ($activation["code"] == "200") {
$ticket['active'] = true;
$ticket['accessCode'] = $activation['accessCode'];
}
}
$nftTickets[] = $ticket;
}
}
return $this->render('user/anonymous-profile.html.twig', [
'user' => $result,
'tickets' => $nftTickets,
'collections' => $spsCollections,
'items_pending' => $items_pending,
'anonymous' => TRUE
]);
}
}