Implementing the PSR12 standard

Using PHPCS and PHPSBF.
This commit is contained in:
TimZ99 2019-12-11 20:19:38 +01:00
parent 0c91d27a70
commit 2c51ad12f7
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
70 changed files with 8944 additions and 8129 deletions

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -25,66 +26,76 @@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
**/ **/
namespace {
// include main configuration and functionality // include main configuration and functionality
require_once __DIR__.'/../src/bootstrap.php'; require_once __DIR__ . '/../src/bootstrap.php';
if (!psm_is_cli()) { if (!psm_is_cli()) {
// check if it's an allowed host // check if it's an allowed host
if (!isset($_SERVER["HTTP_X_FORWARDED_FOR"])) { if (!isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$_SERVER["HTTP_X_FORWARDED_FOR"] = ""; $_SERVER["HTTP_X_FORWARDED_FOR"] = "";
} }
// define won't accept array before php 7.0.0 // define won't accept array before php 7.0.0
// check if data is serialized (not needed when using php 7.0.0 and higher) // check if data is serialized (not needed when using php 7.0.0 and higher)
$data = @unserialize(PSM_CRON_ALLOW); $data = @unserialize(PSM_CRON_ALLOW);
$allow = $data === false ? PSM_CRON_ALLOW : $data; $allow = $data === false ? PSM_CRON_ALLOW : $data;
if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)) { if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)) {
header('HTTP/1.0 403 Forbidden'); header('HTTP/1.0 403 Forbidden');
die('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>403 Forbidden</title></head><body><h1>Forbidden</h1><p>IP address not allowed. See the <a href="http://docs.phpservermonitor.org/en/latest/install.html#cronjob-over-web">documentation</a> for more info.</p></body></html>'); die('
} <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html>
echo "OK"; <head><title>403 Forbidden</title></head>
} <body>
<h1>Forbidden</h1><p>IP address not allowed. See the
<a href="http://docs.phpservermonitor.org/en/latest/install.html#cronjob-over-web">documentation</a>
for more info.</p>
</body>
</html>');
}
echo "OK";
}
$cron_timeout = PSM_CRON_TIMEOUT; $cron_timeout = PSM_CRON_TIMEOUT;
// parse a couple of arguments // parse a couple of arguments
if (!empty($_SERVER['argv'])) { if (!empty($_SERVER['argv'])) {
foreach ($_SERVER['argv'] as $argv) { foreach ($_SERVER['argv'] as $argv) {
$argi = explode('=', ltrim($argv, '--')); $argi = explode('=', ltrim($argv, '--'));
if (count($argi) !== 2) { if (count($argi) !== 2) {
continue; continue;
} }
switch ($argi[0]) { switch ($argi[0]) {
case 'uri': case 'uri':
if (!defined('PSM_BASE_URL')) { if (!defined('PSM_BASE_URL')) {
define('PSM_BASE_URL', $argi[1]); define('PSM_BASE_URL', $argi[1]);
} }
break; break;
case 'timeout': case 'timeout':
$cron_timeout = intval($argi[1]); $cron_timeout = intval($argi[1]);
break; break;
} }
} }
} }
// prevent cron from running twice at the same time // prevent cron from running twice at the same time
// however if the cron has been running for X mins, we'll assume it died and run anyway // however if the cron has been running for X mins, we'll assume it died and run anyway
// if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php. // if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php.
// or you can provide the --timeout=x argument // or you can provide the --timeout=x argument
$time = time(); $time = time();
if ( if (
psm_get_conf('cron_running') == 1 psm_get_conf('cron_running') == 1
&& $cron_timeout > 0 && $cron_timeout > 0
&& ($time - psm_get_conf('cron_running_time') < $cron_timeout) && ($time - psm_get_conf('cron_running_time') < $cron_timeout)
) { ) {
die('Cron is already running. Exiting.'); die('Cron is already running. Exiting.');
} }
if (!defined('PSM_DEBUG') || !PSM_DEBUG) { if (!defined('PSM_DEBUG') || !PSM_DEBUG) {
psm_update_conf('cron_running', 1); psm_update_conf('cron_running', 1);
} }
psm_update_conf('cron_running_time', $time); psm_update_conf('cron_running_time', $time);
$autorun = $router->getService('util.server.updatemanager'); $autorun = $router->getService('util.server.updatemanager');
$autorun->run(true); $autorun->run(true);
psm_update_conf('cron_running', 0); psm_update_conf('cron_running', 0);
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -25,24 +26,24 @@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
**/ **/
require __DIR__.'/src/bootstrap.php'; require __DIR__ . '/src/bootstrap.php';
psm_no_cache(); psm_no_cache();
if (isset($_GET["logout"])) { if (isset($_GET["logout"])) {
$router->getService('user')->doLogout(); $router->getService('user')->doLogout();
// logged out, redirect to login // logged out, redirect to login
header('Location: '.psm_build_url()); header('Location: ' . psm_build_url());
die(); die();
} }
$mod = psm_GET('mod', PSM_MODULE_DEFAULT); $mod = psm_GET('mod', PSM_MODULE_DEFAULT);
try { try {
$router->run($mod); $router->run($mod);
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
// invalid module, try the default one // invalid module, try the default one
// it that somehow also doesnt exist, we have a bit of an issue // it that somehow also doesnt exist, we have a bit of an issue
// and we really have no reason catch it // and we really have no reason catch it
$router->run(PSM_MODULE_DEFAULT); $router->run(PSM_MODULE_DEFAULT);
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -25,8 +26,10 @@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
**/ **/
define('PSM_INSTALL', true); namespace {
define('PSM_INSTALL', true);
require __DIR__.'/src/bootstrap.php'; require __DIR__ . '/src/bootstrap.php';
$router->run('install'); $router->run('install');
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,75 +27,87 @@
* @since phpservermon 2.1.0 * @since phpservermon 2.1.0
**/ **/
// Include paths namespace {
define('PSM_PATH_SRC', __DIR__.DIRECTORY_SEPARATOR); // Include paths
define('PSM_PATH_CONFIG', PSM_PATH_SRC.'config'.DIRECTORY_SEPARATOR); define('PSM_PATH_SRC', __DIR__ . DIRECTORY_SEPARATOR);
define('PSM_PATH_LANG', PSM_PATH_SRC.'lang'.DIRECTORY_SEPARATOR); define('PSM_PATH_CONFIG', PSM_PATH_SRC . 'config' . DIRECTORY_SEPARATOR);
define('PSM_PATH_SMS_GATEWAY', PSM_PATH_SRC.'psm'.DIRECTORY_SEPARATOR.'Txtmsg'.DIRECTORY_SEPARATOR); define('PSM_PATH_LANG', PSM_PATH_SRC . 'lang' . DIRECTORY_SEPARATOR);
define('PSM_PATH_SMS_GATEWAY', PSM_PATH_SRC . 'psm' . DIRECTORY_SEPARATOR . 'Txtmsg' . DIRECTORY_SEPARATOR);
// user levels // user levels
define('PSM_USER_ADMIN', 10); define('PSM_USER_ADMIN', 10);
define('PSM_USER_USER', 20); define('PSM_USER_USER', 20);
define('PSM_USER_ANONYMOUS', 30); define('PSM_USER_ANONYMOUS', 30);
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) { if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
date_default_timezone_set(@date_default_timezone_get()); date_default_timezone_set(@date_default_timezone_get());
}
// find config file
$path_conf = PSM_PATH_SRC . '../config.php';
if (file_exists($path_conf)) {
include_once $path_conf;
}
// check for a debug var
if (!defined('PSM_DEBUG')) {
define('PSM_DEBUG', false);
}
// Debug enabled: report everything
// Debug disabled: report error only if created manually
ini_set('display_errors', 1);
PSM_DEBUG ? error_reporting(E_ALL) : error_reporting(E_USER_ERROR);
// check for a cron allowed ip array
if (!defined('PSM_CRON_ALLOW')) {
//serialize for php version lower than 7.0.0
define('PSM_CRON_ALLOW', serialize(array()));
}
$vendor_autoload = PSM_PATH_SRC . '..' . DIRECTORY_SEPARATOR . 'vendor' .
DIRECTORY_SEPARATOR . 'autoload.php';
if (!file_exists($vendor_autoload)) {
trigger_error(
"No dependencies found in vendor dir. Did you install the dependencies?
Please run \"php composer.phar install\".",
E_USER_ERROR
);
}
require_once $vendor_autoload;
$router = new psm\Router();
// this may seem insignificant, but right now lots of functions
// depend on the following global var definition:
$db = $router->getService('db');
// sanity check!
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');
die();
}
// config file has been loaded, check if we have a connection
if (!$db->status()) {
trigger_error("Unable to establish database connection...", E_USER_ERROR);
}
// attempt to load configuration from database
if (!psm_load_conf()) {
// unable to load from config table
header('Location: install.php');
die();
}
// config load OK, make sure database version is up to date
$installer = new \psm\Util\Install\Installer($db);
if ($installer->isUpgradeRequired()) {
trigger_error(
"Your database is for an older version and requires an upgrade,
<a href=\"install.php\">please click here</a> to update your database to the latest version.",
E_USER_ERROR
);
}
}
$lang = psm_get_conf('language', 'en_US');
psm_load_lang($lang);
} }
// find config file
$path_conf = PSM_PATH_SRC.'../config.php';
if (file_exists($path_conf)) {
include_once $path_conf;
}
// check for a debug var
if (!defined('PSM_DEBUG')) {
define('PSM_DEBUG', false);
}
// Debug enabled: report everything
// Debug disabled: report error only if created manually
ini_set('display_errors', 1);
PSM_DEBUG ? error_reporting(E_ALL) : error_reporting(E_USER_ERROR);
// check for a cron allowed ip array
if (!defined('PSM_CRON_ALLOW')) {
//serialize for php version lower than 7.0.0
define('PSM_CRON_ALLOW', serialize(array()));
}
$vendor_autoload = PSM_PATH_SRC.'..'.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
if (!file_exists($vendor_autoload)) {
trigger_error("No dependencies found in vendor dir. Did you install the dependencies? Please run \"php composer.phar install\".", E_USER_ERROR);
}
require_once $vendor_autoload;
$router = new psm\Router();
// this may seem insignificant, but right now lots of functions depend on the following global var definition:
$db = $router->getService('db');
// sanity check!
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');
die();
}
// config file has been loaded, check if we have a connection
if (!$db->status()) {
trigger_error("Unable to establish database connection...", E_USER_ERROR);
}
// attempt to load configuration from database
if (!psm_load_conf()) {
// unable to load from config table
header('Location: install.php');
die();
}
// config load OK, make sure database version is up to date
$installer = new \psm\Util\Install\Installer($db);
if ($installer->isUpgradeRequired()) {
trigger_error("Your database is for an older version and requires an upgrade, <a href=\"install.php\">please click here</a> to update your database to the latest version.", E_USER_ERROR);
}
}
$lang = psm_get_conf('language', 'en_US');
psm_load_lang($lang);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -35,212 +36,230 @@
*/ */
if (!defined('PASSWORD_DEFAULT')) { if (!defined('PASSWORD_DEFAULT')) {
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
define('PASSWORD_BCRYPT', 1); /**
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); * Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array())
{
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) .
" given", E_USER_WARNING);
return null;
}
switch ($algo) {
case PASSWORD_BCRYPT:
// Note that this is a C constant, but not exposed to PHP, so we don't define it here.
$cost = 10;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(
sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost),
E_USER_WARNING
);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
break;
default:
trigger_error(
sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo),
E_USER_WARNING
);
return null;
}
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
// no break
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (strlen($salt) < $required_salt_len) {
trigger_error(
sprintf(
"password_hash(): Provided salt is too short: %d expecting %d",
strlen($salt),
$required_salt_len
),
E_USER_WARNING
);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt = str_replace('+', '.', base64_encode($salt));
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || strlen($buffer) < $raw_salt_len) {
$bl = strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = str_replace('+', '.', base64_encode($buffer));
}
$salt = substr($salt, 0, $required_salt_len);
/** $hash = $hash_format . $salt;
* Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array()) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, ".gettype($algo)." given", E_USER_WARNING);
return null;
}
switch ($algo) {
case PASSWORD_BCRYPT:
// Note that this is a C constant, but not exposed to PHP, so we don't define it here.
$cost = 10;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
break;
default:
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
return null;
}
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (strlen($salt) < $required_salt_len) {
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt = str_replace('+', '.', base64_encode($salt));
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || strlen($buffer) < $raw_salt_len) {
$bl = strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = str_replace('+', '.', base64_encode($buffer));
}
$salt = substr($salt, 0, $required_salt_len);
$hash = $hash_format.$salt; $ret = crypt($password, $hash);
$ret = crypt($password, $hash); if (!is_string($ret) || strlen($ret) <= 13) {
return false;
}
if (!is_string($ret) || strlen($ret) <= 13) { return $ret;
return false; }
}
return $ret; /**
} * Get information about the password hash. Returns an array of the information
* that was used to generate the password hash.
*
* array(
* 'algo' => 1,
* 'algoName' => 'bcrypt',
* 'options' => array(
* 'cost' => 10,
* ),
* )
*
* @param string $hash The password hash to extract info from
*
* @return array The array of information about the hash.
*/
function password_get_info($hash)
{
$return = array(
'algo' => 0,
'algoName' => 'unknown',
'options' => array(),
);
if (substr($hash, 0, 4) == '$2y$' && strlen($hash) == 60) {
$return['algo'] = PASSWORD_BCRYPT;
$return['algoName'] = 'bcrypt';
list($cost) = sscanf($hash, "$2y$%d$");
$return['options']['cost'] = $cost;
}
return $return;
}
/** /**
* Get information about the password hash. Returns an array of the information * Determine if the password hash needs to be rehashed according to the options provided
* that was used to generate the password hash. *
* * If the answer is true, after validating the password using password_verify, rehash it.
* array( *
* 'algo' => 1, * @param string $hash The hash to test
* 'algoName' => 'bcrypt', * @param int $algo The algorithm used for new password hashes
* 'options' => array( * @param array $options The options array passed to password_hash
* 'cost' => 10, *
* ), * @return boolean True if the password needs to be rehashed.
* ) */
* function password_needs_rehash($hash, $algo, array $options = array())
* @param string $hash The password hash to extract info from {
* $info = password_get_info($hash);
* @return array The array of information about the hash. if ($info['algo'] != $algo) {
*/ return true;
function password_get_info($hash) { }
$return = array( switch ($algo) {
'algo' => 0, case PASSWORD_BCRYPT:
'algoName' => 'unknown', $cost = isset($options['cost']) ? $options['cost'] : 10;
'options' => array(), if ($cost != $info['options']['cost']) {
); return true;
if (substr($hash, 0, 4) == '$2y$' && strlen($hash) == 60) { }
$return['algo'] = PASSWORD_BCRYPT; break;
$return['algoName'] = 'bcrypt'; }
list($cost) = sscanf($hash, "$2y$%d$"); return false;
$return['options']['cost'] = $cost; }
}
return $return;
}
/** /**
* Determine if the password hash needs to be rehashed according to the options provided * Verify a password against a hash using a timing attack resistant approach
* *
* If the answer is true, after validating the password using password_verify, rehash it. * @param string $password The password to verify
* * @param string $hash The hash to verify against
* @param string $hash The hash to test *
* @param int $algo The algorithm used for new password hashes * @return boolean If the password matches the hash
* @param array $options The options array passed to password_hash */
* function password_verify($password, $hash)
* @return boolean True if the password needs to be rehashed. {
*/ if (!function_exists('crypt')) {
function password_needs_rehash($hash, $algo, array $options = array()) { trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
$info = password_get_info($hash); return false;
if ($info['algo'] != $algo) { }
return true; $ret = crypt($password, $hash);
} if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
switch ($algo) { return false;
case PASSWORD_BCRYPT: }
$cost = isset($options['cost']) ? $options['cost'] : 10;
if ($cost != $info['options']['cost']) {
return true;
}
break;
}
return false;
}
/** $status = 0;
* Verify a password against a hash using a timing attack resistant approach for ($i = 0; $i < strlen($ret); $i++) {
* $status |= (ord($ret[$i]) ^ ord($hash[$i]));
* @param string $password The password to verify }
* @param string $hash The hash to verify against
*
* @return boolean If the password matches the hash
*/
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
return false;
}
$status = 0; return $status === 0;
for ($i = 0; $i < strlen($ret); $i++) { }
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -119,13 +120,13 @@ define('PSM_TELEGRAM_GET_ID_URL', 'https://telegram.me/cid_bot');
//define('PSM_BASE_URL', null); //define('PSM_BASE_URL', null);
if (!defined('PSM_MODULE_DEFAULT')) { if (!defined('PSM_MODULE_DEFAULT')) {
/** /**
* Default theme * Default theme
*/ */
define('PSM_THEME', 'default'); define('PSM_THEME', 'default');
/** /**
* Default module (if none given or invalid one) * Default module (if none given or invalid one)
*/ */
define('PSM_MODULE_DEFAULT', 'server_status'); define('PSM_MODULE_DEFAULT', 'server_status');
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,282 +27,282 @@
**/ **/
$sm_lang = array( $sm_lang = array(
'name' => 'Dansk - Danish', 'name' => 'Dansk - Danish',
'locale' => array('da_DK.UTF-8', 'da_DK', 'danish', 'danish-dk'), 'locale' => array('da_DK.UTF-8', 'da_DK', 'danish', 'danish-dk'),
'system' => array( 'system' => array(
'title' => 'Server Monitor', 'title' => 'Server Monitor',
'install' => 'Installér', 'install' => 'Installér',
'action' => 'Action', 'action' => 'Action',
'save' => 'Gem', 'save' => 'Gem',
'edit' => 'Redigér', 'edit' => 'Redigér',
'delete' => 'Slet', 'delete' => 'Slet',
'date' => 'Dato', 'date' => 'Dato',
'message' => 'Besked', 'message' => 'Besked',
'yes' => 'Ja', 'yes' => 'Ja',
'no' => 'Nej', 'no' => 'Nej',
'insert' => 'Indsæt', 'insert' => 'Indsæt',
'add_new' => 'Tilføj ny', 'add_new' => 'Tilføj ny',
'update_available' => 'En ny version ({version}) er tilgængelig på <a href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank" rel="noopener">http://www.phpservermonitor.org</a>.', 'update_available' => 'En ny version ({version}) er tilgængelig på <a href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank" rel="noopener">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'Til toppen', 'back_to_top' => 'Til toppen',
'go_back' => 'Tilbage', 'go_back' => 'Tilbage',
'ok' => 'OK', 'ok' => 'OK',
'cancel' => 'Annullér', 'cancel' => 'Annullér',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php // date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e', 'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y', 'long_day_format' => '%B %e, %Y',
'yesterday_format' => 'Igår %k:%M', 'yesterday_format' => 'Igår %k:%M',
'other_day_format' => '%A %k:%M', 'other_day_format' => '%A %k:%M',
'never' => 'Aldrig', 'never' => 'Aldrig',
'hours_ago' => '%d timer siden', 'hours_ago' => '%d timer siden',
'an_hour_ago' => 'omkring en time siden', 'an_hour_ago' => 'omkring en time siden',
'minutes_ago' => '%d minutter siden', 'minutes_ago' => '%d minutter siden',
'a_minute_ago' => 'omkring et minut siden', 'a_minute_ago' => 'omkring et minut siden',
'seconds_ago' => '%d sekunder siden', 'seconds_ago' => '%d sekunder siden',
'a_second_ago' => 'et sekund siden', 'a_second_ago' => 'et sekund siden',
'year' => 'year', 'year' => 'year',
'years' => 'years', 'years' => 'years',
'month' => 'month', 'month' => 'month',
'months' => 'months', 'months' => 'months',
'day' => 'day', 'day' => 'day',
'days' => 'days', 'days' => 'days',
'hour' => 'hour', 'hour' => 'hour',
'hours' => 'hours', 'hours' => 'hours',
'minute' => 'minute', 'minute' => 'minute',
'minutes' => 'minutes', 'minutes' => 'minutes',
'second' => 'second', 'second' => 'second',
'seconds' => 'seconds', 'seconds' => 'seconds',
), ),
'menu' => array( 'menu' => array(
'config' => 'Indstillinger', 'config' => 'Indstillinger',
'server' => 'Servere', 'server' => 'Servere',
'server_log' => 'Log', 'server_log' => 'Log',
'server_status' => 'Status', 'server_status' => 'Status',
'server_update' => 'Opdatér', 'server_update' => 'Opdatér',
'user' => 'Brugere', 'user' => 'Brugere',
'help' => 'Hjælp', 'help' => 'Hjælp',
), ),
'users' => array( 'users' => array(
'user' => 'Bruger', 'user' => 'Bruger',
'name' => 'Navn', 'name' => 'Navn',
'user_name' => 'Brugernavn', 'user_name' => 'Brugernavn',
'password' => 'Adgangskode', 'password' => 'Adgangskode',
'password_repeat' => 'Adgangskode igen', 'password_repeat' => 'Adgangskode igen',
'password_leave_blank' => 'Udfyldes hvis du vil skifte adgangskode', 'password_leave_blank' => 'Udfyldes hvis du vil skifte adgangskode',
'level' => 'Niveau', 'level' => 'Niveau',
'level_10' => 'Administrator', 'level_10' => 'Administrator',
'level_20' => 'Bruger', 'level_20' => 'Bruger',
'level_description' => '<b>Administratorer</b> har fuld adgang: De kan styre servere, brugere og indstillinger.<br><b>Brugere</b> kan kun se og opdatere servere som er de har adgang til.', 'level_description' => '<b>Administratorer</b> har fuld adgang: De kan styre servere, brugere og indstillinger.<br><b>Brugere</b> kan kun se og opdatere servere som er de har adgang til.',
'mobile' => 'Mobil', 'mobile' => 'Mobil',
'email' => 'E-mail', 'email' => 'E-mail',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se <a href="https://pushover.net/">deres website</a> for mere information.', 'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se <a href="https://pushover.net/">deres website</a> for mere information.',
'pushover_key' => 'Pushover nøgle', 'pushover_key' => 'Pushover nøgle',
'pushover_device' => 'Pushover enhed', 'pushover_device' => 'Pushover enhed',
'pushover_device_description' => 'Navnet på enheden som beskeden skal sendes til. Lad denne være tom hvis alle skal modtage beskeden.', 'pushover_device_description' => 'Navnet på enheden som beskeden skal sendes til. Lad denne være tom hvis alle skal modtage beskeden.',
'delete_title' => 'Slet bruger', 'delete_title' => 'Slet bruger',
'delete_message' => 'Er du sikker på du vil slette bruger \'%1\'?', 'delete_message' => 'Er du sikker på du vil slette bruger \'%1\'?',
'deleted' => 'Bruger slettet.', 'deleted' => 'Bruger slettet.',
'updated' => 'Bruger opdateret.', 'updated' => 'Bruger opdateret.',
'inserted' => 'Bruger tilføjet.', 'inserted' => 'Bruger tilføjet.',
'profile' => 'Profil', 'profile' => 'Profil',
'profile_updated' => 'Din profil er opdateret.', 'profile_updated' => 'Din profil er opdateret.',
'error_user_name_bad_length' => 'Brugernavn skal være mellem 2 til 64 tegn.', '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), prikker (.) og (_).', 'error_user_name_invalid' => 'Brugernavn må kun indholde alfabetiske tegn (a-z, A-Z), tal (0-9), prikker (.) og (_).',
'error_user_name_exists' => 'Det valgte brugernavn findes allerede.', 'error_user_name_exists' => 'Det valgte brugernavn findes allerede.',
'error_user_email_bad_length' => 'E-mail addresser skal være mellem 5 til 255 tegn.', 'error_user_email_bad_length' => 'E-mail addresser skal være mellem 5 til 255 tegn.',
'error_user_email_invalid' => 'Den valgte e-mail er ugyldig.', 'error_user_email_invalid' => 'Den valgte e-mail er ugyldig.',
'error_user_level_invalid' => 'Det angivet bruger niveau er ugyldig.', 'error_user_level_invalid' => 'Det angivet bruger niveau er ugyldig.',
'error_user_no_match' => 'Brugeren findes ikke.', 'error_user_no_match' => 'Brugeren findes ikke.',
'error_user_password_invalid' => 'Den indtastede adgangskode er ugyldig.', 'error_user_password_invalid' => 'Den indtastede adgangskode er ugyldig.',
'error_user_password_no_match' => 'De to adgangskode er ikke ens.', 'error_user_password_no_match' => 'De to adgangskode er ikke ens.',
), ),
'log' => array( 'log' => array(
'title' => 'Logposter', 'title' => 'Logposter',
'type' => 'Type', 'type' => 'Type',
'status' => 'Status', 'status' => 'Status',
'email' => 'E-mail', 'email' => 'E-mail',
'sms' => 'SMS', 'sms' => 'SMS',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'no_logs' => 'Intet i loggen', 'no_logs' => 'Intet i loggen',
'clear' => 'Ryd log', 'clear' => 'Ryd log',
'delete_title' => 'Slet log', 'delete_title' => 'Slet log',
'delete_message' => 'Er du sikker på, at du vil slette <b>alle</b> logfiler?', 'delete_message' => 'Er du sikker på, at du vil slette <b>alle</b> logfiler?',
), ),
'servers' => array( 'servers' => array(
'server' => 'Server', 'server' => 'Server',
'status' => 'Status', 'status' => 'Status',
'label' => 'Label', 'label' => 'Label',
'domain' => 'Domæne/IP', 'domain' => 'Domæne/IP',
'timeout' => 'Timeout', 'timeout' => 'Timeout',
'timeout_description' => 'Antal sekunder som serveren har til at svare.', 'timeout_description' => 'Antal sekunder som serveren har til at svare.',
'port' => 'Port', 'port' => 'Port',
'type' => 'Type', 'type' => 'Type',
'type_website' => 'Hjemmeside', 'type_website' => 'Hjemmeside',
'type_service' => 'Tjeneste', 'type_service' => 'Tjeneste',
'pattern' => 'Søgestreng/mønster', 'pattern' => 'Søgestreng/mønster',
'pattern_description' => 'Hvis dette mønster ikke findes på hjemmesiden, vil serveren blive markeret som værende offline. Regulære udtryk er tilladt.', 'pattern_description' => 'Hvis dette mønster ikke findes på hjemmesiden, vil serveren blive markeret som værende offline. Regulære udtryk er tilladt.',
'last_check' => 'Sidst kontrolleret', 'last_check' => 'Sidst kontrolleret',
'last_online' => 'Sidst online', 'last_online' => 'Sidst online',
'last_offline' => 'Sidst offline', 'last_offline' => 'Sidst offline',
'monitoring' => 'Overvågning', 'monitoring' => 'Overvågning',
'no_monitoring' => 'Ingen overvågning', 'no_monitoring' => 'Ingen overvågning',
'email' => 'E-mail', 'email' => 'E-mail',
'send_email' => 'Send E-mail', 'send_email' => 'Send E-mail',
'sms' => 'SMS', 'sms' => 'SMS',
'send_sms' => 'Send SMS', 'send_sms' => 'Send SMS',
'pushover' => 'Pushover', 'pushover' => 'Pushover',
'users' => 'Users', 'users' => 'Users',
'delete_title' => 'Slet server', 'delete_title' => 'Slet server',
'delete_message' => 'Er du sikker på du vil slette server \'%1\'?', 'delete_message' => 'Er du sikker på du vil slette server \'%1\'?',
'deleted' => 'Server slettet.', 'deleted' => 'Server slettet.',
'updated' => 'Server opdateret.', 'updated' => 'Server opdateret.',
'inserted' => 'Server tilføjet.', 'inserted' => 'Server tilføjet.',
'latency' => 'Forsinkelse', 'latency' => 'Forsinkelse',
'latency_max' => 'Forsinkelse (maksimum)', 'latency_max' => 'Forsinkelse (maksimum)',
'latency_min' => 'Forsinkelse (minimum)', 'latency_min' => 'Forsinkelse (minimum)',
'latency_avg' => 'Forsinkelse (gennemsnitlig)', 'latency_avg' => 'Forsinkelse (gennemsnitlig)',
'uptime' => 'Oppetid', 'uptime' => 'Oppetid',
'year' => 'År', 'year' => 'År',
'month' => 'Måned', 'month' => 'Måned',
'week' => 'Uge', 'week' => 'Uge',
'day' => 'Dag', 'day' => 'Dag',
'hour' => 'Time', 'hour' => 'Time',
'warning_threshold' => 'Advarsel grænse', 'warning_threshold' => 'Advarsel grænse',
'warning_threshold_description' => 'Antallet af fejl, før status skifter til offline.', 'warning_threshold_description' => 'Antallet af fejl, før status skifter til offline.',
'chart_last_week' => 'Sidste uge', 'chart_last_week' => 'Sidste uge',
'chart_history' => 'Historie', 'chart_history' => 'Historie',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html // 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_day_format' => '%d-%m-%Y',
'chart_long_date_format' => '%d-%m-%Y %H:%M:%S', 'chart_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_date_format' => '%d/%m %H:%M',
'chart_short_time_format' => '%H:%M', 'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'SMS notifikationer er deaktiveret.', 'warning_notifications_disabled_sms' => 'SMS notifikationer er deaktiveret.',
'warning_notifications_disabled_email' => 'E-mail notifikationer er deaktiveret.', 'warning_notifications_disabled_email' => 'E-mail notifikationer er deaktiveret.',
'warning_notifications_disabled_pushover' => 'Pushover notifikationer er deaktiveret.', 'warning_notifications_disabled_pushover' => 'Pushover notifikationer er deaktiveret.',
'error_server_no_match' => 'Server ikke fundet.', 'error_server_no_match' => 'Server ikke fundet.',
'error_server_label_bad_length' => 'Label skal være mellem et og 255 karakterer.', 'error_server_label_bad_length' => 'Label skal være mellem et og 255 karakterer.',
'error_server_ip_bad_length' => 'Domænet/IP skal være mellem et og 255 karakterer.', 'error_server_ip_bad_length' => 'Domænet/IP skal være mellem et og 255 karakterer.',
'error_server_ip_bad_service' => 'IP adressen er ikke gyldig.', 'error_server_ip_bad_service' => 'IP adressen er ikke gyldig.',
'error_server_ip_bad_website' => 'Websitets URL er ikke gyldigt.', 'error_server_ip_bad_website' => 'Websitets URL er ikke gyldigt.',
'error_server_type_invalid' => 'Den valgte servertype er ikke gyldig.', 'error_server_type_invalid' => 'Den valgte servertype er ikke gyldig.',
'error_server_warning_threshold_invalid' => 'Advarsels-tærskel skal være et gyldigt tal større end 0.', 'error_server_warning_threshold_invalid' => 'Advarsels-tærskel skal være et gyldigt tal større end 0.',
), ),
'config' => array( 'config' => array(
'general' => 'Generelt', 'general' => 'Generelt',
'language' => 'Sprog', 'language' => 'Sprog',
'show_update' => 'Opdateringer', 'show_update' => 'Opdateringer',
'email_status' => 'Tillad at sende e-mail', 'email_status' => 'Tillad at sende e-mail',
'email_from_email' => 'E-mail fra adresse', 'email_from_email' => 'E-mail fra adresse',
'email_from_name' => 'E-mail fra navn', 'email_from_name' => 'E-mail fra navn',
'email_smtp' => 'Aktiver SMTP', 'email_smtp' => 'Aktiver SMTP',
'email_smtp_host' => 'SMTP vært', 'email_smtp_host' => 'SMTP vært',
'email_smtp_port' => 'SMTP port', 'email_smtp_port' => 'SMTP port',
'email_smtp_security' => 'SMTP c', 'email_smtp_security' => 'SMTP c',
'email_smtp_security_none' => 'Ingen', 'email_smtp_security_none' => 'Ingen',
'email_smtp_username' => 'SMTP brugernavn', 'email_smtp_username' => 'SMTP brugernavn',
'email_smtp_password' => 'SMTP adgangskode', 'email_smtp_password' => 'SMTP adgangskode',
'email_smtp_noauth' => 'Efterlad blank hvis det ikke er krævet', 'email_smtp_noauth' => 'Efterlad blank hvis det ikke er krævet',
'sms_status' => 'Tillad at sende SMS beskeder', 'sms_status' => 'Tillad at sende SMS beskeder',
'sms_gateway' => 'SMS Gateway', 'sms_gateway' => 'SMS Gateway',
'sms_gateway_username' => 'Gateway brugernavn/apikey', 'sms_gateway_username' => 'Gateway brugernavn/apikey',
'sms_gateway_password' => 'Gateway adgangskode', 'sms_gateway_password' => 'Gateway adgangskode',
'sms_from' => 'Afsenderens navn.', 'sms_from' => 'Afsenderens navn.',
'pushover_status' => 'Tillad at sende Pushover beskeder', 'pushover_status' => 'Tillad at sende Pushover beskeder',
'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se <a href="https://pushover.net/">deres website</a> for yderligere information.', 'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se <a href="https://pushover.net/">deres website</a> for yderligere information.',
'pushover_clone_app' => 'Klik her for at oprette din Pushover app', 'pushover_clone_app' => 'Klik her for at oprette din Pushover app',
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du <a href="%1$s" target="_blank" rel="noopener">registrere en app</a> på deres website og indtaste en App API Token her.', 'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du <a href="%1$s" target="_blank" rel="noopener">registrere en app</a> på deres website og indtaste en App API Token her.',
'alert_type' => 'Vælg hvornår du vil modtage beskeden', 'alert_type' => 'Vælg hvornår du vil modtage beskeden',
'alert_type_description' => '<b>Status ændring:</b> '. 'alert_type_description' => '<b>Status ændring:</b> ' .
'Du vil modtage en notifkation når en server har en ændring i status. Fra online -> offline eller offline -> online.<br>'. 'Du vil modtage en notifkation når en server har en ændring i status. Fra online -> offline eller offline -> online.<br>' .
'<br /><b>Offline:</b> '. '<br /><b>Offline:</b> ' .
'Du vil modtage en meddelelse, når en server går offline for første gang. Eksempelvis '. 'Du vil modtage en meddelelse, når en server går offline for første gang. Eksempelvis ' .
'hvis dit cronjob kører hvert kvarter, og din server går ned kl 01 og kommer først op kl 06, '. 'hvis dit cronjob kører hvert kvarter, og din server går ned kl 01 og kommer først op kl 06, ' .
' vil du kun modtage en mail kl 01.<br>'. ' vil du kun modtage en mail kl 01.<br>' .
'<br><b>Altid:</b> '. '<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.', '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_status' => 'Status ændret',
'alert_type_offline' => 'Offline', 'alert_type_offline' => 'Offline',
'alert_type_always' => 'Altid', 'alert_type_always' => 'Altid',
'log_status' => 'Log status', '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_status_description' => 'Hvis log status er sat til TRUE, vil monitoren logge hændelsen hver gang status ændre sig.',
'log_email' => 'Log e-mails sendt af systemet', 'log_email' => 'Log e-mails sendt af systemet',
'log_sms' => 'Log SMS sendt af systemet', 'log_sms' => 'Log SMS sendt af systemet',
'log_pushover' => 'Log pushover messages sent by the script', 'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Indstillingerne er blevet opdateret.', 'updated' => 'Indstillingerne er blevet opdateret.',
'tab_email' => 'E-mail', 'tab_email' => 'E-mail',
'tab_sms' => 'SMS', 'tab_sms' => 'SMS',
'tab_pushover' => 'Pushover', 'tab_pushover' => 'Pushover',
'settings_email' => 'E-mail indstillinger', 'settings_email' => 'E-mail indstillinger',
'settings_sms' => 'SMS indstillinger', 'settings_sms' => 'SMS indstillinger',
'settings_pushover' => 'Pushover settings', 'settings_pushover' => 'Pushover settings',
'settings_notification' => 'Meddelelse indstillinger', 'settings_notification' => 'Meddelelse indstillinger',
'settings_log' => 'Log indstillinger', 'settings_log' => 'Log indstillinger',
'auto_refresh' => 'Genopfrisk automatisk', 'auto_refresh' => 'Genopfrisk automatisk',
'auto_refresh_description' => 'auto_refresh_description' =>
'Genopfrisk automatisk serversider.<br>'. 'Genopfrisk automatisk serversider.<br>' .
'<span class="small">'. '<span class="small">' .
'Tid i sekunder. Hvis 0 vil siden ikke genopfriske automatisk'. 'Tid i sekunder. Hvis 0 vil siden ikke genopfriske automatisk' .
'</span>', '</span>',
'seconds' => 'sekunder', 'seconds' => 'sekunder',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'En e-mail vil blive sendt til den adresse, der er angivet i din brugerprofil.', 'test_email' => 'En e-mail vil blive sendt til den adresse, der er angivet i din brugerprofil.',
'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.', 'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.',
'test_pushover' => 'En Pushover notifikation vil blive sendt til brugerens enhed, specificeret i brugerprofilen.', 'test_pushover' => 'En Pushover notifikation vil blive sendt til brugerens enhed, specificeret i brugerprofilen.',
'send' => 'Send', 'send' => 'Send',
'test_subject' => 'Test', 'test_subject' => 'Test',
'test_message' => 'Test besked', 'test_message' => 'Test besked',
'email_sent' => 'E-mail sendt', 'email_sent' => 'E-mail sendt',
'email_error' => 'Fejl ved afsendelse af e-mail', 'email_error' => 'Fejl ved afsendelse af e-mail',
'sms_sent' => 'Sms sendt', 'sms_sent' => 'Sms sendt',
'sms_error' => 'Fejl ved afsendelse af SMS. %s', 'sms_error' => 'Fejl ved afsendelse af SMS. %s',
'sms_error_nomobile' => 'Ikke muligt at sende SMS: Intet gyldigt telefonnummer blev fundet i din profil.', 'sms_error_nomobile' => 'Ikke muligt at sende SMS: Intet gyldigt telefonnummer blev fundet i din profil.',
'pushover_sent' => 'Pushover notifikation blev sendt', 'pushover_sent' => 'Pushover notifikation blev sendt',
'pushover_error' => 'En fejl opstod under afsendelse af Pushover notifikation: %s', 'pushover_error' => 'En fejl opstod under afsendelse af Pushover notifikation: %s',
'pushover_error_noapp' => 'Ikke muligt at sende test notifikation: Intet Pushover App API token fundet i den globale konfiguration.', 'pushover_error_noapp' => 'Ikke muligt at sende test notifikation: Intet Pushover App API token fundet i den globale konfiguration.',
'pushover_error_nokey' => 'Ikke muligt at sende test notifikation: Ingen Pushover key fundet i din profil.', 'pushover_error_nokey' => 'Ikke muligt at sende test notifikation: Ingen Pushover key fundet i din profil.',
'log_retention_period' => 'Logs gemmes', 'log_retention_period' => 'Logs gemmes',
'log_retention_period_description' => 'Antal dage over hvor længe logs med notifikationer og arkiverede serveres oppetid skal gemmes. Indtast 0 for at deaktivere logoprydning.', 'log_retention_period_description' => 'Antal dage over hvor længe logs med notifikationer og arkiverede serveres oppetid skal gemmes. Indtast 0 for at deaktivere logoprydning.',
'log_retention_days' => 'dage', 'log_retention_days' => 'dage',
), ),
// for newlines in the email messages use <br> // for newlines in the email messages use <br>
'notifications' => array( 'notifications' => array(
'off_sms' => 'Serveren \'%LABEL%\' er NEDE: ip=%IP%, port=%PORT%. Fejl=%ERROR%', 'off_sms' => 'Serveren \'%LABEL%\' er NEDE: ip=%IP%, port=%PORT%. Fejl=%ERROR%',
'off_email_subject' => 'VIGTIGT: Server \'%LABEL%\' er NEDE', 'off_email_subject' => 'VIGTIGT: Server \'%LABEL%\' er NEDE',
'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>Dato: %DATE%", '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>Dato: %DATE%",
'off_pushover_title' => 'Serveren \'%LABEL%\' er NEDE', 'off_pushover_title' => 'Serveren \'%LABEL%\' er NEDE',
'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>Dato: %DATE%", '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>Dato: %DATE%",
'on_sms' => 'Serveren \'%LABEL%\' KØRER: ip=%IP%, port=%PORT%, it was down for %LAST_OFFLINE_DURATION%', 'on_sms' => 'Serveren \'%LABEL%\' KØRER: ip=%IP%, port=%PORT%, it was down for %LAST_OFFLINE_DURATION%',
'on_email_subject' => 'VIGTIGT: Serveren \'%LABEL%\' KØRER', 'on_email_subject' => 'VIGTIGT: Serveren \'%LABEL%\' KØRER',
'on_email_body' => "Serveren '%LABEL%' kører igen, it was down for %LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Dato: %DATE%", 'on_email_body' => "Serveren '%LABEL%' kører igen, it was down for %LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Dato: %DATE%",
'on_pushover_title' => 'Serveren \'%LABEL%\' KØRER', 'on_pushover_title' => 'Serveren \'%LABEL%\' KØRER',
'on_pushover_message' => "Serveren '%LABEL%' kører igen, it was down for %LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Dato: %DATE%", 'on_pushover_message' => "Serveren '%LABEL%' kører igen, it was down for %LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Dato: %DATE%",
), ),
'login' => array( 'login' => array(
'welcome_usermenu' => 'Velkommen, %user_name%', 'welcome_usermenu' => 'Velkommen, %user_name%',
'title_sign_in' => 'Log ind', 'title_sign_in' => 'Log ind',
'title_forgot' => 'Glemt adgangskode?', 'title_forgot' => 'Glemt adgangskode?',
'title_reset' => 'Nulstil din adgangskode', 'title_reset' => 'Nulstil din adgangskode',
'submit' => 'Indsend', 'submit' => 'Indsend',
'remember_me' => 'Husk kode', 'remember_me' => 'Husk kode',
'login' => 'Log ind', 'login' => 'Log ind',
'logout' => 'Log ud', 'logout' => 'Log ud',
'username' => 'Brugernavn', 'username' => 'Brugernavn',
'password' => 'Adgangskode', 'password' => 'Adgangskode',
'password_repeat' => 'Skriv adgangskode igen', 'password_repeat' => 'Skriv adgangskode igen',
'password_forgot' => 'Glemt adgangskode?', 'password_forgot' => 'Glemt adgangskode?',
'password_reset' => 'Nulstil adgangskode', 'password_reset' => 'Nulstil adgangskode',
'password_reset_email_subject' => 'Nulstil din adgangskode for PHP Server Monitor', '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 at linkets gyldighed udløber efter en time.<br><br>%link%', 'password_reset_email_body' => 'Brug venligst følgende link for at nulstille din adgangskode. Bemærk at linkets gyldighed udløber efter en time.<br><br>%link%',
'error_user_incorrect' => 'Det angivet brugernavn kunne ikke findes.', 'error_user_incorrect' => 'Det angivet brugernavn kunne ikke findes.',
'error_login_incorrect' => 'Oplysningerne stemmer ikke overens.', 'error_login_incorrect' => 'Oplysningerne stemmer ikke overens.',
'error_login_passwords_nomatch' => 'De angivne adgangskoder er ikke ens.', 'error_login_passwords_nomatch' => 'De angivne adgangskoder er ikke ens.',
'error_reset_invalid_link' => 'Følgende link er ugyldigt.', '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_forgot' => 'En e-mail er blevet sendt til dig med oplysninger om, hvordan du nulstiller din adgangskode.',
'success_password_reset' => 'Din adgangskode er blevet nulstillet. Log venligst ind igen.', 'success_password_reset' => 'Din adgangskode er blevet nulstillet. Log venligst ind igen.',
), ),
'error' => array( 'error' => array(
'401_unauthorized' => 'Uautoriseret', '401_unauthorized' => 'Uautoriseret',
'401_unauthorized_description' => 'Du har ikke rettigheder til at se denne side.', '401_unauthorized_description' => 'Du har ikke rettigheder til at se denne side.',
), ),
); );

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,480 +27,507 @@
**/ **/
namespace psm\Module; namespace psm\Module;
use psm\Service\Database; use psm\Service\Database;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerAwareTrait;
abstract class AbstractController implements ControllerInterface { abstract class AbstractController implements ControllerInterface
{
use ContainerAwareTrait;
use ContainerAwareTrait; /**
* Current action
* @var string $action
*/
protected $action;
/** /**
* Current action * Default action
* @var string $action * @var string $action_default
*/ * @see setActions()
protected $action; */
protected $action_default;
/** /**
* Default action * Actions available for this module
* @var string $action_default * @var array $actions
* @see setActions() * @see setActions()
*/ * @see getAction()
protected $action_default; */
protected $actions = array();
/** /**
* Actions available for this module * Add footer to page?
* @var array $actions * @var boolean $add_footer
* @see setActions() * @see addFooter()
* @see getAction() */
*/ protected $add_footer = true;
protected $actions = array();
/** /**
* Add footer to page? * Add menu to page?
* @var boolean $add_footer * @var boolean $add_menu
* @see addFooter() * @see addMenu()
*/ */
protected $add_footer = true; protected $add_menu = true;
/** /**
* Add menu to page? * @var string $csrf_key
* @var boolean $add_menu */
* @see addMenu() protected $csrf_key;
*/
protected $add_menu = true;
/** /**
* @var string $csrf_key * Messages to show the user
*/ * @var array $messages
protected $csrf_key; * @see addMessage()
*/
protected $messages = array();
/** /**
* Messages to show the user * Sidebar to add
* @var array $messages * @var \psm\Util\Module\Sidebar $sidebar
* @see addMessage() */
*/ protected $sidebar;
protected $messages = array();
/** /**
* Sidebar to add * array of Modal to add
* @var \psm\Util\Module\Sidebar $sidebar * @var \psm\Util\Module\ModalInterface[] $modal
*/ */
protected $sidebar; protected $modal = array();
/** /**
* array of Modal to add * html code of header accessories
* @var \psm\Util\Module\ModalInterface[] $modal * @var string $header_accessories
*/ */
protected $modal = array(); protected $header_accessories;
/** /**
* html code of header accessories * Database object
* @var string $header_accessories * @var \psm\Service\Database $db
*/ */
protected $header_accessories; protected $db;
/** /**
* Database object * Twig object
* @var \psm\Service\Database $db * @var \Twig_Environment $twig
*/ */
protected $db; protected $twig;
/** /**
* Twig object * User service
* @var \Twig_Environment $twig * @var \psm\Service\User $user
*/ */
protected $twig; protected $user;
/** /**
* User service * Required user level for this module
* @var \psm\Service\User $user * @var int $user_level_required
*/ * @see setMinUserLevelRequired()
protected $user; */
protected $user_level_required = PSM_USER_USER;
/** /**
* Required user level for this module * Required user level for certain actions
* @var int $user_level_required * @var int $user_level_required_actions
* @see setMinUserLevelRequired() * @see setMinUserLevelRequiredForAction()
*/ */
protected $user_level_required = PSM_USER_USER; protected $user_level_required_actions = array();
/** /*
* Required user level for certain actions * Required using black background layout
* @var int $user_level_required_actions * @var boolean $black_background
* @see setMinUserLevelRequiredForAction() */
*/ protected $black_background = false;
protected $user_level_required_actions = array();
/* /**
* Required using black background layout * XHR mode?
* @var boolean $black_background * @var boolean $xhr
*/ * @see isXHR()
protected $black_background = false; */
protected $xhr = false;
/** public function __construct(Database $db, \Twig_Environment $twig)
* XHR mode? {
* @var boolean $xhr $this->db = $db;
* @see isXHR() $this->twig = $twig;
*/ }
protected $xhr = false;
function __construct(Database $db, \Twig_Environment $twig) { /**
$this->db = $db; * Run the controller.
$this->twig = $twig; *
} * @param string $action if NULL, the action will be retrieved from user input (GET/POST)
* @return \Symfony\Component\HttpFoundation\Response
*/
public function run($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) || !($result = $this->runAction($action))) {
* Run the controller. $result = $this->runAction($this->action_default);
* }
* @param string $action if NULL, the action will be retrieved from user input (GET/POST)
* @return \Symfony\Component\HttpFoundation\Response
*/
public function run($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) || !($result = $this->runAction($action))) { if ($result instanceof Response) {
$result = $this->runAction($this->action_default); return $result;
} }
if ($result instanceof Response) { // no response returned from execute, create regular HTML
return $result; return $this->createHTML($result);
} }
// no response returned from execute, create regular HTML /**
return $this->createHTML($result); * Run a specified action
} *
* For it to run, the "execute$action" method must exist.
* @param string $action
* @return mixed FALSE when action couldnt be initialized, response otherwise
*/
protected function runAction($action)
{
if (isset($this->user_level_required_actions[$action])) {
if ($this->getUser()->getUserLevel() > $this->user_level_required_actions[$action]) {
// user is not allowed to access this action..
return false;
}
}
$method = 'execute' . ucfirst($action);
if (method_exists($this, $method)) {
$this->action = $action;
$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;
}
/** /**
* Run a specified action * Create the HTML code for the module.
* *
* For it to run, the "execute$action" method must exist. * If XHR is on, no main template will be added.
* @param string $action *
* @return mixed FALSE when action couldnt be initialized, response otherwise * @param string $html HTML code to add to the main body
*/ * @return \Symfony\Component\HttpFoundation\Response
protected function runAction($action) { */
if (isset($this->user_level_required_actions[$action])) { protected function createHTML($html = null)
if ($this->getUser()->getUserLevel() > $this->user_level_required_actions[$action]) { {
// user is not allowed to access this action.. if (!$this->xhr) {
return false; // in XHR mode, we will not add the main template
} $tpl_data = array(
} 'title' => strtoupper(psm_get_lang('system', 'title')),
$method = 'execute'.ucfirst($action); 'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
if (method_exists($this, $method)) { 'add_footer' => $this->add_footer,
$this->action = $action; 'version' => 'v' . PSM_VERSION,
$result = $this->$method(); 'messages' => $this->getMessages(),
// if result from execute is null, no return value given so return true to indicate a successful execute 'html_content' => $html,
return ($result === null) ? true : $result; );
}
return false;
}
/** // add menu to page?
* Create the HTML code for the module. if ($this->add_menu) {
* $tpl_data['html_menu'] = $this->createHTMLMenu();
* If XHR is on, no main template will be added. }
* // add header accessories to page ?
* @param string $html HTML code to add to the main body if ($this->header_accessories) {
* @return \Symfony\Component\HttpFoundation\Response $tpl_data['header_accessories'] = $this->header_accessories;
*/ }
protected function createHTML($html = null) { // add modal dialog to page ?
if (!$this->xhr) { if (sizeof($this->modal)) {
// in XHR mode, we will not add the main template $html_modal = '';
$tpl_data = array( foreach ($this->modal as $modal) {
'title' => strtoupper(psm_get_lang('system', 'title')), $html_modal .= $modal->createHTML();
'label_back_to_top' => psm_get_lang('system', 'back_to_top'), }
'add_footer' => $this->add_footer, $tpl_data['html_modal'] = $html_modal;
'version' => 'v'.PSM_VERSION, }
'messages' => $this->getMessages(), // add sidebar to page?
'html_content' => $html, if ($this->sidebar !== null) {
); $tpl_data['html_sidebar'] = $this->sidebar->createHTML();
}
// add menu to page? if (psm_update_available()) {
if ($this->add_menu) { $tpl_data['update_available'] = str_replace(
$tpl_data['html_menu'] = $this->createHTMLMenu(); '{version}',
} 'v' .
// add header accessories to page ? psm_get_conf('version_update_check'),
if ($this->header_accessories) { psm_get_lang('system', 'update_available')
$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()) { if ($this->black_background) {
$tpl_data['update_available'] = str_replace('{version}', 'v'.psm_get_conf('version_update_check'), psm_get_lang('system', 'update_available')); $tpl_data['body_class'] = 'black_background';
} }
$html = $this->twig->render('main/body.tpl.html', $tpl_data);
}
if ($this->black_background) { $response = new Response($html);
$tpl_data['body_class'] = 'black_background';
}
$html = $this->twig->render('main/body.tpl.html', $tpl_data);
}
$response = new Response($html); return $response;
}
return $response; /**
} * Create HTML code for the menu
* @return string
*/
protected function createHTMLMenu()
{
$ulvl = $this->getUser()->getUserLevel();
/** $tpl_data = array(
* Create HTML code for the menu 'label_help' => psm_get_lang('menu', 'help'),
* @return string 'label_profile' => psm_get_lang('users', 'profile'),
*/ 'label_logout' => psm_get_lang('login', 'logout'),
protected function createHTMLMenu() { 'url_profile' => psm_build_url(array('mod' => 'user_profile')),
$ulvl = $this->getUser()->getUserLevel(); 'url_logout' => psm_build_url(array('logout' => 1)),
'label_current' => psm_get_lang('system', 'current'),
);
$tpl_data = array( switch ($ulvl) {
'label_help' => psm_get_lang('menu', 'help'), case PSM_USER_ADMIN:
'label_profile' => psm_get_lang('users', 'profile'), $items = array('server_status', 'server', 'server_log', 'user', 'config', 'server_update');
'label_logout' => psm_get_lang('login', 'logout'), break;
'url_profile' => psm_build_url(array('mod' => 'user_profile')), case PSM_USER_USER:
'url_logout' => psm_build_url(array('logout' => 1)), $items = array('server_status', 'server', 'server_log', 'server_update');
'label_current' => psm_get_lang('system', 'current'), break;
); default:
$items = array();
break;
}
$tpl_data['menu'] = array();
foreach ($items as $key) {
$tpl_data['menu'][] = array(
'active' => ($key == psm_GET('mod')) ? 'active' : '',
'url' => psm_build_url(array('mod' => $key)),
'label' => psm_get_lang('menu', $key),
);
}
switch ($ulvl) { if ($ulvl != PSM_USER_ANONYMOUS) {
case PSM_USER_ADMIN: $user = $this->getUser()->getUser();
$items = array('server_status', 'server', 'server_log', 'user', 'config', 'server_update'); $tpl_data['label_usermenu'] = str_replace(
break; '%user_name%',
case PSM_USER_USER: $user->name,
$items = array('server_status', 'server', 'server_log', 'server_update'); psm_get_lang('login', 'welcome_usermenu')
break; );
default: }
$items = array(); return $this->twig->render('main/menu.tpl.html', $tpl_data);
break; }
}
$tpl_data['menu'] = array();
foreach ($items as $key) {
$tpl_data['menu'][] = array(
'active' => ($key == psm_GET('mod')) ? 'active' : '',
'url' => psm_build_url(array('mod' => $key)),
'label' => psm_get_lang('menu', $key),
);
}
if ($ulvl != PSM_USER_ANONYMOUS) { /**
$user = $this->getUser()->getUser(); * Hide or show the footer of the page
$tpl_data['label_usermenu'] = str_replace( * @param boolean $value
'%user_name%', */
$user->name, protected function addFooter($value)
psm_get_lang('login', 'welcome_usermenu') {
); $this->add_footer = $value;
} }
return $this->twig->render('main/menu.tpl.html', $tpl_data);
}
/** /**
* Hide or show the footer of the page * Hide or show the menu of the page
* @param boolean $value * @param boolean $value
*/ */
protected function addFooter($value) { protected function addMenu($value)
$this->add_footer = $value; {
} $this->add_menu = $value;
}
/** /**
* Hide or show the menu of the page * Set actions available
* @param boolean $value * @param string|array $actions
*/ * @param string $default default action
protected function addMenu($value) { * @param boolean $append if TRUE, the actions will be added to the current actions
$this->add_menu = $value; * @return psm\Module\AbstractModule
} * @see getAction()
*/
protected function setActions($actions, $default = null, $append = true)
{
if (!is_array($actions)) {
$actions = array($actions);
}
if ($append) {
$this->actions = array_merge($actions);
} else {
$this->actions = $actions;
}
if ($default !== null) {
$this->action_default = $default;
}
return $this;
}
/** /**
* Set actions available * Get the current action
* @param string|array $actions * @return string
* @param string $default default action * @see setActions()
* @param boolean $append if TRUE, the actions will be added to the current actions */
* @return psm\Module\AbstractModule public function getAction()
* @see getAction() {
*/ return $this->action;
protected function setActions($actions, $default = null, $append = true) { }
if (!is_array($actions)) {
$actions = array($actions);
}
if ($append) {
$this->actions = array_merge($actions);
} else {
$this->actions = $actions;
}
if ($default !== null) {
$this->action_default = $default;
}
return $this;
}
/** /**
* Get the current action * Add one or multiple message to the stack to be displayed to the user
* @return string * @param string|array $msg
* @see setActions() * @param string $shortcode primary/success/warning/danger
*/ * @return \psm\Module\ControllerInterface
public function getAction() { * @see getMessages()
return $this->action; */
} public function addMessage($msg, $shortcode = 'primary')
{
if (!is_array($msg)) {
$msg = array($msg);
}
$class = $shortcode;
switch ($shortcode) {
case 'error':
$icon = 'exclamation-circle';
$class = 'danger';
break;
case 'success':
$icon = 'check-circle';
break;
case 'warning':
$icon = 'exclamation-triangle';
break;
case 'primary':
default:
$icon = 'info-circle';
$shortcode = 'info';
break;
}
/** foreach ($msg as $m) {
* Add one or multiple message to the stack to be displayed to the user $this->messages[] = array(
* @param string|array $msg 'message' => $m,
* @param string $shortcode primary/success/warning/danger 'shortcode' => $shortcode,
* @return \psm\Module\ControllerInterface 'class' => $class,
* @see getMessages() 'icon' => $icon,
*/ );
public function addMessage($msg, $shortcode = 'primary') { }
if (!is_array($msg)) { return $this;
$msg = array($msg); }
}
$class= $shortcode;
switch ($shortcode) {
case 'error':
$icon = 'exclamation-circle';
$class= 'danger';
break;
case 'success':
$icon = 'check-circle';
break;
case 'warning':
$icon = 'exclamation-triangle';
break;
case 'primary':
default:
$icon = 'info-circle';
$shortcode = 'info';
break;
}
foreach ($msg as $m) { /**
$this->messages[] = array( * Get all messages (and optionally clear them)
'message' => $m, * @param boolean $clear
'shortcode' => $shortcode, * @return array
'class' => $class, * @see addMessage()
'icon' => $icon, */
); public function getMessages($clear = true)
} {
return $this; $msgs = $this->messages;
} if ($clear) {
$this->messages = array();
}
return $msgs;
}
/** /**
* Get all messages (and optionally clear them) * Set the minimum required user level for this controller
* @param boolean $clear * @param int $level
* @return array * @return \psm\Module\AbstractController
* @see addMessage() */
*/ public function setMinUserLevelRequired($level)
public function getMessages($clear = true) { {
$msgs = $this->messages; $this->user_level_required = intval($level);
if ($clear) { return $this;
$this->messages = array(); }
}
return $msgs;
}
/** /**
* Set the minimum required user level for this controller * Get the minimum required user level for this controller
* @param int $level * @return int
* @return \psm\Module\AbstractController */
*/ public function getMinUserLevelRequired()
public function setMinUserLevelRequired($level) { {
$this->user_level_required = intval($level); return $this->user_level_required;
return $this; }
}
/** /**
* Get the minimum required user level for this controller * Set the minimum required user level for a certain action.
* @return int *
*/ * Use this only if one of the access is more restricted than the entire controller
public function getMinUserLevelRequired() { * @param int $level
return $this->user_level_required; * @param string|array $actions one or more actions to set this level for
} * @return \psm\Module\AbstractController
* @see setMinUserLevelRequired()
*/
public function setMinUserLevelRequiredForAction($level, $actions)
{
if (!is_array($actions)) {
$actions = array($actions);
}
foreach ($actions as $action) {
$this->user_level_required_actions[$action] = intval($level);
}
return $this;
}
/** /**
* Set the minimum required user level for a certain action. * Add a sidebar to the page
* * @param \psm\Util\Module\SidebarInterface $sidebar
* Use this only if one of the access is more restricted than the entire controller * @return \psm\Module\ControllerInterface
* @param int $level */
* @param string|array $actions one or more actions to set this level for public function setSidebar(\psm\Util\Module\SidebarInterface $sidebar)
* @return \psm\Module\AbstractController {
* @see setMinUserLevelRequired() $this->sidebar = $sidebar;
*/ return $this;
public function setMinUserLevelRequiredForAction($level, $actions) { }
if (!is_array($actions)) {
$actions = array($actions);
}
foreach ($actions as $action) {
$this->user_level_required_actions[$action] = intval($level);
}
return $this;
}
/** /**
* Add a sidebar to the page * Add a modal dialog to the page
* @param \psm\Util\Module\SidebarInterface $sidebar * @param \psm\Util\Module\ModalInterface $modal
* @return \psm\Module\ControllerInterface * @return \psm\Module\ControllerInterface
*/ */
public function setSidebar(\psm\Util\Module\SidebarInterface $sidebar) { public function addModal(\psm\Util\Module\ModalInterface $modal)
$this->sidebar = $sidebar; {
return $this; $this->modal[$modal->getModalID()] = $modal;
} return $this;
}
/** /**
* Add a modal dialog to the page * Set the html code of the header accessories
* @param \psm\Util\Module\ModalInterface $modal * @param string $html
* @return \psm\Module\ControllerInterface */
*/ public function setHeaderAccessories($html)
public function addModal(\psm\Util\Module\ModalInterface $modal) { {
$this->modal[$modal->getModalID()] = $modal; $this->header_accessories = $html;
return $this; }
}
/** /**
* Set the html code of the header accessories * Check if XHR is on
* @param string $html * @return boolean
*/ */
public function setHeaderAccessories($html) { public function isXHR()
$this->header_accessories = $html; {
} return $this->xhr;
}
/** /**
* Check if XHR is on * Get user service
* @return boolean * @return \psm\Service\User
*/ */
public function isXHR() { public function getUser()
return $this->xhr; {
} return $this->container->get('user');
}
/** /**
* Get user service * Get custom key for CSRF validation
* @return \psm\Service\User * @return string
*/ */
public function getUser() { public function getCSRFKey()
return $this->container->get('user'); {
} return $this->csrf_key;
}
/** /**
* Get custom key for CSRF validation * Set CSRF key for validation
* @return string * @param string $key
*/ * @return \psm\Module\ControllerInterface
public function getCSRFKey() { */
return $this->csrf_key; protected function setCSRFKey($key)
} {
$this->csrf_key = $key;
/** $this->twig->addGlobal('csrf_key', $key);
* Set CSRF key for validation return $this;
* @param string $key }
* @return \psm\Module\ControllerInterface
*/
protected function setCSRFKey($key) {
$this->csrf_key = $key;
$this->twig->addGlobal('csrf_key', $key);
return $this;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,7 +24,7 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0 * @since phpservermon 3.0
**/ **/
namespace psm\Module\Config; namespace psm\Module\Config;
@ -31,16 +32,17 @@ namespace psm\Module\Config;
use psm\Module\ModuleInterface; use psm\Module\ModuleInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
class ConfigModule implements ModuleInterface { class ConfigModule implements ModuleInterface
{
public function load(ContainerBuilder $container) { public function load(ContainerBuilder $container)
{
}
} public function getControllers()
{
public function getControllers() { return array(
return array( 'config' => __NAMESPACE__ . '\Controller\ConfigController',
'config' => __NAMESPACE__.'\Controller\ConfigController', );
); }
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,411 +27,431 @@
**/ **/
namespace psm\Module\Config\Controller; namespace psm\Module\Config\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class ConfigController extends AbstractController { class ConfigController extends AbstractController
{
/** /**
* Checkboxes * Checkboxes
* @var array $checkboxes * @var array $checkboxes
*/ */
protected $checkboxes = array( protected $checkboxes = array(
'proxy', 'proxy',
'email_status', 'email_status',
'email_smtp', 'email_smtp',
'sms_status', 'sms_status',
'pushover_status', 'pushover_status',
'telegram_status', 'telegram_status',
'log_status', 'log_status',
'log_email', 'log_email',
'log_sms', 'log_sms',
'log_pushover', 'log_pushover',
'log_telegram', 'log_telegram',
'show_update', 'show_update',
'combine_notifications', 'combine_notifications',
); );
/** /**
* Fields for saving * Fields for saving
* @var array $fields * @var array $fields
*/ */
protected $fields = array( protected $fields = array(
'proxy_url', 'proxy_url',
'proxy_user', 'proxy_user',
'proxy_password', 'proxy_password',
'email_from_name', 'email_from_name',
'email_from_email', 'email_from_email',
'email_smtp_host', 'email_smtp_host',
'email_smtp_port', 'email_smtp_port',
'email_smtp_username', 'email_smtp_username',
'email_smtp_password', 'email_smtp_password',
'sms_gateway_username', 'sms_gateway_username',
'sms_gateway_password', 'sms_gateway_password',
'sms_from', 'sms_from',
'pushover_api_token', 'pushover_api_token',
'telegram_api_token', 'telegram_api_token',
); );
private $default_tab = 'general'; private $default_tab = 'general';
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ADMIN); $this->setMinUserLevelRequired(PSM_USER_ADMIN);
$this->setCSRFKey('config'); $this->setCSRFKey('config');
$this->setActions(array( $this->setActions(array(
'index', 'save', 'index', 'save',
), 'index'); ), 'index');
} }
/** /**
* Populate all the config fields with values from the database * Populate all the config fields with values from the database
* *
* @return string * @return string
*/ */
protected function executeIndex() { protected function executeIndex()
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'config')); {
$tpl_data = $this->getLabels(); $this->twig->addGlobal('subtitle', psm_get_lang('menu', 'config'));
$tpl_data = $this->getLabels();
$config_db = $this->db->select( $config_db = $this->db->select(
PSM_DB_PREFIX.'config', PSM_DB_PREFIX . 'config',
null, null,
array('key', 'value') array('key', 'value')
); );
$config = array(); $config = array();
foreach ($config_db as $entry) { foreach ($config_db as $entry) {
$config[$entry['key']] = $entry['value']; $config[$entry['key']] = $entry['value'];
} }
// generate language array // generate language array
$lang_keys = psm_get_langs(); $lang_keys = psm_get_langs();
$tpl_data['language_current'] = (isset($config['language'])) $tpl_data['language_current'] = (isset($config['language']))
? $config['language'] ? $config['language']
: 'en_US'; : 'en_US';
$tpl_data['languages'] = array(); $tpl_data['languages'] = array();
foreach ($lang_keys as $key => $label) { foreach ($lang_keys as $key => $label) {
$tpl_data['languages'][] = array( $tpl_data['languages'][] = array(
'value' => $key, 'value' => $key,
'label' => $label, 'label' => $label,
); );
} }
// generate sms_gateway array // generate sms_gateway array
$sms_gateways = psm_get_sms_gateways(); $sms_gateways = psm_get_sms_gateways();
$tpl_data['sms_gateway'] = array(); $tpl_data['sms_gateway'] = array();
foreach ($sms_gateways as $sms_gateway => $label) { foreach ($sms_gateways as $sms_gateway => $label) {
$tpl_data['sms_gateway'][] = array( $tpl_data['sms_gateway'][] = array(
'value' => $sms_gateway, 'value' => $sms_gateway,
'label' => $label, 'label' => $label,
); );
} }
foreach (array("status", "offline", "always") as $alert_type) { foreach (array("status", "offline", "always") as $alert_type) {
$tpl_data['alert_type'][] = array( $tpl_data['alert_type'][] = array(
'value' => $alert_type, 'value' => $alert_type,
'label' => psm_get_lang('config', 'alert_type_'.$alert_type), 'label' => psm_get_lang('config', 'alert_type_' . $alert_type),
); );
} }
$tpl_data['email_smtp_security'] = array( $tpl_data['email_smtp_security'] = array(
array( array(
'value' => '', 'value' => '',
'label' => psm_get_lang('config', 'email_smtp_security_none') 'label' => psm_get_lang('config', 'email_smtp_security_none')
), ),
array( array(
'value' => 'ssl', 'value' => 'ssl',
'label' => 'SSL' 'label' => 'SSL'
), ),
array( array(
'value' => 'tls', 'value' => 'tls',
'label' => 'TLS' 'label' => 'TLS'
) )
); );
$tpl_data['sms_gateway_selected'] = isset($config['sms_gateway']) ? $config['sms_gateway'] : current($sms_gateways); $tpl_data['sms_gateway_selected'] = isset($config['sms_gateway']) ?
$tpl_data['alert_type_selected'] = isset($config['alert_type']) ? $config['alert_type'] : ''; $config['sms_gateway'] : current($sms_gateways);
$tpl_data['email_smtp_security_selected'] = isset($config['email_smtp_security']) ? $config['email_smtp_security'] : ''; $tpl_data['alert_type_selected'] = isset($config['alert_type']) ?
$tpl_data['auto_refresh_servers'] = isset($config['auto_refresh_servers']) ? $config['auto_refresh_servers'] : '0'; $config['alert_type'] : '';
$tpl_data['log_retention_period'] = isset($config['log_retention_period']) ? $config['log_retention_period'] : '365'; $tpl_data['email_smtp_security_selected'] = isset($config['email_smtp_security']) ?
$tpl_data['password_encrypt_key'] = isset($config['password_encrypt_key']) ? $config['password_encrypt_key'] : sha1(microtime()); $config['email_smtp_security'] : '';
$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';
$tpl_data['password_encrypt_key'] = isset($config['password_encrypt_key']) ?
$config['password_encrypt_key'] : sha1(microtime());
foreach ($this->checkboxes as $input_key) { foreach ($this->checkboxes as $input_key) {
$tpl_data[$input_key.'_checked'] = $tpl_data[$input_key . '_checked'] =
(isset($config[$input_key]) && (int) $config[$input_key] == 1) (isset($config[$input_key]) && (int) $config[$input_key] == 1)
? 'checked="checked"' ? 'checked="checked"'
: ''; : '';
} }
foreach ($this->fields as $input_key) { foreach ($this->fields as $input_key) {
$tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : ''; $tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : '';
} }
$tpl_data[$this->default_tab.'_active'] = 'active'; $tpl_data[$this->default_tab . '_active'] = 'active';
$testmodals = array('email', 'sms', 'pushover', 'telegram'); $testmodals = array('email', 'sms', 'pushover', 'telegram');
foreach ($testmodals as $modal_id) { foreach ($testmodals as $modal_id) {
$modal = new \psm\Util\Module\Modal($this->twig, 'test'.ucfirst($modal_id), \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL); $modal = new \psm\Util\Module\Modal(
$this->addModal($modal); $this->twig,
$modal->setTitle(psm_get_lang('servers', 'send_'.$modal_id)); 'test' . ucfirst($modal_id),
$modal->setMessage(psm_get_lang('config', 'test_'.$modal_id)); \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL
$modal->setOKButtonLabel(psm_get_lang('config', 'send')); );
} $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); return $this->twig->render('module/config/config.tpl.html', $tpl_data);
} }
/** /**
* If a post has been done, gather all the posted data * If a post has been done, gather all the posted data
* and save it to the database * and save it to the database
*/ */
protected function executeSave() { protected function executeSave()
if (!empty($_POST)) { {
// save new config if (!empty($_POST)) {
$clean = array( // save new config
'language' => $_POST['language'], $clean = array(
'sms_gateway' => $_POST['sms_gateway'], 'language' => $_POST['language'],
'alert_type' => $_POST['alert_type'], 'sms_gateway' => $_POST['sms_gateway'],
'email_smtp_security' => 'alert_type' => $_POST['alert_type'],
in_array($_POST['email_smtp_security'], array('', 'ssl', 'tls')) 'email_smtp_security' =>
? $_POST['email_smtp_security'] in_array($_POST['email_smtp_security'], array('', 'ssl', 'tls'))
: '', ? $_POST['email_smtp_security']
'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)), : '',
'log_retention_period' => intval(psm_POST('log_retention_period', 365)), 'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)),
'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime())), 'log_retention_period' => intval(psm_POST('log_retention_period', 365)),
); 'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime())),
foreach ($this->checkboxes as $input_key) { );
$clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0'; foreach ($this->checkboxes as $input_key) {
} $clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0';
foreach ($this->fields as $input_key) { }
if (isset($_POST[$input_key])) { foreach ($this->fields as $input_key) {
$clean[$input_key] = $_POST[$input_key]; if (isset($_POST[$input_key])) {
} $clean[$input_key] = $_POST[$input_key];
} }
$language_refresh = ($clean['language'] != psm_get_conf('language')); }
foreach ($clean as $key => $value) { $language_refresh = ($clean['language'] != psm_get_conf('language'));
psm_update_conf($key, $value); foreach ($clean as $key => $value) {
} psm_update_conf($key, $value);
$this->addMessage(psm_get_lang('config', 'updated'), 'success'); }
$this->addMessage(psm_get_lang('config', 'updated'), 'success');
if (!empty($_POST['test_email'])) { if (!empty($_POST['test_email'])) {
$this->testEmail(); $this->testEmail();
} elseif (!empty($_POST['test_sms'])) { } elseif (!empty($_POST['test_sms'])) {
$this->testSMS(); $this->testSMS();
} elseif (!empty($_POST['test_pushover'])) { } elseif (!empty($_POST['test_pushover'])) {
$this->testPushover(); $this->testPushover();
} elseif (!empty($_POST['test_telegram'])) { } elseif (!empty($_POST['test_telegram'])) {
$this->testTelegram(); $this->testTelegram();
} }
if ($language_refresh) { if ($language_refresh) {
header('Location: '.psm_build_url(array('mod' => 'config'), true, false)); header('Location: ' . psm_build_url(array('mod' => 'config'), true, false));
die(); die();
} }
if (isset($_POST['general_submit'])) { if (isset($_POST['general_submit'])) {
$this->default_tab = 'general'; $this->default_tab = 'general';
} elseif (isset($_POST['email_submit']) || !empty($_POST['test_email'])) { } elseif (isset($_POST['email_submit']) || !empty($_POST['test_email'])) {
$this->default_tab = 'email'; $this->default_tab = 'email';
} elseif (isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) { } elseif (isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) {
$this->default_tab = 'sms'; $this->default_tab = 'sms';
} elseif (isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) { } elseif (isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) {
$this->default_tab = 'pushover'; $this->default_tab = 'pushover';
} elseif (isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) { } elseif (isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) {
$this->default_tab = 'telegram'; $this->default_tab = 'telegram';
} }
} }
return $this->runAction('index'); return $this->runAction('index');
} }
/** /**
* Execute email test * Execute email test
* *
* @todo move test to separate class * @todo move test to separate class
*/ */
protected function testEmail() { protected function testEmail()
$mail = psm_build_mail(); {
$message = psm_get_lang('config', 'test_message'); $mail = psm_build_mail();
$mail->Subject = psm_get_lang('config', 'test_subject'); $message = psm_get_lang('config', 'test_message');
$mail->Priority = 1; $mail->Subject = psm_get_lang('config', 'test_subject');
$mail->Body = $message; $mail->Priority = 1;
$mail->AltBody = str_replace('<br/>', "\n", $message); $mail->Body = $message;
$user = $this->getUser()->getUser(); $mail->AltBody = str_replace('<br/>', "\n", $message);
$mail->AddAddress($user->email, $user->name); $user = $this->getUser()->getUser();
if ($mail->Send()) { $mail->AddAddress($user->email, $user->name);
$this->addMessage(psm_get_lang('config', 'email_sent'), 'success'); if ($mail->Send()) {
} else { $this->addMessage(psm_get_lang('config', 'email_sent'), 'success');
$this->addMessage(psm_get_lang('config', 'email_error').': '.$mail->ErrorInfo, 'error'); } else {
} $this->addMessage(psm_get_lang('config', 'email_error') . ': ' . $mail->ErrorInfo, 'error');
} }
}
/** /**
* Execute SMS test * Execute SMS test
* *
* @todo move test to separate class * @todo move test to separate class
*/ */
protected function testSMS() { protected function testSMS()
$sms = psm_build_sms(); {
if ($sms) { $sms = psm_build_sms();
$user = $this->getUser()->getUser(); if ($sms) {
if (empty($user->mobile)) { $user = $this->getUser()->getUser();
$this->addMessage(psm_get_lang('config', 'sms_error_nomobile'), 'error'); if (empty($user->mobile)) {
} else { $this->addMessage(psm_get_lang('config', 'sms_error_nomobile'), 'error');
$sms->addRecipients($user->mobile); } else {
$result = $sms->sendSMS(psm_get_lang('config', 'test_message')); $sms->addRecipients($user->mobile);
if ($result === 1) { $result = $sms->sendSMS(psm_get_lang('config', 'test_message'));
$this->addMessage(psm_get_lang('config', 'sms_sent'), 'success'); if ($result === 1) {
} else { $this->addMessage(psm_get_lang('config', 'sms_sent'), 'success');
$this->addMessage(sprintf(psm_get_lang('config', 'sms_error'), $result), 'error'); } else {
} $this->addMessage(sprintf(psm_get_lang('config', 'sms_error'), $result), 'error');
} }
} }
} }
}
/** /**
* Execute pushover test * Execute pushover test
* *
* @todo move test to separate class * @todo move test to separate class
*/ */
protected function testPushover() { protected function testPushover()
$pushover = psm_build_pushover(); {
$pushover->setDebug(true); $pushover = psm_build_pushover();
$user = $this->getUser()->getUser(); $pushover->setDebug(true);
$apiToken = psm_get_conf('pushover_api_token'); $user = $this->getUser()->getUser();
$apiToken = psm_get_conf('pushover_api_token');
if (empty($apiToken)) { if (empty($apiToken)) {
$this->addMessage(psm_get_lang('config', 'pushover_error_noapp'), 'error'); $this->addMessage(psm_get_lang('config', 'pushover_error_noapp'), 'error');
} elseif (empty($user->pushover_key)) { } elseif (empty($user->pushover_key)) {
$this->addMessage(psm_get_lang('config', 'pushover_error_nokey'), 'error'); $this->addMessage(psm_get_lang('config', 'pushover_error_nokey'), 'error');
} else { } else {
$pushover->setPriority(0); $pushover->setPriority(0);
$pushover->setTitle(psm_get_lang('config', 'test_subject')); $pushover->setTitle(psm_get_lang('config', 'test_subject'));
$pushover->setMessage(psm_get_lang('config', 'test_message')); $pushover->setMessage(psm_get_lang('config', 'test_message'));
$pushover->setUser($user->pushover_key); $pushover->setUser($user->pushover_key);
if ($user->pushover_device != '') { if ($user->pushover_device != '') {
$pushover->setDevice($user->pushover_device); $pushover->setDevice($user->pushover_device);
} }
$result = $pushover->send(); $result = $pushover->send();
if (isset($result['output']->status) && $result['output']->status == 1) { if (isset($result['output']->status) && $result['output']->status == 1) {
$this->addMessage(psm_get_lang('config', 'pushover_sent'), 'success'); $this->addMessage(psm_get_lang('config', 'pushover_sent'), 'success');
} else { } else {
if (isset($result['output']->errors->error)) { if (isset($result['output']->errors->error)) {
$error = $result['output']->errors->error; $error = $result['output']->errors->error;
} else { } else {
$error = 'Unknown'; $error = 'Unknown';
} }
$this->addMessage(sprintf(psm_get_lang('config', 'pushover_error'), $error), 'error'); $this->addMessage(sprintf(psm_get_lang('config', 'pushover_error'), $error), 'error');
} }
} }
} }
/** /**
* Execute telegram test * Execute telegram test
* *
* @todo move test to separate class * @todo move test to separate class
*/ */
protected function testTelegram() { protected function testTelegram()
$telegram = psm_build_telegram(); {
$user = $this->getUser()->getUser(); $telegram = psm_build_telegram();
$apiToken = psm_get_conf('telegram_api_token'); $user = $this->getUser()->getUser();
$apiToken = psm_get_conf('telegram_api_token');
if (empty($apiToken)) { if (empty($apiToken)) {
$this->addMessage(psm_get_lang('config', 'telegram_error_notoken'), 'error'); $this->addMessage(psm_get_lang('config', 'telegram_error_notoken'), 'error');
} elseif (empty($user->telegram_id)) { } elseif (empty($user->telegram_id)) {
$this->addMessage(psm_get_lang('config', 'telegram_error_noid'), 'error'); $this->addMessage(psm_get_lang('config', 'telegram_error_noid'), 'error');
} else { } else {
$telegram->setMessage(psm_get_lang('config', 'test_message')); $telegram->setMessage(psm_get_lang('config', 'test_message'));
$telegram->setUser($user->telegram_id); $telegram->setUser($user->telegram_id);
$result = $telegram->send(); $result = $telegram->send();
if (isset($result['ok']) && $result['ok'] != false) { if (isset($result['ok']) && $result['ok'] != false) {
$this->addMessage(psm_get_lang('config', 'telegram_sent'), 'success'); $this->addMessage(psm_get_lang('config', 'telegram_sent'), 'success');
} else { } else {
if (isset($result['description'])) { if (isset($result['description'])) {
$error = $result['description']; $error = $result['description'];
} else { } else {
$error = 'Unknown'; $error = 'Unknown';
} }
$this->addMessage(sprintf(psm_get_lang('config', 'telegram_error'), $error), 'error'); $this->addMessage(sprintf(psm_get_lang('config', 'telegram_error'), $error), 'error');
} }
} }
} }
protected function getLabels() { protected function getLabels()
return array( {
'label_tab_email' => psm_get_lang('config', 'tab_email'), return array(
'label_tab_sms' => psm_get_lang('config', 'tab_sms'), 'label_tab_email' => psm_get_lang('config', 'tab_email'),
'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'), 'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'), 'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_settings_email' => psm_get_lang('config', 'settings_email'), 'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'), 'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'), 'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'), 'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'), 'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'),
'label_settings_log' => psm_get_lang('config', 'settings_log'), 'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'), 'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_general' => psm_get_lang('config', 'general'), 'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'),
'label_language' => psm_get_lang('config', 'language'), 'label_general' => psm_get_lang('config', 'general'),
'label_show_update' => psm_get_lang('config', 'show_update'), 'label_language' => psm_get_lang('config', 'language'),
'label_password_encrypt_key' => psm_get_lang('config', 'password_encrypt_key'), 'label_show_update' => psm_get_lang('config', 'show_update'),
'label_password_encrypt_key_note' => psm_get_lang('config', 'password_encrypt_key_note'), 'label_password_encrypt_key' => psm_get_lang('config', 'password_encrypt_key'),
'label_proxy' => psm_get_lang('config', 'proxy'), 'label_password_encrypt_key_note' => psm_get_lang('config', 'password_encrypt_key_note'),
'label_proxy_url' => psm_get_lang('config', 'proxy_url'), 'label_proxy' => psm_get_lang('config', 'proxy'),
'label_proxy_user' => psm_get_lang('config', 'proxy_user'), 'label_proxy_url' => psm_get_lang('config', 'proxy_url'),
'label_proxy_password' => psm_get_lang('config', 'proxy_password'), 'label_proxy_user' => psm_get_lang('config', 'proxy_user'),
'label_email_status' => psm_get_lang('config', 'email_status'), 'label_proxy_password' => psm_get_lang('config', 'proxy_password'),
'label_email_from_email' => psm_get_lang('config', 'email_from_email'), 'label_email_status' => psm_get_lang('config', 'email_status'),
'label_email_from_name' => psm_get_lang('config', 'email_from_name'), 'label_email_from_email' => psm_get_lang('config', 'email_from_email'),
'label_email_smtp' => psm_get_lang('config', 'email_smtp'), 'label_email_from_name' => psm_get_lang('config', 'email_from_name'),
'label_email_smtp_host' => psm_get_lang('config', 'email_smtp_host'), 'label_email_smtp' => psm_get_lang('config', 'email_smtp'),
'label_email_smtp_port' => psm_get_lang('config', 'email_smtp_port'), 'label_email_smtp_host' => psm_get_lang('config', 'email_smtp_host'),
'label_email_smtp_security' => psm_get_lang('config', 'email_smtp_security'), '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_security' => psm_get_lang('config', 'email_smtp_security'),
'label_email_smtp_password' => psm_get_lang('config', 'email_smtp_password'), 'label_email_smtp_username' => psm_get_lang('config', 'email_smtp_username'),
'label_email_smtp_noauth' => psm_get_lang('config', 'email_smtp_noauth'), 'label_email_smtp_password' => psm_get_lang('config', 'email_smtp_password'),
'label_sms_status' => psm_get_lang('config', 'sms_status'), 'label_email_smtp_noauth' => psm_get_lang('config', 'email_smtp_noauth'),
'label_sms_gateway' => psm_get_lang('config', 'sms_gateway'), 'label_sms_status' => psm_get_lang('config', 'sms_status'),
'label_sms_gateway_username' => psm_get_lang('config', 'sms_gateway_username'), 'label_sms_gateway' => psm_get_lang('config', 'sms_gateway'),
'label_sms_gateway_password' => psm_get_lang('config', 'sms_gateway_password'), 'label_sms_gateway_username' => psm_get_lang('config', 'sms_gateway_username'),
'label_sms_from' => psm_get_lang('config', 'sms_from'), 'label_sms_gateway_password' => psm_get_lang('config', 'sms_gateway_password'),
'label_pushover_description' => psm_get_lang('config', 'pushover_description'), 'label_sms_from' => psm_get_lang('config', 'sms_from'),
'label_pushover_status' => psm_get_lang('config', 'pushover_status'), 'label_pushover_description' => psm_get_lang('config', 'pushover_description'),
'label_pushover_clone_app' => psm_get_lang('config', 'pushover_clone_app'), 'label_pushover_status' => psm_get_lang('config', 'pushover_status'),
'pushover_clone_url' => PSM_PUSHOVER_CLONE_URL, 'label_pushover_clone_app' => psm_get_lang('config', 'pushover_clone_app'),
'label_pushover_api_token' => psm_get_lang('config', 'pushover_api_token'), 'pushover_clone_url' => PSM_PUSHOVER_CLONE_URL,
'label_pushover_api_token_description' => sprintf( 'label_pushover_api_token' => psm_get_lang('config', 'pushover_api_token'),
psm_get_lang('config', 'pushover_api_token_description'), 'label_pushover_api_token_description' => sprintf(
PSM_PUSHOVER_CLONE_URL psm_get_lang('config', 'pushover_api_token_description'),
), PSM_PUSHOVER_CLONE_URL
'label_telegram_description' => psm_get_lang('config', 'telegram_description'), ),
'label_telegram_status' => psm_get_lang('config', 'telegram_status'), 'label_telegram_description' => psm_get_lang('config', 'telegram_description'),
'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'), 'label_telegram_status' => psm_get_lang('config', 'telegram_status'),
'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'), 'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'),
'label_alert_type' => psm_get_lang('config', 'alert_type'), 'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'), 'label_alert_type' => psm_get_lang('config', 'alert_type'),
'label_combine_notifications' => psm_get_lang('config', 'combine_notifications'), 'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_combine_notifications' => psm_get_lang('config', 'combine_notifications'),
'label_combine_notifications_description' => psm_get_lang('config', 'combine_notifications_description'), 'label_combine_notifications_description' => psm_get_lang('config', 'combine_notifications_description'),
'label_log_status' => psm_get_lang('config', 'log_status'), 'label_log_status' => psm_get_lang('config', 'log_status'),
'label_log_status_description' => psm_get_lang('config', 'log_status_description'), 'label_log_status_description' => psm_get_lang('config', 'log_status_description'),
'label_log_email' => psm_get_lang('config', 'log_email'), 'label_log_email' => psm_get_lang('config', 'log_email'),
'label_log_sms' => psm_get_lang('config', 'log_sms'), 'label_log_sms' => psm_get_lang('config', 'log_sms'),
'label_log_pushover' => psm_get_lang('config', 'log_pushover'), 'label_log_pushover' => psm_get_lang('config', 'log_pushover'),
'label_log_telegram' => psm_get_lang('config', 'log_telegram'), 'label_log_telegram' => psm_get_lang('config', 'log_telegram'),
'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'), 'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'),
'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'), 'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'),
'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'), 'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
'label_auto_refresh_description' => psm_get_lang('config', 'auto_refresh_description'), 'label_auto_refresh_description' => psm_get_lang('config', 'auto_refresh_description'),
'label_seconds' => psm_get_lang('config', 'seconds'), 'label_seconds' => psm_get_lang('config', 'seconds'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),
'label_test' => psm_get_lang('config', 'test'), 'label_test' => psm_get_lang('config', 'test'),
'label_log_retention_period' => psm_get_lang('config', 'log_retention_period'), 'label_log_retention_period' => psm_get_lang('config', 'log_retention_period'),
'label_log_retention_period_description' => psm_get_lang('config', 'log_retention_period_description'), 'label_log_retention_period_description' => psm_get_lang('config', 'log_retention_period_description'),
'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'), 'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'),
'label_days' => psm_get_lang('config', 'log_retention_days'), 'label_days' => psm_get_lang('config', 'log_retention_days'),
); );
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,31 +24,33 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 2.1 * @since phpservermon 2.1
**/ **/
namespace psm\Module; namespace psm\Module;
use psm\Service\Database; use psm\Service\Database;
use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface;
interface ControllerInterface extends ContainerAwareInterface { interface ControllerInterface extends ContainerAwareInterface
{
public function __construct(Database $db, \Twig_Environment $twig); public function __construct(Database $db, \Twig_Environment $twig);
/** /**
* Run the controller * Run the controller
*/ */
public function run(); public function run();
/** /**
* Get the minimum required user level for this controller * Get the minimum required user level for this controller
* @return int * @return int
*/ */
public function getMinUserLevelRequired(); public function getMinUserLevelRequired();
/** /**
* Get custom key for CSRF validation * Get custom key for CSRF validation
* @return string * @return string
*/ */
public function getCSRFKey(); public function getCSRFKey();
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,30 +28,34 @@
**/ **/
namespace psm\Module\Error\Controller; namespace psm\Module\Error\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class ErrorController extends AbstractController { class ErrorController extends AbstractController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS); $this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
$this->setActions(array( $this->setActions(array(
'401', '401',
), '401'); ), '401');
} }
/** /**
* 401 error page * 401 error page
* *
* @return string * @return string
*/ */
protected function execute401() { protected function execute401()
return $this->twig->render('module/error/401.tpl.html', array( {
'label_title' => psm_get_lang('error', '401_unauthorized'), return $this->twig->render('module/error/401.tpl.html', array(
'label_description' => psm_get_lang('error', '401_unauthorized_description'), 'label_title' => psm_get_lang('error', '401_unauthorized'),
)); 'label_description' => psm_get_lang('error', '401_unauthorized_description'),
} ));
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -31,16 +32,17 @@ namespace psm\Module\Error;
use psm\Module\ModuleInterface; use psm\Module\ModuleInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
class ErrorModule implements ModuleInterface { class ErrorModule implements ModuleInterface
{
public function load(ContainerBuilder $container) { public function load(ContainerBuilder $container)
{
}
} public function getControllers()
{
public function getControllers() { return array(
return array( 'error' => __NAMESPACE__ . '\Controller\ErrorController',
'error' => __NAMESPACE__.'\Controller\ErrorController', );
); }
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,356 +24,391 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 2.1.0 * @since phpservermon 2.1.0
**/ **/
namespace psm\Module\Install\Controller; namespace psm\Module\Install\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class InstallController extends AbstractController { class InstallController extends AbstractController
{
/** /**
* Full path to config file * Full path to config file
* @var string $path_config * @var string $path_config
*/ */
protected $path_config; protected $path_config;
/** /**
* Full path to old config file (2.0) * Full path to old config file (2.0)
* @var string $path_config_old * @var string $path_config_old
*/ */
protected $path_config_old; protected $path_config_old;
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS); $this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
$this->setCSRFKey('install'); $this->setCSRFKey('install');
$this->addMenu(false); $this->addMenu(false);
$this->path_config = PSM_PATH_SRC.'../config.php'; $this->path_config = PSM_PATH_SRC . '../config.php';
$this->path_config_old = PSM_PATH_SRC.'../config.inc.php'; $this->path_config_old = PSM_PATH_SRC . '../config.inc.php';
$this->setActions(array( $this->setActions(array(
'index', 'config', 'install' 'index', 'config', 'install'
), 'index'); ), 'index');
$this->twig->addGlobal('subtitle', psm_get_lang('system', 'install')); $this->twig->addGlobal('subtitle', psm_get_lang('system', 'install'));
} }
/** /**
* Say hi to our new user * Say hi to our new user
*/ */
protected function executeIndex() { protected function executeIndex()
// build prerequisites {
$errors = 0; // build prerequisites
$errors = 0;
$phpv = phpversion(); $phpv = phpversion();
if (version_compare($phpv, '5.5.9', '<') || (version_compare($phpv, '7.0.8', '<') && version_compare($phpv, '7.0.0', '>='))) { if (
$errors++; version_compare($phpv, '5.5.9', '<') ||
$this->addMessage('PHP 5.5.9+ or 7.0.8+ is required to run PHP Server Monitor. You\'re using '.$phpv.'.', 'error'); (version_compare($phpv, '7.0.8', '<') && version_compare($phpv, '7.0.0', '>='))
} else { ) {
$this->addMessage('PHP version: '.$phpv, 'success'); $errors++;
} $this->addMessage('PHP 5.5.9+ or 7.0.8+ is required to run PHP Server Monitor. You\'re using ' .
if (version_compare(PHP_RELEASE_VERSION, '7', '<')) { $phpv . '.', 'error');
$this->addMessage('PHP 5 reaches the end of life (January 1, 2019), please update to PHP 7. PHP supported versions can be found <a href="https://secure.php.net/supported-versions.php" target="_blank" rel="noopener">here</a>.', 'warning'); } else {
} $this->addMessage('PHP version: ' . $phpv, 'success');
if (!function_exists('curl_init')) { }
$this->addMessage('PHP is installed without the cURL module. Please install cURL.', 'warning'); if (version_compare(PHP_RELEASE_VERSION, '7', '<')) {
} else { $this->addMessage(
$this->addMessage('PHP cURL module found', 'success'); 'PHP 5 reaches the end of life (January 1, 2019), please update to PHP 7.
} PHP supported versions can be found
if (!in_array('mysql', \PDO::getAvailableDrivers())) { <a href="https://secure.php.net/supported-versions.php" target="_blank"
$errors++; rel="noopener">here</a>.',
$this->addMessage('The PDO MySQL driver needs to be installed.', 'error'); 'warning'
} );
if (!ini_get('date.timezone')) { }
$this->addMessage('You should set a timezone in your php.ini file (e.g. \'date.timezone = UTC\'). See <a href="http://www.php.net/manual/en/timezones.php" target="_blank" rel="noopener">this page</a> for more info.', 'warning'); if (!function_exists('curl_init')) {
} $this->addMessage('PHP is installed without the cURL module. Please install cURL.', 'warning');
} else {
$this->addMessage('PHP cURL module found', 'success');
}
if (!in_array('mysql', \PDO::getAvailableDrivers())) {
$errors++;
$this->addMessage('The PDO MySQL driver needs to be installed.', 'error');
}
if (!ini_get('date.timezone')) {
$this->addMessage(
'You should set a timezone in your php.ini file (e.g. \'date.timezone = UTC\').
See <a href="http://www.php.net/manual/en/timezones.php" target="_blank" rel="noopener">this page</a>
for more info.',
'warning'
);
}
if ($errors > 0) { if ($errors > 0) {
$this->addMessage($errors.' error(s) have been encountered. Please fix them and refresh this page.', 'error'); $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( return $this->twig->render('module/install/index.tpl.html', array(
'messages' => $this->getMessages() 'messages' => $this->getMessages()
)); ));
} }
/** /**
* Help the user create a new config file * Help the user create a new config file
*/ */
protected function executeConfig() { protected function executeConfig()
$tpl_name = 'module/install/config_new.tpl.html'; {
$tpl_data = array(); $tpl_name = 'module/install/config_new.tpl.html';
$tpl_data = array();
if (!defined('PSM_DB_PREFIX')) { if (!defined('PSM_DB_PREFIX')) {
// first detect "old" config file (2.0) // first detect "old" config file (2.0)
if (file_exists($this->path_config_old)) { if (file_exists($this->path_config_old)) {
// oldtimer huh // oldtimer huh
$this->addMessage('Configuration file for v2.0 found.', 'success'); $this->addMessage('Configuration file for v2.0 found.', 'success');
$this->addMessage( $this->addMessage(
'The location of the config file has been changed since v2.0.<br/>'. 'The location of the config file has been changed since v2.0.<br/>' .
'We will attempt to create a new config file for you.' 'We will attempt to create a new config file for you.',
, 'warning'); 'warning'
$values = $this->parseConfig20(); );
} else { $values = $this->parseConfig20();
// fresh install } else {
$values = $_POST; // fresh install
} $values = $_POST;
}
$config = array( $config = array(
'db_host' => 'localhost', 'db_host' => 'localhost',
'db_port' => '', 'db_port' => '',
'db_name' => '', 'db_name' => '',
'db_user' => '', 'db_user' => '',
'db_pass' => '', 'db_pass' => '',
'db_prefix' => 'psm_', 'db_prefix' => 'psm_',
'base_url' => $this->getBaseUrl(), 'base_url' => $this->getBaseUrl(),
); );
$changed = false; $changed = false;
foreach ($config as $ckey => &$cvalue) { foreach ($config as $ckey => &$cvalue) {
if (isset($values[$ckey])) { if (isset($values[$ckey])) {
$changed = true; $changed = true;
$cvalue = $values[$ckey]; $cvalue = $values[$ckey];
} }
} }
// add config to template data for prefilling the form // add config to template data for prefilling the form
$tpl_data = $config; $tpl_data = $config;
if ($changed) { if ($changed) {
// test db connection // test db connection
$this->db = new \psm\Service\Database( $this->db = new \psm\Service\Database(
$config['db_host'], $config['db_host'],
$config['db_user'], $config['db_user'],
$config['db_pass'], $config['db_pass'],
$config['db_name'], $config['db_name'],
$config['db_port'] $config['db_port']
); );
if ($this->db->status()) { if ($this->db->status()) {
$this->addMessage('Connection to MySQL successful.', 'success'); $this->addMessage('Connection to MySQL successful.', 'success');
$config_php = $this->writeConfigFile($config); $config_php = $this->writeConfigFile($config);
if ($config_php === true) { if ($config_php === true) {
$this->addMessage('Configuration file written successfully.', 'success'); $this->addMessage('Configuration file written successfully.', 'success');
} else { } else {
$this->addMessage('Config file is not writable, we cannot save it for you.', 'error'); $this->addMessage('Config file is not writable, we cannot save it for you.', 'error');
$tpl_data['include_config_new_copy'] = true; $tpl_data['include_config_new_copy'] = true;
$tpl_data['php_config'] = $config_php; $tpl_data['php_config'] = $config_php;
} }
} else { } else {
$this->addMessage('Unable to connect to MySQL. Please check your information.', 'error'); $this->addMessage('Unable to connect to MySQL. Please check your information.', 'error');
} }
} }
} }
if (defined('PSM_DB_PREFIX')) { if (defined('PSM_DB_PREFIX')) {
if ($this->db->status()) { if ($this->db->status()) {
if ($this->isUpgrade()) { if ($this->isUpgrade()) {
// upgrade // upgrade
$version_from = $this->getPreviousVersion(); $version_from = $this->getPreviousVersion();
if (version_compare($version_from, '3.0.0', '<')) { if (version_compare($version_from, '3.0.0', '<')) {
// upgrade from before 3.0, does not have passwords yet.. create new user first // 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.'); $this->addMessage(
$tpl_name = 'module/install/config_new_user.tpl.html'; 'Your current version does not have an authentication system,
} but since v3.0 access to the monitor is restricted by user accounts.
elseif (version_compare($version_from, PSM_VERSION, '=')) { Please set up a new account to be able to login after the upgrade,
$this->addMessage('Your installation is already at the latest version.', 'success'); and which you can use to change the passwords for your other accounts.'
$tpl_name = 'module/install/success.tpl.html'; );
} $tpl_name = 'module/install/config_new_user.tpl.html';
else { } elseif (version_compare($version_from, PSM_VERSION, '=')) {
$this->addMessage('We have discovered a previous version.'); $this->addMessage('Your installation is already at the latest version.', 'success');
$tpl_name = 'module/install/config_upgrade.tpl.html'; $tpl_name = 'module/install/success.tpl.html';
$tpl_data['version'] = PSM_VERSION; } else {
} $this->addMessage('We have discovered a previous version.');
} else { $tpl_name = 'module/install/config_upgrade.tpl.html';
// fresh install ahead $tpl_data['version'] = PSM_VERSION;
$tpl_name = 'module/install/config_new_user.tpl.html'; }
} else {
// fresh install ahead
$tpl_name = 'module/install/config_new_user.tpl.html';
$tpl_data['username'] = (isset($_POST['username'])) ? $_POST['username'] : ''; $tpl_data['username'] = (isset($_POST['username'])) ? $_POST['username'] : '';
$tpl_data['email'] = (isset($_POST['email'])) ? $_POST['email'] : ''; $tpl_data['email'] = (isset($_POST['email'])) ? $_POST['email'] : '';
} }
} else { } else {
$this->addMessage('Configuration file found, but unable to connect to MySQL. Please check your information.', 'error'); $this->addMessage(
} 'Configuration file found, but unable to connect to MySQL. Please check your information.',
} 'error'
$tpl_data['messages'] = $this->getMessages(); );
return $this->twig->render($tpl_name, $tpl_data); }
} }
$tpl_data['messages'] = $this->getMessages();
return $this->twig->render($tpl_name, $tpl_data);
}
/** /**
* Execute the install and upgrade process to a newer version * Execute the install and upgrade process to a newer version
*/ */
protected function executeInstall() { protected function executeInstall()
if (!defined('PSM_DB_PREFIX') || !$this->db->status()) { {
return $this->executeConfig(); if (!defined('PSM_DB_PREFIX') || !$this->db->status()) {
} return $this->executeConfig();
$add_user = false; }
$add_user = false;
// check if user submitted username + password in previous step // check if user submitted username + password in previous step
// this would only be the case for new installs, and install from // this would only be the case for new installs, and install from
// before 3.0 // before 3.0
$new_user = array( $new_user = array(
'user_name' => psm_POST('username'), 'user_name' => psm_POST('username'),
'name' => psm_POST('username'), 'name' => psm_POST('username'),
'password' => psm_POST('password'), 'password' => psm_POST('password'),
'password_repeat' => psm_POST('password_repeat'), 'password_repeat' => psm_POST('password_repeat'),
'email' => psm_POST('email', ''), 'email' => psm_POST('email', ''),
'mobile' => '', 'mobile' => '',
'level' => PSM_USER_ADMIN, 'level' => PSM_USER_ADMIN,
'pushover_key' => '', 'pushover_key' => '',
'pushover_device' => '', 'pushover_device' => '',
'telegram_id' => '', 'telegram_id' => '',
); );
$validator = $this->container->get('util.user.validator'); $validator = $this->container->get('util.user.validator');
$logger = array($this, 'addMessage'); $logger = array($this, 'addMessage');
$installer = new \psm\Util\Install\Installer($this->db, $logger); $installer = new \psm\Util\Install\Installer($this->db, $logger);
if ($this->isUpgrade()) { if ($this->isUpgrade()) {
$this->addMessage('Upgrade process started.'); $this->addMessage('Upgrade process started.');
$version_from = $this->getPreviousVersion(); $version_from = $this->getPreviousVersion();
if ($version_from === false) { if ($version_from === false) {
$this->addMessage('Unable to locate your previous version. Please run a fresh install.', 'error'); $this->addMessage('Unable to locate your previous version. Please run a fresh install.', 'error');
} else { } else {
if (version_compare($version_from, PSM_VERSION, '=')) { if (version_compare($version_from, PSM_VERSION, '=')) {
$this->addMessage('Your installation is already at the latest version.', 'success'); $this->addMessage('Your installation is already at the latest version.', 'success');
} elseif (version_compare($version_from, PSM_VERSION, '>')) { } elseif (version_compare($version_from, PSM_VERSION, '>')) {
$this->addMessage('This installer does not support downgrading, sorry.', 'error'); $this->addMessage('This installer does not support downgrading, sorry.', 'error');
} else { } else {
$this->addMessage('Upgrading from '.$version_from.' to '.PSM_VERSION); $this->addMessage('Upgrading from ' . $version_from . ' to ' . PSM_VERSION);
$installer->upgrade($version_from, PSM_VERSION); $installer->upgrade($version_from, PSM_VERSION);
}
if (version_compare($version_from, '3.0.0', '<')) {
$add_user = true;
}
}
} else {
// validate the lot
try {
$validator->usernameNew($new_user['user_name']);
$validator->email($new_user['email']);
$validator->password($new_user['password'], $new_user['password_repeat']);
} catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
return $this->executeConfig();
}
} $this->addMessage('Installation process started.', 'success');
if (version_compare($version_from, '3.0.0', '<')) { $installer->install();
$add_user = true; // add user
} $add_user = true;
} }
} else {
// validate the lot
try {
$validator->username_new($new_user['user_name']);
$validator->email($new_user['email']);
$validator->password($new_user['password'], $new_user['password_repeat']);
} catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_'.$e->getMessage()), 'error');
return $this->executeConfig();
}
$this->addMessage('Installation process started.', 'success'); if ($add_user) {
$installer->install(); unset($new_user['password_repeat']);
// add user $user_id = $this->db->save(PSM_DB_PREFIX . 'users', $new_user);
$add_user = true; if (intval($user_id) > 0) {
} $this->getUser()->changePassword($user_id, $new_user['password']);
$this->addMessage('User account has been created successfully.', 'success');
} else {
$this->addMessage('There was an error adding your user account.', 'error');
}
}
if ($add_user) { return $this->twig->render('module/install/success.tpl.html', array(
unset($new_user['password_repeat']); 'messages' => $this->getMessages()
$user_id = $this->db->save(PSM_DB_PREFIX.'users', $new_user); ));
if (intval($user_id) > 0) { }
$this->getUser()->changePassword($user_id, $new_user['password']);
$this->addMessage('User account has been created successfully.', 'success');
} else {
$this->addMessage('There was an error adding your user account.', 'error');
}
}
return $this->twig->render('module/install/success.tpl.html', array( /**
'messages' => $this->getMessages() * Write config file with db variables
)); * @param array $array_config prefix,user,pass,name,host
} * @return boolean|string TRUE on success, string with config otherwise
*/
protected function writeConfigFile($array_config)
{
$config = "<?php" . PHP_EOL;
/** foreach ($array_config as $key => $value) {
* Write config file with db variables $line = "define('PSM_{key}', '{value}');" . PHP_EOL;
* @param array $array_config prefix,user,pass,name,host $line = str_replace(
* @return boolean|string TRUE on success, string with config otherwise array('{key}', '{value}'),
*/ array(strtoupper($key), $value),
protected function writeConfigFile($array_config) { $line
$config = "<?php".PHP_EOL; );
$config .= $line;
}
if (is_writeable($this->path_config)) {
file_put_contents($this->path_config, $config);
return true;
} else {
return $config;
}
}
foreach ($array_config as $key => $value) { /**
$line = "define('PSM_{key}', '{value}');".PHP_EOL; * Parse the 2.0 config file for prefilling
$line = str_replace( * @return array
array('{key}', '{value}'), */
array(strtoupper($key), $value), protected function parseConfig20()
$line {
); $config_old = file_get_contents($this->path_config_old);
$config .= $line; $vars = array(
} 'prefix' => '',
if (is_writeable($this->path_config)) { 'user' => '',
file_put_contents($this->path_config, $config); 'pass' => '',
return true; 'name' => '',
} else { 'host' => '',
return $config; 'port' => ''
} );
} $pattern = "/define\('SM_{key}', '(.*?)'/u";
/** foreach ($vars as $key => $value) {
* Parse the 2.0 config file for prefilling $pattern_key = str_replace('{key}', strtoupper($key), $pattern);
* @return array preg_match($pattern_key, $config_old, $value_matches);
*/ $vars[$key] = (isset($value_matches[1])) ? $value_matches[1] : '';
protected function parseConfig20() { }
$config_old = file_get_contents($this->path_config_old);
$vars = array(
'prefix' => '',
'user' => '',
'pass' => '',
'name' => '',
'host' => '',
'port' => ''
);
$pattern = "/define\('SM_{key}', '(.*?)'/u";
foreach ($vars as $key => $value) { return $vars;
$pattern_key = str_replace('{key}', strtoupper($key), $pattern); }
preg_match($pattern_key, $config_old, $value_matches);
$vars[$key] = (isset($value_matches[1])) ? $value_matches[1] : '';
}
return $vars; /**
} * Is it an upgrade or install?
*/
protected function isUpgrade()
{
if (!$this->db->status()) {
return false;
}
return $this->db->ifTableExists(PSM_DB_PREFIX . 'config');
}
/** /**
* Is it an upgrade or install? * Get the previous version from the config table
*/ * @return boolean|string FALSE on failure, string otherwise
protected function isUpgrade() { */
if (!$this->db->status()) { protected function getPreviousVersion()
return false; {
} if (!$this->isUpgrade()) {
return $this->db->ifTableExists(PSM_DB_PREFIX.'config'); return false;
} }
$version_conf = $this->db->selectRow(PSM_DB_PREFIX . 'config', array('key' => 'version'), array('value'));
if (empty($version_conf)) {
return false;
} else {
$version_from = $version_conf['value'];
if (strpos($version_from, '.') === false) {
// yeah, my bad.. previous version did not follow proper naming scheme
$version_from = rtrim(chunk_split($version_from, 1, '.'), '.');
}
return $version_from;
}
}
/** /**
* Get the previous version from the config table * Get base url of the current application
* @return boolean|string FALSE on failure, string otherwise * @return string
*/ */
protected function getPreviousVersion() { protected function getBaseUrl()
if (!$this->isUpgrade()) { {
return false; $sym_request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
}
$version_conf = $this->db->selectRow(PSM_DB_PREFIX.'config', array('key' => 'version'), array('value'));
if (empty($version_conf)) {
return false;
} else {
$version_from = $version_conf['value'];
if (strpos($version_from, '.') === false) {
// yeah, my bad.. previous version did not follow proper naming scheme
$version_from = rtrim(chunk_split($version_from, 1, '.'), '.');
}
return $version_from;
}
}
/** return $sym_request->getSchemeAndHttpHost() . $sym_request->getBasePath();
* Get base url of the current application }
* @return string
*/
protected function getBaseUrl() {
$sym_request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
return $sym_request->getSchemeAndHttpHost().$sym_request->getBasePath();
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,7 +24,7 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0 * @since phpservermon 3.0
**/ **/
namespace psm\Module\Install; namespace psm\Module\Install;
@ -31,16 +32,17 @@ namespace psm\Module\Install;
use psm\Module\ModuleInterface; use psm\Module\ModuleInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
class InstallModule implements ModuleInterface { class InstallModule implements ModuleInterface
{
public function load(ContainerBuilder $container) { public function load(ContainerBuilder $container)
{
}
} public function getControllers()
{
public function getControllers() { return array(
return array( 'install' => __NAMESPACE__ . '\Controller\InstallController',
'install' => __NAMESPACE__.'\Controller\InstallController', );
); }
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,15 +24,17 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0 * @since phpservermon 3.0
**/ **/
namespace psm\Module; namespace psm\Module;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
interface ModuleInterface { interface ModuleInterface
{
public function load(ContainerBuilder $container); public function load(ContainerBuilder $container);
public function getControllers(); public function getControllers();
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,41 +24,45 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0.0 * @since phpservermon 3.0.0
**/ **/
namespace psm\Module\Server\Controller; namespace psm\Module\Server\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
abstract class AbstractServerController extends AbstractController { abstract class AbstractServerController extends AbstractController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
} parent::__construct($db, $twig);
}
/** /**
* Get all servers for the current user * Get all servers for the current user
* @param Countable|array|\PDOStatement $server_id (int) if true only that server will be retrieved. * @param Countable|array|\PDOStatement $server_id (int) if true only that server will be retrieved.
* @return array * @return array
*/ */
public function getServers($server_id = null) { public function getServers($server_id = null)
$sql_join = ''; {
$sql_where = ''; $sql_join = '';
$sql_where = '';
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) { if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id // restrict by user_id
$sql_join = "JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON ( $sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()} `us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`s`.`server_id` AND `us`.`server_id`=`s`.`server_id`
)"; )";
} }
if ($server_id !== null) { if ($server_id !== null) {
$server_id = intval($server_id); $server_id = intval($server_id);
$sql_where = "WHERE `s`.`server_id`={$server_id} "; $sql_where = "WHERE `s`.`server_id`={$server_id} ";
} }
$sql = "SELECT $sql = "SELECT
`s`.`server_id`, `s`.`server_id`,
`s`.`ip`, `s`.`ip`,
`s`.`port`, `s`.`port`,
@ -91,55 +96,56 @@ abstract class AbstractServerController extends AbstractController {
`s`.`last_error`, `s`.`last_error`,
`s`.`last_error_output`, `s`.`last_error_output`,
`s`.`last_output` `s`.`last_output`
FROM `".PSM_DB_PREFIX."servers` AS `s` FROM `" . PSM_DB_PREFIX . "servers` AS `s`
{$sql_join} {$sql_join}
{$sql_where} {$sql_where}
ORDER BY `active` ASC, `status` DESC, `label` ASC"; ORDER BY `active` ASC, `status` DESC, `label` ASC";
$servers = $this->db->query($sql); $servers = $this->db->query($sql);
if ($server_id !== null && count($servers) == 1) { if ($server_id !== null && count($servers) == 1) {
$servers = $servers[0]; $servers = $servers[0];
} }
return $servers; return $servers;
} }
/** /**
* Format server data for display * Format server data for display
* @param array $server * @param array $server
* @return array * @return array
*/ */
protected function formatServer($server) { protected function formatServer($server)
$server['rtime'] = round((float) $server['rtime'], 4); {
$server['last_online'] = psm_timespan($server['last_online']); $server['rtime'] = round((float) $server['rtime'], 4);
$server['last_offline'] = psm_timespan($server['last_offline']); $server['last_online'] = psm_timespan($server['last_online']);
if ($server['last_offline'] != psm_get_lang('system', 'never')) { $server['last_offline'] = psm_timespan($server['last_offline']);
$server['last_offline_duration'] = is_null($server['last_offline_duration']) ? if ($server['last_offline'] != psm_get_lang('system', 'never')) {
null : "(".$server['last_offline_duration'].")"; $server['last_offline_duration'] = is_null($server['last_offline_duration']) ?
} null : "(" . $server['last_offline_duration'] . ")";
$server['last_check'] = psm_timespan($server['last_check']); }
$server['last_check'] = psm_timespan($server['last_check']);
if ($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) { if ($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) {
$server['status'] = 'warning'; $server['status'] = 'warning';
} }
$server['error'] = htmlentities($server['error']); $server['error'] = htmlentities($server['error']);
$server['type'] = psm_get_lang('servers', 'type_'.$server['type']); $server['type'] = psm_get_lang('servers', 'type_' . $server['type']);
$server['timeout'] = ($server['timeout'] > 0) ? $server['timeout'] : PSM_CURL_TIMEOUT; $server['timeout'] = ($server['timeout'] > 0) ? $server['timeout'] : PSM_CURL_TIMEOUT;
$server['last_error'] = htmlentities($server['last_error']); $server['last_error'] = htmlentities($server['last_error']);
$server['last_error_output'] = htmlentities($server['last_error_output']); $server['last_error_output'] = htmlentities($server['last_error_output']);
$server['last_output'] = htmlentities($server['last_output']); $server['last_output'] = htmlentities($server['last_output']);
$url_actions = array('delete', 'edit', 'view'); $url_actions = array('delete', 'edit', 'view');
foreach ($url_actions as $action) { foreach ($url_actions as $action) {
$server['url_'.$action] = psm_build_url(array( $server['url_' . $action] = psm_build_url(array(
'mod' => 'server', 'mod' => 'server',
'action' => $action, 'action' => $action,
'id' => $server['server_id'], 'id' => $server['server_id'],
)); ));
} }
return $server; return $server;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,172 +27,179 @@
**/ **/
namespace psm\Module\Server\Controller; namespace psm\Module\Server\Controller;
use psm\Service\Database; use psm\Service\Database;
/** /**
* Log module. Create the page to view previous log messages * Log module. Create the page to view previous log messages
*/ */
class LogController extends AbstractServerController { class LogController extends AbstractServerController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setActions(array( $this->setActions(array(
'index', 'delete', 'index', 'delete',
), 'index'); ), 'index');
} }
/** /**
* Prepare the template with a list of all log entries * Prepare the template with a list of all log entries
*/ */
protected function executeIndex() { protected function executeIndex()
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_log')); {
$tpl_data = array( $this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_log'));
'label_status' => psm_get_lang('log', 'status'), $tpl_data = array(
'label_email' => psm_get_lang('log', 'email'), 'label_status' => psm_get_lang('log', 'status'),
'label_sms' => psm_get_lang('log', 'sms'), 'label_email' => psm_get_lang('log', 'email'),
'label_pushover' => psm_get_lang('log', 'pushover'), 'label_sms' => psm_get_lang('log', 'sms'),
'label_telegram' => psm_get_lang('log', 'telegram'), 'label_pushover' => psm_get_lang('log', 'pushover'),
'label_title' => psm_get_lang('log', 'title'), 'label_telegram' => psm_get_lang('log', 'telegram'),
'label_server' => psm_get_lang('servers', 'server'), 'label_title' => psm_get_lang('log', 'title'),
'label_type' => psm_get_lang('log', 'type'), 'label_server' => psm_get_lang('servers', 'server'),
'label_message' => psm_get_lang('system', 'message'), 'label_type' => psm_get_lang('log', 'type'),
'label_date' => psm_get_lang('system', 'date'), 'label_message' => psm_get_lang('system', 'message'),
'label_users' => ucfirst(psm_get_lang('menu', 'user')), 'label_date' => psm_get_lang('system', 'date'),
'label_no_logs' => psm_get_lang('log', 'no_logs'), 'label_users' => ucfirst(psm_get_lang('menu', 'user')),
'tabs' => array(), 'label_no_logs' => psm_get_lang('log', 'no_logs'),
); 'tabs' => array(),
);
$sidebar = new \psm\Util\Module\Sidebar($this->twig); $sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar); $this->setSidebar($sidebar);
if ($this->getUser()->getUserLevel() == PSM_USER_ADMIN) { if ($this->getUser()->getUserLevel() == PSM_USER_ADMIN) {
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER); $modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal); $this->addModal($modal);
$modal->setTitle(psm_get_lang('log', 'delete_title')); $modal->setTitle(psm_get_lang('log', 'delete_title'));
$modal->setMessage(psm_get_lang('log', 'delete_message')); $modal->setMessage(psm_get_lang('log', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete')); $modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$sidebar->addButton( $sidebar->addButton(
'clear_logn', 'clear_logn',
psm_get_lang('log', 'clear'), psm_get_lang('log', 'clear'),
psm_build_url(array('mod' => 'server_log', 'action' => 'delete')), psm_build_url(array('mod' => 'server_log', 'action' => 'delete')),
'trash', 'trash',
'danger show-modal', 'danger show-modal',
psm_get_lang('log', 'delete_title'), psm_get_lang('log', 'delete_title'),
'delete' 'delete'
); );
} }
$log_types = array('status', 'email', 'sms', 'pushover', 'telegram'); $log_types = array('status', 'email', 'sms', 'pushover', 'telegram');
foreach ($log_types as $key) { foreach ($log_types as $key) {
$records = $this->getEntries($key); $records = $this->getEntries($key);
$log_count = count($records); $log_count = count($records);
$tab_data = array( $tab_data = array(
'id' => $key, 'id' => $key,
'label' => psm_get_lang('log', $key), 'label' => psm_get_lang('log', $key),
'has_users' => ($key == 'status') ? false : true, 'has_users' => ($key == 'status') ? false : true,
'no_logs' => ($log_count == 0) ? true : false, 'no_logs' => ($log_count == 0) ? true : false,
'tab_active' => ($key == 'status') ? 'active' : '', 'tab_active' => ($key == 'status') ? 'active' : '',
); );
for ($x = 0; $x < $log_count; $x++) { for ($x = 0; $x < $log_count; $x++) {
$record = &$records[$x]; $record = &$records[$x];
$record['users'] = ''; $record['users'] = '';
if($key == 'status'){ if ($key == 'status') {
$record['server'] = $record['label']; $record['server'] = $record['label'];
$record['type_icon'] = ($record['server_type'] == 'website') ? 'globe-americas' : 'cogs'; $record['type_icon'] = ($record['server_type'] == 'website') ? 'globe-americas' : 'cogs';
$record['type_title'] = psm_get_lang('servers', 'type_'.$record['server_type']); $record['type_title'] = psm_get_lang('servers', 'type_' . $record['server_type']);
$ip = '('.$record['ip']; $ip = '(' . $record['ip'];
if (!empty($record['port']) && (($record['server_type'] != 'website') || ($record['port'] != 80))) { if (!empty($record['port']) && (($record['server_type'] != 'website') || ($record['port'] != 80))) {
$ip .= ':'.$record['port']; $ip .= ':' . $record['port'];
} }
$ip .= ')'; $ip .= ')';
$record['ip'] = $ip; $record['ip'] = $ip;
} }
$record['datetime_format'] = psm_date($record['datetime']); $record['datetime_format'] = psm_date($record['datetime']);
// fix up user list // fix up user list
$users = $this->getLogUsers($record['log_id']); $users = $this->getLogUsers($record['log_id']);
if (!empty($users)) { if (!empty($users)) {
$names = array(); $names = array();
foreach ($users as $user) { foreach ($users as $user) {
$names[] = $user['name']; $names[] = $user['name'];
} }
$record['users'] = implode('<br/>', $names); $record['users'] = implode('<br/>', $names);
$record['user_list'] = implode('&nbsp;&bull; ', $names); $record['user_list'] = implode('&nbsp;&bull; ', $names);
} }
} }
$tab_data['entries'] = $records; $tab_data['entries'] = $records;
$tpl_data['tabs'][] = $tab_data; $tpl_data['tabs'][] = $tab_data;
} }
return $this->twig->render('module/server/log.tpl.html', $tpl_data); return $this->twig->render('module/server/log.tpl.html', $tpl_data);
} }
protected function executeDelete() { protected function executeDelete()
/** {
* Empty table log and log_users. /**
* Only when user is admin. * Empty table log and log_users.
*/ * Only when user is admin.
if ($this->getUser()->getUserLevel() == PSM_USER_ADMIN) { */
$archiver = new \psm\Util\Server\Archiver\LogsArchiver($this->db); if ($this->getUser()->getUserLevel() == PSM_USER_ADMIN) {
$archiver->cleanupall(); $archiver = new \psm\Util\Server\Archiver\LogsArchiver($this->db);
} $archiver->cleanupall();
return $this->runAction('index'); }
} return $this->runAction('index');
}
/** /**
* Get all the log entries for a specific $type * Get all the log entries for a specific $type
* *
* @param string $type status/email/sms * @param string $type status/email/sms
* @return \PDOStatement array * @return \PDOStatement array
*/ */
public function getEntries($type) { public function getEntries($type)
$sql_join = ''; {
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) { $sql_join = '';
// restrict by user_id if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
$sql_join = "JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON ( // restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()} `us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id` AND `us`.`server_id`=`servers`.`server_id`
)"; )";
} }
$entries = $this->db->query( $entries = $this->db->query(
'SELECT '. 'SELECT ' .
'`servers`.`label`, '. '`servers`.`label`, ' .
'`servers`.`ip`, '. '`servers`.`ip`, ' .
'`servers`.`port`, '. '`servers`.`port`, ' .
'`servers`.`type` AS server_type, '. '`servers`.`type` AS server_type, ' .
'`log`.`log_id`, '. '`log`.`log_id`, ' .
'`log`.`type`, '. '`log`.`type`, ' .
'`log`.`message`, '. '`log`.`message`, ' .
'`log`.`datetime` '. '`log`.`datetime` ' .
'FROM `'.PSM_DB_PREFIX.'log` AS `log` '. 'FROM `' . PSM_DB_PREFIX . 'log` AS `log` ' .
'JOIN `'.PSM_DB_PREFIX.'servers` AS `servers` ON (`servers`.`server_id`=`log`.`server_id`) '. 'JOIN `' . PSM_DB_PREFIX . 'servers` AS `servers` ON (`servers`.`server_id`=`log`.`server_id`) ' .
$sql_join. $sql_join .
'WHERE `log`.`type`=\''.$type.'\' '. 'WHERE `log`.`type`=\'' . $type . '\' ' .
'ORDER BY `datetime` DESC '. 'ORDER BY `datetime` DESC ' .
'LIMIT 0,20' 'LIMIT 0,20'
); );
return $entries; return $entries;
} }
/** /**
* Get all the user entries for a specific $log_id * Get all the user entries for a specific $log_id
* *
* @param $log_id * @param $log_id
* @return \PDOStatement array * @return \PDOStatement array
*/ */
protected function getLogUsers($log_id) { protected function getLogUsers($log_id)
return $this->db->query( {
"SELECT return $this->db->query(
"SELECT
u.`user_id`, u.`user_id`,
u.`name` u.`name`
FROM `".PSM_DB_PREFIX."log_users` AS lu FROM `" . PSM_DB_PREFIX . "log_users` AS lu
LEFT JOIN `".PSM_DB_PREFIX."users` AS u ON lu.`user_id` = u.`user_id` LEFT JOIN `" . PSM_DB_PREFIX . "users` AS u ON lu.`user_id` = u.`user_id`
WHERE lu.`log_id` = ".(int) $log_id." WHERE lu.`log_id` = " . (int) $log_id . "
ORDER BY u.`name` ASC" ORDER BY u.`name` ASC"
); );
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,102 +28,109 @@
**/ **/
namespace psm\Module\Server\Controller; namespace psm\Module\Server\Controller;
use psm\Service\Database; use psm\Service\Database;
/** /**
* Status module * Status module
*/ */
class StatusController extends AbstractServerController { class StatusController extends AbstractServerController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setCSRFKey('status'); $this->setCSRFKey('status');
$this->setActions(array('index', 'saveLayout'), 'index'); $this->setActions(array('index', 'saveLayout'), 'index');
} }
/** /**
* Prepare the template to show a list of all servers * Prepare the template to show a list of all servers
*/ */
protected function executeIndex() { protected function executeIndex()
// set background color to black {
$this->black_background = true; // set background color to black
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_status')); $this->black_background = true;
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server_status'));
// add header accessories // add header accessories
$layout = $this->getUser()->getUserPref('status_layout', 0); $layout = $this->getUser()->getUserPref('status_layout', 0);
$layout_data = array( $layout_data = array(
'label_none' => psm_get_lang('system', 'none'), 'label_none' => psm_get_lang('system', 'none'),
'label_last_check' => psm_get_lang('servers', 'last_check'), 'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_last_online' => psm_get_lang('servers', 'last_online'), 'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_last_offline' => psm_get_lang('servers', 'last_offline'), 'label_last_offline' => psm_get_lang('servers', 'last_offline'),
'label_online' => psm_get_lang('servers', 'online'), 'label_online' => psm_get_lang('servers', 'online'),
'label_offline' => psm_get_lang('servers', 'offline'), 'label_offline' => psm_get_lang('servers', 'offline'),
'label_rtime' => psm_get_lang('servers', 'latency'), 'label_rtime' => psm_get_lang('servers', 'latency'),
'block_layout_active' => ($layout == 0) ? 'active' : '', 'block_layout_active' => ($layout == 0) ? 'active' : '',
'list_layout_active' => ($layout != 0) ? 'active' : '', 'list_layout_active' => ($layout != 0) ? 'active' : '',
'label_add_server' => psm_get_lang('system', 'add_new'), 'label_add_server' => psm_get_lang('system', 'add_new'),
'layout' => $layout, 'layout' => $layout,
'url_save' => psm_build_url(array('mod' => 'server', 'action' => 'edit')), 'url_save' => psm_build_url(array('mod' => 'server', 'action' => 'edit')),
); );
$this->setHeaderAccessories($this->twig->render('module/server/status/header.tpl.html', $layout_data)); $this->setHeaderAccessories($this->twig->render('module/server/status/header.tpl.html', $layout_data));
$this->addFooter(false); $this->addFooter(false);
// get the active servers from database // get the active servers from database
$servers = $this->getServers(); $servers = $this->getServers();
$layout_data['servers_offline'] = array(); $layout_data['servers_offline'] = array();
$layout_data['servers_warning'] = array(); $layout_data['servers_warning'] = array();
$layout_data['servers_online'] = array(); $layout_data['servers_online'] = array();
foreach ($servers as $server) { foreach ($servers as $server) {
if ($server['active'] == 'no') { if ($server['active'] == 'no') {
continue; continue;
} }
$server['last_checked_nice'] = psm_timespan($server['last_check']); $server['last_checked_nice'] = psm_timespan($server['last_check']);
$server['last_online_nice'] = psm_timespan($server['last_online']); $server['last_online_nice'] = psm_timespan($server['last_online']);
$server['last_offline_nice'] = psm_timespan($server['last_offline']); $server['last_offline_nice'] = psm_timespan($server['last_offline']);
$server['last_offline_duration_nice'] = ""; $server['last_offline_duration_nice'] = "";
if ($server['last_offline_nice'] != psm_get_lang('system', 'never')) { if ($server['last_offline_nice'] != psm_get_lang('system', 'never')) {
$server['last_offline_duration_nice'] = "(".$server['last_offline_duration'].")"; $server['last_offline_duration_nice'] = "(" . $server['last_offline_duration'] . ")";
} }
$server['url_view'] = psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server['server_id'], 'back_to' => 'server_status')); $server['url_view'] = psm_build_url(
array('mod' => 'server', 'action' => 'view', 'id' => $server['server_id'], 'back_to' => 'server_status')
);
if ($server['status'] == "off") { if ($server['status'] == "off") {
$layout_data['servers_offline'][] = $server; $layout_data['servers_offline'][] = $server;
} elseif ($server['warning_threshold_counter'] > 0) { } elseif ($server['warning_threshold_counter'] > 0) {
$layout_data['servers_warning'][] = $server; $layout_data['servers_warning'][] = $server;
} else { } else {
$layout_data['servers_online'][] = $server; $layout_data['servers_online'][] = $server;
} }
} }
$auto_refresh_seconds = psm_get_conf('auto_refresh_servers'); $auto_refresh_seconds = psm_get_conf('auto_refresh_servers');
if (intval($auto_refresh_seconds) > 0) { if (intval($auto_refresh_seconds) > 0) {
$this->twig->addGlobal('auto_refresh', true); $this->twig->addGlobal('auto_refresh', true);
$this->twig->addGlobal('auto_refresh_seconds', $auto_refresh_seconds); $this->twig->addGlobal('auto_refresh_seconds', $auto_refresh_seconds);
} }
if ($this->isXHR() || isset($_SERVER["HTTP_X_REQUESTED_WITH"])) { if ($this->isXHR() || isset($_SERVER["HTTP_X_REQUESTED_WITH"])) {
$this->xhr = true; $this->xhr = true;
//disable auto refresh in ajax return html //disable auto refresh in ajax return html
$layout_data["auto_refresh"] = 0; $layout_data["auto_refresh"] = 0;
} }
return $this->twig->render('module/server/status/index.tpl.html', $layout_data); return $this->twig->render('module/server/status/index.tpl.html', $layout_data);
} }
protected function executeSaveLayout() { protected function executeSaveLayout()
if ($this->isXHR()) { {
$layout = psm_POST('layout', 0); if ($this->isXHR()) {
$this->getUser()->setUserPref('status_layout', $layout); $layout = psm_POST('layout', 0);
$this->getUser()->setUserPref('status_layout', $layout);
$response = new \Symfony\Component\HttpFoundation\JsonResponse(); $response = new \Symfony\Component\HttpFoundation\JsonResponse();
$response->setData(array( $response->setData(array(
'layout' => $layout, 'layout' => $layout,
)); ));
return $response; return $response;
} }
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -24,29 +25,32 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0.0 * @since phpservermon 3.0.0
**/ **/
namespace psm\Module\Server\Controller; namespace psm\Module\Server\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class UpdateController extends AbstractController { class UpdateController extends AbstractController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setActions('index', 'index'); $this->setActions('index', 'index');
} }
protected function executeIndex() { protected function executeIndex()
$autorun = $this->container->get('util.server.updatemanager'); {
$autorun->run(); $autorun = $this->container->get('util.server.updatemanager');
$autorun->run();
header('Location: '.psm_build_url(array(
'mod' => 'server_status'
), true, false));
die();
}
header('Location: ' . psm_build_url(array(
'mod' => 'server_status'
), true, false));
die();
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,7 +24,7 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0 * @since phpservermon 3.0
**/ **/
namespace psm\Module\Server; namespace psm\Module\Server;
@ -31,19 +32,20 @@ namespace psm\Module\Server;
use psm\Module\ModuleInterface; use psm\Module\ModuleInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
class ServerModule implements ModuleInterface { class ServerModule implements ModuleInterface
{
public function load(ContainerBuilder $container) { public function load(ContainerBuilder $container)
{
}
} public function getControllers()
{
public function getControllers() { return array(
return array( 'server' => __NAMESPACE__ . '\Controller\ServerController',
'server' => __NAMESPACE__.'\Controller\ServerController', 'log' => __NAMESPACE__ . '\Controller\LogController',
'log' => __NAMESPACE__.'\Controller\LogController', 'status' => __NAMESPACE__ . '\Controller\StatusController',
'status' => __NAMESPACE__.'\Controller\StatusController', 'update' => __NAMESPACE__ . '\Controller\UpdateController',
'update' => __NAMESPACE__.'\Controller\UpdateController', );
); }
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,155 +28,161 @@
**/ **/
namespace psm\Module\User\Controller; namespace psm\Module\User\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class LoginController extends AbstractController { class LoginController extends AbstractController
{
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ANONYMOUS); $this->setMinUserLevelRequired(PSM_USER_ANONYMOUS);
$this->setActions(array( $this->setActions(array(
'login', 'forgot', 'reset', 'login', 'forgot', 'reset',
), 'login'); ), 'login');
$this->addMenu(false); $this->addMenu(false);
} }
protected function executeLogin() { protected function executeLogin()
if (isset($_POST['user_name']) && isset($_POST['user_password'])) { {
$rememberme = (isset($_POST['user_rememberme'])) ? true : false; if (isset($_POST['user_name']) && isset($_POST['user_password'])) {
$result = $this->getUser()->loginWithPostData( $rememberme = (isset($_POST['user_rememberme'])) ? true : false;
$_POST['user_name'], $result = $this->getUser()->loginWithPostData(
$_POST['user_password'], $_POST['user_name'],
$rememberme $_POST['user_password'],
); $rememberme
);
if ($result) { if ($result) {
// success login, redirect // success login, redirect
header('Location: '. header('Location: ' .
psm_build_url( psm_build_url(
empty($_SERVER["QUERY_STRING"]) ? null : $_SERVER["QUERY_STRING"] empty($_SERVER["QUERY_STRING"]) ? null : $_SERVER["QUERY_STRING"]
) ));
); die();
die(); } else {
} else { $this->addMessage(psm_get_lang('login', 'error_login_incorrect'), 'error');
$this->addMessage(psm_get_lang('login', 'error_login_incorrect'), 'error'); }
} }
}
$tpl_data = array( $tpl_data = array(
'title_sign_in' => psm_get_lang('login', 'title_sign_in'), 'title_sign_in' => psm_get_lang('login', 'title_sign_in'),
'label_username' => psm_get_lang('login', 'username'), 'label_username' => psm_get_lang('login', 'username'),
'label_password' => psm_get_lang('login', 'password'), 'label_password' => psm_get_lang('login', 'password'),
'label_remember_me' => psm_get_lang('login', 'remember_me'), 'label_remember_me' => psm_get_lang('login', 'remember_me'),
'label_login' => psm_get_lang('login', 'login'), 'label_login' => psm_get_lang('login', 'login'),
'label_password_forgot' => psm_get_lang('login', 'password_forgot'), 'label_password_forgot' => psm_get_lang('login', 'password_forgot'),
'value_user_name' => (isset($_POST['user_name'])) ? $_POST['user_name'] : '', 'value_user_name' => (isset($_POST['user_name'])) ? $_POST['user_name'] : '',
'value_rememberme' => (isset($rememberme) && $rememberme) ? 'checked="checked"' : '', 'value_rememberme' => (isset($rememberme) && $rememberme) ? 'checked="checked"' : '',
); );
return $this->twig->render('module/user/login/login.tpl.html', $tpl_data); return $this->twig->render('module/user/login/login.tpl.html', $tpl_data);
} }
/** /**
* Show/process the password forgot form (before the mail) * Show/process the password forgot form (before the mail)
* *
* @return string * @return string
*/ */
protected function executeForgot() { protected function executeForgot()
if (isset($_POST['user_name'])) { {
$user = $this->getUser()->getUserByUsername($_POST['user_name']); if (isset($_POST['user_name'])) {
$user = $this->getUser()->getUserByUsername($_POST['user_name']);
if (!empty($user)) { if (!empty($user)) {
$token = $this->getUser()->generatePasswordResetToken($user->user_id); $token = $this->getUser()->generatePasswordResetToken($user->user_id);
// we have a token, send it along // we have a token, send it along
$this->sendPasswordForgotMail( $this->sendPasswordForgotMail(
$user->user_id, $user->user_id,
$user->email, $user->email,
$token $token
); );
$this->addMessage(psm_get_lang('login', 'success_password_forgot'), 'success'); $this->addMessage(psm_get_lang('login', 'success_password_forgot'), 'success');
return $this->executeLogin(); return $this->executeLogin();
} else { } else {
$this->addMessage(psm_get_lang('login', 'error_user_incorrect'), 'error'); $this->addMessage(psm_get_lang('login', 'error_user_incorrect'), 'error');
} }
} }
$tpl_data = array( $tpl_data = array(
'title_forgot' => psm_get_lang('login', 'title_forgot'), 'title_forgot' => psm_get_lang('login', 'title_forgot'),
'label_username' => psm_get_lang('login', 'username'), 'label_username' => psm_get_lang('login', 'username'),
'label_submit' => psm_get_lang('login', 'submit'), 'label_submit' => psm_get_lang('login', 'submit'),
'label_go_back' => psm_get_lang('system', 'go_back'), 'label_go_back' => psm_get_lang('system', 'go_back'),
); );
return $this->twig->render('module/user/login/forgot.tpl.html', $tpl_data); return $this->twig->render('module/user/login/forgot.tpl.html', $tpl_data);
} }
/** /**
* Show/process the password reset form (after the mail) * Show/process the password reset form (after the mail)
*/ */
protected function executeReset() { protected function executeReset()
$service_user = $this->getUser(); {
$user_id = (isset($_GET['user_id'])) ? intval($_GET['user_id']) : 0; $service_user = $this->getUser();
$token = (isset($_GET['token'])) ? $_GET['token'] : ''; $user_id = (isset($_GET['user_id'])) ? intval($_GET['user_id']) : 0;
$token = (isset($_GET['token'])) ? $_GET['token'] : '';
if (!$service_user->verifyPasswordResetToken($user_id, $token)) { if (!$service_user->verifyPasswordResetToken($user_id, $token)) {
$this->addMessage(psm_get_lang('login', 'error_reset_invalid_link'), 'error'); $this->addMessage(psm_get_lang('login', 'error_reset_invalid_link'), 'error');
return $this->executeLogin(); return $this->executeLogin();
} }
if (!empty($_POST['user_password_new']) && !empty($_POST['user_password_repeat'])) { if (!empty($_POST['user_password_new']) && !empty($_POST['user_password_repeat'])) {
if ($_POST['user_password_new'] !== $_POST['user_password_repeat']) { if ($_POST['user_password_new'] !== $_POST['user_password_repeat']) {
$this->addMessage(psm_get_lang('login', 'error_login_passwords_nomatch'), 'error'); $this->addMessage(psm_get_lang('login', 'error_login_passwords_nomatch'), 'error');
} else { } else {
$result = $service_user->changePassword($user_id, $_POST['user_password_new']); $result = $service_user->changePassword($user_id, $_POST['user_password_new']);
if ($result) { if ($result) {
$this->addMessage(psm_get_lang('login', 'success_password_reset'), 'success'); $this->addMessage(psm_get_lang('login', 'success_password_reset'), 'success');
return $this->executeLogin(); return $this->executeLogin();
} else { } else {
$this->addMessage(psm_get_lang('login', 'error_login_incorrect'), 'error'); $this->addMessage(psm_get_lang('login', 'error_login_incorrect'), 'error');
} }
} }
} }
$user = $service_user->getUser($user_id); $user = $service_user->getUser($user_id);
$tpl_data = array( $tpl_data = array(
'title_reset' => psm_get_lang('login', 'title_reset'), 'title_reset' => psm_get_lang('login', 'title_reset'),
'label_username' => psm_get_lang('login', 'username'), 'label_username' => psm_get_lang('login', 'username'),
'label_password' => psm_get_lang('login', 'password'), 'label_password' => psm_get_lang('login', 'password'),
'label_password_repeat' => psm_get_lang('login', 'password_repeat'), 'label_password_repeat' => psm_get_lang('login', 'password_repeat'),
'label_reset' => psm_get_lang('login', 'password_reset'), 'label_reset' => psm_get_lang('login', 'password_reset'),
'label_go_back' => psm_get_lang('system', 'go_back'), 'label_go_back' => psm_get_lang('system', 'go_back'),
'value_user_name' => $user->user_name, 'value_user_name' => $user->user_name,
); );
return $this->twig->render('module/user/login/reset.tpl.html', $tpl_data); return $this->twig->render('module/user/login/reset.tpl.html', $tpl_data);
} }
/** /**
* Sends the password-reset-email. * Sends the password-reset-email.
* @param int $user_id * @param int $user_id
* @param string $user_email * @param string $user_email
* @param string $user_password_reset_hash * @param string $user_password_reset_hash
*/ */
protected function sendPasswordForgotMail($user_id, $user_email, $user_password_reset_hash) { protected function sendPasswordForgotMail($user_id, $user_email, $user_password_reset_hash)
$mail = psm_build_mail(); {
$mail->Subject = psm_get_lang('login', 'password_reset_email_subject'); $mail = psm_build_mail();
$mail->Subject = psm_get_lang('login', 'password_reset_email_subject');
$url = psm_build_url(array( $url = psm_build_url(array(
'action' => 'reset', 'action' => 'reset',
'user_id' => $user_id, 'user_id' => $user_id,
'token' => $user_password_reset_hash, 'token' => $user_password_reset_hash,
), true, false); ), true, false);
$body = psm_get_lang('login', 'password_reset_email_body'); $body = psm_get_lang('login', 'password_reset_email_body');
$body = str_replace('%link%', $url, $body); $body = str_replace('%link%', $url, $body);
$mail->Body = $body; $mail->Body = $body;
$mail->AltBody = str_replace('<br/>', "\n", $body); $mail->AltBody = str_replace('<br/>', "\n", $body);
$mail->AddAddress($user_email); $mail->AddAddress($user_email);
$mail->Send(); $mail->Send();
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,160 +27,171 @@
**/ **/
namespace psm\Module\User\Controller; namespace psm\Module\User\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
class ProfileController extends AbstractController { class ProfileController extends AbstractController
{
/** /**
* Editable fields for the profile * Editable fields for the profile
* @var array $profile_fields * @var array $profile_fields
*/ */
protected $profile_fields = array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id'); protected $profile_fields =
array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id');
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setActions(array( $this->setActions(array(
'index', 'save', 'index', 'save',
), 'index'); ), 'index');
$this->setCSRFKey('profile'); $this->setCSRFKey('profile');
} }
/** /**
* Show the profile page * Show the profile page
* @return string * @return string
*/ */
protected function executeIndex() { protected function executeIndex()
$this->twig->addGlobal('subtitle', psm_get_lang('users', 'profile')); {
$user = $this->getUser()->getUser(null, true); $this->twig->addGlobal('subtitle', psm_get_lang('users', 'profile'));
$user = $this->getUser()->getUser(null, true);
$modal = new \psm\Util\Module\Modal($this->twig, 'activate' . ucfirst('telegram'), \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL); $modal = new \psm\Util\Module\Modal(
$this->addModal($modal); $this->twig,
$modal->setTitle(psm_get_lang('users', 'activate_telegram')); 'activate' . ucfirst('telegram'),
$modal->setMessage(psm_get_lang('users', 'activate_telegram_description')); \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL
$modal->setOKButtonLabel(psm_get_lang('system', 'activate')); );
$this->addModal($modal);
$modal->setTitle(psm_get_lang('users', 'activate_telegram'));
$modal->setMessage(psm_get_lang('users', 'activate_telegram_description'));
$modal->setOKButtonLabel(psm_get_lang('system', 'activate'));
$tpl_data = array( $tpl_data = array(
'label_general' => psm_get_lang('config', 'general'), 'label_general' => psm_get_lang('config', 'general'),
'label_name' => psm_get_lang('users', 'name'), 'label_name' => psm_get_lang('users', 'name'),
'label_user_name' => psm_get_lang('users', 'user_name'), 'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password' => psm_get_lang('users', 'password'), 'label_password' => psm_get_lang('users', 'password'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'), 'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'), 'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'), 'label_mobile' => psm_get_lang('users', 'mobile'),
'label_pushover' => psm_get_lang('users', 'pushover'), 'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram' => psm_get_lang('users', 'telegram'), 'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'), 'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'), 'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'),
'label_telegram_chat_id_description' => psm_get_lang('users', 'telegram_chat_id_description'), 'label_telegram_chat_id_description' => psm_get_lang('users', 'telegram_chat_id_description'),
'label_activate_telegram' => psm_get_lang('users', 'activate_telegram'), 'label_activate_telegram' => psm_get_lang('users', 'activate_telegram'),
'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'), 'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'),
'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL, 'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL,
'label_email' => psm_get_lang('users', 'email'), 'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'), 'label_save' => psm_get_lang('system', 'save'),
'form_action' => psm_build_url(array( 'form_action' => psm_build_url(array(
'mod' => 'user_profile', 'mod' => 'user_profile',
'action' => 'save', 'action' => 'save',
)), )),
'level' => psm_get_lang('users', 'level_' . $user->level), 'level' => psm_get_lang('users', 'level_' . $user->level),
'placeholder_password' => psm_get_lang('users', 'password_leave_blank'), 'placeholder_password' => psm_get_lang('users', 'password_leave_blank'),
); );
foreach ($this->profile_fields as $field) { foreach ($this->profile_fields as $field) {
$tpl_data[$field] = (isset($user->$field)) ? $user->$field : ''; $tpl_data[$field] = (isset($user->$field)) ? $user->$field : '';
} }
return $this->twig->render('module/user/profile.tpl.html', $tpl_data); return $this->twig->render('module/user/profile.tpl.html', $tpl_data);
} }
/** /**
* Save the profile * Save the profile
*/ */
protected function executeSave() { protected function executeSave()
if (empty($_POST)) { {
// dont process anything if no data has been posted if (empty($_POST)) {
return $this->executeIndex(); // dont process anything if no data has been posted
} return $this->executeIndex();
$validator = $this->container->get('util.user.validator'); }
$fields = $this->profile_fields; $validator = $this->container->get('util.user.validator');
$fields[] = 'password'; $fields = $this->profile_fields;
$fields[] = 'password_repeat'; $fields[] = 'password';
$fields[] = 'password_repeat';
$clean = array(); $clean = array();
foreach ($fields as $field) { foreach ($fields as $field) {
if (isset($_POST[$field])) { if (isset($_POST[$field])) {
$clean[$field] = trim(strip_tags($_POST[$field])); $clean[$field] = trim(strip_tags($_POST[$field]));
} else { } else {
$clean[$field] = ''; $clean[$field] = '';
} }
} }
// validate the lot // validate the lot
try { try {
$validator->username($clean['user_name'], $this->getUser()->getUserId()); $validator->username($clean['user_name'], $this->getUser()->getUserId());
$validator->email($clean['email']); $validator->email($clean['email']);
// always validate password for new users, // always validate password for new users,
// but only validate it for existing users when they change it. // but only validate it for existing users when they change it.
if ($clean['password'] != '') { if ($clean['password'] != '') {
$validator->password($clean['password'], $clean['password_repeat']); $validator->password($clean['password'], $clean['password_repeat']);
} }
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
return $this->executeIndex(); return $this->executeIndex();
} }
if (!empty($clean['password'])) { if (!empty($clean['password'])) {
$password = $clean['password']; $password = $clean['password'];
} }
unset($clean['password']); unset($clean['password']);
unset($clean['password_repeat']); unset($clean['password_repeat']);
$this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $this->getUser()->getUserId())); $this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $this->getUser()->getUserId()));
$this->container->get('event')->dispatch( $this->container->get('event')->dispatch(
\psm\Module\User\UserEvents::USER_EDIT, \psm\Module\User\UserEvents::USER_EDIT,
new \psm\Module\User\Event\UserEvent($this->getUser()->getUserId()) new \psm\Module\User\Event\UserEvent($this->getUser()->getUserId())
); );
if (isset($password)) { if (isset($password)) {
$this->getUser()->changePassword($this->getUser()->getUserId(), $password); $this->getUser()->changePassword($this->getUser()->getUserId(), $password);
} }
$this->addMessage(psm_get_lang('users', 'profile_updated'), 'success'); $this->addMessage(psm_get_lang('users', 'profile_updated'), 'success');
if (!empty($_POST['activate_telegram'])) { if (!empty($_POST['activate_telegram'])) {
$this->activateTelegram(); $this->activateTelegram();
} }
return $this->executeIndex(); return $this->executeIndex();
} }
/** /**
* Allow the bot to send notifications to chat_id * Allow the bot to send notifications to chat_id
* *
*/ */
protected function activateTelegram() { protected function activateTelegram()
$telegram = psm_build_telegram(); {
$apiToken = psm_get_conf('telegram_api_token'); $telegram = psm_build_telegram();
$apiToken = psm_get_conf('telegram_api_token');
if (empty($apiToken)) { if (empty($apiToken)) {
$this->addMessage(psm_get_lang('config', 'telegram_error_notoken'), 'error'); $this->addMessage(psm_get_lang('config', 'telegram_error_notoken'), 'error');
return; return;
} }
$result = $telegram->getBotUsername(); $result = $telegram->getBotUsername();
if (isset($result['ok']) && $result['ok'] != false) { if (isset($result['ok']) && $result['ok'] != false) {
$url = "https://t.me/" . $result["result"]["username"]; $url = "https://t.me/" . $result["result"]["username"];
$this->addMessage(sprintf(psm_get_lang('users', 'telegram_bot_username_found'), $url), 'success'); $this->addMessage(sprintf(psm_get_lang('users', 'telegram_bot_username_found'), $url), 'success');
return; return;
} }
if (isset($result['error_code']) && $result['error_code'] == 401) { if (isset($result['error_code']) && $result['error_code'] == 401) {
$error = psm_get_lang('users', 'telegram_bot_username_error_token'); $error = psm_get_lang('users', 'telegram_bot_username_error_token');
} elseif (isset($result['description'])) { } elseif (isset($result['description'])) {
$error = $result['description']; $error = $result['description'];
} else { } else {
$error = 'Unknown'; $error = 'Unknown';
} }
$this->addMessage(sprintf(psm_get_lang('users', 'telegram_bot_error'), $error), 'error'); $this->addMessage(sprintf(psm_get_lang('users', 'telegram_bot_error'), $error), 'error');
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -26,6 +27,7 @@
**/ **/
namespace psm\Module\User\Controller; namespace psm\Module\User\Controller;
use psm\Module\AbstractController; use psm\Module\AbstractController;
use psm\Service\Database; use psm\Service\Database;
@ -33,354 +35,392 @@ use psm\Service\Database;
* User module. Add, edit and delete users, or assign * User module. Add, edit and delete users, or assign
* servers to users. * servers to users.
*/ */
class UserController extends AbstractController { class UserController extends AbstractController
public $servers = array(); {
public $servers = array();
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
parent::__construct($db, $twig); {
parent::__construct($db, $twig);
$this->setMinUserLevelRequired(PSM_USER_ADMIN); $this->setMinUserLevelRequired(PSM_USER_ADMIN);
$this->setCSRFKey('user'); $this->setCSRFKey('user');
$this->setActions(array( $this->setActions(array(
'index', 'edit', 'delete', 'save', 'index', 'edit', 'delete', 'save',
), 'index'); ), 'index');
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'user')); $this->twig->addGlobal('subtitle', psm_get_lang('menu', 'user'));
} }
public function run($action = NULL) { public function run($action = null)
$servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'), '', "ORDER BY `label` ASC"); {
// change the indexes to reflect their server ids $servers = $this->db->select(
foreach ($servers as $server) { PSM_DB_PREFIX . 'servers',
$this->servers[$server['server_id']] = $server; null,
} array('server_id', 'label'),
'',
"ORDER BY `label` ASC"
);
// change the indexes to reflect their server ids
foreach ($servers as $server) {
$this->servers[$server['server_id']] = $server;
}
return parent::run($action); return parent::run($action);
} }
/** /**
* Create HTML to show a list of all users * Create HTML to show a list of all users
* *
* @return string * @return string
*/ */
protected function executeIndex() { protected function executeIndex()
$sidebar = new \psm\Util\Module\Sidebar($this->twig); {
$this->setSidebar($sidebar); $sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar);
$sidebar->addButton( $sidebar->addButton(
'add_new', 'add_new',
psm_get_lang('system', 'add_new'), psm_get_lang('system', 'add_new'),
psm_build_url(array('mod' => 'user', 'action' => 'edit')), psm_build_url(array('mod' => 'user', 'action' => 'edit')),
'plus icon-white', 'plus icon-white',
'success', 'success',
psm_get_lang('system', 'add_new') psm_get_lang('system', 'add_new')
); );
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER); $modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal); $this->addModal($modal);
$modal->setTitle(psm_get_lang('users', 'delete_title')); $modal->setTitle(psm_get_lang('users', 'delete_title'));
$modal->setMessage(psm_get_lang('users', 'delete_message')); $modal->setMessage(psm_get_lang('users', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete')); $modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
// build label array for the next loop // build label array for the next loop
$servers_labels = array(); $servers_labels = array();
foreach ($this->servers as $server) { foreach ($this->servers as $server) {
$servers_labels[$server['server_id']] = $server['label']; $servers_labels[$server['server_id']] = $server['label'];
} }
$users = $this->db->select( $users = $this->db->select(
PSM_DB_PREFIX.'users', PSM_DB_PREFIX . 'users',
null, null,
array('user_id', 'user_name', 'level', 'name', 'mobile', 'email'), array('user_id', 'user_name', 'level', 'name', 'mobile', 'email'),
null, null,
array('name') array('name')
); );
foreach ($users as $x => &$user) { foreach ($users as $x => &$user) {
$user_servers = $this->getUserServers($user['user_id']); $user_servers = $this->getUserServers($user['user_id']);
$user['class'] = ($x & 1) ? 'odd' : 'even'; $user['class'] = ($x & 1) ? 'odd' : 'even';
$user['level_text'] = psm_get_lang('users', 'level_'.$user['level']); $user['level_text'] = psm_get_lang('users', 'level_' . $user['level']);
$user['emp_servers'] = array(); $user['emp_servers'] = array();
// fix server list // fix server list
foreach ($user_servers as $server_id) { foreach ($user_servers as $server_id) {
if (!isset($servers_labels[$server_id])) { if (!isset($servers_labels[$server_id])) {
continue; continue;
} }
$user['emp_servers'][] = array( $user['emp_servers'][] = array(
'label' => $servers_labels[$server_id], 'label' => $servers_labels[$server_id],
'url' => psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server_id, 'back_to' => 'user')) 'url' => psm_build_url(
); array('mod' => 'server', 'action' => 'view', 'id' => $server_id, 'back_to' => 'user')
} )
sort($user['emp_servers']); );
}
sort($user['emp_servers']);
$user['url_delete'] = psm_build_url(array( $user['url_delete'] = psm_build_url(array(
'mod' => 'user', 'mod' => 'user',
'action' => 'delete', 'action' => 'delete',
'id' => $user['user_id'], 'id' => $user['user_id'],
)); ));
$user['url_edit'] = psm_build_url(array( $user['url_edit'] = psm_build_url(array(
'mod' => 'user', 'mod' => 'user',
'action' => 'edit', 'action' => 'edit',
'id' => $user['user_id'], 'id' => $user['user_id'],
)); ));
} }
$tpl_data = $this->getLabels(); $tpl_data = $this->getLabels();
$tpl_data['users'] = $users; $tpl_data['users'] = $users;
return $this->twig->render('module/user/user/list.tpl.html', $tpl_data); return $this->twig->render('module/user/user/list.tpl.html', $tpl_data);
} }
/** /**
* Crate HTML for the update screen for a user * Crate HTML for the update screen for a user
* *
* @return string * @return string
*/ */
protected function executeEdit() { protected function executeEdit()
$user_id = isset($_GET['id']) ? intval($_GET['id']) : 0; {
$fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email'); $user_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$fields_prefill = array(
'name',
'user_name',
'mobile',
'pushover_key',
'pushover_device',
'telegram_id',
'email'
);
if ($user_id == 0) { if ($user_id == 0) {
// insert mode // insert mode
$title = psm_get_lang('system', 'insert'); $title = psm_get_lang('system', 'insert');
$placeholder_password = ''; $placeholder_password = '';
$lvl_selected = PSM_USER_USER; // default level is regular user $lvl_selected = PSM_USER_USER; // default level is regular user
// attempt to prefill previously posted fields // attempt to prefill previously posted fields
$edit_user = new \stdClass(); $edit_user = new \stdClass();
foreach ($fields_prefill as $field) { foreach ($fields_prefill as $field) {
$edit_user->$field = (isset($_POST[$field])) ? $_POST[$field] : ''; $edit_user->$field = (isset($_POST[$field])) ? $_POST[$field] : '';
} }
// add inactive class to all servers // add inactive class to all servers
foreach ($this->servers as &$server) { foreach ($this->servers as &$server) {
$server['class'] = 'inactive'; $server['class'] = 'inactive';
} }
} else { } else {
// edit mode // edit mode
try { try {
$this->container->get('util.user.validator')->userId($user_id); $this->container->get('util.user.validator')->userId($user_id);
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_'.$e->getMessage()), 'error'); $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
return $this->executeIndex(); return $this->executeIndex();
} }
$edit_user = $this->getUser()->getUser($user_id); $edit_user = $this->getUser()->getUser($user_id);
$title = psm_get_lang('system', 'edit').' '.$edit_user->name; $title = psm_get_lang('system', 'edit') . ' ' . $edit_user->name;
$placeholder_password = psm_get_lang('users', 'password_leave_blank'); $placeholder_password = psm_get_lang('users', 'password_leave_blank');
$lvl_selected = $edit_user->level; $lvl_selected = $edit_user->level;
// select servers for this user // select servers for this user
$user_servers = $this->getUserServers($user_id); $user_servers = $this->getUserServers($user_id);
foreach ($this->servers as &$server) { foreach ($this->servers as &$server) {
$this->servers[$server['server_id']]['id'] = $server['server_id']; $this->servers[$server['server_id']]['id'] = $server['server_id'];
if (in_array($server['server_id'], $user_servers)) { if (in_array($server['server_id'], $user_servers)) {
$server['edit_selected'] = 'selected="selected"'; $server['edit_selected'] = 'selected="selected"';
$server['class'] = 'active'; $server['class'] = 'active';
} }
} }
} }
$tpl_data = array( $tpl_data = array(
'titlemode' => $title, 'titlemode' => $title,
'placeholder_password' => $placeholder_password, 'placeholder_password' => $placeholder_password,
'edit_user_id' => $user_id, 'edit_user_id' => $user_id,
'url_save' => psm_build_url(array( 'url_save' => psm_build_url(array(
'mod' => 'user', 'mod' => 'user',
'action' => 'save', 'action' => 'save',
'id' => $user_id, 'id' => $user_id,
)), )),
'servers' => $this->servers, 'servers' => $this->servers,
'user_level' => $lvl_selected, 'user_level' => $lvl_selected,
); );
foreach ($fields_prefill as $field) { foreach ($fields_prefill as $field) {
if (isset($edit_user->$field)) { if (isset($edit_user->$field)) {
$tpl_data['edit_value_'.$field] = $edit_user->$field; $tpl_data['edit_value_' . $field] = $edit_user->$field;
} }
} }
$tpl_data['levels'] = array(); $tpl_data['levels'] = array();
foreach ($this->container->get('util.user.validator')->getUserLevels() as $lvl) { foreach ($this->container->get('util.user.validator')->getUserLevels() as $lvl) {
$tpl_data['levels'][] = array( $tpl_data['levels'][] = array(
'value' => $lvl, 'value' => $lvl,
'label' => psm_get_lang('users', 'level_'.$lvl), 'label' => psm_get_lang('users', 'level_' . $lvl),
); );
} }
$tpl_data = array_merge($this->getLabels(), $tpl_data); $tpl_data = array_merge($this->getLabels(), $tpl_data);
return $this->twig->render('module/user/user/update.tpl.html', $tpl_data); return $this->twig->render('module/user/user/update.tpl.html', $tpl_data);
} }
/** /**
* Executes the saving of a user * Executes the saving of a user
*/ */
protected function executeSave() { protected function executeSave()
if (empty($_POST)) { {
// dont process anything if no data has been posted if (empty($_POST)) {
return $this->executeIndex(); // dont process anything if no data has been posted
} return $this->executeIndex();
$user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; }
$user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
$fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email'); $fields = array(
$clean = array(); 'name',
foreach ($fields as $field) { 'user_name',
if (isset($_POST[$field])) { 'password',
$clean[$field] = trim(strip_tags($_POST[$field])); 'password_repeat',
} else { 'level',
$clean[$field] = ''; 'mobile',
} 'pushover_key',
} 'pushover_device',
'telegram_id',
'email'
);
$clean = array();
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$clean[$field] = trim(strip_tags($_POST[$field]));
} else {
$clean[$field] = '';
}
}
$user_validator = $this->container->get('util.user.validator'); $user_validator = $this->container->get('util.user.validator');
try { try {
$user_validator->username($clean['user_name'], $user_id); $user_validator->username($clean['user_name'], $user_id);
$user_validator->email($clean['email']); $user_validator->email($clean['email']);
$user_validator->level($clean['level']); $user_validator->level($clean['level']);
if(count($this->db->select(PSM_DB_PREFIX.'users', array('level' => PSM_USER_ADMIN))) == 1 && if (
$this->getUser()->getUserLevel() == PSM_USER_ADMIN) { count($this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN))) == 1 &&
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'warning'); $this->getUser()->getUserLevel() == PSM_USER_ADMIN
$clean['level'] = PSM_USER_ADMIN; ) {
} $this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'warning');
$clean['level'] = PSM_USER_ADMIN;
}
// always validate password for new users, // always validate password for new users,
// but only validate it for existing users when they change it. // but only validate it for existing users when they change it.
if ($user_id == 0 || ($user_id > 0 && $clean['password'] != '')) { if ($user_id == 0 || ($user_id > 0 && $clean['password'] != '')) {
$user_validator->password($clean['password'], $clean['password_repeat']); $user_validator->password($clean['password'], $clean['password_repeat']);
} }
if ($user_id > 0) { if ($user_id > 0) {
$user_validator->userId($user_id); $user_validator->userId($user_id);
} }
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_'.$e->getMessage()), 'error'); $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
return $this->executeEdit(); return $this->executeEdit();
} }
if (!empty($clean['password'])) { if (!empty($clean['password'])) {
$password = $clean['password']; $password = $clean['password'];
} }
unset($clean['password_repeat']); unset($clean['password_repeat']);
if ($user_id > 0) { if ($user_id > 0) {
// edit user // edit user
unset($clean['password']); // password update is executed separately unset($clean['password']); // password update is executed separately
$this->db->save(PSM_DB_PREFIX.'users', $clean, array('user_id' => $user_id)); $this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $user_id));
$this->addMessage(psm_get_lang('users', 'updated'), 'success'); $this->addMessage(psm_get_lang('users', 'updated'), 'success');
$event = \psm\Module\User\UserEvents::USER_EDIT; $event = \psm\Module\User\UserEvents::USER_EDIT;
} else { } else {
// add user // add user
$clean['password'] = ''; // password update is executed separately $clean['password'] = ''; // password update is executed separately
$user_id = $this->db->save(PSM_DB_PREFIX.'users', $clean); $user_id = $this->db->save(PSM_DB_PREFIX . 'users', $clean);
$this->addMessage(psm_get_lang('users', 'inserted'), 'success'); $this->addMessage(psm_get_lang('users', 'inserted'), 'success');
$event = \psm\Module\User\UserEvents::USER_ADD; $event = \psm\Module\User\UserEvents::USER_ADD;
} }
$this->container->get('event')->dispatch( $this->container->get('event')->dispatch(
$event, $event,
new \psm\Module\User\Event\UserEvent($user_id, $this->getUser()->getUserId()) new \psm\Module\User\Event\UserEvent($user_id, $this->getUser()->getUserId())
); );
if (isset($password)) { if (isset($password)) {
$this->getUser()->changePassword($user_id, $password); $this->getUser()->changePassword($user_id, $password);
} }
// update servers // update servers
$server_idc = psm_POST('server_id', array()); $server_idc = psm_POST('server_id', array());
$server_idc_save = array(); $server_idc_save = array();
foreach ($server_idc as $server_id) { foreach ($server_idc as $server_id) {
$server_idc_save[] = array( $server_idc_save[] = array(
'user_id' => $user_id, 'user_id' => $user_id,
'server_id' => intval($server_id), 'server_id' => intval($server_id),
); );
} }
// delete all existing records // delete all existing records
$this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $user_id)); $this->db->delete(PSM_DB_PREFIX . 'users_servers', array('user_id' => $user_id));
if (!empty($server_idc_save)) { if (!empty($server_idc_save)) {
// add all new servers // add all new servers
$this->db->insertMultiple(PSM_DB_PREFIX.'users_servers', $server_idc_save); $this->db->insertMultiple(PSM_DB_PREFIX . 'users_servers', $server_idc_save);
} }
return $this->executeIndex(); return $this->executeIndex();
} }
/** /**
* Executes the deletion of a user * Executes the deletion of a user
*/ */
protected function executeDelete() { protected function executeDelete()
$id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; {
$id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
try { try {
$this->container->get('util.user.validator')->userId($id); $this->container->get('util.user.validator')->userId($id);
if(count($this->db->select(PSM_DB_PREFIX.'users', array('level' => PSM_USER_ADMIN))) == 1) { if (count($this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN))) == 1) {
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'error'); $this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'error');
} else { } else {
$this->db->delete(PSM_DB_PREFIX.'users', array('user_id' => $id,)); $this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,));
$this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $id)); $this->db->delete(PSM_DB_PREFIX . 'users_servers', array('user_id' => $id));
$this->container->get('event')->dispatch( $this->container->get('event')->dispatch(
\psm\Module\User\UserEvents::USER_DELETE, \psm\Module\User\UserEvents::USER_DELETE,
new \psm\Module\User\Event\UserEvent($id, $this->getUser()->getUserId()) new \psm\Module\User\Event\UserEvent($id, $this->getUser()->getUserId())
); );
$this->addMessage(psm_get_lang('users', 'deleted'), 'success'); $this->addMessage(psm_get_lang('users', 'deleted'), 'success');
} }
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->addMessage(psm_get_lang('users', 'error_'.$e->getMessage()), 'error'); $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error');
} }
return $this->executeIndex(); return $this->executeIndex();
} }
protected function getLabels() { protected function getLabels()
return array( {
'label_users' => psm_get_lang('menu', 'user'), return array(
'label_user' => psm_get_lang('users', 'user'), 'label_users' => psm_get_lang('menu', 'user'),
'label_name' => psm_get_lang('users', 'name'), 'label_user' => psm_get_lang('users', 'user'),
'label_user_name' => psm_get_lang('users', 'user_name'), 'label_name' => psm_get_lang('users', 'name'),
'label_password' => psm_get_lang('users', 'password'), 'label_user_name' => psm_get_lang('users', 'user_name'),
'label_password_repeat' => psm_get_lang('users', 'password_repeat'), 'label_password' => psm_get_lang('users', 'password'),
'label_level' => psm_get_lang('users', 'level'), 'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level_description' => psm_get_lang('users', 'level_description'), 'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'), 'label_level_description' => psm_get_lang('users', 'level_description'),
'label_pushover' => psm_get_lang('users', 'pushover'), 'label_mobile' => psm_get_lang('users', 'mobile'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_telegram' => psm_get_lang('users', 'telegram'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'), 'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_id' => psm_get_lang('users', 'telegram_chat_id'), 'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_id_description' => psm_get_lang('users', 'telegram_chat_id_description'), 'label_telegram_id' => psm_get_lang('users', 'telegram_chat_id'),
'label_email' => psm_get_lang('users', 'email'), 'label_telegram_id_description' => psm_get_lang('users', 'telegram_chat_id_description'),
'label_servers' => psm_get_lang('menu', 'server'), 'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'), 'label_servers' => psm_get_lang('menu', 'server'),
'label_go_back' => psm_get_lang('system', 'go_back'), 'label_save' => psm_get_lang('system', 'save'),
'label_edit' => psm_get_lang('system', 'edit'), 'label_go_back' => psm_get_lang('system', 'go_back'),
'label_delete' => psm_get_lang('system', 'delete'), 'label_edit' => psm_get_lang('system', 'edit'),
'label_add_new' => psm_get_lang('system', 'add_new'), 'label_delete' => psm_get_lang('system', 'delete'),
'label_search' => psm_get_lang('system', 'search'), 'label_add_new' => psm_get_lang('system', 'add_new'),
); 'label_search' => psm_get_lang('system', 'search'),
} );
}
/** /**
* Get all server ids for a user * Get all server ids for a user
* @param int $user_id * @param int $user_id
* @return array with ids only * @return array with ids only
* @todo we should probably find a central place for this kind of stuff * @todo we should probably find a central place for this kind of stuff
*/ */
protected function getUserServers($user_id) { protected function getUserServers($user_id)
$servers = $this->db->select( {
PSM_DB_PREFIX.'users_servers', $servers = $this->db->select(
array('user_id' => $user_id), PSM_DB_PREFIX . 'users_servers',
array('server_id') array('user_id' => $user_id),
); array('server_id')
$result = array(); );
foreach ($servers as $server) { $result = array();
$result[] = $server['server_id']; foreach ($servers as $server) {
} $result[] = $server['server_id'];
return $result; }
} return $result;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -30,22 +31,26 @@ namespace psm\Module\User\Event;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
class UserEvent extends Event { class UserEvent extends Event
{
protected $user_id; protected $user_id;
protected $user_id_by; protected $user_id_by;
public function __construct($user_id, $user_id_by = null) { public function __construct($user_id, $user_id_by = null)
$this->user_id = $user_id; {
$this->user_id_by = $user_id_by; $this->user_id = $user_id;
} $this->user_id_by = $user_id_by;
}
public function getUserId() { public function getUserId()
return $this->user_id; {
} return $this->user_id;
}
public function getUserIdBy() { public function getUserIdBy()
return $this->user_id_by; {
} return $this->user_id_by;
} }
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -32,22 +33,27 @@ use psm\Module\User\UserEvents;
use psm\Module\User\Event\UserEvent; use psm\Module\User\Event\UserEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserSubscriber implements EventSubscriberInterface { class UserSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents() { public static function getSubscribedEvents()
return array( {
UserEvents::USER_ADD => array('onUserAdd', 0), return array(
UserEvents::USER_EDIT => array('onUserEdit', 0), UserEvents::USER_ADD => array('onUserAdd', 0),
UserEvents::USER_DELETE => array('onUserDelete', 0), UserEvents::USER_EDIT => array('onUserEdit', 0),
); UserEvents::USER_DELETE => array('onUserDelete', 0),
} );
}
public function onUserAdd(UserEvent $event) { public function onUserAdd(UserEvent $event)
} {
}
public function onUserEdit(UserEvent $event) { public function onUserEdit(UserEvent $event)
} {
}
public function onUserDelete(UserEvent $event) { public function onUserDelete(UserEvent $event)
} {
} }
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,21 +29,21 @@
namespace psm\Module\User; namespace psm\Module\User;
final class UserEvents { final class UserEvents
{
/** /**
* @var string * @var string
*/ */
const USER_ADD = 'user.add'; public const USER_ADD = 'user.add';
/** /**
* @var string * @var string
*/ */
const USER_EDIT = 'user.edit'; public const USER_EDIT = 'user.edit';
/** /**
* @var string * @var string
*/ */
const USER_DELETE = 'user.delete'; public const USER_DELETE = 'user.delete';
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -23,7 +24,7 @@
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.0 * @since phpservermon 3.0
**/ **/
namespace psm\Module\User; namespace psm\Module\User;
@ -31,19 +32,21 @@ namespace psm\Module\User;
use psm\Module\ModuleInterface; use psm\Module\ModuleInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
class UserModule implements ModuleInterface { class UserModule implements ModuleInterface
{
public function load(ContainerBuilder $container) { public function load(ContainerBuilder $container)
$event = $container->get('event'); {
$event->addSubscriber(new EventListener\UserSubscriber); $event = $container->get('event');
} $event->addSubscriber(new EventListener\UserSubscriber());
}
public function getControllers() { public function getControllers()
return array( {
'user' => __NAMESPACE__.'\Controller\UserController', return array(
'login' => __NAMESPACE__.'\Controller\LoginController', 'user' => __NAMESPACE__ . '\Controller\UserController',
'profile' => __NAMESPACE__.'\Controller\ProfileController', 'login' => __NAMESPACE__ . '\Controller\LoginController',
); 'profile' => __NAMESPACE__ . '\Controller\ProfileController',
);
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,6 +28,7 @@
**/ **/
namespace psm; namespace psm;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\FileLocator;
@ -42,196 +44,207 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
* the module config. If the controller part is absent, it will always try to load * the module config. If the controller part is absent, it will always try to load
* the controller with the same name as the module. * the controller with the same name as the module.
*/ */
class Router { class Router
{
/** /**
* Service container * Service container
* @var \Symfony\Component\DependencyInjection\ContainerBuilder $container * @var \Symfony\Component\DependencyInjection\ContainerBuilder $container
*/ */
protected $container; protected $container;
public function __construct() { public function __construct()
$this->container = $this->buildServiceContainer(); {
$this->container = $this->buildServiceContainer();
$mods = $this->container->getParameter('modules'); $mods = $this->container->getParameter('modules');
foreach ($mods as $mod) { foreach ($mods as $mod) {
$mod_loader = $this->container->get($mod); $mod_loader = $this->container->get($mod);
$mod_loader->load($this->container); $mod_loader->load($this->container);
} }
} }
/** /**
* Run a module. * Run a module.
* *
* The $mod param is in the format $module_$controller. * The $mod param is in the format $module_$controller.
* If the "_$controller" part is omitted, it will attempt to load * If the "_$controller" part is omitted, it will attempt to load
* the controller with the same name as the module. * the controller with the same name as the module.
* *
* @param string $mod * @param string $mod
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \LogicException * @throws \LogicException
*/ */
public function run($mod) { public function run($mod)
if (strpos($mod, '_') !== false) { {
list($mod, $controller) = explode('_', $mod); if (strpos($mod, '_') !== false) {
} else { list($mod, $controller) = explode('_', $mod);
$controller = $mod; } else {
} $controller = $mod;
$this->buildTwigEnvironment(); }
$this->buildTwigEnvironment();
$controller = $this->getController($mod, $controller); $controller = $this->getController($mod, $controller);
$action = null; $action = null;
try { try {
$this->validateRequest($controller); $this->validateRequest($controller);
} catch (\InvalidArgumentException $ex) { } catch (\InvalidArgumentException $ex) {
switch ($ex->getMessage()) { switch ($ex->getMessage()) {
case 'login_required': case 'login_required':
$controller = $this->getController('user', 'login'); $controller = $this->getController('user', 'login');
break; break;
case 'invalid_csrf_token': case 'invalid_csrf_token':
case 'invalid_user_level': case 'invalid_user_level':
default: default:
$controller = $this->getController('error'); $controller = $this->getController('error');
$action = '401'; $action = '401';
break; break;
} }
} }
$response = $controller->run($action); $response = $controller->run($action);
if (!($response instanceof Response)) { if (!($response instanceof Response)) {
throw new \LogicException('Controller did not return a Response object.'); throw new \LogicException('Controller did not return a Response object.');
} }
$response->send(); $response->send();
} }
/** /**
* Get an instance of the requested controller. * Get an instance of the requested controller.
* @param string $module_id * @param string $module_id
* @param string $controller_id if NULL, default controller will be used * @param string $controller_id if NULL, default controller will be used
* @return \psm\Module\ControllerInterface * @return \psm\Module\ControllerInterface
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function getController($module_id, $controller_id = null) { public function getController($module_id, $controller_id = null)
if ($controller_id === null) { {
// by default, we use the controller with the same id as the module. if ($controller_id === null) {
$controller_id = $module_id; // by default, we use the controller with the same id as the module.
} $controller_id = $module_id;
}
$module = $this->container->get('module.'.$module_id); $module = $this->container->get('module.' . $module_id);
$controllers = $module->getControllers(); $controllers = $module->getControllers();
if (!isset($controllers[$controller_id]) || !class_exists($controllers[$controller_id])) { if (!isset($controllers[$controller_id]) || !class_exists($controllers[$controller_id])) {
throw new \InvalidArgumentException('Controller "'.$controller_id.'" is not registered or does not exist.'); throw new \InvalidArgumentException('Controller "' . $controller_id . '"
} is not registered or does not exist.');
$controller = new $controllers[$controller_id]( }
$this->container->get('db'), $controller = new $controllers[$controller_id](
$this->container->get('twig') $this->container->get('db'),
); $this->container->get('twig')
);
if (!$controller instanceof \psm\Module\ControllerInterface) { if (!$controller instanceof \psm\Module\ControllerInterface) {
throw new \Exception('Controller does not implement ControllerInterface'); throw new \Exception('Controller does not implement ControllerInterface');
} }
$controller->setContainer($this->container); $controller->setContainer($this->container);
return $controller; return $controller;
} }
/** /**
* Get service from container * Get service from container
* @param string $id * @param string $id
* @return mixed FALSE on failure, service otherwise * @return mixed FALSE on failure, service otherwise
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function getService($id) { public function getService($id)
return $this->container->get($id); {
} return $this->container->get($id);
}
/** /**
* Validate requets before heading to a controller * Validate requets before heading to a controller
* @param \psm\Module\ControllerInterface $controller * @param \psm\Module\ControllerInterface $controller
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected function validateRequest(\psm\Module\ControllerInterface $controller) { protected function validateRequest(\psm\Module\ControllerInterface $controller)
$request = Request::createFromGlobals(); {
$request = Request::createFromGlobals();
if ($request->getMethod() == 'POST') { if ($request->getMethod() == 'POST') {
// require CSRF token for all POST calls // require CSRF token for all POST calls
$session = $this->container->get('user')->getSession(); $session = $this->container->get('user')->getSession();
$token_in = $request->request->get('csrf', ''); $token_in = $request->request->get('csrf', '');
$csrf_key = $controller->getCSRFKey(); $csrf_key = $controller->getCSRFKey();
if (empty($csrf_key)) { if (empty($csrf_key)) {
if (!hash_equals($session->get('csrf_token'), $token_in)) { if (!hash_equals($session->get('csrf_token'), $token_in)) {
throw new \InvalidArgumentException('invalid_csrf_token'); throw new \InvalidArgumentException('invalid_csrf_token');
} }
} else { } else {
if (!hash_equals( if (
hash_hmac('sha256', $csrf_key, $session->get('csrf_token2')), !hash_equals(
$token_in hash_hmac('sha256', $csrf_key, $session->get('csrf_token2')),
)) { $token_in
throw new \InvalidArgumentException('invalid_csrf_token'); )
} ) {
} throw new \InvalidArgumentException('invalid_csrf_token');
} }
}
}
// get min required level for this controller and make sure the user matches // get min required level for this controller and make sure the user matches
$min_lvl = $controller->getMinUserLevelRequired(); $min_lvl = $controller->getMinUserLevelRequired();
if ($min_lvl < PSM_USER_ANONYMOUS) { if ($min_lvl < PSM_USER_ANONYMOUS) {
// if user is not logged in, load login module // if user is not logged in, load login module
if (!$this->container->get('user')->isUserLoggedIn()) { if (!$this->container->get('user')->isUserLoggedIn()) {
throw new \InvalidArgumentException('login_required'); throw new \InvalidArgumentException('login_required');
} elseif ($this->container->get('user')->getUserLevel() > $min_lvl) { } elseif ($this->container->get('user')->getUserLevel() > $min_lvl) {
throw new \InvalidArgumentException('invalid_user_level'); throw new \InvalidArgumentException('invalid_user_level');
} }
} }
} }
/** /**
* Build a new service container * Build a new service container
* @return \Symfony\Component\DependencyInjection\ContainerBuilder * @return \Symfony\Component\DependencyInjection\ContainerBuilder
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected function buildServiceContainer() { protected function buildServiceContainer()
$builder = new ContainerBuilder(); {
$loader = new XmlFileLoader($builder, new FileLocator(PSM_PATH_CONFIG)); $builder = new ContainerBuilder();
$loader->load('services.xml'); $loader = new XmlFileLoader($builder, new FileLocator(PSM_PATH_CONFIG));
$loader->load('services.xml');
return $builder; return $builder;
} }
/** /**
* Prepare twig environment * Prepare twig environment
* @return \Twig_Environment * @return \Twig_Environment
*/ */
protected function buildTwigEnvironment() { protected function buildTwigEnvironment()
$twig = $this->container->get('twig'); {
$session = $this->container->get('user')->getSession(); $twig = $this->container->get('twig');
if (!$session->has('csrf_token')) { $session = $this->container->get('user')->getSession();
$session->set('csrf_token', bin2hex(random_bytes(32))); if (!$session->has('csrf_token')) {
} $session->set('csrf_token', bin2hex(random_bytes(32)));
if (!$session->has('csrf_token2')) { }
$session->set('csrf_token2', random_bytes(32)); if (!$session->has('csrf_token2')) {
} $session->set('csrf_token2', random_bytes(32));
}
$twig->addFunction( $twig->addFunction(
new \Twig_SimpleFunction( new \Twig_SimpleFunction(
'csrf_token', 'csrf_token',
function($lock_to = null) use ($session) { function ($lock_to = null) use ($session) {
if (empty($lock_to)) { if (empty($lock_to)) {
return $session->get('csrf_token'); return $session->get('csrf_token');
} }
return hash_hmac('sha256', $lock_to, $session->get('csrf_token2')); return hash_hmac('sha256', $lock_to, $session->get('csrf_token2'));
} }
) )
); );
$twig->addGlobal('direction_current', psm_get_lang('locale_dir')); $twig->addGlobal('direction_current', psm_get_lang('locale_dir'));
$twig->addGlobal('language_current', psm_get_lang('locale_tag')); $twig->addGlobal('language_current', psm_get_lang('locale_tag'));
$twig->addGlobal('language', psm_get_lang('locale')[1]); $twig->addGlobal('language', psm_get_lang('locale')[1]);
return $twig; return $twig;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,6 +29,7 @@
**/ **/
namespace psm\Service; namespace psm\Service;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
@ -42,465 +44,501 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
* @link https://github.com/panique/php-login-advanced/ * @link https://github.com/panique/php-login-advanced/
* @license http://opensource.org/licenses/MIT MIT License * @license http://opensource.org/licenses/MIT MIT License
*/ */
class User { class User
{
/** /**
* The database connection * The database connection
* @var \PDO $db_connection * @var \PDO $db_connection
*/ */
protected $db_connection = null; protected $db_connection = null;
/** /**
* Local cache of user data * Local cache of user data
* @var array $user_data * @var array $user_data
*/ */
protected $user_data = array(); protected $user_data = array();
/** /**
* Session object * Session object
* @var \Symfony\Component\HttpFoundation\Session\Session $session * @var \Symfony\Component\HttpFoundation\Session\Session $session
*/ */
protected $session; protected $session;
/** /**
* Current user id * Current user id
* @var int $user_id * @var int $user_id
*/ */
protected $user_id; protected $user_id;
/** /**
*Current user preferences *Current user preferences
* @var array $user_preferences * @var array $user_preferences
*/ */
protected $user_preferences; protected $user_preferences;
/** /**
* The user's login status * The user's login status
* @var boolean $user_is_logged_in * @var boolean $user_is_logged_in
*/ */
protected $user_is_logged_in = false; protected $user_is_logged_in = false;
/** /**
* Open a new user service * Open a new user service
* *
* @param \psm\Service\Database $db * @param \psm\Service\Database $db
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session if NULL, one will be created * @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session if NULL, one will be created
*/ */
public function __construct(Database $db, SessionInterface $session = null) { public function __construct(Database $db, SessionInterface $session = null)
$this->db_connection = $db->pdo(); {
$this->db_connection = $db->pdo();
if (!psm_is_cli()) { if (!psm_is_cli()) {
if ($session == null) { if ($session == null) {
$session = new Session(); $session = new Session();
$session->start(); $session->start();
} }
$this->session = $session; $this->session = $session;
if ((!defined('PSM_INSTALL') || !PSM_INSTALL)) { if ((!defined('PSM_INSTALL') || !PSM_INSTALL)) {
// check the possible login actions: // 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) // 1. login via session data (happens each time user opens a page on your php project AFTER
// 2. login via cookie // he has successfully logged in via the login form)
// 2. login via cookie
// if user has an active session on the server // if user has an active session on the server
if (!$this->loginWithSessionData()) { if (!$this->loginWithSessionData()) {
$this->loginWithCookieData(); $this->loginWithCookieData();
} }
} }
} }
} }
/** /**
* Get user by id, or get current user. * Get user by id, or get current user.
* @param int $user_id if null it will attempt current user id * @param int $user_id if null it will attempt current user id
* @param boolean $flush if TRUE it will query db regardless of whether we already have the data * @param boolean $flush if TRUE it will query db regardless of whether we already have the data
* @return object|boolean FALSE if user not found, object otherwise * @return object|boolean FALSE if user not found, object otherwise
*/ */
public function getUser($user_id = null, $flush = false) { public function getUser($user_id = null, $flush = false)
if ($user_id == null) { {
if (!$this->isUserLoggedIn()) { if ($user_id == null) {
return false; if (!$this->isUserLoggedIn()) {
} else { return false;
$user_id = $this->getUserId(); } else {
} $user_id = $this->getUserId();
} }
}
if (!isset($this->user_data[$user_id]) || $flush) { if (!isset($this->user_data[$user_id]) || $flush) {
$query_user = $this->db_connection->prepare('SELECT * FROM '.PSM_DB_PREFIX.'users WHERE user_id = :user_id'); $query_user = $this->db_connection->prepare('SELECT * FROM ' .
$query_user->bindValue(':user_id', $user_id, \PDO::PARAM_INT); PSM_DB_PREFIX . 'users WHERE user_id = :user_id');
$query_user->execute(); $query_user->bindValue(':user_id', $user_id, \PDO::PARAM_INT);
// get result row (as an object) $query_user->execute();
$this->user_data[$user_id] = $query_user->fetchObject(); // get result row (as an object)
} $this->user_data[$user_id] = $query_user->fetchObject();
return $this->user_data[$user_id]; }
} return $this->user_data[$user_id];
}
/** /**
* Search into database for the user data of user_name specified as parameter * Search into database for the user data of user_name specified as parameter
* @return object|boolean user data as an object if existing user * @return object|boolean user data as an object if existing user
*/ */
public function getUserByUsername($user_name) { public function getUserByUsername($user_name)
// database query, getting all the info of the selected user {
$query_user = $this->db_connection->prepare('SELECT * FROM '.PSM_DB_PREFIX.'users WHERE user_name = :user_name'); // database query, getting all the info of the selected user
$query_user->bindValue(':user_name', $user_name, \PDO::PARAM_STR); $query_user = $this->db_connection->prepare('SELECT * FROM ' .
$query_user->execute(); PSM_DB_PREFIX . 'users WHERE user_name = :user_name');
// get result row (as an object) $query_user->bindValue(':user_name', $user_name, \PDO::PARAM_STR);
return $query_user->fetchObject(); $query_user->execute();
} // get result row (as an object)
return $query_user->fetchObject();
}
/** /**
* Logs in with SESSION data. * Logs in with SESSION data.
* *
* @return boolean * @return boolean
*/ */
protected function loginWithSessionData() { protected function loginWithSessionData()
if (!$this->session->has('user_id')) { {
return false; if (!$this->session->has('user_id')) {
} return false;
$user = $this->getUser($this->session->get('user_id')); }
$user = $this->getUser($this->session->get('user_id'));
if (!empty($user)) { if (!empty($user)) {
$this->setUserLoggedIn($user->user_id); $this->setUserLoggedIn($user->user_id);
return true; return true;
} else { } else {
// user no longer exists in database // user no longer exists in database
// call logout to clean up session vars // call logout to clean up session vars
$this->doLogout(); $this->doLogout();
return false; return false;
} }
} }
/** /**
* Logs in via the Cookie * Logs in via the Cookie
* @return bool success state of cookie login * @return bool success state of cookie login
*/ */
private function loginWithCookieData() { private function loginWithCookieData()
if (isset($_COOKIE['rememberme'])) { {
// extract data from the cookie if (isset($_COOKIE['rememberme'])) {
list ($user_id, $token, $hash) = explode(':', $_COOKIE['rememberme']); // extract data from the cookie
// check cookie hash validity list ($user_id, $token, $hash) = explode(':', $_COOKIE['rememberme']);
if ($hash == hash('sha256', $user_id.':'.$token.PSM_LOGIN_COOKIE_SECRET_KEY) && !empty($token)) { // check cookie hash validity
// cookie looks good, try to select corresponding user if ($hash == hash('sha256', $user_id . ':' . $token . PSM_LOGIN_COOKIE_SECRET_KEY) && !empty($token)) {
// get real token from database (and all other data) // cookie looks good, try to select corresponding user
$user = $this->getUser($user_id); // get real token from database (and all other data)
$user = $this->getUser($user_id);
if (!empty($user) && $token === $user->rememberme_token) { if (!empty($user) && $token === $user->rememberme_token) {
$this->setUserLoggedIn($user->user_id, true); $this->setUserLoggedIn($user->user_id, true);
// Cookie token usable only once // Cookie token usable only once
$this->newRememberMeCookie(); $this->newRememberMeCookie();
return true; return true;
} }
} }
// call logout to remove invalid cookie // call logout to remove invalid cookie
$this->doLogout(); $this->doLogout();
} }
return false; return false;
} }
/** /**
* Logs in with the data provided in $_POST, coming from the login form * Logs in with the data provided in $_POST, coming from the login form
* @param string $user_name * @param string $user_name
* @param string $user_password * @param string $user_password
* @param boolean $user_rememberme * @param boolean $user_rememberme
* @return boolean * @return boolean
*/ */
public function loginWithPostData($user_name, $user_password, $user_rememberme = false) { public function loginWithPostData($user_name, $user_password, $user_rememberme = false)
$user_name = trim($user_name); {
$user_password = trim($user_password); $user_name = trim($user_name);
$user_password = trim($user_password);
if (empty($user_name) && empty($user_password)) { if (empty($user_name) && empty($user_password)) {
return false; return false;
} }
$user = $this->getUserByUsername($user_name); $user = $this->getUserByUsername($user_name);
// using PHP 5.5's password_verify() function to check if the provided passwords fits to the hash of that user's password // using PHP 5.5's password_verify() function to check if the provided passwords
if (!isset($user->user_id)) { // fits to the hash of that user's password
password_verify($user_password, 'dummy_call_against_timing'); if (!isset($user->user_id)) {
return false; password_verify($user_password, 'dummy_call_against_timing');
} else if (!password_verify($user_password, $user->password)) { return false;
return false; } elseif (!password_verify($user_password, $user->password)) {
} return false;
}
$this->setUserLoggedIn($user->user_id, true); $this->setUserLoggedIn($user->user_id, true);
// if user has check the "remember me" checkbox, then generate token and write cookie // if user has check the "remember me" checkbox, then generate token and write cookie
if ($user_rememberme) { if ($user_rememberme) {
$this->newRememberMeCookie(); $this->newRememberMeCookie();
} }
// recalculate the user's password hash // recalculate the user's password hash
// DELETE this if-block if you like, it only exists to recalculate users's hashes when you provide a cost factor, // DELETE this if-block if you like, it only exists to recalculate
// by default the script will use a cost factor of 10 and never change it. // users's hashes when you provide a cost factor,
// check if the have defined a cost factor in config/hashing.php // by default the script will use a cost factor of 10 and never change it.
if (defined('PSM_LOGIN_HASH_COST_FACTOR')) { // check if the have defined a cost factor in config/hashing.php
// check if the hash needs to be rehashed if (defined('PSM_LOGIN_HASH_COST_FACTOR')) {
if (password_needs_rehash($user->password, PASSWORD_DEFAULT, array('cost' => PSM_LOGIN_HASH_COST_FACTOR))) { // check if the hash needs to be rehashed
$this->changePassword($user->user_id, $user_password); if (password_needs_rehash($user->password, PASSWORD_DEFAULT, array('cost' => PSM_LOGIN_HASH_COST_FACTOR))) {
} $this->changePassword($user->user_id, $user_password);
} }
return true; }
} return true;
}
/** /**
* Set the user logged in * Set the user logged in
* @param int $user_id * @param int $user_id
* @param boolean $regenerate regenerate session id against session fixation? * @param boolean $regenerate regenerate session id against session fixation?
*/ */
protected function setUserLoggedIn($user_id, $regenerate = false) { protected function setUserLoggedIn($user_id, $regenerate = false)
if ($regenerate) { {
$this->session->invalidate(); if ($regenerate) {
} $this->session->invalidate();
$this->session->set('user_id', $user_id); }
$this->session->set('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 // declare user id, set the login status to true
$this->user_id = $user_id; $this->user_id = $user_id;
$this->user_is_logged_in = true; $this->user_is_logged_in = true;
} }
/** /**
* Create all data needed for remember me cookie connection on client and server side * Create all data needed for remember me cookie connection on client and server side
*/ */
protected function newRememberMeCookie() { protected function newRememberMeCookie()
// generate 64 char random string and store it in current user data {
$random_token_string = hash('sha256', mt_rand()); // generate 64 char random string and store it in current user data
$sth = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET rememberme_token = :user_rememberme_token WHERE user_id = :user_id'); $random_token_string = hash('sha256', mt_rand());
$sth->execute(array(':user_rememberme_token' => $random_token_string, ':user_id' => $this->getUserId())); $sth = $this->db_connection->prepare('UPDATE ' .
PSM_DB_PREFIX . 'users SET rememberme_token = :user_rememberme_token WHERE user_id = :user_id');
$sth->execute(array(':user_rememberme_token' => $random_token_string, ':user_id' => $this->getUserId()));
// generate cookie string that consists of userid, randomstring and combined hash of both // generate cookie string that consists of userid, randomstring and combined hash of both
$cookie_string_first_part = $this->getUserId().':'.$random_token_string; $cookie_string_first_part = $this->getUserId() . ':' . $random_token_string;
$cookie_string_hash = hash('sha256', $cookie_string_first_part.PSM_LOGIN_COOKIE_SECRET_KEY); $cookie_string_hash = hash('sha256', $cookie_string_first_part . PSM_LOGIN_COOKIE_SECRET_KEY);
$cookie_string = $cookie_string_first_part.':'.$cookie_string_hash; $cookie_string = $cookie_string_first_part . ':' . $cookie_string_hash;
// set cookie // set cookie
setcookie('rememberme', $cookie_string, time() + PSM_LOGIN_COOKIE_RUNTIME, "/", PSM_LOGIN_COOKIE_DOMAIN); setcookie('rememberme', $cookie_string, time() + PSM_LOGIN_COOKIE_RUNTIME, "/", PSM_LOGIN_COOKIE_DOMAIN);
} }
/** /**
* Delete all data needed for remember me cookie connection on client and server side * Delete all data needed for remember me cookie connection on client and server side
*/ */
protected function deleteRememberMeCookie() { protected function deleteRememberMeCookie()
// Reset rememberme token {
if ($this->session->has('user_id')) { // Reset rememberme token
$sth = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET rememberme_token = NULL WHERE user_id = :user_id'); if ($this->session->has('user_id')) {
$sth->execute(array(':user_id' => $this->session->get('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' => $this->session->get('user_id')));
}
// set the rememberme-cookie to ten years ago (3600sec * 365 days * 10). // set the rememberme-cookie to ten years ago (3600sec * 365 days * 10).
// that's obivously the best practice to kill a cookie via php // that's obivously the best practice to kill a cookie via php
// @see http://stackoverflow.com/a/686166/1114320 // @see http://stackoverflow.com/a/686166/1114320
setcookie('rememberme', false, time() - (3600 * 3650), '/', PSM_LOGIN_COOKIE_DOMAIN); setcookie('rememberme', false, time() - (3600 * 3650), '/', PSM_LOGIN_COOKIE_DOMAIN);
} }
/** /**
* Perform the logout, resetting the session * Perform the logout, resetting the session
*/ */
public function doLogout() { public function doLogout()
$this->deleteRememberMeCookie(); {
$this->deleteRememberMeCookie();
$this->session->clear(); $this->session->clear();
$this->session->invalidate(); $this->session->invalidate();
$this->user_is_logged_in = false; $this->user_is_logged_in = false;
} }
/** /**
* Simply return the current state of the user's login * Simply return the current state of the user's login
* @return bool user's login status * @return bool user's login status
*/ */
public function isUserLoggedIn() { public function isUserLoggedIn()
return $this->user_is_logged_in; {
} return $this->user_is_logged_in;
}
/** /**
* Sets a random token into the database (that will verify the user when he/she comes back via the link * Sets a random token into the database (that will verify the user when he/she comes back via the link
* in the email) and returns it * in the email) and returns it
* @param int $user_id * @param int $user_id
* @return string|boolean FALSE on error, string otherwise * @return string|boolean FALSE on error, string otherwise
*/ */
public function generatePasswordResetToken($user_id) { public function generatePasswordResetToken($user_id)
$user_id = intval($user_id); {
$user_id = intval($user_id);
if ($user_id == 0) { if ($user_id == 0) {
return false; return false;
} }
// generate timestamp (to see when exactly the user (or an attacker) requested the password reset mail) // generate timestamp (to see when exactly the user (or an attacker) requested the password reset mail)
$temporary_timestamp = time(); $temporary_timestamp = time();
// generate random hash for email password reset verification (40 char string) // generate random hash for email password reset verification (40 char string)
$user_password_reset_hash = sha1(uniqid(mt_rand(), true)); $user_password_reset_hash = sha1(uniqid(mt_rand(), true));
$query_update = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET password_reset_hash = :user_password_reset_hash, $query_update = $this->db_connection->prepare('UPDATE ' .
password_reset_timestamp = :user_password_reset_timestamp PSM_DB_PREFIX . 'users SET password_reset_hash = :user_password_reset_hash,
WHERE user_id = :user_id'); password_reset_timestamp = :user_password_reset_timestamp
$query_update->bindValue(':user_password_reset_hash', $user_password_reset_hash, \PDO::PARAM_STR); WHERE user_id = :user_id');
$query_update->bindValue(':user_password_reset_timestamp', $temporary_timestamp, \PDO::PARAM_INT); $query_update->bindValue(':user_password_reset_hash', $user_password_reset_hash, \PDO::PARAM_STR);
$query_update->bindValue(':user_id', $user_id, \PDO::PARAM_INT); $query_update->bindValue(':user_password_reset_timestamp', $temporary_timestamp, \PDO::PARAM_INT);
$query_update->execute(); $query_update->bindValue(':user_id', $user_id, \PDO::PARAM_INT);
$query_update->execute();
// check if exactly one row was successfully changed: // check if exactly one row was successfully changed:
if ($query_update->rowCount() == 1) { if ($query_update->rowCount() == 1) {
return $user_password_reset_hash; return $user_password_reset_hash;
} else { } else {
return false; return false;
} }
} }
/** /**
* Checks if the verification string in the account verification mail is valid and matches to the user. * Checks if the verification string in the account verification mail is valid and matches to the user.
* *
* Please note it is valid for 1 hour. * Please note it is valid for 1 hour.
* @param int $user_id * @param int $user_id
* @param string $token * @param string $token
* @return boolean * @return boolean
*/ */
public function verifyPasswordResetToken($user_id, $token) { public function verifyPasswordResetToken($user_id, $token)
$user_id = intval($user_id); {
$user_id = intval($user_id);
if (empty($user_id) || empty($token)) { if (empty($user_id) || empty($token)) {
return false; return false;
} }
$user = $this->getUser($user_id); $user = $this->getUser($user_id);
if (isset($user->user_id) && $user->password_reset_hash == $token) { if (isset($user->user_id) && $user->password_reset_hash == $token) {
$runtime = (defined('PSM_LOGIN_RESET_RUNTIME')) ? PSM_LOGIN_RESET_RUNTIME : 3600; $runtime = (defined('PSM_LOGIN_RESET_RUNTIME')) ? PSM_LOGIN_RESET_RUNTIME : 3600;
$timestamp_max_interval = time() - $runtime; $timestamp_max_interval = time() - $runtime;
if ($user->password_reset_timestamp > $timestamp_max_interval) { if ($user->password_reset_timestamp > $timestamp_max_interval) {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Change the password of a user * Change the password of a user
* @param int|\PDOStatement $user_id * @param int|\PDOStatement $user_id
* @param string $password * @param string $password
* @return boolean TRUE on success, FALSE on failure * @return boolean TRUE on success, FALSE on failure
*/ */
public function changePassword($user_id, $password) { public function changePassword($user_id, $password)
$user_id = intval($user_id); {
$user_id = intval($user_id);
if (empty($user_id) || empty($password)) { if (empty($user_id) || empty($password)) {
return false; return false;
} }
// now it gets a little bit crazy: check if we have a constant PSM_LOGIN_HASH_COST_FACTOR defined (in src/includes/psmconfig.inc.php), // now it gets a little bit crazy: check if we have a constant
// if so: put the value into $hash_cost_factor, if not, make $hash_cost_factor = null // PSM_LOGIN_HASH_COST_FACTOR defined (in src/includes/psmconfig.inc.php),
$hash_cost_factor = (defined('PSM_LOGIN_HASH_COST_FACTOR') ? PSM_LOGIN_HASH_COST_FACTOR : null); // if so: put the value into $hash_cost_factor, if not, make $hash_cost_factor = null
$hash_cost_factor = (defined('PSM_LOGIN_HASH_COST_FACTOR') ? PSM_LOGIN_HASH_COST_FACTOR : null);
// crypt the user's password with the PHP 5.5's password_hash() function, results in a 60 character hash string // crypt the user's password with the PHP 5.5's password_hash() function, results in a 60 character hash string
// the PASSWORD_DEFAULT constant is defined by the PHP 5.5, or if you are using PHP 5.3/5.4, by the password hashing // the PASSWORD_DEFAULT constant is defined by the PHP 5.5,
// compatibility library. the third parameter looks a little bit shitty, but that's how those PHP 5.5 functions // or if you are using PHP 5.3/5.4, by the password hashing
// want the parameter: as an array with, currently only used with 'cost' => XX. // compatibility library. the third parameter looks a little bit shitty, but that's how those PHP 5.5 functions
$user_password_hash = password_hash($password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor)); // want the parameter: as an array with, currently only used with 'cost' => XX.
$user_password_hash = password_hash($password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor));
// write users new hash into database // write users new hash into database
$query_update = $this->db_connection->prepare('UPDATE '.PSM_DB_PREFIX.'users SET password = :user_password_hash, $query_update = $this->db_connection->prepare('UPDATE ' .
password_reset_hash = NULL, password_reset_timestamp = NULL PSM_DB_PREFIX . 'users SET password = :user_password_hash,
WHERE user_id = :user_id'); password_reset_hash = NULL, password_reset_timestamp = NULL
$query_update->bindValue(':user_password_hash', $user_password_hash, \PDO::PARAM_STR); WHERE user_id = :user_id');
$query_update->bindValue(':user_id', $user_id, \PDO::PARAM_STR); $query_update->bindValue(':user_password_hash', $user_password_hash, \PDO::PARAM_STR);
$query_update->execute(); $query_update->bindValue(':user_id', $user_id, \PDO::PARAM_STR);
$query_update->execute();
// check if exactly one row was successfully changed: // check if exactly one row was successfully changed:
if ($query_update->rowCount() == 1) { if ($query_update->rowCount() == 1) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
/** /**
* Gets the user id * Gets the user id
* @return int * @return int
*/ */
public function getUserId() { public function getUserId()
return $this->user_id; {
} return $this->user_id;
}
/** /**
* Gets the username * Gets the username
* @return string * @return string
*/ */
public function getUsername() { public function getUsername()
$user = $this->getUser(); {
return (isset($user->user_name) ? $user->user_name : null); $user = $this->getUser();
} return (isset($user->user_name) ? $user->user_name : null);
}
/** /**
* Gets the user level * Gets the user level
* @return int * @return int
*/ */
public function getUserLevel() { public function getUserLevel()
$user = $this->getUser(); {
$user = $this->getUser();
if (isset($user->level)) { if (isset($user->level)) {
return $user->level; return $user->level;
} else { } else {
return PSM_USER_ANONYMOUS; return PSM_USER_ANONYMOUS;
} }
} }
/** /**
* read current user preferences from the database * read current user preferences from the database
* @return boolean return false is user not connected * @return boolean return false is user not connected
*/ */
protected function loadPreferences() { protected function loadPreferences()
if ($this->user_preferences === null) { {
if (!$this->getUser()) { if ($this->user_preferences === null) {
return false; if (!$this->getUser()) {
} return false;
}
$this->user_preferences = array(); $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) { foreach (
$this->user_preferences[$row['key']] = $row['value']; $this->db_connection->query('SELECT `key`,`value` FROM `' .
} PSM_DB_PREFIX . 'users_preferences` WHERE `user_id` = ' . $this->user_id) as $row
} ) {
return true; $this->user_preferences[$row['key']] = $row['value'];
} }
}
return true;
}
/** /**
* Get a user preference value * Get a user preference value
* @param string $key * @param string $key
* @param mixed $default * @param mixed $default
* @return mixed * @return mixed
*/ */
public function getUserPref($key, $default = '') { public function getUserPref($key, $default = '')
if (!$this->loadPreferences() || !isset($this->user_preferences[$key])) { {
return $default; if (!$this->loadPreferences() || !isset($this->user_preferences[$key])) {
} return $default;
}
$value = $this->user_preferences[$key]; $value = $this->user_preferences[$key];
settype($value, gettype($default)); settype($value, gettype($default));
return $value; return $value;
} }
/** /**
* Set a user preference value * Set a user preference value
* @param string $key * @param string $key
* @param mixed $value * @param mixed $value
*/ */
public function setUserPref($key, $value) { public function setUserPref($key, $value)
if ($this->loadPreferences()) { {
if (isset($this->user_preferences[$key])) { if ($this->loadPreferences()) {
if ($this->user_preferences[$key] == $value) { if (isset($this->user_preferences[$key])) {
return; // no change if ($this->user_preferences[$key] == $value) {
} return; // no change
$sql = 'UPDATE `'.PSM_DB_PREFIX.'users_preferences` SET `key` = ?, `value` = ? WHERE `user_id` = ?'; }
} else { $sql = 'UPDATE `' . PSM_DB_PREFIX . 'users_preferences` SET `key` = ?, `value` = ? WHERE `user_id` = ?';
$sql = 'INSERT INTO `'.PSM_DB_PREFIX.'users_preferences` SET `key` = ?, `value` = ?, `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)); $sth = $this->db_connection->prepare($sql);
$this->user_preferences[$key] = $value; $sth->execute(array($key, $value, $this->user_id));
} $this->user_preferences[$key] = $value;
} }
}
/** /**
* Get session object * Get session object
* @return \Symfony\Component\HttpFoundation\Session\SessionInterface * @return \Symfony\Component\HttpFoundation\Session\SessionInterface
*/ */
public function getSession() { public function getSession()
return $this->session; {
} return $this->session;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,13 +18,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Axel Wehner <mail@axelwehner.de> * @author Axel Wehner <mail@axelwehner.de>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.2.1 * @since phpservermon 3.2.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
@ -36,195 +37,200 @@ namespace psm\Txtmsg;
* *
* Requirements: cURL v7.18.1+ and OpenSSL 0.9.8j+ * Requirements: cURL v7.18.1+ and OpenSSL 0.9.8j+
*/ */
class CMBulkSMS extends Core { class CMBulkSMS extends Core
/** @var bool True when cURL request succeeded */ {
public $result = true; /** @var bool True when cURL request succeeded */
public $result = true;
/** @var string Contains error message if cURL request failed */ /** @var string Contains error message if cURL request failed */
public $error = ''; public $error = '';
/** @var bool Set to true for debug output/logging */ /** @var bool Set to true for debug output/logging */
protected $debug = false; protected $debug = false;
/** @var bool Set to false if your operator isn't able to handle multipart messages */ /** @var bool Set to false if your operator isn't able to handle multipart messages */
protected $multipartMessage = true; protected $multipartMessage = true;
/** @var string|null Gateway API URL uses const GATEWAY_URL_XML or GATEWAY_URL_JSON */ /** @var string|null Gateway API URL uses const GATEWAY_URL_XML or GATEWAY_URL_JSON */
protected $apiUrl; protected $apiUrl;
/** @var string Gateway API Type: Use 'json' (default) or 'xml' */ /** @var string Gateway API Type: Use 'json' (default) or 'xml' */
protected $apiType = 'json'; protected $apiType = 'json';
/** @var string|null JSON or XML message for cURL request */ /** @var string|null JSON or XML message for cURL request */
protected $request; protected $request;
/** @var string|null HTTP Content-Type for cURL request */ /** @var string|null HTTP Content-Type for cURL request */
protected $contentType; protected $contentType;
/** @var string|null Raw sms text message */ /** @var string|null Raw sms text message */
protected $messageBody; protected $messageBody;
/** @var string JSON Gateway API URL */ /** @var string JSON Gateway API URL */
const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message"; public const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message";
/** @var string XML Gateway API URL */ /** @var string XML Gateway API URL */
const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx"; public const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx";
/** /**
* Build the message and send cURL request to the sms gateway * Build the message and send cURL request to the sms gateway
* *
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests
* @param string $message Your text message * @param string $message Your text message
* @return bool|string true when cURL request was successful, otherwise string with error message * @return bool|string true when cURL request was successful, otherwise string with error message
*/ */
public function sendSMS($message) { public function sendSMS($message)
// Check if recipient and text message are available {
if (count($this->recipients) < 1 || empty($message)) { // Check if recipient and text message are available
return false; if (count($this->recipients) < 1 || empty($message)) {
} return false;
}
// Prepare the message in CM's XML or JSON format // Prepare the message in CM's XML or JSON format
switch ($this->apiType) { switch ($this->apiType) {
case 'xml': case 'xml':
$this->request = $this->buildMessageXml(); $this->request = $this->buildMessageXml();
$this->contentType = 'Content-Type: application/xml'; $this->contentType = 'Content-Type: application/xml';
$this->apiUrl = self::GATEWAY_URL_XML; $this->apiUrl = self::GATEWAY_URL_XML;
break; break;
case 'json': case 'json':
default: default:
$this->request = $this->buildMessageJson(); $this->request = $this->buildMessageJson();
$this->contentType = 'Content-Type: application/json'; $this->contentType = 'Content-Type: application/json';
$this->apiUrl = self::GATEWAY_URL_JSON; $this->apiUrl = self::GATEWAY_URL_JSON;
break; break;
} }
$request = $this->executeCurlRequest(); $request = $this->executeCurlRequest();
return $request; return $request;
} }
/** /**
* Create a JSON batch sms message using CM's format * Create a JSON batch sms message using CM's format
* *
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cbatch_messages * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cbatch_messages
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cmultipart * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cmultipart
* @return string JSON message object * @return string JSON message object
*/ */
protected function buildMessageJson() { protected function buildMessageJson()
// Prepare recipient array for batch message {
$recipients = array(); // Prepare recipient array for batch message
foreach ($this->recipients as $recipient) { $recipients = array();
$recipients[] = array('number' => $recipient); foreach ($this->recipients as $recipient) {
} $recipients[] = array('number' => $recipient);
}
// Build message array in CM's Bulk SMS format // Build message array in CM's Bulk SMS format
$msgArray = array( $msgArray = array(
'messages' => array( 'messages' => array(
'authentication' => array( 'authentication' => array(
'producttoken' => $this->password 'producttoken' => $this->password
), ),
'msg' => array( 'msg' => array(
array( array(
'from' => substr($this->originator, 0, 11), 'from' => substr($this->originator, 0, 11),
'to' => $recipients, 'to' => $recipients,
'body' => array( 'body' => array(
'content' => $message 'content' => $message
) )
) )
) )
) )
); );
// Multipart message // Multipart message
if ($this->multipartMessage) { if ($this->multipartMessage) {
$msgArray['messages']['msg'][0]['minimumNumberOfMessageParts'] = 1; $msgArray['messages']['msg'][0]['minimumNumberOfMessageParts'] = 1;
$msgArray['messages']['msg'][0]['maximumNumberOfMessageParts'] = 8; $msgArray['messages']['msg'][0]['maximumNumberOfMessageParts'] = 8;
} }
// Convert array in JSON object // Convert array in JSON object
return json_encode($msgArray); return json_encode($msgArray);
} }
/** /**
* Create a XML batch sms message in CM's format * Create a XML batch sms message in CM's format
* *
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cbatch_messages * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cbatch_messages
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Csample_requests
* @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cmultipart * @see https://docs.cmtelecom.com/bulk-sms/v1.0#/send_a_message%7Cmultipart
* @return string XML message * @return string XML message
*/ */
protected function buildMessageXml() { protected function buildMessageXml()
// Create XML string {
$xml = new \SimpleXMLElement('<MESSAGES/>'); // Create XML string
$xml = new \SimpleXMLElement('<MESSAGES/>');
// API-Token // API-Token
$auth = $xml->addChild('AUTHENTICATION'); $auth = $xml->addChild('AUTHENTICATION');
$auth->addChild('PRODUCTTOKEN', $this->password); $auth->addChild('PRODUCTTOKEN', $this->password);
// Message // Message
$msg = $xml->addChild('MSG'); $msg = $xml->addChild('MSG');
// From // From
$msg->addChild('FROM', substr($this->originator, 0, 11)); $msg->addChild('FROM', substr($this->originator, 0, 11));
// Recipients // Recipients
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$msg->addChild('TO', $recipient); $msg->addChild('TO', $recipient);
} }
// Multipart message // Multipart message
if ($this->multipartMessage) { if ($this->multipartMessage) {
$msg->addChild('MINIMUMNUMBEROFMESSAGEPARTS', 1); $msg->addChild('MINIMUMNUMBEROFMESSAGEPARTS', 1);
$msg->addChild('MAXIMUMNUMBEROFMESSAGEPARTS', 8); $msg->addChild('MAXIMUMNUMBEROFMESSAGEPARTS', 8);
} }
// Add body text // Add body text
$msg->addChild('BODY', $message); $msg->addChild('BODY', $message);
return $xml->asXML(); return $xml->asXML();
} }
/** /**
* Create and execute the curl request * Create and execute the curl request
* *
* @return boolean|string boolean if message is sent, else string * @return boolean|string boolean if message is sent, else string
*/ */
protected function executeCurlRequest() { protected function executeCurlRequest()
$cr = curl_init(); {
curl_setopt_array($cr, array( $cr = curl_init();
CURLOPT_URL => $this->apiUrl, curl_setopt_array($cr, array(
CURLOPT_HTTPHEADER => array($this->contentType), CURLOPT_URL => $this->apiUrl,
CURLOPT_POST => true, CURLOPT_HTTPHEADER => array($this->contentType),
CURLOPT_POSTFIELDS => $this->request, CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => $this->request,
CURLOPT_FAILONERROR => true CURLOPT_RETURNTRANSFER => true,
) CURLOPT_FAILONERROR => true
); ));
// execute curl request and fetch the response/error // execute curl request and fetch the response/error
$cResponse = curl_exec($cr); $cResponse = curl_exec($cr);
$cError = curl_error($cr); $cError = curl_error($cr);
$cErrorCode = curl_errno($cr); $cErrorCode = curl_errno($cr);
curl_close($cr); curl_close($cr);
// set result and log error if needed // set result and log error if needed
if ($cError) { if ($cError) {
$this->error = 'Response: CM SMS API:'.$cResponse.' cURL Error Code: '.$cErrorCode.'"'.$cError.'"'; $this->error = 'Response: CM SMS API:' . $cResponse . ' cURL Error Code: ' .
error_log($this->error, E_USER_ERROR); $cErrorCode . '"' . $cError . '"';
$this->result = false; error_log($this->error, E_USER_ERROR);
} $this->result = false;
}
// Debug output // Debug output
// Note: CM's XML gateway gives no response when message is sent successfully :/ // Note: CM's XML gateway gives no response when message is sent successfully :/
if ($this->debug || PSM_DEBUG) { if ($this->debug || PSM_DEBUG) {
$debug = '<pre>Request: '.$this->request.'<br>Response: '.$cResponse.'</pre>'; $debug = '<pre>Request: ' . $this->request . '<br>Response: ' . $cResponse . '</pre>';
error_log("Request: $this->request\r\nResponse: $cResponse", E_USER_NOTICE); error_log("Request: $this->request\r\nResponse: $cResponse", E_USER_NOTICE);
echo $debug; echo $debug;
} }
return $this->result ? $this->result : $this->error; return $this->result ? $this->result : $this->error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,81 +18,84 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.3.0 * @since phpservermon 3.3.0
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Callr extends Core { class Callr extends Core
{
/** /**
* Send sms using the Callr API * Send sms using the Callr API
* *
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator * @var array $this->originator
* @var string $recipient * @var string $recipient
* *
* @var mixed $result * @var mixed $result
* @var array $headers * @var array $headers
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
foreach ($this->recipients as $recipient) {
$curl = curl_init(); foreach ($this->recipients as $recipient) {
curl_setopt_array($curl, array( $curl = curl_init();
CURLOPT_URL => "https://api.callr.com/rest/v1.1/sms", curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => "https://api.callr.com/rest/v1.1/sms",
CURLOPT_MAXREDIRS => 10, CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30, CURLOPT_MAXREDIRS => 10,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_TIMEOUT => 30,
CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_POSTFIELDS => json_encode( CURLOPT_CUSTOMREQUEST => "POST",
array( CURLOPT_POSTFIELDS => json_encode(
"to" => $recipient, array(
"from" => $this->originator, "to" => $recipient,
"body" => urlencode($message), "from" => $this->originator,
"options" => null, "body" => urlencode($message),
) "options" => null,
), )
CURLOPT_HTTPHEADER => array( ),
"authorization: Basic ".base64_encode($this->username.":".$this->password), CURLOPT_HTTPHEADER => array(
"content-type: application/json" "authorization: Basic " . base64_encode($this->username . ":" . $this->password),
), "content-type: application/json"
)); ),
));
$result = json_decode(curl_exec($curl), true);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $result = json_decode(curl_exec($curl), true);
$err = curl_errno($curl); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $result['status'] == "error") { if ($err != 0 || $httpcode != 200 || $result['status'] == "error") {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". Result: ".$result['data']['code']." - ".$result['data']['message']; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . curl_strerror($err) .
} ". Result: " . $result['data']['code'] . " - " . $result['data']['message'];
curl_close($curl); }
} curl_close($curl);
if ($success) { }
return 1; if ($success) {
} return 1;
return $error; }
} return $error;
} }
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,74 +29,80 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
class ClickSend extends Core { class ClickSend extends Core
{
/**
* Send sms using the SMSgw.NET API /**
* * Send sms using the SMSgw.NET API
* @var string $message *
* @var string $this->password * @var string $message
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* @var string $recipients * @var array $this->originator
* * @var string $recipients
* @var resource $curl *
* @var string $err * @var resource $curl
* @var mixed $result * @var string $err
* * @var mixed $result
* @var int $success *
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$error = ""; public function sendSMS($message)
$success = 1; {
$error = "";
if (empty($this->recipients)) { $success = 1;
return false;
} if (empty($this->recipients)) {
return false;
$data = array('messages' => array()); }
foreach ($this->recipients as $recipient) {
$data['messages'][] = array( $data = array('messages' => array());
'source' => 'phpservermon', foreach ($this->recipients as $recipient) {
'from' => substr($this->originator, 0, 11), $data['messages'][] = array(
'to' => $recipient, 'source' => 'phpservermon',
'body' => $message, 'from' => substr($this->originator, 0, 11),
); 'to' => $recipient,
} 'body' => $message,
);
$curl = curl_init(); }
curl_setopt_array($curl, array(
CURLOPT_URL => "https://rest.clicksend.com/v3/sms/send", $curl = curl_init();
CURLOPT_RETURNTRANSFER => true, curl_setopt_array($curl, array(
CURLOPT_ENCODING => "", CURLOPT_URL => "https://rest.clicksend.com/v3/sms/send",
CURLOPT_MAXREDIRS => 10, CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30, CURLOPT_ENCODING => "",
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_MAXREDIRS => 10,
CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_TIMEOUT => 30,
CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPHEADER => array( CURLOPT_CUSTOMREQUEST => "POST",
"authorization: Basic ".base64_encode($this->username.":".$this->password), CURLOPT_POSTFIELDS => json_encode($data),
"content-type: application/json" CURLOPT_HTTPHEADER => array(
), "authorization: Basic " . base64_encode($this->username . ":" . $this->password),
)); "content-type: application/json"
),
$result = json_decode(curl_exec($curl), true); ));
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $result = json_decode(curl_exec($curl), true);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($err != 0 || ($httpcode != '200' && $httpcode != '201' && $httpcode != '202' && $result['response_code'] != "SUCCESS")) { $err = curl_errno($curl);
$success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". Result: ".$result.""; if (
} $err != 0 ||
curl_close($curl); ($httpcode != '200' && $httpcode != '201' && $httpcode != '202' && $result['response_code'] != "SUCCESS")
) {
if ($success) { $success = 0;
return 1; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
} curl_strerror($err) . ". Result: " . $result . "";
return $error; }
} curl_close($curl);
}
if ($success) {
return 1;
}
return $error;
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,55 +18,58 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Pepijn Over <pep@mailbox.org> * @author Pepijn Over <pep@mailbox.org>
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2018 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2018 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link https://www.phpservermonitor.org/ * @link https://www.phpservermonitor.org/
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Clickatell extends Core { class Clickatell extends Core
{
/** /**
* Send sms using the Clickatell API * Send sms using the Clickatell API
* @var string $message * @var string $message
* @var array $this->recipients * @var array $this->recipients
* @var string $recipient * @var string $recipient
* @var string $this->password * @var string $this->password
* @var string $this->originator * @var string $this->originator
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$success = 1; {
$error = ''; $success = 1;
foreach ($this->recipients as $recipient) { $error = '';
$ch = curl_init(); foreach ($this->recipients as $recipient) {
curl_setopt($ch, CURLOPT_URL, "https://platform.clickatell.com/messages/http/send?apiKey=".urlencode($this->password)."&to=".urlencode($recipient)."&content=".urlencode($message)); $ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, "https://platform.clickatell.com/messages/http/send?apiKey=" .
$headers = array(); urlencode($this->password) . "&to=" . urlencode($recipient) . "&content=" . urlencode($message));
$headers[] = "Content-Type: application/x-www-form-urlencoded"; curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $headers = array();
$result = curl_exec($ch); $headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_close($ch); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
// Check on error // Check on error
if (strpos($result, ",\"errorCode\":null,\"error\":null,\"errorDescription\":null") === False) { if (strpos($result, ",\"errorCode\":null,\"error\":null,\"errorDescription\":null") === false) {
$error = $result; $error = $result;
$success = 0; $success = 0;
} }
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,38 +28,42 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
abstract class Core implements TxtmsgInterface { abstract class Core implements TxtmsgInterface
protected $originator; {
protected $password; protected $originator;
protected $recipients = array(); protected $password;
protected $username; protected $recipients = array();
protected $username;
/** /**
* Define login information for the gateway * Define login information for the gateway
* *
* @param string $username * @param string $username
* @param string $password * @param string $password
*/ */
public function setLogin($username, $password) { public function setLogin($username, $password)
$this->username = $username; {
$this->password = $password; $this->username = $username;
} $this->password = $password;
}
/** /**
* Set the mobile number the text message will be send from * Set the mobile number the text message will be send from
* *
* @param string $originator * @param string $originator
*/ */
public function setOriginator($originator) { public function setOriginator($originator)
$this->originator = $originator; {
} $this->originator = $originator;
}
/** /**
* Add new recipient to the list * Add new recipient to the list
* *
* @param string|int $recipient * @param string|int $recipient
*/ */
public function addRecipients($recipient) { public function addRecipients($recipient)
array_push($this->recipients, $recipient); {
} array_push($this->recipients, $recipient);
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,52 +28,53 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
class FreeMobileSMS extends Core { class FreeMobileSMS extends Core
{
/**
* Send sms using the FreeMobileSMS API /**
* * Send sms using the FreeMobileSMS API
* @var string $message *
* @var string $this->password * @var string $message
* @var string $this->username * @var string $this->password
* * @var string $this->username
* @var resource $curl *
* @var string $err * @var resource $curl
* @var int $success * @var string $err
* @var string $error * @var int $success
* @var string $http_code * @var string $error
* * @var string $http_code
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$success = 1; public function sendSMS($message)
$error = ""; {
$success = 1;
$curl = curl_init(); $error = "";
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "https://smsapi.free-mobile.fr/sendmsg?".http_build_query( $curl = curl_init();
array( curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
"user" => $this->username, curl_setopt($curl, CURLOPT_URL, "https://smsapi.free-mobile.fr/sendmsg?" . http_build_query(
"pass" => $this->password, array(
"msg" => urlencode($message), "user" => $this->username,
) "pass" => $this->password,
) "msg" => urlencode($message),
); )
));
$result = curl_exec($curl); $result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $err = curl_errno($curl);
if ($err != 0 || $httpcode != 200) { if ($err != 0 || $httpcode != 200) {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err); $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . curl_strerror($err);
} }
curl_close($curl); curl_close($curl);
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,71 +18,71 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.1 * @since phpservermon 3.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class FreeVoipDeal extends Core { class FreeVoipDeal extends Core
{
/**
* Send sms using the FreeVoipDeal API /**
* @var string $message * Send sms using the FreeVoipDeal API
* @var string $this->password * @var string $message
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* * @var array $this->originator
* @var resource $curl *
* @var string $err * @var resource $curl
* @var string $recipient * @var string $err
* @var string $from * @var string $recipient
* @var mixed $result * @var string $from
* @var int $success * @var mixed $result
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$error = ""; public function sendSMS($message)
$success = 1; {
$error = "";
$message = rawurlencode($message); $success = 1;
foreach ($this->recipients as $recipient) { $message = rawurlencode($message);
$curl = curl_init(); foreach ($this->recipients as $recipient) {
curl_setopt($curl, CURLOPT_URL, "https://www.freevoipdeal.com/myaccount/sendsms.php?".http_build_query( $curl = curl_init();
array( curl_setopt($curl, CURLOPT_URL, "https://www.freevoipdeal.com/myaccount/sendsms.php?" . http_build_query(
"username" => $this->username, array(
"password" => $this->password, "username" => $this->username,
"from" => substr($this->originator, 0, 11), "password" => $this->password,
"to" => $recipient, "from" => substr($this->originator, 0, 11),
"text" => $message, "to" => $recipient,
) "text" => $message,
) )
); ));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl); $result = curl_exec($curl);
$err = curl_errno($curl); $err = curl_errno($curl);
curl_close($curl); curl_close($curl);
if ($err != 0 || is_numeric(strpos($result, "failure"))) { if ($err != 0 || is_numeric(strpos($result, "failure"))) {
$success = 0; $success = 0;
$error = $result; $error = $result;
} }
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,76 +18,78 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.3.0 * @since phpservermon 3.3.0
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class GatewayAPI extends Core { class GatewayAPI extends Core
{
/** /**
* Send sms using the GatewayAPI API * Send sms using the GatewayAPI API
* *
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator * @var array $this->originator
* @var string $recipient * @var string $recipient
* @var mixed $result * @var mixed $result
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
if (empty($this->recipients)) { if (empty($this->recipients)) {
return false; return false;
} }
$json = [ $json = [
'sender' => isset($this->originator) ? $this->originator : "PHPServerMon", 'sender' => isset($this->originator) ? $this->originator : "PHPServerMon",
'message' => $message, 'message' => $message,
'recipients' => [], 'recipients' => [],
]; ];
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$json['recipients'][] = ['msisdn' => $recipient]; $json['recipients'][] = ['msisdn' => $recipient];
} }
$curl = curl_init(); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://gatewayapi.com/rest/mtsms"); curl_setopt($curl, CURLOPT_URL, "https://gatewayapi.com/rest/mtsms");
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json")); curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_setopt($curl, CURLOPT_USERPWD, $this->password.":"); curl_setopt($curl, CURLOPT_USERPWD, $this->password . ":");
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($json)); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($json));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($curl), true); $result = json_decode(curl_exec($curl), true);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $err = curl_errno($curl);
curl_close($curl); curl_close($curl);
if ($err != 0 || $httpcode != 200) { if ($err != 0 || $httpcode != 200) {
$success = 0; $success = 0;
$error = $result['code']." - ".$result['message']; $error = $result['code'] . " - " . $result['message'];
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,82 +18,85 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Inetworx extends Core { class Inetworx extends Core
{
/** /**
* Send sms using the Inetworx API * Send sms using the Inetworx API
* *
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator * @var array $this->originator
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* @var string $recipient * @var string $recipient
* @var mixed $result * @var mixed $result
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$curl = curl_init(); $curl = curl_init();
curl_setopt_array($curl, array( curl_setopt_array($curl, array(
CURLOPT_URL => "https://sms.inetworx.ch/smsapp/sendsms.php", CURLOPT_URL => "https://sms.inetworx.ch/smsapp/sendsms.php",
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "", CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10, CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30, CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => http_build_query( CURLOPT_POSTFIELDS => http_build_query(
array( array(
"user" => $this->username, "user" => $this->username,
"pass" => $this->password, "pass" => $this->password,
"sender" => $this->originator, "sender" => $this->originator,
"rcpt" => $recipient, "rcpt" => $recipient,
"msgbody" => $message, "msgbody" => $message,
) )
), ),
CURLOPT_HTTPHEADER => array( CURLOPT_HTTPHEADER => array(
"authorization: Basic ".base64_encode("inetworxag:conn2smsapp"), "authorization: Basic " . base64_encode("inetworxag:conn2smsapp"),
"content-type: application/x-www-form-urlencoded" "content-type: application/x-www-form-urlencoded"
), ),
)); ));
$result = curl_exec($curl); $result = curl_exec($curl);
$err = curl_errno($curl); $err = curl_errno($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($err != 0 || $httpcode != 200 || strpos($result, "200") === false) { if ($err != 0 || $httpcode != 200 || strpos($result, "200") === false) {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$result; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
} curl_strerror($err) . ". \nResult: " . $result;
curl_close($curl); }
} curl_close($curl);
}
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -29,57 +30,62 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Messagebird extends Core { class Messagebird extends Core
{
/** /**
* Send sms using the Messagebird API * Send sms using the Messagebird API
* @var string $message * @var string $message
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator (Max 11 characters) * @var array $this->originator (Max 11 characters)
* @var array $recipients_chunk * @var array $recipients_chunk
* @var string $this->password * @var string $this->password
* *
* @var mixed $result * @var mixed $result
* @var array $headers * @var array $headers
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$success = 1; {
$error = ''; $success = 1;
$error = '';
// Maximum of 50 users a time. // Maximum of 50 users a time.
$recipients_chunk = array_chunk($this->recipients, ceil(count($this->recipients) / 50)); $recipients_chunk = array_chunk($this->recipients, ceil(count($this->recipients) / 50));
foreach ($recipients_chunk as $recipients) { foreach ($recipients_chunk as $recipients) {
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://rest.messagebird.com/messages"); curl_setopt($ch, CURLOPT_URL, "https://rest.messagebird.com/messages");
curl_setopt($ch, CURLOPT_POSTFIELDS, curl_setopt(
"originator=".urlencode($this->originator == '' ? 'PSM' : $this->originator). $ch,
"&body=".urlencode($message). CURLOPT_POSTFIELDS,
"&recipients=".implode(",", $recipients)); "originator=" . urlencode($this->originator == '' ? 'PSM' : $this->originator) .
curl_setopt($ch, CURLOPT_POST, 1); "&body=" . urlencode($message) .
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); "&recipients=" . implode(",", $recipients)
$headers = array(); );
$headers[] = "Authorization: AccessKey ".$this->password; curl_setopt($ch, CURLOPT_POST, 1);
$headers[] = "Content-Type: application/x-www-form-urlencoded"; curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $headers = array();
$result = curl_exec($ch); $headers[] = "Authorization: AccessKey " . $this->password;
curl_close($ch); $headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
// Check on error // Check on error
if (is_numeric(strpos($result, "{\"errors\":"))) { if (is_numeric(strpos($result, "{\"errors\":"))) {
$error = $result; $error = $result;
$success = 0; $success = 0;
} }
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,74 +18,73 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 2.1 * @since phpservermon 2.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Mosms extends Core { class Mosms extends Core
{
/** /**
* Send sms using the Mosms API * Send sms using the Mosms API
* *
* @var string $message * @var string $message
* @var array $this->username * @var array $this->username
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var string $recipient * @var string $recipient
* @var array $this->originator (Max 11 characters) * @var array $this->originator (Max 11 characters)
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
$message = rawurlencode($message);
$message = rawurlencode($message);
foreach ($this->recipients as $recipient) {
foreach ($this->recipients as $recipient) {
$curl = curl_init(); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://www.mosms.com/se/sms-send.php?".http_build_query( curl_setopt($curl, CURLOPT_URL, "https://www.mosms.com/se/sms-send.php?" . http_build_query(
array( array(
"username" => $this->username, "username" => $this->username,
"password" => $this->password, "password" => $this->password,
"customsender" => substr($this->originator, 0, 11), "customsender" => substr($this->originator, 0, 11),
"nr" => $recipient, "nr" => $recipient,
"type" => "text", "type" => "text",
"data" => $message, "data" => $message,
) )
) ));
); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$result = curl_exec($curl);
$result = curl_exec($curl); $err = curl_errno($curl);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $result == 2 || $result == 5) {
if ($err != 0 || $httpcode != 200 || $result == 2 || $result == 5) { $success = 0;
$success = 0; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . $err . ". \nResult: " . $result;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".$err.". \nResult: ".$result; }
} curl_close($curl);
curl_close($curl); }
} if ($success) {
return 1;
if ($success) { }
return 1; return $error;
} }
return $error; }
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,73 +18,73 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.1.1 * @since phpservermon 3.1.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Nexmo extends Core { class Nexmo extends Core
{
/**
* Send sms using the GatewayAPI API /**
* * Send sms using the GatewayAPI API
* @var string $message *
* @var string $this->password * @var string $message
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* @var string $recipient * @var array $this->originator
* * @var string $recipient
* @var resource $curl *
* @var string $err * @var resource $curl
* @var mixed $result * @var string $err
* * @var mixed $result
* @var int $success *
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$success = 1; public function sendSMS($message)
$error = ""; {
$success = 1;
$error = "";
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$curl = curl_init();
$curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_URL, "https://rest.nexmo.com/sms/json?" . http_build_query(
curl_setopt($curl, CURLOPT_URL, "https://rest.nexmo.com/sms/json?".http_build_query( array(
array( "api_key" => $this->username,
"api_key" => $this->username, "api_secret" => $this->password,
"api_secret" => $this->password, "from" => $this->originator,
"from" => $this->originator, "to" => $recipient,
"to" => $recipient, "text" => $message,
"text" => $message, )
) ));
)
); $result = json_decode(curl_exec($curl), true);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$result = json_decode(curl_exec($curl), true); $err = curl_errno($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); if ($err != 0 || $httpcode != 200 || $result['messages'][0]['status'] != "0") {
$success = 0;
if ($err != 0 || $httpcode != 200 || $result['messages'][0]['status'] != "0") { $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . curl_strerror($err) .
$success = 0; ". \nResult: " . $result['messages'][0]['error-text'];
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$result['messages'][0]['error-text']; }
} curl_close($curl);
curl_close($curl); }
} if ($success) {
return 1;
if ($success) { }
return 1; return $error;
} }
return $error; }
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,79 +18,82 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Alexis Urien <Alexis.urien@free.fr> * @author Alexis Urien <Alexis.urien@free.fr>
* @Author Tim Zandbergen <Tim@Xervion.nl> * @Author Tim Zandbergen <Tim@Xervion.nl>
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2016 Alexis Urien <alexis.urien@free.fr> * @copyright Copyright (c) 2016 Alexis Urien <alexis.urien@free.fr>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 2.1 * @since phpservermon 2.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Octopush extends Core { class Octopush extends Core
{
/**
* Send sms using the Octopush API /**
* @var string $message * Send sms using the Octopush API
* @var string $this->username * @var string $message
* @var string $this->password * @var string $this->username
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* * @var array $this->originator
* @var resource $curl *
* @var SimpleXMLElement $xmlResults * @var resource $curl
* @var string $err * @var SimpleXMLElement $xmlResults
* @var string $recipient * @var string $err
* @var string $smsType * @var string $recipient
* @var mixed $result * @var string $smsType
* * @var mixed $result
* @var int $success *
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$error = ""; public function sendSMS($message)
$success = 1; {
$smsType = "XXX"; //FR = premium, WWW = world, XXX = Low cost $error = "";
$success = 1;
$recipients = join(',', $this->recipients); $smsType = "XXX"; //FR = premium, WWW = world, XXX = Low cost
$message = ($smsType == "FR") ? urlencode($message." STOP au XXXX") : urlencode($message); $recipients = join(',', $this->recipients);
$message = ($smsType == "FR") ? urlencode($message . " STOP au XXXX") : urlencode($message);
$curl = curl_init(); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://www.octopush-dm.com/api/sms/?".http_build_query( curl_setopt($curl, CURLOPT_URL, "http://www.octopush-dm.com/api/sms/?" . http_build_query(
array( array(
"user_login" => $this->username, "user_login" => $this->username,
"api_key" => $this->password, "api_key" => $this->password,
"sms_recipients" => $recipients, "sms_recipients" => $recipients,
"sms_type" => $smsType, "sms_type" => $smsType,
"sms_sender" => substr($this->originator, 0, 11), "sms_sender" => substr($this->originator, 0, 11),
"sms_text" => $message, "sms_text" => $message,
) )
) ));
); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$result = curl_exec($curl); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $xmlResults = simplexml_load_string($result);
$xmlResults = simplexml_load_string($result); $err = curl_errno($curl);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $xmlResults === false || $xmlResults->error_code != '000') { if ($err != 0 || $httpcode != 200 || $xmlResults === false || $xmlResults->error_code != '000') {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$xmlResults->error_code.". Look at http://www.octopush-dm.com/en/errors for the error description."; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " . curl_strerror($err) .
} ". \nResult: " . $xmlResults->error_code .
curl_close($curl); ". Look at http://www.octopush-dm.com/en/errors for the error description.";
}
if ($success) { curl_close($curl);
return 1;
} if ($success) {
return $error; return 1;
} }
} return $error;
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,82 +18,85 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.3.0 * @since phpservermon 3.3.0
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Plivo extends Core { class Plivo extends Core
{
/**
* Send sms using the Plivo API /**
* * Send sms using the Plivo API
* @var string $message *
* @var string $this->password * @var string $message
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* @var string $recipients * @var array $this->originator
* * @var string $recipients
* @var resource $curl *
* @var string $err * @var resource $curl
* @var int $success * @var string $err
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$error = ""; public function sendSMS($message)
$success = 1; {
$error = "";
if (empty($this->recipients)) { $success = 1;
return false;
} if (empty($this->recipients)) {
return false;
$recipients = join('<', $this->recipients); }
$curl = curl_init(); $recipients = join('<', $this->recipients);
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.plivo.com/v1/Account/".$this->username."/Message/", $curl = curl_init();
CURLOPT_RETURNTRANSFER => true, curl_setopt_array($curl, array(
CURLOPT_ENCODING => "", CURLOPT_URL => "https://api.plivo.com/v1/Account/" . $this->username . "/Message/",
CURLOPT_MAXREDIRS => 10, CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30, CURLOPT_ENCODING => "",
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_MAXREDIRS => 10,
CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_TIMEOUT => 30,
CURLOPT_POSTFIELDS => json_encode( CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
array( CURLOPT_CUSTOMREQUEST => "POST",
"src" => $this->originator, CURLOPT_POSTFIELDS => json_encode(
"dst" => $recipients, array(
"text" => urlencode($message) "src" => $this->originator,
) "dst" => $recipients,
), "text" => urlencode($message)
CURLOPT_HTTPHEADER => array( )
"authorization: Basic ".base64_encode($this->username.":".$this->password), ),
"content-type: application/json" CURLOPT_HTTPHEADER => array(
), "authorization: Basic " . base64_encode($this->username . ":" . $this->password),
)); "content-type: application/json"
),
$result = curl_exec($curl); ));
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($err != 0 || ($httpcode != '200' && $httpcode != '201' && $httpcode != '202')) { $err = curl_errno($curl);
$success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". Result: ".$result.""; if ($err != 0 || ($httpcode != '200' && $httpcode != '201' && $httpcode != '202')) {
} $success = 0;
curl_close($curl); $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_strerror($err) . ". Result: " . $result . "";
if ($success) { }
return 1; curl_close($curl);
}
return $error; if ($success) {
} return 1;
} }
return $error;
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,77 +18,80 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.1 * @since phpservermon 3.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Smsglobal extends Core { class Smsglobal extends Core
{
/** /**
* Send sms using the Smsglobal API * Send sms using the Smsglobal API
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator * @var array $this->originator
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* @var string $recipient * @var string $recipient
* @var string $from * @var string $from
* @var mixed $result * @var mixed $result
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
$recipients = join(',', $this->recipients);
$recipients = join(',', $this->recipients);
$from = substr($this->originator, 0, 11); // Max 11 Characters
$message = substr(rawurlencode($message), 0, 153); $from = substr($this->originator, 0, 11); // Max 11 Characters
$message = substr(rawurlencode($message), 0, 153);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $curl = curl_init();
curl_setopt($curl, CURLOPT_TIMEOUT, 30); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "https://www.smsglobal.com/http-api.php?".http_build_query( curl_setopt($curl, CURLOPT_TIMEOUT, 30);
array( curl_setopt($curl, CURLOPT_URL, "https://www.smsglobal.com/http-api.php?" . http_build_query(
"action" => "sendsms", array(
"user" => $this->username, "action" => "sendsms",
"password" => $this->password, "user" => $this->username,
"from" => $from, "password" => $this->password,
"to" => $recipients, "from" => $from,
"clientcharset" => "ISO-8859-1", "to" => $recipients,
"text" => $message, "clientcharset" => "ISO-8859-1",
) "text" => $message,
)); )
));
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
$err = curl_errno($curl);
if ($err != 0 || substr($result, 0, 5) != "OK: 0") {
$success = 0; if ($err != 0 || substr($result, 0, 5) != "OK: 0") {
$result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$result; $result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result;
} $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_close($curl); curl_strerror($err) . ". \nResult: " . $result;
}
if ($success) { curl_close($curl);
return 1;
} if ($success) {
return $error; return 1;
} }
} return $error;
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -29,62 +30,65 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Smsgw extends Core { class Smsgw extends Core
{
/** /**
* Send sms using the SMSgw.NET API * Send sms using the SMSgw.NET API
* *
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var array $this->originator * @var array $this->originator
* @var string $recipients * @var string $recipients
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
$recipients = join(';', $this->recipients); $recipients = join(';', $this->recipients);
$curl = curl_init(); $curl = curl_init();
curl_setopt_array($curl, array( curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.smsgw.net/SendBulkSMS", CURLOPT_URL => "https://api.smsgw.net/SendBulkSMS",
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "", CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10, CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30, CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array( CURLOPT_POSTFIELDS => array(
'strUserName' => $this->username, 'strUserName' => $this->username,
'strPassword' => $this->password, 'strPassword' => $this->password,
"strTagName" => $this->originator, "strTagName" => $this->originator,
"strRecepientNumbers" => $recipients, "strRecepientNumbers" => $recipients,
"strMessage" => urlencode($message), "strMessage" => urlencode($message),
), ),
)); ));
$result = curl_exec($curl); $result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $err = curl_errno($curl);
if ($err != 0 || ($httpcode != '200' && $httpcode != '201' && $httpcode != '202' && $result != "1")) { if ($err != 0 || ($httpcode != '200' && $httpcode != '201' && $httpcode != '202' && $result != "1")) {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". Result: ".$result.""; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
} curl_strerror($err) . ". Result: " . $result . "";
curl_close($curl); }
curl_close($curl);
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,69 +18,69 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.1 * @since phpservermon 3.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Smsit extends Core { class Smsit extends Core
{
/**
* Send sms using the Smsit API /**
* * Send sms using the Smsit API
* @var string $message *
* @var string $this->password * @var string $message
* @var array $this->recipients * @var string $this->password
* @var array $this->originator * @var array $this->recipients
* * @var array $this->originator
* @var resource $curl *
* @var string $err * @var resource $curl
* @var String $recipient * @var string $err
* @var mixed $result * @var String $recipient
* * @var mixed $result
* @var int $success *
* @var string $error * @var int $success
* * @var string $error
* @return bool|string *
*/ * @return bool|string
*/
public function sendSMS($message) {
$success = 1; public function sendSMS($message)
$error = ""; {
$success = 1;
foreach ($this->recipients as $recipient) { $error = "";
$curl = curl_init(); foreach ($this->recipients as $recipient) {
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://www.smsit.dk/api/v2?".http_build_query( curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
array( curl_setopt($curl, CURLOPT_URL, "https://www.smsit.dk/api/v2?" . http_build_query(
"apiKey" => $this->password, array(
"mobile" => $recipient, "apiKey" => $this->password,
"message" => urlencode($message), "mobile" => $recipient,
"senderId" => substr($this->originator, 0, 11), "message" => urlencode($message),
) "senderId" => substr($this->originator, 0, 11),
) )
); ));
$result = curl_exec($curl); $result = curl_exec($curl);
$err = curl_errno($curl); $err = curl_errno($curl);
curl_close($curl); curl_close($curl);
if ($err != 0 || is_numeric(strpos($result, "{\"errors\":[{\"code\":"))) { if ($err != 0 || is_numeric(strpos($result, "{\"errors\":[{\"code\":"))) {
$success = 0; $success = 0;
$error = $result; $error = $result;
} }
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,72 +18,74 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Ward Pieters <ward@wardpieters.nl> * @author Ward Pieters <ward@wardpieters.nl>
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 3.3.0 * @since phpservermon 3.3.0
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class SolutionsInfini extends Core { class SolutionsInfini extends Core
{
/** /**
* Send sms using the SolutionsInfini API * Send sms using the SolutionsInfini API
* *
* @var string $message * @var string $message
* @var string $this->password * @var string $this->password
* @var array $this->recipients * @var array $this->recipients
* @var string $recipients * @var string $recipients
* @var array $this->originator (Max 11 characters) * @var array $this->originator (Max 11 characters)
* *
* @var resource $curl * @var resource $curl
* @var string $err * @var string $err
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$error = ""; {
$success = 1; $error = "";
$success = 1;
$message = urlencode($message); $message = urlencode($message);
$recipients = join(',', $this->recipients); $recipients = join(',', $this->recipients);
$curl = curl_init(); $curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://api-alerts.solutionsinfini.com/v4/?".http_build_query( curl_setopt($curl, CURLOPT_URL, "https://api-alerts.solutionsinfini.com/v4/?" . http_build_query(
array( array(
"api_key" => $this->password, "api_key" => $this->password,
"method" => "sms", "method" => "sms",
"to" => $recipients, "to" => $recipients,
"sender" => substr($this->originator, 0, 11), "sender" => substr($this->originator, 0, 11),
"message" => $message, "message" => $message,
) )
) ));
); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($curl), true); $result = json_decode(curl_exec($curl), true);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl); $err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $result['status'] != "OK") { if ($err != 0 || $httpcode != 200 || $result['status'] != "OK") {
$success = 0; $success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". Result: ".$result['status']." - ".$result['message']."."; $error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
} curl_strerror($err) . ". Result: " . $result['status'] . " - " . $result['message'] . ".";
curl_close($curl); }
if ($success) { curl_close($curl);
return 1; if ($success) {
} return 1;
return $error; }
} return $error;
} }
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,50 +18,61 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Pepijn Over <pep@mailbox.org> * @author Pepijn Over <pep@mailbox.org>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Spryng extends Core { class Spryng extends Core
{
/** /**
* Send sms using the Spryngsms API * Send sms using the Spryngsms API
* @var string $message * @var string $message
* @var array $this->recipients * @var array $this->recipients
* @var string $this->username * @var string $this->username
* @var string $this->password * @var string $this->password
* @var string $this->originator * @var string $this->originator
* @var mixed $result * @var mixed $result
* @var array $headers * @var array $headers
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$recipients = implode(",", $this->recipients); {
$recipients = implode(",", $this->recipients);
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.spryngsms.com/api/send.php?OPERATION=send&USERNAME=".urlencode($this->username)."&PASSWORD=".urlencode($this->password)."&DESTINATION=".urlencode($recipients)."&SENDER=".urlencode($this->originator)."&BODY=".urlencode($message)."&SMSTYPE=BUSINESS"); curl_setopt(
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $ch,
$headers = array(); CURLOPT_URL,
$headers[] = "Content-Type: application/x-www-form-urlencoded"; "https://api.spryngsms.com/api/send.php?OPERATION=send&USERNAME=" .
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); urlencode($this->username) .
$result = curl_exec($ch); "&PASSWORD=" . urlencode($this->password) .
curl_close($ch); "&DESTINATION=" . urlencode($recipients) .
"&SENDER=" . urlencode($this->originator) .
"&BODY=" . urlencode($message) . "&SMSTYPE=BUSINESS"
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$headers = array();
$headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
// Check on error // Check on error
if ($result != 1) { if ($result != 1) {
return "Error ".$result.": see http://www.spryng.nl/en/developers/http-api/ for the description."; return "Error " . $result . ": see http://www.spryng.nl/en/developers/http-api/ for the description.";
} }
return 1; return 1;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -17,59 +18,68 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>. * along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
* *
* @package phpservermon * @package phpservermon
* @author Perri Vardy-Mason * @author Perri Vardy-Mason
* @author Tim Zandbergen <Tim@Xervion.nl> * @author Tim Zandbergen <Tim@Xervion.nl>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org> * @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://www.phpservermonitor.org/ * @link http://www.phpservermonitor.org/
* @since phpservermon 2.1 * @since phpservermon 2.1
**/ **/
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Textmarketer extends Core { class Textmarketer extends Core
{
/** /**
* Send sms using the Textmarketer API * Send sms using the Textmarketer API
* @var string $message * @var string $message
* @var array $this->recipients * @var array $this->recipients
* @var string $recipient * @var string $recipient
* @var string $this->username * @var string $this->username
* @var string $this->password * @var string $this->password
* @var mixed $result * @var mixed $result
* @var array $headers * @var array $headers
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$success = 1; {
$error = ''; $success = 1;
foreach ($this->recipients as $recipient) { $error = '';
foreach ($this->recipients as $recipient) {
$ch = curl_init();
curl_setopt(
$ch,
CURLOPT_URL,
"https://api.textmarketer.co.uk/gateway/?username=" . $this->username .
"&password=" . $this->password .
"&to=" . $recipient .
"&message=" . urlencode($message) .
"&orig=SERVERALERT"
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$headers = array();
$headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
$ch = curl_init(); // Check on error
curl_setopt($ch, CURLOPT_URL, "https://api.textmarketer.co.uk/gateway/?username=".$this->username."&password=".$this->password."&to=".$recipient."&message=".urlencode($message)."&orig=SERVERALERT"); if (is_numeric(strpos($result, "FAILED"))) {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $error = $result;
$headers = array(); $success = 0;
$headers[] = "Content-Type: application/x-www-form-urlencoded"; }
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); }
$result = curl_exec($ch); if ($success == 1) {
curl_close($ch); return 1;
}
// Check on error return $error;
if (is_numeric(strpos($result, "FAILED"))) { }
$error = $result;
$success = 0;
}
}
if ($success == 1) {
return 1;
}
return $error;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,54 +28,66 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
class Twilio extends Core { class Twilio extends Core
{
/** /**
* Send sms using the Twilio API * Send sms using the Twilio API
* https://www.twilio.com/docs/sms/api#send-an-sms-with-the-sms-api * https://www.twilio.com/docs/sms/api#send-an-sms-with-the-sms-api
* @var string $message * @var string $message
* @var array $this->recipients * @var array $this->recipients
* @var string $recipient * @var string $recipient
* @var string $this->username * @var string $this->username
* @var string $this->password * @var string $this->password
* @var string $this->originator * @var string $this->originator
* @var mixed $result * @var mixed $result
* @var array $headers * @var array $headers
* *
* @var int $success * @var int $success
* @var string $error * @var string $error
* *
* @return bool|string * @return bool|string
*/ */
public function sendSMS($message) { public function sendSMS($message)
$success = 1; {
$error = ''; $success = 1;
$error = '';
foreach ($this->recipients as $recipient) { foreach ($this->recipients as $recipient) {
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.twilio.com/2010-04-01/Accounts/".$this->username."/Messages.json"); curl_setopt(
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $ch,
curl_setopt($ch, CURLOPT_POSTFIELDS, "From=".urlencode($this->originator)."&Body=".urlencode($message)."&To=".urlencode($recipient)); CURLOPT_URL,
curl_setopt($ch, CURLOPT_POST, 1); "https://api.twilio.com/2010-04-01/Accounts/" . $this->username . "/Messages.json"
curl_setopt($ch, CURLOPT_USERPWD, $this->username.":".$this->password); );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch,
CURLOPT_POSTFIELDS,
"From=" . urlencode($this->originator) .
"&Body=" . urlencode($message) .
"&To=" . urlencode($recipient)
);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, $this->username . ":" . $this->password);
$headers = array(); $headers = array();
$headers[] = "Content-Type: application/x-www-form-urlencoded"; $headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch); $result = curl_exec($ch);
curl_close($ch); curl_close($ch);
// When the result string starts with {"code": there is a problem // When the result string starts with {"code": there is a problem
if (strpos($result, "{\"code\":") === 0) { if (strpos($result, "{\"code\":") === 0) {
$error = $result; $error = $result;
$success = 0; $success = 0;
} }
} }
if ($success) { if ($success) {
return 1; return 1;
} }
return $error; return $error;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,11 +28,11 @@
namespace psm\Txtmsg; namespace psm\Txtmsg;
interface TxtmsgInterface { interface TxtmsgInterface
{
public function setLogin($username, $password);
public function setOriginator($originator);
public function addRecipients($recipient);
public function sendSMS($message);
public function setLogin($username, $password);
public function setOriginator($originator);
public function addRecipients($recipient);
public function sendSMS($message);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,122 +29,130 @@
namespace psm\Util\Module; namespace psm\Util\Module;
class Modal implements ModalInterface { class Modal implements ModalInterface
{
const MODAL_TYPE_OK = 0; public const MODAL_TYPE_OK = 0;
const MODAL_TYPE_OKCANCEL = 1; public const MODAL_TYPE_OKCANCEL = 1;
const MODAL_TYPE_DANGER = 2; public const MODAL_TYPE_DANGER = 2;
/** /**
* prefix used for modal dialog box elements * prefix used for modal dialog box elements
* @var string $modal_id * @var string $modal_id
*/ */
protected $modal_id; protected $modal_id;
/** /**
* @var int $type Type of modal dialog * @var int $type Type of modal dialog
*/ */
protected $type; protected $type;
/** /**
* Modal dialog title * Modal dialog title
* @var string $title * @var string $title
*/ */
protected $title; protected $title;
/** /**
* Modal dialog message * Modal dialog message
* @var string $body * @var string $body
*/ */
protected $message; protected $message;
/** /**
* label of the OK button * label of the OK button
* @var string $ok_label * @var string $ok_label
*/ */
protected $ok_label; protected $ok_label;
/** /**
* Twig environment * Twig environment
* @var \Twig_Environment $twig * @var \Twig_Environment $twig
*/ */
protected $twig; protected $twig;
public function __construct(\Twig_Environment $twig, $modal_id = 'main', $type = self::MODAL_TYPE_OK) { public function __construct(\Twig_Environment $twig, $modal_id = 'main', $type = self::MODAL_TYPE_OK)
$this->modal_id = $modal_id; {
$this->twig = $twig; $this->modal_id = $modal_id;
$this->type = $type; $this->twig = $twig;
} $this->type = $type;
}
/** /**
* get the modal dialog box element prefix * get the modal dialog box element prefix
* @return string * @return string
*/ */
public function getModalID() { public function getModalID()
return $this->modal_id; {
} return $this->modal_id;
}
/** /**
* Set the modal dialog type * Set the modal dialog type
* @param int $type * @param int $type
* @return \psm\Util\Module\Modal * @return \psm\Util\Module\Modal
*/ */
public function setType($type) { public function setType($type)
if (in_array($type, array(self::MODAL_TYPE_OK, self::MODAL_TYPE_OKCANCEL, self::MODAL_TYPE_DANGER))) { {
$this->type = $type; if (in_array($type, array(self::MODAL_TYPE_OK, self::MODAL_TYPE_OKCANCEL, self::MODAL_TYPE_DANGER))) {
} $this->type = $type;
return $this; }
} return $this;
}
/** /**
* Set the modal dialog title * Set the modal dialog title
* @param string $title * @param string $title
* @return \psm\Util\Module\Modal * @return \psm\Util\Module\Modal
*/ */
public function setTitle($title) { public function setTitle($title)
$this->title = $title; {
return $this; $this->title = $title;
} return $this;
}
/** /**
* Set the modal dialog message * Set the modal dialog message
* @param string $message * @param string $message
* @return \psm\Util\Module\Modal * @return \psm\Util\Module\Modal
*/ */
public function setMessage($message) { public function setMessage($message)
$this->message = $message; {
return $this; $this->message = $message;
} return $this;
}
public function setOKButtonLabel($label) { public function setOKButtonLabel($label)
$this->ok_label = $label; {
return $this; $this->ok_label = $label;
} return $this;
}
public function createHTML() { public function createHTML()
$has_cancel = ($this->type == self::MODAL_TYPE_OK) ? false : true; {
$button_type = ($this->type == self::MODAL_TYPE_DANGER) ? 'danger' : 'primary'; $has_cancel = ($this->type == self::MODAL_TYPE_OK) ? false : true;
$button_label = empty($this->ok_label) ? psm_get_lang('system', 'ok') : $this->ok_label; $button_type = ($this->type == self::MODAL_TYPE_DANGER) ? 'danger' : 'primary';
$message = !empty($this->message) ? $this->message : ''; $button_label = empty($this->ok_label) ? psm_get_lang('system', 'ok') : $this->ok_label;
$message = !empty($this->message) ? $this->message : '';
$matches = array(); $matches = array();
if (preg_match_all('/%(\d)/', $message, $matches, PREG_SET_ORDER)) { if (preg_match_all('/%(\d)/', $message, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) { foreach ($matches as $match) {
$message = str_replace($match[0], '<span class="modalP'.$match[1].'"></span>', $message); $message = str_replace($match[0], '<span class="modalP' . $match[1] . '"></span>', $message);
} }
} }
$tpl = $this->twig->loadTemplate('util/module/modal.tpl.html'); $tpl = $this->twig->loadTemplate('util/module/modal.tpl.html');
$html = $tpl->render(array( $html = $tpl->render(array(
'modal_id' => $this->modal_id, 'modal_id' => $this->modal_id,
'modal_title' => !empty($this->title) ? $this->title : psm_get_lang('system', 'title'), 'modal_title' => !empty($this->title) ? $this->title : psm_get_lang('system', 'title'),
'modal_body' => $message, 'modal_body' => $message,
'has_cancel' => $has_cancel, 'has_cancel' => $has_cancel,
'label_cancel' => psm_get_lang('system', 'cancel'), 'label_cancel' => psm_get_lang('system', 'cancel'),
'modal_button_type' => $button_type, 'modal_button_type' => $button_type,
'modal_button_label'=> $button_label, 'modal_button_label' => $button_label,
)); ));
return $html; return $html;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,10 +29,11 @@
namespace psm\Util\Module; namespace psm\Util\Module;
interface ModalInterface { interface ModalInterface
{
public function __construct(\Twig_Environment $twig); public function __construct(\Twig_Environment $twig);
public function getModalID(); public function getModalID();
public function createHTML(); public function createHTML();
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,155 +28,163 @@
namespace psm\Util\Module; namespace psm\Util\Module;
class Sidebar implements SidebarInterface { class Sidebar implements SidebarInterface
{
/** /**
* ID of active item * ID of active item
* @var string $active_id * @var string $active_id
* @see setActiveItem() * @see setActiveItem()
*/ */
protected $active_id; protected $active_id;
/** /**
* List of all sidebar items * List of all sidebar items
* @var array $items * @var array $items
*/ */
protected $items = array(); protected $items = array();
/** /**
* Custom subtitle * Custom subtitle
* @var string $subtitle * @var string $subtitle
* @see setSubtitle() * @see setSubtitle()
*/ */
protected $subtitle; protected $subtitle;
/** /**
* Twig environment * Twig environment
* @var \Twig_Environment $twig * @var \Twig_Environment $twig
*/ */
protected $twig; protected $twig;
public function __construct(\Twig_Environment $twig) { public function __construct(\Twig_Environment $twig)
$this->twig = $twig; {
} $this->twig = $twig;
}
/** /**
* Set active item * Set active item
* @param string $id * @param string $id
* @return \psm\Util\Module\Sidebar * @return \psm\Util\Module\Sidebar
*/ */
public function setActiveItem($id) { public function setActiveItem($id)
$this->active_id = $id; {
return $this; $this->active_id = $id;
} return $this;
}
/** /**
* Set a custom subtitle (default is module subitle) * Set a custom subtitle (default is module subitle)
* @param string $title * @param string $title
* @return \psm\Util\Module\Sidebar * @return \psm\Util\Module\Sidebar
*/ */
public function setSubtitle($title) { public function setSubtitle($title)
$this->subtitle = $title; {
return $this; $this->subtitle = $title;
} return $this;
}
/** /**
* Add new link to sidebar * Add new link to sidebar
* @param string $id * @param string $id
* @param string $label * @param string $label
* @param string $url * @param string $url
* @param string $icon * @param string $icon
* @return \psm\Util\Module\Sidebar * @return \psm\Util\Module\Sidebar
*/ */
public function addLink($id, $label, $url, $icon = null) { public function addLink($id, $label, $url, $icon = null)
if (!isset($this->items['link'])) { {
$this->items['link'] = array(); if (!isset($this->items['link'])) {
} $this->items['link'] = array();
}
$this->items['link'][$id] = array( $this->items['link'][$id] = array(
'id' => $id, 'id' => $id,
'label' => $label, 'label' => $label,
'url' => str_replace('"', '\"', $url), 'url' => str_replace('"', '\"', $url),
'icon' => $icon, 'icon' => $icon,
); );
return $this; return $this;
} }
/** /**
* Add a new button to the sidebar * Add a new button to the sidebar
* @param string $id * @param string $id
* @param string $label * @param string $label
* @param string $url * @param string $url
* @param string $icon * @param string $icon
* @param string $btn_class * @param string $btn_class
* @param boolean $url_is_onclick if you want onclick rather than url, change this to true * @param boolean $url_is_onclick if you want onclick rather than url, change this to true
* @return \psm\Util\Module\Sidebar * @return \psm\Util\Module\Sidebar
*/ */
public function addButton($id, $label, $url, $icon = null, $btn_class = 'link', $title = '', $modal_id = null) { public function addButton($id, $label, $url, $icon = null, $btn_class = 'link', $title = '', $modal_id = null)
if (!isset($this->items['button'])) { {
$this->items['button'] = array(); if (!isset($this->items['button'])) {
} $this->items['button'] = array();
}
$this->items['button'][$id] = array( $this->items['button'][$id] = array(
'id' => $id, 'id' => $id,
'label' => $label, 'label' => $label,
'url' => str_replace('"', '\"', $url), 'url' => str_replace('"', '\"', $url),
'icon' => $icon, 'icon' => $icon,
'btn_class'=> $btn_class, 'btn_class' => $btn_class,
'title'=> $title, 'title' => $title,
'modal_id'=> $modal_id 'modal_id' => $modal_id
); );
return $this; return $this;
} }
/** /**
* Add dropdown button * Add dropdown button
* @param string $id * @param string $id
* @param string $label * @param string $label
* @param array $options * @param array $options
* @param string $icon * @param string $icon
* @param string $btn_class * @param string $btn_class
* @return \psm\Util\Module\Sidebar * @return \psm\Util\Module\Sidebar
*/ */
public function addDropdown($id, $label, $options, $icon = null, $btn_class = null) { public function addDropdown($id, $label, $options, $icon = null, $btn_class = null)
if (!isset($this->items['dropdown'])) { {
$this->items['dropdown'] = array(); if (!isset($this->items['dropdown'])) {
} $this->items['dropdown'] = array();
$this->items['dropdown'][$id] = array( }
'id' => $id, $this->items['dropdown'][$id] = array(
'label' => $label, 'id' => $id,
'options' => $options, 'label' => $label,
'icon' => $icon, 'options' => $options,
'btn_class' => $btn_class, 'icon' => $icon,
); 'btn_class' => $btn_class,
return $this; );
} return $this;
}
public function createHTML() { public function createHTML()
$tpl_data = array( {
'subtitle' => $this->subtitle, $tpl_data = array(
); 'subtitle' => $this->subtitle,
$types = array('dropdown', 'button', 'link'); );
$tpl_data['items'] = array(); $types = array('dropdown', 'button', 'link');
$tpl_data['items'] = array();
// loop through all types and build their html // loop through all types and build their html
foreach ($types as $type) { foreach ($types as $type) {
if (empty($this->items[$type])) { if (empty($this->items[$type])) {
// no items for this type // no items for this type
continue; continue;
} }
// build html for each individual item // build html for each individual item
foreach ($this->items[$type] as $id => $item) { foreach ($this->items[$type] as $id => $item) {
$item['type'] = $type; $item['type'] = $type;
$item['class_active'] = ($id === $this->active_id) ? 'active' : ''; $item['class_active'] = ($id === $this->active_id) ? 'active' : '';
$tpl_data['items'][] = $item; $tpl_data['items'][] = $item;
} }
} }
$tpl = $this->twig->loadTemplate('util/module/sidebar.tpl.html'); $tpl = $this->twig->loadTemplate('util/module/sidebar.tpl.html');
$html = $tpl->render($tpl_data); $html = $tpl->render($tpl_data);
return $html; return $html;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,10 +28,10 @@
namespace psm\Util\Module; namespace psm\Util\Module;
interface SidebarInterface { interface SidebarInterface
{
public function __construct(\Twig_Environment $twig); public function __construct(\Twig_Environment $twig);
public function createHTML(); public function createHTML();
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -31,89 +32,94 @@ namespace psm\Util\Server;
/** /**
* Makes sure all data of servers is being archived properly or removed if necessary. * Makes sure all data of servers is being archived properly or removed if necessary.
*/ */
class ArchiveManager { class ArchiveManager
{
/** /**
* Available archiver utils. * Available archiver utils.
* @var array $archivers * @var array $archivers
*/ */
protected $archivers = array(); protected $archivers = array();
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
/** /**
* Retention period * Retention period
* @var \DateInterval|bool $retention_period false if cleanup is disabled * @var \DateInterval|bool $retention_period false if cleanup is disabled
* @see setRetentionPeriod() * @see setRetentionPeriod()
*/ */
protected $retention_period; protected $retention_period;
public function __construct(\psm\Service\Database $db) { public function __construct(\psm\Service\Database $db)
$this->db = $db; {
$this->db = $db;
$this->setRetentionPeriod(psm_get_conf('log_retention_period', 365)); $this->setRetentionPeriod(psm_get_conf('log_retention_period', 365));
$this->archivers[] = new Archiver\UptimeArchiver($db); $this->archivers[] = new Archiver\UptimeArchiver($db);
$this->archivers[] = new Archiver\LogsArchiver($db); $this->archivers[] = new Archiver\LogsArchiver($db);
} }
/** /**
* Archive one or more servers. * Archive one or more servers.
* @param int $server_id * @param int $server_id
* @return boolean * @return boolean
*/ */
public function archive($server_id = null) { public function archive($server_id = null)
$result = true; {
foreach ($this->archivers as $archiver) { $result = true;
if (!$archiver->archive($server_id)) { foreach ($this->archivers as $archiver) {
$result = false; if (!$archiver->archive($server_id)) {
} $result = false;
} }
return $result; }
} return $result;
}
/** /**
* Cleanup old records for one or more servers * Cleanup old records for one or more servers
* @param int $server_id * @param int $server_id
* @return boolean * @return boolean
*/ */
public function cleanup($server_id = null) { public function cleanup($server_id = null)
$result = true; {
if (!$this->retention_period) { $result = true;
// cleanup is disabled if (!$this->retention_period) {
return $result; // cleanup is disabled
} return $result;
$retdate = new \DateTime(); }
$retdate->sub($this->retention_period); $retdate = new \DateTime();
$retdate->sub($this->retention_period);
foreach ($this->archivers as $archiver) { foreach ($this->archivers as $archiver) {
if (!$archiver->cleanup($retdate, $server_id)) { if (!$archiver->cleanup($retdate, $server_id)) {
$result = false; $result = false;
} }
} }
return $result; return $result;
} }
/** /**
* Set retention period for this archive run. * Set retention period for this archive run.
* *
* Set period to 0 to disable cleanup altogether. * Set period to 0 to disable cleanup altogether.
* @param \DateInterval|int $period \DateInterval object or number of days (int) * @param \DateInterval|int $period \DateInterval object or number of days (int)
* @return \psm\Util\Server\ArchiveManager * @return \psm\Util\Server\ArchiveManager
*/ */
public function setRetentionPeriod($period) { public function setRetentionPeriod($period)
if (is_object($period) && $period instanceof \DateInterval) { {
$this->retention_period = $period; if (is_object($period) && $period instanceof \DateInterval) {
} elseif (intval($period) == 0) { $this->retention_period = $period;
// cleanup disabled } elseif (intval($period) == 0) {
$this->retention_period = false; // cleanup disabled
} else { $this->retention_period = false;
$this->retention_period = new \DateInterval('P'.intval($period).'D'); } else {
} $this->retention_period = new \DateInterval('P' . intval($period) . 'D');
return $this; }
} return $this;
} }
}

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -28,20 +29,21 @@
namespace psm\Util\Server\Archiver; namespace psm\Util\Server\Archiver;
interface ArchiverInterface { interface ArchiverInterface
{
/** /**
* Archive for one or all servers. * Archive for one or all servers.
* @param int $server_id * @param int $server_id
* @return boolean * @return boolean
*/ */
public function archive($server_id = null); public function archive($server_id = null);
/** /**
* Cleanup data older than the retention period given. * Cleanup data older than the retention period given.
* @param \DateTime $retention_date * @param \DateTime $retention_date
* @param int $server_id * @param int $server_id
* @return boolean * @return boolean
*/ */
public function cleanup(\DateTime $retention_date, $server_id = null); public function cleanup(\DateTime $retention_date, $server_id = null);
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -32,48 +33,53 @@
namespace psm\Util\Server\Archiver; namespace psm\Util\Server\Archiver;
use psm\Service\Database; use psm\Service\Database;
class LogsArchiver implements ArchiverInterface { class LogsArchiver implements ArchiverInterface
{
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
function __construct(Database $db) { public function __construct(Database $db)
$this->db = $db; {
} $this->db = $db;
}
/** /**
* Currently there is not really a log archive. * Currently there is not really a log archive.
* *
* It stays in the log table until cleaned up. * It stays in the log table until cleaned up.
* @param int $server_id * @param int $server_id
*/ */
public function archive($server_id = null) { public function archive($server_id = null)
return true; {
} return true;
}
public function cleanup(\DateTime $retention_date, $server_id = null) { 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. $sql_where_server = ($server_id !== null)
? ' `server_id` = '.intval($server_id).' AND ' // this is obviously not the cleanest way to implement this when using paramter binding.. sorry.
: ''; ? ' `server_id` = ' . intval($server_id) . ' AND '
: '';
$this->db->execute( $this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."log` WHERE {$sql_where_server} `datetime` < :latest_date", "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')), array('latest_date' => $retention_date->format('Y-m-d 00:00:00')),
false false
); );
return true; return true;
} }
/** /**
* Empty tables log and log_users * Empty tables log and log_users
*/ */
public function cleanupall() { public function cleanupall()
$this->db->delete(PSM_DB_PREFIX."log"); {
$this->db->delete(PSM_DB_PREFIX."log_users"); $this->db->delete(PSM_DB_PREFIX . "log");
return true; $this->db->delete(PSM_DB_PREFIX . "log_users");
} return true;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -40,134 +41,142 @@
namespace psm\Util\Server\Archiver; namespace psm\Util\Server\Archiver;
use psm\Service\Database; use psm\Service\Database;
class UptimeArchiver implements ArchiverInterface { class UptimeArchiver implements ArchiverInterface
{
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
function __construct(Database $db) { public function __construct(Database $db)
$this->db = $db; {
} $this->db = $db;
}
/** /**
* Archive all server status records older than 1 week. * Archive all server status records older than 1 week.
* *
* Archiving means calculating averages per day, and storing 1 single * Archiving means calculating averages per day, and storing 1 single
* history row for each day for each server. * history row for each day for each server.
* *
* @param int $server_id * @param int $server_id
*/ */
public function archive($server_id = null) { public function archive($server_id = null)
$latest_date = new \DateTime('-1 week 0:0:0'); {
$latest_date = new \DateTime('-1 week 0:0:0');
// Lock tables to prevent simultaneous archiving (by other sessions or the cron job) // Lock tables to prevent simultaneous archiving (by other sessions or the cron job)
try { try {
$this->db->pdo()->exec('LOCK TABLES '.PSM_DB_PREFIX.'servers_uptime WRITE, '.PSM_DB_PREFIX.'servers_history WRITE'); $this->db->pdo()->exec('LOCK TABLES ' . PSM_DB_PREFIX .
$locked = true; 'servers_uptime WRITE, ' . PSM_DB_PREFIX . 'servers_history WRITE');
} catch (\PDOException $e) { $locked = true;
// user does not have lock rights, ignore } catch (\PDOException $e) {
$locked = false; // user does not have lock rights, ignore
} $locked = false;
}
$latest_date_str = $latest_date->format('Y-m-d 00:00:00'); $latest_date_str = $latest_date->format('Y-m-d 00:00:00');
$sql_where_server = $this->createSQLWhereServer($server_id); $sql_where_server = $this->createSQLWhereServer($server_id);
$records = $this->db->execute( $records = $this->db->execute(
"SELECT `server_id`,`date`,`status`,`latency` "SELECT `server_id`,`date`,`status`,`latency`
FROM `".PSM_DB_PREFIX."servers_uptime` FROM `" . PSM_DB_PREFIX . "servers_uptime`
WHERE {$sql_where_server} `date` < :latest_date", WHERE {$sql_where_server} `date` < :latest_date",
array('latest_date' => $latest_date_str)); array('latest_date' => $latest_date_str)
);
if (!empty($records)) { if (!empty($records)) {
// first group all records by day and server_id // first group all records by day and server_id
$data_by_day = array(); $data_by_day = array();
foreach ($records as $record) { foreach ($records as $record) {
$server_id = (int) $record['server_id']; $server_id = (int) $record['server_id'];
$day = date('Y-m-d', strtotime($record['date'])); $day = date('Y-m-d', strtotime($record['date']));
if (!isset($data_by_day[$day][$server_id])) { if (!isset($data_by_day[$day][$server_id])) {
$data_by_day[$day][$server_id] = array(); $data_by_day[$day][$server_id] = array();
} }
$data_by_day[$day][$server_id][] = $record; $data_by_day[$day][$server_id][] = $record;
} }
// now get history data day by day // now get history data day by day
$histories = array(); $histories = array();
foreach ($data_by_day as $day => $day_records) { foreach ($data_by_day as $day => $day_records) {
foreach ($day_records as $server_id => $server_day_records) { foreach ($day_records as $server_id => $server_day_records) {
$histories[] = $this->getHistoryForDay($day, $server_id, $server_day_records); $histories[] = $this->getHistoryForDay($day, $server_id, $server_day_records);
} }
} }
// Save all // Save all
$this->db->insertMultiple(PSM_DB_PREFIX.'servers_history', $histories); $this->db->insertMultiple(PSM_DB_PREFIX . 'servers_history', $histories);
// now remove all records from the uptime table // now remove all records from the uptime table
$this->db->execute( $this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."servers_uptime` WHERE {$sql_where_server} `date` < :latest_date", "DELETE FROM `" . PSM_DB_PREFIX . "servers_uptime` WHERE {$sql_where_server} `date` < :latest_date",
array('latest_date' => $latest_date_str), array('latest_date' => $latest_date_str),
false false
); );
} }
if ($locked) { if ($locked) {
$this->db->exec('UNLOCK TABLES'); $this->db->exec('UNLOCK TABLES');
} }
return true; return true;
} }
public function cleanup(\DateTime $retention_date, $server_id = null) { public function cleanup(\DateTime $retention_date, $server_id = null)
$sql_where_server = $this->createSQLWhereServer($server_id); {
$this->db->execute( $sql_where_server = $this->createSQLWhereServer($server_id);
"DELETE FROM `".PSM_DB_PREFIX."servers_history` WHERE {$sql_where_server} `date` < :latest_date", $this->db->execute(
array('latest_date' => $retention_date->format('Y-m-d 00:00:00')), "DELETE FROM `" . PSM_DB_PREFIX . "servers_history` WHERE {$sql_where_server} `date` < :latest_date",
false array('latest_date' => $retention_date->format('Y-m-d 00:00:00')),
); false
return true; );
} return true;
}
/** /**
* Build a history array for a day records * Build a history array for a day records
* @param string $day * @param string $day
* @param int $server_id * @param int $server_id
* @param array $day_records * @param array $day_records
* @return array * @return array
*/ */
protected function getHistoryForDay($day, $server_id, $day_records) { protected function getHistoryForDay($day, $server_id, $day_records)
$latencies = array(); {
$checks_failed = 0; $latencies = array();
$checks_failed = 0;
foreach ($day_records as $day_record) { foreach ($day_records as $day_record) {
$latencies[] = $day_record['latency']; $latencies[] = $day_record['latency'];
if ($day_record['status'] == 0) { if ($day_record['status'] == 0) {
$checks_failed++; $checks_failed++;
} }
} }
sort($latencies, SORT_NUMERIC); sort($latencies, SORT_NUMERIC);
$history = array( $history = array(
'date' => $day, 'date' => $day,
'server_id' => $server_id, 'server_id' => $server_id,
'latency_min' => min($latencies), 'latency_min' => min($latencies),
'latency_avg' => array_sum($latencies) / count($latencies), 'latency_avg' => array_sum($latencies) / count($latencies),
'latency_max' => max($latencies), 'latency_max' => max($latencies),
'checks_total' => count($day_records), 'checks_total' => count($day_records),
'checks_failed' => $checks_failed, 'checks_failed' => $checks_failed,
); );
return $history; return $history;
} }
protected function createSQLWhereServer($server_id) { 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. $sql_where_server = ($server_id !== null)
? ' `server_id` = '.intval($server_id).' AND ' // 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; return $sql_where_server;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,254 +28,293 @@
**/ **/
namespace psm\Util\Server; namespace psm\Util\Server;
use psm\Service\Database; use psm\Service\Database;
/** /**
* History util, create HTML for server graphs * History util, create HTML for server graphs
*/ */
class HistoryGraph { class HistoryGraph
{
/** /**
* Database service * Database service
* @var \psm\Service\Database $db; * @var \psm\Service\Database $db;
*/ */
protected $db; protected $db;
/** /**
* Twig environment * Twig environment
* @var \Twig_Environment $twig * @var \Twig_Environment $twig
*/ */
protected $twig; protected $twig;
function __construct(Database $db, \Twig_Environment $twig) { public function __construct(Database $db, \Twig_Environment $twig)
$this->db = $db; {
$this->twig = $twig; $this->db = $db;
} $this->twig = $twig;
}
/** /**
* Prepare the HTML for the graph * Prepare the HTML for the graph
* @return string * @return string
*/ */
public function createHTML($server_id) { public function createHTML($server_id)
// Archive all records for this server to make sure we have up-to-date stats {
$archive = new ArchiveManager($this->db); // Archive all records for this server to make sure we have up-to-date stats
$archive->archive($server_id); $archive = new ArchiveManager($this->db);
$archive->archive($server_id);
$now = new \DateTime(); $now = new \DateTime();
$last_week = new \DateTime('-1 week 0:0:0'); $last_week = new \DateTime('-1 week 0:0:0');
$last_year = new \DateTime('-1 year -1 week 0:0:0'); $last_year = new \DateTime('-1 year -1 week 0:0:0');
$graphs = array( $graphs = array(
0 => $this->generateGraphUptime($server_id, $last_week, $now), 0 => $this->generateGraphUptime($server_id, $last_week, $now),
1 => $this->generateGraphHistory($server_id, $last_year, $last_week), 1 => $this->generateGraphHistory($server_id, $last_year, $last_week),
); );
$info_fields = array( $info_fields = array(
'latency_avg' => '%01.4f', 'latency_avg' => '%01.4f',
'uptime' => '%01.3f%%', 'uptime' => '%01.3f%%',
); );
foreach ($graphs as $i => &$graph) { foreach ($graphs as $i => &$graph) {
// add subarray for info fields // add subarray for info fields
$graph['info'] = array(); $graph['info'] = array();
foreach ($info_fields as $field => $format) { foreach ($info_fields as $field => $format) {
if (!isset($graph[$field])) { if (!isset($graph[$field])) {
continue; continue;
} }
$graph['info'][] = array( $graph['info'][] = array(
'label' => psm_get_lang('servers', $field), 'label' => psm_get_lang('servers', $field),
'value' => sprintf($format, $graph[$field]), 'value' => sprintf($format, $graph[$field]),
); );
} }
} }
$tpl_data = array( $tpl_data = array(
'graphs' => $graphs, 'graphs' => $graphs,
); );
return $this->twig->render('module/server/history.tpl.html', $tpl_data); return $this->twig->render('module/server/history.tpl.html', $tpl_data);
} }
/** /**
* Generate data for uptime graph * Generate data for uptime graph
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param \DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
public function generateGraphUptime($server_id, $start_time, $end_time) { public function generateGraphUptime($server_id, $start_time, $end_time)
{
$lines = array( $lines = array(
'latency' => array(), 'latency' => array(),
); );
$hour = new \DateTime('-1 hour'); $hour = new \DateTime('-1 hour');
$day = new \DateTime('-1 day'); $day = new \DateTime('-1 day');
$week = new \DateTime('-1 week'); $week = new \DateTime('-1 week');
$records = $this->getRecords('uptime', $server_id, $start_time, $end_time); $records = $this->getRecords('uptime', $server_id, $start_time, $end_time);
$data = $this->generateGraphLines($records, $lines, 'latency', $hour, $end_time, true); $data = $this->generateGraphLines($records, $lines, 'latency', $hour, $end_time, true);
$data['title'] = psm_get_lang('servers', 'chart_last_week'); $data['title'] = psm_get_lang('servers', 'chart_last_week');
$data['id'] = 'history_short'; $data['id'] = 'history_short';
$data['unit'] = 'minute'; $data['unit'] = 'minute';
$data['buttons'] = array(); $data['buttons'] = array();
$data['button_name'] = 'timeframe_short'; $data['button_name'] = 'timeframe_short';
$data['buttons'][] = array('unit' => 'minute', 'time' => $hour->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'hour'), 'class_active' => 'active'); $data['buttons'][] = array(
$data['buttons'][] = array('unit' => 'hour', 'time' => $day->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'day')); 'unit' => 'minute',
$data['buttons'][] = array('unit' => 'day', 'time' => $week->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'week')); 'time' => $hour->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'hour'),
'class_active' => 'active'
);
$data['buttons'][] = array(
'unit' => 'hour',
'time' => $day->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'day')
);
$data['buttons'][] = array(
'unit' => 'day',
'time' => $week->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'week')
);
return $data; return $data;
} }
/** /**
* Generate data for history graph * Generate data for history graph
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param \DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
public function generateGraphHistory($server_id, $start_time, $end_time) { public function generateGraphHistory($server_id, $start_time, $end_time)
$lines = array( {
'latency_min' => array(), $lines = array(
'latency_avg' => array(), 'latency_min' => array(),
'latency_max' => array(), 'latency_avg' => array(),
); 'latency_max' => array(),
);
$week = new \DateTime('-2 week 0:0:0'); $week = new \DateTime('-2 week 0:0:0');
$month = new \DateTime('-1 month -1 week 0:0:0'); $month = new \DateTime('-1 month -1 week 0:0:0');
$year = new \DateTime('-1 year -1 week 0:0:0'); $year = new \DateTime('-1 year -1 week 0:0:0');
$records = $this->getRecords('history', $server_id, $year, $end_time); $records = $this->getRecords('history', $server_id, $year, $end_time);
// dont add uptime for now because we have no way to calculate accurate uptimes for archived records // dont add uptime for now because we have no way to calculate accurate uptimes for archived records
$data = $this->generateGraphLines($records, $lines, 'latency_avg', $start_time, $end_time, false); $data = $this->generateGraphLines($records, $lines, 'latency_avg', $start_time, $end_time, false);
$data['title'] = psm_get_lang('servers', 'chart_history'); $data['title'] = psm_get_lang('servers', 'chart_history');
$data['id'] = 'history_long'; $data['id'] = 'history_long';
$data['unit'] = 'week'; $data['unit'] = 'week';
$data['buttons'] = array(); $data['buttons'] = array();
$data['button_name'] = 'timeframe_long'; $data['button_name'] = 'timeframe_long';
$data['buttons'][] = array('unit' => 'day', 'time' => $week->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'week')); $data['buttons'][] = array(
$data['buttons'][] = array('unit' => 'week', 'time' => $month->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'month'), 'class_active' => 'active'); 'unit' => 'day',
$data['buttons'][] = array('unit' => 'month', 'time' => $year->getTimestamp()*1000, 'label' => psm_get_lang('servers', 'year')); 'time' => $week->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'week')
);
$data['buttons'][] = array(
'unit' => 'week',
'time' => $month->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'month'),
'class_active' => 'active'
);
$data['buttons'][] = array(
'unit' => 'month',
'time' => $year->getTimestamp() * 1000,
'label' => psm_get_lang('servers', 'year')
);
return $data; return $data;
} }
/** /**
* Get all uptime/history records for a server * Get all uptime/history records for a server
* @param string $type * @param string $type
* @param int $server_id * @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph * @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param \DateTime $end_time Highest DateTime of the graph
* @return array * @return array
*/ */
protected function getRecords($type, $server_id, $start_time, $end_time) { protected function getRecords($type, $server_id, $start_time, $end_time)
if (!in_array($type, array('history', 'uptime'))) { {
return array(); if (!in_array($type, array('history', 'uptime'))) {
} return array();
}
$records = $this->db->execute( $records = $this->db->execute(
"SELECT * "SELECT *
FROM `".PSM_DB_PREFIX."servers_$type` FROM `" . PSM_DB_PREFIX . "servers_$type`
WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date` ASC", WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date` ASC",
array( array(
'server_id' => $server_id, 'server_id' => $server_id,
'start_time' => $start_time->format('Y-m-d H:i:s'), 'start_time' => $start_time->format('Y-m-d H:i:s'),
'end_time' => $end_time->format('Y-m-d H:i:s'), 'end_time' => $end_time->format('Y-m-d H:i:s'),
)); )
return $records; );
} return $records;
}
/** /**
* Generate data arrays for graphs * Generate data arrays for graphs
* @param array $records All uptime records to parse, MUST BE SORTED BY DATE IN ASCENDING ORDER * @param array $records All uptime records to parse, MUST BE SORTED BY DATE IN ASCENDING ORDER
* @param array $lines Array with keys as line ids to prepare (key must be available in uptime records) * @param array $lines Array with keys as line ids to prepare (key must be available in uptime records)
* @param string $latency_avg_key which key from uptime records to use for calculating averages * @param string $latency_avg_key which key from uptime records to use for calculating averages
* @param \DateTime $start_time Lowest DateTime of the graph * @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph * @param \DateTime $end_time Highest DateTime of the graph
* @param boolean $add_uptime Add uptime calculation? * @param boolean $add_uptime Add uptime calculation?
* @param array $prev Previous result * @param array $prev Previous result
* @param int $downtime Total downtime * @param int $downtime Total downtime
* @param int $prev_downtime Timestamp from last offline record. 0 when last record is uptime * @param int $prev_downtime Timestamp from last offline record. 0 when last record is uptime
* @return array * @return array
*/ */
protected function generateGraphLines($records, $lines, $latency_avg_key, $start_time, $end_time, $add_uptime = false) { protected function generateGraphLines(
$now = new \DateTime(); $records,
$data = array(); $lines,
$latency_avg_key,
$start_time,
$end_time,
$add_uptime = false
) {
$now = new \DateTime();
$data = array();
// PLEASE NOTE: all times are in microseconds! because of javascript. // PLEASE NOTE: all times are in microseconds! because of javascript.
$latency_avg = 0; $latency_avg = 0;
$prev = reset($records); $prev = reset($records);
$prev_downtime = 0; $prev_downtime = 0;
$downtime = 0; $downtime = 0;
// Create the list of points and server down zones // Create the list of points and server down zones
foreach ($records as $record) { foreach ($records as $record) {
$time = strtotime($record['date']); $time = strtotime($record['date']);
// use the first line to calculate average latency // use the first line to calculate average latency
$latency_avg += (float) $record[$latency_avg_key]; $latency_avg += (float) $record[$latency_avg_key];
foreach ($lines as $key => $value) { foreach ($lines as $key => $value) {
// add the value for each of the different lines // add the value for each of the different lines
if (isset($record[$key])) { if (isset($record[$key])) {
if (isset($record['status'])){ if (isset($record['status'])) {
// down // down
if ($record['status'] == 0){ if ($record['status'] == 0) {
$lines['online'][] = $prev['status'] $lines['online'][] = $prev['status']
// Previous datapoint was online // Previous datapoint was online
? '{ x: '.($time*1000).', y: '.$prev['latency'].'}' ? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] . '}'
// Previous datapoint was offline // Previous datapoint was offline
: '{ x: '.($time*1000).', y: null}'; : '{ x: ' . ($time * 1000) . ', y: null}';
// new outage start // new outage start
$lines['offline'][] = '{ x: '.($time*1000).', y:0.1}'; $lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:0.1}';
$prev_downtime != 0 ?: $prev_downtime = $time; $prev_downtime != 0 ?: $prev_downtime = $time;
} } else {
// up // up
else { // outage ends
// outage ends $lines['offline'][] = $prev['status']
$lines['offline'][] = $prev['status'] // Previous datapoint was online
// Previous datapoint was online ? '{ x: ' . ($time * 1000) . ', y:null}'
? '{ x: '.($time*1000).', y:null}' // Previous datapoint was offline
// Previous datapoint was offline : '{ x: ' . ($time * 1000) . ', y:0.1}';
: '{ x: '.($time*1000).', y:0.1}'; $lines['online'][] = '{ x: ' . ($time * 1000) . ', y: ' .
$lines['online'][] = '{ x: '.($time*1000).', y: '.round((float) $record[$key], 4).'}'; round((float) $record[$key], 4) . '}';
$prev_downtime == 0 ?: $downtime += ($time - $prev_downtime); $prev_downtime == 0 ?: $downtime += ($time - $prev_downtime);
$prev_downtime = 0; $prev_downtime = 0;
} }
} } else {
else { $lines[$key][] = '{ x: \'' . $record['date'] . '\', y: ' . $record[$key] . '}';
$lines[$key][] = '{ x: \''.$record['date'].'\', y: '.$record[$key].'}'; }
} $prev = $record;
$prev = $record; }
} }
} }
} // Was down before.
// Was down before. // Record the first and last date as a string in the down array
// Record the first and last date as a string in the down array $prev_downtime == 0 ?: $downtime += ($now->getTimestamp() - $prev_downtime);
$prev_downtime == 0 ?: $downtime += ($now->getTimestamp()-$prev_downtime); if ($add_uptime) {
if ($add_uptime) { $prev['status'] ?: $lines['offline'][] = '{ x: ' . ($now->getTimestamp() * 1000) . ', y:0.1}';
$prev['status'] ?: $lines['offline'][] = '{ x: '.($now->getTimestamp()*1000).', y:0.1}'; $data['uptime'] = 100 - ($downtime / ($end_time->getTimestamp() - $start_time->getTimestamp()));
$data['uptime'] = 100 - ($downtime / ($end_time->getTimestamp() - $start_time->getTimestamp())); }
}
$lines_merged = array(); $lines_merged = array();
foreach ($lines as $line_key => $line_value) { foreach ($lines as $line_key => $line_value) {
if (empty($line_value)) {
if (empty($line_value)) { continue;
continue; }
} $lines_merged[$line_key]['value'] = implode(', ', $line_value);
$lines_merged[$line_key]['value'] = implode(', ', $line_value); $lines_merged[$line_key]['name'] = psm_get_lang('servers', $line_key);
$lines_merged[$line_key]['name'] = psm_get_lang('servers', $line_key); }
}
$data['latency_avg'] = count($records) > 0 ? ($latency_avg / count($records)) : 0; $data['latency_avg'] = count($records) > 0 ? ($latency_avg / count($records)) : 0;
$data['lines'] = sizeof($lines_merged) ? $lines_merged : ''; $data['lines'] = sizeof($lines_merged) ? $lines_merged : '';
$data['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '')*1000; $data['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '') * 1000;
$data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '')*1000; $data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '') * 1000;
return $data; return $data;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -31,103 +32,126 @@ namespace psm\Util\Server;
/** /**
* The ServerValidator helps you to check input data for servers. * The ServerValidator helps you to check input data for servers.
*/ */
class ServerValidator { class ServerValidator
{
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
public function __construct(\psm\Service\Database $db) { public function __construct(\psm\Service\Database $db)
$this->db = $db; {
} $this->db = $db;
}
/** /**
* Check if the server id exists * Check if the server id exists
* @param int|\PDOStatement $server_id * @param int|\PDOStatement $server_id
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function serverId($server_id) { public function serverId($server_id)
$server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array('server_id' => $server_id), array('server_id')); {
$server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array('server_id' => $server_id), array('server_id'));
if (empty($server)) { if (empty($server)) {
throw new \InvalidArgumentException('server_no_match'); throw new \InvalidArgumentException('server_no_match');
} }
return true; return true;
} }
/** /**
* Check label * Check label
* @param string $label * @param string $label
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function label($label) { public function label($label)
$label = trim($label); {
if (empty($label) || strlen($label) > 255) { $label = trim($label);
throw new \InvalidArgumentException('server_label_bad_length'); if (empty($label) || strlen($label) > 255) {
} throw new \InvalidArgumentException('server_label_bad_length');
return true; }
} return true;
}
/** /**
* Check server domain/ip * Check server domain/ip
* @param string $value * @param string $value
* @param string $type if given, it can be checked for "website"/"ip" * @param string $type if given, it can be checked for "website"/"ip"
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function ip($value, $type = null) { public function ip($value, $type = null)
$value = trim($value); {
$value = trim($value);
if (empty($value) || strlen($value) > 255) { if (empty($value) || strlen($value) > 255) {
throw new \InvalidArgumentException('server_ip_bad_length'); throw new \InvalidArgumentException('server_ip_bad_length');
} }
switch ($type) { switch ($type) {
case 'website': case 'website':
// url regex as per https://stackoverflow.com/a/3809435 // url regex as per https://stackoverflow.com/a/3809435
if (!preg_match_all("/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,12}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/", $value)) { // Regex looks a bit weird, but otherwise it's more then 120 characters
throw new \InvalidArgumentException('server_ip_bad_website'); if (
} !preg_match_all(
break; "/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\." .
case 'service': "[a-z]{2,12}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/",
case 'ping': $value
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_website');
) {throw new \InvalidArgumentException('server_ip_bad_service'); } }
break; break;
} case 'service':
case 'ping':
if (
!filter_var($value, FILTER_VALIDATE_IP)
// domain regex as per
// http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address
// Regex looks a bit weird, but otherwise it's more then 120 characters
&& !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; return true;
} }
/** /**
* Check server type * Check server type
* @param string $type * @param string $type
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function type($type) { public function type($type)
if (!in_array($type, array('ping', 'service', 'website'))) { {
throw new \InvalidArgumentException('server_type_invalid'); if (!in_array($type, array('ping', 'service', 'website'))) {
} throw new \InvalidArgumentException('server_type_invalid');
return true; }
} return true;
}
/** /**
* Check warning threshold * Check warning threshold
* @param int $value * @param int $value
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function warningThreshold($value) { public function warningThreshold($value)
if (!is_numeric($value) || intval($value) == 0) { {
throw new \InvalidArgumentException('server_warning_threshold_invalid'); if (!is_numeric($value) || intval($value) == 0) {
} throw new \InvalidArgumentException('server_warning_threshold_invalid');
return true; }
} return true;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -27,6 +28,7 @@
**/ **/
namespace psm\Util\Server; namespace psm\Util\Server;
use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
@ -34,53 +36,56 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
* Run an update on all servers. * Run an update on all servers.
*/ */
class UpdateManager implements ContainerAwareInterface { class UpdateManager implements ContainerAwareInterface
{
use ContainerAwareTrait;
use ContainerAwareTrait; public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
function __construct(ContainerInterface $container) { /**
$this->container = $container; * Go :-)
} *
* @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated
*/
public function run($skip_perms = false)
{
// check if we need to restrict the servers to a certain user
$sql_join = '';
/** if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) {
* Go :-) // restrict by user_id
* $sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
* @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated
*/
public function run($skip_perms = false) {
// check if we need to restrict the servers to a certain user
$sql_join = '';
if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id
$sql_join = "JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON (
`us`.`user_id`={$this->container->get('user')->getUserId()} `us`.`user_id`={$this->container->get('user')->getUserId()}
AND `us`.`server_id`=`s`.`server_id` AND `us`.`server_id`=`s`.`server_id`
)"; )";
} }
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram` $sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,
FROM `".PSM_DB_PREFIX."servers` AS `s` `s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram`
FROM `" . PSM_DB_PREFIX . "servers` AS `s`
{$sql_join} {$sql_join}
WHERE `active`='yes' "; WHERE `active`='yes' ";
$servers = $this->container->get('db')->query($sql); $servers = $this->container->get('db')->query($sql);
$updater = new Updater\StatusUpdater($this->container->get('db')); $updater = new Updater\StatusUpdater($this->container->get('db'));
$notifier = new Updater\StatusNotifier($this->container->get('db')); $notifier = new Updater\StatusNotifier($this->container->get('db'));
foreach ($servers as $server) { foreach ($servers as $server) {
$status_old = ($server['status'] == 'on') ? true : false; $status_old = ($server['status'] == 'on') ? true : false;
$status_new = $updater->update($server['server_id']); $status_new = $updater->update($server['server_id']);
// notify the nerds if applicable // notify the nerds if applicable
$notifier->notify($server['server_id'], $status_old, $status_new); $notifier->notify($server['server_id'], $status_old, $status_new);
// clean-up time!! archive all records // clean-up time!! archive all records
$archive = new ArchiveManager($this->container->get('db')); $archive = new ArchiveManager($this->container->get('db'));
$archive->archive($server['server_id']); $archive->archive($server['server_id']);
$archive->cleanup($server['server_id']); $archive->cleanup($server['server_id']);
} }
if($notifier->combine){ if ($notifier->combine) {
$notifier->notifyCombined(); $notifier->notifyCombined();
} }
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -34,95 +35,97 @@
namespace psm\Util\Server\Updater; namespace psm\Util\Server\Updater;
use psm\Service\Database; use psm\Service\Database;
class StatusNotifier { class StatusNotifier
{
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
/** /**
* Send emails? * Send emails?
* @var boolean $send_emails * @var boolean $send_emails
*/ */
protected $send_emails = false; protected $send_emails = false;
/** /**
* Send sms? * Send sms?
* @var boolean $send_sms * @var boolean $send_sms
*/ */
protected $send_sms = false; protected $send_sms = false;
/** /**
* Send Pushover notification? * Send Pushover notification?
* @var boolean $send_pushover * @var boolean $send_pushover
*/ */
protected $send_pushover = false; protected $send_pushover = false;
/** /**
* Send telegram? * Send telegram?
* @var boolean $send_telegram * @var boolean $send_telegram
*/ */
protected $send_telegram = false; protected $send_telegram = false;
/** /**
* Save log records? * Save log records?
* @var boolean $save_log * @var boolean $save_log
*/ */
protected $save_logs = false; protected $save_logs = false;
/** /**
* Send multiple notifications as one? * Send multiple notifications as one?
* @var boolean $combine * @var boolean $combine
*/ */
public $combine = false; public $combine = false;
/** /**
* Notification list * Notification list
* @var array $combiNotification * @var array $combiNotification
*/ */
protected $combiNotification = array( protected $combiNotification = array(
'count' => array(), 'count' => array(),
'users' => array(), 'users' => array(),
'notifications' => array(), 'notifications' => array(),
'userNotifications' => array() 'userNotifications' => array()
); );
/** /**
* Server id * Server id
* @var int $server_id * @var int $server_id
*/ */
protected $server_id; protected $server_id;
/** /**
* Server information * Server information
* @var array $server * @var array $server
*/ */
protected $server; protected $server;
/** /**
* Old status * Old status
* @var boolean $status_old * @var boolean $status_old
*/ */
protected $status_old; protected $status_old;
/** /**
* New status * New status
* @var boolean $status_new * @var boolean $status_new
*/ */
protected $status_new; protected $status_new;
function __construct(Database $db) { public function __construct(Database $db)
$this->db = $db; {
$this->db = $db;
$this->send_emails = psm_get_conf('email_status'); $this->send_emails = psm_get_conf('email_status');
$this->send_sms = psm_get_conf('sms_status'); $this->send_sms = psm_get_conf('sms_status');
$this->send_pushover = psm_get_conf('pushover_status'); $this->send_pushover = psm_get_conf('pushover_status');
$this->send_telegram = psm_get_conf('telegram_status'); $this->send_telegram = psm_get_conf('telegram_status');
$this->save_logs = psm_get_conf('log_status'); $this->save_logs = psm_get_conf('log_status');
$this->combine = psm_get_conf('combine_notifications'); $this->combine = psm_get_conf('combine_notifications');
} }
/** /**
* This function initializes the sending (text msg, email, Pushover and Telegram) and logging * This function initializes the sending (text msg, email, Pushover and Telegram) and logging
@ -133,107 +136,119 @@ class StatusNotifier {
* @return boolean * @return boolean
* @throws \PHPMailer\PHPMailer\Exception * @throws \PHPMailer\PHPMailer\Exception
*/ */
public function notify($server_id, $status_old, $status_new) { public function notify($server_id, $status_old, $status_new)
if ( {
!$this->send_emails && if (
!$this->send_sms && !$this->send_emails &&
!$this->send_pushover && !$this->send_sms &&
!$this->send_telegram && !$this->send_pushover &&
!$this->save_logs !$this->send_telegram &&
) { !$this->save_logs
// seems like we have nothing to do. skip the rest ) {
return false; // seems like we have nothing to do. skip the rest
} return false;
$this->server_id = $server_id;
$this->status_old = $status_old;
$this->status_new = $status_new;
// get server info from db
// only get info that will be put into the notification
// or is needed to check if a notification need to be send
$this->server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array(
'server_id' => $server_id,
), array(
'server_id', 'ip', 'port', 'label', 'error', 'email', 'sms', 'pushover', 'telegram', 'last_online', 'last_offline', 'last_offline_duration',
));
if (empty($this->server)) {
return false;
}
$notify = false;
// check which type of alert the user wants
switch (psm_get_conf('alert_type')) {
case 'always':
if ($status_new == false) {
// server is offline. we are in error state.
$notify = true;
}
break;
case 'offline':
// only send a notification if the server goes down for the first time!
if ($status_new == false && $status_old == true) {
$notify = true;
}
break;
case 'status':
if ($status_new != $status_old) {
// status has been changed!
$notify = true;
}
break;
}
if (!$notify) {
return false;
}
// first add to log (we use the same text as the SMS message because its short..)
if ($this->save_logs) {
psm_add_log(
$this->server_id,
'status',
psm_parse_msg($status_new, 'sms', $this->server)
);
}
$users = $this->getUsers($this->server_id);
if (empty($users)) {
return $notify;
}
if($this->combine){
$this->setCombi('init', $users);
} }
// check if email is enabled for this server $this->server_id = $server_id;
if ($this->send_emails && $this->server['email'] == 'yes') { $this->status_old = $status_old;
// send email $this->status_new = $status_new;
$this->combine ? $this->setCombi('email') : $this->notifyByEmail($users);
}
// check if sms is enabled for this server // get server info from db
if ($this->send_sms && $this->server['sms'] == 'yes') { // only get info that will be put into the notification
// sms will not be send combined as some gateways don't support long sms / charge extra // or is needed to check if a notification need to be send
// yay lets wake those nerds up! $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
$this->notifyByTxtMsg($users); 'server_id' => $server_id,
} ), array(
'server_id',
'ip',
'port',
'label',
'error',
'email',
'sms',
'pushover',
'telegram',
'last_online',
'last_offline',
'last_offline_duration',
));
if (empty($this->server)) {
return false;
}
// check if pushover is enabled for this server $notify = false;
if ($this->send_pushover && $this->server['pushover'] == 'yes') {
// yay lets wake those nerds up!
$this->combine ? $this->setCombi('pushover') : $this->notifyByPushover($users);
}
// check if telegram is enabled for this server // check which type of alert the user wants
if ($this->send_telegram && $this->server['telegram'] == 'yes') { switch (psm_get_conf('alert_type')) {
$this->combine ? $this->setCombi('telegram') : $this->notifyByTelegram($users); case 'always':
} if ($status_new == false) {
// server is offline. we are in error state.
$notify = true;
}
break;
case 'offline':
// only send a notification if the server goes down for the first time!
if ($status_new == false && $status_old == true) {
$notify = true;
}
break;
case 'status':
if ($status_new != $status_old) {
// status has been changed!
$notify = true;
}
break;
}
return $notify; if (!$notify) {
} return false;
}
// first add to log (we use the same text as the SMS message because its short..)
if ($this->save_logs) {
psm_add_log(
$this->server_id,
'status',
psm_parse_msg($status_new, 'sms', $this->server)
);
}
$users = $this->getUsers($this->server_id);
if (empty($users)) {
return $notify;
}
if ($this->combine) {
$this->setCombi('init', $users);
}
// check if email is enabled for this server
if ($this->send_emails && $this->server['email'] == 'yes') {
// send email
$this->combine ? $this->setCombi('email') : $this->notifyByEmail($users);
}
// check if sms is enabled for this server
if ($this->send_sms && $this->server['sms'] == 'yes') {
// sms will not be send combined as some gateways don't support long sms / charge extra
// yay lets wake those nerds up!
$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->combine ? $this->setCombi('pushover') : $this->notifyByPushover($users);
}
// check if telegram is enabled for this server
if ($this->send_telegram && $this->server['telegram'] == 'yes') {
$this->combine ? $this->setCombi('telegram') : $this->notifyByTelegram($users);
}
return $notify;
}
/** /**
* This functions collects all of the notifications * This functions collects all of the notifications
@ -242,71 +257,75 @@ class StatusNotifier {
* @param array $users Users * @param array $users Users
* @return void * @return void
*/ */
public function setCombi($method, $users = array()) { public function setCombi($method, $users = array())
$status = $this->status_new ? 'on' : 'off'; {
$status = $this->status_new ? 'on' : 'off';
if ($method == 'init' && !empty($users)){ if ($method == 'init' && !empty($users)) {
foreach($users as $user) { foreach ($users as $user) {
if(!isset($this->combiNotification['count'][$user['user_id']])){ if (!isset($this->combiNotification['count'][$user['user_id']])) {
$this->combiNotification['count'][$user['user_id']] = array('on' => 0, 'off' => 0); $this->combiNotification['count'][$user['user_id']] = array('on' => 0, 'off' => 0);
} }
$this->combiNotification['userNotifications'][$user['user_id']][] = $this->server_id; $this->combiNotification['userNotifications'][$user['user_id']][] = $this->server_id;
$this->combiNotification['users'][$user['user_id']] = $user; $this->combiNotification['users'][$user['user_id']] = $user;
$this->combiNotification['count'][$user['user_id']][$status] += 1; $this->combiNotification['count'][$user['user_id']][$status] += 1;
} }
return; return;
} }
$this->combiNotification['notifications'][$method][$status][$this->server_id] = $this->combiNotification['notifications'][$method][$status][$this->server_id] =
psm_parse_msg($this->status_new, $method.'_message', $this->server, true); psm_parse_msg($this->status_new, $method . '_message', $this->server, true);
return; return;
} }
/** /**
* This functions returns the subject for a combined notification * This functions returns the subject for a combined notification
* *
* @return void * @return void
*/ */
public function notifyCombined() { public function notifyCombined()
if(empty($this->combiNotification['userNotifications'])){ {
return; if (empty($this->combiNotification['userNotifications'])) {
} return;
// Get the servers the user will get notified of }
// Get the servers the user will get notified of
$this->status_new = true; $this->status_new = true;
foreach ($this->combiNotification['userNotifications'] as $user => $servers) { foreach ($this->combiNotification['userNotifications'] as $user => $servers) {
$notifications = array(); $notifications = array();
// Combine all of the messages belonging to the server the user will get notification of // Combine all of the messages belonging to the server the user will get notification of
foreach ($servers as $server) { foreach ($servers as $server) {
foreach ($this->combiNotification['notifications'] as $method => $status){ foreach ($this->combiNotification['notifications'] as $method => $status) {
foreach ($status as $the_status => $value) { foreach ($status as $the_status => $value) {
if(!key_exists($method, $notifications)){ if (!key_exists($method, $notifications)) {
$notifications[$method] = array('on' => '', 'off' => ''); $notifications[$method] = array('on' => '', 'off' => '');
} }
if(key_exists($server, $status[$the_status])){ if (key_exists($server, $status[$the_status])) {
$notifications[$method][$the_status] .= $status[$the_status][$server]; $notifications[$method][$the_status] .= $status[$the_status][$server];
} }
// Set $this->status_new to false if a server is down. // Set $this->status_new to false if a server is down.
// This is used by Pushover to determine the priority. // This is used by Pushover to determine the priority.
if(!empty($notifications[$method]['off'])){ if (!empty($notifications[$method]['off'])) {
$this->status_new = false; $this->status_new = false;
} }
} }
} }
} }
// Send combined notification per user // Send combined notification per user
foreach ($notifications as $method => $notification){ foreach ($notifications as $method => $notification) {
$finalNotification['message'] = $this->createCombiMessage($method, $notification); $finalNotification['message'] = $this->createCombiMessage($method, $notification);
$subject = $this->createCombiSubject($method, $user); $subject = $this->createCombiSubject($method, $user);
if(!is_null($subject)){ if (!is_null($subject)) {
$finalNotification['subject'] = $subject; $finalNotification['subject'] = $subject;
} }
$this->{'notifyBy' . ucwords($method)} $this->{'notifyBy' . ucwords($method)}(
(array($this->combiNotification['users'][$user]), $finalNotification); array($this->combiNotification['users'][$user]),
$finalNotification
);
} }
} }
unset($notifications); unset($notifications);
return; return;
} }
/** /**
* This functions returns the message for a combined notification * This functions returns the message for a combined notification
@ -315,15 +334,16 @@ class StatusNotifier {
* @param array $notification Notification * @param array $notification Notification
* @return string * @return string
*/ */
protected function createCombiMessage($method, $notification){ protected function createCombiMessage($method, $notification)
if(empty($notification['off'])){ {
$notification['off'] = "<ul><li>".psm_get_lang('system', 'none')."</li></ul>"; if (empty($notification['off'])) {
$notification['off'] = "<ul><li>" . psm_get_lang('system', 'none') . "</li></ul>";
} }
if(empty($notification['on'])){ if (empty($notification['on'])) {
$notification['on'] = "<ul><li>".psm_get_lang('system', 'none')."</li></ul>"; $notification['on'] = "<ul><li>" . psm_get_lang('system', 'none') . "</li></ul>";
} }
$vars = array('DOWN_SERVERS' => $notification['off'], 'UP_SERVERS' => $notification['on']); $vars = array('DOWN_SERVERS' => $notification['off'], 'UP_SERVERS' => $notification['on']);
return psm_parse_msg(null, $method.'_message', $vars, true); return psm_parse_msg(null, $method . '_message', $vars, true);
} }
/** /**
@ -333,10 +353,14 @@ class StatusNotifier {
* @param integer $user_id User id * @param integer $user_id User id
* @return string|null * @return string|null
*/ */
protected function createCombiSubject($method, $user_id){ protected function createCombiSubject($method, $user_id)
$vars = array('DOWN' => $this->combiNotification['count'][$user_id]['off'], 'UP' => $this->combiNotification['count'][$user_id]['on']); {
$translation = isset($GLOBALS['sm_lang_default']['notifications']['combi_'.$method.'_subject']) ? $vars = array(
psm_parse_msg(null, $method.'_subject', $vars, true) : 'DOWN' => $this->combiNotification['count'][$user_id]['off'],
'UP' => $this->combiNotification['count'][$user_id]['on']
);
$translation = isset($GLOBALS['sm_lang_default']['notifications']['combi_' . $method . '_subject']) ?
psm_parse_msg(null, $method . '_subject', $vars, true) :
null; null;
return $translation; return $translation;
} }
@ -349,143 +373,150 @@ class StatusNotifier {
* @return void * @return void
* @throws \PHPMailer\PHPMailer\Exception * @throws \PHPMailer\PHPMailer\Exception
*/ */
protected function notifyByEmail($users, $combi = array()) { protected function notifyByEmail($users, $combi = array())
// build mail object with some default values {
$mail = psm_build_mail(); // build mail object with some default values
$mail->Subject = key_exists('subject', $combi) ? $mail = psm_build_mail();
$combi['subject'] : $mail->Subject = key_exists('subject', $combi) ?
psm_parse_msg($this->status_new, 'email_subject', $this->server); $combi['subject'] :
$mail->Priority = 1; psm_parse_msg($this->status_new, 'email_subject', $this->server);
$mail->Priority = 1;
$body = key_exists('message', $combi) ? $body = key_exists('message', $combi) ?
$combi['message'] : $combi['message'] :
psm_parse_msg($this->status_new, 'email_body', $this->server); psm_parse_msg($this->status_new, 'email_body', $this->server);
$mail->Body = $body; $mail->Body = $body;
$mail->AltBody = str_replace('<br/>', "\n", $body); $mail->AltBody = str_replace('<br/>', "\n", $body);
if (psm_get_conf('log_email')) { if (psm_get_conf('log_email')) {
$log_id = psm_add_log($this->server_id, 'email', $body); $log_id = psm_add_log($this->server_id, 'email', $body);
} }
// go through empl // go through empl
foreach ($users as $user) { foreach ($users as $user) {
if (!empty($log_id)) { if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']); psm_add_log_user($log_id, $user['user_id']);
} }
// we sent a separate email to every single user. // we sent a separate email to every single user.
$mail->AddAddress($user['email'], $user['name']); $mail->AddAddress($user['email'], $user['name']);
$mail->Send(); $mail->Send();
$mail->ClearAddresses(); $mail->ClearAddresses();
} }
return; return;
} }
/** /**
* This functions performs the pushover notifications * This functions performs the pushover notifications
* *
* @param \PDOStatement $users * @param \PDOStatement $users
* @param array $combi contains message and subject (optional) * @param array $combi contains message and subject (optional)
* @return void * @return void
*/ */
protected function notifyByPushover($users, $combi = array()) { protected function notifyByPushover($users, $combi = array())
// Remove users that have no pushover_key {
foreach ($users as $k => $user) { // Remove users that have no pushover_key
if (trim($user['pushover_key']) == '') { foreach ($users as $k => $user) {
unset($users[$k]); if (trim($user['pushover_key']) == '') {
} unset($users[$k]);
} }
}
// Validation // Validation
if (empty($users)) { if (empty($users)) {
return; return;
} }
// Pushover // Pushover
$message = key_exists('message', $combi) ? $message = key_exists('message', $combi) ?
$combi['message'] : $combi['message'] :
psm_parse_msg($this->status_new, 'pushover_message', $this->server); psm_parse_msg($this->status_new, 'pushover_message', $this->server);
$pushover = psm_build_pushover(); $pushover = psm_build_pushover();
if ($this->status_new === true) { if ($this->status_new === true) {
$pushover->setPriority(0); $pushover->setPriority(0);
} else { } else {
$pushover->setPriority(2); $pushover->setPriority(2);
$pushover->setRetry(300); //Used with Priority = 2; Pushover will resend the notification every 60 seconds until the user accepts. //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. $pushover->setRetry(300);
} // Used with Priority = 2; Pushover will resend the notification every 60 seconds for 3600 seconds.
$title = key_exists('subject', $combi) ? // After that point, it stops sending notifications.
$combi['subject'] : $pushover->setExpire(3600);
psm_parse_msg($this->status_new, 'pushover_title', $this->server); }
$pushover->setHtml(1); $title = key_exists('subject', $combi) ?
$pushover->setTitle($title); $combi['subject'] :
$pushover->setMessage(str_replace('<br/>', "\n", $message)); psm_parse_msg($this->status_new, 'pushover_title', $this->server);
$pushover->setUrl(psm_build_url()); $pushover->setHtml(1);
$pushover->setUrlTitle(psm_get_lang('system', 'title')); $pushover->setTitle($title);
$pushover->setMessage(str_replace('<br/>', "\n", $message));
$pushover->setUrl(psm_build_url());
$pushover->setUrlTitle(psm_get_lang('system', 'title'));
// Log // Log
if (psm_get_conf('log_pushover')) { if (psm_get_conf('log_pushover')) {
$log_id = psm_add_log($this->server_id, 'pushover', $message); $log_id = psm_add_log($this->server_id, 'pushover', $message);
} }
foreach ($users as $user) { foreach ($users as $user) {
// Log // Log
if (!empty($log_id)) { if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']); psm_add_log_user($log_id, $user['user_id']);
} }
// Set recipient + send // Set recipient + send
$pushover->setUser($user['pushover_key']); $pushover->setUser($user['pushover_key']);
if ($user['pushover_device'] != '') { if ($user['pushover_device'] != '') {
$pushover->setDevice($user['pushover_device']); $pushover->setDevice($user['pushover_device']);
} }
$pushover->send(); $pushover->send();
} }
} }
/** /**
* This functions performs the text message notifications * This functions performs the text message notifications
* *
* @param \PDOStatement $users * @param \PDOStatement $users
* @return boolean * @return boolean
*/ */
protected function notifyByTxtMsg($users) { protected function notifyByTxtMsg($users)
$sms = psm_build_sms(); {
if (!$sms) { $sms = psm_build_sms();
return false; if (!$sms) {
} return false;
}
$message = psm_parse_msg($this->status_new, 'sms', $this->server); $message = psm_parse_msg($this->status_new, 'sms', $this->server);
// Log // Log
if (psm_get_conf('log_sms')) { if (psm_get_conf('log_sms')) {
$log_id = psm_add_log($this->server_id, 'sms', $message); $log_id = psm_add_log($this->server_id, 'sms', $message);
} }
// add all users to the recipients list // add all users to the recipients list
foreach ($users as $user) { foreach ($users as $user) {
// Log // Log
if (!empty($log_id)) { if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']); psm_add_log_user($log_id, $user['user_id']);
} }
$sms->addRecipients($user['mobile']); $sms->addRecipients($user['mobile']);
} }
// Send sms // Send sms
$result = $sms->sendSMS($message); $result = $sms->sendSMS($message);
return $result; return $result;
} }
/** /**
* This functions performs the telegram notifications * This functions performs the telegram notifications
* *
* @param \PDOStatement $users * @param \PDOStatement $users
* @param array $combi contains message and subject (optional) * @param array $combi contains message and subject (optional)
* @return void * @return void
*/ */
protected function notifyByTelegram($users, $combi = array()) { protected function notifyByTelegram($users, $combi = array())
{
// Remove users that have no telegram_id // Remove users that have no telegram_id
foreach ($users as $k => $user) { foreach ($users as $k => $user) {
if (trim($user['telegram_id']) == '') { if (trim($user['telegram_id']) == '') {
@ -500,16 +531,16 @@ class StatusNotifier {
// Telegram // Telegram
$message = key_exists('message', $combi) ? $message = key_exists('message', $combi) ?
$combi['message'] : $combi['message'] :
psm_parse_msg($this->status_new, 'telegram_message', $this->server); psm_parse_msg($this->status_new, 'telegram_message', $this->server);
$telegram = psm_build_telegram(); $telegram = psm_build_telegram();
$telegram->setMessage($message); $telegram->setMessage($message);
// Log // Log
if (psm_get_conf('log_telegram')) { if (psm_get_conf('log_telegram')) {
$log_id = psm_add_log($this->server_id, 'telegram', $message); $log_id = psm_add_log($this->server_id, 'telegram', $message);
} }
foreach ($users as $user) { foreach ($users as $user) {
// Log // Log
if (!empty($log_id)) { if (!empty($log_id)) {
@ -520,21 +551,23 @@ class StatusNotifier {
} }
} }
/** /**
* Get all users for the provided server id * Get all users for the provided server id
* @param int $server_id * @param int $server_id
* @return \PDOStatement array * @return \PDOStatement array
*/ */
public function getUsers($server_id) { public function getUsers($server_id)
// find all the users with this server listed {
$users = $this->db->query(" // find all the users with this server listed
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, `u`.`pushover_device`, `u`.`telegram_id` $users = $this->db->query("
FROM `".PSM_DB_PREFIX."users` AS `u` SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`,
JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON ( `u`.`pushover_device`, `u`.`telegram_id`
FROM `" . PSM_DB_PREFIX . "users` AS `u`
JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id` `us`.`user_id`=`u`.`user_id`
AND `us`.`server_id` = {$server_id} AND `us`.`server_id` = {$server_id}
) )
"); ");
return $users; return $users;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -34,323 +35,353 @@
namespace psm\Util\Server\Updater; namespace psm\Util\Server\Updater;
use psm\Service\Database; use psm\Service\Database;
class StatusUpdater { class StatusUpdater
public $error = ''; {
public $error = '';
public $header = ''; public $header = '';
public $rtime = 0; public $rtime = 0;
public $status_new = false; public $status_new = false;
/** /**
* Database service * Database service
* @var \psm\Service\Database $db * @var \psm\Service\Database $db
*/ */
protected $db; protected $db;
/** /**
* Server id to check * Server id to check
* @var int $server_id * @var int $server_id
*/ */
protected $server_id; protected $server_id;
/** /**
* Server information * Server information
* @var array $server * @var array $server
*/ */
protected $server; protected $server;
function __construct(Database $db) { public function __construct(Database $db)
$this->db = $db; {
} $this->db = $db;
}
/** /**
* The function its all about. This one checks whether the given ip and port are up and running! * The function its all about. This one checks whether the given ip and port are up and running!
* If the server check fails it will try one more time, depending on the $max_runs. * If the server check fails it will try one more time, depending on the $max_runs.
* *
* Please note: if the server is down but has not met the warning threshold, this will return true * Please note: if the server is down but has not met the warning threshold, this will return true
* to avoid any "we are down" events. * to avoid any "we are down" events.
* *
* @todo Get last_output when there is a HTTP 50x error. * @todo Get last_output when there is a HTTP 50x error.
* *
* @param int $server_id * @param int $server_id
* @param int $max_runs how many times should the script recheck the server if unavailable. default is 2 * @param int $max_runs how many times should the script recheck the server if unavailable. default is 2
* @return boolean TRUE if server is up, FALSE otherwise * @return boolean TRUE if server is up, FALSE otherwise
*/ */
public function update($server_id, $max_runs = 2) { public function update($server_id, $max_runs = 2)
$this->server_id = $server_id; {
$this->error = ''; $this->server_id = $server_id;
$this->header = ''; $this->error = '';
$this->rtime = ''; $this->header = '';
$this->rtime = '';
// get server info from db // get server info from db
$this->server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array( $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
'server_id' => $server_id, 'server_id' => $server_id,
), array( ), array(
'server_id', 'ip', 'port', 'request_method', 'label', 'type', 'pattern', 'pattern_online', 'post_field', 'server_id', 'ip', 'port', 'request_method', 'label',
'allow_http_status', 'redirect_check', 'header_name', 'header_value', 'status', 'active', 'warning_threshold', 'type', 'pattern', 'pattern_online', 'post_field',
'warning_threshold_counter', 'timeout', 'website_username', 'website_password', 'last_offline' 'allow_http_status', 'redirect_check', 'header_name',
)); 'header_value', 'status', 'active', 'warning_threshold',
if (empty($this->server)) { 'warning_threshold_counter', 'timeout', 'website_username',
return false; 'website_password', 'last_offline'
} ));
if (empty($this->server)) {
return false;
}
switch ($this->server['type']) { switch ($this->server['type']) {
case 'ping': case 'ping':
$this->status_new = $this->updatePing($max_runs); $this->status_new = $this->updatePing($max_runs);
break; break;
case 'service': case 'service':
$this->status_new = $this->updateService($max_runs); $this->status_new = $this->updateService($max_runs);
break; break;
case 'website': case 'website':
$this->status_new = $this->updateWebsite($max_runs); $this->status_new = $this->updateWebsite($max_runs);
break; break;
} }
// update server status // update server status
$save = array( $save = array(
'last_check' => date('Y-m-d H:i:s'), 'last_check' => date('Y-m-d H:i:s'),
'error' => $this->error, 'error' => $this->error,
'rtime' => $this->rtime 'rtime' => $this->rtime
); );
if(!empty($this->error)){ if (!empty($this->error)) {
$save['last_error'] = $this->error; $save['last_error'] = $this->error;
} }
// log the uptime before checking the warning threshold, // log the uptime before checking the warning threshold,
// so that the warnings can still be reviewed in the server history. // so that the warnings can still be reviewed in the server history.
psm_log_uptime($this->server_id, (int) $this->status_new, $this->rtime); psm_log_uptime($this->server_id, (int) $this->status_new, $this->rtime);
if ($this->status_new == true) { if ($this->status_new == true) {
// if the server is on, add the last_online value and reset the error threshold counter // if the server is on, add the last_online value and reset the error threshold counter
$save['status'] = 'on'; $save['status'] = 'on';
$save['last_online'] = date('Y-m-d H:i:s'); $save['last_online'] = date('Y-m-d H:i:s');
$save['last_output'] = substr($this->header,0,5000); $save['last_output'] = substr($this->header, 0, 5000);
$save['warning_threshold_counter'] = 0; $save['warning_threshold_counter'] = 0;
if ($this->server['status'] == 'off') { if ($this->server['status'] == 'off') {
$online_date = new \DateTime($save['last_online']); $online_date = new \DateTime($save['last_online']);
$offline_date = new \DateTime($this->server['last_offline']); $offline_date = new \DateTime($this->server['last_offline']);
$difference = $online_date->diff($offline_date); $difference = $online_date->diff($offline_date);
$save['last_offline_duration'] = trim(psm_format_interval($difference)); $save['last_offline_duration'] = trim(psm_format_interval($difference));
} }
} else { } else {
// server is offline, increase the error counter and set last offline // server is offline, increase the error counter and set last offline
$save['warning_threshold_counter'] = $this->server['warning_threshold_counter'] + 1; $save['warning_threshold_counter'] = $this->server['warning_threshold_counter'] + 1;
$save['last_offline'] = date('Y-m-d H:i:s'); $save['last_offline'] = date('Y-m-d H:i:s');
$save['last_error_output'] = empty($this->header) ? "Could not get headers. probably HTTP 50x error." : $this->header; $save['last_error_output'] = empty($this->header) ?
"Could not get headers. probably HTTP 50x error." : $this->header;
if ($save['warning_threshold_counter'] < $this->server['warning_threshold']) { if ($save['warning_threshold_counter'] < $this->server['warning_threshold']) {
// the server is offline but the error threshold has not been met yet. // the server is offline but the error threshold has not been met yet.
// so we are going to leave the status "on" for now while we are in a sort of warning state.. // so we are going to leave the status "on" for now while we are in a sort of warning state..
$save['status'] = 'on'; $save['status'] = 'on';
$this->status_new = true; $this->status_new = true;
} else { } else {
$save['status'] = 'off'; $save['status'] = 'off';
if ($this->server['status'] == 'on') { if ($this->server['status'] == 'on') {
$save['last_offline'] = $save['last_check']; $save['last_offline'] = $save['last_check'];
} }
} }
} }
$this->db->save(PSM_DB_PREFIX.'servers', $save, array('server_id' => $this->server_id)); $this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id));
return $this->status_new; return $this->status_new;
}
} /**
* Check the current servers ping status - Code from http://stackoverflow.com/a/20467492
* @param int $max_runs
* @param int $run
* @return boolean
*/
protected function updatePing($max_runs, $run = 1)
{
// save response time
$starttime = microtime(true);
// set ping payload
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
/** $socket = socket_create(AF_INET, SOCK_RAW, 1);
* Check the current servers ping status - Code from http://stackoverflow.com/a/20467492 socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0));
* @param int $max_runs socket_connect($socket, $this->server['ip'], null);
* @param int $run
* @return boolean
*/
protected function updatePing($max_runs, $run = 1) {
// save response time
$starttime = microtime(true);
// set ping payload
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
$socket = socket_create(AF_INET, SOCK_RAW, 1); socket_send($socket, $package, strLen($package), 0);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0)); if (socket_read($socket, 255)) {
socket_connect($socket, $this->server['ip'], null); $status = true;
} else {
$status = false;
socket_send($socket, $package, strLen($package), 0); // set error message
if (socket_read($socket, 255)) { $errorcode = socket_last_error();
$status = true; $this->error = "Couldn't create socket [" . $errorcode . "]: " . socket_strerror($errorcode);
} else { }
$status = false; $this->rtime = microtime(true) - $starttime;
socket_close($socket);
// set error message // check if server is available and rerun if asked.
$errorcode = socket_last_error(); if (!$status && $run < $max_runs) {
$this->error = "Couldn't create socket [".$errorcode."]: ".socket_strerror($errorcode); return $this->updatePing($max_runs, $run + 1);
} }
$this->rtime = microtime(true) - $starttime;
socket_close($socket);
// check if server is available and rerun if asked. return $status;
if (!$status && $run < $max_runs) { }
return $this->updatePing($max_runs, $run + 1);
}
return $status; /**
} * Check the current server as a service
* @param int $max_runs
* @param int $run
* @return boolean
*/
protected function updateService($max_runs, $run = 1)
{
$timeout = ($this->server['timeout'] === null || $this->server['timeout'] > 0) ?
PSM_CURL_TIMEOUT : intval($this->server['timeout']);
$errno = 0;
// save response time
$starttime = microtime(true);
/** $fp = @fsockopen($this->server['ip'], $this->server['port'], $errno, $this->error, $timeout);
* Check the current server as a service
* @param int $max_runs
* @param int $run
* @return boolean
*/
protected function updateService($max_runs, $run = 1) {
$timeout = ($this->server['timeout'] === null || $this->server['timeout'] > 0) ? PSM_CURL_TIMEOUT : intval($this->server['timeout']);
$errno = 0;
// save response time
$starttime = microtime(true);
$fp = @fsockopen($this->server['ip'], $this->server['port'], $errno, $this->error, $timeout); $status = ($fp === false) ? false : true;
$this->rtime = (microtime(true) - $starttime);
$status = ($fp === false) ? false : true; if (is_resource($fp)) {
$this->rtime = (microtime(true) - $starttime); fclose($fp);
}
if (is_resource($fp)) { // check if server is available and rerun if asked.
fclose($fp); if (!$status && $run < $max_runs) {
} return $this->updateService($max_runs, $run + 1);
}
// check if server is available and rerun if asked. return $status;
if (!$status && $run < $max_runs) { }
return $this->updateService($max_runs, $run + 1);
}
return $status; /**
} * Check the current server as a website
* @param int $max_runs
* @param int $run
* @return boolean
*/
protected function updateWebsite($max_runs, $run = 1)
{
$starttime = microtime(true);
/** // We're only interested in the header, because that should tell us plenty!
* Check the current server as a website // unless we have a pattern to search for!
* @param int $max_runs $curl_result = psm_curl_get(
* @param int $run $this->server['ip'],
* @return boolean true,
*/ ($this->server['pattern'] == '' ? false : true),
protected function updateWebsite($max_runs, $run = 1) { $this->server['timeout'],
$starttime = microtime(true); true,
$this->server['website_username'],
psm_password_decrypt($this->server['server_id'] .
psm_get_conf('password_encrypt_key'), $this->server['website_password']),
$this->server['request_method'],
$this->server['post_field']
);
$this->header = $curl_result;
// We're only interested in the header, because that should tell us plenty! $this->rtime = (microtime(true) - $starttime);
// unless we have a pattern to search for!
$curl_result = psm_curl_get(
$this->server['ip'],
true,
($this->server['pattern'] == '' ? false : true),
$this->server['timeout'],
true,
$this->server['website_username'],
psm_password_decrypt($this->server['server_id'].psm_get_conf('password_encrypt_key'), $this->server['website_password']),
$this->server['request_method'],
$this->server['post_field']
);
$this->header = $curl_result;
$this->rtime = (microtime(true) - $starttime); // the first line would be the status code..
$status_code = strtok($curl_result, "\r\n");
// keep it general
// $code[2][0] = status code
// $code[3][0] = name of status code
$code_matches = array();
preg_match_all("/[A-Z]{2,5}\/\d(\.\d)?\s(\d{3})\s?(.*)/", $status_code, $code_matches);
// the first line would be the status code.. if (empty($code_matches[0])) {
$status_code = strtok($curl_result, "\r\n"); // somehow we dont have a proper response.
// keep it general $this->error = 'TIMEOUT ERROR: no response from server';
// $code[2][0] = status code $result = false;
// $code[3][0] = name of status code } else {
$code_matches = array(); $code = $code_matches[2][0];
preg_match_all("/[A-Z]{2,5}\/\d(\.\d)?\s(\d{3})\s?(.*)/", $status_code, $code_matches); $msg = $code_matches[3][0];
if(empty($code_matches[0])) { $allow_http_status = explode("|", $this->server['allow_http_status']);
// somehow we dont have a proper response. // All status codes starting with a 4 or higher mean trouble!
$this->error = 'TIMEOUT ERROR: no response from server'; if (substr($code, 0, 1) >= '4' && !in_array($code, $allow_http_status)) {
$result = false; $this->error = "HTTP STATUS ERROR: " . $code . ' ' . $msg;
} else { $result = false;
$code = $code_matches[2][0]; } else {
$msg = $code_matches[3][0]; $result = true;
$allow_http_status = explode("|", $this->server['allow_http_status']); // Okay, the HTTP status is good : 2xx or 3xx. Now we have to test the pattern if it's set up
// All status codes starting with a 4 or higher mean trouble! if ($this->server['pattern'] != '') {
if (substr($code, 0, 1) >= '4' && !in_array($code ,$allow_http_status)) { // Check to see if the body should not contain specified pattern
$this->error = "HTTP STATUS ERROR: ".$code.' '.$msg; // Check to see if the pattern was [not] found.
$result = false; if (
} else { ($this->server['pattern_online'] == 'yes') ==
$result = true; !preg_match(
"/{$this->server['pattern']}/i",
$curl_result
)
) {
$this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " .
($this->server['pattern_online'] == 'yes' ? 'not' : 'was') .
' found.';
$result = false;
}
}
// Okay, the HTTP status is good : 2xx or 3xx. Now we have to test the pattern if it's set up // Check if the website redirects to another domain
if ($this->server['pattern'] != '') { if ($this->server['redirect_check'] == 'bad') {
// Check to see if the body should not contain specified pattern $location_matches = array();
// Check to see if the pattern was [not] found. preg_match(
if (($this->server['pattern_online'] == 'yes') == !preg_match("/{$this->server['pattern']}/i", $curl_result)) { '/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/',
$this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' ". $curl_result,
($this->server['pattern_online'] == 'yes' ? 'not' : 'was'). $location_matches
' found.'; );
$result = false; if (!empty($location_matches)) {
}
}
// Check if the website redirects to another domain
if ($this->server['redirect_check'] == 'bad'){
$location_matches = array();
preg_match('/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/', $curl_result, $location_matches);
if(!empty($location_matches)) {
$ip_matches = array(); $ip_matches = array();
preg_match('/(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)?/', $this->server['ip'], $ip_matches); preg_match(
'/(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)?/',
$this->server['ip'],
$ip_matches
);
if (strtolower($location_matches[4]) !== strtolower($ip_matches[3])) { if (strtolower($location_matches[4]) !== strtolower($ip_matches[3])) {
$this->error = "The IP/URL redirects to another domain."; $this->error = "The IP/URL redirects to another domain.";
$result = false; $result = false;
} }
} }
} }
// Should we check a header ? // Should we check a header ?
if ($this->server['header_name'] != '' && $this->server['header_value'] != '') { if ($this->server['header_name'] != '' && $this->server['header_value'] != '') {
$header_flag = false; $header_flag = false;
$header_text = substr($curl_result, 0, strpos($curl_result, "\r\n\r\n")); // Only get the header text if the result also includes the body // Only get the header text if the result also includes the body
foreach (explode("\r\n", $header_text) as $i => $line) { $header_text = substr($curl_result, 0, strpos($curl_result, "\r\n\r\n"));
if ($i === 0 || strpos($line, ':') == false) { foreach (explode("\r\n", $header_text) as $i => $line) {
continue; // We skip the status code & other non-header lines. Needed for proxy or redirects if ($i === 0 || strpos($line, ':') == false) {
} else { continue; // We skip the status code & other non-header lines. Needed for proxy or redirects
list ($key, $value) = explode(': ', $line); } else {
if (strcasecmp($key, $this->server['header_name']) == 0) { // Header found (case-insensitive) list ($key, $value) = explode(': ', $line);
if (!preg_match("/{$this->server['header_value']}/i", $value)) { // The value doesn't match what we needed // Header found (case-insensitive)
$result = false; if (strcasecmp($key, $this->server['header_name']) == 0) {
} else { // The value doesn't match what we needed
$header_flag = true; if (!preg_match("/{$this->server['header_value']}/i", $value)) {
break; // No need to go further $result = false;
} } else {
} $header_flag = true;
} break; // No need to go further
} }
}
}
}
if (!$header_flag) { if (!$header_flag) {
// Header was not present // Header was not present
$result = false; $result = false;
} }
} }
} }
} }
// check if server is available and rerun if asked. // check if server is available and rerun if asked.
if (!$result && $run < $max_runs) { if (!$result && $run < $max_runs) {
return $this->updateWebsite($max_runs, $run + 1); return $this->updateWebsite($max_runs, $run + 1);
} }
return $result; return $result;
} }
/** /**
* Get the error returned by the update function * Get the error returned by the update function
* *
* @return string * @return string
*/ */
public function getError() { public function getError()
return $this->error; {
} return $this->error;
}
/** /**
* Get the response time of the server * Get the response time of the server
* *
* @return string * @return string
*/ */
public function getRtime() { public function getRtime()
return $this->rtime; {
} return $this->rtime;
}
} }

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP Server Monitor * PHP Server Monitor
* Monitor your servers and websites. * Monitor your servers and websites.
@ -31,134 +32,143 @@ namespace psm\Util\User;
/** /**
* The UserValidator helps you to check input data for user accounts. * The UserValidator helps you to check input data for user accounts.
*/ */
class UserValidator { class UserValidator
{
/** /**
* Available editable user levels * Available editable user levels
* @var array $user_levels * @var array $user_levels
*/ */
protected $user_levels = array(PSM_USER_ADMIN, PSM_USER_USER); protected $user_levels = array(PSM_USER_ADMIN, PSM_USER_USER);
/** /**
* User service * User service
* @var \psm\Service\User $user * @var \psm\Service\User $user
*/ */
protected $user; protected $user;
public function __construct(\psm\Service\User $user) { public function __construct(\psm\Service\User $user)
$this->user = $user; {
} $this->user = $user;
}
/** /**
* Check if the user id exists * Check if the user id exists
* @param int $user_id * @param int $user_id
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function userId($user_id) { public function userId($user_id)
$user = $this->user->getUser($user_id); {
if (empty($user)) { $user = $this->user->getUser($user_id);
throw new \InvalidArgumentException('user_no_match'); if (empty($user)) {
} throw new \InvalidArgumentException('user_no_match');
return true; }
} return true;
}
/** /**
* Check username on: * Check username on:
* *
* - Length (2-64 chars) * - Length (2-64 chars)
* - Contents (alphabetic chars and digits only) * - Contents (alphabetic chars and digits only)
* - Unique * - Unique
* @param string $username * @param string $username
* @param int $user_id to check whether the username is unique * @param int $user_id to check whether the username is unique
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function username($username, $user_id = 0) { public function username($username, $user_id = 0)
if (strlen($username) > 64 || strlen($username) < 2) { {
throw new \InvalidArgumentException('user_name_bad_length'); if (strlen($username) > 64 || strlen($username) < 2) {
} throw new \InvalidArgumentException('user_name_bad_length');
if (!preg_match('/^[a-zA-Z\d_\.]{2,64}$/i', $username)) { }
throw new \InvalidArgumentException('user_name_invalid'); if (!preg_match('/^[a-zA-Z\d_\.]{2,64}$/i', $username)) {
} throw new \InvalidArgumentException('user_name_invalid');
$user_exists = $this->user->getUserByUsername($username); }
$user_exists = $this->user->getUserByUsername($username);
if (!empty($user_exists) && ($user_id == 0 || $user_id != $user_exists->user_id)) { if (!empty($user_exists) && ($user_id == 0 || $user_id != $user_exists->user_id)) {
throw new \InvalidArgumentException('user_name_exists'); throw new \InvalidArgumentException('user_name_exists');
} }
return true; return true;
} }
/** /**
* Check user password * Check user password
* @param string $password * @param string $password
* @param string $password_repeat * @param string $password_repeat
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function password($password, $password_repeat) { public function password($password, $password_repeat)
if (empty($password) || empty($password_repeat)) { {
throw new \InvalidArgumentException('user_password_invalid'); if (empty($password) || empty($password_repeat)) {
} throw new \InvalidArgumentException('user_password_invalid');
if ($password !== $password_repeat) { }
throw new \InvalidArgumentException('user_password_no_match'); if ($password !== $password_repeat) {
} throw new \InvalidArgumentException('user_password_no_match');
return true; }
} return true;
}
/** /**
* Install only; Check username on: * Install only; Check username on:
* *
* - Length (2-64 chars) * - Length (2-64 chars)
* - Contents (alphabetic chars and digits only) * - Contents (alphabetic chars and digits only)
* @param string $username * @param string $username
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function username_new($username) { public function usernameNew($username)
if (strlen($username) > 64 || strlen($username) < 2) { {
throw new \InvalidArgumentException('user_name_bad_length'); if (strlen($username) > 64 || strlen($username) < 2) {
} throw new \InvalidArgumentException('user_name_bad_length');
if (!preg_match('/^[a-zA-Z\d_\.]{2,64}$/i', $username)) { }
throw new \InvalidArgumentException('user_name_invalid'); if (!preg_match('/^[a-zA-Z\d_\.]{2,64}$/i', $username)) {
} throw new \InvalidArgumentException('user_name_invalid');
return true; }
} return true;
}
/** /**
* Check email * Check email
* @param string $email * @param string $email
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function email($email) { public function email($email)
if (strlen($email) > 255 || strlen($email) < 5) { {
throw new \InvalidArgumentException('user_email_bad_length'); if (strlen($email) > 255 || strlen($email) < 5) {
} throw new \InvalidArgumentException('user_email_bad_length');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { }
throw new \InvalidArgumentException('user_email_invalid'); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
} throw new \InvalidArgumentException('user_email_invalid');
return true; }
} return true;
}
/** /**
* Check user level * Check user level
* @param int $level * @param int $level
* @return boolean * @return boolean
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function level($level) { public function level($level)
if (!in_array($level, $this->user_levels)) { {
throw new \InvalidArgumentException('user_level_invalid'); if (!in_array($level, $this->user_levels)) {
} throw new \InvalidArgumentException('user_level_invalid');
return true; }
} return true;
}
/** /**
* Get list of all available user levels * Get list of all available user levels
* @return array * @return array
*/ */
public function getUserLevels() { public function getUserLevels()
return $this->user_levels; {
} return $this->user_levels;
}
} }