src/Controller/SignalController.php line 491

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\User;
  4. use App\Manager\AreaManagerInterface;
  5. use App\Manager\ContractManagerInterface;
  6. use App\Manager\OrganizationManagerInterface;
  7. use App\Manager\SignalManagerInterface;
  8. use App\Manager\UserManagerInterface;
  9. use App\Models\Heimdall\Service;
  10. use Psr\Log\LoggerInterface;
  11. use Swagger\Annotations as SWG;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\HttpFoundation\JsonResponse;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\Routing\Annotation\Route;
  17. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  18. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  19. class SignalController extends AbstractController
  20. {
  21.     protected AreaManagerInterface $areaManager;
  22.     protected ContractManagerInterface $contractManager;
  23.     protected LoggerInterface $logger;
  24.     protected NormalizerInterface $normalizer;
  25.     protected SignalManagerInterface $signalManager;
  26.     protected UserManagerInterface $userManager;
  27.     protected OrganizationManagerInterface $organizationManager;
  28.     public function __construct(
  29.         AreaManagerInterface $areaManager,
  30.         ContractManagerInterface $contractManager,
  31.         LoggerInterface $logger,
  32.         NormalizerInterface $normalizer,
  33.         SignalManagerInterface $signalManager,
  34.         UserManagerInterface $userManager,
  35.         OrganizationManagerInterface $organizationManager
  36.     ) {
  37.         $this->areaManager $areaManager;
  38.         $this->contractManager $contractManager;
  39.         $this->logger $logger;
  40.         $this->normalizer $normalizer;
  41.         $this->signalManager $signalManager;
  42.         $this->userManager $userManager;
  43.         $this->organizationManager $organizationManager;
  44.     }
  45.     /**
  46.      * Get all Signal.
  47.      *
  48.      * @Route("/api/signal.{format}", name="get_signals" , defaults={"format": "json"},  methods={"GET"})
  49.      *
  50.      * @SWG\Get (
  51.      *      path="/api/signal.{format}",
  52.      *      tags={"Signal"},
  53.      *      summary="Get filtered signals",
  54.      * @SWG\Parameter(
  55.      *        name="format",
  56.      *        in="path",
  57.      *        type="string",
  58.      *        enum={"json","xml","csv","geojson"},
  59.      *        default="json",
  60.      *        description="Technical attribute to manage output format without header 'Accept' data",
  61.      *        required=true
  62.      * ),
  63.      * @SWG\Parameter(
  64.      *     name="q",
  65.      *     in="query",
  66.      *     type="string",
  67.      *     description="Search",
  68.      *     required=false
  69.      * ),
  70.      * @SWG\Parameter(
  71.      *     name="filter[ownerApplication][]",
  72.      *     in="query",
  73.      *     type="array",
  74.      *     @SWG\Items(type="string"),
  75.      *     collectionFormat="multi",
  76.      *     description="The owner Application code (created by)",
  77.      *     required=false
  78.      * ),
  79.      * @SWG\Parameter(
  80.      *     name="filter[creatorApplication][]",
  81.      *     in="query",
  82.      *     type="array",
  83.      *     @SWG\Items(type="string"),
  84.      *     collectionFormat="multi",
  85.      *     description="The creator application id (created for)",
  86.      *     required=false
  87.      * ),
  88.      * @SWG\Parameter(
  89.      *     name="filter[requestType][]",
  90.      *     in="query",
  91.      *     type="array",
  92.      *     @SWG\Items(type="string"),
  93.      *     collectionFormat="multi",
  94.      *     description="The specific type of request",
  95.      *     required=false
  96.      * ),
  97.      * @SWG\Parameter(
  98.      *     name="filter[comment][]",
  99.      *     in="query",
  100.      *     type="array",
  101.      *     @SWG\Items(type="string"),
  102.      *     collectionFormat="multi",
  103.      *     description="The specific comment of request (part of text)",
  104.      *     required=false
  105.      * ),
  106.      * @SWG\Parameter(
  107.      *     name="filter[languageCode][]",
  108.      *     in="query",
  109.      *     type="array",
  110.      *     @SWG\Items(type="string"),
  111.      *     collectionFormat="multi",
  112.      *     description="The language code of the request",
  113.      *     required=false
  114.      * ),
  115.      * @SWG\Parameter(
  116.      *     name="filter[applicationUser][]",
  117.      *     in="query",
  118.      *     type="array",
  119.      *     @SWG\Items(type="string"),
  120.      *     collectionFormat="multi",
  121.      *     description="The user of the request",
  122.      *     required=false
  123.      * ),
  124.      * @SWG\Parameter(
  125.      *     name="filter[thirdParty][]",
  126.      *     in="query",
  127.      *     type="array",
  128.      *     @SWG\Items(type="string"),
  129.      *     collectionFormat="multi",
  130.      *     description="The thirdParty of the request",
  131.      *     required=false
  132.      * ),
  133.      * @SWG\Parameter(
  134.      *     name="filter[siret][]",
  135.      *     in="query",
  136.      *     type="array",
  137.      *     @SWG\Items(type="string"),
  138.      *     collectionFormat="multi",
  139.      *     description="The user of the request",
  140.      *     required=false
  141.      * ),
  142.      * @SWG\Parameter(
  143.      *     name="filter[status][]",
  144.      *     in="query",
  145.      *     type="array",
  146.      *     @SWG\Items(type="string"),
  147.      *     collectionFormat="multi",
  148.      *     description="The id of the current status of the request",
  149.      *     required=false
  150.      * ),
  151.      * @SWG\Parameter(
  152.      *     name="timeline",
  153.      *     in="query",
  154.      *     type="boolean",
  155.      *     description="Display timeLine",
  156.      *     required=false
  157.      * ),
  158.      * @SWG\Parameter(
  159.      *     name="filter[createdAt][start]",
  160.      *     in="query",
  161.      *     type="string",
  162.      *     format="date-time",
  163.      *     description="Start date to filter the creation date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  164.      *     required=false
  165.      * ),
  166.      * @SWG\Parameter(
  167.      *     name="filter[createdAt][end]",
  168.      *     in="query",
  169.      *     type="string",
  170.      *     format="date-time",
  171.      *     description="End date to filter the creation date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  172.      *     required=false
  173.      * ),
  174.      * @SWG\Parameter(
  175.      *     name="filter[updatedAt][start]",
  176.      *     in="query",
  177.      *     type="string",
  178.      *     format="date-time",
  179.      *     description="Start date to filter the modification date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  180.      *     required=false
  181.      * ),
  182.      * @SWG\Parameter(
  183.      *     name="filter[updatedAt][end]",
  184.      *     in="query",
  185.      *     type="string",
  186.      *     format="date-time",
  187.      *     description="End date to filter the modification date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  188.      *     required=false
  189.      * ),
  190.      * @SWG\Parameter(
  191.      *     name="filter[receiptDate][start]",
  192.      *     in="query",
  193.      *     type="string",
  194.      *     format="date-time",
  195.      *     description="Start date to filter the receipt date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  196.      *     required=false
  197.      * ),
  198.      *     @SWG\Parameter(
  199.      *         name="filter[receiptDate][end]",
  200.      *         in="query",
  201.      *         type="string",
  202.      *         format="date-time",
  203.      *         description="End date to filter the receipt date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  204.      *         required=false
  205.      *     ),
  206.      *    @SWG\Parameter(
  207.      *         name="filter[deadlineResponseDate][start]",
  208.      *         in="query",
  209.      *         type="string",
  210.      *         format="date-time",
  211.      *         description="Start date to filter the deadline response date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  212.      *         required=false
  213.      *     ),
  214.      *     @SWG\Parameter(
  215.      *         name="filter[deadlineResponseDate][end]",
  216.      *         in="query",
  217.      *         type="string",
  218.      *         format="date-time",
  219.      *         description="End date to filter the deadline response date (ISO 8601, ex : 2016-01-01T00:00:00Z)",
  220.      *         required=false
  221.      *     ),
  222.      *     @SWG\Parameter(
  223.      *         name="filterFields[]",
  224.      *         in="query",
  225.      *         type="array",
  226.      *         @SWG\Items(type="string"),
  227.      *         collectionFormat="multi",
  228.      *         description="Filter fields, to filter one by one some fields. Each line have format : ```<fieldName><operator>[<valuesCommaSeparator>]```. Operator can be ```__EQ__, __EQS__, __RANGE__, __LT__, __GT__, __EQLT__, __EQGT__, __NULLGT__, __NULLLT__, __IS__, __ISNOT__```",
  229.      *         required=false
  230.      *     ),
  231.      *     @SWG\Parameter(
  232.      *         name="context[type][]",
  233.      *         in="query",
  234.      *         type="array",
  235.      *         @SWG\Items(type="string"),
  236.      *         collectionFormat="multi",
  237.      *         required=false
  238.      *     ),
  239.      *     @SWG\Parameter(
  240.      *         name="context[id][]",
  241.      *         in="query",
  242.      *         type="array",
  243.      *         @SWG\Items(type="string"),
  244.      *     ),
  245.      *     @SWG\Parameter(
  246.      *         name="context[condition][]",
  247.      *         in="query",
  248.      *         type="array",
  249.      *         @SWG\Items(type="string"),
  250.      *     ),
  251.      *     @SWG\Parameter(
  252.      *         name="sort[fields][]",
  253.      *         in="query",
  254.      *         type="array",
  255.      *         @SWG\Items(type="string"),
  256.      *         collectionFormat="multi",
  257.      *         description="Name of the field to sort",
  258.      *         required=false
  259.      *     ),
  260.      *     @SWG\Parameter(
  261.      *         name="sort[order][]",
  262.      *         in="query",
  263.      *         type="array",
  264.      *         @SWG\Items(type="string"),
  265.      *         collectionFormat="multi",
  266.      *         description="The way to order (asc or desc)",
  267.      *         required=false
  268.      *     ),
  269.      *     @SWG\Parameter(
  270.      *         name="pagination[page]",
  271.      *         in="query",
  272.      *         type="integer",
  273.      *         description="Current page",
  274.      *         required=false
  275.      *     ),
  276.      *     @SWG\Parameter(
  277.      *         name="pagination[size]",
  278.      *         in="query",
  279.      *         description="Items per page",
  280.      *         required=false,
  281.      *         type="integer"
  282.      *     ),
  283.      *     @SWG\Parameter(
  284.      *         name="exportFields[]",
  285.      *         in="query",
  286.      *         type="array",
  287.      *         @SWG\Items(type="string"),
  288.      *         collectionFormat="multi",
  289.      *         description="Fields to export",
  290.      *         required=false
  291.      *     ),
  292.      *     @SWG\Parameter(
  293.      *         name="exportLabels[]",
  294.      *         in="query",
  295.      *         type="array",
  296.      *         @SWG\Items(type="string"),
  297.      *         collectionFormat="multi",
  298.      *         description="Labels for export",
  299.      *         required=false
  300.      *     ),
  301.      *     @SWG\Parameter(
  302.      *         name="distance[length]",
  303.      *         in="query",
  304.      *         type="number",
  305.      *         description="The distance is in meter.",
  306.      *         required=false
  307.      *     ),
  308.      *     @SWG\Parameter(
  309.      *         name="distance[latitude]",
  310.      *         in="query",
  311.      *         type="number",
  312.      *         description="latitude",
  313.      *         required=false
  314.      *     ),
  315.      *     @SWG\Parameter(
  316.      *         name="distance[longitude]",
  317.      *         in="query",
  318.      *         type="number",
  319.      *         description="longitude",
  320.      *         required=false
  321.      *     ),
  322.      *     @SWG\Parameter(
  323.      *         name="withStatuses",
  324.      *         in="query",
  325.      *         type="boolean",
  326.      *         description="Display all statuses",
  327.      *         required=false
  328.      *     ),
  329.      *     @SWG\Response(
  330.      *         response="200",
  331.      *         description="Returned when successful"
  332.      *     )
  333.      *)
  334.      *
  335.      * @return JsonResponse
  336.      *
  337.      * @throws \App\Exception\UserNotFoundException
  338.      */
  339.     public function getSignalements(Request $requeststring $format)
  340.     {
  341.         $parameters $request->query->all();
  342.         /** @var User $user */
  343.         $user $this->getUser();
  344.         $userHeimdall $this->userManager->findUser($user->getUsername());
  345.         $contractId $user->getCurrentContractId();
  346.         $geojson $this->areaManager->getUserGeoJsonByService(
  347.             $userHeimdall,
  348.             [Service::SIGNAL_NOTIFY_SERVICE_CODE], $contractId
  349.         ); 
  350.         if (empty($geojson)) {
  351.             $this->logger->error(
  352.                 sprintf (
  353.                     'Error getting user\'s geojson %s by services %s',
  354.                     $user->getUsername(),
  355.                     Service::SIGNAL_NOTIFY_SERVICE_CODE
  356.                 )
  357.             );
  358.             return new JsonResponse([]);
  359.         }
  360.         $parameters $this->addRequestTypeFiltersByUser($parameters);
  361.         /** @var array $signals */
  362.         $signals$this->signalManager->getFilteredSignals(['query' => $parameters'body' => $geojson], $format);
  363.         return new JsonResponse($signals["data"], Response::HTTP_OK$signals["headers"]);
  364.     }
  365.     /**
  366.      * Get one Signal.
  367.      *
  368.      * @Route("/api/signal/{signalId}", name="get_one_signal", methods={"GET"})
  369.      *
  370.      * @SWG\Get (
  371.      *      path="/api/signal/{signalId}",
  372.      *      tags={"Signal"},
  373.      *      summary="Get one signal",
  374.      *      @SWG\Parameter(
  375.      *          name="signalId",
  376.      *          in="path",
  377.      *          type="string",
  378.      *          description="The signal unique id",
  379.      *          required=true
  380.      *      ),
  381.      *      @SWG\Parameter(
  382.      *          name="withTranslationKey",
  383.      *          in="query",
  384.      *          type="boolean",
  385.      *          description="If true, add translationKey to response",
  386.      *          required=false
  387.      *      ),
  388.      *      @SWG\Response(
  389.      *          response="200",
  390.      *          description="Returned when successful"
  391.      *      ),
  392.      *      @SWG\Response(
  393.      *          response=403,
  394.      *          description="Access denied. You do not have permission to view this request."
  395.      *      ),
  396.      *      @SWG\Response(
  397.      *          response="404",
  398.      *          description="Returned when the signal is not found"
  399.      *      )
  400.      * )
  401.      *
  402.      * @param string $signalId
  403.      *
  404.      * @return JsonResponse
  405.      *
  406.      * @throws ClientExceptionInterface
  407.      */
  408.     public function getOne(string $signalIdRequest $request): JsonResponse
  409.     {
  410.         $withTranslationKey json_decode($request->query->get('withTranslationKey'));
  411.         $withStatuses json_decode($request->query->get('withStatuses'));
  412.         $signal $this->signalManager->getSignalById($signalId$this->getUser(), $withTranslationKey$withStatuses);
  413.        
  414.         return new JsonResponse($signalResponse::HTTP_OK);
  415.     }
  416.     private function addRequestTypeFiltersByUser(array $parameters): array
  417.     {
  418.         /** @var User $user */
  419.         $user $this->getUser();
  420.         $contractId $user->getCurrentContractId();
  421.         $userRequestTypes $this->signalManager->getUserOrganizationsRequestTypes($user->getHeimdallId(), $contractId);
  422.         $userRequestTypesToFilter array_filter(
  423.             $parameters['filter']['requestType'] ?? [],
  424.             fn($requestType) => in_array($requestType$userRequestTypes)
  425.         );
  426.         $parameters['filter']['requestType'] = $userRequestTypesToFilter;
  427.         return $parameters;
  428.     }
  429.     /**
  430.      * Get all Signal.
  431.      *
  432.      * @Route("/api/requestTypes", name="get_signal_request_types", methods={"GET"})
  433.      *
  434.      * @SWG\Get (
  435.      *      path="/api/requestTypes",
  436.      *      tags={"Signal"},
  437.      *      summary="Get all request types from signal organizations",
  438.      *      @SWG\Response(
  439.      *          response="200",
  440.      *          description="Returned when successful"
  441.      *      )
  442.      * )
  443.      *
  444.      * @param Request $request
  445.      * @return JsonResponse
  446.      */
  447.     public function getSignalRequestTypes(Request $request): JsonResponse
  448.     {
  449.         $parameters $request->query->all();
  450.         $signals$this->signalManager->getSignalRequestTypes(['query' => $parameters]);
  451.         return new JsonResponse($signals["data"], Response::HTTP_OK$signals["headers"]);
  452.     }
  453.     /**
  454.      * Get top category signal in user perimeter.
  455.      *
  456.      * @Route("/api/widget/signal/top-category/{length}", name="get_signal_top_category",  methods={"GET"})
  457.      *
  458.      * @SWG\Get(
  459.      *     path="/api/widget/signal/top-category/{length}",
  460.      *     tags={"Signal"},
  461.      *     summary="Get top category signal in user perimeter",
  462.      *     @SWG\Parameter(
  463.      *         name="length",
  464.      *         in="path",
  465.      *         type="integer",
  466.      *         default=5,
  467.      *         description="Number of elements returned",
  468.      *         required=true
  469.      *     ),
  470.      *     @SWG\Response(
  471.      *         response="200",
  472.      *         description="Returned when successful"
  473.      *     )
  474.      * )
  475.      */
  476.     public function getSignalTopCategory(int $length 5): JsonResponse
  477.     {
  478.         $user $this->userManager->findUser($this->getUser()->getUsername());
  479.         $geoJson $this->areaManager->getUserGeoJsonByService($user, [Service::SIGNAL_NOTIFY_SERVICE_CODE]);
  480.         if ('' === $geoJson) {
  481.             $this->logger->error(
  482.                 sprintf (
  483.                     'Error getting user\'s geojson %s by services %s',
  484.                     $this->getUser()->getUsername(),
  485.                     Service::SIGNAL_NOTIFY_SERVICE_CODE
  486.                 )
  487.             );
  488.             return new JsonResponse([], Response::HTTP_OK);
  489.         }
  490.         $topCategory $this->signalManager->getSignalTopCategory($length$geoJson);
  491.         if ('' === $topCategory) {
  492.             return new JsonResponse(nullResponse::HTTP_BAD_REQUEST);
  493.         }
  494.         return new JsonResponse($topCategoryResponse::HTTP_OK, [], true);
  495.     }
  496.     /**
  497.      * Get stats for Signal.
  498.      *
  499.      * @Route("/api/statistics/status", name="get_signals_status_direct", methods={"GET"})
  500.      *
  501.      * @SWG\Get (
  502.      *      path="/api/statistics/status",
  503.      *      tags={"Signal"},
  504.      *      summary="Get statistics for signals",
  505.      *     @SWG\Response(
  506.      *         response="200",
  507.      *         description="stats"
  508.      *     )
  509.      * )
  510.      */
  511.     public function getStatsDirect(Request $request): JsonResponse
  512.     {
  513.         $parameters $request->query->all();
  514.         $user $this->userManager->findUser($this->getUser()->getUsername());
  515.         $geoJson $this->areaManager->getUserGeoJsonByService($user, [Service::SIGNAL_NOTIFY_SERVICE_CODE]);
  516.        if (empty($geoJson)) {
  517.             $this->logger->error(
  518.                 sprintf (
  519.                     'Error getting user\'s geojson %s by services %s',
  520.                     $this->getUser()->getUsername(),
  521.                     Service::SIGNAL_NOTIFY_SERVICE_CODE
  522.                 )
  523.             );
  524.             return new JsonResponse([], Response::HTTP_OK);
  525.         }
  526.         $parameters $this->addRequestTypeFiltersByUser($parameters);
  527.         list($stats) = $this->signalManager->getStatsSignals($geoJson$parameters);
  528.         return new JsonResponse($stats);
  529.     }
  530.     /**
  531.      * Get stats for Signal.
  532.      *
  533.      * @Route("/api/widget/signal/stats", name="get_signals_stats",  methods={"GET"})
  534.      *
  535.      * @SWG\Get (
  536.      *      path="/api/widget/signal/stats",
  537.      *      tags={"Signal"},
  538.      *      summary="Get statistics for signals",
  539.      *     @SWG\Response(
  540.      *         response="200",
  541.      *         description="stats"
  542.      *     )
  543.      * )
  544.      */
  545.     public function getStats(): JsonResponse
  546.     {
  547.         /** @var User $user */
  548.         $user $this->getUser();
  549.         $userHeimdall $this->userManager->findUser($user->getUsername());
  550.         $contractId $user->getCurrentContractId();
  551.         $geoJson $this->areaManager->getUserGeoJsonByService($userHeimdall, [Service::SIGNAL_NOTIFY_SERVICE_CODE], $contractId);
  552.         $userRequestTypes $this->signalManager->getUserOrganizationsRequestTypes($user->getId(), $contractId);
  553.         if ('' === $geoJson) {
  554.             $this->logger->error(
  555.                 sprintf (
  556.                     'Error getting user\'s geojson %s by services %s',
  557.                     $this->getUser()->getUsername(),
  558.                     Service::SIGNAL_NOTIFY_SERVICE_CODE
  559.                 )
  560.             );
  561.             return new JsonResponse([], Response::HTTP_OK);
  562.         }
  563.         $queryParams = [
  564.             'filter' => [
  565.                 'requestType' => $userRequestTypes
  566.             ]
  567.         ];
  568.         list($stats) = $this->signalManager->getStatsSignals($geoJson$queryParams);
  569.         return new JsonResponse($stats);
  570.     }
  571.     /**
  572.      * @Route("/api/organization/{organizationId}/signal", methods={"POST"})
  573.      * 
  574.      * @SWG\Post (
  575.      *      path="/api/organization/{organizationId}/signal",
  576.      *      tags={"Signal"},
  577.      *      summary="Create signals",
  578.      *      @SWG\Response(
  579.      *         response="201",
  580.      *         description="created"
  581.      *     )
  582.      * )
  583.      *
  584.      * @param Request $request
  585.      * @param string $organizationId
  586.      *
  587.      * @return Response
  588.      */
  589.     public function create(Request $requeststring $organizationId): Response
  590.     {
  591.         /** @var User $user */
  592.         $user $this->getUser();
  593.         
  594.         $data json_decode($request->getContent(), true);
  595.         $options['contract'] = $user->getCurrentContract();
  596.         $options['authorization'] = $request->headers->get('authorization');
  597.         try {
  598.             $response $this->signalManager->createSignal($organizationId$data$options);
  599.             $explodedLocation explode('/'$response->getHeaders()['location'][0]);
  600.             $signalId end($explodedLocation);
  601.             return new JsonResponse([], Response::HTTP_CREATED, [
  602.                 "location" => "/api/signal/" $signalId
  603.             ]);
  604.         } catch (ClientExceptionInterface $exception) {
  605.             return new JsonResponse(nullResponse::HTTP_NOT_FOUND);
  606.         }
  607.     }
  608.      
  609. }