Merge remote-tracking branch 'origin/develop' into feature/public_page

# Conflicts:
#	README.rst
#	config.php.sample
#	src/includes/psmconfig.inc.php
#	src/lang/en_US.lang.php
#	src/psm/Module/User/Controller/UserController.php
#	src/psm/Util/Install/Installer.php
This commit is contained in:
TimZ99 2020-08-24 22:27:51 +02:00
commit e599c18f0b
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
97 changed files with 3288 additions and 911 deletions

2
.github/FUNDING.yml vendored
View File

@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] custom: ["https://www.paypal.me/TimZandbergen99", "https://bunq.me/t"]

View File

@ -23,8 +23,9 @@ A clear and concise description of what you expected to happen.
**Screenshots** **Screenshots**
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):** **Version (please complete the following information):**
- Version [e.g. 3.3.5, develop] - Version [e.g. 3.3.5]
- PHP [e.g. 7.3]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View File

@ -2,7 +2,7 @@
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: "[Feature Request]" title: "[Feature Request]"
labels: '' labels: 'Type: Feature'
assignees: '' assignees: ''
--- ---

View File

@ -2,7 +2,7 @@
name: Question name: Question
about: Ask your questions about: Ask your questions
title: "[Question] " title: "[Question] "
labels: '' labels: 'Type: Question'
assignees: '' assignees: ''
--- ---

2
.gitignore vendored
View File

@ -10,3 +10,5 @@
*.bak *.bak
__MACOSX/ __MACOSX/
.DS_Store .DS_Store
.buildpath
.settings/

View File

@ -6,6 +6,23 @@ Not yet released
---------------- ----------------
\- \-
v3.5.2 (released August 12, 2020)
-----------------------------
* Fixed missing version numbers.
* See https://github.com/phpservermon/phpservermon/compare/v3.5.1...v3.5.2
v3.5.1 (released August 12, 2020)
-----------------------------
* Security update regaring jQuery, see #972.
* See https://github.com/phpservermon/phpservermon/compare/v3.5.0...v3.5.1
v3.5.0 (released May 1, 2020)
-----------------------------
* See https://github.com/phpservermon/phpservermon/compare/v3.4.5...v3.5.0
v3.4.5 (released September 30, 2019) v3.4.5 (released September 30, 2019)
------------------------------------ ------------------------------------

0
Makefile Executable file → Normal file
View File

27
README.rst Executable file → Normal file
View File

@ -5,7 +5,7 @@ PHP Server Monitor
:alt: Join the chat at https://gitter.im/erickrf/nlpnet :alt: Join the chat at https://gitter.im/erickrf/nlpnet
:target: https://gitter.im/phpservermon/phpservermon :target: https://gitter.im/phpservermon/phpservermon
Version 3.6.0 Version 3.6.0.beta2
PHP Server Monitor is a script that checks whether your websites and servers are up and running. PHP Server Monitor is a script that checks whether your websites and servers are up and running.
It comes with a web based user interface where you can manage your services and websites, It comes with a web based user interface where you can manage your services and websites,
@ -16,7 +16,7 @@ Features:
--------- ---------
* Monitor services and websites (see below). * Monitor services and websites (see below).
* Email, SMS, Pushover, Telegram notifications. * Email, SMS, Discord, Pushover, Telegram and Jabber notifications.
* View history graphs of uptime and latency. * View history graphs of uptime and latency.
* User authentication with 2 levels (administrator and regular user). * User authentication with 2 levels (administrator and regular user).
* Logs of connection errors, outgoing emails and text messages. * Logs of connection errors, outgoing emails and text messages.
@ -39,7 +39,7 @@ There are two different ways to monitor a server:
In both cases the script will return a "status offline", and will start sending out notifications. In both cases the script will return a "status offline", and will start sending out notifications.
Each server has its own settings regarding notification. Each server has its own settings regarding notification.
You can choose for email, text message (SMS), Pushover.net and Telegram notifications. You can choose for email, text message (SMS), Pushover.net, Telegram and Jabber notifications.
The following SMS gateways are currently available: The following SMS gateways are currently available:
* Clickatell - <https://www.clickatell.com> * Clickatell - <https://www.clickatell.com>
@ -60,6 +60,8 @@ 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>
* OVH SMS PRO - <https://www.ovhtelecom.fr/sms/>
@ -79,10 +81,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
------- -------
@ -105,7 +116,7 @@ If you are familiar with Vagrant (https://www.vagrantup.com)::
Documentation Documentation
------------- -------------
The documentation is available in the docs folder or http://docs.phpservermonitor.org. The documentation is available in the docs folder or https://docs.phpservermonitor.org.
License License
@ -122,7 +133,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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/. along with PHP Server Monitor. If not, see https://www.gnu.org/licenses/.
Docker Docker
------- -------

6
composer.json Executable file → Normal file
View File

@ -6,6 +6,7 @@
"require": { "require": {
"php": "^5.5.9|>=7.0.8", "php": "^5.5.9|>=7.0.8",
"ext-curl": "*", "ext-curl": "*",
"ext-json": "*",
"ext-pdo": "*", "ext-pdo": "*",
"ext-xml": "*", "ext-xml": "*",
"phpmailer/phpmailer": ">=6.0.6 ~6.0", "phpmailer/phpmailer": ">=6.0.6 ~6.0",
@ -16,7 +17,8 @@
"symfony/filesystem": "~3.4", "symfony/filesystem": "~3.4",
"php-pushover/php-pushover": "dev-master", "php-pushover/php-pushover": "dev-master",
"paragonie/random_compat": "^2.0", "paragonie/random_compat": "^2.0",
"twig/twig": "~1.35" "twig/twig": "~1.35",
"jaxl/jaxl": "^3.1"
}, },
"autoload": { "autoload": {
"files": [ "files": [
@ -27,4 +29,4 @@
"psm\\": "src/psm/" "psm\\": "src/psm/"
} }
} }
} }

85
composer.lock generated
View File

