src/Controller/Api/ItineraryController.php line 121

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Api;
  3. use App\Constants;
  4. use App\Entity\Itinerary;
  5. use App\Entity\ItineraryVersion;
  6. use App\Entity\ItineraryVersionTranslation;
  7. use App\Entity\Player;
  8. use App\Entity\PlayerVersion;
  9. use App\Entity\PlayerVersionTranslation;
  10. use App\Entity\Sound;
  11. use App\Repository\ItineraryRepository;
  12. use App\Service\GohApiService;
  13. use Doctrine\Common\Collections\Criteria;
  14. use Doctrine\ORM\NonUniqueResultException;
  15. use Doctrine\ORM\NoResultException;
  16. use Doctrine\Persistence\Mapping\MappingException;
  17. use FOS\RestBundle\Controller\AbstractFOSRestController;
  18. use FOS\RestBundle\Controller\Annotations\QueryParam;
  19. use FOS\RestBundle\Request\ParamFetcher;
  20. use JMS\Serializer\SerializationContext;
  21. use JMS\Serializer\SerializerInterface;
  22. use Symfony\Component\HttpFoundation\JsonResponse;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Symfony\Component\Validator\Constraints;
  26. /**
  27.  * Class ItineraryController
  28.  * @package App\Controller\Api
  29.  * @Route("/api/v4/itineraries")
  30.  */
  31. class ItineraryController extends AbstractFOSRestController
  32. {
  33.     /**
  34.      * @var SerializerInterface
  35.      */
  36.     private $serializer;
  37.     public function __construct(SerializerInterface $serializer)
  38.     {
  39.         $this->serializer $serializer;
  40.     }
  41.     /**
  42.      * @Route("/test",name="hello_test")
  43.      */
  44.     public function test(): Response
  45.     {
  46.         return JsonResponse::create("hello");
  47.     }
  48.     /**
  49.      * @Route("", name="api_v4_itineraries_index")
  50.      *
  51.      * @QueryParam(name="locale", strict=true, requirements=@Constraints\Locale(canonicalize=true))
  52.      * @QueryParam(name="identifier", strict=true, requirements=@Constraints\Type("string"))
  53.      * @QueryParam(name="latitude", strict=true, requirements=@App\Validator\Constraints\Latitude())
  54.      * @QueryParam(name="longitude", strict=true, requirements=@App\Validator\Constraints\Longitude())
  55.      *
  56.      * @param ParamFetcher $paramFetcher
  57.      * @param ItineraryRepository $itineraryRepository
  58.      * @return Response
  59.      * @throws MappingException
  60.      */
  61.     public function index(ParamFetcher $paramFetcherItineraryRepository $itineraryRepositoryGohApiService $apiService): Response
  62.     {
  63.         $isDev $this->getParameter('includeDevApi') === 'true';
  64.         $locale $paramFetcher->get('locale');
  65.         $identifier $paramFetcher->get('identifier');
  66.         $latitude $paramFetcher->get('latitude');
  67.         $longitude $paramFetcher->get('longitude');
  68.         $serializationContext SerializationContext::create()
  69.             ->setGroups(Constants::SERIALIZE_GROUP_API_LIST)
  70.             ->setAttribute('latitude', (float)$latitude)
  71.             ->setAttribute('longitude', (float)$longitude)
  72.             ->setAttribute('locale'$locale)
  73.             ->setSerializeNull(true);
  74.         $liveItineraries $itineraryRepository->getItinerariesForStateLocaleIdentifier(Constants::STATE_LIVE$locale);
  75.         $liveItineraries $this->serializeMany($liveItineraries$serializationContext);
  76.         $liveItineraries $this->filterDuplicates($liveItineraries$locale);
  77.         $betaItineraries $itineraryRepository->getItinerariesForStateLocaleIdentifier(Constants::STATE_BETA$locale$identifier);
  78.         $betaItineraries $this->serializeMany($betaItineraries$serializationContext);
  79.         $betaItineraries $this->filterDuplicates($betaItineraries$locale);
  80.         /** @var Itinerary[] $itineraries */
  81.         $itineraries array_merge($liveItineraries$betaItineraries);
  82.         $itineraries $this->serializeOrdered($itineraries);
  83.         /*if($isDev) {
  84.             $itineraries = array_merge(
  85.                 $itineraries,
  86.                 $apiService->getItinerariesForStateLocaleIdentifier(Constants::STATE_LIVE, $locale, $latitude, $longitude, $identifier),
  87.                 $apiService->getItinerariesForStateLocaleIdentifier(Constants::STATE_BETA, $locale, $latitude, $longitude, $identifier)
  88.             );
  89.         }*/
  90.         return Response::create(json_encode($itineraries));
  91.     }
  92.     /**
  93.      * @Route("/{slug}/{state}/{locale}", name="api_v4_itineraries_detail")
  94.      *
  95.      * @QueryParam(name="identifier", strict=true, requirements=@Constraints\Type("string"))
  96.      * @QueryParam(name="latitude", strict=true, requirements=@App\Validator\Constraints\Latitude())
  97.      * @QueryParam(name="longitude", strict=true, requirements=@App\Validator\Constraints\Longitude())
  98.      *
  99.      * @param string $slug
  100.      * @param string $state
  101.      * @param string $locale
  102.      * @param ParamFetcher $paramFetcher
  103.      * @param ItineraryRepository $itineraryRepository
  104.      * @param GohApiService $apiService
  105.      * @return Response
  106.      * @throws NonUniqueResultException
  107.      */
  108.     public function detail(string $slugstring $statestring $localeParamFetcher $paramFetcherItineraryRepository $itineraryRepositoryGohApiService $apiService): Response
  109.     {
  110.         $identifier $paramFetcher->get('identifier');
  111.         $latitude $paramFetcher->get('latitude');
  112.         $longitude $paramFetcher->get('longitude');
  113.         $serializationContext SerializationContext::create()
  114.             ->setGroups(Constants::SERIALIZE_GROUP_API_DETAIL)
  115.             ->setAttribute('latitude', (float)$latitude)
  116.             ->setAttribute('longitude', (float)$longitude)
  117.             ->setAttribute('locale'$locale)
  118.             ->setSerializeNull(true);
  119.         try {
  120.             $itinerary $itineraryRepository->getItineraryForStateLocaleSlug($state$locale$slug);
  121.             $serializedItineraries $this->serializeMany([$itinerary], $serializationContext);
  122.             return Response::create(json_encode(current($serializedItineraries)));
  123.         }
  124.         catch (NoResultException $exception) {
  125.             $serializedItineraries = []; // $apiService->getItineraryForStateLocaleSlug($state, $locale, $slug, $latitude, $longitude, $identifier);
  126.             return Response::create(json_encode($serializedItineraries));
  127.         }
  128.     }
  129.     protected function serializeOrdered(array $itineraries): array
  130.     {
  131.         $itinerariesInside array_filter($itineraries, function($itinerary) {
  132.             return $itinerary['distance'] === 'ICI';
  133.         });
  134.         usort($itinerariesInside, function($itinerary1$itinerary2) {
  135.             return strnatcmp($itinerary1['name'], $itinerary2['name']);
  136.         });
  137.         $itinerariesNotInside array_filter($itineraries, function($itinerary) {
  138.             return $itinerary['distance'] !== 'ICI';
  139.         });
  140.         usort($itinerariesNotInside, function ($itinerary1$itinerary2) {
  141.             return $itinerary1['distance_raw'] - $itinerary2['distance_raw'];
  142.         });
  143.         return array_merge($itinerariesInside$itinerariesNotInside);
  144.     }
  145.     /**
  146.      * @param array $itineraries
  147.      * @param SerializationContext $context
  148.      * @return array
  149.      */
  150.     protected function serializeMany(array $itinerariesSerializationContext $context): array
  151.     {
  152.         $locale $context->getAttribute('locale');
  153.         $withPlayers in_array(Constants::SERIALIZE_GROUP_API_DETAIL$context->getAttribute('groups'));
  154.         $serializedItineraries = [];
  155.         /** @var Itinerary $itinerary */
  156.         foreach ($itineraries as $itinerary) {
  157.             $serializedPlayers = [];
  158.             /** @var Player $player */
  159.             foreach ($itinerary->getPlayers() as $player) {
  160.                 /** @var PlayerVersion $playerVersion */
  161.                 foreach ($player->getVersions() as $playerVersion) {
  162.                     /** @var PlayerVersionTranslation $playerVersionTranslation */
  163.                     foreach ($playerVersion->getTranslations() as $playerVersionTranslation) {
  164.                         $sortByNameCriteria Criteria::create()->orderBy(['name' => Criteria::ASC]);
  165.                         $playerVersionTranslationSounds $playerVersionTranslation->getSounds()->matching($sortByNameCriteria);
  166.                         $serializedSounds = [];
  167.                         /** @var Sound $sound */
  168.                         foreach ($playerVersionTranslationSounds as $sound) {
  169.                             $serializedSounds[] = $this->serializeSound($sound$context);
  170.                         }
  171.                         $serializedPlayers[] = array_merge(
  172.                             $this->serializePlayer($player$context),
  173.                             $this->serializePlayerVersion($playerVersion$context),
  174.                             $this->serializePlayerVersionTranslation($playerVersionTranslation$context),
  175.                             [
  176.                                 "sounds" => $serializedSounds,
  177.                             ]
  178.                         );
  179.                     }
  180.                 }
  181.             }
  182.             if($withPlayers) {
  183.                 $serializedPlayers $this->filterDuplicates($serializedPlayers$locale);
  184.             }
  185.             /** @var ItineraryVersion $itineraryVersion */
  186.             foreach ($itinerary->getVersions() as $itineraryVersion) {
  187.                 foreach ($itineraryVersion->getTranslations() as $itineraryVersionTranslation) {
  188.                     $serializedItineraries[] = array_merge(
  189.                         $this->serializeItinerary($itinerary$context),
  190.                         $this->serializeItineraryVersion($itineraryVersion$context),
  191.                         $this->serializeItineraryVersionTranslation($itineraryVersionTranslation$context),
  192.                         [
  193.                             "players" => $withPlayers $serializedPlayers : [],
  194.                         ]
  195.                     );
  196.                 }
  197.             }
  198.         }
  199.         return $serializedItineraries;
  200.     }
  201.     protected function serializeItinerary(Itinerary $itinerarySerializationContext $context): array
  202.     {
  203.         return $this->serialize($itinerary$context);
  204.     }
  205.     protected function serializeItineraryVersion(ItineraryVersion $itineraryVersionSerializationContext $context): array
  206.     {
  207.         return $this->serialize($itineraryVersion$context);
  208.     }
  209.     protected function serializeItineraryVersionTranslation(ItineraryVersionTranslation $itineraryVersionTranslationSerializationContext $context): array
  210.     {
  211.         return $this->serialize($itineraryVersionTranslation$context);
  212.     }
  213.     protected function serializePlayer(Player $playerSerializationContext $context): array
  214.     {
  215.         return $this->serialize($player$context);
  216.     }
  217.     protected function serializePlayerVersion(PlayerVersion $playerVersionSerializationContext $context): array
  218.     {
  219.         return $this->serialize($playerVersion$context);
  220.     }
  221.     protected function serializePlayerVersionTranslation(PlayerVersionTranslation $playerVersionTranslationSerializationContext $context): array
  222.     {
  223.         return $this->serialize($playerVersionTranslation$context);
  224.     }
  225.     protected function serializeSound(Sound $soundSerializationContext $context): array
  226.     {
  227.         return $this->serialize($sound$context);
  228.     }
  229.     protected function serialize($entitySerializationContext $context): array
  230.     {
  231.         return json_decode($this->serializer->serialize($entity'json', clone $context), true);
  232.     }
  233.     protected function filterDuplicates(array $serializedEntitiesstring $expectedLocale): array
  234.     {
  235.         $filtered = [];
  236.         foreach($serializedEntities as $serializedEntityIndex => $serializedEntity) {
  237.             $exactEntityIndex $this->getIndexFromExactEntityExistsInArray($serializedEntities$serializedEntity['slug'], $serializedEntity['state'], $expectedLocale);
  238.             if($serializedEntityIndex !== $exactEntityIndex && $exactEntityIndex 0) {
  239.                 continue;
  240.             }
  241.             $filtered[] = $serializedEntity;
  242.         }
  243.         return $filtered;
  244.     }
  245.     protected function getIndexFromExactEntityExistsInArray(array $arraystring $slugstring $statestring $locale): int {
  246.         foreach($array as $index => $item) {
  247.             if($item['slug'] === $slug && $item['state'] === $state && $item['locale'] === $locale) {
  248.                 return $index;
  249.             }
  250.         }
  251.         return -1;
  252.     }
  253. }