src/Controller/Account/AccountController.php line 78

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Account;
  3. use AngelGamez\PorpaginasBundle\Controller\PaginationTrait;
  4. use App\Entity\Account\Customer;
  5. use App\Entity\User;
  6. use App\Form\BulkActionForm;
  7. use App\Form\ChangeAccountPasswordForm;
  8. use App\Form\ChangeAccountInformationForm;
  9. use App\Repository\ProfileRepository;
  10. use App\Repository\SaloonRepository;
  11. use App\Service\AccountChargesDurationEstimator;
  12. use App\Service\AccountChargesDurationPresenter;
  13. use App\Service\AccountPaidServicesPricesProvider;
  14. use App\Service\BulkQueueService;
  15. use App\Service\Features;
  16. use App\Service\ProfilePlanPlacementService;
  17. use App\Service\ProfileCtrService;
  18. use App\Service\UserService;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  21. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  22. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  23. use Symfony\Component\HttpFoundation\JsonResponse;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\RequestStack;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  29. use Symfony\Component\HttpKernel\KernelInterface;
  30. use Symfony\Component\Routing\Annotation\Route;
  31. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  32. class AccountController extends AbstractController
  33. {
  34.     use PaginationTrait;
  35.     use AccountListFilterTrait;
  36.     private const STEP_TURN_ON_PROFILE = 0;
  37.     private const STEP_ENTER_PHONE = 1;
  38.     private const STEP_SEND_CODE = 2;
  39.     private const STEP_CONNECT_PROFILES = 3;
  40.     private const STEP_REPEAT_CALL = 4;
  41.     public const ACTION_ACTIVATE = 1;
  42.     public const ACTION_DEACTIVATE = 2;
  43.     const LEGACY_MASSEUR_LIST_PARAM = 'massagers';
  44.     const AVAILABLE_CTR_PERIODS = ['today', 'yesterday', 'week', 'month', 'all_time'];
  45.     const AVAILABLE_PROFILE_PLACEMENT_TYPES = ['all', 'paid', 'free', 'ultra-vip', 'vip', 'standard', 'hidden'];
  46.     private KernelInterface $kernel;
  47.     private Features $features;
  48.     function __construct(
  49.         RequestStack $requestStack, SessionInterface $session, ParameterBagInterface $parameterBag,
  50.         KernelInterface $kernel, Features $features, ProfileRepository $profileRepository
  51.     )
  52.     {
  53.         $this->request = $requestStack->getCurrentRequest();
  54.         $this->session = $session;
  55.         $this->parameterBag = $parameterBag;
  56.         $this->availablePlacementTypeFilters = self::AVAILABLE_PROFILE_PLACEMENT_TYPES;
  57.         $this->kernel = $kernel;
  58.         $this->profileRepository = $profileRepository;
  59.         $this->features = $features;
  60.     }
  61.     /**
  62.      * @throws \Doctrine\ORM\NoResultException
  63.      * @throws \Doctrine\ORM\NonUniqueResultException
  64.      */
  65.     #[Route(path: '/', name: 'account', options: ['expose' => true])]
  66.     #[Route(path: '/page{page<\d+>}/', name: 'account._pagination', options: ['expose' => true])]
  67.     #[Security("is_granted('ROLE_ADVERTISER') or is_granted('ROLE_CUSTOMER')")]
  68.     public function homepage(ProfileRepository $profileRepository, SaloonRepository $saloonRepository,
  69.         Request $request, ParameterBagInterface $parameterBag, SessionInterface $session, ProfileCtrService $profileCtrService,
  70.         BulkQueueService $bulkQueueService, ProfilePlanPlacementService $planPlacementService): Response
  71.     {
  72.         $user = $this->getUser();
  73.         if($user instanceof Customer) {
  74.             return $this->redirectToRoute('account.preferred_profiles.list');
  75.         }
  76.         if($this->features->account_main_is_profiles()) {
  77.             return $this->redirectToRoute('account_girls');
  78.         }
  79.         list(
  80.             'per_page' => $perPage, 'placement_type_filter' => $placementTypeFilter, 'name_filter' =>  $nameFilter,
  81.             'sort' =>  $sort, 'sort_direction' =>  $sortDirection, 'ctr_period' => $ctrPeriod,
  82.             ) = $this->processListRequestData($request, true);
  83.         $profilesCtr = $profileCtrService->getCtrByOwner($user, $ctrPeriod);
  84.         $profileIdsWaitingAction = $bulkQueueService->getProfilesWaitingAction($user);
  85.         $isMasseur = $this->features->non_masseur_on_account_profile_list() ? false : null;
  86.         $profiles = $this->getFilteredAndSortedProfiles(
  87.             $user, $perPage, $sort, $sortDirection, $placementTypeFilter, $nameFilter, $profilesCtr, $isMasseur
  88.         );
  89.         $templateParameters = [
  90.             'is_masseur_list' => null,
  91.             'profiles' => $profiles,
  92.             'all_profiles_ids' => $this->showDebugData() ? $this->getProfileIdsByFilter($user, $placementTypeFilter, $nameFilter, null) : [],
  93.             'profiles_ctr' => $profilesCtr,
  94.             'ctr_period' => $ctrPeriod,
  95.             'per_page' => $perPage == 99999 ? -1 : $perPage,
  96.             'placement_type_filter' => $placementTypeFilter,
  97.             'name_filter' => $nameFilter,
  98.             'sort' => $sort,
  99.             'sort_direction' => $sortDirection,
  100.             'profiles_waiting_action' => $profileIdsWaitingAction,
  101.             'plan_placement_enabled' => $planPlacementService->isEnabled(),
  102.             'profile_plan_badges' => $planPlacementService->buildBadgesByProfiles($profiles),
  103.         ];
  104.         if($request->isXmlHttpRequest()) {
  105.             return $this->render('account/advertiser/account.profiles.html.twig', $templateParameters);
  106.         } else {
  107.             if(null !== ($redirectResponse = $this->redirectToRouteWithoutPaginationIfNeeded($profiles)))
  108.                 return $redirectResponse;
  109.             $bulkAction = $this->createForm(BulkActionForm::class, null, [
  110.                 'action' => $this->generateUrl('account.profile_management.bulk_action'),
  111.                 'method' => 'post',
  112.                 'data' => [
  113.                     'entity_repository' => $profileRepository,
  114.                 ],
  115.             ]);
  116.             return $this->render('account/advertiser/account.html.twig', array_merge($templateParameters, [
  117.                 'user' => $user,
  118.                 'profiles_active_count' => $profileRepository->countActiveOfOwner($user, $this->features->non_masseur_on_account_profile_list() ? false : null),
  119.                 'profiles_all_count' => $profileRepository->countAllOfOwnerNotDeleted($user, $this->features->non_masseur_on_account_profile_list() ? false : null),
  120.                 'masseurs_active_count' => $profileRepository->countActiveOfOwner($user, true),
  121.                 'masseurs_all_count' => $profileRepository->countAllOfOwnerNotDeleted($user, true),
  122.                 'saloons_active_count' => $saloonRepository->countActiveOfOwner($user),
  123.                 'saloons_all_count' => $saloonRepository->countAllOfOwner($user),
  124.                 'bulk_form' => $bulkAction->createView(),
  125.                 'per_page_variants' => explode(',', $parameterBag->get('account.setting.advertiser_profile_list_per_page.variants')),
  126.                 'ctr_periods' => AccountController::AVAILABLE_CTR_PERIODS,
  127.                 'placement_type_filter_variants' => self::AVAILABLE_PROFILE_PLACEMENT_TYPES,
  128.             ]));
  129.         }
  130.     }
  131.     #[Route(path: '/profile/', name: 'account.settings')]
  132.     #[Security("is_granted('ROLE_ADVERTISER') or is_granted('ROLE_CUSTOMER')")]
  133.     public function accountProfileEdit(Request $request, UserService $userService, ParameterBagInterface $parameterBag): RedirectResponse|Response
  134.     {
  135.         /** @var User $user */
  136.         $user = $this->getUser();
  137.         $form = $this->createForm(ChangeAccountInformationForm::class, $user);
  138.         $form->handleRequest($request);
  139.         $passwordForm = $this->createForm(ChangeAccountPasswordForm::class);
  140.         $passwordForm->handleRequest($request);
  141.         if ($form->isSubmitted() && $form->isValid()) {
  142.             $userService->edit($form->getData());
  143.             $this->addFlash('success', 'Profile settings updated.');
  144.             return $this->redirectToRoute('account.settings');
  145.         } elseif ($passwordForm->isSubmitted() && $passwordForm->isValid()) {
  146.             $newPassword = $passwordForm->get('new_password')->getData();
  147.             $userService->changePassword($user, $newPassword);
  148.             $this->addFlash('success', 'Profile password updated.');
  149.             return $this->redirectToRoute('account.settings');
  150.         }
  151.         return $this->render('account/profile.html.twig', [
  152.             'user' => $user,
  153.             'form' => $form->createView(),
  154.             'password_form' => $passwordForm->createView(),
  155.             'approval_media_upload_domain' => $parameterBag->get('app.approval_media_upload_domain'),
  156.         ]);
  157.     }
  158.     #[Route(path: '/top/', name: 'account.profile.top_placement')]
  159.     #[Route(path: '/top/page{page<\d+>}/', name: 'account.profile.top_placement._pagination', options: ['expose' => true])]
  160.     #[IsGranted('ROLE_ADVERTISER')]
  161.     public function topPlacement(
  162.          ProfileRepository $profileRepository,
  163.          AccountPaidServicesPricesProvider $accountPaidServicesPricesProvider,
  164.          Request $request, ParameterBagInterface $parameterBag): Response
  165.     {
  166.         /** @var User $user */
  167.         $user = $this->getUser();
  168.         $result = $profileRepository->ofOwnerPaged($user);
  169.         $profiles = $this->takePage($result, $parameterBag->get('advertiser.profiles.per_page'));
  170.         $city = $user->getCity();
  171.         $topPlacementHourlyPrice = $accountPaidServicesPricesProvider
  172.             ->getPricesForAccount($user)
  173.             ->getTopPlacementHourlyPrice();
  174.         if($request->isXmlHttpRequest()) {
  175.             return $this->render('account/profile_top/top_placement.profiles.html.twig', [
  176.                 'profiles' => $profiles,
  177.             ]);
  178.         } else {
  179.             return $this->render('account/profile_top/top_placement.html.twig', [
  180.                 'profiles' => $profiles,
  181.                 'city' => $city,
  182.                 'profile_top_placement_hourly_price' => $topPlacementHourlyPrice,
  183.                 'top_price_tables' => $accountPaidServicesPricesProvider->getTopPriceTablesForAccount($user),
  184.             ]);
  185.         }
  186.     }
  187.     /**
  188.      * @deprecated ?
  189.      */
  190.     #[Route(path: '/settings/profile-list/per-page/{count}/', name: 'account.settings.advertiser_profile_list_per_page')]
  191.     #[Route(path: '/settings/saloon-list/per-page/{count}/', name: 'account.settings.advertiser_saloon_list_per_page')]
  192.     #[IsGranted('ROLE_ADVERTISER')]
  193.     public function settingsPerPage(int $count, SessionInterface $session, Request $request, ParameterBagInterface $parameterBag): Response
  194.     {
  195.         $route = $request->attributes->get('_route');
  196.         $isProfileSetting = ("account.settings.advertiser_profile_list_per_page" == $route);
  197.         $variants = $isProfileSetting
  198.             ? $parameterBag->get('account.setting.advertiser_profile_list_per_page.variants')
  199.             : $parameterBag->get('account.setting.advertiser_saloon_list_per_page.variants');
  200.         $variants = explode(',', $variants);
  201.         if(false === array_search($count, $variants)) {
  202.             throw new \LogicException(sprintf('Count must be one of %s', implode(',', $variants)));
  203.         }
  204.         $isProfileSetting
  205.            ? $session->set($parameterBag->get('account.setting.advertiser_profile_list_per_page.name'), $count)
  206.            : $session->set($parameterBag->get('account.setting.advertiser_saloon_list_per_page.name'), $count);
  207.         $referer = $request->headers->get('referer');
  208.         return $referer ? $this->redirect($request->headers->get('referer')) : $this->redirectToRoute('account');
  209.     }
  210.     #[Route(path: '/settings/profile-list/ctr-period/{period}/', name: 'account.settings.advertiser_profile_list_ctr_period')]
  211.     #[IsGranted('ROLE_ADVERTISER')]
  212.     public function settingsCtrPeriod(string $period, SessionInterface $session, Request $request, ParameterBagInterface $parameterBag, ProfileCtrService $profileCtrService): Response
  213.     {
  214.         if(false === array_search($period, self::AVAILABLE_CTR_PERIODS)) {
  215.             throw new \LogicException(sprintf('Ctr period must be one of %s', implode(',', self::AVAILABLE_CTR_PERIODS)));
  216.         }
  217.         $session->set($parameterBag->get('account.setting.advertiser_profile_list_ctr_period.name'), $period);
  218.         if($request->isXmlHttpRequest()) {
  219.             return $this->json([
  220.                 'success' => true,
  221.                 'profiles_ctr' => $profileCtrService->getCtrByOwner($this->getUser(), $period),
  222.                 'period' => $period,
  223.             ]);
  224.         } else {
  225.             $referer = $request->headers->get('referer');
  226.             return $referer ? $this->redirect($request->headers->get('referer')) : $this->redirectToRoute('account');
  227.         }
  228.     }
  229.     
  230.     #[Route(path: '/rules/', name: 'account.rules')]
  231.     public function rules(): Response
  232.     {
  233.         return $this->render('account/static/rules.html.twig');
  234.     }
  235.     #[Route(path: '/charges/duration/', name: 'account.charges_duration', options: ['expose' => true])]
  236.     #[Security("is_granted('ROLE_ADVERTISER') or is_granted('ROLE_CUSTOMER')")]
  237.     public function chargesDuration(
  238.         Request $request,
  239.         AccountChargesDurationEstimator $accountChargesDurationEstimator,
  240.         AccountChargesDurationPresenter $accountChargesDurationPresenter
  241.     ): JsonResponse
  242.     {
  243.         $user = $this->getUser();
  244.         if (!$user instanceof User) {
  245.             return $this->json(['success' => false, 'duration' => null], 401);
  246.         }
  247.         $referenceAt = null;
  248.         $referenceAtRaw = $request->query->get('at');
  249.         if (is_scalar($referenceAtRaw) && ctype_digit((string)$referenceAtRaw)) {
  250.             $referenceAt = (new \DateTimeImmutable('@'.(string)$referenceAtRaw))
  251.                 ->setTimezone(new \DateTimeZone('UTC'));
  252.         }
  253.         $estimate = $accountChargesDurationEstimator->estimate($user, $referenceAt);
  254.         $durationKey = $accountChargesDurationPresenter->messageKey($estimate);
  255.         $durationParameters = $accountChargesDurationPresenter->messageParameters($estimate);
  256.         return $this->json([
  257.             'success' => true,
  258.             'duration' => $accountChargesDurationPresenter->present($estimate),
  259.             'duration_key' => $durationKey,
  260.             'duration_parameters' => $durationParameters,
  261.             'hours' => $estimate->getHours(),
  262.             'has_paid_placements' => $estimate->hasPaidPlacements(),
  263.             'unlimited' => $estimate->isUnlimited(),
  264.         ]);
  265.     }
  266.     #[Route(path: '/hide-offer-bar/', name: 'account.offer_bar.hide')]
  267.     public function hideOfferBar(EntityManagerInterface $entityManager): Response
  268.     {
  269.         /** @var User $user */
  270.         $user = $this->getUser();
  271.         $user->setOfferBarHidden();
  272.         $entityManager->flush();
  273.         return $this->json(['status' => 1]);
  274.     }
  275.     private function showDebugData(): bool
  276.     {
  277.         return $this->kernel->getEnvironment() == 'dev' || $this->kernel->getEnvironment() == 'review';
  278.     }
  279. }