<?php
namespace App\Controller\Account;
use AngelGamez\PorpaginasBundle\Controller\PaginationTrait;
use App\Entity\Account\Customer;
use App\Entity\User;
use App\Form\BulkActionForm;
use App\Form\ChangeAccountPasswordForm;
use App\Form\ChangeAccountInformationForm;
use App\Repository\PaidPlacementPriceRepository;
use App\Repository\ProfileRepository;
use App\Repository\SaloonRepository;
use App\Service\BulkQueueService;
use App\Service\Features;
use App\Service\ProfileCtrService;
use App\Service\UserService;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AccountController extends AbstractController
{
use PaginationTrait;
use AccountListFilterTrait;
private const STEP_TURN_ON_PROFILE = 0;
private const STEP_ENTER_PHONE = 1;
private const STEP_SEND_CODE = 2;
private const STEP_CONNECT_PROFILES = 3;
private const STEP_REPEAT_CALL = 4;
public const ACTION_ACTIVATE = 1;
public const ACTION_DEACTIVATE = 2;
const LEGACY_MASSEUR_LIST_PARAM = 'massagers';
const AVAILABLE_CTR_PERIODS = ['today', 'yesterday', 'week', 'month', 'all_time'];
const AVAILABLE_PROFILE_PLACEMENT_TYPES = ['all', 'paid', 'free', 'ultra-vip', 'vip', 'standard', 'hidden'];
private KernelInterface $kernel;
private Features $features;
function __construct(
RequestStack $requestStack, SessionInterface $session, ParameterBagInterface $parameterBag,
KernelInterface $kernel, Features $features, ProfileRepository $profileRepository
)
{
$this->request = $requestStack->getCurrentRequest();
$this->session = $session;
$this->parameterBag = $parameterBag;
$this->availablePlacementTypeFilters = self::AVAILABLE_PROFILE_PLACEMENT_TYPES;
$this->kernel = $kernel;
$this->profileRepository = $profileRepository;
$this->features = $features;
}
/**
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
#[Route(path: '/', name: 'account', options: ['expose' => true])]
#[Route(path: '/page{page<\d+>}/', name: 'account._pagination', options: ['expose' => true])]
#[Security("is_granted('ROLE_ADVERTISER') or is_granted('ROLE_CUSTOMER')")]
public function homepage(ProfileRepository $profileRepository, SaloonRepository $saloonRepository,
Request $request, ParameterBagInterface $parameterBag, SessionInterface $session, ProfileCtrService $profileCtrService,
BulkQueueService $bulkQueueService): Response
{
$user = $this->getUser();
if($user instanceof Customer) {
return $this->redirectToRoute('account.preferred_profiles.list');
}
if($this->features->account_main_is_profiles()) {
return $this->redirectToRoute('account_girls');
}
list(
'per_page' => $perPage, 'placement_type_filter' => $placementTypeFilter, 'name_filter' => $nameFilter,
'sort' => $sort, 'sort_direction' => $sortDirection, 'ctr_period' => $ctrPeriod,
) = $this->processListRequestData($request, true);
$profilesCtr = $profileCtrService->getCtrByOwner($user, $ctrPeriod);
$profileIdsWaitingAction = $bulkQueueService->getProfilesWaitingAction($user);
$isMasseur = $this->features->non_masseur_on_account_profile_list() ? false : null;
$profiles = $this->getFilteredAndSortedProfiles(
$user, $perPage, $sort, $sortDirection, $placementTypeFilter, $nameFilter, $profilesCtr, $isMasseur
);
$templateParameters = [
'is_masseur_list' => null,
'profiles' => $profiles,
'all_profiles_ids' => $this->showDebugData() ? $this->getProfileIdsByFilter($user, $placementTypeFilter, $nameFilter, null) : [],
'profiles_ctr' => $profilesCtr,
'ctr_period' => $ctrPeriod,
'per_page' => $perPage == 99999 ? -1 : $perPage,
'placement_type_filter' => $placementTypeFilter,
'name_filter' => $nameFilter,
'sort' => $sort,
'sort_direction' => $sortDirection,
'profiles_waiting_action' => $profileIdsWaitingAction,
];
if($request->isXmlHttpRequest()) {
return $this->render('account/advertiser/account.profiles.html.twig', $templateParameters);
} else {
if(null !== ($redirectResponse = $this->redirectToRouteWithoutPaginationIfNeeded($profiles)))
return $redirectResponse;
$bulkAction = $this->createForm(BulkActionForm::class, null, [
'action' => $this->generateUrl('account.profile_management.bulk_action'),
'method' => 'post',
'data' => [
'entity_repository' => $profileRepository,
],
]);
return $this->render('account/advertiser/account.html.twig', array_merge($templateParameters, [
'user' => $user,
'profiles_active_count' => $profileRepository->countActiveOfOwner($user, $this->features->non_masseur_on_account_profile_list() ? false : null),
'profiles_all_count' => $profileRepository->countAllOfOwnerNotDeleted($user, $this->features->non_masseur_on_account_profile_list() ? false : null),
'masseurs_active_count' => $profileRepository->countActiveOfOwner($user, true),
'masseurs_all_count' => $profileRepository->countAllOfOwnerNotDeleted($user, true),
'saloons_active_count' => $saloonRepository->countActiveOfOwner($user),
'saloons_all_count' => $saloonRepository->countAllOfOwner($user),
'bulk_form' => $bulkAction->createView(),
'per_page_variants' => explode(',', $parameterBag->get('account.setting.advertiser_profile_list_per_page.variants')),
'ctr_periods' => AccountController::AVAILABLE_CTR_PERIODS,
'placement_type_filter_variants' => self::AVAILABLE_PROFILE_PLACEMENT_TYPES,
]));
}
}
#[Route(path: '/profile/', name: 'account.settings')]
#[Security("is_granted('ROLE_ADVERTISER') or is_granted('ROLE_CUSTOMER')")]
public function accountProfileEdit(Request $request, UserService $userService, ParameterBagInterface $parameterBag): RedirectResponse|Response
{
/** @var User $user */
$user = $this->getUser();
$form = $this->createForm(ChangeAccountInformationForm::class, $user);
$form->handleRequest($request);
$passwordForm = $this->createForm(ChangeAccountPasswordForm::class);
$passwordForm->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$userService->edit($form->getData());
$this->addFlash('success', 'Profile settings updated.');
return $this->redirectToRoute('account.settings');
} elseif ($passwordForm->isSubmitted() && $passwordForm->isValid()) {
$newPassword = $passwordForm->get('new_password')->getData();
$userService->changePassword($user, $newPassword);
$this->addFlash('success', 'Profile password updated.');
return $this->redirectToRoute('account.settings');
}
return $this->render('account/profile.html.twig', [
'user' => $user,
'form' => $form->createView(),
'password_form' => $passwordForm->createView(),
'approval_media_upload_domain' => $parameterBag->get('app.approval_media_upload_domain'),
]);
}
#[Route(path: '/top/', name: 'account.profile.top_placement')]
#[Route(path: '/top/page{page<\d+>}/', name: 'account.profile.top_placement._pagination', options: ['expose' => true])]
#[IsGranted('ROLE_ADVERTISER')]
public function topPlacement(ProfileRepository $profileRepository, PaidPlacementPriceRepository $priceRepository,
Request $request, ParameterBagInterface $parameterBag): Response
{
$result = $profileRepository->ofOwnerPaged($this->getUser());
$profiles = $this->takePage($result, $parameterBag->get('advertiser.profiles.per_page'));
if($request->isXmlHttpRequest()) {
return $this->render('account/profile_top/top_placement.profiles.html.twig', [
'profiles' => $profiles,
]);
} else {
return $this->render('account/profile_top/top_placement.html.twig', [
'profiles' => $profiles,
'profile_top_placement_price' => $priceRepository->getProfileTopPlacementBasePriceWithinCity($this->getUser()->getCity()),
]);
}
}
/**
* @deprecated ?
*/
#[Route(path: '/settings/profile-list/per-page/{count}/', name: 'account.settings.advertiser_profile_list_per_page')]
#[Route(path: '/settings/saloon-list/per-page/{count}/', name: 'account.settings.advertiser_saloon_list_per_page')]
#[IsGranted('ROLE_ADVERTISER')]
public function settingsPerPage(int $count, SessionInterface $session, Request $request, ParameterBagInterface $parameterBag): Response
{
$route = $request->attributes->get('_route');
$isProfileSetting = ("account.settings.advertiser_profile_list_per_page" == $route);
$variants = $isProfileSetting
? $parameterBag->get('account.setting.advertiser_profile_list_per_page.variants')
: $parameterBag->get('account.setting.advertiser_saloon_list_per_page.variants');
$variants = explode(',', $variants);
if(false === array_search($count, $variants)) {
throw new \LogicException(sprintf('Count must be one of %s', implode(',', $variants)));
}
$isProfileSetting
? $session->set($parameterBag->get('account.setting.advertiser_profile_list_per_page.name'), $count)
: $session->set($parameterBag->get('account.setting.advertiser_saloon_list_per_page.name'), $count);
$referer = $request->headers->get('referer');
return $referer ? $this->redirect($request->headers->get('referer')) : $this->redirectToRoute('account');
}
#[Route(path: '/settings/profile-list/ctr-period/{period}/', name: 'account.settings.advertiser_profile_list_ctr_period')]
#[IsGranted('ROLE_ADVERTISER')]
public function settingsCtrPeriod(string $period, SessionInterface $session, Request $request, ParameterBagInterface $parameterBag, ProfileCtrService $profileCtrService): Response
{
if(false === array_search($period, self::AVAILABLE_CTR_PERIODS)) {
throw new \LogicException(sprintf('Ctr period must be one of %s', implode(',', self::AVAILABLE_CTR_PERIODS)));
}
$session->set($parameterBag->get('account.setting.advertiser_profile_list_ctr_period.name'), $period);
if($request->isXmlHttpRequest()) {
return $this->json([
'success' => true,
'profiles_ctr' => $profileCtrService->getCtrByOwner($this->getUser(), $period),
'period' => $period,
]);
} else {
$referer = $request->headers->get('referer');
return $referer ? $this->redirect($request->headers->get('referer')) : $this->redirectToRoute('account');
}
}
#[Route(path: '/rules/', name: 'account.rules')]
public function rules(): Response
{
return $this->render('account/static/rules.html.twig');
}
#[Route(path: '/hide-offer-bar/', name: 'account.offer_bar.hide')]
public function hideOfferBar(EntityManagerInterface $entityManager): Response
{
/** @var User $user */
$user = $this->getUser();
$user->setOfferBarHidden();
$entityManager->flush();
return $this->json(['status' => 1]);
}
private function showDebugData(): bool
{
return $this->kernel->getEnvironment() == 'dev' || $this->kernel->getEnvironment() == 'review';
}
}