<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-04-15
* Time: 12:36
*/
namespace App\Controller;
use App\Entity\Location\City;
use App\Repository\CityRepository;
use App\Repository\ProfileRepository;
use App\Service\DefaultCityProvider;
use Flagception\Bundle\FlagceptionBundle\Annotations\Feature;
use Nelmio\ApiDocBundle\Attribute\Model;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Intl\Countries;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use OpenApi\Attributes as OA;
class CityListController extends AbstractController
{
public function __construct(
private CityRepository $cityRepository,
private ProfileRepository $profileRepository,
private TranslatorInterface $translator
) {}
public function page(): Response
{
$countByCity = $this->profileRepository->countByCity();
$cities = [
'megalopolis' => [],
'moscow_region' => [],
];
foreach ($this->cityRepository->findAll() as $city) {
/** @var City $city */
$label = sprintf('%s (%d)', $this->translator->trans($city->getName()), $countByCity[$city->getId()] ?? 0);
if (City::GROUP_MEGALOPOLIS === $city->getCityGroup()) {
$cities['megalopolis'][$label] = $city;
} elseif (City::GROUP_MOSCOW_REGION === $city->getCityGroup()) {
$cities['moscow_region'][$label] = $city;
} else {
$cities[$city->getCountryCode()][$label] = $city;
}
}
return $this->render('CityList/list.html.twig', [
'cities' => $cities,
]);
}
/**
* @Feature("has_city_list_page")
*/
public function listByCountry(Request $request, DefaultCityProvider $defaultCityProvider): Response
{
$locale = $request->getLocale() ?? 'ru';
$countries = Countries::getNames($locale);
$countByCity = $this->profileRepository->countByCity();
$cities = [];
foreach ($this->cityRepository->findAll() as $city) {
/** @var City $city */
$countryCode = $city->getCountryCode();
$country = $countries[$countryCode];
if (!isset($cities[$country]))
$cities[$country] = [];
$route = $city->equals($defaultCityProvider->getDefaultCity()) ? 'homepage' : 'profile_list.list_by_city';
$cities[$country][$city->getId()] = [
'city' => $city,
'count' => $countByCity[$city->getId()] ?? 0,
'uri' => $this->generateUrl($route, ['city' => $city->getUriIdentity()]),
];
}
return $this->render('CityList/list_by_country.html.twig', [
'cities' => $cities,
]);
}
#[Route("/api/geo/cities", name: "api.geo.cities", methods: ["GET"], format: "json")]
#[OA\Parameter(name: "withCounters", description: "Добавить в ответ количество анкет с разбивкой по городам", in: "query", schema: new OA\Schema(type: "boolean"))]
#[OA\Tag(name: "GEO")]
#[OA\Response(
response: 200,
description: 'Список городов с количеством анкет по городам',
content: new OA\JsonContent(
properties: [
new OA\Property(property: "cities", type: "array", items: new OA\Items(ref: new Model(type: City::class))),
new OA\Property(property: "profile_counters", type: "array", items: new OA\Items(properties: [
new OA\Property(property: "city_id", type: "integer"),
new OA\Property(property: "count", type: "integer"),
], type: "object")),
],
type: 'object',
),
)]
public function listAll(Request $request): JsonResponse
{
$withCounters = $request->query->getBoolean('withCounters');
$data = [
'cities' => $this->cityRepository->findAll(),
];
if ($withCounters) {
$data['profile_counters'] = [];
foreach ($this->profileRepository->countByCity() as $cityId => $count) {
$data['profile_counters'][] = [
'city_id' => $cityId,
'count' => $count,
];
}
}
return $this->json($data);
}
}