@ -4,8 +4,81 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "b2a2bd93aeb6abf9b4e1905aa7ea4217", "content-hash": "f78e950e2dfef7debe88d7b64e2b4aec",
"packages": [ "packages": [
{
"name": "jaxl/jaxl",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/jaxl/JAXL.git",
"reference": "27aa43c4600b05809779428843d8d51db6ce6e0d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jaxl/JAXL/zipball/27aa43c4600b05809779428843d8d51db6ce6e0d",
"reference": "27aa43c4600b05809779428843d8d51db6ce6e0d",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-hash": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-openssl": "*",
"ext-pcre": "*",
"ext-sockets": "*",
"php": ">=5.2.4"
},
"require-dev": {
"phpunit/phpunit": "^3.7.0",
"squizlabs/php_codesniffer": "*"
},
"suggest": {
"ext-pcntl": "Interrupt JAXL with signals"
},
"bin": [
"jaxlctl"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1.x-dev"
}
},
"autoload": {
"classmap": [
"src/JAXL"
],
"exclude-from-classmap": [
"/tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Abhinavsingh",
"homepage": "https://abhinavsingh.com/"
}
],
"description": "Jaxl - Async, Non-Blocking, Event based Networking Library in PHP.",
"homepage": "http://jaxl.readthedocs.org/en/latest/index.html",
"keywords": [
"abhinavsingh",
"asynchronous",
"event loop",
"http",
"jabber",
"jaxl",
"non blocking",
"php",
"xmpp"
],
"time": "2016-09-13T01:59:35+00:00"
},
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v2.0.18", "version": "v2.0.18",
@ -87,16 +160,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.1.3", "version": "v6.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a25ae38e03de4ee4031725498a600012364787c7" "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a25ae38e03de4ee4031725498a600012364787c7", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"reference": "a25ae38e03de4ee4031725498a600012364787c7", "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -145,7 +218,7 @@
} }
], ],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2019-11-21T09:37:46+00:00" "time": "2020-05-27T12:24:03+00:00"
}, },
{ {
"name": "psr/container", "name": "psr/container",

1
config.php.sample Executable file → Normal file
View File

@ -6,4 +6,5 @@ define('PSM_DB_NAME', 'db_name');
define('PSM_DB_HOST', 'localhost'); define('PSM_DB_HOST', 'localhost');
define('PSM_DB_PORT', '3306'); //3306 is the default port for MySQL. If no specfic port is used, leave it empty. define('PSM_DB_PORT', '3306'); //3306 is the default port for MySQL. If no specfic port is used, leave it empty.
define('PSM_BASE_URL', ''); define('PSM_BASE_URL', '');
define('PSM_WEBCRON_KEY', '');
define('PSM_PUBLIC', true); define('PSM_PUBLIC', true);

View File

@ -28,6 +28,9 @@
namespace { namespace {
// include main configuration and functionality // include main configuration and functionality
use psm\Router;
use psm\Util\Server\UpdateManager;
require_once __DIR__ . '/../src/bootstrap.php'; require_once __DIR__ . '/../src/bootstrap.php';
if (!psm_is_cli()) { if (!psm_is_cli()) {
@ -41,7 +44,10 @@ namespace {
$data = @unserialize(PSM_CRON_ALLOW); $data = @unserialize(PSM_CRON_ALLOW);
$allow = $data === false ? PSM_CRON_ALLOW : $data; $allow = $data === false ? PSM_CRON_ALLOW : $data;
if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)) { if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)
&& ! (array_key_exists ("webcron_key", $_GET) &&
$_GET["webcron_key"]==PSM_WEBCRON_KEY && (PSM_WEBCRON_KEY != ""))
) {
header('HTTP/1.0 403 Forbidden'); header('HTTP/1.0 403 Forbidden');
die(' die('
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html> <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html>
@ -81,21 +87,79 @@ namespace {
// however if the cron has been running for X mins, we'll assume it died and run anyway // however if the cron has been running for X mins, we'll assume it died and run anyway
// if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php. // if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php.
// or you can provide the --timeout=x argument // or you can provide the --timeout=x argument
$status = null;
if (PHP_SAPI === 'cli') {
$shortOptions = 's:'; // status
$longOptions = [
'status:'
];
$options = getopt($shortOptions, $longOptions);
$possibleValues = [
'on' => 'on',
'1' => 'on',
'up' => 'on',
'off' => 'off',
'0' => 'off',
'down' => 'off'
];
if (
true === array_key_exists('status', $options) &&
true === array_key_exists(strtolower($options['status']), $possibleValues)
) {
$status = $possibleValues[$options['status']];
} elseif (
true === array_key_exists('s', $options) &&
true === array_key_exists(strtolower($options['s']), $possibleValues)
) {
$status = $possibleValues[$options['s']];
}
}
if ($status === 'off') {
$confPrefix = 'cron_off_';
} else {
$confPrefix = 'cron_';
}
$time = time(); $time = time();
if ( if (
psm_get_conf('cron_running') == 1 psm_get_conf($confPrefix . 'running') == 1
&& $cron_timeout > 0 && $cron_timeout > 0
&& ($time - psm_get_conf('cron_running_time') < $cron_timeout) && ($time - psm_get_conf($confPrefix . 'running_time') < $cron_timeout)
) { ) {
die('Cron is already running. Exiting.'); die('Cron is already running. Exiting.');
} }
if (!defined('PSM_DEBUG') || !PSM_DEBUG) { if (!defined('PSM_DEBUG') || !PSM_DEBUG) {
psm_update_conf('cron_running', 1); psm_update_conf($confPrefix . 'running', 1);
} }
psm_update_conf('cron_running_time', $time); psm_update_conf($confPrefix . 'running_time', $time);
/** @var Router $router */
/** @var UpdateManager $autorun */
$autorun = $router->getService('util.server.updatemanager'); $autorun = $router->getService('util.server.updatemanager');
$autorun->run(true);
psm_update_conf('cron_running', 0); if ($status !== 'off') {
$autorun->run(true, $status);
} else {
set_time_limit(60);
if (false === defined('CRON_DOWN_INTERVAL')) {
define('CRON_DOWN_INTERVAL', 5); // every 5 second call update
}
$start = time();
$i = 0;
while ($i < 59) {
$autorun->run(true, $status);
if ($i < (59 - CRON_DOWN_INTERVAL)) {
time_sleep_until($start + $i + CRON_DOWN_INTERVAL);
}
$i += CRON_DOWN_INTERVAL;
}
}
psm_update_conf($confPrefix . 'running', 0);
} }

View File

@ -51,9 +51,9 @@ copyright = u'2008-2017, Pepijn Over'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '3.4.5' version = '3.6'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = version release = '3.6.0.beta2'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@ -85,6 +85,14 @@ 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
* Daniel Krusky - https://github.com/dkrusky
* Discord webhook support
Translators Translators
+++++++++++ +++++++++++
@ -192,3 +200,4 @@ The following libraries are being used by PHP Server Monitor:
* PHP-Pushover - https://github.com/kryap/php-pushover * PHP-Pushover - https://github.com/kryap/php-pushover
* Symfony - https://symfony.com * Symfony - https://symfony.com
* Random_compat - https://github.com/paragonie/random_compat * Random_compat - https://github.com/paragonie/random_compat
* Hammer.js - https://github.com/hammerjs/hammer.js

View File

@ -61,7 +61,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)
@ -169,3 +169,16 @@ What is the username of my bot?
1. Go to profile on the monitor. 1. Go to profile on the monitor.
2. Press activate. 2. Press activate.
3. A button will appear, this will direct you to your Telegram bot. 3. A button will appear, this will direct you to your Telegram bot.
How do I setup Jabber notifications from Google account?
--------------------------------------------------------
A few steps are required to get Jabber notifications working for Google account.
You need to be an administrator for this part.
1. Go into you Google Account Security settings (https://myaccount.google.com/security).
2. Check that you have two factor auth enabled. If not, activate it.
3. Add new app password - copy it.
4. Login to PhpServerMonitor dashboard > config > Jabber and use password from step 3 with your Google account in PhpServerMonitor jabber settings.
5. As host use `talk.google.com`.
6. As username use your whole Google account (for example `example@google.com`).
7. As port use `5223` (really, not typo error ...).

View File

@ -50,6 +50,8 @@ For a regular upgrade, follow these steps:
* Follow the steps * Follow the steps
* Enjoy * Enjoy
Alternatively you can use updater.sh script.
From 2.0 From 2.0
-------- --------
@ -92,6 +94,16 @@ Please note that some distros have user-specific crontabs (e.g. Debian). If that
*/15 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php */15 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php
If you want to check in different intervals online and offline servers you can use attribute `-s` (or `--status`) with value `on` or `off`.
So for example you want to check your servers which are online every 10 minutes and offline every 5 seconds. So configure two cron jobs::
*/10 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s on
*/1 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s off
By default `off` servers are checked every 5 seconds. If you want to change it add into your config file this constant with required value in seconds::
define('CRON_DOWN_INTERVAL', 1); // every 1 second call update
The update script has been designed to prevent itself from running multiple times. It has a maximum timeout of 10 minutes. The update script has been designed to prevent itself from running multiple times. It has a maximum timeout of 10 minutes.
After that the script is assumed dead and the cronjob will run again. After that the script is assumed dead and the cronjob will run again.
If you want to change the 10 minutes timeout, find the constant "PSM_CRON_TIMEOUT" in src/includes/psmconfig.inc.php. If you want to change the 10 minutes timeout, find the constant "PSM_CRON_TIMEOUT" in src/includes/psmconfig.inc.php.
@ -136,6 +148,13 @@ In config.php add following line::
After that, you can hit the url http(s)://"yourmonitor.com"/cron/status.cron.php over the web from your allowed IP. After that, you can hit the url http(s)://"yourmonitor.com"/cron/status.cron.php over the web from your allowed IP.
Alternatively, define a secret key to allow the update over the web:
In config.php add following line::
define('PSM_WEBCRON_KEY', 'YOURKEY');
After that, you can hit the url http(s)://"yourmonitor.com"/cron/status.cron.php?webcron_key=YOURKEY .
Troubleshooting Troubleshooting
+++++++++++++++ +++++++++++++++
@ -144,3 +163,4 @@ If you have problems setting up or accessing your monitor and do not know why, e
To enable debug mode, add the following line to your config.php file:: To enable debug mode, add the following line to your config.php file::
define('PSM_DEBUG', true); define('PSM_DEBUG', true);

View File

@ -15,7 +15,7 @@ Features
++++++++ ++++++++
* Monitor services and websites (see below). * Monitor services and websites (see below).
* Email, SMS, Pushover and Telegram notifications. * Email, SMS, Pushover, Telegram and Jabber notifications.
* View history graphs of uptime and latency. * View history graphs of uptime and latency.
* User authentication with 2 levels (administrator and regular user). * User authentication with 2 levels (administrator and regular user).
* Logs of connection errors, outgoing emails and text messages. * Logs of connection errors, outgoing emails and text messages.
@ -44,7 +44,7 @@ There are two different ways to monitor a server:
Notifications Notifications
------------- -------------
Each server has its own settings regarding notification. Each server has its own settings regarding notification.
You can choose for email, text message (SMS), Pushover.net and Telegram notifications. You can choose for email, text message (SMS), Pushover.net, Telegram and Jabber notifications.
The following SMS gateways are currently available: The following SMS gateways are currently available:
* Clickatell - <https://www.clickatell.com> * Clickatell - <https://www.clickatell.com>

2
logs/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

0
manifest.json Executable file → Normal file
View File

0
phpservermon.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

2
service-worker.js Executable file → Normal file
View File

@ -1,7 +1,7 @@
var dataCacheName = 'PSM-v1'; var dataCacheName = 'PSM-v1';
var cacheName = 'PSM-PWA-final-1'; var cacheName = 'PSM-PWA-final-1';
var filesToCache = [ var filesToCache = [
'/', '',
'index.php', 'index.php',
'src/templates/default/static/js/history.js', 'src/templates/default/static/js/history.js',
'src/templates/default/static/js/scripts.js', 'src/templates/default/static/js/scripts.js',

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
/** /**
* Current PSM version * Current PSM version
*/ */
define('PSM_VERSION', '3.6.0'); define('PSM_VERSION', '3.6.0.beta2');
/** /**
* URL to check for updates. Will not be checked if turned off on config page. * URL to check for updates. Will not be checked if turned off on config page.
@ -130,3 +130,15 @@ if (!defined('PSM_MODULE_DEFAULT')) {
*/ */
define('PSM_MODULE_DEFAULT', 'server_status'); define('PSM_MODULE_DEFAULT', 'server_status');
} }
if (defined('PSM_JABBER_FORCE_TLS') === false) {
define('PSM_JABBER_FORCE_TLS', true);
}
if (defined('PSM_JABBER_AUTH_TYPE') === false) {
// possible values: PLAIN, X-OAUTH2, DIGEST-MD5, CRAM-MD5, SCRAM-SHA-1, ANONYMOUS, EXTERNAL
define('PSM_JABBER_AUTH_TYPE', 'PLAIN'); // default just plain because of google for example :(
}
if (defined('PSM_JABBER_DEBUG_LEVEL') === false) {
// possible values: ERROR, WARNING, NOTICE, INFO, DEBUG
define('PSM_JABBER_DEBUG_LEVEL', JAXLLogger::WARNING);
}

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' => 'Настройки',
@ -99,8 +100,8 @@ $sm_lang = array(
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover е услуга, която улеснява получаването на 'pushover_description' => 'Pushover е услуга, която улеснява получаването на
известия в реално време. Посетете <a известия в реално време. Посетете <a
href="https://pushover.net/">техния сайт</a> за повече href="https://pushover.net/" target="_blank">техния сайт</a> за
информация.', повече информация.',
'pushover_key' => 'Pushover Ключ', 'pushover_key' => 'Pushover Ключ',
'pushover_device' => 'Pushover Устройство', 'pushover_device' => 'Pushover Устройство',
'pushover_device_description' => 'Име на устройство, което да получава 'pushover_device_description' => 'Име на устройство, което да получава
@ -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' => 'Оставете празно за "без аутентикация"',
@ -232,8 +231,8 @@ $sm_lang = array(
'pushover_status' => 'Позволява изпращането на Pushover съобщения', 'pushover_status' => 'Позволява изпращането на Pushover съобщения',
'pushover_description' => 'Pushover е услуга, която улеснява получаването на 'pushover_description' => 'Pushover е услуга, която улеснява получаването на
известия в реално време. Посетете <a известия в реално време. Посетете <a
href="https://pushover.net/">техния сайт</a> за повече href="https://pushover.net/" target="_blank">техния сайт</a> за
информация.', повече информация.',
'pushover_clone_app' => 'Кликнете тук за да създаване на вашият Pushover App', 'pushover_clone_app' => 'Кликнете тук за да създаване на вашият Pushover App',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Преди да използвате Pushover, трябва да <a 'pushover_api_token_description' => 'Преди да използвате Pushover, трябва да <a
@ -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

@ -109,16 +109,17 @@ $sm_lang = array(
'email' => 'Correu', 'email' => 'Correu',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover és un servei que fa fàcil obtenir notificacions en temps real. Veieu <a 'pushover_description' => 'Pushover és un servei que fa fàcil obtenir notificacions en temps real. Veieu <a
href="https://pushover.net/">la seva web</a> per a més informació.', href="https://pushover.net/" target="_blank">la seva web</a> per a més
informació.',
'pushover_key' => 'Clau Pushover', 'pushover_key' => 'Clau Pushover',
'pushover_device' => 'Dispositiu Pushover', 'pushover_device' => 'Dispositiu Pushover',
'pushover_device_description' => 'Nom del dispositiu al qual enviar els missatges. Deixau en blanc per enviar 'pushover_device_description' => 'Nom del dispositiu al qual enviar els missatges. Deixau en blanc per enviar
a tots els dispositius.', a tots els dispositius.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> és una app de missatgeria que 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> és una app de
facilita el rebre notificacions en temps real. Consulteu la <a missatgeria que facilita el rebre notificacions en temps real. Consulteu la <a
href="http://docs.phpservermonitor.org/">documentació</a> per a més informació i href="http://docs.phpservermonitor.org/" target="_blank">documentació</a> per a
per saber com instal·lar-ho.', més informació i per saber com instal·lar-ho.',
'telegram_chat_id' => 'Codi ID del xat a Telegram', 'telegram_chat_id' => 'Codi ID del xat a Telegram',
'telegram_chat_id_description' => 'Els missatges seran enviats al xat de Telegram amb aquest ID.', 'telegram_chat_id_description' => 'Els missatges seran enviats al xat de Telegram amb aquest ID.',
'telegram_get_chat_id' => 'Premeu aquí per a obtenir el codi ID del vostre xat', 'telegram_get_chat_id' => 'Premeu aquí per a obtenir el codi ID del vostre xat',
@ -298,15 +299,14 @@ $sm_lang = array(
target="_blank">registrar una app</a> al seu portal web i introduïr target="_blank">registrar una app</a> al seu portal web i introduïr
aquí el Token de la API.', aquí el Token de la API.',
'telegram_status' => 'Permetre l\'enviament de missatges per Telegram', 'telegram_status' => 'Permetre l\'enviament de missatges per Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> és una app de xat (mòbil i PC) que 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> és una app de xat
facilita la recepció de notificacions en temps real. Veieu la <a (mòbil i PC) que facilita la recepció de notificacions en temps real. Veieu la <a
href="http://docs.phpservermonitor.org/">documentació</a> per saber més i saber href="http://docs.phpservermonitor.org/" target="_blank">documentació</a> per
com activar-ho.', saber més i saber com activar-ho.',
'telegram_api_token' => 'Token de l\'API de Telegram', 'telegram_api_token' => 'Token de l\'API de Telegram',
'telegram_api_token_description' => 'Abans de poder emprar Telegram necessiteu obtenir un token de l\'API. 'telegram_api_token_description' => 'Abans de poder emprar Telegram necessiteu obtenir un token de l\'API.
Consulteu la <a Consulteu la <a href="http://docs.phpservermonitor.org/"
href="http://docs.phpservermonitor.org/">documentació</a> per saber target="_blank">documentació</a> per saber més.',
més.',
'alert_type' => 'Seleccioneu quan voleu ser notificats.', 'alert_type' => 'Seleccioneu quan voleu ser notificats.',
'alert_type_description' => '<b>Canvi d\'estat:</b> Rebreu una notificació quan un servidor tingui un canvi 'alert_type_description' => '<b>Canvi d\'estat:</b> Rebreu una notificació quan un servidor tingui un canvi
d\'estat. És a dir, passi d\'estar en línia a fora de línia o viceversa.<br d\'estat. És a dir, passi d\'estar en línia a fora de línia o viceversa.<br
@ -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',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'E-mail', 'email' => 'E-mail',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění. 'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění.
Více na <a href="https://pushover.net/">webu Pushover</a>', Více na <a href="https://pushover.net/" target="_blank">webu Pushover</a>',
'pushover_key' => 'Pushover Token', 'pushover_key' => 'Pushover Token',
'pushover_device' => 'Pushover Zařízení', 'pushover_device' => 'Pushover Zařízení',
'pushover_device_description' => 'Název zařízení, na které být zráva odeslána. Ponechte prázdné 'pushover_device_description' => 'Název zařízení, na které být zráva odeslána. Ponechte prázdné
@ -227,7 +228,7 @@ $sm_lang = array(
'sms_from' => 'Telefonní číslo odesilatele', 'sms_from' => 'Telefonní číslo odesilatele',
'pushover_status' => 'Povolit zasílání Pushover zpráv', 'pushover_status' => 'Povolit zasílání Pushover zpráv',
'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění. 'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění.
Více na <a href="https://pushover.net/">webu Pushover</a>', Více na <a href="https://pushover.net/" target="_blank">webu Pushover</a>',
'pushover_clone_app' => 'Klikněte pro vytvoření Pushover aplikace', 'pushover_clone_app' => 'Klikněte pro vytvoření Pushover aplikace',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Pře použitím Pushoveru se musíte <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Pře použitím Pushoveru se musíte <a href="%1$s" target="_blank"
@ -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',
@ -92,7 +93,8 @@ $sm_lang = array(
'email' => 'E-mail', 'email' => 'E-mail',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se <a 'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se <a
href="https://pushover.net/">deres website</a> for mere information.', href="https://pushover.net/" target="_blank">deres website</a> for mere
information.',
'pushover_key' => 'Pushover nøgle', 'pushover_key' => 'Pushover nøgle',
'pushover_device' => 'Pushover enhed', 'pushover_device' => 'Pushover enhed',
'pushover_device_description' => 'Navnet enheden som beskeden skal sendes til. Lad denne være tom hvis 'pushover_device_description' => 'Navnet enheden som beskeden skal sendes til. Lad denne være tom hvis
@ -208,7 +210,8 @@ $sm_lang = array(
'sms_from' => 'Afsenderens navn.', 'sms_from' => 'Afsenderens navn.',
'pushover_status' => 'Tillad at sende Pushover beskeder', 'pushover_status' => 'Tillad at sende Pushover beskeder',
'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se <a 'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se <a
href="https://pushover.net/">deres website</a> for yderligere information.', href="https://pushover.net/" target="_blank">deres website</a> for yderligere
information.',
'pushover_clone_app' => 'Klik her for at oprette din Pushover app', 'pushover_clone_app' => 'Klik her for at oprette din Pushover app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du <a href="%1$s" target="_blank"
@ -243,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',
@ -93,8 +94,8 @@ $sm_lang = array(
'email' => 'E-Mail', 'email' => 'E-Mail',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in 'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/">pushover.net</a> Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/"
für weitere Informationen.', target="_blank">pushover.net</a> für weitere Informationen.',
'pushover_key' => 'Pushover Key/Schlüssel', 'pushover_key' => 'Pushover Key/Schlüssel',
'pushover_device' => 'Pushover Gerät', 'pushover_device' => 'Pushover Gerät',
'pushover_device_description' => 'Name des Gerätes, an das die Nachricht gesendet werden soll. Leer lassen, 'pushover_device_description' => 'Name des Gerätes, an das die Nachricht gesendet werden soll. Leer lassen,
@ -213,8 +214,8 @@ $sm_lang = array(
'sms_from' => 'SMS-Sendernummer', 'sms_from' => 'SMS-Sendernummer',
'pushover_status' => 'Ermögliche das Senden von Pushover-Nachrichten', 'pushover_status' => 'Ermögliche das Senden von Pushover-Nachrichten',
'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in 'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/">pushover.net</a> Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/"
für weitere Informationen.', target="_blank">pushover.net</a> für weitere Informationen.',
'pushover_clone_app' => 'Klicken Sie hier, um Ihre Pushover-Anwendung zu erstellen', 'pushover_clone_app' => 'Klicken Sie hier, um Ihre Pushover-Anwendung zu erstellen',
'pushover_api_token' => 'Pushover-Anwendungs-API-Token', 'pushover_api_token' => 'Pushover-Anwendungs-API-Token',
'pushover_api_token_description' => 'Bevor Sie Pushover verwenden können, müssen Sie Ihre <a href="%1$s" 'pushover_api_token_description' => 'Bevor Sie Pushover verwenden können, müssen Sie Ihre <a href="%1$s"
@ -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

@ -50,9 +50,7 @@ $sm_lang = array(
'no' => 'No', 'no' => 'No',
'insert' => 'Insert', 'insert' => 'Insert',
'add_new' => 'Add new', 'add_new' => 'Add new',
'update_available' => 'A new version ({version}) is available. Click <a 'update_available' => 'A new version ({version}) is available. Click <a href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank" rel="noopener">here</a> to download the update.',
href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank"
rel="noopener">here</a> to download the update.',
'back_to_top' => 'Back to top', 'back_to_top' => 'Back to top',
'go_back' => 'Go back', 'go_back' => 'Go back',
'ok' => 'OK', 'ok' => 'OK',
@ -83,6 +81,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',
@ -113,27 +113,33 @@ $sm_lang = array(
'mobile' => 'Mobile', 'mobile' => 'Mobile',
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a 'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/" target="_blank">their website</a> for more info.',
href="https://pushover.net/">their website</a> for more info.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Device name to send the message to. Leave empty to send it to all devices.', 'pushover_device_description' => 'Device name to send the message to. Leave empty to send it to all devices.',
'discord' => 'Discord',
'discord_label' => 'Discord',
'discord_description' => 'Put your <a href="https://discordjs.guide/popular-topics/webhooks.html" target="_blank">webhook</a> here.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more info and an install guide.',
get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an
install guide.',
'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'The message will be send to the corresponding chat.', 'telegram_chat_id_description' => 'The message will be send to the corresponding chat.',
'telegram_get_chat_id' => 'Click here to get your chat id', 'telegram_get_chat_id' => 'Click here to get your chat id',
'activate_telegram' => 'Activate Telegram notifications', 'activate_telegram' => 'Activate Telegram notifications',
'activate_telegram_description' => 'Allow Telegram notifications to be sent to the specified chat id. Without 'activate_telegram_description' => 'Allow Telegram notifications to be sent to the specified chat id. Without this permission, Telegram doesn\'t allow us to send notifications to you.',
this permission, Telegram doesn\'t allow us to send notifications to you.', 'telegram_bot_username_found' => 'The bot was found!<br><a href="%s" target="_blank" rel="noopener"><button class="btn btn-primary">Next step</button></a> <br>This will open a chat with the bot. Here you need to press start or type /start.',
'telegram_bot_username_found' => 'The bot was found!<br><a href="%s" target="_blank" rel="noopener"><button
class="btn btn-primary">Next step</button></a> <br>This will open a chat
with the bot. Here you need to press start of type /start.',
'telegram_bot_username_error_token' => '401 - Unauthorized. Please make sure that the API token is valid.', 'telegram_bot_username_error_token' => '401 - Unauthorized. Please make sure that the API token is valid.',
'telegram_bot_error' => 'An error has occurred while activating Telegram notification: %s', 'telegram_bot_error' => 'An error has occurred while activating Telegram notification: %s',
'jabber' => 'Jabber',
'jabber_label' => 'Jabber',
'jabber_description' => 'You Jabber account',
'webhook' => 'Webhook',
'webhook_description' => 'Send a json webhook to a certain endpoint. <br/> The json can be customized, e.g. {
"text":"servermon: #message"}',
'webhook_url' => 'Webhook Url',
'webhook_url_description' => 'Webhook public endpoint url, should start with https://.',
'webhook_json' => 'Webhook JSON',
'webhook_json_description' => 'Define a custom json, use #message as message variable.',
'delete_title' => 'Delete User', 'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?', 'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.', 'deleted' => 'User deleted.',
@ -142,8 +148,7 @@ $sm_lang = array(
'profile' => 'Profile', 'profile' => 'Profile',
'profile_updated' => 'Your profile has been updated.', 'profile_updated' => 'Your profile has been updated.',
'error_user_name_bad_length' => 'Usernames must be between 2 and 64 characters.', 'error_user_name_bad_length' => 'Usernames must be between 2 and 64 characters.',
'error_user_name_invalid' => 'The username may only contain alphabetic characters (a-z, A-Z), digits (0-9), 'error_user_name_invalid' => 'The username may only contain alphabetic characters (a-z, A-Z), digits (0-9), dots (.) and underscores (_).',
dots (.) and underscores (_).',
'error_user_name_exists' => 'The given username already exists in the database.', 'error_user_name_exists' => 'The given username already exists in the database.',
'error_user_email_bad_length' => 'Email addresses must be between 5 and 255 characters.', 'error_user_email_bad_length' => 'Email addresses must be between 5 and 255 characters.',
'error_user_email_invalid' => 'The email address is invalid.', 'error_user_email_invalid' => 'The email address is invalid.',
@ -160,8 +165,11 @@ $sm_lang = array(
'status' => 'Status', 'status' => 'Status',
'email' => 'Email', 'email' => 'Email',
'sms' => 'SMS', 'sms' => 'SMS',
'discord' => 'Discord',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'webhook' => 'Webhook',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'jabber' => 'Jabber',
'no_logs' => 'No logs', 'no_logs' => 'No logs',
'clear' => 'Clear log', 'clear' => 'Clear log',
'delete_title' => 'Delete log', 'delete_title' => 'Delete log',
@ -197,17 +205,13 @@ $sm_lang = array(
'type_service' => 'Service', 'type_service' => 'Service',
'type_ping' => 'Ping', 'type_ping' => 'Ping',
'pattern' => 'Search string/pattern', 'pattern' => 'Search string/pattern',
'pattern_description' => 'If this pattern is not found on the website, the server will be marked 'pattern_description' => 'If this pattern is not found on the website, the server will be marked online/offline. Regular expressions are allowed.',
online/offline. Regular expressions are allowed.',
'pattern_online' => 'Pattern indicates website is', 'pattern_online' => 'Pattern indicates website is',
'pattern_online_description' => 'Online: If this pattern was found on the website, the server will be marked 'pattern_online_description' => 'Online: If this pattern was found on the website, the server will be marked online. Offline: If this pattern was not found on the website, the server will be marked offline.',
online. Offline: If this pattern was not found on the website, the server
will be marked offline.',
'redirect_check' => 'Redirecting to another domain is', 'redirect_check' => 'Redirecting to another domain is',
'redirect_check_description' => 'Redirect to another domain is usually a bad sign.', 'redirect_check_description' => 'Redirect to another domain is usually a bad sign.',
'allow_http_status' => 'Allow HTTP status code', 'allow_http_status' => 'Allow HTTP status code',
'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as 'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as online by default. Seperate with |.',
online by default. Seperate with |.',
'header_name' => 'Header name', 'header_name' => 'Header name',
'header_value' => 'Header value', 'header_value' => 'Header value',
'header_name_description' => 'Case-sensitive.', 'header_name_description' => 'Case-sensitive.',
@ -225,10 +229,16 @@ $sm_lang = array(
'send_email' => 'Send Email', 'send_email' => 'Send Email',
'sms' => 'SMS', 'sms' => 'SMS',
'send_sms' => 'Send SMS', 'send_sms' => 'Send SMS',
'discord' => 'Discord',
'send_discord' => 'Send Discord notification',
'webhook' => 'Webhook',
'send_webhook' => 'Send Webhook notification',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'send_pushover' => 'Send Pushover notification', 'send_pushover' => 'Send Pushover notification',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'send_telegram' => 'Send Telegram notification', 'send_telegram' => 'Send Telegram notification',
'jabber' => 'Jabber',
'send_jabber' => 'Send Jabber notification',
'users' => 'Users', 'users' => 'Users',
'delete_title' => 'Delete server', 'delete_title' => 'Delete server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?', 'delete_message' => 'Are you sure you want to delete server \'%1\'?',
@ -249,6 +259,10 @@ $sm_lang = array(
'hour' => 'Hour', 'hour' => 'Hour',
'warning_threshold' => 'Warning threshold', 'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'ssl_cert_expiry_days' => 'SSL Certificate Validity',
'ssl_cert_expiry_days_description' => 'The minimum remaining days the SSL certificate is still valid. Use 0 to disable check.',
'ssl_cert_expired' => 'SSL certificate expired since',
'ssl_cert_expiring' => 'SSL certificate expiring:',
'chart_last_week' => 'Last week', 'chart_last_week' => 'Last week',
'chart_history' => 'History', 'chart_history' => 'History',
'chart_day_format' => '%Y-%m-%d', 'chart_day_format' => '%Y-%m-%d',
@ -257,8 +271,11 @@ $sm_lang = array(
'chart_short_time_format' => '%H:%M', 'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'SMS notifications are disabled.', 'warning_notifications_disabled_sms' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.', 'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_discord' => 'Discord notifications are disabled.',
'warning_notifications_disabled_webhook' => 'Webhook notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover notifications are disabled.', 'warning_notifications_disabled_pushover' => 'Pushover notifications are disabled.',
'warning_notifications_disabled_telegram' => 'Telegram notifications are disabled.', 'warning_notifications_disabled_telegram' => 'Telegram notifications are disabled.',
'warning_notifications_disabled_jabber' => 'Jabber notifications are disabled.',
'error_server_no_match' => 'Server not found.', 'error_server_no_match' => 'Server not found.',
'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.',
'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.',
@ -266,14 +283,15 @@ $sm_lang = array(
'error_server_ip_bad_website' => 'The website URL is not valid.', 'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.', 'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
'error_server_ssl_cert_expiry_days' => 'The remaining days for SSL certificate validity must be a valid integer greater than or equal to 0.',
), ),
'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',
'password_encrypt_key_note' => 'This key is used to encrypt passwords that are stored on servers for access to 'password_encrypt_key_note' => 'This key is used to encrypt passwords that are stored on servers for access to websites. If the key will change the stored password is invalid!',
websites. If the key will change the stored password is invalid!',
'proxy' => 'Enable proxy', 'proxy' => 'Enable proxy',
'proxy_url' => 'Proxy URL', 'proxy_url' => 'Proxy URL',
'proxy_user' => 'Proxy username', 'proxy_user' => 'Proxy username',
@ -294,67 +312,84 @@ $sm_lang = array(
'sms_gateway_username' => 'Gateway username', 'sms_gateway_username' => 'Gateway username',
'sms_gateway_password' => 'Gateway password', 'sms_gateway_password' => 'Gateway password',
'sms_from' => 'Sender\'s phone number', 'sms_from' => 'Sender\'s phone number',
'discord_status' => 'Allow sending Discord messages',
'discord_description' => 'Discord is a service that makes it easy to get real-time notifications. See <a href="https://discord.com/" target="_blank">their website</a> for more info.',
'webhook_status' => 'Allow sending webhooks',
'webhook_description' => 'Allow sending webhooks to services like slack. The message payload end endpoint are defined in the profile settings.',
'webhook_url' => 'Webhook Url',
'webhook_url_description' => 'Url to webhook endpoint',
'webhook_json' => 'Webhook Json',
'webhook_json_description' => 'Customized Json, use #message as message variable.',
'pushover_status' => 'Allow sending Pushover messages', 'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a 'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/" target="_blank">their website</a> for more info.',
href="https://pushover.net/">their website</a> for more info.',
'pushover_clone_app' => 'Click here to create your Pushover app', 'pushover_clone_app' => 'Click here to create your Pushover app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank" rel="noopener">register an App</a> at their website and enter the App API Token here.',
rel="noopener">register an App</a> at their website and enter the App API
Token here.',
'telegram_status' => 'Allow sending Telegram messages', 'telegram_status' => 'Allow sending Telegram messages',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more info and an install guide.',
get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an
install guide.',
'telegram_api_token' => 'Telegram API Token', 'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the <a 'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for help.',
href="http://docs.phpservermonitor.org/">documentation</a> for help.', 'jabber_status' => 'Allow sending Jabber (XMPP) messages',
'jabber_description' => 'Visit the <a href="http://docs.phpservermonitor.org/">documentation</a> for more info and an install guide.',
'jabber_host' => 'Host',
'jabber_host_description' => 'Host of your Jabber account provider. For Google Account use talk.google.com.',
'jabber_port' => 'Port',
'jabber_port_description' => 'Port of your Jabber provider. Default 5222. For Google Account use 5223.',
'jabber_username' => 'Username',
'jabber_username_description' => 'For Google Account use incl. domain so for example example@google.com.',
'jabber_domain' => 'Domain',
'jabber_domain_description' => 'Domain of your Jabber provider. Left empty for Google Account.',
'jabber_password' => 'Password',
'jabber_password_description' => 'Fill only to set or change.',
'jabber_check' => 'Check your Jabber account if message was received.',
'alert_type' => 'Select when you\'d like to be notified.', 'alert_type' => 'Select when you\'d like to be notified.',
'alert_type_description' => '<b>Status change:</b> You will receive a notification when a server has a change 'alert_type_description' => '<b>Status change:</b> You will receive a notification when a server has a change in status. So from online -> offline or offline -> online.<br><br><b>Offline:</b> You will receive a notification when a server goes offline for the *FIRST TIME ONLY*. For example, your cronjob is every 15 minutes and your server goes down at 1 am and stays down till 6 am. You will get 1 notification at 1 am and that\'s it.<br><br><b>Always:</b> You will receive a notification every time the script runs and a site is down, even if the site has been offline for hours.',
in status. So from online -> offline or offline -> online.<br><br><b>Offline:</b>
You will receive a notification when a server goes offline for the *FIRST TIME
ONLY*. For example, your cronjob is every 15 minutes and your server goes down at
1 am and stays down till 6 am. You will get 1 notification at 1 am and that\'s
it.<br><br><b>Always:</b> You will receive a notification every time the script
runs and a site is down, even if the site has been offline for hours.',
'alert_type_status' => 'Status change', 'alert_type_status' => 'Status change',
'alert_type_offline' => 'Offline', 'alert_type_offline' => 'Offline',
'alert_type_always' => 'Always', 'alert_type_always' => 'Always',
'combine_notifications' => 'Combine notifications', 'combine_notifications' => 'Combine notifications',
'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into 'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into 1 single notification. (This does not affect SMS notifications.)',
1 single notification. (This does not affect SMS notifications.)',
'alert_proxy' => 'Even if enabled, proxy is never used for services', 'alert_proxy' => 'Even if enabled, proxy is never used for services',
'alert_proxy_url' => 'Format: host:port', 'alert_proxy_url' => 'Format: host:port',
'log_status' => 'Log status', 'log_status' => 'Log status',
'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the 'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the notification settings are passed.',
notification settings are passed.',
'log_email' => 'Log emails sent by the script', 'log_email' => 'Log emails sent by the script',
'log_sms' => 'Log text messages sent by the script', 'log_sms' => 'Log text messages sent by the script',
'log_discord' => 'Log Discord messages sent by the script',
'log_pushover' => 'Log pushover messages sent by the script', 'log_pushover' => 'Log pushover messages sent by the script',
'log_webhook' => 'Log webhook messages sent by the script',
'log_telegram' => 'Log Telegram messages sent by the script', 'log_telegram' => 'Log Telegram messages sent by the script',
'log_jabber' => 'Log Jabber messages sent by the script',
'updated' => 'The configuration has been updated.', 'updated' => 'The configuration has been updated.',
'tab_email' => 'Email', 'tab_email' => 'Email',
'tab_sms' => 'SMS', 'tab_sms' => 'SMS',
'tab_discord' => 'Discord',
'tab_pushover' => 'Pushover', 'tab_pushover' => 'Pushover',
'tab_webhook' => 'Webhook',
'tab_telegram' => 'Telegram', 'tab_telegram' => 'Telegram',
'tab_jabber' => 'Jabber',
'settings_email' => 'Email settings', 'settings_email' => 'Email settings',
'settings_sms' => 'Text message settings', 'settings_sms' => 'Text message settings',
'settings_discord' => 'Discord settings',
'settings_pushover' => 'Pushover settings', 'settings_pushover' => 'Pushover settings',
'settings_webhook' => 'Webhook settings',
'settings_telegram' => 'Telegram settings', 'settings_telegram' => 'Telegram settings',
'settings_jabber' => 'Jabber settings',
'settings_notification' => 'Notification settings', 'settings_notification' => 'Notification settings',
'settings_log' => 'Log settings', 'settings_log' => 'Log settings',
'settings_proxy' => 'Proxy settings', 'settings_proxy' => 'Proxy settings',
'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.',
'test_discord' => 'A Discord notification will be sent to the webhook specified in your user profile.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user 'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user
profile.', profile.',
'test_webhook' => 'A webhook notification will be sent to the given url endpoint.',
'test_telegram' => 'A Telegram notification will be sent to the chat id specified in your user profile.', 'test_telegram' => 'A Telegram notification will be sent to the chat id specified in your user profile.',
'test_jabber' => 'A Jabber notification will be sent to the jabber account specified in your user profile.',
'send' => 'Send', 'send' => 'Send',
'test_subject' => 'Test', 'test_subject' => 'Test',
'test_message' => 'Test message', 'test_message' => 'Test message',
@ -363,35 +398,55 @@ $sm_lang = array(
'sms_sent' => 'SMS sent', 'sms_sent' => 'SMS sent',
'sms_error' => 'An error has occurred while sending the SMS: %s', 'sms_error' => 'An error has occurred while sending the SMS: %s',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your profile.', 'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your profile.',
'discord_sent' => 'Discord notification sent',
'discord_error' => 'An error has occurred while sending the Discord notification: %s',
'discord_error_nowebhook' => 'Unable to send test Discord notification: no valid Discord webhook found in your user profile.',
'webhook_sent' => 'Webhook notification sent',
'webhook_error' => 'An error has occurred while sending the webhook notification: %s',
'webhook_error_nourl' => 'Unable to send test notification: no url found in user profile.',
'webhook_error_nojson' => 'Unable to send test notification: no json found in user profile.',
'pushover_sent' => 'Pushover notification sent', 'pushover_sent' => 'Pushover notification sent',
'pushover_error' => 'An error has occurred while sending the Pushover notification: %s', 'pushover_error' => 'An error has occurred while sending the Pushover notification: %s',
'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global 'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global configuration.',
configuration.',
'pushover_error_nokey' => 'Unable to send test notification: no Pushover key found in your profile.', 'pushover_error_nokey' => 'Unable to send test notification: no Pushover key found in your profile.',
'telegram_sent' => 'Telegram notification sent', 'telegram_sent' => 'Telegram notification sent',
'telegram_error' => 'An error has occurred while sending the Telegram notification: %s', 'telegram_error' => 'An error has occurred while sending the Telegram notification: %s',
'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global 'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global configuration.',
configuration.',
'telegram_error_noid' => 'Unable to send test notification: no chat id found in your profile.', 'telegram_error_noid' => 'Unable to send test notification: no chat id found in your profile.',
'jabber_sent' => 'Telegram notification sent',
'jabber_error' => 'An error has occurred while sending the Telegram notification: %s',
'jabber_error_noconfig' => 'Unable to send test notification: no Jabber account set in the global configuration.',
'jabber_error_noaccount' => 'Unable to send test notification: no Jabber account found in your profile.',
'log_retention_period' => 'Log retention period', 'log_retention_period' => 'Log retention period',
'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%',
'off_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is DOWN', 'off_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is DOWN',
'off_email_body' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_discord_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_email_body' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: 'off_email_body' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port:
%PORT%<br>Error: %ERROR%<br>Date: %DATE%', %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_webhook_title' => 'Server \'%LABEL%\' is DOWN',
'off_webhook_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP:
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_pushover_title' => 'Server \'%LABEL%\' is DOWN', 'off_pushover_title' => 'Server \'%LABEL%\' is DOWN',
'off_pushover_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: 'off_pushover_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%', 'off_telegram_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_telegram_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: 'off_jabber_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%, it was down for %LAST_OFFLINE_DURATION%', 'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%, it was down for %LAST_OFFLINE_DURATION%',
'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING', 'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING',
'on_email_body' => 'Server \'%LABEL%\' is running again, it was down for 'on_email_body' => 'Server \'%LABEL%\' is running again, it was down for
%LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date: %LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'on_discord_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date: %DATE%',
'on_webhook_title' => 'Server \'%LABEL%\' is RUNNING',
'on_webhook_message' => 'Server \'%LABEL%\' is running again, it was down for
%LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%', %DATE%',
'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING', 'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING',
'on_pushover_message' => 'Server \'%LABEL%\' is running again, it was down for 'on_pushover_message' => 'Server \'%LABEL%\' is running again, it was down for
@ -399,27 +454,50 @@ $sm_lang = array(
%DATE%', %DATE%',
'on_telegram_message' => 'Server \'%LABEL%\' is running again, it was down for: 'on_telegram_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date: %LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'on_jabber_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%', %DATE%',
'combi_off_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error: 'combi_off_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_discord_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>',
'combi_off_webhook_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>', %ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error: 'combi_off_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>', %ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>- 'combi_off_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>',
'combi_off_jabber_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>', Date: %DATE%<br><br>',
'combi_on_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Downtime: 'combi_on_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Downtime:
%LAST_OFFLINE_DURATION%</li><li>Date: %DATE%</li></ul>', %LAST_OFFLINE_DURATION%</li><li>Date: %DATE%</li></ul>',
'combi_on_webhook_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port:
%PORT%</li><li>Downtime: %LAST_OFFLINE_DURATION%</li><li>Date:
%DATE%</li></ul>',
'combi_on_discord_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>-
Downtime: %LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_on_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: 'combi_on_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port:
%PORT%</li><li>Downtime: %LAST_OFFLINE_DURATION%</li><li>Date: %PORT%</li><li>Downtime: %LAST_OFFLINE_DURATION%</li><li>Date:
%DATE%</li></ul>', %DATE%</li></ul>',
'combi_on_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Downtime: 'combi_on_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Downtime:
%LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_on_jabber_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Downtime:
%LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>', %LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_email_subject' => 'IMPORTANT: \'%UP%\' servers UP again, \'%DOWN%\' servers DOWN', 'combi_email_subject' => 'IMPORTANT: \'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_webhook_subject' => '\'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_pushover_subject' => '\'%UP%\' servers UP again, \'%DOWN%\' servers DOWN', 'combi_pushover_subject' => '\'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_email_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following 'combi_email_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_discord_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_webhook_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%', servers are up again:</b><br>%UP_SERVERS%',
'combi_pushover_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following 'combi_pushover_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%', servers are up again:</b><br>%UP_SERVERS%',
'combi_telegram_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following 'combi_telegram_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_jabber_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%', servers are up again:</b><br>%UP_SERVERS%',
), ),
'login' => array( 'login' => array(
@ -437,8 +515,7 @@ $sm_lang = array(
'password_forgot' => 'Forgot password?', 'password_forgot' => 'Forgot password?',
'password_reset' => 'Reset password', 'password_reset' => 'Reset password',
'password_reset_email_subject' => 'Reset your password for PHP Server Monitor', 'password_reset_email_subject' => 'Reset your password for PHP Server Monitor',
'password_reset_email_body' => 'Please use the following link to reset your password. Please note it expires 'password_reset_email_body' => 'Please use the following link to reset your password. Please note it expires in 1 hour.<br><br>%link%',
in 1 hour.<br><br>%link%',
'error_user_incorrect' => 'The provided username could not be found.', 'error_user_incorrect' => 'The provided username could not be found.',
'error_login_incorrect' => 'The information is incorrect.', 'error_login_incorrect' => 'The information is incorrect.',
'error_login_passwords_nomatch' => 'The provided passwords do not match.', 'error_login_passwords_nomatch' => 'The provided passwords do not match.',

View File

@ -116,17 +116,17 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo 'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo
real. Vea <a href="https://pushover.net/"> su página web </a> para más real. Vea <a href="https://pushover.net/" target="_blank"> su página web </a> para
información.', más información.',
'pushover_key' => 'Clave Pushover', 'pushover_key' => 'Clave Pushover',
'pushover_device' => 'Dispositivo Pushover', 'pushover_device' => 'Dispositivo Pushover',
'pushover_device_description' => 'Nombre del dispositivo para enviar el mensaje. Dejar en blanco para enviarlo 'pushover_device_description' => 'Nombre del dispositivo para enviar el mensaje. Dejar en blanco para enviarlo
a todos los dispositivos.', a todos los dispositivos.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that
get real-time notifications. Visit the <a makes it easy to get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more
install guide.', info and an install guide.',
'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'El mensaje será enviado al chat correspondiente.', 'telegram_chat_id_description' => 'El mensaje será enviado al chat correspondiente.',
'telegram_get_chat_id' => 'Haga click aquí para obtener su chat id', 'telegram_get_chat_id' => 'Haga click aquí para obtener su chat id',
@ -302,22 +302,22 @@ $sm_lang = array(
'sms_from' => 'Número origen del SMS', 'sms_from' => 'Número origen del SMS',
'pushover_status' => '¿Habilitar el envío de mensajes Pushover?', 'pushover_status' => '¿Habilitar el envío de mensajes Pushover?',
'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo 'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo
real. Vea <a href="https://pushover.net/"> su página web </a> para más real. Vea <a href="https://pushover.net/" target="_blank"> su página web </a> para
información.', más información.',
'pushover_clone_app' => 'Haga clic aquí para crear tu aplicación Pushover', 'pushover_clone_app' => 'Haga clic aquí para crear tu aplicación Pushover',
'pushover_api_token' => 'Token API de Pushover', 'pushover_api_token' => 'Token API de Pushover',
'pushover_api_token_description' => 'Antes de poder utilizar Pushover, necesita <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Antes de poder utilizar Pushover, necesita <a href="%1$s" target="_blank"
rel="noopener"> registrar </a> su aplicación en la página web e rel="noopener"> registrar </a> su aplicación en la página web e
ingresar el token API.', ingresar el token API.',
'telegram_status' => '¿Habilitar el envío de mensajes de Telegram?', 'telegram_status' => '¿Habilitar el envío de mensajes de Telegram?',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> es una aplicación de mensajería 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> es una aplicación de
instantánea que permite recibir notificaciones en tiempo real. Visite la <a mensajería instantánea que permite recibir notificaciones en tiempo real. Visite
href="http://docs.phpservermonitor.org/">documentación</a> para una guía mas la <a href="http://docs.phpservermonitor.org/" target="_blank">documentación</a>
detallada.', para una guía mas detallada.',
'telegram_api_token' => 'Token API de Telegram', 'telegram_api_token' => 'Token API de Telegram',
'telegram_api_token_description' => 'Antes de utilizar Telegram, necesita un Token de API. Visite la <a 'telegram_api_token_description' => 'Antes de utilizar Telegram, necesita un Token de API. Visite la <a
href="http://docs.phpservermonitor.org/">documentación</a> para más href="http://docs.phpservermonitor.org/"
información.', target="_blank">documentación</a> para más información.',
'alert_type' => '¿Cuándo desea recibir notificaciones?', 'alert_type' => '¿Cuándo desea recibir notificaciones?',
'alert_type_description' => '<b>Al cambiar el estado:</b> p.ej. en línea -> fuera de línea o fuera de línea 'alert_type_description' => '<b>Al cambiar el estado:</b> p.ej. en línea -> fuera de línea o fuera de línea
-> en línea.<br><br /><b>Fuera de Línea:</b> Recibirá una notificación cuando -> en línea.<br><br /><b>Fuera de Línea:</b> Recibirá una notificación cuando
@ -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',
@ -93,7 +94,8 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a 'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a
href="https://pushover.net/">nende kodulehte</a> rohkema info jaoks.', href="https://pushover.net/" target="_blank">nende kodulehte</a> rohkema info
jaoks.',
'pushover_key' => 'Pushoveri Võti', 'pushover_key' => 'Pushoveri Võti',
'pushover_device' => 'Pushoveri Seade', 'pushover_device' => 'Pushoveri Seade',
'pushover_device_description' => 'Seadme nimi, kuhu teavitus saata. Jäta tühjaks, et saata igale seadmele.', 'pushover_device_description' => 'Seadme nimi, kuhu teavitus saata. Jäta tühjaks, et saata igale seadmele.',
@ -207,7 +209,8 @@ $sm_lang = array(
'sms_from' => 'Saatja telefoni number', 'sms_from' => 'Saatja telefoni number',
'pushover_status' => 'Luba Pushoveri sõnumite saatmine', 'pushover_status' => 'Luba Pushoveri sõnumite saatmine',
'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a 'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a
href="https://pushover.net/">nende kodulehte</a> rohkema info jaoks.', href="https://pushover.net/" target="_blank">nende kodulehte</a> rohkema info
jaoks.',
'pushover_clone_app' => 'Kliki siia, et teha oma Pushover äpp', 'pushover_clone_app' => 'Kliki siia, et teha oma Pushover äpp',
'pushover_api_token' => 'Pushover Äppi API Žetoon', 'pushover_api_token' => 'Pushover Äppi API Žetoon',
'pushover_api_token_description' => 'Enne, kui saad Pushoverida pead sa <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Enne, kui saad Pushoverida pead sa <a href="%1$s" target="_blank"
@ -242,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' => 'تنظیم',
@ -97,7 +98,8 @@ $sm_lang = array(
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ 'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ
را ساده می کند. برای اطلاعات بیشتر <a را ساده می کند. برای اطلاعات بیشتر <a
href="https://pushover.net/">سایت آن ها</a> را ببینید.', href="https://pushover.net/" target="_blank">سایت آن ها</a> را
ببینید.',
'pushover_key' => 'کلید Pushover', 'pushover_key' => 'کلید Pushover',
'pushover_device' => 'دستگاه Pushover', 'pushover_device' => 'دستگاه Pushover',
'pushover_device_description' => 'نام دستگاه برای ارسال پیام. برای ارسال به 'pushover_device_description' => 'نام دستگاه برای ارسال پیام. برای ارسال به
@ -217,7 +219,8 @@ $sm_lang = array(
'pushover_status' => 'اجازه ارسال پیام های Pushover', 'pushover_status' => 'اجازه ارسال پیام های Pushover',
'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ 'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ
را ساده می کند. برای اطلاعات بیشتر <a را ساده می کند. برای اطلاعات بیشتر <a
href="https://pushover.net/">سایت آن ها</a> را ببینید.', href="https://pushover.net/" target="_blank">سایت آن ها</a> را
ببینید.',
'pushover_clone_app' => 'برای ایجاد برنامه پوش آور خود اینجا را کلیک 'pushover_clone_app' => 'برای ایجاد برنامه پوش آور خود اینجا را کلیک
کنید.', کنید.',
'pushover_api_token' => 'رمز API برنامه پوش آور', 'pushover_api_token' => 'رمز API برنامه پوش آور',
@ -261,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

@ -94,7 +94,7 @@ $sm_lang = array(
'email' => 'Sähköposti', 'email' => 'Sähköposti',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso 'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso
<a href="https://pushover.net/">verkkosivuilta</a> lisäinfoa.', <a href="https://pushover.net/" target="_blank">verkkosivuilta</a> lisäinfoa.',
'pushover_key' => 'Pushover avain', 'pushover_key' => 'Pushover avain',
'pushover_device' => 'Pushover laite', 'pushover_device' => 'Pushover laite',
'pushover_device_description' => 'Laitteen nimi johon viesti lähetetään. Jätä tyhjäksi lähettääksesi 'pushover_device_description' => 'Laitteen nimi johon viesti lähetetään. Jätä tyhjäksi lähettääksesi
@ -209,7 +209,7 @@ $sm_lang = array(
'sms_from' => 'Lähettäjän puhelinnumero', 'sms_from' => 'Lähettäjän puhelinnumero',
'pushover_status' => 'Salli Pushover-viestien lähetys', 'pushover_status' => 'Salli Pushover-viestien lähetys',
'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso 'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso
<a href="https://pushover.net/">verkkosivuilta</a> lisäinfoa.', <a href="https://pushover.net/" target="_blank">verkkosivuilta</a> lisäinfoa.',
'pushover_clone_app' => 'Paina tästä luodaksesi Pushover-sovelluksesi', 'pushover_clone_app' => 'Paina tästä luodaksesi Pushover-sovelluksesi',
'pushover_api_token' => 'Pushover API-avain', 'pushover_api_token' => 'Pushover API-avain',
'pushover_api_token_description' => 'Ennen kuin voit käyttää Pushoveria, sinun täytyy <a href="%1$s" 'pushover_api_token_description' => 'Ennen kuin voit käyttää Pushoveria, sinun täytyy <a href="%1$s"
@ -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

@ -113,16 +113,18 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a 'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a
href="https://pushover.net/">leur site web</a> pour plus d\'informations.', href="https://pushover.net/" target="_blank">leur site web</a> pour plus
d\'informations.',
'pushover_key' => 'Clé Pushover', 'pushover_key' => 'Clé Pushover',
'pushover_device' => 'Appareil Pushover', 'pushover_device' => 'Appareil Pushover',
'pushover_device_description' => 'Nom de l\'appareil auquel le message doit être envoyé. Laissez vide pour 'pushover_device_description' => 'Nom de l\'appareil auquel le message doit être envoyé. Laissez vide pour
l\'envoyer à tous les appareils.', l\'envoyer à tous les appareils.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> est une application de messagerie 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> est une application de
instantanée qui facilite la réception de notification en temps réel. Lisez la <a messagerie instantanée qui facilite la réception de notification en temps réel.
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir plus Lisez la <a href="http://docs.phpservermonitor.org/"
d\'informations sur la configuration de ce service.', target="_blank">documentation</a> pour obtenir plus d\'informations sur la
configuration de ce service.',
'telegram_chat_id' => 'ID de conversation (Chat ID) Telegram', 'telegram_chat_id' => 'ID de conversation (Chat ID) Telegram',
'telegram_chat_id_description' => 'Les notifications seront envoyées à la conversation correspondante.', 'telegram_chat_id_description' => 'Les notifications seront envoyées à la conversation correspondante.',
'telegram_get_chat_id' => 'Cliquez ici pour obtenir votre ID de conversation (Chat ID)', 'telegram_get_chat_id' => 'Cliquez ici pour obtenir votre ID de conversation (Chat ID)',
@ -302,22 +304,23 @@ $sm_lang = array(
'sms_from' => 'SMS de l\'expéditeur', 'sms_from' => 'SMS de l\'expéditeur',
'pushover_status' => 'Autoriser l\'envoi des messages Pushover', 'pushover_status' => 'Autoriser l\'envoi des messages Pushover',
'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a 'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a
href="https://pushover.net/">leur site web</a> pour plus d\'informations.', href="https://pushover.net/" target="_blank">leur site web</a> pour plus
d\'informations.',
'pushover_clone_app' => 'Cliquez ici pour créer votre application Pushover', 'pushover_clone_app' => 'Cliquez ici pour créer votre application Pushover',
'pushover_api_token' => 'Jeton application Pushover', 'pushover_api_token' => 'Jeton application Pushover',
'pushover_api_token_description' => 'Avant de pouvoir utiliser Pushover, vous devez <a href="%1$s" 'pushover_api_token_description' => 'Avant de pouvoir utiliser Pushover, vous devez <a href="%1$s"
target="_blank" rel="noopener">créer une application</a> sur leur site target="_blank" rel="noopener">créer une application</a> sur leur site
web et entrer ici le jeton (Token) de l\'application.', web et entrer ici le jeton (Token) de l\'application.',
'telegram_status' => 'Autorise l\'envoi de message Telegram', 'telegram_status' => 'Autorise l\'envoi de message Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> est une application de messagerie 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> est une application de
instantanée qui facilite la réception de notification en temps réel. Lisez la <a messagerie instantanée qui facilite la réception de notification en temps réel.
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir plus Lisez la <a href="http://docs.phpservermonitor.org/"
d\'informations sur la configuration de ce service.', target="_blank">documentation</a> pour obtenir plus d\'informations sur la
configuration de ce service.',
'telegram_api_token' => 'Token API Telegram', 'telegram_api_token' => 'Token API Telegram',
'telegram_api_token_description' => 'Afin de pouvoir utiliser Telegram, il vous faut obtenir un token api. 'telegram_api_token_description' => 'Afin de pouvoir utiliser Telegram, il vous faut obtenir un token api.
Consultez la <a Consultez la <a href="http://docs.phpservermonitor.org/"
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir target="_blank">documentation</a> pour obtenir de l\'aide.',
de l\'aide.',
'alert_type' => 'Choisissez quand vous souhaitez être notifié', 'alert_type' => 'Choisissez quand vous souhaitez être notifié',
'alert_type_description' => '<b>Changement d\'état&nbsp;: </b>Vous recevez une notification chaque fois que 'alert_type_description' => '<b>Changement d\'état&nbsp;: </b>Vous recevez une notification chaque fois que
le serveur change d\'état. C\'est-à-dire passe de l\'état OK à HORS SERVICE le serveur change d\'état. C\'est-à-dire passe de l\'état OK à HORS SERVICE
@ -358,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/">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/">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

@ -107,16 +107,16 @@ $sm_lang = array(
'email' => 'E-post', 'email' => 'E-post',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a 'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a
href="https://pushover.net/">deres nettside</a> for mer info.', href="https://pushover.net/" target="_blank">deres nettside</a> for mer info.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Enhetsnavn for å sende meldingen til. La det være tomt for å sende det 'pushover_device_description' => 'Enhetsnavn for å sende meldingen til. La det være tomt for å sende det
til alle enheter.', til alle enheter.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> er en chat-app som gjør det enkelt å 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> er en chat-app som
meldinger i sanntid. til <a gjør det enkelt å meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for mer informasjon og href="http://docs.phpservermonitor.org/" target="_blank">dokumentasjonen</a> for
en installasjonsguide. ', mer informasjon og en installasjonsguide. ',
'telegram_chat_id' => 'Telegram chat-ID', 'telegram_chat_id' => 'Telegram chat-ID',
'telegram_chat_id_description' => 'Meldingen vil bli sendt til tilhørende chat.', 'telegram_chat_id_description' => 'Meldingen vil bli sendt til tilhørende chat.',
'telegram_get_chat_id' => 'Klikk her for å få chat-ID', 'telegram_get_chat_id' => 'Klikk her for å få chat-ID',
@ -276,21 +276,21 @@ $sm_lang = array(
'sms_from' => 'Avsenderens telefonnummer', 'sms_from' => 'Avsenderens telefonnummer',
'pushover_status' => 'Tillat sending av Pushover-meldinger', 'pushover_status' => 'Tillat sending av Pushover-meldinger',
'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a 'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a
href="https://pushover.net/">deres nettside</a> for mer info.', href="https://pushover.net/" target="_blank">deres nettside</a> for mer info.',
'pushover_clone_app' => 'Klikk her for å lage din Pushover-app', 'pushover_clone_app' => 'Klikk her for å lage din Pushover-app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Før du kan bruke Pushover, du <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Før du kan bruke Pushover, du <a href="%1$s" target="_blank"
rel="noopener"> registrere en app </a> deres nettside og angi App API rel="noopener"> registrere en app </a> deres nettside og angi App API
Token her.', Token her.',
'telegram_status' => 'Tillat sending av Telegram-meldinger', 'telegram_status' => 'Tillat sending av Telegram-meldinger',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> er en chat-app som gjør det enkelt å 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> er en chat-app som
meldinger i sanntid. til <a gjør det enkelt å meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for mer informasjon og href="http://docs.phpservermonitor.org/" target="_blank">dokumentasjonen</a> for
en installasjonsveiledning.', mer informasjon og en installasjonsveiledning.',
'telegram_api_token' => 'Telegram API Token', 'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Før du kan bruke Telegram, du en API-token. til <a 'telegram_api_token_description' => 'Før du kan bruke Telegram, du en API-token. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for å href="http://docs.phpservermonitor.org/"
hjelp.', target="_blank">dokumentasjonen</a> for å hjelp.',
'alert_type' => 'Velg når du vil bli varslet.', 'alert_type' => 'Velg når du vil bli varslet.',
'alert_type_description' => '<b>Statusendring:</b> Du vil motta et varsel når en server har endret status. 'alert_type_description' => '<b>Statusendring:</b> Du vil motta et varsel når en server har endret status.
fra online -> offline eller offline -> online.<br><br /><b>Offline:</b> Du fra online -> offline eller offline -> online.<br><br /><b>Offline:</b> Du
@ -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',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover jest usługą szybkich notyfikacji. Sprawdź <a 'pushover_description' => 'Pushover jest usługą szybkich notyfikacji. Sprawdź <a
href="https://pushover.net/">ich stronę</a> po więcej informacji.', href="https://pushover.net/" target="_blank">ich stronę</a> po więcej informacji.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Urządzenie dla Pushover', 'pushover_device' => 'Urządzenie dla Pushover',
'pushover_device_description' => 'Nazwa urządzenia do którego wysłać powiadomienie. Pozostaw puste aby 'pushover_device_description' => 'Nazwa urządzenia do którego wysłać powiadomienie. Pozostaw puste aby
@ -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/">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',
@ -93,7 +94,7 @@ $sm_lang = array(
'email' => 'Email', 'email' => 'Email',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover para enviar notificações em real-tome. Veja <a 'pushover_description' => 'Pushover para enviar notificações em real-tome. Veja <a
href="https://pushover.net/">o website</a> para mais informações.', href="https://pushover.net/" target="_blank">o website</a> para mais informações.',
'pushover_key' => 'Pushover Key', 'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device', 'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Nome do Device para enviar a mensagem. Deixe em branco para enviar a todos 'pushover_device_description' => 'Nome do Device para enviar a mensagem. Deixe em branco para enviar a todos
@ -209,7 +210,7 @@ $sm_lang = array(
'sms_from' => 'Número de telefone de envio', 'sms_from' => 'Número de telefone de envio',
'pushover_status' => 'Habilitar envio de mensagens Pushover', 'pushover_status' => 'Habilitar envio de mensagens Pushover',
'pushover_description' => 'Pushover é um serviço de notificações em tempo real. Veja <a 'pushover_description' => 'Pushover é um serviço de notificações em tempo real. Veja <a
href="https://pushover.net/">o website</a> para mais informações.', href="https://pushover.net/" target="_blank">o website</a> para mais informações.',
'pushover_clone_app' => 'Clique aqui para criar sua app Pushover', 'pushover_clone_app' => 'Clique aqui para criar sua app Pushover',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank"
@ -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

@ -113,7 +113,7 @@ $sm_lang = array(
'pushover_description' => 'Pushover - это сервис, который позволяет легко 'pushover_description' => 'Pushover - это сервис, который позволяет легко
получать уведомления в режиме реального получать уведомления в режиме реального
времени. Больше информации на <a времени. Больше информации на <a
href="https://pushover.net/">их веб-сайте</a>.', href="https://pushover.net/" target="_blank">их веб-сайте</a>.',
'pushover_key' => 'Pushover ключ', 'pushover_key' => 'Pushover ключ',
'pushover_device' => 'Pushover устройство', 'pushover_device' => 'Pushover устройство',
'pushover_device_description' => 'Имя устройства, на которое будут 'pushover_device_description' => 'Имя устройства, на которое будут
@ -121,12 +121,12 @@ $sm_lang = array(
пустым, что бы отправлять уведомления на пустым, что бы отправлять уведомления на
все устройства.', все устройства.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> удобный мессенджер 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
для получения уведомлений в реальном мессенджер для получения уведомлений в
времени. Посетите <a реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/">раздел документации</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' => 'Сообщения будут отправляться на
указанный идентификатор чата.', указанный идентификатор чата.',
@ -304,7 +304,7 @@ $sm_lang = array(
'pushover_description' => 'Pushover - это сервис, который позволяет легко 'pushover_description' => 'Pushover - это сервис, который позволяет легко
получать уведомления в режиме реального получать уведомления в режиме реального
времени. Больше информации на <a времени. Больше информации на <a
href="https://pushover.net/">их веб-сайте</a>.', href="https://pushover.net/" target="_blank">их веб-сайте</a>.',
'pushover_clone_app' => 'Нажмите здесь чтобы создать ваш Pushover app', 'pushover_clone_app' => 'Нажмите здесь чтобы создать ваш Pushover app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Прежде чем вы сможете начать 'pushover_api_token_description' => 'Прежде чем вы сможете начать
@ -313,17 +313,17 @@ $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/">Telegram</a> удобный мессенджер 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
для получения уведомлений в реальном мессенджер для получения уведомлений в
времени. Посетите <a реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/">раздел документации</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, вам необходимо
получить API Token. Посетите <a получить API Token. Посетите <a
href="http://docs.phpservermonitor.org/">раздел href="http://docs.phpservermonitor.org/" target="_blank">раздел
документации</a> для получения помощи.', документации</a> для получения помощи.',
'alert_type' => 'Тип уведомлений', 'alert_type' => 'Тип уведомлений',
'alert_type_description' => '<b>Изменение статуса:</b> Вы получите 'alert_type_description' => '<b>Изменение статуса:</b> Вы получите
@ -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/">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/">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/">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
@ -210,7 +212,7 @@ $sm_lang = array(
'sms_from' => 'Avsändarens telefonnummer', 'sms_from' => 'Avsändarens telefonnummer',
'pushover_status' => 'Tillåt Pushover-meddelande', 'pushover_status' => 'Tillåt Pushover-meddelande',
'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/">deras webbsida</a> för mer info.', href="https://pushover.net/" target="_blank">deras webbsida</a> för mer info.',
'pushover_clone_app' => 'Klicka här för att skapa din Pushover app', 'pushover_clone_app' => 'Klicka här för att skapa din Pushover app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Innan du kan använda Pushover behöver du <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Innan du kan använda Pushover behöver du <a href="%1$s" target="_blank"
@ -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',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'E-posta', 'email' => 'E-posta',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi 'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi
için <a href="https://pushover.net/">sitesine</a> bakabilirsiniz.', için <a href="https://pushover.net/" target="_blank">sitesine</a> bakabilirsiniz.',
'pushover_key' => 'Pushover Anahtarı', 'pushover_key' => 'Pushover Anahtarı',
'pushover_device' => 'Pushover Aracı', 'pushover_device' => 'Pushover Aracı',
'pushover_device_description' => 'Mesajın gönderileceği cihazın adı. Tüm cihazlara göndermek için boş 'pushover_device_description' => 'Mesajın gönderileceği cihazın adı. Tüm cihazlara göndermek için boş
@ -211,7 +212,7 @@ $sm_lang = array(
'sms_from' => 'Gönderen numarası', 'sms_from' => 'Gönderen numarası',
'pushover_status' => 'Pushover mesaj gönderimine izin ver', 'pushover_status' => 'Pushover mesaj gönderimine izin ver',
'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi 'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi
için <a href="https://pushover.net/">sitesine</a> bakabilirsiniz.', için <a href="https://pushover.net/" target="_blank">sitesine</a> bakabilirsiniz.',
'pushover_clone_app' => 'Pushover uygulaması oluşturmak için buraya tıklayınız.', 'pushover_clone_app' => 'Pushover uygulaması oluşturmak için buraya tıklayınız.',
'pushover_api_token' => 'Pushover Uygulaması API Token Bilgisi', 'pushover_api_token' => 'Pushover Uygulaması API Token Bilgisi',
'pushover_api_token_description' => 'Pushover kullanmadan önce, <a href="%1$s" target="_blank" 'pushover_api_token_description' => 'Pushover kullanmadan önce, <a href="%1$s" target="_blank"
@ -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

@ -116,7 +116,7 @@ $sm_lang = array(
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати 'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати
сповіщення у реальному часі. За деталями сповіщення у реальному часі. За деталями
перейдіть на <a href="https://pushover.net/">їхній перейдіть на <a href="https://pushover.net/" target="_blank">їхній
вебсайт</a>.', вебсайт</a>.',
'pushover_key' => 'Ключ Pushover', 'pushover_key' => 'Ключ Pushover',
'pushover_device' => 'Пристрій Pushover', 'pushover_device' => 'Пристрій Pushover',
@ -124,11 +124,12 @@ $sm_lang = array(
повідомлення. Залиште пустим, щоб повідомлення. Залиште пустим, щоб
надсилати на всі пристрої.', надсилати на всі пристрої.',
'telegram' => 'Telegram', 'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> чат-застосунок, що 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
дозволяє легко отримувати сповіщення у чат-застосунок, що дозволяє легко отримувати
реальному часі. За деталями й інструкцією зі сповіщення у реальному часі. За деталями й
встановлення зверніться до <a інструкцією зі встановлення зверніться до <a
href="http://docs.phpservermonitor.org/">документації</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/">їхній вебсайт</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/">Telegram</a> чат-застосунок, що 'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
дозволяє легко отримувати сповіщення у чат-застосунок, що дозволяє легко отримувати
реальному часі. Детальніша інформація та сповіщення у реальному часі. Детальніша
інструкція зі встановлення доступні у <a інформація та інструкція зі встановлення
href="http://docs.phpservermonitor.org/">документації</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/">документації</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/">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/">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' => '设置',
@ -124,9 +125,6 @@ $sm_lang = array(
'sms' => '短信', 'sms' => '短信',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'no_logs' => '没有日志', 'no_logs' => '没有日志',
'clear' => 'Clear log',
'delete_title' => 'Delete log',
'delete_message' => 'Are you sure you want to delete <b>all</b> logs?',
), ),
'servers' => array( 'servers' => array(
'server' => '业务', 'server' => '业务',
@ -262,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' => '将发送一封短信到您账户设置的手机号码.',

368
src/lang/zh_TW.lang.php Normal file
View File

@ -0,0 +1,368 @@
<?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 Jason Cheng <https://github.com/jasoncheng7115>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: v3.1.1
* @link http://www.phpservermonitor.org/
**/
$sm_lang = array(
'name' => '繁體中文 - Traditional Chinese',
'locale' => array(
'0' => 'zh_TW.UTF-8',
'1' => 'zh_TW',
'2' => 'chinese',
'3' => 'chinese-tw',
),
'locale_tag' => 'zh_TW',
'locale_dir' => 'ltr',
'system' => array(
'title' => 'Server Monitor',
'install' => '安裝',
'action' => '動作',
'save' => '儲存',
'edit' => '編輯',
'delete' => '刪除',
'date' => '日期',
'message' => '訊息',
'yes' => '是',
'no' => '否',
'insert' => '插入',
'add_new' => '增加',
'back_to_top' => '回到最上層',
'go_back' => '返回',
'ok' => '確定',
'cancel' => '取消',
'activate' => '啟用',
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
'yesterday_format' => '昨日 %k:%M',
'other_day_format' => '%A %k:%M',
'never' => '從未',
'hours_ago' => '%d小時前',
'an_hour_ago' => '1小時前',
'minutes_ago' => '%d分鐘前',
'a_minute_ago' => '1分鐘前',
'seconds_ago' => '%d秒前',
'a_second_ago' => '剛剛',
'year' => '年',
'years' => '年',
'month' => '月',
'months' => '月',
'day' => '日',
'days' => '日',
'hour' => '時',
'hours' => '時',
'minute' => '分',
'minutes' => '分',
'second' => '秒',
'seconds' => '秒',
),
'menu' => array(
'config' => '設定',
'server' => '伺服器',
'server_log' => '記錄',
'server_status' => '狀態',
'server_update' => '更新',
'user' => '使用者',
'help' => '說明',
),
'users' => array(
'user' => '使用者',
'name' => '顯示名稱',
'user_name' => '使用者名稱',
'password' => '密碼',
'password_repeat' => '再次輸入密碼',
'password_leave_blank' => '若密碼欄位保持空白,表示不做修改',
'level' => '等級',
'level_10' => '超級管理員',
'level_20' => '一般使用者',
'level_description' => '<b>超級管理員</b>
具備所有伺服器的管理權限,可管理使用者以及修改系統設定。<br/><b>一般使用者</b>
僅能查看以及更新自己所負責的伺服器。',
'mobile' => '行動電話',
'email' => '電子郵件',
'pushover' => 'Pushover 通知',
'pushover_description' => 'Pushover
是一種雲端服務,讓你可以很方便的收到即時訊息通知,您可以到<a
href="https://pushover.net/">網站</a>了解更多的內容。',
'pushover_key' => 'Pushover 金鑰',
'pushover_device' => 'Pushover 裝置',
'pushover_device_description' => '發送訊息的裝置名稱,若保留空白,將會發送到所有的裝置。',
'telegram' => 'Telegram 通知',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
是一種聊天應用程式,它提供很容易使用的的即時通知能力。您可以到
<a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a>
了解更多的內容。',
'telegram_chat_id' => 'Telegram Chat ID',
'telegram_chat_id_description' => '將訊息發送到指定的聊天室',
'telegram_get_chat_id' => '點選這裡可以取得您的 Chat ID',
'activate_telegram' => '啟用 Telegram 通知',
'activate_telegram_description' => '允許 Telegram 將訊息發送到指定的 Chat
ID。若沒有啟用此項目Telegram
將不允許我們發送通知給您。',
'telegram_bot_username_error_token' => '401 - 未授權,請確認您的 API Token 是有效的。',
'telegram_bot_error' => '啟用 Telegram 通知時發生錯誤:%s',
'delete_title' => '刪除使用者',
'delete_message' => '您確定要刪除使用者 \'%1\'?',
'deleted' => '已刪除使用者。',
'updated' => '已更新使用者。',
'inserted' => '已增加使用者。',
'profile' => '個人資料',
'profile_updated' => '個人資料已經更新。',
'error_user_name_bad_length' => '使用者名稱長度必須為2-64個字元。',
'error_user_name_invalid' => '使用者名稱只允許英文字母(a-z、A-Z)、數字(0-9)以及底線(_)。',
'error_user_name_exists' => '這個使用者名稱已存在。',
'error_user_email_bad_length' => '電子郵件長度為5-255個字元。',
'error_user_email_invalid' => '無效的電子郵件。',
'error_user_level_invalid' => '無效的使用者等級。',
'error_user_no_match' => '這個使用者名稱不存在。',
'error_user_password_invalid' => '無效的密碼。',
'error_user_password_no_match' => '密碼不符。',
),
'log' => array(
'title' => '記錄概覽',
'type' => '類型',
'status' => '狀態',
'email' => '電子郵件通知',
'sms' => '簡訊通知',
'pushover' => 'Pushover 通知',
'telegram' => 'Telegram 通知',
'no_logs' => '沒有記錄',
'clear' => '清除記錄',
'delete_title' => '刪除記錄',
'delete_message' => '您確定要刪除 <b>所有</b> 記錄?',
),
'servers' => array(
'server' => '伺服器',
'status' => '狀態',
'label' => '標籤',
'domain' => '網域/IP',
'timeout' => '逾時',
'timeout_description' => '等待伺服器回應的秒數。',
'authentication_settings' => '驗證設定 (非必要)',
'website_username' => '使用者',
'website_username_description' => '存取這個網站的使用者。(只支援 Apache 驗證)',
'website_password' => '密碼',
'website_password_description' => '存取這個網站的使用者。(密碼將會以加密形式存放在資料庫)',
'fieldset_monitoring' => '監視',
'fieldset_permissions' => '權限',
'port' => '連接埠',
'custom_port' => '自訂連接埠',
'popular_ports' => '常用連接埠',
'please_select' => '請選擇',
'type' => '類型',
'type_website' => '網站',
'type_service' => '服務',
'type_ping' => 'Ping',
'pattern' => '字串',
'pattern_description' => '如果在網站上沒有找到符合的字串,則將網站標示為離線。',
'pattern_online' => '指明網站上的字串',
'pattern_online_description' => '線上:如果在網站上沒有找到符合的字串,則將網站標示為線上。',
'header_name_description' => '標頭名稱 (區分大小寫)',
'header_value_description' => '標頭的值,可以使用正則表示式。',
'last_check' => '最後一次檢查',
'last_online' => '最後一次上線',
'last_offline' => '最後一次離線',
'monitoring' => '監控中',
'no_monitoring' => '未監控',
'email' => '電子郵件通知',
'send_email' => '發送電子郵件',
'sms' => '簡訊通知',
'send_sms' => '發送簡訊',
'pushover' => 'Pushover 通知',
'send_pushover' => '發送 Pushover 通知',
'telegram' => 'Telegram 通知',
'send_telegram' => '發送 Telegram 通知',
'users' => '使用者',
'delete_title' => '刪除伺服器',
'delete_message' => '您確定要刪除這個伺服器 \'%1\'?',
'deleted' => '伺服器已刪除。',
'updated' => '伺服器已更新。',
'inserted' => '伺服器已增加。',
'latency' => '延遲',
'latency_max' => '延遲 (最大)',
'latency_min' => '延遲 (最小)',
'latency_avg' => '延遲 (平均)',
'uptime' => '上線時間',
'year' => '年',
'month' => '月',
'week' => '週',
'day' => '日',
'hour' => '小時',
'warning_threshold' => '警報臨界值',
'warning_threshold_description' => '失敗達到多少次數則標示為離線。',
'chart_last_week' => '上週',
'chart_history' => '更早',
'chart_day_format' => '%Y-%m-%d',
'chart_long_date_format' => '%Y-%m-%d %H:%M:%S',
'chart_short_date_format' => '%m/%d %H:%M',
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => '簡訊通知已關閉。',
'warning_notifications_disabled_email' => '電子郵件通知已關閉。',
'warning_notifications_disabled_pushover' => 'Pushover 通知已關閉。',
'warning_notifications_disabled_telegram' => 'Telegram 通知已關閉。',
'error_server_no_match' => '找不到伺服器。',
'error_server_label_bad_length' => '標籤必須在1到255間的字元。',
'error_server_ip_bad_length' => '網域/IP必須在1到255間的字元。',
'error_server_ip_bad_service' => '無效的 IP 位址。',
'error_server_ip_bad_website' => '無效的網址。',
'error_server_type_invalid' => '無效的的伺服器型態',
'error_server_warning_threshold_invalid' => '警報臨界值必須是大於 0 的有效整數。',
),
'config' => array(
'general' => '一般',
'language' => '語言',
'show_update' => '檢查更新',
'password_encrypt_key' => '加密金鑰',
'password_encrypt_key_note' => '這個加密金鑰將用於保護您登入這個網站的密碼,如果修改了此金鑰,原本已經存在的密碼將無法使用!',
'proxy' => '啟用 Proxy',
'proxy_url' => 'Proxy URL',
'proxy_user' => 'Proxy 使用者名稱',
'proxy_password' => 'Proxy 密碼',
'email_status' => '啟用電子郵件通知',
'email_from_email' => '寄件者信箱',
'email_from_name' => '寄件者名稱',
'email_smtp' => '使用SMTP發信',
'email_smtp_host' => 'SMTP主機',
'email_smtp_port' => 'SMTP連接埠口',
'email_smtp_security' => 'SMTP安全性',
'email_smtp_security_none' => '無',
'email_smtp_username' => 'SMTP使用者名稱',
'email_smtp_password' => 'SMTP使用者密碼',
'email_smtp_noauth' => '留空白表示不做帳號驗證',
'sms_status' => '啟用簡訊通知',
'sms_gateway' => '簡訊服務提供者',
'sms_gateway_username' => '簡訊閘道使用者名稱',
'sms_gateway_password' => '簡訊閘道使用者密碼',
'sms_from' => '發送人電話號碼',
'pushover_status' => '啟用Pushover通知',
'pushover_description' => 'Pushover是線上服務讓您可以方便的收到即時通知請參考 <a
href="https://pushover.net/" target="_blank"> 網站</a>
可以得到更詳細的資訊。</a> ',
'pushover_clone_app' => '點選這裡可快速建立Pushover App',
'pushover_api_token_description' => '在您使用 Pushover 通知之前,需要先到這裡-><a href="%1$s"
target="_blank" rel="noopener">註冊Pushover App帳號</a>
接著在這個網頁輸入你的的Pushover App API Token號碼。',
'telegram_status' => '允許發送 Telegram 訊息',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
是一種聊天應用程式,它提供很容易使用的即時通知服務。請參考
<a href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
可以取得更多資訊與安裝說明。',
'telegram_api_token_description' => '使用 Telegram 通知之前,您必需先取得 API Token。請到 <a
href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
取得說明。',
'alert_type' => '需要提醒的類別',
'alert_type_description' => '<b>狀態改變:</b> 伺服器 連線 -> 離線或連線 ->
連線的狀態變化將會收到提醒通知。<br/><br /><b>離線:</b>
伺服器首次發生離線狀態將會收到提醒設定為15分鐘執行一次伺服器從1:00-6:00一直處於離線狀態那麼你將會在1:00首次收到一則提醒通知,之後便不會在收到重覆的提醒通知。<br/><br><b>全部:</b>
每次執行當伺服器離線(即使伺服器離線很久已提醒過了)均發送提醒通知。',
'alert_type_status' => '狀態改變',
'alert_type_offline' => '離線',
'alert_type_always' => '全部',
'alert_proxy_url' => '<b>格式:</b> Host:Port',
'log_status' => '狀態記錄',
'log_status_description' => '如果啟用狀態記錄,則每一筆提醒通知都會保留記錄。',
'log_email' => '保留電子郵件通知發送記錄',
'log_sms' => '保留簡訊通知發送記錄',
'log_pushover' => '保留 pushover 通知發送記錄',
'log_telegram' => '保留 telegram 通知發送記錄',
'updated' => '已更新設定。',
'tab_email' => '電子郵件發送設定',
'tab_sms' => '簡訊發送設定',
'tab_pushover' => 'Pushover 通知',
'tab_telegram' => 'Telegram 通知',
'settings_email' => '電子郵件發送設定',
'settings_sms' => '簡訊發送設定',
'settings_pushover' => 'Pushover 發送設定',
'settings_telegram' => 'Telegram 發送設定',
'settings_notification' => '提醒設定',
'settings_log' => '記錄設定',
'settings_proxy' => 'Proxy 設定',
'auto_refresh' => '自動更新',
'test' => '測試',
'test_email' => '電子郵件將發送到您在使用者設定內指定的電子郵件信箱。',
'test_sms' => '簡訊將發送到您在使用者設定內指定的行動電話號碼。',
'test_pushover' => 'Pushover 通知將發送到您在使用者設定的裝置。',
'test_telegram' => 'Telegram 通知將發送到您在使用者設定的 Chat ID。',
'send' => '傳送',
'test_subject' => '標題',
'test_message' => '訊息',
'email_sent' => '傳送',
'email_error' => '電子郵件傳送發生錯誤',
'sms_sent' => '簡訊發送',
'sms_error' => '簡訊發送發生錯誤',
'sms_error_nomobile' => '無法傳送 SMS 簡訊測試:您設定的電話號碼無效或無法找到。',
'pushover_sent' => '傳送 Pushover 通知',
'pushover_error' => '傳送 Pushover 通知發生錯誤: %s',
'pushover_error_noapp' => '無法傳送 Pushover 通知: 在系統設定找不到 Pushover App API token。',
'pushover_error_nokey' => '無法傳送 Pushover 通知: 在系統設定找不到 Pushover key found 。',
'telegram_sent' => '傳送 Telegram 通知',
'telegram_error' => '傳送 Telegram 通知發生錯誤: %s',
'telegram_error_notoken' => '無法傳送 Telegram 通知: 在系統設定找不到 Telegram API token。',
'telegram_error_noid' => '無法傳送 Telegram 通知: 在您的個人資料找不到 Chat ID。',
'log_retention_period' => '記錄保留期限',
'log_retention_period_description' => '保留伺服器運作時間和記錄歸檔的天數輸入0可以防止記錄被清除',
'log_retention_days' => '日',
),
'notifications' => array(
'off_sms' => '伺服器 \'%LABEL%\' 關機: ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => 'IMPORTANT: 服務器 \'%LABEL%\' 關機',
'off_email_body' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'off_pushover_title' => '伺服器 \'%LABEL%\' 關機',
'off_pushover_message' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'off_telegram_message' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'on_email_subject' => 'IMPORTANT: 伺服器 \'%LABEL%\' 運行中',
'on_pushover_title' => '伺服器 \'%LABEL%\' 運作中',
),
'login' => array(
'welcome_usermenu' => '歡迎,%user_name%',
'title_sign_in' => '請登入',
'title_forgot' => '忘記密碼',
'title_reset' => '密碼重置',
'submit' => '送出',
'remember_me' => '記住我',
'login' => '登入',
'logout' => '登出',
'username' => '使用者名稱',
'password' => '密碼',
'password_repeat' => '再次輸入密碼',
'password_forgot' => '忘記密碼',
'password_reset' => '重設密碼',
'password_reset_email_subject' => '重設您的密碼',
'password_reset_email_body' => '點選以下連結來重設密碼這個連結於1小時後失效。<br/><br/>%link%',
'error_user_incorrect' => '使用者不存在。',
'error_login_incorrect' => '登入資料不正確。',
'error_login_passwords_nomatch' => '密碼不符合。',
'error_reset_invalid_link' => '重設密碼連結無效。',
'success_password_forgot' => '重設密碼電子郵件已發送。',
'success_password_reset' => '密碼重設成功,請登入。',
),
'error' => array(
'401_unauthorized' => '驗證失敗',
'401_unauthorized_description' => '您没有權限進入這個頁面。',
),
);

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

@ -43,13 +43,19 @@ class ConfigController extends AbstractController
'email_status', 'email_status',
'email_smtp', 'email_smtp',
'sms_status', 'sms_status',
'discord_status',
'pushover_status', 'pushover_status',
'webhook_status',
'telegram_status', 'telegram_status',
'jabber_status',
'log_status', 'log_status',
'log_email', 'log_email',
'log_sms', 'log_sms',
'log_discord',
'log_pushover', 'log_pushover',
'log_webhook',
'log_telegram', 'log_telegram',
'log_jabber',
'show_update', 'show_update',
'combine_notifications', 'combine_notifications',
); );
@ -67,14 +73,30 @@ class ConfigController extends AbstractController
'email_smtp_host', 'email_smtp_host',
'email_smtp_port', 'email_smtp_port',
'email_smtp_username', 'email_smtp_username',
'email_smtp_password',
'sms_gateway_username', 'sms_gateway_username',
'sms_gateway_password', 'sms_gateway_password',
'sms_from', 'sms_from',
'webhook_url',
'webhook_json',
'pushover_api_token', 'pushover_api_token',
'telegram_api_token', 'telegram_api_token',
'jabber_host',
'jabber_port',
'jabber_username',
'jabber_domain',
'user_agent',
'site_title'
); );
/**
* Fields for saving encrypted.
* @var array
*/
protected $encryptedFields = [
'email_smtp_password',
'jabber_password'
];
private $default_tab = 'general'; private $default_tab = 'general';
public function __construct(Database $db, \Twig_Environment $twig) public function __construct(Database $db, \Twig_Environment $twig)
@ -178,9 +200,22 @@ class ConfigController extends AbstractController
$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
foreach ($this->encryptedFields as $encryptedField) {
$tpl_data[$encryptedField] = '';
}
$tpl_data[$this->default_tab . '_active'] = 'active'; $tpl_data[$this->default_tab . '_active'] = 'active';
$testmodals = array('email', 'sms', 'pushover', 'telegram'); $testmodals = array('email', 'sms', 'discord', 'webhook', 'pushover', 'telegram', 'jabber');
foreach ($testmodals as $modal_id) { foreach ($testmodals as $modal_id) {
$modal = new \psm\Util\Module\Modal( $modal = new \psm\Util\Module\Modal(
$this->twig, $this->twig,
@ -206,6 +241,7 @@ class ConfigController extends AbstractController
// 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' =>
@ -214,7 +250,7 @@ class ConfigController extends AbstractController
: '', : '',
'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)), 'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)),
'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';
@ -224,6 +260,13 @@ class ConfigController extends AbstractController
$clean[$input_key] = $_POST[$input_key]; $clean[$input_key] = $_POST[$input_key];
} }
} }
foreach ($this->encryptedFields as $encryptedField) {
$value = filter_input(INPUT_POST, $encryptedField);
if ($value !== null && $value !== '') {
$clean[$encryptedField] = psm_password_encrypt(psm_get_conf('password_encrypt_key'), $value);
}
// else { leave as is }
}
$language_refresh = ($clean['language'] != psm_get_conf('language')); $language_refresh = ($clean['language'] != psm_get_conf('language'));
foreach ($clean as $key => $value) { foreach ($clean as $key => $value) {
psm_update_conf($key, $value); psm_update_conf($key, $value);
@ -234,10 +277,16 @@ class ConfigController extends AbstractController
$this->testEmail(); $this->testEmail();
} elseif (!empty($_POST['test_sms'])) { } elseif (!empty($_POST['test_sms'])) {
$this->testSMS(); $this->testSMS();
} elseif (!empty($_POST['test_discord'])) {
$this->testDiscord();
} elseif (!empty($_POST['test_pushover'])) { } elseif (!empty($_POST['test_pushover'])) {
$this->testPushover(); $this->testPushover();
}elseif (!empty($_POST['test_webhook'])) {
$this->testWebhook();
} elseif (!empty($_POST['test_telegram'])) { } elseif (!empty($_POST['test_telegram'])) {
$this->testTelegram(); $this->testTelegram();
} elseif (!empty($_POST['test_jabber'])) {
$this->testJabber();
} }
if ($language_refresh) { if ($language_refresh) {
@ -251,10 +300,16 @@ class ConfigController extends AbstractController
$this->default_tab = 'email'; $this->default_tab = 'email';
} elseif (isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) { } elseif (isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) {
$this->default_tab = 'sms'; $this->default_tab = 'sms';
} elseif (isset($_POST['discord_submit']) || !empty($_POST['test_discord'])) {
$this->default_tab = 'discord';
} elseif (isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) { } elseif (isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) {
$this->default_tab = 'pushover'; $this->default_tab = 'pushover';
} elseif (isset($_POST['webhook_submit']) || !empty($_POST['test_webhook'])) {
$this->default_tab = 'webhook';
} 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'])) {
$this->default_tab = 'jabber';
} }
} }
return $this->runAction('index'); return $this->runAction('index');
@ -306,6 +361,88 @@ class ConfigController extends AbstractController
} }
} }
/**
* Execute Discord test
*
* @todo move test to separate class
*/
protected function testDiscord()
{
$user = $this->getUser()->getUser();
if (empty($user->discord)) {
$this->addMessage(psm_get_lang('config', 'discord_error_nowebhook'), 'error');
} else {
$success = 0;
$result = 'An unknown error has occurred.';
try {
$curl = curl_init($user->discord);
$json = json_decode(
'{"content":""}',
true
);
$json['content'] = psm_get_lang('config', 'test_message');
$msg = "payload_json=" . urlencode(json_encode($json));
if(isset($curl)) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 204) {
$success = 0;
// $result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result;
$error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_strerror($err) . ". \nResult: " . $result;
$result = $error;
} else {
$success = 1;
}
curl_close($curl);
}
} catch (Exception $e) {
$success = 0;
$result = $e->getMessage();
}
if ($success === 1) {
$this->addMessage(psm_get_lang('config', 'discord_sent'), 'success');
} else {
$this->addMessage(sprintf(psm_get_lang('config', 'discord_error'), $result), 'error');
}
}
}
/** Execute webhook test
*
* @todo move test to separate class
*/
protected function testWebhook()
{
$user = $this->getUser()->getUser();
if (empty($user->webhook_url)) {
$this->addMessage(psm_get_lang('config', 'webhook_error_nourl'), 'error');
} elseif (empty($user->webhook_json)) {
$this->addMessage(psm_get_lang('config', 'webhook_error_nojson'), 'error');
} else {
$webhook = psm_build_webhook();
$webhook->setUrl($user->webhook_url);
$webhook->setJson($user->webhook_json);
$message = (psm_get_lang('config', 'test_message'));
$result = $webhook->sendWebhook($message);
if ($result==1) {
$this->addMessage(psm_get_lang('config', 'webhook_sent'), 'success');
} else {
$this->addMessage(sprintf(psm_get_lang('config', 'webhook_error'), $result), 'error');
}
}
}
/** /**
* Execute pushover test * Execute pushover test
* *
@ -379,17 +516,43 @@ class ConfigController extends AbstractController
} }
} }
/**
* Test Jabber.
*/
protected function testJabber()
{
$user = $this->getUser()->getUser();
psm_jabber_send_message(
psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
[$user->jabber],
psm_get_lang('config', 'test_message'),
(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)
);
// no message - async ... so just info
$this->addMessage(psm_get_lang('config', 'jabber_check'), 'info');
// @todo possible to set message via ajax with callback ...
}
protected function getLabels() protected function getLabels()
{ {
return array( return array(
'label_tab_email' => psm_get_lang('config', 'tab_email'), 'label_tab_email' => psm_get_lang('config', 'tab_email'),
'label_tab_sms' => psm_get_lang('config', 'tab_sms'), 'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_discord' => psm_get_lang('config', 'tab_discord'),
'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'), 'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_tab_webhook' => psm_get_lang('config', 'tab_webhook'),
'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_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_discord' => psm_get_lang('config', 'settings_discord'),
'label_settings_webhook' => psm_get_lang('config', 'settings_webhook'),
'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_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'),
@ -417,6 +580,14 @@ class ConfigController extends AbstractController
'label_sms_gateway_username' => psm_get_lang('config', 'sms_gateway_username'), 'label_sms_gateway_username' => psm_get_lang('config', 'sms_gateway_username'),
'label_sms_gateway_password' => psm_get_lang('config', 'sms_gateway_password'), 'label_sms_gateway_password' => psm_get_lang('config', 'sms_gateway_password'),
'label_sms_from' => psm_get_lang('config', 'sms_from'), 'label_sms_from' => psm_get_lang('config', 'sms_from'),
'label_discord_status' => psm_get_lang('config', 'discord_status'),
'label_discord_description' => psm_get_lang('config', 'discord_description'),
'label_webhook_description' => psm_get_lang('config', 'webhook_description'),
'label_webhook_status' => psm_get_lang('config', 'webhook_status'),
'label_webhook_url' => psm_get_lang('config', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('config', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('config', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('config', 'webhook_json_description'),
'label_pushover_description' => psm_get_lang('config', 'pushover_description'), 'label_pushover_description' => psm_get_lang('config', 'pushover_description'),
'label_pushover_status' => psm_get_lang('config', 'pushover_status'), 'label_pushover_status' => psm_get_lang('config', 'pushover_status'),
'label_pushover_clone_app' => psm_get_lang('config', 'pushover_clone_app'), 'label_pushover_clone_app' => psm_get_lang('config', 'pushover_clone_app'),
@ -430,6 +601,18 @@ class ConfigController extends AbstractController
'label_telegram_status' => psm_get_lang('config', 'telegram_status'), 'label_telegram_status' => psm_get_lang('config', 'telegram_status'),
'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_description' => psm_get_lang('config', 'jabber_description'),
'label_jabber_host' => psm_get_lang('config', 'jabber_host'),
'label_jabber_host_description' => psm_get_lang('config', 'jabber_host_description'),
'label_jabber_port' => psm_get_lang('config', 'jabber_port'),
'label_jabber_port_description' => psm_get_lang('config', 'jabber_port_description'),
'label_jabber_username' => psm_get_lang('config', 'jabber_username'),
'label_jabber_username_description' => psm_get_lang('config', 'jabber_username_description'),
'label_jabber_domain' => psm_get_lang('config', 'jabber_domain'),
'label_jabber_domain_description' => psm_get_lang('config', 'jabber_domain_description'),
'label_jabber_password' => psm_get_lang('config', 'jabber_password'),
'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'),
@ -438,20 +621,26 @@ class ConfigController extends AbstractController
'label_log_status_description' => psm_get_lang('config', 'log_status_description'), 'label_log_status_description' => psm_get_lang('config', 'log_status_description'),
'label_log_email' => psm_get_lang('config', 'log_email'), 'label_log_email' => psm_get_lang('config', 'log_email'),
'label_log_sms' => psm_get_lang('config', 'log_sms'), 'label_log_sms' => psm_get_lang('config', 'log_sms'),
'label_log_discord' => psm_get_lang('config', 'log_discord'),
'label_log_pushover' => psm_get_lang('config', 'log_pushover'), 'label_log_pushover' => psm_get_lang('config', 'log_pushover'),
'label_log_webhook' => psm_get_lang('config', 'log_webhook'),
'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_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'),
'label_log_retention_period_description' => psm_get_lang('config', 'log_retention_period_description'), 'label_log_retention_period_description' => psm_get_lang('config', 'log_retention_period_description'),
'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_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

@ -101,6 +101,53 @@ class InstallController extends AbstractController
if (!in_array('mysql', \PDO::getAvailableDrivers())) { if (!in_array('mysql', \PDO::getAvailableDrivers())) {
$errors++; $errors++;
$this->addMessage('The PDO MySQL driver needs to be installed.', 'error'); $this->addMessage('The PDO MySQL driver needs to be installed.', 'error');
} else {
$this->addMessage('PHP PDO MySQL driver found', 'success');
}
if (!extension_loaded('filter')) {
$this->addMessage('PHP is installed without the filter module. Please install filter.', 'warning');
} else {
$this->addMessage('PHP filter module found', 'success');
}
if (!extension_loaded('ctype')) {
$this->addMessage('PHP is installed without the ctype module. Please install ctype.', 'warning');
} else {
$this->addMessage('PHP ctype module found', 'success');
}
if (!extension_loaded('hash')) {
$this->addMessage('PHP is installed without the hash module. Please install hash.', 'warning');
} else {
$this->addMessage('PHP hash module found', 'success');
}
if (!extension_loaded('json')) {
$this->addMessage('PHP is installed without the json module. Please install json.', 'warning');
} else {
$this->addMessage('PHP json module found', 'success');
}
if (!extension_loaded('libxml')) {
$this->addMessage('PHP is installed without the libxml module. Please install libxml.', 'warning');
} else {
$this->addMessage('PHP libxml module found', 'success');
}
if (!extension_loaded('openssl')) {
$this->addMessage('PHP is installed without the openssl module. Please install openssl.', 'warning');
} else {
$this->addMessage('PHP openssl module found', 'success');
}
if (!extension_loaded('pcre')) {
$this->addMessage('PHP is installed without the pcre module. Please install pcre.', 'warning');
} else {
$this->addMessage('PHP pcre module found', 'success');
}
if (!extension_loaded('sockets')) {
$this->addMessage('PHP is installed without the sockets module. Please install sockets.', 'warning');
} else {
$this->addMessage('PHP sockets module found', 'success');
}
if (!extension_loaded('xml')) {
$this->addMessage('PHP is installed without the xml module. Please install xml.', 'warning');
} else {
$this->addMessage('PHP xml module found', 'success');
} }
if (!ini_get('date.timezone')) { if (!ini_get('date.timezone')) {
$this->addMessage( $this->addMessage(
@ -256,7 +303,10 @@ class InstallController extends AbstractController
'level' => PSM_USER_ADMIN, 'level' => PSM_USER_ADMIN,
'pushover_key' => '', 'pushover_key' => '',
'pushover_device' => '', 'pushover_device' => '',
'webhook_url' => '',
'webhook_json' => '',
'telegram_id' => '', 'telegram_id' => '',
'jabber' => ''
); );
$validator = $this->container->get('util.user.validator'); $validator = $this->container->get('util.user.validator');

View File

@ -81,10 +81,15 @@ abstract class AbstractServerController extends AbstractController
`s`.`active`, `s`.`active`,
`s`.`email`, `s`.`email`,
`s`.`sms`, `s`.`sms`,
`s`.`discord`,
`s`.`webhook`,
`s`.`pushover`, `s`.`pushover`,
`s`.`telegram`, `s`.`telegram`,
`s`.`jabber`,
`s`.`warning_threshold`, `s`.`warning_threshold`,
`s`.`warning_threshold_counter`, `s`.`warning_threshold_counter`,
`s`.`ssl_cert_expiry_days`,
`s`.`ssl_cert_expired_time`,
`s`.`timeout`, `s`.`timeout`,
`s`.`website_username`, `s`.`website_username`,
`s`.`website_password`, `s`.`website_password`,
@ -111,7 +116,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')) {
@ -120,7 +125,16 @@ abstract class AbstractServerController extends AbstractController
} }
$server['last_check'] = psm_timespan($server['last_check']); $server['last_check'] = psm_timespan($server['last_check']);
if ($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) { if (
(
$server['status'] == 'on' &&
$server['warning_threshold_counter'] > 0
) || (
$server['status'] == 'on' &&
$server['ssl_cert_expired_time'] !== null &&
$server['ssl_cert_expiry_days'] > 0
)
) {
$server['status'] = 'warning'; $server['status'] = 'warning';
} }

View File

@ -55,8 +55,11 @@ class LogController extends AbstractServerController
'label_status' => psm_get_lang('log', 'status'), 'label_status' => psm_get_lang('log', 'status'),
'label_email' => psm_get_lang('log', 'email'), 'label_email' => psm_get_lang('log', 'email'),
'label_sms' => psm_get_lang('log', 'sms'), 'label_sms' => psm_get_lang('log', 'sms'),
'label_discord' => psm_get_lang('log', 'discord'),
'label_pushover' => psm_get_lang('log', 'pushover'), 'label_pushover' => psm_get_lang('log', 'pushover'),
'label_webhook' => psm_get_lang('log', 'webhook'),
'label_telegram' => psm_get_lang('log', 'telegram'), 'label_telegram' => psm_get_lang('log', 'telegram'),
'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'),
@ -76,7 +79,7 @@ class LogController extends AbstractServerController
$modal->setTitle(psm_get_lang('log', 'delete_title')); $modal->setTitle(psm_get_lang('log', 'delete_title'));
$modal->setMessage(psm_get_lang('log', 'delete_message')); $modal->setMessage(psm_get_lang('log', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete')); $modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$sidebar->addButton( $sidebar->addButton(
'clear_logn', 'clear_logn',
psm_get_lang('log', 'clear'), psm_get_lang('log', 'clear'),
@ -88,7 +91,7 @@ class LogController extends AbstractServerController
); );
} }
$log_types = array('status', 'email', 'sms', 'pushover', 'telegram'); $log_types = array('status', 'email', 'sms', 'pushover', 'telegram', 'jabber', 'discord', 'webhook');
foreach ($log_types as $key) { foreach ($log_types as $key) {
$records = $this->getEntries($key); $records = $this->getEntries($key);
@ -160,9 +163,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

@ -100,8 +100,11 @@ class ServerController extends AbstractServerController
$icons = array( $icons = array(
'email' => 'icon-envelope', 'email' => 'icon-envelope',
'sms' => 'icon-mobile', 'sms' => 'icon-mobile',
'discord' => 'icon-discord',
'pushover' => 'icon-pushover', 'pushover' => 'icon-pushover',
'webhook' => 'icon-webhook',
'telegram' => 'icon-telegram', 'telegram' => 'icon-telegram',
'jabber' => 'icon-jabber'
); );
$servers = $this->getServers(); $servers = $this->getServers();
@ -114,6 +117,9 @@ class ServerController extends AbstractServerController
$servers[$x]['ip'] = '<a href="' . $servers[$x]['ip'] . $servers[$x]['ip'] = '<a href="' . $servers[$x]['ip'] .
'" target="_blank" rel="noopener">' . $ip . '</a>'; '" target="_blank" rel="noopener">' . $ip . '</a>';
} }
if ($servers[$x]['type'] == 'ping') {
$servers[$x]['port'] = '';
}
if (($servers[$x]['active'] == 'yes')) { if (($servers[$x]['active'] == 'yes')) {
$servers[$x]['active_title'] = psm_get_lang('servers', 'monitoring'); $servers[$x]['active_title'] = psm_get_lang('servers', 'monitoring');
} else { } else {
@ -123,6 +129,14 @@ class ServerController extends AbstractServerController
$servers[$x] = $this->formatServer($servers[$x]); $servers[$x] = $this->formatServer($servers[$x]);
} }
$tpl_data['servers'] = $servers; $tpl_data['servers'] = $servers;
$tpl_data['config']['email'] = psm_get_conf('email_status');
$tpl_data['config']['sms'] = psm_get_conf('sms_status');
$tpl_data['config']['discord'] = psm_get_conf('discord_status');
$tpl_data['config']['webhook'] = psm_get_conf('webhook_status');
$tpl_data['config']['pushover'] = psm_get_conf('pushover_status');
$tpl_data['config']['telegram'] = psm_get_conf('telegram_status');
return $this->twig->render('module/server/server/list.tpl.html', $tpl_data); return $this->twig->render('module/server/server/list.tpl.html', $tpl_data);
} }
@ -133,6 +147,12 @@ class ServerController extends AbstractServerController
{ {
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : ''; $back_to = isset($_GET['back_to']) ? $_GET['back_to'] : '';
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal);
$modal->setTitle(psm_get_lang('servers', 'delete_title'));
$modal->setMessage(psm_get_lang('servers', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$tpl_data = $this->getLabels(); $tpl_data = $this->getLabels();
$tpl_data['edit_server_id'] = $this->server_id; $tpl_data['edit_server_id'] = $this->server_id;
$tpl_data['url_save'] = psm_build_url(array( $tpl_data['url_save'] = psm_build_url(array(
@ -141,6 +161,11 @@ class ServerController extends AbstractServerController
'id' => $this->server_id, 'id' => $this->server_id,
'back_to' => $back_to, 'back_to' => $back_to,
)); ));
$tpl_data['url_delete'] = psm_build_url(array(
'mod' => 'server',
'action' => 'delete',
'id' => $this->server_id,
));
// depending on where the user came from, add the go back url: // depending on where the user came from, add the go back url:
if ($back_to == 'view' && $this->server_id > 0) { if ($back_to == 'view' && $this->server_id > 0) {
@ -153,6 +178,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
@ -173,10 +205,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"';
} }
@ -208,16 +236,20 @@ class ServerController extends AbstractServerController
'edit_value_website_username' => $edit_server['website_username'], 'edit_value_website_username' => $edit_server['website_username'],
'edit_value_website_password' => empty($edit_server['website_password']) ? '' : 'edit_value_website_password' => empty($edit_server['website_password']) ? '' :
sha1($edit_server['website_password']), sha1($edit_server['website_password']),
'edit_value_ssl_cert_expiry_days' => $edit_server['ssl_cert_expiry_days'],
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"', 'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
'edit_active_selected' => $edit_server['active'], 'edit_active_selected' => $edit_server['active'],
'edit_email_selected' => $edit_server['email'], 'edit_email_selected' => $edit_server['email'],
'edit_sms_selected' => $edit_server['sms'], 'edit_sms_selected' => $edit_server['sms'],
'edit_discord_selected' => $edit_server['discord'],
'edit_webhook_selected' => $edit_server['webhook'],
'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'],
)); ));
} }
$notifications = array('email', 'sms', 'pushover', 'telegram'); $notifications = array('email', 'sms', 'pushover', 'discord', 'webhook', 'telegram', 'jabber');
foreach ($notifications as $notification) { foreach ($notifications as $notification) {
if (psm_get_conf($notification . '_status') == 0) { if (psm_get_conf($notification . '_status') == 0) {
$tpl_data['warning_' . $notification] = true; $tpl_data['warning_' . $notification] = true;
@ -245,7 +277,7 @@ class ServerController extends AbstractServerController
// We need the server id to encrypt the password. Encryption will be done after the server is added // We need the server id to encrypt the password. Encryption will be done after the server is added
$encrypted_password = ''; $encrypted_password = '';
if (!empty($_POST['website_password'])) { if (!empty($_POST['website_password'])) {
$new_password = psm_POST('website_password'); $new_password = psm_POST('website_password');
@ -281,11 +313,15 @@ class ServerController extends AbstractServerController
'header_name' => psm_POST('header_name', ''), 'header_name' => psm_POST('header_name', ''),
'header_value' => psm_POST('header_value', ''), 'header_value' => psm_POST('header_value', ''),
'warning_threshold' => intval(psm_POST('warning_threshold', 0)), 'warning_threshold' => intval(psm_POST('warning_threshold', 0)),
'ssl_cert_expiry_days' => intval(psm_POST('ssl_cert_expiry_days', 1)),
'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no', 'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no',
'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no', 'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no',
'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no', 'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no',
'discord' => in_array($_POST['discord'], array('yes', 'no')) ? $_POST['discord'] : 'no',
'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no', 'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no',
'webhook' => in_array($_POST['webhook'], array('yes', 'no')) ? $_POST['webhook'] : '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',
); );
// make sure websites start with http:// // make sure websites start with http://
if ( if (
@ -325,6 +361,7 @@ class ServerController extends AbstractServerController
$server_validator->type($clean['type']); $server_validator->type($clean['type']);
$server_validator->ip($clean['ip'], $clean['type']); $server_validator->ip($clean['ip'], $clean['type']);
$server_validator->warningThreshold($clean['warning_threshold']); $server_validator->warningThreshold($clean['warning_threshold']);
$server_validator->sslCertExpiryDays($clean['ssl_cert_expiry_days']);
} catch (\InvalidArgumentException $ex) { } catch (\InvalidArgumentException $ex) {
$this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error'); $this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error');
return $this->executeEdit(); return $this->executeEdit();
@ -492,6 +529,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);
} }
@ -551,13 +597,22 @@ class ServerController extends AbstractServerController
'label_send_email' => psm_get_lang('servers', 'send_email'), 'label_send_email' => psm_get_lang('servers', 'send_email'),
'label_sms' => psm_get_lang('servers', 'sms'), 'label_sms' => psm_get_lang('servers', 'sms'),
'label_send_sms' => psm_get_lang('servers', 'send_sms'), 'label_send_sms' => psm_get_lang('servers', 'send_sms'),
'label_discord' => psm_get_lang('servers', 'discord'),
'label_send_discord' => psm_get_lang('servers', 'send_discord'),
'label_pushover' => psm_get_lang('servers', 'pushover'),
'label_send_pushover' => psm_get_lang('servers', 'send_pushover'), 'label_send_pushover' => psm_get_lang('servers', 'send_pushover'),
'label_send_webhook' => psm_get_lang('servers', 'send_webhook'),
'label_telegram' => psm_get_lang('servers', 'telegram'), 'label_telegram' => psm_get_lang('servers', 'telegram'),
'label_jabber' => psm_get_lang('servers', 'jabber'),
'label_send_jabber' => psm_get_lang('servers', 'send_jabber'),
'label_webhook' => psm_get_lang('servers', 'webhook'),
'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_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'),
'label_ssl_cert_expiry_days' => psm_get_lang('servers', 'ssl_cert_expiry_days'),
'label_ssl_cert_expiry_days_description' => psm_get_lang('servers', 'ssl_cert_expiry_days_description'),
'label_action' => psm_get_lang('system', 'action'), 'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'), 'label_go_back' => psm_get_lang('system', 'go_back'),
@ -567,7 +622,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'),
@ -576,6 +632,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'),
); );
} }
@ -597,4 +657,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

@ -100,6 +100,8 @@ class StatusController extends AbstractServerController
$layout_data['servers_offline'][] = $server; $layout_data['servers_offline'][] = $server;
} elseif ($server['warning_threshold_counter'] > 0) { } elseif ($server['warning_threshold_counter'] > 0) {
$layout_data['servers_warning'][] = $server; $layout_data['servers_warning'][] = $server;
} elseif ($server['ssl_cert_expired_time'] !== null && $server['ssl_cert_expiry_days'] > 0) {
$layout_data['servers_warning'][] = $server;
} else { } else {
$layout_data['servers_online'][] = $server; $layout_data['servers_online'][] = $server;
} }

View File

@ -39,7 +39,7 @@ class ProfileController extends AbstractController
* @var array $profile_fields * @var array $profile_fields
*/ */
protected $profile_fields = protected $profile_fields =
array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id'); array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'discord', 'webhook_url', 'webhook_json', 'telegram_id', 'jabber');
public function __construct(Database $db, \Twig_Environment $twig) public function __construct(Database $db, \Twig_Environment $twig)
{ {
@ -78,11 +78,21 @@ class ProfileController extends AbstractController
'label_password_repeat' => psm_get_lang('users', 'password_repeat'), 'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'), 'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'), 'label_mobile' => psm_get_lang('users', 'mobile'),
'label_webhook' => psm_get_lang('users', 'webhook'),
'label_webhook_description' => psm_get_lang('users', 'webhook_description'),
'label_webhook_url' => psm_get_lang('users', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('users', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('users', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('users', 'webhook_json_description'),
'label_pushover' => psm_get_lang('users', 'pushover'), 'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_discord' => psm_get_lang('users', 'discord'),
'label_discord_description' => psm_get_lang('users', 'discord_description'),
'label_telegram' => psm_get_lang('users', 'telegram'), 'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'), 'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'), 'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'),
@ -90,6 +100,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_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(

View File

@ -158,9 +158,13 @@ class UserController extends AbstractController
'name', 'name',
'user_name', 'user_name',
'mobile', 'mobile',
'discord',
'webhook_url',
'webhook_json',
'pushover_key', 'pushover_key',
'pushover_device', 'pushover_device',
'telegram_id', 'telegram_id',
'jabber',
'email' 'email'
); );
@ -254,9 +258,13 @@ class UserController extends AbstractController
'password_repeat', 'password_repeat',
'level', 'level',
'mobile', 'mobile',
'discord',
'webhook_url',
'webhook_json',
'pushover_key', 'pushover_key',
'pushover_device', 'pushover_device',
'telegram_id', 'telegram_id',
'jabber',
'email' 'email'
); );
$clean = array(); $clean = array();
@ -310,6 +318,15 @@ class UserController extends AbstractController
if ($user_id > 0) { if ($user_id > 0) {
// edit user // edit user
unset($clean['password']); // password update is executed separately unset($clean['password']); // password update is executed separately
$admins = $this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN));
if (
(int) count($admins) === (int) 1 &&
(int) $admins[0]['user_id'] === (int) $user_id &&
(int) $clean['level'] === (int) PSM_USER_USER
) {
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'warning');
$clean['level'] = PSM_USER_ADMIN;
}
$this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $user_id)); $this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $user_id));
$this->addMessage(psm_get_lang('users', 'updated'), 'success'); $this->addMessage(psm_get_lang('users', 'updated'), 'success');
@ -360,7 +377,11 @@ class UserController extends AbstractController
try { try {
$this->container->get('util.user.validator')->userId($id); $this->container->get('util.user.validator')->userId($id);
if (count($this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN))) == 1) { $admins = $this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN));
if (
(int) count($admins) === (int) 1 &&
(int) $admins[0]['user_id'] === (int) $id
) {
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'error'); $this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'error');
} else { } else {
$this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,)); $this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,));
@ -392,15 +413,24 @@ class UserController extends AbstractController
'label_level' => psm_get_lang('users', 'level'), 'label_level' => psm_get_lang('users', 'level'),
'label_level_description' => psm_get_lang('users', 'level_description'), 'label_level_description' => psm_get_lang('users', 'level_description'),
'label_mobile' => psm_get_lang('users', 'mobile'), 'label_mobile' => psm_get_lang('users', 'mobile'),
'label_discord' => psm_get_lang('users', 'discord'),
'label_discord_description' => psm_get_lang('users', 'discord_description'),
'label_webhook' => psm_get_lang('users', 'webhook'),
'label_webhook_description' => psm_get_lang('users', 'webhook_description'),
'label_webhook_url' => psm_get_lang('users', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('users', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('users', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('users', 'webhook_json_description'),
'label_pushover' => psm_get_lang('users', 'pushover'), 'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram' => psm_get_lang('users', 'telegram'), 'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_id' => psm_get_lang('users', 'telegram_chat_id'), 'label_telegram_id' => psm_get_lang('users', 'telegram_chat_id'),
'label_telegram_id_description' => psm_get_lang('users', 'telegram_chat_id_description'), 'label_telegram_id_description' => psm_get_lang('users', 'telegram_chat_id_description'),
'label_jabber' => psm_get_lang('users', 'jabber'),
'label_jabber_description' => psm_get_lang('users', 'jabber_description'),
'label_email' => psm_get_lang('users', 'email'), 'label_email' => psm_get_lang('users', 'email'),
'label_servers' => psm_get_lang('menu', 'server'), 'label_servers' => psm_get_lang('menu', 'server'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),

View File

@ -35,15 +35,15 @@ final class UserEvents
/** /**
* @var string * @var string
*/ */
public const USER_ADD = 'user.add'; const USER_ADD = 'user.add';
/** /**
* @var string * @var string
*/ */
public const USER_EDIT = 'user.edit'; const USER_EDIT = 'user.edit';
/** /**
* @var string * @var string
*/ */
public const USER_DELETE = 'user.delete'; const USER_DELETE = 'user.delete';
} }

View File

@ -67,10 +67,10 @@ class CMBulkSMS extends Core
protected $messageBody; protected $messageBody;
/** @var string JSON Gateway API URL */ /** @var string JSON Gateway API URL */
public const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message"; const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message";
/** @var string XML Gateway API URL */ /** @var string XML Gateway API URL */
public const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx"; const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx";
/** /**
* Build the message and send cURL request to the sms gateway * Build the message and send cURL request to the sms gateway
@ -131,7 +131,7 @@ class CMBulkSMS extends Core
), ),
'msg' => array( 'msg' => array(
array( array(
'from' => substr($this->originator, 0, 11), 'from' => substr($this->originator, 0, 15),
'to' => $recipients, 'to' => $recipients,
'body' => array( 'body' => array(
'content' => $message 'content' => $message
@ -172,7 +172,7 @@ class CMBulkSMS extends Core
$msg = $xml->addChild('MSG'); $msg = $xml->addChild('MSG');
// From // From
$msg->addChild('FROM', substr($this->originator, 0, 11)); $msg->addChild('FROM', substr($this->originator, 0, 15));
// Recipients // Recipients
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {

View File

@ -64,7 +64,7 @@ class ClickSend extends Core
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$data['messages'][] = array( $data['messages'][] = array(
'source' => 'phpservermon', 'source' => 'phpservermon',
'from' => substr($this->originator, 0, 11), 'from' => substr($this->originator, 0, 15),
'to' => $recipient, 'to' => $recipient,
'body' => $message, 'body' => $message,
); );

2
src/psm/Txtmsg/FreeVoipDeal.php Executable file → Normal file
View File

@ -63,7 +63,7 @@ class FreeVoipDeal extends Core
array( array(
"username" => $this->username, "username" => $this->username,
"password" => $this->password, "password" => $this->password,
"from" => substr($this->originator, 0, 11), "from" => substr($this->originator, 0, 15),
"to" => $recipient, "to" => $recipient,
"text" => $message, "text" => $message,
) )

View File

@ -63,7 +63,7 @@ class Mosms extends Core
array( array(
"username" => $this->username, "username" => $this->username,
"password" => $this->password, "password" => $this->password,
"customsender" => substr($this->originator, 0, 11), "customsender" => substr($this->originator, 0, 15),
"nr" => $recipient, "nr" => $recipient,
"type" => "text", "type" => "text",
"data" => $message, "data" => $message,

101
src/psm/Txtmsg/OVHsms.php Normal file
View File

@ -0,0 +1,101 @@
<?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 Alexis Urien <Alexis.urien@free.fr>
* @Author Tim Zandbergen <Tim@Xervion.nl>
* @author Ward Pieters <ward@wardpieters.nl>
* @author Alexandre ZANELLI <alexandre@les-z.org>
* @copyright Copyright (c) 2016 Alexis Urien <alexis.urien@free.fr>
* @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 OVHsms extends Core {
/**
* Send sms using the OVH http2sms gateway
* Online documentation :https://docs.ovh.com/fr/sms/envoyer_des_sms_depuis_une_url_-_http2sms/
* Ovh need Account and Login, then use format login@account in username field.
*
* @var string $message
* @var string $this->username
* @var string $this->password
* @var array $this->recipients
* @var array $this->originator
*
* @var resource $curl
* @var SimpleXMLElement $xmlResults
* @var string $err
* @var string $recipient
* @var mixed $result
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message) {
$error = "";
$success = 1;
$account_login = explode('@',$this->username);
$recipients = join(',', $this->recipients);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://www.ovh.com/cgi-bin/sms/http2sms.cgi?".http_build_query(
array(
"account" => $account_login[1],
"login" => $account_login[0],
"password" => $this->password,
"from" => str_replace('+', '00', $this->originator),
"to" => $recipients,
"message" => $message,
"contentType" => "text/xml",
"noStop" => 1,
)
)
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$xmlResults = simplexml_load_string($result);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $xmlResults === false ||($xmlResults->status != '100' && $xmlResults->status != '101')) {
$success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$xmlResults->status." \n".$xmlResults->Message;
}
curl_close($curl);
if ($success) {
return 1;
}
return $error;
}
}

View File

@ -59,11 +59,11 @@ class Octopush extends Core
{ {
$error = ""; $error = "";
$success = 1; $success = 1;
$smsType = "XXX"; //FR = premium, WWW = world, XXX = Low cost $smsType = "FR"; //FR = premium, WWW = world, XXX = Low cost
$recipients = join(',', $this->recipients); $recipients = join(',', $this->recipients);
$message = ($smsType == "FR") ? urlencode($message . " STOP au XXXX") : urlencode($message); $message = ($smsType == "FR") ? rawurlencode($message . " STOP au XXXXX") : rawurlencode($message);
$curl = curl_init(); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://www.octopush-dm.com/api/sms/?" . http_build_query( curl_setopt($curl, CURLOPT_URL, "http://www.octopush-dm.com/api/sms/?" . http_build_query(
@ -72,7 +72,7 @@ class Octopush extends Core
"api_key" => $this->password, "api_key" => $this->password,
"sms_recipients" => $recipients, "sms_recipients" => $recipients,
"sms_type" => $smsType, "sms_type" => $smsType,
"sms_sender" => substr($this->originator, 0, 11), "sms_sender" => substr($this->originator, 0, 15),
"sms_text" => $message, "sms_text" => $message,
) )
)); ));

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

@ -58,7 +58,7 @@ class Smsglobal extends Core
$recipients = join(',', $this->recipients); $recipients = join(',', $this->recipients);
$from = substr($this->originator, 0, 11); // Max 11 Characters $from = substr($this->originator, 0, 15); // Max 15 Characters
$message = substr(rawurlencode($message), 0, 153); $message = substr(rawurlencode($message), 0, 153);
$curl = curl_init(); $curl = curl_init();

View File

@ -64,7 +64,7 @@ class Smsit extends Core
"apiKey" => $this->password, "apiKey" => $this->password,
"mobile" => $recipient, "mobile" => $recipient,
"message" => urlencode($message), "message" => urlencode($message),
"senderId" => substr($this->originator, 0, 11), "senderId" => substr($this->originator, 0, 15),
) )
)); ));

View File

@ -66,7 +66,7 @@ class SolutionsInfini extends Core
"api_key" => $this->password, "api_key" => $this->password,
"method" => "sms", "method" => "sms",
"to" => $recipients, "to" => $recipients,
"sender" => substr($this->originator, 0, 11), "sender" => substr($this->originator, 0, 15),
"message" => $message, "message" => $message,
) )
)); ));

92
src/psm/Txtmsg/Ysmal.php Normal file
View File

@ -0,0 +1,92 @@
<?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 Perri Vardy-Mason
* @author Dylan Ysmal <dylan@ysmal.fr>
* @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 Ysmal extends Core
{
/**
* Send sms using the Hermes SMS API on Ysmal.fr
* @var string $message
* @var array $this->recipients
* @var string $this->password
*
* @var mixed $result
* @var array $headers
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message)
{
$success = 1;
$error = '';
foreach ($this->recipients as $recipient) {
$opts['http'] = [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
'User-Agent: PHPServerMonitor (+https://phpservermonitor.org)',
'content' => http_build_query([
'key' => $this->password,
'number' => $recipient,
'message' => $message
]),
'ignore_errors' => true
];
$api = 'https://sms-api.ysmal.fr/';
$ctx = stream_context_create($opts);
$res = file_get_contents($api, false, $ctx);
$json = json_decode($res, true);
if ($json === NULL) {
$success = 0;
$error = "($recipient) json_decode_error";
break;
}
if ($json['status'] !== 'success') {
$success = 0;
$error = "($recipient) $json[error]";
break;
}
}
if ($success) {
return 1;
}
return $error;
}
}

View File

@ -134,51 +134,64 @@ class Installer
$queries = array(); $queries = array();
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` ( $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (
`ip`, `port`, `label`, `type`, `pattern`, `pattern_online`, `redirect_check`, `ip`, `port`, `label`, `type`, `pattern`, `pattern_online`, `redirect_check`,
`status`, `rtime`, `active`, `email`, `sms`, `pushover`, `telegram`) `status`, `rtime`, `active`, `email`, `sms`, `pushover`,`webhook`, `telegram`, `jabber`)
VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '',
'yes', 'bad', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes'), 'yes', 'bad', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes','yes', 'yes', 'yes'),
('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '',
'yes', 'bad','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes')"; 'yes', 'bad','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);"; $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('language', 'en_US'), ('language', 'en_US'),
('proxy', '0'), ('proxy', '0'),
('proxy_url', ''), ('proxy_url', ''),
('proxy_user', ''), ('proxy_user', ''),
('proxy_password', ''), ('proxy_password', ''),
('email_status', '1'), ('email_status', '1'),
('email_from_email', 'monitor@example.org'), ('email_from_email', 'monitor@example.org'),
('email_from_name', 'Server Monitor'), ('email_from_name', 'Server Monitor'),
('email_smtp', ''), ('email_smtp', ''),
('email_smtp_host', ''), ('email_smtp_host', ''),
('email_smtp_port', ''), ('email_smtp_port', ''),
('email_smtp_security', ''), ('email_smtp_security', ''),
('email_smtp_username', ''), ('email_smtp_username', ''),
('email_smtp_password', ''), ('email_smtp_password', ''),
('sms_status', '0'), ('sms_status', '0'),
('sms_gateway', 'messagebird'), ('sms_gateway', 'messagebird'),
('sms_gateway_username', 'username'), ('sms_gateway_username', 'username'),
('sms_gateway_password', 'password'), ('sms_gateway_password', 'password'),
('sms_from', '1234567890'), ('sms_from', '1234567890'),
('pushover_status', '0'), ('webhook_status', '0'),
('pushover_api_token', ''), ('pushover_status', '0'),
('telegram_status', '0'), ('pushover_api_token', ''),
('telegram_api_token', ''), ('telegram_status', '0'),
('password_encrypt_key', '" . sha1(microtime()) . "'), ('telegram_api_token', ''),
('alert_type', 'status'), ('jabber_status', '1'),
('log_status', '1'), ('jabber_host', ''),
('log_email', '1'), ('jabber_port', ''),
('log_sms', '1'), ('jabber_username', ''),
('log_pushover', '1'), ('jabber_domain', ''),
('log_telegram', '1'), ('jabber_password', ''),
('log_retention_period', '365'), ('password_encrypt_key', '" . sha1(microtime()) . "'),
('version', '" . PSM_VERSION . "'), ('alert_type', 'status'),
('version_update_check', '" . PSM_VERSION . "'), ('log_status', '1'),
('auto_refresh_servers', '0'), ('log_email', '1'),
('show_update', '1'), ('log_sms', '1'),
('last_update_check', '0'), ('log_pushover', '1'),
('cron_running', '0'), ('log_webhook', '1'),
('cron_running_time', '0');"; ('log_telegram', '1'),
('log_jabber', '1'),
('discord_status', '0'),
('log_jdiscord', '1'),
('log_retention_period', '365'),
('version', '" . PSM_VERSION . "'),
('version_update_check', '" . PSM_VERSION . "'),
('auto_refresh_servers', '0'),
('show_update', '1'),
('last_update_check', '0'),
('cron_running', '0'),
('cron_running_time', '0'),
('cron_off_running', '0'),
('cron_off_running_time', '0');";
$this->execSQL($queries); $this->execSQL($queries);
} }
@ -189,45 +202,49 @@ class Installer
{ {
$tables = array( $tables = array(
PSM_DB_PREFIX . 'config' => "CREATE TABLE `" . PSM_DB_PREFIX . "config` ( PSM_DB_PREFIX . 'config' => "CREATE TABLE `" . PSM_DB_PREFIX . "config` (
`key` varchar(255) NOT NULL, `key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL, `value` varchar(255) NOT NULL,
PRIMARY KEY (`key`) PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'users' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users` ( PSM_DB_PREFIX . 'users' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique', `user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique',
`password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format', `password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format',
`password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code', `password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code',
`password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request', `password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
`rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token', `rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token',
`level` tinyint(2) unsigned NOT NULL DEFAULT '20', `level` tinyint(2) unsigned NOT NULL DEFAULT '20',
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
`mobile` varchar(15) NOT NULL, `mobile` varchar(15) NOT NULL,
`pushover_key` varchar(255) NOT NULL, `discord` varchar(255) NOT NULL,
`pushover_device` varchar(255) NOT NULL, `pushover_key` varchar(255) NOT NULL,
`telegram_id` varchar(255) NOT NULL, `pushover_device` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL, `webhook_url` varchar(255) NOT NULL,
`webhook_json` varchar(255) NOT NULL DEFAULT '{\"text\":\"servermon: #message\"}',
`telegram_id` varchar(255) NOT NULL ,
`jabber` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`), PRIMARY KEY (`user_id`),
UNIQUE KEY `unique_username` (`user_name`) UNIQUE KEY `unique_username` (`user_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . PSM_DB_PREFIX .
'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` ( 'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
`user_id` int(11) unsigned NOT NULL, `user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL, `key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL, `value` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`, `key`) PRIMARY KEY (`user_id`, `key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'users_servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` ( PSM_DB_PREFIX . 'users_servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` (
`user_id` INT( 11 ) UNSIGNED NOT NULL , `user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL , `server_id` INT( 11 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `user_id` , `server_id` ) PRIMARY KEY ( `user_id` , `server_id` )
) ENGINE = MyISAM DEFAULT CHARSET=utf8;", ) ENGINE = MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'log' => "CREATE TABLE `" . PSM_DB_PREFIX . "log` ( PSM_DB_PREFIX . 'log' => "CREATE TABLE `" . PSM_DB_PREFIX . "log` (
`log_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `log_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL, `server_id` int(11) unsigned NOT NULL,
`type` enum('status','email','sms','pushover','telegram') NOT NULL, `type` enum('status','email','sms','discord','pushover','webhook','telegram', 'jabber') NOT NULL,
`message` TEXT NOT NULL, `message` TEXT NOT NULL,
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP, `datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`log_id`) PRIMARY KEY (`log_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'log_users' => "CREATE TABLE `" . PSM_DB_PREFIX . "log_users` ( PSM_DB_PREFIX . 'log_users' => "CREATE TABLE `" . PSM_DB_PREFIX . "log_users` (
@ -236,41 +253,46 @@ class Installer
PRIMARY KEY (`log_id`, `user_id`) PRIMARY KEY (`log_id`, `user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "servers` ( PSM_DB_PREFIX . 'servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "servers` (
`server_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `server_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(500) NOT NULL, `ip` varchar(500) NOT NULL,
`port` int(5) NOT NULL, `port` int(5) NOT NULL,
`request_method` varchar(50) NULL, `request_method` varchar(50) NULL,
`label` varchar(255) NOT NULL, `label` varchar(255) NOT NULL,
`type` enum('ping','service','website') NOT NULL default 'service', `type` enum('ping','service','website') NOT NULL default 'service',
`pattern` varchar(255) NOT NULL default '', `pattern` varchar(255) NOT NULL default '',
`pattern_online` enum('yes','no') NOT NULL default 'yes', `pattern_online` enum('yes','no') NOT NULL default 'yes',
`post_field` varchar(255) NULL, `post_field` varchar(255) NULL,
`redirect_check` enum('ok','bad') NOT NULL default 'bad', `redirect_check` enum('ok','bad') NOT NULL default 'bad',
`allow_http_status` varchar(255) NOT NULL default '', `allow_http_status` varchar(255) NOT NULL default '',
`header_name` varchar(255) NOT NULL default '', `header_name` varchar(255) NOT NULL default '',
`header_value` varchar(255) NOT NULL default '', `header_value` varchar(255) NOT NULL default '',
`status` enum('on','off') NOT NULL default 'on', `status` enum('on','off') NOT NULL default 'on',
`error` varchar(255) NULL, `error` varchar(255) NULL,
`rtime` FLOAT(9, 7) NULL, `rtime` FLOAT(9, 7) NULL,
`last_online` datetime NULL, `last_online` datetime NULL,
`last_offline` datetime NULL, `last_offline` datetime NULL,
`last_offline_duration` varchar(255) NULL, `last_offline_duration` varchar(255) NULL,
`last_check` datetime NULL, `last_check` datetime NULL,
`active` enum('yes','no') NOT NULL default 'yes', `active` enum('yes','no') NOT NULL default 'yes',
`email` enum('yes','no') NOT NULL default 'yes', `email` enum('yes','no') NOT NULL default 'yes',
`sms` enum('yes','no') NOT NULL default 'no', `sms` enum('yes','no') NOT NULL default 'no',
`pushover` enum('yes','no') NOT NULL default 'yes', `discord` enum('yes','no') NOT NULL default 'yes',
`telegram` enum('yes','no') NOT NULL default 'yes', `pushover` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1', `webhook` enum('yes','no') NOT NULL default 'yes',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0', `telegram` enum('yes','no') NOT NULL default 'yes',
`timeout` smallint(1) unsigned NULL DEFAULT NULL, `jabber` enum('yes','no') NOT NULL default 'yes',
`website_username` varchar(255) DEFAULT NULL, `warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`website_password` varchar(255) DEFAULT NULL, `warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`last_error` varchar(255) DEFAULT NULL, `ssl_cert_expiry_days` mediumint(1) unsigned NOT NULL DEFAULT '0',
`last_error_output` TEXT, `ssl_cert_expired_time` varchar(255) NULL,
`last_output` TEXT, `timeout` smallint(1) unsigned NULL DEFAULT NULL,
PRIMARY KEY (`server_id`) `website_username` varchar(255) DEFAULT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", `website_password` varchar(255) DEFAULT NULL,
`last_error` varchar(255) DEFAULT NULL,
`last_error_output` TEXT,
`last_output` TEXT,
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers_uptime' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` ( PSM_DB_PREFIX . 'servers_uptime' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` (
`servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL, `server_id` int(11) unsigned NOT NULL,
@ -281,14 +303,14 @@ class Installer
KEY `server_id` (`server_id`) KEY `server_id` (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers_history' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` ( PSM_DB_PREFIX . 'servers_history' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` (
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL, `server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL, `date` date NOT NULL,
`latency_min` float(9,7) NOT NULL, `latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL, `latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL, `latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL, `checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL, `checks_failed` int(11) unsigned NOT NULL,
PRIMARY KEY (`servers_history_id`), PRIMARY KEY (`servers_history_id`),
UNIQUE KEY `server_id_date` (`server_id`,`date`) UNIQUE KEY `server_id_date` (`server_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
@ -341,6 +363,9 @@ class Installer
if (version_compare($version_from, '3.4.2', '<')) { if (version_compare($version_from, '3.4.2', '<')) {
$this->upgrade342(); $this->upgrade342();
} }
if (version_compare($version_from, '3.5.0', '<')) {
$this->upgrade350();
}
if (version_compare($version_from, '3.6.0', '<')) { if (version_compare($version_from, '3.6.0', '<')) {
$this->upgrade360(); $this->upgrade360();
} }
@ -418,49 +443,49 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` CHANGE `user_id` `user_id` INT( 11 ) $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` CHANGE `user_id` `user_id` INT( 11 )
UNSIGNED NOT NULL AUTO_INCREMENT;"; UNSIGNED NOT NULL AUTO_INCREMENT;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `user_name` varchar(64) COLLATE utf8_general_ci NOT NULL ADD `user_name` varchar(64) COLLATE utf8_general_ci NOT NULL
COMMENT 'user\'s name, unique' AFTER `user_id`, COMMENT 'user\'s name, unique' AFTER `user_id`,
ADD `password` varchar(255) COLLATE utf8_general_ci NOT NULL ADD `password` varchar(255) COLLATE utf8_general_ci NOT NULL
COMMENT 'user\'s password in salted and hashed format' AFTER `user_name`, COMMENT 'user\'s password in salted and hashed format' AFTER `user_name`,
ADD `password_reset_hash` char(40) COLLATE utf8_general_ci DEFAULT NULL ADD `password_reset_hash` char(40) COLLATE utf8_general_ci DEFAULT NULL
COMMENT 'user\'s password reset code' AFTER `password`, COMMENT 'user\'s password reset code' AFTER `password`,
ADD `password_reset_timestamp` bigint(20) DEFAULT NULL ADD `password_reset_timestamp` bigint(20) DEFAULT NULL
COMMENT 'timestamp of the password reset request' AFTER `password_reset_hash`, COMMENT 'timestamp of the password reset request' AFTER `password_reset_hash`,
ADD `rememberme_token` varchar(64) COLLATE utf8_general_ci DEFAULT NULL ADD `rememberme_token` varchar(64) COLLATE utf8_general_ci DEFAULT NULL
COMMENT 'user\'s remember-me cookie token' AFTER `password_reset_timestamp`, COMMENT 'user\'s remember-me cookie token' AFTER `password_reset_timestamp`,
ADD `level` TINYINT( 2 ) UNSIGNED NOT NULL DEFAULT '20' AFTER `rememberme_token`;"; ADD `level` TINYINT( 2 ) UNSIGNED NOT NULL DEFAULT '20' AFTER `rememberme_token`;";
// make sure all current users are admins (previously we didnt have non-admins): // make sure all current users are admins (previously we didnt have non-admins):
$queries[] = "UPDATE `" . PSM_DB_PREFIX . "users` SET `user_name`=`email`, `level`=10;"; $queries[] = "UPDATE `" . PSM_DB_PREFIX . "users` SET `user_name`=`email`, `level`=10;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD UNIQUE `unique_username` ( `user_name` );"; $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD UNIQUE `unique_username` ( `user_name` );";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` ( $queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` (
`servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL, `server_id` int(11) unsigned NOT NULL,
`date` datetime NOT NULL, `date` datetime NOT NULL,
`status` tinyint(1) unsigned NOT NULL, `status` tinyint(1) unsigned NOT NULL,
`latency` float(9,7) DEFAULT NULL, `latency` float(9,7) DEFAULT NULL,
PRIMARY KEY (`servers_uptime_id`), PRIMARY KEY (`servers_uptime_id`),
KEY `server_id` (`server_id`) KEY `server_id` (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` ( $queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` (
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL, `server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL, `date` date NOT NULL,
`latency_min` float(9,7) NOT NULL, `latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL, `latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL, `latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL, `checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL, `checks_failed` int(11) unsigned NOT NULL,
PRIMARY KEY (`servers_history_id`), PRIMARY KEY (`servers_history_id`),
UNIQUE KEY `server_id_date` (`server_id`,`date`) UNIQUE KEY `server_id_date` (`server_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$queries[] = "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` ( $queries[] = "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` (
`user_id` INT( 11 ) UNSIGNED NOT NULL , `user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL , `server_id` INT( 11 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `user_id` , `server_id` ) PRIMARY KEY ( `user_id` , `server_id` )
) ENGINE = MYISAM ;"; ) ENGINE = MYISAM ;";
$this->execSQL($queries); $this->execSQL($queries);
// from 3.0 all user-server relations are in a separate table // from 3.0 all user-server relations are in a separate table
@ -512,11 +537,11 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `last_offline_duration` varchar(255) NULL;"; $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `last_offline_duration` varchar(255) NULL;";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` ( $queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
`user_id` int(11) unsigned NOT NULL, `user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL, `key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL, `value` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`, `key`) PRIMARY KEY (`user_id`, `key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$this->execSQL($queries); $this->execSQL($queries);
} }
@ -533,14 +558,14 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `website_username` varchar(255) NULL, $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `website_username` varchar(255) NULL,
ADD `website_password` varchar(255) NULL AFTER `website_username`;"; ADD `website_password` varchar(255) NULL AFTER `website_username`;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('proxy', '0'), ('proxy', '0'),
('proxy_url', ''), ('proxy_url', ''),
('proxy_user', ''), ('proxy_user', ''),
('proxy_password', '');"; ('proxy_password', '');";
$this->execSQL($queries); $this->execSQL($queries);
// Create log_users table // Create log_users table
$this->execSQL("CREATE TABLE `" . PSM_DB_PREFIX . "log_users` ( $this->execSQL("CREATE TABLE `" . PSM_DB_PREFIX . "log_users` (
`log_id` int(11) UNSIGNED NOT NULL , `log_id` int(11) UNSIGNED NOT NULL ,
`user_id` int(11) UNSIGNED NOT NULL , `user_id` int(11) UNSIGNED NOT NULL ,
@ -590,9 +615,9 @@ class Installer
"log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram' ) "log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram' )
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;"; CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('telegram_status', '0'), ('telegram_status', '0'),
('log_telegram', '1'), ('log_telegram', '1'),
('telegram_api_token', '');"; ('telegram_api_token', '');";
$this->execSQL($queries); $this->execSQL($queries);
} }
@ -646,7 +671,7 @@ class Installer
$this->execSQL($queries); $this->execSQL($queries);
$this->log('Combined notifications enabled. Check out the config page for more info.'); $this->log('Combined notifications enabled. Check out the config page for more info.');
} }
/** /**
* Patch for v3.4.2 release * Patch for v3.4.2 release
* Version_compare was forgotten in v3.4.1 and query failed. * Version_compare was forgotten in v3.4.1 and query failed.
@ -659,13 +684,80 @@ class Installer
$this->execSQL($queries); $this->execSQL($queries);
} }
protected function upgrade360() /**
* Upgrade for v3.5.0 release
*/
protected function upgrade350()
{ {
$queries = array(); $queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `ssl_cert_expiry_days` MEDIUMINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `warning_threshold_counter`";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `ssl_cert_expired_time` VARCHAR(255) NULL AFTER `ssl_cert_expiry_days`";
if (
@psm_password_decrypt(
psm_get_conf('password_encrypt_key'),
psm_get_conf('email_smtp_password')
) === false
) {
// Prevents encrypting the password multiple times.
$queries[] = "UPDATE `" . PSM_DB_PREFIX . "config`
SET `value` = '" .
psm_password_encrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('email_smtp_password')) .
"' WHERE `key` = 'email_smtp_password'";
$this->log('SMTP password is now encrypted.');
}
$queries[] = 'ALTER TABLE `' . PSM_DB_PREFIX . 'users` ADD `jabber` VARCHAR( 255 )
NOT NULL AFTER `telegram_id`;';
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `jabber` ENUM( 'yes','no' )
NOT NULL DEFAULT 'yes' AFTER `telegram`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX .
"log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram', 'jabber' )
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('jabber_status', '0'),
('log_jabber', '1'),
('jabber_host', ''),
('jabber_port', ''),
('jabber_username', ''),
('jabber_domain', ''),
('jabber_password', '');";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users` ( $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users` (
`user_name`, `level`, `name`, `email`) `user_name`, `level`, `name`, `email`)
VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')"; VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')";
$this->execSQL($queries); $this->execSQL($queries);
$this->log('Added user \'__PUBLIC__\'.'); $this->log('Added user \'__PUBLIC__\'.');
} }
/**
* Patch for v3.6.0 release
* Added support for Discord and webhooks
*/
protected function upgrade360()
{
$queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `webhook_url` VARCHAR( 255 ) NOT NULL AFTER `telegram_id`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `webhook_json` VARCHAR( 255 ) NOT NULL AFTER `telegram_id`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "log`
CHANGE `type` `type` ENUM('status','email','sms','discord','webhook','pushover','telegram','jabber')
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `webhook` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `telegram`;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('discord_status', '0'),
('log_discord', '1'),
('webhook_status', '0'),
('log_webhook', '1')";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `discord` VARCHAR( 255 ) NOT NULL AFTER `mobile`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `discord` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `sms`;";
$this->execSQL($queries);
}
} }

