src/Controller/CityListController.php line 62

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by simpson <simpsonwork@gmail.com>
  4.  * Date: 2019-04-15
  5.  * Time: 12:36
  6.  */
  7. namespace App\Controller;
  8. use App\Entity\Location\City;
  9. use App\Repository\CityRepository;
  10. use App\Repository\ProfileRepository;
  11. use App\Service\DefaultCityProvider;
  12. use Flagception\Bundle\FlagceptionBundle\Annotations\Feature;
  13. use Nelmio\ApiDocBundle\Attribute\Model;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\Intl\Countries;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use Symfony\Contracts\Translation\TranslatorInterface;
  21. use OpenApi\Attributes as OA;
  22. class CityListController extends AbstractController
  23. {
  24.     public function __construct(
  25.         private CityRepository $cityRepository,
  26.         private ProfileRepository $profileRepository,
  27.         private TranslatorInterface $translator
  28.     ) {}
  29.     public function page(): Response
  30.     {
  31.         $countByCity = $this->profileRepository->countByCity();
  32.         $cities = [
  33.             'megalopolis' => [],
  34.             'moscow_region' => [],
  35.         ];
  36.         foreach ($this->cityRepository->findAll() as $city) {
  37.             /** @var City $city */
  38.             $label = sprintf('%s (%d)', $this->translator->trans($city->getName()), $countByCity[$city->getId()] ?? 0);
  39.             if (City::GROUP_MEGALOPOLIS === $city->getCityGroup()) {
  40.                 $cities['megalopolis'][$label] = $city;
  41.             } elseif (City::GROUP_MOSCOW_REGION === $city->getCityGroup()) {
  42.                 $cities['moscow_region'][$label] = $city;
  43.             } else {
  44.                 $cities[$city->getCountryCode()][$label] = $city;
  45.             }
  46.         }
  47.         return $this->render('CityList/list.html.twig', [
  48.             'cities' => $cities,
  49.         ]);
  50.     }
  51.     /**
  52.      * @Feature("has_city_list_page")
  53.      */
  54.     public function listByCountry(Request $request, DefaultCityProvider $defaultCityProvider): Response
  55.     {
  56.         $locale = $request->getLocale() ?? 'ru';
  57.         $countries = Countries::getNames($locale);
  58.         $countByCity = $this->profileRepository->countByCity();
  59.         $cities = [];
  60.         foreach ($this->cityRepository->findAll() as $city) {
  61.             /** @var City $city */
  62.             $countryCode = $city->getCountryCode();
  63.             $country = $countries[$countryCode];
  64.             if (!isset($cities[$country]))
  65.                 $cities[$country] = [];
  66.             $route = $city->equals($defaultCityProvider->getDefaultCity()) ? 'homepage' : 'profile_list.list_by_city';
  67.             $cities[$country][$city->getId()] = [
  68.                 'city' => $city,
  69.                 'count' => $countByCity[$city->getId()] ?? 0,
  70.                 'uri' => $this->generateUrl($route, ['city' => $city->getUriIdentity()]),
  71.             ];
  72.         }
  73.         return $this->render('CityList/list_by_country.html.twig', [
  74.             'cities' => $cities,
  75.         ]);
  76.     }
  77.     #[Route("/api/geo/cities", name: "api.geo.cities", methods: ["GET"], format: "json")]
  78.     #[OA\Parameter(name: "withCounters", description: "Добавить в ответ количество анкет с разбивкой по городам", in: "query", schema: new OA\Schema(type: "boolean"))]
  79.     #[OA\Parameter(name: "region", description: "Фильтрация городов по региону", in: "query", schema: new OA\Schema(type: "string"))]
  80.     #[OA\Tag(name: "GEO")]
  81.     #[OA\Response(
  82.         response: 200,
  83.         description: 'Список городов с количеством анкет по городам',
  84.         content: new OA\JsonContent(
  85.             properties: [
  86.                 new OA\Property(property: "cities", type: "array", items: new OA\Items(ref: new Model(type: City::class))),
  87.                 new OA\Property(property: "profile_counters", type: "array", items: new OA\Items(properties: [
  88.                     new OA\Property(property: "city_id", type: "integer"),
  89.                     new OA\Property(property: "count", type: "integer"),
  90.                 ], type: "object")),
  91.             ],
  92.             type: 'object',
  93.         ),
  94.     )]
  95.     public function listAll(Request $request): JsonResponse
  96.     {
  97.         $withCounters = $request->query->getBoolean('withCounters');
  98.         $data = [
  99.             'cities' => $this->cityRepository->findAll($request->query->get('region')),
  100.         ];
  101.         if ($withCounters) {
  102.             $data['profile_counters'] = [];
  103.             foreach ($this->profileRepository->countByCity() as $cityId => $count) {
  104.                 $data['profile_counters'][] = [
  105.                     'city_id' => $cityId,
  106.                     'count' => $count,
  107.                 ];
  108.             }
  109.         }
  110.         return $this->json($data);
  111.     }
  112. }