Merge branch 'release-3.1.0'

This commit is contained in:
Pepijn Over 2014-08-07 14:26:46 +02:00
commit b17b4ec59c
117 changed files with 5920 additions and 6631 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/config.php
/build
/docs/_build
/vendor/

35
CHANGELOG.rst Executable file → Normal file
View File

@ -1,8 +1,41 @@
Changelog
=========
v3.1.0 (released August 7, 2014)
--------------------------------
Features:
* #52: Uptime percentage per server for the last week.
* #101: Pushover.net support.
* #54: Improved phone/tablet compatibility.
* #75: Test mode for email and SMS settings.
* #86: Different design styles on status page (list, table).
* #82: Added Danish translation.
* #103: Added Russian translation.
* #109: Custom time-out per server.
* #119: Log and archive retention period.
* #110: Support for SMSGlobal SMS gateway <https://www.smsglobal.com/>.
* #82: Support for Danish SMS provider Smsit <http://www.smsit.dk/>
Bugs:
* #50: Validation on servers page.
* #62: Replace javascript confirm dialogs with Bootstrap modal dialogs.
* #66: Unable to add users with MySQL in strict mode.
* #83: Invalid redirect after switching languages and logging in.
* #105: Fixing check for websites with unverified SSL certificates.
* #107: Fixing update job for Synology DSM Task Scheduler.
* #108: URLs on Windows contained both back- and forward slashes.
* #111: Generated urls for non-default ports included the port twice.
* #28: Permission denied page.
* #53: User selection on server edit page.
* #115: Warning on server page when notifications are disabled.
* #117: Template service has been replaced by Twig.
* Composer added for dependencies.
v3.0.1 (released April 12, 2014)
----------------
--------------------------------
* #56: Minimum PHP version is PHP 5.3.7 (not PHP 5.3.0).
* #58: Server order on users page now matches the order on servers page.

View File

@ -1,29 +1,45 @@
tag = $(shell git describe)
VERSION = ${subst v,,$(tag)}
RELEASE_DIR = ./build
RELEASE_FILE = phpservermon-$(VERSION)
help:
@echo ' PHP Server Monitor - $(tag) '
@echo ' - make export [tag=...] - create a new release from tag '
@echo ' PHP Server Monitor - $(tag)'
@echo ' - make export [tag=...] - create a new release from tag '
@echo ' - make install - install all dependencies '
install:
@echo 'Downloading dependencies using Composer'
php composer.phar install
@echo 'Install complete '
export:
@echo 'Building release for tag $(tag) '
mkdir -p ./build ./build/phpservermon
rm -rf ./build/phpservermon/*
git archive $(tag) | tar -xf - -C ./build/phpservermon/
mkdir -p $(RELEASE_DIR) $(RELEASE_DIR)/$(RELEASE_FILE)
rm -rf $(RELEASE_DIR)/$(RELEASE_FILE)/*
git archive $(tag) | tar -xf - -C $(RELEASE_DIR)/$(RELEASE_FILE)/
#find $(RELEASE_DIR)/$(RELEASE_FILE) -name "*.php" -exec sed -i "" "s/@package_version@/$(tag)/" {} \; # for osx
find $(RELEASE_DIR)/$(RELEASE_FILE) -name "*.php" -exec sed -i "s/@package_version@/$(tag)/" {} \; # for linux
@echo 'Testing on syntax errors (thats all the automated testing your are going to get for now..) '
find ./build/phpservermon -name "*.php" | xargs -I file php -l file
find ./build/phpservermon -name "*.php" -exec sed -i "" "s/@package_version@/$(tag)/" {} \;
@echo 'Building HTML documentation'
cd ./build/phpservermon/docs; make BUILDDIR=. html; cd ../../../;
find $(RELEASE_DIR)/$(RELEASE_FILE) -name "*.php" | xargs -I file php -l file
@echo 'Downloading dependencies'
cd $(RELEASE_DIR)/$(RELEASE_FILE); php composer.phar install; php composer.phar dump-autoload --optimize; cd ../../;
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/composer.phar
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/composer.json
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/composer.lock
@echo 'Building HTML documentation using sphinx (http://sphinx-doc.org/)'
mkdir -p $(RELEASE_DIR)/$(RELEASE_FILE)/docs/html
cd $(RELEASE_DIR)/$(RELEASE_FILE)/docs; make BUILDDIR=. html; cd ../../../;
@echo 'Cleaning up docs dir'
rm -f ./build/phpservermon/Makefile
rm -f ./build/phpservermon/docs/Makefile
rm -f ./build/phpservermon/docs/make.bat
rm -f ./build/phpservermon/docs/conf.py
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/Makefile
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/docs/Makefile
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/docs/make.bat
rm -f $(RELEASE_DIR)/$(RELEASE_FILE)/docs/conf.py
@echo 'Setting folder and file permissions'
find ./build/phpservermon -type f | xargs chmod 0644
find ./build/phpservermon -type d | xargs chmod 0755
find $(RELEASE_DIR)/$(RELEASE_FILE) -type f | xargs chmod 0644
find $(RELEASE_DIR)/$(RELEASE_FILE) -type d | xargs chmod 0755
@echo 'Creating archives'
cd ./build; zip -rq phpservermon-$(tag).zip ./phpservermon; cd ../;
cd ./build; tar -pczf phpservermon-$(tag).tar.gz ./phpservermon; cd ../;
rm -rf ./build/phpservermon
cd $(RELEASE_DIR); zip -rq $(RELEASE_FILE).zip ./$(RELEASE_FILE); cd ../;
cd $(RELEASE_DIR); tar -pczf $(RELEASE_FILE).tar.gz ./$(RELEASE_FILE); cd ../;
#rm -rf $(RELEASE_DIR)/$(RELEASE_FILE)
@echo 'Building release finished '

View File

@ -1,7 +1,7 @@
PHP Server Monitor
==================
Version 3.0.1
Version 3.1.0
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,
@ -12,7 +12,7 @@ Features:
---------
* Monitor services and websites (see below).
* Email and SMS notifications.
* Email, SMS and Pushover 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.
@ -35,14 +35,16 @@ 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 notification or text message (SMS).
You can choose for email, text message (SMS) and Pushover.net notifications.
The following SMS gateways are currently available:
* Mollie - <http://www.mollie.nl>
* Spryng - <http://www.spryng.nl>
* Inetworx - <http://www.inetworx.ch>
* Clickatell - <https://www.clickatell.com>
* Inetworx - <http://www.inetworx.ch>
* Mollie - <http://www.mollie.nl>
* Mosms - <http://www.mosms.com>
* Smsglobal - <http://smsglobal.com/>
* SMSit - <http://www.smsit.dk/>
* Spryng - <http://www.spryng.nl>
* Textmarketer - <http://www.textmarketer.co.uk>
Please note: for these gateways you will need an account with sufficient credits.
@ -70,6 +72,12 @@ Install
Please see docs/install.rst.
In a nutshell: unzip, upload, run install.php, enjoy.
If you have downloaded the source from GitHub (and not a pre-built package), the dependencies are not included.
To be able to run an installation from the repo, you need to run the following command to install the dependencies::
php composer.phar install
Documentation
-------------

18
composer.json Executable file
View File

@ -0,0 +1,18 @@
{
"name": "phpservermon/phpservermon",
"description": "PHP Server Monitor",
"homepage": "http://www.phpservermonitor.org",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/phpservermon/php-pushover"
}
],
"require": {
"php": ">=5.3.7",
"phpmailer/phpmailer": "5.2.6",
"symfony/http-foundation": "2.4.*",
"php-pushover/php-pushover": "dev-master",
"twig/twig": "1.*"
}
}

216
composer.lock generated Normal file
View File

@ -0,0 +1,216 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "1d763e23381a086e18f83644bd89f16c",
"packages": [
{
"name": "php-pushover/php-pushover",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/phpservermon/php-pushover.git",
"reference": "d13d08dbf5f1cfa73f4adca7e8d27f79c804dd7b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpservermon/php-pushover/zipball/d13d08dbf5f1cfa73f4adca7e8d27f79c804dd7b",
"reference": "d13d08dbf5f1cfa73f4adca7e8d27f79c804dd7b",
"shasum": ""
},
"type": "library",
"autoload": {
"files": [
"Pushover.php"
]
},
"description": "PHP class for the Pushover.net project",
"support": {
"source": "https://github.com/phpservermon/php-pushover/tree/master"
},
"time": "2014-07-30 13:55:53"
},
{
"name": "phpmailer/phpmailer",
"version": "v5.2.6",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "4d9434e394496a5bb7acd9e73046587184b413df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/4d9434e394496a5bb7acd9e73046587184b413df",
"reference": "4d9434e394496a5bb7acd9e73046587184b413df",
"shasum": ""
},
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"phpdocumentor/phpdocumentor": "*",
"phpunit/phpunit": "*"
},
"type": "library",
"autoload": {
"classmap": [
"class.phpmailer.php",
"class.pop3.php",
"class.smtp.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2013-04-11 16:45:39"
},
{
"name": "symfony/http-foundation",
"version": "v2.4.8",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
"reference": "68abe34601c519359b60363b99c29ecfb6679bc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/68abe34601c519359b60363b99c29ecfb6679bc4",
"reference": "68abe34601c519359b60363b99c29ecfb6679bc4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/expression-language": "~2.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
"Symfony/Component/HttpFoundation/Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com",
"time": "2014-07-15 14:07:10"
},
{
"name": "twig/twig",
"version": "v1.16.0",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Twig.git",
"reference": "8ce37115802e257a984a82d38254884085060024"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Twig/zipball/8ce37115802e257a984a82d38254884085060024",
"reference": "8ce37115802e257a984a82d38254884085060024",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.16-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
},
{
"name": "Twig Team",
"homepage": "https://github.com/fabpot/Twig/graphs/contributors",
"role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"time": "2014-07-05 12:19:05"
}
],
"packages-dev": [
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": {
"php-pushover/php-pushover": 20
},
"platform": {
"php": ">=5.3.7"
},
"platform-dev": [
]
}

BIN
composer.phar Normal file

Binary file not shown.

View File

@ -4,4 +4,4 @@ define('PSM_DB_USER', 'db_user');
define('PSM_DB_PASS', 'db_pass');
define('PSM_DB_NAME', 'db_name');
define('PSM_DB_HOST', 'localhost');
?>

View File

@ -39,12 +39,12 @@ $time = time();
if(psm_get_conf('cron_running') == 1 && ($time - psm_get_conf('cron_running_time') < PSM_CRON_TIMEOUT)) {
die('Cron is already running. Exiting.');
}
if(!PSM_DEBUG) {
if(!defined('PSM_DEBUG') || !PSM_DEBUG) {
psm_update_conf('cron_running', 1);
}
psm_update_conf('cron_running_time', $time);
$autorun = new \psm\Util\Updater\Autorun($db);
$autorun = new \psm\Util\Server\UpdateManager($db);
$autorun->run();
psm_update_conf('cron_running', 0);

View File

@ -51,7 +51,7 @@ copyright = u'2008-2014, Pepijn Over'
# built documents.
#
# The short X.Y version.
version = '3.0.1'
version = '3.1.0'
# The full version, including alpha/beta/rc tags.
release = version

View File

@ -9,32 +9,32 @@ Credits
The following people have contributed to the development of PHP Server Monitor:
* Pepijn Over <pep_at_neanderthal-technology.com>
* Pepijn Over - https://github.com/dopeh
* Creator and project maintainer
* Jérôme Cabanis <https://github.com/Abawell>
* Jérôme Cabanis - https://github.com/Abawell
* History graphs
* Date localization
* Mobile compatibility
* Various fixes and improvements
* Perri Vardy-Mason <https://github.com/VeoPVM>
* Perri Vardy-Mason - https://github.com/VeoPVM
* Textmarketer SMS gateway
* Various fixes and improvements
* Luiz Alberto S. Ribeiro <https://github.com/madeinnordeste>
* Luiz Alberto S. Ribeiro - https://github.com/madeinnordeste
* Bootstrap implementation
* Portuguese Brazilian translation
* Michael Greenhill <https://github.com/doctorjbeam>
* Michael Greenhill - https://github.com/doctorjbeam
* Status page
* Andreas Ek <https://github.com/EkAndreas>
* Andreas Ek - https://github.com/EkAndreas
* Mosms SMS gateway
@ -42,6 +42,25 @@ The following people have contributed to the development of PHP Server Monitor:
* Website pattern / regular expression search
* nerdalertdk - https://github.com/nerdalertdk
* Smsit SMS gateway
* Victor Macko - https://github.com/victormacko
* SMSGlobal SMS gateway
* Julien Lebouteiller - https://github.com/Halvra
* Custom time-out per server
* Mathias Lange - https://github.com/remmedia
* Pushover.net support
* Alexander Moore - http://www.famfamfam.com
* Icon
Translators
+++++++++++
@ -50,11 +69,15 @@ The following people have contributed to the translation of PHP Server Monitor:
* Chinese
* manhere <https://github.com/manhere>
* manhere - https://github.com/manhere
* Bulgarian
* Plamen Vasilev <https://github.com/PVasileff>
* Plamen Vasilev - https://github.com/PVasileff
* Danish
* nerdalertdk
* French
@ -79,7 +102,13 @@ The following people have contributed to the translation of PHP Server Monitor:
* Spanish
* Klemens Häckel <http://clickdimension.wordpress.com/>
* Klemens Häckel - http://clickdimension.wordpress.com
* Russian
* Roman Beylin - https://github.com/roman-beylin
* Yuriy Lyutov - https://github.com/delysh
Vendors
+++++++
@ -88,4 +117,7 @@ The following libraries are being used by PHP Server Monitor:
* jqPlot - http://www.jqplot.com
* Twitter Bootstrap - http://getbootstrap.com
* PHP Mailer - https://github.com/PHPMailer/PHPMailer
* Bootstrap Multiselect - https://github.com/davidstutz/bootstrap-multiselect
* PHP Mailer - https://github.com/PHPMailer/PHPMailer
* php-pushover - https://github.com/kryap/php-pushover
* Twig - http://twig.sensiolabs.org

View File

@ -8,4 +8,50 @@ There is a master branch, which is stable and always reflects the latest release
The develop branch is used for ongoing development and should not be considered stable.
If you would like to contribute a patch or feature, please fork the develop branch and send a pull request.
More information can be found in the wiki at https://github.com/phpservermon/phpservermon/wiki.
Languages
+++++++++
The server monitor uses language files, which are stored in the directory "src/lang".
The name of the language file consists of the language code (ISO 639-1) and the country code (ISO 3166-1), separated by an underscore.
The extension is ".lang.php".
Locales
-------
Each language file should contain a 'locale' key which can be used for formatting dates and times. This 'locale' key must include the locales for different server environments:
* Linux / OS X: same as filename (language code and country code separated by underscore)
* Windows: http://msdn.microsoft.com/en-US/library/39cwe7zf%28v=vs.80%29.aspx
For more information, see http://www.php.net/manual/en/function.setlocale.php
Adding a new language
---------------------
To add a new language, follow these steps:
* Create a new file in the directory "src/lang" named "{locale}.lang.php".
* Copy the contents of the file "en_US.lang.php" to your new file.
* Your new language should now be available on the config page.
* Translate :-)
* Please send a pull request on github (https://github.com/phpservermon/phpservermon) so it can be included in the next release :-)
Getting started
+++++++++++++++
All code related to phpservermon lives in the "psm" namespace, which can be found under "src/psm".
The Router (https://github.com/phpservermon/phpservermon/blob/develop/src/psm/Router.class.php) is used to load the modules.
All modules are registered inside the Router class with a unique ID (see getModules()), and can either be loaded manually ($router->run('mod')), or if no module is given it will attempt to discover the module from the $_GET['mod'] var.
If no valid module or controller is found, it will fall back to the default module.
The module var may exist of 2 parts, separated by an underscore. The first part is the ID of the module, and the second part is the ID of the controller registered in the module.
If no controller ID is found, it will attempt to load the controller with the same ID as the module.
Examples ::
$router->run('config'); // module ID "config" and controller ID also "config" (same as $router->run('config_config'))
$router->run('server_status'); // module ID "server" and controller ID "status"
If the user is not logged in and login is required, it will automatically load the user login controller without throwing an error.

View File

@ -25,6 +25,37 @@ Regular users:
* Run the updater on their assigned servers.
Servers
+++++++
What is the difference between a service and a website?
-------------------------------------------------------
For websites, the monitor attempts to open a regular web page, just like you do in your browser.
It will attempt to retrieve its contents, and also check the HTTP status code (for example "404 not found" will cause an error).
You can then even add a check to make sure the content of the website includes a certain string or matches a certain regular expression.
Please note, it only retrieves the contents and does not execute any Javascript. Your search pattern will not work if it depends on Javascript being executed.
For services, the monitor only attempts to connect to the IP address and specified port to check whether the server is listening on that port.
For example, if you are running a webserver it will usually listen on port 80 for incoming connections.
So if the monitor is able to connect to the server on port 80, you know the webserver is running and accepting connections.
It does not, however, mean that your website is available to your users, because it might have PHP errors or database problems.
This can be monitored using the website type with a pattern search as described above.
Are requests made by the monitor included in my website statistics?
-------------------------------------------------------------------
There are two different ways to gather statistics.
One way is to include a piece of Javascript in your HTML, e.g. for Google Analytics and Piwik.
The other way is to parse the access logs created by your webserver software, which does not require any changes to your code, and is done by tools like Awstats.
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::
Mozilla/5.0 (compatible; phpservermon/3.0.1; +http://www.phpservermonitor.org)
Configuration
+++++++++++++

View File

@ -64,6 +64,15 @@ One of the new features introduced in 3.0 is a user authentication system. Becau
For that reason the upgrade script will ask you to create a new account during the upgrade, which you can then use to change the password for the existing accounts.
If, for whatever reason this does not work, the upgrade script automatically changes the username of all existing users to their email addresses, which you could use for the forgot password screen.
Installing from GitHub
++++++++++++++++++++++
If you have downloaded the source from GitHub (and not a pre-built package), the dependencies are not included.
To be able to run an installation from the repo, you need to run the following command to install the dependencies::
php composer.phar install
Setting up a cronjob
++++++++++++++++++++
@ -78,10 +87,15 @@ If it is your own server or you have shell access and permission to open the cro
As you can see, this line will run the status.cron.php script every 15 minutes. Change the line to suit your needs.
If you do not have shell access, ask your web hosting provider to set it up for you.
Please note that some distros have user-specific crontabs (e.g. Debian). If that is the case, you need to omit the user part::
*/15 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php
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.
Troubleshooting
+++++++++++++++

View File

