src/Twig/AppFunctions.php line 61

Open in your IDE?
  1. <?php
  2. namespace App\Twig;
  3. use App\Entity\Company;
  4. use App\Entity\Event;
  5. use App\Entity\ExternalCompany;
  6. use App\Entity\MarketplaceReservation;
  7. use App\Entity\Registration;
  8. use App\Entity\Specialist;
  9. use App\Entity\SpecialistEventApplication;
  10. use App\Entity\User;
  11. use App\Entity\VisioEvent;
  12. use App\Entity\Workshop;
  13. use App\Service\PriceService;
  14. use App\Service\ToolsService;
  15. use DateTime;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use LogicException;
  18. use Symfony\Component\Asset\Packages;
  19. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  20. use Symfony\Component\Security\Core\Security;
  21. use Symfony\Contracts\Translation\TranslatorInterface;
  22. use Twig\Extension\AbstractExtension;
  23. use Twig\TwigFunction;
  24. use Twig\TwigTest;
  25. use Vich\UploaderBundle\Storage\StorageInterface;
  26. use function Composer\Autoload\includeFile;
  27. class AppFunctions extends AbstractExtension
  28. {
  29.     /**
  30.      * @var Security
  31.      */
  32.     private $security;
  33.     /**
  34.      * @var EntityManagerInterface
  35.      */
  36.     private $em;
  37.     /**
  38.      * @var StorageInterface
  39.      */
  40.     private $storage;
  41.     /**
  42.      * @var Packages
  43.      */
  44.     private $packages;
  45.     /**
  46.      * @var UrlGeneratorInterFace
  47.      */
  48.     private $urlGeneratorInterface;
  49.     /**
  50.      * @var PriceService
  51.      */
  52.     private $priceService;
  53.     public function __construct(Security $securityEntityManagerInterface $emStorageInterface $storage,
  54.                                 Packages $packagesPriceService $priceServiceTranslatorInterface $translator,
  55.                                 UrlGeneratorInterface $urlGeneratorInterface) {
  56.         $this->security $security;
  57.         $this->em $em;
  58.         $this->storage $storage;
  59.         $this->packages $packages;
  60.         $this->priceService $priceService;
  61.         $this->translator $translator;
  62.         $this->urlGeneratorInterface $urlGeneratorInterface;
  63.     }
  64.     /**
  65.      * @return TwigTest[]
  66.      */
  67.     public function getTests(): array
  68.     {
  69.         return [
  70.             new TwigTest('image', [$this'isImage']),
  71.             new TwigTest('application_available', [$this'isEventApplicable']),
  72.         ];
  73.     }
  74.     /**
  75.      * Checks if the specialist can postulate to the event
  76.      * @param Event $event
  77.      * @return bool
  78.      */
  79.     public function isEventApplicable(Event $event): bool
  80.     {
  81.         $result false;
  82.         if ($this->security->getUser() != null && !$this->security->isGranted(User::ROLE_SPECIALIST)){
  83.             throw new LogicException('You are trying to use this filter with a non connected environnement or a wrong user');
  84.         }
  85.         if ($event->getStatus() == Event::STATUS_OPEN && $event->getStart() > new \DateTime()) {
  86.             $users $event->getApplications()->map(function ($element) {
  87.                 return $element->getSpecialist()->getUser()->getId();
  88.             });
  89.             if (!$users->contains($this->security->getUser()->getId())) {
  90.                 $result true;
  91.             }
  92.         }
  93.         return $result;
  94.     }
  95.     /**
  96.      * @param string $filename
  97.      * @return bool
  98.      */
  99.     public function isImage(string $filename): bool
  100.     {
  101.         $supported_image = array(
  102.             'gif',
  103.             'jpg',
  104.             'jpeg',
  105.             'png'
  106.         );
  107.         $ext strtolower(pathinfo($filenamePATHINFO_EXTENSION)); // Using strtolower to overcome case sensitive
  108.         if (in_array($ext$supported_image)) {
  109.             return true;
  110.         }
  111.         return false;
  112.     }
  113.     /**
  114.      * @return TwigFunction[]
  115.      */
  116.     public function getFunctions(): array
  117.     {
  118.         return [
  119.             new TwigFunction('clientCompany', [$this'getClientCompany']),
  120.             new TwigFunction('userCompany', [$this'getUserCompany']),
  121.             new TwigFunction('companyLogo', [$this'getCompanyLogo']),
  122.             new TwigFunction('applicationPrice', [$this'getApplicationPrice']),
  123.             new TwigFunction('badgeColor', [$this'getBadgeColor']),
  124.             new TwigFunction('displayDate', [$this'displayDate']),
  125.             new TwigFunction('generateDeleteModal', [$this'generateDeleteModal']),
  126.             new TwigFunction('displayEventStatus', [$this'displayEventStatus']),
  127.             new TwigFunction('displayAccessTitle', [$this'displayAccessTitle']),
  128.             new TwigFunction('estimatedSpecialistPrice', [$this'getEstimatedSpecialistPrice']),
  129.             new TwigFunction('generateCancelModal', [$this'generateCancelModal']),
  130.             new TwigFunction('generateEventCreationModal', [$this'generateEventCreationModal']),
  131.             new TwigFunction('visioCanceledPercent', [$this'visioCancelledPercentSpecialist']),
  132.             new TwigFunction('displaySpecialistStatus', [$this'displaySpecialistStatus']),
  133.             new TwigFunction('generateEventUrl', [$this'generateEventUrl']),
  134.             new TwigFunction('displayWorkshopType', [$this'displayWorkshopType']),
  135.             new TwigFunction('displayPaymentStatus', [$this'displayPaymentStatus']),
  136.             new TwigFunction('displayReservationStatus', [$this'displayReservationStatus']),
  137.             new TwigFunction('displayRegistrationStatus', [$this'displayRegistrationStatus']),
  138.             new TwigFunction('tradStatusVisio', [$this'tradStatusVisio']),
  139.         ];
  140.     }
  141.     /**
  142.      * @param SpecialistEventApplication $application
  143.      * @param Company $company
  144.      * @return float
  145.      */
  146.     public function getApplicationPrice(SpecialistEventApplication $applicationCompany $company): float
  147.     {
  148.         return $this->priceService->calculatePriceEvent($company$application);
  149.     }
  150.     /**
  151.      * @param Event $event
  152.      * @param Specialist $specialist
  153.      * @return float
  154.      */
  155.     public function getEstimatedSpecialistPrice(Event $eventSpecialist $specialist): float
  156.     {
  157.         return $this->priceService->calculateEstimatedSpecialistEventPrice($event$specialist);
  158.     }
  159.     /**
  160.      * @return Company|mixed|object|null
  161.      */
  162.     public function getClientCompany()
  163.     {
  164.         try {
  165.             $company $this->security->getUser()->getClient()->getCompany();
  166.         } catch (\Throwable $th) {
  167.             return null;
  168.         }
  169.         return $this->em->getRepository(Company::class)->findOneBy(['id' => $company->getId()]);
  170.     }
  171.     /**
  172.      * @return Company|null
  173.      */
  174.     public function getUserCompany(): ?Company
  175.     {
  176.         try {
  177.             $user $this->security->getUser();
  178.         } catch (\Throwable $th) {
  179.             throw new LogicException("User not connected");
  180.         }
  181.         $company  $this->em->getRepository(Company::class)->findOneBy(['user' => $user->getId()]);
  182.         if (!$company instanceof Company){
  183.             throw new LogicException("Calling a company on a non company user");
  184.         }
  185.         return $company;
  186.     }
  187.     /**
  188.      * Returns company logo url depending on if it's external or not
  189.      *
  190.      * @param Company|null $company
  191.      * @return string|null
  192.      */
  193.     public function getCompanyLogo(Company $company null): ?string
  194.     {
  195.         try {
  196.             $company $company ?? $this->getUserCompany();
  197.             return $this->storage->resolveUri($company'imageFile'Company::class);
  198.         }catch (\Exception $e){
  199.             return $this->packages->getUrl('build/images/toreplace.jpg');
  200.         }
  201.     }
  202.     public function getBadgeColor($value, array $configs null): ?string
  203.     {
  204.         $color "success";
  205.         $configs = [
  206.             'colors' => ["danger""warning""success"],
  207.             'steps' => [
  208.                 ["min" => 0"max" => 25],
  209.                 ["min" => 25"max" => 50],
  210.                 ["min" => 50"max" => 100],
  211.             ],
  212.         ];
  213.         foreach($configs['steps'] as $key => $stepConfig) {
  214.             if($value >= $stepConfig['min'] && $value $stepConfig['max'])
  215.                 $color $configs['colors'][$key];
  216.         }
  217.         return $color;
  218.     }
  219.     public function displayDate($value$return 'full')
  220.     {
  221.         if ($value instanceof DateTime) {
  222.             if($return == 'date') {
  223.                 return $value->format('d/m/Y');
  224.             }else if($return == 'date-text') {
  225.                 return $value->format('d')." ".ToolsService::getFrenchMonths($value->format('m'));
  226.             }else if($return == 'date-text-year') {
  227.                 return $value->format('d')." ".ToolsService::getFrenchMonths($value->format('m'))." ".$value->format('Y');
  228.             }else if($return == 'time') {
  229.                 return $value->format('H') ."H"$value->format('i');
  230.             }else if($return == 'no-seconds'){
  231.                 return $value->format('d/m/Y H')."H"$value->format('i');
  232.             }else if($return == 'text'){
  233.                 return $value->format('d')." ".ToolsService::getFrenchMonths($value->format('m'))." à "$value->format('H') ."H"$value->format('i');
  234.             } else if($return == 'full-text') {
  235.                 return $value->format('d')." ".ToolsService::getFrenchMonths($value->format('m'))." ".$value->format('Y')." à "$value->format('H') ."H"$value->format('i');
  236.             }
  237.             return  $value->format('d/m/Y H:i:s');
  238.         }else{
  239.             return "";
  240.         }
  241.     }
  242.     public function generateDeleteModal($myModalDatas)
  243.     {
  244.         $default = array(
  245.             'buttonText'        => $this->translator->trans('delete', [], 'commun'),
  246.             'buttonClass'       => "btn btn-danger btn-sm me-1",
  247.             'modalTitle'        => $this->translator->trans('modal.delete.title', [], 'commun'),
  248.             'modalCloseText'    => $this->translator->trans('close', [], 'commun'),
  249.             'modalAcceptText'   => $this->translator->trans('accept', [], 'commun'),
  250.             'modalDeactivateText' => $this->translator->trans('deactivate', [], 'commun'),
  251.             'modalActivateText' => $this->translator->trans('activate', [], 'commun'),
  252.         );
  253.         $deactivateCTA '';
  254.         if (!empty($myModalDatas['deactivateUrl'])) {
  255.             if ($myModalDatas['deactivate'] == true) {
  256.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalDeactivateText'] . '</a>';
  257.             }else{
  258.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalActivateText'] . '</a>';
  259.             }
  260.         }
  261.         $myModalDatas array_merge($default$myModalDatas);
  262.         return '<button type="button" class="'.$myModalDatas['buttonClass'].'" data-bs-toggle="modal" data-bs-target="#delete' $myModalDatas['id'] . '">
  263.                     <i data-feather="trash"></i>
  264.                 </button>
  265.                 <div class="modal fade text-start modal-warning" id="delete' $myModalDatas['id'] . '" tabindex="-1" aria-labelledby="deleteModalLabel' $myModalDatas['id'] . '" style="display: none;" aria-hidden="true">
  266.                     <div class="modal-dialog modal-dialog-centered">
  267.                         <div class="modal-content">
  268.                             <div class="modal-header">
  269.                                 <h5 class="modal-title" id="deleteModalLabel' $myModalDatas['id'] . '">' $myModalDatas['modalTitle'] . '</h5>
  270.                                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  271.                             </div>
  272.                             <div class="modal-body">
  273.                                 ' $this->translator->trans('modal.delete.text10', [], 'commun') . '<br>
  274.                                 <b>' $myModalDatas['label'] . '</b>.<br>
  275.                                 ' $this->translator->trans('modal.delete.text20', [], 'commun') . '<br>
  276.                                 ' $this->translator->trans('modal.delete.text40', [], 'commun') . '
  277.                             </div>
  278.                             <div class="modal-footer">
  279.                             <button type="button" class="btn btn-dark waves-effect waves-float waves-light" data-bs-dismiss="modal">' $myModalDatas['modalCloseText'] . '</button>
  280.                             ' .$deactivateCTA'
  281.                             <a href="' $myModalDatas['deleteUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $myModalDatas['modalAcceptText'] . '</a>
  282.                             </div>
  283.                         </div>
  284.                     </div>
  285.                 </div>';
  286.     }
  287.     public function generateEventCreationModal($myModalDatas)
  288.     {
  289.         $default = array(
  290.             'buttonText'        => $this->translator->trans('delete', [], 'commun'),
  291.             'buttonClass'       => "btn btn-success btn-sm me-1",
  292.             'modalTitle'        => $this->translator->trans('modal.delete.title', [], 'commun'),
  293.             'modalCloseText'    => $this->translator->trans('close', [], 'commun'),
  294.             'modalCreateEventText'   => $this->translator->trans('modal.create_event.create_text', [], 'commun'),
  295.             'modalCreateRoomText'   => $this->translator->trans('modal.create_event.create_room', [], 'commun'),
  296.             'modalDeactivateText' => $this->translator->trans('deactivate', [], 'commun'),
  297.             'modalActivateText' => $this->translator->trans('activate', [], 'commun'),
  298.         );
  299.         $deactivateCTA '';
  300.         if (!empty($myModalDatas['deactivateUrl'])) {
  301.             if ($myModalDatas['deactivate'] == true) {
  302.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalDeactivateText'] . '</a>';
  303.             }else{
  304.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalActivateText'] . '</a>';
  305.             }
  306.         }
  307.         $myModalDatas array_merge($default$myModalDatas);
  308.         return '<button type="button" class="'.$myModalDatas['buttonClass'].'" data-bs-toggle="modal" data-bs-target="#delete' $myModalDatas['id'] . '">
  309.                     <i data-feather="plus-square"></i>
  310.                 </button>
  311.                 <div class="modal fade text-start modal-warning" id="delete' $myModalDatas['id'] . '" tabindex="-1" aria-labelledby="deleteModalLabel' $myModalDatas['id'] . '" style="display: none;" aria-hidden="true">
  312.                     <div class="modal-dialog modal-dialog-centered">
  313.                         <div class="modal-content">
  314.                             <div class="modal-header">
  315.                                 <h5 class="modal-title" id="deleteModalLabel' $myModalDatas['id'] . '">' $myModalDatas['modalTitle'] . '</h5>
  316.                                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  317.                             </div>
  318.                             <div class="modal-body text-wrap">
  319.                                 ' $this->translator->trans('modal.create_event.text10', [], 'commun') . '<br>
  320.                                 <b>' $myModalDatas['companyName'] . '</b>.<br>
  321.                                 ' $this->translator->trans('modal.create_event.text20', [], 'commun') . '<br>
  322.                                 ' $this->translator->trans('modal.create_event.text40', [], 'commun') . '
  323.                             </div>
  324.                             <div class="modal-footer">
  325.                             <button type="button" class="btn btn-dark waves-effect waves-float waves-light" data-bs-dismiss="modal">' $myModalDatas['modalCloseText'] . '</button>
  326.                             ' .$deactivateCTA'
  327.                             <a href="' $myModalDatas['createRoomUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $myModalDatas['modalCreateRoomText'] . '</a>
  328.                             </div>
  329.                         </div>
  330.                     </div>
  331.                 </div>';
  332.     }
  333.     public function generateCancelModal($myModalDatas)
  334.     {
  335.         $default = array(
  336.             'buttonText'        => $this->translator->trans('cancel', [], 'commun'),
  337.             'modalTitle'        => $this->translator->trans('modal.cancel.title', [], 'commun'),
  338.             'modalCloseText'    => $this->translator->trans('close', [], 'commun'),
  339.             'modalAcceptText'   => $this->translator->trans('accept', [], 'commun'),
  340.             'modalDeactivateText' => $this->translator->trans('deactivate', [], 'commun'),
  341.             'modalActivateText' => $this->translator->trans('activate', [], 'commun'),
  342.             'buttonClass'       => "btn btn-warning btn-sm me-1",
  343.             'redirectRoute'     => "admin_event_index",
  344.             'buttonContent'     => "<i data-feather='x-circle'></i>",
  345.             'buttonDisabled'    => false,
  346.         );
  347.         $deactivateCTA '';
  348.         if (!empty($myModalDatas['deactivateUrl'])) {
  349.             if ($myModalDatas['deactivate'] == true) {
  350.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalDeactivateText'] . '</a>';
  351.             }else{
  352.                 $deactivateCTA '<a href="' $myModalDatas['deactivateUrl'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $default['modalActivateText'] . '</a>';
  353.             }
  354.         }
  355.         $myModalDatas array_merge($default$myModalDatas);
  356.         if ($myModalDatas['buttonDisabled'] == true$myModalDatas['buttonClass'] .= " disabled";
  357.         $text20 = (isset($myModalDatas['isFree']) && $myModalDatas['isFree'] == false) ? $this->translator->trans('modal.cancel.text20', [], 'commun') : '';
  358.         return '<button type="button" class="'.$myModalDatas['buttonClass'].'" data-bs-toggle="modal" data-bs-target="#cancel' $myModalDatas['id'] . '">'
  359.                     .$myModalDatas['buttonContent'].
  360.                 '</button>
  361.                 <div class="modal fade text-start modal-warning" id="cancel' $myModalDatas['id'] . '" tabindex="-1" aria-labelledby="cancelModalLabel' $myModalDatas['id'] . '" style="display: none;" aria-hidden="true">
  362.                     <div class="modal-dialog modal-dialog-centered">
  363.                         <div class="modal-content">
  364.                             <div class="modal-header">
  365.                                 <h5 class="modal-title" id="cancelModalLabel' $myModalDatas['id'] . '">' $myModalDatas['modalTitle'] . '</h5>
  366.                                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  367.                             </div>
  368.                             <div class="modal-body">
  369.                                 ' $this->translator->trans('modal.cancel.text10', [], 'commun') . '<br>
  370.                                 <b>' $myModalDatas['label'] . '</b>.<br>
  371.                                 ' $text20 '<br>
  372.                                 ' $this->translator->trans('modal.cancel.text40', [], 'commun') . '
  373.                             </div>
  374.                             <div class="modal-footer">
  375.                             <button type="button" class="btn btn-dark waves-effect waves-float waves-light" data-bs-dismiss="modal">' $myModalDatas['modalCloseText'] . '</button>
  376.                             ' .$deactivateCTA'
  377.                             <a href="' $myModalDatas['cancelUrl'] . '?redirect_route=' $myModalDatas['redirectRoute'] . '" class="btn btn-warning waves-effect waves-float waves-light">' $myModalDatas['modalAcceptText'] . '</a>
  378.                             </div>
  379.                         </div>
  380.                     </div>
  381.                 </div>';
  382.     }
  383.     public function displayEventStatus($eventStatus)
  384.     {
  385.         if ($eventStatus != null) {
  386.             if ($eventStatus == "open") {
  387.                 return "En attente d'expert";
  388.             } else if ($eventStatus == "canceled") {
  389.                 return "Annulé";
  390.             } else if ($eventStatus == "finished") {
  391.                 return "Terminé";
  392.             } else if ($eventStatus == "valid") {
  393.                 return "A venir";
  394.             }
  395.         }
  396.         return "-";
  397.     }
  398.     /**
  399.      * @param Specialist $specialist
  400.      * @return array
  401.      */
  402.     public function visioCancelledPercentSpecialist(Specialist $specialist): array
  403.     {
  404.         return $this->em->getRepository(VisioEvent::class)->getCancelRatioSpecialist($specialist);
  405.     }
  406.     public function displayAccessTitlestring $envSlug)
  407.     {
  408.         if ($envSlug != null) {
  409.             if ($envSlug == "admin") {
  410.                 return "Accès <br> Admin";
  411.             }else if ($envSlug == "expert") {
  412.                  return "Accès <br> Expert";
  413.             }else if ($envSlug == "company") {
  414.                 return "Accès <br> Entreprise";
  415.             }else if ($envSlug == "client") {
  416.                 return "Plateforme de réservation <br> de vos cours et ateliers";
  417.             }
  418.          }else{
  419.              return "Plateforme de réservation <br> de vos cours et ateliers";
  420.          }
  421.     }
  422.     public function displaySpecialistStatus($specialistStatus)
  423.     {
  424.         if ($specialistStatus != null) {
  425.            if ($specialistStatus == "granted") {
  426.                return "Accepté";
  427.            }else if ($specialistStatus == "refused") {
  428.                 return "Refusé";
  429.            }else if ($specialistStatus == "waiting_ulteam_confirmation") {
  430.                return "En attente de validation";
  431.            }else if ($specialistStatus == "waiting_mail_confirmation") {
  432.                return "Doit valider son mail";
  433.            }
  434.         }else{
  435.             return "-";
  436.         }
  437.     }
  438.     public function generateEventUrl($eventId)
  439.     {
  440.         return $this->urlGeneratorInterface->generate('admin_event_edit', ['id' => $eventId], UrlGeneratorInterface::ABSOLUTE_URL);;
  441.     }
  442.     public function displayWorkshopType(Workshop $workshop)
  443.     {
  444.         if ($workshop instanceof Workshop) {
  445.             if ($workshop->getIsVirtual() == true) {
  446.                 return "Atelier virtuel";
  447.             } else if ($workshop->getIsVirtual() == false) {
  448.                 return "Atelier collectif";
  449.             } 
  450.         }
  451.         return "-";
  452.     }
  453.     /**
  454.      * Pour le payment status des MarketplaceReservation 
  455.      * @param String $paymentStatus
  456.      * @return String
  457.      */
  458.     public function displayPaymentStatus(string $paymentStatus)
  459.     {
  460.         return ToolsService::displayPaymentStatus($paymentStatus);
  461.     }
  462.     /**
  463.      * Pour le status des MarketplaceReservation
  464.      * @param String $reservationStatus
  465.      * @return String
  466.      */
  467.     public function displayReservationStatus(string $reservationStatus)
  468.     {
  469.         return ToolsService::displayReservationStatus($reservationStatus);
  470.     }
  471.     /**
  472.      * Pour le status des Registration 
  473.      * @param String $registrationStatus
  474.      * @return String
  475.      */
  476.     public function displayRegistrationStatus(String $registrationStatus)
  477.     {
  478.         return ToolsService::displayRegistrationStatus($registrationStatus);
  479.     }
  480.     /**
  481.      * Permet de traduire les status des visio dans les Statistiques
  482.      * @param String $status
  483.      * @return String
  484.      */
  485.     public function tradStatusVisio(string $status): String
  486.     {
  487.         return ToolsService::tradStatusVisio($status);
  488.     }
  489. }