src/Controller/CityListController.php line 86

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\Tag(name: "GEO")]
  80.     #[OA\Response(
  81.         response: 200,
  82.         description: 'Список городов с количеством анкет по городам',
  83.         content: new OA\JsonContent(
  84.             properties: [
  85.                 new OA\Property(property: "cities", type: "array", items: new OA\Items(ref: new Model(type: City::class))),
  86.                 new OA\Property(property: "profile_counters", type: "array", items: new OA\Items(properties: [
  87.                     new OA\Property(property: "city_id", type: "integer"),
  88.                     new OA\Property(property: "count", type: "integer"),
  89.                 ], type: "object")),
  90.             ],
  91.             type: 'object',
  92.         ),
  93.     )]
  94.     public function listAll(Request $request): JsonResponse
  95.     {
  96.         $withCounters = $request->query->getBoolean('withCounters');
  97.         $data = [
  98.             'cities' => $this->cityRepository->findAll(),
  99.         ];
  100.         if ($withCounters) {
  101.             $data['profile_counters'] = [];
  102.             foreach ($this->profileRepository->countByCity() as $cityId => $count) {
  103.                 $data['profile_counters'][] = [
  104.                     'city_id' => $cityId,
  105.                     'count' => $count,
  106.                 ];
  107.             }
  108.         }
  109.         return $this->json($data);
  110.     }
  111. }