<?php
namespace App\Controller;
use App\Services\Functions;
use Carbon\Carbon;
use Exception;
use Pimcore\Log\ApplicationLogger;
use Pimcore\Model\DataObject\Coupon;
use Pimcore\Model\DataObject\LocationSource;
use Pimcore\Model\DataObject\MemberStripeAccount;
use Pimcore\Model\DataObject\MembersUser;
use Pimcore\Model\DataObject\Price;
use Pimcore\Model\DataObject\Promocode;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class SecurityController extends AbstractController
{
private JWTTokenManagerInterface $jwtManager;
private UserPasswordHasherInterface $passwordHasher;
public function __construct(
JWTTokenManagerInterface $jwtManager,
UserPasswordHasherInterface $passwordHasher
) {
$this->jwtManager = $jwtManager;
$this->passwordHasher = $passwordHasher;
}
#[Route('/v1/api/login', name: 'v1_app_login', methods: ['POST'])]
public function loginAction(Request $request): JsonResponse
{
$logger = ApplicationLogger::getInstance();
try {
$data = json_decode($request->getContent(), true);
if (!isset($data['email']) || !isset($data['password'])) {
return new JsonResponse([
'error' => true,
'message' => 'Email, password and source are required',
'data' => []
], Response::HTTP_BAD_REQUEST);
}
$email = $data['email'];
$password = $data['password'];
$sourceKey = $data['source'] ?? null;
// Trova l'utente
$user = MembersUser::getByEmail($email, ['limit' => 1, 'unpublished' => false]);
if (!$user instanceof MembersUser) {
return new JsonResponse([
'error' => true,
'message' => 'Invalid credentials',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
// Verifica la password
if (!$this->passwordHasher->isPasswordValid($user, $password)) {
return new JsonResponse([
'error' => true,
'message' => 'Invalid credentials',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
// Verifica che l'utente sia attivo
if (!$user->getActive()) {
return new JsonResponse([
'error' => true,
'message' => 'Utente non attivo',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
$source = null;
if ($sourceKey) {
$source = LocationSource::getByObjectKey($sourceKey, 1);
if (!$source instanceof LocationSource) {
return new JsonResponse([
'error' => true,
'message' => 'Source not found',
'data' => []
], Response::HTTP_BAD_REQUEST);
}
}
if (!empty($user->getEndDate()) && !$user->getEndDate()->greaterThan(Carbon::now())) {
return new JsonResponse([
'error' => true,
'message' => 'Iscrizione scaduta',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
// Genera il token JWT
$token = $this->jwtManager->create($user);
// Resto della logica per prodotti e promo codes...
// $userData = $this->getUserData($user, $source);
$role = '';
if (in_array('ROLE_PIMCORE_USER', $user->getRoles())) {
$role = 'admin';
} elseif (in_array('ROLE_USER', $user->getRoles())) {
$role = 'user';
}
return new JsonResponse([
'token' => $token,
'user' => [
'id' => $user->getId(),
'firstname' => $user->getFirstname(),
'lastname' => $user->getLastname(),
'email' => $user->getEmail(),
'phone' => $user->getPhone(),
'role' => $role,
// 'roles' => $user->getRoles()
]
]);
} catch (Exception $e) {
$logger->error($e);
return new JsonResponse([
'error' => true,
'message' => $e->getMessage(),
'data' => []
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
#[Route('/v1/api/profile', name: 'app_profile', methods: ['GET'])]
public function getProfileAction(Request $request, #[CurrentUser] $user = null): JsonResponse
{
$sourceKey = $request->query->get('source');
if (!$user instanceof MembersUser) {
return new JsonResponse([
'error' => true,
'message' => 'User not found',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
$source = LocationSource::getByObjectKey($sourceKey, 1);
if (!$source instanceof LocationSource) {
return new JsonResponse([
'error' => true,
'message' => 'Source not found',
'data' => []
], Response::HTTP_BAD_REQUEST);
}
$userData = $this->getUserData($user, $source, false);
return new JsonResponse([
'error' => false,
'message' => null,
'data' => $userData
]);
}
#[Route('/v1/api/refresh-token', name: 'app_refresh_token', methods: ['POST'])]
public function refreshTokenAction(#[CurrentUser] $user = null): JsonResponse
{
if (!$user instanceof MembersUser) {
return new JsonResponse([
'error' => true,
'message' => 'User not found',
'data' => []
], Response::HTTP_UNAUTHORIZED);
}
$token = $this->jwtManager->create($user);
return new JsonResponse([
'token' => $token
]);
}
private function getUserData(MembersUser $user, LocationSource $source, $exception = true): array
{
$products = [];
$promoCodes = [];
$MemberStripeAccount = new MemberStripeAccount\Listing();
$MemberStripeAccount->setCondition('customerId = ? AND source__id = ?', [
$user->getId(),
$source->getId()
]);
$MemberStripeAccount = $MemberStripeAccount->current();
if (!$MemberStripeAccount instanceof MemberStripeAccount) {
if ($exception) {
throw new Exception('Account not found');
}
}
$mainGroup = '';
$groups = $user->getGroups();
if (isset($groups[0]) && $groups[0]->getName() === 'Private') {
$mainGroup = $groups[0]->getName();
if (!empty($user->getEndDate()) && !$user->getEndDate()->greaterThan(Carbon::now())) {
if ($exception) {
throw new Exception('Iscrizione utente scaduto');
}
}
} elseif (isset($groups[0]) && !empty($groups[0]->getName())) {
$mainGroup = $groups[0]->getName();
}
if ($MemberStripeAccount) {
$stripe = new \Stripe\StripeClient($MemberStripeAccount->getSource()?->getStripeAccount()->getStripeSecret());
// Prodotti base
if (null !== ($price = Price::getByPriceid($MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem(), 1))) {
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem()]['price'] = $price->getPrice() / 100;
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem()]['title'] = $price->getTitle();
}
if (null !== ($price = Price::getByPriceid($MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem(), 1))) {
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem()]['price'] = $price->getPrice() / 100;
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem()]['title'] = $price->getTitle();
}
// Gestione promo codes
if (!empty($MemberStripeAccount->getPromoCode())) {
foreach ($MemberStripeAccount->getPromoCode() as $k => $promos) {
$promoCodes[$promos[0]] = $promos[1];
if (null !== ($price = Price::getByPriceid($promos[0], 1))) {
$products[$promos[0]]['price'] = $price->getPrice() / 100;
$products[$promos[0]]['title'] = $price->getTitle();
}
if (null !== ($promo = Promocode::getByPromoid($promos[1], 1))) {
$coupon = Coupon::getByPromo($promo, 1);
if ($coupon instanceof Coupon) {
preg_match('/\d+$/', $coupon->getTitle(), $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
} else {
try {
$promoObj = $stripe->promotionCodes->retrieve($promos[1], []);
if ($promoObj->active) {
preg_match('/\d+$/', $promoObj->coupon->name, $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
} catch (\Exception $e) {
// Log dell'errore se necessario
}
}
}
}
}
$role = '';
if (in_array('ROLE_PIMCORE_USER', $user->getRoles())) {
$role = 'admin';
} elseif (in_array('ROLE_USER', $user->getRoles())) {
$role = 'user';
}
return [
'fullName' => $user->getFirstname() . ' ' . $user->getLastname(),
'taxCode' => $user->getFiscalCode(),
'role' => $role,
'membership' => [
'number' => $user->getMembershipNumber(),
'expirationDate' => $user->getEndDate()?->format('Y-m-d'),
],
'customerType' => $mainGroup,
'customerTypeId' => \Pimcore\Model\DataObject\MembersGroup::getByName($mainGroup, 1)?->getId(),
'businessName' => !empty($user->getBusinessName()) ? $user->getBusinessName() : '',
'firstname' => $user->getFirstname(),
'startDate' => $user->getCreatedDate(),
'endDate' => $user->getEndDate(),
'lastname' => $user->getLastname(),
'email' => $user->getEmail(),
'phone' => $user->getPhone(),
'customerId' => $user->getId(),
'stripeCustomerId' => $MemberStripeAccount ? $MemberStripeAccount?->getStripeCustomerId() : null,
'stripePromoCodes' => $promoCodes,
'products' => $products
];
}
#[Route('/api/login', name: 'app_login', methods: ['POST'])]
public function appLoginAction(Request $request, #[CurrentUser] $user = null): Response
{
$logger = ApplicationLogger::getInstance();
try {
$source = LocationSource::getByObjectKey($request->toArray()['source'])->current();
if (empty($source)) {
throw new Exception('Source not found');
}
$products = [];
if ($user instanceof MembersUser && $user !== null && $user->getActive()) {
$MemberStripeAccount = new MemberStripeAccount\Listing();
$MemberStripeAccount->setCondition('customerId = ? AND source__id = ?', [
$user->getId(),
$source->getId()
]);
$MemberStripeAccount = $MemberStripeAccount->current();
$stripe = new \Stripe\StripeClient($MemberStripeAccount->getSource()->getStripeAccount()->getStripeSecret());
if (!$MemberStripeAccount instanceof MemberStripeAccount) {
throw new Exception('Account not found');
}
if (null !== ($price = Price::getByPriceid($MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem(), 1))) {
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem()]['price'] = $price->getPrice() / 100;
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAssistanceItem()]['title'] = $price->getTitle();
}
if (null !== ($price = Price::getByPriceid($MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem(), 1))) {
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem()]['price'] = $price->getPrice() / 100;
$products[$MemberStripeAccount->getSource()->getStripeAccount()->getAttestationItem()]['title'] = $price->getTitle();
}
$promoCodes = [];
$mainGroup = '';
$groups = $user->getGroups();
if (isset($groups[0]) && $groups[0]->getName() === 'Private') {
$mainGroup = $groups[0]->getName();
if (!empty($user->getEndDate()) && !$user->getEndDate()->greaterThan(Carbon::now())) {
$logger->info($user->getId() . ' Iscrizione utente scaduto');
return $this->json([
'error' => true,
'message' => 'Iscrizione utente scaduto',
'data' => []
]);
}
} elseif (isset($groups[0]) && !empty($groups[0]->getName())) {
$mainGroup = $groups[0]->getName();
}
if (!empty($user->getEndDate()) && !$user->getEndDate()->greaterThan(Carbon::now())) {
if (!empty($MemberStripeAccount->getPromocode())) {
foreach ($MemberStripeAccount->getPromoCode() as $k => $promos) {
$promoCodes[$promos[0]] = $promos[1];
if (null !== ($price = Price::getByPriceid($promos[0], 1))) {
$products[$promos[0]]['price'] = $price->getPrice() / 100;
$products[$promos[0]]['title'] = $price->getTitle();
}
if (null !== ($promo = Promocode::getByPromoid($promos[1], 1))) {
$coupon = Coupon::getByPromo($promo, 1);
if ($coupon instanceof Coupon) {
preg_match('/\d+$/', $coupon->getTitle(), $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
} else {
$promoObj = $stripe->promotionCodes->retrieve($promos[1], []);
if ($promoObj->active) {
preg_match('/\d+$/', $promoObj->coupon->name, $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
}
}
}
} elseif (!empty($MemberStripeAccount->getPromoCode())) {
foreach ($MemberStripeAccount->getPromoCode() as $k => $promos) {
$promoCodes[$promos[0]] = $promos[1];
if (null !== ($price = Price::getByPriceid($promos[0], 1))) {
$products[$promos[0]]['price'] = $price->getPrice() / 100;
$products[$promos[0]]['title'] = $price->getTitle();
}
if (null !== ($promo = Promocode::getByPromoid($promos[1], 1))) {
$coupon = Coupon::getByPromo($promo, 1);
if ($coupon instanceof Coupon) {
preg_match('/\d+$/', $coupon->getTitle(), $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
} else {
$promoObj = $stripe->promotionCodes->retrieve($promos[1], []);
if ($promoObj->active) {
preg_match('/\d+$/', $promoObj->coupon->name, $matches);
if (!empty($matches)) {
$products[$promos[0]]['promo'] = (float) $matches[0];
}
}
}
}
}
return $this->json([
'error' => false,
'message' => null,
'data' => [
'customerType' => $mainGroup,
'customerTypeId' => \Pimcore\Model\DataObject\MembersGroup::getByName($mainGroup, 1)?->getId(),
'businessName' => !empty($user->getBusinessName()) ? $user->getBusinessName() : '',
'firstname' => $user->getFirstname(),
'startDate' => $user->getCreatedDate(),
'endDate' => $user->getEndDate(),
'lastname' => $user->getLastname(),
'email' => $user->getEmail(),
'phone' => $user->getPhone(),
'authorization' => \Pimcore\Config::getWebsiteConfig()->get('rent_calculator_authorization'),
'customerId' => $user->getId(),
'stripeCustomerId' => $MemberStripeAccount->getStripeCustomerId(),
'stripePromoCodes' => $promoCodes,
'products' => $products,
'token' => Functions::securedEncrypt($user->getId())
]
]);
} else {
$logger->info($user->getId() . ' Utente non attivo');
return $this->json([
'error' => true,
'message' => 'Utente non attivo',
'data' => []
]);
}
} catch (Exception $e) {
return $this->json([
'error' => true,
'message' => $e->getMessage(),
'data' => []
]);
}
}
}