REL-0.9 Intranet refactoring

This commit is contained in:
cytopia
2017-05-15 08:56:17 +02:00
parent 83ab3d8758
commit f1b88a9c60
39 changed files with 1830 additions and 1680 deletions

View File

@ -0,0 +1,246 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class BaseClass
{
/*********************************************************************************
*
* Statics
*
*********************************************************************************/
/**
* Class instance
* @var array
*/
private static $_instance = array();
/**
* Generic singleton instance getter.
* Make sure to overwrite this in your class
* for a more complex initialization.
*
* @param string $hostname Hostname
* @param array $data Additional data (if required)
* @return object|null
*/
public static function getInstance($hostname, $data = array())
{
if (!isset(self::$_instance[$hostname])) {
self::$_instance[$hostname] = new static($hostname, $data);
}
return self::$_instance[$hostname];
}
/*********************************************************************************
*
* Instance
*
*********************************************************************************/
/**
* Hostname
* @var string
*/
private $_hostname = null;
/**
* Container is running
* @var boolean
*/
private $_available = null;
/**
* Connection error string
* @var string
*/
private $_connect_error = '';
/**
* Connection error code
* @var integer
*/
private $_connect_errno = 0;
/**
* Error string
* @var string
*/
private $_error = '';
/**
* Error code
* @var integer
*/
private $_errno = 0;
/*********************************************************************************
*
* Private constructor for singleton
*
*********************************************************************************/
/**
* DO NOT CALL ME!
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
*/
public function __construct($hostname, $data = array())
{
$this->_hostname = $hostname;
}
/*********************************************************************************
*
* Public Default Interface Implementations
*
*********************************************************************************/
/**
* Check if this container is available.
* Note, this is a very basic check to see if its IP address
* can be resolved. Implement a better check in the actual class
* if it is required.
*
* @return boolean available
*/
public function isAvailable()
{
// Request was already done before and is cached
if (isset($this->_available[$this->_hostname])) {
return $this->_available[$this->_hostname];
}
// New request, check if hostname was set
if ($this->_hostname === null) {
loadClass('Logger')->error('Hostname has not been initialized. Cannot determine if it is available.');
$this->_available = false;
return false;
}
// New request, generic check
$ip = $this->getIpAddress();
$this->_available[$this->_hostname] = ($ip && $ip != $this->_hostname) ? true : false;
return $this->_available[$this->_hostname];
}
/**
* Retrieve the IP address of the container.
*
* @return string|boolean IP address or false
*/
public function getIpAddress()
{
// Check if hostname was set
if ($this->_hostname === null) {
loadClass('Logger')->error('Hostname has not been initialized. Cannot determine IP address.');
return false;
}
return loadClass('Helper')->getIpAddress($this->_hostname);
}
/*********************************************************************************
*
* Connection Error Getter/Setter
*
*********************************************************************************/
/**
* Set Connection Error Message.
*
* @param string $error Error Message
*/
public function setConnectError($error)
{
$this->_connect_error = $error;
}
/**
* Set Connection Error Code.
*
* @param integer $errno Error Code
*/
public function setConnectErrno($errno)
{
$this->_connect_erro = $errno;
}
/**
* Set Error Message.
*
* @param string $error Error message
*/
public function setError($error)
{
$this->_error = $error;
}
/**
* Set Error Code.
*
* @param integer $errno Error Code
*/
public function setErrno($errno)
{
$this->_erro = $errno;
}
/**
* Return connection error message.
*
* @return string Error message
*/
public function getConnectError()
{
return $this->_connect_error;
}
/**
* Return connection errno code.
*
* @return integer Error code
*/
public function getConnectErrno()
{
return $this->_connect_errno;
}
/**
* Return error message.
*
* @return string Error message
*/
public function getError()
{
return $this->_error;
}
/**
* Return errno code.
*
* @return integer Error code
*/
public function getErrno()
{
return $this->_errno;
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace devilbox;
/**
* Interface
*
* Must be implemented by all devilbox service classes.
* @see _Base.php: Most functions will have a default implementationin the mother class
*/
interface BaseInterface
{
/**
* Get singleton instance
*
* @param string $hostname Internal Hostname of docker (as described in docker-compose.yml)
* @param array $data Additional data required for the container (username, password, db...)
* @return object Returns class object
*/
public static function getInstance($hostname, $data = array());
/**
* The constructor of this type must be implemented by each class.
* Note, the constructor MUST set the hostname!
*
* @param string $hostname Internal Hostname of docker (as described in docker-compose.yml)
* @param array $data Additional data required for the container (username, password, db...)
*/
public function __construct($hostname, $data = array());
/**
* Check if the PHP container can connect to the specified service.
* Additional arguments (user, pass, port, etc) can be specified
* withing the $data array.
*
* @param string|bool &$err Connection error string or false
* @param string $hostname Hostname to connect to (127.0.0.1, host, IP, ...)
* @param array $data Optional data (user, pass, port...)
* @return bool Can we connect?
*/
public function canConnect(&$err, $hostname, $data = array());
/**
* Check if the container is running/available
*
* @return boolean Running state
*/
public function isAvailable();
/**
* Get the IP Address of the container
*
* @return string|boolean IP Address or false if it cannot be determined
*/
public function getIpAddress();
/**
* Retrieve name of the service the docker container provides.
*
* @param string $default Default name if it can't be found
* @return string Name
*/
public function getName($default);
/**
* Get version string of the service the docker container provides.
*
* @return string Version string
*/
public function getVersion();
}

View File

@ -0,0 +1,65 @@
<?php
namespace devilbox;
class Dns extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_version = null;
private $_can_connect = array();
private $_can_connect_err = array();
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
$version = $this->getVersion();
if (strlen($version)) {
$this->_can_connect[$hostname] = true;
} else {
$err = 'Could not connect to Bind via hostname: '.$hostname;
$this->_can_connect[$hostname] = false;
}
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'Bind')
{
return $default;
}
public function getVersion()
{
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
$cmd = 'dig +time=1 +tries=1 @'.$this->getIpAddress().' version.bind chaos TXT | grep -iE "^version\.bind.*TXT"';
$output = loadClass('Helper')->exec($cmd);
$version = loadClass('Helper')->egrep('/"[0-9.-]+.*"/', $output);
$version = loadClass('Helper')->egrep('/[0-9.-]+/', $version);
// Cache and return
$this->_version = $version ? $version : '';
return $this->_version;
}
}

