Refactor web libraries

This commit is contained in:
cytopia 2016-11-15 19:39:34 +01:00
parent 086fd5bc50
commit 8834828a95
No known key found for this signature in database
GPG Key ID: 6D56EDB8695128A2
5 changed files with 467 additions and 26 deletions

@ -36,9 +36,12 @@ $HTTPD_HOST_ADDR = gethostbyname($HTTPD_HOST_NAME);
$PHP_HOST_NAME = 'php';
$PHP_HOST_ADDR = gethostbyname($PHP_HOST_NAME);
$MYSQL_HOST_NAME = 'db';
$MYSQL_HOST_NAME = 'mysql';
$MYSQL_HOST_ADDR = gethostbyname($MYSQL_HOST_NAME);
$POSTGRES_HOST_NAME = 'postgres';
$POSTGRES_HOST_ADDR = gethostbyname($POSTGRES_HOST_NAME);
//
// Load files
@ -46,19 +49,20 @@ $MYSQL_HOST_ADDR = gethostbyname($MYSQL_HOST_NAME);
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Logger.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Docker.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Mysql.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Postgres.php';
//
// Instantiate Basics
//
$Logger = \devilbox\Logger::getInstance();
$Docker = \devilbox\Docker::getInstance();
$MySQL = \devilbox\Mysql::getInstance('root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), $MYSQL_HOST_ADDR);
$Logger = \devilbox\Logger::getInstance();
$Docker = \devilbox\Docker::getInstance();
$MySQL = \devilbox\Mysql::getInstance('root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), $MYSQL_HOST_ADDR);
$Postgres = \devilbox\Postgres::getInstance($Docker->getEnv('POSTGRES_USER'), $Docker->getEnv('POSTGRES_PASSWORD'), $POSTGRES_HOST_ADDR);
// VirtualHost DNS check
// Temporarily disable due to:
// https://github.com/cytopia/devilbox/issues/8
$ENABLE_VHOST_DNS_CHECK = false;
$ENABLE_VHOST_DNS_CHECK = true;

@ -9,6 +9,7 @@
</nav>
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/vendor/bootstrap/bootstrap.min.js"></script>
<?php /*
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

@ -108,7 +108,7 @@ class Docker
{
if (!isset($this->_env[$variable])) {
$Logger = \devilbox\Logger::getInstance();
$logger->error('Docker environment variable not found: '.$variable);
$Logger->error('Docker environment variable not found: '.$variable);
return null;
}
return $this->_env[$variable];
@ -296,7 +296,7 @@ class Docker
$version = $this->MySQL_config('version');
if (!$name && !$version) {
return 'Unknown Version';
return 'Unknown MySQL version';
}
return $name . ' ' . $version;
}
@ -342,6 +342,74 @@ class Docker
}
/*********************************************************************************
*
* Postgres Docker functions
*
*********************************************************************************/
/**
* Get Postgres Version.
*
* @return string Postgres version string.
*/
public function Postgres_version()
{
$callback = function ($row, &$data) {
$data = $row['version'];
};
$version = \devilbox\Postgres::getInstance()->select('SELECT version();', $callback);
// Extract shorthand
preg_match('/\w+[[:space:]]*[.0-9]+/i', $version, $matches);
if (isset($matches[0])) {
return $matches[0];
}
// Unknown
if (!$version) {
return 'Unknown Postgres version';
}
return $version;
}
/**
* Read out PostgreSQL Server configuration by variable
*
* @param string|null $key Config key name
* @return string|mixed[]
*/
public function Postgres_config($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 = \devilbox\Postgres::getInstance()->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 = \devilbox\Postgres::getInstance()->select($sql, $callback);
return is_array($val) ? '' : $val;
}
}
/*********************************************************************************
*

@ -0,0 +1,348 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Postgres
{
/*********************************************************************************
*
* Statics
*
*********************************************************************************/
/**
* Postgres instance
* @var Postgres|null
*/
protected static $instance = null;
/**
* Singleton Instance getter.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
* @return object|null
*/
public static function getInstance($user = null, $pass = null, $host = null)
{
if (!isset(static::$instance)) {
static::$instance = new static($user, $pass, $host);
}
// If current Postgres instance was unable to connect
if ((static::$instance->getConnectError())) {
\devilbox\Logger::getInstance()->error('Instance has errors:' . "\r\n" . var_export(static::$instance, true) . "\r\n");
//return null;
}
return static::$instance;
}
/**
* Connect to database
*
* @param string $err Reference to error message
* @param string $user Postgres username
* @param string $pass Postgres password
* @param string $host Postgres hostname
* @return boolean
*/
public static function testConnection(&$err, $user, $pass, $host)
{
$err = false;
// Silence errors and try to connect
error_reporting(0);
$link = pg_pconnect('host='.$host.' user='.$user.' password='.$pass);
error_reporting(-1);
if (!$link || pg_connection_status($link) !== PGSQL_CONNECTION_OK) {
$err = 'Failed to connect: ' .pg_last_error($link);
return false;
}
pg_close($link);
return true;
}
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* Postgres Resource
* @var resource|null
*/
private $_link = 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;
/*********************************************************************************
*
* Construct/Destructor
*
*********************************************************************************/
/**
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
* @param string $database Database name
*/
public function __construct($user, $pass, $host, $database = null)
{
// Silence errors and try to connect
error_reporting(0);
if ($database !== null) {
$link = pg_pconnect('host='.$host.' dbname='.$database.' user='.$user.' password='.$pass);
} else {
$link = pg_pconnect('host='.$host.' user='.$user.' password='.$pass);
}
error_reporting(-1);
if (!$link || pg_connection_status($link) !== PGSQL_CONNECTION_OK) {
$this->_connect_error = 'Failed to connect to '.$user.'@'.$host;
$this->_connect_errno = 1;
\devilbox\Logger::getInstance()->error($this->_connect_error);
} else {
$this->_link = $link;
}
}
/**
* Destructor
*/
public function __destruct()
{
if ($this->_link) {
pg_close($this->_link);
}
}
/*********************************************************************************
*
* PostgreSQL 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) {
\devilbox\Logger::getInstance()->error('Postgres error, link is no resource in select()');
return false;
}
if (!($result = pg_query($this->_link, $query))) {
$this->_error = 'PostgreSQL - error on result: '.pg_result_error($result)."\n" . 'query:'."\n" . $query;
$this->_errno = 1;
\devilbox\Logger::getInstance()->error($this->_error);
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 Postgres('postgres', \devilbox\Docker::getInstance()->getEnv('POSTGRES_PASSWORD'), $GLOBALS['POSTGRES_HOST_ADDR'], $name);
$sql = "SELECT n.nspname AS schemas FROM pg_catalog.pg_namespace AS n WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema';";
$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 Postgres('postgres', \devilbox\Docker::getInstance()->getEnv('POSTGRES_PASSWORD'), $GLOBALS['POSTGRES_HOST_ADDR'], $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 Postgres('postgres', \devilbox\Docker::getInstance()->getEnv('POSTGRES_PASSWORD'), $GLOBALS['POSTGRES_HOST_ADDR'], $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;
}
/*********************************************************************************
*
* MySQL Error functions
*
*********************************************************************************/
/**
* 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;
}
}

@ -2,7 +2,7 @@
<nav class="navbar navbar-full navbar-dark bg-inverse">
<div class="container">
<a class="navbar-brand" href="#">
<a class="navbar-brand" href="/index.php">
<img src="/assets/img/logo_30.png" width="30" height="30" class="d-inline-block align-top" alt="">
devilbox
</a>
@ -18,40 +18,60 @@
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
</li>
<?php $file = 'databases.php'; $name = 'Databases';?>
<?php $file = 'db_mysql.php'; $name = 'MySQL DB';?>
<li class="nav-item <?php echo $file == $current ? 'active' : '';?>">
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
</li>
<?php $file = 'mail.php'; $name = 'Mail';?>
<?php $file = 'db_postgres.php'; $name = 'PostgreSQL DB';?>
<li class="nav-item <?php echo $file == $current ? 'active' : '';?>">
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
</li>
<?php $file = 'phpinfo.php'; $name = 'PHP info';?>
<?php $file = 'mail.php'; $name = 'Emails';?>
<li class="nav-item <?php echo $file == $current ? 'active' : '';?>">
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
</li>
<?php $file = 'mysqlinfo.php'; $name = 'MySQL info';?>
<li class="nav-item <?php echo $file == $current ? 'active' : '';?>">
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
<?php
// ---- Info ---- //
$script = $_SERVER['SCRIPT_NAME'];
$files = array(
'phpinfo.php' => 'PHP info',
'mysqlinfo.php' => 'MySQL info',
'postgresinfo.php' => 'PostgreSQL info'
);
$active = (in_array($script, array_keys($files))) ? 'active' : '';
?>
<li class="nav-item dropdown <?php echo $active;?>">
<a class="nav-link dropdown-toggle" href="#" id="supportedContentDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Info</a>
<div class="dropdown-menu" aria-labelledby="supportedContentDropdown">
<?php foreach ($files as $href => $name): ?>
<a class="dropdown-item" href="<?php echo $href;?>"><?php echo $name;?></a>
<?php endforeach; ?>
</div>
</li>
<?php $file = 'opcache.php'; $name = 'Opcache';?>
<li class="nav-item <?php echo $file == $current ? 'active' : '';?>">
<a class="nav-link" href="<?php echo $file == $current ? '#' : '/'.$file;?>"><?php echo $name;?><?php echo $file == $current ? ' <span class="sr-only">(current)</span>' : '';?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="/vendor/phpmyadmin/index.php">phpMyAdmin</a>
<?php
// ---- Tools ---- //
$files = array(
'/vendor/phpmyadmin/index.php' => 'phpMyAdmin',
'/vendor/adminer/adminer/index.php' => 'Adminer',
'opcache.php' => 'Opcache GUI'
);
$active = (in_array($script, array_keys($files))) ? 'active' : '';
?>
<li class="nav-item dropdown <?php echo $active;?>">
<a class="nav-link dropdown-toggle" href="#" id="supportedContentDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Tools</a>
<div class="dropdown-menu" aria-labelledby="supportedContentDropdown">
<?php foreach ($files as $href => $name): ?>
<a class="dropdown-item" href="<?php echo $href;?>"><?php echo $name;?></a>
<?php endforeach; ?>
</div>
</li>
</ul>
</div>
</nav>
<br/>
<br/>