<?php
namespace App\Controller;
use App\Dto\ProfileFilterFormData;
use App\Dto\ProfileFilterFormDataFilters;
use App\Dto\ProfileListSpecification;
use App\Entity\Location\City;
use App\Form\ProfileFilterForm;
use App\Service\ProfileList;
use App\Service\ProfileListingDataCreator;
use App\Service\ProfileFilterService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ProfileFilterController extends AbstractController
{
use ResponseTrait;
public function __construct(
private ProfileListingDataCreator $profileListingDataCreator,
private ProfileFilterService $profilesFilterService,
private ProfileList $profileList,
) {}
#[ParamConverter("city", converter: "city_converter")]
public function form(City $city, Request $request): Response
{
if(!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
$listing = $request->request->get('listing');
$listingParameters = json_decode($request->request->get('listingParams'), true);
$formData = new ProfileFilterFormData($listing, $listingParameters, new ProfileFilterFormDataFilters());
$listingData = $this->profileListingDataCreator->getListingDataForFilter($listing, $listingParameters, $city);
/** @var ProfileListSpecification $specs */
$specs = $listingData['specs'];
//холостой вызов, чтобы сформировался запрос и записался в свойство ProfileList
$this->profileList->listActiveWithinCityOrderedByStatusWithSpecAvoidingTopPlacement($city, $specs->spec(), $specs->additionalSpecs(), $specs->genders());
$this->profilesFilterService->checkProfilesPresenceByFilters($city, $listingData['listingTypeName']);
$profilePresenceByFilters = $this->profilesFilterService->profilesPresenceByFilters();
$form = $this->createForm(ProfileFilterForm::class, $formData, [
'action' => $this->generateUrl('profile_filters.filter', ['city' => $city->getUriIdentity()]),
'csrf_protection' => false,
'form_data' => $formData,
'profiles_presence_by_filters' => $profilePresenceByFilters,
]);
return $this->prepareForXhr($this->render('ProfileList/filter/form.html.twig', [
'profiles_presence_by_filters' => $profilePresenceByFilters,
'profile_filter_form' => $form->createView(),
]));
}
#[ParamConverter("city", converter: "city_converter")]
public function filter(City $city, Request $request, ProfileFilterService $profilesFilterService): Response
{
if(!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
$form = $this->createForm(ProfileFilterForm::class, new ProfileFilterFormData('', [], new ProfileFilterFormDataFilters()), [
'action' => $this->generateUrl('profile_filters.filter', ['city' => $city->getUriIdentity()]),
'csrf_protection' => false,
]);
$form->handleRequest($request);
if (false === $form->isSubmitted() || false === $form->isValid()) {
throw new BadRequestHttpException('Form is not submitted');
}
/** @var ProfileFilterFormData $formData */
$formData = $form->getData();
// $specs = $this->profileListSpecificationService->{$listingType}(...$listingArgs);
$listingData = $this->profileListingDataCreator->getListingDataForFilter($formData->listing, $formData->listingParameters, $city);
$specs = $listingData['specs'];
$listingTypeName = $listingData['listingTypeName'];
$result = $profilesFilterService->filter($city, $listingTypeName, $formData->filters, $specs->spec(), $specs->additionalSpecs(), $specs->genders());
$presence = $profilesFilterService->profilesPresenceByFilters();
$form = $this->createForm(ProfileFilterForm::class, $formData, [
'action' => $this->generateUrl('profile_filters.filter', ['city' => $city->getUriIdentity()]),
'csrf_protection' => false,
'form_data' => $formData,
'profiles_presence_by_filters' => $presence,
]);
return $this->prepareForXhr($this->render('ProfileList/profile_filter.profiles.partial.html.twig', [
'profiles' => $result,
'recommendationSpec' => \App\Specification\ElasticSearch\ProfileIsLocated::withinCity($city),
'show_pagination' => true,
'profiles_presence_by_filters' => $presence,
'profile_filter_form' => $form->createView(),
]));
}
}