View File

@ -32,9 +32,9 @@ namespace psm\Util\Module;
class Modal implements ModalInterface class Modal implements ModalInterface
{ {
public const MODAL_TYPE_OK = 0; const MODAL_TYPE_OK = 0;
public const MODAL_TYPE_OKCANCEL = 1; const MODAL_TYPE_OKCANCEL = 1;
public const MODAL_TYPE_DANGER = 2; const MODAL_TYPE_DANGER = 2;
/** /**
* prefix used for modal dialog box elements * prefix used for modal dialog box elements
@ -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

@ -29,7 +29,10 @@
namespace psm\Util\Server; namespace psm\Util\Server;
use DateTime;
use psm\Service\Database; use psm\Service\Database;
use Twig\Error\Error;
use Twig_Environment;
/** /**
* History util, create HTML for server graphs * History util, create HTML for server graphs
@ -39,17 +42,17 @@ class HistoryGraph
/** /**
* Database service * Database service
* @var \psm\Service\Database $db; * @var Database $db;
*/ */
protected $db; protected $db;
/** /**
* Twig environment * Twig environment
* @var \Twig_Environment $twig * @var Twig_Environment $twig
*/ */
protected $twig; protected $twig;
public function __construct(Database $db, \Twig_Environment $twig) public function __construct(Database $db, Twig_Environment $twig)
{ {
$this->db = $db; $this->db = $db;
$this->twig = $twig; $this->twig = $twig;
@ -57,7 +60,9 @@ class HistoryGraph
/** /**
* Prepare the HTML for the graph * Prepare the HTML for the graph
* @return string * @param string $server_id ID of server to fetch data for
* @return string Created HTML
* @throws Error On twig error
*/ */
public function createHTML($server_id) public function createHTML($server_id)
{ {
@ -65,16 +70,16 @@ class HistoryGraph
$archive = new ArchiveManager($this->db); $archive = new ArchiveManager($this->db);
$archive->archive($server_id); $archive->archive($server_id);
$now = new \DateTime(); $now = new DateTime();
$last_week = new \DateTime('-1 week 0:0:0'); $last_week = new DateTime('-1 week 0:0:0');
$last_year = new \DateTime('-1 year -1 week 0:0:0'); $last_year = new DateTime('-1 year -1 week 0:0:0');
$graphs = array( $graphs = array(
0 => $this->generateGraphUptime($server_id, $last_week, $now), 0 => $this->generateGraphUptime($server_id, $last_week, $now),
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%%',
); );
@ -101,8 +106,8 @@ class HistoryGraph
/** /**
* Generate data for uptime graph * Generate data for uptime graph
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
public function generateGraphUptime($server_id, $start_time, $end_time) public function generateGraphUptime($server_id, $start_time, $end_time)
@ -112,9 +117,9 @@ class HistoryGraph
'latency' => array(), 'latency' => array(),
); );
$hour = new \DateTime('-1 hour'); $hour = new DateTime('-1 hour');
$day = new \DateTime('-1 day'); $day = new DateTime('-1 day');
$week = new \DateTime('-1 week'); $week = new DateTime('-1 week');
$records = $this->getRecords('uptime', $server_id, $start_time, $end_time); $records = $this->getRecords('uptime', $server_id, $start_time, $end_time);
@ -148,8 +153,8 @@ class HistoryGraph
/** /**
* Generate data for history graph * Generate data for history graph
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
public function generateGraphHistory($server_id, $start_time, $end_time) public function generateGraphHistory($server_id, $start_time, $end_time)
@ -160,9 +165,9 @@ class HistoryGraph
'latency_max' => array(), 'latency_max' => array(),
); );
$week = new \DateTime('-2 week 0:0:0'); $week = new DateTime('-2 week 0:0:0');
$month = new \DateTime('-1 month -1 week 0:0:0'); $month = new DateTime('-1 month -1 week 0:0:0');
$year = new \DateTime('-1 year -1 week 0:0:0'); $year = new DateTime('-1 year -1 week 0:0:0');
$records = $this->getRecords('history', $server_id, $year, $end_time); $records = $this->getRecords('history', $server_id, $year, $end_time);
@ -197,8 +202,8 @@ class HistoryGraph
* Get all uptime/history records for a server * Get all uptime/history records for a server
* @param string $type * @param string $type
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
protected function getRecords($type, $server_id, $start_time, $end_time) protected function getRecords($type, $server_id, $start_time, $end_time)
@ -207,17 +212,19 @@ class HistoryGraph
return array(); return array();
} }
$records = $this->db->execute( /** @noinspection SqlNoDataSourceInspection */
"SELECT * /** @noinspection SqlResolve */
/** @noinspection PhpUndefinedConstantInspection */
return $this->db->execute(
"SELECT *, UNIX_TIMESTAMP(CONVERT_TZ(`date`, '+00:00', @@session.time_zone)) AS date_ts
FROM `" . PSM_DB_PREFIX . "servers_$type` FROM `" . PSM_DB_PREFIX . "servers_$type`
WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date` ASC", WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date`",
array( array(
'server_id' => $server_id, 'server_id' => $server_id,
'start_time' => $start_time->format('Y-m-d H:i:s'), 'start_time' => $start_time->format('Y-m-d H:i:s'),
'end_time' => $end_time->format('Y-m-d H:i:s'), 'end_time' => $end_time->format('Y-m-d H:i:s'),
) )
); );
return $records;
} }
/** /**
@ -225,12 +232,9 @@ class HistoryGraph
* @param array $records All uptime records to parse, MUST BE SORTED BY DATE IN ASCENDING ORDER * @param array $records All uptime records to parse, MUST BE SORTED BY DATE IN ASCENDING ORDER
* @param array $lines Array with keys as line ids to prepare (key must be available in uptime records) * @param array $lines Array with keys as line ids to prepare (key must be available in uptime records)
* @param string $latency_avg_key which key from uptime records to use for calculating averages * @param string $latency_avg_key which key from uptime records to use for calculating averages
* @param \DateTime $start_time Lowest DateTime of the graph * @param DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param DateTime $end_time Highest DateTime of the graph
* @param boolean $add_uptime Add uptime calculation? * @param boolean $add_uptime Add uptime calculation?
* @param array $prev Previous result
* @param int $downtime Total downtime
* @param int $prev_downtime Timestamp from last offline record. 0 when last record is uptime
* @return array * @return array
*/ */
protected function generateGraphLines( protected function generateGraphLines(
@ -241,64 +245,90 @@ class HistoryGraph
$end_time, $end_time,
$add_uptime = false $add_uptime = false
) { ) {
$now = new \DateTime(); $now = new DateTime();
$data = array(); $data = array();
// PLEASE NOTE: all times are in microseconds! because of javascript. // PLEASE NOTE: all times are in microseconds! because of javascript.
$latency_avg = 0; $latency_avg = 0;
/** @var array $prev Previous record */
$prev = reset($records); $prev = reset($records);
// Timestamp from last offline record. 0 when last record is up.
$prev_downtime = 0; $prev_downtime = 0;
// Total downtime
$downtime = 0; $downtime = 0;
// The keys of the lines iterated
$line_keys = array_keys($lines);
// Determine whether to process data for the short history graph
$is_short_graph = count($line_keys) === 1 && $line_keys[0] === 'latency';
// get highest latency record for offline height
$highest_latency = 0.0;
if ($is_short_graph) {
foreach ($records as $record) {
$latency = (float) $record['latency'];
if ($latency > $highest_latency) {
$highest_latency = $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']);
// use the first line to calculate average latency // use the first line to calculate average latency
$latency_avg += (float) $record[$latency_avg_key]; $latency_avg += (float) $record[$latency_avg_key];
foreach ($lines as $key => $value) { if ($is_short_graph) {
// add the value for each of the different lines $time = (int) $record['date_ts'];
if (isset($record[$key])) { // Timestamp in milliseconds
if (isset($record['status'])) { $time_ms = $time * 1000;
// down if (!$record['status']) {
if ($record['status'] == 0) { // down
$lines['online'][] = $prev['status'] $lines['online'][] = $prev['status']
// Previous datapoint was online // Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] . '}' ? ['x' => $time_ms, 'y' => round($prev['latency'] * 1000, 3)]
// Previous datapoint was offline // Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y: null}'; : ['x' => $time_ms, 'y' => null];
// new outage start // new outage start
$lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:0.1}'; $lines['offline'][] = ['x' => $time_ms, 'y' => $highest_latency];
$prev_downtime != 0 ?: $prev_downtime = $time; if ($prev_downtime === 0) {
} else { $prev_downtime = $time;
// up
// outage ends
$lines['offline'][] = $prev['status']
// Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y:null}'
// Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y:0.1}';
$lines['online'][] = '{ x: ' . ($time * 1000) . ', y: ' .
round((float) $record[$key], 4) . '}';
$prev_downtime == 0 ?: $downtime += ($time - $prev_downtime);
$prev_downtime = 0;
}
} else {
$lines[$key][] = '{ x: \'' . $record['date'] . '\', y: ' . $record[$key] . '}';
} }
$prev = $record; } else {
// up
// outage ends
$lines['offline'][] = $prev['status']
// Previous datapoint was online
? ['x' => $time_ms, 'y' => null]
// Previous datapoint was offline
: ['x' => $time_ms, 'y' => $highest_latency];
$lines['online'][] = ['x' => $time_ms, 'y' => round($record['latency'] * 1000, 3)];
if ($prev_downtime !== 0) {
$downtime += ($time - $prev_downtime);
}
$prev_downtime = 0;
}
} else {
foreach ($line_keys as $key) {
// add the value for each of the different lines
$lines[$key][] = ['x' => $record['date'], 'y' => $record[$key] * 1000];
} }
} }
$prev = $record;
} }
// Was down before. // Was down before.
// 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}'; if (!$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()));
} }
@ -307,11 +337,12 @@ class HistoryGraph
if (empty($line_value)) { if (empty($line_value)) {
continue; continue;
} }
$lines_merged[$line_key]['value'] = implode(', ', $line_value); $lines_merged[$line_key]['value'] = json_encode($line_value);
$lines_merged[$line_key]['name'] = psm_get_lang('servers', $line_key); $lines_merged[$line_key]['name'] = psm_get_lang('servers', $line_key);
} }
$data['latency_avg'] = count($records) > 0 ? ($latency_avg / count($records)) : 0; $n_records = count($records);
$data['latency_avg'] = $n_records > 0 ? ($latency_avg / $n_records) : 0;
$data['lines'] = sizeof($lines_merged) ? $lines_merged : ''; $data['lines'] = sizeof($lines_merged) ? $lines_merged : '';
$data['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '') * 1000; $data['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '') * 1000;
$data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '') * 1000; $data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '') * 1000;

