Merge branch 'production' into master

This commit is contained in:
Matteo Gheza 2022-05-27 18:30:49 +02:00 committed by GitHub
commit 3e4c6779ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 134 additions and 409 deletions

View File

@ -93,7 +93,7 @@ function updateAlertMessages($alert, $crew=null, $alertDeleted = false) {
if(!is_null($message_id) && !is_null($chat_id)) {
$Bot->sendMessage([
"chat_id" => $chat_id,
"text" => __("alerts.alert_removed"),
"text" => "Allerta rimossa.\nPartecipazione non più richiesta.",
"reply_to_message_id" => $message_id
]);
try {
@ -160,7 +160,7 @@ function updateAlertMessages($alert, $crew=null, $alertDeleted = false) {
if((!is_null($message_id) || !is_null($chat_id)) && $member["response"] === "waiting") {
$Bot->sendMessage([
"chat_id" => $chat_id,
"text" => __("alerts.alert_completed"),
"text" => "Numero minimo vigili richiesti raggiunto.\nPartecipazione non più richiesta.",
"reply_to_message_id" => $message_id
]);
try {
@ -192,7 +192,7 @@ function setAlertResponse($response, $userId, $alertId) {
if(!$alert["enabled"]) return;
$crew = json_decode($alert["crew"], true);
$messageText = $response ? __("alerts.accepted") : __("alerts.rejected");
$messageText = $response ? "🟢 Partecipazione accettata." : "🔴 Partecipazione rifiutata.";
foreach($crew as &$member) {
if($member["id"] == $userId) {
@ -272,20 +272,20 @@ function alertsRouter (FastRoute\RouteCollector $r) {
requireLogin();
$users->online_time_update();
if(!$users->hasRole(Role::SUPER_EDITOR)) {
apiResponse(["status" => "error", "message" => __("access_denied")]);
apiResponse(["status" => "error", "message" => "Access denied"]);
return;
}
try {
$crew_members = callsList($_POST["type"]);
} catch (NoChiefAvailableException) {
apiResponse(["status" => "error", "message" => __("alerts.no_chief_available")]);
apiResponse(["status" => "error", "message" => "Nessun caposquadra disponibile. Contattare i vigili manualmente."]);
return;
} catch (NoDriverAvailableException) {
apiResponse(["status" => "error", "message" => __("alerts.no_drivers_available")]);
apiResponse(["status" => "error", "message" => "Nessun autista disponibile. Contattare i vigili manualmente."]);
return;
} catch (NotEnoughAvailableUsersException) {
apiResponse(["status" => "error", "message" => __("alerts.not_enough_available_users")]);
apiResponse(["status" => "error", "message" => "Nessun utente disponibile. Distaccamento non operativo."]);
return;
}
@ -340,7 +340,7 @@ function alertsRouter (FastRoute\RouteCollector $r) {
requireLogin();
$alert = $db->selectRow("SELECT * FROM `".DB_PREFIX."_alerts` WHERE `id` = :id", [":id" => $vars["id"]]);
if(is_null($alert)) {
apiResponse(["error" => __("alerts.alert_not_found")]);
apiResponse(["error" => "alert not found"]);
return;
}
$alert["crew"] = json_decode($alert["crew"], true);
@ -359,7 +359,7 @@ function alertsRouter (FastRoute\RouteCollector $r) {
requireLogin();
$users->online_time_update();
if(!$users->hasRole(Role::SUPER_EDITOR)) {
apiResponse(["status" => "error", "message" => __("access_denied")]);
apiResponse(["status" => "error", "message" => "Access denied"]);
return;
}
$db->update(
@ -390,7 +390,7 @@ function alertsRouter (FastRoute\RouteCollector $r) {
requireLogin();
$users->online_time_update();
if(!$users->hasRole(Role::SUPER_EDITOR)) {
apiResponse(["status" => "error", "message" => __("access_denied")]);
apiResponse(["status" => "error", "message" => "Access denied"]);
return;
}
$db->update(

View File

@ -124,7 +124,6 @@ function apiRouter (FastRoute\RouteCollector $r) {
foreach($response as &$row) {
$row['changed'] = $users->getName($row['changed']);
$row['editor'] = $users->getName($row['editor']);
$row['action'] = __($row['action'], null, true);
}
} else {
$response = [];
@ -164,16 +163,6 @@ function apiRouter (FastRoute\RouteCollector $r) {
apiResponse($services->get($vars['id']));
}
);
$r->addRoute(
['POST'],
'/services/{id}',
function ($vars) {
global $services, $users;
requireLogin();
$users->online_time_update();
apiResponse($services->update($vars['id'], $_POST["start"], $_POST["end"], $_POST["code"], $_POST["chief"], $_POST["drivers"], $_POST["crew"], $_POST["place"], $_POST["notes"], $_POST["type"], $users->auth->getUserId()));
}
);
$r->addRoute(
['DELETE'],
'/services/{id}',
@ -285,7 +274,7 @@ function apiRouter (FastRoute\RouteCollector $r) {
$users->online_time_update();
if(!$users->hasRole(Role::SUPER_EDITOR) && (int) $_POST["id"] !== $users->auth->getUserId()){
statusCode(401);
apiResponse(["status" => "error", "message" => __("other_user_availability_change_forbidden"), "t" => $users->auth->getUserId()]);
apiResponse(["status" => "error", "message" => "You don't have permission to change other users availability", "t" => $users->auth->getUserId()]);
return;
}
$user_id = is_numeric($_POST["id"]) ? $_POST["id"] : $users->auth->getUserId();
@ -394,32 +383,32 @@ function apiRouter (FastRoute\RouteCollector $r) {
global $users;
try {
$token = $users->loginAndReturnToken($_POST["username"], $_POST["password"]);
logger("log_messages.new_login");
logger("Login effettuato");
apiResponse(["status" => "success", "access_token" => $token]);
}
catch (\Delight\Auth\InvalidEmailException $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("login.wrong_email")]);
apiResponse(["status" => "error", "message" => "Wrong email address"]);
}
catch (\Delight\Auth\InvalidPasswordException $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("login.wrong_password")]);
apiResponse(["status" => "error", "message" => "Wrong password"]);
}
catch (\Delight\Auth\EmailNotVerifiedException $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("login.email_not_confirmed")]);
apiResponse(["status" => "error", "message" => "Email not verified"]);
}
catch (\Delight\Auth\UnknownUsernameException $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("login.wrong_username")]);
apiResponse(["status" => "error", "message" => "Wrong username"]);
}
catch (\Delight\Auth\TooManyRequestsException $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("too_many_requests")]);
apiResponse(["status" => "error", "message" => "Too many requests"]);
}
catch (Exception $e) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("unknown_error"), "error" => $e]);
apiResponse(["status" => "error", "message" => "Unknown error", "error" => $e]);
}
}
);
@ -432,7 +421,7 @@ function apiRouter (FastRoute\RouteCollector $r) {
if(!$users->hasRole(Role::SUPER_ADMIN)) {
statusCode(401);
apiResponse(["status" => "error", "message" => __("impersonate_user_forbidden")]);
apiResponse(["status" => "error", "message" => "You don't have permission to impersonate"]);
return;
}
@ -442,15 +431,15 @@ function apiRouter (FastRoute\RouteCollector $r) {
}
catch (\Delight\Auth\UnknownIdException $e) {
statusCode(400);
apiResponse(["status" => "error", "message" => __("login.wrong_userid")]);
apiResponse(["status" => "error", "message" => "Wrong user ID"]);
}
catch (\Delight\Auth\EmailNotVerifiedException $e) {
statusCode(400);
apiResponse(["status" => "error", "message" => __("login.email_not_confirmed")]);
apiResponse(["status" => "error", "message" => "Email not verified"]);
}
catch (Exception $e) {
statusCode(400);
apiResponse(["status" => "error", "message" => __("unknown_error"), "error" => $e]);
apiResponse(["status" => "error", "message" => "Unknown error", "error" => $e]);
}
}
);

View File

@ -174,7 +174,8 @@ function job_send_notification_if_manual_mode() {
$notified_users = [];
foreach ($profiles as $profile) {
$notified_users[] = $profile["id"];
sendTelegramNotificationToUser(sprintf(__("telegram_bot.schedule_disabled_warning"), __($profile["available"] ? 'available' : 'not_available')), $profile["id"]);
$stato = $profile["available"] ? "disponibile" : "non disponibile";
sendTelegramNotificationToUser("⚠️ Attenzione! La tua disponibilità <b>non segue la programmazione oraria</b>.\nAttualmente sei <b>{$stato}</b>.\nScrivi \"/programma\" se vuoi ripristinare la programmazione.", $profile["id"]);
}
$output = $notified_users;
$output_status = "ok";
@ -195,7 +196,7 @@ function cronRouter (FastRoute\RouteCollector $r) {
'POST',
'/execute',
function ($vars) {
global $executed_actions;
global $db, $executed_actions;
$cron_job_allowed = get_option("cron_job_enabled", false) && ((isset($_POST['cron']) && $_POST['cron'] == "cron_job-".get_option("cron_job_code")) || (isset($_SERVER['HTTP_CRON']) && $_SERVER['HTTP_CRON'] == "cron_job-".get_option("cron_job_code")));
if(!$cron_job_allowed) {

View File

@ -33,15 +33,6 @@ function initializeBot($mode = WEBHOOK) {
}
}
function getLanguageFromTelegramMessage(Message $message) {
global $translations;
$language = $translations->default_language;
if ($message->from->language_code !== null) {
$language = explode("-", $message->from->language_code)[0];
}
return $language;
}
function getUserIdByFrom($from_id)
{
global $db;
@ -59,7 +50,10 @@ function requireBotLogin(Message $message)
$userId = getUserIdByMessage($message);
if ($userId === null) {
$message->reply(__("telegram_bot.account_not_linked"));
$message->reply(
"Non hai ancora collegato il tuo account Allerta al bot.".
"\nPer farlo, premere su <strong>\"Collega l'account al bot Telegram\"</strong>."
);
exit();
} else {
if($users->auth->hasRole(\Delight\Auth\Role::CONSULTANT)) {
@ -120,14 +114,14 @@ function generateAlertMessage($alertType, $alertEnabled, $alertNotes, $alertCrea
global $users;
$message =
"<b><i><u>".($alertEnabled ? __("alerts.alert_in_progress") : ($alertDeleted ? __("alerts.alert_cancelled") : __("alerts.alert_complete"))).":</u></i></b> ".
($alertType === "full" ? __("telegram.full_team_requested") : __("telegram.support_team_requested")) . "\n";
"<b><i><u>".($alertEnabled ? "Allertamento in corso" : ($alertDeleted ? "Allertamento completato" : "Allerta rimossa")).":</u></i></b> ".
($alertType === "full" ? "Richiesta <b>squadra completa 🚒</b>" : "<b>Supporto 🧯</b>\n");
if(!is_null($alertNotes) && $alertNotes !== "") {
$message .= ucfirst(__("notes")).":\n<b>".$alertNotes."</b>\n";
$message .= "Note:\n<b>".$alertNotes."</b>\n";
}
if(!is_null($alertCreatedBy)) {
$message .= __("alerts.added_by") . "<b>".$users->getName($alertCreatedBy)."</b>\n";
$message .= "Lanciata da: <b>".$users->getName($alertCreatedBy)."</b>\n";
}
return $message;
@ -137,21 +131,21 @@ function generateAlertReportMessage($alertType, $crew, $alertEnabled, $alertNote
global $users;
$message = generateAlertMessage($alertType, $alertEnabled, $alertNotes, $alertCreatedBy);
$message .= "\n".ucfirst(__("team")).":\n";
$message .= "\nSquadra:\n";
foreach($crew as $member) {
if((!$alertEnabled || $alertDeleted) && $member["response"] === "waiting") continue;
$user = $users->getUserById($member['id']);
$message .= "<i>".$user["name"]."</i> ";
if($user["chief"]) $message .= __("telegram_bot.chief_abbr");
if($user["chief"]) $message .= "CS";
if($user["driver"]) $message .= "🚒";
$message .= "- ";
if($member["response"] === "waiting") {
$message .= __("telegram_bot.alert_waiting");
$message .= "In attesa 🟡";
} else if($member["response"] === true) {
$message .= __("telegram_bot.alert_available");
$message .= "Presente 🟢";
} else if($member["response"] === false) {
$message .= __("telegram_bot.alert_not_available");
$message .= "Assente 🔴";
}
$message .= "\n";
}
@ -171,11 +165,11 @@ function sendAlertRequestMessage($alertType, $userId, $alertId, $alertNotes, $al
'inline_keyboard' => [
[
[
'text' => __("telegram_bot.alert_accept_button"),
'text' => '✅ Partecipo',
'callback_data' => "alert_yes_".$alertId
],
[
'text' => __("telegram_bot.alert_decline_button"),
'text' => 'Non partecipo ❌',
'callback_data' => "alert_no_".$alertId
]
]
@ -186,7 +180,7 @@ function sendAlertRequestMessage($alertType, $userId, $alertId, $alertNotes, $al
function yesOrNo($value)
{
return '<b>'.strtoupper(($value === 1 || $value) ? __("yes") : __('no')).'</b>';
return ($value === 1 || $value) ? '<b>SI</b>' : '<b>NO</b>';
}
function sendLongMessage($text, $userId) {
@ -215,13 +209,14 @@ function telegramBotRouter() {
});
$Bot->onCommand('start', function (Message $message, array $args = []) {
global $db, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $db;
if(isset($args[0])) {
$registered_chats = $db->select("SELECT * FROM `".DB_PREFIX."_bot_telegram` WHERE `chat_id` = ?", [$message->from->id]);
if(!is_null($registered_chats) && count($registered_chats) > 1) {
$message->chat->sendMessage(__("telegram_bot.account_already_linked"));
$message->chat->sendMessage(
"⚠️ Questo account Allerta è già associato ad un'altro utente Telegram.".
"\nContattare un amministratore."
);
return;
}
$response = $db->update(
@ -230,48 +225,62 @@ function telegramBotRouter() {
['tmp_login_token' => $args[0]]
);
if($response === 1) {
logger("log_messages.telegram_account_linked");
$message->chat->sendMessage(__("telegram_bot.login_successful"));
logger("Utente collegato ad account telegram (".$message->from->id.")");
$message->chat->sendMessage(
"✅ Login avvenuto con successo!".
"\nPer ottenere informazioni sul profilo, utilizzare il comando /info".
"\nPer ricevere informazioni sui comandi, utilizzare il comando /help o visualizzare il menu dei comandi da Telegram"
);
} else {
$message->chat->sendMessage(__("telegram_bot.login_failed"));
$message->chat->sendMessage(
"⚠️ Chiave di accesso non valida, impossibile eseguire il login.".
"\nRiprovare o contattare un amministratore."
);
}
} else {
$message->chat->sendMessage(__("telegram_bot.account_not_linked"));
$message->chat->sendMessage(
"Per iniziare, è necessario collegare l'account di Allerta con Telegram.".
"\nPer farlo, premere su <strong>\"Collega l'account al bot Telegram\"</strong>."
);
}
});
$Bot->onCommand('help', function (Message $message, array $args = []) {
global $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
$message->chat->sendMessage(__("telegram_bot.help_command"));
$message->chat->sendMessage(
" Elenco dei comandi disponibili:".
"\n/info - Ottieni informazioni sul profilo connesso".
"\n/help - Ottieni informazioni sui comandi".
"\n/attiva - Modifica la tua disponibilità in \"reperibile\"".
"\n/disattiva - Modifica la tua disponibilità in \"non reperibile\"".
"\n/programma - Abilita programmazione oraria".
"\n/disponibili - Mostra un elenco dei vigili attualmente disponibili".
"\n/stato - Mostra lo stato della disponibilità della squadra"
);
});
$Bot->onCommand('debug_userid', function (Message $message) {
global $Bot, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $Bot;
$messageText = sprintf(__("telegram_bot.debug_telegram_user_id"), $message->from->id);
$messageText .= "\n".sprintf(__("telegram_bot.debug_chat_id"), $message->chat->id);
$messageText = "🔎 ID utente Telegram: <b>".$message->from->id."</b>";
if(isset($message->from->username)) {
$messageText .= "\n".sprintf(__("telegram_bot.debug_username"), $message->from->username);
$messageText .= "\n💬 Username: <b>".$message->from->username."</b>";
}
if(isset($message->from->first_name)) {
$messageText .= "\n".sprintf(__("telegram_bot.debug_first_name"), $message->from->first_name);
$messageText .= "\n🔎 Nome: <b>".$message->from->first_name."</b>";
}
if(isset($message->from->last_name)) {
$messageText .= "\n".sprintf(__("telegram_bot.debug_last_name"), $message->from->last_name);
$messageText .= "\n🔎 Cognome: <b>".$message->from->last_name."</b>";
}
if(isset($message->from->language_code)) {
$messageText .= "\n".sprintf(__("telegram_bot.debug_language_code"), $message->from->language_code);
$messageText .= "\n🌐 Lingua: <b>".$message->from->language_code."</b>";
}
if(isset($message->from->is_bot)) {
$messageText .= "\n".sprintf(__("telegram_bot.debug_is_bot"), yesOrNo($message->from->is_bot));
$messageText .= "\n🤖 Bot: <b>".yesOrNo($message->from->is_bot)."</b>";
}
$message->reply($messageText);
if(defined("BOT_TELEGRAM_DEBUG_USER") && BOT_TELEGRAM_DEBUG_USER !== $message->from->id){
$messageText .= "\n\n".__("telegram_bot.debug_message_json");
$messageText .= "\n\n🔎 JSON del messaggio:";
$Bot->sendMessage(BOT_TELEGRAM_DEBUG_USER, $messageText);
$message_json = json_encode($message, JSON_PRETTY_PRINT);
sendLongMessage($message_json, BOT_TELEGRAM_DEBUG_USER);
@ -279,114 +288,92 @@ function telegramBotRouter() {
});
$Bot->onCommand('info', function (Message $message) {
global $users, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $users;
$user_id = getUserIdByMessage($message);
if(is_null($user_id)) {
$message->chat->sendMessage(__("telegram_bot.account_not_linked"));
$message->chat->sendMessage('⚠️ Questo account Telegram non è associato a nessun utente di Allerta.');
} else {
$user = $users->getUserById($user_id);
$template_replacements = [
"{name}" => $user["name"],
"{available}" => yesOrNo($user["available"]),
"{chief}" => yesOrNo($user["chief"] === 1),
"{driver}" => yesOrNo($user["driver"] === 1),
"{services}" => $user["services"],
"{trainings}" => $user["trainings"],
"{availability_minutes}" => $user["availability_minutes"]
];
$message->chat->sendMessage(strtr(__("telegram_bot.info_command"), $template_replacements));
$message->chat->sendMessage(
" Informazioni sul profilo:".
"\n<i>Nome:</i> <b>".$user["name"]."</b>".
"\n<i>Disponibile:</i> ".yesOrNo($user["available"]).
"\n<i>Caposquadra:</i> ".yesOrNo($user["chief"] === 1).
"\n<i>Autista:</i> ".yesOrNo($user["driver"] === 1).
"\n<i>Interventi svolti:</i> <b>".$user["services"]."</b>".
"\n<i>Esercitazioni svolte:</i> <b>".$user["trainings"]."</b>".
"\n<i>Minuti di disponibilità:</i> <b>".$user["availability_minutes"]."</b>"
);
}
});
//Too difficult and "spaghetti to explain it here in comments, please use https://regexr.com/
//Jokes apart, checks if text contains something like "Attiva", "attiva", "Disponibile", "disponibile" but not "Non ", "non ", "Non_", "non_", "Dis" or "dis"
$Bot->onText("/\/?(Sono |sono |Io sono |Io sono )?(?<!non( |_))(?<!dis)(?<!Non( |_))(?<!Dis)(Attiva|Attivami|Attivo|Disponibile|Operativo|attiva|attivami|attivo|disponibile|operativo)/", function (Message $message, $matches = []) {
global $Bot, $availability, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $Bot, $availability;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 3) return;
$user_id = getUserIdByMessage($message);
$availability->change(1, $user_id, true);
$Bot->sendMessage([
"chat_id" => $message->from->id,
"text" => sprintf(__("telegram_bot.availability_updated"), __("available")),
"disable_notification" => true
]);
$Bot->sendMessage($message->from->id, "Disponibilità aggiornata con successo.\nOra sei <b>operativo</b>.");
});
$Bot->onText("/\/?(Io |Io sono )?(Disattiva|Disattivo|Disattivami|Non( |_)attivo|Non( |_)(Sono |sono )?disponibile|Non( |_)(Sono |sono )?operativo|disattiva|disattivo|sisattivami|non( |_)(Sono |sono )?attivo|non( |_)(Sono |sono )?disponibile|non( |_)(Sono |sono )?operativo)/", function (Message $message, $matches = []) {
global $Bot, $availability, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $Bot, $availability;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 4) return;
$user_id = getUserIdByMessage($message);
$availability->change(0, $user_id, true);
$Bot->sendMessage([
"chat_id" => $message->from->id,
"text" => sprintf(__("telegram_bot.availability_updated"), __("not_available")),
"disable_notification" => true
]);
$Bot->sendMessage($message->from->id, "Disponibilità aggiornata con successo.\nOra sei <b>non operativo</b>.");
});
$Bot->onText("/\/?(Abilita( |_)|abilita( |_)|Attiva( |_)|attiva( |_))?(Programma|Programmazione|programmazione|Programmazione( |_)oraria|programma|programmazione( |_)oraria)/", function (Message $message, $matches = []) {
global $Bot, $availability, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $Bot, $availability;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 3) return;
$userId = getUserIdByMessage($message);
$availability->change_manual_mode(0, $userId);
$Bot->sendMessage($message->from->id, __("telegram_bot.schedule_mode_enabled"));
$Bot->sendMessage($message->from->id, "Programmazione oraria <b>abilitata</b>.\nPer disabilitarla (e tornare in modalità manuale), cambiare la disponbilità usando i comandi \"/attiva\" e \"/disattiva\"");
});
$Bot->onText("/\/?(Stato|stato)( |_)?(Distaccamento|distaccamento)?/", function (Message $message, $matches = []) {
global $db, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $db;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 2) return;
$available_users_count = $db->selectValue("SELECT COUNT(id) FROM `".DB_PREFIX."_profiles` WHERE `available` = 1 AND `hidden` = 0");
if($available_users_count >= 5) {
$message->reply(__("telegram_bot.available_full"));
$message->reply("🚒 Distaccamento operativo con squadra completa");
} else if($available_users_count >= 2) {
$message->reply(__("telegram_bot.available_support"));
$message->reply("🧯 Distaccamento operativo per supporto");
} else if($available_users_count >= 0) {
$message->reply(__("telegram_bot.not_available"));
$message->reply("⚠️ Distaccamento non operativo");
}
});
$Bot->onText("/\/?(Elenco|elenco|Elenca|elenca)?(_| )?(Disponibili|disponibili)/", function (Message $message, $matches = []) {
global $db, $translations;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
global $db, $users;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 2) return;
$result = $db->select("SELECT `chief`, `driver`, `available`, `name` FROM `".DB_PREFIX."_profiles` WHERE available = 1 and hidden = 0 ORDER BY chief DESC, services ASC, trainings DESC, availability_minutes DESC, name ASC");
if(!is_null($result) && count($result) > 0) {
$msg = __("telegram_bot.available_users");
$msg = " Vigili attualmente disponibili:";
foreach($result as $user) {
$msg .= "\n<b>".$user["name"]."</b>";
if($user["driver"]) $msg .= " 🚒";
if($user["chief"]) {
$msg .= " ".__("telegram_bot.chief_abbr");
$msg .= " CS";
}
}
} else {
$msg = __("telegram_bot.no_user_available");
$msg = "⚠️ Nessun vigile disponibile.";
}
$message->reply($msg);
});
$Bot->onCallbackQuery(function (CallbackQuery $callback_query) use ($Bot) {
global $translations;
$user = $callback_query->from;
$message = $callback_query->message;
$chat = $message->chat;
$translations->setLanguage(getLanguageFromTelegramMessage($message));
if(strpos($callback_query->data, 'alert_') === 0) {
$data = explode("_", str_replace("alert_", "", $callback_query->data));

View File

@ -1,108 +0,0 @@
<?php
return [
"log_messages" => [
"new_login" => "New login",
"availability_schedules_updated" => "Availability schedules updated",
"user_added" => "User added",
"user_updated" => "User updated",
"user_removed" => "User removed",
"service_added" => "Service added",
"service_updated" => "Service updated",
"service_removed" => "Service removed",
"training_added" => "Training added",
"training_updated" => "Training updated",
"training_removed" => "Training removed",
"available" => "Availability changed to \"available\"",
"not_available" => "Availability changed to \"not available\"",
"telegram_account_linked" => "Telegram account linked"
],
"login" => [
"wrong_email" => "Wrong email",
"wrong_password" => "Wrong password",
"wrong_username" => "Wrong username",
"wrong_userid" => "Wrong userid",
"email_not_confirmed" => "Email not confirmed"
],
"alerts" => [
"alert_removed" => "Alerta removed.\\nAvailability not requested anymore.",
"alert_completed" => "Minimum number of members required reached.\\nParticipation not requested anymore.",
"accepted" => "🟢 Accepted.",
"rejected" => "🔴 Reject.",
"no_chief_available" => "No chief available. Contact the members manually.",
"no_driver_available" => "No driver available. Contact the members manually.",
"not_enough_users_available" => "Not enough users available. Contact the members manually.",
"alert_not_found" => "Alert not found",
"alert_in_progress" => "Alert in progress",
"alert_complete" => "Alert complete",
"alert_cancelled" => "Alert cancelled",
"added_by" => "Added by: "
],
"telegram_bot" => [
"available_support" => "🧯 Available for support",
"available_full" => "🚒 Available with full team",
"not_available" => "⚠️ Not available",
"schedule_disabled_warning" => "⚠️ Warning! Your availability <b>doesn't follow the schedule</b>.\nCurrently you are <b>%s</b>.\nType \"/programma\" to restore the schedule.",
"available_users" => " Available users:",
"no_user_available" => "⚠️ No user available.",
"chief_abbr" => "C",
"account_not_linked" =>
"⚠️ You have not yet linked your Alert account to the bot.".
"\nTo do this, click on <strong> \"Link account to Telegram bot\"</strong>.",
"account_already_linked" =>
"⚠️ This Alert account is already associated with another Telegram user.".
"\nContact an administrator.",
"login_successful" =>
"✅ Login successful!".
"\nTo get profile information, use the /info command".
"\nTo see commands list, use the command /help or view the command menu from Telegram",
"login_failed" =>
"⚠️ Invalid access key, unable to login.".
"\nPlease try again or contact an administrator.",
"full_team_requested" => "<b>Complete team 🚒</b> requested",
"support_team_requested" => "<b>Support 🧯</b>",
"alert_waiting" => "Waiting ⏳",
"alert_available" => "Available 🟢",
"alert_not_available" => "Not available 🔴",
"alert_accept_button" => "✅ Partecipate",
"alert_decline_button" => "Don't Partecipate ❌",
"help_command" =>
" Commands list:".
"\n/info - Returns profile info".
"\n/help - Returns commands list".
"\n/attiva - Update your availability into \"available\"".
"\n/disattiva - Update your availability into \"not available\"".
"\n/programma - Enable schedule mode".
"\n/disponibili - Returns available users list".
"\n/stato - Returns team availability status",
"info_command" =>
" Profile info:".
"\n<i>Name:</i> <b>{name}</b>".
"\n<i>Available:</i> {available}".
"\n<i>Chief:</i> {chief}".
"\n<i>Driver:</i> {driver}".
"\n<i>Services:</i> <b>{services}</b>".
"\n<i>Trainings:</i> <b>{trainings}</b>".
"\n<i>Availability minutes:</i> <b>{availability_minutes}</b>",
"schedule_mode_enabled" => "Schedule mode <b>enabled</b>.\nTo disable it (and re-enable manual mode), change your availability using the commands \"/attiva\" e \"/disattiva\"",
"availability_updated" => "Availability updated successfully.\nNow you are <b>%s</b>",
"debug_telegram_user_id" => "🔎 Telegram User ID: <b>%s</b>",
"debug_chat_id" => "💬 Chat ID: <b>%s</b>",
"debug_username" => "🔎 Username: <b>%s</b>",
"debug_first_name" => "🔎 First Name: <b>%s</b>",
"debug_last_name" => "🔎 Last Name: <b>%s</b>",
"debug_language_code" => "🌐 Linguage Code: <b>%s</b>",
"debug_is_bot" => "🤖 Bot: <b>%s</b>",
"debug_message_json" => "🔎 JSON Message: <b>%s</b>",
],
"other_user_availability_change_forbidden" => "You don't have permission to change other users availability",
"impersonate_user_forbidden" => "You don't have permission to impersonate other users",
"too_many_requests" => "Too many requests",
"unknown_error" => "Unknown error",
"access_denied" => "Access denied",
"available" => "available",
"not_available" => "not available",
"notes" => "notes",
"team" => "team",
"yes" => "yes",
"no" => "no"
];

View File

@ -1,108 +0,0 @@
<?php
return [
"log_messages" => [
"new_login" => "Nuovo accesso",
"availability_schedules_updated" => "Programmazione disponibilità aggiornata",
"user_added" => "Utente aggiunto",
"user_updated" => "Utente aggiornato",
"user_removed" => "Utente rimosso",
"service_added" => "Servizio aggiunto",
"service_updated" => "Servizio aggiornato",
"service_removed" => "Servizio rimosso",
"training_added" => "Esercitazione aggiunta",
"training_updated" => "Esercitazione aggiornata",
"training_removed" => "Esercitazione rimossa",
"available" => "Disponibilità cambiata in \"reperibile\"",
"not_available" => "Disponibilità cambiata in \"non reperibile\"",
"telegram_account_linked" => "Account Telegram collegato"
],
"login" => [
"wrong_email" => "Email errata",
"wrong_password" => "Password errata",
"wrong_username" => "Nome utente errato",
"wrong_userid" => "ID utente errato",
"email_not_confirmed" => "Email non confermata"
],
"alerts" => [
"alert_removed" => "Allerta rimossa.\\nDisponibilità non più richiesta.",
"alert_completed" => "Numero minimo vigili richiesti raggiunto.\nPartecipazione non più richiesta.",
"accepted" => "🟢 Partecipazione accettata.",
"rejected" => "🔴 Partecipazione rifiutata.",
"no_chief_available" => "Nessun caposquadra disponibile. Contattare i vigili manualmente.",
"no_driver_available" => "Nessun autista disponibile. Contattare i vigili manualmente.",
"not_enough_users_available" => "Non ci sono abbastanza utenti disponibili. Contattare i vigili manualmente.",
"alert_not_found" => "Allerta non trovata",
"alert_in_progress" => "Allertamento in corso",
"alert_complete" => "Allertamento completato",
"alert_cancelled" => "Allertamento annullato",
"added_by" => "Lanciata da: "
],
"telegram_bot" => [
"available_support" => "🧯 Distaccamento operativo per supporto",
"available_full" => "🚒 Distaccamento operativo con squadra completa",
"not_available" => "⚠️ Distaccamento non operativo",
"schedule_disabled_warning" => "⚠️ Attenzione! La tua disponibilità <b>non segue la programmazione oraria</b>.\nAttualmente sei <b>%s</b>.\nScrivi \"/programma\" se vuoi ripristinare la programmazione.",
"available_users" => " Vigili attualmente disponibili:",
"no_user_available" => "⚠️ Nessun utente disponibile.",
"chief_abbr" => "CS",
"account_not_linked" =>
"⚠️ Non hai ancora collegato il tuo account Allerta al bot.".
"\nPer farlo, premere su <strong>\"Collega l'account al bot Telegram\"</strong>.",
"account_already_linked" =>
"⚠️ Questo account Allerta è già associato ad un'altro utente Telegram.".
"\nContattare un amministratore.",
"login_successful" =>
"✅ Login avvenuto con successo!".
"\nPer ottenere informazioni sul profilo, utilizzare il comando /info".
"\nPer ricevere informazioni sui comandi, utilizzare il comando /help o visualizzare il menu dei comandi da Telegram",
"login_failed" =>
"⚠️ Chiave di accesso non valida, impossibile eseguire il login.".
"\nRiprovare o contattare un amministratore.",
"full_team_requested" => "Richiesta <b>squadra completa 🚒</b>",
"support_team_requested" => "<b>Supporto 🧯</b>",
"alert_waiting" => "In attesa ⏳",
"alert_available" => "Presente 🟢",
"alert_not_available" => "Non presente 🔴",
"alert_accept_button" => "✅ Partecipo",
"alert_decline_button" => "Non partecipo ❌",
"help_command" =>
" Elenco dei comandi disponibili:".
"\n/info - Ottieni informazioni sul profilo connesso".
"\n/help - Ottieni informazioni sui comandi".
"\n/attiva - Modifica la tua disponibilità in \"reperibile\"".
"\n/disattiva - Modifica la tua disponibilità in \"non reperibile\"".
"\n/programma - Abilita programmazione oraria".
"\n/disponibili - Mostra un elenco dei vigili attualmente disponibili".
"\n/stato - Mostra lo stato della disponibilità della squadra",
"info_command" =>
" Informazioni sul profilo:".
"\n<i>Nome:</i> <b>{name}</b>".
"\n<i>Disponibile:</i> {available}".
"\n<i>Caposquadra:</i> {chief}".
"\n<i>Autista:</i> {driver}".
"\n<i>Interventi svolti:</i> <b>{services}</b>".
"\n<i>Esercitazioni svolte:</i> <b>{trainings}</b>".
"\n<i>Minuti di disponibilità:</i> <b>{availability_minutes}</b>",
"schedule_mode_enabled" => "Programmazione oraria <b>abilitata</b>.\nPer disabilitarla (e tornare in modalità manuale), cambiare la disponbilità usando i comandi \"/attiva\" e \"/disattiva\"",
"availability_updated" => "Disponibilità aggiornata con successo.\nOra sei <b>%s</b>",
"debug_telegram_user_id" => "🔎 ID Utente Telegram: <b>%s</b>",
"debug_chat_id" => "💬 ID Chat: <b>%s</b>",
"debug_username" => "🔎 Nome utente: <b>%s</b>",
"debug_first_name" => "🔎 Nome: <b>%s</b>",
"debug_last_name" => "🔎 Cognome: <b>%s</b>",
"debug_language_code" => "🌐 Codice lingua: <b>%s</b>",
"debug_is_bot" => "🤖 Bot: <b>%s</b>",
"debug_message_json" => "🔎 Messaggio JSON:"
],
"other_user_availability_change_forbidden" => "Non hai il permesso di cambiare la disponibilità di altri utenti",
"impersonate_user_forbidden" => "Non hai il permesso di impersonare altri utenti",
"too_many_requests" => "Troppe richieste",
"unknown_error" => "Errore sconosciuto",
"access_denied" => "Accesso negato",
"available" => "disponibile",
"not_available" => "non disponibile",
"notes" => "note",
"team" => "squadra",
"yes" => "si",
"no" => "no"
];

View File

@ -196,7 +196,7 @@ class Users
if($chief == 1) {
$this->auth->admin()->addRoleForUserById($userId, Role::SUPER_EDITOR);
}
logger("log_messages.user_created", $userId, $inserted_by);
logger("User added", $userId, $inserted_by);
return $userId;
} else {
return false;
@ -223,7 +223,7 @@ class Users
DB_PREFIX."_profiles",
["id" => $id]
);
logger("log_messages.user_removed", null, $removed_by);
logger("User removed", null, $removed_by);
}
public function online_time_update($id=null){
@ -336,7 +336,7 @@ class Availability {
public function change($availability, $user_id, $is_manual_mode=true)
{
if($is_manual_mode) logger($availability ? 'log_messages.available' : 'log_messages.not_available', $user_id, $this->users->auth->getUserId());
if($is_manual_mode) logger("Disponibilità cambiata in ".($availability ? '"disponibile"' : '"non disponibile"'), $user_id, $this->users->auth->getUserId());
$change_values = ["available" => $availability];
if($is_manual_mode) $change_values["manual_mode"] = 1;
@ -350,11 +350,11 @@ class Availability {
if(!$this->users->isHidden($user_id)) {
$available_users_count = $this->db->selectValue("SELECT COUNT(id) FROM `".DB_PREFIX."_profiles` WHERE `available` = 1 AND `hidden` = 0");
if($available_users_count === 5) {
sendTelegramNotification(__("telegram_bot.available_full"));
sendTelegramNotification("🚒 Distaccamento operativo con squadra completa");
} else if($available_users_count < 2) {
sendTelegramNotification(__("telegram_bot.not_available"));
sendTelegramNotification("⚠️ Distaccamento non operativo");
} else if($available_users_count < 5) {
sendTelegramNotification(__("telegram_bot.available_support"));
sendTelegramNotification("🧯 Distaccamento operativo per supporto");
}
}
@ -454,31 +454,11 @@ class Services {
$serviceId = $this->db->getLastInsertId();
$this->increment_counter($chief.",".$drivers.",".$crew);
logger("log_messages.service_added");
logger("Service added");
return $serviceId;
}
public function update($id, $start, $end, $code, $chief, $drivers, $crew, $place, $notes, $type, $inserted_by)
{
$service = $this->db->selectRow(
"SELECT `chief`, `drivers`, `crew` FROM `".DB_PREFIX."_services` WHERE `id` = :id",
["id" => $id]
);
$this->decrement_counter($service["chief"].";".$service["drivers"].";".$service["crew"]);
$this->db->update(
DB_PREFIX."_services",
["start" => $start, "end" => $end, "code" => $code, "chief" => $chief, "drivers" => $drivers, "crew" => $crew, "place" => $place, "place_reverse" => $this->places->save_place_reverse(explode(";", $place)[0], explode(";", $place)[1]), "notes" => $notes, "type" => $type, "inserted_by" => $inserted_by],
["id" => $id]
);
$this->increment_counter($chief.",".$drivers.",".$crew);
logger("log_messages.service_updated");
return $id;
}
public function delete($id)
{
$service = $this->db->selectRow(
@ -491,7 +471,7 @@ class Services {
DB_PREFIX."_services",
["id" => $id]
);
logger("log_messages.service_removed");
logger("Intervento eliminato");
return true;
}
@ -630,7 +610,7 @@ class Schedules {
public function update($schedules, $profile="default") {
//TODO implement multiple profiles
//TODO implement holidays
logger("log_messages.availability_schedules_updated");
logger("Aggiornata programmazione orari disponibilità");
if(empty($this->get($profile))) {
return $this->db->insert(
DB_PREFIX."_schedules",
@ -753,10 +733,3 @@ $availability = new Availability($db, $users);
$places = new Places($cache, $users, $db);
$services = new Services($db, $users, $places);
$schedules = new Schedules($db, $users);
$translations = new Translations();
function __(string $string, $language=null, $returnStringIfNotFound=false)
{
global $translations;
return $translations->translate($string, $language, $returnStringIfNotFound);
}

View File

@ -7,7 +7,6 @@ $baseConfig = [
.github
.vscode
*.json
!dist-frontend/assets/i18n/*
config.old.php
config.php
keys

View File

@ -37,7 +37,7 @@
"@angular-devkit/build-angular": "~13.0.3",
"@angular/cli": "~13.0.3",
"@angular/compiler-cli": "~13.0.0",
"@types/jasmine": "4.0.0",
"@types/jasmine": "~3.10.0",
"@types/leaflet": "^1.7.8",
"@types/node": "16.11.17",
"jasmine-core": "4.0.0",
@ -2724,9 +2724,9 @@
}
},
"node_modules/@types/jasmine": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.0.0.tgz",
"integrity": "sha512-KvhqNz4NaONk7cfp4E9x+uXOUp7x4H2Zeyb4yXnw2vIuxD5YfSi1767x+aF7z54elhZcC0OH9/78/WL6+5jcDg==",
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.10.2.tgz",
"integrity": "sha512-qs4xjVm4V/XjM6owGm/x6TNmhGl5iKX8dkTdsgdgl9oFnqgzxLepnS7rN9Tdo7kDmnFD/VEqKrW57cGD2odbEg==",
"dev": true
},
"node_modules/@types/json-schema": {
@ -14567,9 +14567,9 @@
}
},
"@types/jasmine": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.0.0.tgz",
"integrity": "sha512-KvhqNz4NaONk7cfp4E9x+uXOUp7x4H2Zeyb4yXnw2vIuxD5YfSi1767x+aF7z54elhZcC0OH9/78/WL6+5jcDg==",
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.10.2.tgz",
"integrity": "sha512-qs4xjVm4V/XjM6owGm/x6TNmhGl5iKX8dkTdsgdgl9oFnqgzxLepnS7rN9Tdo7kDmnFD/VEqKrW57cGD2odbEg==",
"dev": true
},
"@types/json-schema": {

View File

@ -41,7 +41,7 @@
"@angular-devkit/build-angular": "~13.0.3",
"@angular/cli": "~13.0.3",
"@angular/compiler-cli": "~13.0.0",
"@types/jasmine": "4.0.0",
"@types/jasmine": "~3.10.0",
"@types/leaflet": "^1.7.8",
"@types/node": "16.11.17",
"jasmine-core": "4.0.0",

View File

@ -86,12 +86,12 @@ export class ModalAlertComponent implements OnInit, OnDestroy {
this.bsModalRef.hide();
this.api.alertsChanged.next();
/*
this.translate.get('table.service_removed_successfully').subscribe((res: string) => {
this.translate.get('table.service_deleted_successfully').subscribe((res: string) => {
this.toastr.success(res);
});
this.loadTableData();
}).catch((e) => {
this.translate.get('table.service_removed_error').subscribe((res: string) => {
this.translate.get('table.service_deleted_error').subscribe((res: string) => {
this.toastr.error(res);
*/
});

View File

@ -106,12 +106,12 @@ export class TableComponent implements OnInit, OnDestroy {
}).then((result) => {
if (result.isConfirmed) {
this.api.delete(`services/${id}`).then((response) => {
this.translate.get('table.service_removed_successfully').subscribe((res: string) => {
this.translate.get('table.service_deleted_successfully').subscribe((res: string) => {
this.toastr.success(res);
});
this.loadTableData();
}).catch((e) => {
this.translate.get('table.service_removed_error').subscribe((res: string) => {
this.translate.get('table.service_deleted_error').subscribe((res: string) => {
this.toastr.error(res);
});
});

View File

@ -177,19 +177,15 @@ export class EditServiceComponent implements OnInit {
values.drivers = values.drivers.join(";");
values.crew = values.crew.join(";");
console.log(values);
let submit_url = "services";
if(!this.addingService) {
submit_url = `services/${this.serviceId}`;
}
this.api.post(submit_url, values).then((res) => {
this.api.post("services", values).then((res) => {
console.log(res);
this.translate.get(this.addingService ? 'edit_service.service_added_successfully' : 'edit_service.service_updated_successfully').subscribe((res: string) => {
this.translate.get('edit_service.service_added_successfully').subscribe((res: string) => {
this.toastr.success(res);
});
this.submittingForm = false;
}).catch((err) => {
console.error(err);
this.translate.get(this.addingService ? 'edit_service.service_add_failed' : 'edit_service.service_update_failed').subscribe((res: string) => {
this.translate.get('edit_service.service_add_failed').subscribe((res: string) => {
this.toastr.error(res);
});
this.submittingForm = false;

View File

@ -12,8 +12,8 @@
"cancel": "Cancel",
"remove_service_confirm": "Are you sure you want to remove this service?",
"remove_service_confirm_text": "This action cannot be undone.",
"service_removed_successfully": "Service deleted successfully",
"service_removed_error": "Service could not be deleted. Please try again."
"service_deleted_successfully": "Service deleted successfully",
"service_deleted_error": "Service could not be deleted. Please try again."
},
"list": {
"your_availability_is": "You are:",
@ -54,9 +54,7 @@
"type_already_exists": "Type already exists",
"type_added_successfully": "Type added successfully",
"service_added_successfully": "Service added successfully",
"service_add_error": "Service could not be added. Please try again",
"service_updated_successfully": "Service updated successfully",
"service_update_error": "Service could not be updated. Please try again"
"service_add_error": "Service could not be added. Please try again"
},
"update_availability_schedule": "Update availability schedule",
"save_changes": "Save changes",

View File

@ -12,8 +12,8 @@
"cancel": "Annulla",
"remove_service_confirm": "Sei sicuro di voler rimuovere questo intervento?",
"remove_service_confirm_text": "Questa operazione non può essere annullata.",
"service_removed_successfully": "Intervento rimosso con successo",
"service_removed_error": "Errore durante la rimozione dell'intervento. Riprova più tardi"
"service_deleted_successfully": "Intervento rimosso con successo",
"service_deleted_error": "Errore durante la rimozione dell'intervento. Riprova più tardi"
},
"list": {
"your_availability_is": "Attualmente sei:",
@ -54,9 +54,7 @@
"type_already_exists": "La tipologia è già presente",
"type_added_successfully": "Tipologia aggiunta con successo",
"service_added_successfully": "Intervento aggiunto con successo",
"service_add_error": "Errore durante l'aggiunta dell'intervento. Riprovare più tardi",
"service_updated_successfully": "Intervento modificato con successo",
"service_update_error": "Errore durante la modifica dell'intervento. Riprovare più tardi"
"service_add_error": "Errore durante l'aggiunta dell'intervento. Riprovare più tardi"
},
"update_availability_schedule": "Aggiorna programmazione disponibilità",
"save_changes": "Salva modifiche",