Merge branch 'develop' of https://github.com/phpservermon/phpservermon into develop

This commit is contained in:
wienfuchs 2020-05-19 05:44:57 +02:00
commit 23e09b613a
52 changed files with 552 additions and 252 deletions

View File

@ -60,6 +60,7 @@ The following SMS gateways are currently available:
* SolutionsInfini - <https://solutionsinfini.com/> * SolutionsInfini - <https://solutionsinfini.com/>
* Plivo - <https://www.plivo.com/> * Plivo - <https://www.plivo.com/>
* Callr - <https://www.callr.com/> * Callr - <https://www.callr.com/>
* SMSAPI - <https://www.smsapi.com/en>
@ -79,10 +80,19 @@ Requirements
* MySQL database * MySQL database
* For PHP5: 5.5.9+ * For PHP5: 5.5.9+
* For PHP7: 7.0.8+ * For PHP7: 7.0.8+
* PHP cURL package * PHP Extensions (modules)
* PHP PDO mysql driver
* PHP-XML
* ext-curl
* ext-ctype
* ext-filter
* ext-hash
* ext-json
* ext-libxml
* ext-openssl
* ext-pdo
* ext-pcre
* ext-sockets
* ext-xml
Install Install
------- -------

View File

@ -85,6 +85,10 @@ The following people have contributed to the development of PHP Server Monitor:
* Nexmo SMS gateway * Nexmo SMS gateway
* Mateusz Małek - https://github.com/mateuszmalek
* SMSAPI gateway
Translators Translators
+++++++++++ +++++++++++

View File