View File

@ -154,4 +154,18 @@ class ServerValidator
} }
return true; return true;
} }
/**
* Check SSL expiry days
* @param int $value
* @return boolean
* @throws \InvalidArgumentException
*/
public function sslCertExpiryDays($value)
{
if (!is_numeric($value) || $value < 0) {
throw new \InvalidArgumentException('server_ssl_cert_expiry_days');
}
return true;
}
} }

View File

@ -49,25 +49,31 @@ class UpdateManager implements ContainerAwareInterface
* Go :-) * Go :-)
* *
* @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated * @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated
* @param string|null $status If all servers (null), or just `on` or `off` should be checked.
*/ */
public function run($skip_perms = false) public function run($skip_perms = false, $status = null)
{ {
if (false === in_array($status, ['on', 'off'], true)) {
$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 = '';
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`.`webhook`,`s`.`telegram`,
FROM `" . PSM_DB_PREFIX . "servers` AS `s` `s`.`jabber`
{$sql_join} FROM `" . PSM_DB_PREFIX . "servers` AS `s`
WHERE `active`='yes' "; {$sql_join}
WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : '');
$servers = $this->container->get('db')->query($sql); $servers = $this->container->get('db')->query($sql);
@ -76,7 +82,8 @@ class UpdateManager implements ContainerAwareInterface
foreach ($servers as $server) { foreach ($servers as $server) {
$status_old = ($server['status'] == 'on') ? true : false; $status_old = ($server['status'] == 'on') ? true : false;
$status_new = $updater->update($server['server_id']); $status_new = $updater->
update($server['server_id']);
// notify the nerds if applicable // notify the nerds if applicable
$notifier->notify($server['server_id'], $status_old, $status_new); $notifier->notify($server['server_id'], $status_old, $status_new);
// clean-up time!! archive all records // clean-up time!! archive all records

View File

@ -33,6 +33,7 @@
* @see \psm\Util\Server\Updater\Autorun * @see \psm\Util\Server\Updater\Autorun
*/ */
namespace psm\Util\Server\Updater; namespace psm\Util\Server\Updater;
use Norgul\Xmpp\Options;
use psm\Service\Database; use psm\Service\Database;
class StatusNotifier class StatusNotifier
@ -56,18 +57,36 @@ class StatusNotifier
*/ */
protected $send_sms = false; protected $send_sms = false;
/**
* Send Discord notification?
* @var boolean $send_discord
*/
protected $send_discord = false;
/** /**
* Send Pushover notification? * Send Pushover notification?
* @var boolean $send_pushover * @var boolean $send_pushover
*/ */
protected $send_pushover = false; protected $send_pushover = false;
/**
* Send webhook notification?
* @var boolean $send_webhook
*/
protected $send_webhook = false;
/** /**
* Send telegram? * Send telegram?
* @var boolean $send_telegram * @var boolean $send_telegram
*/ */
protected $send_telegram = false; protected $send_telegram = false;
/**
* Send Jabber?
* @var bool
*/
protected $send_jabber = false;
/** /**
* Save log records? * Save log records?
* @var boolean $save_log * @var boolean $save_log
@ -119,12 +138,15 @@ class StatusNotifier
{ {
$this->db = $db; $this->db = $db;
$this->send_emails = psm_get_conf('email_status'); $this->send_emails = (bool)psm_get_conf('email_status');
$this->send_sms = psm_get_conf('sms_status'); $this->send_sms = (bool)psm_get_conf('sms_status');
$this->send_pushover = psm_get_conf('pushover_status'); $this->send_discord = (bool)psm_get_conf('discord_status');
$this->send_telegram = psm_get_conf('telegram_status'); $this->send_webhook = (bool)psm_get_conf('webhook_status');
$this->save_logs = psm_get_conf('log_status'); $this->send_pushover = (bool)psm_get_conf('pushover_status');
$this->combine = psm_get_conf('combine_notifications'); $this->send_telegram = (bool)psm_get_conf('telegram_status');
$this->send_jabber = (bool)psm_get_conf('jabber_status');
$this->save_logs = (bool)psm_get_conf('log_status');
$this->combine = (bool)psm_get_conf('combine_notifications');
} }
/** /**
@ -141,8 +163,11 @@ class StatusNotifier
if ( if (
!$this->send_emails && !$this->send_emails &&
!$this->send_sms && !$this->send_sms &&
!$this->send_discord &&
!$this->send_webhook &&
!$this->send_pushover && !$this->send_pushover &&
!$this->send_telegram && !$this->send_telegram &&
!$this->send_jabber &&
!$this->save_logs !$this->save_logs
) { ) {
// seems like we have nothing to do. skip the rest // seems like we have nothing to do. skip the rest
@ -166,8 +191,11 @@ class StatusNotifier
'error', 'error',
'email', 'email',
'sms', 'sms',
'discord',
'webhook',
'pushover', 'pushover',
'telegram', 'telegram',
'jabber',
'last_online', 'last_online',
'last_offline', 'last_offline',
'last_offline_duration', 'last_offline_duration',
@ -236,6 +264,18 @@ class StatusNotifier
$this->notifyByTxtMsg($users); $this->notifyByTxtMsg($users);
} }
// check if discord is enabled for this server
if ($this->send_discord && $this->server['discord'] == 'yes') {
// yay lets wake those nerds up!
$this->combine ? $this->setCombi('discord') : $this->notifyByDiscord($users);
}
// check if webhook is enabled for this server
if ($this->send_webhook && $this->server['webhook'] == 'yes') {
// yay lets wake those nerds up!
$this->combine ? $this->setCombi('webhook') : $this->notifyByWebhook($users);
}
// check if pushover is enabled for this server // check if pushover is enabled for this server
if ($this->send_pushover && $this->server['pushover'] == 'yes') { if ($this->send_pushover && $this->server['pushover'] == 'yes') {
// yay lets wake those nerds up! // yay lets wake those nerds up!
@ -247,6 +287,10 @@ class StatusNotifier
$this->combine ? $this->setCombi('telegram') : $this->notifyByTelegram($users); $this->combine ? $this->setCombi('telegram') : $this->notifyByTelegram($users);
} }
if ($this->send_jabber && $this->server['jaber'] == 'yes') {
$this->combine ? $this->setCombi('jabber') : $this->notifyByJabber($users);
}
return $notify; return $notify;
} }
@ -403,6 +447,86 @@ class StatusNotifier
} }
} }
/**
* This functions performs the discord notifications
*
* @param \PDOStatement $users
* @param array $combi contains message and subject (optional)
* @return void
*/
protected function notifyByDiscord($users, $combi = array())
{
$message_log = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'discord_message', $this->server);
// Remove users that have no Discord webhook
foreach ($users as $k => $user) {
if (trim($user['discord']) == '') {
unset($users[$k]);
}
}
// Validation
if (empty($users)) {
return;
}
// fix message for Discord viewing
$message = str_replace(array('<b>', '</b>'), array('**', '**'), $message_log);
$message = str_replace(array('<ul>', '</ul>'), array('', ''), $message);
$message = str_replace(array('<br>', '</li>'), array("\n", "\n"), $message);
$message = str_replace('<li>', " * ", $message);
$json = json_decode(
'{"content":""}',
true
);
$json['content'] = $message;
// Log
if (psm_get_conf('log_discord')) {
$log_id = psm_add_log($this->server_id, 'discord', $message_log);
}
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
// set discord webhook and send
try {
$msg = "payload_json=" . urlencode(json_encode($json));
$curl = curl_init(trim($user['discord']));
if(isset($curl)) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 204) {
// $result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result;
$error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_strerror($err) . ". \nResult: " . $result;
$log_id = psm_add_log($this->server_id, 'discord', $error);
}
curl_close($curl);
}
} catch (Exception $e) {
$log_id = psm_add_log($this->server_id, 'discord', $e->getMessage());
}
}
}
/** /**
* This functions performs the pushover notifications * This functions performs the pushover notifications
* *
@ -447,7 +571,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')) {
@ -468,7 +592,48 @@ class StatusNotifier
$pushover->send(); $pushover->send();
} }
} }
/**
* This functions performs the webhook notifications
*
* @param \PDOStatement $users
* @param array $combi contains message and subject (optional)
* @return void
*/
protected function notifyByWebhook($users, $combi = array())
{
foreach ($users as $k => $user) {
if (trim($user['webhook_url']) == '') {
unset($users[$k]);
}
}
$webhook = psm_build_webhook();
$message = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'webhook_message', $this->server);
$message = str_replace('<br/>', "\n", $message);
$message = str_replace('<br>', "\n", $message);
$title = key_exists('subject', $combi) ?
$combi['subject'] :
psm_parse_msg($this->status_new, 'webhook_title', $this->server);
// Log
if (psm_get_conf('log_webhook')) {
$log_id = psm_add_log($this->server_id, 'webhook', $message);
}
// send notifications to all users
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
$webhook->setUrl($user['webhook_url']);
$webhook->setJson($user['webhook_json']);
$webhook->sendWebhook($message);
}
}
/** /**
* This functions performs the text message notifications * This functions performs the text message notifications
* *
@ -548,6 +713,54 @@ class StatusNotifier
} }
} }
/**
* @param array $users
* @param array $combi
*/
protected function notifyByJabber($users, $combi = [])
{
// Remove users that have no jabber
foreach ($users as $k => $user) {
if (trim($user['jabber']) === '') {
unset($users[$k]);
}
}
// Validation
if (empty($users)) {
return;
}
// Message
$message = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'jabber_message', $this->server);
// Log
if (psm_get_conf('log_jabber')) {
$log_id = psm_add_log($this->server_id, 'jabber', $message);
}
$usersJabber = [];
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
$usersJabber[] = $user['jabber'];
}
// Jabber
psm_jabber_send_message(
psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
$usersJabber,
$message,
(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)
);
}
/** /**
* Get all users for the provided server id * Get all users for the provided server id
* @param int $server_id * @param int $server_id
@ -556,15 +769,16 @@ class StatusNotifier
public function getUsers($server_id) public function getUsers($server_id)
{ {
// find all the users with this server listed // find all the users with this server listed
$users = $this->db->query(" $users = $this->db->query('
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`.`discord`, `u`.`webhook_url`,`u`.`webhook_json`,
`u`.`pushover_device`, `u`.`telegram_id` `u`.`pushover_device`, `u`.`telegram_id`,
FROM `" . PSM_DB_PREFIX . "users` AS `u` `u`.`jabber`
JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON ( FROM `' . PSM_DB_PREFIX . 'users` AS `u`
`us`.`user_id`=`u`.`user_id` JOIN `' . PSM_DB_PREFIX . "users_servers` AS `us` ON (
AND `us`.`server_id` = {$server_id} `us`.`user_id`=`u`.`user_id`
) AND `us`.`server_id` = {$server_id}
"); )
");
return $users; return $users;
} }
} }

