diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 59012128..42242799 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt 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"] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 19282003..3b079baa 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,8 +23,9 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** - - Version [e.g. 3.3.5, develop] +**Version (please complete the following information):** + - Version [e.g. 3.3.5] + - PHP [e.g. 7.3] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 4a439c2d..eee253b6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: "[Feature Request]" -labels: '' +labels: 'Type: Feature' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index c522ec69..d1b6afb8 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -2,7 +2,7 @@ name: Question about: Ask your questions title: "[Question] " -labels: '' +labels: 'Type: Question' assignees: '' --- diff --git a/.gitignore b/.gitignore index 7118155f..e1c85147 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ *.bak __MACOSX/ .DS_Store +.buildpath +.settings/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bd10a7d9..50e1d286 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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) ------------------------------------ diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 diff --git a/README.rst b/README.rst old mode 100755 new mode 100644 index 1940063c..26e51041 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ PHP Server Monitor :alt: Join the chat at https://gitter.im/erickrf/nlpnet :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. 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). -* Email, SMS, Pushover, Telegram notifications. +* Email, SMS, Discord, Pushover, Telegram and Jabber notifications. * View history graphs of uptime and latency. * User authentication with 2 levels (administrator and regular user). * 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. 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: * Clickatell - @@ -60,6 +60,8 @@ The following SMS gateways are currently available: * SolutionsInfini - * Plivo - * Callr - +* SMSAPI - +* OVH SMS PRO - @@ -79,10 +81,19 @@ Requirements * MySQL database * For PHP5: 5.5.9+ * For PHP7: 7.0.8+ -* PHP cURL package -* PHP PDO mysql driver -* PHP-XML +* PHP Extensions (modules) + * ext-curl + * ext-ctype + * ext-filter + * ext-hash + * ext-json + * ext-libxml + * ext-openssl + * ext-pdo + * ext-pcre + * ext-sockets + * ext-xml Install ------- @@ -105,7 +116,7 @@ If you are familiar with Vagrant (https://www.vagrantup.com):: 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 @@ -122,7 +133,7 @@ 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/. +along with PHP Server Monitor. If not, see https://www.gnu.org/licenses/. Docker ------- diff --git a/composer.json b/composer.json old mode 100755 new mode 100644 index d09fb164..0498c033 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ "require": { "php": "^5.5.9|>=7.0.8", "ext-curl": "*", + "ext-json": "*", "ext-pdo": "*", "ext-xml": "*", "phpmailer/phpmailer": ">=6.0.6 ~6.0", @@ -16,7 +17,8 @@ "symfony/filesystem": "~3.4", "php-pushover/php-pushover": "dev-master", "paragonie/random_compat": "^2.0", - "twig/twig": "~1.35" + "twig/twig": "~1.35", + "jaxl/jaxl": "^3.1" }, "autoload": { "files": [ @@ -27,4 +29,4 @@ "psm\\": "src/psm/" } } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index f07bb924..6ce79bb8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,81 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b2a2bd93aeb6abf9b4e1905aa7ea4217", + "content-hash": "f78e950e2dfef7debe88d7b64e2b4aec", "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", "version": "v2.0.18", @@ -87,16 +160,16 @@ }, { "name": "phpmailer/phpmailer", - "version": "v6.1.3", + "version": "v6.1.6", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "a25ae38e03de4ee4031725498a600012364787c7" + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a25ae38e03de4ee4031725498a600012364787c7", - "reference": "a25ae38e03de4ee4031725498a600012364787c7", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", "shasum": "" }, "require": { @@ -145,7 +218,7 @@ } ], "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", diff --git a/config.php.sample b/config.php.sample old mode 100755 new mode 100644 index a892215c..fd0775f4 --- a/config.php.sample +++ b/config.php.sample @@ -6,4 +6,5 @@ define('PSM_DB_NAME', 'db_name'); 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_BASE_URL', ''); +define('PSM_WEBCRON_KEY', ''); define('PSM_PUBLIC', true); \ No newline at end of file diff --git a/cron/status.cron.php b/cron/status.cron.php index 92b70182..0151d202 100644 --- a/cron/status.cron.php +++ b/cron/status.cron.php @@ -28,6 +28,9 @@ namespace { // include main configuration and functionality + use psm\Router; + use psm\Util\Server\UpdateManager; + require_once __DIR__ . '/../src/bootstrap.php'; if (!psm_is_cli()) { @@ -41,7 +44,10 @@ namespace { $data = @unserialize(PSM_CRON_ALLOW); $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'); die(' @@ -81,21 +87,79 @@ namespace { // 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. // 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(); if ( - psm_get_conf('cron_running') == 1 + psm_get_conf($confPrefix . 'running') == 1 && $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.'); } 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->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); } diff --git a/docs/conf.py b/docs/conf.py index 266839e9..826a5acf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,9 +51,9 @@ copyright = u'2008-2017, Pepijn Over' # built documents. # # The short X.Y version. -version = '3.4.5' +version = '3.6' # 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 # for a list of supported languages. diff --git a/docs/credits.rst b/docs/credits.rst index 6786fb1d..83ee5bf7 100644 --- a/docs/credits.rst +++ b/docs/credits.rst @@ -85,6 +85,14 @@ The following people have contributed to the development of PHP Server Monitor: * Nexmo SMS gateway +* Mateusz Małek - https://github.com/mateuszmalek + + * SMSAPI gateway + +* Daniel Krusky - https://github.com/dkrusky + + * Discord webhook support + Translators +++++++++++ @@ -192,3 +200,4 @@ The following libraries are being used by PHP Server Monitor: * PHP-Pushover - https://github.com/kryap/php-pushover * Symfony - https://symfony.com * Random_compat - https://github.com/paragonie/random_compat +* Hammer.js - https://github.com/hammerjs/hammer.js diff --git a/docs/faq.rst b/docs/faq.rst index a2f88ecb..13c8454f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -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. 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) @@ -169,3 +169,16 @@ What is the username of my bot? 1. Go to profile on the monitor. 2. Press activate. 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 ...). diff --git a/docs/install.rst b/docs/install.rst index 93898e36..771b7edb 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -50,6 +50,8 @@ For a regular upgrade, follow these steps: * Follow the steps * Enjoy +Alternatively you can use updater.sh script. + 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 +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. 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. @@ -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. +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 +++++++++++++++ @@ -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:: define('PSM_DEBUG', true); + diff --git a/docs/intro.rst b/docs/intro.rst index 40c66a4e..1ed2e397 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -15,7 +15,7 @@ Features ++++++++ * 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. * User authentication with 2 levels (administrator and regular user). * Logs of connection errors, outgoing emails and text messages. @@ -44,7 +44,7 @@ There are two different ways to monitor a server: Notifications ------------- 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: * Clickatell - diff --git a/logs/.gitignore b/logs/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/manifest.json b/manifest.json old mode 100755 new mode 100644 diff --git a/phpservermon.png b/phpservermon.png old mode 100755 new mode 100644 diff --git a/service-worker.js b/service-worker.js old mode 100755 new mode 100644 index 3d0a4edb..e0758905 --- a/service-worker.js +++ b/service-worker.js @@ -1,7 +1,7 @@ var dataCacheName = 'PSM-v1'; var cacheName = 'PSM-PWA-final-1'; var filesToCache = [ - '/', + '', 'index.php', 'src/templates/default/static/js/history.js', 'src/templates/default/static/js/scripts.js', diff --git a/src/includes/functions.inc.php b/src/includes/functions.inc.php index 783aa795..59717599 100644 --- a/src/includes/functions.inc.php +++ b/src/includes/functions.inc.php @@ -34,21 +34,21 @@ namespace { # ############################################### -/** - * Retrieve language settings from the selected language file - * Return false if arg is not found - * - * @return string|bool - * @see psm_load_lang() - */ + /** + * Retrieve language settings from the selected language file + * Return false if arg is not found + * + * @return string|bool + * @see psm_load_lang() + */ function psm_get_lang() { $args = func_get_args(); - + if (empty($args)) { return isset($GLOBALS['sm_lang']) ? $GLOBALS['sm_lang'] : $GLOBALS['sm_lang_default']; } - + if (isset($GLOBALS['sm_lang'])) { $lang = $GLOBALS['sm_lang']; $not_found = false; @@ -72,13 +72,13 @@ namespace { return $lang; } -/** - * Load default language from the English (en_US) language file to the $GLOBALS['sm_lang_default'] variable - * Load language from the language file to the $GLOBALS['sm_lang'] variable if language is different from default - * - * @param string $lang language - * @see psm_get_lang() - */ + /** + * Load default language from the English (en_US) language file to the $GLOBALS['sm_lang_default'] variable + * Load language from the language file to the $GLOBALS['sm_lang'] variable if language is different from default + * + * @param string $lang language + * @see psm_get_lang() + */ function psm_load_lang($lang) { // load default language - English (en_US) @@ -86,29 +86,29 @@ namespace { $default_lang_file = PSM_PATH_LANG . 'en_US.lang.php'; file_exists($default_lang_file) ? require $default_lang_file : - trigger_error("English translation needs to be installed at all time!", E_USER_ERROR); + trigger_error("English translation needs to be installed at all time!", E_USER_ERROR); isset($sm_lang) ? $GLOBALS['sm_lang_default'] = $sm_lang : - trigger_error("\$sm_lang not found in English translation!", E_USER_ERROR); + trigger_error("\$sm_lang not found in English translation!", E_USER_ERROR); unset($sm_lang); // load translation is the selected language is not English (en_US) if ($lang != "en_US") { $lang_file = PSM_PATH_LANG . $lang . '.lang.php'; file_exists($lang_file) ? require $lang_file : - trigger_error("Translation file could not be found! Default language will be used.", E_USER_WARNING); - + trigger_error("Translation file could not be found! Default language will be used.", E_USER_WARNING); + isset($sm_lang) ? $GLOBALS['sm_lang'] = $sm_lang : - trigger_error("\$sm_lang not found in translation file! Default language will be used.", E_USER_WARNING); + trigger_error("\$sm_lang not found in translation file! Default language will be used.", E_USER_WARNING); isset($sm_lang['locale']) ? setlocale(LC_TIME, $sm_lang['locale']) : - trigger_error("locale could not ben found in translation file.", E_USER_WARNING); + trigger_error("locale could not ben found in translation file.", E_USER_WARNING); } } -/** - * Retrieve a list with keys of the available languages - * - * @return array - * @see psm_load_lang() - */ + /** + * Retrieve a list with keys of the available languages + * + * @return array + * @see psm_load_lang() + */ function psm_get_langs() { $fn_ext = '.lang.php'; @@ -133,11 +133,11 @@ namespace { return $langs; } -/** - * Retrieve a list with available sms gateways - * - * @return array - */ + /** + * Retrieve a list with available sms gateways + * + * @return array + */ function psm_get_sms_gateways() { $sms_gateway_files = glob(PSM_PATH_SMS_GATEWAY . '*.php'); @@ -155,14 +155,14 @@ namespace { return $sms_gateways; } -/** - * Get a setting from the config. - * - * @param string $key - * @param mixed $alt if not set, return this alternative - * @return string - * @see psm_load_conf() - */ + /** + * Get a setting from the config. + * + * @param string $key + * @param mixed $alt if not set, return this alternative + * @return string + * @see psm_load_conf() + */ function psm_get_conf($key, $alt = null) { if (!isset($GLOBALS['sm_config'])) { @@ -173,13 +173,13 @@ namespace { return $result; } -/** - * Load config from the database to the $GLOBALS['sm_config'] variable - * - * @global object $db - * @return boolean - * @see psm_get_conf() - */ + /** + * Load config from the database to the $GLOBALS['sm_config'] variable + * + * @return boolean + * @global object $db + * @see psm_get_conf() + */ function psm_load_conf() { global $db; @@ -204,14 +204,14 @@ namespace { } } -/** - * Update a config setting. - * - * If the key does not exist yet it will be created. - * @global \psm\Service\Database $db - * @param string $key - * @param string $value - */ + /** + * Update a config setting. + * + * If the key does not exist yet it will be created. + * @param string $key + * @param string $value + * @global \psm\Service\Database $db + */ function psm_update_conf($key, $value) { global $db; @@ -223,8 +223,8 @@ namespace { $db->save( PSM_DB_PREFIX . 'config', array( - 'key' => $key, - 'value' => $value, + 'key' => $key, + 'value' => $value, ) ); } else { @@ -243,16 +243,16 @@ namespace { # ############################################### -/** - * This function merely adds the message to the log table. It does not perform any checks, - * everything should have been handled when calling this function - * - * @param string $server_id - * @param string $type - * @param string $message - * - * @return int log_id - */ + /** + * This function merely adds the message to the log table. It does not perform any checks, + * everything should have been handled when calling this function + * + * @param string $server_id + * @param string $type + * @param string $message + * + * @return int log_id + */ function psm_add_log($server_id, $type, $message) { global $db; @@ -260,19 +260,19 @@ namespace { return $db->save( PSM_DB_PREFIX . 'log', array( - 'server_id' => $server_id, - 'type' => $type, - 'message' => $message, + 'server_id' => $server_id, + 'type' => $type, + 'message' => $message, ) ); } -/** - * This function just adds a user to the log_users table. - * - * @param $log_id - * @param $user_id - */ + /** + * This function just adds a user to the log_users table. + * + * @param $log_id + * @param $user_id + */ function psm_add_log_user($log_id, $user_id) { global $db; @@ -280,19 +280,19 @@ namespace { $db->save( PSM_DB_PREFIX . 'log_users', array( - 'log_id' => $log_id, - 'user_id' => $user_id, + 'log_id' => $log_id, + 'user_id' => $user_id, ) ); } -/** - * This function adds the result of a check to the uptime table for logging purposes. - * - * @param int $server_id - * @param int $status - * @param string $latency - */ + /** + * This function adds the result of a check to the uptime table for logging purposes. + * + * @param int $server_id + * @param int $status + * @param string $latency + */ function psm_log_uptime($server_id, $status, $latency) { global $db; @@ -300,62 +300,62 @@ namespace { $db->save( PSM_DB_PREFIX . 'servers_uptime', array( - 'server_id' => $server_id, - 'date' => date('Y-m-d H:i:s'), - 'status' => $status, - 'latency' => $latency, + 'server_id' => $server_id, + 'date' => date('Y-m-d H:i:s'), + 'status' => $status, + 'latency' => $latency, ) ); } -/** - * Converts an interval into a string - * - * @param DateInterval $interval - * @return string - */ + /** + * Converts an interval into a string + * + * @param DateInterval $interval + * @return string + */ function psm_format_interval(DateInterval $interval) { $result = ""; if ($interval->y) { $result .= $interval->format("%y ") . (($interval->y == 1) ? - psm_get_lang('system', 'year') : psm_get_lang('system', 'years')) . " "; + psm_get_lang('system', 'year') : psm_get_lang('system', 'years')) . " "; } if ($interval->m) { $result .= $interval->format("%m ") . (($interval->m == 1) ? - psm_get_lang('system', 'month') : psm_get_lang('system', 'months')) . " "; + psm_get_lang('system', 'month') : psm_get_lang('system', 'months')) . " "; } if ($interval->d) { $result .= $interval->format("%d ") . (($interval->d == 1) ? - psm_get_lang('system', 'day') : psm_get_lang('system', 'days')) . " "; + psm_get_lang('system', 'day') : psm_get_lang('system', 'days')) . " "; } if ($interval->h) { $result .= $interval->format("%h ") . (($interval->h == 1) ? - psm_get_lang('system', 'hour') : psm_get_lang('system', 'hours')) . " "; + psm_get_lang('system', 'hour') : psm_get_lang('system', 'hours')) . " "; } if ($interval->i) { $result .= $interval->format("%i ") . (($interval->i == 1) ? - psm_get_lang('system', 'minute') : psm_get_lang('system', 'minutes')) . " "; + psm_get_lang('system', 'minute') : psm_get_lang('system', 'minutes')) . " "; } if ($interval->s) { $result .= $interval->format("%s ") . (($interval->s == 1) ? - psm_get_lang('system', 'second') : psm_get_lang('system', 'seconds')) . " "; + psm_get_lang('system', 'second') : psm_get_lang('system', 'seconds')) . " "; } return $result; } -/** - * Parses a string from the language file with the correct variables replaced in the message - * - * @param boolean|null $status - * @param string $type is either 'sms', 'email', 'pushover_title', 'pushover_message' or 'telegram_message' - * @param array $vars server information about the server which may be placed in a message: - * %KEY% will be replaced by your value - * @param boolean $combi parse other message if notifications need to be send combined - * @return string parsed message - */ + /** + * Parses a string from the language file with the correct variables replaced in the message + * + * @param boolean|null $status + * @param string $type is either 'sms', 'email', 'pushover_title', 'pushover_message', 'webhook_title', 'webhook_message' or 'telegram_message' + * @param array $vars server information about the server which may be placed in a message: + * %KEY% will be replaced by your value + * @param boolean $combi parse other message if notifications need to be send combined + * @return string parsed message + */ function psm_parse_msg($status, $type, $vars, $combi = false) { if (is_bool($status)) { @@ -378,20 +378,20 @@ namespace { return $message; } -/** - * Shortcut to curl_init(), curl_exec and curl_close() - * - * @param string $href - * @param boolean $header return headers? - * @param boolean $body return body? - * @param int|null $timeout connection timeout in seconds. defaults to PSM_CURL_TIMEOUT (10 secs). - * @param boolean $add_agent add user agent? - * @param string|bool $website_username Username website - * @param string|bool $website_password Password website - * @param string|null $request_method Request method like GET, POST etc. - * @param string|null $post_field POST data - * @return string cURL result - */ + /** + * Shortcut to curl_init(), curl_exec and curl_close() + * + * @param string $href + * @param boolean $header return headers? + * @param boolean $body return body? + * @param int|null $timeout connection timeout in seconds. defaults to PSM_CURL_TIMEOUT (10 secs). + * @param boolean $add_agent add user agent? + * @param string|bool $website_username Username website + * @param string|bool $website_password Password website + * @param string|null $request_method Request method like GET, POST etc. + * @param string|null $post_field POST data + * @return array cURL result + */ function psm_curl_get( $href, $header = false, @@ -418,7 +418,8 @@ namespace { curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_ENCODING, ''); - + curl_setopt($ch, CURLOPT_CERTINFO, 1); + if (!empty($request_method)) { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method); } @@ -451,31 +452,33 @@ namespace { } if ($add_agent) { - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; phpservermon/' . - PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)'); + curl_setopt($ch, CURLOPT_USERAGENT, psm_get_conf('user_agent', 'Mozilla/5.0 (compatible; phpservermon/' . + PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)')); } - $result = curl_exec($ch); + $result['exec'] = curl_exec($ch); + $result['info'] = curl_getinfo($ch); + curl_close($ch); - + if (defined('PSM_DEBUG') && PSM_DEBUG === true && psm_is_cli()) { echo PHP_EOL . - '==============cURL Result for: ' . $href . '===========================================' . PHP_EOL; + '==============cURL Result for: ' . $href . '===========================================' . PHP_EOL; print_r($result); echo PHP_EOL . - '==============END cURL Resul for: ' . $href . '===========================================' . PHP_EOL; + '==============END cURL Resul for: ' . $href . '===========================================' . PHP_EOL; } return $result; } -/** - * Get a "nice" timespan message - * - * Source: http://www.interactivetools.com/forum/forum-posts.php?postNum=2208966 - * @param string $time - * @return string - */ + /** + * Get a "nice" timespan message + * + * Source: http://www.interactivetools.com/forum/forum-posts.php?postNum=2208966 + * @param string $time + * @return string + */ function psm_timespan($time) { if (empty($time) || $time == '0000-00-00 00:00:00') { @@ -486,7 +489,7 @@ namespace { } if ($time < strtotime(date('Y-m-d 00:00:00')) - 60 * 60 * 24 * 3) { $format = psm_get_lang('system', (date('Y') !== date('Y', $time)) ? - 'long_day_format' : 'short_day_format'); + 'long_day_format' : 'short_day_format'); // Check for Windows to find and replace the %e // modifier correctly if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { @@ -497,7 +500,7 @@ namespace { $d = time() - $time; if ($d >= 60 * 60 * 24) { $format = psm_get_lang('system', (date('l', time() - 60 * 60 * 24) == date('l', $time)) ? - 'yesterday_format' : 'other_day_format'); + 'yesterday_format' : 'other_day_format'); return strftime($format, $time); } if ($d >= 60 * 60 * 2) { @@ -519,11 +522,11 @@ namespace { return psm_get_lang('system', 'a_second_ago'); } -/** - * Get a localised date from MySQL date format - * @param string $time - * @return string - */ + /** + * Get a localised date from MySQL date format + * @param string $time + * @return string + */ function psm_date($time) { if (empty($time) || $time == '0000-00-00 00:00:00') { @@ -532,12 +535,12 @@ namespace { return strftime('%x %X', strtotime($time)); } -/** - * Check if an update is available for PHP Server Monitor. - * - * Will only check for new version if user turned updates on in config. - * @return boolean - */ + /** + * Check if an update is available for PHP Server Monitor. + * + * Will only check for new version if user turned updates on in config. + * @return boolean + */ function psm_update_available() { if (!psm_get_conf('show_update')) { @@ -552,32 +555,41 @@ namespace { // update last check date psm_update_conf('last_update_check', time()); $latest = psm_curl_get(PSM_UPDATE_URL); - // extract latest version from Github. - preg_match('/"tag_name":"[v](([\d][.][\d][.][\d])(-?\w*))"/', $latest, $latest); - // add latest version to database - if (!empty($latest) && strlen($latest[2]) < 15) { - psm_update_conf('version_update_check', $latest[2]); + if ($latest['info'] === false || (int)$latest['info']['http_code'] >= 300) { + // error + return false; } + // extract latest version from Github. + $githubInfo = json_decode($latest['exec']); + if (property_exists($githubInfo, 'tag_name') === false) { + // version not found + return false; + } + $tagName = $githubInfo->tag_name; + $latestVersion = str_replace('v', '', $tagName); + // check from old version ... maybe has reason but I don't think so ... + if (empty($latestVersion) === true || strlen($latestVersion) >= 15) { + // weird version + return false; + } + // add latest version to database + psm_update_conf('version_update_check', $latestVersion); } else { - $latest[2] = psm_get_conf('version_update_check'); + $latestVersion = psm_get_conf('version_update_check'); } - if (!empty($latest)) { - $current = psm_get_conf('version'); - return version_compare($latest[2], $current, '>'); - } else { - return false; - } + $current = psm_get_conf('version'); + return version_compare($latestVersion, $current, '>'); } -/** - * Prepare a new phpmailer instance. - * - * If the from name and email are left blank they will be prefilled from the config. - * @param string $from_name - * @param string $from_email - * @return \PHPMailer\PHPMailer\PHPMailer - */ + /** + * Prepare a new phpmailer instance. + * + * If the from name and email are left blank they will be prefilled from the config. + * @param string $from_name + * @param string $from_email + * @return \PHPMailer\PHPMailer\PHPMailer + */ function psm_build_mail($from_name = null, $from_email = null) { $phpmailer = new \PHPMailer\PHPMailer\PHPMailer(); @@ -588,11 +600,14 @@ namespace { if (psm_get_conf('email_smtp') == '1') { $phpmailer->IsSMTP(); $phpmailer->Host = psm_get_conf('email_smtp_host'); - $phpmailer->Port = (int) psm_get_conf('email_smtp_port'); + $phpmailer->Port = (int)psm_get_conf('email_smtp_port'); $phpmailer->SMTPSecure = psm_get_conf('email_smtp_security'); $smtp_user = psm_get_conf('email_smtp_username'); - $smtp_pass = psm_get_conf('email_smtp_password'); + $smtp_pass = psm_password_decrypt( + psm_get_conf('password_encrypt_key'), + psm_get_conf('email_smtp_password') + ); if ($smtp_user != '' && $smtp_pass != '') { $phpmailer->SMTPAuth = true; @@ -613,11 +628,11 @@ namespace { return $phpmailer; } -/** - * Prepare a new Pushover util. - * - * @return \Pushover - */ + /** + * Prepare a new Pushover util. + * + * @return \Pushover + */ function psm_build_pushover() { $pushover = new \Pushover(); @@ -626,10 +641,22 @@ namespace { return $pushover; } -/** - * - * @return \Telegram - */ + /** + * Prepare a new Webhook util. + * + * @return Webhook + */ + function psm_build_webhook() + { + $webhook = new Webhook(); + + return $webhook; + } + + /** + * + * @return \Telegram + */ function psm_build_telegram() { $telegram = new \Telegram(); @@ -638,11 +665,65 @@ namespace { return $telegram; } -/** - * Prepare a new SMS util. - * - * @return \psm\Txtmsg\TxtmsgInterface - */ + /** + * Send message via XMPP. + * + * @param string $host + * @param string $username + * @param string $password + * @param array $receivers + * @param string $message + * @param int|null $port + * @param string|null $domain + */ + function psm_jabber_send_message($host, $username, $password, $receivers, $message, $port = null, $domain = null) + { + $options = [ + 'jid' => $username, // incl. gmail.com + 'pass' => $password, + 'domain' => $domain, // gmail.com or null + 'host' => $host, // talk.google.com + 'port' => $port, // talk.google.com needs to have 5223 ... 5222 - CN problem - gmail.com vs talk.google.com + 'log_path' => __DIR__ . '/../../logs/jaxl.log', // own log + + // force tls + 'force_tls' => PSM_JABBER_FORCE_TLS, + // (required) perform X-OAUTH2 + 'auth_type' => PSM_JABBER_AUTH_TYPE, //'X-OAUTH2', // auth failure with this option :( so just PLAIN ... + + 'log_level' => PSM_JABBER_DEBUG_LEVEL + ]; + + try { + $client = new JAXL($options); + + // Add Callbacks + $client->add_cb('on_auth_success', function () use ($client, $receivers, $message) { + JAXLLogger::info('got on_auth_success cb'); + foreach ($receivers as $receiver) { + $client->send_chat_msg($receiver, $message); + } + $client->send_end_stream(); + }); + $client->add_cb('on_auth_failure', function ($reason) use ($client) { + $client->send_end_stream(); + JAXLLogger::info('got on_auth_failure cb with reason: ' . $reason); + }); + $client->add_cb('on_disconnect', function () use ($client) { + JAXLLogger::info('got on_disconnect cb'); + }); + + $client->start(); + } catch (Exception $ex) { + JAXLLogger::error('Exception: ' . $ex->getMessage()); + } + } + + /** + * Prepare a new SMS util. + * + * @return \psm\Txtmsg\TxtmsgInterface + */ function psm_build_sms() { $sms = null; @@ -689,6 +770,9 @@ namespace { case 'octopush': $sms = new \psm\Txtmsg\Octopush(); break; + case 'ovhsms': + $sms = new \psm\Txtmsg\OVHsms(); + break; case 'smsgw': $sms = new \psm\Txtmsg\Smsgw(); break; @@ -710,6 +794,11 @@ namespace { case 'solutionsinfini': $sms = new \psm\Txtmsg\SolutionsInfini(); break; + case 'ysmal': + $sms = new \psm\Txtmsg\Ysmal(); + case 'smsapi': + $sms = new \psm\Txtmsg\SMSAPI(); + break; } // copy login information from the config file @@ -721,20 +810,20 @@ namespace { return $sms; } -/** - * Generate a new link to the current monitor - * @param array|string $params key value pairs or pre-formatted string - * @param boolean $urlencode urlencode all params? - * @param boolean $htmlentities use entities in url? - * @return string - */ + /** + * Generate a new link to the current monitor + * @param array|string $params key value pairs or pre-formatted string + * @param boolean $urlencode urlencode all params? + * @param boolean $htmlentities use entities in url? + * @return string + */ function psm_build_url($params = array(), $urlencode = true, $htmlentities = true) { if (defined('PSM_BASE_URL') && PSM_BASE_URL !== null) { $url = PSM_BASE_URL; } else { $url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || - $_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; + $_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; // on Windows, dirname() adds both back- and forward slashes (http://php.net/dirname). // for urls, we only want the forward slashes. $url .= dirname($_SERVER['SCRIPT_NAME']); @@ -761,12 +850,12 @@ namespace { return $url; } -/** - * Try existence of a GET var, if not return the alternative - * @param string $key - * @param string $alt - * @return mixed - */ + /** + * Try existence of a GET var, if not return the alternative + * @param string $key + * @param string $alt + * @return mixed + */ function psm_GET($key, $alt = null) { if (isset($_GET[$key])) { @@ -776,12 +865,12 @@ namespace { } } -/** - * Try existence of a POST var, if not return the alternative - * @param string $key - * @param string|array|bool $alt - * @return mixed - */ + /** + * Try existence of a POST var, if not return the alternative + * @param string $key + * @param string|array|bool $alt + * @return mixed + */ function psm_POST($key, $alt = null) { if (isset($_POST[$key])) { @@ -791,12 +880,12 @@ namespace { } } -/** - * Check if we are in CLI mode - * - * Note, php_sapi cannot be used because cgi-fcgi returns both for web and cli. - * @return boolean - */ + /** + * Check if we are in CLI mode + * + * Note, php_sapi cannot be used because cgi-fcgi returns both for web and cli. + * @return boolean + */ function psm_is_cli() { return (!isset($_SERVER['SERVER_SOFTWARE']) || php_sapi_name() == 'cli'); @@ -808,11 +897,11 @@ namespace { # ############################################### -/** - * Only used for debugging and testing - * - * @param mixed $arr - */ + /** + * Only used for debugging and testing + * + * @param mixed $arr + */ function pre($arr = null) { echo "
";
@@ -823,9 +912,9 @@ namespace {
         echo "
"; } -/** - * Send headers to the browser to avoid caching - */ + /** + * Send headers to the browser to avoid caching + */ function psm_no_cache() { header("Expires: Mon, 20 Dec 1998 01:00:00 GMT"); @@ -834,14 +923,14 @@ namespace { header("Pragma: no-cache"); } -/** - * Encrypts the password for storage in the database - * - * @param string $key - * @param string $password - * @return string - * @author Pavel Laupe Dvorak - */ + /** + * Encrypts the password for storage in the database + * + * @param string $key + * @param string $password + * @return string + * @author Pavel Laupe Dvorak + */ function psm_password_encrypt($key, $password) { if (empty($password)) { @@ -870,14 +959,14 @@ namespace { return $encrypted; } -/** - * Decrypts password stored in the database for future use - * - * @param string $key - * @param string $encryptedString - * @return string - * @author Pavel Laupe Dvorak - */ + /** + * Decrypts password stored in the database for future use + * + * @param string $key + * @param string $encryptedString + * @return string + * @author Pavel Laupe Dvorak + */ function psm_password_decrypt($key, $encryptedString) { if (empty($encryptedString)) { @@ -885,7 +974,7 @@ namespace { } if (empty($key)) { - throw new \InvalidArgumentException('invalid_encryption_key'); + throw new \InvalidArgumentException('invalid_encryption_key'); } // using open ssl @@ -893,26 +982,23 @@ namespace { $cipher = "AES-256-CBC"; $ivlen = openssl_cipher_iv_length($cipher); $iv = substr($data, 0, $ivlen); - $decrypted = rtrim( - openssl_decrypt( - base64_encode(substr($data, $ivlen)), - $cipher, - hash('sha256', $key, true), - OPENSSL_ZERO_PADDING, - $iv - ), - "\0" + $decrypted = openssl_decrypt( + substr($data, $ivlen), + $cipher, + hash('sha256', $key, true), + OPENSSL_RAW_DATA, + $iv ); - + return $decrypted; } -/** -* Send notification to Telegram -* -* @return string -* @author Tim Zandbergen -*/ + /** + * Send notification to Telegram + * + * @return string + * @author Tim Zandbergen + */ class Telegram { private $token; @@ -922,12 +1008,14 @@ namespace { public function setToken($token) { - $this->token = (string) $token; + $this->token = (string)$token; } + public function setUser($user) { - $this->user = (string) $user; + $this->user = (string)$user; } + public function setMessage($message) { $message = str_replace("
    ", "", $message); @@ -936,8 +1024,9 @@ namespace { $message = str_replace("", "\n", $message); $message = str_replace("
    ", "\n", $message); $message = str_replace("
    ", "\n", $message); - $this->message = (string) $message; + $this->message = (string)$message; } + public function sendurl() { $con = curl_init($this->url); @@ -948,15 +1037,17 @@ namespace { $response = json_decode($response, true); return $response; } + public function send() { if (!empty($this->token) && !empty($this->user) && !empty($this->message)) { $this->url = 'https://api.telegram.org/bot' . urlencode($this->token) . - '/sendMessage?chat_id=' . urlencode($this->user) . '&text=' . - urlencode($this->message) . '&parse_mode=HTML'; + '/sendMessage?chat_id=' . urlencode($this->user) . '&text=' . + urlencode($this->message) . '&parse_mode=HTML&disable_web_page_preview=True'; } return $this->sendurl(); } + // Get the bots username public function getBotUsername() { @@ -966,4 +1057,121 @@ namespace { return $this->sendurl(); } } + + /** + * Send notification via webhooks + * + * @return string + * @author Malte Grosse + */ + class Webhook + { + protected $url; + protected $json; + protected $message; + + /** + * Send Webhook + * + * @return bool|string + * @var string $message + * + */ + + public function sendWebhook($message) + { + $error = ""; + $success = 1; + + $this->setMessage($message); + $jsonMessage = strtr($this->json, array('#message' => $this->message)); + + $curl = curl_init($this->url); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonMessage); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($curl, CURLOPT_TIMEOUT, 60); + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); + $result = curl_exec($curl); + + $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $err = curl_errno($curl); + + if ($err != 0 || $httpcode < 200 || $httpcode >= 300) { + $success = 0; + $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . $err . ". \nResult: " . $result; + } + + curl_close($curl); + + if ($success) { + return 1; + } + return $error; + } + + /** + * setUrl + * + * @var string $url + * + */ + public function setUrl($url) + { + $this->url = $url; + } + + /** + * getUrl + * + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * setJson + * + * @var string $json + * + */ + public function setJson($json) + { + $this->json = $json; + } + + /** + * getJson + * + * @return string + */ + public function getJson() + { + return $this->json; + } + + /** + * Set message + * + * @return string + * @var string $message + * + */ + public function setMessage($message) + { + $message = str_replace("
      ", "", $message); + $message = str_replace("
    ", "\n", $message); + $message = str_replace("
  • ", "- ", $message); + $message = str_replace("
  • ", "\n", $message); + $message = str_replace("
    ", "\n", $message); + $message = str_replace("
    ", "\n", $message); + $message = str_replace("", "", $message); + $message = str_replace("", "", $message); + $message = strip_tags($message); + $this->message = (string)$message; + } + } } diff --git a/src/includes/psmconfig.inc.php b/src/includes/psmconfig.inc.php index c70d24e5..862ccda4 100644 --- a/src/includes/psmconfig.inc.php +++ b/src/includes/psmconfig.inc.php @@ -30,7 +30,7 @@ /** * 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. @@ -130,3 +130,15 @@ if (!defined('PSM_MODULE_DEFAULT')) { */ 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); +} diff --git a/src/lang/bg_BG.lang.php b/src/lang/bg_BG.lang.php index 9f15fdbb..1e4f3846 100644 --- a/src/lang/bg_BG.lang.php +++ b/src/lang/bg_BG.lang.php @@ -66,6 +66,7 @@ $sm_lang = array( 'a_minute_ago' => 'преди минута', 'seconds_ago' => 'преди %d секунди', 'a_second_ago' => 'преди секунда', + 'seconds' => 'секунди', ), 'menu' => array( 'config' => 'Настройки', @@ -99,8 +100,8 @@ $sm_lang = array( 'pushover' => 'Pushover', 'pushover_description' => 'Pushover е услуга, която улеснява получаването на известия в реално време. Посетете техния сайт за повече - информация.', + href="https://pushover.net/" target="_blank">техния сайт за + повече информация.', 'pushover_key' => 'Pushover Ключ', 'pushover_device' => 'Pushover Устройство', 'pushover_device_description' => 'Име на устройство, което да получава @@ -219,8 +220,6 @@ $sm_lang = array( 'email_smtp' => 'Активиране на SMTP', 'email_smtp_host' => 'SMTP сървър', 'email_smtp_port' => 'SMTP порт', - 'email_smtp_security' => 'SMTP security', - 'email_smtp_security_none' => 'None', 'email_smtp_username' => 'SMTP потребителско име', 'email_smtp_password' => 'SMTP парола', 'email_smtp_noauth' => 'Оставете празно за "без аутентикация"', @@ -232,8 +231,8 @@ $sm_lang = array( 'pushover_status' => 'Позволява изпращането на Pushover съобщения', 'pushover_description' => 'Pushover е услуга, която улеснява получаването на известия в реално време. Посетете техния сайт за повече - информация.', + href="https://pushover.net/" target="_blank">техния сайт за + повече информация.', 'pushover_clone_app' => 'Кликнете тук за да създаване на вашият Pushover App', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Преди да използвате Pushover, трябва да 'Да се пази ли лог на изпратените SMS съобщения от системата', - 'log_pushover' => 'Log pushover messages sent by the script', 'updated' => 'Настройките са обновени успешно.', 'tab_email' => 'Имейл', 'tab_sms' => 'SMS', diff --git a/src/lang/ca_ES.lang.php b/src/lang/ca_ES.lang.php index f23b51e7..94dcc8d6 100644 --- a/src/lang/ca_ES.lang.php +++ b/src/lang/ca_ES.lang.php @@ -109,16 +109,17 @@ $sm_lang = array( 'email' => 'Correu', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover és un servei que fa fàcil obtenir notificacions en temps real. Veieu la seva web per a més informació.', + href="https://pushover.net/" target="_blank">la seva web per a més + informació.', 'pushover_key' => 'Clau Pushover', 'pushover_device' => 'Dispositiu Pushover', 'pushover_device_description' => 'Nom del dispositiu al qual enviar els missatges. Deixau en blanc per enviar a tots els dispositius.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram és una app de missatgeria que - facilita el rebre notificacions en temps real. Consulteu la documentació per a més informació i - per saber com instal·lar-ho.', + 'telegram_description' => 'Telegram és una app de + missatgeria que facilita el rebre notificacions en temps real. Consulteu la documentació per a + més informació i per saber com instal·lar-ho.', '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_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 al seu portal web i introduïr aquí el Token de la API.', 'telegram_status' => 'Permetre l\'enviament de missatges per Telegram', - 'telegram_description' => 'Telegram és una app de xat (mòbil i PC) que - facilita la recepció de notificacions en temps real. Veieu la documentació per saber més i saber - com activar-ho.', + 'telegram_description' => 'Telegram és una app de xat + (mòbil i PC) que facilita la recepció de notificacions en temps real. Veieu la documentació per + saber més i saber com activar-ho.', '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. - Consulteu la documentació per saber - més.', + Consulteu la documentació per saber més.', 'alert_type' => 'Seleccioneu quan voleu ser notificats.', 'alert_type_description' => 'Canvi d\'estat: 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.
    'Auto-recàrrega', 'auto_refresh_description' => 'Recarregar automàticament la plana Servidors.
    Temps en segons, si poseu ZERO la plana no s\'auto-recarregarà.', - 'seconds' => 'segons', 'test' => 'Provar', '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.', diff --git a/src/lang/cs_CZ.lang.php b/src/lang/cs_CZ.lang.php index 8a4e3207..fff3a945 100644 --- a/src/lang/cs_CZ.lang.php +++ b/src/lang/cs_CZ.lang.php @@ -68,6 +68,7 @@ $sm_lang = array( 'a_minute_ago' => 'cca před minutou', 'seconds_ago' => 'před %d vteřinami', 'a_second_ago' => 'před chvílí', + 'seconds' => 'sekunder', ), 'menu' => array( 'config' => 'Konfigurace', @@ -95,7 +96,7 @@ $sm_lang = array( 'email' => 'E-mail', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění. - Více na webu Pushover', + Více na webu Pushover', 'pushover_key' => 'Pushover Token', 'pushover_device' => 'Pushover Zařízení', 'pushover_device_description' => 'Název zařízení, na které má být zráva odeslána. Ponechte prázdné @@ -227,7 +228,7 @@ $sm_lang = array( 'sms_from' => 'Telefonní číslo odesilatele', '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í. - Více na webu Pushover', + Více na webu Pushover', 'pushover_clone_app' => 'Klikněte pro vytvoření Pushover aplikace', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Pře použitím Pushoveru se musíte 'Automaticky obnovit', 'auto_refresh_description' => 'Automaticky obnovit stránku Servery.
    Čas v sekundách, 0 pro vypnutí automatického obnovení.', - 'seconds' => 'sekund', 'test' => 'Test', '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.', diff --git a/src/lang/da_DK.lang.php b/src/lang/da_DK.lang.php index dc20a5ce..4b805583 100644 --- a/src/lang/da_DK.lang.php +++ b/src/lang/da_DK.lang.php @@ -65,6 +65,7 @@ $sm_lang = array( 'a_minute_ago' => 'omkring et minut siden', 'seconds_ago' => '%d sekunder siden', 'a_second_ago' => 'et sekund siden', + 'seconds' => 'sekunder', ), 'menu' => array( 'config' => 'Indstillinger', @@ -92,7 +93,8 @@ $sm_lang = array( 'email' => 'E-mail', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se
    deres website for mere information.', + href="https://pushover.net/" target="_blank">deres website for mere + information.', 'pushover_key' => 'Pushover nøgle', 'pushover_device' => 'Pushover enhed', 'pushover_device_description' => 'Navnet på enheden som beskeden skal sendes til. Lad denne være tom hvis @@ -208,7 +210,8 @@ $sm_lang = array( 'sms_from' => 'Afsenderens navn.', 'pushover_status' => 'Tillad at sende Pushover beskeder', 'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se deres website for yderligere information.', + href="https://pushover.net/" target="_blank">deres website for yderligere + information.', 'pushover_clone_app' => 'Klik her for at oprette din Pushover app', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du 'Genopfrisk automatisk', 'auto_refresh_description' => 'Genopfrisk automatisk serversider.
    Tid i sekunder. Hvis 0 vil siden ikke genopfriske automatisk', - 'seconds' => 'sekunder', 'test' => 'Test', '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.', diff --git a/src/lang/de_DE.lang.php b/src/lang/de_DE.lang.php index 2e4b11e4..9f0473de 100644 --- a/src/lang/de_DE.lang.php +++ b/src/lang/de_DE.lang.php @@ -66,6 +66,7 @@ $sm_lang = array( 'a_minute_ago' => 'vor über einer Minute', 'seconds_ago' => 'vor %d Sekunden', 'a_second_ago' => 'vor über einer Sekunde', + 'seconds' => 'Sekunden', ), 'menu' => array( 'config' => 'Einstellungen', @@ -93,8 +94,8 @@ $sm_lang = array( 'email' => 'E-Mail', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in - Echtzeit zu erhalten. Besuchen Sie
    pushover.net - für weitere Informationen.', + Echtzeit zu erhalten. Besuchen Sie pushover.net für weitere Informationen.', 'pushover_key' => 'Pushover Key/Schlüssel', 'pushover_device' => 'Pushover Gerät', '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', 'pushover_status' => 'Ermögliche das Senden von Pushover-Nachrichten', 'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in - Echtzeit zu erhalten. Besuchen Sie pushover.net - für weitere Informationen.', + Echtzeit zu erhalten. Besuchen Sie pushover.net für weitere Informationen.', 'pushover_clone_app' => 'Klicken Sie hier, um Ihre Pushover-Anwendung zu erstellen', 'pushover_api_token' => 'Pushover-Anwendungs-API-Token', 'pushover_api_token_description' => 'Bevor Sie Pushover verwenden können, müssen Sie Ihre 'Automatische Aktualisierung der Server-Übersichtsseite
    Zeit in Sekunden - die Ziffer \'0\' deaktiviert die automatische Aktualisierung.', - 'seconds' => 'Sekunden', 'test' => 'Test', '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.', diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index 21dabb9e..3a92df2f 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -50,9 +50,7 @@ $sm_lang = array( 'no' => 'No', 'insert' => 'Insert', 'add_new' => 'Add new', - 'update_available' => 'A new version ({version}) is available. Click
    here to download the update.', + 'update_available' => 'A new version ({version}) is available. Click here to download the update.', 'back_to_top' => 'Back to top', 'go_back' => 'Go back', 'ok' => 'OK', @@ -83,6 +81,8 @@ $sm_lang = array( 'minutes' => 'minutes', 'second' => 'second', 'seconds' => 'seconds', + 'millisecond' => 'millisecond', + 'milliseconds' => 'milliseconds', 'current' => 'current', 'settings' => 'Settings', 'search' => 'Search', @@ -113,27 +113,33 @@ $sm_lang = array( 'mobile' => 'Mobile', 'email' => 'Email', 'pushover' => 'Pushover', - 'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See their website for more info.', + 'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See their website for more info.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', '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 webhook here.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram is a chat app that makes it easy to - get real-time notifications. Visit the documentation for more info and an - install guide.', + 'telegram_description' => 'Telegram is a chat app that makes it easy to get real-time notifications. Visit the documentation for more info and an install guide.', 'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id_description' => 'The message will be send to the corresponding chat.', 'telegram_get_chat_id' => 'Click here to get your chat id', 'activate_telegram' => 'Activate Telegram notifications', - '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.', - 'telegram_bot_username_found' => 'The bot was found!

    This will open a chat - with the bot. Here you need to press start of type /start.', + '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.', + 'telegram_bot_username_found' => 'The bot was found!

    This will open a chat with the bot. Here you need to press start or type /start.', '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', + 'jabber' => 'Jabber', + 'jabber_label' => 'Jabber', + 'jabber_description' => 'You Jabber account', + 'webhook' => 'Webhook', + 'webhook_description' => 'Send a json webhook to a certain endpoint.
    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_message' => 'Are you sure you want to delete user \'%1\'?', 'deleted' => 'User deleted.', @@ -142,8 +148,7 @@ $sm_lang = array( 'profile' => 'Profile', 'profile_updated' => 'Your profile has been updated.', '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), - dots (.) and underscores (_).', + 'error_user_name_invalid' => 'The username may only contain alphabetic characters (a-z, A-Z), digits (0-9), dots (.) and underscores (_).', '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_invalid' => 'The email address is invalid.', @@ -160,8 +165,11 @@ $sm_lang = array( 'status' => 'Status', 'email' => 'Email', 'sms' => 'SMS', + 'discord' => 'Discord', 'pushover' => 'Pushover', + 'webhook' => 'Webhook', 'telegram' => 'Telegram', + 'jabber' => 'Jabber', 'no_logs' => 'No logs', 'clear' => 'Clear log', 'delete_title' => 'Delete log', @@ -197,17 +205,13 @@ $sm_lang = array( 'type_service' => 'Service', 'type_ping' => 'Ping', 'pattern' => 'Search string/pattern', - 'pattern_description' => 'If this pattern is not found on the website, the server will be marked - online/offline. Regular expressions are allowed.', + 'pattern_description' => 'If this pattern is not found on the website, the server will be marked online/offline. Regular expressions are allowed.', 'pattern_online' => 'Pattern indicates website is', - '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.', + '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.', 'redirect_check' => 'Redirecting to another domain is', 'redirect_check_description' => 'Redirect to another domain is usually a bad sign.', 'allow_http_status' => 'Allow HTTP status code', - 'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as - online by default. Seperate with |.', + 'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as online by default. Seperate with |.', 'header_name' => 'Header name', 'header_value' => 'Header value', 'header_name_description' => 'Case-sensitive.', @@ -225,10 +229,16 @@ $sm_lang = array( 'send_email' => 'Send Email', 'sms' => 'SMS', 'send_sms' => 'Send SMS', + 'discord' => 'Discord', + 'send_discord' => 'Send Discord notification', + 'webhook' => 'Webhook', + 'send_webhook' => 'Send Webhook notification', 'pushover' => 'Pushover', 'send_pushover' => 'Send Pushover notification', 'telegram' => 'Telegram', 'send_telegram' => 'Send Telegram notification', + 'jabber' => 'Jabber', + 'send_jabber' => 'Send Jabber notification', 'users' => 'Users', 'delete_title' => 'Delete server', 'delete_message' => 'Are you sure you want to delete server \'%1\'?', @@ -249,6 +259,10 @@ $sm_lang = array( 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', '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_history' => 'History', 'chart_day_format' => '%Y-%m-%d', @@ -257,8 +271,11 @@ $sm_lang = array( 'chart_short_time_format' => '%H:%M', 'warning_notifications_disabled_sms' => 'SMS 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_telegram' => 'Telegram notifications are disabled.', + 'warning_notifications_disabled_jabber' => 'Jabber notifications are disabled.', 'error_server_no_match' => 'Server not found.', '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.', @@ -266,14 +283,15 @@ $sm_lang = array( 'error_server_ip_bad_website' => 'The website URL is not valid.', '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_ssl_cert_expiry_days' => 'The remaining days for SSL certificate validity must be a valid integer greater than or equal to 0.', ), 'config' => array( 'general' => 'General', + 'site_title' => 'Site title', 'language' => 'Language', 'show_update' => 'Check for updates?', '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 - websites. If the key will change the stored password is invalid!', + '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!', 'proxy' => 'Enable proxy', 'proxy_url' => 'Proxy URL', 'proxy_user' => 'Proxy username', @@ -294,67 +312,84 @@ $sm_lang = array( 'sms_gateway_username' => 'Gateway username', 'sms_gateway_password' => 'Gateway password', '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 their website 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_description' => 'Pushover is a service that makes it easy to get real-time notifications. See their website for more info.', + 'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See their website for more info.', 'pushover_clone_app' => 'Click here to create your Pushover app', 'pushover_api_token' => 'Pushover App API Token', - 'pushover_api_token_description' => 'Before you can use Pushover, you need to register an App at their website and enter the App API - Token here.', + 'pushover_api_token_description' => 'Before you can use Pushover, you need to register an App at their website and enter the App API Token here.', 'telegram_status' => 'Allow sending Telegram messages', - 'telegram_description' => 'Telegram is a chat app that makes it easy to - get real-time notifications. Visit the documentation for more info and an - install guide.', + 'telegram_description' => 'Telegram is a chat app that makes it easy to get real-time notifications. Visit the documentation for more info and an install guide.', 'telegram_api_token' => 'Telegram API Token', - 'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the documentation for help.', + 'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the documentation for help.', + 'jabber_status' => 'Allow sending Jabber (XMPP) messages', + 'jabber_description' => 'Visit the documentation 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_description' => 'Status change: You will receive a notification when a server has a change - in status. So from online -> offline or offline -> online.

    Offline: - 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.

    Always: 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_description' => 'Status change: You will receive a notification when a server has a change in status. So from online -> offline or offline -> online.

    Offline: 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.

    Always: 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_offline' => 'Offline', 'alert_type_always' => 'Always', 'combine_notifications' => 'Combine notifications', - 'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into - 1 single notification. (This does not affect SMS notifications.)', + 'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into 1 single notification. (This does not affect SMS notifications.)', 'alert_proxy' => 'Even if enabled, proxy is never used for services', 'alert_proxy_url' => 'Format: host:port', 'log_status' => 'Log status', - 'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the - notification settings are passed.', + 'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the notification settings are passed.', 'log_email' => 'Log emails 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_webhook' => 'Log webhook 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.', 'tab_email' => 'Email', 'tab_sms' => 'SMS', + 'tab_discord' => 'Discord', 'tab_pushover' => 'Pushover', + 'tab_webhook' => 'Webhook', 'tab_telegram' => 'Telegram', + 'tab_jabber' => 'Jabber', 'settings_email' => 'Email settings', 'settings_sms' => 'Text message settings', + 'settings_discord' => 'Discord settings', 'settings_pushover' => 'Pushover settings', + 'settings_webhook' => 'Webhook settings', 'settings_telegram' => 'Telegram settings', + 'settings_jabber' => 'Jabber settings', 'settings_notification' => 'Notification settings', 'settings_log' => 'Log settings', 'settings_proxy' => 'Proxy settings', 'auto_refresh' => 'Auto-refresh', - 'auto_refresh_description' => 'Auto-refresh servers page.
    Time in seconds, if 0 the - page won\'t refresh.', - 'seconds' => 'seconds', + 'auto_refresh_description' => 'Auto-refresh servers page.
    Time in seconds, if 0 the page won\'t refresh.', 'test' => 'Test', '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_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 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_jabber' => 'A Jabber notification will be sent to the jabber account specified in your user profile.', 'send' => 'Send', 'test_subject' => 'Test', 'test_message' => 'Test message', @@ -363,35 +398,55 @@ $sm_lang = array( 'sms_sent' => 'SMS sent', '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.', + '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_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 - configuration.', + 'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global configuration.', 'pushover_error_nokey' => 'Unable to send test notification: no Pushover key found in your profile.', 'telegram_sent' => 'Telegram notification sent', '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 - configuration.', + 'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global configuration.', '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_description' => 'Number of days to keep logs of notifications and archives of server - uptime. Enter 0 to disable log cleanup.', + 'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server uptime. Enter 0 to disable log cleanup.', '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( 'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Error=%ERROR%', 'off_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is DOWN', + 'off_email_body' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', + 'off_discord_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', 'off_email_body' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', + 'off_webhook_title' => 'Server \'%LABEL%\' is DOWN', + 'off_webhook_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: + %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', 'off_pushover_title' => 'Server \'%LABEL%\' is DOWN', - 'off_pushover_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: - %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', - 'off_telegram_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: - %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', + 'off_pushover_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', + 'off_telegram_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', + 'off_jabber_message' => 'Failed to connect to the following server:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Error: %ERROR%
    Date: %DATE%', '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_body' => 'Server \'%LABEL%\' is running again, it was down for %LAST_OFFLINE_DURATION%:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Date: + %DATE%', + 'on_discord_message' => 'Server \'%LABEL%\' is running again, it was down for: + %LAST_OFFLINE_DURATION%

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Date: %DATE%', + 'on_webhook_title' => 'Server \'%LABEL%\' is RUNNING', + 'on_webhook_message' => 'Server \'%LABEL%\' is running again, it was down for + %LAST_OFFLINE_DURATION%:

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Date: %DATE%', 'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING', 'on_pushover_message' => 'Server \'%LABEL%\' is running again, it was down for @@ -399,27 +454,50 @@ $sm_lang = array( %DATE%', 'on_telegram_message' => 'Server \'%LABEL%\' is running again, it was down for: %LAST_OFFLINE_DURATION%

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Date: + %DATE%', + 'on_jabber_message' => 'Server \'%LABEL%\' is running again, it was down for: + %LAST_OFFLINE_DURATION%

    Server: %LABEL%
    IP: %IP%
    Port: %PORT%
    Date: %DATE%', 'combi_off_email_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: %PORT%
    • Error: + %ERROR%
    • Date: %DATE%
    ', + 'combi_off_discord_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - Error: %ERROR%
    - + Date: %DATE%

    ', + 'combi_off_webhook_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: %PORT%
    • Error: %ERROR%
    • Date: %DATE%
    ', 'combi_off_pushover_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: %PORT%
    • Error: %ERROR%
    • Date: %DATE%
    ', 'combi_off_telegram_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - Error: %ERROR%
    - + Date: %DATE%

    ', + 'combi_off_jabber_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - Error: %ERROR%
    - Date: %DATE%

    ', 'combi_on_email_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: %PORT%
    • Downtime: %LAST_OFFLINE_DURATION%
    • Date: %DATE%
    ', + 'combi_on_webhook_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: + %PORT%
    • Downtime: %LAST_OFFLINE_DURATION%
    • Date: + %DATE%
    ', + 'combi_on_discord_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - + Downtime: %LAST_OFFLINE_DURATION%
    - Date: %DATE%

    ', 'combi_on_pushover_message' => '
    • Server: %LABEL%
    • IP: %IP%
    • Port: %PORT%
    • Downtime: %LAST_OFFLINE_DURATION%
    • Date: %DATE%
    ', 'combi_on_telegram_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - Downtime: + %LAST_OFFLINE_DURATION%
    - Date: %DATE%

    ', + 'combi_on_jabber_message' => '- Server: %LABEL%
    - IP: %IP%
    - Port: %PORT%
    - Downtime: %LAST_OFFLINE_DURATION%
    - Date: %DATE%

    ', '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_email_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following + servers are up again:
    %UP_SERVERS%', + 'combi_discord_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following + servers are up again:
    %UP_SERVERS%', + 'combi_webhook_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following servers are up again:
    %UP_SERVERS%', 'combi_pushover_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following servers are up again:
    %UP_SERVERS%', 'combi_telegram_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following + servers are up again:
    %UP_SERVERS%', + 'combi_jabber_message' => 'The following servers went down:
    %DOWN_SERVERS%
    The following servers are up again:
    %UP_SERVERS%', ), 'login' => array( @@ -437,8 +515,7 @@ $sm_lang = array( 'password_forgot' => 'Forgot password?', 'password_reset' => 'Reset password', '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 - in 1 hour.

    %link%', + 'password_reset_email_body' => 'Please use the following link to reset your password. Please note it expires in 1 hour.

    %link%', 'error_user_incorrect' => 'The provided username could not be found.', 'error_login_incorrect' => 'The information is incorrect.', 'error_login_passwords_nomatch' => 'The provided passwords do not match.', diff --git a/src/lang/es_ES.lang.php b/src/lang/es_ES.lang.php index ba2b9711..88ed969d 100644 --- a/src/lang/es_ES.lang.php +++ b/src/lang/es_ES.lang.php @@ -116,17 +116,17 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo - real. Vea su página web para más - información.', + real. Vea su página web para + más información.', 'pushover_key' => 'Clave Pushover', 'pushover_device' => 'Dispositivo Pushover', 'pushover_device_description' => 'Nombre del dispositivo para enviar el mensaje. Dejar en blanco para enviarlo a todos los dispositivos.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram is a chat app that makes it easy to - get real-time notifications. Visit the documentation for more info and an - install guide.', + 'telegram_description' => 'Telegram is a chat app that + makes it easy to get real-time notifications. Visit the documentation for more + info and an install guide.', 'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id_description' => 'El mensaje será enviado al chat correspondiente.', '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', '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 - real. Vea su página web para más - información.', + real. Vea su página web para + más información.', 'pushover_clone_app' => 'Haga clic aquí para crear tu aplicación Pushover', 'pushover_api_token' => 'Token API de Pushover', 'pushover_api_token_description' => 'Antes de poder utilizar Pushover, necesita registrar su aplicación en la página web e ingresar el token API.', 'telegram_status' => '¿Habilitar el envío de mensajes de Telegram?', - 'telegram_description' => 'Telegram es una aplicación de mensajería - instantánea que permite recibir notificaciones en tiempo real. Visite la documentación para una guía mas - detallada.', + 'telegram_description' => 'Telegram es una aplicación de + mensajería instantánea que permite recibir notificaciones en tiempo real. Visite + la documentación + para una guía mas detallada.', 'telegram_api_token' => 'Token API de Telegram', 'telegram_api_token_description' => 'Antes de utilizar Telegram, necesita un Token de API. Visite la documentación para más - información.', + href="http://docs.phpservermonitor.org/" + target="_blank">documentación para más información.', 'alert_type' => '¿Cuándo desea recibir notificaciones?', 'alert_type_description' => 'Al cambiar el estado: p.ej. en línea -> fuera de línea o fuera de línea -> en línea.

    Fuera de Línea: Recibirá una notificación cuando @@ -354,7 +354,6 @@ $sm_lang = array( 'auto_refresh' => 'Auto-actualizar', 'auto_refresh_description' => 'Auto-actualizar la página de servidores.
    Tiempo en segundos, si se utiliza 0 la página no se actualizará.', - 'seconds' => 'segundos', 'test' => 'Prueba', '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.', diff --git a/src/lang/et_ET.lang.php b/src/lang/et_ET.lang.php index 22921fb5..3c13a6ac 100644 --- a/src/lang/et_ET.lang.php +++ b/src/lang/et_ET.lang.php @@ -66,6 +66,7 @@ $sm_lang = array( 'a_minute_ago' => 'umbes minut aega tagasi', 'seconds_ago' => '%d sekundit tagasi', 'a_second_ago' => 'üks sekund tagasi', + 'seconds' => 'sekundit', ), 'menu' => array( 'config' => 'Konfiguratsioon', @@ -93,7 +94,8 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata nende kodulehte rohkema info jaoks.', + href="https://pushover.net/" target="_blank">nende kodulehte rohkema info + jaoks.', 'pushover_key' => 'Pushoveri Võti', 'pushover_device' => 'Pushoveri Seade', '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', 'pushover_status' => 'Luba Pushoveri sõnumite saatmine', 'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata nende kodulehte rohkema info jaoks.', + href="https://pushover.net/" target="_blank">nende kodulehte rohkema info + jaoks.', 'pushover_clone_app' => 'Kliki siia, et teha oma Pushover äpp', 'pushover_api_token' => 'Pushover Äppi API Žetoon', 'pushover_api_token_description' => 'Enne, kui saad Pushoverida pead sa 'Automaatne värskendamine', 'auto_refresh_description' => 'Värskenda lehte automaatselt.
    Aeg sekundites, kui 0 siis lehte ei värskendata.', - 'seconds' => 'sekundit', 'test' => 'Test', 'test_email' => 'Email saadetakse profiilil märgitud aadressile.', 'test_sms' => 'SMS saadetakse profiilil märgitud numbrile.', diff --git a/src/lang/fa_IR.lang.php b/src/lang/fa_IR.lang.php index 84be04cd..c5ecea6a 100644 --- a/src/lang/fa_IR.lang.php +++ b/src/lang/fa_IR.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'حدود یک دقیقه پیش', 'seconds_ago' => '%d ثانیه پیش', 'a_second_ago' => 'یک ثانیه پیش', + 'seconds' => 'ثانیه', ), 'menu' => array( 'config' => 'تنظیم', @@ -97,7 +98,8 @@ $sm_lang = array( 'pushover' => 'Pushover', 'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ را ساده می کند. برای اطلاعات بیشتر
    سایت آن ها را ببینید.', + href="https://pushover.net/" target="_blank">سایت آن ها را + ببینید.', 'pushover_key' => 'کلید Pushover', 'pushover_device' => 'دستگاه Pushover', 'pushover_device_description' => 'نام دستگاه برای ارسال پیام. برای ارسال به @@ -217,7 +219,8 @@ $sm_lang = array( 'pushover_status' => 'اجازه ارسال پیام های Pushover', 'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ را ساده می کند. برای اطلاعات بیشتر سایت آن ها را ببینید.', + href="https://pushover.net/" target="_blank">سایت آن ها را + ببینید.', 'pushover_clone_app' => 'برای ایجاد برنامه پوش آور خود اینجا را کلیک کنید.', 'pushover_api_token' => 'رمز API برنامه پوش آور', @@ -261,7 +264,6 @@ $sm_lang = array( 'auto_refresh' => 'رفرش خودکار', 'auto_refresh_description' => 'رفرش خودکار صفحه سرورها.
    زمان به ثنیه, اگر 0 باشد صفحه رفرش نخواهد شد.', - 'seconds' => 'ثانیه', 'test' => 'تست', 'test_email' => 'یک ایمیل به آدرس تعیین شده در پروفایل شما ارسال خواهد شد.', diff --git a/src/lang/fi_FI.lang.php b/src/lang/fi_FI.lang.php index b0271779..17dec27d 100644 --- a/src/lang/fi_FI.lang.php +++ b/src/lang/fi_FI.lang.php @@ -94,7 +94,7 @@ $sm_lang = array( 'email' => 'Sähköposti', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso - verkkosivuilta lisäinfoa.', + verkkosivuilta lisäinfoa.', 'pushover_key' => 'Pushover avain', 'pushover_device' => 'Pushover laite', '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', 'pushover_status' => 'Salli Pushover-viestien lähetys', 'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso - verkkosivuilta lisäinfoa.', + verkkosivuilta lisäinfoa.', 'pushover_clone_app' => 'Paina tästä luodaksesi Pushover-sovelluksesi', 'pushover_api_token' => 'Pushover API-avain', 'pushover_api_token_description' => 'Ennen kuin voit käyttää Pushoveria, sinun täytyy 'Automaattipäivitys', 'auto_refresh_description' => 'Päivittää automaattisesti palvelimet-sivun.
    Aika sekunteina, jos 0, sivu ei päivity automaattisesti.', - 'seconds' => 'sekuntia', 'test' => 'Testi', 'test_email' => 'Testisähköposti lähetetään profiilisi sähköpostiosoitteeseen.', 'test_sms' => 'Testitekstiviesti lähetetään profiilisi numeroon.', diff --git a/src/lang/fr_FR.lang.php b/src/lang/fr_FR.lang.php index 9babc7c3..e2bac203 100644 --- a/src/lang/fr_FR.lang.php +++ b/src/lang/fr_FR.lang.php @@ -113,16 +113,18 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir
    leur site web pour plus d\'informations.', + href="https://pushover.net/" target="_blank">leur site web pour plus + d\'informations.', 'pushover_key' => 'Clé Pushover', 'pushover_device' => 'Appareil Pushover', 'pushover_device_description' => 'Nom de l\'appareil auquel le message doit être envoyé. Laissez vide pour l\'envoyer à tous les appareils.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram est une application de messagerie - instantanée qui facilite la réception de notification en temps réel. Lisez la documentation pour obtenir plus - d\'informations sur la configuration de ce service.', + 'telegram_description' => 'Telegram est une application de + messagerie instantanée qui facilite la réception de notification en temps réel. + Lisez la documentation pour obtenir plus d\'informations sur la + configuration de ce service.', 'telegram_chat_id' => 'ID de conversation (Chat ID) Telegram', '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)', @@ -302,22 +304,23 @@ $sm_lang = array( 'sms_from' => 'SMS de l\'expéditeur', 'pushover_status' => 'Autoriser l\'envoi des messages Pushover', 'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir leur site web pour plus d\'informations.', + href="https://pushover.net/" target="_blank">leur site web pour plus + d\'informations.', 'pushover_clone_app' => 'Cliquez ici pour créer votre application Pushover', 'pushover_api_token' => 'Jeton application Pushover', 'pushover_api_token_description' => 'Avant de pouvoir utiliser Pushover, vous devez créer une application sur leur site web et entrer ici le jeton (Token) de l\'application.', 'telegram_status' => 'Autorise l\'envoi de message Telegram', - 'telegram_description' => 'Telegram est une application de messagerie - instantanée qui facilite la réception de notification en temps réel. Lisez la documentation pour obtenir plus - d\'informations sur la configuration de ce service.', + 'telegram_description' => 'Telegram est une application de + messagerie instantanée qui facilite la réception de notification en temps réel. + Lisez la documentation pour obtenir plus d\'informations sur la + configuration de ce service.', 'telegram_api_token' => 'Token API Telegram', 'telegram_api_token_description' => 'Afin de pouvoir utiliser Telegram, il vous faut obtenir un token api. - Consultez la documentation pour obtenir - de l\'aide.', + Consultez la documentation pour obtenir de l\'aide.', 'alert_type' => 'Choisissez quand vous souhaitez être notifié', 'alert_type_description' => 'Changement d\'état : Vous recevez une notification chaque fois que 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_description' => 'Auto-rachaîchissement de la page serveurs.
    Temps en secondes. Si 0, la page n\'est pas rafraîchie.', - 'seconds' => 'secondes', 'test' => 'Tester', '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.', diff --git a/src/lang/it_IT.lang.php b/src/lang/it_IT.lang.php index 80d15d76..29907826 100644 --- a/src/lang/it_IT.lang.php +++ b/src/lang/it_IT.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'circa un minuto fa', 'seconds_ago' => '%d secondi fa', 'a_second_ago' => 'un secondo fa', + 'seconds' => 'secondi', ), 'menu' => array( 'config' => 'Configurazione', @@ -247,7 +248,6 @@ $sm_lang = array( 'auto_refresh' => 'Auto-Aggiornamento', 'auto_refresh_description' => 'Auto-Aggiornamento pagina servers.
    Tempo in secondi, se impostato a 0 la pagina non si aggiornerà.', - 'seconds' => 'secondi', 'test' => 'Test', '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.', diff --git a/src/lang/ja_JP.lang.php b/src/lang/ja_JP.lang.php index 3b6831f1..c15c60a4 100644 --- a/src/lang/ja_JP.lang.php +++ b/src/lang/ja_JP.lang.php @@ -345,7 +345,6 @@ $sm_lang = array( 'auto_refresh' => '自動更新', 'auto_refresh_description' => 'サーバーページを自動更新します。
    時間を秒で指定し、0に設定すると更新しません。', - 'seconds' => '秒', 'test' => 'テスト', 'test_email' => 'あなたのユーザープロフィールで指定されたアドレスに電子メールが送信されます。', 'test_sms' => 'あなたのユーザープロフィールで指定された電話番号にSMSが送信されます。', diff --git a/src/lang/nl_NL.lang.php b/src/lang/nl_NL.lang.php index bc1da5e1..a5a1c728 100644 --- a/src/lang/nl_NL.lang.php +++ b/src/lang/nl_NL.lang.php @@ -81,6 +81,8 @@ $sm_lang = array( 'minutes' => 'minuten', 'second' => 'seconde', 'seconds' => 'seconden', + 'millisecond' => 'milliseconde', + 'milliseconds' => 'milliseconden', 'current' => 'huidig', 'settings' => 'Instellingen', ), @@ -110,8 +112,8 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te - ontvangen. Zie hun website voor meer - informatie.', + ontvangen. Zie hun website voor + meer informatie.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', 'pushover_device_description' => 'Apparaat waar de berichten naar toe gaan. Laat leeg voor alle apparaten.', @@ -244,6 +246,7 @@ $sm_lang = array( ), 'config' => array( 'general' => 'Algemeen', + 'site_title' => 'Website titel', 'language' => 'Taal', 'show_update' => 'Controleer wekelijks voor updates?', 'email_status' => 'Sta email berichten toe?', @@ -264,8 +267,8 @@ $sm_lang = array( 'sms_from' => 'Telefoonnummer afzender', 'pushover_status' => 'Sta Pushover berichten toe?', 'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te - ontvangen. Zie hun website voor meer - informatie.', + ontvangen. Zie hun website voor + meer informatie.', 'pushover_clone_app' => 'Klik hier om je Pushover app te maken', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een 'Herlaad automatisch', 'auto_refresh_description' => 'Auto-herladen servers pagina.
    Tijd in seconden, als de tijd 0 is wordt de pagina niet ververst.', - 'seconds' => 'seconden', 'test' => 'Test', '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.', @@ -336,6 +338,9 @@ $sm_lang = array( '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.', '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( 'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%', diff --git a/src/lang/no_NB.lang.php b/src/lang/no_NB.lang.php index d6b2c44e..e73ccc55 100644 --- a/src/lang/no_NB.lang.php +++ b/src/lang/no_NB.lang.php @@ -107,16 +107,16 @@ $sm_lang = array( 'email' => 'E-post', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å få meldinger i sanntid. Se
    deres nettside for mer info.', + href="https://pushover.net/" target="_blank">deres nettside for mer info.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', 'pushover_device_description' => 'Enhetsnavn for å sende meldingen til. La det være tomt for å sende det til alle enheter.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram er en chat-app som gjør det enkelt å - få meldinger i sanntid. Gå til dokumentasjonen for mer informasjon og - en installasjonsguide. ', + 'telegram_description' => 'Telegram er en chat-app som + gjør det enkelt å få meldinger i sanntid. Gå til dokumentasjonen for + mer informasjon og en installasjonsguide. ', 'telegram_chat_id' => 'Telegram chat-ID', 'telegram_chat_id_description' => 'Meldingen vil bli sendt til tilhørende chat.', 'telegram_get_chat_id' => 'Klikk her for å få chat-ID', @@ -276,21 +276,21 @@ $sm_lang = array( 'sms_from' => 'Avsenderens telefonnummer', 'pushover_status' => 'Tillat sending av Pushover-meldinger', 'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å få meldinger i sanntid. Se deres nettside for mer info.', + href="https://pushover.net/" target="_blank">deres nettside for mer info.', 'pushover_clone_app' => 'Klikk her for å lage din Pushover-app', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Før du kan bruke Pushover, må du registrere en app på deres nettside og angi App API Token her.', 'telegram_status' => 'Tillat sending av Telegram-meldinger', - 'telegram_description' => 'Telegram er en chat-app som gjør det enkelt å - få meldinger i sanntid. Gå til dokumentasjonen for mer informasjon og - en installasjonsveiledning.', + 'telegram_description' => 'Telegram er en chat-app som + gjør det enkelt å få meldinger i sanntid. Gå til dokumentasjonen for + mer informasjon og en installasjonsveiledning.', 'telegram_api_token' => 'Telegram API Token', 'telegram_api_token_description' => 'Før du kan bruke Telegram, må du få en API-token. Gå til dokumentasjonen for å få - hjelp.', + href="http://docs.phpservermonitor.org/" + target="_blank">dokumentasjonen for å få hjelp.', 'alert_type' => 'Velg når du vil bli varslet.', 'alert_type_description' => 'Statusendring: Du vil motta et varsel når en server har endret status. Så fra online -> offline eller offline -> online.

    Offline: Du @@ -326,7 +326,6 @@ $sm_lang = array( 'auto_refresh' => 'Auto-refresh', 'auto_refresh_description' => 'Auto-refresh server side.
    Tid i sekunder, hvis 0 siden ikke blir oppdatert.', - 'seconds' => 'sekunder', 'test' => 'Test', '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.', diff --git a/src/lang/pl_PL.lang.php b/src/lang/pl_PL.lang.php index 49dd2158..1fa25092 100644 --- a/src/lang/pl_PL.lang.php +++ b/src/lang/pl_PL.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'minutę temu', 'seconds_ago' => '%d sekund temu', 'a_second_ago' => 'sekundę temu', + 'seconds' => 'sekund', ), 'menu' => array( 'config' => 'Konfiguracja', @@ -95,7 +96,7 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover jest usługą szybkich notyfikacji. Sprawdź ich stronę po więcej informacji.', + href="https://pushover.net/" target="_blank">ich stronę po więcej informacji.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Urządzenie dla Pushover', 'pushover_device_description' => 'Nazwa urządzenia do którego wysłać powiadomienie. Pozostaw puste aby @@ -191,6 +192,7 @@ $sm_lang = array( ), 'config' => array( 'general' => 'Ogólne', + 'site_title' => 'Tytuł strony', 'language' => 'Język', 'show_update' => 'Sprawdzić aktualizacje?', 'email_status' => 'Pozwól na wysyłkę email', @@ -211,8 +213,8 @@ $sm_lang = array( 'sms_from' => 'Numer nadawcy', 'pushover_status' => 'Pozwól na wysyłkę notyfikacji Pushover', 'pushover_description' => 'Pushover jest usługą ułatwiającą otrzymywanie powiadomień w czasie - rzeczywistym. Sprawdź ich stronę aby uzyskać - więcej informacji.', + rzeczywistym. Sprawdź ich + stronę aby uzyskać więcej informacji.', 'pushover_clone_app' => 'Kliknij tutaj aby stworzyć aplikację korzystającą z Pushover', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Zanim zaczniesz używać Pushover, musisz 'Auto-odświeżanie', 'auto_refresh_description' => 'Auto-odświeżanie strony serwera.
    Czas w sekundach, dla czasu 0 strona nie będzie odświeżana.', - 'seconds' => 'sekund', 'test' => 'Test', 'test_email' => 'Email zostanie wysłany na adres 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 logów.', '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( 'off_sms' => 'Serwer \'%LABEL%\' przestał odpowiadać: ip=%IP%, port=%PORT%. Błąd=%ERROR%', diff --git a/src/lang/pt_BR.lang.php b/src/lang/pt_BR.lang.php index 5017ce68..91ead663 100644 --- a/src/lang/pt_BR.lang.php +++ b/src/lang/pt_BR.lang.php @@ -66,6 +66,7 @@ $sm_lang = array( 'a_minute_ago' => 'cerca de um minuto atrás', 'seconds_ago' => '%d segundos atrás', 'a_second_ago' => 'um segundo atrás', + 'seconds' => 'segundos', ), 'menu' => array( 'config' => 'Configuração', @@ -93,7 +94,7 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover para enviar notificações em real-tome. Veja
    o website para mais informações.', + href="https://pushover.net/" target="_blank">o website para mais informações.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', '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', 'pushover_status' => 'Habilitar envio de mensagens Pushover', 'pushover_description' => 'Pushover é um serviço de notificações em tempo real. Veja o website para mais informações.', + href="https://pushover.net/" target="_blank">o website para mais informações.', 'pushover_clone_app' => 'Clique aqui para criar sua app Pushover', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Before you can use Pushover, you need to 'Atualizar automaticamente', 'auto_refresh_description' => 'Atualizar automaticamente a página de servidores.
    Tempo em segundos, Se 0 a página não será atualizada.', - 'seconds' => 'segundos', 'test' => 'Teste', '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.', diff --git a/src/lang/ru_RU.lang.php b/src/lang/ru_RU.lang.php index fb038f86..40ad4041 100644 --- a/src/lang/ru_RU.lang.php +++ b/src/lang/ru_RU.lang.php @@ -113,7 +113,7 @@ $sm_lang = array( 'pushover_description' => 'Pushover - это сервис, который позволяет легко получать уведомления в режиме реального времени. Больше информации на
    их веб-сайте.', + href="https://pushover.net/" target="_blank">их веб-сайте.', 'pushover_key' => 'Pushover ключ', 'pushover_device' => 'Pushover устройство', 'pushover_device_description' => 'Имя устройства, на которое будут @@ -121,12 +121,12 @@ $sm_lang = array( пустым, что бы отправлять уведомления на все устройства.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram удобный мессенджер - для получения уведомлений в реальном - времени. Посетите раздел документации - для получения доп. информации и инструкций по - установке.', + 'telegram_description' => 'Telegram удобный + мессенджер для получения уведомлений в + реальном времени. Посетите раздел + документации для получения доп. информации + и инструкций по установке.', 'telegram_chat_id' => 'Telegram chat id', 'telegram_chat_id_description' => 'Сообщения будут отправляться на указанный идентификатор чата.', @@ -304,7 +304,7 @@ $sm_lang = array( 'pushover_description' => 'Pushover - это сервис, который позволяет легко получать уведомления в режиме реального времени. Больше информации на их веб-сайте.', + href="https://pushover.net/" target="_blank">их веб-сайте.', 'pushover_clone_app' => 'Нажмите здесь чтобы создать ваш Pushover app', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Прежде чем вы сможете начать @@ -313,17 +313,17 @@ $sm_lang = array( rel="noopener">"App" на их веб-сайте и ввести "App API Token" сюда.', 'telegram_status' => 'Разрешить отправку уведомлений в Telegram', - 'telegram_description' => 'Telegram удобный мессенджер - для получения уведомлений в реальном - времени. Посетите раздел документации - для получения доп. информации и инструкций по - установке.', + 'telegram_description' => 'Telegram удобный + мессенджер для получения уведомлений в + реальном времени. Посетите раздел + документации для получения доп. информации + и инструкций по установке.', 'telegram_api_token' => 'Telegram API Token', 'telegram_api_token_description' => 'Прежде чем вы сможете начать пользоваться Telegram, вам необходимо получить API Token. Посетите раздел + href="http://docs.phpservermonitor.org/" target="_blank">раздел документации для получения помощи.', 'alert_type' => 'Тип уведомлений', 'alert_type_description' => 'Изменение статуса: Вы получите @@ -371,7 +371,6 @@ $sm_lang = array( серверов.
    Время в секундах. Если указано 0, то страница не будет обновляться.', - 'seconds' => 'секунд', 'test' => 'Проверка', 'test_email' => 'Сообщение будет отправлено на адрес указаный в профиле пользователя.', diff --git a/src/lang/sk_SK.lang.php b/src/lang/sk_SK.lang.php index f40379b0..f8faa782 100644 --- a/src/lang/sk_SK.lang.php +++ b/src/lang/sk_SK.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'cca pred minútou', 'seconds_ago' => 'pred %d sekundami', 'a_second_ago' => 'pred chvíľou', + 'seconds' => 'sekúnd', ), 'menu' => array( 'config' => 'Konfigurácia', @@ -259,7 +260,6 @@ $sm_lang = array( 'auto_refresh' => 'Automaticky obnoviť', 'auto_refresh_description' => 'Automaticky obnoviť stránku Servery.
    Čas v sekundách, 0 pre vypnutie automatického obnovenia.', - 'seconds' => 'sekúnd', 'test' => 'Test', '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.', diff --git a/src/lang/sl_SI.lang.php b/src/lang/sl_SI.lang.php index da9b046f..5dcf73df 100644 --- a/src/lang/sl_SI.lang.php +++ b/src/lang/sl_SI.lang.php @@ -65,6 +65,7 @@ $sm_lang = array( 'a_minute_ago' => 'pred približno minuto', 'seconds_ago' => 'pred %d sekundami', 'a_second_ago' => 'pred sekundo', + 'seconds' => 'sekund', ), 'menu' => array( 'config' => 'Nastavitve', @@ -92,8 +93,8 @@ $sm_lang = array( 'email' => 'E-pošta', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času. - Več informacij je na voljo na njihovi spletni - strani.', + Več informacij je na voljo na + njihovi spletni strani.', 'pushover_key' => 'Pushover ključ', 'pushover_device' => 'Pushover naprava', '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', 'pushover_status' => 'Dovolim pošiljanje Pushover sporočil', 'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času. - Več informacij je na voljo na njihovi spletni - strani.', + Več informacij je na voljo na + njihovi spletni strani.', 'pushover_clone_app' => 'Kliknite za ustvarjanje vaše Pushover aplikacije', 'pushover_api_token' => 'Pushover API žeton', 'pushover_api_token_description' => 'Pred uporabo storitve Pushover, morate na njihovi spletni strani 'Samodejno posodabljanje pregleda statusa strežnikov.
    Čas v sekundah. Če je vrednost 0 se stran ne bo samodejno posodabljala.', - 'seconds' => 'sekund', 'test' => 'Test', '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.', diff --git a/src/lang/sv_SE.lang.php b/src/lang/sv_SE.lang.php index 37420272..ca8ae553 100644 --- a/src/lang/sv_SE.lang.php +++ b/src/lang/sv_SE.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'ungefär en minut sen', 'seconds_ago' => '%d sekunder sedan', 'a_second_ago' => 'en sekund sedan', + 'seconds' => 'sekunder', ), 'menu' => array( 'config' => 'Inställningar', @@ -94,7 +95,8 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se
    deras webbsida för mer information.', + href="https://pushover.net/" target="_blank">deras webbsida för mer + information.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', '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', 'pushover_status' => 'Tillåt Pushover-meddelande', 'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se deras webbsida för mer info.', + href="https://pushover.net/" target="_blank">deras webbsida för mer info.', 'pushover_clone_app' => 'Klicka här för att skapa din Pushover app', 'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Innan du kan använda Pushover behöver du 'Auto-uppdatera', 'auto_refresh_description' => 'Auto-uppdatera status-sidan.
    Tid i sekunder, om "0" så uppdateras sidan inte automatiskt.', - 'seconds' => 'sekunder', 'test' => 'Test', 'test_email' => 'Ett emial kommer skickas till adressen i din profil.', 'test_sms' => 'Ett SMS kommer skickas till mobilnumret i din profil.', diff --git a/src/lang/tr_TR.lang.php b/src/lang/tr_TR.lang.php index 85cbca61..efc6d6ce 100644 --- a/src/lang/tr_TR.lang.php +++ b/src/lang/tr_TR.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => 'yaklaşık bir dakika önce', 'seconds_ago' => '%d saniye önce', 'a_second_ago' => 'bir saniye önce', + 'seconds' => 'saniye', ), 'menu' => array( 'config' => 'Ayarlar', @@ -95,7 +96,7 @@ $sm_lang = array( 'email' => 'E-posta', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi - için
    sitesine bakabilirsiniz.', + için sitesine bakabilirsiniz.', 'pushover_key' => 'Pushover Anahtarı', 'pushover_device' => 'Pushover Aracı', '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ı', 'pushover_status' => 'Pushover mesaj gönderimine izin ver', 'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi - için sitesine bakabilirsiniz.', + için sitesine bakabilirsiniz.', '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_description' => 'Pushover kullanmadan önce, 'Otomatik Yenileme', 'auto_refresh_description' => 'Otomatik yenileme sunucu sayfası
    Eğer sayfa yenilenmez ise.', - 'seconds' => 'saniye', 'test' => 'Test', '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.', diff --git a/src/lang/uk_UA.lang.php b/src/lang/uk_UA.lang.php index 5a1c5a05..bdc02c74 100644 --- a/src/lang/uk_UA.lang.php +++ b/src/lang/uk_UA.lang.php @@ -116,7 +116,7 @@ $sm_lang = array( 'pushover' => 'Pushover', 'pushover_description' => 'Pushover — сервіс, що дозволяє легко отримувати сповіщення у реальному часі. За деталями - перейдіть на
    їхній + перейдіть на їхній вебсайт.', 'pushover_key' => 'Ключ Pushover', 'pushover_device' => 'Пристрій Pushover', @@ -124,11 +124,12 @@ $sm_lang = array( повідомлення. Залиште пустим, щоб надсилати на всі пристрої.', 'telegram' => 'Telegram', - 'telegram_description' => 'Telegram — чат-застосунок, що - дозволяє легко отримувати сповіщення у - реальному часі. За деталями й інструкцією зі - встановлення зверніться до документації.', + 'telegram_description' => 'Telegram — + чат-застосунок, що дозволяє легко отримувати + сповіщення у реальному часі. За деталями й + інструкцією зі встановлення зверніться до документації.', 'telegram_chat_id' => 'Ідентифікатор чату Telegram', 'telegram_chat_id_description' => 'Повідомлення буде надіслане у відповідний чат.', @@ -330,8 +331,8 @@ $sm_lang = array( 'pushover_status' => 'Дозволити надсилання Pushover-повідомлень', 'pushover_description' => 'Pushover — сервіс, що дозволяє легко отримувати сповіщення у реальному часі. За детальнішою - інформацію перейдіть на їхній вебсайт.', + інформацію перейдіть на їхній вебсайт.', 'pushover_clone_app' => 'Натисніть тут, щоб створити ваш Pushover-додаток', 'pushover_api_token' => 'Токен API Pushover-додатку', 'pushover_api_token_description' => 'Перед використанням Pushover ви маєте на їхньому вебсайті та ввести токен API Додатку тут.', 'telegram_status' => 'Дозволити надсилання Telegram-повідомлень', - 'telegram_description' => 'Telegram — чат-застосунок, що - дозволяє легко отримувати сповіщення у - реальному часі. Детальніша інформація та - інструкція зі встановлення доступні у документації.', + 'telegram_description' => 'Telegram — + чат-застосунок, що дозволяє легко отримувати + сповіщення у реальному часі. Детальніша + інформація та інструкція зі встановлення + доступні у документації.', 'telegram_api_token' => 'Токен Telegram API', 'telegram_api_token_description' => 'Перед використанням Telegram ви маєте отримати токен API. За довідкою - зверніться до документації.', + зверніться до документації.', 'alert_type' => 'Виберіть, коли б вам хотілося отримувати сповіщення.', 'alert_type_description' => 'Зміна статусу: Ви отримуватимете @@ -404,7 +406,6 @@ $sm_lang = array( 'auto_refresh_description' => 'Сторінка автооновлення серверів.
    Час у секундах; якщо 0, сторінка не оновлюватиметься.', - 'seconds' => 'секунд', 'test' => 'Тест', 'test_email' => 'Електронний лист буде надісланий на адресу, вказану у вашому профілі користувача.', diff --git a/src/lang/vi_VN.lang.php b/src/lang/vi_VN.lang.php index 887abe90..9a5d7ef8 100644 --- a/src/lang/vi_VN.lang.php +++ b/src/lang/vi_VN.lang.php @@ -64,6 +64,7 @@ $sm_lang = array( 'a_minute_ago' => 'khoảng một phút trước', 'seconds_ago' => '%d giây trước', 'a_second_ago' => 'một giây trước', + 'seconds' => 'giây', ), 'menu' => array( 'config' => 'Cấu hình', @@ -91,8 +92,8 @@ $sm_lang = array( 'email' => 'Email', 'pushover' => 'Pushover', 'pushover_description' => 'Pushover là một dịch vụ dễ dàng nhận các thông báo theo thời gian - thực. Xem website của họ để biết - thêm thông tin.', + thực. Xem website của họ + để biết thêm thông tin.', 'pushover_key' => 'Pushover Key', 'pushover_device' => 'Pushover Device', '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', 'pushover_status' => 'Cho phép gửi tin nhắn bằng Pushover', 'pushover_description' => 'Pushover là một dịch vụ dễ dàng nhận các thông báo theo thời gian - thực. Xem website của họ để biết - thêm thông tin.', + thực. Xem website của họ + để 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_api_token' => 'Pushover App API Token', 'pushover_api_token_description' => 'Trước khi bạn có thể sử dụng Pushover, bạn cần phải 'Tự động làm mới', 'auto_refresh_description' => 'Tự động làm mới servers page.
    Trong vài giây, nếu 0 trang sẽ không làm mới.', - 'seconds' => 'giây', 'test' => 'Thử', 'test_email' => 'Một email sẽ được gửi đến địa chỉ được xác định trong hồ sơ người dùng của bạn.', diff --git a/src/lang/zh_CN.lang.php b/src/lang/zh_CN.lang.php index a33c6664..2d593b54 100644 --- a/src/lang/zh_CN.lang.php +++ b/src/lang/zh_CN.lang.php @@ -67,6 +67,7 @@ $sm_lang = array( 'a_minute_ago' => '1分钟前', 'seconds_ago' => '%d 秒前', 'a_second_ago' => '刚刚', + 'seconds' => '秒', ), 'menu' => array( 'config' => '设置', @@ -124,9 +125,6 @@ $sm_lang = array( 'sms' => '短信', 'pushover' => 'Pushover', 'no_logs' => '没有日志', - 'clear' => 'Clear log', - 'delete_title' => 'Delete log', - 'delete_message' => 'Are you sure you want to delete all logs?', ), 'servers' => array( 'server' => '业务', @@ -262,7 +260,6 @@ $sm_lang = array( 'auto_refresh' => '自动刷新', 'auto_refresh_description' => '自动刷新服务器页.
    单位为秒, 设置为 0 则不自动刷新.', - 'seconds' => '秒', 'test' => '测试', 'test_email' => '将发送一封邮件到您账户设置的邮件地址.', 'test_sms' => '将发送一封短信到您账户设置的手机号码.', diff --git a/src/lang/zh_TW.lang.php b/src/lang/zh_TW.lang.php new file mode 100644 index 00000000..0069f8bd --- /dev/null +++ b/src/lang/zh_TW.lang.php @@ -0,0 +1,368 @@ +. + * + * @package phpservermon + * @author Jason Cheng + * @copyright Copyright (c) 2008-2014 Pepijn Over + * @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' => '超級管理員 + 具備所有伺服器的管理權限,可管理使用者以及修改系統設定。
    一般使用者 + 僅能查看以及更新自己所負責的伺服器。', + 'mobile' => '行動電話', + 'email' => '電子郵件', + 'pushover' => 'Pushover 通知', + 'pushover_description' => 'Pushover + 是一種雲端服務,讓你可以很方便的收到即時訊息通知,您可以到
    網站了解更多的內容。', + 'pushover_key' => 'Pushover 金鑰', + 'pushover_device' => 'Pushover 裝置', + 'pushover_device_description' => '發送訊息的裝置名稱,若保留空白,將會發送到所有的裝置。', + 'telegram' => 'Telegram 通知', + 'telegram_description' => 'Telegram + 是一種聊天應用程式,它提供很容易使用的的即時通知能力。您可以到 + documentation + 了解更多的內容。', + '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' => '您確定要刪除 所有 記錄?', + ), + '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是線上服務,讓您可以方便的收到即時通知,請參考 網站 + 可以得到更詳細的資訊。 ', + 'pushover_clone_app' => '點選這裡可快速建立Pushover App', + 'pushover_api_token_description' => '在您使用 Pushover 通知之前,需要先到這裡->註冊Pushover App帳號 + 接著在這個網頁輸入你的的Pushover App API Token號碼。', + 'telegram_status' => '允許發送 Telegram 訊息', + 'telegram_description' => 'Telegram + 是一種聊天應用程式,它提供很容易使用的即時通知服務。請參考 + 文件庫 + 可以取得更多資訊與安裝說明。', + 'telegram_api_token_description' => '使用 Telegram 通知之前,您必需先取得 API Token。請到 文件庫 + 取得說明。', + 'alert_type' => '需要提醒的類別', + 'alert_type_description' => '狀態改變: 伺服器 連線 -> 離線或連線 -> + 連線的狀態變化將會收到提醒通知。

    離線: + 伺服器首次發生離線狀態將會收到提醒,如:設定為15分鐘執行一次,伺服器從1:00-6:00一直處於離線狀態那麼你將會在1:00首次收到一則提醒通知,之後便不會在收到重覆的提醒通知。

    全部: + 每次執行當伺服器離線(即使伺服器離線很久已提醒過了)均發送提醒通知。', + 'alert_type_status' => '狀態改變', + 'alert_type_offline' => '離線', + 'alert_type_always' => '全部', + 'alert_proxy_url' => '格式: 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' => '無法連線到以下伺服器:

    伺服器: %LABEL%
    IP: %IP%
    Port: + %PORT%
    錯誤: %ERROR%
    日期: %DATE%', + 'off_pushover_title' => '伺服器 \'%LABEL%\' 關機', + 'off_pushover_message' => '無法連線到以下伺服器:

    伺服器: %LABEL%
    IP: %IP%
    Port: + %PORT%
    錯誤: %ERROR%
    日期: %DATE%', + 'off_telegram_message' => '無法連線到以下伺服器:

    伺服器: %LABEL%
    IP: %IP%
    Port: + %PORT%
    錯誤: %ERROR%
    日期: %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小時後失效。

    %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' => '您没有權限進入這個頁面。', + ), +); diff --git a/src/psm/Module/AbstractController.php b/src/psm/Module/AbstractController.php index 2fe2209b..d5cc0187 100644 --- a/src/psm/Module/AbstractController.php +++ b/src/psm/Module/AbstractController.php @@ -217,7 +217,7 @@ abstract class AbstractController implements ControllerInterface if (!$this->xhr) { // in XHR mode, we will not add the main template $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'), 'add_footer' => $this->add_footer, 'version' => 'v' . PSM_VERSION, diff --git a/src/psm/Module/Config/Controller/ConfigController.php b/src/psm/Module/Config/Controller/ConfigController.php index 52b6920c..df524c4d 100644 --- a/src/psm/Module/Config/Controller/ConfigController.php +++ b/src/psm/Module/Config/Controller/ConfigController.php @@ -43,13 +43,19 @@ class ConfigController extends AbstractController 'email_status', 'email_smtp', 'sms_status', + 'discord_status', 'pushover_status', + 'webhook_status', 'telegram_status', + 'jabber_status', 'log_status', 'log_email', 'log_sms', + 'log_discord', 'log_pushover', + 'log_webhook', 'log_telegram', + 'log_jabber', 'show_update', 'combine_notifications', ); @@ -67,14 +73,30 @@ class ConfigController extends AbstractController 'email_smtp_host', 'email_smtp_port', 'email_smtp_username', - 'email_smtp_password', 'sms_gateway_username', 'sms_gateway_password', 'sms_from', + 'webhook_url', + 'webhook_json', 'pushover_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'; 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['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'; - $testmodals = array('email', 'sms', 'pushover', 'telegram'); + $testmodals = array('email', 'sms', 'discord', 'webhook', 'pushover', 'telegram', 'jabber'); + foreach ($testmodals as $modal_id) { $modal = new \psm\Util\Module\Modal( $this->twig, @@ -206,6 +241,7 @@ class ConfigController extends AbstractController // save new config $clean = array( 'language' => $_POST['language'], + 'site_title' => $_POST['site_title'], 'sms_gateway' => $_POST['sms_gateway'], 'alert_type' => $_POST['alert_type'], 'email_smtp_security' => @@ -214,7 +250,7 @@ class ConfigController extends AbstractController : '', 'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)), '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) { $clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0'; @@ -224,6 +260,13 @@ class ConfigController extends AbstractController $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')); foreach ($clean as $key => $value) { psm_update_conf($key, $value); @@ -234,10 +277,16 @@ class ConfigController extends AbstractController $this->testEmail(); } elseif (!empty($_POST['test_sms'])) { $this->testSMS(); + } elseif (!empty($_POST['test_discord'])) { + $this->testDiscord(); } elseif (!empty($_POST['test_pushover'])) { $this->testPushover(); + }elseif (!empty($_POST['test_webhook'])) { + $this->testWebhook(); } elseif (!empty($_POST['test_telegram'])) { $this->testTelegram(); + } elseif (!empty($_POST['test_jabber'])) { + $this->testJabber(); } if ($language_refresh) { @@ -251,10 +300,16 @@ class ConfigController extends AbstractController $this->default_tab = 'email'; } elseif (isset($_POST['sms_submit']) || !empty($_POST['test_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'])) { $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'])) { $this->default_tab = 'telegram'; + } elseif (isset($_POST['jabber_submit']) || !empty($_POST['test_jabber'])) { + $this->default_tab = 'jabber'; } } 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 * @@ -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() { return array( 'label_tab_email' => psm_get_lang('config', 'tab_email'), '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_webhook' => psm_get_lang('config', 'tab_webhook'), '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_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_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_log' => psm_get_lang('config', 'settings_log'), '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_password' => psm_get_lang('config', 'sms_gateway_password'), '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_status' => psm_get_lang('config', 'pushover_status'), '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_api_token' => psm_get_lang('config', 'telegram_api_token'), '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_description' => psm_get_lang('config', 'alert_type_description'), '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_email' => psm_get_lang('config', 'log_email'), '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_webhook' => psm_get_lang('config', 'log_webhook'), '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_url' => psm_get_lang('config', 'alert_proxy_url'), 'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'), '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_test' => psm_get_lang('config', 'test'), '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_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'), ); } } diff --git a/src/psm/Module/Install/Controller/InstallController.php b/src/psm/Module/Install/Controller/InstallController.php index 3a4ee208..b1b9bc0b 100644 --- a/src/psm/Module/Install/Controller/InstallController.php +++ b/src/psm/Module/Install/Controller/InstallController.php @@ -101,6 +101,53 @@ class InstallController extends AbstractController if (!in_array('mysql', \PDO::getAvailableDrivers())) { $errors++; $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')) { $this->addMessage( @@ -256,7 +303,10 @@ class InstallController extends AbstractController 'level' => PSM_USER_ADMIN, 'pushover_key' => '', 'pushover_device' => '', + 'webhook_url' => '', + 'webhook_json' => '', 'telegram_id' => '', + 'jabber' => '' ); $validator = $this->container->get('util.user.validator'); diff --git a/src/psm/Module/Server/Controller/AbstractServerController.php b/src/psm/Module/Server/Controller/AbstractServerController.php index 1a1c210e..8ae2968c 100644 --- a/src/psm/Module/Server/Controller/AbstractServerController.php +++ b/src/psm/Module/Server/Controller/AbstractServerController.php @@ -81,10 +81,15 @@ abstract class AbstractServerController extends AbstractController `s`.`active`, `s`.`email`, `s`.`sms`, + `s`.`discord`, + `s`.`webhook`, `s`.`pushover`, `s`.`telegram`, + `s`.`jabber`, `s`.`warning_threshold`, `s`.`warning_threshold_counter`, + `s`.`ssl_cert_expiry_days`, + `s`.`ssl_cert_expired_time`, `s`.`timeout`, `s`.`website_username`, `s`.`website_password`, @@ -111,7 +116,7 @@ abstract class AbstractServerController extends AbstractController */ 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_offline'] = psm_timespan($server['last_offline']); 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']); - 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'; } diff --git a/src/psm/Module/Server/Controller/LogController.php b/src/psm/Module/Server/Controller/LogController.php index b84ac85d..39817695 100644 --- a/src/psm/Module/Server/Controller/LogController.php +++ b/src/psm/Module/Server/Controller/LogController.php @@ -55,8 +55,11 @@ class LogController extends AbstractServerController 'label_status' => psm_get_lang('log', 'status'), 'label_email' => psm_get_lang('log', 'email'), 'label_sms' => psm_get_lang('log', 'sms'), + 'label_discord' => psm_get_lang('log', 'discord'), 'label_pushover' => psm_get_lang('log', 'pushover'), + 'label_webhook' => psm_get_lang('log', 'webhook'), 'label_telegram' => psm_get_lang('log', 'telegram'), + 'label_jabber' => psm_get_lang('log', 'jabber'), 'label_title' => psm_get_lang('log', 'title'), 'label_server' => psm_get_lang('servers', 'server'), 'label_type' => psm_get_lang('log', 'type'), @@ -76,7 +79,7 @@ class LogController extends AbstractServerController $modal->setTitle(psm_get_lang('log', 'delete_title')); $modal->setMessage(psm_get_lang('log', 'delete_message')); $modal->setOKButtonLabel(psm_get_lang('system', 'delete')); - + $sidebar->addButton( 'clear_logn', 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) { $records = $this->getEntries($key); @@ -160,9 +163,9 @@ class LogController extends AbstractServerController 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` - )"; + `us`.`user_id`={$this->getUser()->getUserId()} + AND `us`.`server_id`=`servers`.`server_id` + )"; } $entries = $this->db->query( 'SELECT ' . diff --git a/src/psm/Module/Server/Controller/ServerController.php b/src/psm/Module/Server/Controller/ServerController.php index 097329fd..cb08e5fc 100644 --- a/src/psm/Module/Server/Controller/ServerController.php +++ b/src/psm/Module/Server/Controller/ServerController.php @@ -100,8 +100,11 @@ class ServerController extends AbstractServerController $icons = array( 'email' => 'icon-envelope', 'sms' => 'icon-mobile', + 'discord' => 'icon-discord', 'pushover' => 'icon-pushover', + 'webhook' => 'icon-webhook', 'telegram' => 'icon-telegram', + 'jabber' => 'icon-jabber' ); $servers = $this->getServers(); @@ -114,6 +117,9 @@ class ServerController extends AbstractServerController $servers[$x]['ip'] = '' . $ip . ''; } + if ($servers[$x]['type'] == 'ping') { + $servers[$x]['port'] = ''; + } if (($servers[$x]['active'] == 'yes')) { $servers[$x]['active_title'] = psm_get_lang('servers', 'monitoring'); } else { @@ -123,6 +129,14 @@ class ServerController extends AbstractServerController $servers[$x] = $this->formatServer($servers[$x]); } $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); } @@ -133,6 +147,12 @@ class ServerController extends AbstractServerController { $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['edit_server_id'] = $this->server_id; $tpl_data['url_save'] = psm_build_url(array( @@ -141,6 +161,11 @@ class ServerController extends AbstractServerController 'id' => $this->server_id, '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: 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'); + 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) { case 0: // insert mode @@ -173,10 +205,6 @@ class ServerController extends AbstractServerController $user_idc_selected = $this->getServerUsers($this->server_id); 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)) { $user['edit_selected'] = 'selected="selected"'; } @@ -208,16 +236,20 @@ class ServerController extends AbstractServerController 'edit_value_website_username' => $edit_server['website_username'], 'edit_value_website_password' => empty($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_active_selected' => $edit_server['active'], 'edit_email_selected' => $edit_server['email'], '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_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) { if (psm_get_conf($notification . '_status') == 0) { $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 $encrypted_password = ''; - + if (!empty($_POST['website_password'])) { $new_password = psm_POST('website_password'); @@ -281,11 +313,15 @@ class ServerController extends AbstractServerController 'header_name' => psm_POST('header_name', ''), 'header_value' => psm_POST('header_value', ''), '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', 'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : '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', + 'webhook' => in_array($_POST['webhook'], array('yes', 'no')) ? $_POST['webhook'] : '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:// if ( @@ -325,6 +361,7 @@ class ServerController extends AbstractServerController $server_validator->type($clean['type']); $server_validator->ip($clean['ip'], $clean['type']); $server_validator->warningThreshold($clean['warning_threshold']); + $server_validator->sslCertExpiryDays($clean['ssl_cert_expiry_days']); } catch (\InvalidArgumentException $ex) { $this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error'); return $this->executeEdit(); @@ -492,6 +529,15 @@ class ServerController extends AbstractServerController if (strlen($tpl_data['last_error_output']) > 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); } @@ -551,13 +597,22 @@ class ServerController extends AbstractServerController 'label_send_email' => psm_get_lang('servers', 'send_email'), 'label_sms' => psm_get_lang('servers', '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_webhook' => psm_get_lang('servers', 'send_webhook'), '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_send_telegram' => psm_get_lang('servers', 'send_telegram'), 'label_users' => psm_get_lang('servers', 'users'), 'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'), '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_save' => psm_get_lang('system', 'save'), '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_no' => psm_get_lang('system', 'no'), '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_offline' => psm_get_lang('servers', 'offline'), 'label_ok' => psm_get_lang('system', 'ok'), @@ -576,6 +632,10 @@ class ServerController extends AbstractServerController 'label_settings' => psm_get_lang('system', 'settings'), 'label_output' => psm_get_lang('servers', 'output'), '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; } + + /** + * 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; + } } diff --git a/src/psm/Module/Server/Controller/StatusController.php b/src/psm/Module/Server/Controller/StatusController.php index efe840f3..d4ee083d 100644 --- a/src/psm/Module/Server/Controller/StatusController.php +++ b/src/psm/Module/Server/Controller/StatusController.php @@ -100,6 +100,8 @@ class StatusController extends AbstractServerController $layout_data['servers_offline'][] = $server; } elseif ($server['warning_threshold_counter'] > 0) { $layout_data['servers_warning'][] = $server; + } elseif ($server['ssl_cert_expired_time'] !== null && $server['ssl_cert_expiry_days'] > 0) { + $layout_data['servers_warning'][] = $server; } else { $layout_data['servers_online'][] = $server; } diff --git a/src/psm/Module/User/Controller/ProfileController.php b/src/psm/Module/User/Controller/ProfileController.php index bcd04c0f..6b9b0cf1 100644 --- a/src/psm/Module/User/Controller/ProfileController.php +++ b/src/psm/Module/User/Controller/ProfileController.php @@ -39,7 +39,7 @@ class ProfileController extends AbstractController * @var array $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) { @@ -78,11 +78,21 @@ class ProfileController extends AbstractController 'label_password_repeat' => psm_get_lang('users', 'password_repeat'), 'label_level' => psm_get_lang('users', 'level'), '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_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'), '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_description' => psm_get_lang('users', 'telegram_description'), '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_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'), '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_save' => psm_get_lang('system', 'save'), 'form_action' => psm_build_url(array( diff --git a/src/psm/Module/User/Controller/UserController.php b/src/psm/Module/User/Controller/UserController.php index a45f24a7..0704cc39 100644 --- a/src/psm/Module/User/Controller/UserController.php +++ b/src/psm/Module/User/Controller/UserController.php @@ -158,9 +158,13 @@ class UserController extends AbstractController 'name', 'user_name', 'mobile', + 'discord', + 'webhook_url', + 'webhook_json', 'pushover_key', 'pushover_device', 'telegram_id', + 'jabber', 'email' ); @@ -254,9 +258,13 @@ class UserController extends AbstractController 'password_repeat', 'level', 'mobile', + 'discord', + 'webhook_url', + 'webhook_json', 'pushover_key', 'pushover_device', 'telegram_id', + 'jabber', 'email' ); $clean = array(); @@ -310,6 +318,15 @@ class UserController extends AbstractController if ($user_id > 0) { // edit user 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->addMessage(psm_get_lang('users', 'updated'), 'success'); @@ -360,7 +377,11 @@ class UserController extends AbstractController try { $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'); } else { $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_description' => psm_get_lang('users', 'level_description'), '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_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), '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_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_servers' => psm_get_lang('menu', 'server'), 'label_save' => psm_get_lang('system', 'save'), diff --git a/src/psm/Module/User/UserEvents.php b/src/psm/Module/User/UserEvents.php index 33767928..de5ca932 100644 --- a/src/psm/Module/User/UserEvents.php +++ b/src/psm/Module/User/UserEvents.php @@ -35,15 +35,15 @@ final class UserEvents /** * @var string */ - public const USER_ADD = 'user.add'; + const USER_ADD = 'user.add'; /** * @var string */ - public const USER_EDIT = 'user.edit'; + const USER_EDIT = 'user.edit'; /** * @var string */ - public const USER_DELETE = 'user.delete'; + const USER_DELETE = 'user.delete'; } diff --git a/src/psm/Txtmsg/CMBulkSMS.php b/src/psm/Txtmsg/CMBulkSMS.php index d0d3e0b1..9a20c126 100644 --- a/src/psm/Txtmsg/CMBulkSMS.php +++ b/src/psm/Txtmsg/CMBulkSMS.php @@ -67,10 +67,10 @@ class CMBulkSMS extends Core protected $messageBody; /** @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 */ - 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 @@ -131,7 +131,7 @@ class CMBulkSMS extends Core ), 'msg' => array( array( - 'from' => substr($this->originator, 0, 11), + 'from' => substr($this->originator, 0, 15), 'to' => $recipients, 'body' => array( 'content' => $message @@ -172,7 +172,7 @@ class CMBulkSMS extends Core $msg = $xml->addChild('MSG'); // From - $msg->addChild('FROM', substr($this->originator, 0, 11)); + $msg->addChild('FROM', substr($this->originator, 0, 15)); // Recipients foreach ($this->recipients as $recipient) { diff --git a/src/psm/Txtmsg/ClickSend.php b/src/psm/Txtmsg/ClickSend.php index d0176ce7..b62261a0 100644 --- a/src/psm/Txtmsg/ClickSend.php +++ b/src/psm/Txtmsg/ClickSend.php @@ -64,7 +64,7 @@ class ClickSend extends Core foreach ($this->recipients as $recipient) { $data['messages'][] = array( 'source' => 'phpservermon', - 'from' => substr($this->originator, 0, 11), + 'from' => substr($this->originator, 0, 15), 'to' => $recipient, 'body' => $message, ); diff --git a/src/psm/Txtmsg/FreeVoipDeal.php b/src/psm/Txtmsg/FreeVoipDeal.php old mode 100755 new mode 100644 index 234e6bd0..7decf766 --- a/src/psm/Txtmsg/FreeVoipDeal.php +++ b/src/psm/Txtmsg/FreeVoipDeal.php @@ -63,7 +63,7 @@ class FreeVoipDeal extends Core array( "username" => $this->username, "password" => $this->password, - "from" => substr($this->originator, 0, 11), + "from" => substr($this->originator, 0, 15), "to" => $recipient, "text" => $message, ) diff --git a/src/psm/Txtmsg/Mosms.php b/src/psm/Txtmsg/Mosms.php index 98381579..ffcf15d0 100644 --- a/src/psm/Txtmsg/Mosms.php +++ b/src/psm/Txtmsg/Mosms.php @@ -63,7 +63,7 @@ class Mosms extends Core array( "username" => $this->username, "password" => $this->password, - "customsender" => substr($this->originator, 0, 11), + "customsender" => substr($this->originator, 0, 15), "nr" => $recipient, "type" => "text", "data" => $message, diff --git a/src/psm/Txtmsg/OVHsms.php b/src/psm/Txtmsg/OVHsms.php new file mode 100644 index 00000000..709f9d19 --- /dev/null +++ b/src/psm/Txtmsg/OVHsms.php @@ -0,0 +1,101 @@ +. + * + * @package phpservermon + * @author Alexis Urien + * @Author Tim Zandbergen + * @author Ward Pieters + * @author Alexandre ZANELLI + * @copyright Copyright (c) 2016 Alexis Urien + * @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; + } +} diff --git a/src/psm/Txtmsg/Octopush.php b/src/psm/Txtmsg/Octopush.php index 4ce98de1..f14eb464 100644 --- a/src/psm/Txtmsg/Octopush.php +++ b/src/psm/Txtmsg/Octopush.php @@ -59,11 +59,11 @@ class Octopush extends Core { $error = ""; $success = 1; - $smsType = "XXX"; //FR = premium, WWW = world, XXX = Low cost + $smsType = "FR"; //FR = premium, WWW = world, XXX = Low cost $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_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, "sms_recipients" => $recipients, "sms_type" => $smsType, - "sms_sender" => substr($this->originator, 0, 11), + "sms_sender" => substr($this->originator, 0, 15), "sms_text" => $message, ) )); diff --git a/src/psm/Txtmsg/SMSAPI.php b/src/psm/Txtmsg/SMSAPI.php new file mode 100755 index 00000000..83601e05 --- /dev/null +++ b/src/psm/Txtmsg/SMSAPI.php @@ -0,0 +1,149 @@ +. + * + * @package phpservermon + * @author Mateusz Małek + * @copyright Copyright (c) 2008-2017 Pepijn Over + * @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); + } +} diff --git a/src/psm/Txtmsg/Smsglobal.php b/src/psm/Txtmsg/Smsglobal.php index 9947b05a..174fc0bb 100644 --- a/src/psm/Txtmsg/Smsglobal.php +++ b/src/psm/Txtmsg/Smsglobal.php @@ -58,7 +58,7 @@ class Smsglobal extends Core $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); $curl = curl_init(); diff --git a/src/psm/Txtmsg/Smsit.php b/src/psm/Txtmsg/Smsit.php index 964ff5eb..58e6a53b 100644 --- a/src/psm/Txtmsg/Smsit.php +++ b/src/psm/Txtmsg/Smsit.php @@ -64,7 +64,7 @@ class Smsit extends Core "apiKey" => $this->password, "mobile" => $recipient, "message" => urlencode($message), - "senderId" => substr($this->originator, 0, 11), + "senderId" => substr($this->originator, 0, 15), ) )); diff --git a/src/psm/Txtmsg/SolutionsInfini.php b/src/psm/Txtmsg/SolutionsInfini.php index a21d1479..bc1e8196 100644 --- a/src/psm/Txtmsg/SolutionsInfini.php +++ b/src/psm/Txtmsg/SolutionsInfini.php @@ -66,7 +66,7 @@ class SolutionsInfini extends Core "api_key" => $this->password, "method" => "sms", "to" => $recipients, - "sender" => substr($this->originator, 0, 11), + "sender" => substr($this->originator, 0, 15), "message" => $message, ) )); diff --git a/src/psm/Txtmsg/Ysmal.php b/src/psm/Txtmsg/Ysmal.php new file mode 100644 index 00000000..3daf956e --- /dev/null +++ b/src/psm/Txtmsg/Ysmal.php @@ -0,0 +1,92 @@ +. + * + * @package phpservermon + * @author Perri Vardy-Mason + * @author Dylan Ysmal + * @copyright Copyright (c) 2008-2017 Pepijn Over + * @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; + } +} diff --git a/src/psm/Util/Install/Installer.php b/src/psm/Util/Install/Installer.php index 114eba65..b36d13a1 100644 --- a/src/psm/Util/Install/Installer.php +++ b/src/psm/Util/Install/Installer.php @@ -134,51 +134,64 @@ class Installer $queries = array(); $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` ( `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', '', - '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', '', - '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 . "config` (`key`, `value`) VALUE - ('language', 'en_US'), - ('proxy', '0'), - ('proxy_url', ''), - ('proxy_user', ''), - ('proxy_password', ''), - ('email_status', '1'), - ('email_from_email', 'monitor@example.org'), - ('email_from_name', 'Server Monitor'), - ('email_smtp', ''), - ('email_smtp_host', ''), - ('email_smtp_port', ''), - ('email_smtp_security', ''), - ('email_smtp_username', ''), - ('email_smtp_password', ''), - ('sms_status', '0'), - ('sms_gateway', 'messagebird'), - ('sms_gateway_username', 'username'), - ('sms_gateway_password', 'password'), - ('sms_from', '1234567890'), - ('pushover_status', '0'), - ('pushover_api_token', ''), - ('telegram_status', '0'), - ('telegram_api_token', ''), - ('password_encrypt_key', '" . sha1(microtime()) . "'), - ('alert_type', 'status'), - ('log_status', '1'), - ('log_email', '1'), - ('log_sms', '1'), - ('log_pushover', '1'), - ('log_telegram', '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');"; + ('language', 'en_US'), + ('proxy', '0'), + ('proxy_url', ''), + ('proxy_user', ''), + ('proxy_password', ''), + ('email_status', '1'), + ('email_from_email', 'monitor@example.org'), + ('email_from_name', 'Server Monitor'), + ('email_smtp', ''), + ('email_smtp_host', ''), + ('email_smtp_port', ''), + ('email_smtp_security', ''), + ('email_smtp_username', ''), + ('email_smtp_password', ''), + ('sms_status', '0'), + ('sms_gateway', 'messagebird'), + ('sms_gateway_username', 'username'), + ('sms_gateway_password', 'password'), + ('sms_from', '1234567890'), + ('webhook_status', '0'), + ('pushover_status', '0'), + ('pushover_api_token', ''), + ('telegram_status', '0'), + ('telegram_api_token', ''), + ('jabber_status', '1'), + ('jabber_host', ''), + ('jabber_port', ''), + ('jabber_username', ''), + ('jabber_domain', ''), + ('jabber_password', ''), + ('password_encrypt_key', '" . sha1(microtime()) . "'), + ('alert_type', 'status'), + ('log_status', '1'), + ('log_email', '1'), + ('log_sms', '1'), + ('log_pushover', '1'), + ('log_webhook', '1'), + ('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); } @@ -189,45 +202,49 @@ class Installer { $tables = array( PSM_DB_PREFIX . 'config' => "CREATE TABLE `" . PSM_DB_PREFIX . "config` ( - `key` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`key`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", + `key` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`key`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'users' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users` ( - `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `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_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', - `rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token', - `level` tinyint(2) unsigned NOT NULL DEFAULT '20', - `name` varchar(255) NOT NULL, - `mobile` varchar(15) NOT NULL, - `pushover_key` varchar(255) NOT NULL, - `pushover_device` varchar(255) NOT NULL, - `telegram_id` varchar(255) NOT NULL, - `email` varchar(255) NOT NULL, + `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `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_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', + `rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token', + `level` tinyint(2) unsigned NOT NULL DEFAULT '20', + `name` varchar(255) NOT NULL, + `mobile` varchar(15) NOT NULL, + `discord` varchar(255) NOT NULL, + `pushover_key` varchar(255) NOT NULL, + `pushover_device` 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`), UNIQUE KEY `unique_username` (`user_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` ( - `user_id` int(11) unsigned NOT NULL, - `key` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, + `user_id` int(11) unsigned NOT NULL, + `key` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, PRIMARY KEY (`user_id`, `key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'users_servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` ( - `user_id` INT( 11 ) UNSIGNED NOT NULL , - `server_id` INT( 11 ) UNSIGNED NOT NULL , + `user_id` INT( 11 ) UNSIGNED NOT NULL , + `server_id` INT( 11 ) UNSIGNED NOT NULL , PRIMARY KEY ( `user_id` , `server_id` ) ) ENGINE = MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'log' => "CREATE TABLE `" . PSM_DB_PREFIX . "log` ( - `log_id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `server_id` int(11) unsigned NOT NULL, - `type` enum('status','email','sms','pushover','telegram') NOT NULL, - `message` TEXT NOT NULL, - `datetime` timestamp NOT NULL default CURRENT_TIMESTAMP, + `log_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `server_id` int(11) unsigned NOT NULL, + `type` enum('status','email','sms','discord','pushover','webhook','telegram', 'jabber') NOT NULL, + `message` TEXT NOT NULL, + `datetime` timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (`log_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'log_users' => "CREATE TABLE `" . PSM_DB_PREFIX . "log_users` ( @@ -236,41 +253,46 @@ class Installer PRIMARY KEY (`log_id`, `user_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "servers` ( - `server_id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `ip` varchar(500) NOT NULL, - `port` int(5) NOT NULL, - `request_method` varchar(50) NULL, - `label` varchar(255) NOT NULL, - `type` enum('ping','service','website') NOT NULL default 'service', - `pattern` varchar(255) NOT NULL default '', - `pattern_online` enum('yes','no') NOT NULL default 'yes', - `post_field` varchar(255) NULL, - `redirect_check` enum('ok','bad') NOT NULL default 'bad', - `allow_http_status` varchar(255) NOT NULL default '', - `header_name` varchar(255) NOT NULL default '', - `header_value` varchar(255) NOT NULL default '', - `status` enum('on','off') NOT NULL default 'on', - `error` varchar(255) NULL, - `rtime` FLOAT(9, 7) NULL, - `last_online` datetime NULL, - `last_offline` datetime NULL, - `last_offline_duration` varchar(255) NULL, - `last_check` datetime NULL, - `active` enum('yes','no') NOT NULL default 'yes', - `email` enum('yes','no') NOT NULL default 'yes', - `sms` enum('yes','no') NOT NULL default 'no', - `pushover` enum('yes','no') NOT NULL default 'yes', - `telegram` enum('yes','no') NOT NULL default 'yes', - `warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1', - `warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0', - `timeout` smallint(1) unsigned NULL DEFAULT NULL, - `website_username` varchar(255) DEFAULT NULL, - `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;", + `server_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ip` varchar(500) NOT NULL, + `port` int(5) NOT NULL, + `request_method` varchar(50) NULL, + `label` varchar(255) NOT NULL, + `type` enum('ping','service','website') NOT NULL default 'service', + `pattern` varchar(255) NOT NULL default '', + `pattern_online` enum('yes','no') NOT NULL default 'yes', + `post_field` varchar(255) NULL, + `redirect_check` enum('ok','bad') NOT NULL default 'bad', + `allow_http_status` varchar(255) NOT NULL default '', + `header_name` varchar(255) NOT NULL default '', + `header_value` varchar(255) NOT NULL default '', + `status` enum('on','off') NOT NULL default 'on', + `error` varchar(255) NULL, + `rtime` FLOAT(9, 7) NULL, + `last_online` datetime NULL, + `last_offline` datetime NULL, + `last_offline_duration` varchar(255) NULL, + `last_check` datetime NULL, + `active` enum('yes','no') NOT NULL default 'yes', + `email` enum('yes','no') NOT NULL default 'yes', + `sms` enum('yes','no') NOT NULL default 'no', + `discord` enum('yes','no') NOT NULL default 'yes', + `pushover` enum('yes','no') NOT NULL default 'yes', + `webhook` enum('yes','no') NOT NULL default 'yes', + `telegram` enum('yes','no') NOT NULL default 'yes', + `jabber` enum('yes','no') NOT NULL default 'yes', + `warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1', + `warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0', + `ssl_cert_expiry_days` mediumint(1) unsigned NOT NULL DEFAULT '0', + `ssl_cert_expired_time` varchar(255) NULL, + `timeout` smallint(1) unsigned NULL DEFAULT NULL, + `website_username` varchar(255) DEFAULT NULL, + `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` ( `servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `server_id` int(11) unsigned NOT NULL, @@ -281,14 +303,14 @@ class Installer KEY `server_id` (`server_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", 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, - `server_id` int(11) unsigned NOT NULL, - `date` date NOT NULL, - `latency_min` float(9,7) NOT NULL, - `latency_avg` float(9,7) NOT NULL, - `latency_max` float(9,7) NOT NULL, - `checks_total` int(11) unsigned NOT NULL, - `checks_failed` int(11) unsigned NOT NULL, + `servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `server_id` int(11) unsigned NOT NULL, + `date` date NOT NULL, + `latency_min` float(9,7) NOT NULL, + `latency_avg` float(9,7) NOT NULL, + `latency_max` float(9,7) NOT NULL, + `checks_total` int(11) unsigned NOT NULL, + `checks_failed` int(11) unsigned NOT NULL, PRIMARY KEY (`servers_history_id`), UNIQUE KEY `server_id_date` (`server_id`,`date`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", @@ -341,6 +363,9 @@ class Installer if (version_compare($version_from, '3.4.2', '<')) { $this->upgrade342(); } + if (version_compare($version_from, '3.5.0', '<')) { + $this->upgrade350(); + } if (version_compare($version_from, '3.6.0', '<')) { $this->upgrade360(); } @@ -418,49 +443,49 @@ class Installer $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` CHANGE `user_id` `user_id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT;"; $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`, - 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`, - 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`, - 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`, - 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`, - 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): $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[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` ( - `servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `server_id` int(11) unsigned NOT NULL, - `date` datetime NOT NULL, - `status` tinyint(1) unsigned NOT NULL, - `latency` float(9,7) DEFAULT NULL, - PRIMARY KEY (`servers_uptime_id`), - KEY `server_id` (`server_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; + `servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `server_id` int(11) unsigned NOT NULL, + `date` datetime NOT NULL, + `status` tinyint(1) unsigned NOT NULL, + `latency` float(9,7) DEFAULT NULL, + PRIMARY KEY (`servers_uptime_id`), + KEY `server_id` (`server_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; $queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` ( - `servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `server_id` int(11) unsigned NOT NULL, - `date` date NOT NULL, - `latency_min` float(9,7) NOT NULL, - `latency_avg` float(9,7) NOT NULL, - `latency_max` float(9,7) NOT NULL, - `checks_total` int(11) unsigned NOT NULL, - `checks_failed` int(11) unsigned NOT NULL, - PRIMARY KEY (`servers_history_id`), - UNIQUE KEY `server_id_date` (`server_id`,`date`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; + `servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `server_id` int(11) unsigned NOT NULL, + `date` date NOT NULL, + `latency_min` float(9,7) NOT NULL, + `latency_avg` float(9,7) NOT NULL, + `latency_max` float(9,7) NOT NULL, + `checks_total` int(11) unsigned NOT NULL, + `checks_failed` int(11) unsigned NOT NULL, + PRIMARY KEY (`servers_history_id`), + UNIQUE KEY `server_id_date` (`server_id`,`date`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; $queries[] = "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` ( - `user_id` INT( 11 ) UNSIGNED NOT NULL , - `server_id` INT( 11 ) UNSIGNED NOT NULL , - PRIMARY KEY ( `user_id` , `server_id` ) - ) ENGINE = MYISAM ;"; + `user_id` INT( 11 ) UNSIGNED NOT NULL , + `server_id` INT( 11 ) UNSIGNED NOT NULL , + PRIMARY KEY ( `user_id` , `server_id` ) + ) ENGINE = MYISAM ;"; $this->execSQL($queries); // 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[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` ( - `user_id` int(11) unsigned NOT NULL, - `key` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`user_id`, `key`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; + `user_id` int(11) unsigned NOT NULL, + `key` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`user_id`, `key`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; $this->execSQL($queries); } @@ -533,14 +558,14 @@ class Installer $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `website_username` varchar(255) NULL, ADD `website_password` varchar(255) NULL AFTER `website_username`;"; $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE - ('proxy', '0'), - ('proxy_url', ''), - ('proxy_user', ''), - ('proxy_password', '');"; + ('proxy', '0'), + ('proxy_url', ''), + ('proxy_user', ''), + ('proxy_password', '');"; $this->execSQL($queries); - // Create log_users table + // Create log_users table $this->execSQL("CREATE TABLE `" . PSM_DB_PREFIX . "log_users` ( `log_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' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;"; $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE - ('telegram_status', '0'), - ('log_telegram', '1'), - ('telegram_api_token', '');"; + ('telegram_status', '0'), + ('log_telegram', '1'), + ('telegram_api_token', '');"; $this->execSQL($queries); } @@ -646,7 +671,7 @@ class Installer $this->execSQL($queries); $this->log('Combined notifications enabled. Check out the config page for more info.'); } - + /** * Patch for v3.4.2 release * Version_compare was forgotten in v3.4.1 and query failed. @@ -659,13 +684,80 @@ class Installer $this->execSQL($queries); } - protected function upgrade360() + /** + * Upgrade for v3.5.0 release + */ + protected function upgrade350() { $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` ( `user_name`, `level`, `name`, `email`) VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')"; $this->execSQL($queries); $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); + } } diff --git a/src/psm/Util/Module/Modal.php b/src/psm/Util/Module/Modal.php index 76d27ee6..21176096 100644 --- a/src/psm/Util/Module/Modal.php +++ b/src/psm/Util/Module/Modal.php @@ -32,9 +32,9 @@ namespace psm\Util\Module; class Modal implements ModalInterface { - public const MODAL_TYPE_OK = 0; - public const MODAL_TYPE_OKCANCEL = 1; - public const MODAL_TYPE_DANGER = 2; + const MODAL_TYPE_OK = 0; + const MODAL_TYPE_OKCANCEL = 1; + const MODAL_TYPE_DANGER = 2; /** * prefix used for modal dialog box elements @@ -145,7 +145,7 @@ class Modal implements ModalInterface $tpl = $this->twig->loadTemplate('util/module/modal.tpl.html'); $html = $tpl->render(array( '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, 'has_cancel' => $has_cancel, 'label_cancel' => psm_get_lang('system', 'cancel'), diff --git a/src/psm/Util/Server/HistoryGraph.php b/src/psm/Util/Server/HistoryGraph.php index 8b5b8e38..11425e8b 100644 --- a/src/psm/Util/Server/HistoryGraph.php +++ b/src/psm/Util/Server/HistoryGraph.php @@ -29,7 +29,10 @@ namespace psm\Util\Server; +use DateTime; use psm\Service\Database; +use Twig\Error\Error; +use Twig_Environment; /** * History util, create HTML for server graphs @@ -39,17 +42,17 @@ class HistoryGraph /** * Database service - * @var \psm\Service\Database $db; + * @var Database $db; */ protected $db; /** * Twig environment - * @var \Twig_Environment $twig + * @var Twig_Environment $twig */ protected $twig; - public function __construct(Database $db, \Twig_Environment $twig) + public function __construct(Database $db, Twig_Environment $twig) { $this->db = $db; $this->twig = $twig; @@ -57,7 +60,9 @@ class HistoryGraph /** * 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) { @@ -65,16 +70,16 @@ class HistoryGraph $archive = new ArchiveManager($this->db); $archive->archive($server_id); - $now = new \DateTime(); - $last_week = new \DateTime('-1 week 0:0:0'); - $last_year = new \DateTime('-1 year -1 week 0:0:0'); + $now = new DateTime(); + $last_week = new DateTime('-1 week 0:0:0'); + $last_year = new DateTime('-1 year -1 week 0:0:0'); $graphs = array( 0 => $this->generateGraphUptime($server_id, $last_week, $now), 1 => $this->generateGraphHistory($server_id, $last_year, $last_week), ); $info_fields = array( - 'latency_avg' => '%01.4f', + 'latency_avg' => '%01.5f', 'uptime' => '%01.3f%%', ); @@ -101,8 +106,8 @@ class HistoryGraph /** * Generate data for uptime graph * @param int $server_id - * @param \DateTime $start_time Lowest DateTime of the graph - * @param \DateTime $end_time Highest DateTime of the graph + * @param DateTime $start_time Lowest DateTime of the graph + * @param DateTime $end_time Highest DateTime of the graph * @return array */ public function generateGraphUptime($server_id, $start_time, $end_time) @@ -112,9 +117,9 @@ class HistoryGraph 'latency' => array(), ); - $hour = new \DateTime('-1 hour'); - $day = new \DateTime('-1 day'); - $week = new \DateTime('-1 week'); + $hour = new DateTime('-1 hour'); + $day = new DateTime('-1 day'); + $week = new DateTime('-1 week'); $records = $this->getRecords('uptime', $server_id, $start_time, $end_time); @@ -148,8 +153,8 @@ class HistoryGraph /** * Generate data for history graph * @param int $server_id - * @param \DateTime $start_time Lowest DateTime of the graph - * @param \DateTime $end_time Highest DateTime of the graph + * @param DateTime $start_time Lowest DateTime of the graph + * @param DateTime $end_time Highest DateTime of the graph * @return array */ public function generateGraphHistory($server_id, $start_time, $end_time) @@ -160,9 +165,9 @@ class HistoryGraph 'latency_max' => array(), ); - $week = new \DateTime('-2 week 0:0:0'); - $month = new \DateTime('-1 month -1 week 0:0:0'); - $year = new \DateTime('-1 year -1 week 0:0:0'); + $week = new DateTime('-2 week 0:0:0'); + $month = new DateTime('-1 month -1 week 0:0:0'); + $year = new DateTime('-1 year -1 week 0:0:0'); $records = $this->getRecords('history', $server_id, $year, $end_time); @@ -197,8 +202,8 @@ class HistoryGraph * Get all uptime/history records for a server * @param string $type * @param int $server_id - * @param \DateTime $start_time Lowest DateTime of the graph - * @param \DateTime $end_time Highest DateTime of the graph + * @param DateTime $start_time Lowest DateTime of the graph + * @param DateTime $end_time Highest DateTime of the graph * @return array */ protected function getRecords($type, $server_id, $start_time, $end_time) @@ -207,17 +212,19 @@ class HistoryGraph return array(); } - $records = $this->db->execute( - "SELECT * + /** @noinspection SqlNoDataSourceInspection */ + /** @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` - 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( 'server_id' => $server_id, 'start_time' => $start_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 $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 \DateTime $start_time Lowest DateTime of the graph - * @param \DateTime $end_time Highest DateTime of the graph + * @param DateTime $start_time Lowest DateTime of the graph + * @param DateTime $end_time Highest DateTime of the graph * @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 */ protected function generateGraphLines( @@ -241,64 +245,90 @@ class HistoryGraph $end_time, $add_uptime = false ) { - $now = new \DateTime(); + $now = new DateTime(); $data = array(); // PLEASE NOTE: all times are in microseconds! because of javascript. $latency_avg = 0; + /** @var array $prev Previous record */ $prev = reset($records); + // Timestamp from last offline record. 0 when last record is up. $prev_downtime = 0; + // Total downtime $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 foreach ($records as $record) { - $time = strtotime($record['date']); // use the first line to calculate average latency $latency_avg += (float) $record[$latency_avg_key]; - foreach ($lines as $key => $value) { - // add the value for each of the different lines - if (isset($record[$key])) { - if (isset($record['status'])) { - // down - if ($record['status'] == 0) { - $lines['online'][] = $prev['status'] - // Previous datapoint was online - ? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] . '}' - // Previous datapoint was offline - : '{ x: ' . ($time * 1000) . ', y: null}'; - // new outage start - $lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:0.1}'; + if ($is_short_graph) { + $time = (int) $record['date_ts']; + // Timestamp in milliseconds + $time_ms = $time * 1000; + if (!$record['status']) { + // down + $lines['online'][] = $prev['status'] + // Previous datapoint was online + ? ['x' => $time_ms, 'y' => round($prev['latency'] * 1000, 3)] + // Previous datapoint was offline + : ['x' => $time_ms, 'y' => null]; + // new outage start + $lines['offline'][] = ['x' => $time_ms, 'y' => $highest_latency]; - $prev_downtime != 0 ?: $prev_downtime = $time; - } else { - // 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] . '}'; + if ($prev_downtime === 0) { + $prev_downtime = $time; } - $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. // Record the first and last date as a string in the down array $prev_downtime == 0 ?: $downtime += ($now->getTimestamp() - $prev_downtime); 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())); } @@ -307,11 +337,12 @@ class HistoryGraph if (empty($line_value)) { 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); } - $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['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '') * 1000; $data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '') * 1000; diff --git a/src/psm/Util/Server/ServerValidator.php b/src/psm/Util/Server/ServerValidator.php index 63e5688b..18dc658b 100644 --- a/src/psm/Util/Server/ServerValidator.php +++ b/src/psm/Util/Server/ServerValidator.php @@ -154,4 +154,18 @@ class ServerValidator } 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; + } } diff --git a/src/psm/Util/Server/UpdateManager.php b/src/psm/Util/Server/UpdateManager.php index 29a397cd..2ba6ff0a 100644 --- a/src/psm/Util/Server/UpdateManager.php +++ b/src/psm/Util/Server/UpdateManager.php @@ -49,25 +49,31 @@ class UpdateManager implements ContainerAwareInterface * Go :-) * * @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 $sql_join = ''; if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) { // restrict by user_id $sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON ( - `us`.`user_id`={$this->container->get('user')->getUserId()} - AND `us`.`server_id`=`s`.`server_id` - )"; + `us`.`user_id`={$this->container->get('user')->getUserId()} + 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`, - `s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram` - FROM `" . PSM_DB_PREFIX . "servers` AS `s` - {$sql_join} - WHERE `active`='yes' "; + `s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`webhook`,`s`.`telegram`, + `s`.`jabber` + FROM `" . PSM_DB_PREFIX . "servers` AS `s` + {$sql_join} + WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : ''); $servers = $this->container->get('db')->query($sql); @@ -76,7 +82,8 @@ class UpdateManager implements ContainerAwareInterface foreach ($servers as $server) { $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 $notifier->notify($server['server_id'], $status_old, $status_new); // clean-up time!! archive all records diff --git a/src/psm/Util/Server/Updater/StatusNotifier.php b/src/psm/Util/Server/Updater/StatusNotifier.php index 1e798742..dd145db7 100644 --- a/src/psm/Util/Server/Updater/StatusNotifier.php +++ b/src/psm/Util/Server/Updater/StatusNotifier.php @@ -33,6 +33,7 @@ * @see \psm\Util\Server\Updater\Autorun */ namespace psm\Util\Server\Updater; +use Norgul\Xmpp\Options; use psm\Service\Database; class StatusNotifier @@ -56,18 +57,36 @@ class StatusNotifier */ protected $send_sms = false; + /** + * Send Discord notification? + * @var boolean $send_discord + */ + protected $send_discord = false; + /** * Send Pushover notification? * @var boolean $send_pushover */ protected $send_pushover = false; + /** + * Send webhook notification? + * @var boolean $send_webhook + */ + protected $send_webhook = false; + /** * Send telegram? * @var boolean $send_telegram */ protected $send_telegram = false; + /** + * Send Jabber? + * @var bool + */ + protected $send_jabber = false; + /** * Save log records? * @var boolean $save_log @@ -119,12 +138,15 @@ class StatusNotifier { $this->db = $db; - $this->send_emails = psm_get_conf('email_status'); - $this->send_sms = psm_get_conf('sms_status'); - $this->send_pushover = psm_get_conf('pushover_status'); - $this->send_telegram = psm_get_conf('telegram_status'); - $this->save_logs = psm_get_conf('log_status'); - $this->combine = psm_get_conf('combine_notifications'); + $this->send_emails = (bool)psm_get_conf('email_status'); + $this->send_sms = (bool)psm_get_conf('sms_status'); + $this->send_discord = (bool)psm_get_conf('discord_status'); + $this->send_webhook = (bool)psm_get_conf('webhook_status'); + $this->send_pushover = (bool)psm_get_conf('pushover_status'); + $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 ( !$this->send_emails && !$this->send_sms && + !$this->send_discord && + !$this->send_webhook && !$this->send_pushover && !$this->send_telegram && + !$this->send_jabber && !$this->save_logs ) { // seems like we have nothing to do. skip the rest @@ -166,8 +191,11 @@ class StatusNotifier 'error', 'email', 'sms', + 'discord', + 'webhook', 'pushover', 'telegram', + 'jabber', 'last_online', 'last_offline', 'last_offline_duration', @@ -236,6 +264,18 @@ class StatusNotifier $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 if ($this->send_pushover && $this->server['pushover'] == 'yes') { // yay lets wake those nerds up! @@ -247,6 +287,10 @@ class StatusNotifier $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; } @@ -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('', ''), array('**', '**'), $message_log); + $message = str_replace(array('
      ', '
    '), array('', ''), $message); + $message = str_replace(array('
    ', ''), array("\n", "\n"), $message); + $message = str_replace('
  • ', " * ", $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 * @@ -447,7 +571,7 @@ class StatusNotifier $pushover->setTitle($title); $pushover->setMessage(str_replace('
    ', "\n", $message)); $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 if (psm_get_conf('log_pushover')) { @@ -468,7 +592,48 @@ class StatusNotifier $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('
    ', "\n", $message); + $message = str_replace('
    ', "\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 * @@ -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 * @param int $server_id @@ -556,15 +769,16 @@ class StatusNotifier public function getUsers($server_id) { // find all the users with this server listed - $users = $this->db->query(" - SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, - `u`.`pushover_device`, `u`.`telegram_id` - FROM `" . PSM_DB_PREFIX . "users` AS `u` - JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON ( - `us`.`user_id`=`u`.`user_id` - AND `us`.`server_id` = {$server_id} - ) - "); + $users = $this->db->query(' + 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`.`jabber` + FROM `' . PSM_DB_PREFIX . 'users` AS `u` + JOIN `' . PSM_DB_PREFIX . "users_servers` AS `us` ON ( + `us`.`user_id`=`u`.`user_id` + AND `us`.`server_id` = {$server_id} + ) + "); return $users; } } diff --git a/src/psm/Util/Server/Updater/StatusUpdater.php b/src/psm/Util/Server/Updater/StatusUpdater.php index bbcc5791..5cc42f1c 100644 --- a/src/psm/Util/Server/Updater/StatusUpdater.php +++ b/src/psm/Util/Server/Updater/StatusUpdater.php @@ -41,6 +41,8 @@ class StatusUpdater public $header = ''; + public $curl_info = ''; + public $rtime = 0; public $status_new = false; @@ -86,7 +88,8 @@ class StatusUpdater $this->server_id = $server_id; $this->error = ''; $this->header = ''; - $this->rtime = ''; + $this->curl_info = ''; + $this->rtime = 0; // get server info from db $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array( @@ -96,7 +99,7 @@ class StatusUpdater 'type', 'pattern', 'pattern_online', 'post_field', 'allow_http_status', 'redirect_check', 'header_name', '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' )); 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 $run * @return boolean */ protected function updatePing($max_runs, $run = 1) { - // save response time - $starttime = microtime(true); - // set ping payload - $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost"; + // Settings + $max_runs = ($max_runs == null || $max_runs > 1) ? 1 : $max_runs; + $server_ip = escapeshellcmd($this->server['ip']); + $os_is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; - $socket = socket_create(AF_INET, SOCK_RAW, 1); - socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0)); - socket_connect($socket, $this->server['ip'], null); - - 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); + $status = $os_is_windows ? + $this->pingFromWindowsMachine($server_ip, $max_runs) : + $this->pingFromNonWindowsMachine($server_ip, $max_runs); // check if server is available and rerun if asked. if (!$status && $run < $max_runs) { return $this->updatePing($max_runs, $run + 1); } - return $status; } @@ -216,7 +205,11 @@ class StatusUpdater // save response time $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; $this->rtime = (microtime(true) - $starttime); @@ -257,12 +250,13 @@ class StatusUpdater $this->server['request_method'], $this->server['post_field'] ); - $this->header = $curl_result; + $this->header = $curl_result['exec']; + $this->curl_info = $curl_result['info']; $this->rtime = (microtime(true) - $starttime); // 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 // $code[2][0] = status code // $code[3][0] = name of status code @@ -293,7 +287,7 @@ class StatusUpdater ($this->server['pattern_online'] == 'yes') == !preg_match( "/{$this->server['pattern']}/i", - $curl_result + $curl_result['exec'] ) ) { $this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " . @@ -308,7 +302,7 @@ class StatusUpdater $location_matches = array(); preg_match( '/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/', - $curl_result, + $curl_result['exec'], $location_matches ); if (!empty($location_matches)) { @@ -329,7 +323,7 @@ class StatusUpdater if ($this->server['header_name'] != '' && $this->server['header_value'] != '') { $header_flag = false; // 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) { if ($i === 0 || strpos($line, ':') == false) { 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. if (!$result && $run < $max_runs) { return $this->updateWebsite($max_runs, $run + 1); @@ -383,4 +382,129 @@ class StatusUpdater { 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; + } } diff --git a/src/templates/default/main/body.tpl.html b/src/templates/default/main/body.tpl.html index 7a1c3523..31b96f98 100644 --- a/src/templates/default/main/body.tpl.html +++ b/src/templates/default/main/body.tpl.html @@ -31,31 +31,33 @@ {{ html_modal|raw }} -
    +
    {% if not user_level and subtitle %}

    {{ subtitle }}

    {% endif %} -
    {{ header_accessories|raw }}
    +
    {{ header_accessories|raw }}
    {% for msg in messages %} {% endfor %} -
    +
    {{ html_sidebar|raw }}
    {{ html_content|raw }}
    @@ -74,7 +76,7 @@ {% endblock %} {% endif %} - + @@ -87,7 +89,8 @@ - + + diff --git a/src/templates/default/module/config/config.tpl.html b/src/templates/default/module/config/config.tpl.html index 48b2730c..ffb36a54 100644 --- a/src/templates/default/module/config/config.tpl.html +++ b/src/templates/default/module/config/config.tpl.html @@ -27,6 +27,21 @@ role="tab" aria-controls="config-telegram" aria-selected="{% if telegram_active %}true{% else %}false{% endif %}">{{ label_tab_telegram }}
  • + + +
@@ -36,6 +51,8 @@ {{ label_general }} {{ macro.input_checkbox("show_update", "show_update[]", label_show_update, show_update_checked) }} + + {{ macro.input_field("text", "site_title", null, "site_title", label_site_title, site_title, label_site_title, "255", null, null, null, null, true) }} {{ macro.input_select("language", "language", label_language, languages, language_current) }} @@ -43,6 +60,8 @@ {{ 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", "user_agent", null, "user_agent", label_user_agent, user_agent, "Mozilla/5.0...", "255", "user_agent_key_help", label_user_agent_key_note) }}
@@ -99,7 +118,7 @@ {{ 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("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.input_hidden("test_email", "0") }} {{ 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_from", null, "sms_from", label_sms_from, sms_from, "+31123456789", "255") }} - + {{ macro.button_test("testSms", label_test) }} {{ macro.input_hidden("test_sms", "0") }} {{ macro.button_save("sms_submit", label_save) }}
-
+
+
+ {{ label_settings_discord }} + + {{ macro.input_checkbox("discord_status", "discord_status[]", label_discord_status, discord_status_checked) }} + + {{ 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) }} +
+
+
{{ label_settings_pushover }} +

{{ label_pushover_description|raw }}

{{ macro.input_checkbox("pushover_status", "pushover_status", label_pushover_status, pushover_status_checked) }} @@ -140,9 +172,10 @@ {{ macro.button_save("pushover_submit", label_save) }}
-
+
{{ label_settings_telegram }} +

{{ label_telegram_description|raw }}

{{ macro.input_checkbox("telegram_status", "telegram_status[]", label_telegram_status, telegram_status_checked) }} @@ -154,6 +187,42 @@ {{ macro.button_save("telegram_submit", label_save) }}
+
+
+ {{ label_settings_jabber }} + + {{ macro.input_checkbox("jabber_status", "jabber_status[]", label_jabber_status, jabber_status_checked) }} + + {{ macro.input_checkbox("log_jabber", "log_jabber[]", label_log_jabber, log_jabber_checked) }} + + {{ 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) }} +
+
+
+
+ {{ label_settings_webhook }} +

{{ label_webhook_description|raw }}

+ + {{ macro.input_checkbox("webhook_status", "webhook_status", label_webhook_status, webhook_status_checked) }} + + {{ macro.input_checkbox("log_webhook", "log_webhook", label_log_webhook, log_webhook_checked) }} + + + + + + {{ macro.button_test("testWebhook", label_test) }} + {{ macro.input_hidden("test_webhook", "0") }} + {{ macro.button_save("webhook_submit", label_save) }} +
+
{{ macro.input_csrf() }} diff --git a/src/templates/default/module/install/success.tpl.html b/src/templates/default/module/install/success.tpl.html index dc369a9d..cdc3f577 100644 --- a/src/templates/default/module/install/success.tpl.html +++ b/src/templates/default/module/install/success.tpl.html @@ -12,8 +12,8 @@ If no errors have occurred, you are good to go.

Go to your monitor - PHP Server Monitor - Documentation + PHP Server Monitor + Documentation
{% endblock %} \ No newline at end of file diff --git a/src/templates/default/module/server/history.tpl.html b/src/templates/default/module/server/history.tpl.html index 7f76bc69..7c08a2b3 100644 --- a/src/templates/default/module/server/history.tpl.html +++ b/src/templates/default/module/server/history.tpl.html @@ -1,5 +1,7 @@ + + {% for graph in graphs %}
Your browser does not support the canvas element. @@ -20,7 +22,7 @@

{% endif %} - {{ graph.info.0.label }}: {{ graph.info.0.value }}s + {{ graph.info.0.label }}: {{ graph.info.0.value * 1000 }} ms {% if graph.id == 'history_short' %} @@ -30,7 +32,7 @@ data: { datasets: [ { - data: [{{ graph.lines.offline.value }}], + data: {{ graph.lines.offline.value|raw }}, label: '{{ graph.lines.offline.name }}', backgroundColor: '#dc3545', borderColor: '#dc3545', @@ -41,7 +43,7 @@ spanGaps: false, }, { - data: [{{ graph.lines.online.value }}], + data: {{ graph.lines.online.value|raw }}, label: '{{graph.lines.online.name }}', fill: false, spanGaps: false, @@ -72,6 +74,25 @@ 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: [ {% for key,line in graph.lines %} { - data: [{{ line.value|raw }}], + data: {{ line.value|raw }}, label: '{{ line.name }}', backgroundColor: colors['{{key}}'], borderColor: colors['{{key}}'], @@ -133,6 +154,25 @@ 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, + } + } } } }); diff --git a/src/templates/default/module/server/server/list.tpl.html b/src/templates/default/module/server/server/list.tpl.html index 17c6262d..c0b62b89 100644 --- a/src/templates/default/module/server/server/list.tpl.html +++ b/src/templates/default/module/server/server/list.tpl.html @@ -5,17 +5,17 @@ - {{ label_label }} - {{ label_domain }} - {{ label_port }} - {{ label_type }} - {{ label_rtime }} - {{ label_last_online }} - {{ label_last_offline }} - {{ label_monitoring }} - {% if user_level == 10 %} - - {% endif %} + {{ label_label }} + {{ label_domain }} + {{ label_port }} + {{ label_type }} + {{ label_rtime }} (ms) + {{ label_last_online }} + {{ label_last_offline }} + {{ label_monitoring }} + {% if user_level == 10 %} + + {% endif %} No result @@ -41,7 +41,7 @@
{{ server.ip|raw }}
{{ server.port }} {{ server.type }} - {{ server.rtime }} + {{ (server.rtime * 1000)|round(2) }}
{{ server.last_online }}
{{ server.last_offline }}
@@ -50,24 +50,36 @@ {% else %} {% endif %} - {% if server.email|lower == 'yes'%} + {% if server.email|lower == 'yes' and config.email|lower%} {% endif %} - {% if server.sms|lower == 'yes'%} + {% if server.sms|lower == 'yes' and config.sms|lower%} {% endif %} - {% if server.pushover|lower == 'yes'%} + {% if server.pushover|lower == 'yes'and config.pushover|lower %} P {% endif %} - {% if server.telegram|lower == 'yes'%} - - - T - + {% if server.telegram|lower == 'yes' and config.telegram|lower%} + {% endif %} + {% if server.jabber|lower == 'yes'%} + + + J + + {% endif %} + {% if server.discord|lower == 'yes' and config.discord|lower %} + + {% endif %} + {% if server.webhook|lower == 'yes' and config.webhook|lower %} + + + W + + {% endif %} {% if user_level == 10 %} @@ -81,7 +93,7 @@ {{ label_edit }} + data-modal-param="{{ server.label }}"> {{ label_delete }} diff --git a/src/templates/default/module/server/server/update.tpl.html b/src/templates/default/module/server/server/update.tpl.html index 5d9eee53..286a05d3 100644 --- a/src/templates/default/module/server/server/update.tpl.html +++ b/src/templates/default/module/server/server/update.tpl.html @@ -46,7 +46,9 @@ - {{ 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") }} + + {{ 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) }}
@@ -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("telegram", "telegram", label_send_telegram, edit_telegram_selected, label_yes, label_no, warning_telegram, label_warning_telegram) }} + + {{ macro.input_select_monitoring("jabber", "jabber", label_send_jabber, edit_jabber_selected, label_yes, label_no, warning_jabber, label_warning_jabber) }} + + {{ macro.input_select_monitoring("discord", "discord", label_send_discord, edit_discord_selected, label_yes, label_no, warning_discord, label_warning_discord) }} + + {{ macro.input_select_monitoring("webhook", "webhook", label_send_webhook, edit_webhook_selected, label_yes, label_no, warning_webhook, label_warning_webhook) }}
- +
{{ label_fieldset_permissions }} {{ macro.input_select_multiple("user_id", "user_id[]", label_permissions, label_search, users, label_please_select) }} - {{ macro.button_save(null, label_save) }} - {{ label_go_back }} -
+ +
+ {{ label_save }} + {{ macro.button_save(null, label_save) }} + {{ label_go_back }} +
+ {% if edit_server_id > 0 %} +
+ {{ label_delete }} + + {{ label_delete }} + +
+ {% endif %} {{ macro.input_csrf() }} diff --git a/src/templates/default/module/server/server/view.tpl.html b/src/templates/default/module/server/server/view.tpl.html index ff8783a6..e6d37498 100644 --- a/src/templates/default/module/server/server/view.tpl.html +++ b/src/templates/default/module/server/server/view.tpl.html @@ -1,6 +1,6 @@ {% import 'main/macros.tpl.html' as macro %} {{ macro.input_csrf() }} -
+
@@ -27,7 +27,11 @@
  • {{ label_domain }}:
    -
    {{ ip|raw }}
    +
    + + {{ ip|raw }} + +
  • {% if type|lower == 'service' %} @@ -47,7 +51,7 @@
  • {{ label_rtime }}:
    -
    {{ rtime }} {{ label_seconds }}
    +
    {{ (rtime * 1000)|round(2) }} {{ label_milliseconds }}
  • @@ -227,13 +231,13 @@
  • {{ label_last_error }}:
    -
    {{ last_error }}
    +
    {{ last_error|nl2br }}
  • {{ label_last_output }}:
    -
    {{ last_output_truncated }}
    +
    {{ last_output_truncated|nl2br }}
    {% if last_output_truncated != last_output %}
    @@ -247,7 +251,7 @@
  • {{ label_last_error_output }}:
    -
    {{ last_error_output_truncated }}
    +
    {{ last_error_output_truncated|nl2br }}
    {% if last_error_output_truncated != last_error_output %}
    @@ -305,6 +309,19 @@ {% endif %}
  • +
  • + {{ label_discord }}: + {% if discord|lower == 'yes' %} + + + {% elseif discord|lower == 'no' %} + + + {% else %} + + + {% endif %} +
  • {{ label_pushover }}: {% if pushover|lower == 'yes' %} @@ -331,12 +348,67 @@ {% endif %}
  • +
  • + {{ label_jabber }}: + {% if jabber|lower == 'yes' %} + + + {% elseif jabber|lower == 'no' %} + + + {% else %} + + + {% endif %} +
  • +
  • + {{ label_webhook }}: + {% if webhook|lower == 'yes' %} + + + {% elseif webhook|lower == 'no' %} + + + {% else %} + + + {% endif %} +
  • {{ html_history|raw }}
    + {% if log_entries %} +
    +
    +
    + {{ label_log_title }} +
    +
    +
    + + + + + + + + + {% for entry in log_entries %} + + + + + {% endfor %} + +
    {{ label_date }}{{ label_message }}
    {{ entry.message|raw }}
    +
    +
    +
    +
    + {% endif %}