@ -51,7 +51,7 @@ The other way is to parse the access logs created by your webserver software, wh
When using tools such as Google Analytics, the monitor requests will not show up in your statistics, because the monitor does not execute any Javascript. When using tools such as Google Analytics, the monitor requests will not show up in your statistics, because the monitor does not execute any Javascript.
Tools that parse your raw access logs like Awstats, will include the requests made by the monitor. Tools that parse your raw access logs like Awstats, will include the requests made by the monitor.
To make sure these requests can be identified, the monitor uses a custom user agent, which you can usually filter out. The user agent of the monitor looks like:: To make sure these requests can be identified, the monitor uses a custom user agent, which you can usually filter out. The user agent can be modified in the config section, but bij default looks like::
Mozilla/5.0 (compatible; phpservermon/3.0.1; +http://www.phpservermonitor.org) Mozilla/5.0 (compatible; phpservermon/3.0.1; +http://www.phpservermonitor.org)

View File

@ -452,8 +452,8 @@ namespace {
} }
if ($add_agent) { if ($add_agent) {
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; phpservermon/' . curl_setopt($ch, CURLOPT_USERAGENT, psm_get_conf('user_agent', 'Mozilla/5.0 (compatible; phpservermon/' .
PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)'); PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)'));
} }
$result['exec'] = curl_exec($ch); $result['exec'] = curl_exec($ch);
@ -689,7 +689,7 @@ namespace {
$client->add_cb('on_auth_success', function () use ($client, $receivers, $message) { $client->add_cb('on_auth_success', function () use ($client, $receivers, $message) {
JAXLLogger::info('got on_auth_success cb'); JAXLLogger::info('got on_auth_success cb');
foreach ($receivers as $receiver) { foreach ($receivers as $receiver) {
$client->send_chat_msg($receiver, $message); $client->send_chat_msg($receiver, $message);
} }
$client->send_end_stream(); $client->send_end_stream();
}); });
@ -779,6 +779,9 @@ namespace {
case 'solutionsinfini': case 'solutionsinfini':
$sms = new \psm\Txtmsg\SolutionsInfini(); $sms = new \psm\Txtmsg\SolutionsInfini();
break; break;
case 'smsapi':
$sms = new \psm\Txtmsg\SMSAPI();
break;
} }
// copy login information from the config file // copy login information from the config file

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'преди минута', 'a_minute_ago' => 'преди минута',
'seconds_ago' => 'преди %d секунди', 'seconds_ago' => 'преди %d секунди',
'a_second_ago' => 'преди секунда', 'a_second_ago' => 'преди секунда',
'seconds' => 'секунди',
), ),
'menu' => array( 'menu' => array(
'config' => 'Настройки', 'config' => 'Настройки',
@ -219,8 +220,6 @@ $sm_lang = array(
'email_smtp' => 'Активиране на SMTP', 'email_smtp' => 'Активиране на SMTP',
'email_smtp_host' => 'SMTP сървър', 'email_smtp_host' => 'SMTP сървър',
'email_smtp_port' => 'SMTP порт', 'email_smtp_port' => 'SMTP порт',
'email_smtp_security' => 'SMTP security',
'email_smtp_security_none' => 'None',
'email_smtp_username' => 'SMTP потребителско име', 'email_smtp_username' => 'SMTP потребителско име',
'email_smtp_password' => 'SMTP парола', 'email_smtp_password' => 'SMTP парола',
'email_smtp_noauth' => 'Оставете празно за "без аутентикация"', 'email_smtp_noauth' => 'Оставете празно за "без аутентикация"',
@ -267,7 +266,6 @@ $sm_lang = array(
системата', системата',
'log_sms' => 'Да се пази ли лог на изпратените SMS съобщения от 'log_sms' => 'Да се пази ли лог на изпратените SMS съобщения от
системата', системата',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Настройките са обновени успешно.', 'updated' => 'Настройките са обновени успешно.',
'tab_email' => 'Имейл', 'tab_email' => 'Имейл',
'tab_sms' => 'SMS', 'tab_sms' => 'SMS',

View File

@ -347,7 +347,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-recàrrega', 'auto_refresh' => 'Auto-recàrrega',
'auto_refresh_description' => 'Recarregar automàticament la plana Servidors.<br/><span class="small">Temps en 'auto_refresh_description' => 'Recarregar automàticament la plana Servidors.<br/><span class="small">Temps en
segons, si poseu ZERO la plana no s\'auto-recarregarà.</span>', segons, si poseu ZERO la plana no s\'auto-recarregarà.</span>',
'seconds' => 'segons',
'test' => 'Provar', 'test' => 'Provar',
'test_email' => 'S\'enviarà un correu a l\'adreça que teniu al vostre perfil d\'usuari.', 'test_email' => 'S\'enviarà un correu a l\'adreça que teniu al vostre perfil d\'usuari.',
'test_sms' => 'S\'enviarà un SMS al telèfon que teniu al vostre perfil d\'usuari.', 'test_sms' => 'S\'enviarà un SMS al telèfon que teniu al vostre perfil d\'usuari.',

View File

@ -68,6 +68,7 @@ $sm_lang = array(
'a_minute_ago' => 'cca před minutou', 'a_minute_ago' => 'cca před minutou',
'seconds_ago' => 'před %d vteřinami', 'seconds_ago' => 'před %d vteřinami',
'a_second_ago' => 'před chvílí', 'a_second_ago' => 'před chvílí',
'seconds' => 'sekunder',
), ),
'menu' => array( 'menu' => array(
'config' => 'Konfigurace', 'config' => 'Konfigurace',
@ -260,7 +261,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaticky obnovit', 'auto_refresh' => 'Automaticky obnovit',
'auto_refresh_description' => 'Automaticky obnovit stránku Servery.<br><span class="small">Čas v sekundách, 'auto_refresh_description' => 'Automaticky obnovit stránku Servery.<br><span class="small">Čas v sekundách,
0 pro vypnutí automatického obnovení.</span>', 0 pro vypnutí automatického obnovení.</span>',
'seconds' => 'sekund',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'E-mail bude odeslán na adresu uvedenou v uživatelském profilu.', 'test_email' => 'E-mail bude odeslán na adresu uvedenou v uživatelském profilu.',
'test_sms' => 'SMS bude odeslána na telefonní číslo uvedené v uživatelském profilu.', 'test_sms' => 'SMS bude odeslána na telefonní číslo uvedené v uživatelském profilu.',

View File

@ -65,6 +65,7 @@ $sm_lang = array(
'a_minute_ago' => 'omkring et minut siden', 'a_minute_ago' => 'omkring et minut siden',
'seconds_ago' => '%d sekunder siden', 'seconds_ago' => '%d sekunder siden',
'a_second_ago' => 'et sekund siden', 'a_second_ago' => 'et sekund siden',
'seconds' => 'sekunder',
), ),
'menu' => array( 'menu' => array(
'config' => 'Indstillinger', 'config' => 'Indstillinger',
@ -245,7 +246,6 @@ $sm_lang = array(
'auto_refresh' => 'Genopfrisk automatisk', 'auto_refresh' => 'Genopfrisk automatisk',
'auto_refresh_description' => 'Genopfrisk automatisk serversider.<br><span class="small">Tid i sekunder. Hvis 'auto_refresh_description' => 'Genopfrisk automatisk serversider.<br><span class="small">Tid i sekunder. Hvis
0 vil siden ikke genopfriske automatisk</span>', 0 vil siden ikke genopfriske automatisk</span>',
'seconds' => 'sekunder',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'En e-mail vil blive sendt til den adresse, der er angivet i din brugerprofil.', 'test_email' => 'En e-mail vil blive sendt til den adresse, der er angivet i din brugerprofil.',
'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.', 'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'vor über einer Minute', 'a_minute_ago' => 'vor über einer Minute',
'seconds_ago' => 'vor %d Sekunden', 'seconds_ago' => 'vor %d Sekunden',
'a_second_ago' => 'vor über einer Sekunde', 'a_second_ago' => 'vor über einer Sekunde',
'seconds' => 'Sekunden',
), ),
'menu' => array( 'menu' => array(
'config' => 'Einstellungen', 'config' => 'Einstellungen',
@ -249,7 +250,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Automatische Aktualisierung der Server-Übersichtsseite<br><span 'auto_refresh_description' => 'Automatische Aktualisierung der Server-Übersichtsseite<br><span
class="small">Zeit in Sekunden - die Ziffer \'0\' deaktiviert die automatische class="small">Zeit in Sekunden - die Ziffer \'0\' deaktiviert die automatische
Aktualisierung.</span>', Aktualisierung.</span>',
'seconds' => 'Sekunden',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Eine E-Mail wird an die E-Mail-Adresse gesendet, die in Ihrem Profil hinterlegt ist.', 'test_email' => 'Eine E-Mail wird an die E-Mail-Adresse gesendet, die in Ihrem Profil hinterlegt ist.',
'test_sms' => 'Eine SMS wird an die Telefonnummer gesendet, die in Ihrem Profil hinterlegt ist.', 'test_sms' => 'Eine SMS wird an die Telefonnummer gesendet, die in Ihrem Profil hinterlegt ist.',

View File

@ -83,6 +83,8 @@ $sm_lang = array(
'minutes' => 'minutes', 'minutes' => 'minutes',
'second' => 'second', 'second' => 'second',
'seconds' => 'seconds', 'seconds' => 'seconds',
'millisecond' => 'millisecond',
'milliseconds' => 'milliseconds',
'current' => 'current', 'current' => 'current',
'settings' => 'Settings', 'settings' => 'Settings',
'search' => 'Search', 'search' => 'Search',
@ -281,6 +283,7 @@ $sm_lang = array(
), ),
'config' => array( 'config' => array(
'general' => 'General', 'general' => 'General',
'site_title' => 'Site title',
'language' => 'Language', 'language' => 'Language',
'show_update' => 'Check for updates?', 'show_update' => 'Check for updates?',
'password_encrypt_key' => 'The encryption key password', 'password_encrypt_key' => 'The encryption key password',
@ -379,7 +382,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-refresh', 'auto_refresh' => 'Auto-refresh',
'auto_refresh_description' => 'Auto-refresh servers page.<br><span class="small">Time in seconds, if 0 the 'auto_refresh_description' => 'Auto-refresh servers page.<br><span class="small">Time in seconds, if 0 the
page won\'t refresh.</span>', page won\'t refresh.</span>',
'seconds' => 'seconds',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'An email will be sent to the address specified in your user profile.', 'test_email' => 'An email will be sent to the address specified in your user profile.',
'test_sms' => 'An SMS will be sent to the phone number specified in your user profile.', 'test_sms' => 'An SMS will be sent to the phone number specified in your user profile.',
@ -414,6 +416,8 @@ $sm_lang = array(
'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server 'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server
uptime. Enter 0 to disable log cleanup.', uptime. Enter 0 to disable log cleanup.',
'log_retention_days' => 'days', 'log_retention_days' => 'days',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Custom user agent used by monitor within communication with external services.',
), ),
'notifications' => array( 'notifications' => array(
'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Error=%ERROR%', 'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Error=%ERROR%',

View File

@ -354,7 +354,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-actualizar', 'auto_refresh' => 'Auto-actualizar',
'auto_refresh_description' => 'Auto-actualizar la página de servidores.<br><span class="small">Tiempo en 'auto_refresh_description' => 'Auto-actualizar la página de servidores.<br><span class="small">Tiempo en
segundos, si se utiliza 0 la página no se actualizará.</span>', segundos, si se utiliza 0 la página no se actualizará.</span>',
'seconds' => 'segundos',
'test' => 'Prueba', 'test' => 'Prueba',
'test_email' => 'Un correo electrónico será enviado a la dirección especificada en su perfil de usuario.', 'test_email' => 'Un correo electrónico será enviado a la dirección especificada en su perfil de usuario.',
'test_sms' => 'Un SMS se enviará al número de teléfono especificado en su perfil de usuario.', 'test_sms' => 'Un SMS se enviará al número de teléfono especificado en su perfil de usuario.',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'umbes minut aega tagasi', 'a_minute_ago' => 'umbes minut aega tagasi',
'seconds_ago' => '%d sekundit tagasi', 'seconds_ago' => '%d sekundit tagasi',
'a_second_ago' => 'üks sekund tagasi', 'a_second_ago' => 'üks sekund tagasi',
'seconds' => 'sekundit',
), ),
'menu' => array( 'menu' => array(
'config' => 'Konfiguratsioon', 'config' => 'Konfiguratsioon',
@ -244,7 +245,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaatne värskendamine', 'auto_refresh' => 'Automaatne värskendamine',
'auto_refresh_description' => 'Värskenda lehte automaatselt.<br><span class="small">Aeg sekundites, kui 0 'auto_refresh_description' => 'Värskenda lehte automaatselt.<br><span class="small">Aeg sekundites, kui 0
siis lehte ei värskendata.</span>', siis lehte ei värskendata.</span>',
'seconds' => 'sekundit',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Email saadetakse profiilil märgitud aadressile.', 'test_email' => 'Email saadetakse profiilil märgitud aadressile.',
'test_sms' => 'SMS saadetakse profiilil märgitud numbrile.', 'test_sms' => 'SMS saadetakse profiilil märgitud numbrile.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'حدود یک دقیقه پیش', 'a_minute_ago' => 'حدود یک دقیقه پیش',
'seconds_ago' => '%d ثانیه پیش', 'seconds_ago' => '%d ثانیه پیش',
'a_second_ago' => 'یک ثانیه پیش', 'a_second_ago' => 'یک ثانیه پیش',
'seconds' => 'ثانیه',
), ),
'menu' => array( 'menu' => array(
'config' => 'تنظیم', 'config' => 'تنظیم',
@ -263,7 +264,6 @@ $sm_lang = array(
'auto_refresh' => 'رفرش خودکار', 'auto_refresh' => 'رفرش خودکار',
'auto_refresh_description' => 'رفرش خودکار صفحه سرورها.<br><span class="small">زمان 'auto_refresh_description' => 'رفرش خودکار صفحه سرورها.<br><span class="small">زمان
به ثنیه, اگر 0 باشد صفحه رفرش نخواهد شد.</span>', به ثنیه, اگر 0 باشد صفحه رفرش نخواهد شد.</span>',
'seconds' => 'ثانیه',
'test' => 'تست', 'test' => 'تست',
'test_email' => 'یک ایمیل به آدرس تعیین شده در پروفایل شما ارسال 'test_email' => 'یک ایمیل به آدرس تعیین شده در پروفایل شما ارسال
خواهد شد.', خواهد شد.',

View File

@ -244,7 +244,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaattipäivitys', 'auto_refresh' => 'Automaattipäivitys',
'auto_refresh_description' => 'Päivittää automaattisesti palvelimet-sivun.<br><span class="small">Aika 'auto_refresh_description' => 'Päivittää automaattisesti palvelimet-sivun.<br><span class="small">Aika
sekunteina, jos 0, sivu ei päivity automaattisesti.</span>', sekunteina, jos 0, sivu ei päivity automaattisesti.</span>',
'seconds' => 'sekuntia',
'test' => 'Testi', 'test' => 'Testi',
'test_email' => 'Testisähköposti lähetetään profiilisi sähköpostiosoitteeseen.', 'test_email' => 'Testisähköposti lähetetään profiilisi sähköpostiosoitteeseen.',
'test_sms' => 'Testitekstiviesti lähetetään profiilisi numeroon.', 'test_sms' => 'Testitekstiviesti lähetetään profiilisi numeroon.',

View File

@ -361,7 +361,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-rachaîchissement', 'auto_refresh' => 'Auto-rachaîchissement',
'auto_refresh_description' => 'Auto-rachaîchissement de la page serveurs.<br><span class="small">Temps en 'auto_refresh_description' => 'Auto-rachaîchissement de la page serveurs.<br><span class="small">Temps en
secondes. Si 0, la page n\'est pas rafraîchie.</span>', secondes. Si 0, la page n\'est pas rafraîchie.</span>',
'seconds' => 'secondes',
'test' => 'Tester', 'test' => 'Tester',
'test_email' => 'Un email va vous être envoyé à l\'adresse définie dans votre profil utilisateur.', 'test_email' => 'Un email va vous être envoyé à l\'adresse définie dans votre profil utilisateur.',
'test_sms' => 'Un SMS va vous être envoyé au numéro défini dans votre profil utilisateur.', 'test_sms' => 'Un SMS va vous être envoyé au numéro défini dans votre profil utilisateur.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'circa un minuto fa', 'a_minute_ago' => 'circa un minuto fa',
'seconds_ago' => '%d secondi fa', 'seconds_ago' => '%d secondi fa',
'a_second_ago' => 'un secondo fa', 'a_second_ago' => 'un secondo fa',
'seconds' => 'secondi',
), ),
'menu' => array( 'menu' => array(
'config' => 'Configurazione', 'config' => 'Configurazione',
@ -247,7 +248,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-Aggiornamento', 'auto_refresh' => 'Auto-Aggiornamento',
'auto_refresh_description' => 'Auto-Aggiornamento pagina servers.<br><span class="small">Tempo in secondi, se 'auto_refresh_description' => 'Auto-Aggiornamento pagina servers.<br><span class="small">Tempo in secondi, se
impostato a 0 la pagina non si aggiornerà.</span>', impostato a 0 la pagina non si aggiornerà.</span>',
'seconds' => 'secondi',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Un Email verrà inviata all\'indirizzo specificato nel tuo profilo.', 'test_email' => 'Un Email verrà inviata all\'indirizzo specificato nel tuo profilo.',
'test_sms' => 'Un SMS verrà inviato al numero di telefono specificato nel tuo profilo.', 'test_sms' => 'Un SMS verrà inviato al numero di telefono specificato nel tuo profilo.',

View File

@ -345,7 +345,6 @@ $sm_lang = array(
'auto_refresh' => '自動更新', 'auto_refresh' => '自動更新',
'auto_refresh_description' => 'サーバーページを自動更新します。<br><span 'auto_refresh_description' => 'サーバーページを自動更新します。<br><span
class="small">時間を秒で指定し、0に設定すると更新しません。</span>', class="small">時間を秒で指定し、0に設定すると更新しません。</span>',
'seconds' => '秒',
'test' => 'テスト', 'test' => 'テスト',
'test_email' => 'あなたのユーザープロフィールで指定されたアドレスに電子メールが送信されます。', 'test_email' => 'あなたのユーザープロフィールで指定されたアドレスに電子メールが送信されます。',
'test_sms' => 'あなたのユーザープロフィールで指定された電話番号にSMSが送信されます。', 'test_sms' => 'あなたのユーザープロフィールで指定された電話番号にSMSが送信されます。',

View File

@ -81,6 +81,8 @@ $sm_lang = array(
'minutes' => 'minuten', 'minutes' => 'minuten',
'second' => 'seconde', 'second' => 'seconde',
'seconds' => 'seconden', 'seconds' => 'seconden',
'millisecond' => 'milliseconde',
'milliseconds' => 'milliseconden',
'current' => 'huidig', 'current' => 'huidig',
'settings' => 'Instellingen', 'settings' => 'Instellingen',
), ),
@ -110,8 +112,8 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te 'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te
ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor meer ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor
informatie.', meer informatie.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Apparaat waar de berichten naar toe gaan. Laat leeg voor alle apparaten.', 'pushover_device_description' => 'Apparaat waar de berichten naar toe gaan. Laat leeg voor alle apparaten.',
@ -244,6 +246,7 @@ $sm_lang = array(
), ),
'config' => array( 'config' => array(
'general' => 'Algemeen', 'general' => 'Algemeen',
'site_title' => 'Website titel',
'language' => 'Taal', 'language' => 'Taal',
'show_update' => 'Controleer wekelijks voor updates?', 'show_update' => 'Controleer wekelijks voor updates?',
'email_status' => 'Sta email berichten toe?', 'email_status' => 'Sta email berichten toe?',
@ -264,8 +267,8 @@ $sm_lang = array(
'sms_from' => 'Telefoonnummer afzender', 'sms_from' => 'Telefoonnummer afzender',
'pushover_status' => 'Sta Pushover berichten toe?', 'pushover_status' => 'Sta Pushover berichten toe?',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te 'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te
ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor meer ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor
informatie.', meer informatie.',
'pushover_clone_app' => 'Klik hier om je Pushover app te maken', 'pushover_clone_app' => 'Klik hier om je Pushover app te maken',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een <a href="%1$s" 'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een <a href="%1$s"
@ -308,7 +311,6 @@ $sm_lang = array(
'auto_refresh' => 'Herlaad automatisch', 'auto_refresh' => 'Herlaad automatisch',
'auto_refresh_description' => 'Auto-herladen servers pagina.<br><span class="small">Tijd in seconden, als de 'auto_refresh_description' => 'Auto-herladen servers pagina.<br><span class="small">Tijd in seconden, als de
tijd 0 is wordt de pagina niet ververst.</span>', tijd 0 is wordt de pagina niet ververst.</span>',
'seconds' => 'seconden',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Er zal een email verstuurd worden naar het email adres in je profiel.', 'test_email' => 'Er zal een email verstuurd worden naar het email adres in je profiel.',
'test_sms' => 'Er zal een SMS verstuurd worden naar het telefoonnummer in je profiel.', 'test_sms' => 'Er zal een SMS verstuurd worden naar het telefoonnummer in je profiel.',
@ -336,6 +338,9 @@ $sm_lang = array(
'log_retention_period_description' => 'Aantal dagen dat logs van notificaties en archieven van server uptime 'log_retention_period_description' => 'Aantal dagen dat logs van notificaties en archieven van server uptime
worden bewaard. Vul 0 in om log opruiming uit te zetten.', worden bewaard. Vul 0 in om log opruiming uit te zetten.',
'log_retention_days' => 'dagen', 'log_retention_days' => 'dagen',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Aangepaste user agent wordt door de monitor gebruikt bij de communicatie met externe
services.',
), ),
'notifications' => array( 'notifications' => array(
'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%', 'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%',

View File

@ -326,7 +326,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-refresh', 'auto_refresh' => 'Auto-refresh',
'auto_refresh_description' => 'Auto-refresh server side.<br><span class="small">Tid i sekunder, hvis 0 siden 'auto_refresh_description' => 'Auto-refresh server side.<br><span class="small">Tid i sekunder, hvis 0 siden
ikke blir oppdatert.</span>', ikke blir oppdatert.</span>',
'seconds' => 'sekunder',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'En e-post vil bli sendt til adressen spesifisert i brukerprofilen din.', 'test_email' => 'En e-post vil bli sendt til adressen spesifisert i brukerprofilen din.',
'test_sms' => 'En tekstmelding vil bli sendt til telefonnummeret som er angitt i brukerprofilen din.', 'test_sms' => 'En tekstmelding vil bli sendt til telefonnummeret som er angitt i brukerprofilen din.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'minutę temu', 'a_minute_ago' => 'minutę temu',
'seconds_ago' => '%d sekund temu', 'seconds_ago' => '%d sekund temu',
'a_second_ago' => 'sekundę temu', 'a_second_ago' => 'sekundę temu',
'seconds' => 'sekund',
), ),
'menu' => array( 'menu' => array(
'config' => 'Konfiguracja', 'config' => 'Konfiguracja',
@ -191,6 +192,7 @@ $sm_lang = array(
), ),
'config' => array( 'config' => array(
'general' => 'Ogólne', 'general' => 'Ogólne',
'site_title' => 'Tytuł strony',
'language' => 'Język', 'language' => 'Język',
'show_update' => 'Sprawdzić aktualizacje?', 'show_update' => 'Sprawdzić aktualizacje?',
'email_status' => 'Pozwól na wysyłkę email', 'email_status' => 'Pozwól na wysyłkę email',
@ -211,8 +213,8 @@ $sm_lang = array(
'sms_from' => 'Numer nadawcy', 'sms_from' => 'Numer nadawcy',
'pushover_status' => 'Pozwól na wysyłkę notyfikacji Pushover', 'pushover_status' => 'Pozwól na wysyłkę notyfikacji Pushover',
'pushover_description' => 'Pushover jest usługą ułatwiającą otrzymywanie powiadomień w czasie 'pushover_description' => 'Pushover jest usługą ułatwiającą otrzymywanie powiadomień w czasie
rzeczywistym. Sprawdź <a href="https://pushover.net/" target="_blank">ich stronę</a> aby uzyskać rzeczywistym. Sprawdź <a href="https://pushover.net/" target="_blank">ich
więcej informacji.', stronę</a> aby uzyskać więcej informacji.',
'pushover_clone_app' => 'Kliknij tutaj aby stworzyć aplikację korzystającą z Pushover', 'pushover_clone_app' => 'Kliknij tutaj aby stworzyć aplikację korzystającą z Pushover',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Zanim zaczniesz używać Pushover, musisz <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Zanim zaczniesz używać Pushover, musisz <a href="%1$s" target="_blank"
@ -247,7 +249,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-odświeżanie', 'auto_refresh' => 'Auto-odświeżanie',
'auto_refresh_description' => 'Auto-odświeżanie strony serwera.<br><span class="small">Czas w sekundach, dla 'auto_refresh_description' => 'Auto-odświeżanie strony serwera.<br><span class="small">Czas w sekundach, dla
czasu 0 strona nie będzie odświeżana.</span>', czasu 0 strona nie będzie odświeżana.</span>',
'seconds' => 'sekund',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Email zostanie wysłany na adres podany w Twoim profilu.', 'test_email' => 'Email zostanie wysłany na adres podany w Twoim profilu.',
'test_sms' => 'SMS zostanie wysłany na numer podany w Twoim profilu.', 'test_sms' => 'SMS zostanie wysłany na numer podany w Twoim profilu.',
@ -272,6 +273,8 @@ $sm_lang = array(
archiwizować uptime serwera. Wpisz 0 aby wyłączyć czyszczenie archiwizować uptime serwera. Wpisz 0 aby wyłączyć czyszczenie
logów.', logów.',
'log_retention_days' => 'dni', 'log_retention_days' => 'dni',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Nazwa używana przez monitoring do identyfikacji ze sprawdzaną usługą.',
), ),
'notifications' => array( 'notifications' => array(
'off_sms' => 'Serwer \'%LABEL%\' przestał odpowiadać: ip=%IP%, port=%PORT%. Błąd=%ERROR%', 'off_sms' => 'Serwer \'%LABEL%\' przestał odpowiadać: ip=%IP%, port=%PORT%. Błąd=%ERROR%',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'cerca de um minuto atrás', 'a_minute_ago' => 'cerca de um minuto atrás',
'seconds_ago' => '%d segundos atrás', 'seconds_ago' => '%d segundos atrás',
'a_second_ago' => 'um segundo atrás', 'a_second_ago' => 'um segundo atrás',
'seconds' => 'segundos',
), ),
'menu' => array( 'menu' => array(
'config' => 'Configuração', 'config' => 'Configuração',
@ -245,7 +246,6 @@ $sm_lang = array(
'auto_refresh' => 'Atualizar automaticamente', 'auto_refresh' => 'Atualizar automaticamente',
'auto_refresh_description' => 'Atualizar automaticamente a página de servidores.<br><span class="small">Tempo 'auto_refresh_description' => 'Atualizar automaticamente a página de servidores.<br><span class="small">Tempo
em segundos, Se 0 a página não será atualizada.</span>', em segundos, Se 0 a página não será atualizada.</span>',
'seconds' => 'segundos',
'test' => 'Teste', 'test' => 'Teste',
'test_email' => 'Um e-mail será enviado para o endereço especificado em seu perfil de usuário.', 'test_email' => 'Um e-mail será enviado para o endereço especificado em seu perfil de usuário.',
'test_sms' => 'Um SMS será enviado para o número de telefone especificado em seu perfil de usuário.', 'test_sms' => 'Um SMS será enviado para o número de telefone especificado em seu perfil de usuário.',

View File

@ -121,12 +121,12 @@ $sm_lang = array(
пустым, что бы отправлять уведомления на пустым, что бы отправлять уведомления на
все устройства.', все устройства.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный мессенджер 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
для получения уведомлений в реальном мессенджер для получения уведомлений в
времени. Посетите <a реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/" target="_blank">раздел документации</a> href="http://docs.phpservermonitor.org/" target="_blank">раздел
для получения доп. информации и инструкций по документации</a> для получения доп. информации
установке.', и инструкций по установке.',
'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'Сообщения будут отправляться на 'telegram_chat_id_description' => 'Сообщения будут отправляться на
указанный идентификатор чата.', указанный идентификатор чата.',
@ -313,12 +313,12 @@ $sm_lang = array(
rel="noopener">"App"</a> на их веб-сайте и ввести "App rel="noopener">"App"</a> на их веб-сайте и ввести "App
API Token" сюда.', API Token" сюда.',
'telegram_status' => 'Разрешить отправку уведомлений в Telegram', 'telegram_status' => 'Разрешить отправку уведомлений в Telegram',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный мессенджер 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
для получения уведомлений в реальном мессенджер для получения уведомлений в
времени. Посетите <a реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/" target="_blank">раздел документации</a> href="http://docs.phpservermonitor.org/" target="_blank">раздел
для получения доп. информации и инструкций по документации</a> для получения доп. информации
установке.', и инструкций по установке.',
'telegram_api_token' => 'Telegram API Token', 'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Прежде чем вы сможете начать 'telegram_api_token_description' => 'Прежде чем вы сможете начать
пользоваться Telegram, вам необходимо пользоваться Telegram, вам необходимо
@ -371,7 +371,6 @@ $sm_lang = array(
серверов.<br><span class="small">Время в секундах. серверов.<br><span class="small">Время в секундах.
Если указано 0, то страница не будет Если указано 0, то страница не будет
обновляться.</span>', обновляться.</span>',
'seconds' => 'секунд',
'test' => 'Проверка', 'test' => 'Проверка',
'test_email' => 'Сообщение будет отправлено на адрес указаный в 'test_email' => 'Сообщение будет отправлено на адрес указаный в
профиле пользователя.', профиле пользователя.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'cca pred minútou', 'a_minute_ago' => 'cca pred minútou',
'seconds_ago' => 'pred %d sekundami', 'seconds_ago' => 'pred %d sekundami',
'a_second_ago' => 'pred chvíľou', 'a_second_ago' => 'pred chvíľou',
'seconds' => 'sekúnd',
), ),
'menu' => array( 'menu' => array(
'config' => 'Konfigurácia', 'config' => 'Konfigurácia',
@ -259,7 +260,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaticky obnoviť', 'auto_refresh' => 'Automaticky obnoviť',
'auto_refresh_description' => 'Automaticky obnoviť stránku Servery.<br><span class="small">Čas v 'auto_refresh_description' => 'Automaticky obnoviť stránku Servery.<br><span class="small">Čas v
sekundách, 0 pre vypnutie automatického obnovenia.</span>', sekundách, 0 pre vypnutie automatického obnovenia.</span>',
'seconds' => 'sekúnd',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'E-mail bude odoslaný na adresu uvedenú v užívateľskom profile.', 'test_email' => 'E-mail bude odoslaný na adresu uvedenú v užívateľskom profile.',
'test_sms' => 'SMS bude odoslaná na telefónne číslo uvedené v užívateľskom profile.', 'test_sms' => 'SMS bude odoslaná na telefónne číslo uvedené v užívateľskom profile.',

View File

@ -65,6 +65,7 @@ $sm_lang = array(
'a_minute_ago' => 'pred približno minuto', 'a_minute_ago' => 'pred približno minuto',
'seconds_ago' => 'pred %d sekundami', 'seconds_ago' => 'pred %d sekundami',
'a_second_ago' => 'pred sekundo', 'a_second_ago' => 'pred sekundo',
'seconds' => 'sekund',
), ),
'menu' => array( 'menu' => array(
'config' => 'Nastavitve', 'config' => 'Nastavitve',
@ -92,8 +93,8 @@ $sm_lang = array(
'email' => 'E-pošta', 'email' => 'E-pošta',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času. 'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času.
Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na njihovi spletni Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na
strani</a>.', njihovi spletni strani</a>.',
'pushover_key' => 'Pushover ključ', 'pushover_key' => 'Pushover ključ',
'pushover_device' => 'Pushover naprava', 'pushover_device' => 'Pushover naprava',
'pushover_device_description' => 'Ime naprave na katero naj se pošlje obvestilo. Če želite obvestilo 'pushover_device_description' => 'Ime naprave na katero naj se pošlje obvestilo. Če želite obvestilo
@ -209,8 +210,8 @@ $sm_lang = array(
'sms_from' => 'Telefonska številka pošiljatelja', 'sms_from' => 'Telefonska številka pošiljatelja',
'pushover_status' => 'Dovolim pošiljanje Pushover sporočil', 'pushover_status' => 'Dovolim pošiljanje Pushover sporočil',
'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času. 'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času.
Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na njihovi spletni Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na
strani</a>.', njihovi spletni strani</a>.',
'pushover_clone_app' => 'Kliknite za ustvarjanje vaše Pushover aplikacije', 'pushover_clone_app' => 'Kliknite za ustvarjanje vaše Pushover aplikacije',
'pushover_api_token' => 'Pushover API žeton', 'pushover_api_token' => 'Pushover API žeton',
'pushover_api_token_description' => 'Pred uporabo storitve Pushover, morate na njihovi spletni strani <a 'pushover_api_token_description' => 'Pred uporabo storitve Pushover, morate na njihovi spletni strani <a
@ -247,7 +248,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Samodejno posodabljanje pregleda statusa strežnikov.<br><span 'auto_refresh_description' => 'Samodejno posodabljanje pregleda statusa strežnikov.<br><span
class="small">Čas v sekundah. Če je vrednost 0 se stran ne bo samodejno class="small">Čas v sekundah. Če je vrednost 0 se stran ne bo samodejno
posodabljala.</span>', posodabljala.</span>',
'seconds' => 'sekund',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Na naslov, ki ste ga določili v vašem profilu, bo poslano e-sporočilo.', 'test_email' => 'Na naslov, ki ste ga določili v vašem profilu, bo poslano e-sporočilo.',
'test_sms' => 'Na telefonsko številko, ki ste jo določili v vašem profilu, bo poslan SMS.', 'test_sms' => 'Na telefonsko številko, ki ste jo določili v vašem profilu, bo poslan SMS.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'ungefär en minut sen', 'a_minute_ago' => 'ungefär en minut sen',
'seconds_ago' => '%d sekunder sedan', 'seconds_ago' => '%d sekunder sedan',
'a_second_ago' => 'en sekund sedan', 'a_second_ago' => 'en sekund sedan',
'seconds' => 'sekunder',
), ),
'menu' => array( 'menu' => array(
'config' => 'Inställningar', 'config' => 'Inställningar',
@ -94,7 +95,8 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se <a 'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se <a
href="https://pushover.net/" target="_blank">deras webbsida</a> för mer information.', href="https://pushover.net/" target="_blank">deras webbsida</a> för mer
information.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Enhetsnman att skicka meddelande till. Lämna tomt för att skicka till alla 'pushover_device_description' => 'Enhetsnman att skicka meddelande till. Lämna tomt för att skicka till alla
@ -245,7 +247,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-uppdatera', 'auto_refresh' => 'Auto-uppdatera',
'auto_refresh_description' => 'Auto-uppdatera status-sidan.<br><span class="small">Tid i sekunder, om "0" 'auto_refresh_description' => 'Auto-uppdatera status-sidan.<br><span class="small">Tid i sekunder, om "0"
uppdateras sidan inte automatiskt.</span>', uppdateras sidan inte automatiskt.</span>',
'seconds' => 'sekunder',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Ett emial kommer skickas till adressen i din profil.', 'test_email' => 'Ett emial kommer skickas till adressen i din profil.',
'test_sms' => 'Ett SMS kommer skickas till mobilnumret i din profil.', 'test_sms' => 'Ett SMS kommer skickas till mobilnumret i din profil.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'yaklaşık bir dakika önce', 'a_minute_ago' => 'yaklaşık bir dakika önce',
'seconds_ago' => '%d saniye önce', 'seconds_ago' => '%d saniye önce',
'a_second_ago' => 'bir saniye önce', 'a_second_ago' => 'bir saniye önce',
'seconds' => 'saniye',
), ),
'menu' => array( 'menu' => array(
'config' => 'Ayarlar', 'config' => 'Ayarlar',
@ -248,7 +249,6 @@ $sm_lang = array(
'auto_refresh' => 'Otomatik Yenileme', 'auto_refresh' => 'Otomatik Yenileme',
'auto_refresh_description' => 'Otomatik yenileme sunucu sayfası<br><span class="small">Eğer sayfa yenilenmez 'auto_refresh_description' => 'Otomatik yenileme sunucu sayfası<br><span class="small">Eğer sayfa yenilenmez
ise.</span>', ise.</span>',
'seconds' => 'saniye',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Profilinizde tanımladığınız e-posta adresinize bir e-posta gönderilecek.', 'test_email' => 'Profilinizde tanımladığınız e-posta adresinize bir e-posta gönderilecek.',
'test_sms' => 'Profilinizde tanımladığınız numaranıza bir SMS mesajı gönderilecek.', 'test_sms' => 'Profilinizde tanımladığınız numaranıza bir SMS mesajı gönderilecek.',

View File

@ -124,11 +124,12 @@ $sm_lang = array(
повідомлення. Залиште пустим, щоб повідомлення. Залиште пустим, щоб
надсилати на всі пристрої.', надсилати на всі пристрої.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> чат-застосунок, що 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
дозволяє легко отримувати сповіщення у чат-застосунок, що дозволяє легко отримувати
реальному часі. За деталями й інструкцією зі сповіщення у реальному часі. За деталями й
встановлення зверніться до <a інструкцією зі встановлення зверніться до <a
href="http://docs.phpservermonitor.org/" target="_blank">документації</a>.', href="http://docs.phpservermonitor.org/"
target="_blank">документації</a>.',
'telegram_chat_id' => 'Ідентифікатор чату Telegram', 'telegram_chat_id' => 'Ідентифікатор чату Telegram',
'telegram_chat_id_description' => 'Повідомлення буде надіслане у 'telegram_chat_id_description' => 'Повідомлення буде надіслане у
відповідний чат.', відповідний чат.',
@ -330,8 +331,8 @@ $sm_lang = array(
'pushover_status' => 'Дозволити надсилання Pushover-повідомлень', 'pushover_status' => 'Дозволити надсилання Pushover-повідомлень',
'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати 'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати
сповіщення у реальному часі. За детальнішою сповіщення у реальному часі. За детальнішою
інформацію перейдіть на <a інформацію перейдіть на <a href="https://pushover.net/"
href="https://pushover.net/" target="_blank">їхній вебсайт</a>.', target="_blank">їхній вебсайт</a>.',
'pushover_clone_app' => 'Натисніть тут, щоб створити ваш Pushover-додаток', 'pushover_clone_app' => 'Натисніть тут, щоб створити ваш Pushover-додаток',
'pushover_api_token' => 'Токен API Pushover-додатку', 'pushover_api_token' => 'Токен API Pushover-додатку',
'pushover_api_token_description' => 'Перед використанням Pushover ви маєте <a 'pushover_api_token_description' => 'Перед використанням Pushover ви маєте <a
@ -339,16 +340,17 @@ $sm_lang = array(
Додаток</a> на їхньому вебсайті та ввести Додаток</a> на їхньому вебсайті та ввести
токен API Додатку тут.', токен API Додатку тут.',
'telegram_status' => 'Дозволити надсилання Telegram-повідомлень', 'telegram_status' => 'Дозволити надсилання Telegram-повідомлень',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> чат-застосунок, що 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
дозволяє легко отримувати сповіщення у чат-застосунок, що дозволяє легко отримувати
реальному часі. Детальніша інформація та сповіщення у реальному часі. Детальніша
інструкція зі встановлення доступні у <a інформація та інструкція зі встановлення
href="http://docs.phpservermonitor.org/" target="_blank">документації</a>.', доступні у <a href="http://docs.phpservermonitor.org/"
target="_blank">документації</a>.',
'telegram_api_token' => 'Токен Telegram API', 'telegram_api_token' => 'Токен Telegram API',
'telegram_api_token_description' => 'Перед використанням Telegram ви маєте 'telegram_api_token_description' => 'Перед використанням Telegram ви маєте
отримати токен API. За довідкою отримати токен API. За довідкою
зверніться до <a зверніться до <a href="http://docs.phpservermonitor.org/"
href="http://docs.phpservermonitor.org/" target="_blank">документації</a>.', target="_blank">документації</a>.',
'alert_type' => 'Виберіть, коли б вам хотілося отримувати 'alert_type' => 'Виберіть, коли б вам хотілося отримувати
сповіщення.', сповіщення.',
'alert_type_description' => '<b>Зміна статусу:</b> Ви отримуватимете 'alert_type_description' => '<b>Зміна статусу:</b> Ви отримуватимете
@ -404,7 +406,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Сторінка автооновлення серверів.<br><span 'auto_refresh_description' => 'Сторінка автооновлення серверів.<br><span
class="small">Час у секундах; якщо 0, сторінка не class="small">Час у секундах; якщо 0, сторінка не
оновлюватиметься.</span>', оновлюватиметься.</span>',
'seconds' => 'секунд',
'test' => 'Тест', 'test' => 'Тест',
'test_email' => 'Електронний лист буде надісланий на адресу, 'test_email' => 'Електронний лист буде надісланий на адресу,
вказану у вашому профілі користувача.', вказану у вашому профілі користувача.',

View File

@ -64,6 +64,7 @@ $sm_lang = array(
'a_minute_ago' => 'khoảng một phút trước', 'a_minute_ago' => 'khoảng một phút trước',
'seconds_ago' => '%d giây trước', 'seconds_ago' => '%d giây trước',
'a_second_ago' => 'một giây trước', 'a_second_ago' => 'một giây trước',
'seconds' => 'giây',
), ),
'menu' => array( 'menu' => array(
'config' => 'Cấu hình', 'config' => 'Cấu hình',
@ -91,8 +92,8 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian 'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian
thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a> để biết thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a>
thêm thông tin.', để biết thêm thông tin.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Tên thiết bị để gửi tin nhắn đến. Để trống để gửi 'pushover_device_description' => 'Tên thiết bị để gửi tin nhắn đến. Để trống để gửi
@ -208,8 +209,8 @@ $sm_lang = array(
'sms_from' => 'Số điện thoại của người gửi', 'sms_from' => 'Số điện thoại của người gửi',
'pushover_status' => 'Cho phép gửi tin nhắn bằng Pushover', 'pushover_status' => 'Cho phép gửi tin nhắn bằng Pushover',
'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian 'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian
thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a> để biết thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a>
thêm thông tin.', để biết thêm thông tin.',
'pushover_clone_app' => 'Nhấn vào đây để tạo ứng dụng Pushover của bạn', 'pushover_clone_app' => 'Nhấn vào đây để tạo ứng dụng Pushover của bạn',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Trước khi bạn thể sử dụng Pushover, bạn cần phải <a 'pushover_api_token_description' => 'Trước khi bạn thể sử dụng Pushover, bạn cần phải <a
@ -246,7 +247,6 @@ $sm_lang = array(
'auto_refresh' => 'Tự động làm mới', 'auto_refresh' => 'Tự động làm mới',
'auto_refresh_description' => 'Tự động làm mới servers page.<br><span class="small">Trong vài giây, 'auto_refresh_description' => 'Tự động làm mới servers page.<br><span class="small">Trong vài giây,
nếu 0 trang sẽ không làm mới.</span>', nếu 0 trang sẽ không làm mới.</span>',
'seconds' => 'giây',
'test' => 'Thử', 'test' => 'Thử',
'test_email' => 'Một email sẽ được gửi đến địa chỉ được xác định trong hồ 'test_email' => 'Một email sẽ được gửi đến địa chỉ được xác định trong hồ
người dùng của bạn.', người dùng của bạn.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => '1分钟前', 'a_minute_ago' => '1分钟前',
'seconds_ago' => '%d 秒前', 'seconds_ago' => '%d 秒前',
'a_second_ago' => '刚刚', 'a_second_ago' => '刚刚',
'seconds' => '秒',
), ),
'menu' => array( 'menu' => array(
'config' => '设置', 'config' => '设置',
@ -259,7 +260,6 @@ $sm_lang = array(
'auto_refresh' => '自动刷新', 'auto_refresh' => '自动刷新',
'auto_refresh_description' => '自动刷新服务器页.<br><span class="small">单位为秒, 设置为 0 'auto_refresh_description' => '自动刷新服务器页.<br><span class="small">单位为秒, 设置为 0
则不自动刷新.</span>', 则不自动刷新.</span>',
'seconds' => '秒',
'test' => '测试', 'test' => '测试',
'test_email' => '将发送一封邮件到您账户设置的邮件地址.', 'test_email' => '将发送一封邮件到您账户设置的邮件地址.',
'test_sms' => '将发送一封短信到您账户设置的手机号码.', 'test_sms' => '将发送一封短信到您账户设置的手机号码.',

View File

@ -258,7 +258,8 @@ $sm_lang = array(
'sms_from' => '發送人電話號碼', 'sms_from' => '發送人電話號碼',
'pushover_status' => '啟用Pushover通知', 'pushover_status' => '啟用Pushover通知',
'pushover_description' => 'Pushover是線上服務讓您可以方便的收到即時通知請參考 <a 'pushover_description' => 'Pushover是線上服務讓您可以方便的收到即時通知請參考 <a
href="https://pushover.net/" target="_blank"> 網站</a> 可以得到更詳細的資訊。</a> ', href="https://pushover.net/" target="_blank"> 網站</a>
可以得到更詳細的資訊。</a> ',
'pushover_clone_app' => '點選這裡可快速建立Pushover App', 'pushover_clone_app' => '點選這裡可快速建立Pushover App',
'pushover_api_token_description' => '在您使用 Pushover 通知之前,需要先到這裡-><a href="%1$s" 'pushover_api_token_description' => '在您使用 Pushover 通知之前,需要先到這裡-><a href="%1$s"
target="_blank" rel="noopener">註冊Pushover App帳號</a> target="_blank" rel="noopener">註冊Pushover App帳號</a>
@ -269,7 +270,8 @@ $sm_lang = array(
<a href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a> <a href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
可以取得更多資訊與安裝說明。', 可以取得更多資訊與安裝說明。',
'telegram_api_token_description' => '使用 Telegram 通知之前,您必需先取得 API Token。請到 <a 'telegram_api_token_description' => '使用 Telegram 通知之前,您必需先取得 API Token。請到 <a
href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a> 取得說明。', href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
取得說明。',
'alert_type' => '需要提醒的類別', 'alert_type' => '需要提醒的類別',
'alert_type_description' => '<b>狀態改變:</b> 伺服器 連線 -> 離線或連線 -> 'alert_type_description' => '<b>狀態改變:</b> 伺服器 連線 -> 離線或連線 ->
連線的狀態變化將會收到提醒通知。<br/><br /><b>離線:</b> 連線的狀態變化將會收到提醒通知。<br/><br /><b>離線:</b>
@ -298,7 +300,6 @@ $sm_lang = array(
'settings_log' => '記錄設定', 'settings_log' => '記錄設定',
'settings_proxy' => 'Proxy 設定', 'settings_proxy' => 'Proxy 設定',
'auto_refresh' => '自動更新', 'auto_refresh' => '自動更新',
'seconds' => '秒',
'test' => '測試', 'test' => '測試',
'test_email' => '電子郵件將發送到您在使用者設定內指定的電子郵件信箱。', 'test_email' => '電子郵件將發送到您在使用者設定內指定的電子郵件信箱。',
'test_sms' => '簡訊將發送到您在使用者設定內指定的行動電話號碼。', 'test_sms' => '簡訊將發送到您在使用者設定內指定的行動電話號碼。',

View File

@ -217,7 +217,7 @@ abstract class AbstractController implements ControllerInterface
if (!$this->xhr) { if (!$this->xhr) {
// in XHR mode, we will not add the main template // in XHR mode, we will not add the main template
$tpl_data = array( $tpl_data = array(
'title' => strtoupper(psm_get_lang('system', 'title')), 'title' => psm_get_conf('site_title', strtoupper(psm_get_lang('system', 'title'))),
'label_back_to_top' => psm_get_lang('system', 'back_to_top'), 'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
'add_footer' => $this->add_footer, 'add_footer' => $this->add_footer,
'version' => 'v' . PSM_VERSION, 'version' => 'v' . PSM_VERSION,

View File

@ -74,10 +74,12 @@ class ConfigController extends AbstractController
'sms_from', 'sms_from',
'pushover_api_token', 'pushover_api_token',
'telegram_api_token', 'telegram_api_token',
'jabber_host', 'jabber_host',
'jabber_port', 'jabber_port',
'jabber_username', 'jabber_username',
'jabber_domain' 'jabber_domain',
'user_agent',
'site_title'
); );
/** /**
@ -86,7 +88,7 @@ class ConfigController extends AbstractController
*/ */
protected $encryptedFields = [ protected $encryptedFields = [
'email_smtp_password', 'email_smtp_password',
'jabber_password' 'jabber_password'
]; ];
private $default_tab = 'general'; private $default_tab = 'general';
@ -191,6 +193,14 @@ class ConfigController extends AbstractController
foreach ($this->fields as $input_key) { foreach ($this->fields as $input_key) {
$tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : ''; $tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : '';
} }
$tpl_data['user_agent'] = empty($tpl_data['user_agent']) ?
'Mozilla/5.0 (compatible; phpservermon/' .
PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)' : $tpl_data['user_agent'];
$tpl_data['site_title'] = empty($tpl_data['site_title']) ?
strtoupper(psm_get_lang('system', 'title')) : $tpl_data['site_title'];
// encrypted fields // encrypted fields
foreach ($this->encryptedFields as $encryptedField) { foreach ($this->encryptedFields as $encryptedField) {
$tpl_data[$encryptedField] = ''; $tpl_data[$encryptedField] = '';
@ -221,9 +231,10 @@ class ConfigController extends AbstractController
protected function executeSave() protected function executeSave()
{ {
if (!empty($_POST)) { if (!empty($_POST)) {
// save new config // save new config
$clean = array( $clean = array(
'language' => $_POST['language'], 'language' => $_POST['language'],
'site_title' => $_POST['site_title'],
'sms_gateway' => $_POST['sms_gateway'], 'sms_gateway' => $_POST['sms_gateway'],
'alert_type' => $_POST['alert_type'], 'alert_type' => $_POST['alert_type'],
'email_smtp_security' => 'email_smtp_security' =>
@ -234,7 +245,7 @@ class ConfigController extends AbstractController
'log_retention_period' => intval(psm_POST('log_retention_period', 365)), 'log_retention_period' => intval(psm_POST('log_retention_period', 365)),
'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime())) 'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime()))
); );
foreach ($this->checkboxes as $input_key) { foreach ($this->checkboxes as $input_key) {
$clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0'; $clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0';
} }
foreach ($this->fields as $input_key) { foreach ($this->fields as $input_key) {
@ -264,7 +275,7 @@ class ConfigController extends AbstractController
} elseif (!empty($_POST['test_telegram'])) { } elseif (!empty($_POST['test_telegram'])) {
$this->testTelegram(); $this->testTelegram();
} elseif (!empty($_POST['test_jabber'])) { } elseif (!empty($_POST['test_jabber'])) {
$this->testJabber(); $this->testJabber();
} }
if ($language_refresh) { if ($language_refresh) {
@ -283,7 +294,7 @@ class ConfigController extends AbstractController
} elseif (isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) { } elseif (isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) {
$this->default_tab = 'telegram'; $this->default_tab = 'telegram';
} elseif (isset($_POST['jabber_submit']) || !empty($_POST['test_jabber'])) { } elseif (isset($_POST['jabber_submit']) || !empty($_POST['test_jabber'])) {
$this->default_tab = 'jabber'; $this->default_tab = 'jabber';
} }
} }
return $this->runAction('index'); return $this->runAction('index');
@ -408,24 +419,24 @@ class ConfigController extends AbstractController
} }
} }
/** /**
* Test Jabber. * Test Jabber.
*/ */
protected function testJabber() protected function testJabber()
{ {
$user = $this->getUser()->getUser(); $user = $this->getUser()->getUser();
psm_jabber_send_message( psm_jabber_send_message(
psm_get_conf('jabber_host'), psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'), psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')), psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
[$user->jabber], [$user->jabber],
psm_get_lang('config', 'test_message'), psm_get_lang('config', 'test_message'),
(trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null), (trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null),
(trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null) (trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null)
); );
// no message - async ... so just info // no message - async ... so just info
$this->addMessage(psm_get_lang('config', 'jabber_check'), 'info'); $this->addMessage(psm_get_lang('config', 'jabber_check'), 'info');
// @todo possible to set message via ajax with callback ... // @todo possible to set message via ajax with callback ...
} }
protected function getLabels() protected function getLabels()
@ -435,12 +446,12 @@ class ConfigController extends AbstractController
'label_tab_sms' => psm_get_lang('config', 'tab_sms'), 'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'), 'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'), 'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'),
'label_tab_jabber' => psm_get_lang('config', 'tab_jabber'), 'label_tab_jabber' => psm_get_lang('config', 'tab_jabber'),
'label_settings_email' => psm_get_lang('config', 'settings_email'), 'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'), 'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'), 'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'),
'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'), 'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'),
'label_settings_jabber' => psm_get_lang('config', 'settings_jabber'), 'label_settings_jabber' => psm_get_lang('config', 'settings_jabber'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'), 'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_log' => psm_get_lang('config', 'settings_log'), 'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'), 'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'),
@ -482,17 +493,17 @@ class ConfigController extends AbstractController
'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'), 'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'),
'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'), 'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'),
'label_jabber_status' => psm_get_lang('config', 'jabber_status'), 'label_jabber_status' => psm_get_lang('config', 'jabber_status'),
'label_jabber_description' => psm_get_lang('config', 'jabber_description'), 'label_jabber_description' => psm_get_lang('config', 'jabber_description'),
'label_jabber_host' => psm_get_lang('config', 'jabber_host'), 'label_jabber_host' => psm_get_lang('config', 'jabber_host'),
'label_jabber_host_description' => psm_get_lang('config', 'jabber_host_description'), 'label_jabber_host_description' => psm_get_lang('config', 'jabber_host_description'),
'label_jabber_port' => psm_get_lang('config', 'jabber_port'), 'label_jabber_port' => psm_get_lang('config', 'jabber_port'),
'label_jabber_port_description' => psm_get_lang('config', 'jabber_port_description'), 'label_jabber_port_description' => psm_get_lang('config', 'jabber_port_description'),
'label_jabber_username' => psm_get_lang('config', 'jabber_username'), 'label_jabber_username' => psm_get_lang('config', 'jabber_username'),
'label_jabber_username_description' => psm_get_lang('config', 'jabber_username_description'), 'label_jabber_username_description' => psm_get_lang('config', 'jabber_username_description'),
'label_jabber_domain' => psm_get_lang('config', 'jabber_domain'), 'label_jabber_domain' => psm_get_lang('config', 'jabber_domain'),
'label_jabber_domain_description' => psm_get_lang('config', 'jabber_domain_description'), 'label_jabber_domain_description' => psm_get_lang('config', 'jabber_domain_description'),
'label_jabber_password' => psm_get_lang('config', 'jabber_password'), 'label_jabber_password' => psm_get_lang('config', 'jabber_password'),
'label_jabber_password_description' => psm_get_lang('config', 'jabber_password_description'), 'label_jabber_password_description' => psm_get_lang('config', 'jabber_password_description'),
'label_alert_type' => psm_get_lang('config', 'alert_type'), 'label_alert_type' => psm_get_lang('config', 'alert_type'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'), 'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_combine_notifications' => psm_get_lang('config', 'combine_notifications'), 'label_combine_notifications' => psm_get_lang('config', 'combine_notifications'),
@ -503,12 +514,12 @@ class ConfigController extends AbstractController
'label_log_sms' => psm_get_lang('config', 'log_sms'), 'label_log_sms' => psm_get_lang('config', 'log_sms'),
'label_log_pushover' => psm_get_lang('config', 'log_pushover'), 'label_log_pushover' => psm_get_lang('config', 'log_pushover'),
'label_log_telegram' => psm_get_lang('config', 'log_telegram'), 'label_log_telegram' => psm_get_lang('config', 'log_telegram'),
'label_log_jabber' => psm_get_lang('config', 'log_jabber'), 'label_log_jabber' => psm_get_lang('config', 'log_jabber'),
'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'), 'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'),
'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'), 'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'),
'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'), 'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
'label_auto_refresh_description' => psm_get_lang('config', 'auto_refresh_description'), 'label_auto_refresh_description' => psm_get_lang('config', 'auto_refresh_description'),
'label_seconds' => psm_get_lang('config', 'seconds'), 'label_seconds' => psm_get_lang('system', 'seconds'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),
'label_test' => psm_get_lang('config', 'test'), 'label_test' => psm_get_lang('config', 'test'),
'label_log_retention_period' => psm_get_lang('config', 'log_retention_period'), 'label_log_retention_period' => psm_get_lang('config', 'log_retention_period'),
@ -516,7 +527,9 @@ class ConfigController extends AbstractController
'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'), 'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'),
'label_days' => psm_get_lang('config', 'log_retention_days'), 'label_days' => psm_get_lang('config', 'log_retention_days'),
'label_leave_blank' => psm_get_lang('users', 'password_leave_blank'), 'label_leave_blank' => psm_get_lang('users', 'password_leave_blank'),
'label_user_agent' => psm_get_lang('config', 'user_agent'),
'label_user_agent_key_note' => psm_get_lang('config', 'user_agent_key_note'),
'label_site_title' => psm_get_lang('config', 'site_title'),
); );
} }
} }

View File

@ -257,7 +257,7 @@ class InstallController extends AbstractController
'pushover_key' => '', 'pushover_key' => '',
'pushover_device' => '', 'pushover_device' => '',
'telegram_id' => '', 'telegram_id' => '',
'jabber' => '' 'jabber' => ''
); );
$validator = $this->container->get('util.user.validator'); $validator = $this->container->get('util.user.validator');

View File

@ -114,7 +114,7 @@ abstract class AbstractServerController extends AbstractController
*/ */
protected function formatServer($server) protected function formatServer($server)
{ {
$server['rtime'] = round((float) $server['rtime'], 4); $server['rtime'] = $server['rtime'];
$server['last_online'] = psm_timespan($server['last_online']); $server['last_online'] = psm_timespan($server['last_online']);
$server['last_offline'] = psm_timespan($server['last_offline']); $server['last_offline'] = psm_timespan($server['last_offline']);
if ($server['last_offline'] != psm_get_lang('system', 'never')) { if ($server['last_offline'] != psm_get_lang('system', 'never')) {

View File

@ -57,7 +57,7 @@ class LogController extends AbstractServerController
'label_sms' => psm_get_lang('log', 'sms'), 'label_sms' => psm_get_lang('log', 'sms'),
'label_pushover' => psm_get_lang('log', 'pushover'), 'label_pushover' => psm_get_lang('log', 'pushover'),
'label_telegram' => psm_get_lang('log', 'telegram'), 'label_telegram' => psm_get_lang('log', 'telegram'),
'label_jabber' => psm_get_lang('log', 'jabber'), 'label_jabber' => psm_get_lang('log', 'jabber'),
'label_title' => psm_get_lang('log', 'title'), 'label_title' => psm_get_lang('log', 'title'),
'label_server' => psm_get_lang('servers', 'server'), 'label_server' => psm_get_lang('servers', 'server'),
'label_type' => psm_get_lang('log', 'type'), 'label_type' => psm_get_lang('log', 'type'),
@ -161,9 +161,9 @@ class LogController extends AbstractServerController
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) { if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id // restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON ( $sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()} `us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id` AND `us`.`server_id`=`servers`.`server_id`
)"; )";
} }
$entries = $this->db->query( $entries = $this->db->query(
'SELECT ' . 'SELECT ' .

View File

@ -102,7 +102,7 @@ class ServerController extends AbstractServerController
'sms' => 'icon-mobile', 'sms' => 'icon-mobile',
'pushover' => 'icon-pushover', 'pushover' => 'icon-pushover',
'telegram' => 'icon-telegram', 'telegram' => 'icon-telegram',
'jabber' => 'icon-jabber' 'jabber' => 'icon-jabber'
); );
$servers = $this->getServers(); $servers = $this->getServers();
@ -174,6 +174,13 @@ class ServerController extends AbstractServerController
$tpl_data['users'] = $this->db->select(PSM_DB_PREFIX . 'users', null, array('user_id', 'name'), '', 'name'); $tpl_data['users'] = $this->db->select(PSM_DB_PREFIX . 'users', null, array('user_id', 'name'), '', 'name');
foreach ($tpl_data['users'] as &$user) {
$user['id'] = $user['user_id'];
unset($user['user_id']);
$user['label'] = $user['name'];
unset($user['name']);
}
switch ($this->server_id) { switch ($this->server_id) {
case 0: case 0:
// insert mode // insert mode
@ -194,10 +201,6 @@ class ServerController extends AbstractServerController
$user_idc_selected = $this->getServerUsers($this->server_id); $user_idc_selected = $this->getServerUsers($this->server_id);
foreach ($tpl_data['users'] as &$user) { foreach ($tpl_data['users'] as &$user) {
$user['id'] = $user['user_id'];
unset($user['user_id']);
$user['label'] = $user['name'];
unset($user['name']);
if (in_array($user['id'], $user_idc_selected)) { if (in_array($user['id'], $user_idc_selected)) {
$user['edit_selected'] = 'selected="selected"'; $user['edit_selected'] = 'selected="selected"';
} }
@ -236,7 +239,7 @@ class ServerController extends AbstractServerController
'edit_sms_selected' => $edit_server['sms'], 'edit_sms_selected' => $edit_server['sms'],
'edit_pushover_selected' => $edit_server['pushover'], 'edit_pushover_selected' => $edit_server['pushover'],
'edit_telegram_selected' => $edit_server['telegram'], 'edit_telegram_selected' => $edit_server['telegram'],
'edit_jabber_selected' => $edit_server['jabber'], 'edit_jabber_selected' => $edit_server['jabber'],
)); ));
} }
@ -310,7 +313,7 @@ class ServerController extends AbstractServerController
'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no', 'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no',
'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no', 'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no',
'telegram' => in_array($_POST['telegram'], array('yes', 'no')) ? $_POST['telegram'] : 'no', 'telegram' => in_array($_POST['telegram'], array('yes', 'no')) ? $_POST['telegram'] : 'no',
'jabber' => in_array($_POST['jabber'], array('yes', 'no')) ? $_POST['jabber'] : 'no', 'jabber' => in_array($_POST['jabber'], array('yes', 'no')) ? $_POST['jabber'] : 'no',
); );
// make sure websites start with http:// // make sure websites start with http://
if ( if (
@ -518,6 +521,15 @@ class ServerController extends AbstractServerController
if (strlen($tpl_data['last_error_output']) > 255) { if (strlen($tpl_data['last_error_output']) > 255) {
$tpl_data['last_error_output_truncated'] = substr($tpl_data['last_error_output'], 0, 255) . '...'; $tpl_data['last_error_output_truncated'] = substr($tpl_data['last_error_output'], 0, 255) . '...';
} }
// fetch server status logs
$log_entries = $this->getServerLogs($this->server_id);
for ($x = 0; $x < count($log_entries); $x++) {
$record = &$log_entries[$x];
$record['datetime_format'] = psm_date($record['datetime']);
}
$tpl_data['log_entries'] = $log_entries;
return $this->twig->render('module/server/server/view.tpl.html', $tpl_data); return $this->twig->render('module/server/server/view.tpl.html', $tpl_data);
} }
@ -579,10 +591,10 @@ class ServerController extends AbstractServerController
'label_send_sms' => psm_get_lang('servers', 'send_sms'), 'label_send_sms' => psm_get_lang('servers', 'send_sms'),
'label_send_pushover' => psm_get_lang('servers', 'send_pushover'), 'label_send_pushover' => psm_get_lang('servers', 'send_pushover'),
'label_telegram' => psm_get_lang('servers', 'telegram'), 'label_telegram' => psm_get_lang('servers', 'telegram'),
'label_jabber' => psm_get_lang('servers', 'jabber'), 'label_jabber' => psm_get_lang('servers', 'jabber'),
'label_pushover' => psm_get_lang('servers', 'pushover'), 'label_pushover' => psm_get_lang('servers', 'pushover'),
'label_send_telegram' => psm_get_lang('servers', 'send_telegram'), 'label_send_telegram' => psm_get_lang('servers', 'send_telegram'),
'label_send_jabber' => psm_get_lang('servers', 'send_jabber'), 'label_send_jabber' => psm_get_lang('servers', 'send_jabber'),
'label_users' => psm_get_lang('servers', 'users'), 'label_users' => psm_get_lang('servers', 'users'),
'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'), 'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'),
'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'), 'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'),
@ -597,7 +609,8 @@ class ServerController extends AbstractServerController
'label_yes' => psm_get_lang('system', 'yes'), 'label_yes' => psm_get_lang('system', 'yes'),
'label_no' => psm_get_lang('system', 'no'), 'label_no' => psm_get_lang('system', 'no'),
'label_add_new' => psm_get_lang('system', 'add_new'), 'label_add_new' => psm_get_lang('system', 'add_new'),
'label_seconds' => psm_get_lang('config', 'seconds'), 'label_seconds' => psm_get_lang('system', 'seconds'),
'label_milliseconds' => psm_get_lang('system', 'milliseconds'),
'label_online' => psm_get_lang('servers', 'online'), 'label_online' => psm_get_lang('servers', 'online'),
'label_offline' => psm_get_lang('servers', 'offline'), 'label_offline' => psm_get_lang('servers', 'offline'),
'label_ok' => psm_get_lang('system', 'ok'), 'label_ok' => psm_get_lang('system', 'ok'),
@ -606,6 +619,10 @@ class ServerController extends AbstractServerController
'label_settings' => psm_get_lang('system', 'settings'), 'label_settings' => psm_get_lang('system', 'settings'),
'label_output' => psm_get_lang('servers', 'output'), 'label_output' => psm_get_lang('servers', 'output'),
'label_search' => psm_get_lang('system', 'search'), 'label_search' => psm_get_lang('system', 'search'),
'label_log_title' => psm_get_lang('log', 'title'),
'label_log_no_logs' => psm_get_lang('log', 'no_logs'),
'label_date' => psm_get_lang('system', 'date'),
'label_message' => psm_get_lang('system', 'message'),
); );
} }
@ -627,4 +644,42 @@ class ServerController extends AbstractServerController
} }
return $result; return $result;
} }
/**
* Get logs for a server
* @param int $server_id
* @param string $type status/email/sms
* @return \PDOStatement array
*/
protected function getServerLogs($server_id, $type = 'status')
{
$sql_join = '';
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id`
)";
}
$entries = $this->db->query(
'SELECT ' .
'`servers`.`label`, ' .
'`servers`.`ip`, ' .
'`servers`.`port`, ' .
'`servers`.`type` AS server_type, ' .
'`log`.`log_id`, ' .
'`log`.`type`, ' .
'`log`.`message`, ' .
'`log`.`datetime` ' .
'FROM `' . PSM_DB_PREFIX . 'log` AS `log` ' .
'JOIN `' . PSM_DB_PREFIX . 'servers` AS `servers` ON (`servers`.`server_id`=`log`.`server_id`) ' .
$sql_join .
'WHERE `log`.`type`=\'' . $type . '\' ' .
'AND `log`.`server_id`=' . $server_id . ' ' .
'ORDER BY `datetime` DESC ' .
'LIMIT 0,20'
);
return $entries;
}
} }

View File

@ -90,8 +90,8 @@ class ProfileController extends AbstractController
'label_activate_telegram' => psm_get_lang('users', 'activate_telegram'), 'label_activate_telegram' => psm_get_lang('users', 'activate_telegram'),
'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'), 'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'),
'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL, 'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL,
'label_jabber' => psm_get_lang('users', 'jabber'), 'label_jabber' => psm_get_lang('users', 'jabber'),
'label_jabber_description' => psm_get_lang('users', 'jabber_description'), 'label_jabber_description' => psm_get_lang('users', 'jabber_description'),
'label_email' => psm_get_lang('users', 'email'), 'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),
'form_action' => psm_build_url(array( 'form_action' => psm_build_url(array(

149
src/psm/Txtmsg/SMSAPI.php Executable file
View File

@ -0,0 +1,149 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Mateusz Małek <tajgeer@gmail.com>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.5
**/
namespace psm\Txtmsg;
class SMSAPI extends Core
{
const VARIANT_INTERNATIONAL = 1;
const VARIANT_POLISH = 2;
/**
* SMSAPI comes with two variants - designed for polish or international customers.
*
* @var int
*/
private $variant = self::VARIANT_INTERNATIONAL;
/**
* Name of the sender. As a default the sender name is set to "Test".
* Only verified names are being accepted.
* Sender name may be set after logging into Customer Portal on Sendernames.
* @see https://www.smsapi.com/docs/#2-single-sms
*
* @var string
*/
protected $originator;
/**
* Token used to authenticate in SMSAPI system.
* @see https://www.smsapi.com/docs/#authentication
*
* @var string
*/
protected $password;
/**
* Send sms using the SMSAPI
*
* @var string $message
* @var array $this->recipients
* @var array $this->originator
* @var string $this->password
* @var array $recipients_chunk
* @var string $host
*
* @var mixed $result
* @var array $headers
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message)
{
$tld = ($this->variant === static::VARIANT_INTERNATIONAL) ? "com" : "pl";
$host = "api.smsapi.{$tld}";
$backupHost = "api2.smsapi.{$tld}";
// One user at a time.
$recipients_chunk = array_chunk($this->recipients, 1);
foreach ($recipients_chunk as $recipient) {
try {
$response = $this->processSendOperation($host, $recipient, $message);
} catch (\RuntimeException $e) {
try {
$response = $this->processSendOperation($backupHost, $recipient, $message);
} catch (\RuntimeException $e) {
return "({$recipient}) " . $e->getMessage();
}
}
if (isset($response->error)) {
return $response->message;
}
return 1;
}
}
/**
* Perform actual SMS sending operation
*
* @param $host
* @param $recipient
* @param $message
* @return object
* @throws RuntimeException
*/
private function processSendOperation($host, $recipient, $message)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://{$host}/sms.do");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
"access_token" => $this->password,
"from" => $this->originator,
"to" => $recipient,
"message" => $message,
"encoding" => "utf-8",
"normalize" => "1",
"format" => "json"
)));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$result = curl_exec($ch);
$error = false;
if (curl_errno($ch)) {
$error = curl_error($ch);
}
curl_close($ch);
if ($error !== false) {
throw new \RuntimeException($error);
}
return json_decode($result);
}
}

View File

@ -145,7 +145,7 @@ class Modal implements ModalInterface
$tpl = $this->twig->loadTemplate('util/module/modal.tpl.html'); $tpl = $this->twig->loadTemplate('util/module/modal.tpl.html');
$html = $tpl->render(array( $html = $tpl->render(array(
'modal_id' => $this->modal_id, 'modal_id' => $this->modal_id,
'modal_title' => !empty($this->title) ? $this->title : psm_get_lang('system', 'title'), 'modal_title' => !empty($this->title) ? $this->title : psm_get_conf('site_title', psm_get_lang('system', 'title')),
'modal_body' => $message, 'modal_body' => $message,
'has_cancel' => $has_cancel, 'has_cancel' => $has_cancel,
'label_cancel' => psm_get_lang('system', 'cancel'), 'label_cancel' => psm_get_lang('system', 'cancel'),

View File

@ -74,7 +74,7 @@ class HistoryGraph
1 => $this->generateGraphHistory($server_id, $last_year, $last_week), 1 => $this->generateGraphHistory($server_id, $last_year, $last_week),
); );
$info_fields = array( $info_fields = array(
'latency_avg' => '%01.4f', 'latency_avg' => '%01.5f',
'uptime' => '%01.3f%%', 'uptime' => '%01.3f%%',
); );
@ -252,6 +252,20 @@ class HistoryGraph
$prev_downtime = 0; $prev_downtime = 0;
$downtime = 0; $downtime = 0;
// get highest latency record for offline height
$n = count($records);
$highest_latency = 0.0000;
for ($i = 0; $i < $n; $i++) {
if (!array_key_exists('latency', $records[$i])) {
continue;
}
// Update if latency is higher
$highest_latency = $highest_latency < floatval($records[$i]['latency']) ?
floatval($records[$i]['latency']) : $highest_latency;
}
// to ms
$highest_latency = round($highest_latency * 1000);
// Create the list of points and server down zones // Create the list of points and server down zones
foreach ($records as $record) { foreach ($records as $record) {
$time = strtotime($record['date']); $time = strtotime($record['date']);
@ -266,11 +280,11 @@ class HistoryGraph
if ($record['status'] == 0) { if ($record['status'] == 0) {
$lines['online'][] = $prev['status'] $lines['online'][] = $prev['status']
// Previous datapoint was online // Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] . '}' ? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] * 1000 . '}'
// Previous datapoint was offline // Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y: null}'; : '{ x: ' . ($time * 1000) . ', y: null}';
// new outage start // new outage start
$lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:0.1}'; $lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:' . $highest_latency . '}';
$prev_downtime != 0 ?: $prev_downtime = $time; $prev_downtime != 0 ?: $prev_downtime = $time;
} else { } else {
@ -280,15 +294,15 @@ class HistoryGraph
// Previous datapoint was online // Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y:null}' ? '{ x: ' . ($time * 1000) . ', y:null}'
// Previous datapoint was offline // Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y:0.1}'; : '{ x: ' . ($time * 1000) . ', y:' . $highest_latency . '}';
$lines['online'][] = '{ x: ' . ($time * 1000) . ', y: ' . $lines['online'][] = '{ x: ' . ($time * 1000) . ', y: ' .
round((float) $record[$key], 4) . '}'; round((float) $record[$key] * 1000, 2) . '}';
$prev_downtime == 0 ?: $downtime += ($time - $prev_downtime); $prev_downtime == 0 ?: $downtime += ($time - $prev_downtime);
$prev_downtime = 0; $prev_downtime = 0;
} }
} else { } else {
$lines[$key][] = '{ x: \'' . $record['date'] . '\', y: ' . $record[$key] . '}'; $lines[$key][] = '{ x: \'' . $record['date'] . '\', y: ' . $record[$key] * 1000 . '}';
} }
$prev = $record; $prev = $record;
} }
@ -298,7 +312,8 @@ class HistoryGraph
// Record the first and last date as a string in the down array // Record the first and last date as a string in the down array
$prev_downtime == 0 ?: $downtime += ($now->getTimestamp() - $prev_downtime); $prev_downtime == 0 ?: $downtime += ($now->getTimestamp() - $prev_downtime);
if ($add_uptime) { if ($add_uptime) {
$prev['status'] ?: $lines['offline'][] = '{ x: ' . ($now->getTimestamp() * 1000) . ', y:0.1}'; $prev['status'] ?: $lines['offline'][] =
'{ x: ' . ($now->getTimestamp() * 1000) . ', y:' . $highest_latency . '}';
$data['uptime'] = 100 - ($downtime / ($end_time->getTimestamp() - $start_time->getTimestamp())); $data['uptime'] = 100 - ($downtime / ($end_time->getTimestamp() - $start_time->getTimestamp()));
} }

View File

@ -53,9 +53,9 @@ class UpdateManager implements ContainerAwareInterface
*/ */
public function run($skip_perms = false, $status = null) public function run($skip_perms = false, $status = null)
{ {
if (false === in_array($status, ['on', 'off'], true)) { if (false === in_array($status, ['on', 'off'], true)) {
$status = null; $status = null;
} }
// check if we need to restrict the servers to a certain user // check if we need to restrict the servers to a certain user
$sql_join = ''; $sql_join = '';
@ -63,17 +63,17 @@ class UpdateManager implements ContainerAwareInterface
if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) { if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id // restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON ( $sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->container->get('user')->getUserId()} `us`.`user_id`={$this->container->get('user')->getUserId()}
AND `us`.`server_id`=`s`.`server_id` AND `us`.`server_id`=`s`.`server_id`
)"; )";
} }
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`, $sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,
`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram`, `s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram`,
`s`.`jabber` `s`.`jabber`
FROM `" . PSM_DB_PREFIX . "servers` AS `s` FROM `" . PSM_DB_PREFIX . "servers` AS `s`
{$sql_join} {$sql_join}
WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : ''); WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : '');
$servers = $this->container->get('db')->query($sql); $servers = $this->container->get('db')->query($sql);

