<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-03-19
* Time: 22:28
*/
namespace App\Controller;
use App\Bridge\Porpaginas\Doctrine\ORM\FakeORMQueryPage;
use App\Entity\Location\City;
use App\Entity\Location\County;
use App\Entity\Location\District;
use App\Entity\Location\Station;
use App\Entity\Profile\BodyTypes;
use App\Entity\Profile\BreastTypes;
use App\Entity\Profile\Genders;
use App\Entity\Profile\HairColors;
use App\Entity\Profile\Nationalities;
use App\Entity\Profile\PrivateHaircuts;
use App\Entity\Service;
use App\Entity\ServiceGroups;
use App\Entity\TakeOutLocations;
use App\Repository\ServiceRepository;
use App\Repository\StationRepository;
use App\Service\CountryCurrencyResolver;
use App\Service\DefaultCityProvider;
use App\Service\Features;
use App\Service\ListingRotationApi;
use App\Service\ListingService;
use App\Service\ProfileList;
use App\Service\ProfileListingDataCreator;
use App\Service\ProfileListSpecificationService;
use App\Service\ProfileFilterService;
use App\Specification\ElasticSearch\ISpecification;
use App\Specification\Profile\ProfileHasApartments;
use App\Specification\Profile\ProfileHasComments;
use App\Specification\Profile\ProfileHasVideo;
use App\Specification\Profile\ProfileIdIn;
use App\Specification\Profile\ProfileIdINOrderedByINValues;
use App\Specification\Profile\ProfileIdNotIn;
use App\Specification\Profile\ProfileIsApproved;
use App\Specification\Profile\ProfileIsElite;
use App\Specification\Profile\ProfileIsLocated;
use App\Specification\Profile\ProfileIsProvidingOneOfServices;
use App\Specification\Profile\ProfileIsProvidingTakeOut;
use App\Specification\Profile\ProfileWithAge;
use App\Specification\Profile\ProfileWithBodyType;
use App\Specification\Profile\ProfileWithBreastType;
use App\Specification\Profile\ProfileWithHairColor;
use App\Specification\Profile\ProfileWithNationality;
use App\Specification\Profile\ProfileWithApartmentsOneHourPrice;
use App\Specification\Profile\ProfileWithPrivateHaircut;
use Flagception\Bundle\FlagceptionBundle\Annotations\Feature;
use Happyr\DoctrineSpecification\Filter\Filter;
use Happyr\DoctrineSpecification\Logic\OrX;
use Porpaginas\Doctrine\ORM\ORMQueryResult;
use Porpaginas\Page;
use Psr\Cache\CacheItemPoolInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Request;
use Happyr\DoctrineSpecification\Spec;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
#[Cache(maxage: 60, public: true)]
class ProfileListController extends AbstractController
{
use ExtendedPaginationTrait;
use SpecTrait;
use ProfileMinPriceTrait;
use ResponseTrait;
const ENTRIES_ON_PAGE = 36;
const RESULT_SOURCE_COUNTY = 'county';
const RESULT_SOURCE_DISTRICT = 'district';
const RESULT_SOURCE_STATION = 'station';
const RESULT_SOURCE_APPROVED = 'approved';
const RESULT_SOURCE_WITH_COMMENTS = 'with_comments';
const RESULT_SOURCE_WITH_VIDEO = 'with_video';
const RESULT_SOURCE_WITH_SELFIE = 'with_selfie';
const RESULT_SOURCE_ELITE = 'elite';
const RESULT_SOURCE_MASSEURS = 'masseurs';
const RESULT_SOURCE_MASSAGE_SERVICE = 'massage_service';
const RESULT_SOURCE_BY_PARAMS = 'by_params';
const RESULT_SOURCE_SERVICE = 'service';
const RESULT_SOURCE_CITY = 'city';
const RESULT_SOURCE_COUNTRY = 'country';
const CACHE_ITEM_STATION_ADDED_PROFILES = 'station_added_profiles_ids_';
private ?string $source = null;
public function __construct(
private RequestStack $requestStack,
private ProfileList $profileList,
private CountryCurrencyResolver $countryCurrencyResolver,
private ServiceRepository $serviceRepository,
private ListingService $listingService,
private Features $features,
private ProfileFilterService $profilesFilterService,
private ProfileListSpecificationService $profileListSpecificationService,
private ProfileListingDataCreator $profileListingDataCreator,
private CacheItemPoolInterface $stationAddedProfilesCache,
private ParameterBagInterface $parameterBag,
private ListingRotationApi $listingRotationApi,
) {}
/**
* @Feature("has_masseurs")
*/
#[ParamConverter("city", converter: "city_converter")]
public function listForMasseur(City $city, ServiceRepository $serviceRepository): Response
{
$specs = $this->profileListSpecificationService->listForMasseur($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$massageGroupServices = $serviceRepository->findBy(['group' => ServiceGroups::MASSAGE]);
$orX = $this->getORSpecForItemsArray([$massageGroupServices], function($item): ProfileIsProvidingOneOfServices {
return new ProfileIsProvidingOneOfServices($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_MASSAGE_SERVICE);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_MASSEURS,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
public function listByDefaultCity(ParameterBagInterface $parameterBag, Request $request): Response
{
$controller = get_class($this).'::listByCity';
$path = [
'city' => $parameterBag->get('default_city'),
'subRequest' => true,
];
//чтобы в обработчике можно было понять, по какому роуту зашли
$request->request->set('_route', 'profile_list.list_by_city');
return $this->forward($controller, $path);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByCity(ParameterBagInterface $parameterBag, Request $request, City $city, bool $subRequest = false): Response
{
$page = $this->getCurrentPageNumber();
if ($this->features->redirect_default_city_to_homepage() && false === $subRequest && $city->equals($parameterBag->get('default_city')) && $page < 2) {
return $this->redirectToRoute('homepage', [], 301);
}
$specs = $this->profileListSpecificationService->listByCity();
$response = null;
try {
$result = $this->listingRotationApi->paginate(['city' => $city->getId()], $page);
$response = new Response();
$response->setMaxAge(10);
} catch (\Exception) {
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => $specs->recommendationSpec(),
], response: $response);
}
#[ParamConverter("city", converter: "city_converter")]
#[Entity("county", expr:"repository.ofUriIdentityWithinCity(county, city)")]
public function listByCounty(Request $request, City $city, County $county): Response
{
if (!$city->hasCounty($county)) {
throw $this->createNotFoundException();
}
$specs = $this->profileListSpecificationService->listByCounty($county);
$response = null;
try {
$result = $this->listingRotationApi->paginate(['city' => $city->getId(), 'county' => $county->getId()], $this->getCurrentPageNumber());
$response = new Response();
$response->setMaxAge(10);
} catch (\Exception) {
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
}
$prevCount = $result->count();
$result = $this->checkEmptyResultNotMasseur($result, $city, Spec::orX(ProfileIsLocated::withinCounties($city, $city->getCounties()->toArray())), self::RESULT_SOURCE_COUNTY);
if ($result->count() > $prevCount) {
$response?->setMaxAge(60);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_COUNTY,
'county' => $county,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'county' => $county->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
], response: $response);
}
#[ParamConverter("city", converter: "city_converter")]
#[Entity("district", expr:"repository.ofUriIdentityWithinCity(district, city)")]
public function listByDistrict(Request $request, City $city, District $district): Response
{
if (!$city->hasDistrict($district)) {
throw $this->createNotFoundException();
}
$specs = $this->profileListSpecificationService->listByDistrict($district);
$response = null;
try {
$result = $this->listingRotationApi->paginate(['city' => $city->getId(), 'district' => $district->getId()], $this->getCurrentPageNumber());
$response = new Response();
$response->setMaxAge(10);
} catch (\Exception) {
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
}
$prevCount = $result->count();
$result = $this->checkEmptyResultNotMasseur($result, $city, Spec::orX(ProfileIsLocated::withinDistricts($city, $city->getDistricts()->toArray())), self::RESULT_SOURCE_DISTRICT);
if ($result->count() > $prevCount) {
$response?->setMaxAge(60);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_DISTRICT,
'district' => $district,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'district' => $district->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
], response: $response);
}
#[ParamConverter("city", converter: "city_converter")]
#[Entity("station", expr:"repository.ofUriIdentityWithinCity(station, city)")]
public function listByStation(Request $request, City $city, Station $station): Response
{
if (!$city->hasStation($station)) {
throw $this->createNotFoundException();
}
$specs = $this->profileListSpecificationService->listByStation($station);
$response = null;
try {
$result = $this->listingRotationApi->paginate(['city' => $city->getId(), 'station' => $station->getId()], $this->getCurrentPageNumber());
$response = new Response();
$response->setMaxAge(10);
} catch (\Exception) {
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
}
$prevCount = $result->count();
if(true === $this->features->station_page_add_profiles()) {
$spread = $this->parameterBag->get('app.profile.station_page.added_profiles.spread');
$result = $this->addSinglePageStationResults($result, $city, $station, $spread ?: 5);
}
if (null !== $station->getDistrict()) {
$result = $this->checkEmptyResultNotMasseur($result, $city, Spec::orX(ProfileIsLocated::nearStations($city, $station->getDistrict()->getStations()->toArray())), self::RESULT_SOURCE_STATION);
} else {
$result = $this->checkCityAndCountrySource($result, $city);
}
if ($result->count() > $prevCount) {
$response?->setMaxAge(60);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_STATION,
'station' => $station,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'station' => $station->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
], response: $response);
}
private function addSinglePageStationResults(Page $result, City $city, Station $station, int $spread): Page
{
if($result->totalCount() >= $result->getCurrentLimit()) {
return $result;
}
$addedProfileIds = $this->stationAddedProfilesCache->get(self::CACHE_ITEM_STATION_ADDED_PROFILES . $station->getId(), function() use ($result, $city, $station, $spread): array {
$currentSpread = rand(0, $spread);
$plannedTotalCount = $result->getCurrentLimit() - $spread + $currentSpread;
$result = iterator_to_array($result->getIterator());
$originalProfileIds = array_map(fn($item) => $item->id, $result);
if($station->getDistrict()) {
$result = $this->addSinglePageResultsUptoAmount($result, $city, Spec::orX(ProfileIsLocated::withinDistrict($station->getDistrict())), $plannedTotalCount);
}
if($station->getDistrict()?->getCounty()) {
$result = $this->addSinglePageResultsUptoAmount($result, $city, Spec::orX(ProfileIsLocated::withinCounty($station->getDistrict()->getCounty())), $plannedTotalCount);
}
$result = $this->addSinglePageResultsUptoAmount($result, $city, Spec::orX(ProfileIsLocated::withinCity($city)), $plannedTotalCount);
$result = array_map(fn($item) => $item->id, $result);
return array_diff($result, $originalProfileIds);
});
$addedProfileIds = array_slice($addedProfileIds, 0, $result->getCurrentLimit() - $result->totalCount());
$originalProfiles = iterator_to_array($result->getIterator());
$addedProfiles = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacementLimited($city, new ProfileIdIn($addedProfileIds), null, [Genders::FEMALE], count($addedProfileIds));
$newResult = array_merge($originalProfiles, $addedProfiles);
return new FakeORMQueryPage(0, 1, $result->getCurrentLimit(), count($newResult), $newResult);
}
private function addSinglePageResultsUptoAmount(array $result, City $city, ?Filter $specs, int $totalCount): array
{
$toAdd = $totalCount - count($result);
$currentResultIds = array_map(fn($profile) => $profile->id, $result);
$resultsToAdd = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacementLimited($city, $specs, [new ProfileIdNotIn($currentResultIds)], [Genders::FEMALE], $toAdd);
$result = array_merge($result, $resultsToAdd);
return $result;
}
#[ParamConverter("city", converter: "city_converter")]
public function listByStations(City $city, string $stations, StationRepository $stationRepository): Response
{
$stationIds = explode(',', $stations);
$stations = $stationRepository->findBy(['uriIdentity' => $stationIds]);
$specs = $this->profileListSpecificationService->listByStations($stations);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listApproved(Request $request, City $city): Response
{
$specs = $this->profileListSpecificationService->listApproved();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$this->source = self::RESULT_SOURCE_WITH_COMMENTS;
$result = $this->listRandomSinglePage($city, null, new ProfileHasComments(), null, true, false);
if($result->count() == 0) {
$this->source = self::RESULT_SOURCE_WITH_VIDEO;
$result = $this->listRandomSinglePage($city, null, new ProfileHasVideo(), null, true, false);
}
if($result->count() == 0) {
$this->source = self::RESULT_SOURCE_ELITE;
$result = $this->listRandomSinglePage($city, null, $this->getSpecForEliteGirls($city), null, true, null);
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_APPROVED,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listWithComments(Request $request, City $city): Response
{
$specs = $this->profileListSpecificationService->listWithComments();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$this->source = self::RESULT_SOURCE_APPROVED;
$result = $this->listRandomSinglePage($city, null, new ProfileIsApproved(), null, true, false);
if ($result->count() == 0) {
$this->source = self::RESULT_SOURCE_WITH_VIDEO;
$result = $this->listRandomSinglePage($city, null, new ProfileHasVideo(), null, true, false);
}
if ($result->count() == 0) {
$this->source = self::RESULT_SOURCE_ELITE;
$result = $this->listRandomSinglePage($city, null, $this->getSpecForEliteGirls($city), null, true, null);
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_WITH_COMMENTS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listWithVideo(Request $request, City $city): Response
{
$specs = $this->profileListSpecificationService->listWithVideo();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$this->source = self::RESULT_SOURCE_APPROVED;
$result = $this->listRandomSinglePage($city, null, new ProfileIsApproved(), null, true, false);
if($result->count() == 0) {
$this->source = self::RESULT_SOURCE_WITH_COMMENTS;
$result = $this->listRandomSinglePage($city, null, new ProfileHasComments(), null, true, false);
}
if($result->count() == 0) {
$this->source = self::RESULT_SOURCE_ELITE;
$result = $this->listRandomSinglePage($city, null, $this->getSpecForEliteGirls($city), null, true, null);
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_WITH_VIDEO,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listWithSelfie(Request $request, City $city): Response
{
$specs = $this->profileListSpecificationService->listWithSelfie();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$this->source = self::RESULT_SOURCE_WITH_VIDEO;
$result = $this->listRandomSinglePage($city, null, new ProfileHasVideo(), null, true, false);
if ($result->count() == 0) {
$this->source = self::RESULT_SOURCE_APPROVED;
$result = $this->listRandomSinglePage($city, null, new ProfileIsApproved(), null, true, false);
}
if ($result->count() == 0) {
$this->source = self::RESULT_SOURCE_ELITE;
$result = $this->listRandomSinglePage($city, null, $this->getSpecForEliteGirls($city), null, true, null);
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_WITH_SELFIE,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByPrice(Request $request, CountryCurrencyResolver $countryCurrencyResolver, City $city, string $priceType, int $minPrice = null, int $maxPrice = null): Response
{
$specs = $this->profileListSpecificationService->listByPrice($city, $priceType, $minPrice, $maxPrice);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$result = $this->processListByPriceEmptyResult($result, $city, $priceType, $minPrice, $maxPrice);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'priceType' => $priceType,
'minPrice' => $minPrice,
'maxPrice' => $maxPrice,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
private function processListByPriceEmptyResult(Page $result, City $city, string $priceType, int $minPrice = null, int $maxPrice = null)
{
if(!$this->features->fill_empty_profile_list())
return $result;
$this->source = self::RESULT_SOURCE_BY_PARAMS;
if($this->countryCurrencyResolver->getCurrencyFor($city->getCountryCode()) == 'RUB') {
if ($minPrice && $maxPrice) {
if ($minPrice == 2000 && $maxPrice == 3000) {
$priceSpec = [
ProfileWithApartmentsOneHourPrice::range(1500, 2000),
ProfileWithApartmentsOneHourPrice::range(3000, 4000),
];
} else if ($minPrice == 3000 && $maxPrice == 4000) {
$priceSpec = [
ProfileWithApartmentsOneHourPrice::range(2000, 3000),
ProfileWithApartmentsOneHourPrice::range(4000, 5000),
];
} else if ($minPrice == 4000 && $maxPrice == 5000) {
$priceSpec = [
ProfileWithApartmentsOneHourPrice::range(3000, 4000),
ProfileWithApartmentsOneHourPrice::range(5000, 6000),
];
} else if ($minPrice == 5000 && $maxPrice == 6000) {
$priceSpec = [
ProfileWithApartmentsOneHourPrice::range(4000, 999999)
];
} else {
$priceSpec = [
ProfileWithApartmentsOneHourPrice::range($minPrice, $maxPrice)
];
}
$result = $this->listRandomSinglePage($city, null, null, $priceSpec, true, false);
} elseif ($maxPrice) {
if ($maxPrice == 500) {
$priceSpec = ProfileWithApartmentsOneHourPrice::cheaperThan(1500);
$result = $this->listRandomSinglePage($city, null, $priceSpec, null, true, false);
if ($result->count() == 0) {
$priceSpec = ProfileWithApartmentsOneHourPrice::range(1500, 2000);
$result = $this->listRandomSinglePage($city, null, $priceSpec, null, true, false);
}
} else if ($maxPrice == 1500) {
$priceSpec = ProfileWithApartmentsOneHourPrice::range(1500, 2000);
$result = $this->listRandomSinglePage($city, null, $priceSpec, null, true, false);
if ($result->count() == 0) {
$priceSpec = ProfileWithApartmentsOneHourPrice::range(2000, 3000);
$result = $this->listRandomSinglePage($city, null, $priceSpec, null, true, false);
}
}
} else {
switch ($priceType) {
case 'not_expensive':
$priceSpec = ProfileWithApartmentsOneHourPrice::cheaperThan(2000);
break;
case 'high':
$priceSpec = ProfileWithApartmentsOneHourPrice::range(3000, 6000);
break;
case 'low':
$priceSpec = ProfileWithApartmentsOneHourPrice::cheaperThan(2000);
break;
case 'elite':
$priceSpec = ProfileWithApartmentsOneHourPrice::moreExpensiveThan(6000);
break;
default:
throw new \LogicException('Unknown price type');
break;
}
$result = $this->listRandomSinglePage($city, null, $priceSpec, null, true, false);
}
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $result;
}
#[ParamConverter("city", converter: "city_converter")]
public function listByAge(Request $request, City $city, string $ageType, int $minAge = null, int $maxAge = null): Response
{
$specs = $this->profileListSpecificationService->listByAge($ageType, $minAge, $maxAge);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$filled = $this->processListByAgeEmptyResult($result, $city, $ageType, $minAge, $maxAge);
if($filled)
$result = $filled;
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'ageType' => $ageType,
'minAge' => $minAge,
'maxAge' => $maxAge,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
private function processListByAgeEmptyResult(Page $result, City $city, string $ageType, int $minAge = null, int $maxAge = null)
{
if(!$this->features->fill_empty_profile_list())
return $result;
$this->source = self::RESULT_SOURCE_BY_PARAMS;
if ($minAge && !$maxAge) {
$startMinAge = $minAge;
do {
$startMinAge -= 2;
$ageSpec = ProfileWithAge::olderThan($startMinAge);
$result = $this->listRandomSinglePage($city, null, $ageSpec, null, true, false);
} while($result->count() == 0 && $startMinAge >= 18);
} else if($ageType == 'young') {
$startMaxAge = 20;
do {
$startMaxAge += 2;
$ageSpec = ProfileWithAge::youngerThan($startMaxAge);
$result = $this->listRandomSinglePage($city, null, $ageSpec, null, true, false);
} while($result->count() == 0 && $startMaxAge <= 100);
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $result;
}
#[ParamConverter("city", converter: "city_converter")]
public function listByHeight(Request $request, City $city, string $heightType): Response
{
$specs = $this->profileListSpecificationService->listByHeight($heightType);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'heightType' => $heightType,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByBreastType(Request $request, City $city, string $breastType): Response
{
if(null === BreastTypes::getValueByUriIdentity($breastType))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByBreastType($breastType);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(BreastTypes::getList(), function($item): ProfileWithBreastType {
return new ProfileWithBreastType($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'breastType' => $breastType,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByHairColor(Request $request, City $city, string $hairColor): Response
{
if(null === HairColors::getValueByUriIdentity($hairColor))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByHairColor($hairColor);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(HairColors::getList(), function($item): ProfileWithHairColor {
return new ProfileWithHairColor($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'hairColor' => $hairColor,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByBodyType(Request $request, City $city, string $bodyType): Response
{
if(null === BodyTypes::getValueByUriIdentity($bodyType))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByBodyType($bodyType);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(BodyTypes::getList(), function($item): ProfileWithBodyType {
return new ProfileWithBodyType($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'bodyType' => $bodyType,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByPlace(Request $request, City $city, string $placeType, string $takeOutLocation = null): Response
{
$specs = $this->profileListSpecificationService->listByPlace($placeType, $takeOutLocation);
if(null === $specs)
throw $this->createNotFoundException();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(TakeOutLocations::getList(), function($item): ProfileIsProvidingTakeOut {
return new ProfileIsProvidingTakeOut($item);
});
if($placeType == 'take-out')
$orX->orX(new ProfileHasApartments());
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'placeType' => $placeType,
'takeOutLocation' => TakeOutLocations::getUriIdentity(TakeOutLocations::getValueByUriIdentity($takeOutLocation)),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByPrivateHaircut(Request $request, City $city, string $privateHaircut): Response
{
if(null === PrivateHaircuts::getValueByUriIdentity($privateHaircut))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByPrivateHaircut($privateHaircut);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(PrivateHaircuts::getList(), function($item): ProfileWithPrivateHaircut {
return new ProfileWithPrivateHaircut($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'privateHaircut' => $privateHaircut,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByNationality(Request $request, City $city, string $nationality): Response
{
if(null === Nationalities::getValueByUriIdentity($nationality))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByNationality($nationality);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$orX = $this->getORSpecForItemsArray(Nationalities::getList(), function($item): ProfileWithNationality {
return new ProfileWithNationality($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_BY_PARAMS);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'nationality' => $nationality,
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
#[ParamConverter("service", options: ['mapping' => ['service' => 'uriIdentity']])]
public function listByProvidedService(Request $request, City $city, Service $service): Response
{
$specs = $this->profileListSpecificationService->listByProvidedService($service, $city);
$response = null;
try {
$result = $this->listingRotationApi->paginate(['city' => $city->getId(), 'service' => $service->getId()], $this->getCurrentPageNumber());
$response = new Response();
$response->setMaxAge(10);
} catch (\Exception) {
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
}
$prevCount = $result->count();
$sameGroupServices = $this->serviceRepository->findBy(['group' => $service->getGroup()]);
$orX = $this->getORSpecForItemsArray([$sameGroupServices], function($item): ProfileIsProvidingOneOfServices {
return new ProfileIsProvidingOneOfServices($item);
});
$result = $this->checkEmptyResultNotMasseur($result, $city, $orX, self::RESULT_SOURCE_SERVICE);
if ($result->count() > $prevCount) {
$response?->setMaxAge(60);
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_SERVICE,
'service' => $service,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'service' => $service->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
], response: $response);
}
/**
* @Feature("has_archive_page")
*/
#[ParamConverter("city", converter: "city_converter")]
public function listArchived(Request $request, City $city): Response
{
$result = $this->profileList->list($city, null, null, null, false, null, ProfileList::ORDER_BY_UPDATED);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => new \App\Specification\ElasticSearch\ProfileIsNotArchived(), //ProfileIsArchived, согласно https://redminez.net/issues/28305 в реках выводятся неарзивные
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listNew(City $city, int $weeks = 2): Response
{
$specs = $this->profileListSpecificationService->listNew($weeks);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByNoRetouch(City $city): Response
{
$specs = $this->profileListSpecificationService->listByNoRetouch();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByNice(City $city): Response
{
$specs = $this->profileListSpecificationService->listByNice();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByOnCall(City $city): Response
{
$specs = $this->profileListSpecificationService->listByOnCall();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForHour(City $city): Response
{
$specs = $this->profileListSpecificationService->listForHour();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForNight(City $city): Response
{
$specs = $this->profileListSpecificationService->listForNight();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
private function getSpecForEliteGirls(City $city):Filter
{
$minPrice = $this->countryCurrencyResolver->getValueByCountryCode($city->getCountryCode(), [
'RUB' => 5000,
'UAH' => 1500,
'USD' => 100,
'EUR' => 130,
]);
return new ProfileIsElite($minPrice);
}
private function getElasticSearchSpecForEliteGirls(City $city): ISpecification
{
$minPrice = $this->countryCurrencyResolver->getValueByCountryCode($city->getCountryCode(), [
'RUB' => 5000,
'UAH' => 1500,
'USD' => 100,
'EUR' => 130,
]);
return new \App\Specification\ElasticSearch\ProfileIsElite($minPrice);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForEliteGirls(CountryCurrencyResolver $countryCurrencyResolver, Request $request, City $city): Response
{
$specs = $this->profileListSpecificationService->listForEliteGirls($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
if($this->features->fill_empty_profile_list() && $result->count() == 0) {
$prices = [
'RUB' => 5000,
'UAH' => 1500,
'USD' => 100,
'EUR' => 130,
];
$currency = $countryCurrencyResolver->getCurrencyFor($city->getCountryCode());
if(isset($prices[$currency])) {
$minPrice = $prices[$currency];
switch ($currency) {
case 'RUB': $diff = 1000; break;
case 'UAH': $diff = 500; break;
case 'USD':
case 'EUR': $diff = 20; break;
default:
throw new \LogicException('Unexpected currency code');
}
while ($minPrice >= $diff) {
$minPrice -= $diff;
$result = $this->listRandomSinglePage($city, null, ProfileWithApartmentsOneHourPrice::moreExpensiveThan($minPrice), null, true, false);
if ($result->count() > 0) {
$this->source = self::RESULT_SOURCE_BY_PARAMS;
break;
}
}
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
}
}
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'source_default' => self::RESULT_SOURCE_BY_PARAMS,
'category_url' => $this->generateUrl($request->attributes->get('_route'), [
'city' => $city->getUriIdentity(),
'page' => $this->getCurrentPageNumber()
]),
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForRealElite(CountryCurrencyResolver $countryCurrencyResolver, City $city): Response
{
$specs = $this->profileListSpecificationService->listForRealElite($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForVipPros(CountryCurrencyResolver $countryCurrencyResolver, City $city): Response
{
$specs = $this->profileListSpecificationService->listForVipPros($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForVipIndividual(CountryCurrencyResolver $countryCurrencyResolver, City $city): Response
{
$specs = $this->profileListSpecificationService->listForVipIndividual($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listForVipGirlsCity(City $city): Response
{
$specs = $this->profileListSpecificationService->listForVipGirlsCity($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listOfGirlfriends(City $city): Response
{
$specs = $this->profileListSpecificationService->listOfGirlfriends();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listOfMostExpensive(City $city): Response
{
$specs = $this->profileListSpecificationService->listOfMostExpensive($city);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec());
$result = $this->checkEmptyResultNotMasseur($result, $city, null, self::RESULT_SOURCE_CITY);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'source' => $this->source,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listBdsm(City $city, ServiceRepository $serviceRepository, ParameterBagInterface $parameterBag): Response
{
$specs = $this->profileListSpecificationService->listBdsm();
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec(), $specs->additionalSpecs());
$bdsmIds = $serviceRepository->findBy(['group' => ServiceGroups::BDSM]);
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
#[ParamConverter("city", converter: "city_converter")]
public function listByGender(City $city, string $gender, DefaultCityProvider $defaultCityProvider): Response
{
if($city->getId() != $defaultCityProvider->getDefaultCity()->getId()) {
throw $this->createNotFoundException();
}
if(null === Genders::getValueByUriIdentity($gender))
throw $this->createNotFoundException();
$specs = $this->profileListSpecificationService->listByGender($gender);
$result = $this->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec(), $specs->additionalSpecs(), $specs->genders());
return $this->render('ProfileList/list.html.twig', [
'profiles' => $result,
'recommendationSpec' => $specs->recommendationSpec(),
]);
}
protected function checkCityAndCountrySource(Page $result, City $city): Page
{
if(($result && $result->count() != 0) || false == $this->features->fill_empty_profile_list())
return $result;
$this->source = self::RESULT_SOURCE_CITY;
$result = $this->listRandomSinglePage($city, null, null, null, true, false);
if($result->count() == 0) {
$this->source = self::RESULT_SOURCE_COUNTRY;
$result = $this->listRandomSinglePage($city, $city->getCountryCode(), null, null, true, false);
}
return $result;
}
protected function checkEmptyResultNotMasseur(Page $result, City $city, ?OrX $alternativeSpec, string $source): Page
{
if($result->count() != 0 || false == $this->features->fill_empty_profile_list())
return $result;
if(null != $alternativeSpec) {
$this->source = $source;
$result = $this->listRandomSinglePage($city, null, $alternativeSpec, null, true, false);
}
if($result->count() == 0)
$result = $this->checkCityAndCountrySource($result, $city);
return $result;
}
/**
* Сейчас не используется, решили доставать их всех соседних подкатегорий разом.
* Пока оставил, вдруг передумают.
* @deprecated
*/
public function listByNextSimilarCategories(callable $listMethod, $requestCategory, array $similarItems): ORMQueryResult
{
$similarItems = array_filter($similarItems, function($item) use ($requestCategory): bool {
return $item != $requestCategory;
});
//shuffle($similarItems);
$item = null; $result = null;
do {
$item = $item == null ? current($similarItems) : next($similarItems);
if(false === $item)
return $result;
$result = $listMethod($item);
} while($result->count() == 0);
return $result;
}
protected function getCurrentPageNumber(): int
{
$page = (int) $this->requestStack->getCurrentRequest()?->get($this->pageParameter, 1);
if ($page < 1) {
$page = 1;
}
return $page;
}
protected function render(string $view, array $parameters = [], Response $response = null): Response
{
$this->listingService->setCurrentListingPage($parameters['profiles']);
$requestAttrs = $this->requestStack->getCurrentRequest();
$listing = $requestAttrs->get('_controller');
$listing = is_array($listing) ? $listing[count($listing) - 1] : $listing;
$listing = preg_replace('/[^:]+::/', '', $listing);
$listingParameters = $requestAttrs->get('_route_params');
$listingParameters = is_array($listingParameters) ? $listingParameters : [];
$mainRequestHasPageParam = isset(($this->requestStack->getMainRequest()->get('_route_params') ?? [])['page']);
if($this->requestStack->getCurrentRequest()->isXmlHttpRequest()) {
$view = (
str_starts_with($listing, 'list')
&& 'ProfileList/list.html.twig' === $view
&& $mainRequestHasPageParam //isset($listingParameters['page'])
)
? 'ProfileList/list.profiles.html.twig'
: $view
;
return $this->prepareForXhr(parent::render($view, $parameters, $response));
//return $this->getJSONResponse($parameters);
} else {
$parameters = array_merge($parameters, [
'listing' => $listing,
'listing_parameters' => $listingParameters,
]);
return parent::render($view, $parameters, $response);
}
}
private function listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement(
City $city, ?Filter $spec, array $additionalSpecs = null, array $genders = [Genders::FEMALE]
): array|Page
{
return $this->profileList->listActiveWithinCityOrderedByStatusWithSpec($city, $spec, $additionalSpecs, $genders, $this->getCurrentPageNumber() < 2);
}
private function listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacementLimited(
City $city, ?Filter $spec, array $additionalSpecs = null, array $genders = [Genders::FEMALE], int $limit = 0,
): array|Page
{
return $this->profileList->listActiveWithinCityOrderedByStatusWithSpecLimited($city, $spec, $additionalSpecs, $genders, true, $limit);
}
private function listRandomSinglePage(
City $city, ?string $country, ?Filter $spec, ?array $additionalSpecs, bool $active, ?bool $masseur = false,
array $genders = [Genders::FEMALE]
): Page
{
return $this->profileList->listRandom($city, $country, $spec, $additionalSpecs, $active, $masseur, $genders, true);
}
// protected function getJSONResponse(array $parameters)
// {
// $request = $this->request;
// $data = json_decode($request->getContent(), true);
//
// $imageSize = !empty($data['imageSize']) ? $data['imageSize'] : "357x500";
//
// /** @var FakeORMQueryPage $queryPage */
// $queryPage = $parameters['profiles'];
//
// $profiles = array_map(function(ProfileListingReadModel $profile) use ($imageSize) {
// $profile->stations = array_values($profile->stations);
// $profile->avatar['path'] = $this->responsiveAssetsService->getResponsiveImageUrl($profile->avatar['path'], 'profile_media', $imageSize, 'jpg');
// $profile->uri = $this->generateUrl('profile_preview.page', ['city' => $profile->city->uriIdentity, 'profile' => $profile->uriIdentity]);
// return $profile;
// }, $queryPage->getArray());
//
// return new JsonResponse([
// 'profiles' => $profiles,
// 'currentPage' => $queryPage->getCurrentPage(),
// ], Response::HTTP_OK);
// }
}