View File

@ -41,6 +41,8 @@ class StatusUpdater
public $header = ''; public $header = '';
public $curl_info = '';
public $rtime = 0; public $rtime = 0;
public $status_new = false; public $status_new = false;
@ -86,7 +88,8 @@ class StatusUpdater
$this->server_id = $server_id; $this->server_id = $server_id;
$this->error = ''; $this->error = '';
$this->header = ''; $this->header = '';
$this->rtime = ''; $this->curl_info = '';
$this->rtime = 0;
// get server info from db // get server info from db
$this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array( $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
@ -96,7 +99,7 @@ class StatusUpdater
'type', 'pattern', 'pattern_online', 'post_field', 'type', 'pattern', 'pattern_online', 'post_field',
'allow_http_status', 'redirect_check', 'header_name', 'allow_http_status', 'redirect_check', 'header_name',
'header_value', 'status', 'active', 'warning_threshold', 'header_value', 'status', 'active', 'warning_threshold',
'warning_threshold_counter', 'timeout', 'website_username', 'warning_threshold_counter', 'ssl_cert_expiry_days', 'ssl_cert_expired_time', 'timeout', 'website_username',
'website_password', 'last_offline' 'website_password', 'last_offline'
)); ));
if (empty($this->server)) { if (empty($this->server)) {
@ -165,40 +168,26 @@ class StatusUpdater
} }
/** /**
* Check the current servers ping status - Code from http://stackoverflow.com/a/20467492 * Check the current servers ping status
* @param int $max_runs * @param int $max_runs
* @param int $run * @param int $run
* @return boolean * @return boolean
*/ */
protected function updatePing($max_runs, $run = 1) protected function updatePing($max_runs, $run = 1)
{ {
// save response time // Settings
$starttime = microtime(true); $max_runs = ($max_runs == null || $max_runs > 1) ? 1 : $max_runs;
// set ping payload $server_ip = escapeshellcmd($this->server['ip']);
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost"; $os_is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
$socket = socket_create(AF_INET, SOCK_RAW, 1); $status = $os_is_windows ?
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0)); $this->pingFromWindowsMachine($server_ip, $max_runs) :
socket_connect($socket, $this->server['ip'], null); $this->pingFromNonWindowsMachine($server_ip, $max_runs);
socket_send($socket, $package, strLen($package), 0);
if (socket_read($socket, 255)) {
$status = true;
} else {
$status = false;
// set error message
$errorcode = socket_last_error();
$this->error = "Couldn't create socket [" . $errorcode . "]: " . socket_strerror($errorcode);
}
$this->rtime = microtime(true) - $starttime;
socket_close($socket);
// check if server is available and rerun if asked. // check if server is available and rerun if asked.
if (!$status && $run < $max_runs) { if (!$status && $run < $max_runs) {
return $this->updatePing($max_runs, $run + 1); return $this->updatePing($max_runs, $run + 1);
} }
return $status; return $status;
} }
@ -216,7 +205,11 @@ class StatusUpdater
// save response time // save response time
$starttime = microtime(true); $starttime = microtime(true);
$fp = @fsockopen($this->server['ip'], $this->server['port'], $errno, $this->error, $timeout); $serverIp = $this->server['ip'];
if (filter_var($serverIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
$serverIp = "[$serverIp]";
}
$fp = @fsockopen($serverIp, $this->server['port'], $errno, $this->error, $timeout);
$status = ($fp === false) ? false : true; $status = ($fp === false) ? false : true;
$this->rtime = (microtime(true) - $starttime); $this->rtime = (microtime(true) - $starttime);
@ -257,12 +250,13 @@ class StatusUpdater
$this->server['request_method'], $this->server['request_method'],
$this->server['post_field'] $this->server['post_field']
); );
$this->header = $curl_result; $this->header = $curl_result['exec'];
$this->curl_info = $curl_result['info'];
$this->rtime = (microtime(true) - $starttime); $this->rtime = (microtime(true) - $starttime);
// the first line would be the status code.. // the first line would be the status code..
$status_code = strtok($curl_result, "\r\n"); $status_code = strtok($curl_result['exec'], "\r\n");
// keep it general // keep it general
// $code[2][0] = status code // $code[2][0] = status code
// $code[3][0] = name of status code // $code[3][0] = name of status code
@ -293,7 +287,7 @@ class StatusUpdater
($this->server['pattern_online'] == 'yes') == ($this->server['pattern_online'] == 'yes') ==
!preg_match( !preg_match(
"/{$this->server['pattern']}/i", "/{$this->server['pattern']}/i",
$curl_result $curl_result['exec']
) )
) { ) {
$this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " . $this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " .
@ -308,7 +302,7 @@ class StatusUpdater
$location_matches = array(); $location_matches = array();
preg_match( preg_match(
'/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/', '/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/',
$curl_result, $curl_result['exec'],
$location_matches $location_matches
); );
if (!empty($location_matches)) { if (!empty($location_matches)) {
@ -329,7 +323,7 @@ class StatusUpdater
if ($this->server['header_name'] != '' && $this->server['header_value'] != '') { if ($this->server['header_name'] != '' && $this->server['header_value'] != '') {
$header_flag = false; $header_flag = false;
// Only get the header text if the result also includes the body // Only get the header text if the result also includes the body
$header_text = substr($curl_result, 0, strpos($curl_result, "\r\n\r\n")); $header_text = substr($curl_result['exec'], 0, strpos($curl_result['exec'], "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) { foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0 || strpos($line, ':') == false) { if ($i === 0 || strpos($line, ':') == false) {
continue; // We skip the status code & other non-header lines. Needed for proxy or redirects continue; // We skip the status code & other non-header lines. Needed for proxy or redirects
@ -356,6 +350,11 @@ class StatusUpdater
} }
} }
// Check ssl cert just when other error is not already in...
if ($result !== false) {
$this->checkSsl($this->server, $this->error, $result);
}
// check if server is available and rerun if asked. // check if server is available and rerun if asked.
if (!$result && $run < $max_runs) { if (!$result && $run < $max_runs) {
return $this->updateWebsite($max_runs, $run + 1); return $this->updateWebsite($max_runs, $run + 1);
@ -383,4 +382,129 @@ class StatusUpdater
{ {
return $this->rtime; return $this->rtime;
} }
/**
* Check if a server speaks SSL and if the certificate is not expired.
* @param string $error
* @param bool $result
*/
private function checkSsl($server, &$error, &$result)
{
if (version_compare(PHP_VERSION, '7.1', '<')) {
$error = "The server you're running PSM on must use PHP 7.1 or higher to test the SSL expiration.";
return;
}
if (
!empty($this->curl_info['certinfo']) &&
$server['ssl_cert_expiry_days'] > 0
) {
$certinfo = reset($this->curl_info['certinfo']);
$certinfo = openssl_x509_parse($certinfo['Cert']);
$cert_expiration_date = $certinfo['validTo_time_t'];
$expiration_time =
round((int)($cert_expiration_date - time()) / 86400);
$latest_time = time() + (86400 * $server['ssl_cert_expiry_days']);
if ($expiration_time - $server['ssl_cert_expiry_days'] < 0) {
// Cert is not expired, but date is withing user set range
$this->header = psm_get_lang('servers', 'ssl_cert_expiring') . " " .
psm_date($this->curl_info['certinfo'][0]['Expire date']) .
"\n\n" . $this->header;
$save['ssl_cert_expired_time'] = $expiration_time - $server['ssl_cert_expiry_days'];
} elseif ($expiration_time >= 0) {
// Cert is not expired
$save['ssl_cert_expired_time'] = null;
} else {
// Cert is expired
$error = psm_get_lang('servers', 'ssl_cert_expired') . " " .
psm_timespan($cert_expiration_date) . ".\n\n" .
$error;
$save['ssl_cert_expired_time'] = $expiration_time;
}
$this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id));
}
}
/**
* Ping from a Windows Machine
* @param string $server_id
* @param int $max_runs
* @return boolean
*/
private function pingFromWindowsMachine($server_ip, $max_runs)
{
// Windows / Linux variant: use socket on Windows, commandline on Linux
// socket ping - Code from http://stackoverflow.com/a/20467492
// save response time
$starttime = microtime(true);
// set ping payload
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
$socket = socket_create(AF_INET, SOCK_RAW, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0));
socket_connect($socket, $server_ip, null);
socket_send($socket, $package, strLen($package), 0);
// socket_read returns a string or false
$status = socket_read($socket, 255) !== false ? true : false;
if ($status) {
$this->header = "Success.";
} else {
$this->error = "Couldn't create socket [" . $errorcode . "]: " . socket_strerror(socket_last_error());
}
$this->rtime = microtime(true) - $starttime;
socket_close($socket);
return $status;
}
/**
* Ping from a non Windows Machine
* @param string $server_id
* @param int $max_runs
* @param string $ping_command
* @return boolean
*/
private function pingFromNonWindowsMachine($server_ip, $max_runs)
{
// Choose right ping version, ping6 for IPV6, ping for IPV4
$ping_command = filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false ? 'ping6' : 'ping';
// execute PING
exec($ping_command . " -c " . $max_runs . " " . $server_ip . " 2>&1", $output);
// 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);
// Converted to milliseconds
$this->rtime = floatval($result[0][1]) / 1000;
$this->header = "";
foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
return true;
}
$this->header = "-";
foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
$this->error = $output[count($output) - 2];
return false;
}
} }

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>
@ -74,7 +76,7 @@
</footer> </footer>
{% endblock %} {% endblock %}
{% endif %} {% endif %}
<script src="src/templates/default/static/plugin/jquery/jquery-3.3.1.min.js"></script> <script src="src/templates/default/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<script src="src/templates/default/static/plugin/popper.js/popper.min.js"></script> <script src="src/templates/default/static/plugin/popper.js/popper.min.js"></script>
<script src="src/templates/default/static/plugin/bootstrap/js/dist/index.js"></script> <script src="src/templates/default/static/plugin/bootstrap/js/dist/index.js"></script>
<script src="src/templates/default/static/plugin/bootstrap/js/dist/util.js"></script> <script src="src/templates/default/static/plugin/bootstrap/js/dist/util.js"></script>
@ -87,7 +89,8 @@
<script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/bootstrap-select.min.js"></script> <script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/bootstrap-select.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/i18n/defaults-{{ language }}.min.js"></script> <script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/i18n/defaults-{{ language }}.min.js"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/solid.min.js"></script> <script defer src="src/templates/default/static/plugin/font-awesome/js/solid.min.js"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/fontawesome.min.js" data-auto-replace-svg="nest"></script> <script defer src="src/templates/default/static/plugin/font-awesome/js/fontawesome.min.js" data-auto-replace-svg="nest"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/brands.min.js" data-auto-replace-svg="nest"></script>
<script type="text/javascript" src="src/templates/default/static/js/scripts.js"></script> <script type="text/javascript" src="src/templates/default/static/js/scripts.js"></script>
</body> </body>