View File

@ -69,10 +69,10 @@ class StatusNotifier
*/ */
protected $send_telegram = false; protected $send_telegram = false;
/** /**
* Send Jabber? * Send Jabber?
* @var bool * @var bool
*/ */
protected $send_jabber = false; protected $send_jabber = false;
/** /**
@ -258,7 +258,7 @@ class StatusNotifier
} }
if ($this->send_jabber && $this->server['jaber'] == 'yes') { if ($this->send_jabber && $this->server['jaber'] == 'yes') {
$this->combine ? $this->setCombi('jabber') : $this->notifyByJabber($users); $this->combine ? $this->setCombi('jabber') : $this->notifyByJabber($users);
} }
return $notify; return $notify;
@ -461,7 +461,7 @@ class StatusNotifier
$pushover->setTitle($title); $pushover->setTitle($title);
$pushover->setMessage(str_replace('<br/>', "\n", $message)); $pushover->setMessage(str_replace('<br/>', "\n", $message));
$pushover->setUrl(psm_build_url()); $pushover->setUrl(psm_build_url());
$pushover->setUrlTitle(psm_get_lang('system', 'title')); $pushover->setUrlTitle(psm_get_conf('site_title', psm_get_lang('system', 'title')));
// Log // Log
if (psm_get_conf('log_pushover')) { if (psm_get_conf('log_pushover')) {
@ -562,52 +562,52 @@ class StatusNotifier
} }
} }
/** /**
* @param array $users * @param array $users
* @param array $combi * @param array $combi
*/ */
protected function notifyByJabber($users, $combi = []) protected function notifyByJabber($users, $combi = [])
{ {
// Remove users that have no jabber // Remove users that have no jabber
foreach ($users as $k => $user) { foreach ($users as $k => $user) {
if (trim($user['jabber']) === '') { if (trim($user['jabber']) === '') {
unset($users[$k]); unset($users[$k]);
} }
} }
// Validation // Validation
if (empty($users)) { if (empty($users)) {
return; return;
} }
// Message // Message
$message = key_exists('message', $combi) ? $message = key_exists('message', $combi) ?
$combi['message'] : $combi['message'] :
psm_parse_msg($this->status_new, 'jabber_message', $this->server); psm_parse_msg($this->status_new, 'jabber_message', $this->server);
// Log // Log
if (psm_get_conf('log_jabber')) { if (psm_get_conf('log_jabber')) {
$log_id = psm_add_log($this->server_id, 'jabber', $message); $log_id = psm_add_log($this->server_id, 'jabber', $message);
} }
$usersJabber = []; $usersJabber = [];
foreach ($users as $user) { foreach ($users as $user) {
// Log // Log
if (!empty($log_id)) { if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']); psm_add_log_user($log_id, $user['user_id']);
} }
$usersJabber[] = $user['jabber']; $usersJabber[] = $user['jabber'];
} }
// Jabber // Jabber
psm_jabber_send_message( psm_jabber_send_message(
psm_get_conf('jabber_host'), psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'), psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')), psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
$usersJabber, $usersJabber,
$message, $message,
(trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null), (trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null),
(trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null) (trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null)
); );
} }
/** /**
@ -622,12 +622,12 @@ class StatusNotifier
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`,
`u`.`pushover_device`, `u`.`telegram_id`, `u`.`pushover_device`, `u`.`telegram_id`,
`u`.`jabber` `u`.`jabber`
FROM `' . PSM_DB_PREFIX . 'users` AS `u` FROM `' . PSM_DB_PREFIX . 'users` AS `u`
JOIN `' . PSM_DB_PREFIX . "users_servers` AS `us` ON ( JOIN `' . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id` `us`.`user_id`=`u`.`user_id`
AND `us`.`server_id` = {$server_id} AND `us`.`server_id` = {$server_id}
) )
"); ");
return $users; return $users;
} }
} }

View File

@ -179,36 +179,42 @@ class StatusUpdater
$max_runs = 1; $max_runs = 1;
} }
$result = null; $result = null;
// Execute ping // Choose right ping version, ping6 for IPV6, ping for IPV4
$pingCommand = 'ping6'; $pingCommand = 'ping6';
$serverIp = $this->server['ip']; $serverIp = $this->server['ip'];
if (filter_var($serverIp,FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false){ if (filter_var($serverIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$pingCommand = 'ping'; $pingCommand = 'ping';
}
$txt = exec($pingCommand . " -c " . $max_runs . " " . $serverIp . " 2>&1", $output);
// Non-greedy match on filler
$re1 = '.*?';
// Uninteresting: float
$re2 = '[+-]?\\d*\\.\\d+(?![-+0-9\\.])';
// Non-greedy match on filler
$re3 = '.*?';
// Float 1
$re4 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])';
if (preg_match_all("/" . $re1 . $re2 . $re3 . $re4 . "/is", $txt, $matches)) {
$result = $matches[1][0];
} }
if (substr($output[0],0,4) == 'PING' && strpos($output[count($output)-2],'packets transmitted')){
$result = 0; // execute PING
} $txt = exec($pingCommand . " -c " . $max_runs . " " . $serverIp . " 2>&1", $output);
if (!is_null($result)) {
$this->header = $output[0]; // Check if output is PING and if transmitted packets is equal to received packets.
preg_match('/^(\d{1,3}) packets transmitted, (\d{1,3}).*$/', $output[count($output) - 2], $output_package_loss);
if (
substr($output[0], 0, 4) == 'PING' &&
!empty($output_package_loss) &&
$output_package_loss[1] === $output_package_loss[2]
) {
// Gets avg from 'round-trip min/avg/max/stddev = 7.109/7.109/7.109/0.000 ms'
preg_match_all("/(\d+\.\d+)/", $output[count($output) - 1], $result);
$result = floatval($result[0][1]);
$this->header = "";
foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
$status = true; $status = true;
} else { } else {
$this->header = "-"; $this->header = "-";
$this->error = $output[0]; foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
$this->error = $output[count($output) - 2];
$status = false; $status = false;
} }
//Divide by a thousand to convert to milliseconds // To miliseconds
$this->rtime = $result / 1000; $this->rtime = $result / 1000;
// check if server is available and rerun if asked. // check if server is available and rerun if asked.
@ -233,7 +239,7 @@ class StatusUpdater
$starttime = microtime(true); $starttime = microtime(true);
$serverIp = $this->server['ip']; $serverIp = $this->server['ip'];
if (filter_var($serverIp,FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false){ if (filter_var($serverIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
$serverIp = "[$serverIp]"; $serverIp = "[$serverIp]";
} }
$fp = @fsockopen($serverIp, $this->server['port'], $errno, $this->error, $timeout); $fp = @fsockopen($serverIp, $this->server['port'], $errno, $this->error, $timeout);

View File

@ -31,31 +31,33 @@
<body> <body>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"> <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="index.php">{{ title }}</a> <div class="container-fluid">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" <a class="navbar-brand" href="index.php">{{ title }}</a>
aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar"
<span class="navbar-toggler-icon"></span> aria-expanded="false" aria-label="Toggle navigation">
</button> <span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar"> <div class="collapse navbar-collapse" id="navbar">
{{ html_menu|raw }} {{ html_menu|raw }}
</div> </div>
</div>
</nav> </nav>
{{ html_modal|raw }} {{ html_modal|raw }}
<main role="main" class="container"> <main role="main" class="container-fluid px-4">
<noscript> <noscript>
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
<b>Javascript is disabled!</b> PHP Server Monitor works best with JavaScript enabled! <b>Javascript is disabled!</b> PHP Server Monitor works best with JavaScript enabled!
</div> </div>
</noscript> </noscript>
{% if not user_level and subtitle %}<h1>{{ subtitle }}</h1>{% endif %} {% if not user_level and subtitle %}<h1>{{ subtitle }}</h1>{% endif %}
<div class="container">{{ header_accessories|raw }}</div> <div class="container-fluid">{{ header_accessories|raw }}</div>
{% for msg in messages %} {% for msg in messages %}
<div class="alert alert-{{ msg.class }}" role="alert"> <div class="alert alert-{{ msg.class }}" role="alert">
<i class="fas fa-{{ msg.icon }}"></i> {{ msg.message|raw }} <i class="fas fa-{{ msg.icon }}"></i> {{ msg.message|raw }}
</div> </div>
{% endfor %} {% endfor %}
<div class="container"> <div class="container-fluid">
<div class="row">{{ html_sidebar|raw }}</div> <div class="row">{{ html_sidebar|raw }}</div>
<div class="row" id="content">{{ html_content|raw }}</div> <div class="row" id="content">{{ html_content|raw }}</div>
</div> </div>

View File

@ -41,6 +41,8 @@
<legend>{{ label_general }}</legend> <legend>{{ label_general }}</legend>
<!-- Update check --> <!-- Update check -->
{{ macro.input_checkbox("show_update", "show_update[]", label_show_update, show_update_checked) }} {{ macro.input_checkbox("show_update", "show_update[]", label_show_update, show_update_checked) }}
<!-- Site title -->
{{ macro.input_field("text", "site_title", null, "site_title", label_site_title, site_title, label_site_title, "255", null, null, null, null, true) }}
<!-- Language --> <!-- Language -->
{{ macro.input_select("language", "language", label_language, languages, language_current) }} {{ macro.input_select("language", "language", label_language, languages, language_current) }}
<!-- Auto refresh --> <!-- Auto refresh -->
@ -48,6 +50,8 @@
<!-- Password encryption key --> <!-- Password encryption key -->
<!-- TODO how does the encryption function works currently? --> <!-- TODO how does the encryption function works currently? -->
{{ macro.input_field("text", "password_encrypt_key", null, "password_encrypt_key", label_password_encrypt_key, password_encrypt_key, "cab03a766...", "40", "password_encrypt_key_help", label_password_encrypt_key_note) }} {{ macro.input_field("text", "password_encrypt_key", null, "password_encrypt_key", label_password_encrypt_key, password_encrypt_key, "cab03a766...", "40", "password_encrypt_key_help", label_password_encrypt_key_note) }}
<!-- Custom user agent -->
{{ macro.input_field("text", "user_agent", null, "user_agent", label_user_agent, user_agent, "Mozilla/5.0...", "255", "user_agent_key_help", label_user_agent_key_note) }}
</fieldset> </fieldset>
<!-- Notification settings --> <!-- Notification settings -->
<fieldset> <fieldset>

View File

@ -20,7 +20,7 @@
<span id="needle" style="transform: rotate({{ ((graph.uptime|round/100)*180)|round }}deg);"></span> <span id="needle" style="transform: rotate({{ ((graph.uptime|round/100)*180)|round }}deg);"></span>
</div><br> </div><br>
{% endif %} {% endif %}
{{ graph.info.0.label }}: {{ graph.info.0.value }}s {{ graph.info.0.label }}: {{ graph.info.0.value * 1000 }} ms
</div> </div>
{% if graph.id == 'history_short' %} {% if graph.id == 'history_short' %}

View File

@ -9,7 +9,7 @@
<th scope="col">{{ label_domain }}</th> <th scope="col">{{ label_domain }}</th>
<th scope="col" style="width: 5%;">{{ label_port }}</th> <th scope="col" style="width: 5%;">{{ label_port }}</th>
<th scope="col" style="width: 8%;">{{ label_type }}</th> <th scope="col" style="width: 8%;">{{ label_type }}</th>
<th scope="col" style="width: 8%;">{{ label_rtime }}</th> <th scope="col" style="width: 8%;">{{ label_rtime }} (ms)</th>
<th scope="col" style="width: 10%;">{{ label_last_online }}</th> <th scope="col" style="width: 10%;">{{ label_last_online }}</th>
<th scope="col" style="width: 10%;">{{ label_last_offline }}</th> <th scope="col" style="width: 10%;">{{ label_last_offline }}</th>
<th scope="col" style="width: 10%;">{{ label_monitoring }}</th> <th scope="col" style="width: 10%;">{{ label_monitoring }}</th>
@ -41,7 +41,7 @@
<td><div class="content">{{ server.ip|raw }}</div></td> <td><div class="content">{{ server.ip|raw }}</div></td>
<td>{{ server.port }}</td> <td>{{ server.port }}</td>
<td>{{ server.type }}</td> <td>{{ server.type }}</td>
<td>{{ server.rtime }}</td> <td>{{ (server.rtime * 1000)|round(2) }}</td>
<td><div class="content">{{ server.last_online }}</div></td> <td><div class="content">{{ server.last_online }}</div></td>
<td><div class="content">{{ server.last_offline }}</div></td> <td><div class="content">{{ server.last_offline }}</div></td>
<td> <td>

View File

@ -1,6 +1,6 @@
{% import 'main/macros.tpl.html' as macro %} {% import 'main/macros.tpl.html' as macro %}
{{ macro.input_csrf() }} {{ macro.input_csrf() }}
<div class="container"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="card text-white text-center col-md-2 pl-0 pr-0 mb-4 {% if status|lower == 'on' %}bg-success{% elseif status|lower == 'warning' %}bg-warning{% elseif status|lower == 'off' %}bg-danger{% endif %}"> <div class="card text-white text-center col-md-2 pl-0 pr-0 mb-4 {% if status|lower == 'on' %}bg-success{% elseif status|lower == 'warning' %}bg-warning{% elseif status|lower == 'off' %}bg-danger{% endif %}">
<div class="card-body d-flex align-items-center justify-content-center"> <div class="card-body d-flex align-items-center justify-content-center">
@ -51,7 +51,7 @@
<li class="list-group-item"> <li class="list-group-item">
<dl class="row"> <dl class="row">
<dt class="col-md-4">{{ label_rtime }}:</dt> <dt class="col-md-4">{{ label_rtime }}:</dt>
<dd class="col-md-8">{{ rtime }} {{ label_seconds }}</dd> <dd class="col-md-8">{{ (rtime * 1000)|round(2) }} {{ label_milliseconds }}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
@ -354,6 +354,35 @@
<div class="row"> <div class="row">
{{ html_history|raw }} {{ html_history|raw }}
</div> </div>
{% if log_entries %}
<div class="row mt-4">
<div class="card col-md-12 pl-0 pr-0">
<div class="card-header">
{{ label_log_title }}
</div>
<div class="card-body d-flex align-items-center justify-content-center">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col" style="width: 15%;">{{ label_date }}</th>
<th scope="col">{{ label_message }}</th>
</tr>
</thead>
<tbody>
{% for entry in log_entries %}
<tr>
<td><time>{{ entry.datetime_format }}</time></td>
<td class="full">{{ entry.message|raw }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endif %}
<div class="modal fade" id="modal_last_output" tabindex="-1" role="dialog" aria-labelledby="modal_last_output_label" aria-hidden="true"> <div class="modal fade" id="modal_last_output" tabindex="-1" role="dialog" aria-labelledby="modal_last_output_label" aria-hidden="true">
<div class="modal-dialog" style="width:75%;max-width: 100%" role="document"> <div class="modal-dialog" style="width:75%;max-width: 100%" role="document">

View File

@ -1,10 +1,10 @@
{% import 'main/macros.tpl.html' as macro %} {% import 'main/macros.tpl.html' as macro %}
{{ macro.input_csrf() }} {{ macro.input_csrf() }}
<div class="container"> <div class="container-fluid">
<div id="flow-layout" class="{{ block_layout_active }}" aria-labelledby="block-layout"> <div id="flow-layout" class="{{ block_layout_active }}" aria-labelledby="block-layout">
<div class="row"> <div class="row">
{% for server in servers_offline %} {% for server in servers_offline %}
<div class="col-sm-4 col-md-3"> <div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-danger mb-3" onclick="window.location.href='{{ server.url_view|raw }}'"> <div class="card text-white bg-danger mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></a></div> <div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></a></div>
<div class="card-body"> <div class="card-body">
@ -17,7 +17,7 @@
</div> </div>
{% endfor %} {% endfor %}
{% for server in servers_warning %} {% for server in servers_warning %}
<div class="col-sm-4 col-md-3"> <div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-warning mb-3" onclick="window.location.href='{{ server.url_view|raw }}'"> <div class="card text-white bg-warning mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></a></div> <div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></a></div>
<div class="card-body"> <div class="card-body">
@ -30,14 +30,14 @@
</div> </div>
{% endfor %} {% endfor %}
{% for server in servers_online %} {% for server in servers_online %}
<div class="col-sm-4 col-md-3"> <div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-success mb-3" onclick="window.location.href='{{ server.url_view|raw }}'"> <div class="card text-white bg-success mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></div> <div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></div>
<div class="card-body"> <div class="card-body">
<p class="card-text"> <p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br> {{ label_last_online }}: {{ server.last_online_nice }}<br>
{{ label_last_offline }}: {{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}<br> {{ label_last_offline }}: {{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}<br>
{{ label_rtime }}: {{ server.rtime }} {{ label_rtime }}: {{ (server.rtime * 1000)|round(2) }} ms
</p> </p>
</div> </div>
</div> </div>
@ -97,7 +97,7 @@
<th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></th> <th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></th>
<td>{{ server.last_online_nice }}</td> <td>{{ server.last_online_nice }}</td>
<td>{{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}</td> <td>{{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}</td>
<td>{{ server.rtime }}s</td> <td>{{ (server.rtime * 1000)|round(2) }} ms</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -1,2 +1,2 @@
html{position:relative;min-height:100%}html[dir='rtl'] #auto_refresh_description,html[dir='rtl'] #log_retention_period_help{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}html[dir='ltr'] #auto_refresh_description,html[dir='ltr'] #log_retention_period_help{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}body{padding-top:4.5rem;margin-bottom:80px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;background-color:#f5f5f5}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.64)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,0.85)}dl,dt,dd{margin-bottom:0}footer .text-muted{color:#4C5557 !important}a,button,.nav-link{min-height:44px !important;min-width:44px !important}a.icon{text-decoration:none;cursor:pointer;padding-left:10px}form.form-signin input[type="text"],form.form-reset input[type="text"]{border-bottom-left-radius:0;border-bottom-right-radius:0}form.form-signin input[type="password"]{border-top-left-radius:0;border-top-right-radius:0}form.form-reset input#input-password{border-radius:0}form.form-reset input#input-password-repeat{border-top-left-radius:0;border-top-right-radius:0}form.form-signin,form.form-forgot,form.form-reset{margin:auto}table{table-layout:fixed}th,td{max-width:1px}.content{word-wrap:break-word;overflow-wrap:break-word}table tr[visible='false'],.no-result{display:none}table tr[visible='true']{display:table-row}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:unset}#meter{border-radius:200px 200px 0 0;height:100px;margin:50px auto 0;overflow:hidden;position:relative;width:200px}#meter:before{background:#fbfbfb;border-radius:200px 200px 0 0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;content:"";height:100px;position:absolute;width:200px}#meter:after{background:#fff;border-radius:140px 140px 0 0;bottom:0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15);box-shadow:3px 1px 8px rgba(0,0,0,0.15);content:"\a" attr(data-value) "%\a" attr(translation);font-size:1.5em;font-weight:100;height:80px;left:20px;line-height:25px;position:absolute;text-align:center;width:160px;z-index:3;white-space:pre}#needle{background:rgba(52,52,64,0.7);border-radius:4px;bottom:-4px;-webkit-box-shadow:3px -1px 4px rgba(0,0,0,0.4);box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;-webkit-transform-origin:100% 4px;transform-origin:100% 4px;-webkit-transition:all 1s;transition:all 1s;border-radius:4px;bottom:-4px;box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;transform-origin:100% 4px;transition:all 1s}.dropdown-menu.show{left:inherit;right:0px} html{position:relative;min-height:100%}html[dir='rtl'] #auto_refresh_description,html[dir='rtl'] #log_retention_period_help{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}html[dir='ltr'] #auto_refresh_description,html[dir='ltr'] #log_retention_period_help{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}body{padding-top:4.5rem;margin-bottom:80px}.container-fluid{max-width:1920px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;background-color:#f5f5f5}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.64)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,0.85)}dl,dt,dd{margin-bottom:0}footer .text-muted{color:#4C5557 !important}a,button,.nav-link{min-height:44px !important;min-width:44px !important}a.icon{text-decoration:none;cursor:pointer;padding-left:10px}form.form-signin input[type="text"],form.form-reset input[type="text"]{border-bottom-left-radius:0;border-bottom-right-radius:0}form.form-signin input[type="password"]{border-top-left-radius:0;border-top-right-radius:0}form.form-reset input#input-password{border-radius:0}form.form-reset input#input-password-repeat{border-top-left-radius:0;border-top-right-radius:0}form.form-signin,form.form-forgot,form.form-reset{margin:auto}table{table-layout:fixed}th,td{max-width:1px}.content{word-wrap:break-word;overflow-wrap:break-word}table tr[visible='false'],.no-result{display:none}table tr[visible='true']{display:table-row}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:unset}#meter{border-radius:200px 200px 0 0;height:100px;margin:50px auto 0;overflow:hidden;position:relative;width:200px}#meter:before{background:#fbfbfb;border-radius:200px 200px 0 0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;content:"";height:100px;position:absolute;width:200px}#meter:after{background:#fff;border-radius:140px 140px 0 0;bottom:0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15);box-shadow:3px 1px 8px rgba(0,0,0,0.15);content:"\a" attr(data-value) "%\a" attr(translation);font-size:1.5em;font-weight:100;height:80px;left:20px;line-height:25px;position:absolute;text-align:center;width:160px;z-index:3;white-space:pre}#needle{background:rgba(52,52,64,0.7);border-radius:4px;bottom:-4px;-webkit-box-shadow:3px -1px 4px rgba(0,0,0,0.4);box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;-webkit-transform-origin:100% 4px;transform-origin:100% 4px;-webkit-transition:all 1s;transition:all 1s;border-radius:4px;bottom:-4px;box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;transform-origin:100% 4px;transition:all 1s}.dropdown-menu.show{left:inherit;right:0px}
/*# sourceMappingURL=style.min.css.map */ /*# sourceMappingURL=style.min.css.map */