@ -15,7 +15,7 @@ Features
++++++++
* Monitor services and websites (see below).
* Email and SMS notifications.
* Email, SMS and Pushover 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,14 +44,22 @@ There are two different ways to monitor a server:
Notifications
-------------
Each server has its own settings regarding notification.
You can choose for email notification or text message (SMS).
You can choose for email, text message (SMS) and Pushover.net notifications.
The following SMS gateways are currently available:
* Mollie - http://www.mollie.nl
* Spryng - http://www.spryng.nl
* Inetworx - http://www.inetworx.ch
* Clickatell - https://www.clickatell.com
* Mosms - http://www.mosms.com
* Textmarketer - http://www.textmarketer.co.uk
* Clickatell - <https://www.clickatell.com>
* Inetworx - <http://www.inetworx.ch>
* Mollie - <http://www.mollie.nl>
* Mosms - <http://www.mosms.com>
* Smsglobal - <http://smsglobal.com/>
* SMSit - <http://www.smsit.dk/>
* Spryng - <http://www.spryng.nl>
* Textmarketer - <http://www.textmarketer.co.uk>
Please note: for these gateways you will need an account with sufficient credits.
Download
++++++++
The latest version can be downloaded from http://www.phpservermonitor.org/.

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -28,7 +28,6 @@
// Include paths
define('PSM_PATH_SRC', dirname(__FILE__) . DIRECTORY_SEPARATOR);
define('PSM_PATH_VENDOR', PSM_PATH_SRC . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR);
define('PSM_PATH_INC', PSM_PATH_SRC . 'includes' . DIRECTORY_SEPARATOR);
define('PSM_PATH_TPL', PSM_PATH_SRC . 'templates' . DIRECTORY_SEPARATOR);
define('PSM_PATH_LANG', PSM_PATH_SRC . 'lang' . DIRECTORY_SEPARATOR);
@ -48,7 +47,10 @@ if(file_exists($path_conf)) {
include_once $path_conf;
}
// check for a debug var
if(defined('PSM_DEBUG') && PSM_DEBUG) {
if(!defined('PSM_DEBUG')) {
define('PSM_DEBUG', false);
}
if(PSM_DEBUG) {
error_reporting(E_ALL);
ini_set('display_erors', 1);
} else {
@ -56,29 +58,28 @@ if(defined('PSM_DEBUG') && PSM_DEBUG) {
ini_set('display_errors', 0);
}
$vendor_autoload = PSM_PATH_SRC . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
if(!file_exists($vendor_autoload)) {
die('No dependencies found in vendor dir. Did you install the dependencies? Please run "php composer.phar install".');
}
require_once $vendor_autoload;
// set autoloader, make sure to set $prepend = true so that our autoloader is called first
function __autoload($class) {
spl_autoload_register(function($class) {
// remove leading \
$class = ltrim($class, '\\');
$path_parts = explode('\\', $class);
$filename = array_pop($path_parts);
$path = implode(DIRECTORY_SEPARATOR, $path_parts) .
$path = PSM_PATH_SRC . implode(DIRECTORY_SEPARATOR, $path_parts) .
DIRECTORY_SEPARATOR .
$filename . '.class.php'
;
// search in these dirs:
$basedirs = array(
PSM_PATH_SRC,
PSM_PATH_VENDOR
);
foreach($basedirs as $dir) {
if(file_exists($dir . $path)) {
require_once $dir . $path;
return;
}
if(file_exists($path)) {
require_once $path;
return;
}
}
});
// auto-find all include files
$includes = glob(PSM_PATH_INC . '*.inc.php');
@ -89,14 +90,7 @@ foreach($includes as $file) {
$db = new psm\Service\Database();
// sanity check!
if(defined('PSM_INSTALL') && PSM_INSTALL) {
// install mode
if($db->status()) {
// connection established, attempt to load config.
// no biggie if it doesnt work because the user is still in the install module.
psm_load_conf();
}
} else {
if(!defined('PSM_INSTALL') || !PSM_INSTALL) {
if($db->getDbHost() === null) {
// no config file has been loaded, redirect the user to the install
header('Location: install.php');

View File

@ -111,7 +111,6 @@ function psm_get_langs() {
/**
* Get a setting from the config.
* The config must have been loaded first using psm_load_conf()
*
* @param string $key
* @param mixed $alt if not set, return this alternative
@ -119,6 +118,9 @@ function psm_get_langs() {
* @see psm_load_conf()
*/
function psm_get_conf($key, $alt = null) {
if(!isset($GLOBALS['sm_config'])) {
psm_load_conf();
}
$result = (isset($GLOBALS['sm_config'][$key])) ? $GLOBALS['sm_config'][$key] : $alt;
return $result;
@ -134,9 +136,11 @@ function psm_get_conf($key, $alt = null) {
function psm_load_conf() {
global $db;
// load config from database into global scope
$GLOBALS['sm_config'] = array();
if(!defined('PSM_DB_PREFIX') || !$db->status()) {
return false;
}
if(!$db->ifTableExists(PSM_DB_PREFIX.'config')) {
return false;
}
@ -163,13 +167,10 @@ function psm_load_conf() {
function psm_update_conf($key, $value) {
global $db;
$result = $db->save(
PSM_DB_PREFIX.'config',
array('value' => $value),
array('key' => $key)
);
// save returns the # rows updated, if 0, key doenst exist yet
if($result === 0) {
// check if key exists
$exists = psm_get_conf($key, false);
if($exists === false) {
// add new config record
$db->save(
PSM_DB_PREFIX . 'config',
array(
@ -177,6 +178,12 @@ function psm_update_conf($key, $value) {
'value' => $value,
)
);
} else {
$db->save(
PSM_DB_PREFIX.'config',
array('value' => $value),
array('key' => $key)
);
}
$GLOBALS['sm_config'][$key] = $value;
}
@ -260,16 +267,20 @@ function psm_parse_msg($status, $type, $vars) {
* @param string $href
* @param boolean $header return headers?
* @param boolean $body return body?
* @param int $timeout connection timeout in seconds
* @param int $timeout connection timeout in seconds. defaults to PSM_CURL_TIMEOUT (10 secs).
* @param boolean $add_agent add user agent?
* @return string cURL result
*/
function psm_curl_get($href, $header = false, $body = true, $timeout = 10, $add_agent = true) {
function psm_curl_get($href, $header = false, $body = true, $timeout = null, $add_agent = true) {
$timeout = $timeout == null ? PSM_CURL_TIMEOUT : intval($timeout);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, $header);
curl_setopt($ch, CURLOPT_NOBODY, (!$body));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_ENCODING, '');
@ -335,12 +346,9 @@ function psm_date($time) {
* Check if an update is available for PHP Server Monitor.
*
* Will only check for new version if user turned updates on in config.
* @global object $db
* @return boolean
*/
function psm_update_available() {
global $db;
if(!psm_get_conf('show_update')) {
// user does not want updates, fair enough.
return false;
@ -370,15 +378,15 @@ function psm_update_available() {
}
/**
* Prepare a new Mailer util.
* 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 \psm\Util\Mailer
* @return \PHPMailer
*/
function psm_build_mail($from_name = null, $from_email = null) {
$phpmailer = new \psm\Util\Mailer();
$phpmailer = new \PHPMailer();
$phpmailer->Encoding = "base64";
$phpmailer->SMTPDebug = false;
@ -409,30 +417,93 @@ function psm_build_mail($from_name = null, $from_email = null) {
return $phpmailer;
}
/**
* Prepare a new Pushover util.
*
* @return \Pushover
*/
function psm_build_pushover() {
$pushover = new \Pushover();
$pushover->setToken(psm_get_conf('pushover_api_token'));
return $pushover;
}
/**
* Prepare a new SMS util.
*
* @return \psm\Txtmsg\TxtmsgInterface
*/
function psm_build_sms() {
$sms = null;
// open the right class
// not making this any more dynamic, because perhaps some gateways need custom settings (like Mollie)
switch(strtolower(psm_get_conf('sms_gateway'))) {
case 'mosms':
$sms = new \psm\Txtmsg\Mosms();
break;
case 'smsit':
$sms = new \psm\Txtmsg\Smsit();
break;
case 'inetworx':
$sms = new \psm\Txtmsg\Inetworx();
break;
case 'mollie':
$sms = new \psm\Txtmsg\Mollie();
$sms->setGateway(1);
break;
case 'spryng':
$sms = new \psm\Txtmsg\Spryng();
break;
case 'clickatell':
$sms = new \psm\Txtmsg\Clickatell();
break;
case 'textmarketer':
$sms = new \psm\Txtmsg\Textmarketer();
break;
case 'smsglobal':
$sms = new \psm\Txtmsg\Smsglobal();
break;
}
// copy login information from the config file
if($sms) {
$sms->setLogin(psm_get_conf('sms_gateway_username'), psm_get_conf('sms_gateway_password'));
$sms->setOriginator(psm_get_conf('sms_from'));
}
return $sms;
}
/**
* Generate a new link to the current monitor
* @param array $params key value pairs
* @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) {
$defports = array(80, 443);
$url = ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
if(!in_array($_SERVER['SERVER_PORT'], $defports)) {
$url .= ':' . $_SERVER['SERVER_PORT'];
}
// 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']) . '/';
$url = str_replace('\\', '', $url);
if($params != null) {
$url .= '?';
$delim = ($htmlentities) ? '&amp;' : '&';
if(is_array($params)) {
$delim = ($htmlentities) ? '&amp;' : '&';
foreach($params as $k => $v) {
if($urlencode) {
$v = urlencode($v);
foreach($params as $k => $v) {
if($urlencode) {
$v = urlencode($v);
}
$url .= $delim . $k . '=' . $v;
}
$url .= $delim . $k . '=' . $v;
} else {
$url .= $params;
}
}
@ -470,12 +541,11 @@ function psm_POST($key, $alt = null) {
/**
* Check if we are in CLI mode
*
* Note, php_sapi cannot be used because cgi-fcgi returns both for web and cli
* source: https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_is_cli/7
* 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' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
return (!isset($_SERVER['SERVER_SOFTWARE']) || php_sapi_name() == 'cli');
}
###############################################
@ -491,7 +561,9 @@ function psm_is_cli() {
*/
function pre($arr = null) {
echo "<pre>";
if ($arr === null) debug_print_backtrace();
if ($arr === null) {
debug_print_backtrace();
}
print_r($arr);
echo "</pre>";
}

View File

@ -29,7 +29,7 @@
/**
* Current PSM version
*/
define('PSM_VERSION', '3.0.1');
define('PSM_VERSION', '3.1.0');
/**
* URL to check for updates. Will not be checked if turned off on config page.
@ -96,3 +96,19 @@ define('PSM_LOGIN_RESET_RUNTIME', 3600);
* Number of seconds the cron is supposedly dead and we will run another cron anyway.
*/
define('PSM_CRON_TIMEOUT', 600);
/**
* Default timeout in seconds for curl requests (can be overwritten per-server).
*/
define('PSM_CURL_TIMEOUT', 10);
/**
* Name of the default theme.
*/
define('PSM_THEME', 'default');
/**
* Clone URL for the Pushover.net service.
*/
define('PSM_PUSHOVER_CLONE_URL', 'https://pushover.net/apps/clone/php_server_monitor');

View File

@ -18,7 +18,7 @@
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Plamen Vasilev <p.vasileff@gmail.com>
* @author Plamen Vasilev a.k.a Paco <p.vasileff@gmail.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
@ -29,35 +29,35 @@ $sm_lang = array(
'name' => 'Български - Bulgarian',
'locale' => array('bg_BG.UTF-8', 'bg_BG', 'bulgarian'),
'system' => array(
'title' => 'Server Monitor',
'title' => 'Мониторинг',
'install' => 'Инсталация',
'action' => 'Действие',
'save' => 'Запиши',
'edit' => 'Редактирай',
'delete' => 'Изтрии',
'deleted' => 'Записът е изтрит',
'delete' => 'Изтрий',
'date' => 'Дата',
'message' => 'Съобщебие',
'message' => 'Съобщение',
'yes' => 'Да',
'no' => 'Не',
'edit' => 'Редактиране на',
'insert' => 'Добавяне',
'add_new' => 'Добави нов',
'update_available' => 'Налична е нова версия ({version}). Може да я свалите от <a href="http://www.phpservermonitor.org" target="_blank">тук</a>.',
'update_available' => 'Налична е нова версия: ({version}). Може да я свалите от <a href="http://www.phpservermonitor.org" target="_blank">тук</a>.',
'back_to_top' => 'Нагоре',
'go_back' => 'Go back',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'go_back' => 'Назад',
'ok' => 'Ок',
'cancel' => 'Отказ',
// date/time са във формат според параметъра strftime PHP функцията http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
'yesterday_format' => 'Yesterday at %k:%M',
'other_day_format' => '%A at %k:%M',
'never' => 'Never',
'hours_ago' => '%d hours ago',
'an_hour_ago' => 'about an hour ago',
'minutes_ago' => '%d minutes ago',
'a_minute_ago' => 'about a minute ago',
'seconds_ago' => '%d seconds ago',
'a_second_ago' => 'a second ago',
'yesterday_format' => 'Вчера в %k:%M',
'other_day_format' => '%A в %k:%M',
'never' => 'Никога',
'hours_ago' => 'преди %d часа',
'an_hour_ago' => 'преди час',
'minutes_ago' => 'преди %d минути',
'a_minute_ago' => 'преди минута',
'seconds_ago' => 'преди %d секунди',
'a_second_ago' => 'преди секунда',
),
'menu' => array(
'config' => 'Настройки',
@ -71,29 +71,37 @@ $sm_lang = array(
'users' => array(
'user' => 'Потребител',
'name' => 'Име',
'user_name' => 'Username',
'password' => 'Password',
'password_repeat' => 'Password repeat',
'password_leave_blank' => 'Leave blank to keep unchanged',
'level' => 'Level',
'level_10' => 'Administrator',
'level_20' => 'User',
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'user_name' => 'Потребител',
'password' => 'Парола',
'password_repeat' => 'Повторете паролата',
'password_leave_blank' => 'Оставете празно, за да не бъде променена паролата',
'level' => 'Ниво на достъп',
'level_10' => 'Администратор',
'level_20' => 'Потребител',
'level_description' => '<b>Администраторите</b> имат пълен достъп: могат да управляват сървърите, потребителите и да редактират глобалните настройки.<br/><b>Потребителите</b> могат само да виждат статуса на сървърите и да обнояват информацията за даден сървър, за който им е разрешен достъп.',
'mobile' => 'Мобилен телефон',
'email' => 'Имейл',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Изтриване на потребител',
'delete_message' => 'Сигурни ли сте, че искате да изтриете потребител \'%1\'?',
'deleted' => 'Потребителят е изтрит успешно.',
'updated' => 'Информацията за потребителя е обновена.',
'inserted' => 'Потребителят е добавен.',
'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' => 'It may only contain alphabetic characters (a-z, A-Z), digits (0-9) 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.',
'error_user_level_invalid' => 'The given user level is invalid.',
'error_user_no_match' => 'The user could not be found in the database.',
'error_user_password_invalid' => 'The entered password is invalid.',
'error_user_password_no_match' => 'The entered passwords do not match.',
'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' => 'Записи в лога',
@ -101,42 +109,66 @@ $sm_lang = array(
'status' => 'Статус',
'email' => 'Имейл',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'Няма налични логове',
),
'servers' => array(
'server' => 'Сървър',
'status' => 'Статус',
'label' => 'Име',
'domain' => 'Хост',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Порт',
'type' => 'Тип',
'type_website' => 'Website',
'type_service' => 'Service',
'pattern' => 'Търсене на образец/схема',
'pattern_description' => 'If this pattern is not found on the website, the server will be marked offline. Regular expressions are allowed.',
'type_website' => 'Сайт',
'type_service' => 'Услуга',
'pattern' => 'Търсене на стринг/образец',
'pattern_description' => 'Ако този текст не е намерен в интернет страницата (когато имате добавен сайт), той ще бъде маркиран като Офлайн. Регулярните изрази са разрешени.',
'last_check' => 'Последна проверка',
'last_online' => 'Последно на линия',
'monitoring' => 'Мониторинг',
'no_monitoring' => 'Не се наблюдава',
'email' => 'Имейл',
'send_email' => 'Имейл',
'sms' => 'SMS',
'send_sms' => 'SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Изтриване на сървър',
'delete_message' => 'Сигурни ли сте, че искате да изтриете сървър \'%1\'?',
'deleted' => 'Сървъра е изтрит успешно.',
'updated' => 'Информацията за сървъра е обновена.',
'inserted' => 'Сървърът е добвен успешно.',
'latency' => 'Пинг',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'inserted' => 'Сървърът е добавен успешно.',
'latency' => 'Латенция',
'latency_max' => 'Латенция (максимална)',
'latency_min' => 'Латенция (минимална)',
'latency_avg' => 'Латенция (средна)',
'uptime' => 'Ъптайм',
'year' => 'Година',
'month' => 'Месец',
'week' => 'Седмица',
'day' => 'Ден',
'hour' => 'Час',
'warning_threshold' => 'Предупредителен праг',
'warning_threshold_description' => 'Брой неуспешни проверки, преди сървъра или сайта да бъдат маркирани като Офлайн.',
'chart_last_week' => 'Последната седмица',
'chart_history' => 'История',
// Charts формат на датата според jqPlot http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%d.%m.%Y',
'chart_long_date_format' => '%d.%m.%Y %H:%M:%S',
'chart_short_date_format' => '%d.%m %H:%M',
'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_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'Основни настройки',
@ -154,24 +186,30 @@ $sm_lang = array(
'sms_status' => 'Да се изпращат ли SMS-и',
'sms_gateway' => 'Портал за изпращане на SMS-и',
'sms_gateway_mosms' => 'Mosms',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_mollie' => 'Mollie',
'sms_gateway_spryng' => 'Spryng',
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_username' => 'Потребител',
'sms_gateway_password' => 'Парола',
'sms_from' => 'Номер на изпращача',
'alert_type' => 'Изберете кога желаете да получавате известия<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Изберете кога желаете да получавате известия',
'alert_type_description' => '<b>Промяна на сатуса:</b><br>'.
'Ще получавате известие когато има промяна със връзката на даден някой от описаните сървър или сайт. От Онлайн -> Офлайн и от Офлайн -> Онлайн.<br/>'.
'<br/><b>Офлайн</b><br>'.
'Ще получите известие когато връзката до сървъра е изгубена за *ПЪРВИ ПЪТ*. Например, '.
'вашия cron скрипт проверява всеки 15 минути и връзката до сървъра е изгубена в 1 часа през ноща и не работи до 6 часа сутринта '.
'вашия cron скрипт проверява всеки 15 минути и връзката до сървъра е изгубена в 1 часа през нощта и не работи до 6 часа сутринта '.
'Вие ще получите едно известие в 1 часа за това<br/>'.
'<br><b>Винаги:</b><br> '.
'Ще получавате известие при всяка проверка на Вашия cron скрипт дори когато връзката до даден сървър или сайт е била'.
'прекъсната в продължение на часове.',
'Ще получавате известие при всяка проверка на Вашия крон скрипт дори когато връзката до даден сървър или сайт е била прекъсната в продължение на часове.',
'alert_type_status' => 'Промяна на статуса',
'alert_type_offline' => 'Офлайн',
'alert_type_always' => 'Винаги',
@ -179,52 +217,81 @@ $sm_lang = array(
'log_status_description' => 'Ако е отметнато, системата ще записва всяка промяна.',
'log_email' => 'Да се пази ли лог на изпратените имейли от системата',
'log_sms' => 'Да се пази ли лог на изпратените SMS съобщения от системата',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Настройките са обновени успешно.',
'tab_email' => 'Имейл',
'tab_sms' => 'SMS',
'tab_log' => 'логовете',
'tab_pushover' => 'Pushover',
'settings_email' => 'Имейл настройки',
'settings_sms' => 'SMS настройки',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Настройки на известията',
'settings_log' => 'Настройки на логовете',
'auto_refresh' => 'Автоматично опресняване',
'auto_refresh_servers' =>
'Автоматично опресняване на страницата.<br/>'.
'<span class="small">'.
'Времето е в секунди, ако е 0 страницата няма да се обноява.'.
'Времето е в секунди, ако е 0 страницата няма да се обновява.'.
'</span>',
'seconds' => 'seconds',
'seconds' => 'секунди',
'test' => 'Тест',
'test_email' => 'Ще бъде изпратенo тестово съобщение до имейл адреса, който сте задали в профила си.',
'test_sms' => 'Ще бъде изпратен тестово SMS съобщение до телефонния номер, който сте задали в профила си.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Изпрати',
'test_subject' => 'Test',
'test_message' => 'Тестово съобщение',
'email_sent' => 'Тестовия имейл е изпратен успешно.',
'email_error' => 'Възникна грешка при изпращането на тесовия имейл',
'sms_sent' => 'Тестовото SMS съобщение е изпратеното успешно.',
'sms_error' => 'Възникна грешка при изпращането на тестовия SMS',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// За нов ред в имейл съобщението, моля използвайте тага <br/>
'notifications' => array(
'off_sms' => 'Syrvyryt \'%LABEL%\' e OFFLINE: ip=%IP%, port=%PORT%. Greshka=%ERROR%',
'off_sms' => 'Сървър \'%LABEL%\' е Офлайн: ip=%IP%, port=%PORT%. Greshka=%ERROR%',
'off_email_subject' => 'Връзката до \'%LABEL%\' е ИЗГУБЕНА',
'off_email_body' => "Неуспешно свързване:<br/><br/>Сървър: %LABEL%<br/>IP адрес: %IP%<br/>Порт: %PORT%<br/>Грешка: %ERROR%<br/>Днес: %DATE%",
'on_sms' => 'Syrvyryt \'%LABEL%\' e ONLINE: ip=%IP%, port=%PORT%',
'off_pushover_title' => 'Връзката до \'%LABEL%\' е ИЗГУБЕНА',
'off_pushover_message' => "Неуспешно свързване:<br/><br/>Сървър: %LABEL%<br/>IP адрес: %IP%<br/>Порт: %PORT%<br/>Грешка: %ERROR%<br/>Днес: %DATE%",
'on_sms' => 'Сървър \'%LABEL%\' е Онлайн: ip=%IP%, port=%PORT%',
'on_email_subject' => 'Връзката до \'%LABEL%\' е ВЪЗСТАНОВЕНА',
'on_email_body' => "Връзката до '%LABEL%' беше ВЪЗСТАНОВЕНА:<br/><br/>Сървър: %LABEL%<br/>IP адрес: %IP%<br/>Порт: %PORT%<br/>Днес: %DATE%",
'on_pushover_title' => 'Връзката до \'%LABEL%\' е ВЪЗСТАНОВЕНА',
'on_pushover_message' => "Връзката до '%LABEL%' беше ВЪЗСТАНОВЕНА:<br/><br/>Сървър: %LABEL%<br/>IP адрес: %IP%<br/>Порт: %PORT%<br/>Днес: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
'title_sign_in' => 'Please sign in',
'title_forgot' => 'Forgot your password?',
'title_reset' => 'Reset your password',
'submit' => 'Submit',
'remember_me' => 'Remember me',
'login' => 'Login',
'logout' => 'Logout',
'username' => 'Username',
'password' => 'Password',
'password_repeat' => 'Repeat password',
'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.<br/><br/>%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.',
'error_reset_invalid_link' => 'The reset link you provided is invalid.',
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
'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' => 'Възстановяване на парола за PHP Сървър Мониторинг',
'password_reset_email_body' => 'За да възстановите паролата си е нужно да кликнете на линка по-долу. Валидността на линка е един час.<br/><br/>%link%',
'error_user_incorrect' => 'Потребителят не може да бъде намерен.',
'error_login_incorrect' => 'Информацията е грешна.',
'error_login_passwords_nomatch' => 'Паролите не съвпадат.',
'error_reset_invalid_link' => 'Линкът за възстановяване на паролата не е валиден.',
'success_password_forgot' => 'Изпратен е имейл с информация за възстановяване на паролата.',
'success_password_reset' => 'Вашата парола е променена успешно. Моля, влезте в системата.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

297
src/lang/da_DK.lang.php Normal file
View File

@ -0,0 +1,297 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author nerdalertdk
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
$sm_lang = array(
'name' => 'Dansk - Danish',
'locale' => array('da_DK.UTF-8', 'da_DK', 'danish', 'danish-dk'),
'system' => array(
'title' => 'Server Monitor',
'install' => 'Installere',
'action' => 'Action',
'save' => 'Gem',
'edit' => 'Redigere',
'delete' => 'Slet',
'date' => 'Dato',
'message' => 'Besked',
'yes' => 'Ja',
'no' => 'Nej',
'insert' => 'Indsæt',
'add_new' => 'Tilføj ny',
'update_available' => 'En ny version ({version}) er tilgængelig på <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Til toppen',
'go_back' => 'Tilbage',
'ok' => 'OK',
'cancel' => 'Annuller',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
'yesterday_format' => 'Igår %k:%M',
'other_day_format' => '%A %k:%M',
'never' => 'Aldrig',
'hours_ago' => '%d timer siden',
'an_hour_ago' => 'omkring en time siden',
'minutes_ago' => '%d minutter siden',
'a_minute_ago' => 'omkring et minut siden',
'seconds_ago' => '%d sekunder siden',
'a_second_ago' => 'et sekund siden',
),
'menu' => array(
'config' => 'Indstillinger',
'server' => 'Servere',
'server_log' => 'Log',
'server_status' => 'Status',
'server_update' => 'Opdatere',
'user' => 'Brugere',
'help' => 'Hjælp',
),
'users' => array(
'user' => 'Bruger',
'name' => 'Navn',
'user_name' => 'Brugernavn',
'password' => 'Adgangskode',
'password_repeat' => 'Adgangskode igen',
'password_leave_blank' => 'Udfyldes hvis du vil skifte kode',
'level' => 'Level',
'level_10' => 'Administrator',
'level_20' => 'Bruger',
'level_description' => '<b>Administratore</b> har fuld adgang: De kan styre servere, brugere og indstillingere.<br/><b>Brugere</b> kan kun se og køre opdatere for servere som er tildelt til dem.',
'mobile' => 'Mobil',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Slet bruger',
'delete_message' => 'Er du sikker på du vil slette bruger \'%1\'?',
'deleted' => 'Bruger slettet.',
'updated' => 'Bruger opdateret.',
'inserted' => 'Bruger tilføjet.',
'profile' => 'Profil',
'profile_updated' => 'Din profil er opdateret.',
'error_user_name_bad_length' => 'Brugernavn skal være mellem 2 til 64 tegn.',
'error_user_name_invalid' => 'Brugernavn må kun indholde alfabetiske tegn (a-z, A-Z), tal (0-9) og (_).',
'error_user_name_exists' => 'Det valgte brugernavn findes allerede.',
'error_user_email_bad_length' => 'Email addresser skal være mellem 5 til 255 tegn.',
'error_user_email_invalid' => 'Den valgte email er ugyldig.',
'error_user_level_invalid' => 'Det angivet bruger niveau er ugyldig.',
'error_user_no_match' => 'Brugeren findes ikke.',
'error_user_password_invalid' => 'Den indtastede adgangskode er ugyldig.',
'error_user_password_no_match' => 'De to adgangskode er ikke ens.',
),
'log' => array(
'title' => 'Logposter',
'type' => 'Type',
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'Intet i loggen',
),
'servers' => array(
'server' => 'Server',
'status' => 'Status',
'label' => 'Label',
'domain' => 'Domæne/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Type',
'type_website' => 'Hjemmeside',
'type_service' => 'Tjeneste',
'pattern' => 'Søge streng/mønster',
'pattern_description' => 'Hvis dette mønster ikke findes på hjemmesiden, vil serveren blive markeret offline. Regulære udtryk er tilladt.',
'last_check' => 'Sidst kontrolleret',
'last_online' => 'Sidst online',
'monitoring' => 'Overvågning',
'no_monitoring' => 'Ingen overvågning',
'email' => 'Email',
'send_email' => 'Send Email',
'sms' => 'SMS',
'send_sms' => 'Send SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Slet server',
'delete_message' => 'Er du sikker på du vil slette server \'%1\'?',
'deleted' => 'Server slettet.',
'updated' => 'Server opdateret.',
'inserted' => 'Server tilføjet.',
'latency' => 'Latency',
'latency_max' => 'Latency (maksimum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (gennemsnitlig)',
'uptime' => 'Oppetid',
'year' => 'År',
'month' => 'Måned',
'week' => 'Uge',
'day' => 'Dag',
'hour' => 'Time',
'warning_threshold' => 'Advarsel grænse',
'warning_threshold_description' => 'Antal af fejl før status skifter til offline.',
'chart_last_week' => 'Sidste uge',
'chart_history' => 'Historie',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%d-%m-%Y',
'chart_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'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_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'Generelt',
'language' => 'Sprog',
'show_update' => 'Opdateringer',
'email_status' => 'Tillad at sende mail',
'email_from_email' => 'Email fra adresse',
'email_from_name' => 'Email fra navn',
'email_smtp' => 'Aktiver SMTP',
'email_smtp_host' => 'SMTP vært',
'email_smtp_port' => 'SMTP port',
'email_smtp_username' => 'SMTP brugernavn',
'email_smtp_password' => 'SMTP adgangskode',
'email_smtp_noauth' => 'Efterladt blank hvis det ikke er opkrævet',
'sms_status' => 'Tillad at sende SMS beskeder',
'sms_gateway' => 'SMS Gateway',
'sms_gateway_mosms' => 'Mosms',
'sms_gateway_mollie' => 'Mollie',
'sms_gateway_spryng' => 'Spryng',
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Gateway brugernavn/apikey',
'sms_gateway_password' => 'Gateway adgangskode',
'sms_from' => 'Afsenders navn.',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Vælg hvornår du vil modtage besked',
'alert_type_description' => '<b>Status ændring:</b> '.
'Du vil modtage en notifcation når en server har en ændring i status. Fra online -> offline eller offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
'Du vil modtage en meddelelse, når en server går offline for * kun første gang *. for eksempel, '.
'Hvis dit cronjob køre hvert kvatere og din server går ned kl 01 og kommer først op kl 06 '.
' så vil du kun modtage en mail kl 01.<br/>'.
'<br><b>Altid:</b> '.
'Du vil modtage en besked, hver gang scriptet kører og et websted er nede, selvom site har været offline i flere timer.',
'alert_type_status' => 'Status ændret',
'alert_type_offline' => 'Offline',
'alert_type_always' => 'Altid',
'log_status' => 'Log status',
'log_status_description' => 'Hvis log status er sat til TRUE, vil monitoren logge hændelsen hver gang status ændre sig.',
'log_email' => 'Log mails sendt af systemet',
'log_sms' => 'Log SMS sendt af systemet',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Indstillingerne er blevet opdateret.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email indstillinger',
'settings_sms' => 'SMS indstillinger',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Meddelelse indstillinger',
'settings_log' => 'Log indstillinger',
'auto_refresh' => 'Genopfriske automatisk',
'auto_refresh_servers' =>
'Genopfriske automatisk server sider.<br/>'.
'<span class="small">'.
'Tid i sekunder, Hvis 0 vil siden ikke genopfriske automatisk'.
'</span>',
'seconds' => 'sekunder',
'test' => 'Test',
'test_email' => 'En email vil blive sendt til den adresse, der er angivet i din brugerprofil.',
'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test besked',
'email_sent' => 'Email sendt',
'email_error' => 'Fejl ved afsendelse af email',
'sms_sent' => 'Sms sendt',
'sms_error' => 'Fejl ved afsendelse af SMS',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Fejl=%ERROR%',
'off_email_subject' => 'VIGTIG: Server \'%LABEL%\' is DOWN',
'off_email_body' => "Det lykkedes ikke at oprette forbindelse til følgende server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fejl: %ERROR%<br/>Date: %DATE%",
'off_pushover_title' => 'Server \'%LABEL%\' is DOWN',
'off_pushover_message' => "Det lykkedes ikke at oprette forbindelse til følgende server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fejl: %ERROR%<br/>Date: %DATE%",
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%',
'on_email_subject' => 'VIGTIG: Server \'%LABEL%\' is RUNNING',
'on_email_body' => "Server '%LABEL%' køre igen:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Dato: %DATE%",
'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING',
'on_pushover_message' => "Server '%LABEL%' køre igen:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Dato: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Velkommen, %user_name%',
'title_sign_in' => 'Log ind',
'title_forgot' => 'Glemt adgangskode?',
'title_reset' => 'Nulstil din adgangskode',
'submit' => 'Indsend',
'remember_me' => 'Husk kode',
'login' => 'Log ind',
'logout' => 'Log ud',
'username' => 'Brugernavn',
'password' => 'Adgangskode',
'password_repeat' => 'Skriv adgangskode igen',
'password_forgot' => 'Glemt adgangskode?',
'password_reset' => 'Nulstil adgangskode',
'password_reset_email_subject' => 'Nulstil din adgangskode for PHP Server Monitor',
'password_reset_email_body' => 'Brug venligst følgende link for at nulstille din adgangskode. Bemærk det udløber på 1 time.<br/><br/>%link%',
'error_user_incorrect' => 'Det angivet brugernavn kunne ikke findes.',
'error_login_incorrect' => 'Oplysningerne stemmer ikke overens.',
'error_login_passwords_nomatch' => 'De angivet adgangskoder matcher ikke.',
'error_reset_invalid_link' => 'Følgende link er ugyldigt.',
'success_password_forgot' => 'En e-mail er blevet sendt til dig med oplysninger om, hvordan du nulstiller din adgangskode.',
'success_password_reset' => 'Dit password er blevet nulstillet. venligst log ind.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => 'Speichern',
'edit' => 'Bearbeiten',
'delete' => 'L&ouml;schen',
'deleted' => 'Eintrag wurde gel&ouml;scht',
'date' => 'Datum',
'message' => 'Meldung',
'yes' => 'Ja',
'no' => 'Nein',
'edit' => 'Bearbeiten',
'insert' => 'Einf&uuml;gen',
'add_new' => 'Neuen Eintrag erstellen',
'update_available' => 'Ein neues Update ({version}) ist verf&uuml;gbar auf <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'mobile' => 'Mobil',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => 'Benutzer bearbeitet.',
'inserted' => 'Benutzer eingetragen.',
'profile' => 'Profile',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Server',
'status' => 'Status',
'label' => 'Beschriftung',
'domain' => 'Domain/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Type',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Letzter Check',
'last_online' => 'Letztes mal Online',
'monitoring' => 'Monitoring',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Email',
'sms' => 'SMS',
'send_sms' => 'SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => 'Server aktualisiert.',
'inserted' => 'Server eingetragen.',
'latency' => 'Antwortzeit',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'uptime' => 'Uptime',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
@ -137,6 +159,16 @@ $sm_lang = array(
'chart_long_date_format' => '%d.%m.%Y %H:%M:%S',
'chart_short_date_format' => '%d.%m %H:%M',
'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_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'General',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Gateway Benutzername',
'sms_gateway_password' => 'Gateway Passwort',
'sms_from' => 'SMS Sendernummer',
'alert_type' => 'Wann m&ouml;chten Sie benachrichtig werden?<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Wann m&ouml;chten Sie benachrichtig werden?',
'alert_type_description' => '<b>Status ge&auml;ndert:</b> '.
'... wenn sich der Status &auml;ndert<br/>'.
'z.B. online -> offline oder offline -> online.<br/>'.
@ -170,8 +209,7 @@ $sm_lang = array(
'Sie bekommen eine Benachrichtigung, wenn ein Server Offline ist.<br/>'.
'Es wird nur eine Mitteilung versendet.<br/>'.
'<br/><b>Immer: </b>'.
'Sie werden jedesmal wenn der CronJob oder das Script ausgef&uuml;hrt wird benachrichtigt,<br>'.
'auch wenn der Dienst mehreres Stunden offline ist',
'Sie werden jedesmal wenn der CronJob oder das Script ausgef&uuml;hrt wird benachrichtigt auch wenn der Dienst mehreres Stunden offline ist',
'alert_type_status' => 'Status ge&auml;ndert',
'alert_type_offline' => 'Offline',
'alert_type_always' => 'Immer',
@ -179,12 +217,14 @@ $sm_lang = array(
'log_status_description' => 'Ist der Log Status auf TRUE (ein Hacken) gesetzt, wird jeder Status protokolliert.',
'log_email' => 'Email Log per Script senden?',
'log_sms' => 'SMS Log per Script senden?',
'log_pushover' => 'Pushover Log per Script senden?',
'updated' => 'Die Einstellungen wurden gespeichert.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Log',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email',
'settings_sms' => 'SMS Nachricht',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Benachrichtigung',
'settings_log' => 'Log',
'auto_refresh' => 'Auto-refresh',
@ -194,15 +234,38 @@ $sm_lang = array(
'Time in seconds, if 0 the page won\'t refresh.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Server \'%LABEL%\' ist Offline: ip=%IP%, port=%PORT%. Fehler=%ERROR%',
'off_email_subject' => 'Wichtig: Server \'%LABEL%\' ist Offline',
'off_email_body' => "Kann keine Verbindung zum Server aufbauen:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fehler: %ERROR%<br/>Datum: %DATE%",
'off_pushover_title' => 'Server \'%LABEL%\' ist Offline',
'off_pushover_message' => "Kann keine Verbindung zum Server aufbauen:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fehler: %ERROR%<br/>Datum: %DATE%",
'on_sms' => 'Server \'%LABEL%\' ist wieder Online: ip=%IP%, port=%PORT%',
'on_email_subject' => 'Wichtig: Server \'%LABEL%\' ist wieder Online',
'on_email_body' => "Server '%LABEL%' l&auml;uft wieder:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Datum: %DATE%",
'on_pushover_title' => 'Server \'%LABEL%\' ist wieder Online',
'on_pushover_message' => "Server '%LABEL%' l&auml;uft wieder:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Datum: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
@ -227,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => 'Save',
'edit' => 'Edit',
'delete' => 'Delete',
'deleted' => 'Record has been deleted',
'date' => 'Date',
'message' => 'Message',
'yes' => 'Yes',
'no' => 'No',
'edit' => 'Edit',
'insert' => 'Insert',
'add_new' => 'Add new',
'update_available' => 'A new version ({version}) is available from <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -69,7 +69,7 @@ $sm_lang = array(
'help' => 'Help',
),
'users' => array(
'user' => 'user',
'user' => 'User',
'name' => 'Name',
'user_name' => 'Username',
'password' => 'Password',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'mobile' => 'Mobile',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => 'User updated.',
'inserted' => 'User added.',
'profile' => 'Profile',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Server',
'status' => 'Status',
'label' => 'Label',
'domain' => 'Domain/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Type',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Last check',
'last_online' => 'Last online',
'monitoring' => 'Monitoring',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Send Email',
'sms' => 'SMS',
'send_sms' => 'Send SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => 'Server updated.',
'inserted' => 'Server added.',
'latency' => 'Latency',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'uptime' => 'Uptime',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
@ -137,11 +159,21 @@ $sm_lang = array(
'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' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'General',
'language' => 'Language',
'show_update' => 'Updates',
'show_update' => 'Check for updates?',
'email_status' => 'Allow sending email',
'email_from_email' => 'Email from address',
'email_from_name' => 'Email from name',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Gateway username',
'sms_gateway_password' => 'Gateway password',
'sms_from' => 'Sender\'s phone number',
'alert_type' => 'Select when you\'d like to be notified.<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Select when you\'d like to be notified.',
'alert_type_description' => '<b>Status change:</b> '.
'You will receive a notifcation when a server has a change in status. So from online -> offline or offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
@ -170,8 +209,7 @@ $sm_lang = array(
'your cronjob is every 15 mins and your server goes down at 1 am and stays down till 6 am. '.
'You will get 1 notification at 1 am and thats it.<br/>'.
'<br><b>Always:</b> '.
'You will receive a notification every time the script runs and a site is down, even if the site has been '.
'offline for hours.',
'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',
@ -179,12 +217,14 @@ $sm_lang = array(
'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_pushover' => 'Log pushover messages sent by the script',
'updated' => 'The configuration has been updated.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Log',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email settings',
'settings_sms' => 'Text message settings',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Notification settings',
'settings_log' => 'Log settings',
'auto_refresh' => 'Auto-refresh',
@ -194,15 +234,38 @@ $sm_lang = array(
'Time in seconds, if 0 the page won\'t refresh.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'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:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'off_pushover_title' => 'Server \'%LABEL%\' is DOWN',
'off_pushover_message' => "Failed to connect to the following server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%',
'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING',
'on_email_body' => "Server '%LABEL%' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING',
'on_pushover_message' => 'Server \'%LABEL%\' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%',
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
@ -227,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => 'Guardar',
'edit' => 'Modificar',
'delete' => 'Eliminar',
'deleted' => 'Registro eliminado',
'date' => 'Fecha',
'message' => 'Mensaje',
'yes' => 'Si',
'no' => 'No',
'edit' => 'Modificar',
'insert' => 'Insertar',
'add_new' => 'Agregar nuevo',
'update_available' => 'Hay una nueva versión ({version}) disponible en <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'mobile' => 'Mobil',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => 'Usuario actualizado.',
'inserted' => 'Usuario ingresado.',
'profile' => 'Profile',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Estado',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Servidores',
'status' => 'Status',
'label' => 'Titulo',
'domain' => 'Domain/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Tipo',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Ultima verificación',
'last_online' => 'Última vez en línea',
'monitoring' => 'Monitoreo',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Email',
'sms' => 'SMS',
'send_sms' => 'SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => 'Servidor arctualizado.',
'inserted' => 'Servidor ingresado.',
'latency' => 'Tiempo de respuesta',
'latency_max' => 'Tiempo de respuesta (maximum)',
'latency_min' => 'Tiempo de respuesta (minimum)',
'latency_avg' => 'Tiempo de respuesta (average)',
'uptime' => 'Uptime',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
@ -137,6 +159,16 @@ $sm_lang = array(
'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' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'General',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Gateway username',
'sms_gateway_password' => 'Gateway password',
'sms_from' => 'Número origen del SMS',
'alert_type' => 'Cuando desea recibir notificaciones ?<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Cuando desea recibir notificaciones ?',
'alert_type_description' => '<b>... Al cambiar el estado:</b> '.
'p.ej. online -> offline o offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
@ -178,12 +217,14 @@ $sm_lang = array(
'log_status_description' => 'Al setear TRUE (marcar) se protocolan todos los estados.',
'log_email' => 'Enviar Log via email?',
'log_sms' => 'Enviar Log via SMS ?',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Configuración guardada.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Log',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email',
'settings_sms' => 'Mensaje SMS',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Notificación',
'settings_log' => 'Log',
'auto_refresh' => 'Refrescar automáticamente página de servidores',
@ -193,15 +234,38 @@ $sm_lang = array(
'Tiempo en segundos, indicar "0" para no actualizar.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Servidor \'%LABEL%\' está fuera de línea: ip=%IP%, port=%PORT%. error=%ERROR%',
'off_email_subject' => 'Importante: Servidor \'%LABEL%\' está fuera de línea',
'off_email_body' => "No posible conectar al servidor:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Fecha: %DATE%",
'off_pushover_title' => 'Servidor \'%LABEL%\' está fuera de línea',
'off_pushover_message' => "No posible conectar al servidor:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Fecha: %DATE%",
'on_sms' => 'Servidor \'%LABEL%\' ya está de nuevo funcionando en línea: ip=%IP%, port=%PORT%',
'on_email_subject' => 'Importante: Servidor \'%LABEL%\' ya está de nuevo en línea',
'on_email_body' => "Servidor '%LABEL%' ya está funcionando en línea de nuevo:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fecha: %DATE%",
'on_pushover_title' => 'Servidor \'%LABEL%\' ya está de nuevo en línea',
'on_pushover_message' => "Servidor '%LABEL%' ya está funcionando en línea de nuevo:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Fecha: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
@ -226,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -19,6 +19,7 @@
*
* @package phpservermon
* @author David Ribeiro
* @author Jérôme Cabanis <jerome@lauraly.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
@ -35,17 +36,17 @@ $sm_lang = array(
'save' => 'Enregistrer',
'edit' => 'Editer',
'delete' => 'Supprimer',
'deleted' => 'L\'enregistrement a été supprimé',
'date' => 'Date',
'message' => 'Message',
'yes' => 'Oui',
'no' => 'Non',
'edit' => 'Editer',
'insert' => 'Nouveau',
'add_new' => 'Nouveau',
'update_available' => 'Une nouvelle version ({version}) est disponible à l\'adresse <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Haut de page',
'go_back' => 'Retour',
'ok' => 'OK',
'cancel' => 'Annuler',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => 'Le %e %B',
'long_day_format' => 'Le %e %B %Y',
@ -79,8 +80,16 @@ $sm_lang = array(
'level_10' => 'Administrateur',
'level_20' => 'Utilisateur',
'level_description' => 'Les <b>Administrateurs</b> ont un accès total. Ils peuvent gérer les serveurs, les utilisateurs et éditer la configuration globale.<br/>Les <b>Utilisateurs</b> ne peuvent que voir et mettre à jour les serveurs qui leur ont été assignés.',
'mobile' => 'Numéro de téléphone',
'mobile' => 'Téléphone',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Supprimer un utilisateur',
'delete_message' => 'Êtes-vous sûr de vouloir supprimer l\'utilisateur \'%1\' ?',
'deleted' => 'Utilisateur supprimé.',
'updated' => 'Utilisateur mis à jour.',
'inserted' => 'Utilisateur ajouté.',
'profile' => 'Profil',
@ -101,11 +110,16 @@ $sm_lang = array(
'status' => 'État',
'email' => 'email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'Aucun événement',
),
'servers' => array(
'server' => 'Serveur',
'label' => 'Description',
'status' => 'État',
'label' => 'Nom',
'domain' => 'Domaine/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Type',
'type_website' => 'Site Web',
@ -115,14 +129,23 @@ $sm_lang = array(
'last_check' => 'Dernière vérification',
'last_online' => 'Dernière fois OK',
'monitoring' => 'Serveillé',
'no_monitoring' => 'Non serveillé',
'email' => 'Email',
'send_email' => 'Envoyer un email',
'sms' => 'SMS',
'send_sms' => 'Envoyer un SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Supprimer un serveur',
'delete_message' => 'Êtes-vous sûr de vouloir supprimer le serveur \'%1\' ?',
'deleted' => 'Serveur supprimé.',
'updated' => 'Serveur mis à jour.',
'inserted' => 'Serveur ajouté.',
'latency' => 'Temps de réponse',
'latency_max' => 'Temps de réponse maximum',
'latency_min' => 'Temps de réponse minimum',
'latency_avg' => 'Temps de réponse moyen',
'uptime' => 'Disponibilité',
'year' => 'Année',
'month' => 'Mois',
'week' => 'Semaine',
@ -137,6 +160,16 @@ $sm_lang = array(
'chart_long_date_format' => '%d/%m/%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'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_pushover' => 'Pushover notifications are disabled.',
'error_server_no_match' => 'Serveur non trouvé.',
'error_server_label_bad_length' => 'Le nom doit avoir entre 1 et 255 caractères.',
'error_server_ip_bad_length' => 'Domaine/IP doit avoir entre 1 et 255 caractères.',
'error_server_ip_bad_service' => 'L\'adresse IP n\'est pas valide.',
'error_server_ip_bad_website' => 'L\'URL du site web n\'est pas valide.',
'error_server_type_invalid' => 'Le type de service sélectionné n\'est pas valide.',
'error_server_warning_threshold_invalid' => 'Le seuil d\'alerte doit être un nombre entier supérieur à 0.',
),
'config' => array(
'general' => 'Général',
@ -159,10 +192,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Nom utilisateur de la passerelle',
'sms_gateway_password' => 'Mot de passe de la passerelle',
'sms_from' => 'SMS de l\'expéditeur',
'alert_type' => 'Choisissez quand vous souhaitez être notifié.<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Choisissez quand vous souhaitez être notifié',
'alert_type_description' => '<b>Changement d\'état : </b>'.
'Vous recevez une notification chaque fois que le serveur change d\'état. C\'est-à-dire passe de l\'état OK à HORS SERVICE ou de HORS SERVICE à OK.<br/>'.
'<br/><b>Hors service : </b>'.
@ -178,12 +218,14 @@ $sm_lang = array(
'log_status_description' => 'Si l\'option est activée, un événement est enregistré chaque fois qu\'une notification a lieu.',
'log_email' => 'Enregistrer tout les emails envoyés',
'log_sms' => 'Enregistrer tout les SMS envoyés',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'La configuration a été mise à jour.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Événements',
'tab_pushover' => 'Pushover',
'settings_email' => 'Configuration email',
'settings_sms' => 'Configuration SMS',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Configuration des notifications',
'settings_log' => 'Configuration des événements',
'auto_refresh' => 'Auto-rachaîchissement',
@ -193,15 +235,38 @@ $sm_lang = array(
'Temps en secondes. Si 0, la page n\'est pas rafraîchie.'.
'</span>',
'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.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Envoyer',
'test_subject' => 'Test',
'test_message' => 'Message de test',
'email_sent' => 'Email envoyé',
'email_error' => 'Erreur lors de l\'envoie de l\'email',
'sms_sent' => 'Sms envoyé',
'sms_error' => 'Erreur lors de l\'envoie du sms',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Le Serveur \'%LABEL%\' est HORS SERVICE: IP=%IP%, Port=%PORT%. Erreur=%ERROR%',
'off_email_subject' => 'IMPORTANT: Le Serveur \'%LABEL%\' est HORS SERVICE',
'off_email_body' => "Impossible de se connecter au serveur suivant:<br/><br/>Serveur: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Erreur: %ERROR%<br/>Date: %DATE%",
'off_pushover_title' => 'Le Serveur \'%LABEL%\' est HORS SERVICE',
'off_pushover_message' => "Impossible de se connecter au serveur suivant:<br/><br/>Serveur: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Erreur: %ERROR%<br/>Date: %DATE%",
'on_sms' => 'Le Serveur \'%LABEL%\' est OK: IP=%IP%, Port=%PORT%',
'on_email_subject' => 'IMPORTANT: Le Serveur \'%LABEL%\' est OK',
'on_email_body' => "Le Serveur '%LABEL%' est de nouveau OK:<br/><br/>Serveur: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
'on_pushover_title' => 'Le Serveur \'%LABEL%\' est OK',
'on_pushover_message' => "Le Serveur '%LABEL%' est de nouveau OK:<br/><br/>Serveur: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Bonjour %user_name%',
@ -226,4 +291,8 @@ $sm_lang = array(
'success_password_forgot' => 'Un email vous a été envoyé pour réinitialiser votre mot de passe.',
'success_password_reset' => 'Votre mot de passe a été réinitialisé.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => 'Salva',
'edit' => 'Modifica',
'delete' => 'Elimina',
'deleted' => 'L\'oggetto è stato eliminato',
'date' => 'Data',
'message' => 'Messaggio',
'yes' => 'Sì',
'no' => 'No',
'edit' => 'Modifica',
'insert' => 'Inserisci',
'add_new' => 'Aggiungi Nuovo?',
'update_available' => 'Un nuovo aggiornamento ({version}) è disponibile su <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -69,7 +69,7 @@ $sm_lang = array(
'help' => 'Aiuto',
),
'users' => array(
'user' => 'utente',
'user' => 'Utente',
'name' => 'Nome',
'user_name' => 'Username',
'password' => 'Password',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'mobile' => 'Cellulare',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => 'Utente aggiornato.',
'inserted' => 'Utente aggiunto.',
'profile' => 'Profile',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Stato',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Server',
'status' => 'Status',
'label' => 'Nome',
'domain' => 'Dominio/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Porta',
'type' => 'Tipo',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Ultimo Controllo',
'last_online' => 'Ultima volta Online',
'monitoring' => 'Sotto Controllo',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Invia Email',
'sms' => 'SMS',
'send_sms' => 'Invia SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => 'Server aggiornato.',
'inserted' => 'Server aggiunto.',
'latency' => 'Tempo di risposta',
'latency_max' => 'Tempo di risposta (maximum)',
'latency_min' => 'Tempo di risposta (minimum)',
'latency_avg' => 'Tempo di risposta (average)',
'uptime' => 'Uptime',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
@ -137,6 +159,16 @@ $sm_lang = array(
'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' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'Generale',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Nome Utente Gateway',
'sms_gateway_password' => 'Password Gateway',
'sms_from' => 'Numero di telefono del mittente',
'alert_type' => 'Seleziona quando vuoi essere notificato.<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Seleziona quando vuoi essere notificato',
'alert_type_description' => '<b>Cambio di Stato:</b> '.
'Riceverai una notifica solo quando un server cambierà stato. Quindi da online -> offline oppure da offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
@ -178,12 +217,14 @@ $sm_lang = array(
'log_status_description' => 'Se lo Stato Log è impostato su VERO, il monitor registrerà nel log gli eventi appena le notifiche verranno inviate.',
'log_email' => 'Registra email inviate dallo script.',
'log_sms' => 'Registra SMS inviati dallo script.',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'La configurazione è stato aggiornata.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Log',
'tab_pushover' => 'Pushover',
'settings_email' => 'Impostazioni Email',
'settings_sms' => 'Impostazioni SMS',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Impostazioni Notifiche',
'settings_log' => 'Impostazioni Log',
'auto_refresh' => 'Auto-Aggiorna pagina servers',
@ -193,15 +234,38 @@ $sm_lang = array(
'Tempo in secondi, se impostato a 0 la pagina non si aggiornerà.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Server \'%LABEL%\' è DOWN: ip=%IP%, porta=%PORT%. Errore=%ERROR%',
'off_email_subject' => 'IMPORTANTE: Server \'%LABEL%\' è DOWN',
'off_email_body' => "Impossibile connettersi al seguente server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Errore: %ERROR%<br/>Data: %DATE%",
'off_pushover_title' => 'Server \'%LABEL%\' è DOWN',
'off_pushover_message' => "Impossibile connettersi al seguente server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Errore: %ERROR%<br/>Data: %DATE%",
'on_sms' => 'Server \'%LABEL%\' è ATTIVO: ip=%IP%, porta=%PORT%',
'on_email_subject' => 'IMPORTANTE: Server \'%LABEL%\' è ATTIVO',
'on_email_body' => "Server '%LABEL%' è di nuovo attivo:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Data: %DATE%",
'on_pushover_title' => 'Server \'%LABEL%\' è ATTIVO',
'on_pushover_message' => "Server '%LABEL%' è di nuovo attivo:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Data: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
@ -226,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => '저장',
'edit' => '수정',
'delete' => '삭제',
'deleted' => '삭제되었습니다.',
'date' => '날짜',
'message' => '메세지',
'yes' => '예',
'no' => '아니오',
'edit' => '수정',
'insert' => '삽입',
'add_new' => '새계정 추가',
'update_available' => '새로운 업데이트가 있습니다 ({version}). 다음사이트를 방문 해 주십시오. <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administrators</b> have full access: they can manage servers, users and edit the global configuration.<br/><b>Users</b> can only view and run the updater for the servers that have been assigned to them.',
'mobile' => '휴대폰',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => '수정되었습니다.',
'inserted' => '추가되었습니다.',
'profile' => 'Profile',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => '상태',
'email' => 'email',
'sms' => 'sms',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => '서버',
'status' => 'Status',
'label' => 'Label',
'domain' => 'Domain/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Port',
'type' => 'Type',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => '최근체크',
'last_online' => '최근접속',
'monitoring' => '확인중',
'no_monitoring' => 'No monitoring',
'email' => '메일 전송',
'send_email' => '메일 전송',
'sms' => 'SMS 전송',
'send_sms' => 'SMS 전송',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => '서버가 수정되었습니다.',
'inserted' => '서버가 추가되었습니다.',
'latency' => '응답',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'uptime' => 'Uptime',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
@ -137,6 +159,16 @@ $sm_lang = array(
'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' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => '일반',
@ -158,11 +190,18 @@ $sm_lang = array(
'sms_gateway_spryng' => 'Spryng',
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_username' => 'Gateway username',
'sms_gateway_password' => 'Gateway password',
'sms_from' => 'Sender\'s phone number',
'alert_type' => '알림을 원하면 다음과 같이 변경하십시오..<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => '알림을 원하면 다음과 같이 변경하십시오.',
'alert_type_description' => '<b>상태 변경: </b><br/>'.
'서버 상태가 변경이되면 알림을 받습니다. online -> offline -> online.<br/>'.
'<br/><b>오프라인: </b><br/>'.
@ -170,6 +209,7 @@ $sm_lang = array(
'cron이 매 15분이고 오전1시 부터 오전6시까지 다운되었을때 오전1시에 한번 알림을 받습니다.<br />' .
'<br/><b>항상: </b><br/>'.
'사이트가 다운되었을 때 매시간 알림을 받습니다.',
'alert_type_status' => '상태 변경',
'alert_type_offline' => '오프라인',
'alert_type_always' => '항상',
@ -177,12 +217,14 @@ $sm_lang = array(
'log_status_description' => '로그상태가 TRUE이면 알림설정이 통과할때마다 이벤트를 기록합니다.',
'log_email' => '이메일로 로그를 전송하시겠습니까?',
'log_sms' => 'SMS로 로그를 전송하시겠습니까?',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => '설정이 수정되었습니다.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => '로그',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email 설정',
'settings_sms' => 'SMS 설정',
'settings_pushover' => 'Pushover settings',
'settings_notification' => '알림 설정',
'settings_log' => '로그 설정',
'auto_refresh' => 'Auto-refresh',
@ -192,15 +234,38 @@ $sm_lang = array(
'시간은 초(sec)로 설정을 하고, 0은 새로고침을 하지 않습니다.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => '서버(\'%LABEL%\')가 다운되었습니다. : ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => '중요: 서버(\'%LABEL%\')가 다운되었습니다.',
'off_email_body' => "서버 접속을 실패하였습니다.<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'off_pushover_title' => '서버(\'%LABEL%\')가 다운되었습니다.',
'off_pushover_message' => "서버 접속을 실패하였습니다.<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'on_sms' => '서버(\'%LABEL%\') 가동중: ip=%IP%, port=%PORT%',
'on_email_subject' => '중요: 서버(\'%LABEL%\')가 가동중입니다.',
'on_email_body' => "서버('%LABEL%')가 재가동됩니다.:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
'on_pushover_title' => '서버(\'%LABEL%\')가 가동중입니다.',
'on_pushover_message' => "서버('%LABEL%')가 재가동됩니다.:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',
@ -225,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'An email has been sent to you with information how to reset your password.',
'success_password_reset' => 'Your password has been reset successfully. Please login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -30,22 +30,22 @@ $sm_lang = array(
'locale' => array('nl_NL.UTF-8', 'nl_NL', 'dutch'),
'system' => array(
'title' => 'Server Monitor',
'install' => 'Install',
'install' => 'Intalleren',
'action' => 'Actie',
'save' => 'Opslaan',
'edit' => 'Wijzig',
'delete' => 'Verwijder',
'deleted' => 'Record is verwijderd',
'date' => 'Datum',
'message' => 'Bericht',
'yes' => 'Ja',
'no' => 'Nee',
'edit' => 'Wijzig',
'insert' => 'Voeg toe',
'add_new' => 'Voeg toe',
'update_available' => 'Een nieuwe update ({version}) is beschikbaar op <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Terug naar boven',
'go_back' => 'Terug',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -60,7 +60,7 @@ $sm_lang = array(
'a_second_ago' => 'een seconde geleden',
),
'menu' => array(
'config' => 'Config',
'config' => 'Configuratie',
'server' => 'Servers',
'server_log' => 'Log',
'server_status' => 'Status',
@ -69,7 +69,7 @@ $sm_lang = array(
'help' => 'Help',
),
'users' => array(
'user' => 'gebruiker',
'user' => 'Gebruiker',
'name' => 'Naam',
'user_name' => 'Gebruikersnaam',
'password' => 'Wachtwoord',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Beheerders</b> hebben volledige toegang: ze kunnen servers en gebruiker beheren en de globale configuratie aanpassen.<br/><b>Gebruikers</b> kunnen alleen de servers bekijken en op fouten testen die aan hun zijn toegewezen.',
'mobile' => 'Mobiel',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te ontvangen. Zie <a href="https://pushover.net/">hun website</a> voor meer informatie.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Apparaat waar de berichten naar toe gaan. Laat leeg voor alle apparaten.',
'delete_title' => 'Verwijder gebruiker',
'delete_message' => 'Weet je zeker dat je deze gebruiker wilt verwijderen: \'%1\'?',
'deleted' => 'Gebruiker verwijderd.',
'updated' => 'Gebruiker gewijzigd.',
'inserted' => 'Gebruiker toegevoegd.',
'profile' => 'Profiel',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Server',
'status' => 'Status',
'label' => 'Label',
'domain' => 'Domein/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Aantal seconden te wachten op een reactie van de server.',
'port' => 'Poort',
'type' => 'Type',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Laatst gecontroleerd',
'last_online' => 'Laatst online',
'monitoring' => 'Monitoring',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Stuur email',
'sms' => 'SMS',
'send_sms' => 'Stuur SMS',
'pushover' => 'Pushover',
'users' => 'Gebruikers',
'delete_title' => 'Verwijder server',
'delete_message' => 'Weet je zeker dat je deze server wilt verwijderen: \'%1\'?',
'deleted' => 'Server verwijderd.',
'updated' => 'Server gewijzigd.',
'inserted' => 'Server toegevoegd.',
'latency' => 'Response tijd',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (gemiddeld)',
'uptime' => 'Uptime',
'year' => 'Jaar',
'month' => 'Maand',
'week' => 'Week',
@ -137,6 +159,16 @@ $sm_lang = array(
'chart_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d-%m %H:%M',
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'SMS notificaties zijn uitgeschakeld.',
'warning_notifications_disabled_email' => 'Email notificaties zijn uitgeschakeld.',
'warning_notifications_disabled_pushover' => 'Pushover notificaties zijn uitgeschakeld.',
'error_server_no_match' => 'Server niet gevonden.',
'error_server_label_bad_length' => 'Het label moet tussen de 1 en 255 karakters lang zijn.',
'error_server_ip_bad_length' => 'Het domein / IP moet tussen de 1 en 255 karakters lang zijn.',
'error_server_ip_bad_service' => 'Het IP adres is ongeldig.',
'error_server_ip_bad_website' => 'De website URL is ongeldig.',
'error_server_type_invalid' => 'Het geselecteerde server type is ongeldig.',
'error_server_warning_threshold_invalid' => 'De warning threshold moet een numerieke waarde zijn groter dan 0.',
),
'config' => array(
'general' => 'Algemeen',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Gateway gebruikersnaam',
'sms_gateway_password' => 'Gateway wachtwoord',
'sms_from' => 'Telefoonnummer afzender',
'alert_type' => 'Selecteer wanneer je een notificatie wilt.<br/>',
'pushover_status' => 'Sta Pushover berichten toe?',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te ontvangen. Zie <a href="https://pushover.net/">hun website</a> voor meer 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 <a href="%1$s" target="_blank">App registreren</a> via hun website, en daarvan de App API Token hier invullen.',
'alert_type' => 'Selecteer wanneer je een notificatie wilt',
'alert_type_description' => '<b>Status change:</b> '.
'Je ontvangt alleen bericht wanneer een server van status verandert. Dus van online -> offline of offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
@ -178,12 +217,14 @@ $sm_lang = array(
'log_status_description' => 'Als de log status aan staat, zal de monitor een log aanmaken elke keer dat hij door de notificatie instellingen komt.',
'log_email' => 'Log emails verstuurd bij het script?',
'log_sms' => 'Log sms berichten verstuurd bij het script?',
'log_pushover' => 'Log Pushover berichten verstuurd bij het script?',
'updated' => 'De configuratie is gewijzigd.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_log' => 'Log',
'tab_pushover' => 'Pushover',
'settings_email' => 'Email instellingen',
'settings_sms' => 'SMS instellingen',
'settings_pushover' => 'Pushover instellingen',
'settings_notification' => 'Notificatie instellingen',
'settings_log' => 'Log instellingen',
'auto_refresh' => 'Auto-refresh',
@ -192,16 +233,39 @@ $sm_lang = array(
'<span class="small">'.
'Tijd in seconden, als de tijd 0 is wordt de pagina niet ververst.'.
'</span>',
'seconds' => 'seconds',
'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.',
'test_pushover' => 'Er zal een Pushover notificatie verstuurd worden naar de user key/device in je profiel.',
'send' => 'Verstuur',
'test_subject' => 'Test',
'test_message' => 'Test bericht',
'email_sent' => 'Email verzonden',
'email_error' => 'Er is een fout opgetreden tijdens het verzenden',
'sms_sent' => 'SMS verzonden',
'sms_error' => 'Er is een fout opgetreden tijdens het verzenden',
'sms_error_nomobile' => 'Kan test SMS niet verzenden: er is geen telefoonnummer ingevuld in je profiel.',
'pushover_sent' => 'Pushover notificatie verzonden',
'pushover_error' => 'De volgende fout is opgetreden bij het versturen van de Pushover notificatie: %s',
'pushover_error_noapp' => 'Kan test notificatie niet verzenden: er is geen Pushover App API token gevonden in de algemene configuratie.',
'pushover_error_nokey' => 'Kan test notificatie niet verzenden: er is geen Pushover key gevonden in je profiel.',
'log_retention_period' => 'Log retentie periode',
'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',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%',
'off_email_subject' => 'BELANGRIJK: Server %LABEL% is DOWN',
'off_email_body' => "De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%",
'off_pushover_title' => 'Server %LABEL% is DOWN',
'off_pushover_message' => "De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%",
'on_sms' => 'Server %LABEL% is RUNNING: ip=%IP%, poort=%PORT%',
'on_email_subject' => 'BELANGRIJK: Server %LABEL% is RUNNING',
'on_email_body' => "Server %LABEL% is weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%",
'on_pushover_title' => 'Server %LABEL% is RUNNING',
'on_pushover_message' => "Server %LABEL% is weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Welkom, %user_name%',
@ -218,7 +282,7 @@ $sm_lang = array(
'password_forgot' => 'Wachtwoord vergeten?',
'password_reset' => 'Wachtwoord herstellen',
'password_reset_email_subject' => 'Wijzig je wachtwoord voor PHP Server Monitor',
'password_reset_email_body' => 'Gebruik de onderstaande link om uw wachtwoord te wijzigen. Let op, deze link verloopt na 1 uur.<br/><br/>%link%',
'password_reset_email_body' => 'Gebruik de onderstaande link om je wachtwoord te wijzigen. Let op, deze link verloopt na 1 uur.<br/><br/>%link%',
'error_user_incorrect' => 'De opgegeven gebruikersnaam is onjuist.',
'error_login_incorrect' => 'De informatie is niet juist.',
'error_login_passwords_nomatch' => 'De ingevulde wachtwoorden komen niet overeen.',
@ -226,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'Er is een mail verstuurd met informatie om je wachtwoord aan te passen.',
'success_password_reset' => 'Je wachtwoord is aangepast. Je kunt nu inloggen.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'U heeft niet de juiste bevoegdheden om deze pagina te bekijken.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => 'Salvar',
'edit' => 'Editar',
'delete' => 'Excluir',
'deleted' => 'Registro excluído',
'date' => 'Data',
'message' => 'Mensagem',
'yes' => 'Sim',
'no' => 'Não',
'edit' => 'Editar',
'insert' => 'Inserir',
'add_new' => 'Adicionar novo',
'update_available' => 'Uma atualização ({version}) disponível em <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Voltar ao topo',
'go_back' => 'Voltar',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%e %m',
'long_day_format' => '%e/%m/%Y',
@ -69,7 +69,7 @@ $sm_lang = array(
'help' => 'Ajuda',
),
'users' => array(
'user' => 'usuário',
'user' => 'Usuário',
'name' => 'Nome',
'user_name' => 'Username',
'password' => 'Senha',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>Administradores</b> Tem total acesso: podem gerenciar servidores, usuários e configurações globais.<br/><b>Usuários</b> só podem executar atualizações para servidores que lhe foram atribuídos.',
'mobile' => 'Celular',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => 'Usuário atualizado.',
'inserted' => 'Usuário adicionado.',
'profile' => 'Perfil',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => 'Servidor',
'status' => 'Status',
'label' => 'Etiqueta',
'domain' => 'Domínio/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => 'Porta',
'type' => 'Tipo',
'type_website' => 'Website',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => 'Última verificação',
'last_online' => 'Última vez online',
'monitoring' => 'Monitoramento',
'no_monitoring' => 'No monitoring',
'email' => 'Email',
'send_email' => 'Enviar Email',
'sms' => 'SMS',
'send_sms' => 'Enviar SMS',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => 'Servidor atualizado.',
'inserted' => 'Servidor adicionar.',
'latency' => 'Tempo de resposta',
'latency_max' => 'Latência (máxima)',
'latency_min' => 'Latência (minima)',
'latency_avg' => 'Latência (média)',
'uptime' => 'Uptime',
'year' => 'Ano',
'month' => 'Mês',
'week' => 'Semana',
@ -137,6 +159,16 @@ $sm_lang = array(
'chart_long_date_format' => '%d/%m/%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'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_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => 'Geral',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Usuário do Gateway',
'sms_gateway_password' => 'Senha do Gateway',
'sms_from' => 'Número de telefone de envio',
'alert_type' => 'Selecione como você gostaria de ser notificado.<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => 'Selecione como você gostaria de ser notificado.',
'alert_type_description' => '<b>Mudança de Status:</b> '.
'Você receberá uma notificação quando o seridor tive uma mudança de status. De online -> offline ou offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
@ -170,8 +209,7 @@ $sm_lang = array(
'A cronjob é a cada 15 minutos e seu servidor caiu em 1:00 e permanece offline até 6 am. '.
'Você receberá uma notificação a 1:00 apenas<br/>'.
'<br><b>Sempre:</b> '.
'Você receberá uma notificação toda vez que o script é executado e um site esta offline, mesmo se o site tenha ficado '.
'offline por horas.',
'Você receberá uma notificação toda vez que o script é executado e um site esta offline, mesmo se o site tenha ficado offline por horas.',
'alert_type_status' => 'Mudança de Status',
'alert_type_offline' => 'Offline',
'alert_type_always' => 'Sempre',
@ -179,12 +217,14 @@ $sm_lang = array(
'log_status_description' => 'Se o status de registro é definido como TRUE, o monitor irá registrar o evento sempre que as configurações de notificação forem passadas.',
'log_email' => 'Registrar no Log os envios de email feitos pelo script?',
'log_sms' => 'Registrar no Log os envios de mensagens de texto feitos pelo script?',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'A configuração foi atualizada.',
'tab_email' => 'Email',
'tab_sms' => 'Texto',
'tab_log' => 'Logs',
'tab_pushover' => 'Pushover',
'settings_email' => 'Configuração de email',
'settings_sms' => 'Configuração de mensagens de texto',
'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Configuração de notificações',
'settings_log' => 'Configuração de Logs',
'auto_refresh' => 'Atualizar automaticamente',
@ -194,15 +234,38 @@ $sm_lang = array(
'Tempo em segundos, Se 0 a página não será atualizada.'.
'</span>',
'seconds' => 'segundos',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Servidor \'%LABEL%\' está OFFLINE: ip=%IP%, porta=%PORT%. Erro=%ERROR%',
'off_email_subject' => 'IMPORTANTE: Servidor \'%LABEL%\' está OFFLINE',
'off_email_body' => "Falha ao conectar ao servidor:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Erro: %ERROR%<br/>Data: %DATE%",
'off_pushover_title' => 'Servidor \'%LABEL%\' está OFFLINE',
'off_pushover_message' => "Falha ao conectar ao servidor:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Erro: %ERROR%<br/>Data: %DATE%",
'on_sms' => 'Servidor \'%LABEL%\' esta ONLINE: ip=%IP%, porta=%PORT%',
'on_email_subject' => 'IMPORTANTE: Servidor \'%LABEL%\' esta ONLINE',
'on_email_body' => "Servidor '%LABEL%' esta ONLINE novamente:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Data: %DATE%",
'on_pushover_title' => 'Servidor \'%LABEL%\' esta ONLINE',
'on_pushover_message' => "Servidor '%LABEL%' esta ONLINE novamente:<br/><br/>Servidor: %LABEL%<br/>IP: %IP%<br/>Porta: %PORT%<br/>Data: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'Bem vindo, %user_name%',
@ -227,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => 'Um email foi enviado para você com as instruções de redefinição de senha.',
'success_password_reset' => 'Sua senha foi redefinida com sucesso. Por favor faça login.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

297
src/lang/ru_RU.lang.php Normal file
View File

@ -0,0 +1,297 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Roman Beylin <roman.beylin@yandex.ru>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
$sm_lang = array(
'name' => 'Russian - Русский',
'locale' => array('ru_RU.UTF-8', 'ru_RU', 'russian', 'russian'),
'system' => array(
'title' => 'Сервер Мониторинг',
'install' => 'Установка',
'action' => 'Действие',
'save' => 'Сохранить',
'edit' => 'Редактировать',
'delete' => 'Удалить',
'date' => 'Дата',
'message' => 'Сообщение',
'yes' => 'Да',
'no' => 'Нет',
'insert' => 'Добавить',
'add_new' => 'Добавить новый',
'update_available' => 'Новая версия ({version}) доступна по адресу <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Наверх',
'go_back' => 'Вернуться',
'ok' => 'OK',
'cancel' => 'Отмена',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%e %B',
'long_day_format' => '%e %B %Y',
'yesterday_format' => 'Вчера в %k:%M',
'other_day_format' => '%A в %k:%M',
'never' => 'Никогда',
'hours_ago' => '%d часов назад',
'an_hour_ago' => 'час назад',
'minutes_ago' => '%d минут назад',
'a_minute_ago' => 'минуту назад',
'seconds_ago' => '%d секунд назад',
'a_second_ago' => 'секунду назад',
),
'menu' => array(
'config' => 'Параметры',
'server' => 'Серверы',
'server_log' => 'Лог',
'server_status' => 'Статус',
'server_update' => 'Обновить',
'user' => 'Пользователи',
'help' => 'Помощь',
),
'users' => array(
'user' => 'Пользователь',
'name' => 'Имя пользователя',
'user_name' => 'Логин',
'password' => 'Пароль',
'password_repeat' => 'Повтор пароля',
'password_leave_blank' => 'Оставить пустым, если не меняется',
'level' => 'Уровень',
'level_10' => 'Администратор',
'level_20' => 'Пользователь',
'level_description' => '<b>Администраторы</b> имеют полный доступ: они могут управлять серверами, пользователями и изменять общую конфигурацию.<br/><b>Пользователи</b> могут только просматривать и запускать проверку для серверов, которые были к ним прикреплены.',
'mobile' => 'Телефон',
'email' => 'E-mail',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover - это сервис, который позволяет легко получать уведомления в режиме реального времени. Больше информации на <a href="https://pushover.net/">их веб-сайте</a>.',
'pushover_key' => 'Pushover ключ',
'pushover_device' => 'Pushover устройство',
'pushover_device_description' => 'Имя устройства, на которое будут отправляться уведомления. Оставьте пустым, что бы отправлять уведомления на все устройства.',
'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' => 'E-mail может содержать от 5 до 255 знаков.',
'error_user_email_invalid' => 'E-mail указан неверно.',
'error_user_level_invalid' => 'Данный уровень пользователя недействителен.',
'error_user_no_match' => 'Данного пользователя нет в базе данных.',
'error_user_password_invalid' => 'Пароль указан неверно.',
'error_user_password_no_match' => 'Введенные пароли не совпадают.',
),
'log' => array(
'title' => 'Запись',
'type' => 'Тип',
'status' => 'Статус',
'email' => 'E-mail',
'sms' => 'СМС',
'pushover' => 'Pushover',
'no_logs' => 'Записей нет',
),
'servers' => array(
'server' => 'Сервер',
'status' => 'Состояние',
'label' => 'Название',
'domain' => 'Домен/IP',
'timeout' => 'Тайм-аут',
'timeout_description' => 'Количество секунд ожидания ответа сервера.',
'port' => 'Порт',
'type' => 'Тип',
'type_website' => 'Веб-сайт',
'type_service' => 'Сервис',
'pattern' => 'Искать текст/шаблон',
'pattern_description' => 'Если текст по шаблону не найден на сайте, сервер будет помечен как Оффлайн. Регулярные выражения допустимы.',
'last_check' => 'Последняя проверка',
'last_online' => 'Был онлайн',
'monitoring' => 'Мониторинг',
'no_monitoring' => 'Нет мониторинга',
'email' => 'E-mail',
'send_email' => 'Отправить E-mail',
'sms' => 'CMC',
'send_sms' => 'Отправить CMC',
'pushover' => 'Pushover',
'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' => 'История',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%d-%m-%Y',
'chart_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'СМС уведомления отключены.',
'warning_notifications_disabled_email' => 'E-mail уведомления отключены.',
'warning_notifications_disabled_pushover' => 'Pushover уведомления отключены.',
'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' => 'Обновления',
'email_status' => 'Разрешить отправку E-mail',
'email_from_email' => 'Отправлять от адреса',
'email_from_name' => 'Отправлять от имени',
'email_smtp' => 'Включить SMTP',
'email_smtp_host' => 'SMTP сервер',
'email_smtp_port' => 'SMTP порт',
'email_smtp_username' => 'SMTP пользователь',
'email_smtp_password' => 'SMTP пароль',
'email_smtp_noauth' => 'Оставить пустым, если без аутентификации',
'sms_status' => 'Разрешить отправку СМС',
'sms_gateway' => 'Шлюз для отправки СМС',
'sms_gateway_mosms' => 'Mosms',
'sms_gateway_mollie' => 'Mollie',
'sms_gateway_spryng' => 'Spryng',
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'Пользователь',
'sms_gateway_password' => 'Пароль',
'sms_from' => 'Номер отправителя',
'pushover_status' => 'Разрешить отправку Pushover сообщений',
'pushover_description' => 'Pushover - это сервис, который позволяет легко получать уведомления в режиме реального времени. Больше информации на <a href="https://pushover.net/">их веб-сайте</a>.',
'pushover_clone_app' => 'Click here to create your Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Прежде чем вы сможете начать пользоваться Pushover, вам необходимо зарегестрировать <a href="%1$s" target="_blank">"App"</a> на их веб-сайте и ввести "App API Token" сюда.',
'alert_type' => 'Выбeрите, какие вы хотите получать уведомления',
'alert_type_description' => '<b>Изменение статуса :</b> '.
'Вы получите уведомление об изменение статуса. Для онлайн -> оффлайн или офлайн -> онлайн.<br/>'.
'<br /><b>Оффлайн:</b> '.
'Вы получите уведомление только когда сервер перейдет в статус оффлайн. Например, '.
'Задание Cron выставлено на каждые 15 минут. Сервер перейдет в статус оффлайн в 1:00 и не измениться до 6:00. '.
'Вы получите 1 уведомление только в 1:00<br/>'.
'<br><b>Всегда:</b> '.
'Вы будете получать уведомление при каждом запуске скрипта проверки, как только сервер перейдет в статус оффлайн, даже если сервер находится в этом статусе несколько часов',
'alert_type_status' => 'Изменение статуса',
'alert_type_offline' => 'Оффлайн',
'alert_type_always' => 'Всегда',
'log_status' => 'Лог статусов',
'log_status_description' => 'Если лог установлен в TRUE, монитор будет логировать все события режим которых выбран в типе уведомлений.',
'log_email' => 'Логировать уведомления отправленые по E-mail',
'log_sms' => 'Логировать уведомления отправленые по СМС',
'log_pushover' => 'Логировать Pushover уведомления',
'updated' => 'Параметры были успешно применены.',
'tab_email' => 'E-mail',
'tab_sms' => 'СМС',
'tab_pushover' => 'Pushover',
'settings_email' => 'Настройка E-mail',
'settings_sms' => 'Настройка SMS',
'settings_pushover' => 'Настройка Pushover',
'settings_notification' => 'Настройка уведомлений',
'settings_log' => 'Настройка логирования',
'auto_refresh' => 'Авто-обновление',
'auto_refresh_servers' =>
'Авто-обновление страницы статуса серверов.<br/>'.
'<span class="small">'.
'Вермя в секундах, если 0 страница не будет обновляться.'.
'</span>',
'seconds' => 'секунд',
'test' => 'Проверка',
'test_email' => 'Сообщение будет отправлено на адрес указаный в профиле пользователя.',
'test_sms' => 'Сообщение будет отправлено на номер телефона указаный в профиле пользователя.',
'test_pushover' => 'Pushover уведомление будет отправленно на устройство указанное в профиле пользователя.',
'send' => 'Отправить',
'test_subject' => 'Проверка',
'test_message' => 'Тестовое сообщение',
'email_sent' => 'Сообщение отправлено',
'email_error' => 'Ошибка при отправке сообщения',
'sms_sent' => 'СМС отправлено',
'sms_error' => 'Ошибка при отправке СМС',
'sms_error_nomobile' => 'Не удалось отправить пробный СМС: действительный телефонный номер не был найден в вашем профиле.',
'pushover_sent' => 'Pushover уведомление отправлено',
'pushover_error' => 'Произошла ошибка во время отправки Pushover уведомления: %s',
'pushover_error_noapp' => 'Не удалось отправить пробное уведомление: Pushover "App API token" не был найден в основных настройках.',
'pushover_error_nokey' => 'Не удалось отправить пробное уведомление: Pushover ключ не был найден в вашем профиле.',
'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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'Сервер \'%LABEL%\' сейчас НЕДОСТУПЕН: ip=%IP%, port=%PORT%. Ошибка=%ERROR%',
'off_email_subject' => 'ВАЖНО: сервер \'%LABEL%\' сейчас НЕДОСТУПЕН',
'off_email_body' => "Невозможно подключиться к следующему серверу:<br/><br/>Сервер: %LABEL%<br/>IP: %IP%<br/>Порт: %PORT%<br/>Ошибка: %ERROR%<br/>Дата: %DATE%",
'off_pushover_title' => 'Cервер \'%LABEL%\' сейчас НЕДОСТУПЕН',
'off_pushover_message' => "Невозможно подключиться к следующему серверу:<br/><br/>Сервер: %LABEL%<br/>IP: %IP%<br/>Порт: %PORT%<br/>Ошибка: %ERROR%<br/>Дата: %DATE%",
'on_sms' => 'Сервер \'%LABEL%\' сейчас ДОСТУПЕН: ip=%IP%, port=%PORT%',
'on_email_subject' => 'ВАЖНО: Сервер \'%LABEL%\' сейчас ДОСТУПЕН',
'on_email_body' => "Сервер '%LABEL%' снова доступен:<br/><br/>Сервер: %LABEL%<br/>IP: %IP%<br/>Порт: %PORT%<br/>Дата: %DATE%",
'on_pushover_title' => 'Сервер \'%LABEL%\' сейчас ДОСТУПЕН',
'on_pushover_message' => "Сервер '%LABEL%' снова доступен:<br/><br/>Сервер: %LABEL%<br/>IP: %IP%<br/>Порт: %PORT%<br/>Дата: %DATE%",
),
'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' => 'Сбросить пароль для PHP Server Monitor',
'password_reset_email_body' => 'Пожалуйста, используйте следующую ссылку для сброса пароля. Ссылка действительна 1 час.<br/><br/>%link%',
'error_user_incorrect' => 'Пользователь с указаными данными не найден.',
'error_login_incorrect' => 'Информация указана неверно.',
'error_login_passwords_nomatch' => 'Пароль указан неверно.',
'error_reset_invalid_link' => 'Ссылка для сброса пароля недействительна.',
'success_password_forgot' => 'Вам был отправлен email, с описанием сброса пароля.',
'success_password_reset' => 'Ваш пароль был сброшен. Пожалуйста авторизуйтесь.',
),
'error' => array(
'401_unauthorized' => 'Доступ закрыт',
'401_unauthorized_description' => 'У вас нет прав доступа к этой странице.',
),
);

View File

@ -35,17 +35,17 @@ $sm_lang = array(
'save' => '保存',
'edit' => '编辑',
'delete' => '删除',
'deleted' => '纪录已删除',
'date' => '日期',
'message' => '消息',
'yes' => '是',
'no' => '否o',
'edit' => '编辑',
'insert' => '插入',
'add_new' => '添加',
'update_available' => '发现新版本({version}) <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => '返回顶部',
'go_back' => '后退',
'ok' => 'OK',
'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
@ -81,6 +81,14 @@ $sm_lang = array(
'level_description' => '<b>超级管理员</b> 拥有所有权限: 管理服务器, 用户 以及修改设置.<br/><b>普通用户</b> 只能查看及更新自己名下所属的服务器.',
'mobile' => '手机',
'email' => '邮件',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
'updated' => '用户已更新.',
'inserted' => '用户已添加.',
'profile' => '个人资料',
@ -101,11 +109,16 @@ $sm_lang = array(
'status' => '状态',
'email' => '邮件',
'sms' => '短信',
'pushover' => 'Pushover',
'no_logs' => 'No logs',
),
'servers' => array(
'server' => '服务器',
'status' => '状态',
'label' => '标签',
'domain' => '域名/IP',
'timeout' => 'Timeout',
'timeout_description' => 'Number of seconds to wait for the server to respond.',
'port' => '端口',
'type' => '类型',
'type_website' => '网站',
@ -115,14 +128,23 @@ $sm_lang = array(
'last_check' => '最后检查',
'last_online' => '最后在线',
'monitoring' => '监控中',
'no_monitoring' => 'No monitoring',
'email' => '邮件',
'send_email' => '发送邮件',
'sms' => '短信',
'send_sms' => '发送短信',
'pushover' => 'Pushover',
'users' => 'Users',
'delete_title' => 'Delete Server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
'deleted' => 'Server deleted.',
'updated' => '服务器已更新.',
'inserted' => '服务器已添加.',
'latency' => '延迟',
'latency_max' => '延迟(最大)',
'latency_min' => '延迟(最小)',
'latency_avg' => '延迟(平均)',
'uptime' => 'Uptime',
'year' => '年',
'month' => '月',
'week' => '周',
@ -137,6 +159,16 @@ $sm_lang = array(
'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' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover 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.',
'error_server_ip_bad_service' => 'The IP address is not valid.',
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
),
'config' => array(
'general' => '通用',
@ -159,10 +191,17 @@ $sm_lang = array(
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_username' => 'SMS网关用户名',
'sms_gateway_password' => 'SMS网关密码',
'sms_from' => '发信人电话号',
'alert_type' => '如果想要收到提醒请选中此项.<br/>',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/">their website</a> 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 <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'alert_type' => '如果想要收到提醒请选中此项.',
'alert_type_description' => '<b>状态变化:</b> '.
'服务器 online -> offline 或 offline -> online 的状态变化将会收到提醒.<br/>'.
'<br /><b>离线状态:</b> '.
@ -178,12 +217,14 @@ $sm_lang = array(
'log_status_description' => '如果状态记录设置为开, 提醒发送时均会保存记录.',
'log_email' => '记录脚本所发邮件?',
'log_sms' => '记录脚本所发短信SMS?',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => '设置已更新.',
'tab_email' => '邮件发送设置',
'tab_sms' => '短信发送设置',
'tab_log' => '日志设置',
'tab_pushover' => 'Pushover',
'settings_email' => '邮件发送设置',
'settings_sms' => '短信发送设置',
'settings_pushover' => 'Pushover settings',
'settings_notification' => '提醒设置',
'settings_log' => '日志设置',
'auto_refresh' => 'Auto-refresh',
@ -193,15 +234,38 @@ $sm_lang = array(
'单位为秒, 设置为0则不自动刷新.'.
'</span>',
'seconds' => 'seconds',
'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_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
'email_sent' => 'Email sent',
'email_error' => 'Error in email sending',
'sms_sent' => 'Sms sent',
'sms_error' => 'Error in sms sending',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your 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_nokey' => 'Unable to send test notification: no Pushover key 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_days' => 'days',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => '服务器 \'%LABEL%\' 宕机: ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => 'IMPORTANT: 服务器 \'%LABEL%\' 宕机',
'off_email_body' => "无法连接到以下服务器:<br/><br/>服务器: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>错误: %ERROR%<br/>日期: %DATE%",
'off_pushover_title' => '服务器 \'%LABEL%\' 宕机',
'off_pushover_message' => "无法连接到以下服务器:<br/><br/>服务器: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>错误: %ERROR%<br/>日期: %DATE%",
'on_sms' => '服务器 \'%LABEL%\' 运行中: ip=%IP%, port=%PORT%',
'on_email_subject' => 'IMPORTANT: 服务器 \'%LABEL%\' 运行中',
'on_email_body' => "服务器 '%LABEL%' 恢复运行:<br/><br/>服务器: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>日期: %DATE%",
'on_pushover_title' => '服务器 \'%LABEL%\' 运行中',
'on_pushover_message' => "服务器 '%LABEL%' 恢复运行:<br/><br/>服务器: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>日期: %DATE%",
),
'login' => array(
'welcome_usermenu' => '欢迎, %user_name%',
@ -226,4 +290,8 @@ $sm_lang = array(
'success_password_forgot' => '密码重设邮件已发送.',
'success_password_reset' => '密码重设成功.请登录.',
),
'error' => array(
'401_unauthorized' => 'Unauthorized',
'401_unauthorized_description' => 'You do not have the privileges to view this page.',
),
);

View File

@ -27,7 +27,7 @@
namespace psm\Module;
use psm\Service\Database;
use psm\Service\Template;
use Symfony\Component\HttpFoundation\Response;
abstract class AbstractController implements ControllerInterface {
@ -79,6 +79,18 @@ abstract class AbstractController implements ControllerInterface {
*/
protected $sidebar;
/**
* array of Modal to add
* @var \psm\Util\Module\ModalInterface[] $modal
*/
protected $modal = array();
/**
* html code of header accessories
* @var string $header_accessories
*/
protected $header_accessories;
/**
* Database object
* @var \psm\Service\Database $db
@ -86,17 +98,10 @@ abstract class AbstractController implements ControllerInterface {
protected $db;
/**
* Template object
* @var \psm\Service\Template $tpl
* Twig object
* @var \Twig_Environment $twig
*/
protected $tpl;
/**
* Template Id that should be added to the main template
* @var string
* @see setTemplateId() getTemplateId()
*/
protected $tpl_id;
protected $twig;
/**
* User service
@ -118,22 +123,46 @@ abstract class AbstractController implements ControllerInterface {
*/
protected $user_level_required_actions = array();
function __construct(Database $db, Template $tpl) {
/*
* Required using black background layout
* @var boolean $black_background
*/
protected $black_background = false;
/**
* XHR mode?
* @var boolean $xhr
* @see isXHR()
*/
protected $xhr = false;
function __construct(Database $db, \Twig_Environment $twig) {
$this->db = $db;
$this->tpl = $tpl;
$this->twig = $twig;
}
/**
* Initialize the module
* Initialize the controller.
*
* @param string $action if NULL, the action will be retrieved from user input (GET/POST)
* @return \Symfony\Component\HttpFoundation\Response
*/
public function initialize() {
$action = psm_GET('action', psm_POST('action', $this->action_default));
public function initialize($action = null) {
if($action === null) {
$action = psm_GET('action', psm_POST('action', $this->action_default));
}
$this->xhr = (bool) psm_GET('xhr', psm_POST('xhr', false));
if(!in_array($action, $this->actions) || !$this->initializeAction($action)) {
$this->initializeAction($this->action_default);
if(!in_array($action, $this->actions) || !($result = $this->initializeAction($action))) {
$result = $this->initializeAction($this->action_default);
}
$this->createHTML();
if($result instanceof Response) {
return $result;
}
// no response returned from execute, create regular HTML
return $this->createHTML($result);
}
/**
@ -141,7 +170,7 @@ abstract class AbstractController implements ControllerInterface {
*
* For it to run, the "execute$action" method must exist.
* @param string $action
* @return boolean whether action has been initialized successfully
* @return mixed FALSE when action couldnt be initialized, response otherwise
*/
protected function initializeAction($action) {
if(isset($this->user_level_required_actions[$action])) {
@ -155,57 +184,67 @@ abstract class AbstractController implements ControllerInterface {
$method = 'execute' . ucfirst($action);
if(method_exists($this, $method)) {
$this->action = $action;
$this->$method();
return true;
$result = $this->$method();
// if result from execute is null, no return value given so return true to indicate a successful execute
return ($result === null) ? true : $result;
}
return false;
}
/**
* Create the HTML code for the module.
* First the createHTMLLabels() will be called to add all labels to the template,
* Then the tpl_id set in $this->getTemplateId() will be added to the main template automatically
*
* If XHR is on, no main template will be added.
*
* @param string $html HTML code to add to the main body
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function createHTML() {
$tpl_data = array();
protected function createHTML($html = null) {
if(!$this->xhr) {
// in XHR mode, we will not add the main template
$tpl_data = array(
'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,
'messages' => $this->getMessages(),
'html_content' => $html,
);
if(!empty($this->messages)) {
$this->tpl->addTemplateDataRepeat('main', 'messages', $this->messages);
}
// add menu to page?
if($this->add_menu) {
$tpl_data['html_menu'] = $this->createHTMLMenu();
}
// add sidebar to page?
if($this->sidebar !== null) {
$tpl_data['html_sidebar'] = $this->sidebar->createHTML();
$tpl_data['content_span'] = '10';
} else {
$tpl_data['content_span'] = '12';
}
// add footer to page?
if($this->add_footer) {
$this->tpl->newTemplate('main_footer', 'main.tpl.html');
$tpl_data['html_footer'] = $this->tpl->getTemplate('main_footer');
$tpl_data['version'] = 'v' . PSM_VERSION;
// add menu to page?
if($this->add_menu) {
$tpl_data['html_menu'] = $this->createHTMLMenu();
}
// add header accessories to page ?
if($this->header_accessories) {
$tpl_data['header_accessories'] = $this->header_accessories;
}
// add modal dialog to page ?
if(sizeof($this->modal)) {
$html_modal = '';
foreach($this->modal as $modal) {
$html_modal .= $modal->createHTML();
}
$tpl_data['html_modal'] = $html_modal;
}
// add sidebar to page?
if($this->sidebar !== null) {
$tpl_data['html_sidebar'] = $this->sidebar->createHTML();
}
if(psm_update_available()) {
$tpl_data['update_available'] = str_replace('{version}', 'v'.psm_get_conf('version_update_check'), psm_get_lang('system', 'update_available'));
}
if($this->black_background) {
$tpl_data['body_class'] = 'black_background';
}
$html = $this->twig->render('main/body.tpl.html', $tpl_data);
}
$tpl_id_content = $this->getTemplateId();
if($tpl_id_content) {
$tpl_data['content'] = $this->tpl->getTemplate($tpl_id_content);
}
$response = new Response($html);
if(psm_update_available()) {
$tpl_data['update_available'] = str_replace('{version}', 'v'.psm_get_conf('version_update_check'), psm_get_lang('system', 'update_available'));
}
// add the module's custom template to the main template to get some content
$this->setTemplateId('main');
$this->tpl->addTemplatedata($this->getTemplateId(), $tpl_data);
$this->createHTMLLabels();
// display main template
echo $this->tpl->display($this->getTemplateId());
return $response;
}
/**
@ -215,9 +254,6 @@ abstract class AbstractController implements ControllerInterface {
protected function createHTMLMenu() {
$ulvl = ($this->user) ? $this->user->getUserLevel() : PSM_USER_ANONYMOUS;
$tpl_id = 'main_menu';
$this->tpl->newTemplate($tpl_id, 'main.tpl.html');
$tpl_data = array(
'label_help' => psm_get_lang('menu', 'help'),
'label_profile' => psm_get_lang('users', 'profile'),
@ -237,17 +273,14 @@ abstract class AbstractController implements ControllerInterface {
$items = array();
break;
}
$menu = array();
$tpl_data['menu'] = array();
foreach($items as $key) {
$menu[] = array(
$tpl_data['menu'][] = array(
'active' => ($key == psm_GET('mod')) ? 'active' : '',
'url' => psm_build_url(array('mod' => $key)),
'label' => psm_get_lang('menu', $key),
);
}
if(!empty($menu)) {
$this->tpl->addTemplateDataRepeat($tpl_id, 'menu', $menu);
}
if($ulvl != PSM_USER_ANONYMOUS) {
$user = $this->user->getUser();
@ -257,53 +290,7 @@ abstract class AbstractController implements ControllerInterface {
psm_get_lang('login', 'welcome_usermenu')
);
}
$this->tpl->addTemplateData($tpl_id, $tpl_data);
return $this->tpl->getTemplate($tpl_id);
}
/**
* Use this to add language specific labels to template
*
* @see createHTML()
*/
protected function createHTMLLabels() {
global $type;
$this->tpl->addTemplateData(
'main',
array(
'title' => strtoupper(psm_get_lang('system', 'title')),
'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
)
);
}
/**
* Set a template id that will be added to the main template automatically
* once you call the parent::createHTML()
*
* @param string $tpl_id
* @param string $tpl_file if given, the tpl_id will be created automatically from this file
* @see getTemplateId() createHTML()
*/
public function setTemplateId($tpl_id, $tpl_file = null) {
$this->tpl_id = $tpl_id;
if($tpl_file != null) {
// tpl_file given, try to load the template..
$this->tpl->newTemplate($tpl_id, $tpl_file);
}
}
/**
* Get the mpalte id that will be added to the main template
*
* @return string
* @see setTemplateId()
*/
public function getTemplateId() {
return $this->tpl_id;
return $this->twig->render('main/menu.tpl.html', $tpl_data);
}
/**
@ -358,7 +345,8 @@ abstract class AbstractController implements ControllerInterface {
* Add one or multiple message to the stack to be displayed to the user
* @param string|array $msg
* @param string $shortcode info/success/warning/error
* @return \psm\Module\AbstractModule
* @return \psm\Module\ControllerInterface
* @see getMessages()
*/
public function addMessage($msg, $shortcode = 'info') {
if(!is_array($msg)) {
@ -389,6 +377,20 @@ abstract class AbstractController implements ControllerInterface {
return $this;
}
/**
* Get all messages (and optionally clear them)
* @param boolean $clear
* @return array
* @see addMessage()
*/
public function getMessages($clear = true) {
$msgs = $this->messages;
if($clear) {
$this->messages = array();
}
return $msgs;
}
/**
* Set user service
* @param \psm\Service\User $user
@ -443,4 +445,30 @@ abstract class AbstractController implements ControllerInterface {
$this->sidebar = $sidebar;
return $this;
}
/**
* Add a modal dialog to the page
* @param \psm\Util\Module\ModalInterface $modal
* @return \psm\Module\ControllerInterface
*/
public function addModal(\psm\Util\Module\ModalInterface $modal) {
$this->modal[$modal->getModalID()] = $modal;
return $this;
}
/**
* Set the html code of the header accessories
* @param string $html
*/
public function setHeaderAccessories($html) {
$this->header_accessories = $html;
}
/**
* Check if XHR is on
* @return boolean
*/
public function isXHR() {
return $this->xhr;
}
}

View File

@ -28,7 +28,6 @@
namespace psm\Module\Config\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
class ConfigController extends AbstractController {
@ -40,9 +39,11 @@ class ConfigController extends AbstractController {
'email_status',
'email_smtp',
'sms_status',
'pushover_status',
'log_status',
'log_email',
'log_sms',
'log_pushover',
'show_update',
);
@ -60,10 +61,13 @@ class ConfigController extends AbstractController {
'sms_gateway_username',
'sms_gateway_password',
'sms_from',
'pushover_api_token',
);
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
private $default_tab = 'general';
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ADMIN);
@ -74,9 +78,12 @@ class ConfigController extends AbstractController {
/**
* Populate all the config fields with values from the database
*
* @return string
*/
protected function executeIndex() {
$this->setTemplateId('config', 'config/config.tpl.html');
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'config'));
$tpl_data = $this->getLabels();
$config_db = $this->db->select(
PSM_DB_PREFIX . 'config',
@ -91,21 +98,21 @@ class ConfigController extends AbstractController {
// generate language array
$lang_keys = psm_get_langs();
$languages = array();
$tpl_data['language_current'] = (isset($config['language']))
? $config['language']
: 'en_US';
$tpl_data['languages'] = array();
foreach($lang_keys as $key => $label) {
$languages[] = array(
$tpl_data['languages'][] = array(
'value' => $key,
'label' => $label,
'selected' => ($key == $config['language']) ? 'selected="selected"' : '',
);
}
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'languages', $languages);
$tpl_data = array(
'sms_selected_' . $config['sms_gateway'] => 'selected="selected"',
'alert_type_selected_' . $config['alert_type'] => 'selected="selected"',
'auto_refresh_servers' => (isset($config['auto_refresh_servers'])) ? $config['auto_refresh_servers'] : '0',
);
$tpl_data['sms_selected_' . $config['sms_gateway']] = 'selected="selected"';
$tpl_data['alert_type_selected_' . $config['alert_type']] = 'selected="selected"';
$tpl_data['auto_refresh_servers'] = (isset($config['auto_refresh_servers'])) ? $config['auto_refresh_servers'] : '0';
$tpl_data['log_retention_period'] = (isset($config['log_retention_period'])) ? $config['log_retention_period'] : '365';
foreach($this->checkboxes as $input_key) {
$tpl_data[$input_key . '_checked'] =
@ -117,7 +124,18 @@ class ConfigController extends AbstractController {
$tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : '';
}
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
$tpl_data[$this->default_tab . '_active'] = 'active';
$testmodals = array('email', 'sms', 'pushover');
foreach($testmodals as $modal_id) {
$modal = new \psm\Util\Module\Modal($this->twig, 'test' . ucfirst($modal_id), \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL);
$this->addModal($modal);
$modal->setTitle(psm_get_lang('servers', 'send_' . $modal_id));
$modal->setMessage(psm_get_lang('config', 'test_' . $modal_id));
$modal->setOKButtonLabel(psm_get_lang('config', 'send'));
}
return $this->twig->render('module/config/config.tpl.html', $tpl_data);
}
/**
@ -131,7 +149,8 @@ class ConfigController extends AbstractController {
'language' => $_POST['language'],
'sms_gateway' => $_POST['sms_gateway'],
'alert_type' => $_POST['alert_type'],
'auto_refresh_servers' => (isset($_POST['auto_refresh_servers'])) ? intval($_POST['auto_refresh_servers']) : '0',
'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)),
'log_retention_period' => intval(psm_POST('log_retention_period', 365)),
);
foreach($this->checkboxes as $input_key) {
$clean[$input_key] = (isset($_POST[$input_key])) ? '1': '0';
@ -141,91 +160,181 @@ class ConfigController extends AbstractController {
$clean[$input_key] = $_POST[$input_key];
}
}
// save all values to the database
$language_refresh = ($clean['language'] != psm_get_conf('language'));
foreach($clean as $key => $value) {
// check if key already exists, otherwise add it
if(psm_get_conf($key) === null) {
// not yet set, add it
$this->db->save(
PSM_DB_PREFIX . 'config',
array(
'key' => $key,
'value' => $value,
)
);
} else {
// update
$this->db->save(
PSM_DB_PREFIX . 'config',
array('value' => $value),
array('key' => $key)
);
}
psm_update_conf($key, $value);
}
$this->addMessage(psm_get_lang('config', 'updated'), 'success');
if($clean['language'] != psm_get_conf('language')) {
header('Location: ' . $_SERVER['REQUEST_URI']);
if(!empty($_POST['test_email'])) {
$this->testEmail();
} elseif(!empty($_POST['test_sms'])) {
$this->testSMS();
} elseif(!empty($_POST['test_pushover'])) {
$this->testPushover();
}
if($language_refresh) {
header('Location: ' . psm_build_url(array('mod' => 'config'), true, false));
die();
}
if(isset($_POST['general_submit'])) {
$this->default_tab = 'general';
} elseif(isset($_POST['email_submit']) || !empty($_POST['test_email'])) {
$this->default_tab = 'email';
} elseif(isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) {
$this->default_tab = 'sms';
} elseif(isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) {
$this->default_tab = 'pushover';
}
}
$this->initializeAction('index');
return $this->initializeAction('index');
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'config'),
'label_tab_email' => psm_get_lang('config', 'tab_email'),
'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_log' => psm_get_lang('config', 'tab_log'),
'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_general' => psm_get_lang('config', 'general'),
'label_language' => psm_get_lang('config', 'language'),
'label_show_update' => psm_get_lang('config', 'show_update'),
'label_email_status' => psm_get_lang('config', 'email_status'),
'label_email_from_email' => psm_get_lang('config', 'email_from_email'),
'label_email_from_name' => psm_get_lang('config', 'email_from_name'),
'label_email_smtp' => psm_get_lang('config', 'email_smtp'),
'label_email_smtp_host' => psm_get_lang('config', 'email_smtp_host'),
'label_email_smtp_port' => psm_get_lang('config', 'email_smtp_port'),
'label_email_smtp_username' => psm_get_lang('config', 'email_smtp_username'),
'label_email_smtp_password' => psm_get_lang('config', 'email_smtp_password'),
'label_email_smtp_noauth' => psm_get_lang('config', 'email_smtp_noauth'),
'label_sms_status' => psm_get_lang('config', 'sms_status'),
'label_sms_gateway' => psm_get_lang('config', 'sms_gateway'),
'label_sms_gateway_mosms' => psm_get_lang('config', 'sms_gateway_mosms'),
'label_sms_gateway_mollie' => psm_get_lang('config', 'sms_gateway_mollie'),
'label_sms_gateway_spryng' => psm_get_lang('config', 'sms_gateway_spryng'),
'label_sms_gateway_inetworx' => psm_get_lang('config', 'sms_gateway_inetworx'),
'label_sms_gateway_clickatell' => psm_get_lang('config', 'sms_gateway_clickatell'),
'label_sms_gateway_textmarketer' => psm_get_lang('config', 'sms_gateway_textmarketer'),
'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_alert_type' => psm_get_lang('config', 'alert_type'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_alert_type_status' => psm_get_lang('config', 'alert_type_status'),
'label_alert_type_offline' => psm_get_lang('config', 'alert_type_offline'),
'label_alert_type_always' => psm_get_lang('config', 'alert_type_always'),
'label_log_status' => psm_get_lang('config', 'log_status'),
'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_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
'label_auto_refresh_servers' => psm_get_lang('config', 'auto_refresh_servers'),
'label_seconds' => psm_get_lang('config', 'seconds'),
'label_save' => psm_get_lang('system', 'save'),
)
);
/**
* Execute email test
*
* @todo move test to separate class
*/
protected function testEmail() {
$mail = psm_build_mail();
$message = psm_get_lang('config', 'test_message');
$mail->Subject = psm_get_lang('config', 'test_subject');
$mail->Priority = 1;
$mail->Body = $message;
$mail->AltBody = str_replace('<br/>', "\n", $message);
$user = $this->user->getUser();
$mail->AddAddress($user->email, $user->name);
if($mail->Send()) {
$this->addMessage(psm_get_lang('config', 'email_sent'), 'success');
} else {
$this->addMessage(psm_get_lang('config', 'email_error') . ': ' . $mail->ErrorInfo, 'error');
}
}
return parent::createHTMLLabels();
/**
* Execute SMS test
*
* @todo move test to separate class
*/
protected function testSMS() {
$sms = psm_build_sms();
if($sms) {
$user = $this->user->getUser();
if(empty($user->mobile)) {
$this->addMessage(psm_get_lang('config', 'sms_error_nomobile'), 'error');
} else {
$sms->addRecipients($user->mobile);
if($sms->sendSMS(psm_get_lang('config', 'test_message'))) {
$this->addMessage(psm_get_lang('config', 'sms_sent'), 'success');
} else {
$this->addMessage(psm_get_lang('config', 'sms_error'), 'error');
}
}
}
}
/**
* Execute pushover test
*
* @todo move test to separate class
*/
protected function testPushover() {
$pushover = psm_build_pushover();
$pushover->setDebug(true);
$user = $this->user->getUser();
$api_token = psm_get_conf('pushover_api_token');
if(empty($api_token)) {
$this->addMessage(psm_get_lang('config', 'pushover_error_noapp'), 'error');
} elseif(empty($user->pushover_key)) {
$this->addMessage(psm_get_lang('config', 'pushover_error_nokey'), 'error');
} else {
$pushover->setPriority(0);
$pushover->setTitle(psm_get_lang('config', 'test_subject'));
$pushover->setMessage(psm_get_lang('config', 'test_message'));
$pushover->setUser($user->pushover_key);
if($user->pushover_device != '') {
$pushover->setDevice($user->pushover_device);
}
$result = $pushover->send();
if(isset($result['output']->status) && $result['output']->status == 1) {
$this->addMessage(psm_get_lang('config', 'pushover_sent'), 'success');
} else {
if(isset($result['output']->errors->error)) {
$error = $result['output']->errors->error;
} else {
$error = 'Unknown';
}
$this->addMessage(sprintf(psm_get_lang('config', 'pushover_error'), $error), 'error');
}
}
}
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_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_general' => psm_get_lang('config', 'general'),
'label_language' => psm_get_lang('config', 'language'),
'label_show_update' => psm_get_lang('config', 'show_update'),
'label_email_status' => psm_get_lang('config', 'email_status'),
'label_email_from_email' => psm_get_lang('config', 'email_from_email'),
'label_email_from_name' => psm_get_lang('config', 'email_from_name'),
'label_email_smtp' => psm_get_lang('config', 'email_smtp'),
'label_email_smtp_host' => psm_get_lang('config', 'email_smtp_host'),
'label_email_smtp_port' => psm_get_lang('config', 'email_smtp_port'),
'label_email_smtp_username' => psm_get_lang('config', 'email_smtp_username'),
'label_email_smtp_password' => psm_get_lang('config', 'email_smtp_password'),
'label_email_smtp_noauth' => psm_get_lang('config', 'email_smtp_noauth'),
'label_sms_status' => psm_get_lang('config', 'sms_status'),
'label_sms_gateway' => psm_get_lang('config', 'sms_gateway'),
'label_sms_gateway_mosms' => psm_get_lang('config', 'sms_gateway_mosms'),
'label_sms_gateway_mollie' => psm_get_lang('config', 'sms_gateway_mollie'),
'label_sms_gateway_spryng' => psm_get_lang('config', 'sms_gateway_spryng'),
'label_sms_gateway_inetworx' => psm_get_lang('config', 'sms_gateway_inetworx'),
'label_sms_gateway_clickatell' => psm_get_lang('config', 'sms_gateway_clickatell'),
'label_sms_gateway_textmarketer' => psm_get_lang('config', 'sms_gateway_textmarketer'),
'label_sms_gateway_smsit' => psm_get_lang('config', 'sms_gateway_smsit'),
'label_sms_gateway_smsglobal' => psm_get_lang('config', 'sms_gateway_smsglobal'),
'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_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'),
'pushover_clone_url' => PSM_PUSHOVER_CLONE_URL,
'label_pushover_api_token' => psm_get_lang('config', 'pushover_api_token'),
'label_pushover_api_token_description' => sprintf(
psm_get_lang('config', 'pushover_api_token_description'),
PSM_PUSHOVER_CLONE_URL
),
'label_alert_type' => psm_get_lang('config', 'alert_type'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_alert_type_status' => psm_get_lang('config', 'alert_type_status'),
'label_alert_type_offline' => psm_get_lang('config', 'alert_type_offline'),
'label_alert_type_always' => psm_get_lang('config', 'alert_type_always'),
'label_log_status' => psm_get_lang('config', 'log_status'),
'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_pushover' => psm_get_lang('config', 'log_pushover'),
'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
'label_auto_refresh_servers' => psm_get_lang('config', 'auto_refresh_servers'),
'label_seconds' => psm_get_lang('config', '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'),
);
}
}

View File

@ -28,11 +28,10 @@
namespace psm\Module;
use psm\Service\Database;
use psm\Service\Template;
interface ControllerInterface {
public function __construct(Database $db, Template $tpl);
public function __construct(Database $db, \Twig_Environment $twig);
/**
* Initialize the module

View File

@ -0,0 +1,56 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Module\Error\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
class ErrorController extends AbstractController {
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
$this->setActions(array(
'401',
), '401');
}
/**
* 401 error page
*
* @return string
*/
protected function execute401() {
return $this->twig->render('module/error/401.tpl.html', array(
'label_title' => psm_get_lang('error', '401_unauthorized'),
'label_description' => psm_get_lang('error', '401_unauthorized_description'),
));
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Module\Error;
use psm\Module\ModuleInterface;
class ErrorModule implements ModuleInterface {
public function getControllers() {
return array(
'error' => __NAMESPACE__ . '\Controller\ErrorController',
);
}
}

View File

@ -29,7 +29,6 @@
namespace psm\Module\Install\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
class InstallController extends AbstractController {
@ -45,8 +44,8 @@ class InstallController extends AbstractController {
*/
protected $path_config_old;
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
$this->addMenu(false);
@ -57,33 +56,14 @@ class InstallController extends AbstractController {
$this->setActions(array(
'index', 'config', 'install'
), 'index');
}
protected function createHTML() {
$html_results = '';
if(!empty($this->messages)) {
$this->tpl->newTemplate('install_results', 'install/install.tpl.html');
$this->tpl->addTemplateDataRepeat('install_results', 'resultmsgs', $this->messages);
$html_results = $this->tpl->getTemplate('install_results');
$this->messages = array();
}
$tpl_id = $this->getTemplateId();
$this->setTemplateId('install', 'install/install.tpl.html');
$this->tpl->addTemplateData($this->getTemplateId(), array(
'html_install' => $this->tpl->getTemplate($tpl_id),
'html_results' => $html_results,
));
return parent::createHTML();
$this->twig->addGlobal('subtitle', psm_get_lang('system,', 'install'));
}
/**
* Say hi to our new user
*/
protected function executeIndex() {
$this->setTemplateId('install_index', 'install/install.tpl.html');
// build prerequisites
$errors = 0;
@ -110,13 +90,17 @@ class InstallController extends AbstractController {
if($errors > 0) {
$this->addMessage($errors . ' error(s) have been encountered. Please fix them and refresh this page.', 'error');
}
return $this->twig->render('module/install/index.tpl.html', array(
'messages' => $this->getMessages()
));
}
/**
* Help the user create a new config file
*/
protected function executeConfig() {
$this->setTemplateId('install_config_new', 'install/install.tpl.html');
$tpl_name = 'module/install/config_new.tpl.html';
$tpl_data = array();
if(!defined('PSM_DB_PREFIX')) {
@ -168,8 +152,7 @@ class InstallController extends AbstractController {
$this->addMessage('Configuration file written successfully.', 'success');
} else {
$this->addMessage('Config file is not writable, we cannot save it for you.', 'error');
$this->tpl->newTemplate('install_config_new_copy', 'install/install.tpl.html');
$tpl_data['html_config_copy'] = $this->tpl->getTemplate('install_config_new_copy');
$tpl_data['include_config_new_copy'] = true;
$tpl_data['php_config'] = $config_php;
}
} else {
@ -185,14 +168,14 @@ class InstallController extends AbstractController {
if(version_compare($this->getPreviousVersion(), '3.0.0', '<')) {
// upgrade from before 3.0, does not have passwords yet.. create new user first
$this->addMessage('Your current version does not have an authentication system, but since v3.0 access to the monitor is restricted by user accounts. Please set up a new account to be able to login after the upgrade, and which you can use to change the passwords for your other accounts.', 'info');
$this->setTemplateId('install_config_new_user', 'install/install.tpl.html');
$tpl_name = 'module/install/config_new_user.tpl.html';
} else {
$this->setTemplateId('install_config_upgrade', 'install/install.tpl.html');
$tpl_name = 'module/install/config_upgrade.tpl.html';
$tpl_data['version'] = PSM_VERSION;
}
} else {
// fresh install ahead
$this->setTemplateId('install_config_new_user', 'install/install.tpl.html');
$tpl_name = 'module/install/config_new_user.tpl.html';
$tpl_data['username'] = (isset($_POST['username'])) ? $_POST['username'] : '';
$tpl_data['email'] = (isset($_POST['email'])) ? $_POST['email'] : '';
@ -201,7 +184,8 @@ class InstallController extends AbstractController {
$this->addMessage('Configuration file found, but unable to connect to MySQL. Please check your information.', 'error');
}
}
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
$tpl_data['messages'] = $this->getMessages();
return $this->twig->render($tpl_name, $tpl_data);
}
/**
@ -211,6 +195,8 @@ class InstallController extends AbstractController {
if(!defined('PSM_DB_PREFIX') || !$this->db->status()) {
return $this->executeConfig();
}
$add_user = false;
// check if user submitted username + password in previous step
// this would only be the case for new installs, and install from
// before 3.0
@ -220,7 +206,10 @@ class InstallController extends AbstractController {
'password' => psm_POST('password'),
'password_repeat' => psm_POST('password_repeat'),
'email' => psm_POST('email', ''),
'mobile' => '',
'level' => PSM_USER_ADMIN,
'pushover_key' => '',
'pushover_device' => '',
);
$validator = new \psm\Util\User\UserValidator($this->user);
@ -275,7 +264,9 @@ class InstallController extends AbstractController {
}
}
$this->setTemplateId('install_success', 'install/install.tpl.html');
return $this->twig->render('module/install/success.tpl.html', array(
'messages' => $this->getMessages()
));
}
/**
@ -295,7 +286,6 @@ class InstallController extends AbstractController {
);
$config .= $line;
}
$config .= "?>".PHP_EOL;
if(is_writeable($this->path_config)) {
file_put_contents($this->path_config, $config);
return true;
@ -358,15 +348,4 @@ class InstallController extends AbstractController {
return $version_from;
}
}
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('system', 'install'),
)
);
return parent::createHTMLLabels();
}
}

View File

@ -27,8 +27,6 @@
**/
namespace psm\Module;
use psm\Service\Database;
use psm\Service\Template;
interface ModuleInterface {

View File

@ -29,12 +29,11 @@
namespace psm\Module\Server\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
abstract class AbstractServerController extends AbstractController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
}
/**
@ -73,8 +72,10 @@ abstract class AbstractServerController extends AbstractController {
`s`.`active`,
`s`.`email`,
`s`.`sms`,
`s`.`pushover`,
`s`.`warning_threshold`,
`s`.`warning_threshold_counter`
`s`.`warning_threshold_counter`,
`s`.`timeout`
FROM `".PSM_DB_PREFIX."servers` AS `s`
{$sql_join}
{$sql_where}
@ -100,11 +101,7 @@ abstract class AbstractServerController extends AbstractController {
$server['active'] = psm_get_lang('system', $server['active']);
$server['email'] = psm_get_lang('system', $server['email']);
$server['sms'] = psm_get_lang('system', $server['sms']);
$server['url_view'] = psm_build_url(array(
'mod' => 'server',
'action' => 'view',
'id' => $server['server_id'],
));
$server['pushover'] = psm_get_lang('system', $server['pushover']);
if($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) {
$server['status'] = 'warning';
@ -112,7 +109,17 @@ abstract class AbstractServerController extends AbstractController {
$server['error'] = htmlentities($server['error']);
$server['type'] = psm_get_lang('servers', 'type_' . $server['type']);
$server['timeout'] = ($server['timeout'] > 0) ? $server['timeout'] : PSM_CURL_TIMEOUT;
$url_actions = array('delete', 'edit', 'view');
foreach($url_actions as $action) {
$server['url_' . $action] = psm_build_url(array(
'mod' => 'server',
'action' => $action,
'id' => $server['server_id'],
));
}
return $server;
}
}
}

View File

@ -27,15 +27,14 @@
namespace psm\Module\Server\Controller;
use psm\Service\Database;
use psm\Service\Template;
/**
* Log module. Create the page to view previous log messages
*/
class LogController extends AbstractServerController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setActions('index', 'index');
}
@ -44,12 +43,22 @@ class LogController extends AbstractServerController {
* Prepare the template with a list of all log entries
*/
protected function executeIndex() {
$this->setTemplateId('server_log_list', 'server/log.tpl.html');
$entries = array();
$entries['status'] = $this->getEntries('status');
$entries['email'] = $this->getEntries('email');
$entries['sms'] = $this->getEntries('sms');
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_log'));
$tpl_data = array(
'label_status' => psm_get_lang('log', 'status'),
'label_email' => psm_get_lang('log', 'email'),
'label_sms' => psm_get_lang('log', 'sms'),
'label_pushover' => psm_get_lang('log', 'pushover'),
'label_title' => psm_get_lang('log', 'title'),
'label_server' => psm_get_lang('servers', 'server'),
'label_type' => psm_get_lang('log', 'type'),
'label_message' => psm_get_lang('system', 'message'),
'label_date' => psm_get_lang('system', 'date'),
'label_users' => ucfirst(psm_get_lang('menu', 'user')),
'label_no_logs' => psm_get_lang('log', 'no_logs'),
'tabs' => array(),
);
$log_types = array('status', 'email', 'sms', 'pushover');
// get users
$users = $this->db->select(PSM_DB_PREFIX.'users', null, array('user_id','name'));
@ -59,42 +68,50 @@ class LogController extends AbstractServerController {
$users_labels[$user['user_id']] = $user['name'];
}
foreach($entries as $key => $records) {
foreach($log_types as $key) {
$records = $this->getEntries($key);
$log_count = count($records);
$tab_data = array(
'id' => $key,
'has_users' => ($key == 'status') ? false : true,
'no_logs' => ($log_count == 0) ? true : false,
'tab_active' => ($key == 'status') ? 'active' : '',
);
for ($x = 0; $x < $log_count; $x++) {
$records[$x]['class'] = ($x & 1) ? 'odd' : 'even';
$records[$x]['users'] = '';
$records[$x]['server'] = $records[$x]['label'] . ' (' . $records[$x]['label_adv'] . ')';
$records[$x]['datetime_format'] = psm_date($records[$x]['datetime']);
$record = &$records[$x];
$record['class'] = ($x & 1) ? 'odd' : 'even';
$record['users'] = '';
$record['server'] = $record['label'];
$record['type_icon'] = ($record['server_type'] == 'website') ? 'icon-globe' : 'icon-cog';
$record['type_title'] = psm_get_lang('servers', 'type_' . $record['server_type']);
$ip = '(' . $record['ip'];
if(!empty($record['port']) && (($record['server_type'] != 'website') || ($record['port'] != 80))) {
$ip .= ':' . $record['port'];
}
$ip .= ')';
$record['ip'] = $ip;
$record['datetime_format'] = psm_date($record['datetime']);
// fix up user list
if($records[$x]['user_id'] == '') continue;
$users = explode(',', $records[$x]['user_id']);
foreach($users as $user_id) {
if((int) $user_id == 0 || !isset($users_labels[$user_id])) continue;
$records[$x]['users'] .= '<br/>'.$users_labels[$user_id];
if(!empty($record['user_id'])) {
$names = array();
$users = explode(',', $record['user_id']);
foreach($users as $user_id) {
if(isset($users_labels[$user_id])) {
$names[] = $users_labels[$user_id];
}
}
sort($names);
$record['users'] = implode('<br/>', $names);
$record['user_list'] = implode('&nbsp;&bull; ', $names);
}
}
// add entries to template
$this->tpl->newTemplate('server_log_entries', 'server/log.tpl.html');
$this->tpl->addTemplateDataRepeat('server_log_entries', 'entries', $records);
$this->tpl->addTemplateData(
'server_log_entries',
array(
'logtitle' => $key,
)
);
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'content_' . $key => $this->tpl->getTemplate('server_log_entries'),
)
);
$tab_data['entries'] = $records;
$tpl_data['tabs'][] = $tab_data;
}
return $this->twig->render('module/server/log.tpl.html', $tpl_data);
}
/**
@ -115,11 +132,9 @@ class LogController extends AbstractServerController {
$entries = $this->db->query(
'SELECT '.
'`servers`.`label`, '.
'CONCAT_WS('.
'\':\','.
'`servers`.`ip`, '.
'`servers`.`port`'.
') AS `label_adv`, '.
'`servers`.`ip`, '.
'`servers`.`port`, '.
'`servers`.`type` AS server_type, '.
'`log`.`type`, '.
'`log`.`message`, '.
'`log`.`datetime`, '.
@ -133,25 +148,4 @@ class LogController extends AbstractServerController {
);
return $entries;
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'server_log'),
'label_status' => psm_get_lang('log', 'status'),
'label_email' => psm_get_lang('log', 'email'),
'label_sms' => psm_get_lang('log', 'sms'),
'label_title' => psm_get_lang('log', 'title'),
'label_server' => psm_get_lang('servers', 'server'),
'label_type' => psm_get_lang('log', 'type'),
'label_message' => psm_get_lang('system', 'message'),
'label_date' => psm_get_lang('system', 'date'),
'label_users' => ucfirst(psm_get_lang('menu', 'user')),
)
);
return parent::createHTMLLabels();
}
}

View File

@ -27,7 +27,6 @@
namespace psm\Module\Server\Controller;
use psm\Service\Database;
use psm\Service\Template;
/**
* Server module. Add/edit/delete servers, show a list of all servers etc.
@ -40,8 +39,8 @@ class ServerController extends AbstractServerController {
*/
protected $server_id;
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->server_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
@ -53,29 +52,32 @@ class ServerController extends AbstractServerController {
$this->setMinUserLevelRequiredForAction(PSM_USER_ADMIN, array(
'delete', 'edit', 'save'
));
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server'));
}
/**
* Prepare the template to show a list of all servers
*/
protected function executeIndex() {
$this->setTemplateId('server_list', 'server/server.tpl.html');
$sidebar = new \psm\Util\Module\Sidebar($this->tpl);
$tpl_data = $this->getLabels();
$tpl_data['user_level'] = $this->user->getUserLevel();
$sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar);
// check if user is admin, in that case we add the buttons
if($this->user->getUserLevel() == PSM_USER_ADMIN) {
$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'));
$sidebar->addButton(
'add_new',
psm_get_lang('system', 'add_new'),
psm_build_url(array('mod' => 'server', 'action' => 'edit')),
'plus icon-white', 'success'
);
// get the action buttons per server
$this->tpl->newTemplate('server_list_admin_actions', 'server/server.tpl.html');
$html_actions = $this->tpl->getTemplate('server_list_admin_actions');
} else {
$html_actions = '';
}
$sidebar->addButton(
@ -85,45 +87,65 @@ class ServerController extends AbstractServerController {
'refresh'
);
// we need an array for our template magic (see below):
$html_actions = array('html_actions' => $html_actions);
$icons = array(
'email' => 'icon-envelope',
'sms' => 'icon-mobile',
'pushover' => 'icon-pushover',
);
$servers = $this->getServers();
$server_count = count($servers);
for ($x = 0; $x < $server_count; $x++) {
// template magic: push the actions html to the front of the server array
// so the template handler will add it first. that way the other server vars
// will also be replaced in the html_actions template itself
$servers[$x] = $html_actions + $servers[$x];
$servers[$x]['class'] = ($x & 1) ? 'odd' : 'even';
if($servers[$x]['type'] == 'website') {
$servers[$x]['type_icon'] = 'icon-globe';
// add link to label
$servers[$x]['ip'] = '<a href="'.$servers[$x]['ip'].'" target="_blank">'.$servers[$x]['ip'].'</a>';
$ip = $servers[$x]['ip'];
if(!empty($servers[$x]['port']) && ($servers[$x]['port'] != 80)) {
$ip .= ' : ' . $servers[$x]['port'];
}
$servers[$x]['ip'] = '<a href="'.$servers[$x]['ip'].'" target="_blank">'.$ip.'</a>';
$servers[$x]['ip_short'] = $ip;
} else {
$servers[$x]['type_icon'] = 'icon-cog';
$servers[$x]['ip_short'] = $servers[$x]['ip'] . ' : ' . $servers[$x]['port'];
}
if(($servers[$x]['active'] == 'yes')) {
$servers[$x]['active_icon'] = 'icon-eye-open';
$servers[$x]['active_title'] = psm_get_lang('servers', 'monitoring');
foreach($icons as $i_id => $i_icon) {
if(psm_get_conf($i_id . '_status') && $servers[$x][$i_id] == 'yes') {
$servers[$x][$i_id . '_icon'] = $i_icon;
}
}
} else {
$servers[$x]['active_icon'] = 'icon-eye-close';
$servers[$x]['active_title'] = psm_get_lang('servers', 'no_monitoring');
}
$servers[$x] = $this->formatServer($servers[$x]);
}
// add servers to template
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $servers);
$tpl_data['servers'] = $servers;
return $this->twig->render('module/server/server/list.tpl.html', $tpl_data);
}
/**
* Prepare the template to show the update screen for a single server
*/
protected function executeEdit() {
$this->setTemplateId('server_update', 'server/server.tpl.html');
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : '';
$tpl_data = array(
// form url:
'url_save' => psm_build_url(array(
'mod' => 'server',
'action' => 'save',
'id' => $this->server_id,
'back_to' => $back_to,
)),
);
$tpl_data = $this->getLabels();
$tpl_data['edit_server_id'] = $this->server_id;
$tpl_data['url_save'] = psm_build_url(array(
'mod' => 'server',
'action' => 'save',
'id' => $this->server_id,
'back_to' => $back_to,
));
// depending on where the user came from, add the go back url:
if($back_to == 'view' && $this->server_id > 0) {
@ -132,85 +154,153 @@ class ServerController extends AbstractServerController {
$tpl_data['url_go_back'] = psm_build_url(array('mod' => 'server'));
}
$tpl_data['users'] = $this->db->select(PSM_DB_PREFIX.'users', null, array('user_id', 'name'), '', 'name');
switch($this->server_id) {
case 0:
// insert mode
$tpl_data['titlemode'] = psm_get_lang('system', 'insert');
$tpl_data['edit_server_id'] = '0';
$tpl_data['edit_value_warning_threshold'] = '1';
$edit_server = $_POST;
break;
default:
// edit mode
// get server entry
$edit_server = $this->getServers($this->server_id);
if (empty($edit_server)) {
$this->addMessage('Invalid server', 'error');
if(empty($edit_server)) {
$this->addMessage(psm_get_lang('servers', 'error_server_no_match'), 'error');
return $this->initializeAction('index');
}
$tpl_data['titlemode'] = psm_get_lang('system', 'edit') . ' ' . $edit_server['label'];
$tpl_data = array_merge($tpl_data, array(
'titlemode' => psm_get_lang('system', 'edit') . ' ' . $edit_server['label'],
'edit_server_id' => $edit_server['server_id'],
'edit_value_label' => $edit_server['label'],
'edit_value_ip' => $edit_server['ip'],
'edit_value_port' => $edit_server['port'],
'edit_value_pattern' => $edit_server['pattern'],
'edit_value_warning_threshold' => $edit_server['warning_threshold'],
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
'edit_active_selected_' . $edit_server['active'] => 'selected="selected"',
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"',
));
$user_idc_selected = $this->getServerUsers($this->server_id);
foreach($tpl_data['users'] as &$user) {
if(in_array($user['user_id'], $user_idc_selected)) {
$user['edit_selected'] = 'selected="selected"';
}
}
break;
}
$this->tpl->addTemplateData(
$this->getTemplateId(),
$tpl_data
);
if(!empty($edit_server)) {
// attempt to prefill previously posted fields
foreach($edit_server as $key => $value) {
$edit_server[$key] = psm_POST($key, $value);
}
$tpl_data = array_merge($tpl_data, array(
'edit_value_label' => $edit_server['label'],
'edit_value_ip' => $edit_server['ip'],
'edit_value_port' => $edit_server['port'],
'edit_value_timeout' => $edit_server['timeout'],
'default_value_timeout' => PSM_CURL_TIMEOUT,
'edit_value_pattern' => $edit_server['pattern'],
'edit_value_warning_threshold' => $edit_server['warning_threshold'],
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
'edit_active_selected_' . $edit_server['active'] => 'selected="selected"',
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"',
'edit_pushover_selected_' . $edit_server['pushover'] => 'selected="selected"',
));
}
$notifications = array('email', 'sms', 'pushover');
foreach($notifications as $notification) {
if(psm_get_conf($notification . '_status') == 0) {
$tpl_data['warning_' . $notification] = true;
$tpl_data['control_class_' . $notification] = 'warning';
$tpl_data['label_warning_' . $notification] = psm_get_lang(
'servers', 'warning_notifications_disabled_' . $notification
);
} else {
$tpl_data['warning_' . $notification] = false;
}
}
return $this->twig->render('module/server/server/update.tpl.html', $tpl_data);
}
/**
* Executes the saving of one of the servers
*/
protected function executeSave() {
// check for add/edit mode
if(isset($_POST['label']) && isset($_POST['ip']) && isset($_POST['port'])) {
$clean = array(
'label' => strip_tags($_POST['label']),
'ip' => strip_tags($_POST['ip']),
'port' => intval($_POST['port']),
'type' => in_array($_POST['type'], array('website', 'service')) ? $_POST['type'] : 'website',
'pattern' => $_POST['pattern'],
'warning_threshold' => intval($_POST['warning_threshold']),
'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',
);
if(empty($_POST)) {
// dont process anything if no data has been posted
return $this->executeIndex();
}
$clean = array(
'label' => trim(strip_tags(psm_POST('label', ''))),
'ip' => trim(strip_tags(psm_POST('ip', ''))),
'timeout' => (isset($_POST['timeout']) && intval($_POST['timeout']) > 0) ? intval($_POST['timeout']) : null,
'port' => intval(psm_POST('port', 0)),
'type' => psm_POST('type', ''),
'pattern' => psm_POST('pattern', ''),
'warning_threshold' => intval(psm_POST('warning_threshold', 0)),
'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',
'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no',
);
// make sure websites start with http://
if($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http') {
$clean['ip'] = 'http://' . $clean['ip'];
}
// check for edit or add
// validate the lot
$server_validator = new \psm\Util\Server\ServerValidator($this->db);
try {
if($this->server_id > 0) {
// edit
$this->db->save(
PSM_DB_PREFIX.'servers',
$clean,
array('server_id' => $this->server_id)
);
$this->addMessage(psm_get_lang('servers', 'updated'), 'success');
} else {
// add
$clean['status'] = 'on';
$this->server_id = $this->db->save(PSM_DB_PREFIX.'servers', $clean);
$this->addMessage(psm_get_lang('servers', 'inserted'), 'success');
$server_validator->serverId($this->server_id);
}
$server_validator->label($clean['label']);
$server_validator->type($clean['type']);
$server_validator->ip($clean['ip'], $clean['type']);
$server_validator->warningThreshold($clean['warning_threshold']);
} catch(\InvalidArgumentException $ex) {
$this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error');
return $this->executeEdit();
}
// check for edit or add
if($this->server_id > 0) {
// edit
$this->db->save(
PSM_DB_PREFIX.'servers',
$clean,
array('server_id' => $this->server_id)
);
$this->addMessage(psm_get_lang('servers', 'updated'), 'success');
} else {
// add
$clean['status'] = 'on';
$this->server_id = $this->db->save(PSM_DB_PREFIX.'servers', $clean);
$this->addMessage(psm_get_lang('servers', 'inserted'), 'success');
}
// update users
$user_idc = psm_POST('user_id', array());
$user_idc_save = array();
foreach($user_idc as $user_id) {
$user_idc_save[] = array(
'user_id' => intval($user_id),
'server_id' => intval($this->server_id),
);
}
$this->db->delete(PSM_DB_PREFIX.'users_servers', array('server_id' => $this->server_id));
if(!empty($user_idc_save)) {
// add all new users
$this->db->insertMultiple(PSM_DB_PREFIX.'users_servers', $user_idc_save);
}
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : 'index';
if($back_to == 'view') {
$this->initializeAction('view');
return $this->initializeAction('view');
} else {
$this->initializeAction('index');
return $this->initializeAction('index');
}
}
@ -229,9 +319,9 @@ class ServerController extends AbstractServerController {
$this->db->delete(PSM_DB_PREFIX.'servers_uptime', array('server_id' => $id));
$this->db->delete(PSM_DB_PREFIX.'servers_history', array('server_id' => $id));
}
$this->addMessage(psm_get_lang('system', 'deleted'), 'success');
$this->addMessage(psm_get_lang('servers', 'deleted'), 'success');
}
$this->initializeAction('index');
return $this->initializeAction('index');
}
/**
@ -247,35 +337,37 @@ class ServerController extends AbstractServerController {
return $this->initializeAction('index');
}
$this->setTemplateId('server_view', 'server/view.tpl.html');
$tpl_data = $this->formatServer($server);
$tpl_data = $this->getLabels();
$tpl_data = array_merge($tpl_data, $this->formatServer($server));
// create history HTML
$history = new \psm\Util\Server\HistoryGraph($this->db, $this->tpl);
$history = new \psm\Util\Server\HistoryGraph($this->db, $this->twig);
$tpl_data['html_history'] = $history->createHTML($this->server_id);
// add edit/delete buttons for admins
if($this->user->getUserLevel() == PSM_USER_ADMIN) {
$tpl_id_actions = 'server_view_admin_actions';
$this->tpl->newTemplate($tpl_id_actions, 'server/view.tpl.html');
$tpl_data['html_actions'] = $this->tpl->getTemplate($tpl_id_actions);
$tpl_data['has_admin_actions'] = true;
$tpl_data['url_edit'] = psm_build_url(array('mod' => 'server', 'action' => 'edit', 'id' => $this->server_id, 'back_to' => 'view'));
$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'));
}
// add all available servers to the menu
$servers = $this->getServers();
$options = array();
$tpl_data['options'] = array();
foreach($servers as $i => $server_available) {
$options[] = array(
$tpl_data['options'][] = array(
'class_active' => ($server_available['server_id'] == $this->server_id) ? 'active' : '',
'url' => psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server_available['server_id'])),
'label' => $server_available['label'],
);
}
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'options', $options);
$sidebar = new \psm\Util\Module\Sidebar($this->tpl);
$sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar);
// check which module the user came from, and add a link accordingly
@ -287,44 +379,61 @@ class ServerController extends AbstractServerController {
'th-list'
);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
return $this->twig->render('module/server/server/view.tpl.html', $tpl_data);
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'server'),
'label_label' => psm_get_lang('servers', 'label'),
'label_status' => psm_get_lang('menu', 'server_status'),
'label_domain' => psm_get_lang('servers', 'domain'),
'label_port' => psm_get_lang('servers', 'port'),
'label_type' => psm_get_lang('servers', 'type'),
'label_website' => psm_get_lang('servers', 'type_website'),
'label_service' => psm_get_lang('servers', 'type_service'),
'label_type' => psm_get_lang('servers', 'type'),
'label_pattern' => psm_get_lang('servers', 'pattern'),
'label_pattern_description' => psm_get_lang('servers', 'pattern_description'),
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_rtime' => psm_get_lang('servers', 'latency'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_monitoring' => psm_get_lang('servers', 'monitoring'),
'label_send_email' => psm_get_lang('servers', 'send_email'),
'label_send_sms' => psm_get_lang('servers', 'send_sms'),
'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'),
'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'),
'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),
'label_edit' => psm_get_lang('system', 'edit'),
'label_delete' => psm_get_lang('system', 'delete'),
'label_yes' => psm_get_lang('system', 'yes'),
'label_no' => psm_get_lang('system', 'no'),
'label_add_new' => psm_get_lang('system', 'add_new'),
)
protected function getLabels() {
return array(
'label_label' => psm_get_lang('servers', 'label'),
'label_status' => psm_get_lang('servers', 'status'),
'label_domain' => psm_get_lang('servers', 'domain'),
'label_timeout' => psm_get_lang('servers', 'timeout'),
'label_timeout_description' => psm_get_lang('servers', 'timeout_description'),
'label_port' => psm_get_lang('servers', 'port'),
'label_type' => psm_get_lang('servers', 'type'),
'label_website' => psm_get_lang('servers', 'type_website'),
'label_service' => psm_get_lang('servers', 'type_service'),
'label_type' => psm_get_lang('servers', 'type'),
'label_pattern' => psm_get_lang('servers', 'pattern'),
'label_pattern_description' => psm_get_lang('servers', 'pattern_description'),
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_rtime' => psm_get_lang('servers', 'latency'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_monitoring' => psm_get_lang('servers', 'monitoring'),
'label_email' => psm_get_lang('servers', 'email'),
'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_pushover' => psm_get_lang('servers', 'pushover'),
'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_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),
'label_edit' => psm_get_lang('system', 'edit'),
'label_delete' => psm_get_lang('system', 'delete'),
'label_yes' => psm_get_lang('system', 'yes'),
'label_no' => psm_get_lang('system', 'no'),
'label_add_new' => psm_get_lang('system', 'add_new'),
);
}
return parent::createHTMLLabels();
/**
* Get all user ids for a server
* @param int $server_id
* @return array with ids only
*/
protected function getServerUsers($server_id) {
$users = $this->db->select(
PSM_DB_PREFIX.'users_servers',
array('server_id' => $server_id),
array('user_id')
);
$result = array();
foreach($users as $user) {
$result[] = $user['user_id'];
}
return $result;
}
}

View File

@ -28,17 +28,16 @@
namespace psm\Module\Server\Controller;
use psm\Service\Database;
use psm\Service\Template;
/**
* Status module
*/
class StatusController extends AbstractServerController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setActions(array('index'), 'index');
$this->setActions(array('index', 'saveLayout'), 'index');
}
/**
@ -46,14 +45,28 @@ class StatusController extends AbstractServerController {
* @todo move the background colurs to the config
*/
protected function executeIndex() {
$this->setTemplateId('server_status', 'server/status.tpl.html');
// set background color to black
$this->black_background = true;
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_status'));
// add header accessories
$layout = $this->user->getUserPref('status_layout', 0);
$layout_data = array(
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_rtime' => psm_get_lang('servers', 'latency'),
'block_layout_active' => ($layout == 0) ? 'active' : '',
'list_layout_active' => ($layout != 0) ? 'active' : '',
);
$this->setHeaderAccessories($this->twig->render('module/server/status/header.tpl.html', $layout_data));
$this->addFooter(false);
// get the active servers from database
$servers = $this->getServers();
$offline = array();
$online = array();
$layout_data['servers_offline'] = array();
$layout_data['servers_online'] = array();
foreach ($servers as $server) {
if($server['active'] == 'no') {
@ -64,40 +77,33 @@ class StatusController extends AbstractServerController {
$server['url_view'] = psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server['server_id'], 'back_to' => 'server_status'));
if ($server['status'] == "off") {
$offline[$server['server_id']] = $server;
$layout_data['servers_offline'][] = $server;
} elseif($server['warning_threshold_counter'] > 0) {
$server['class_warning'] = 'warning';
$offline[$server['server_id']] = $server;
$layout_data['servers_offline'][] = $server;
} else {
$online[$server['server_id']] = $server;
$layout_data['servers_online'][] = $server;
}
}
// add servers to template
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers_offline', $offline);
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers_online', $online);
// check if we need to add the auto refresh
$auto_refresh = psm_get_conf('auto_refresh_servers');
if(intval($auto_refresh) > 0) {
// add it
$this->tpl->newTemplate('main_auto_refresh', 'main.tpl.html');
$this->tpl->addTemplateData('main_auto_refresh', array('seconds' => $auto_refresh));
$this->tpl->addTemplateData('main', array('auto_refresh' => $this->tpl->getTemplate('main_auto_refresh')));
$auto_refresh_seconds = psm_get_conf('auto_refresh_servers');
if(intval($auto_refresh_seconds) > 0) {
$this->twig->addGlobal('auto_refresh', true);
$this->twig->addGlobal('auto_refresh_seconds', $auto_refresh_seconds);
}
return $this->twig->render('module/server/status/index.tpl.html', $layout_data);
}
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'server_status'),
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_rtime' => psm_get_lang('servers', 'latency'),
)
);
protected function executeSaveLayout() {
if($this->isXHR()) {
$layout = psm_POST('layout', 0);
$this->user->setUserPref('status_layout', $layout);
return parent::createHTMLLabels();
$response = new \Symfony\Component\HttpFoundation\JsonResponse();
$response->setData(array(
'layout' => $layout,
));
return $response;
}
}
}

View File

@ -30,18 +30,17 @@
namespace psm\Module\Server\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
class UpdateController extends AbstractController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setActions('index', 'index');
}
protected function executeIndex() {
$autorun = new \psm\Util\Updater\Autorun($this->db);
$autorun = new \psm\Util\Server\UpdateManager($this->db);
$autorun->setUser($this->user);
$autorun->run();

View File

@ -29,12 +29,11 @@
namespace psm\Module\User\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
class LoginController extends AbstractController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
@ -46,8 +45,6 @@ class LoginController extends AbstractController {
}
protected function executeLogin() {
$this->setTemplateId('user_login', 'user/login.tpl.html');
if(isset($_POST['user_name']) && isset($_POST['user_password'])) {
$rememberme = (isset($_POST['user_rememberme'])) ? true : false;
$result = $this->user->loginWithPostData(
@ -58,7 +55,7 @@ class LoginController extends AbstractController {
if($result) {
// success login, redirect
header('Location: ' . $_SERVER['REQUEST_URI']);
header('Location: ' . psm_build_url($_SERVER['QUERY_STRING']));
die();
} else {
$this->addMessage(psm_get_lang('login', 'error_login_incorrect'), 'error');
@ -76,15 +73,15 @@ class LoginController extends AbstractController {
'value_rememberme' => (isset($rememberme) && $rememberme) ? 'checked="checked"' : '',
);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
return $this->twig->render('module/user/login/login.tpl.html', $tpl_data);
}
/**
* Show/process the password forgot form (before the mail)
*
* @return string
*/
protected function executeForgot() {
$this->setTemplateId('user_login_forgot', 'user/login.tpl.html');
if(isset($_POST['user_name'])) {
$user = $this->user->getUserByUsername($_POST['user_name']);
@ -110,16 +107,13 @@ class LoginController extends AbstractController {
'label_submit' => psm_get_lang('login', 'submit'),
'label_go_back' => psm_get_lang('system', 'go_back'),
);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
return $this->twig->render('module/user/login/forgot.tpl.html', $tpl_data);
}
/**
* Show/process the password reset form (after the mail)
*/
protected function executeReset() {
$this->setTemplateId('user_login_reset', 'user/login.tpl.html');
$user_id = (isset($_GET['user_id'])) ? intval($_GET['user_id']) : 0;
$token = (isset($_GET['token'])) ? $_GET['token'] : '';
@ -153,8 +147,7 @@ class LoginController extends AbstractController {
'label_go_back' => psm_get_lang('system', 'go_back'),
'value_user_name' => $user->user_name,
);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
return $this->twig->render('module/user/login/reset.tpl.html', $tpl_data);
}
/**

View File

@ -28,7 +28,6 @@
namespace psm\Module\User\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
class ProfileController extends AbstractController {
@ -36,10 +35,10 @@ class ProfileController extends AbstractController {
* Editable fields for the profile
* @var array $profile_fields
*/
protected $profile_fields = array('name', 'user_name', 'mobile', 'email');
protected $profile_fields = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'email');
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setActions(array(
'index', 'save',
@ -48,13 +47,26 @@ class ProfileController extends AbstractController {
/**
* Show the profile page
* @return string
*/
protected function executeIndex() {
$this->setTemplateId('user_profile', 'user/profile.tpl.html');
$this->twig->addGlobal('subtitle', psm_get_lang('users', 'profile'));
$user = $this->user->getUser(null, true);
$tpl_data = array(
'label_name' => psm_get_lang('users', 'name'),
'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password' => psm_get_lang('users', 'password'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'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_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'),
'form_action' => psm_build_url(array(
'mod' => 'user_profile',
'action' => 'save',
@ -65,7 +77,7 @@ class ProfileController extends AbstractController {
foreach($this->profile_fields as $field) {
$tpl_data[$field] = (isset($user->$field)) ? $user->$field : '';
}
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
return $this->twig->render('module/user/profile.tpl.html', $tpl_data);
}
/**
@ -119,24 +131,4 @@ class ProfileController extends AbstractController {
return $this->executeIndex();
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('users', 'profile'),
'label_name' => psm_get_lang('users', 'name'),
'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password' => psm_get_lang('users', 'password'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'),
)
);
return parent::createHTMLLabels();
}
}
}

View File

@ -28,7 +28,6 @@
namespace psm\Module\User\Controller;
use psm\Module\AbstractController;
use psm\Service\Database;
use psm\Service\Template;
/**
* User module. Add, edit and delete users, or assign
@ -43,14 +42,15 @@ class UserController extends AbstractController {
*/
protected $user_validator;
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ADMIN);
$this->setActions(array(
'index', 'edit', 'delete', 'save',
), 'index');
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'user'));
}
public function initialize() {
@ -65,11 +65,12 @@ class UserController extends AbstractController {
}
/**
* Prepare the template to show a list of all users
* Create HTML to show a list of all users
*
* @return string
*/
protected function executeIndex() {
$this->setTemplateId('user_list', 'user/user.tpl.html');
$sidebar = new \psm\Util\Module\Sidebar($this->tpl);
$sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar);
$sidebar->addButton(
@ -79,6 +80,12 @@ class UserController extends AbstractController {
'plus icon-white', 'success'
);
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal);
$modal->setTitle(psm_get_lang('users', 'delete_title'));
$modal->setMessage(psm_get_lang('users', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
// build label array for the next loop
$servers_labels = array();
foreach ($this->servers as $server) {
@ -88,7 +95,7 @@ class UserController extends AbstractController {
$users = $this->db->select(
PSM_DB_PREFIX.'users',
null,
array('user_id', 'user_name', 'level', 'name', 'mobile', 'email'),
array('user_id', 'user_name', 'level', 'name', 'mobile', 'pushover_key', 'pushover_device', 'email'),
null,
array('name')
);
@ -96,26 +103,43 @@ class UserController extends AbstractController {
foreach($users as $x => &$user) {
$user_servers = $this->getUserServers($user['user_id']);
$user['class'] = ($x & 1) ? 'odd' : 'even';
$user['level_text'] = psm_get_lang('users', 'level_' . $user['level']);
$user['emp_servers'] = '';
$user['emp_servers'] = array();
// fix server list
foreach($user_servers as $server_id) {
if (!isset($servers_labels[$server_id])) continue;
$user['emp_servers'] .= $servers_labels[$server_id] . '<br/>';
$user['emp_servers'][] = array(
'label' => $servers_labels[$server_id]
);
}
$user['emp_servers'] = substr($user['emp_servers'], 0, -5);
$user['url_delete'] = psm_build_url(array(
'mod' => 'user',
'action' => 'delete',
'id' => $user['user_id'],
));
$user['url_edit'] = psm_build_url(array(
'mod' => 'user',
'action' => 'edit',
'id' => $user['user_id'],
));
}
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'users', $users);
$tpl_data = $this->getLabels();
$tpl_data['users'] = $users;
return $this->twig->render('module/user/user/list.tpl.html', $tpl_data);
}
/**
* Prepare the template to show the update screen for a user
* Crate HTML for the update screen for a user
*
* @return string
*/
protected function executeEdit() {
$this->setTemplateId('user_update', 'user/user.tpl.html');
$user_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$fields_prefill = array('name', 'user_name', 'mobile', 'email');
$fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'email');
if($user_id == 0) {
// insert mode
@ -151,7 +175,7 @@ class UserController extends AbstractController {
foreach($this->servers as &$server) {
if(in_array($server['server_id'], $user_servers)) {
$server['edit_checked'] = 'checked="checked"';
$server['edit_selected'] = 'selected="selected"';
$server['class'] = 'active';
}
}
@ -160,6 +184,13 @@ class UserController extends AbstractController {
'titlemode' => $title,
'placeholder_password' => $placeholder_password,
'edit_user_id' => $user_id,
'url_save' => psm_build_url(array(
'mod' => 'user',
'action' => 'save',
'id' => $user_id,
)),
'servers' => $this->servers,
'user_level' => $lvl_selected,
);
foreach($fields_prefill as $field) {
if(isset($edit_user->$field)) {
@ -167,17 +198,17 @@ class UserController extends AbstractController {
}
}
$ulvls_tpl = array();
$tpl_data['levels'] = array();
foreach($this->user_validator->getUserLevels() as $lvl) {
$ulvls_tpl[] = array(
$tpl_data['levels'][] = array(
'value' => $lvl,
'label' => psm_get_lang('users', 'level_' . $lvl),
'selected' => ($lvl == $lvl_selected) ? 'selected="selected"' : '',
);
}
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'levels', $ulvls_tpl);
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $this->servers);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
$tpl_data = array_merge($this->getLabels(), $tpl_data);
return $this->twig->render('module/user/user/update.tpl.html', $tpl_data);
}
/**
@ -190,7 +221,7 @@ class UserController extends AbstractController {
}
$user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
$fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'email');
$fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'email');
$clean = array();
foreach($fields as $field) {
if(isset($_POST[$field])) {
@ -221,15 +252,16 @@ class UserController extends AbstractController {
if(!empty($clean['password'])) {
$password = $clean['password'];
}
unset($clean['password']);
unset($clean['password_repeat']);
if($user_id > 0) {
// edit user
unset($clean['password']); // password update is executed separately
$this->db->save(PSM_DB_PREFIX.'users', $clean, array('user_id' => $user_id));
$this->addMessage(psm_get_lang('users', 'updated'), 'success');
} else {
// add user
$clean['password'] = ''; // password update is executed separately
$user_id = $this->db->save(PSM_DB_PREFIX.'users', $clean);
$this->addMessage(psm_get_lang('users', 'inserted'), 'success');
}
@ -268,7 +300,7 @@ class UserController extends AbstractController {
$this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,));
$this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $id));
$this->addMessage(psm_get_lang('system', 'deleted'), 'success');
$this->addMessage(psm_get_lang('users', 'deleted'), 'success');
} catch(\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
}
@ -276,34 +308,31 @@ class UserController extends AbstractController {
return $this->executeIndex();
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'user'),
'label_users' => psm_get_lang('menu', 'users'),
'label_name' => psm_get_lang('users', 'name'),
'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password' => psm_get_lang('users', 'password'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'),
'label_level_10' => psm_get_lang('users', 'level_10'),
'label_level_20' => psm_get_lang('users', 'level_20'),
'label_level_description' => psm_get_lang('users', 'level_description'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'label_email' => psm_get_lang('users', 'email'),
'label_servers' => psm_get_lang('menu', 'server'),
'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),
'label_edit' => psm_get_lang('system', 'edit') . ' ' . psm_get_lang('users', 'user'),
'label_delete' => psm_get_lang('system', 'delete') . ' ' . psm_get_lang('users', 'user'),
'label_add_new' => psm_get_lang('system', 'add_new'),
)
protected function getLabels() {
return array(
'label_users' => psm_get_lang('menu', 'users'),
'label_user' => psm_get_lang('users', 'user'),
'label_name' => psm_get_lang('users', 'name'),
'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password' => psm_get_lang('users', 'password'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'),
'label_level_description' => psm_get_lang('users', 'level_description'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'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_email' => psm_get_lang('users', 'email'),
'label_servers' => psm_get_lang('menu', 'server'),
'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),
'label_edit' => psm_get_lang('system', 'edit'),
'label_delete' => psm_get_lang('system', 'delete'),
'label_add_new' => psm_get_lang('system', 'add_new'),
);
return parent::createHTMLLabels();
}
/**

View File

@ -27,6 +27,7 @@
**/
namespace psm;
use Symfony\Component\HttpFoundation\Response;
/**
* The router class opens the controller and initializes the module.
@ -63,9 +64,14 @@ class Router {
public function __construct() {
global $db;
$this->services['db'] = $db;
$this->services['tpl'] = new \psm\Service\Template();
$this->services['user'] = new \psm\Service\User($db);
$loader = new \Twig_Loader_Filesystem(PSM_PATH_TPL . PSM_THEME);
$this->services['twig'] = new \Twig_Environment($loader);
if(PSM_DEBUG) {
$this->services['twig']->enableDebug();
}
$modules = $this->getModules();
foreach($modules as $id => $module) {
@ -82,6 +88,7 @@ class Router {
public function getModules() {
return array(
'config' => new Module\Config\ConfigModule(),
'error' => new Module\Error\ErrorModule(),
'server' => new Module\Server\ServerModule(),
'user' => new Module\User\UserModule(),
'install' => new Module\Install\InstallModule(),
@ -97,8 +104,16 @@ class Router {
* If no mod is given it will attempt to load the default module.
* @param string $mod if empty, the mod getvar will be used, or fallback to default
* @throws \InvalidArgumentException
* @throws \LogicException
*/
public function run($mod = null) {
if(!psm_is_cli() && isset($_GET["logout"])) {
$this->services['user']->doLogout();
// logged out, redirect to login
header('Location: ' . psm_build_url());
die();
}
if($mod === null) {
$mod = psm_GET('mod', $this->default_module);
}
@ -113,21 +128,25 @@ class Router {
}
// get min required level for this controller and make sure the user matches
$min_lvl = $controller->getMinUserLevelRequired();
$action = null;
if($min_lvl < PSM_USER_ANONYMOUS) {
// if user is not logged in, load login module
if(!$this->services['user']->isUserLoggedIn()) {
// redirect to login
$controller = $this->getController('user_login');
} elseif($this->services['user']->getUserLevel() > $min_lvl) {
// @todo perhaps show a nice permission denied page
die('You do not have the privileges to view this page.');
$controller = $this->getController('error');
$action = '401';
}
}
$controller->setUser($this->services['user']);
// let the module prepare it's HTML code
$controller->initialize();
$response = $controller->initialize($action);
if(!($response instanceof Response)) {
throw new \LogicException('Controller did not return a Response object.');
}
$response->send();
}
/**
@ -142,7 +161,7 @@ class Router {
if($controller === false) {
throw new \InvalidArgumentException('Controller is not registered');
}
$controller = new $controller($this->services['db'], $this->services['tpl']);
$controller = new $controller($this->services['db'], $this->services['twig']);
if(!$controller instanceof \psm\Module\ControllerInterface) {
throw new \Exception('Controller does not use ControllerInterface');

View File

@ -77,9 +77,9 @@ class Database {
* Constructor
*
* @param string $host
* @param string $db
* @param string $user
* @param string $pass
* @param string $db
*/
function __construct($host = null, $user = null, $pass = null, $db = null) {
if($host != null && $user != null && $pass != null && $db != null) {
@ -151,6 +151,29 @@ class Database {
return $this->last;
}
/**
* Prepare and execute SQL statement with parameters
* @param string $query SQL statement
* @param Array $parameters An array of values with as many elements as there are bound parameters in the SQL statement
* @param boolean $fetch automatically fetch results, or return PDOStatement?
* @return @return array|\PDOStatement if $fetch = true, array, otherwise \PDOStatement
*/
public function execute($query, $parameters, $fetch = true) {
try {
$this->last = $this->pdo()->prepare($query);
$this->last->execute($parameters);
} catch (\PDOException $e) {
$this->error($e);
}
if($fetch && $this->last != false) {
$result = $this->last->fetchAll(\PDO::FETCH_ASSOC);
} else {
$result = $this->last;
}
return $result;
}
/**
* Performs a select on the given table and returns an multi dimensional associative array with results
* @param string $table tablename

View File

@ -1,283 +0,0 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
namespace psm\Service;
class Template {
/**
* Loaded templates
* @var array $templates
*/
protected $templates = array();
/**
* Cache of parsed files
* @var array $files_parsed
* @see parseFile()
*/
protected $files_parsed = array();
function __construct() {
// add the main template
$this->newTemplate('main', 'main.tpl.html');
}
/**
* Add template
*
* @param string $id template id used in the tpl file (<!--%tpl_ID-->html<!--%%tpl_ID-->)
* @param string $filename path to template file, or if file is located in the default template dir just the filename
* @return mixed false if template cannot be found, html code on success
*/
public function newTemplate($id, $filename) {
if (file_exists($filename)) {
$this->templates[$id] = $this->parseFile($filename);
} elseif (file_exists(PSM_PATH_TPL.$filename)) {
$this->templates[$id] = $this->parseFile(PSM_PATH_TPL.$filename);
} else {
// file does not exist
trigger_error('Template not found with id: '.$id.' and filename: '.$filename);
return false;
}
$use_tpl = null;
// only get data from the file that's between the tpl id tags with this id
// find "tpl_{$row_id}" in the current template
//preg_match_all('{<!--%(.+?)-->(.*?)<!--%%\\1-->}is', $this->templates[$id], $matches);
preg_match_all("{<!--%tpl_{$id}-->(.*?)<!--%%tpl_{$id}-->}is", $this->templates[$id], $matches);
// no repeat tpl found? skip to next one
if (empty($matches)) return false;
// check if the row_id is in one of the matches (aka whether the supplied row id actually has a template in this file)
if (isset($matches[1][0])) {
$use_tpl = $matches[1][0];
}
// no template with the given id found..
if ($use_tpl === null) return false;
// remove tpl code tags from original template so it won't be in the source
$this->templates[$id] = preg_replace("{<!--%tpl_".$id."-->(.*?)<!--%%tpl_".$id."-->}is", "", $use_tpl);
return $this->templates[$id];
}
/**
* Add data to the template
*
* @param string $tpl_id template_id used by add_template()
* @param array $data
* @param boolean $use_html if true, $tpl_id is considered to be HTML code and used rather than a template
* @return string new template
*/
public function addTemplateData($tpl_id, $data, $use_html = false) {
if($use_html) {
// no template
$source = $tpl_id;
} else {
// does the template exist?
if (!isset($this->templates[$tpl_id])) {
// file does not exist
trigger_error("Template '{$tpl_id}' could not be found", E_USER_WARNING);
return false;
}
$source =& $this->templates[$tpl_id];
}
foreach($data as $key => $value) {
if(is_array($value)) {
$subdata = array();
foreach($value as $k => $v) {
$subdata[$key.'_'.$k] = $v;
}
$source = $this->addTemplateData($source, $subdata, true);
} else {
$source = str_replace('{'.$key.'}', $value, $source);
}
}
return $source;
}
/**
* Add repeat rows to template.
* It's possible to create a nested repeat tpl. All you need to do is to create a subarray
* For example:
* $data = array(
* 0 => array(
* 'name' => 'Test',
* 'subdata' => array(
* 0 => array(
* 'name' => 'Subtest 1',
* ),
* 1 => array(...)
* ),
* ),
* );
* In your template you would literally put the nested repeat inside the first repeat.
* If you have more than 1 nested array, the first subtemplate will be used for all others.
*
* @param string $id template id used by add_template() or html code in case of repeat-repeat tpl
* @param string $repeat_id ID used in template file for the repeat template: <!--%tpl_repeat_ID-->html<!--%%tpl_repeat_ID-->
* @param array $data
* @param boolean $use_html can only be used from within this function for recursive repeat templating. in this case the $id is the html code
* @param int $level starts off with 0. if level=2, current repeat template will be used again for subs, so you can go all the way
* @param int $level_reuse_prev from what level should we start repeating the current template for more subrecords, so we can go all the way?
* @return mixed false if repeat template cannot be found, html code on success
*/
public function addTemplateDataRepeat($tpl_id, $repeat_id, $data, $use_html = false, $level = 0, $level_reuse_prev = 2) {
if($use_html) {
$source = $tpl_id;
} else {
// does the template exist?
if (!isset($this->templates[$tpl_id])) {
// file does not exist
trigger_error("Template '{$tpl_id}' could not be found", E_USER_WARNING);
return false;
}
$source =& $this->templates[$tpl_id];
}
if($level < $level_reuse_prev) {
// find "tpl_repeat_{$repeat_id}_" in the current template
preg_match_all("{<!--%tpl_repeat_{$repeat_id}-->(.*?)<!--%%tpl_repeat_{$repeat_id}-->}is", $source, $matches);
// check if the repeat_id is in one of the matches
if (isset($matches[1][0])) {
$use_tpl = $matches[1][0];
} else {
// if we didn't find a repeat template for the repeat_id supplied, skip the rest..
return false;
}
// remove repeat tpl code from original template so it won't be in the source
$source = preg_replace("{<!--%tpl_repeat_".$repeat_id."-->(.*?)<!--%%tpl_repeat_".$repeat_id."-->}is", "", $source);
} else {
$use_tpl = $source;
}
// now lets go through all the records supplied and put them in the HTML repeat code we just found
$result = '';
foreach($data as $record) {
$tmp_string = $use_tpl;
if(!is_array($record)) {
$record = array(
'value' => $record,
);
}
// multi dim array
foreach($record as $k => $v) {
if(is_array($v)) {
// nested repeat
if(isset($v[0]) && is_array($v[0])) {
// repeat template in a repeat template
$repeat_html = $this->addTemplateDataRepeat($use_tpl, $k, $v, true, ($level + 1), $level_reuse_prev);
$tmp_string = str_replace('{'.$k.'}', $repeat_html, $tmp_string);
} else {
foreach($v as $vk => $vv) {
$tmp_string = str_replace('{'.$k.'_'.$vk.'}', $vv, $tmp_string);
}
}
} else {
$tmp_string = str_replace('{'.$k.'}', $v, $tmp_string);
}
}
$result .= $tmp_string.PHP_EOL;
}
if($use_html === false) {
// add to main template..
return $this->addTemplateData($tpl_id, array($repeat_id => $result));
} else {
return $result;
}
}
public function display($id) {
// check if there are any unused tpl_repeat templates, and if there are remove them
$result = preg_replace('{<!--%(.+?)-->(.*?)<!--%%\\1-->}is', '', $this->templates[$id]);
// check for tpl variables that have not been replaced. ie: {name}. ignore literal stuff, though. ie: {{name}} is {name} and should not be removed
preg_match_all('~{?{(\w+?)}}?~', $result, $matches);
foreach($matches[0] as $match) {
if (substr($match, 0, 2) == '{{') {
// literal! remove only first and last bracket!
$result = str_replace($match, substr($match, 1, -1), $result);
} else {
// unused variable, remove completely
$result = str_replace($match, '', $result);
}
}
return $result;
}
/**
* Get html code for a template, or if no template id given get all templates
*
* @param string $template_id
* @return mixed string when ID given, else array
*/
public function getTemplate($template_id = null) {
if ($template_id === null) {
return $this->templates;
} elseif (isset($this->templates[$template_id])) {
return $this->templates[$template_id];
} else {
return false;
}
}
/**
*
* Get file content
*
* @param string $filename filename
* @return string file contents
*/
protected function parseFile($filename) {
if (!file_exists($filename)) return false;
if(isset($this->files_parsed[$filename])) {
return $this->files_parsed[$filename];
}
ob_start();
include($filename);
$file_content = ob_get_contents();
ob_end_clean();
$this->files_parsed[$filename] = $file_content;
return $file_content;
}
}

View File

@ -28,10 +28,14 @@
**/
namespace psm\Service;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
/**
* This is a heavily modified version of the php-login-advanced project by Panique.
*
* It uses the Session classes from the Symfony HttpFoundation component.
*
* @author Panique
* @author Pepijn Over
* @link http://www.php-login.net
@ -52,44 +56,55 @@ class User {
*/
protected $user_data = array();
/**
* Session object
* @var \Symfony\Component\HttpFoundation\Session\Session $session
*/
protected $session;
/**
* Current user id
* @var int $user_id
*/
protected $user_id;
/**
/**
*Current user preferences
* @var array $user_preferences
*/
protected $user_preferences;
/**
* The user's login status
* @var boolean $user_is_logged_in
*/
protected $user_is_logged_in = false;
/**
* the function "__construct()" automatically starts whenever an object of this class is created,
* you know, when you do "$login = new Login();"
* Open a new user service
*
* @param \psm\Service\Database $db
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session if NULL, one will be created
*/
public function __construct(Database $db) {
public function __construct(Database $db, SessionInterface $session = null) {
$this->db_connection = $db->pdo();
if(php_sapi_name() != 'cli' && (!defined('PSM_INSTALL') || !PSM_INSTALL)) {
if(!$this->isSessionStarted()) {
session_start();
if(!psm_is_cli()) {
if($session == null) {
$session = new Session();
$session->start();
}
// check the possible login actions:
// 1. login via session data (happens each time user opens a page on your php project AFTER he has successfully logged in via the login form)
// 2. login via cookie
// 3. logout (happen when user clicks logout button)
$this->session = $session;
// if user has an active session on the server
if(!$this->loginWithSessionData()) {
$this->loginWithCookieData();
}
if((!defined('PSM_INSTALL') || !PSM_INSTALL)) {
// check the possible login actions:
// 1. login via session data (happens each time user opens a page on your php project AFTER he has successfully logged in via the login form)
// 2. login via cookie
if(isset($_GET["logout"])) {
$this->doLogout();
// logged out, redirect to login
header('Location: ' . psm_build_url());
die();
// if user has an active session on the server
if(!$this->loginWithSessionData()) {
$this->loginWithCookieData();
}
}
}
}
@ -133,13 +148,15 @@ class User {
}
/**
* Logs in with S_SESSION data.
* Logs in with SESSION data.
*
* @return boolean
*/
private function loginWithSessionData() {
if(empty($_SESSION) || !isset($_SESSION['user_id'])) {
protected function loginWithSessionData() {
if(!$this->session->has('user_id')) {
return false;
}
$user = $this->getUser($_SESSION['user_id']);
$user = $this->getUser($this->session->get('user_id'));
if(!empty($user)) {
$this->setUserLoggedIn($user->user_id);
@ -161,7 +178,7 @@ class User {
// extract data from the cookie
list ($user_id, $token, $hash) = explode(':', $_COOKIE['rememberme']);
// check cookie hash validity
if ($hash == hash('sha256', $user_id . ':' . $token . PSM_LOGIN_COOKIE_SECRET_KEY) && !empty($token)) {
if($hash == hash('sha256', $user_id . ':' . $token . PSM_LOGIN_COOKIE_SECRET_KEY) && !empty($token)) {
// cookie looks good, try to select corresponding user
// get real token from database (and all other data)
$user = $this->getUser($user_id);
@ -200,14 +217,14 @@ class User {
if(!isset($user->user_id)) {
password_verify($user_password, 'dummy_call_against_timing');
return false;
} else if (! password_verify($user_password, $user->password)) {
} else if(!password_verify($user_password, $user->password)) {
return false;
}
$this->setUserLoggedIn($user->user_id, true);
// if user has check the "remember me" checkbox, then generate token and write cookie
if ($user_rememberme) {
if($user_rememberme) {
$this->newRememberMeCookie();
}
@ -215,9 +232,9 @@ class User {
// DELETE this if-block if you like, it only exists to recalculate users's hashes when you provide a cost factor,
// by default the script will use a cost factor of 10 and never change it.
// check if the have defined a cost factor in config/hashing.php
if (defined('PSM_LOGIN_HASH_COST_FACTOR')) {
if(defined('PSM_LOGIN_HASH_COST_FACTOR')) {
// check if the hash needs to be rehashed
if (password_needs_rehash($user->password, PASSWORD_DEFAULT, array('cost' => PSM_LOGIN_HASH_COST_FACTOR))) {
if(password_needs_rehash($user->password, PASSWORD_DEFAULT, array('cost' => PSM_LOGIN_HASH_COST_FACTOR))) {
$this->changePassword($user->user_id, $user_password);
}
}
@ -231,10 +248,10 @@ class User {
*/
protected function setUserLoggedIn($user_id, $regenerate = false) {
if($regenerate) {
session_regenerate_id();
$this->session->migrate();
}
$_SESSION['user_id'] = $user_id;
$_SESSION['user_logged_in'] = 1;
$this->session->set('user_id', $user_id);
$this->session->set('user_logged_in', 1);
// declare user id, set the login status to true
$this->user_id = $user_id;
@ -244,7 +261,7 @@ class User {
/**
* Create all data needed for remember me cookie connection on client and server side
*/
private function newRememberMeCookie() {
protected function newRememberMeCookie() {
// generate 64 char random string and store it in current user data
$random_token_string = hash('sha256', mt_rand());
$sth = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET rememberme_token = :user_rememberme_token WHERE user_id = :user_id');
@ -262,11 +279,11 @@ class User {
/**
* Delete all data needed for remember me cookie connection on client and server side
*/
private function deleteRememberMeCookie() {
protected function deleteRememberMeCookie() {
// Reset rememberme token
if(isset($_SESSION['user_id'])) {
if($this->session->has('user_id')) {
$sth = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET rememberme_token = NULL WHERE user_id = :user_id');
$sth->execute(array(':user_id' => $_SESSION['user_id']));
$sth->execute(array(':user_id' => $this->session->get('user_id')));
}
// set the rememberme-cookie to ten years ago (3600sec * 365 days * 10).
@ -281,10 +298,8 @@ class User {
public function doLogout() {
$this->deleteRememberMeCookie();
$_SESSION = array();
session_destroy();
session_start();
session_regenerate_id();
$this->session->clear();
$this->session->invalidate();
$this->user_is_logged_in = false;
}
@ -427,17 +442,65 @@ class User {
}
/**
* Check if the session has already started
* @return boolean
* read current user preferences from the database
* @return boolean return false is user not connected
*/
public function isSessionStarted() {
if(php_sapi_name() !== 'cli') {
if(version_compare(phpversion(), '5.4.0', '>=')) {
return session_status() === PHP_SESSION_ACTIVE ? true : false;
} else {
return session_id() === '' ? false : true;
protected function loadPreferences() {
if($this->user_preferences === null) {
if(!$this->getUser()) {
return false;
}
$this->user_preferences = array();
foreach($this->db_connection->query('SELECT `key`,`value` FROM `' . PSM_DB_PREFIX . 'users_preferences` WHERE `user_id` = ' . $this->user_id) as $row) {
$this->user_preferences[$row['key']] = $row['value'];
}
}
return false;
return true;
}
/**
* Get a user preference value
* @param string $key
* @param mixed $default
* @return mixed
*/
public function getUserPref($key, $default = '') {
if(!$this->loadPreferences() || !isset($this->user_preferences[$key])) {
return $default;
}
$value = $this->user_preferences[$key];
settype($value, gettype($default));
return $value;
}
/**
* Set a user preference value
* @param string $key
* @param mixed $value
*/
public function setUserPref($key, $value) {
if($this->loadPreferences()) {
if(isset($this->user_preferences[$key])) {
if($this->user_preferences[$key] == $value) {
return; // no change
}
$sql = 'UPDATE `' . PSM_DB_PREFIX . 'users_preferences` SET `key` = ?, `value` = ? WHERE `user_id` = ?';
} else{
$sql = 'INSERT INTO `' . PSM_DB_PREFIX . 'users_preferences` SET `key` = ?, `value` = ?, `user_id` = ?';
}
$sth = $this->db_connection->prepare($sql);
$sth->execute(array($key, $value, $this->user_id));
$this->user_preferences[$key] = $value;
}
}
/**
* Get session object
* @return \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
public function getSession() {
return $this->session;
}
}

View File

@ -0,0 +1,80 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Victor Macko
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Txtmsg;
class Smsglobal extends Core {
// =========================================================================
// [ Fields ]
// =========================================================================
public $gateway = 1;
public $resultcode = null;
public $resultmessage = null;
public $success = false;
public $successcount = 0;
/**
* Send the SMS message
* @param string $message
* @return boolean (true = message was sent successfully, false = there was a problem sending the message)
*/
public function sendSMS($message) {
$recipients = join(',', $this->recipients);
if(count($recipients) == 0) {
return false;
}
/**
* Documentation is here: http://www.smsglobal.com/http-api/
* Recipient numbers should be in the MSIDSN format (eg. 61400111222). The '+' sign should not be included before the country code.
*/
$from = urlencode(substr($this->originator,0 , 11)); // Max 11 Char.
$url = 'http://www.smsglobal.com/http-api.php' .
'?action=sendsms' .
'&user=' . $this->username .
'&password=' . $this->password .
'&from=' . $from .
'&to=' . rawurlencode($recipients) .
'&clientcharset=ISO-8859-1' .
'&text=' . substr(rawurlencode($message), 0, 153);
$returnedData = file_get_contents($url);
$isOk = strpos($returnedData, 'OK: 0') !== false;
$this->success = $isOk;
$this->resultmessage = $returnedData;
if(!$isOk) {
error_log($this->resultmessage, E_USER_NOTICE);
}
return $isOk;
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author nerdalertdk
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Txtmsg;
class Smsit extends Core {
// =========================================================================
// [ Fields ]
// =========================================================================
public $gateway = 1;
public $resultcode = null;
public $resultmessage = null;
public $success = false;
public $successcount = 0;
public function sendSMS($message) {
// http://www.smsit.dk/api/sendSms.php?apiKey=[KEY]x&senderId=[SENDER]&mobile=[PHONENUMBER]&message=[MESSAGE]
// Use USERNAME as API KEY, password not needed
$apiurl = "http://www.smsit.dk/api/sendSms.php";
$msg = urlencode( $message );
$from = urlencode( substr($this->originator,0,11) ); // Max 11 Char.
foreach( $this->recipients as $phone ){
$URL = $apiurl."?apiKey=" . $this->username . "&mobile=" . $phone . "&message=" . $msg . "&senderId=" . $from;
$result = file_get_contents( $URL );
/*
0 Everything went as it should
1 Invalid API key
2 Invalid sender name
3 Invalid character set (charset)
4 Invalid mobile number
5 There is not filled out a message
6 The message is too long (That was she said)
7 API-key does not exist
*/
if((int)$result == 0) {
$success = true;
}
}
return $result;
}
}

View File

@ -78,7 +78,7 @@ class Installer {
// different DB version, check if the version requires any changes
// @todo this is currently a manual check for each version, similar to upgrade().. not a clean way
if(version_compare($version_db, '3.0.0', '<')) {
if(version_compare($version_db, '3.1.0', '<')) {
return true;
} else {
// change database version to current version so this check won't be required next time
@ -126,7 +126,7 @@ class Installer {
$this->log('Populating database...');
$queries = array();
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (`ip`, `port`, `label`, `type`, `status`, `error`, `rtime`, `last_online`, `last_check`, `active`, `email`, `sms`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', 'on', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', 'on', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (`ip`, `port`, `label`, `type`, `pattern`, `status`, `error`, `rtime`, `last_online`, `last_check`, `active`, `email`, `sms`, `pushover`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', 'on', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 'yes', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', 'on', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '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'),
@ -138,15 +138,19 @@ class Installer {
('email_smtp_port', ''),
('email_smtp_username', ''),
('email_smtp_password', ''),
('sms_status', '1'),
('sms_status', '0'),
('sms_gateway', 'mollie'),
('sms_gateway_username', 'username'),
('sms_gateway_password', 'password'),
('sms_from', '1234567890'),
('pushover_status', '0'),
('pushover_api_token', ''),
('alert_type', 'status'),
('log_status', '1'),
('log_email', '1'),
('log_sms', '1'),
('log_pushover', '1'),
('log_retention_period', '365'),
('version', '" . PSM_VERSION . "'),
('version_update_check', '" . PSM_VERSION . "'),
('auto_refresh_servers', '0'),
@ -177,10 +181,18 @@ class Installer {
`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,
`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,
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 ,
@ -189,7 +201,7 @@ class Installer {
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') NOT NULL,
`type` enum('status','email','sms','pushover') NOT NULL,
`message` varchar(255) NOT NULL,
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
`user_id` varchar(255) NOT NULL,
@ -210,8 +222,10 @@ class Installer {
`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',
`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,
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers_uptime' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` (
@ -264,6 +278,10 @@ class Installer {
// upgrade to 3.0.0
$this->upgrade300();
}
if(version_compare($version_from, '3.1.0', '<')) {
// upgrade to 3.1.0
$this->upgrade310();
}
psm_update_conf('version', $version_to);
}
@ -378,4 +396,29 @@ class Installer {
}
$this->execSQL("ALTER TABLE `".PSM_DB_PREFIX."users` DROP `server_id`;");
}
protected function upgrade310() {
$queries = array();
psm_update_conf('log_retention_period', '365');
psm_update_conf('pushover_status', 0);
psm_update_conf('log_pushover', 1);
psm_update_conf('pushover_api_token', '');
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD `pushover_key` VARCHAR( 255 ) NOT NULL AFTER `mobile`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD `pushover_device` VARCHAR( 255 ) NOT NULL AFTER `pushover_key`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `pushover` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `sms`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `timeout` smallint(1) unsigned NULL DEFAULT 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;";
$this->execSQL($queries);
}
}

View File

@ -0,0 +1,149 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @author Jérôme Cabanis <jerome@lauraly.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
namespace psm\Util\Module;
class Modal implements ModalInterface {
const MODAL_TYPE_OK = 0;
const MODAL_TYPE_OKCANCEL = 1;
const MODAL_TYPE_DANGER = 2;
/**
* prefix used for modal dialog box elements
* @var string $modal_id
*/
protected $modal_id;
/**
* @var int $type Type of modal dialog
*/
protected $type;
/**
* Modal dialog title
* @var string $title
*/
protected $title;
/**
* Modal dialog message
* @var string $body
*/
protected $message;
/**
* label of the OK button
* @var string $ok_label
*/
protected $ok_label;
/**
* Twig environment
* @var \Twig_Environment $twig
*/
protected $twig;
public function __construct(\Twig_Environment $twig, $modal_id = 'main', $type = self::MODAL_TYPE_OK ) {
$this->modal_id = $modal_id;
$this->twig = $twig;
$this->type = $type;
}
/**
* get the modal dialog box element prefix
* @return string
*/
public function getModalID() {
return $this->modal_id;
}
/**
* Set the modal dialog type
* @param int $type
* @return \psm\Util\Module\Modal
*/
public function setType($type) {
if(in_array($type, array(self::MODAL_TYPE_OK, self::MODAL_TYPE_OKCANCEL, self::MODAL_TYPE_DANGER))) {
$this->type = $type;
}
return $this;
}
/**
* Set the modal dialog title
* @param string $title
* @return \psm\Util\Module\Modal
*/
public function setTitle($title) {
$this->title = $title;
return $this;
}
/**
* Set the modal dialog message
* @param string $message
* @return \psm\Util\Module\Modal
*/
public function setMessage($message) {
$this->message = $message;
return $this;
}
public function setOKButtonLabel($label) {
$this->ok_label = $label;
return $this;
}
public function createHTML() {
$has_cancel = ($this->type == self::MODAL_TYPE_OK) ? false : true;
$button_type = ($this->type == self::MODAL_TYPE_DANGER) ? 'danger' : 'primary';
$button_label = empty($this->ok_label) ? psm_get_lang('system', 'ok') : $this->ok_label;
$message = !empty($this->message) ? $this->message : '';
$matches = array();
if(preg_match_all('/%(\d)/', $message, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
$message = str_replace($match[0], '<span class="modalP' . $match[1] . '"></span>', $message);
}
}
$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_body' => $message,
'has_cancel' => $has_cancel,
'label_cancel' => psm_get_lang('system', 'cancel'),
'modal_button_type' => $button_type,
'modal_button_label'=> $button_label,
));
return $html;
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @author Jérôme Cabanis <jerome@lauraly.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
namespace psm\Util\Module;
interface ModalInterface {
public function __construct(\Twig_Environment $twig);
public function getModalID();
public function createHTML();
}

View File

@ -26,7 +26,6 @@
**/
namespace psm\Util\Module;
use psm\Service\Template;
class Sidebar implements SidebarInterface {
@ -51,13 +50,13 @@ class Sidebar implements SidebarInterface {
protected $subtitle;
/**
* Template service
* @var \psm\Service\Template $tpl
* Twig environment
* @var \Twig_Environment $twig
*/
protected $tpl;
protected $twig;
public function __construct(Template $tpl) {
$this->tpl = $tpl;
public function __construct(\Twig_Environment $twig) {
$this->twig = $twig;
}
/**
@ -73,7 +72,7 @@ class Sidebar implements SidebarInterface {
/**
* Set a custom subtitle (default is module subitle)
* @param string $title
* @return \psm\Util\Moduke\Sidebar
* @return \psm\Util\Module\Sidebar
*/
public function setSubtitle($title) {
$this->subtitle = $title;
@ -154,11 +153,11 @@ class Sidebar implements SidebarInterface {
}
public function createHTML() {
$tpl_id = 'main_sidebar_container';
$this->tpl->newTemplate($tpl_id, 'main_sidebar.tpl.html');
$tpl_data = array(
'subtitle' => $this->subtitle,
);
$types = array('dropdown', 'button', 'link');
$items = array();
$tpl_data['items'] = array();
// loop through all types and build their html
foreach($types as $type) {
@ -166,37 +165,17 @@ class Sidebar implements SidebarInterface {
// no items for this type
continue;
}
// retrieve template for this type once so we can use it in the loop
$tpl_id_type = 'main_sidebar_types_' . $type;
$this->tpl->newTemplate($tpl_id_type, 'main_sidebar.tpl.html');
$html_type = $this->tpl->getTemplate($tpl_id_type);
// build html for each individual item
foreach($this->items[$type] as $id => $item) {
$html_item = $html_type;
if(isset($item['options'])) {
$item['options'] = $this->tpl->addTemplateDataRepeat($html_item, 'options', $item['options'], true);
}
$html_item = $this->tpl->addTemplateData($html_type, $item, true);
$items[] = array(
'html_item' => $html_item,
'class_active' => ($id === $this->active_id) ? 'active' : '',
);
$item['type'] = $type;
$item['class_active'] = ($id === $this->active_id) ? 'active' : '';
$tpl_data['items'][] = $item;
}
}
if(!empty($items)) {
$this->tpl->addTemplateDataRepeat($tpl_id, 'items', $items);
}
if($this->subtitle !== null) {
$this->tpl->addTemplateData($tpl_id, array(
'subtitle' => $this->subtitle,
));
}
$html = $this->tpl->getTemplate($tpl_id);
$tpl = $this->twig->loadTemplate('util/module/sidebar.tpl.html');
$html = $tpl->render($tpl_data);
return $html;
}

View File

@ -29,7 +29,7 @@ namespace psm\Util\Module;
interface SidebarInterface {
public function __construct(\psm\Service\Template $tpl);
public function __construct(\Twig_Environment $twig);
public function createHTML();

View File

@ -0,0 +1,119 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Util\Server;
/**
* Makes sure all data of servers is being archived properly or removed if necessary.
*/
class ArchiveManager {
/**
* Available archiver utils.
* @var array $archivers
*/
protected $archivers = array();
/**
* Database service
* @var \psm\Service\Database $db
*/
protected $db;
/**
* Retention period
* @var \DateInterval $retention_period
* @see setRetentionPeriod()
*/
protected $retention_period;
public function __construct(\psm\Service\Database $db) {
$this->db = $db;
$this->setRetentionPeriod(psm_get_conf('log_retention_period', 365));
$this->archivers[] = new Archiver\UptimeArchiver($db);
$this->archivers[] = new Archiver\LogsArchiver($db);
}
/**
* Archive one or more servers.
* @param int $server_id
* @return boolean
*/
public function archive($server_id = null) {
$result = true;
foreach($this->archivers as $archiver) {
if(!$archiver->archive($server_id)) {
$result = false;
}
}
return $result;
}
/**
* Cleanup old records for one or more servers
* @param int $server_id
* @return boolean
*/
public function cleanup($server_id = null) {
$result = true;
if(!$this->retention_period) {
// cleanup is disabled
return $result;
}
$retdate = new \DateTime();
$retdate->sub($this->retention_period);
foreach($this->archivers as $archiver) {
if(!$archiver->cleanup($retdate, $server_id)) {
$result = false;
}
}
return $result;
}
/**
* Set retention period for this archive run.
*
* Set period to 0 to disable cleanup altogether.
* @param \DateInterval|int $period \DateInterval object or number of days (int)
* @return \psm\Util\Server\ArchiveManager
*/
public function setRetentionPeriod($period) {
if(is_object($period) && $period instanceof \DateInterval) {
$this->retention_period = $period;
} elseif(intval($period) == 0) {
// cleanup disabled
$this->retention_period = false;
} else {
$this->retention_period = new \DateInterval('P' . intval($period) . 'D');
}
return $this;
}
}

View File

@ -1,55 +1,47 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.0.0
**/
namespace psm\Util;
/**
* PHPMailer is not using namespaces so unable to load files in autoloader.
*/
require_once(PSM_PATH_VENDOR . '/PHPMailer/class.phpmailer.php');
require_once(PSM_PATH_VENDOR . '/PHPMailer/class.smtp.php');
/**
* PSM Mailer utility
*
* The PHPMailer is an open source lib that can be found in vendor/PHPMailer.
*
* @see \PHPMailer
*/
class Mailer extends \PHPMailer {
/**
* Open new PHPMailer
*
* @param boolean $exceptions
*/
function __construct($exceptions = false) {
parent::__construct($exceptions);
}
}
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
namespace psm\Util\Server\Archiver;
interface ArchiverInterface {
/**
* Archive for one or all servers.
* @param int $server_id
* @return boolean
*/
public function archive($server_id = null);
/**
* Cleanup data older than the retention period given.
* @param \DateTime $retention_date
* @param int $server_id
* @return boolean
*/
public function cleanup(\DateTime $retention_date, $server_id = null);
}

View File

@ -0,0 +1,70 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1
**/
/**
* Cleanup log table
*/
namespace psm\Util\Server\Archiver;
use psm\Service\Database;
class LogsArchiver implements ArchiverInterface {
/**
* Database service
* @var \psm\Service\Database $db
*/
protected $db;
function __construct(Database $db) {
$this->db = $db;
}
/**
* Currently there is not really a log archive.
*
* It stays in the log table until cleaned up.
* @param int $server_id
*/
public function archive($server_id = null) {
return true;
}
public function cleanup(\DateTime $retention_date, $server_id = null) {
$sql_where_server = ($server_id !== null)
// this is obviously not the cleanest way to implement this when using paramter binding.. sorry.
? ' `server_id` = ' . intval($server_id) . ' AND '
: '';
$this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."log` WHERE {$sql_where_server} `datetime` < :latest_date",
array('latest_date' => $retention_date->format('Y-m-d 00:00:00')),
false
);
return true;
}
}

View File

@ -0,0 +1,173 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* Jérôme Cabanis <http://lauraly.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
/**
* The archiver class moves active data from the uptime table to the history table.
*
* Because the uptime table has a record for every single run of the status-check,
* it will grow very large over time. For this reason, uptime records are only kept for a limited time
* to provide detailed statistics. After that, the archiver comes in and saves the averages per day
* in the history table. That way we can always show statistics regarding average latency and failed checks per day,
* but we only need 1 record per server per day.
*
* @see \psm\Util\Updater\Autorun
*/
namespace psm\Util\Server\Archiver;
use psm\Service\Database;
class UptimeArchiver implements ArchiverInterface {
/**
* Database service
* @var \psm\Service\Database $db
*/
protected $db;
function __construct(Database $db) {
$this->db = $db;
}
/**
* Archive all server status records older than 1 week.
*
* Archiving means calculating averages per day, and storing 1 single
* history row for each day for each server.
*
* @param int $server_id
*/
public function archive($server_id = null) {
$latest_date = new \DateTime('-1 week 0:0:0');
// Lock tables to prevent simultaneous archiving (by other sessions or the cron job)
try {
$this->db->pdo()->exec('LOCK TABLES ' . PSM_DB_PREFIX . 'servers_uptime WRITE, ' . PSM_DB_PREFIX . 'servers_history WRITE');
$locked = true;
} catch (\PDOException $e) {
// user does not have lock rights, ignore
$locked = false;
}
$latest_date_str = $latest_date->format('Y-m-d 00:00:00');
$sql_where_server = $this->createSQLWhereServer($server_id);
$records = $this->db->execute(
"SELECT `server_id`,`date`,`status`,`latency`
FROM `" . PSM_DB_PREFIX."servers_uptime`
WHERE {$sql_where_server} `date` < :latest_date",
array('latest_date' => $latest_date_str));
if(!empty($records)) {
// first group all records by day and server_id
$data_by_day = array();
foreach($records as $record) {
$server_id = (int)$record['server_id'];
$day = date('Y-m-d', strtotime($record['date']));
if(!isset($data_by_day[$day][$server_id])) {
$data_by_day[$day][$server_id] = array();
}
$data_by_day[$day][$server_id][] = $record;
}
// now get history data day by day
$histories = array();
foreach($data_by_day as $day => $day_records) {
foreach ($day_records as $server_id => $server_day_records) {
$histories[] = $this->getHistoryForDay($day, $server_id, $server_day_records);
}
}
// Save all
$this->db->insertMultiple(PSM_DB_PREFIX.'servers_history', $histories);
// now remove all records from the uptime table
$this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."servers_uptime` WHERE {$sql_where_server} `date` < :latest_date",
array('latest_date' => $latest_date_str),
false
);
}
if($locked) {
$this->db->exec('UNLOCK TABLES');
}
return true;
}
public function cleanup(\DateTime $retention_date, $server_id = null) {
$sql_where_server = $this->createSQLWhereServer($server_id);
$this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."servers_history` WHERE {$sql_where_server} `date` < :latest_date",
array('latest_date' => $retention_date->format('Y-m-d 00:00:00')),
false
);
return true;
}
/**
* Build a history array for a day records
* @param string $day
* @param int $server_id
* @param array $day_records
* @return array
*/
protected function getHistoryForDay($day, $server_id, $day_records) {
$latencies = array();
$checks_failed = 0;
foreach($day_records as $day_record) {
$latencies[] = $day_record['latency'];
if($day_record['status'] == 0) {
$checks_failed++;
}
}
sort($latencies, SORT_NUMERIC);
$history = array(
'date' => $day,
'server_id' => $server_id,
'latency_min' => min($latencies),
'latency_avg' => array_sum($latencies) / count($latencies),
'latency_max' => max($latencies),
'checks_total' => count($day_records),
'checks_failed' => $checks_failed,
);
return $history;
}
protected function createSQLWhereServer($server_id) {
$sql_where_server = ($server_id !== null)
// this is obviously not the cleanest way to implement this when using paramter binding.. sorry.
? ' `server_id` = ' . intval($server_id) . ' AND '
: '';
return $sql_where_server;
}
}

View File

@ -28,7 +28,6 @@
namespace psm\Util\Server;
use psm\Service\Database;
use psm\Service\Template;
/**
* History util, create HTML for server graphs
@ -42,14 +41,14 @@ class HistoryGraph {
protected $db;
/**
* Template service
* @var \psm\Service\Template $tpl
* Twig environment
* @var \Twig_Environment $twig
*/
protected $tpl;
protected $twig;
function __construct(Database $db, Template $tpl) {
function __construct(Database $db, \Twig_Environment $twig) {
$this->db = $db;
$this->tpl = $tpl;
$this->twig = $twig;
}
/**
@ -57,127 +56,184 @@ class HistoryGraph {
* @return string
*/
public function createHTML($server_id) {
$tpl_id = 'server_history';
$this->tpl->newTemplate($tpl_id, 'server/history.tpl.html');
// Archive all records for this server to make sure we have up-to-date stats
$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');
$graphs = array(
0 => $this->generateGraphUptime($server_id),
1 => $this->generateGraphHistory($server_id),
0 => $this->generateGraphUptime($server_id, $last_week, $now),
1 => $this->generateGraphHistory($server_id, $last_year, $last_week),
);
$this->tpl->addTemplateDataRepeat($tpl_id, 'graphs', $graphs);
$this->tpl->addTemplateData(
$tpl_id,
array(
'label_server' => psm_get_lang('servers', 'server'),
'label_latency_avg' => psm_get_lang('servers', 'latency_avg'),
'day_format' => psm_get_lang('servers', 'chart_day_format'),
'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'),
'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'),
'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'),
)
$info_fields = array(
'latency_avg' => '%01.4f',
'uptime' => '%01.3f%%',
);
return $this->tpl->getTemplate($tpl_id);
foreach($graphs as $i => &$graph) {
// add subarray for info fields
$graph['info'] = array();
foreach($info_fields as $field => $format) {
if(!isset($graph[$field])) {
continue;
}
$graph['info'][] = array(
'label' => psm_get_lang('servers', $field),
'value' => sprintf($format, $graph[$field]),
);
}
}
$tpl_data = array(
'graphs' => $graphs,
'label_server' => psm_get_lang('servers', 'server'),
'day_format' => psm_get_lang('servers', 'chart_day_format'),
'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'),
'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'),
'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'),
);
return $this->twig->render('module/server/history.tpl.html', $tpl_data);
}
/**
* 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
* @return array
*/
protected function generateGraphUptime($server_id) {
$uptimes = $this->db->select(PSM_DB_PREFIX.'servers_uptime' , array('server_id' => $server_id), null, '', 'date');
$last_date = 0;
$latency_avg = 0;
// Create the list of points and server down zones
$line = array();
$lines = array();
$down = array();
foreach ($uptimes as $uptime) {
$latency_avg += (float) $uptime['latency'];
$time = strtotime($uptime['date']) * 1000;
if($uptime['status']) {
// The server is up
$line[] = '[' . $time . ',' . round((float)$uptime['latency'], 4) . ']';
if($last_date) {
// Was down before.
// Record the first and last date as a string in the down array
$down[] = '[' . $last_date . ',' . $time . ']';
$last_date = 0;
}
}
else {
if(!$last_date) {
$last_date = $time;
}
}
}
if(!empty($line)) {
$lines[] = '[' . implode(',', $line) . ']';
}
if($last_date) {
$down[] = '[' . $last_date . ',0]';
}
$buttons = array();
$buttons[] = array('mode' => 'hour', 'label' => psm_get_lang('servers', 'hour'), 'class_active' => 'btn-info');
$buttons[] = array('mode' => 'day', 'label' => psm_get_lang('servers', 'day'));
$buttons[] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week'));
$data = array(
'title' => psm_get_lang('servers', 'chart_last_week'),
'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0,
'server_lines' => sizeof($lines) ? '[' . implode(',', $lines) . ']' : '',
'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '',
'series' => "[{label: '".psm_get_lang('servers', 'latency')."'}]",
'plotmode' => 'hour',
'buttons' => $buttons,
'chart_id' => $server_id . '_uptime',
public function generateGraphUptime($server_id, $start_time, $end_time) {
$lines = array(
'latency' => array(),
);
$cb_if_up = function($uptime_record) {
return ($uptime_record['status'] == 1);
};
$records = $this->getRecords('uptime', $server_id, $start_time, $end_time);
$data = $this->generateGraphLines($records, $lines, $cb_if_up, 'latency', $start_time, $end_time, true);
$data['title'] = psm_get_lang('servers', 'chart_last_week');
$data['plotmode'] = 'hour';
$data['buttons'] = array();
$data['buttons'][] = array('mode' => 'hour', 'label' => psm_get_lang('servers', 'hour'), 'class_active' => 'btn-info');
$data['buttons'][] = array('mode' => 'day', 'label' => psm_get_lang('servers', 'day'));
$data['buttons'][] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week'));
// make sure to add chart id after buttons so its added to those tmeplates as well
$data['chart_id'] = $server_id . '_uptime';
return $data;
}
/**
* 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
* @return array
*/
protected function generateGraphHistory($server_id) {
$uptimes = $this->db->select(PSM_DB_PREFIX.'servers_history' , array('server_id' => $server_id), null, '', 'date');
$last_date = 0;
// Create the list of points and server down zones
public function generateGraphHistory($server_id, $start_time, $end_time) {
$lines = array(
'latency_avg' => array(),
'latency_max' => array(),
'latency_min' => array(),
);
$server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array('server_id' => $server_id), array('warning_threshold'));
$cb_if_up = function($uptime_record) use($server) {
return ($uptime_record['checks_failed'] < $server['warning_threshold']);
};
$records = $this->getRecords('history', $server_id, $start_time, $end_time);
// dont add uptime for now because we have no way to calculate accurate uptimes for archived records
$data = $this->generateGraphLines($records, $lines, $cb_if_up, 'latency_avg', $start_time, $end_time, false);
$data['title'] = psm_get_lang('servers', 'chart_history');
$data['plotmode'] = 'month';
$data['buttons'] = array();
$data['buttons'][] = array('mode' => 'week2', 'label' => psm_get_lang('servers', 'week'));
$data['buttons'][] = array('mode' => 'month', 'label' => psm_get_lang('servers', 'month'), 'class_active' => 'btn-info');
$data['buttons'][] = array('mode' => 'year', 'label' => psm_get_lang('servers', 'year'));
// make sure to add chart id after buttons so its added to those tmeplates as well
$data['chart_id'] = $server_id . '_history';
return $data;
}
/**
* 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
* @return array
*/
protected function getRecords($type, $server_id, $start_time, $end_time) {
if(!in_array($type, array('history', 'uptime'))) {
return array();
}
$records = $this->db->execute(
'SELECT *
FROM `' . PSM_DB_PREFIX . "servers_$type`
WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time",
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;
}
/**
* Generate data arrays for graphs
* @param array $records all uptime records to parse
* @param array $lines array with keys as line ids to prepare (key must be available in uptime records)
* @param callable $cb_if_up function to check if the server is up or down
* @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 boolean $add_uptime add uptime calculation?
* @return array
*/
protected function generateGraphLines($records, $lines, $cb_if_up, $latency_avg_key, $start_time, $end_time, $add_uptime = false) {
$data = array();
// PLEASE NOTE: all times are in microseconds! because of javascript.
$last_date = 0;
$latency_avg = 0;
$series = array();
$time_end = 0;
// number of microseconds of downtime
$time_down = 0;
$down = array();
foreach ($uptimes as $uptime) {
$time = strtotime($uptime['date']) * 1000;
// keep track of highest timestamp to use as end-date for graphs
if($time > $time_end) {
$time_end = $time;
}
$latency_avg += (float) $uptime['latency_avg'];
if($uptime['checks_failed'] == 0) {
// Create the list of points and server down zones
foreach ($records as $uptime) {
$time = strtotime($uptime['date']) * 1000;
// use the first line to calculate average latency
$latency_avg += (float) $uptime[$latency_avg_key];
if($cb_if_up($uptime)) {
// The server is up
foreach($lines as $key => &$value) {
// add the value for each of the different lines
if(isset($uptime[$key])) {
$value[] = '[' . $time . ',' . round((float)$uptime[$key], 4) . ']';
$value[] = '[' . $time . ',' . round((float) $uptime[$key], 4) . ']';
}
}
if($last_date) {
// Was down before.
// Record the first and last date as a string in the down array
$down[] = '[' . $last_date . ',' . $time . ']';
// add the number of microseconds of downtime to counter for %
$time_down += ($time - $last_date);
$last_date = 0;
}
} else {
@ -198,24 +254,20 @@ class HistoryGraph {
}
if($last_date) {
$down[] = '[' . $last_date . ',0]';
$time = $end_time->getTimestamp() * 1000;
$time_down += ($time - $last_date);
}
$buttons = array();
$buttons[] = array('mode' => 'week2', 'label' => psm_get_lang('servers', 'week'));
$buttons[] = array('mode' => 'month', 'label' => psm_get_lang('servers', 'month'), 'class_active' => 'btn-info');
$buttons[] = array('mode' => 'year', 'label' => psm_get_lang('servers', 'year'));
$data = array(
'title' => psm_get_lang('servers', 'chart_history'),
'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0,
'server_lines' => sizeof($lines_merged) ? '[' . implode(',', $lines_merged) . ']' : '',
'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '',
'series' => sizeof($series) ? '[' . implode(',', $series) . ']' : '',
'plotmode' => 'month',
'end_timestamp' => $time_end ? $time_end : '',
'buttons' => $buttons,
// make sure to add chart id after buttons so its added to those tmeplates as well
'chart_id' => $server_id . '_history',
);
if($add_uptime) {
$data['uptime'] = 100 - (($time_down / ($end_time->getTimestamp() - $start_time->getTimestamp())) / 10);
}
$data['latency_avg'] = count($records) > 0 ? ($latency_avg / count($records)) : 0;
$data['server_lines'] = sizeof($lines_merged) ? '[' . implode(',', $lines_merged) . ']' : '';
$data['server_down'] = sizeof($down) ? '[' . implode(',', $down) . ']' : '';
$data['series'] = sizeof($series) ? '[' . implode(',', $series) . ']' : '';
$data['end_timestamp'] = $end_time->getTimestamp() * 1000;
return $data;
}
}
}

View File

@ -0,0 +1,134 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.1.0
**/
namespace psm\Util\Server;
/**
* The ServerValidator helps you to check input data for servers.
*/
class ServerValidator {
/**
* Database service
* @var \psm\Service\Database $db
*/
protected $db;
public function __construct(\psm\Service\Database $db) {
$this->db = $db;
}
/**
* Check if the server id exists
* @param int $server_id
* @return boolean
* @throws \InvalidArgumentException
*/
public function serverId($server_id) {
$server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array('server_id' => $server_id), array('server_id'));
if(empty($server)) {
throw new \InvalidArgumentException('server_no_match');
}
return true;
}
/**
* Check label
* @param string $label
* @return boolean
* @throws \InvalidArgumentException
*/
public function label($label) {
$label = trim($label);
if(empty($label) || strlen($label) > 255) {
throw new \InvalidArgumentException('server_label_bad_length');
}
return true;
}
/**
* Check server domain/ip
* @param string $value
* @param string $type if given, it can be checked for "website"/"ip"
* @return boolean
* @throws \InvalidArgumentException
*/
public function ip($value, $type = null) {
$value = trim($value);
if(empty($value) || strlen($value) > 255) {
throw new \InvalidArgumentException('server_ip_bad_length');
}
switch($type) {
case 'website':
if(!filter_var($value, FILTER_VALIDATE_URL)) {
throw new \InvalidArgumentException('server_ip_bad_website');
}
break;
case 'service':
if(
!filter_var($value, FILTER_VALIDATE_IP)
// domain regex as per http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address :
&& !preg_match("/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])/", $value)
) {
throw new \InvalidArgumentException('server_ip_bad_service');
}
break;
}
return true;
}
/**
* Check server type
* @param string $type
* @return boolean
* @throws \InvalidArgumentException
*/
public function type($type) {
if(!in_array($type, array('service', 'website'))) {
throw new \InvalidArgumentException('server_type_invalid');
}
return true;
}
/**
* Check warning threshold
* @param int $value
* @return boolean
* @throws \InvalidArgumentException
*/
public function warningThreshold($value) {
if(!is_numeric($value) || intval($value) == 0) {
throw new \InvalidArgumentException('server_warning_threshold_invalid');
}
return true;
}
}

View File

@ -26,7 +26,7 @@
* @since phpservermon 3.0.0
**/
namespace psm\Util\Updater;
namespace psm\Util\Server;
use psm\Service\Database;
use psm\Service\User;
@ -36,7 +36,7 @@ use psm\Service\User;
* If you provide a User service instance it will be
* restricted to that user only.
*/
class Autorun {
class UpdateManager {
/**
* Database service
@ -69,29 +69,27 @@ class Autorun {
)";
}
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`
FROM `".PSM_DB_PREFIX."servers` AS `s`
{$sql_join}
WHERE `active`='yes' ";
$servers = $this->db->query($sql);
$updater = new StatusUpdater($this->db);
$notifier = new StatusNotifier($this->db);
$archiver = new StatusArchiver($this->db);
$cleanup_date = new \DateTime();
$cleanup_date->modify('-1 week');
$updater = new Updater\StatusUpdater($this->db);
$notifier = new Updater\StatusNotifier($this->db);
foreach($servers as $server) {
$status_old = ($server['status'] == 'on') ? true : false;
$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 older than 1 week
$archiver->archive($server['server_id'], $cleanup_date);
}
// clean-up time!! archive all records
$archive = new ArchiveManager($this->db);
$archive->archive();
$archive->cleanup();
}
/**

View File

@ -28,10 +28,10 @@
/**
* The status updater is for sending notifications to the users.
*
* @see \psm\Util\Updater\StatusUpdater
* @see \psm\Util\Updater\Autorun
* @see \psm\Util\Server\Updater\StatusUpdater
* @see \psm\Util\Server\Updater\Autorun
*/
namespace psm\Util\Updater;
namespace psm\Util\Server\Updater;
use psm\Service\Database;
class StatusNotifier {
@ -54,6 +54,12 @@ class StatusNotifier {
*/
protected $send_sms = false;
/**
* Send sms?
* @var boolean $send_pushover
*/
protected $send_pushover = false;
/**
* Save log records?
* @var boolean $save_log
@ -89,6 +95,7 @@ class StatusNotifier {
$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->save_logs = psm_get_conf('log_status');
}
@ -114,7 +121,7 @@ class StatusNotifier {
$this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
'server_id' => $server_id,
), array(
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'error', 'active', 'email', 'sms',
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'error', 'active', 'email', 'sms', 'pushover',
));
if(empty($this->server)) {
return false;
@ -157,16 +164,28 @@ class StatusNotifier {
);
}
$users = $this->getUsers($this->server_id);
if(empty($users)) {
return $notify;
}
// check if email is enabled for this server
if($this->send_emails && $this->server['email'] == 'yes') {
// send email
$this->notifyByEmail();
$this->notifyByEmail($users);
}
// check if sms is enabled for this server
if($this->send_sms && $this->server['sms'] == 'yes') {
// yay lets wake those nerds up!
$this->notifyByTxtMsg();
$this->notifyByTxtMsg($users);
}
// check if pushover is enabled for this server
if($this->send_pushover && $this->server['pushover'] == 'yes') {
// yay lets wake those nerds up!
$this->notifyByPushover($users);
}
return $notify;
@ -175,17 +194,12 @@ class StatusNotifier {
/**
* This functions performs the email notifications
*
* @param array $users
* @return boolean
*/
protected function notifyByEmail() {
protected function notifyByEmail($users) {
$userlist = array();
$users = $this->getUsers($this->server_id);
if (empty($users)) {
return false;
}
// build mail object with some default values
$mail = psm_build_mail();
$mail->Subject = psm_parse_msg($this->status_new, 'email_subject', $this->server);
@ -210,50 +224,63 @@ class StatusNotifier {
}
}
/**
* This functions performs the pushover notifications
*
* @param array $users
* @return boolean
*/
protected function notifyByPushover($users) {
$userlist = array();
$pushover = psm_build_pushover();
if($this->status_new === true) {
$pushover->setPriority(0);
} else {
$pushover->setPriority(2);
$pushover->setRetry(300); //Used with Priority = 2; Pushover will resend the notification every 60 seconds until the user accepts.
$pushover->setExpire(3600); //Used with Priority = 2; Pushover will resend the notification every 60 seconds for 3600 seconds. After that point, it stops sending notifications.
}
$message = psm_parse_msg($this->status_new, 'pushover_message', $this->server);
$pushover->setTitle(psm_parse_msg($this->status_new, 'pushover_title', $this->server));
$pushover->setMessage(str_replace('<br/>', "\n", $message));
// @todo fix url when script is executed via CLI
// $pushover->setUrl($url);
// $pushover->setUrlTitle(psm_get_lang('system', 'title'));
foreach($users as $user) {
if(trim($user['pushover_key']) == '') {
continue;
}
$userlist[] = $user['user_id'];
$pushover->setUser($user['pushover_key']);
if($user['pushover_device'] != '') {
$pushover->setDevice($user['pushover_device']);
}
$pushover->send();
}
if(psm_get_conf('log_pushover')) {
psm_add_log($this->server_id, 'pushover', $message, implode(',', $userlist));
}
}
/**
* This functions performs the text message notifications
*
* @return unknown
* @param array $users
* @return boolean
*/
protected function notifyByTxtMsg() {
// send sms to all users for this server using defined gateway
$users = $this->getUsers($this->server_id);
if (empty($users)) {
protected function notifyByTxtMsg($users) {
$sms = psm_build_sms();
if(!$sms) {
return false;
}
// we have to build an userlist for the log table..
$userlist = array();
// open the right class
// not making this any more dynamic, because perhaps some gateways need custom settings (like Mollie)
switch(strtolower(psm_get_conf('sms_gateway'))) {
case 'mosms':
$sms = new \psm\Txtmsg\Mosms();
break;
case 'inetworx':
$sms = new \psm\Txtmsg\Inetworx();
break;
case 'mollie':
$sms = new \psm\Txtmsg\Mollie();
$sms->setGateway(1);
break;
case 'spryng':
$sms = new \psm\Txtmsg\Spryng();
break;
case 'clickatell':
$sms = new \psm\Txtmsg\Clickatell();
break;
case 'textmarketer':
$sms = new \psm\Txtmsg\Textmarketer();
break;
}
// copy login information from the config file
$sms->setLogin(psm_get_conf('sms_gateway_username'), psm_get_conf('sms_gateway_password'));
$sms->setOriginator(psm_get_conf('sms_from'));
// add all users to the recipients list
foreach ($users as $user) {
$userlist[] = $user['user_id'];
@ -280,7 +307,7 @@ 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`
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, `u`.`pushover_device`
FROM `".PSM_DB_PREFIX."users` AS `u`
JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id`

View File

@ -28,10 +28,10 @@
/**
* The status class is for checking the status of a server.
*
* @see \psm\Util\Updater\StatusNotifier
* @see \psm\Util\Updater\Autorun
* @see \psm\Util\Server\Updater\StatusNotifier
* @see \psm\Util\Server\Updater\Autorun
*/
namespace psm\Util\Updater;
namespace psm\Util\Server\Updater;
use psm\Service\Database;
class StatusUpdater {
@ -82,7 +82,7 @@ class StatusUpdater {
$this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
'server_id' => $server_id,
), array(
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'active', 'warning_threshold', 'warning_threshold_counter',
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'active', 'warning_threshold', 'warning_threshold_counter', 'timeout',
));
if(empty($this->server)) {
return false;
@ -149,7 +149,9 @@ class StatusUpdater {
$status = ($fp === false) ? false : true;
$this->rtime = (microtime(true) - $starttime);
fclose($fp);
if(is_resource($fp)) {
fclose($fp);
}
// check if server is available and rerun if asked.
if(!$status && $run < $max_runs) {
@ -173,7 +175,8 @@ class StatusUpdater {
$curl_result = psm_curl_get(
$this->server['ip'],
true,
($this->server['pattern'] == '' ? false : true)
($this->server['pattern'] == '' ? false : true),
$this->server['timeout']
);
$this->rtime = (microtime(true) - $starttime);

View File

@ -1,140 +0,0 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
/**
* The archiver class moves active data from the uptime table to the history table.
*
* Because the uptime table has a record for every single run of the status-check,
* it will grow very large over time. For this reason, uptime records are only kept for a limited time
* to provide detailed statistics. After that, the archiver comes in and saves the averages per day
* in the history table. That way we can always show statistics regarding average latency and failed checks per day,
* but we only need 1 record per server per day.
*
* @see \psm\Util\Updater\Autorun
*/
namespace psm\Util\Updater;
use psm\Service\Database;
class StatusArchiver {
/**
* Database service
* @var \psm\Service\Database $db
*/
protected $db;
function __construct(Database $db) {
$this->db = $db;
}
/**
* Archive the active records of a server before a certain date.
*
* Archiving means calculating averages per day, and storing 1 single
* history row for each day for this server.
*
* @param int $server_id
* @param \DateTime $date_before archive all records before this date
*/
public function archive($server_id, \DateTime $date_before) {
// get all uptime records for this server
$q_records = $this->db->pdo()->prepare("
SELECT `date`,`status`,`latency`
FROM `".PSM_DB_PREFIX."servers_uptime`
WHERE `server_id` = :server_id AND `date` < :latest_date
");
$q_records->execute(array(
'server_id' => $server_id,
'latest_date' => $date_before->format('Y-m-d 00:00:00'),
));
$records = $q_records->fetchAll();
if(empty($records)) {
return false;
}
$data_by_day = array();
// first group all records by day
foreach($records as $record) {
$day = date('Y-m-d', strtotime($record['date']));
if(!isset($data_by_day[$day])) {
$data_by_day[$day] = array();
}
$data_by_day[$day][] = $record;
}
// now lets sort out and save the history day by day
foreach($data_by_day as $day => $day_records) {
$history = $this->getHistoryForDay($day, $day_records);
$history['server_id'] = $server_id;
// store the history for this day in the history table
$this->db->save(PSM_DB_PREFIX.'servers_history', $history);
}
// now remove all records from the uptime table
$q_records_cleanup = $this->db->pdo()->prepare("
DELETE FROM `".PSM_DB_PREFIX."servers_uptime`
WHERE `server_id` = :server_id AND `date` < :latest_date
");
$q_records_cleanup->execute(array(
'server_id' => $server_id,
'latest_date' => $date_before->format('Y-m-d 00:00:00'),
));
}
/**
* Build a history array for a certain day and its records
* @param string $day
* @param array $day_records
* @return array
*/
protected function getHistoryForDay($day, $day_records) {
$latencies = array();
$checks_failed = 0;
foreach($day_records as $day_record) {
$latencies[] = $day_record['latency'];
if($day_record['status'] == 0) {
$checks_failed++;
}
}
sort($latencies, SORT_NUMERIC);
$history = array(
'date' => $day,
'latency_min' => min($latencies),
'latency_avg' => array_sum($latencies) / count($latencies),
'latency_max' => max($latencies),
'checks_total' => count($day_records),
'checks_failed' => $checks_failed,
);
return $history;
}
}

View File

@ -1,166 +0,0 @@
<!--%tpl_config-->
<form class="form-horizontal" action="index.php?mod=config&action=save" id="edit_config" method="post">
<ul class="nav nav-tabs">
<li class="active"><a href="#config-general" data-toggle="tab">{label_general}</a></li>
<li><a href="#config-email" data-toggle="tab">{label_tab_email}</a></li>
<li><a href="#config-sms" data-toggle="tab">{label_tab_sms}</a></li>
<li><a href="#config-logging" data-toggle="tab">{label_tab_log}</a></li>
</ul>
<div class="tab-content well">
<div id="config-general" class="tab-pane active">
<fieldset>
<legend>{label_general}</legend>
<div class="control-group">
<label class="control-label" for="language">{label_language}</label>
<div class="controls">
<select id="language" name="language">
<!--%tpl_repeat_languages-->
<option value="{value}" {selected}>{label}</option>
<!--%%tpl_repeat_languages-->
{languages}
</select>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="show_update"><input type="checkbox" id="show_update" name="show_update[]" {show_update_checked} /> {label_show_update}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="auto_refresh_servers">{label_auto_refresh}</label>
<div class="controls">
<input type="text" class="input-mini" id="auto_refresh_servers" name="auto_refresh_servers" value="{auto_refresh_servers}" maxlength="10" />&nbsp;{label_seconds}
<p class="help-block">{label_auto_refresh_servers}</p>
</div>
</div>
<legend>{label_settings_notification}</legend>
<div class="control-group">
<label class="control-label" for="alert_type">{label_alert_type}</label>
<div class="controls">
<select id="alert_type" name="alert_type">
<option value="status" {alert_type_selected_status}>{label_alert_type_status}</option>
<option value="offline" {alert_type_selected_offline}>{label_alert_type_offline}</option>
<option value="always" {alert_type_selected_always}>{label_alert_type_always}</option>
</select>
<p class="help-block">{label_alert_type_description}</p>
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{label_save}</button>
</div>
</fieldset>
</div>
<div id="config-email" class="tab-pane">
<fieldset>
<legend>{label_settings_email}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="email_status"><input type="checkbox" id="email_status" name="email_status[]" {email_status_checked} /> {label_email_status}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_from_name">{label_email_from_name}</label>
<div class="controls">
<input type="text" id="email_from_name" name="email_from_name" value="{email_from_name}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_from_email">{label_email_from_email}</label>
<div class="controls">
<input type="text" id="email_from_email" name="email_from_email" value="{email_from_email}" maxlength="255" />
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="email_smtp"><input type="checkbox" id="email_smtp" name="email_smtp[]" {email_smtp_checked} />{label_email_smtp}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_host">{label_email_smtp_host}</label>
<div class="controls">
<input type="text" id="email_smtp_host" name="email_smtp_host" value="{email_smtp_host}" maxlength="100" placeholder="{label_email_smtp_host}" />
<input type="text" class="input-small" id="email_smtp_port" name="email_smtp_port" value="{email_smtp_port}" maxlength="10" placeholder="{label_email_smtp_port}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_username">{label_email_smtp_username}</label>
<div class="controls">
<input type="text" id="email_smtp_username" name="email_smtp_username" value="{email_smtp_username}" maxlength="100" placeholder="{label_email_smtp_noauth}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_password">{label_email_smtp_password}</label>
<div class="controls">
<input type="password" id="email_smtp_password" name="email_smtp_password" value="{email_smtp_password}" maxlength="100" placeholder="{label_email_smtp_noauth}" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{label_save}</button>
</div>
</fieldset>
</div>
<div id="config-sms" class="tab-pane">
<fieldset>
<legend>{label_settings_sms}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="sms_status"><input type="checkbox" id="sms_status" name="sms_status[]" {sms_status_checked} /> {label_sms_status}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway">{label_sms_gateway}</label>
<div class="controls">
<select id="sms_gateway" name="sms_gateway">
<option value="mosms" {sms_selected_mosms}>{label_sms_gateway_mosms}</option>
<option value="mollie" {sms_selected_mollie}>{label_sms_gateway_mollie}</option>
<option value="spryng" {sms_selected_spryng}>{label_sms_gateway_spryng}</option>
<option value="inetworx" {sms_selected_inetworx}>{label_sms_gateway_inetworx}</option>
<option value="clickatell" {sms_selected_clickatell}>{label_sms_gateway_clickatell}</option>
<option value="textmarketer" {sms_selected_textmarketer}>{label_sms_gateway_textmarketer}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway_username">{label_sms_gateway_username}</label>
<div class="controls">
<input type="text" id="sms_gateway_username" name="sms_gateway_username" value="{sms_gateway_username}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway_password">{label_sms_gateway_password}</label>
<div class="controls">
<input type="password" id="sms_gateway_password" name="sms_gateway_password" value="{sms_gateway_password}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_from">{label_sms_from}</label>
<div class="controls">
<input type="text" id="sms_from" name="sms_from" value="{sms_from}" maxlength="255" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{label_save}</button>
</div>
</fieldset>
</div>
<div id="config-logging" class="tab-pane">
<fieldset>
<legend>{label_settings_log}</legend>
<div class="control-group">
<label class="checkbox"><input type="checkbox" id="log_status" name="log_status[]" {log_status_checked} /> {label_log_status}</label>
<p class="help-block">{label_log_status_description}</p>
</div>
<div class="control-group">
<label class="checkbox"><input type="checkbox" id="log_email" name="log_email[]" {log_email_checked} /> {label_log_email}</label>
</div>
<div class="control-group">
<label class="checkbox"><input type="checkbox" id="log_sms" name="log_sms[]" {log_sms_checked} /> {label_log_sms}</label>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{label_save}</button>
</div>
</fieldset>
</div>
</div>
</form>
<!--%%tpl_config-->

View File

@ -0,0 +1,79 @@
{% block header %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="icon" type="image/png" href="favicon.png" />
{% if auto_refresh %}
<meta http-equiv="refresh" content="{{ auto_refresh_seconds }}" />
{% endif %}
<!-- Le styles -->
<link href="static/plugin/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="static/plugin/twitter-bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="static/plugin/bootstrap-multiselect/bootstrap-multiselect.min.css" rel="stylesheet">
<link href="static/css/style.css" rel="stylesheet">
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript" src="static/plugin/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="static/plugin/twitter-bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="static/plugin/bootstrap-multiselect/bootstrap-multiselect.min.js"></script>
<script type="text/javascript" src="static/js/scripts.js"></script>
</head>
{% endblock %}
<body data-spy="scroll" data-target=".subnav" data-offset="50" class="{{ body_class }}">
<!-- navbar -->
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="index.php">{{ title }}</a>
{{ html_menu|raw }}
</div>
</div>
</div>
<!-- /navbar -->
{{ html_modal|raw }}
<!-- container -->
<div id="main-container">
<div class="page-header">
<div class="header-label"><h1>{{ subtitle }}</h1></div>
<div class="header-accessories">{{ header_accessories|raw }}</div>
</div>
<div id="main-content">
{{ html_sidebar|raw }}
<div id="page-container">
<div id="flashmessage" class="hide">
{% for msg in messages %}
<div class="alert alert-{{ msg.shortcode }}">
<p class="pull-left span1"><i class="icon-{{ msg.icon }}"></i></p>
<p>{{ msg.message }}</p>
</div>
{% endfor %}
</div>
{{ html_content|raw }}
</div>
</div>
{% if add_footer %}
{% block footer %}
<footer class="footer">
<p class="pull-right"><a href="#">{{ label_back_to_top }}</a></p>
<p class="powered"><small>Powered by <a href="http://www.phpservermonitor.org/" target="_blank">PHP Server Monitor {{ version }}</a>.<br/>{{ update_available }}</small></p>
</footer>
{% endblock %}
{% endif %}
</div>
<!-- /container -->
</body>
</html>

View File

@ -0,0 +1,22 @@
<div class="nav-collapse">
<ul class="nav">
{% for item in menu %}
<li class="{{ item.active }}"><a href="{{ item.url|raw }}">{{ item.label }}</a></li>
{% endfor %}
<li id="nav_option_help">
<a href="http://www.phpservermonitor.org/support" target="_blank">{{ label_help }}</a>
</li>
</ul>
<ul class="nav pull-right">
<li class="dropdown visible-desktop">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ label_usermenu }} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{{ url_profile|raw }}"><i class="icon-cog"></i>&nbsp;{{ label_profile }}</a></li>
<li><a href="{{ url_logout|raw }}"><i class="icon-off"></i>&nbsp;{{ label_logout }}</a></li>
</ul>
</li>
<li class="hidden-desktop divider"></li>
<li class="hidden-desktop"><a href="{{ url_profile|raw }}">{{ label_profile }}</a></li>
<li class="hidden-desktop"><a href="{{ url_logout|raw }}">{{ label_logout }}</a></li>
</ul>
</div>

View File

@ -0,0 +1,217 @@
<form class="form-horizontal" name="edit_config" action="index.php?mod=config&amp;action=save" id="edit_config" method="post">
<ul class="nav nav-tabs">
<li class="{{ general_active }}"><a href="#config-general" data-toggle="tab">{{ label_general }}</a></li>
<li class="{{ email_active }}"><a href="#config-email" data-toggle="tab">{{ label_tab_email }}</a></li>
<li class="{{ sms_active }}"><a href="#config-sms" data-toggle="tab">{{ label_tab_sms }}</a></li>
<li class="{{ pushover_active }}"><a href="#config-pushover" data-toggle="tab">{{ label_tab_pushover }}</a></li>
</ul>
<div class="tab-content well">
<div id="config-general" class="tab-pane {{ general_active }}">
<fieldset>
<legend>{{ label_general }}</legend>
<div class="control-group">
<label class="control-label" for="language">{{ label_language }}</label>
<div class="controls">
<select id="language" name="language">
{% for language in languages %}
<option value="{{ language.value }}" {% if language.value == language_current %} selected="selected" {% endif %}>{{ language.label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="show_update"><input type="checkbox" id="show_update" name="show_update[]" {{ show_update_checked|raw }} /> {{ label_show_update }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="auto_refresh_servers">{{ label_auto_refresh }}</label>
<div class="controls">
<input type="text" class="input-mini" id="auto_refresh_servers" name="auto_refresh_servers" value="{{ auto_refresh_servers }}" maxlength="10" data-toggle="tooltip" title="{{ label_auto_refresh_servers }}" />&nbsp;{{ label_seconds }}
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ label_settings_notification }}</legend>
<div class="control-group">
<label class="control-label" for="alert_type">{{ label_alert_type }}</label>
<div class="controls">
<select id="alert_type" name="alert_type">
<option value="status" {{ alert_type_selected_status|raw }}>{{ label_alert_type_status }}</option>
<option value="offline" {{ alert_type_selected_offline|raw }}>{{ label_alert_type_offline }}</option>
<option value="always" {{ alert_type_selected_always|raw }}>{{ label_alert_type_always }}</option>
</select>
<p class="help-block">{{ label_alert_type_description|raw }}</p>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ label_settings_log }}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox"><input type="checkbox" id="log_status" name="log_status[]" {{ log_status_checked|raw }} data-toggle="tooltip" title="{{ label_log_status_description }}" /> {{ label_log_status }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="log_retention_period">{{ label_log_retention_period }}</label>
<div class="controls">
<input type="text" class="input-mini" id="log_retention_period" name="log_retention_period" value="{{ log_retention_period }}" data-toggle="tooltip" title="{{ label_log_retention_period_description }}" />&nbsp;{{ label_log_retention_days }}
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit" name="general_submit">{{ label_save }}</button>
</div>
</fieldset>
</div>
<div id="config-email" class="tab-pane {{ email_active }}">
<fieldset>
<legend>{{ label_settings_email }}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="email_status"><input type="checkbox" id="email_status" name="email_status[]" {{ email_status_checked|raw }} /> {{ label_email_status }}</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox"><input type="checkbox" id="log_email" name="log_email[]" {{ log_email_checked|raw }} /> {{ label_log_email }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_from_name">{{ label_email_from_name }}</label>
<div class="controls">
<input type="text" id="email_from_name" name="email_from_name" value="{{ email_from_name }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_from_email">{{ label_email_from_email }}</label>
<div class="controls">
<input type="text" id="email_from_email" name="email_from_email" value="{{ email_from_email }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="email_smtp"><input type="checkbox" id="email_smtp" name="email_smtp[]" {{ email_smtp_checked|raw }} />{{ label_email_smtp }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_host">{{ label_email_smtp_host }}</label>
<div class="controls">
<input type="text" id="email_smtp_host" name="email_smtp_host" value="{{ email_smtp_host }}" maxlength="100" placeholder="{{ label_email_smtp_host }}" />
<input type="text" class="input-small" id="email_smtp_port" name="email_smtp_port" value="{{ email_smtp_port }}" maxlength="10" placeholder="{{ label_email_smtp_port }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_username">{{ label_email_smtp_username }}</label>
<div class="controls">
<input type="text" id="email_smtp_username" name="email_smtp_username" value="{{ email_smtp_username }}" maxlength="100" placeholder="{{ label_email_smtp_noauth }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email_smtp_password">{{ label_email_smtp_password }}</label>
<div class="controls">
<input type="password" id="email_smtp_password" name="email_smtp_password" value="{{ email_smtp_password }}" maxlength="100" placeholder="{{ label_email_smtp_noauth }}" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary show-modal" data-modal-id="testEmail">{{ label_test }}</button>
<input type="hidden" name="test_email" value="0" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit" name="email_submit" >{{ label_save }}</button>
</div>
</fieldset>
</div>
<div id="config-sms" class="tab-pane {{ sms_active }}">
<fieldset>
<legend>{{ label_settings_sms }}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="sms_status"><input type="checkbox" id="sms_status" name="sms_status[]" {{ sms_status_checked|raw }} /> {{ label_sms_status }}</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox"><input type="checkbox" id="log_sms" name="log_sms[]" {{ log_sms_checked|raw }} /> {{ label_log_sms }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway">{{ label_sms_gateway }}</label>
<div class="controls">
<select id="sms_gateway" name="sms_gateway">
<option value="mosms" {{ sms_selected_mosms|raw }}>{{ label_sms_gateway_mosms }}</option>
<option value="mollie" {{ sms_selected_mollie|raw }}>{{ label_sms_gateway_mollie }}</option>
<option value="spryng" {{ sms_selected_spryng|raw }}>{{ label_sms_gateway_spryng }}</option>
<option value="inetworx" {{ sms_selected_inetworx|raw }}>{{ label_sms_gateway_inetworx }}</option>
<option value="clickatell" {{ sms_selected_clickatell|raw }}>{{ label_sms_gateway_clickatell }}</option>
<option value="textmarketer" {{ sms_selected_textmarketer|raw }}>{{ label_sms_gateway_textmarketer }}</option>
<option value="smsglobal" {{ sms_selected_smsglobal|raw }}>{{ label_sms_gateway_smsglobal }}</option>
<option value="smsit" {{ sms_selected_smsit|raw }}>{{ label_sms_gateway_smsit }}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway_username">{{ label_sms_gateway_username }}</label>
<div class="controls">
<input type="text" id="sms_gateway_username" name="sms_gateway_username" value="{{ sms_gateway_username }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_gateway_password">{{ label_sms_gateway_password }}</label>
<div class="controls">
<input type="password" id="sms_gateway_password" name="sms_gateway_password" value="{{ sms_gateway_password }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms_from">{{ label_sms_from }}</label>
<div class="controls">
<input type="text" id="sms_from" name="sms_from" value="{{ sms_from }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary show-modal" data-modal-id="testSms">{{ label_test }}</button>
<input type="hidden" name="test_sms" value="0" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit" name="sms_submit">{{ label_save }}</button>
</div>
</fieldset>
</div>
<div id="config-pushover" class="tab-pane {{ pushover_active }}">
<fieldset>
<legend>{{ label_settings_pushover }}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="pushover_status"><input type="checkbox" id="pushover_status" name="pushover_status[]" {{ pushover_status_checked|raw }} /> {{ label_pushover_status }}</label>
<p class="help-block">{{ label_pushover_description|raw }}</p>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox"><input type="checkbox" id="log_pushover" name="log_pushover[]" {{ log_pushover_checked|raw }} /> {{ label_log_pushover }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="pushover_api_token">{{ label_pushover_api_token }}</label>
<div class="controls">
<p><button class="btn btn-primary" onclick="window.open('{{ pushover_clone_url }}');return false;">{{ label_pushover_clone_app }}</button></p>
<input type="text" id="pushover_api_token" name="pushover_api_token" value="{{ pushover_api_token }}" maxlength="255" />
<p class="help-block">{{ label_pushover_api_token_description|raw }}</p>
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary show-modal" data-modal-id="testPushover">{{ label_test }}</button>
<input type="hidden" name="test_pushover" value="0" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit" name="pushover_submit">{{ label_save }}</button>
</div>
</fieldset>
</div>
</div>
</form>

View File

@ -0,0 +1,2 @@
<h2>{{ label_title }}</h2>
<p>{{ label_description }}</p>

View File

@ -0,0 +1,61 @@
{% extends "module/install/main.tpl.html" %}
{% use "module/install/results.tpl.html" %}
{% block install %}
<div class="row-fluid">
<div class="span12">{{ block('results') }}</div>
</div>
<div class="row-fluid">
<div class="span6">
<form id="psm_config" class="form-horizontal" action="install.php?action=config" method="post">
<p>Please enter your database info:</p>
<div class="control-group">
<label class="control-label" for="host">Database host</label>
<div class="controls">
<input type="text" id="host" name="host" value="{{ host }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="name">Database name</label>
<div class="controls">
<input type="text" id="name" name="name" value="{{ name }}" placeholder="db name" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="user">Database user</label>
<div class="controls">
<input type="text" id="user" name="user" value="{{ user }}" placeholder="db user" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="pass">Database password</label>
<div class="controls">
<input type="password" id="pass" name="pass" value="{{ pass }}" placeholder="db password" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="prefix">Table prefix</label>
<div class="controls">
<input type="text" id="prefix" name="prefix" value="{{ prefix }}" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Save configuration</button>
</div>
</div>
</form>
</div>
{% if include_config_new_copy %}
<div class="span6">
<h3>Your config file:</h3>
<div class="alert alert-error">Unable to save your configuration.</div>
<p>Your database information is valid, however we are unable to create the configuration file automatically.
Please create a new file in the project directory called "config.php" and copy the information below.</p>
<p>After you have copied the configuration, press the button to continue.</p>
<p class="pull-left"><textarea rows="10">{{ php_config }}</textarea></p>
<p class="offset2"><input type="submit" class="btn btn-primary" value="I have saved the configuration" onclick="location.reload(true);" /></p>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,44 @@
{% extends "module/install/main.tpl.html" %}
{% use "module/install/results.tpl.html" %}
{% block install %}
<p>Sweet, your database connection is up and running!</p>
<p>Next, please set up a new account to access your monitor:</p>
{{ block('results') }}
<p>&nbsp;</p>
<div class="row-fluid">
<div class="span6">
<form id="psm_config" class="form-horizontal" action="install.php?action=install" method="post">
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input type="text" id="username" name="username" value="{{ username }}">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" id="password" name="password" value="">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_repeat">Password repeat</label>
<div class="controls">
<input type="password" id="password_repeat" name="password_repeat" value="">
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">Email</label>
<div class="controls">
<input type="text" id="email" name="email" value="{{ email }}" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary btn-large">Install</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "module/install/main.tpl.html" %}
{% block install %}
<p>We have discovered a previous version.</p>
<p>In the next step we will upgrade your database to the latest version.</p>
{{ block('results') }}
<p>&nbsp;</p>
<p><a class="btn btn-primary btn-large" href="install.php?action=install">Upgrade to {{ version }}</a></p>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends "module/install/main.tpl.html" %}
{% use "module/install/results.tpl.html" %}
{% block install %}
<p>Welcome to the installation of PHP Server Monitor. This page will guide you through the steps to install or upgrade your monitor.</p>
<p>Before we start, we need to verify your system meets the requirements.
If you see any errors in the list below, you may still continue, but PHP Server Monitor may not work correctly.
It is recommended you fix any errors before continuing.
</p>
{{ block('results') }}
<p>&nbsp;</p>
<p>
<a class="btn btn-primary btn-large" href="install.php?action=config">Let's go</a>
</p>
{% endblock %}

View File

@ -0,0 +1,8 @@
<div class="hero-unit">
<div class="install_header">
<p class="pull-left"><a href="http://www.phpservermonitor.org/"><img class="pull-left" src="static/phpservermon.png" alt="" /></a></p>
<h2>&nbsp;PHP Server Monitor</h2>
<p class="clearfix"></p>
</div>
{% block install %} {% endblock %}
</div>

View File

@ -0,0 +1,10 @@
{% block results %}
{% if messages %}
{% for msg in messages %}
<div>
<p class="pull-left"><span class="label label-{{ msg.shortcode }}">{{ msg.shortcode }}</span></p>
<p class="offset1">{{ msg.message }}</p>
</div>
{% endfor %}
{% endif %}
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "module/install/main.tpl.html" %}
{% use "module/install/results.tpl.html" %}
{% block install %}
<div class="row-fluid">
<div class="span12">{{ block('results') }}</div>
</div>
<div class="row-fluid">
<div class="span12">
<p>&nbsp;</p>
<p>The installation is complete. Please check above if errors have occurred.<br>
If no errors have occurred, you are good to go.<br><br></p>
<p>
<a class="btn btn-primary btn-large" href="index.php">Go to your monitor</a>
<a class="btn btn-large" target="_blank" href="http://www.phpservermonitor.org/">PHP Server Monitor</a>
<a class="btn btn-large" target="_blank" href="http://docs.phpservermonitor.org/">Documentation</a>
</p>
</div>
</div>
{% endblock %}

View File

@ -1,4 +1,3 @@
<!--%tpl_server_history-->
<link href="static/plugin/jqplot/jquery.jqplot.min.css" rel="stylesheet" >
<!--[if lt IE 9]><script type="text/javascript" src="static/plugin/excanvas.js"></script><![endif]-->
<script type="text/javascript" src="static/plugin/jqplot/jquery.jqplot.min.js"></script>
@ -9,19 +8,19 @@
<link href="static/css/history.css" rel="stylesheet" >
<script type="text/javascript">
var day_format = '{day_format}';
var long_date_format = '{long_date_format}';
var short_date_format = '{short_date_format}';
var short_time_format = '{short_time_format}';
var day_format = '{{ day_format }}';
var long_date_format = '{{ long_date_format }}';
var short_date_format = '{{ short_date_format }}';
var short_time_format = '{{ short_time_format }}';
</script>
<script type="text/javascript" src="static/js/history.js"></script>
<div id="history-panel">
<!--%tpl_repeat_graphs-->
{% for graph in graphs %}
<div class="chart-row">
<div class="chart-container">
<div class="chart-content">
<div id="chart{chart_id}" class="chart" data-title="{title}" data-plotMode="{plotmode}" data-endTime="{end_timestamp}" data-series="{series}" data-lines="{server_lines}" data-down="{server_down}"></div>
<div id="chart{{ graph.chart_id }}" class="chart" data-title="{{ graph.title }}" data-plotMode="{{ graph.plotmode }}" data-endTime="{{ graph.end_timestamp }}" data-series="{{ graph.series|raw }}" data-lines="{{ graph.server_lines }}" data-down="{{ graph.server_down }}"></div>
</div>
</div>
<div class="info-container">
@ -29,25 +28,28 @@
<div class="info-dropdown btn-group">
<button class="btn dropdown-toggle" data-toggle="dropdown"><i class="icon-info-sign"></i></button>
<ul class="dropdown-menu">
<li><span>{label_latency_avg}: {latency_avg}</span></li>
{% for record in graph.info %}
<li><span>{{ record.label }}: {{ record.value }}</span></li>
{% endfor %}
</ul>
</div>
<div class="server-info">
{label_latency_avg}: {latency_avg}<br/>
<ul>
{% for record in graph.info %}
<li><span>{{ record.label }}: {{ record.value }}</span></li>
{% endfor %}
</ul>
</div>
</div>
<div class="chart-selector">
<div class="btn-group">
<!--%tpl_repeat_buttons-->
<button class="btn {class_active}" data-chartId="{chart_id}" data-chartMode="{mode}" >{label}</button>
<!--%%tpl_repeat_buttons-->
{buttons}
{% for button in graph.buttons %}
<button class="btn {{ button.class_active }}" data-chartId="{{ graph.chart_id }}" data-chartMode="{{ button.mode }}" >{{ button.label }}</button>
{% endfor %}
</div>
</div>
</div>
</div>
<div style="clear: both;">&nbsp;</div>
<!--%%tpl_repeat_graphs-->
{graphs}
</div>
<!--%%tpl_server_history-->
{% endfor %}
</div>

View File

@ -0,0 +1,60 @@
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><a href="#log_status_content" data-toggle="tab">{{ label_status }}</a></li>
<li><a href="#log_email_content" data-toggle="tab">{{ label_email }}</a></li>
<li><a href="#log_sms_content" data-toggle="tab">{{ label_sms }}</a></li>
<li><a href="#log_pushover_content" data-toggle="tab">{{ label_pushover }}</a></li>
</ul>
<div class="tab-content well">
{% for tab in tabs %}
<div class="tab-pane {{ tab.tab_active }}" id="log_{{ tab.id }}_content">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th class="hidden-phone">{{ label_server }}</th>
<th class="hidden-phone">{{ label_message }}</th>
<th class="hidden-phone">{{ label_date }}</th>
{% if tab.has_users %} <th class="hidden-phone">{{ label_users }}</th> {% endif %}
</tr>
</thead>
<tbody>
{% for entry in tab.entries %}
<tr class="{{ entry.class }}">
<td>
<div class="table-body">
<div class="table-cell">
<div class="visible-phone pull-right">
&nbsp;{{ entry.datetime_format }}
</div>
<i class="{{ entry.type_icon }}" title="{{ entry.type_title }}"></i> <span class="title">{{ entry.server }}</span> {{ entry.ip }}
</div>
</div>
<div class="visible-phone">
<div class="table-separator"/></div>
<div class="table-body">
<div class="table-cell-details">{{ entry.message|raw }}</div>
</div>
</div>
{% if tab.has_users %}<div class="visible-phone">
<div class="table-separator"/></div>
<div class="table-body">
<div class="table-cell-details">{{ label_users }}: {{ entry.user_list|raw }}</div>
</div>
</div>{% endif %}
</td>
<td class="hidden-phone">{{ entry.message|raw }}</td>
<td class="hidden-phone tight">{{ entry.datetime_format }}</td>
{% if tab.has_users %}<td class="hidden-phone tight">{{ entry.users|raw }}</td>{% endif %}
</tr>
{% endfor %}
{% if tab.no_logs %}
<tr class="{{ class }}">
<td colspan="4" class="cell-center">{{ label_no_logs }}</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</div>

View File

@ -0,0 +1,66 @@
<table class="table table-bordered table-striped">
<thead>
<tr>
<th class="hidden-phone">&nbsp;</th>
<th class="hidden-phone">{{ label_label }}</th>
<th class="hidden-phone">{{ label_domain }}</th>
<th class="visible-desktop">{{ label_port }}</th>
<th class="visible-desktop">{{ label_type }}</th>
<th class="hidden-phone">{{ label_rtime }}</th>
<th class="hidden-phone">{{ label_last_online }}</th>
<th class="hidden-phone">{{ label_monitoring }}</th>
<th class="hidden-phone">{{ label_action }}</th>
</tr>
</thead>
<tbody>
{% for server in servers %}
<tr>
<td class="hidden-phone"><div class="table-cell-title"><span class="label label-status-{{ server.status }}"><a href="{{ server.url_view|raw }}" title="{{ server.error }}">{{ server.status }}</a></span></div></td>
<td class="hidden-phone"><div class="table-cell-title"><a href="{{ server.url_view|raw }}">{{ server.label }}</a></div></td>
<td class="nowrap visible-tablet"><div class="table-cell-title"><i class="{{ server.type_icon }}" title="{{ server.type }}"></i> {{ server.ip_short|raw }}</div></td>
<td class="nowrap visible-desktop"><div class="table-cell-title">{{ server.ip|raw }}</div></td>
<td class="nowrap visible-desktop"><div class="table-cell-title">{{ server.port }}</div></td>
<td class="nowrap visible-desktop"><div class="table-cell-title">{{ server.type }}</div></td>
<td class="nowrap hidden-phone"><div class="table-cell-title">{{ server.rtime }} s</div></td>
<td class="nowrap hidden-phone"><div class="table-cell-title">{{ server.last_online }}</div></td>
<td class="tight hidden-phone"><div class="table-cell-title"><i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i> <i class="{{ server.email_icon }}" title="{{ label_email }}"></i> <i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i> <i class="{{ server.pushover_icon }}" title="Pushover"></i></div></td>
<td class="tight hidden-phone">
<div class="table-cell-title">
<a class="btn btn-small" href="{{ server.url_view|raw }}"><i class="icon-chart"></i></a>
{% if user_level == 10 %}
<a class="btn btn-small" href="{{ server.url_edit|raw }}" title="{{ label_edit }}"><i class="icon-pencil"></i></a>
<a class="btn btn-small btn-danger show-modal" href="{{ server.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete" data-modal-param="{{ server.label }}"><i class="icon-remove icon-white"></i></a>
{% endif %}
</div>
</td>
<td class="visible-phone">
<div class="table-body">
<div class="table-cell-title">
<span class="label label-status-{{ server.status }}"><a href="{{ server.url_view|raw }}" title="{{ server.error }}">{{ server.status }}</a></span>
<a class="title" href="{{ server.url_view|raw }}">{{ server.label }}</a>
</div>
<div class="table-cell tight">
&nbsp;<a class="btn btn-small" href="{{ server.url_view|raw }}"><i class="icon-chart"></i></a>
{% if user_level == 10 %}
<a class="btn btn-small" href="{{ server.url_edit|raw }}" title="{{ label_edit }}"><i class="icon-pencil"></i></a>
<a class="btn btn-small btn-danger show-modal" href="{{ server.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete" data-modal-param="{{ server.label }}"><i class="icon-remove icon-white"></i></a>
{% endif %}
</div>
</div>
<div class="table-body">
<div class="table-row">
<div class="table-cell"><i class="{{ server.type_icon }}" title="{{ server.type }}"></i> {{ server.ip_short|raw }}</div>
<div class="table-cell tight">
<i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i> <i class="{{ server.email_icon }}" title="{{ label_email }}"></i> <i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i> <i class="{{ server.pushover_icon }}" title="Pushover"></i>
</div>
</div>
</div>
<div class="table-body">
<div class="table-row"><div class="table-cell-details tight">{{ label_rtime }}: &nbsp;</div><div class="table-cell-details">{{ server.rtime }} s</div></div>
<div class="table-row"><div class="table-cell-details tight">{{ label_last_online }}: &nbsp;</div><div class="table-cell-details">{{ server.last_online }}</div></div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,106 @@
<form class="form-horizontal well" action="{{ url_save|raw }}" method="post">
<fieldset>
<legend>{{ titlemode }}</legend>
<div class="control-group">
<label class="control-label" for="label">{{ label_label }}</label>
<div class="controls">
<input type="text" id="label" name="label" value="{{ edit_value_label }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="ip">{{ label_domain }}</label>
<div class="controls">
<input type="text" id="ip" name="ip" value="{{ edit_value_ip }}" maxlength="100" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="type">{{ label_type }}</label>
<div class="controls">
<select id="type" name="type">
<option value="service" {{ edit_type_selected_service|raw }}>{{ label_service }}</option>
<option value="website" {{ edit_type_selected_website|raw }}>{{ label_website }}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="port">{{ label_port }}</label>
<div class="controls">
<input class="input-mini" type="text" id="port" name="port" value="{{ edit_value_port }}" maxlength="5" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="pattern">{{ label_pattern }}</label>
<div class="controls">
<input type="text" id="pattern" name="pattern" value="{{ edit_value_pattern }}" maxlength="255" data-toggle="tooltip" title="{{ label_pattern_description }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="warning_threshold">{{ label_warning_threshold }}</label>
<div class="controls">
<input class="input-mini" type="text" id="warning_threshold" name="warning_threshold" value="{{ edit_value_warning_threshold }}" maxlength="5" data-toggle="tooltip" title="{{ label_warning_threshold_description }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="timeout">{{ label_timeout }}</label>
<div class="controls">
<input class="input-mini" type="text" id="timeout" name="timeout" value="{{ edit_value_timeout }}" placeholder="{{ default_value_timeout }}" maxlength="10" data-toggle="tooltip" title="{{ label_timeout_description }}" /> s
</div>
</div>
<div class="control-group">
<label class="control-label" for="active">{{ label_monitoring }}</label>
<div class="controls">
<select id="active" name="active">
<option value="yes" {{ edit_active_selected_yes|raw }}>{{ label_yes }}</option>
<option value="no" {{ edit_active_selected_no|raw }}>{{ label_no }}</option>
</select>
</div>
</div>
<div class="control-group {{ control_class_email }}">
<label class="control-label" for="email">{{ label_send_email }}
{% if warning_email %} <p class="help-inline"><i class="icon-warning-sign" data-toggle="tooltip" title="{{ label_warning_email }}"></i></p> {% endif %}
</label>
<div class="controls">
<select id="email" name="email">
<option value="yes" {{ edit_email_selected_yes|raw }}>{{ label_yes }}</option>
<option value="no" {{ edit_email_selected_no|raw }}>{{ label_no }}</option>
</select>
</div>
</div>
<div class="control-group {{ control_class_sms }}">
<label class="control-label" for="sms">{{ label_send_sms }}
{% if warning_sms %} <p class="help-inline"><i class="icon-warning-sign" data-toggle="tooltip" title="{{ label_warning_sms }}"></i></p> {% endif %}
</label>
<div class="controls">
<select id="sms" name="sms">
<option value="yes" {{ edit_sms_selected_yes|raw }}>{{ label_yes }}</option>
<option value="no" {{ edit_sms_selected_no|raw }}>{{ label_no }}</option>
</select>
</div>
</div>
<div class="control-group {{ control_class_pushover }}">
<label class="control-label" for="pushover">{{ label_pushover }}
{% if warning_pushover %} <p class="help-inline"><i class="icon-warning-sign" data-toggle="tooltip" title="{{ label_warning_pushover }}"></i></p> {% endif %}
</label>
<div class="controls">
<select id="pushover" name="pushover">
<option value="yes" {{ edit_pushover_selected_yes|raw }}>{{ label_yes }}</option>
<option value="no" {{ edit_pushover_selected_no|raw }}>{{ label_no }}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="user_id">{{ label_users }}</label>
<div class="controls">
<select class="multiselect" multiple="multiple" id="user_id" name="user_id[]">
{% for user in users %}
<option value="{{ user.user_id }}" {{ user.edit_selected|raw }}> {{ user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{{ label_save }}</button>
<a class="btn" href="{{ url_go_back|raw }}" >{{ label_go_back }}</a>
</div>
</fieldset>
</form>

View File

@ -0,0 +1,91 @@
<table class="table table-bordered">
<colgroup>
<col class="oce-first" />
<col />
</colgroup>
<thead>
<tr class="head">
<th colspan="2">
<div class="btn-group">
<button class="btn btn-success dropdown-toggle" data-toggle="dropdown">
<i class="icon-th icon-white"></i>&nbsp;{{ label }}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for option in options %}
<li class="{{ option.class_active }}"><a href="{{ option.url|raw }}">{{ option.label }}</a>
{% endfor %}
</ul>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ label_status }}:</td>
<td>
<span class="label label-status-{{ status }}">
<a href="#" title="{{ error }}">{{ status }}</a>
</span>&nbsp;{{ error }}
</td>
</tr>
<tr>
<td>{{ label_type }}:</td>
<td>{{ type }}</td>
</tr>
<tr>
<td>{{ label_domain }}:</td>
<td>{{ ip|raw }}</td>
</tr>
<tr>
<td>{{ label_port }}:</td>
<td>{{ port }}</td>
</tr>
<tr>
<td>{{ label_last_check }}:</td>
<td>{{ last_check }}</td>
</tr>
<tr>
<td>{{ label_last_online }}:</td>
<td>{{ last_online }}</td>
</tr>
<tr>
<td>{{ label_rtime }}:</td>
<td>{{ rtime }} s</td>
</tr>
<tr>
<td>{{ label_monitoring }}:</td>
<td>{{ active }}</td>
</tr>
<tr>
<td>{{ label_email }}:</td>
<td>{{ email }}</td>
</tr>
<tr>
<td>{{ label_sms }}:</td>
<td>{{ sms }}</td>
</tr>
<tr>
<td>{{ label_pushover }}:</td>
<td>{{ pushover }}</td>
</tr>
<tr>
<td>{{ label_timeout }}:</td>
<td>{{ timeout }} s</td>
</tr>
{% if has_admin_actions %}
<tr>
<td class="hidden-small">&nbsp;</td>
<td class="action-small" colspan="2">
<a class="btn btn-success" href="{{ url_edit|raw }}">
<i class="icon-edit icon-white"></i>&nbsp;{{ label_edit }}
</a>
<a class="btn btn-danger show-modal" href="{{ url_delete|raw }}" data-modal-id="delete" data-modal-param="{{ label }}">
<i class="icon-remove icon-white"></i>&nbsp;{{ label_delete }}
</a>
</td>
</tr>
{% endif %}
</tbody>
</table>
{{ html_history|raw }}

View File

@ -0,0 +1,4 @@
<div class="btn-group" data-toggle="buttons-radio">
<button class="btn {{ block_layout_active }}" data-toggle="tab" data-target="#flow-layout" onclick="psm_saveLayout(0)"><i class="icon-th-large"></i></button>
<button class="btn {{ list_layout_active }}" data-toggle="tab" data-target="#list-layout" onclick="psm_saveLayout(1)"><i class="icon-th-list"></i></button>
</div>

View File

@ -0,0 +1,60 @@
<div class="tab-content">
<div id="flow-layout" class="tab-pane {{ block_layout_active }}">
<div class="entity-container">
{% for server in servers_offline %}
<div class="offline">
<div class="entity {{ server.class_warning }}" onclick="window.location.href='{{ server.url_view|raw }}'">
<h2>{{ server.label }}</h2>
<p>{{ label_last_online }}: {{ server.last_online_nice }}</p>
<p>{{ label_last_check }}: {{ server.last_checked_nice }}</p>
</div>
</div>
{% endfor %}
{% for server in servers_online %}
<div class="online">
<div class="entity" onclick="window.location.href='{{ server.url_view|raw }}'">
<h2>{{ server.label }}</h2>
<p>{{ label_last_online }}: {{ server.last_online_nice }}</p>
<p>{{ label_rtime }}: {{ server.rtime }}s</p>
</div>
</div>
{% endfor %}
</div>
</div>
<div id="list-layout" class="tab-pane {{ list_layout_active }}">
<div class="entity-container">
<table class="table table-bordered">
<tbody>
{% for server in servers_offline %}
<tr class="row-offline" onclick="window.location.href='{{ server.url_view|raw }}'">
<td class="{{ server.class_warning }}"><div class="server-name">{{ server.label }}</div>
<div class="visible-phone">
<div class="table-body">
<div class="table-row"><div class="table-cell-details tight">{{ label_last_online }}: &nbsp;</div><div class="table-cell-details">{{ server.last_online_nice }}</div></div>
<div class="table-row"><div class="table-cell-details tight">{{ label_last_check }}: &nbsp;</div><div class="table-cell-details">{{ server.last_checked_nice }}</div></div>
</div>
</div>
</td>
<td class="{{ server.class_warning }} hidden-phone">{{ label_last_online }}: {{ server.last_online_nice }}</td>
<td class="{{ server.class_warning }} hidden-phone">{{ label_last_check }}: {{ server.last_checked_nice }}</td>
</tr>
{% endfor %}
{% for server in servers_online %}
<tr class="row-online" onclick="window.location.href='{{ server.url_view|raw }}'">
<td><div class="server-name">{{ server.label }}</div>
<div class="visible-phone">
<div class="table-body">
<div class="table-row"><div class="table-cell-details tight">{{ label_last_online }}: &nbsp;</div><div class="table-cell-details">{{ server.last_online_nice }}</div></div>
<div class="table-row"><div class="table-cell-details tight">{{ label_rtime }}: &nbsp;</div><div class="table-cell-details">{{ server.rtime }}</div></div>
</div>
</div>
</td>
<td class="hidden-phone">{{ label_last_online }}: {{ server.last_online_nice }}</td>
<td class="hidden-phone">{{ label_rtime }}: {{ server.rtime }}s</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,8 @@
<div class="container">
<form class="form-signin" method="post">
<h3 class="form-signin-heading">{{ title_forgot }}</h3>
<input type="text" name="user_name" class="input-block-level" placeholder="{{ label_username }}" value="{{ value_user_name }}" required>
<button class="btn btn-primary" type="submit">{{ label_submit }}</button>
<a class="btn" href="?">{{ label_go_back }}</a>
</form>
</div>

View File

@ -0,0 +1,13 @@
<div class="container">
<form class="form-signin" method="post">
<h3 class="form-signin-heading">{{ title_sign_in }}</h3>
<input type="text" name="user_name" class="input-block-level" placeholder="{{ label_username }}" value="{{ value_user_name }}" required>
<input type="password" name="user_password" class="input-block-level" placeholder="{{ label_password }}" required>
<input type="hidden" name="action" value="login">
<label class="checkbox">
<input type="checkbox" name="user_rememberme" value="1" {{ value_rememberme }}> {{ label_remember_me }}
</label>
<button class="btn btn-primary" type="submit">{{ label_login }}</button>
<a class="btn" href="?action=forgot">{{ label_password_forgot }}</a>
</form>
</div>

View File

@ -0,0 +1,10 @@
<div class="container">
<form class="form-signin" method="post">
<h3 class="form-signin-heading">{{ title_reset }}</h3>
<input type="text" name="user_name" class="input-block-level" placeholder="{{ label_username }}" value="{{ value_user_name }}" required disabled="disabled">
<input type="password" name="user_password_new" class="input-block-level" placeholder="{{ label_password }}" required autocomplete="off">
<input type="password" name="user_password_repeat" class="input-block-level" placeholder="{{ label_password_repeat }}" required autocomplete="off">
<button class="btn btn-primary" type="submit">{{ label_reset }}</button>
<a class="btn" href="?">{{ label_go_back }}</a>
</form>
</div>

View File

@ -0,0 +1,71 @@
<form class="form-horizontal well" action="{{ form_action|raw }}" method="post">
<fieldset>
<div class="row-fluid">
<div class="span6">
<div class="control-group">
<label class="control-label" for="user_name">{{ label_user_name }}</label>
<div class="controls">
<input type="text" id="user_name" name="user_name" value="{{ user_name }}" maxlength="64" required autofocus=>
</div>
</div>
<div class="control-group">
<label class="control-label" for="name">{{ label_name }}</label>
<div class="controls">
<input type="text" id="name" name="name" value="{{ name }}" maxlength="255" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="level">{{ label_level }}</label>
<div class="controls"><input type="text" value="{{ level }}" disabled="disabled" /></div>
</div>
<div class="control-group">
<label class="control-label" for="password">{{ label_password }}</label>
<div class="controls">
<input type="password" id="password" name="password" maxlength="255" placeholder="{{ placeholder_password }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_repeat">{{ label_password_repeat }}</label>
<div class="controls">
<input type="password" id="password_repeat" name="password_repeat" maxlength="255" placeholder="{{ placeholder_password }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">{{ label_email }}</label>
<div class="controls">
<input type="text" id="email" name="email" value="{{ email }}" maxlength="255" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">{{ label_mobile }}</label>
<div class="controls">
<input type="text" id="mobile" name="mobile" value="{{ mobile }}" maxlength="15" />
</div>
</div>
</div>
<div class="span6">
<div class="control-group">
<label class="control-label">{{ label_pushover }}</label>
<div class="controls">{{ label_pushover_description|raw }} </div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_pushover_key }}</label>
<div class="controls">
<input type="text" id="pushover_key" name="pushover_key" value="{{ pushover_key }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_pushover_device }}</label>
<div class="controls">
<input type="text" id="pushover_device" name="pushover_device" value="{{ pushover_device }}" maxlength="255" data-toggle="tooltip" title="{{ label_pushover_device_description }}" />
</div>
</div>
</div>
</div>
<div class="row-fluid">
<div class="form-actions">
<button class="btn btn-success" type="submit">{{ label_save }}</button>
</div>
</div>
</fieldset>
</form>

View File

@ -0,0 +1,66 @@
<table class="table table-bordered table-striped">
<thead>
<tr>
<th class="hidden-phone">{{ label_user }}</th>
<th class="visible-desktop">{{ label_name }}</th>
<th class="visible-desktop">{{ label_level }}</th>
<th class="hidden-phone">{{ label_email }}</th>
<th class="hidden-phone">{{ label_mobile }}</th>
<th class="hidden-phone">{{ label_servers }}</th>
<th class="hidden-phone tight">{{ label_action }}</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>
<div class="table-body">
<div class="table-cell-title">
<span class="nowrap">
<span class="hidden-desktop">
{% if user.level == '10' %}
<i class="icon-admin" title="{{ user.level_text }}"></i>&nbsp;
{% elseif user.level == '20' %}
<i class="icon-user" title="{{ user.level_text }}"></i>&nbsp;
{% endif %}
</span>
<span class="title">{{ user.user_name }}</span>
</span>
<span class="hidden-desktop">({{ user.name }})</span>
</div>
<div class="table-cell tight">
<div class="visible-phone">
<a class="btn btn-small" href="{{ user.url_edit|raw }}" title="{{ user.label_edit }}">
<i class="icon-pencil"></i>
</a>
<a class="btn btn-small btn-danger show-modal" href="{{ user.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete" data-modal-param="{{ user.user_name }}">
<i class="icon-remove icon-white"></i>
</a>
</div>
</div>
</div>
<div class="visible-phone">
<div class="table-body">
<div class="table-row"><div class="table-cell-details tight">{{ label_email }}:&nbsp;</div><div class="table-cell-details">{{ user.email }}</div></div>
<div class="table-row"><div class="table-cell-details tight">{{ label_mobile }}:&nbsp;</div><div class="table-cell-details">{{ user.mobile }}</div></div>
<div class="table-row"><div class="table-cell-details tight">{{ label_servers }}:&nbsp;</div><div class="table-cell-details">{% for server in user.emp_servers %} {{ server.label }}<br/> {% endfor %}</div></div>
</div>
</div>
</td>
<td class="visible-desktop nowrap"><div class="table-cell-title">{{ user.name }}</div></td>
<td class="visible-desktop tight"><div class="table-cell-title">{{ user.level_text }}</div></td>
<td class="hidden-phone tight"><div class="table-cell-title">{{ user.email }}</div></td>
<td class="hidden-phone tight"><div class="table-cell-title">{{ user.mobile }}</div></td>
<td class="hidden-phone"><div class="table-cell-title">{% for server in user.emp_servers %} {{ server.label }}<br/> {% endfor %}</div></td>
<td class="hidden-phone tight">
<a class="btn btn-small" href="{{ user.url_edit|raw }}" title="{{ label_edit }}">
<i class="icon-pencil"></i>
</a>
<a class="btn btn-small btn-danger show-modal" href="{{ user.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete" data-modal-param="{{ user.user_name }}">
<i class="icon-remove icon-white"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,82 @@
<form class="form-horizontal well" action="{{ url_save|raw }}" method="post">
<fieldset>
<legend>{{ titlemode }}</legend>
<div class="control-group">
<label class="control-label" for="user_name">{{ label_user_name }}</label>
<div class="controls">
<input type="text" id="user_name" name="user_name" value="{{ edit_value_user_name }}" maxlength="64" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="name">{{ label_name }}</label>
<div class="controls">
<input type="text" id="name" name="name" value="{{ edit_value_name }}" maxlength="255" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="level">{{ label_level }}</label>
<div class="controls">
<select id="level" name="level">
{% for level in levels %}
<option value="{{ level.value }}" {% if level.value == user_level %} selected="selected" {% endif %}>{{ level.label }}</option>
{% endfor %}
</select>
<p class="help-block">{{ label_level_description|raw }}</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">{{ label_password }}</label>
<div class="controls">
<input type="password" id="password" name="password" maxlength="255" placeholder="{{ placeholder_password }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_repeat">{{ label_password_repeat }}</label>
<div class="controls">
<input type="password" id="password_repeat" name="password_repeat" maxlength="255" placeholder="{{ placeholder_password }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">{{ label_email }}</label>
<div class="controls">
<input type="text" id="email" name="email" value="{{ edit_value_email }}" maxlength="255" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_mobile }}</label>
<div class="controls">
<input type="text" id="mobile" name="mobile" value="{{ edit_value_mobile }}" maxlength="15" />
</div>
</div>
<div class="control-group">
<label class="control-label">{{ label_pushover }}</label>
<div class="controls">{{ label_pushover_description|raw }} </div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_pushover_key }}</label>
<div class="controls">
<input type="text" id="pushover_key" name="pushover_key" value="{{ edit_value_pushover_key }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_pushover_device }}</label>
<div class="controls">
<input type="text" id="pushover_device" name="pushover_device" value="{{ edit_value_pushover_device }}" maxlength="255" data-toggle="tooltip" title="{{ label_pushover_device_description }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="server_id">{{ label_servers }}</label>
<div class="controls">
<select class="multiselect" multiple="multiple" id="server_id" name="server_id[]">
{% for server in servers %}
<option value="{{ server.server_id }}" {{ server.edit_selected }}> {{ server.label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{{ label_save }}</button>
<button class="btn" onclick="history.back();return false;" >{{ label_go_back }}</button>
</div>
</fieldset>
</form>

View File

@ -0,0 +1,14 @@
<div id="{{ modal_id }}Modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="{{ modal_id }}ModalLabel" aria-hidden="true">
<div class="modal-header">
<h3 id="{{ modal_id }}ModalLabel">{{ modal_title }}</h3>
</div>
<div class="modal-body">
<p>{{ modal_body|raw }}</p>
</div>
<div class="modal-footer">
{% if has_cancel %}
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">{{ label_cancel }}</button>
{% endif %}
<button class="btn btn-{{ modal_button_type }} modalOKButton" >{{ modal_button_label }}</button>
</div>
</div>

View File

@ -0,0 +1,26 @@
<div id="sidebar-container">
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">{{ subtitle }}</li>
{% for item in items %}
<li class="{{ item.class_active }}">
{% if item.type == 'link' %}
<a href="{{ item.url|raw }}"><i class="icon-{{ item.icon }}"></i>&nbsp;{{ item.label }}</a>
{% elseif item.type == 'button' %}
<button class="btn btn-{{ item.btn_class }}" onclick="{{ item.onclick|raw }}"><i class="icon-{{ item.icon }}"></i>&nbsp;{{ item.label }}</button>
{% elseif item.type == 'dropdown' %}
<div class="btn-group">
<button class="btn btn-{{ item.btn_class }} dropdown-toggle" data-toggle="dropdown"><i class="icon-{{ item.icon }}"></i>&nbsp;{{ item.label }} <span class="caret"></span></button>
<ul class="dropdown-menu">
{% for option in item.options %}
<li class="{{ option.class_active }}"><a href="{{ option.url|raw }}">{{ option.label }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
</li>
{% endfor %}
</ul>
<div class="clearfix"></div>
</div>
</div>

View File

@ -1,160 +0,0 @@
<!--%tpl_install-->
<div class="hero-unit">
<h2><a href="http://www.phpservermonitor.org/"><img class="pull-right" src="static/opensource.png" width="100" alt="" /></a> &nbsp;PHP Server Monitor</h2>
<p>&nbsp;</p>
{html_install}
</div>
<!--%%tpl_install-->
<!--%tpl_install_index-->
<p>Welcome to the installation of PHP Server Monitor. This page will guide you through the steps to install or upgrade your monitor.</p>
<p>Before we start, we need to verify your system meets the requirements.
If you see any errors in the list below, you may still continue, but PHP Server Monitor may not work correctly.
It is recommended you fix any errors before continuing.
</p>
{html_results}
<p>&nbsp;</p>
<p>
<a class="btn btn-primary btn-large" href="install.php?action=config">Let's go</a>
</p>
<!--%%tpl_install_index-->
<!--%tpl_install_config_upgrade-->
<p>We have discovered a previous version.</p>
<p>In the next step we will upgrade your database to the latest version.</p>
{html_results}
<p>&nbsp;</p>
<p><a class="btn btn-primary btn-large" href="install.php?action=install">Upgrade to {version}</a></p>
<!--%%tpl_install_config_upgrade-->
<!--%tpl_install_config_new_user-->
<p>Sweet, your database connection is up and running!</p>
<p>Next, please set up a new account to access your monitor:</p>
{html_results}
<p>&nbsp;</p>
<div class="row-fluid">
<div class="span6">
<form id="psm_config" class="form-horizontal" action="install.php?action=install" method="post">
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input type="text" id="username" name="username" value="{username}">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" id="password" name="password" value="">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_repeat">Password repeat</label>
<div class="controls">
<input type="password" id="password_repeat" name="password_repeat" value="">
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">Email</label>
<div class="controls">
<input type="text" id="email" name="email" value="{email}" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary btn-large">Install</button>
</div>
</div>
</form>
</div>
{html_config_copy}
</div>
<!--%%tpl_install_config_new_user-->
<!--%tpl_install_config_new-->
<div class="row-fluid">
<div class="span12">{html_results}</div>
</div>
<div class="row-fluid">
<div class="span6">
<form id="psm_config" class="form-horizontal" action="install.php?action=config" method="post">
<p>Please enter your database info:</p>
<div class="control-group">
<label class="control-label" for="host">Database host</label>
<div class="controls">
<input type="text" id="host" name="host" value="{host}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="name">Database name</label>
<div class="controls">
<input type="text" id="name" name="name" value="{name}" placeholder="db name" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="user">Database user</label>
<div class="controls">
<input type="text" id="user" name="user" value="{user}" placeholder="db user" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="pass">Database password</label>
<div class="controls">
<input type="password" id="pass" name="pass" value="{pass}" placeholder="db password" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="prefix">Table prefix</label>
<div class="controls">
<input type="text" id="prefix" name="prefix" value="{prefix}" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Save configuration</button>
</div>
</div>
</form>
</div>
{html_config_copy}
</div>
<!--%%tpl_install_config_new-->
<!--%tpl_install_config_new_copy-->
<div class="span6">
<h3>Your config file:</h3>
<div class="alert alert-error">Unable to save your configuration.</div>
<p>Your database information is valid, however we are unable to create the configuration file automatically.
Please create a new file in the project directory called "config.php" and copy the information below.</p>
<p>After you have copied the configuration, press the button to continue.</p>
<p class="pull-left"><textarea rows="10">{php_config}</textarea></p>
<p class="offset2"><input type="submit" class="btn btn-primary" value="I have saved the configuration" onclick="location.reload(true);" /></p>
</div>
<!--%%tpl_install_config_new_copy-->
<!--%tpl_install_success-->
<div class="row-fluid">
<div class="span12">{html_results}</div>
</div>
<div class="row-fluid">
<div class="span12">
<p>&nbsp;</p>
<p>The installation is complete. Please check above if errors have occurred.<br>
If no errors have occurred, you are good to go.<br><br></p>
<p>
<a class="btn btn-primary btn-large" href="index.php">Go to your monitor</a>
<a class="btn btn-large" target="_blank" href="http://www.phpservermonitor.org/">PHP Server Monitor</a>
<a class="btn btn-large" target="_blank" href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>
</p>
</div>
</div>
<!--%%tpl_install_success-->
<!--%tpl_install_results-->
<!--%tpl_repeat_resultmsgs-->
<div>
<p class="pull-left"><span class="label label-{shortcode}">{shortcode}</span></p>
<p class="offset1">{message}</p>
</div>
<!--%%tpl_repeat_resultmsgs-->
{resultmsgs}
<!--%%tpl_install_results-->

View File

@ -1,110 +0,0 @@
<!--%tpl_main-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1">
<meta name="description" content="">
<meta name="author" content="">
{auto_refresh}
<!-- Le styles -->
<link href="static/plugin/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="static/plugin/twitter-bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="static/css/style.css" rel="stylesheet">
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript" src="static/plugin/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="static/plugin/twitter-bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="static/js/scripts.js"></script>
<script type="text/javascript">
$(document).bind('ready', function(){
psm_flash_message();
psm_tooltips();
});
</script>
</head>
<body data-spy="scroll" data-target=".subnav" data-offset="50">
<!-- navbar -->
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="index.php">{title}</a>
{html_menu}
</div>
</div>
</div>
<!-- /navbar -->
<!-- container -->
<div class="container-fluid">
<div class="page-header">
<h1>{subtitle}</h1>
</div>
<div class="row-fluid">
{html_sidebar}
<div class="span{content_span}">
<div id="flashmessage" class="hide">
<!--%tpl_repeat_messages-->
<div class="alert alert-{shortcode}">
<p class="pull-left span1"><i class="icon-{icon}"></i></p>
<p>{message}</p>
</div>
<!--%%tpl_repeat_messages-->
{messages}
</div>
{content}
</div>
</div>
{html_footer}
</div>
<!-- /container -->
</body>
</html>
<!--%%tpl_main-->
<!--%tpl_main_menu-->
<div class="nav-collapse">
<ul class="nav">
<!--%tpl_repeat_menu-->
<li class="{active}">
<a href="{url}">{label}</a>
</li>
<!--%%tpl_repeat_menu-->
{menu}
<li id="nav_option_help">
<a href="http://www.phpservermonitor.org/" target="_blank">{label_help}</a>
</li>
</ul>
<ul class="nav pull-right">
<li class="dropdown visible-desktop">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{label_usermenu} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{url_profile}"><i class="icon-cog"></i>&nbsp;{label_profile}</a></li>
<li><a href="{url_logout}"><i class="icon-off"></i>&nbsp;{label_logout}</a></li>
</ul>
</li>
<li class="hidden-desktop divider"></li>
<li class="hidden-desktop"><a href="{url_profile}">{label_profile}</a></li>
<li class="hidden-desktop"><a href="{url_logout}">{label_logout}</a></li>
</ul>
</div>
<!--%%tpl_main_menu-->
<!--%tpl_main_auto_refresh-->
<meta http-equiv="refresh" content="{seconds}" />
<!--%%tpl_main_auto_refresh-->
<!--%tpl_main_footer-->
<footer class="footer">
<p class="pull-right"><a href="#">{label_back_to_top}</a></p>
<p class="powered"><small>Powered by <a href="http://www.phpservermonitor.org/" target="_blank">PHP Server Monitor {version}</a>.<br/>{update_available}</small></p>
</footer>
<!--%%tpl_main_footer-->

View File

@ -1,37 +0,0 @@
<!--%tpl_main_sidebar_container-->
<div class="span2">
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">{subtitle}</li>
<!--%tpl_repeat_items-->
<li class="{class_active}">{html_item}</li>
<!--%%tpl_repeat_items-->
{items}
</ul>
<div class="clearfix"></div>
</div>
</div>
<!--%%tpl_main_sidebar_container-->
<!--%tpl_main_sidebar_types_link--><a href="{url}"><i class="icon-{icon}"></i>&nbsp;{label}</a><!--%%tpl_main_sidebar_types_link-->
<!--%tpl_main_sidebar_types_button-->
<button class="btn btn-{btn_class}" onclick="{onclick}">
<i class="icon-{icon}"></i>&nbsp;{label}
</button>
<!--%%tpl_main_sidebar_types_button-->
<!--%tpl_main_sidebar_types_dropdown-->
<div class="btn-group">
<button class="btn btn-{btn_class} dropdown-toggle" data-toggle="dropdown">
<i class="icon-{icon}"></i>&nbsp;{label}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<!--%tpl_repeat_options-->
<li class="{class_active}"><a href="{url}">{label}</a>
<!--%%tpl_repeat_options-->
{options}
</ul>
</div>
<!--%%tpl_main_sidebar_types_dropdown-->

View File

@ -1,51 +0,0 @@
<!--%tpl_server_log_list-->
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><a href="#log_status_content" data-toggle="tab">{label_status}</a></li>
<li><a href="#log_email_content" data-toggle="tab">{label_email}</a></li>
<li><a href="#log_sms_content" data-toggle="tab">{label_sms}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="log_status_content">
{content_status}
</div>
<div class="tab-pane" id="log_email_content">
{content_email}
</div>
<div class="tab-pane" id="log_sms_content">
{content_sms}
</div>
</div>
</div>
<!--%%tpl_server_log_list-->
<!--%tpl_server_log_entries-->
<!-- {logtitle} -->
<table class="table table-bordered table-striped">
<colgroup>
<col />
<col />
<col style="width: 135px" />
<col />
</colgroup>
<thead>
<tr>
<th>{label_server}</th>
<th>{label_message}</th>
<th>{label_date}</th>
<th>{label_users}</th>
</tr>
</thead>
<tbody>
<!--%tpl_repeat_entries-->
<tr class="{class}">
<td>{server}</td>
<td>{message}</td>
<td>{datetime_format}</td>
<td>{users}</td>
</tr>
<!--%%tpl_repeat_entries-->
{entries}
</tbody>
</table>
<!--%%tpl_server_log_entries-->

View File

@ -1,129 +0,0 @@
<!--%tpl_server_list-->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>&nbsp;</th>
<th>{label_label}</th>
<th>{label_domain}</th>
<th>{label_port}</th>
<th>{label_type}</th>
<th>{label_rtime}</th>
<th>{label_last_online}</th>
<th>{label_monitoring}</th>
<th>{label_send_email}</th>
<th>{label_send_sms}</th>
<th>{label_action}</th>
</tr>
</thead>
<tbody>
<!--%tpl_repeat_servers-->
<tr>
<td>
<span class="label label-status-{status}">
<a href="{url_view}" title="{error}">{status}</a>
</span>
</td>
<td><a href="{url_view}">{label}</a></td>
<td>{ip}</td>
<td>{port}</td>
<td>{type}</td>
<td>{rtime} s</td>
<td>{last_online}</td>
<td>{active}</td>
<td>{email}</td>
<td>{sms}</td>
<td><a class="btn btn-small" href="index.php?mod=server&amp;action=view&amp;id={server_id}"><i class="icon-eye-open"></i></a>
{html_actions}</td>
</tr>
<!--%%tpl_repeat_servers-->
{servers}
</tbody>
</table>
<!--%%tpl_server_list-->
<!--%tpl_server_list_admin_actions-->
<a class="btn btn-small" href="index.php?mod=server&amp;action=edit&amp;id={server_id}" title="{label_edit}">
<i class="icon-pencil"></i>
</a>
<a class="btn btn-small btn-danger" href="javascript:sm_delete('{server_id}', 'server');" title="{label_delete}">
<i class="icon-remove icon-white"></i>
</a>
<!--%%tpl_server_list_admin_actions-->
<!--%tpl_server_update-->
<form class="form-horizontal well" action="{url_save}" method="post">
<fieldset>
<legend>{titlemode}</legend>
<div class="control-group">
<label class="control-label" for="label">{label_label}</label>
<div class="controls">
<input type="text" id="label" name="label" value="{edit_value_label}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="ip">{label_domain}</label>
<div class="controls">
<input type="text" id="ip" name="ip" value="{edit_value_ip}" maxlength="100" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="type">{label_type}</label>
<div class="controls">
<select id="type" name="type">
<option value="service" {edit_type_selected_service}>{label_service}</option>
<option value="website" {edit_type_selected_website}>{label_website}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="port">{label_port}</label>
<div class="controls">
<input class="input-mini" type="text" id="port" name="port" value="{edit_value_port}" maxlength="5" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="pattern">{label_pattern}</label>
<div class="controls">
<input type="text" id="pattern" name="pattern" value="{edit_value_pattern}" maxlength="255" data-toggle="tooltip" title="{label_pattern_description}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="active">{label_monitoring}</label>
<div class="controls">
<select id="active" name="active">
<option value="yes" {edit_active_selected_yes}>{label_yes}</option>
<option value="no" {edit_active_selected_no}>{label_no}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">{label_send_email}</label>
<div class="controls">
<select id="email" name="email">
<option value="yes" {edit_email_selected_yes}>{label_yes}</option>
<option value="no" {edit_email_selected_no}>{label_no}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="sms">{label_send_sms}</label>
<div class="controls">
<select id="sms" name="sms">
<option value="yes" {edit_sms_selected_yes}>{label_yes}</option>
<option value="no" {edit_sms_selected_no}>{label_no}</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="warning_threshold">{label_warning_threshold}</label>
<div class="controls">
<input class="input-mini" type="text" id="warning_threshold" name="warning_threshold" value="{edit_value_warning_threshold}" maxlength="5" data-toggle="tooltip" title="{label_warning_threshold_description}" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit">{label_save}</button>
<a class="btn" href="{url_go_back}" >{label_go_back}</a>
</div>
</fieldset>
</form>
<!--%%tpl_server_update-->

Some files were not shown because too many files have changed in this diff Show More