src/Controller/PublicApiController.php line 37

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Carbon\Carbon;
  4. use Knp\Snappy\Pdf;
  5. use Knp\Snappy\Image;
  6. use Pimcore\Model\Asset;
  7. use App\Service\RedisCache;
  8. use App\Model\ReportLogModel;
  9. use App\Service\EmailService;
  10. use App\Service\ReportService;
  11. use DateTime;
  12. use Pimcore\Log\ApplicationLogger;
  13. use App\Model\EwsNotificationModel;
  14. use App\Service\NotificationService;
  15. use Pimcore\Model\DataObject\Report;
  16. use App\Service\MeteomaticApiService;
  17. use App\Model\WeatherForecastCityModel;
  18. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  19. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  20. use App\Service\CustomNotificationService;
  21. use App\Service\MeteomaticsWeatherService;
  22. use Pimcore\Controller\FrontendController;
  23. use Knp\Component\Pager\PaginatorInterface;
  24. use App\Service\PublicUserPermissionService;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Pimcore\Model\DataObject\ReportWeatherSymbols;
  29. use Symfony\Component\HttpFoundation\JsonResponse;
  30. use Symfony\Contracts\Translation\TranslatorInterface;
  31. use Symfony\Component\Security\Core\User\UserInterface;
  32. use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
  33. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  34. class PublicApiController extends FrontendController
  35. {
  36.     private $ewsNotificationModel;
  37.     private $reportModel;
  38.     public function __construct(
  39.         private TokenStorageInterface $tokenStorageInterface,
  40.         private JWTTokenManagerInterface $jwtManager,
  41.         private PublicUserPermissionService $publicUserPermissionService,
  42.         protected TranslatorInterface $translator,
  43.         private ApplicationLogger $logger,
  44.         private MeteomaticApiService $meteomaticApiService,
  45.         private \Doctrine\DBAL\Connection $connection,
  46.         private RedisCache $redisCache,
  47.         private MeteomaticsWeatherService $meteomaticsWeatherService,
  48.         private Pdf $snappy,
  49.         private CustomNotificationService $customNotificationService,
  50.         private ReportService $reportService,
  51.         private NotificationService $notificationService,
  52.         private Image $snappyImage,
  53.         private EmailService $emailService
  54.     ) {
  55.        // header('Content-Type: application/json; charset=UTF-8');
  56.        // header("Access-Control-Allow-Origin: *");
  57.         $this->meteomaticApiService $meteomaticApiService;
  58.         $this->publicUserPermissionService $publicUserPermissionService;
  59.         $this->ewsNotificationModel = new EwsNotificationModel();
  60.         $this->reportModel = new ReportLogModel();
  61.     }
  62.     /**
  63.      * @Route("/api/public/{startdate}/{enddate}/{resolution}/{parameter}/{coordinate}/{format}", name="api_public_route_query", methods={"GET"})
  64.      */
  65.     public function publicRouteQueryData(Request $request): JsonResponse
  66.     {
  67.         try {
  68.             // check user credentials and expiry
  69.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  70.             if ($response['success'] !== true) {
  71.                 return $this->json($response);
  72.             }
  73.             $startDate $request->get('startdate');
  74.             $endDate $request->get('enddate');
  75.             $resolution $request->get('resolution');
  76.             $parameter $request->get('parameter');
  77.             $coordinate $request->get('coordinate');
  78.             $format $request->get('format');
  79.             // Optional Parameter
  80.             $source $request->get('source');
  81.             $onInvalid $request->get('on_invalid');
  82.             $model $request->get('model');
  83.             if (!$startDate) {
  84.                 throw new \InvalidArgumentException("Missing mandatory parameter: start date");
  85.             }
  86.             if (!$endDate) {
  87.                 throw new \InvalidArgumentException("Missing mandatory parameter: end date");
  88.             }
  89.             if (!$resolution) {
  90.                 throw new \InvalidArgumentException("Missing mandatory parameter: resolution");
  91.             }
  92.             if (!$parameter) {
  93.                 throw new \InvalidArgumentException("Missing mandatory parameter: parameters");
  94.             }
  95.             if (!$coordinate) {
  96.                 throw new \InvalidArgumentException("Missing mandatory parameter: coordinate");
  97.             }
  98.             if (!$format) {
  99.                 throw new \InvalidArgumentException("Missing mandatory parameter: format");
  100.             }
  101.             $startDate = new DateTime($startDate);
  102.             $endDate = new DateTime($endDate);
  103.             $user $response['user'];
  104.             $parametersArray explode(','$parameter);
  105.             // Varify user allowed permissions
  106.             // $reslult = $this->publicUserPermissionService->publicUserPermissionCheck($user, $parametersArray, $this->translator);
  107.             // if ($reslult['success'] !== true) {
  108.             //     return $this->json($reslult);
  109.             // }
  110.             $response $this->meteomaticApiService->publicRouteQuery(
  111.                 $startDate,
  112.                 $endDate,
  113.                 $resolution,
  114.                 $parametersArray,
  115.                 $coordinate,
  116.                 $format,
  117.                 $model,
  118.                 $source,
  119.                 $onInvalid
  120.             );
  121.             // For demonstration purposes, we will just return a JSON response
  122.             return $this->json($response);
  123.         } catch (\Exception $ex) {
  124.             $this->logger->error($ex->getMessage());
  125.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  126.         }
  127.     }
  128.     /**
  129.      * @Route("/api/public/get-report-detail", name="public_get_report_detail")
  130.      */
  131.     public function getReportDetails(Request $request)
  132.     {
  133.         try {
  134.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  135.             if ($response['success'] !== true) {
  136.                 return $this->json($response);
  137.             }
  138.             $user $response['user'];
  139.             // $params = json_decode($request->getContent(), true);
  140.             $requestUri $request->getRequestUri();
  141.             // Extract the last segment from the URL
  142.             $segments explode('/'trim($requestUri'/'));
  143.             $action end($segments);
  144.             $action str_replace("-""_"$action);
  145.             $params[] = $action;
  146.             // $reslult = $this->publicUserPermissionService->publicUserPermissionCheck($user, $params, $this->translator);
  147.             // if ($reslult['success'] !== true) {
  148.             //     return $this->json($reslult);
  149.             // }
  150.             $latestReport Report::getList([
  151.                 "limit" => 1,
  152.                 "orderKey" => "createdOn",
  153.                 "order" => "desc"
  154.             ]);
  155.             if ($latestReport->getCount() <= 0) {
  156.                 throw new \Exception('no_latest_report_found');
  157.             } else {
  158.                 $data = [];
  159.                 foreach ($latestReport as $report) {
  160.                     $data = [
  161.                         'name' => $report->getCreatedBy()?->getName(),
  162.                         'email' => $report->getCreatedBy()?->getEmail(),
  163.                         'jsonData' => json_decode($report->getJsonData(), true),
  164.                         'createdOn' => $report->getCreatedOn()
  165.                     ];
  166.                 }
  167.                 return $this->json(['success' => true'data' => $data]);
  168.             }
  169.         } catch (\Exception $ex) {
  170.             $this->logger->error($ex->getMessage());
  171.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  172.         }
  173.     }
  174.     /**
  175.      * @Route("/api/public/ews-analytics", methods={"POST"})
  176.      */
  177.     public function ewsAnalyticsAction(Request $request): JsonResponse
  178.     {
  179.         try {
  180.             $params json_decode($request->getContent(), true);
  181.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  182.             $lang = ($request->headers->has('lang')) ? $request->headers->get('lang') : "en";
  183.             $result $this->ewsNotificationModel->ewsAnalytics($params$this->connection$lang);
  184.             return $this->json($result);
  185.         } catch (\Exception $ex) {
  186.             $this->logger->error($ex->getMessage());
  187.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  188.         }
  189.     }
  190.     /**
  191.      * @Route("/api/public/generate-report", methods={"POST"})
  192.      */
  193.     public function generateReport(Request $request): JsonResponse
  194.     {
  195.         try {
  196.             $response = [];
  197.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  198.             if ($permissions['success'] !== true) {
  199.                 return $this->json($permissions);
  200.             }
  201.             $params json_decode($request->getContent(), true);
  202.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  203.             if (
  204.                 !isset($params['from_date']) ||
  205.                 !isset($params['to_date']) ||
  206.                 !isset($params['hours']) ||
  207.                 !isset($params['parameters'])  ||
  208.                 !isset($params['locations'])
  209.             ) {
  210.                 throw new \Exception('Missing required parameters');
  211.             }
  212.             if (empty($params['parameters'] || !is_array($params['parameters']))) {
  213.                 throw new \Exception('Parameters should be non empty array');
  214.             }
  215.             if (empty($params['locations'] || !is_array($params['locations']))) {
  216.                 throw new \Exception('Locations should be non empty array');
  217.             }
  218.             $model = isset($params['model']) ? $params['model'] : 'mix';
  219.             $redisKey md5('generate_city_report-' $params['from_date'] . '-' $params['to_date'] . '-' $params['hours'] . '-' implode('_'$params['locations'])) . '-' implode('_'$params['parameters']) . '-' $model;
  220.             $data $this->redisCache->get($redisKey);
  221.             if (!$data) {
  222.                 $cities = new \Pimcore\Model\DataObject\City\Listing();
  223.                 if (!empty($params['locations'])) {
  224.                     $cities->setCondition('o_id IN (?)', [$params['locations']]);
  225.                 }
  226.                 $cities->load();
  227.                 if ($cities->getCount() > 0) {
  228.                     $params['coordinates'] = []; // Initialize an empty array for coordinates
  229.                     $result = [];
  230.                     $citiesArr = [];
  231.                     foreach ($cities as $city) {
  232.                         $params['coordinates'][] = [$city->getLatitude(), $city->getLongitude()];
  233.                         // Append the coordinates for each city
  234.                         $long number_format($city->getLongitude(), 6'.''');
  235.                         $lat number_format($city->getLatitude(), 6'.''');
  236.                         $citiesArr[$lat '|' $long]["en"] =  $city->getCityName("en");
  237.                         $citiesArr[$lat '|' $long]["ar"] =  $city->getCityName("ar");
  238.                     }
  239.                     $result $this->meteomaticsWeatherService->getReportForecastData($params['coordinates'], $params['from_date'], $params['to_date'], $params['hours'], $model$params['parameters'], $this->translator$citiesArr$params);
  240.                     $response[] = $result;
  241.                     $jsonResponse = ['success' => true'data' => $response];
  242.                     $this->redisCache->set($redisKey$jsonResponseREDIS_CACHE_TIME);
  243.                     return $this->json($jsonResponse);
  244.                 } else {
  245.                     return $this->json(['success' => true'message' => $this->translator->trans('no_city_found')]);
  246.                 }
  247.             } else {
  248.                 return $this->json($data);
  249.             }
  250.         } catch (\Exception $ex) {
  251.             $this->logger->error($ex->getMessage());
  252.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  253.         }
  254.     }
  255.     /**
  256.      * @Route("/api/public/update-report", methods={"POST"})
  257.      */
  258.     public function updateReport(Request $request)
  259.     {
  260.         try {
  261.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  262.             if ($permissions['success'] !== true) {
  263.                 return $this->json($permissions);
  264.             }
  265.             $user $permissions['user'];
  266.             $params  json_decode($request->getContent(), true);
  267.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  268.             // Perform parameter validation here
  269.             // || !isset($params['locations'])
  270.             if (!isset($params['data'])  || !isset($params['start_date']) || !isset($params['end_date']) || !isset($params['lang'])) {
  271.                 return $this->json(['success' => false'message' =>  $this->translator->trans('missing_required_parameters')]);
  272.             }
  273.             if (isset($params['organizations'])) {
  274.                 if (!is_array($params['organizations'])) {
  275.                     throw new \Exception($this->translator->trans('Organizations should be non empty array'), 400);
  276.                 }
  277.             }
  278.             if (isset($params['channels'])) {
  279.                 if (!is_array($params['channels']) || empty($params['channels'])) {
  280.                     throw new \Exception($this->translator->trans('Channels should be non empty array'), 400);
  281.                 }
  282.                 if (in_array('email'$params['channels'])) {
  283.                     if (!isset($params['emails']) || !is_array($params['emails']) || empty($params['emails'])) {
  284.                         throw new \Exception($this->translator->trans('Emails should be non empty array'), 400);
  285.                     }
  286.                 }
  287.             }
  288.             $result $this->reportModel->editReport($user$params$this->translator$this->logger);
  289.             return $this->json($result);
  290.         } catch (\Exception $ex) {
  291.             $this->logger->error($ex->getMessage());
  292.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  293.         }
  294.     }
  295.     /**
  296.      * @Route("/api/public/get-city-list", name="public-city-listing")
  297.      */
  298.     public function getCityListAction(Request $request)
  299.     {
  300.         try {
  301.             $result = [];
  302.             $lang = ($request->headers->has('lang')) ? $request->headers->get('lang') : "en";
  303.             $params  json_decode($request->getContent(), true);
  304.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  305.             $reportTypeId $params['report_type_id'] ?? null;
  306.             $cities = new \Pimcore\Model\DataObject\City\Listing();
  307.             if ($reportTypeId) {
  308.                 $cities->setCondition("reportType REGEXP CONCAT('(^|,)', REPLACE('" $reportTypeId "', ',', '|'), '(,|$)')");
  309.             } else {
  310.                 $db \Pimcore\Db::get();
  311.                 $selectedLocalities $db->fetchAllAssociative("SELECT oo_id  FROM `object_query_ReportType` WHERE (`isAutomaticReport` = 0)");
  312.                 $ooIds array_column($selectedLocalities'oo_id');
  313.                 $cities->setCondition("reportType REGEXP CONCAT('(^|,)', REPLACE('" implode(','$ooIds) . "', ',', '|'), '(,|$)')");
  314.             }
  315.             $cities->load();
  316.             if ($cities->getCount() > 0) {
  317.                 foreach ($cities as $city) {
  318.                     $result[] = [
  319.                         "id" => $city->getId(),
  320.                         "name" => $city->getCityName($lang),
  321.                         "nameEn" => $city->getCityName('en'),
  322.                         "nameAr" => $city->getCityName('ar'),
  323.                         "lat" => $city->getLatitude(),
  324.                         "long" => $city->getLongitude(),
  325.                         "googlePlaceName" => $city->getGooglePlaceName(),
  326.                     ];
  327.                 }
  328.                 return $this->json(["success" => true"data" => $result]);
  329.             }
  330.             return $this->json(["success" => false"message" => $this->translator->trans("no_city_is_available")]);
  331.         } catch (\Exception $ex) {
  332.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  333.         }
  334.     }
  335.     /**
  336.      * @Route("/api/public/list-report", name="public-report-listing")
  337.      */
  338.     public function getReportListAction(Request $requestPaginatorInterface $paginator)
  339.     {
  340.         try {
  341.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  342.             if ($permissions['success'] !== true) {
  343.                 return $this->json($permissions);
  344.             }
  345.             $user $permissions['user'];
  346.             $params  json_decode($request->getContent(), true);
  347.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  348.             if (!isset($params['page']) || !isset($params['limit'])) {
  349.                 throw new \Exception('Missing required params: page or limit');
  350.             }
  351.             $report_type = isset($params['report_type']) ? $params['report_type'] : null;
  352.             $lang = isset($params['lang']) ? $params['lang'] : DEFAULT_LOCALE;
  353.             $isPublicReports = isset($params['publicReports']) ? $params['publicReports'] : false// sending this flag from public portal to get all reports accordong to our needs
  354.             $page $params['page'];
  355.             $limit $params['limit'];
  356.             $result $this->reportModel->reportList($params$page$limit$this->translator$paginator$report_type$user$lang$isPublicReports);
  357.             return $this->json($result);
  358.         } catch (\Exception $ex) {
  359.             $this->logger->error($ex->getMessage());
  360.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  361.         }
  362.     }
  363.     /**
  364.      * @Route("/api/public/generate-report-pdf", name="public-report-pdf")
  365.      */
  366.     public function generateReportPdf(Request $request)
  367.     {
  368.         try {
  369.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  370.             if ($permissions['success'] !== true) {
  371.                 return $this->json($permissions);
  372.             }
  373.             $user $permissions['user'];
  374.             $params  json_decode($request->getContent(), true);
  375.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  376.             return $this->getPdfReport($request$user'pdf/report_pdf_template.html.twig'$this->translator'_manned_forecast_report.pdf');
  377.         } catch (\Exception $ex) {
  378.             $this->logger->error($ex->getMessage());
  379.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  380.         }
  381.     }
  382.     /**
  383.      * @Route("/api/public/get-report-types", name="public-report-types-listing")
  384.      */
  385.     public function getReportTypes(Request $request)
  386.     {
  387.         try {
  388.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  389.             if ($permissions['success'] !== true) {
  390.                 return $this->json($permissions);
  391.             }
  392.             $params  json_decode($request->getContent(), true);
  393.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  394.             if (!isset($params['automatic'])) {
  395.                 throw new \Exception('missing_required_parameters');
  396.             }
  397.             $result = [];
  398.             $automatic $params['automatic'] ? true false;
  399.             $reportTypes = new \Pimcore\Model\DataObject\ReportType\Listing();
  400.             $reportTypes->setCondition('isAutomaticReport = ?', [$automatic]);
  401.             $reportTypes->load();
  402.             if ($reportTypes->getCount() > 0) {
  403.                 foreach ($reportTypes as $reportType) {
  404.                     $result[] = [
  405.                         "id" => $reportType->getId(),
  406.                         "key" => $reportType->getReportKey(),
  407.                         "nameEn" => $reportType->getName('en'),
  408.                         "nameAr" => $reportType->getName('ar'),
  409.                         "descriptionEn" => $reportType->getDescription('en'),
  410.                         "descriptionAr" => $reportType->getDescription('ar'),
  411.                         "titleEn" => $reportType->getTitle('en'),
  412.                         "titleAr" => $reportType->getTitle('ar'),
  413.                         "automatic" => $reportType->getIsAutomaticReport()
  414.                     ];
  415.                 }
  416.                 return $this->json(["success" => true"data" => $result]);
  417.             }
  418.             return $this->json(["success" => false"message" => $this->translator->trans("no_reportType_is_available")]);
  419.         } catch (\Exception $ex) {
  420.             $this->logger->error($ex->getMessage());
  421.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  422.         }
  423.     }
  424.     /**
  425.      * @Route("/api/public/get-weather-params-list", name="public-weather-params-listing")
  426.      */
  427.     public function getWeatherParamsListAction(Request $request)
  428.     {
  429.         try {
  430.             $result = [];
  431.             $lang = ($request->headers->has('lang')) ? $request->headers->get('lang') : "en";
  432.             $params  json_decode($request->getContent(), true);
  433.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  434.             if (!isset($params['report_type_id'])) {
  435.                 return $this->json(['success' => false'message' =>  $this->translator->trans('missing_required_parameters')]);
  436.             }
  437.             $reportTypeId $params['report_type_id'];
  438.             $parameters = new \Pimcore\Model\DataObject\ReportWeatherParameters\Listing();
  439.             $parameters->setCondition("reportType REGEXP CONCAT('(^|,)', REPLACE('" $reportTypeId "', ',', '|'), '(,|$)')");
  440.             $parameters->load();
  441.             if ($parameters->getCount() > 0) {
  442.                 foreach ($parameters as $paramter) {
  443.                     $result[] = [
  444.                         "id" => $paramter->getId(),
  445.                         "nameEn" => $paramter->getName('en'),
  446.                         "nameAr" => $paramter->getName('ar'),
  447.                         "meteoMaticsKey" => $paramter->getMeteoMaticsKey(),
  448.                         "units" => $paramter->getUnits(),
  449.                         "unitTitle" => $paramter->getUnitTitle()
  450.                     ];
  451.                 }
  452.                 return $this->json(["success" => true"data" => $result]);
  453.             }
  454.             return $this->json(["success" => false"message" => $this->translator->trans("no_weather_parameter_is_available")]);
  455.         } catch (\Exception $ex) {
  456.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  457.         }
  458.     }
  459.     /**
  460.      * @Route("/api/public/generate-excel", name="public-generate-excel")
  461.      */
  462.     public function generateExcelReport(Request $request)
  463.     {
  464.         $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  465.         if ($permissions['success'] !== true) {
  466.             return $this->json($permissions);
  467.         }
  468.         $user $permissions['user'];
  469.         $params  json_decode($request->getContent(), true);
  470.         $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  471.         if (!isset($params['id'])) {
  472.             throw new \Exception('missing_required_parameters');
  473.         }
  474.         $report Report::getById($params['id'], true);
  475.         if (!$report instanceof Report) {
  476.             throw new \Exception('no_report_found');
  477.         }
  478.         // Replace this with the actual data you want to use
  479.         $jsonData json_decode($report->getJsonData(), true);
  480.         // Create a new PhpSpreadsheet instance
  481.         $spreadsheet = new Spreadsheet();
  482.         // Create a worksheet
  483.         $sheet $spreadsheet->getActiveSheet();
  484.         // Determine headers dynamically based on the first item in the data
  485.         $firstItem reset($jsonData);
  486.         $parameters $firstItem['parameters'] ?? [];
  487.         $headers = ['City''Lat''Lon''Date']; // Initialize headers with common columns
  488.         // Extract parameter names and add them to headers
  489.         foreach ($parameters as $parameter) {
  490.             $headers[] = $parameter['parameter'];
  491.         }
  492.         // Add headers to the worksheet
  493.         foreach ($headers as $index => $header) {
  494.             $sheet->setCellValueByColumnAndRow($index 11$header);
  495.         }
  496.         // Initialize row counter
  497.         $row 2;
  498.         foreach ($jsonData as $item) {
  499.             // Extract city-related data
  500.             $cityData = [$item['city'] ?? ''$item['lat'] ?? ''$item['lon'] ?? ''];
  501.             // Loop through each date for all parameters
  502.             foreach ($item['parameters'][0]['dates'] as $dateIndex => $date) {
  503.                 // Initialize row data with city-related data and date
  504.                 $rowData array_merge($cityData, [date('Y-m-d'strtotime($date['date']))]);
  505.                 // Loop through each parameter
  506.                 foreach ($item['parameters'] as $parameter) {
  507.                     // Check if the value is set for the current date, otherwise set it to 0
  508.                     $value = isset($parameter['dates'][$dateIndex]['value']) ? $parameter['dates'][$dateIndex]['value'] : 0;
  509.                     // Add parameter value for the current date to the row data
  510.                     $rowData[] = $value;
  511.                 }
  512.                 // Set cell values explicitly
  513.                 foreach ($rowData as $colIndex => $cellValue) {
  514.                     $sheet->setCellValueByColumnAndRow($colIndex 1$row$cellValue);
  515.                 }
  516.                 // Increment the row counter
  517.                 $row++;
  518.             }
  519.         }
  520.         // Save the Excel file to a temporary file
  521.         $tempFile tempnam(sys_get_temp_dir(), 'weather_report');
  522.         $writer = new Xlsx($spreadsheet);
  523.         $writer->save($tempFile);
  524.         // Store the file in Pimcore Assets
  525.         $assetFolder '/report/ExcelReports'// Change this to your actual asset folder path
  526.         $filename $user->getId() . '_' time() . '_' 'weather_report.xlsx';
  527.         $assetPath =  API_BASE_URL '/' $assetFolder '/' $filename;
  528.         // Create a new asset
  529.         $asset = new \Pimcore\Model\Asset();
  530.         $asset->setFilename($filename);
  531.         $asset->setData(file_get_contents($tempFile));
  532.         $asset->setParent(\Pimcore\Model\Asset\Service::createFolderByPath($assetFolder));
  533.         $asset->save();
  534.         // Remove the temporary file
  535.         unlink($tempFile);
  536.         $report->setAsset($asset);
  537.         $report->setIsHistorical(true);
  538.         $report->save();
  539.         // Return the path to the stored Excel file in Pimcore
  540.         return $this->json(['success' => true'data' => $assetPath]);
  541.     }
  542.     /**
  543.      * @Route("/api/public/generate-historical-report", methods={"POST"})
  544.      */
  545.     public function generateHistoricalReport(Request $request): JsonResponse
  546.     {
  547.         try {
  548.             $response = [];
  549.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  550.             if ($permissions['success'] !== true) {
  551.                 return $this->json($permissions);
  552.             }
  553.             $params json_decode($request->getContent(), true);
  554.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  555.             if (
  556.                 !isset($params['from_date']) ||
  557.                 !isset($params['to_date']) ||
  558.                 !isset($params['hours']) ||
  559.                 !isset($params['parameters'])  ||
  560.                 !isset($params['locations'])
  561.             ) {
  562.                 throw new \Exception('Missing required parameters');
  563.             }
  564.             if (empty($params['parameters'] || !is_array($params['parameters']))) {
  565.                 throw new \Exception('Parameters should be non empty array');
  566.             }
  567.             if (empty($params['locations'] || !is_array($params['locations']))) {
  568.                 throw new \Exception('Locations should be non empty array');
  569.             }
  570.             if ($params['to_date'] > date('Y-m-d'strtotime(Carbon::now()))) {
  571.                 $daysadd date('Y-m-d'strtotime(Carbon::now()->addDays('17')));
  572.                 if ($params['to_date'] >= $daysadd) {
  573.                     throw new \Exception('End date limit exceeded');
  574.                 }
  575.             }
  576.             $model = isset($params['model']) ? $params['model'] : 'mix';
  577.             $redisKey md5('generate_city_report-' $params['from_date'] . '-' $params['to_date'] . '-' $params['hours'] . '-' implode('_'$params['locations'])) . '-' implode('_'$params['parameters']) . '-' $model;
  578.             $data $this->redisCache->get($redisKey);
  579.             if (!$data) {
  580.                 $cities = new \Pimcore\Model\DataObject\Location\Listing();
  581.                 if (!empty($params['locations'])) {
  582.                     $cities->setCondition('o_id IN (?)', [$params['locations']]);
  583.                 }
  584.                 $cities->load();
  585.                 if ($cities->getCount() > 0) {
  586.                     $params['coordinates'] = []; // Initialize an empty array for coordinates
  587.                     $result = [];
  588.                     $citiesArr = [];
  589.                     foreach ($cities as $city) {
  590.                         $cityLocations json_decode($city->getCoordinates(), true);
  591.                         foreach ($cityLocations as $coordinates) {
  592.                             $long number_format($coordinates[1], 6'.''');
  593.                             $lat number_format($coordinates[0], 6'.''');
  594.                             $params['coordinates'][] = $coordinates;
  595.                             $citiesArr[$lat '|' $long] =  $city->getName();
  596.                         }
  597.                     }
  598.                     $result $this->meteomaticsWeatherService->getReportForecastData($params['coordinates'], $params['from_date'], $params['to_date'], $params['hours'], $model$params['parameters'], $this->translator$citiesArr$params);
  599.                     $response[] = $result;
  600.                     $jsonResponse = ['success' => true'data' => $response];
  601.                     $this->redisCache->set($redisKey$jsonResponseREDIS_CACHE_TIME);
  602.                     return $this->json($jsonResponse);
  603.                 } else {
  604.                     return $this->json(['success' => true'message' => $this->translator->trans('no_city_found')]);
  605.                 }
  606.             } else {
  607.                 return $this->json($data);
  608.             }
  609.         } catch (\Exception $ex) {
  610.             $this->logger->error($ex->getMessage());
  611.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  612.         }
  613.     }
  614.     /**
  615.      * @Route("/api/public/get-latest-report", name="public-get-latest-report")
  616.      */
  617.     public function getLatestReport(Request $request)
  618.     {
  619.         try {
  620.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  621.             if ($permissions['success'] !== true) {
  622.                 return $this->json($permissions);
  623.             }
  624.             $params  json_decode($request->getContent(), true);
  625.             $reportType = (isset($params['report_type']) && !empty($params['report_type'])) ? $params['report_type'] : 'ten-day-forecast-report';
  626.             $result $this->reportModel->getLatestReport($reportType$this->translatorfalse);
  627.             return $this->json($result);
  628.         } catch (\Exception $ex) {
  629.             $this->logger->error($ex->getMessage());
  630.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  631.         }
  632.     }
  633.     /**
  634.      * @Route("/api/public/get-automatic-reports", name="public_get_automatic_reports")
  635.      */
  636.     public function getAutomaticReports(Request $requestPaginatorInterface $paginator)
  637.     {
  638.         try {
  639.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  640.             if ($permissions['success'] !== true) {
  641.                 return $this->json($permissions);
  642.             }
  643.             $user $permissions['user'];
  644.             $params  json_decode($request->getContent(), true);
  645.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  646.             if (!isset($params['page']) || !isset($params['limit']) || !isset($params['lang'])) {
  647.                 throw new \Exception('Missing required parameters');
  648.             }
  649.             $search = isset($params['search']) ? $params['search'] : null;
  650.             $orderKey = isset($params['orderKey']) ? $params['orderKey'] : 'createdOn';
  651.             $order = isset($params['order']) ? $params['order'] : 'desc';
  652.             $result $this->reportModel->listAutomaticPublicReports($params$user$search$orderKey$order$this->translator$paginator);
  653.             return $this->json($result);
  654.         } catch (\Exception $ex) {
  655.             $this->logger->error($ex->getMessage());
  656.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  657.         }
  658.     }
  659.     /**
  660.      * @Route("/api/public/generate-automatic-report-pdf", name="public-automatic-report-pdf")
  661.      */
  662.     public function generateAutomaticReportPdf(Request $request)
  663.     {
  664.         try {
  665.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  666.             if ($permissions['success'] !== true) {
  667.                 return $this->json($permissions);
  668.             }
  669.             $user $permissions['user'];
  670.             $result $this->reportModel->generatePdfReport($request$user$this->snappy$this->translator);
  671.             return  $this->json($result);
  672.         } catch (\Exception $ex) {
  673.             $this->logger->error($ex->getMessage());
  674.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  675.         }
  676.     }
  677.     public function getPdfReport($request$user$template$translator$report_type)
  678.     {
  679.         $params  json_decode($request->getContent(), true);
  680.         if (!isset($params['id'])) {
  681.             return $this->json(["success" => false"message" => $translator->trans("missing_required_parameters")]);
  682.         }
  683.         $report Report::getById($params['id'], true);
  684.         $lang = isset($params['lang']) ? $params['lang'] : "en";
  685.         if (!$report instanceof Report) {
  686.             return $this->json(["success" => false"message" => $translator->trans("no_report_found")]);
  687.         }
  688.         $asset $lang == 'ar' $report->getAssetAr() : $report->getAsset();
  689.         if ($asset) {
  690.             $pdfasset API_BASE_URL $asset->getPath() . $asset->getFilename();
  691.             return $this->json(['success' => true'data' => $pdfasset]);
  692.         }
  693.         //$template=$report->getReportType()?->getKey() == 'MannForecastReport'?'pdf/report_pdf_template.html.twig':'pdf/automatic_report_pdf_template.html.twig';
  694.         $fileName '_custom_weather_report.pdf';
  695.         $reportPath '/report/ReportPdf';
  696.         if ($report->getReportType()?->getKey() == 'MannForecastReport') {
  697.             $template =  'pdf/report_pdf_template.html.twig';
  698.         } elseif ($report->getReportType()?->getKey() == 'advance-custom-weather-report') {
  699.             $template 'pdf/advance_custom_report_pdf_template.html.twig';
  700.             $fileName '_advance_custom_weather_report.pdf';
  701.             $reportPath '/report/advanceCustomReportPdf';
  702.         } else {
  703.             $template 'pdf/automatic_report_pdf_template.html.twig';
  704.         }
  705.         $parameter = [
  706.             'data' => $report,
  707.             'reportTitleEn' => $report->getReportTitle('en'),
  708.             'reportTitleAr' => $report->getReportTitle('ar'),
  709.             'reportDescriptionEn' => $report->getDescription('en'),
  710.             'reportDescriptionAr' => $report->getDescription('ar'),
  711.             'reportDisclaimerEn' => $report->getReportDisclaimer('en'), // new 
  712.             'reportDisclaimerAr' => $report->getReportDisclaimer('ar'), // new 
  713.             'additionalNoteEn' => $report->getAdditionalNote('en'), // new 
  714.             'additionalNoteAr' => $report->getAdditionalNote('ar'), // new 
  715.             'template' => $template,
  716.             'lang' => $lang
  717.         ];
  718.         // return $this->render('pdf/automatic_report_pdf_template_copy.html.twig',$parameter);
  719.         $pdf \App\Lib\Utility::generatePdf($parameter$this->snappy);
  720.         // $tempFilePath = tempnam(sys_get_temp_dir(), 'image_');
  721.         // file_put_contents($tempFilePath, $pdf);
  722.         // Create a BinaryFileResponse and set headers
  723.         //    $response = new BinaryFileResponse($tempFilePath);
  724.         //    $response->headers->set('Content-Type', 'application/pdf');
  725.         //    $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE, 'image.pdf');
  726.         // Return the response
  727.         //    return $response;
  728.         $asset \App\Lib\Utility::createAsset($pdf$user->getId() . '_' time() . $report_type,  $reportPath);
  729.         $pdfasset '';
  730.         if ($asset instanceof Asset) {
  731.             $pdfasset API_BASE_URL $asset->getPath() . $asset->getFilename();
  732.         }
  733.         if ($lang == 'ar') {
  734.             $report->setAssetAr($asset);
  735.         } else {
  736.             $report->setAsset($asset);
  737.         }
  738.         $report->save();
  739.         return $this->json(['success' => true'data' => $pdfasset]);
  740.     }
  741.     /**
  742.      * @Route("/api/public/get-today-weather-report", name="public_get_today_weather_report")
  743.      */
  744.     public function getTodayWeatherReports(Request $requestPaginatorInterface $paginator)
  745.     {
  746.         try {
  747.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  748.             if ($permissions['success'] !== true) {
  749.                 return $this->json($permissions);
  750.             }
  751.             $user $permissions['user'];
  752.             $params  json_decode($request->getContent(), true);
  753.             if (!isset($params['page']) || !isset($params['limit']) || !isset($params['lang'])) {
  754.                 throw new \Exception('Missing required parameters');
  755.             }
  756.             $result $this->reportModel->getTodayWeatherReports($params$this->translator$paginator);
  757.             return $this->json($result);
  758.         } catch (\Exception $ex) {
  759.             $this->logger->error($ex->getMessage());
  760.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  761.         }
  762.     }
  763.     /**
  764.      * @Route("/api/public/get-report-weather-symbols", name="public_get_report_weather_symbols")
  765.      */
  766.     public function getReportWeatherSymbols(Request $request): JsonResponse
  767.     {
  768.         try {
  769.             $permissions $this->publicUserPermissionService->isAuthorized($request$this->translator);
  770.             if ($permissions['success'] !== true) {
  771.                 return $this->json($permissions);
  772.             }
  773.             $user $permissions['user'];
  774.             $data = [];
  775.             $weatherSymbols = new ReportWeatherSymbols\Listing();
  776.             foreach ($weatherSymbols as $weatherSymbol) {
  777.                 if ($weatherSymbol) {
  778.                     $weatherSymbolNames $weatherSymbol->getWeatherSymbols();
  779.                     $weatherSymbolIcons $weatherSymbol->getWeatherIcons();
  780.                     if ($weatherSymbolNames) {
  781.                         foreach ($weatherSymbolNames as $weatherSymbolName) {
  782.                             $response['symbols'][] = [
  783.                                 'nameEn' => $weatherSymbolName->getSymbolName('en'),
  784.                                 'nameAr' => $weatherSymbolName->getSymbolName('ar'),
  785.                             ];
  786.                         }
  787.                     }
  788.                     if ($weatherSymbolIcons) {
  789.                         foreach ($weatherSymbolIcons as $weatherSymbolIcon) {
  790.                             $response['icons'][] = [
  791.                                 'iconValue' => $weatherSymbolIcon->getIconValue(),
  792.                             ];
  793.                         }
  794.                     }
  795.                 }
  796.                 $data[] = $response;
  797.             }
  798.             return $this->json(['success' => true'data' => $data]);
  799.         } catch (\Exception $ex) {
  800.             $this->logger->error($ex->getMessage());
  801.             return $this->json(['success' => false'message' => $this->translator->trans(USER_ERROR_MESSAGE)]);
  802.         }
  803.     }
  804.     /**
  805.      * @Route("/api/public/get-forecast-cities", methods={"POST"})
  806.      */
  807.     public function getForecastCities(Request $request): Response
  808.     {
  809.         try {
  810.             $params json_decode($request->getContent(), true);
  811.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  812.             // check user credentials and expiry
  813.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  814.             if ($response['success'] !== true) {
  815.                 return $this->json($response);
  816.             }
  817.             $forecastCityModel = new WeatherForecastCityModel();
  818.             $cities $forecastCityModel->getWeatherForecastCities();
  819.             return $this->json(['success' => true'data' => $cities]);
  820.         } catch (\Exception $ex) {
  821.             $this->logger->error($ex->getMessage());
  822.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  823.         }
  824.     }
  825.     /**
  826.      * @Route("/api/public/get-regions-bbox", name="get-regions-bbox")
  827.      */
  828.     public function getRegionsBbox(Request $request)
  829.     {
  830.         try {
  831.             $params json_decode($request->getContent(), true);
  832.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  833.             // check user credentials and expiry
  834.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  835.             if ($response['success'] !== true) {
  836.                 return $this->json($response);
  837.             }
  838.             $data REGIONS_BBOX;
  839.             return $this->json(['success' => true'data' => $data]);
  840.         } catch (\Exception $ex) {
  841.             $this->logger->error($ex->getMessage());
  842.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  843.         }
  844.     }
  845.     /**
  846.      * @Route("/api/public/get-station-data", methods={"GET"})
  847.      */
  848.     public function getWeatherStationDataAction(Request $request)
  849.     {
  850.         try {
  851.             $params json_decode($request->getContent(), true);
  852.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  853.             // check user credentials and expiry
  854.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  855.             if ($response['success'] !== true) {
  856.                 return $this->json($response);
  857.             }
  858.             $typeName $request->get('type_name');
  859.             $parameters $request->get('parameters');
  860.             $dateTime $request->get('date_time');
  861.             $bBox $request->get('b_box');
  862.             if (!$typeName) {
  863.                 throw new \InvalidArgumentException("Missing mandatory parameter: type_name");
  864.             }
  865.             if (!$parameters) {
  866.                 throw new \InvalidArgumentException("Missing mandatory parameter: parameters");
  867.             }
  868.             if (!$dateTime) {
  869.                 throw new \InvalidArgumentException("Missing mandatory parameter: date_time");
  870.             }
  871.             if (!$bBox) {
  872.                 throw new \InvalidArgumentException("Missing mandatory parameter: b_box");
  873.             }
  874.             $result $this->meteomaticsWeatherService->getWeatherStationData($typeName$parameters$dateTime$bBox);
  875.             return $result;
  876.         } catch (\Exception $ex) {
  877.             return $this->json(['success' => false'message' => $ex->getMessage()]);
  878.         }
  879.     }
  880.     /**
  881.      * @Route("/api/public/daily-forecast", methods={"POST"})
  882.      */
  883.     public function dailyForecast(Request $request): JsonResponse
  884.     {
  885.         try {
  886.             $params json_decode($request->getContent(), true);
  887.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  888.             // check user credentials and expiry
  889.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  890.             if ($response['success'] !== true) {
  891.                 return $this->json($response);
  892.             }
  893.             $requiredParameters = ['coordinates''from_date''to_date''model'];
  894.             foreach ($requiredParameters as $param) {
  895.                 if (!isset($params[$param])) {
  896.                     $missingParams[] = $param;
  897.                 }
  898.             }
  899.             if (!empty($missingParams)) {
  900.                 // Throw an exception with a message that includes the missing parameters
  901.                 $parameterList implode(", "$missingParams);
  902.                 return $this->json(['success' => false'message' => sprintf($this->translator->trans("missing_required_parameters: %s"), $parameterList)]);
  903.             }
  904.             $result $this->meteomaticsWeatherService->getForecastData($params['coordinates'], $params['from_date'], $params['to_date'], $params['hours'], $params['model'], $this->translator);
  905.             return $this->json($result);
  906.         } catch (\Exception $ex) {
  907.             $this->logger->error($ex->getMessage());
  908.             return $this->json(['success' => false'message' => $this->translator->trans(USER_ERROR_MESSAGE)]);
  909.         }
  910.     }
  911.     /**
  912.      * @Route("/api/public/weather/{path}", name="api_meteomatics", requirements={"path"=".+"}, methods={"GET"})
  913.      */
  914.     public function getDynamicWeatherData(Request $requeststring $path): Response
  915.     {
  916.         try {
  917.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  918.             if ($response['success'] !== true) {
  919.                 return $this->json($response);
  920.             }
  921.             $user $response['user'];
  922.             $queryParams $request->query->all();
  923.             $weatherData $this->meteomaticApiService->getDynamicWeatherData($path$queryParams$user);
  924.             return $weatherData;
  925.         } catch (\Exception $ex) {
  926.             $this->logger->error($ex->getMessage());
  927.             return $this->json(['success' => false'message' => $this->translator->trans(USER_ERROR_MESSAGE)]);
  928.         }
  929.     }
  930.     /**
  931.      * @Route("/api/public/create-manned-alert-subscription", methods={"POST"})
  932.      */
  933.     public function mannedAlertSubscription(Request $request): JsonResponse
  934.     {
  935.         try {
  936.             $response $this->publicUserPermissionService->isAuthorized($request$this->translator);
  937.             if ($response['success'] !== true) {
  938.                 return $this->json($response);
  939.             }
  940.             $user $response['user'];
  941.             $params json_decode($request->getContent(), true);
  942.             $this->translator->setlocale(isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE);
  943.             // $requiredParameters = ['region_id', 'governorate_id', 'alert_type_id'];
  944.             // foreach ($requiredParameters as $param) {
  945.             //     if (!isset($params[$param]) || empty($params[$param])) {
  946.             //         $missingParams[] = $param;
  947.             //     }
  948.             // }
  949.             // if (!empty($missingParams)) {
  950.             //     // Throw an exception with a message that includes the missing parameters
  951.             //     $parameterList = implode(", ", $missingParams);
  952.             //     return $this->json(['success' => false, 'message' => sprintf($this->translator->trans("missing_required_parameters: %s"), $parameterList)]);
  953.             // }
  954.             $result $this->customNotificationService->mannedAlertSubscription($user$params$this->translator);
  955.             return $this->json($result);
  956.         } catch (\Exception $ex) {
  957.             $this->logger->error($ex->getMessage());
  958.             return $this->json(['success' => false'message' => $this->translator->trans(USER_ERROR_MESSAGE)]);
  959.         }
  960.     }
  961. }