<?php
namespace App\Controller\Front\UserZone;
use App\Config\Pages;
use App\Entity\Order\Orders;
use App\Entity\Page\Page;
use App\Entity\User\Admin;
use App\Entity\User\User;
use App\Entity\User\UserPackage;
use App\Exception\TokenNotException;
use App\Exception\UserAccountIsActivatedException;
use App\Exception\UserExistException;
use App\Exception\EmailExistException;
use App\Exception\PasswordNotEqualException;
use Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Exception\UserAccountBlockedException;
use App\Utils\ResponseMessage\ResponseMessage;
use Symfony\Component\HttpFoundation\Response;
use App\Exception\OldPasswordNotEqualException;
use App\Exception\UserAccountNotActiveException;
use App\Exception\PasswordIsNotSecureEnoughException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SecurityController extends SecurityUtilsController
{
private const LOGIN_TEMPLATE_PATH = 'front/user_zone/security/login.twig';
private const REGISTER_TEMPLATE_PATH = 'front/user_zone/security/register.twig';
private const REMIND_PASSWORD_PATH = 'front/user_zone/security/remind_password.twig';
private const CHANGE_PASSWORD_PATH = 'front/user_zone/security/change_password.twig';
private const ACCOUNT_TEMPLATE_PATH = 'front/user_zone/my_account.twig';
private const COMPANY_TEMPLATE_PATH = 'front/user_zone/my_company_data.twig';
private const ADVERTISING_PACKAGE_TEMPLATE_PATH = 'front/user_zone/advertising/advertising_package.twig';
private const ADVERTISING_PACKAGE_SHOW_TEMPLATE_PATH = 'front/user_zone/advertising/advertising_package_show.twig';
public function registerAction(Request $originalRequest, Page $page): Response
{
$error = '';
$locale = $originalRequest->getLocale();
$userLogged = $this->checkUserLogIn($originalRequest, $page);
$data = $originalRequest->request->all();
$viewParams = $this->createViewParams($originalRequest, $error, $page);
$viewParams['links_in_footer'] = $this->footerLinkProvider->getAll();
if (false === is_null($userLogged)) {
return $userLogged;
}
if ($originalRequest->isMethod('POST')) {
try {
return $this->registerUser($originalRequest);
} catch (UserExistException $e) {
$page = $this->pageProvider->getOneByMigrationId(Pages::USER_ZONE_LOGIN);
$link = $page->translate($locale, false)->getUrl();
$error = ResponseMessage::onUserExistException($locale, $link);
$viewParams['old_email'] = $data['email'] ?? '';
$viewParams['old_password_1'] = $data['password'] ?? '';
$viewParams['old_password_2'] = $data['password_repeat'] ?? '';
} catch (PasswordNotEqualException $e) {
$error = ResponseMessage::onPasswordNotEqualException($locale);
$viewParams['old_email'] = $data['email'] ?? '';
$viewParams['old_password_1'] = $data['password'] ?? '';
$viewParams['old_password_2'] = $data['password_repeat'] ?? '';
} catch (PasswordIsNotSecureEnoughException $e) {
$error = ResponseMessage::onPasswordIsNotSecureEnoughException($locale);
$viewParams['old_email'] = $data['email'] ?? '';
$viewParams['old_password_1'] = $data['password'] ?? '';
$viewParams['old_password_2'] = $data['password_repeat'] ?? '';
}
if (!empty($error)) {
$this->addFlash('response_message', $error);
}
}
return $this->render(self::REGISTER_TEMPLATE_PATH, $viewParams);
}
public function loginAction(Request $originalRequest, Page $page): Response
{
$error = '';
$locale = $originalRequest->getLocale();
$userLogged = $this->checkUserLogIn($originalRequest, $page);
if (false === is_null($userLogged)) {
return $userLogged;
}
if ($originalRequest->isMethod('POST')) {
try {
return $this->logInUser($originalRequest);
} catch (BadCredentialsException $e) {
$error = ResponseMessage::onBadCredentialsException($locale);
} catch (UserAccountNotActiveException $e) {
$error = ResponseMessage::onUserAccountNotActiveException($locale);
} catch (UserAccountBlockedException $e) {
$error = ResponseMessage::onUserAccountBlockedException($locale);
}
}
if (!empty($error)) {
$this->addFlash('response_message', $error);
}
$viewParams = $this->createViewParams($originalRequest, $error, $page);
return $this->render(self::LOGIN_TEMPLATE_PATH, $viewParams);
}
public function logoutAction(Request $originalRequest, Page $page): Response
{
return $this->logOutUser($originalRequest);
}
public function activateAccount(Request $request, Page $page): Response
{
$error = '';
$viewParams = $this->createViewParams($request, $error, $page);
$originalRequest = $request->attributes->get('originalRequest');
$token = $originalRequest->query->get('token') ?? $originalRequest->query->get('securityLoginToken');
$locale = $request->getLocale();
$login = $this->pageProvider->getOneByMigrationId(Pages::USER_ZONE_LOGIN);
$loginPageUrl = $login->translate($locale, false)->getUrl();
try {
return $this->checkIfTokenActivationExists($token, $request);
} catch (TokenNotException $e) {
$error = ResponseMessage::badToken($locale);
$this->addFlash('response_message', $error);
} catch (UserAccountIsActivatedException $e) {
$error = ResponseMessage::tryActivateAccount($locale);
$this->addFlash('response_message', $error);
return $this->redirectToRoute('front-page', ['_locale' => $locale, 'url' => $loginPageUrl]);
}
return $this->render(self::LOGIN_TEMPLATE_PATH, $viewParams);
}
public function forgotPasswordAction(Request $request, Page $page): ?Response
{
$error = '';
$locale = $request->getLocale();
$viewParams = $this->createViewParams($request, $error, $page);
if ($request->isMethod("POST")) {
try {
$this->checkIfEmailExists($request);
$error = ResponseMessage::onSendMessageResetPassword($locale);
} catch (EmailExistException $e) {
$error = ResponseMessage::onEmailExistException($locale);
}
if (!empty($error)) {
$this->addFlash('response_message', $error);
}
}
return $this->render(self::REMIND_PASSWORD_PATH, $viewParams);
}
public function orderCreatePasswordAndLoginAction(Request $request, Page $page): Response
{
$originalRequest = $request->attributes->get('originalRequest');
$securityLoginToken = $originalRequest->query->get('securityLoginToken') ??
$originalRequest->query->get('token');
$locale = $request->getLocale();
$viewParams = $this->createViewParams($request, '', $page);
$data = $request->request->all();
$viewParams['mode'] = 'order_set_password';
$errorMessage = ResponseMessage::onTokenExistException($locale);
$userLinkLoginUsed = $this->userLinkLoginProvider->getOneByTokenAndUsed($securityLoginToken, true);
$userLinkLoginNoUsed = $this->userLinkLoginProvider->getOneByTokenAndUsed($securityLoginToken, false);
if ($userLinkLoginNoUsed) {
if ($request->isMethod('POST')) {
if ($data['password_1'] === $data['password_2']) {
try {
$user = $userLinkLoginNoUsed->getUser();
$this->userService->checkIfPasswordSecureEnough($data['password_1']);
$newPassword = $this->userFactory->changePassword($data['password_1'], $user);
$this->userService->updatePassword($newPassword);
$page = $this->pageProvider->getOneByMigrationId(Pages::USER_ZONE_PACKAGE_ADVERTISING);
$pageUrl = $page->translate($locale, false)->getUrl();
$token = new UsernamePasswordToken(
$userLinkLoginNoUsed->getUser(),
'user_firewall', $user->getRoles(),
);
$this->container->get("security.token_storage")->setToken($token);
$event = new InteractiveLoginEvent($originalRequest, $token);
$this->eventDispatcher->dispatch($event);
$userLinkLoginNoUsed->setUsed(true);
$this->userLinkLoginService->update($userLinkLoginNoUsed);
return $this->redirectToRoute('front-page', ['_locale' => $locale, 'url' => $pageUrl]);
} catch (PasswordIsNotSecureEnoughException $e) {
$this->addFlash(
'response_message',
ResponseMessage::onPasswordIsNotSecureEnoughException($locale),
);
}
} else {
$this->addFlash(
'response_message',
ResponseMessage::onPasswordNotEqualException($locale),
);
}
}
}
if ($userLinkLoginNoUsed === null) {
if ($userLinkLoginUsed !== null) {
$errorMessage = ResponseMessage::tryActivateAccount($locale);
}
$this->addFlash('response_message', $errorMessage);
$loginUrl = $this->pageProvider
->getOneByMigrationId(Pages::USER_ZONE_LOGIN)
->translate($locale, false)->getUrl();
return $this->redirectToRoute('front-page', ['_locale' => $locale, 'url' => $loginUrl]);
}
return $this->render(self::CHANGE_PASSWORD_PATH, $viewParams);
}
public function resetPasswordAction(Request $request, Page $page): Response
{
$token = $request->attributes->get('originalRequest')->query->get('token');
$error = '';
$locale = $request->getLocale();
$data = $request->request->all();
$viewParams = $this->createViewParams($request, $error, $page);
try {
$this->checkIfTokenExists($token);
} catch (TokenNotException $e) {
$error = ResponseMessage::onTokenExistException($locale);
$this->addFlash('response_message', $error);
$loginUrl = $this->pageProvider
->getOneByMigrationId(Pages::USER_ZONE_LOGIN)
->translate($locale, false)->getUrl();
return $this->redirectToRoute('front-page', ['_locale' => $locale, 'url' => $loginUrl]);
}
if ($request->isMethod('POST')) {
if ($data['password_1'] === $data['password_2']) {
$data['token'] = $token;
try {
$user = $this->userPasswordResetProvider->getOneByToken($token)->getUser();
return $this->changePasswordIfIsSecure($data, $user, $request);
} catch (PasswordIsNotSecureEnoughException $e) {
$error = ResponseMessage::onPasswordIsNotSecureEnoughException($locale);
}
} else {
$error = ResponseMessage::onPasswordNotEqualException($locale);
}
}
if (!empty($error)) {
$this->addFlash('response_message', $error);
}
return $this->render(self::CHANGE_PASSWORD_PATH, $viewParams);
}
public function userAccountAction(Request $request, Page $page): Response
{
$data = $request->request->all();
$locale = $request->getLocale();
$error = '';
$viewParams = $this->createViewParams($request, $error, $page);
$viewParams['user'] = $this->userProvider->getUserFromId($this->getUser());
$userLogged = $this->checkUserLogOut($request, $page);
if (false === is_null($userLogged)) {
return $userLogged;
}
if ($request->isMethod('POST')) {
try {
$this->changePasswordAccount($request, $viewParams['user']);
$this->addFlash('response_message', ResponseMessage::onChangeMessageResetPassword($locale));
} catch (OldPasswordNotEqualException $e) {
$error = ResponseMessage::badOldPassword($locale);
$viewParams['lastPasswords'] = $data['password'];
} catch (PasswordNotEqualException $e) {
$error = ResponseMessage::onPasswordNotEqualException($locale);
$viewParams['lastPasswords'] = $data['password'];
} catch (PasswordIsNotSecureEnoughException $e) {
$error = ResponseMessage::onPasswordIsNotSecureEnoughException($locale);
$viewParams['lastPasswords'] = $data['password'];
}
if (!empty($error)) {
$this->addFlash('response_message', $error);
}
}
return $this->render(self::ACCOUNT_TEMPLATE_PATH, $viewParams);
}
public function userCompanyAction(Request $request, Page $page): Response
{
$userLogged = $this->checkUserLogOut($request, $page);
if (false === is_null($userLogged)) {
return $userLogged;
}
$error = '';
$user = $this->getUser();
$userId = $user->getId();
if ($request->isMethod('POST')) {
$company = $this->companyProvider->getEntityByUserId($userId);
if (is_null($company)) {
$company = $this->companyFactory->createEmptyCompany($user);
$this->companyService->create($company);
}
$this->companyFactory->updateCompanyFromRequestParams($request, $company);
$this->companyService->flush();
}
$viewParams = $this->createViewParams($request, $error, $page);
$viewParams['company'] = $this->companyProvider->getOneByUserId($userId);
return $this->render(self::COMPANY_TEMPLATE_PATH, $viewParams);
}
public function userAccountDeleteAction(Request $request, Page $page): Response
{
$userLogged = $this->checkUserLogOut($request, $page);
if (false === is_null($userLogged)) {
return $userLogged;
}
$user = $this->getUser();
$this->userService->deleteAccount($user);
return $this->logoutAction($request, $page);
}
public function userAdvertisingPackages(Request $request, Page $page): Response
{
$userLogged = $this->checkUserLogOut($request, $page);
$user = $this->getUser();
$locale = $request->getLocale();
if (false === is_null($userLogged)) {
return $userLogged;
}
$originalRequest = $request->attributes->get('originalRequest', null);
$id = $originalRequest->query->get('id', null);
$viewParams = [
'links_in_footer' => $this->footerLinkProvider->getAll(),
];
if (is_null($id) === false) {
$userPackage = $this->userPackageProvider->getOneById($id);
$entity = $request->attributes->get('entity');
if (is_null($userPackage) === false) {
if (
($userPackage->getAdditionalUser() && !$userPackage->getActive()) ||
$userPackage->getUser() !== $user
) {
$redirectUrl = $this->pageProvider->getOneByMigrationId(
Pages::USER_ZONE_PACKAGE_ADVERTISING,
)->translate($locale, false)->getUrl();
return $this->redirectToRoute('front-page', ['_locale' => $locale, 'url' => $redirectUrl]);
}
$offers = $this->userPackageOfferProvider
->getAllByUserPackageOrder(
$userPackage->getUser(),
$userPackage->getPackage(),
$userPackage->getOrder(),
);
if ($userPackage->getAdditionalUser() === false) {
$offers = [];
foreach (
$this->userPackageProvider->getAllByPackageAndOrder(
$userPackage->getPackage(),
$userPackage->getOrder(),
) as $userPackageEntity
) {
foreach (
$this->userPackageOfferProvider->getAllByUserPackageOrder(
$userPackageEntity->getUser(),
$userPackageEntity->getPackage(),
$userPackageEntity->getOrder(),
) as $userPackageOffer
) {
$offers[] = $userPackageOffer;
}
}
}
}
$template = self::ADVERTISING_PACKAGE_SHOW_TEMPLATE_PATH;
$viewParams['offers'] = $offers ?? [];
$viewParams['entity'] = $entity;
$viewParams['userPackage'] = $this->packageFactory->createUserPackageDetailsView($request, $userPackage);
$viewParams['configuration'] = $this->createConfiguration($userPackage);
} else {
$template = self::ADVERTISING_PACKAGE_TEMPLATE_PATH;
$entity = $request->attributes->get('entity');
$viewParams['entity'] = $entity;
$viewParams['entities'] = $this->createPackagesView($user, $request);
}
return $this->render($template, $viewParams);
}
/**
* @Route("add/user/assigned/to/package", name="add-user-assigned-to-package", methods={"POST"})
*/
public function addUsersAssignedToThePackage(Request $request): Response
{
$locale = $request->get('locale', 'pl');
try {
$data = $request->request->all();
$customers = $request->get('customers', []);
$entityPackage = $this->packageProvider->getOneById($data['package'] ?? '');
$entityOrder = $this->orderProvider->getOneById($data['order'] ?? '');
$emailOwner = is_null($this->getUser()) === false ? $this->getUser()->getEmail() : '';
foreach ($customers as $customer) {
$entityUser = $this->userProvider->getUserByUsername($customer);
if (is_null($entityPackage) || is_null($entityOrder)) {
$response = [
'error' => true,
'message' => ResponseMessage::accountNoExists($locale),
];
return new JsonResponse($response);
}
if (is_null($entityUser)) {
$request->request->set('email', $customer);
$request->request->set('emailOwner', $emailOwner);
$this->userService->sharePackageCreateAccount($request);
$entityUser = $this->userProvider->getUserByUsername($customer);
}
$packageUserEntity = $this->userPackageProvider
->getOneByUserPackageOrder(
$entityUser,
$entityPackage,
$entityOrder,
);
if (is_null($packageUserEntity) === false) {
$userPackageRequest = new Request();
$userPackageRequest->request->set('id', $packageUserEntity->getId());
$this->userPackageService->editActive($userPackageRequest, true);
$response = [
'error' => false,
'message' => ResponseMessage::addUsersAssigned($locale),
];
return new JsonResponse($response);
}
$userRequest = new Request();
$userRequest->request->set('user', $entityUser->getId());
$userRequest->request->set('order', $entityOrder->getId());
$userRequest->request->set('package', $entityPackage->getId());
$userRequest->request->set('additionalUser', true);
$userRequest->request->set('emailOwner', $emailOwner);
$userRequest->request->set('locale', $locale);
$userRequest->request->set('isActive', $entityOrder->isActive());
$this->userPackageService->create($userRequest);
}
$response = [
'error' => false,
'message' => ResponseMessage::addUsersAssigned($locale),
];
} catch (Exception $e) {
$response = [
'error' => true,
'message' => ResponseMessage::unknownError($locale),
];
}
return new JsonResponse($response);
}
/**
* @Route("remove/user/assigned/to/package", name="remove-user-assigned-to-package", methods={"DELETE"})
*/
public function deleteUsersAssignedToThePackage(Request $request): Response
{
$locale = $request->get('locale', 'pl');
try {
$this->userPackageService->editActive($request, false);
$response = [
'alert' => 'success',
'message' => ResponseMessage::removeUsersAssigned($locale),
];
} catch (Exception $e) {
$response = [
'alert' => 'success',
'message' => ResponseMessage::unknownError($locale),
];
}
return new JsonResponse($response);
}
private function createConfiguration(?UserPackage $userPackage): array
{
if (
is_null($userPackage) ||
is_null($userPackage->getPackage()) ||
is_null($userPackage->getUser())
) {
return [];
}
$orderOffer = (int)$userPackage->getOrder()->getConfiguration()['number_ads'] ?? 0;
$orderUsed = $userPackage->getOrder()->getConfiguration()['number_used_ads'] ?? 0;
if ($orderOffer === 0) {
$orderOffer = $userPackage->getPackage()->getNumberOfAds();
}
return [
'orderOffer' => $orderOffer,
'orderUsed' => is_null($orderUsed) === false ? ($orderOffer - $orderUsed) : 0,
];
}
private function createPackagesView(null|Admin|User $user, Request $request): ?array
{
$response = [];
if (null === $user) {
return $response;
}
if (in_array('ROLE_ADMIN', $user->getRoles())) {
return $response;
}
foreach ($this->userPackageProvider->getAllByUser($user) as $entity) {
if (is_null($entity->getOrder()) === false) {
if ($entity->getOrder()->getNeedToAccepted()) {
continue;
}
}
if ($entity->getAdditionalUser() && !$entity->getActive()) {
continue;
}
$response[] = $this->packageFactory->createUserPackageListView($request, $entity);
}
return $response;
}
}