<?php
declare(strict_types=1);
namespace ApiBundle\Controller;
use AppBundle\Repository\PharmacyCityRepository;
use AppBundle\Tool\StringTools;
use OpenApi\Attributes as OA;
use Pimcore\Model\DataObject\PharmacyCity;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class CityController extends ApiController
{
public const CITIES_LIMIT = 10;
private PharmacyCityRepository $repository;
public function __construct(string $apiKey, PharmacyCityRepository $repository)
{
parent::__construct($apiKey);
$this->repository = $repository;
}
#[Route('/api/cities/search', name: 'api_cities_search', methods: ['GET'])]
#[OA\Get(path: '/api/cities/search', description: "Endpoint wyszukuje miasta na podstawie przesłanej frazy query param 'q'. Zwraca listę pasujących miast jako tablicę obiektów z polami id, name i province.", summary: 'Wyszukaj miasta po frazie', tags: ['Cities'])]
#[OA\Parameter(name: 'X-API-KEY', description: 'Klucz API wymagany do autoryzacji', in: 'header', required: true, schema: new OA\Schema(type: 'string', example: 'your-api-key'))]
#[OA\Parameter(name: 'q', description: 'Fraza do wyszukania miasta', in: 'query', required: true, schema: new OA\Schema(type: 'string', example: 'Warsz'))]
#[OA\Parameter(name: 'limit', description: 'Limit zwracanych miast', in: 'query', schema: new OA\Schema(type: 'integer', default: 10, example: 10))]
#[OA\Response(
response: 200,
description: 'Lista pasujących miast',
content: new OA\JsonContent(
properties: [
new OA\Property(property: 'success', type: 'boolean', example: true),
new OA\Property(
property: 'data',
type: 'array',
items: new OA\Items(
properties: [
new OA\Property(property: 'id', type: 'integer', example: 1),
new OA\Property(property: 'name', type: 'string', example: 'Warszawa'),
new OA\Property(property: 'province', type: 'string', example: 'mazowieckie'),
new OA\Property(
property: 'gpsPoint',
properties: [
new OA\Property(property: 'lat', type: 'number', format: 'float', example: 50.06143),
new OA\Property(property: 'lon', type: 'number', format: 'float', example: 19.93658),
],
type: 'object',
),
],
type: 'object',
),
),
],
type: 'object',
),
)]
public function search(Request $request): JsonResponse
{
if (!$this->validateApiKey($request)) {
return $this->returnInvalidApiKeyError();
}
$query = $request->query->get('q');
$limit = (int) $request->query->get('limit');
if ($limit < 1) {
$limit = self::CITIES_LIMIT;
}
$querySlug = StringTools::prepareCityNameSlug($query);
$data = [];
foreach ($this->repository->getBySlugPart($querySlug, $limit) as $city) {
/** @var PharmacyCity $city */
$data[] = [
'id' => $city->getId(),
'name' => $city->getCityName(),
'province' => (null !== $city->getProvince()) ? $city->getProvince()->getName() : '',
'gpsPoint' => [
'lat' => (null !== $city->getCoordinates()) ? $city->getCoordinates()->getLatitude() : '',
'lng' => (null !== $city->getCoordinates()) ? $city->getCoordinates()->getLongitude() : '',
],
];
}
return new JsonResponse([
'success' => true,
'data' => $data,
]);
}
#[Route('/api/cities/popular', name: 'api_cities_popular', methods: ['GET'])]
#[OA\Get(path: '/api/cities/popular', description: 'Endpoint zwraca listę popularnych miast jako tablicę obiektów z polami id, name i region.', summary: 'Lista popularnych miast', tags: ['Cities'])]
#[OA\Parameter(name: 'X-API-KEY', description: 'Klucz API wymagany do autoryzacji', in: 'header', required: true, schema: new OA\Schema(type: 'string', example: 'your-api-key'))]
#[OA\Response(
response: 200,
description: 'Lista popularnych miast',
content: new OA\JsonContent(
properties: [
new OA\Property(property: 'success', type: 'boolean', example: true),
new OA\Property(
property: 'data',
type: 'array',
items: new OA\Items(
properties: [
new OA\Property(property: 'id', type: 'integer', example: 1),
new OA\Property(property: 'name', type: 'string', example: 'Warszawa'),
new OA\Property(property: 'province', type: 'string', example: 'mazowieckie'),
new OA\Property(
property: 'gpsPoint',
properties: [
new OA\Property(property: 'lat', type: 'number', format: 'float', example: 50.06143),
new OA\Property(property: 'lon', type: 'number', format: 'float', example: 19.93658),
],
type: 'object',
),
],
type: 'object',
),
),
],
type: 'object',
),
)]
public function popular(Request $request): JsonResponse
{
if (!$this->validateApiKey($request)) {
return $this->returnInvalidApiKeyError();
}
$data = [];
foreach ($this->repository->getPopular() as $city) {
/** @var PharmacyCity $city */
$data[] = [
'id' => $city->getId(),
'name' => $city->getCityName(),
'province' => (null !== $city->getProvince()) ? $city->getProvince()->getName() : '',
'gpsPoint' => [
'lat' => (null !== $city->getCoordinates()) ? $city->getCoordinates()->getLatitude() : '',
'lng' => (null !== $city->getCoordinates()) ? $city->getCoordinates()->getLongitude() : '',
],
];
}
return new JsonResponse([
'success' => true,
'data' => $data,
]);
}
}