View File

@ -27,6 +27,21 @@
role="tab" aria-controls="config-telegram" aria-selected="{% if telegram_active %}true{% else %}false{% endif %}">{{ role="tab" aria-controls="config-telegram" aria-selected="{% if telegram_active %}true{% else %}false{% endif %}">{{
label_tab_telegram }}</a> label_tab_telegram }}</a>
</li> </li>
<li class="nav-item">
<a class="nav-link {{ jabber_active }}" id="config-jabber-tab" data-toggle="tab" href="#config-jabber"
role="tab" aria-controls="config-jabber" aria-selected="{% if jabber_active %}true{% else %}false{% endif %}">{{
label_tab_jabber }}</a>
</li>
<li class="nav-item">
<a class="nav-link {{ discord_active }}" id="config-discord-tab" data-toggle="tab" href="#config-discord" role="tab"
aria-controls="config-discord" aria-selected="{% if discord_active %}true{% else %}false{% endif %}">{{
label_tab_discord }}</a>
</li>
<li class="nav-item">
<a class="nav-link {{ webhook_active }}" id="config-webhook-tab" data-toggle="tab" href="#config-webhook" role="tab"
aria-controls="config-webhook" aria-selected="{% if webhook_active %}true{% else %}false{% endif %}">{{
label_tab_webhook }}</a>
</li>
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content"> <div class="tab-content">
@ -36,6 +51,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 -->
@ -43,6 +60,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>
@ -99,7 +118,7 @@
<!-- email user --> <!-- email user -->
{{ macro.input_field("text", "email_smtp_username", null, "email_smtp_username", label_email_smtp_username, email_smtp_username, label_email_smtp_username, "255") }} {{ macro.input_field("text", "email_smtp_username", null, "email_smtp_username", label_email_smtp_username, email_smtp_username, label_email_smtp_username, "255") }}
<!-- email password --> <!-- email password -->
{{ macro.input_field("password", "email_smtp_password", null, "email_smtp_password", label_email_smtp_password, email_smtp_password, label_email_smtp_password, "255", null, null, null, true) }} {{ macro.input_field("password", "email_smtp_password", null, "email_smtp_password", label_email_smtp_password, email_smtp_password, label_leave_blank, "255", null, null, null, true) }}
{{ macro.button_test("testEmail", label_test) }} {{ macro.button_test("testEmail", label_test) }}
{{ macro.input_hidden("test_email", "0") }} {{ macro.input_hidden("test_email", "0") }}
{{ macro.button_save("email_submit", label_save) }} {{ macro.button_save("email_submit", label_save) }}
@ -120,15 +139,28 @@
{{ macro.input_field("text", "sms_gateway_password", null, "sms_gateway_password", label_sms_gateway_password, sms_gateway_password, label_sms_gateway_password, "255") }} {{ macro.input_field("text", "sms_gateway_password", null, "sms_gateway_password", label_sms_gateway_password, sms_gateway_password, label_sms_gateway_password, "255") }}
<!-- sms sender number--> <!-- sms sender number-->
{{ macro.input_field("text", "sms_from", null, "sms_from", label_sms_from, sms_from, "+31123456789", "255") }} {{ macro.input_field("text", "sms_from", null, "sms_from", label_sms_from, sms_from, "+31123456789", "255") }}
{{ macro.button_test("testSms", label_test) }} {{ macro.button_test("testSms", label_test) }}
{{ macro.input_hidden("test_sms", "0") }} {{ macro.input_hidden("test_sms", "0") }}
{{ macro.button_save("sms_submit", label_save) }} {{ macro.button_save("sms_submit", label_save) }}
</fieldset> </fieldset>
</div> </div>
<div class="tab-pane {{ pushover_active }}" id="config-pushover" role="tabpanel" aria-labelledby="config-telegram-tab"> <div class="tab-pane {{ discord_active }}" id="config-discord" role="tabpanel" aria-labelledby="config-discord-tab">
<fieldset>
<legend>{{ label_settings_discord }}</legend>
<!-- enable discord -->
{{ macro.input_checkbox("discord_status", "discord_status[]", label_discord_status, discord_status_checked) }}
<!-- enable discord log -->
{{ macro.input_checkbox("log_discord", "log_discord[]", label_log_discord, log_discord_checked) }}
{{ macro.button_test("testDiscord", label_test) }}
{{ macro.input_hidden("test_discord", "0") }}
{{ macro.button_save("discord_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ pushover_active }}" id="config-pushover" role="tabpanel" aria-labelledby="config-pushover-tab">
<fieldset> <fieldset>
<legend>{{ label_settings_pushover }}</legend> <legend>{{ label_settings_pushover }}</legend>
<p>{{ label_pushover_description|raw }}</p>
<!-- enable pushover --> <!-- enable pushover -->
{{ macro.input_checkbox("pushover_status", "pushover_status", label_pushover_status, pushover_status_checked) }} {{ macro.input_checkbox("pushover_status", "pushover_status", label_pushover_status, pushover_status_checked) }}
<!-- enable pushover log --> <!-- enable pushover log -->
@ -140,9 +172,10 @@
{{ macro.button_save("pushover_submit", label_save) }} {{ macro.button_save("pushover_submit", label_save) }}
</fieldset> </fieldset>
</div> </div>
<div class="tab-pane {{ telegram_active }}" id="config-telegram" role="tabpanel" aria-labelledby="config-pushover-tab"> <div class="tab-pane {{ telegram_active }}" id="config-telegram" role="tabpanel" aria-labelledby="config-telegram-tab">
<fieldset> <fieldset>
<legend>{{ label_settings_telegram }}</legend> <legend>{{ label_settings_telegram }}</legend>
<p>{{ label_telegram_description|raw }}</p>
<!-- enable telegram --> <!-- enable telegram -->
{{ macro.input_checkbox("telegram_status", "telegram_status[]", label_telegram_status, telegram_status_checked) }} {{ macro.input_checkbox("telegram_status", "telegram_status[]", label_telegram_status, telegram_status_checked) }}
<!-- enable telegram log --> <!-- enable telegram log -->
@ -154,6 +187,42 @@
{{ macro.button_save("telegram_submit", label_save) }} {{ macro.button_save("telegram_submit", label_save) }}
</fieldset> </fieldset>
</div> </div>
<div class="tab-pane {{ jabber_active }}" id="config-jabber" role="tabpanel" aria-labelledby="config-jabber-tab">
<fieldset>
<legend>{{ label_settings_jabber }}</legend>
<!-- enable jabber -->
{{ macro.input_checkbox("jabber_status", "jabber_status[]", label_jabber_status, jabber_status_checked) }}
<!-- enable jabber log -->
{{ macro.input_checkbox("log_jabber", "log_jabber[]", label_log_jabber, log_jabber_checked) }}
<!-- jabber settings -->
{{ macro.input_field("text", "jabber_host", null, "jabber_host", label_jabber_host, jabber_host, label_jabber_host, "255", "jabber_host_help", label_jabber_host_description) }}
{{ macro.input_field("number", "jabber_port", null, "jabber_port", label_jabber_port, jabber_port, label_jabber_port, "255", "jabber_port_help", label_jabber_port_description) }}
{{ macro.input_field("text", "jabber_username", null, "jabber_username", label_jabber_username, jabber_username, label_jabber_username, "255", 'jabber_username_help', label_jabber_username_description) }}
{{ macro.input_field("text", "jabber_domain", null, "jabber_domain", label_jabber_domain, jabber_domain, label_jabber_domain, "255", "jabber_domain_help", label_jabber_domain_description) }}
{{ macro.input_field("password", "jabber_password", null, "jabber_password", label_jabber_password, jabber_password, label_jabber_password, "255", "jabber_password_help", label_jabber_password_description) }}
{{ macro.button_test("testJabber", label_test) }}
{{ macro.input_hidden("test_jabber", "0") }}
{{ macro.button_save("jabber_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ webhook_active }}" id="config-webhook" role="tabpanel" aria-labelledby="config-webhook-tab">
<fieldset>
<legend>{{ label_settings_webhook }}</legend>
<p>{{ label_webhook_description|raw }}</p>
<!-- enable webhooks -->
{{ macro.input_checkbox("webhook_status", "webhook_status", label_webhook_status, webhook_status_checked) }}
<!-- enable webhook log -->
{{ macro.input_checkbox("log_webhook", "log_webhook", label_log_webhook, log_webhook_checked) }}
<!-- webhook url -->
<!-- {{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, webhook_url, label_webhook_url, "255", "webhook_url_help", label_webhook_url_description) }} -->
<!-- webhook json -->
<!-- {{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, webhook_json, label_webhook_json, "255", "webhook_json_help", label_webhook_json_description) }} -->
{{ macro.button_test("testWebhook", label_test) }}
{{ macro.input_hidden("test_webhook", "0") }}
{{ macro.button_save("webhook_submit", label_save) }}
</fieldset>
</div>
</div> </div>
{{ macro.input_csrf() }} {{ macro.input_csrf() }}
</form> </form>

View File

@ -12,8 +12,8 @@
If no errors have occurred, you are good to go.</p> If no errors have occurred, you are good to go.</p>
<div class="w-100 mb-4"></div> <div class="w-100 mb-4"></div>
<a class="btn btn-primary btn-lg" href="index.php">Go to your monitor</a> <a class="btn btn-primary btn-lg" href="index.php">Go to your monitor</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://www.phpservermonitor.org/">PHP Server Monitor</a> <a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://www.phpservermonitor.org/ " target="_blank">PHP Server Monitor</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://docs.phpservermonitor.org/">Documentation</a> <a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://docs.phpservermonitor.org/" target="_blank">Documentation</a>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,7 @@
<script type="text/javascript" src="src/templates/default/static/plugin/momentjs/moment.js"></script> <script type="text/javascript" src="src/templates/default/static/plugin/momentjs/moment.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/chartjs/chart-2.7.3.min.js"></script> <script type="text/javascript" src="src/templates/default/static/plugin/chartjs/chart-2.7.3.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/hammer/hammer.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/chartjs/plugin-zoom.min.js"></script>
{% for graph in graphs %} {% for graph in graphs %}
<div class="chart-container col-10" style="position: relative; width:60vw"> <div class="chart-container col-10" style="position: relative; width:60vw">
<canvas id="{{ graph.id }}">Your browser does not support the canvas element.</canvas> <canvas id="{{ graph.id }}">Your browser does not support the canvas element.</canvas>
@ -20,7 +22,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' %}
@ -30,7 +32,7 @@
data: { data: {
datasets: [ datasets: [
{ {
data: [{{ graph.lines.offline.value }}], data: {{ graph.lines.offline.value|raw }},
label: '{{ graph.lines.offline.name }}', label: '{{ graph.lines.offline.name }}',
backgroundColor: '#dc3545', backgroundColor: '#dc3545',
borderColor: '#dc3545', borderColor: '#dc3545',
@ -41,7 +43,7 @@
spanGaps: false, spanGaps: false,
}, },
{ {
data: [{{ graph.lines.online.value }}], data: {{ graph.lines.online.value|raw }},
label: '{{graph.lines.online.name }}', label: '{{graph.lines.online.name }}',
fill: false, fill: false,
spanGaps: false, spanGaps: false,
@ -72,6 +74,25 @@
source: 'auto', source: 'auto',
} }
}] }]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
},
zoom: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
speed: 0.05,
}
}
} }
} }
}); });
@ -99,7 +120,7 @@
datasets: [ datasets: [
{% for key,line in graph.lines %} {% for key,line in graph.lines %}
{ {
data: [{{ line.value|raw }}], data: {{ line.value|raw }},
label: '{{ line.name }}', label: '{{ line.name }}',
backgroundColor: colors['{{key}}'], backgroundColor: colors['{{key}}'],
borderColor: colors['{{key}}'], borderColor: colors['{{key}}'],
@ -133,6 +154,25 @@
source: 'auto', source: 'auto',
} }
}] }]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
},
zoom: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
speed: 0.05,
}
}
} }
} }
}); });

