src/Controller/Api/MobileAppController.php line 105

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Api;
  3. use App\Entity\Institution;
  4. use App\Entity\Dish;
  5. use App\Entity\Wine;
  6. use App\Entity\WineColor;
  7. use App\Entity\Grape;
  8. use App\Entity\Beer;
  9. use App\Entity\BeerColor;
  10. use App\Entity\Drink;
  11. use App\Entity\Menu;
  12. use App\Entity\Allergen;
  13. use App\Entity\Label;
  14. use App\Entity\LocaleFront;
  15. use App\Entity\InstitutionReview;
  16. use App\Entity\InstitutionReviewSummary;
  17. use App\Entity\Contest;
  18. use App\Entity\ContestEntry;
  19. use App\Entity\ContestTicket;
  20. use App\Service\MobileAppSerializeService;
  21. use App\Service\ProductTranslationService;
  22. use DateInterval;
  23. use DateTime;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. use Doctrine\Common\Collections\Criteria;
  26. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  27. use Symfony\Component\HttpFoundation\JsonResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\Routing\Annotation\Route;
  30. use Symfony\Contracts\Translation\TranslatorInterface;
  31. /**
  32.  * Class MizogooMobileController
  33.  * @package App\Controller\Api
  34.  * @Route(path="/api/mobile/app/", name="api_mobile_app_")
  35.  */
  36. class MobileAppController extends AbstractController
  37. {
  38.     private EntityManagerInterface $em;
  39.     private MobileAppSerializeService $mobileAppSerializeService;
  40.     private ProductTranslationService $productTranslationService;
  41.     private TranslatorInterface $translator;
  42.     public function __construct(
  43.         EntityManagerInterface $em,
  44.         MobileAppSerializeService $mobileAppSerializeService,
  45.         ProductTranslationService $productTranslationService,
  46.         TranslatorInterface $translator
  47.     ) {
  48.         $this->em $em;
  49.         $this->mobileAppSerializeService $mobileAppSerializeService;
  50.         $this->productTranslationService $productTranslationService;
  51.         $this->translator $translator;
  52.     }
  53.     /**
  54.      * @param Institution $institution 
  55.      * @return JsonResponse
  56.      * @Route("supported-data-languages/{institution}", name="getSupportedDataLanguages", requirements={"institution"="\d+"})
  57.      */
  58.     public function getSupportedDataLanguages(Institution $institution)
  59.     {
  60.         return new JsonResponse([
  61.             'success' => true,
  62.             'supportedDataLanguages' => $this->mobileAppSerializeService->serializeSupportedDataLanguages($institution),
  63.         ]);
  64.     }
  65.     /**
  66.      * @param Institution $institution 
  67.      * @return JsonResponse
  68.      * @Route("institution/functionalities/{institution}", name="getFunctionalities", requirements={"institution"="\d+"})
  69.      */
  70.     public function getFunctionalities(Institution $institution)
  71.     {
  72.         return new JsonResponse([
  73.             'success' => true,
  74.             'functionalities' => $this->mobileAppSerializeService->serializeFunctionalities($institution),
  75.         ]);
  76.     }
  77.     /**
  78.      * @param Institution $institution
  79.      * @return JsonResponse
  80.      * @Route("institution/personalization/{institution}", name="getInstitutionPersonalization", requirements={"institution"="\d+"})
  81.      * @Route("{language}/institution/personalization/{institution}", name="getInstitutionPersonalizationLanguage", requirements={"institution"="\d+"})
  82.      */
  83.     public function getInstitutionPersonalization(Institution $institution)
  84.     {
  85.         return new JsonResponse([
  86.             'success' => true,
  87.             'institutionPersonalization' => $this->mobileAppSerializeService->serializeInstitutionPersonalization($institution),
  88.         ]);
  89.     }
  90.     /**
  91.      * @param string|null $language
  92.      * @param Institution $institution
  93.      * @return JsonResponse
  94.      * @Route("institution/overview/{institution}", name="getInstitutionOverview", requirements={"institution"="\d+"})
  95.      * @Route("{language}/institution/overview/{institution}", name="getInstitutionOverviewLanguage", requirements={"institution"="\d+"})
  96.      */
  97.     public function getInstitutionOverview(Institution $institution, ?string $language null): JsonResponse
  98.     {
  99.         if ($institution->isActive() && $institution->getUser()->isActive()) {
  100.             // And if the translation should be updated automatically when an item has been altered
  101.             $updateTranslationIfAltered true;
  102.             foreach ($institution->getInstitutionLocaleFronts() as $institutionLocaleFront) {
  103.                 if (strcmp($institutionLocaleFront->getLocaleFront()->getTag(), $language) === 0) {
  104.                     $updateTranslationIfAltered false;
  105.                     break;
  106.                 }
  107.             }
  108.             /** @var LocaleFront $localeFront */
  109.             $localeFront $this->em->getRepository(LocaleFront::class)->findOneBy(array('tag' => $language));
  110.             // Retrieve default institutionLocaleFront
  111.             $institutionLocaleFronts $institution->getInstitutionLocaleFronts();
  112.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  113.                 ->where(Criteria::expr()->eq('isDefault'true));
  114.             $defaultInstitutionLocaleFront $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront();
  115.             if ($localeFront) {
  116.                 // Default locale front criteria (used to check if the item has already been translated or not)
  117.                 $defaultLocaleElementTranslationCriteria Criteria::create()
  118.                     ->where(Criteria::expr()->eq('localeFront'$defaultInstitutionLocaleFront));
  119.                 // Requested locale front criteria (used to check if the item has already been translated or not)
  120.                 $currentLocaleElementTranslationCriteria Criteria::create()
  121.                     ->where(Criteria::expr()->eq('localeFront'$localeFront));
  122.                 // Going throw every products
  123.                 foreach ($institution->getDishes() as $dish) {
  124.                     // Retrieve the original translation
  125.                     $defaultDishTranslation $dish->getDishTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  126.                     // Try to retrieve the translated item
  127.                     $alreadyTranslatedItem $dish->getDishTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  128.                     // Check if this item has already been translated in the required language
  129.                     if (!$alreadyTranslatedItem) {
  130.                         // If not, translate it and create a new 'translation item'
  131.                         $this->productTranslationService->translateDish($dish$defaultDishTranslationnull$localeFront);
  132.                     } else {
  133.                         // But even if the translation exists, it's not enough, we have to make sure that the 'orginal' dish has not been altered
  134.                         // To do so, we check whether the 'updated' timestamp of the requested translation is earlier than the one of the original language
  135.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultDishTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  136.                             // Update translation
  137.                             $this->productTranslationService->translateDish($dish$defaultDishTranslation$alreadyTranslatedItem$localeFront);
  138.                         }
  139.                     }
  140.                 }
  141.                 foreach ($institution->getDishCategories() as $dishCategory) {
  142.                     $defaultDishCategoryTranslation $dishCategory->getDishCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  143.                     $alreadyTranslatedItem $dishCategory->getDishCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  144.                     if (!$alreadyTranslatedItem) {
  145.                         $this->productTranslationService->translateDishCategory($dishCategory$defaultDishCategoryTranslationnull$localeFront);
  146.                     } else {
  147.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultDishCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  148.                             $this->productTranslationService->translateDishCategory($dishCategory$defaultDishCategoryTranslation$alreadyTranslatedItem$localeFront);
  149.                         }
  150.                     }
  151.                 }
  152.                 $allergens $this->em->getRepository(Allergen::class)->findAll();
  153.                 foreach ($allergens as $allergen) {
  154.                     $defaultAllergenTranslation $allergen->getAllergenTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  155.                     $alreadyTranslatedItem $allergen->getAllergenTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  156.                     if (!$alreadyTranslatedItem) {
  157.                         $this->productTranslationService->translateAllergen($allergen$defaultAllergenTranslationnull$localeFront);
  158.                     } else {
  159.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultAllergenTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  160.                             $this->productTranslationService->translateAllergen($allergen$defaultAllergenTranslation$alreadyTranslatedItem$localeFront);
  161.                         }
  162.                     }
  163.                 }
  164.                 $labels $this->em->getRepository(Label::class)->findAll();
  165.                 foreach ($labels as $label) {
  166.                     $defaultLabelTranslation $label->getLabelTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  167.                     $alreadyTranslatedItem $label->getLabelTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  168.                     if (!$alreadyTranslatedItem) {
  169.                         $this->productTranslationService->translateLabel($label$defaultLabelTranslationnull$localeFront);
  170.                     } else {
  171.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultLabelTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  172.                             $this->productTranslationService->translateLabel($label$defaultLabelTranslation$alreadyTranslatedItem$localeFront);
  173.                         }
  174.                     }
  175.                 }
  176.                 foreach ($institution->getWines() as $wine) {
  177.                     $defaultWineTranslation $wine->getWineTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  178.                     $alreadyTranslatedItem $wine->getWineTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  179.                     if (!$alreadyTranslatedItem) {
  180.                         $this->productTranslationService->translateWine($wine$defaultWineTranslationnull$localeFront);
  181.                     } else {
  182.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultWineTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  183.                             $this->productTranslationService->translateWine($wine$defaultWineTranslation$alreadyTranslatedItem$localeFront);
  184.                         }
  185.                     }
  186.                 }
  187.                 foreach ($institution->getWineCategories() as $wineCategory) {
  188.                     $defaultWineCategoryTranslation $wineCategory->getWineCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  189.                     $alreadyTranslatedItem $wineCategory->getWineCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  190.                     if (!$alreadyTranslatedItem) {
  191.                         $this->productTranslationService->translateWineCategory($wineCategory$defaultWineCategoryTranslationnull$localeFront);
  192.                     } else {
  193.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultWineCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  194.                             $this->productTranslationService->translateWineCategory($wineCategory$defaultWineCategoryTranslation$alreadyTranslatedItem$localeFront);
  195.                         }
  196.                     }
  197.                 }
  198.                 $wineColors $this->em->getRepository(WineColor::class)->findAll();
  199.                 foreach ($wineColors as $wineColor) {
  200.                     $defaultWineColorTranslation $wineColor->getWineColorTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  201.                     $alreadyTranslatedItem $wineColor->getWineColorTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  202.                     if (!$alreadyTranslatedItem) {
  203.                         $this->productTranslationService->translateWineColor($wineColor$defaultWineColorTranslationnull$localeFront);
  204.                     } else {
  205.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultWineColorTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  206.                             $this->productTranslationService->translateWineColor($wineColor$defaultWineColorTranslation$alreadyTranslatedItem$localeFront);
  207.                         }
  208.                     }
  209.                 }
  210.                 $criteria Criteria::create()
  211.                     ->where(Criteria::expr()->eq('institution'null))
  212.                     ->orWhere(Criteria::expr()->eq('institution'$institution));
  213.                 $grapes $this->em->getRepository(Grape::class)->matching($criteria);
  214.                 foreach ($grapes as $grape) {
  215.                     $defaultGrapeTranslation $grape->getGrapeTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  216.                     $alreadyTranslatedItem $grape->getGrapeTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  217.                     if (!$alreadyTranslatedItem) {
  218.                         $this->productTranslationService->translateGrape($grape$defaultGrapeTranslation$localeFront);
  219.                     } else {
  220.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultGrapeTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  221.                             $this->productTranslationService->translateGrape($grape$defaultGrapeTranslation$localeFront);
  222.                         }
  223.                     }
  224.                 }
  225.                 foreach ($institution->getBeers() as $beer) {
  226.                     $defaultBeerTranslation $beer->getBeerTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  227.                     $alreadyTranslatedItem $beer->getBeerTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  228.                     if (!$alreadyTranslatedItem) {
  229.                         $this->productTranslationService->translateBeer($beer$defaultBeerTranslationnull$localeFront);
  230.                     } else {
  231.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultBeerTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  232.                             $this->productTranslationService->translateBeer($beer$defaultBeerTranslation$alreadyTranslatedItem$localeFront);
  233.                         }
  234.                     }
  235.                 }
  236.                 foreach ($institution->getBeerCategories() as $beerCategory) {
  237.                     $defaultBeerCategoryTranslation $beerCategory->getBeerCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  238.                     $alreadyTranslatedItem $beerCategory->getBeerCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  239.                     if (!$alreadyTranslatedItem) {
  240.                         $this->productTranslationService->translateBeerCategory($beerCategory$defaultBeerCategoryTranslationnull$localeFront);
  241.                     } else {
  242.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultBeerCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  243.                             $this->productTranslationService->translateBeerCategory($beerCategory$defaultBeerCategoryTranslation$alreadyTranslatedItem$localeFront);
  244.                         }
  245.                     }
  246.                 }
  247.                 $beerColors $this->em->getRepository(BeerColor::class)->findAll();
  248.                 foreach ($beerColors as $beerColor) {
  249.                     $defaultBeerColorTranslation $beerColor->getBeerColorTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  250.                     $alreadyTranslatedItem $beerColor->getBeerColorTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  251.                     if (!$alreadyTranslatedItem) {
  252.                         $this->productTranslationService->translateBeerColor($beerColor$defaultBeerColorTranslationnull$localeFront);
  253.                     } else {
  254.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultBeerColorTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  255.                             $this->productTranslationService->translateBeerColor($beerColor$defaultBeerColorTranslation$alreadyTranslatedItem$localeFront);
  256.                         }
  257.                     }
  258.                 }
  259.                 foreach ($institution->getDrinks() as $drink) {
  260.                     $defaultDrinkTranslation $drink->getDrinkTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  261.                     $alreadyTranslatedItem $drink->getDrinkTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  262.                     if (!$alreadyTranslatedItem) {
  263.                         $this->productTranslationService->translateDrink($drink$defaultDrinkTranslationnull$localeFront);
  264.                     } else {
  265.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultDrinkTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  266.                             $this->productTranslationService->translateDrink($drink$defaultDrinkTranslation$alreadyTranslatedItem$localeFront);
  267.                         }
  268.                     }
  269.                 }
  270.                 foreach ($institution->getDrinkCategories() as $drinkCategory) {
  271.                     $defaultDrinkCategoryTranslation $drinkCategory->getDrinkCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  272.                     $alreadyTranslatedItem $drinkCategory->getDrinkCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  273.                     if (!$alreadyTranslatedItem) {
  274.                         $this->productTranslationService->translateDrinkCategory($drinkCategory$defaultDrinkCategoryTranslationnull$localeFront);
  275.                     } else {
  276.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultDrinkCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  277.                             $this->productTranslationService->translateDrinkCategory($drinkCategory$defaultDrinkCategoryTranslation$alreadyTranslatedItem$localeFront);
  278.                         }
  279.                     }
  280.                 }
  281.                 foreach ($institution->getMenus() as $menu) {
  282.                     $defaultMenuTranslation $menu->getMenuTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  283.                     $alreadyTranslatedItem $menu->getMenuTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  284.                     if (!$alreadyTranslatedItem) {
  285.                         $this->productTranslationService->translateMenu($menu$defaultMenuTranslationnull$localeFront);
  286.                     } else {
  287.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultMenuTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  288.                             $this->productTranslationService->translateMenu($menu$defaultMenuTranslation$alreadyTranslatedItem$localeFront);
  289.                         }
  290.                     }
  291.                     foreach ($menu->getInnerCategories() as $menuInnerCategory) {
  292.                         $defaultMenuInnerCategoryTranslation $menuInnerCategory->getMenuInnerCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  293.                         $alreadyTranslatedItem $menuInnerCategory->getMenuInnerCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  294.                         if (!$alreadyTranslatedItem) {
  295.                             $this->productTranslationService->translateMenuInnerCategory($menuInnerCategory$defaultMenuInnerCategoryTranslationnull$localeFront);
  296.                         } else {
  297.                             if ($alreadyTranslatedItem->getUpdatedAt() < $defaultMenuInnerCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  298.                                 $this->productTranslationService->translateMenuInnerCategory($menuInnerCategory$defaultMenuInnerCategoryTranslation$alreadyTranslatedItem$localeFront);
  299.                             }
  300.                         }
  301.                     }
  302.                 }
  303.                 foreach ($institution->getMenuCategories() as $menuCategory) {
  304.                     $defaultMenuCategoryTranslation $menuCategory->getMenuCategoryTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  305.                     $alreadyTranslatedItem $menuCategory->getMenuCategoryTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  306.                     if (!$alreadyTranslatedItem) {
  307.                         $this->productTranslationService->translateMenuCategory($menuCategory$defaultMenuCategoryTranslationnull$localeFront);
  308.                     } else {
  309.                         if ($alreadyTranslatedItem->getUpdatedAt() < $defaultMenuCategoryTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  310.                             $this->productTranslationService->translateMenuCategory($menuCategory$defaultMenuCategoryTranslation$alreadyTranslatedItem$localeFront);
  311.                         }
  312.                     }
  313.                 }
  314.                 foreach ($institution->getOffers() as $offer) {
  315.                     foreach ($offer->getOfferDishes() as $offerDish) {
  316.                         $defaultOfferDishTranslation $offerDish->getOfferDishTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  317.                         $alreadyTranslatedItem $offerDish->getOfferDishTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  318.                         if ($defaultOfferDishTranslation) {
  319.                             if (!$alreadyTranslatedItem) {
  320.                                 $this->productTranslationService->translateOfferDish($offerDish$defaultOfferDishTranslationnull$localeFront);
  321.                             } else {
  322.                                 if ($alreadyTranslatedItem->getUpdatedAt() < $defaultOfferDishTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  323.                                     $this->productTranslationService->translateOfferDish($offerDish$defaultOfferDishTranslation$alreadyTranslatedItem$localeFront);
  324.                                 }
  325.                             }
  326.                         }
  327.                     }
  328.                     foreach ($offer->getOfferWines() as $offerWine) {
  329.                         $defaultOfferWineTranslation $offerWine->getOfferWineTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  330.                         $alreadyTranslatedItem $offerWine->getOfferWineTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  331.                         if ($defaultOfferWineTranslation) {
  332.                             if (!$alreadyTranslatedItem) {
  333.                                 $this->productTranslationService->translateOfferWine($offerWine$defaultOfferWineTranslationnull$localeFront);
  334.                             } else {
  335.                                 if ($alreadyTranslatedItem->getUpdatedAt() < $defaultOfferWineTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  336.                                     $this->productTranslationService->translateOfferWine($offerWine$defaultOfferWineTranslation$alreadyTranslatedItem$localeFront);
  337.                                 }
  338.                             }
  339.                         }
  340.                     }
  341.                     foreach ($offer->getOfferBeers() as $offerBeer) {
  342.                         $defaultOfferBeerTranslation $offerBeer->getOfferBeerTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  343.                         $alreadyTranslatedItem $offerBeer->getOfferBeerTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  344.                         if ($defaultOfferBeerTranslation) {
  345.                             if (!$alreadyTranslatedItem) {
  346.                                 $this->productTranslationService->translateOfferBeer($offerBeer$defaultOfferBeerTranslationnull$localeFront);
  347.                             } else {
  348.                                 if ($alreadyTranslatedItem->getUpdatedAt() < $defaultOfferBeerTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  349.                                     $this->productTranslationService->translateOfferBeer($offerBeer$defaultOfferBeerTranslation$alreadyTranslatedItem$localeFront);
  350.                                 }
  351.                             }
  352.                         }
  353.                     }
  354.                     foreach ($offer->getOfferDrinks() as $offerDrink) {
  355.                         $defaultOfferDrinkTranslation $offerDrink->getOfferDrinkTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  356.                         $alreadyTranslatedItem $offerDrink->getOfferDrinkTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  357.                         if ($defaultOfferDrinkTranslation) {
  358.                             if (!$alreadyTranslatedItem) {
  359.                                 $this->productTranslationService->translateOfferDrink($offerDrink$defaultOfferDrinkTranslationnull$localeFront);
  360.                             } else {
  361.                                 if ($alreadyTranslatedItem->getUpdatedAt() < $defaultOfferDrinkTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  362.                                     $this->productTranslationService->translateOfferDrink($offerDrink$defaultOfferDrinkTranslation$alreadyTranslatedItem$localeFront);
  363.                                 }
  364.                             }
  365.                         }
  366.                     }
  367.                     foreach ($offer->getOfferMenus() as $offerMenu) {
  368.                         $defaultOfferMenuTranslation $offerMenu->getOfferMenuTranslations()->matching($defaultLocaleElementTranslationCriteria)->first();
  369.                         $alreadyTranslatedItem $offerMenu->getOfferMenuTranslations()->matching($currentLocaleElementTranslationCriteria)->first();
  370.                         if ($defaultOfferMenuTranslation) {
  371.                             if (!$alreadyTranslatedItem) {
  372.                                 $this->productTranslationService->translateOfferMenu($offerMenu$defaultOfferMenuTranslationnull$localeFront);
  373.                             } else {
  374.                                 if ($alreadyTranslatedItem->getUpdatedAt() < $defaultOfferMenuTranslation->getUpdatedAt() && $updateTranslationIfAltered) {
  375.                                     $this->productTranslationService->translateOfferMenu($offerMenu$defaultOfferMenuTranslation$alreadyTranslatedItem$localeFront);
  376.                                 }
  377.                             }
  378.                         }
  379.                     }
  380.                 }
  381.                 // No corresponding LocaleFront get the one by default
  382.             } else {
  383.                 $language $defaultInstitutionLocaleFront->getTag();
  384.             }
  385.             return new JsonResponse([
  386.                 'success' => true,
  387.                 'institution' => $this->mobileAppSerializeService->serializeInstitutionOverview($institution$language),
  388.             ]);
  389.         }
  390.         return new JsonResponse([
  391.             'success' => false,
  392.             'message' => $this->translator->trans('institutionHome.notFound'),
  393.         ]);
  394.     }
  395.     /**
  396.      * @param Institution $institution
  397.      * @return JsonResponse
  398.      * @Route("institution/{institution}", name="getInstitutionDetail", requirements={"institution"="\d+"})
  399.      */
  400.     public function getInstitutionDetail(Institution $institution): JsonResponse
  401.     {
  402.         return new JsonResponse([
  403.             'success' => true,
  404.             'institution' => $this->mobileAppSerializeService->serializeInstitution($institution),
  405.         ]);
  406.     }
  407.     /**
  408.      * @param Dish $dish
  409.      * @param string|null $language
  410.      * @return JsonResponse
  411.      * @Route("dish/{dish}", name="getDishDetail", requirements={"dish"="\d+"})
  412.      * @Route("{language}/dish/{dish}", name="getDishDetailLanguage", requirements={"dish"="\d+"})
  413.      */
  414.     public function getDishDetail(Dish $dish, ?string $language null): JsonResponse
  415.     {
  416.         if (is_null($language)) {
  417.             $institutionLocaleFronts $dish->getInstitution()->getInstitutionLocaleFronts();
  418.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  419.                 ->where(Criteria::expr()->eq('isDefault'true));
  420.             $language $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront()->getTag();
  421.         }
  422.         return new JsonResponse([
  423.             'success' => true,
  424.             'dish' => $this->mobileAppSerializeService->serializeDish($dish$language),
  425.         ]);
  426.     }
  427.     /**
  428.      * @param Wine $wine
  429.      * @param string|null $language
  430.      * @return JsonResponse
  431.      * @Route("wine/{wine}", name="getWineDetail", requirements={"wine"="\d+"})
  432.      * @Route("{language}/wine/{wine}", name="getWineDetailLanguage", requirements={"wine"="\d+"})
  433.      */
  434.     public function getWineDetail(Wine $wine, ?string $language null): JsonResponse
  435.     {
  436.         if (is_null($language)) {
  437.             $institutionLocaleFronts $wine->getInstitution()->getInstitutionLocaleFronts();
  438.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  439.                 ->where(Criteria::expr()->eq('isDefault'true));
  440.             $language $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront()->getTag();
  441.         }
  442.         return new JsonResponse([
  443.             'success' => true,
  444.             'wine' => $this->mobileAppSerializeService->serializeWine($wine$language),
  445.         ]);
  446.     }
  447.     /**
  448.      * @param Beer $beer
  449.      * @param string|null $language
  450.      * @return JsonResponse
  451.      * @Route("beer/{beer}", name="getBeerDetail", requirements={"beer"="\d+"})
  452.      * @Route("{language}/beer/{beer}", name="getBeerDetailLanguage", requirements={"beer"="\d+"})
  453.      */
  454.     public function getBeerDetail(Beer $beer, ?string $language null): JsonResponse
  455.     {
  456.         if (is_null($language)) {
  457.             $institutionLocaleFronts $beer->getInstitution()->getInstitutionLocaleFronts();
  458.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  459.                 ->where(Criteria::expr()->eq('isDefault'true));
  460.             $language $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront()->getTag();
  461.         }
  462.         return new JsonResponse([
  463.             'success' => true,
  464.             'beer' => $this->mobileAppSerializeService->serializeBeer($beer$language),
  465.         ]);
  466.     }
  467.     /**
  468.      * @param Drink $drink
  469.      * @param string|null $language
  470.      * @return JsonResponse
  471.      * @Route("drink/{drink}", name="getDrinkDetail", requirements={"drink"="\d+"})
  472.      * @Route("{language}/drink/{drink}", name="getDrinkDetailLanguage", requirements={"drink"="\d+"})
  473.      */
  474.     public function getDrinkDetail(Drink $drink, ?string $language null): JsonResponse
  475.     {
  476.         if (is_null($language)) {
  477.             $institutionLocaleFronts $drink->getInstitution()->getInstitutionLocaleFronts();
  478.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  479.                 ->where(Criteria::expr()->eq('isDefault'true));
  480.             $language $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront()->getTag();
  481.         }
  482.         return new JsonResponse([
  483.             'success' => true,
  484.             'drink' => $this->mobileAppSerializeService->serializeDrink($drink$language),
  485.         ]);
  486.     }
  487.     /**
  488.      * @param Menu $menu
  489.      * @param string|null $language
  490.      * @return JsonResponse
  491.      * @Route("menu/{menu}", name="getMenuDetail", requirements={"menu"="\d+"})
  492.      * @Route("{language}/menu/{menu}", name="getMenuDetailLanguage", requirements={"menu"="\d+"})
  493.      */
  494.     public function getMenuDetail(Menu $menu, ?string $language null): JsonResponse
  495.     {
  496.         if (is_null($language)) {
  497.             $institutionLocaleFronts $menu->getInstitution()->getInstitutionLocaleFronts();
  498.             $defaultInstitutionLocaleFrontCriteria Criteria::create()
  499.                 ->where(Criteria::expr()->eq('isDefault'true));
  500.             $language $institutionLocaleFronts->matching($defaultInstitutionLocaleFrontCriteria)->first()->getLocaleFront()->getTag();
  501.         }
  502.         return new JsonResponse([
  503.             'success' => true,
  504.             'menu' => $this->mobileAppSerializeService->serializeMenu($menu$language),
  505.         ]);
  506.     }
  507.     /**
  508.      * @param Request $request
  509.      * @param string|null $language
  510.      * @return JsonResponse|void
  511.      * @Route("paired-wines", name="getPairedWines")
  512.      * @Route("{language}/paired-wines", name="getPairedWinesLanguage")
  513.      */
  514.     public function getPairedWines(Request $request, ?string $language null)
  515.     {
  516.         // Retrieve the parameters (the list of selected dishes id)
  517.         $data json_decode($request->getContent(), true);
  518.         $dishesId $data['dishesId'] ?? null;
  519.         $selectedDishes $data['selectedDishes'] ?? null;
  520.         // The final pairing list that will be return in the end (Json serialized format)
  521.         $winePairings = [];
  522.         $dishes = [];
  523.         if (!is_null($dishesId) || !is_null($selectedDishes)) {
  524.             $pairings = [];
  525.             if (!is_null($dishesId)) {
  526.                 // Find dishes by ID list
  527.                 $dishes $this->em->getRepository(Dish::class)->findBy(['id' => $dishesId]);
  528.             } elseif (!is_null($selectedDishes)) {
  529.                 // Extract IDs from selectedDishes
  530.                 $dishIds array_column($selectedDishes'id');
  531.                 $dishes $this->em->getRepository(Dish::class)->findBy(['id' => $dishIds]);
  532.             }
  533.             // Get every selected dishes
  534.             foreach ($dishes as $dish) {
  535.                 // Determine quantity (default 1 if not provided)
  536.                 if ($selectedDishes) {
  537.                     $sel array_filter($selectedDishes, fn($s) => $s['id'] == $dish->getId());
  538.                     $qty $sel ? (int)reset($sel)['quantity'] : 1;
  539.                 } else {
  540.                     $qty 1;
  541.                 }
  542.                 // For each of them, get the associated wines
  543.                 foreach ($dish->getWinePairings() as $winePairing) {
  544.                     $alreadyInsidePairings false;
  545.                     // Check if the wine is already in the list
  546.                     foreach ($pairings as $pairing) {
  547.                         // If the wine is already in the list, increase the matching count
  548.                         $currentPairingId $pairing->getWine()->getId();
  549.                         if ($currentPairingId == $winePairing->getWine()->getId()) {
  550.                             $alreadyInsidePairings true;
  551.                             // Increase the matching value considering quantity
  552.                             $pairing->setValue($pairing->getValue() + ($winePairing->getValue() * $qty));
  553.                             break;
  554.                         }
  555.                     }
  556.                     // If not already in the list, add it (with quantity applied)
  557.                     if (!$alreadyInsidePairings) {
  558.                         $winePairing->setValue($winePairing->getValue() * $qty);
  559.                         $pairings[] = $winePairing;
  560.                     }
  561.                 }
  562.             }
  563.             // Serialize pairings
  564.             foreach ($pairings as $pairing) {
  565.                 $serializedWinePairing $this->mobileAppSerializeService->serializeWinePairing($pairingfalsetrue$language);
  566.                 if (!is_null($serializedWinePairing)) {
  567.                     $winePairings[] = $serializedWinePairing;
  568.                 }
  569.             }
  570.             // Sort paired wines by value (best to worst)
  571.             usort($winePairings, function ($item1$item2) {
  572.                 return $item1['value'] <= $item2['value'];
  573.             });
  574.             return new JsonResponse([
  575.                 'success' => true,
  576.                 'winePairings' => $winePairings,
  577.             ]);
  578.         }
  579.         return new JsonResponse([
  580.             'success' => true,
  581.             'winePairings' => [],
  582.         ]);
  583.     }
  584.     /**
  585.      * @param Request $request
  586.      * @param string|null $language
  587.      * @return JsonResponse|void
  588.      * @Route("paired-beers", name="getPairedBeers")
  589.      * @Route("{language}/paired-beers", name="getPairedBeersLanguage")
  590.      */
  591.     public function getPairedBeers(Request $request, ?string $language null)
  592.     {
  593.         // Retrieve the parameters (the list of selected dishes id)
  594.         $data $request->getContent();
  595.         $data json_decode($datatrue);
  596.         $dishesId $data['dishesId'];
  597.         // The final pairing list that will be return in the end (Json serialized format)
  598.         $beerPairings = [];
  599.         if (!is_null($dishesId)) {
  600.             $pairings = [];
  601.             // Get every selected dishes
  602.             foreach ($dishesId as $dishId) {
  603.                 $dish $this->em->getRepository(Dish::class)->find($dishId);
  604.                 // For each of them, get the associated beers
  605.                 foreach ($dish->getBeerPairings() as $beerPairing) {
  606.                     // Check if the wine is already in the list
  607.                     $alreadyInsidePairings false;
  608.                     foreach ($pairings as $pairing) {
  609.                         // If the beer is already in the list, increase the matching count
  610.                         $currentPairingId $pairing->getBeer()->getId();
  611.                         if ($currentPairingId == $beerPairing->getBeer()->getId()) {
  612.                             $alreadyInsidePairings true;
  613.                             $pairing->setValue($pairing->getValue() + $beerPairing->getValue());
  614.                             break;
  615.                         }
  616.                     }
  617.                     // Else, if the beer is not already in the list, we need to add it
  618.                     if (!$alreadyInsidePairings) {
  619.                         $pairings[] = $beerPairing;
  620.                     }
  621.                 }
  622.             }
  623.             // Serialize pairings
  624.             foreach ($pairings as $pairing) {
  625.                 $serializedBeerPairing $this->mobileAppSerializeService->serializeBeerPairing($pairingfalsetrue$language);
  626.                 if (!is_null($serializedBeerPairing)) {
  627.                     $beerPairings[] = $serializedBeerPairing;
  628.                 }
  629.             }
  630.             // Sort paired wines by value (best to worst)
  631.             usort($beerPairings, function ($item1$item2) {
  632.                 return $item1['value'] <= $item2['value'];
  633.             });
  634.             return new JsonResponse([
  635.                 'success' => true,
  636.                 'beerPairings' => $beerPairings,
  637.             ]);
  638.         }
  639.     }
  640.     /**
  641.      * @param Request $request
  642.      * @return JsonResponse
  643.      * @Route("institution-review", name="getInstitutionReview")
  644.      */
  645.     public function getInstitutionReview(Request $request): JsonResponse
  646.     {
  647.         $data $request->getContent();
  648.         $data json_decode($datatrue);
  649.         $institutionId $data['restaurantId'];
  650.         $userAppId $data['userAppId'];
  651.         $institution $this->em->getRepository(Institution::class)->find($institutionId);
  652.         $institutionReviews $institution->getInstitutionReviews();
  653.         $criteria Criteria::create()
  654.             ->where(Criteria::expr()->eq('userAppId'$userAppId));
  655.         $userReview $institutionReviews->matching($criteria)->first();
  656.         if (!$userReview) {
  657.             return new JsonResponse([
  658.                 'success' => false,
  659.             ]);
  660.         }
  661.         return new JsonResponse([
  662.             'success' => true,
  663.             'institutionReview' => $this->mobileAppSerializeService->serializeInstitutionReview($userReview),
  664.         ]);
  665.     }
  666.     /**
  667.      * @param Request $request
  668.      * @return JsonResponse
  669.      * @Route("institution-review/create", name="setInstitutionReview")
  670.      */
  671.     public function setInstitutionReview(Request $request): JsonResponse
  672.     {
  673.         // Retrieve the review (contains appUserId, restaurantId, rating and comments)
  674.         $data $request->getContent();
  675.         $data json_decode($datatrue);
  676.         $review $data['review'];
  677.         if (!is_null($review)) {
  678.             $institution $this->em->getRepository(Institution::class)->find($review['restaurantId']);
  679.             $institutionReviews $institution->getInstitutionReviews();
  680.             $criteria Criteria::create()
  681.                 ->where(Criteria::expr()->eq('userAppId'$review['userAppId']));
  682.             $userReview $institutionReviews->matching($criteria)->first();
  683.             $institutionReview null;
  684.             $reviewTotalNumber count($institutionReviews);
  685.             $institutionReviewSummary $institution->getInstitutionReviewSummary();
  686.             if ($institution) {
  687.                 // Update the review if this user already rate this institution
  688.                 if ($userReview) {
  689.                     $previousRating $userReview->getRating();
  690.                     if ($reviewTotalNumber 1) {
  691.                         // Calculate the total score (average * number of reviews)
  692.                         $totalScore $institutionReviewSummary->getAverageReviewScore() * $reviewTotalNumber;
  693.                         $totalScore $totalScore $previousRating $review['rating'];
  694.                         $average $totalScore $reviewTotalNumber;
  695.                     } else {
  696.                         // Special case: there was only one review → the average simply becomes the new score
  697.                         $average $review['rating'];
  698.                     }
  699.                     $institutionReviewSummary->setAverageReviewScore($average);
  700.                     // Decrement the previous counter
  701.                     $this->decrementStarCount($institutionReviewSummary$previousRating);
  702.                     // Increment the new counter
  703.                     $this->incrementStarCount($institutionReviewSummary$review['rating']);
  704.                     $this->em->persist($institutionReviewSummary);
  705.                     $userReview->setRating($review['rating']);
  706.                     $userReview->setComments($review['comments'] ?: null);
  707.                     $userReview->setDate(new DateTime());
  708.                     $this->em->persist($userReview);
  709.                     $this->em->flush();
  710.                     return new JsonResponse([
  711.                         'success' => true,
  712.                         'institutionReview' => $this->mobileAppSerializeService->serializeInstitutionReview($userReview),
  713.                     ]);
  714.                     // Or create a new InstitutionReview otherwise
  715.                 } else {
  716.                     if (!$institutionReviewSummary) {
  717.                         $institutionReviewSummary = new InstitutionReviewSummary();
  718.                         $institutionReviewSummary->setAverageReviewScore($review['rating']);
  719.                         $institutionReviewSummary->setOneStarNumber(0);
  720.                         $institutionReviewSummary->setTwoStarNumber(0);
  721.                         $institutionReviewSummary->setThreeStarNumber(0);
  722.                         $institutionReviewSummary->setFourStarNumber(0);
  723.                         $institutionReviewSummary->setFiveStarNumber(0);
  724.                         $institutionReviewSummary->setInstitution($institution);
  725.                     } else {
  726.                         $averageScore $institutionReviewSummary->getAverageReviewScore();
  727.                         $newAverage $averageScore + (($review['rating'] - $averageScore) / ($reviewTotalNumber 1));
  728.                         $institutionReviewSummary->setAverageReviewScore($newAverage);
  729.                     }
  730.                     $this->incrementStarCount($institutionReviewSummary$review['rating']);
  731.                     $this->em->persist($institutionReviewSummary);
  732.                     $institutionReview = new InstitutionReview();
  733.                     $institutionReview->setUserAppId($review['userAppId']);
  734.                     $institutionReview->setRating($review['rating']);
  735.                     $institutionReview->setComments($review['comments'] ?: null);
  736.                     $institutionReview->setInstitution($institution);
  737.                     $institutionReview->setDate(new DateTime());
  738.                     $this->em->persist($institutionReview);
  739.                     $this->em->flush();
  740.                     return new JsonResponse([
  741.                         'success' => true,
  742.                         'institutionReview' => $this->mobileAppSerializeService->serializeInstitutionReview($institutionReview),
  743.                     ]);
  744.                 }
  745.             } else {
  746.                 return new JsonResponse([
  747.                     'success' => false,
  748.                 ]);
  749.             }
  750.         } else {
  751.             return new JsonResponse([
  752.                 'success' => false,
  753.             ]);
  754.         }
  755.     }
  756.     private function incrementStarCount(InstitutionReviewSummary $summaryint $rating): void
  757.     {
  758.         switch ($rating) {
  759.             case 1$summary->setOneStarNumber($summary->getOneStarNumber() + 1); break;
  760.             case 2$summary->setTwoStarNumber($summary->getTwoStarNumber() + 1); break;
  761.             case 3$summary->setThreeStarNumber($summary->getThreeStarNumber() + 1); break;
  762.             case 4$summary->setFourStarNumber($summary->getFourStarNumber() + 1); break;
  763.             case 5$summary->setFiveStarNumber($summary->getFiveStarNumber() + 1); break;
  764.         }
  765.     }
  766.     private function decrementStarCount(InstitutionReviewSummary $summaryint $rating): void
  767.     {
  768.         switch ($rating) {
  769.             case 1$summary->setOneStarNumber($summary->getOneStarNumber() - 1); break;
  770.             case 2$summary->setTwoStarNumber($summary->getTwoStarNumber() - 1); break;
  771.             case 3$summary->setThreeStarNumber($summary->getThreeStarNumber() - 1); break;
  772.             case 4$summary->setFourStarNumber($summary->getFourStarNumber() - 1); break;
  773.             case 5$summary->setFiveStarNumber($summary->getFiveStarNumber() - 1); break;
  774.         }
  775.     }
  776.     /**
  777.      * @param Institution $institution
  778.      * @param Request $request
  779.      * @return JsonResponse
  780.      * @Route("contest/tickets/{institution}", name="getTickets", requirements={"institution"="\d+"}))
  781.      */
  782.     public function getTickets(Institution $institutionRequest $request): JsonResponse
  783.     {
  784.         $data $request->getContent();
  785.         $data json_decode($datatrue);
  786.         $userAppId $data['userAppId'];
  787.         if (is_null($userAppId)) {
  788.             return new JsonResponse([
  789.                 'success' => false,
  790.             ]);
  791.         }
  792.         $userAppTickets = [];
  793.         $contests $institution->getContests();
  794.         foreach ($contests as $contest) {
  795.             $criteria Criteria::create()
  796.                 ->where(Criteria::expr()->eq('userAppId'$userAppId));
  797.             $contestTickets $contest->getContestTickets()->matching($criteria);
  798.             foreach ($contestTickets as $ticket) {
  799.                 $userAppTickets[] = $this->mobileAppSerializeService->serializeTicket($ticket);
  800.             }
  801.         }
  802.         return new JsonResponse([
  803.             'success' => true,
  804.             'tickets' => $userAppTickets,
  805.         ]);
  806.     }
  807.     /**
  808.      * @param Contest $contest
  809.      * @param Request $request
  810.      * @return JsonResponse
  811.      * @throws \Exception
  812.      * @Route("contest/draw/{contest}", name="draw", requirements={"contest"="\d+"}))
  813.      */
  814.     public function draw(Contest $contestRequest $request): JsonResponse
  815.     {
  816.         $data $request->getContent();
  817.         $data json_decode($datatrue);
  818.         $userAppId $data['userAppId'];
  819.         if (is_null($userAppId)) {
  820.             return new JsonResponse([
  821.                 'success' => false,
  822.             ]);
  823.         }
  824.         $now date_create();
  825.         $entryLimitTime $contest->getEntryLimitTime();
  826.         //on vérifie si l'utilisateur n'a pas déjà participé dans la période maximum
  827.         $criteria Criteria::create()
  828.             ->where(Criteria::expr()->eq('userAppId'$userAppId))
  829.             ->orderBy(array('enterAt' => Criteria::DESC));
  830.         /** @var ContestEntry $contestEntry */
  831.         $contestEntry $contest->getContestEntries()->matching($criteria)->first();
  832.         //si l'utilisateur a déjà participé
  833.         if ($contestEntry) {
  834.             //on vérifie si l'utilisateur peut participer à nouveau
  835.             $nextTicketDateTime = clone $contestEntry->getEnterAt();
  836.             $nextTicketDateTime->add(new DateInterval('PT' $entryLimitTime 'S'));
  837.             if ($now $nextTicketDateTime) {
  838.                 return new JsonResponse([
  839.                     'success' => false,
  840.                     'message' => "mobile user already got an entry on that period",
  841.                 ]);
  842.             }
  843.         }
  844.         //on ajoute une nouvelle participation au jeu concours
  845.         $contestEntry = new ContestEntry();
  846.         $contestEntry->setEnterAt($now);
  847.         $contestEntry->setContest($contest);
  848.         $contestEntry->setUserAppId($userAppId);
  849.         $this->em->persist($contestEntry);
  850.         //on vérifie si il existe un instant gagnant à cet instant
  851.         $criteria Criteria::create()
  852.             ->where(Criteria::expr()->lte('instantWinDate'$now))
  853.             ->andWhere(Criteria::expr()->eq('isWon'false));
  854.         /** @var ContestTicket $contestTicket */
  855.         $contestTicket $contest->getContestTickets()->matching($criteria)->first();
  856.         //si le ticket gagnant existe, on l'associe à l'utilisateur
  857.         if ($contestTicket) {
  858.             $contestTicket->setUserAppId($userAppId);
  859.             $contestTicket->setIsWon(true);
  860.             $contestTicket->setWonAt($now);
  861.             $this->em->persist($contestTicket);
  862.             $this->em->flush();
  863.             return new JsonResponse([
  864.                 'success' => true,
  865.                 'ticket' => $this->mobileAppSerializeService->serializeTicket($contestTicket)
  866.             ]);
  867.         }
  868.         //sinon le ticket est perdant
  869.         else {
  870.             $this->em->flush();
  871.             return new JsonResponse([
  872.                 'success' => true,
  873.                 'ticket' => false
  874.             ]);
  875.         }
  876.     }
  877.     /**
  878.      * @param Institution $institution
  879.      * @param Request $request
  880.      * @return JsonResponse
  881.      * @throws \Exception
  882.      * @Route("contest/access/{institution}", name="getAccess", requirements={"institution"="\d+"}))
  883.      */
  884.     public function getAccess(Institution $institutionRequest $request): JsonResponse
  885.     {
  886.         $data $request->getContent();
  887.         $data json_decode($datatrue);
  888.         $userAppId $data['userAppId'];
  889.         if (is_null($userAppId)) {
  890.             return new JsonResponse([
  891.                 'success' => false,
  892.             ]);
  893.         }
  894.         $now date_create();
  895.         //on récupère le premier jeu concours valide à cette date du restaurant /!\ 1 seul jeu concours possible pour la période donnée
  896.         $criteria Criteria::create()
  897.             ->where(Criteria::expr()->lte('startDate'$now))
  898.             ->andWhere(Criteria::expr()->gte('endDate'$now))
  899.             ->andWhere(Criteria::expr()->eq('isPlaying'true));
  900.         /** @var Contest $contest */
  901.         $contest $institution->getContests()->matching($criteria)->first();
  902.         if (!$contest) {
  903.             //pas de jeux concours en cours
  904.             return new JsonResponse([
  905.                 'success' => true,
  906.                 'access' => [
  907.                     'hasAccess' => false,
  908.                     'nextTicketTime' => null
  909.                 ]
  910.             ]);
  911.         }
  912.         $entryLimitTime $contest->getEntryLimitTime();
  913.         //on vérifie si l'utilisateur n'a pas déjà participé dans la période maximum
  914.         $criteria Criteria::create()
  915.             ->where(Criteria::expr()->eq('userAppId'$userAppId))
  916.             ->orderBy(array('enterAt' => Criteria::DESC));
  917.         /** @var ContestEntry $contestEntry */
  918.         $contestEntry $contest->getContestEntries()->matching($criteria)->first();
  919.         //si l'utilisateur a déjà participé
  920.         if ($contestEntry) {
  921.             //on vérifie si l'utilisateur a le droit à une nouvelle participation
  922.             $nextTicketDateTime = clone $contestEntry->getEnterAt();
  923.             $nextTicketDateTime->add(new DateInterval('PT' $entryLimitTime 'S'));
  924.             if ($now $nextTicketDateTime) {
  925.                 //participation disponible
  926.                 return new JsonResponse([
  927.                     'success' => true,
  928.                     'contestId' => $contest->getId(),
  929.                     'access' => [
  930.                         'hasAccess' => true,
  931.                         'nextTicketTime' => null,
  932.                         'type' => $contest->getType()
  933.                     ]
  934.                 ]);
  935.             } else {
  936.                 //tirage indisponible pour le moment
  937.                 return new JsonResponse([
  938.                     'success' => true,
  939.                     'contestId' => $contest->getId(),
  940.                     'access' => [
  941.                         'hasAccess' => false,
  942.                         'nextTicketTime' => date_diff($nextTicketDateTime$now),
  943.                         'type' => $contest->getType()
  944.                     ]
  945.                 ]);
  946.             }
  947.         } else {
  948.             //tirage disponible
  949.             return new JsonResponse([
  950.                 'success' => true,
  951.                 'contestId' => $contest->getId(),
  952.                 'access' => [
  953.                     'hasAccess' => true,
  954.                     'nextTicketTime' => null,
  955.                     'type' => $contest->getType()
  956.                 ]
  957.             ]);
  958.         }
  959.     }
  960.     /**
  961.      * @param Contest $contest
  962.      * @return JsonResponse
  963.      * @Route("contest/{contest}", name="getContest", requirements={"contest"="\d+"}))
  964.      */
  965.     public function getContest(Contest $contest): JsonResponse
  966.     {
  967.         return new JsonResponse([
  968.             'success' => true,
  969.             'contest' => $this->mobileAppSerializeService->serializeContest($contest)
  970.         ]);
  971.     }
  972. }