View File

@ -0,0 +1,202 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Httpd extends BaseClass implements BaseInterface
{
private $_docRoot = '/shared/httpd';
/*********************************************************************************
*
* Select/Check Functions
*
*********************************************************************************/
/**
* Check single mass virtual host
*
* @param string $vhost Virtual Host name
* @return string Errors
*/
public function checkVirtualHost($vhost)
{
$htdocs = $this->_docRoot . DIRECTORY_SEPARATOR . $vhost . DIRECTORY_SEPARATOR . 'htdocs';
$domain = $vhost . '.' . $this->getTldSuffix();
$url = 'http://'.$domain;
$error = array();
// 1. Check htdocs folder
if (!$this->_is_valid_dir($htdocs)) {
$error[] = 'Missing <strong>htdocs</strong> directory in: <strong>'.loadClass('Helper')->getEnv('HOST_PATH_HTTPD_DATADIR').'/'.$vhost.'/</strong>';
}
if ($GLOBALS['ENABLE_VHOST_DNS_CHECK']) {
// 2. Check /etc/resolv DNS entry
$output;
if (loadClass('Helper')->exec('getent hosts '.$domain, $output) !== 0) {
$error[] = 'Missing entry in <strong>/etc/hosts</strong>:<br/><code>127.0.0.1 '.$domain.'</code>';
}
// 3. Check correct /etc/resolv entry
$dns_ip = '127.0.0.1';
if (isset($output[0])) {
$tmp = explode(' ', $output[0]);
if (isset($tmp[0])) {
$dns_ip = $tmp[0];
}
}
if ($dns_ip != '127.0.0.1') {
$error[] = 'Error in <strong>/etc/hosts</strong><br/>'.
'Found:<br/>'.
'<code>'.$dns_ip.' '.$domain.'</code><br/>'.
'But it should be:<br/>'.
'<code>127.0.0.1 '.$domain.'</code><br/>';
}
}
if (is_array($error) && count($error)) {
return implode('<br/>', $error);
} else {
return '';
}
}
/**
* Get all mass virtual Hosts by directories
*
* @return mixed[]
*/
public function getVirtualHosts()
{
$docRoot = $this->_docRoot;
$vhosts = array();
if ($handle = opendir($docRoot)) {
while (false !== ($directory = readdir($handle))) {
if ($this->_is_valid_dir($docRoot . DIRECTORY_SEPARATOR . $directory) && $directory != '.' && $directory != '..') {
$vhosts[] = array(
'name' => $directory,
'domain' => $directory .'.' . $this->getTldSuffix(),
'href' => 'http://' . $directory . '.' . $this->getTldSuffix()
);
}
}
}
return $vhosts;
}
public function getTldSuffix()
{
return loadClass('Helper')->getEnv('TLD_SUFFIX');
}
/**
* Get HTTP port.
*
* @return string
*/
public function getPort()
{
$port = loadClass('Helper')->getEnv('HOST_PORT_HTTPD');
if ( empty($port) ) {
return '';
}
if ( $port == 80 ) {
return '';
}
return ":$port";
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_can_connect = array();
private $_can_connect_err = array();
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
// Silence errors and try to connect
$url = 'http://'.$hostname.'/'.$GLOBALS['DEVILBOX_API_PAGE'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 0) {
$err = 'Failed to connect to Httpd host on '.$hostname;
$this->_can_connect[$hostname] = false;
} else {
$this->_can_connect[$hostname] = true;
}
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'Httpd')
{
$name = loadClass('Helper')->egrep('/[a-zA-Z0-9]+/', $_SERVER['SERVER_SOFTWARE']);
if (!$name) {
loadClass('Logger')->error('Could not get Httpd name');
return $default;
}
return $name;
}
public function getVersion()
{
$version = loadClass('Helper')->egrep('/[.0-9]+/', $_SERVER['SERVER_SOFTWARE']);
if (!$version) {
loadClass('Logger')->error('Could not get Httpd version');
return '';
}
return $version;
}
/*********************************************************************************
*
* Private functions
*
*********************************************************************************/
/**
* Check if the directory exists or
* in case of a symlink the target is an
* existing directory.
*
* @param string $path The path.
* @return boolean
*/
private function _is_valid_dir($path)
{
return (is_dir($path) || (is_link($path) && is_dir(readlink($path))));
}
}

