<?php
namespace App\Command;
use App\Model\UserModel;
use Datetime;
use Pimcore\Db;
use GuzzleHttp\Client;
use Pimcore\Log\Simple;
use App\Service\RedisCache;
use App\Model\LocationModel;
use GuzzleHttp\Psr7\Request;
use App\Service\EmailService;
use Pimcore\Model\DataObject;
use App\Model\EwsNotificationModel;
use App\Service\NCMWeatherAPIService;
use App\Service\MeteomaticsWeatherService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Templating\EngineInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use App\C2IntegrationBundle\Service\C2Service;
use App\Service\RichService;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class SendMannedAlertsCommand extends Command
{
protected static $defaultName = 'app:get-manned-alerts';
const HOURS = 24;
var $emailService = null;
private $templating;
private $nCMWeatherAPIService;
private $redisCache;
private $locationModel;
private $userModel;
private $ewsNotificationModel;
private $c2Service;
private $richService;
private $httpClient;
public function __construct(EngineInterface $templating, RedisCache $redisCache, RichService $richService, HttpClientInterface $httpClient)
{
parent::__construct();
$this->templating = $templating;
$this->nCMWeatherAPIService = new NCMWeatherAPIService($redisCache,$httpClient);
$this->redisCache = $redisCache;
$this->locationModel = new LocationModel();
$this->userModel = new UserModel();
$this->ewsNotificationModel = new EwsNotificationModel();
$this->c2Service = new C2Service();
$this->richService = $richService;
}
protected function configure()
{
$this->setDescription('Retrieve manned alerts by location');
}
protected function execute(InputInterface $input, OutputInterface $output)
{ date_default_timezone_set(TIMEZONE);
$this->emailService = new EmailService();
$mateoMaticsService = new MeteomaticsWeatherService($this->redisCache);
$db = DB::get();
$localities = [];
$loopCount = 5;
$distincLocalities = $db->fetchAll("SELECT GROUP_CONCAT(DISTINCT addressValue) as localities FROM `object_collection_AddressComponents_location` WHERE `addressKey` = 'locality'");
if ($distincLocalities) {
$localities = explode(",", $distincLocalities[0]['localities']);
}
// Fetching alerts
$alerts = $this->nCMWeatherAPIService->getAlerts();
if ($alerts) {
foreach ($alerts as $alert) {
try {
// Create update alert
$mannedAlert = $this->createUpdateAlertNotification($alert, $output);
if (!$mannedAlert) {
$output->writeln('Nothing updated on notification = ' . $alert['id']);
continue;
}
if ($_ENV['SEND_EMAIL_NOTIFICATION'] == "false") {
$output->writeln('Email is not allowed on this environment');
continue;
}
if (!$mannedAlert->getIsSent()) {
$mannedAlertSubscription = new DataObject\MannedAlertSubscription\Listing();
$mannedAlertSubscription->setOrderKey("o_creationDate");
$mannedAlertSubscription->setOrder("desc");
foreach ($mannedAlertSubscription as $subscription) {
if ($subscription->getIsPublic() == false) {
# code...
// $subscriptionRegion = $subscription->getIsPublic() ?? false;
$subscriptionRegion = false;
if ($subscription->getRegion()) {
if ($subscription->getRegion()->getRegionId() == $alert['regionID']) {
$subscriptionRegion = true;
}
}
// $alertTypeMatch = $subscription->getIsPublic() ?? false;
$alertTypeMatch = false;
if ($subscription->getAlertType()) {
foreach ($subscription->getAlertType() as $alertType) {
if ($alertType->getAlertTypeId() == $alert['alertType']) {
$alertTypeMatch = true;
break;
}
}
}
// $alertGovernorate = $subscription->getIsPublic() ?? false;
$alertGovernorate = false;
$alertGovernoratesIds = array_column($alert['governorates'], 'id');
if ($subscription->getGovernorate()) {
foreach ($subscription->getGovernorate() as $governorate) {
if (in_array($governorate->getGovernoteId(), $alertGovernoratesIds)) {
$alertGovernorate = true;
break;
}
}
}
// $phenomena = $subscription->getIsPublic() ?? false;
$phenomena = false;
$phenomenaIds = array_column($alert['alertHazards'], 'id');
if ($subscription->getPhenomena()) {
foreach ($subscription->getPhenomena() as $phenomenas) {
if (in_array($phenomenas->getPhenomenaListId(), $phenomenaIds)) {
$phenomena = true;
break;
}
}
}
if ($subscriptionRegion && $alertTypeMatch && $alertGovernorate && $phenomena) {
// if (!empty($subscription->getEmail())) {
// $user_name = explode('@', $subscription->getEmail());
// $email = $this->sendEmailNotification($user_name[0], $alert, $subscription->getEmail(), $actualUser = false);
// // continue;
// }
if (!empty($subscription->getCreator())) {
$user = $subscription->getCreator();
$entityUserSubscription = $this->userModel->getEntitySubscription($user);
$packageExpired = $entityUserSubscription ? (new \DateTime() > $entityUserSubscription->getEndDate() ? true : false) : false;
$subActive = $entityUserSubscription ? $entityUserSubscription->getIsActive() : false;
$nonSubUser = $subActive && !$packageExpired;
if ($user->getSevereWeatherAlert() && $nonSubUser) {
$email = $this->sendEmailNotification($user, $alert, null , true);
}
}
}
}
}
// if (in_array($alert['regionEn'], $localities)) {
// // SELECT olqre.name as region,olqge.name as governate,olqwfc.name as municipality FROM object_region ore LEFT JOIN object_governorate ogo ON ore.oo_id = ogo.regionId__id LEFT JOIN object_weather_forecasting_city owfc ON owfc.MappedGovernorateId__id = ogo.oo_id LEFT JOIN object_localized_query_region_en olqre ON ore.oo_id = olqre.ooo_id LEFT JOIN object_localized_query_governorate_en olqge ON ogo.oo_id = olqge.ooo_id LEFT JOIN object_localized_query_weather_forecasting_city_en olqwfc ON owfc.oo_id = olqwfc.ooo_id
// // Fetching user fall in found localities
// $selectedLocalities = $this->ewsNotificationModel->getEwsNotificationByByRegionName($alert['regionEn']);
// if ($selectedLocalities) {
// $totalIterations = count($selectedLocalities);
// $iterations = 0;
// foreach ($selectedLocalities as $locality) {
// $locality = \Pimcore\Model\DataObject::getById($locality['o_id']);
// $users = $locality->getUser();
// // $email = $this->sendEmailNotification($users, $alert);
// // Increment the iteration count
// $iterations++;
// // Check if 5 iterations have passed
// if ($iterations % $loopCount === 0 && $iterations !== $totalIterations) {
// // If 5 iterations have passed and it's not the last iteration, sleep for 65 seconds
// sleep(65);
// }
// }
// }
// }
}
$mannedAlert->setIsSent(true);
$mannedAlert->save();
} catch (\Exception $ex) {
p_r($ex->getMessage());
}
}
}
return 0;
}
private function sendEmailNotification($users, $alert, $email = null, $actualUser)
{
$mailSent = null;
if ($alert) {
$governatesArr = $alert['governorates'];
$governates = [];
if ($governatesArr) {
foreach ($governatesArr as $gov) {
$governates[] = $gov['nameEn'];
}
}
$alertHazardsArr = $alert['alertHazards'];
$alertHazards = [];
$alertHazards_ar = [];
if ($alertHazardsArr) {
foreach ($alertHazardsArr as $alertHazard) {
$alertHazards[] = $alertHazard['descriptionEn'];
$alertHazards_ar[] = ['nameAr' =>$alertHazard['descriptionAr']];
}
}
$alertActionsArr = $alert['alertActions'];
$alertActions = [];
if ($alertActionsArr) {
foreach ($alertActionsArr as $alertAction) {
$alertActions[] = $alertAction['descriptionEn'];
}
}
$data = $alert;
$data['sender'] = 'National Center for Meteorology';
// $subject =$alert['searchEwsIdAr'] ??'Severe Weather Alert - ' . $alert['regionEn'];
$subject = $alert['alertStatusAr'] . ' - ' . $alert['regionAR'];
//sending an email document (pimcore document)
$emailAlertTemplate = '/email/alert_notification';
if ($users) {
$data['name'] = $email ? $users : $users->getName();
// extra param js
$alertObj = \Pimcore\Model\DataObject\AlertType::getByAlertTypeId($alert['alertType'], true);
$alertName = $alertObj->getColor() ? $alertObj->getColor() : '';
$alert['user_name'] = $email ? $users : $users->getName();
$alert['host'] = API_BASE_URL;
$alert['alertColor'] = $alertName;
$backgroundColor = '#fcb82526';
$borderColor = '#000000';
$textColor = '#000000';
if (isset($alert['alertColor']) && !empty(trim($alert['alertColor']))) {
$alertColorLower = strtolower(trim($alert['alertColor']));
if ($alertColorLower === 'red') {
$backgroundColor = '#f6000017';
$borderColor = '#F60000';
$textColor = '#F60000';
} elseif ($alertColorLower === 'orange') {
$backgroundColor = '#ff66001f';
$borderColor = '#FF6600';
$textColor = '#FF6600';
} elseif ($alertColorLower === 'yellow') {
$backgroundColor = '#fcb82526';
$borderColor = '#FCB825';
$textColor = '#FCB825';
}
}
$alert['backgroundColor'] = $backgroundColor;
$alert['borderColor'] = $borderColor;
$alert['textColor'] = $textColor;
$currentDate = new \DateTime($alert['fromDate']);
$searchIdAr= 'النظام الالي للإنذار المبكر | '.$currentDate->format('dmY').'-'.$alert['id'].' | '.$alert['alertTypeAr'].' | '.$alert['alertStatusAr'];
$alert['searchEwsIdAr'] = $searchIdAr;
$alert['alertHazard'] = $alertHazards_ar;
$alert['last_modified_date'] = $alert['lastModified'];
$alert['tokenURL'] = null; // for now this is null but we have to develop unsubscribe functionality for this as well
if ($actualUser) {
// general un subscribe function
$token = \App\Lib\Utility::getUnSubscribeToken($users->getId());
$alert['tokenURL'] = BASE_URL . '/unsubscribe/email?token=' . $token;
}
$alert['mannedAlertDatailUrl'] = "https://ncm.gov.sa/Ar/alert/Pages/MapDetail.aspx?AlertId=".$alert['id'];
$html = $this->templating->render('web2print/_manned_alert_notification_ar.html.twig', $alert);
$mannedAlert = \Pimcore\Model\DataObject\MannedAlertNotification::getByAlertId($alert['id'], true);
$purpose = MANNED_ALERT_MESSAGE;
if ($email) {
$mailSent = $this->c2Service->sendDefaultEmail($_ENV['EWS_MAIL_TEMPLATE'], $mannedAlert->getId(), $email, $html, $subject, $purpose);
} else {
$mailSent = $this->c2Service->sendNotificationEmail($_ENV['EWS_MAIL_TEMPLATE'], $mannedAlert->getId(), $users->getId(), $html, $subject, $purpose);
}
if ($users->getPhoneNo() && strlen($users->getPhoneNo()) == 9) {
$messageSMS = sprintf(SMS_MESSAGE["MANNED_ALERT"], strtoupper($alertName) . " alert raised in " . $alert['regionAR'] . ' for ' . $alert['alertStatusAr'] . " event");
$this->richService->sendSms(SAUDI_CALL_CODE.$users->getPhoneNo(), $messageSMS);
}
// $html = $this->templating->render('web2print/_manned_alert_notification_ar.html.twig', $alert);
// $response['message_en'] = $html;
// $email = $users->getEmail();
// $param = ['user' => $users, 'message' => $html, 'url' => null];
// $mailSent = $this->emailService->sendMail($param, $email, $emailAlertTemplate, $subject);
}
// if ($users) {
// foreach ($users as $user) {
// $data['name'] = $user->getName();
// $html = $this->templating->render('web2print/_manned_alert_notification_ar.html.twig', $data);
// $currentUser = $user->getObject();
// $data = $user->getData();
// if (isset($data['get_severe_alert']) && $data['get_severe_alert']) {
// $email = $currentUser->getEmail();
// $param = ['user' => $currentUser, 'message' => $html, 'url' => null];
// $mailSent = $this->emailService->sendMail($param, $email, $emailAlertTemplate, $subject);
// }
// }
// }
}
return $mailSent;
}
private function createUpdateAlertNotification($alert, $output)
{
// Generate the hash for the current alert data
$alertHash = md5(json_encode($alert));
// Retrieve the existing MannedAlertNotification object by alert ID
$mannedAlert = \Pimcore\Model\DataObject\MannedAlertNotification::getByAlertId($alert['id'], true);
// Check if the alert already exists
if ($mannedAlert) {
// Compare the old hash with the new hash
if ($mannedAlert->getHash() === $alertHash) {
// If the hashes match, the alert has not changed; ignore it
return null;
}
} else {
// If the alert does not exist, create a new MannedAlertNotification object
$mannedAlert = new DataObject\MannedAlertNotification();
$mannedAlert->setKey($alert['id']);
$date = date('Y-m-d', strtotime($alert['fromDate']));
$mannedAlert->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/Notification/' . $date));
$mannedAlert->setPublished(TRUE);
}
// Update the MannedAlertNotification object with the new alert data
$mannedAlert->setAlertId($alert['id']);
$mannedAlert->setTitle($alert['title']);
$mannedAlert->setAlertType($this->getAlertType($alert['alertType'], $alert['alertTypeAr'], $alert['alertTypeEn']));
$fromDate = \Carbon\Carbon::createFromFormat('m/d/Y h:i:s A', $alert['fromDate']);
$toDate = \Carbon\Carbon::createFromFormat('m/d/Y h:i:s A', $alert['toDate']);
$lastModified = \Carbon\Carbon::createFromFormat('m/d/Y h:i:s A', $alert['lastModified']);
$mannedAlert->setFromDate($fromDate);
$mannedAlert->setToDate($toDate);
$mannedAlert->setLastModifiedDate($lastModified);
$mannedAlert->setAlertStatusCategory($this->getAlertStatusCategory($alert['alertStatusCategory']));
$mannedAlert->setAlertStatus($this->getAlertStatus($alert['alertStatusID'], $alert['alertStatusAr'], $alert['alertStatusEn']));
$alertHazardArr = [];
if ($alert['alertHazards']) {
foreach ($alert['alertHazards'] as $alertHazard) {
$alertHazardArr[] = $this->getAlertHazard($alertHazard['id'], $alertHazard['descriptionAr'], $alertHazard['descriptionEn']);
}
$mannedAlert->setAlertHazards(array_filter($alertHazardArr));
}
$mannedAlert->setRegion($this->getRegion($alert['regionID'], $alert['regionAR'], $alert['regionEn']));
$alertGovernorateArr = [];
if ($alert['governorates']) {
foreach ($alert['governorates'] as $alertGovernorate) {
$alertGovernorateArr[] = $this->getGovernorates($alertGovernorate['id'], $alertGovernorate['nameAr'], $alertGovernorate['nameEn'], $alertGovernorate['longitude'], $alertGovernorate['latitude']);
}
$mannedAlert->setGovernorates(array_filter($alertGovernorateArr));
}
$mannedAlert->setOtherLocation($alert['otherLocationsEn'], 'en');
$mannedAlert->setOtherLocation($alert['otherLocationsAr'], 'ar');
$mannedAlert->settweetID($alert['tweetID']);
$alertAlertActionArr = [];
if ($alert['alertActions']) {
foreach ($alert['alertActions'] as $alertAlertAction) {
$alertAlertActionArr[] = $this->getAlertAction($alertAlertAction['id'], $alertAlertAction['descriptionAr'], $alertAlertAction['descriptionEn']);
}
$mannedAlert->setAlertAction(array_filter($alertAlertActionArr));
}
// Set the hash for the alert
$mannedAlert->setHash($alertHash);
$mannedAlert->setRawText(json_encode($alert));
$mannedAlert->setIsSent(false);
// Save the updated MannedAlertNotification object
$mannedAlert->save();
return $mannedAlert;
}
private function getAlertType($id, $nameAr, $nameEn)
{
$alertType = \Pimcore\Model\DataObject\AlertType::getByAlertTypeId($id, true);
if (!$alertType) {
$alertType = new \Pimcore\Model\DataObject\AlertType();
$alertType->setKey($id);
$alertType->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/AlertType'));
$alertType->setAlertTypeId($id);
$alertType->setName($nameAr, "en");
$alertType->setName($nameEn, "ar");
$alertType->setPublished(true);
$alertType->save();
}
return $alertType;
}
private function getAlertStatusCategory($name)
{
$alertStatusCategory = \Pimcore\Model\DataObject\AlertStatusCategory::getByName($name, true);
if (!$alertStatusCategory) {
$alertStatusCategory = new \Pimcore\Model\DataObject\AlertStatusCategory();
$alertStatusCategory->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/AlertStatusCategory'));
$alertStatusCategory->setKey($name);
$alertStatusCategory->setName($name);
$alertStatusCategory->setPublished(true);
$alertStatusCategory->save();
}
return $alertStatusCategory;
}
private function getAlertStatus($id, $nameAr, $nameEn)
{
$alertStatus = \Pimcore\Model\DataObject\AlertStatus::getByAlertStatusId($id, true);
if (!$alertStatus) {
$alertStatus = new \Pimcore\Model\DataObject\AlertStatus();
$alertStatus->setKey($id);
$alertStatus->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/AlertStatus'));
$alertStatus->setAlertStatusId($id);
$alertStatus->setName($nameAr, 'ar');
$alertStatus->setName($nameEn, 'en');
$alertStatus->setPublished(true);
$alertStatus->save();
}
return $alertStatus;
}
private function getAlertHazard($id, $descriptionAr, $descriptionEn)
{
$alertHazard = \Pimcore\Model\DataObject\AlertHazard::getByAlertHazardId($id, true);
if (!$alertHazard) {
$alertHazard = new \Pimcore\Model\DataObject\AlertHazard();
$alertHazard->setKey($id);
$alertHazard->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/AlertHazard'));
$alertHazard->setAlertHazardId($id);
$alertHazard->setName($descriptionAr, "ar");
$alertHazard->setName($descriptionEn, "en");
$alertHazard->setPublished(true);
$alertHazard->save();
} else {
$alertHazard->setName($descriptionAr, "ar");
$alertHazard->setName($descriptionEn, "en");
$alertHazard->save();
}
return $alertHazard;
}
private function getRegion($id, $nameAr, $nameEn)
{
$region = \Pimcore\Model\DataObject\Region::getByRegionId($id, true);
if (!$region) {
$region = new \Pimcore\Model\DataObject\Region();
$region->setKey($id);
$region->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/Region'));
$region->setRegionId($id);
$region->setName($nameAr, 'ar');
$region->setName($nameEn, 'en');
$region->setPublished(true);
$region->save();
}
return $region;
}
private function getGovernorates($id, $nameAr, $nameEn, $longitude, $latitude)
{
$governorate = \Pimcore\Model\DataObject\Governorate::getByGovernoteId($id, true);
if (!$governorate) {
$governorate = new \Pimcore\Model\DataObject\Governorate();
$governorate->setKey($id);
$governorate->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/Governorate'));
$governorate->setGovernoteId($id);
$governorate->setName($nameAr, "ar");
$governorate->setName($nameEn, "en");
$governorate->setLongitude($longitude);
$governorate->setLatitude($latitude);
$governorate->setPublished(true);
$governorate->save();
}
return $governorate;
}
private function getAlertAction($id, $descriptionAr, $descriptionEn)
{
$alertAction = \Pimcore\Model\DataObject\AlertAction::getByAlertActionId($id, true);
if (!$alertAction) {
$alertAction = new \Pimcore\Model\DataObject\AlertAction();
$alertAction->setKey($id);
$alertAction->setParent(\Pimcore\Model\DataObject\Service::createFolderByPath('/MannedAlert/Master/AlertAction'));
$alertAction->setAlertActionId($id);
$alertAction->setName($descriptionAr, "ar");
$alertAction->setName($descriptionEn, "en");
$alertAction->setPublished(true);
$alertAction->save();
}
return $alertAction;
}
}