<?php
namespace App\Service;
use App\Bridge\Porpaginas\Doctrine\ORM\FakeORMQueryPage;
use App\Entity\Location\City;
use App\Form\SearchByKeywordsForm;
use App\Repository\ProfileRepository;
use App\Repository\SearchByKeywordsESRepository;
use App\Specification\Profile\ProfileIdINOrderedByINValues;
use Porpaginas\Page;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class SearchByKeywordsService
{
private ?Request $request;
private int $perPage;
public function __construct(
RequestStack $requestStack,
ParameterBagInterface $parameterBag,
private SearchByKeywordsESRepository $searchByKeywordsESRepository,
private FormFactoryInterface $formFactory,
private UrlGeneratorInterface $urlGenerator,
private DefaultCityProvider $defaultCityProvider,
private PhoneNumberService $phoneNumberService,
private ProfileRepository $profileRepository
)
{
$this->request = $requestStack->getCurrentRequest();
$this->perPage = $parameterBag->get('search_profiles_by_keywords.per_page');
}
public function searchByKeywords(City $city, string $keywords): Page
{
$keywords = preg_replace("/[^\w0-9 -\(\)\+]/u", "", $keywords);
$keywords = preg_replace_callback('/\+?[\d\s\)\(\-]{5,25}/', function($matches) use ($city): string {
// return ' '.str_replace(['-','+7'], ['', ''], $this->phoneNumberService->getInternationalNumber(trim($matches[0]), $city)).' ';
return ' '.$this->phoneNumberService->getInternationalNumber(trim($matches[0]), $city).' ';
}, $keywords);
$profileIds = $this->searchByKeywordsESRepository->searchProfileIdsByKeywords($city, $keywords, $this->getOffset(), $this->perPage);
$profiles = !empty($profileIds) ? $this->profileRepository->fetchListingByIds(new ProfileIdINOrderedByINValues($profileIds)) : [];
return $this->takeFakePage($this->searchByKeywordsESRepository->getTotal(), $profiles);
}
protected function getPage(): int
{
$page = (int)$this->request->get('page');
if ($page < 1)
$page = 1;
return $page;
}
protected function getOffset(): int|float
{
return ($this->getPage() - 1) * $this->perPage;
}
protected function takeFakePage(int $totalResults, array $profiles): Page
{
$pageCount = ceil($totalResults / $this->perPage);
if($pageCount > 0 && $this->getPage() > $pageCount)
throw new NotFoundHttpException('Wrong page number');
return new FakeORMQueryPage($this->getOffset(), $this->getPage(), $this->perPage, $totalResults, $profiles);
}
public function getLastQuery(): ?array
{
return $this->searchByKeywordsESRepository->getLastQuery();
}
public function getScores(): array
{
return $this->searchByKeywordsESRepository->getScores();
}
public function getSearchByKeywordsForm(): FormInterface
{
$city = $this->request->attributes->get('city');
if (null === $city) {
$city = $this->defaultCityProvider->getDefaultCity();
}
$form = $this->formFactory->create(SearchByKeywordsForm::class, null, [
'action' => $this->urlGenerator->generate('search_by_keywords.page', ['city' => $city->getUriIdentity()]),
'csrf_protection' => false,
]);
return $form;
}
}