View File

@ -0,0 +1,218 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Memcd extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* Memcached instance
* @var object|null
*/
private $_memcached = null;
/*********************************************************************************
*
* Constructor Overwrite
*
*********************************************************************************/
/**
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
*/
public function __construct($hostname, $data = array())
{
parent::__construct($hostname, $data);
$memcd = new \Memcached('_devilbox');
$list = $memcd->getServerList();
// if (!empty($list)) {
// $memcd->resetServerList();
// }
if (empty($list)) {
//$memcd->setOption(\Memcached::OPT_RECV_TIMEOUT, 100);
//$memcd->setOption(\Memcached::OPT_SEND_TIMEOUT, 100);
$memcd->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$memcd->setOption(\Memcached::OPT_BINARY_PROTOCOL, false);
//$memcd->setOption(\Memcached::OPT_SERVER_FAILURE_LIMIT, 50);
//$memcd->setOption(\Memcached::OPT_CONNECT_TIMEOUT, 100);
//$memcd->setOption(\Memcached::OPT_RETRY_TIMEOUT, 100);
//$memcd->setOption(\Memcached::OPT_REMOVE_FAILED_SERVERS, true);
$memcd->addServer($hostname, 11211);
}
$err = false;
$stats = $memcd->getStats();
if (!isset($stats[$hostname.':11211'])) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (no connection array)';
$this->_connect_errno = 1;
return;
}
else if (!isset($stats[$hostname.':11211']['pid'])) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (no pid)';
$this->_connect_errno = 2;
return;
}
else if ($stats[$hostname.':11211']['pid'] < 1) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (invalid pid)';
$this->_connect_errno = 3;
return;
}
$memcd->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
$this->_memcached = $memcd;
}
/**
* Destructor
*/
public function __destruct()
{
if ($this->_memcached) {
$this->_memcached->quit();
}
}
/*********************************************************************************
*
* Select functions
*
*********************************************************************************/
public function getKeys()
{
$store = array();
if ($this->_memcached) {
if (!($keys = $this->_memcached->getAllKeys())) {
$keys = array();
}
$this->_memcached->getDelayed($keys);
$store = $this->_memcached->fetchAll();
}
return $store;
}
public function getInfo()
{
$stats = array();
if ($this->_memcached) {
$stats = $this->_memcached->getStats();
}
return $stats;
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_can_connect = array();
private $_can_connect_err = array();
private $_name = null;
private $_version = null;
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
// Silence errors and try to connect
//error_reporting(-1);
$memcd = new \Memcached();
$memcd->resetServerList();
if (!$memcd->addServer($hostname, 11211)) {
$memcd->quit();
$err = 'Failed to connect to Memcached host on '.$hostname;
$this->_can_connect[$hostname] = false;
$this->_can_connect_err[$hostname] = $err;
return false;
}
$stats = $memcd->getStats();
if (!isset($stats[$hostname.':11211'])) {
$err = 'Failed to connect to Memcached host on '.$hostname;
$this->_can_connect[$hostname] = false;
}
else if (!isset($stats[$hostname.':11211']['pid'])) {
$err = 'Failed to connect to Memcached host on '.$hostname;
$this->_can_connect[$hostname] = false;
}
else if ($stats[$hostname.':11211']['pid'] < 1) {
$err = 'Failed to connect to Memcached host on '.$hostname;
$this->_can_connect[$hostname] = false;
}
else {
$this->_can_connect[$hostname] = true;
}
$memcd->quit();
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'Memcached')
{
return $default;
}
public function getVersion()
{
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
// Return empty if not available
if (!$this->isAvailable()) {
$this->_version = '';
return $this->_version;
}
if ($this->_memcached) {
$info = $this->_memcached->getVersion();
$info = array_values($info);
if (!isset($info[0])) {
loadClass('Logger')->error('Could not get Memcached version');
$this->_version = '';
} else {
$this->_version = $info[0];
}
}
return $this->_version;
}
}

