<?php
namespace Aviatur\SearchBundle\Controller;
use Aviatur\SearchBundle\Entity\SearchHeliports;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Doctrine\Persistence\ManagerRegistry;
use Aviatur\SearchBundle\Controller\TravelDestinationController;
use Aviatur\SearchBundle\Entity\TravelDestination;
class SearchController extends AbstractController {
function Slug($string) {
return mb_strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
}
public function citiesAutocompleteAction(Request $request, ManagerRegistry $registry, $type) {
if ($request->isXmlHttpRequest()) {
$term = $this->Slug($request->query->get('term'));
$json_template = '<value>:<label>:<countrycode>-';
$em = $registry->getManager();
$jsonArray = [];
if ($type != "cars") {
$cities = $em->getRepository(\Aviatur\SearchBundle\Entity\SearchCities::class)->findByOrWithSingleValue(["iata", "city"], $term);
if ($cities) {
$jsonArray['cities'] = '';
foreach ($cities as $city) {
$jsonArray['cities'] .= str_replace(['<value>', '<label>', '<countrycode>'], [$city['iata'], $city['city'] . ', ' . $city['country'], $city['countrycode']], $json_template);
}
$jsonArray['cities'] = \rtrim($jsonArray['cities'], '-');
} else {
$jsonArray['cities'] = 'NN:No hay Resultados';
}
}
if (($type != "hotels") || ($type == "cars")) {
$airports = $em->getRepository(\Aviatur\SearchBundle\Entity\SearchAirports::class)->findByOrWithSingleValue(["search"], $this->unaccent($term));
if ($airports) {
$jsonArray['airports'] = '';
foreach ($airports as $airport) {
$jsonArray['airports'] .= str_replace(['<value>', '<label>', '<countrycode>'], [$airport['iata'], $airport['name'] . ', ' . $airport['city'] . ', ' . $airport['country'], $airport['countrycode']], $json_template);
}
} else {
$jsonArray['airports'] = 'NN:No hay Resultados';
}
}
$json = implode(';', $jsonArray);
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
public function countryAction(Request $request, ManagerRegistry $registry) {
if ($request->isXmlHttpRequest()) {
$term = $this->Slug($request->query->get('term'));
$json_template = '<value>:<label>-';
$em = $registry->getManager();
$countries = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findByOrWithSingleValue(["iatacode", "description"], $term);
$json = '';
if ($countries) {
foreach ($countries as $country) {
$json .= str_replace(['<value>', '<label>'], [$country['iata'], ucwords(mb_strtolower($country['description']))], $json_template);
}
} else {
$json = 'NN:No hay Resultados';
}
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
public function airlinesAction(Request $request, ManagerRegistry $registry) {
if ($request->isXmlHttpRequest()) {
$term = $this->Slug($request->query->get('term'));
$json_template = '<value>:<label>-';
$em = $registry->getManager();
$airlines = $em->getRepository(\Aviatur\FlightBundle\Entity\Airline::class)->findByOrWithSingleValue(["iata", "name"], $term);
$uniqueIata = [];
$uniqueNames = [];
$filteredAirlines = array_filter($airlines, function($airline) use (&$uniqueIata, &$uniqueNames) {
$iata = $airline['iata'];
$name = trim($airline['name']); // Elimina espacios extra
if (in_array($iata, $uniqueIata) || in_array($name, $uniqueNames)) {
return false; // Si ya existe en iata o en name, se ignora
}
$uniqueIata[] = $iata;
$uniqueNames[] = $name;
return true;
});
// Convertir a array indexado
$airlines = array_values($filteredAirlines);
$json = '';
if ($airlines) {
foreach ($airlines as $airline) {
$json .= str_replace(['<value>', '<label>'], [$airline['iata'], ucwords(mb_strtolower($airline['name']))], $json_template);
}
} else {
$json = 'NN:No hay Resultados';
}
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
public function heliportsAction(Request $request, ManagerRegistry $registry) {
if ($request->isXmlHttpRequest()) {
$term = $this->Slug($request->query->get('term'));
$json_template = '<value>:<label>-';
$em = $registry->getManager();
$heliports = $em->getRepository(SearchHeliports::class)->findByOrWithSingleValue(["iata", "name", "city"], $term);
$json = '';
if ($heliports) {
foreach ($heliports as $heliport) {
$json .= str_replace(['<value>', '<label>'], [$heliport['iata'], ucwords(mb_strtolower($heliport['name'])) . ', ' . $heliport['city'] . ', ' . $heliport['country']], $json_template);
}
} else {
$json = 'NN:No hay Resultados';
}
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
public function trainStationsAction(Request $request, ManagerRegistry $registry) {
if ($request->isXmlHttpRequest()) {
$term = $this->Slug($request->query->get('term'));
$json_template = '<value>:<label>:<type>-';
$em = $registry->getManager();
$trainStations = $em->getRepository(\Aviatur\TrainBundle\Entity\TrainStation::class)->searchStation($term);
$json = '';
if ($trainStations) {
foreach ($trainStations as $station) {
$nameStation = ($station['namestationes'] != null && $station['namestationes'] != "") ? $station['namestationes'] : $station['namestation'];
$json .= str_replace(['<value>', '<label>', '<type>'], [$station['id'], ucwords(mb_strtolower($nameStation)), $station['type']], $json_template);
}
} else {
$json = 'NN:No hay Resultados';
}
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
public function terminalsAction(Request $request, ManagerRegistry $registry) {
$fullRequest = $request;
if ($fullRequest->isXmlHttpRequest()) {
$json_template = '<value>:<label>-';
$em = $registry->getManager();
$json = '';
$term = $this->Slug($fullRequest->query->get('term'));
if ($fullRequest->query->has('origin')) {
$origin = $this->Slug($fullRequest->query->get('origin'));
$terminals = $em->getRepository(\Aviatur\BusBundle\Entity\Terminal::class)->findDestinationByOrigin(["name", "city", "state"], $term, $origin);
} else {
$terminals = $em->getRepository(\Aviatur\BusBundle\Entity\Terminal::class)->findByOrWithSingleValue(["name", "city", "state"], $term);
}
if ($terminals) {
foreach ($terminals as $terminal) {
$terminalLabel = ($terminal['state']) ? $terminal['name'] . ', ' . $terminal['state'] : $terminal['name'];
$json .= str_replace(['<value>', '<label>'], [$terminal['pinbusid'], $terminalLabel], $json_template);
}
} else {
$json = 'NN:No hay Resultados';
}
$response = \rtrim($json, '-');
return new Response($response);
} else {
return new Response('Acceso Restringido');
}
}
private function unaccent($string) {
return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8'));
}
public static function autocompleteOnCitySearch(Request $request, ManagerRegistry $registry, $type) {
try {
$em = $registry->getManager();
$searchParameters = json_decode($request->getContent(), true);
$searchQuery = $searchParameters["city"];
$fetchMore = $searchParameters["fetch_more"] ?? false;
$dbTravelDestinationCounter = $em->getRepository(TravelDestination::class)->countTravelDestinationResults($searchQuery);
$limitResults = 7;
if($fetchMore === true){
$limitResults = 20;
}
if (empty($searchQuery)) {
return new JsonResponse(
[
"results" => [],
"status" => [
"message" => "Error: Ciudad obligatoria",
"code" => 503
]
],
Response::HTTP_BAD_REQUEST
);
}
if($dbTravelDestinationCounter >= $limitResults){
$getFromSource = 'DATABASE';
}else{
$getFromSource = "API";
}
switch ($getFromSource) {
case 'API':
$apiResponse = TravelDestinationController::fetchAndStoreApiCities($registry, $searchQuery, $limitResults);
return new JsonResponse(
$apiResponse,
Response::HTTP_OK,
);
break;
case 'DATABASE':
$citiesFromTravelDestinations = TravelDestinationController::getCitiesFromTravelDestinations($registry, $searchQuery, $limitResults);
return new JsonResponse(
$citiesFromTravelDestinations,
Response::HTTP_OK,
);
break;
default:
return new JsonResponse(
[
"results" => [],
"status" => [
"message" => "Error: Fuente inválida",
"code" => 503
]
],
Response::HTTP_BAD_REQUEST
);
}
} catch (\Throwable $th) {
$response = array(
"results" => [],
"status" => array(
//"error" => $th->getMessage(). " - " . $th->getLine(),
"message" => "Error: buscar ciudades",
"code" => 503
)
);
return new Response(
$response,
Response::HTTP_SERVICE_UNAVAILABLE,
['Content-Type' => 'application/json']
);
}
}
}