View File

@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "AAAA,AAAA,IAAI,AAAC,CACD,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CACnB,AAED,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,sBAAsB,CAAE,MAAM,CAC9B,yBAAyB,CAAE,MAAM,CACpC,AAGL,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,uBAAuB,CAAE,MAAM,CAC/B,0BAA0B,CAAE,MAAM,CACrC,AAGL,AAAA,IAAI,AAAC,CACD,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,IAAI,CACtB,AAED,AAAA,OAAO,AAAC,CACJ,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,IAAI,CACjB,gBAAgB,CAAE,OAAO,CAC5B,AAED,AAAA,YAAY,CAAC,WAAW,CAAC,SAAS,AAAC,CAC/B,KAAK,CAAE,sBAAwB,CAMlC,AAPD,AAGI,YAHQ,CAAC,WAAW,CAAC,SAAS,AAG7B,MAAM,CAHX,YAAY,CAAC,WAAW,CAAC,SAAS,AAI7B,MAAM,AAAC,CACJ,KAAK,CAAE,sBAAwB,CAClC,AAGL,AAAA,EAAE,CACF,EAAE,CACF,EAAE,AAAC,CACC,aAAa,CAAE,CAAC,CACnB,AAED,AAAA,MAAM,CAAC,WAAW,AAAC,CACf,KAAK,CAAE,kBAAkB,CAC5B,AAED,AAAA,CAAC,CACD,MAAM,CACN,SAAS,AAAC,CACN,UAAU,CAAE,eAAe,CAC3B,SAAS,CAAE,eAAe,CAC7B,AAED,AAAA,CAAC,AAAA,KAAK,AAAC,CACH,eAAe,CAAE,IAAI,CACrB,MAAM,CAAE,OAAO,CACf,YAAY,CAAE,IAAI,CACrB,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,EACvB,IAAI,AAAA,WAAW,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAAa,CAC/B,yBAAyB,CAAE,CAAC,CAC5B,0BAA0B,CAAE,CAAC,CAChC,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,UAAU,AAAf,CAAiB,CACpC,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAED,AACI,IADA,AAAA,WAAW,CACX,KAAK,AAAA,eAAe,AAAC,CACjB,aAAa,CAAE,CAAC,CACnB,AAHL,AAKI,IALA,AAAA,WAAW,CAKX,KAAK,AAAA,sBAAsB,AAAC,CACxB,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAGL,AAAA,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,WAAW,AAAC,CACZ,MAAM,CAAE,IAAI,CACf,AAED,AAAA,KAAK,AAAC,CACF,YAAY,CAAE,KAAK,CACtB,AAED,AAAA,EAAE,CAAE,EAAE,AAAC,CACH,SAAS,CAAC,GAAG,CAChB,AACD,AAAA,QAAQ,AAAC,CACL,SAAS,CAAC,UAAU,CACpB,aAAa,CAAC,UAAU,CAC3B,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,OAAO,AAAf,EACT,UAAU,AAAC,CACP,OAAO,CAAE,IAAI,CAChB,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,MAAM,AAAd,CAAgB,CACrB,OAAO,CAAE,SAAS,CACrB,AAED,AAAA,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,CACjD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,OAAO,CACxD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,CACvD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,AAAC,CACpD,KAAK,CAAE,KAAK,CACf,AAED,AAAA,MAAM,AAAC,CACH,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,WAAW,CACnB,QAAQ,CAAE,MAAM,CAChB,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CA4Bf,AAlCD,AAOI,MAPE,AAOD,OAAO,AAAC,CACL,UAAU,CAAE,OAAO,CACnB,aAAa,CAAE,eAAe,CAC9B,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAAC,KAAK,CACjD,OAAO,CAAE,EAAE,CACX,MAAM,CAAE,KAAK,CACb,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CACf,AAfL,AAgBI,MAhBE,AAgBD,MAAM,AAAC,CACJ,UAAU,CAAE,IAAI,CAChB,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,CAAC,CACT,kBAAkB,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CACnD,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAC3C,OAAO,CAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAA,iBAAiB,CACrD,SAAS,CAAE,KAAK,CAChB,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,IAAI,CACZ,IAAI,CAAE,IAAI,CACV,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,MAAM,CAClB,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,CAAC,CACV,WAAW,CAAE,GAAG,CACnB,AAGL,AAAA,OAAO,AAAC,CACJ,UAAU,CAAE,kBAAqB,CACjC,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CACrB,AAED,AAAA,cAAc,AAAA,KAAK,AAAC,CAChB,IAAI,CAAE,OAAO,CACb,KAAK,CAAE,GAAG,CACb", "mappings": "AAAA,AAAA,IAAI,AAAC,CACD,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CACnB,AAED,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,sBAAsB,CAAE,MAAM,CAC9B,yBAAyB,CAAE,MAAM,CACpC,AAGL,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,uBAAuB,CAAE,MAAM,CAC/B,0BAA0B,CAAE,MAAM,CACrC,AAGL,AAAA,IAAI,AAAC,CACD,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,IAAI,CACtB,AAED,AAAA,gBAAgB,AAAC,CACb,SAAS,CAAE,MAAM,CACpB,AAED,AAAA,OAAO,AAAC,CACJ,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,IAAI,CACjB,gBAAgB,CAAE,OAAO,CAC5B,AAED,AAAA,YAAY,CAAC,WAAW,CAAC,SAAS,AAAC,CAC/B,KAAK,CAAE,sBAAwB,CAMlC,AAPD,AAGI,YAHQ,CAAC,WAAW,CAAC,SAAS,AAG7B,MAAM,CAHX,YAAY,CAAC,WAAW,CAAC,SAAS,AAI7B,MAAM,AAAC,CACJ,KAAK,CAAE,sBAAwB,CAClC,AAGL,AAAA,EAAE,CACF,EAAE,CACF,EAAE,AAAC,CACC,aAAa,CAAE,CAAC,CACnB,AAED,AAAA,MAAM,CAAC,WAAW,AAAC,CACf,KAAK,CAAE,kBAAkB,CAC5B,AAED,AAAA,CAAC,CACD,MAAM,CACN,SAAS,AAAC,CACN,UAAU,CAAE,eAAe,CAC3B,SAAS,CAAE,eAAe,CAC7B,AAED,AAAA,CAAC,AAAA,KAAK,AAAC,CACH,eAAe,CAAE,IAAI,CACrB,MAAM,CAAE,OAAO,CACf,YAAY,CAAE,IAAI,CACrB,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,EACvB,IAAI,AAAA,WAAW,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAAa,CAC/B,yBAAyB,CAAE,CAAC,CAC5B,0BAA0B,CAAE,CAAC,CAChC,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,UAAU,AAAf,CAAiB,CACpC,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAED,AACI,IADA,AAAA,WAAW,CACX,KAAK,AAAA,eAAe,AAAC,CACjB,aAAa,CAAE,CAAC,CACnB,AAHL,AAKI,IALA,AAAA,WAAW,CAKX,KAAK,AAAA,sBAAsB,AAAC,CACxB,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAGL,AAAA,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,WAAW,AAAC,CACZ,MAAM,CAAE,IAAI,CACf,AAED,AAAA,KAAK,AAAC,CACF,YAAY,CAAE,KAAK,CACtB,AAED,AAAA,EAAE,CAAE,EAAE,AAAC,CACH,SAAS,CAAC,GAAG,CAChB,AACD,AAAA,QAAQ,AAAC,CACL,SAAS,CAAC,UAAU,CACpB,aAAa,CAAC,UAAU,CAC3B,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,OAAO,AAAf,EACT,UAAU,AAAC,CACP,OAAO,CAAE,IAAI,CAChB,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,MAAM,AAAd,CAAgB,CACrB,OAAO,CAAE,SAAS,CACrB,AAED,AAAA,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,CACjD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,OAAO,CACxD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,CACvD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,AAAC,CACpD,KAAK,CAAE,KAAK,CACf,AAED,AAAA,MAAM,AAAC,CACH,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,WAAW,CACnB,QAAQ,CAAE,MAAM,CAChB,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CA4Bf,AAlCD,AAOI,MAPE,AAOD,OAAO,AAAC,CACL,UAAU,CAAE,OAAO,CACnB,aAAa,CAAE,eAAe,CAC9B,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAAC,KAAK,CACjD,OAAO,CAAE,EAAE,CACX,MAAM,CAAE,KAAK,CACb,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CACf,AAfL,AAgBI,MAhBE,AAgBD,MAAM,AAAC,CACJ,UAAU,CAAE,IAAI,CAChB,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,CAAC,CACT,kBAAkB,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CACnD,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAC3C,OAAO,CAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAA,iBAAiB,CACrD,SAAS,CAAE,KAAK,CAChB,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,IAAI,CACZ,IAAI,CAAE,IAAI,CACV,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,MAAM,CAClB,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,CAAC,CACV,WAAW,CAAE,GAAG,CACnB,AAGL,AAAA,OAAO,AAAC,CACJ,UAAU,CAAE,kBAAqB,CACjC,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CACrB,AAED,AAAA,cAAc,AAAA,KAAK,AAAC,CAChB,IAAI,CAAE,OAAO,CACb,KAAK,CAAE,GAAG,CACb",
"sources": [ "sources": [
"../scss/style.scss" "../scss/style.scss"
], ],

View File

@ -24,6 +24,10 @@ body {
margin-bottom: 80px; margin-bottom: 80px;
} }
.container-fluid {
max-width: 1920px;
}
.footer { .footer {
position: absolute; position: absolute;
bottom: 0; bottom: 0;