View File

@ -5,17 +5,17 @@
<thead> <thead>
<tr> <tr>
<!--class="d-none d-lg-table-cell"--> <!--class="d-none d-lg-table-cell"-->
<th scope="col">{{ label_label }}</th> <th scope="col">{{ label_label }}</th>
<th scope="col">{{ label_domain }}</th> <th scope="col">{{ label_domain }}</th>
<th scope="col">{{ label_port }}</th> <th scope="col" style="width: 5%;">{{ label_port }}</th>
<th scope="col">{{ label_type }}</th> <th scope="col" style="width: 8%;">{{ label_type }}</th>
<th scope="col">{{ label_rtime }}</th> <th scope="col" style="width: 8%;">{{ label_rtime }} (ms)</th>
<th scope="col">{{ label_last_online }}</th> <th scope="col" style="width: 10%;">{{ label_last_online }}</th>
<th scope="col">{{ label_last_offline }}</th> <th scope="col" style="width: 10%;">{{ label_last_offline }}</th>
<th scope="col">{{ label_monitoring }}</th> <th scope="col" style="width: 10%;">{{ label_monitoring }}</th>
{% if user_level == 10 %} {% if user_level == 10 %}
<th scope="col">&#32</th> <th scope="col" style="width: 5%;">&#32</th>
{% endif %} {% endif %}
</tr> </tr>
<tr class="warning no-result"> <tr class="warning no-result">
<td colspan="9"><i class="fas fa-exclamation-triangle"></i> No result</td> <td colspan="9"><i class="fas fa-exclamation-triangle"></i> No result</td>
@ -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>
@ -50,24 +50,36 @@
{% else %} {% else %}
<i class="fas fa-eye-slash" title="{{ server.active_title }}"></i> <i class="fas fa-eye-slash" title="{{ server.active_title }}"></i>
{% endif %} {% endif %}
{% if server.email|lower == 'yes'%} {% if server.email|lower == 'yes' and config.email|lower%}
<i class="fas fa-envelope" title="{{ label_email }}"></i> <i class="fas fa-envelope" title="{{ label_email }}"></i>
{% endif %} {% endif %}
{% if server.sms|lower == 'yes'%} {% if server.sms|lower == 'yes' and config.sms|lower%}
<i class="fas fa-sms" title="{{ label_sms }}"></i> <i class="fas fa-sms" title="{{ label_sms }}"></i>
{% endif %} {% endif %}
{% if server.pushover|lower == 'yes'%} {% if server.pushover|lower == 'yes'and config.pushover|lower %}
<span class="fa-layers"> <span class="fa-layers">
<i class="fas fa-circle" title="{{ label_pushover }}"></i> <i class="fas fa-circle" title="{{ label_pushover }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">P</span> <span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">P</span>
</span> </span>
{% endif %} {% endif %}
{% if server.telegram|lower == 'yes'%} {% if server.telegram|lower == 'yes' and config.telegram|lower%}
<span class="fa-layers"> <i class="fab fa-telegram" title="{{ label_telegram }}"></i>
<i class="fas fa-circle" title="{{ label_telegram }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">T</span>
</span>
{% endif %} {% endif %}
{% if server.jabber|lower == 'yes'%}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_jabber }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">J</span>
</span>
{% endif %}
{% if server.discord|lower == 'yes' and config.discord|lower %}
<i class="fab fa-discord" title="{{ label_discord }}"></i>
{% endif %}
{% if server.webhook|lower == 'yes' and config.webhook|lower %}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_webhook }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:600; font-size:55%">W</span>
</span>
{% endif %}
</td> </td>
{% if user_level == 10 %} {% if user_level == 10 %}
<td> <td>
@ -81,7 +93,7 @@
<i class="fas fa-edit"></i> {{ label_edit }} <i class="fas fa-edit"></i> {{ label_edit }}
</a> </a>
<a class="dropdown-item show-modal" href="{{ server.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete" <a class="dropdown-item show-modal" href="{{ server.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete"
data-modal-param="{{ server.server_name }}"> data-modal-param="{{ server.label }}">
<i class="fas fa-trash"></i> {{ label_delete }} <i class="fas fa-trash"></i> {{ label_delete }}
</a> </a>
</div> </div>