View File

@ -0,0 +1,310 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Mysql extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* Variables
*
*********************************************************************************/
/**
* MySQL connection link
* @var null
*/
private $_link = null;
/*********************************************************************************
*
* Constructor Overwrite
*
*********************************************************************************/
public function __construct($hostname, $data = array())
{
parent::__construct($hostname, $data);
$user = $data['user'];
$pass = $data['pass'];
// Silence errors and try to connect
error_reporting(0);
$link = mysqli_connect($hostname, $user, $pass);
error_reporting(-1);
if (mysqli_connect_errno()) {
$this->setConnectError('Failed to connect: ' .mysqli_connect_error());
$this->setConnectErrno(mysqli_connect_errno());
//loadClass('Logger')->error($this->_connect_error);
} else {
$this->_link = $link;
}
}
public function __destruct()
{
if ($this->_link) {
mysqli_close($this->_link);
}
}
/*********************************************************************************
*
* Select Functions
*
*********************************************************************************/
/**
* Query Database
*
* @param string $query MySQL Query
* @param function $callback Callback function
* @return mixed[]
*/
public function select($query, $callback = null)
{
if (!$this->_link) {
loadClass('Logger')->error('MySQL error, link is no resource in select(): '.$query);
return false;
}
if (!($result = mysqli_query($this->_link, $query))) {
$this->setError(mysqli_error($this->_link));
$this->setErrno(mysqli_errno($this->_link));
loadClass('Logger')->error($this->getError());
return false;
}
$data = array();
if ($callback) {
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$callback($row, $data);
}
} else {
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$data[] = $row;
}
}
mysqli_free_result($result);
return $data;
}
/**
* Get all MySQL Databases.
* @return mixed[] Array of databases
*/
public function getDatabases()
{
$callback = function ($row, &$data) {
$data[$row['database']] = array(
'charset' => $row['charset'],
'collation' => $row['collation']
);
};
$sql = "SELECT
S.SCHEMA_NAME AS 'database',
S.DEFAULT_COLLATION_NAME AS 'collation',
S.default_character_set_name AS 'charset'
FROM
information_schema.SCHEMATA AS S;";
$databases = $this->select($sql, $callback);
return $databases ? $databases : array();
}
/**
* Get Database size in Megabytes.
*
* @param string $database Database name.
* @return integer
*/
public function getDBSize($database)
{
$callback = function ($row, &$data) {
$data = $row['size'];
};
$sql = "SELECT
ROUND( SUM((T.data_length+T.index_length)/1048576), 2 ) AS 'size'
FROM
information_schema.TABLES AS T
WHERE
T.TABLE_SCHEMA = '".$database."';";
$size = $this->select($sql, $callback);
return $size ? $size : 0;
}
/**
* Get Number of Tables per Database
*
* @param string $database Database name.
* @return integer
*/
public function getTableCount($database)
{
$callback = function ($row, &$data) {
$data = $row['count'];
};
$sql = "SELECT
COUNT(*) AS 'count'
FROM
information_schema.TABLES AS T
WHERE
T.TABLE_SCHEMA = '".$database."';";
$count = $this->select($sql, $callback);
return $count ? $count : 0;
}
/**
* Read out MySQL Server configuration by variable
*
* @param string|null $key Config key name
* @return string|mixed[]
*/
public function getConfig($key = null)
{
// Get all configs as array
if ($key === null) {
$callback = function ($row, &$data) {
$key = $row['Variable_name'];
$val = $row['Value'];
$data[$key] = $val;
};
$config = $this->select('SHOW VARIABLES;', $callback);
if (!$config) {
$config = array();
}
return $config;
} else { // Get single config
$key = str_replace('-', '_', $key);
$callback = function ($row, &$data) use ($key) {
$data = isset($row['Value']) ? $row['Value'] : false;
};
$sql = 'SHOW VARIABLES WHERE Variable_Name = "'.$key.'";';
$val = $this->select($sql, $callback);
if (is_array($val) && $val) {
return array_values($val)[0];
} else {
return $val;
}
}
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_can_connect = array();
private $_can_connect_err = array();
private $_name = null;
private $_version = null;
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
// Silence errors and try to connect
error_reporting(0);
$link = mysqli_connect($hostname, $data['user'], $data['pass']);
error_reporting(-1);
if (mysqli_connect_errno()) {
$err = 'Failed to connect: ' .mysqli_connect_error();
$this->_can_connect[$hostname] = false;
} else {
$this->_can_connect[$hostname] = true;
}
if ($link) {
mysqli_close($link);
}
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'MySQL')
{
// Return if already cached
if ($this->_name !== null) {
return $this->_name;
}
// Return default if not available
if (!$this->isAvailable()) {
return $default;
}
$name = loadClass('Helper')->egrep('/[a-zA-Z0-9]+/', $this->getConfig('version_comment'));
if (!$name) {
loadClass('Logger')->error('Could not get MySQL Name');
$this->_name = $default;
} else {
$this->_name = $name;
}
return $this->_name;
}
public function getVersion()
{
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
// Return empty if not available
if (!$this->isAvailable()) {
$this->_version = '';
return $this->_version;
}
$version = loadClass('Helper')->egrep('/[.0-9]+/', $this->getConfig('version'));
if (!$version) {
loadClass('Logger')->error('Could not get MySQL Version');
$this->_version = '';
} else {
$this->_version = $version;
}
return $this->_version;
}
}