View File

@ -46,7 +46,9 @@
</select> </select>
</div> </div>
<!-- Custom port --> <!-- Custom port -->
{{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }} {{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }}
<!-- SSL Cert check -->
{{ macro.input_field("number", "ssl_cert_expiry_days", "types typeWebsite", "ssl_cert_expiry_days", label_ssl_cert_expiry_days, edit_value_ssl_cert_expiry_days, 0, "5", 'ssl_cert_help', label_ssl_cert_expiry_days_description) }}
<!-- Request method --> <!-- Request method -->
<div class="form-group types typeWebsite"> <div class="form-group types typeWebsite">
<label for="popular_request_methods">{{ label_request_method }}</label> <label for="popular_request_methods">{{ label_request_method }}</label>
@ -140,14 +142,32 @@
{{ macro.input_select_monitoring("pushover", "pushover", label_send_pushover, edit_pushover_selected, label_yes, label_no, warning_pushover, label_warning_pushover) }} {{ macro.input_select_monitoring("pushover", "pushover", label_send_pushover, edit_pushover_selected, label_yes, label_no, warning_pushover, label_warning_pushover) }}
<!-- Telegram --> <!-- Telegram -->
{{ macro.input_select_monitoring("telegram", "telegram", label_send_telegram, edit_telegram_selected, label_yes, label_no, warning_telegram, label_warning_telegram) }} {{ macro.input_select_monitoring("telegram", "telegram", label_send_telegram, edit_telegram_selected, label_yes, label_no, warning_telegram, label_warning_telegram) }}
<!-- Jabber -->
{{ macro.input_select_monitoring("jabber", "jabber", label_send_jabber, edit_jabber_selected, label_yes, label_no, warning_jabber, label_warning_jabber) }}
<!-- Discord -->
{{ macro.input_select_monitoring("discord", "discord", label_send_discord, edit_discord_selected, label_yes, label_no, warning_discord, label_warning_discord) }}
<!-- Webhook -->
{{ macro.input_select_monitoring("webhook", "webhook", label_send_webhook, edit_webhook_selected, label_yes, label_no, warning_webhook, label_warning_webhook) }}
</div> </div>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{{ label_fieldset_permissions }}</legend> <legend>{{ label_fieldset_permissions }}</legend>
<!-- Permissions --> <!-- Permissions -->
{{ macro.input_select_multiple("user_id", "user_id[]", label_permissions, label_search, users, label_please_select) }} {{ macro.input_select_multiple("user_id", "user_id[]", label_permissions, label_search, users, label_please_select) }}
{{ macro.button_save(null, label_save) }} </fieldset>
<a class="btn" href="{{ url_go_back|raw }}">{{ label_go_back }}</a> <fieldset>
</fieldset> <legend>{{ label_save }}</legend>
{{ macro.button_save(null, label_save) }}
<a class="btn" href="{{ url_go_back|raw }}">{{ label_go_back }}</a>
</fieldset>
{% if edit_server_id > 0 %}
<fieldset>
<legend class="mt-4">{{ label_delete }}</legend>
<a class="btn btn-danger show-modal" href="{{ url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete"
data-modal-param="{{ edit_value_label }}">
<i class="fas fa-trash"></i> {{ label_delete }}
</a>
</fieldset>
{% endif %}
{{ macro.input_csrf() }} {{ macro.input_csrf() }}
</form> </form>

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">
@ -27,7 +27,11 @@
<li class="list-group-item"> <li class="list-group-item">
<dl class="row"> <dl class="row">
<dt class="col-md-4">{{ label_domain }}:</dt> <dt class="col-md-4">{{ label_domain }}:</dt>
<dd class="col-md-8">{{ ip|raw }}</dd> <dd class="col-md-8">
<a href="{{ ip|raw }}" title="{{ ip|raw }}" target="_blank" rel="noopener">
{{ ip|raw }}
</a>
</dd>
</dl> </dl>
</li> </li>
{% if type|lower == 'service' %} {% if type|lower == 'service' %}
@ -47,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>
@ -227,13 +231,13 @@
<li class="list-group-item"> <li class="list-group-item">
<dl class="row"> <dl class="row">
<dt class="col-md-3">{{ label_last_error }}:</dt> <dt class="col-md-3">{{ label_last_error }}:</dt>
<dd class="col-md-9">{{ last_error }}</dd> <dd class="col-md-9">{{ last_error|nl2br }}</dd>
</dl> </dl>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<dl class="row"> <dl class="row">
<dt class="col-md-3">{{ label_last_output }}:</dt> <dt class="col-md-3">{{ label_last_output }}:</dt>
<dd class="col-md-9">{{ last_output_truncated }}</dd> <dd class="col-md-9">{{ last_output_truncated|nl2br }}</dd>
{% if last_output_truncated != last_output %} {% if last_output_truncated != last_output %}
<dt class="col-md-3"></dt> <dt class="col-md-3"></dt>
<dd class="col-md-9"> <dd class="col-md-9">
@ -247,7 +251,7 @@
<li class="list-group-item"> <li class="list-group-item">
<dl class="row"> <dl class="row">
<dt class="col-md-3">{{ label_last_error_output }}:</dt> <dt class="col-md-3">{{ label_last_error_output }}:</dt>
<dd class="col-md-9">{{ last_error_output_truncated }}</dd> <dd class="col-md-9">{{ last_error_output_truncated|nl2br }}</dd>
{% if last_error_output_truncated != last_error_output %} {% if last_error_output_truncated != last_error_output %}
<dt class="col-md-3"></dt> <dt class="col-md-3"></dt>
<dd class="col-md-9"> <dd class="col-md-9">
@ -305,6 +309,19 @@
<noscript>&#8263</noscript> <noscript>&#8263</noscript>
{% endif %} {% endif %}
</li> </li>
<li class="list-group-item">
{{ label_discord }}:
{% if discord|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif discord|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item"> <li class="list-group-item">
{{ label_pushover }}: {{ label_pushover }}:
{% if pushover|lower == 'yes' %} {% if pushover|lower == 'yes' %}
@ -331,12 +348,67 @@
<noscript>&#8263</noscript> <noscript>&#8263</noscript>
{% endif %} {% endif %}
</li> </li>
<li class="list-group-item">
{{ label_jabber }}:
{% if jabber|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif jabber|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item">
{{ label_webhook }}:
{% if webhook|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif webhook|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
</ul> </ul>
</div> </div>
</div> </div>
<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,13 +1,12 @@
{% 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">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<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">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></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">
<p class="card-text"> <p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br> {{ label_last_online }}: {{ server.last_online_nice }}<br>
@ -15,14 +14,12 @@
</p> </p>
</div> </div>
</div> </div>
<noscript></a></noscript>
</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">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<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">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></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">
<p class="card-text"> <p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br> {{ label_last_online }}: {{ server.last_online_nice }}<br>
@ -30,23 +27,20 @@
</p> </p>
</div> </div>
</div> </div>
<noscript></a></noscript>
</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">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<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">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></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>
<noscript></a></noscript>
</div> </div>
{% endfor %} {% endfor %}
{% if not servers_offline and not servers_warning and not servers_online %} {% if not servers_offline and not servers_warning and not servers_online %}
@ -72,7 +66,7 @@
<tbody> <tbody>
{% for server in servers_offline %} {% for server in servers_offline %}
<tr class="bg-danger text-white" onclick="window.location.href='{{ server.url_view|raw }}'"> <tr class="bg-danger text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></th> <th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></a></th>
<td>{{ server.last_online_nice }}</td> <td>{{ server.last_online_nice }}</td>
<td>{{ server.last_checked_nice }}</td> <td>{{ server.last_checked_nice }}</td>
<td></td> <td></td>
@ -80,7 +74,7 @@
{% endfor %} {% endfor %}
{% for server in servers_warning %} {% for server in servers_warning %}
<tr class="bg-warning text-white" onclick="window.location.href='{{ server.url_view|raw }}'"> <tr class="bg-warning text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></th> <th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></a></th>
<td>{{ server.last_online_nice }}</td> <td>{{ server.last_online_nice }}</td>
<td>{{ server.last_checked_nice }}</td> <td>{{ server.last_checked_nice }}</td>
<td></td> <td></td>
@ -100,10 +94,10 @@
<tbody> <tbody>
{% for server in servers_online %} {% for server in servers_online %}
<tr class="bg-success text-white" onclick="window.location.href='{{ server.url_view|raw }}'"> <tr class="bg-success text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></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>
@ -130,4 +124,4 @@ setInterval(function() {
}); });
}, {{ auto_refresh_seconds }} * 1000); }, {{ auto_refresh_seconds }} * 1000);
</script> </script>
{% endif %} {% endif %}

View File

@ -21,22 +21,44 @@
</fieldset> </fieldset>
<!-- Pushover settings --> <!-- Pushover settings -->
<fieldset> <fieldset>
<legend>{{ label_pushover }}</legend> <legend>{{ label_pushover }}</legend>
<p>{{ label_pushover_description|raw }}</p>
<!-- pushover key --> <!-- pushover key -->
{{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, pushover_key, label_pushover_key, "255", "pushover_key_help", pushover_key_description) }} {{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, pushover_key, label_pushover_key, "255", "pushover_key_help", label_pushover_key_description) }}
<!-- pushover device --> <!-- pushover device -->
{{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, pushover_device, label_pushover_device, "255", "pushover_device_help", pushover_device_description) }} {{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, pushover_device, label_pushover_device, "255", "pushover_device_help", label_pushover_device_description) }}
</fieldset> </fieldset>
<!-- Telegram settings --> <!-- Telegram settings -->
<fieldset> <fieldset>
<legend>{{ label_telegram }}</legend> <legend>{{ label_telegram }}</legend>
<p>{{ label_telegram_description|raw }}</p>
<!-- telegram id --> <!-- telegram id -->
<div class="form-group"> <div class="form-group">
<a class="btn btn-primary mb-2" href="{{ telegram_get_chat_id_url }}">{{ label_telegram_get_chat_id }}</a> <a class="btn btn-primary mb-2" href="{{ telegram_get_chat_id_url }}">{{ label_telegram_get_chat_id }}</a>
</div> </div>
{{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_chat_id, telegram_id, label_telegram_chat_id, "255", "telegram_id_help", telegram_id_description) }} {{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_chat_id, telegram_id, label_telegram_chat_id, "255", "telegram_id_help", label_telegram_id_description) }}
<button class="btn btn-primary show-modal" data-toggle="modal" data-modal-id="activateTelegram">{{ label_activate_telegram }}</button> <button class="btn btn-primary show-modal" data-toggle="modal" data-modal-id="activateTelegram">{{ label_activate_telegram }}</button>
{{ macro.input_hidden("activate_telegram", "0") }} {{ macro.input_hidden("activate_telegram", "0") }}
{{ macro.button_save(null, label_save) }}
</fieldset> </fieldset>
</form> <!-- Jabber settings -->
<fieldset>
<legend>{{ label_jabber }}</legend>
<!-- jabber -->
{{ macro.input_field("text", "jabber", null, "jabber", label_jabber, jabber, label_jabber, "255", "jabber_help", label_jabber_description) }}
</fieldset>
<!-- Discord settings -->
<fieldset>
<legend>{{ label_discord }}</legend>
{{ macro.input_field("text", "discord", null, "discord", label_discord, discord, "https://discordapp.com/api/webhooks/xxxxx", "255", "discord_help", label_discord_description) }}
</fieldset>
<!-- Webhook settings -->
<fieldset>
<legend>{{ label_webhook }}</legend>
<p>{{ label_webhook_description|raw }}</p>
<!-- webhook url -->
{{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, webhook_url, "https://test.com/api/abcde", "255", "webhook_url_help", label_webhook_url_description) }}
<!-- webhook json -->
{{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, webhook_json, "{\"text\":\"servermon: #message\"}", "255", "webhook_json_help", label_webhook_json_description) }}
</fieldset>
{{ macro.button_save(null, label_save) }}
</form>

View File

@ -17,12 +17,20 @@
{{ macro.input_field("email", "email", null, "email", label_email, edit_value_email, null, "255") }} {{ macro.input_field("email", "email", null, "email", label_email, edit_value_email, null, "255") }}
<!-- Mobile --> <!-- Mobile -->
{{ macro.input_field("tel", "mobile", null, "mobile", label_mobile, edit_value_mobile, null, "20") }} {{ macro.input_field("tel", "mobile", null, "mobile", label_mobile, edit_value_mobile, null, "20") }}
<!-- Discord -->
{{ macro.input_field("text", "discord", null, "discord", label_discord, edit_value_discord, null, "255") }}
<!-- Webhook_url -->
{{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, edit_value_webhook_url, null, "255") }}
<!-- Webhook_json -->
{{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, edit_value_webhook_json, null, "255") }}
<!-- Pushover_key --> <!-- Pushover_key -->
{{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, edit_value_pushover_key, null, "255") }} {{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, edit_value_pushover_key, null, "255") }}
<!-- Pushover_device --> <!-- Pushover_device -->
{{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, edit_value_pushover_device, null, "255") }} {{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, edit_value_pushover_device, null, "255") }}
<!-- Telegram_id --> <!-- Telegram_id -->
{{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_id, edit_value_telegram_id, null, "255") }} {{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_id, edit_value_telegram_id, null, "255") }}
<!-- Jabber -->
{{ macro.input_field("text", "jabber", null, "jabber", label_jabber, edit_value_jabber, null, "255") }}
<!-- Servers --> <!-- Servers -->
{{ macro.input_select_multiple("server_id", "server_id[]", label_servers, label_search, servers, label_please_select) }} {{ macro.input_select_multiple("server_id", "server_id[]", label_servers, label_search, servers, label_please_select) }}
</div> </div>

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} 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", "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"
], ],

0
src/templates/default/static/js/history.js Executable file → Normal file
View File

0
src/templates/default/static/js/scripts.js Executable file → Normal file
View File

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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;
@ -179,4 +183,9 @@ table tr[visible='true'] {
width: 95px; width: 95px;
transform-origin: 100% 4px; transform-origin: 100% 4px;
transition: all 1s; transition: all 1s;
}
.dropdown-menu.show {
left: inherit;
right: 0px;
} }