View File

@ -0,0 +1,375 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Pgsql extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* Variables
*
*********************************************************************************/
/**
* PgSQL connection link
* @var null
*/
private $_link = null;
/*********************************************************************************
*
* Constructor Overwrite
*
*********************************************************************************/
/**
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
* @param string $database Database name
*/
public function __construct($hostname, $data = array())
{
parent::__construct($hostname, $data);
$user = $data['user'];
$pass = $data['pass'];
$db = isset($data['db']) ? $data['db'] : null;
// Silence errors and try to connect
error_reporting(0);
if ($db !== null) {
$link = pg_connect('host='.$hostname.' dbname='.$db.' user='.$user.' password='.$pass);
} else {
$link = pg_connect('host='.$hostname.' user='.$user.' password='.$pass);
}
error_reporting(-1);
if (!$link || pg_connection_status($link) !== PGSQL_CONNECTION_OK) {
$this->setConnectError('Failed to connect to '.$user.'@'.$hostname);
$this->setConnectErrno(1);
//loadClass('Logger')->error($this->_connect_error);
} else {
$this->_link = $link;
}
}
/**
* Destructor
*/
public function __destruct()
{
if ($this->_link) {
pg_close($this->_link);
}
}
/*********************************************************************************
*
* Select functions
*
*********************************************************************************/
/**
* Query Database
*
* @param string $query Postgres Query
* @param function $callback Callback function
* @return mixed[]
*/
public function select($query, $callback = null)
{
if (!$this->_link) {
loadClass('Logger')->error('Postgres error, link is no resource in select(): \''.$this->_link.'\'');
return false;
}
if (!($result = pg_query($this->_link, $query))) {
$this->setError('PostgreSQL - error on result: '.pg_result_error($result)."\n" . 'query:'."\n" . $query);
$this->setErrno(1);
loadClass('Logger')->error($this->getError());
return false;
}
$data = array();
if ($callback) {
while ($row = pg_fetch_assoc($result)) {
$callback($row, $data);
}
} else {
while ($row = pg_fetch_assoc($result)) {
$data[] = $row;
}
}
pg_free_result($result);
return $data;
}
/**
* Get all PostgreSQL Databases.
* @return mixed[] Array of databases
*/
public function getDatabases()
{
$callback = function ($row, &$data) {
$data[$row['database']] = array(
'charset' => $row['charset'],
'collation' => $row['collation']
);
};
$sql = 'SELECT
S.datname AS database,
S.datcollate AS collation,
pg_encoding_to_char(S.encoding) AS charset
FROM
pg_database AS S
WHERE datistemplate = false;';
$databases = $this->select($sql, $callback);
$databases = $databases ? $databases : array();
// Get schemas for each database
foreach ($databases as $name => &$database) {
$PSQL = new Pgsql(
$this->getIpAddress(),
array(
'user' => loadClass('Helper')->getEnv('PGSQL_ROOT_USER'),
'pass' => loadClass('Helper')->getEnv('PGSQL_ROOT_PASSWORD'),
'db' => $name
)
);
//$sql = "SELECT n.nspname AS schemas FROM pg_catalog.pg_namespace AS n WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema';";
$sql = "SELECT n.nspname AS schemas FROM pg_catalog.pg_namespace AS n;";
$callback = function ($row, &$data) {
$data[$row['schemas']] = array();
};
$schemas = $PSQL->select($sql, $callback);
$databases[$name]['schemas'] = $schemas;
}
return $databases;
}
/**
* Get Schema size in Megabytes.
*
* @param string $database Database name.
* @param string $schema Schema name.
* @return integer
*/
public function getSchemaSize($database, $schema)
{
$PSQL = new Pgsql(
$this->getIpAddress(),
array(
'user' => loadClass('Helper')->getEnv('PGSQL_ROOT_USER'),
'pass' => loadClass('Helper')->getEnv('PGSQL_ROOT_PASSWORD'),
'db' => $database
)
);
$callback = function ($row, &$data) {
$data = $row['size'];
};
$sql = "SELECT
ROUND(sum(table_size) / 1048576, 2) AS size
FROM (
SELECT pg_catalog.pg_namespace.nspname AS schema_name,
pg_relation_size(pg_catalog.pg_class.oid) AS table_size
FROM pg_catalog.pg_class
JOIN pg_catalog.pg_namespace ON relnamespace = pg_catalog.pg_namespace.oid
WHERE pg_catalog.pg_namespace.nspname = '".$schema."'
) t
GROUP BY schema_name;";
$size = $PSQL->select($sql, $callback);
return $size ? $size : 0;
}
/**
* Get Number of Tables per Schema
*
* @param string $database Database name.
* @param string $schema Schema name.
* @return integer
*/
public function getTableCount($database, $schema)
{
$PSQL = new Pgsql(
$this->getIpAddress(),
array(
'user' => loadClass('Helper')->getEnv('PGSQL_ROOT_USER'),
'pass' => loadClass('Helper')->getEnv('PGSQL_ROOT_PASSWORD'),
'db' => $database
)
);
$callback = function ($row, &$data) {
$data = $row['count'];
};
$sql = "SELECT
COUNT(*) AS count
FROM
information_schema.tables
WHERE
table_schema = '".$schema."'
AND
table_type = 'BASE TABLE';
";
$count = $PSQL->select($sql, $callback);
return $count ? $count : 0;
}
/**
* Read out PostgreSQL Server configuration by variable
*
* @param string|null $key Config key name
* @return string|mixed[]
*/
public function getConfig($key = null)
{
// Get all configs as array
if ($key === null) {
$callback = function ($row, &$data) {
$key = $row['name'];
$val = $row['setting'];
$data[$key] = $val;
};
$sql = 'SELECT name, setting FROM pg_settings;';
$configs = $this->select($sql, $callback);
return $configs ? $configs : array();
} else { // Get single config
$callback = function ($row, &$data) use ($key) {
$data = isset($row['setting']) ? $row['setting'] : false;
};
$sql = "SELECT name, setting FROM pg_settings WHERE name = '".$key."';";
$val = $this->select($sql, $callback);
return is_array($val) ? '' : $val;
}
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_can_connect = array();
private $_can_connect_err = array();
private $_name = null;
private $_version = null;
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
// Silence errors and try to connect
error_reporting(0);
$link = pg_connect('host='.$hostname.' user='.$data['user'].' password='.$data['pass']);
error_reporting(-1);
if (!$link || pg_connection_status($link) !== PGSQL_CONNECTION_OK) {
$err = 'Failed to connect to host: '.$hostname;
$this->_can_connect[$hostname] = false;
} else {
$this->_can_connect[$hostname] = true;
}
if ($link) {
pg_close($link);
}
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'PostgreSQL')
{
// Return if already cached
if ($this->_name !== null) {
return $this->_name;
}
// Return default if not available
if (!$this->isAvailable()) {
return $default;
}
$callback = function ($row, &$data) {
$data = $row['version'];
};
$name = loadClass('Helper')->egrep('/[a-zA-Z0-9]*/', $this->select('SELECT version();', $callback));
if (!$name) {
loadClass('Logger')->error('Could not get PgSQL Name');
$this->_name = $default;
} else {
$this->_name = $name;
}
return $this->_name;
}
public function getVersion()
{
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
// Return empty if not available
if (!$this->isAvailable()) {
$this->_version = '';
return $this->_version;
}
$callback = function ($row, &$data) {
$data = $row['version'];
};
$version = loadClass('Helper')->egrep('/[.0-9]+/', $this->select('SELECT version();', $callback));
if (!$version) {
loadClass('Logger')->error('Could not get PgSQL version');
$this->_version = '';
} else {
$this->_version = $version;
}
return $this->_version;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace devilbox;
class Php extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* PHP Select functions
*
*********************************************************************************/
public function getConfig($key = null)
{
// Get all configs as array
if ($key === null) {
return ini_get_all();
} else {
return ini_get($key);
}
}
public function getUid()
{
$output = loadClass('Helper')->exec('id', $output);
$uid = loadClass('Helper')->egrep('/uid=[0-9]+/', $output);
$uid = loadClass('Helper')->egrep('/[0-9]+/', $uid);
return $uid;
}
public function getGid()
{
$output = loadClass('Helper')->exec('id', $output);
$uid = loadClass('Helper')->egrep('/gid=[0-9]+/', $output);
$uid = loadClass('Helper')->egrep('/[0-9]+/', $uid);
return $uid;
}
public function getGitVersion()
{
$output = loadClass('Helper')->exec('git --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
public function getComposerVersion()
{
$output = loadClass('Helper')->exec('composer --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
public function getDrushVersion()
{
$output = loadClass('Helper')->exec('drush --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
public function getDrushConsoleVersion()
{
$output = loadClass('Helper')->exec('drush-console --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
public function getNodeVersion()
{
$output = loadClass('Helper')->exec('node --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
public function getNpmVersion()
{
$output = loadClass('Helper')->exec('npm --version', $output);
return loadClass('Helper')->egrep('/[0-9.]+/', $output);
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
public function canConnect(&$err, $hostname, $data = array())
{
// PHP can always connect, otherwise you could not see anything.
$err = false;
return true;
}
public function getName($default = 'PHP')
{
if (defined('HHVM_VERSION')) {
return 'HHVM';
}
return $default;
}
public function getVersion()
{
if (defined('HHVM_VERSION')) {
return HHVM_VERSION . ' php-'.str_replace('-hhvm', '', phpversion());
} else {
return phpversion();
}
}
}

View File

@ -0,0 +1,165 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Redis extends BaseClass implements BaseInterface
{
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* Redis instance
* @var object|null
*/
private $_redis = null;
/*********************************************************************************
*
* Constructor Overwrite
*
*********************************************************************************/
/**
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
*/
public function __construct($hostname, $data = array())
{
parent::__construct($hostname, $data);
// Silence errors and try to connect
error_reporting(0);
$redis = new \Redis();
if (!$redis->connect($hostname, 6379)) {
$this->setConnectError('Failed to connect to Redis host on '.$hostname);
$this->setConnectErrno(1);
//loadClass('Logger')->error($this->_connect_error);
} else {
$redis->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
$this->_redis = $redis;
}
error_reporting(-1);
}
/**
* Destructor
*/
public function __destruct()
{
if ($this->_redis) {
$this->_redis->close();
}
}
/*********************************************************************************
*
* Select functions
*
*********************************************************************************/
public function getInfo()
{
if ($this->_redis) {
return $this->_redis->info('all');
} else {
return array();
}
}
public function getKeys()
{
$store = array();
if ($this->_redis) {
$keys = $this->_redis->keys('*');
foreach ($keys as $key) {
$store[$key] = $this->_redis->get($key);
}
}
return $store;
}
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
private $_can_connect = array();
private $_can_connect_err = array();
private $_name = null;
private $_version = null;
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
// Silence errors and try to connect
//error_reporting(0);
$redis = new \Redis();
if (!$redis->connect($hostname, 6379)) {
$err = 'Failed to connect to Redis host on '.$hostname;
$this->_can_connect[$hostname] = false;
} else {
$this->_can_connect[$hostname] = true;
}
//error_reporting(-1);
$redis->close();
$this->_can_connect_err[$hostname] = $err;
return $this->_can_connect[$hostname];
}
public function getName($default = 'Redis')
{
return $default;
}
public function getVersion()
{
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
// Return empty if not available
if (!$this->isAvailable()) {
$this->_version = '';
return $this->_version;
}
$info = $this->getInfo();
if (!isset($info['redis_version'])) {
loadClass('Logger')->error('Could not get Redis version');
$this->_version = '';
} else {
$this->_version = $info['redis_version'];
}
return $this->_version;
}
}