Refactor PHP code for intranet

This commit is contained in:
cytopia 2016-11-06 13:36:07 +01:00
parent 2a05d1a0a8
commit 4c2d5bb480
No known key found for this signature in database
GPG Key ID: 6D56EDB8695128A2
17 changed files with 1058 additions and 585 deletions

View File

@ -1,43 +1,53 @@
<?PHP
// Measure time
$TIME_START = microtime(true);
$MY_DIR = dirname(__FILE__);
// PHP Error reporting
error_reporting(-1);
// Translate Docker environmental variables to $ENV
$ENV = array();
exec('env', $output);
foreach ($output as $var) {
$tmp = explode('=', $var);
$ENV[$tmp[0]] = $tmp[1];
}
//
// Set Directories
//
$CONF_DIR = dirname(__FILE__);
$INCL_DIR = $CONF_DIR . DIRECTORY_SEPARATOR . 'include';
$LIB_DIR = $INCL_DIR . DIRECTORY_SEPARATOR . 'lib';
$VEN_DIR = $INCL_DIR . DIRECTORY_SEPARATOR . 'include';
$LOG_DIR = dirname(dirname($CONF_DIR)) . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'devilbox';
// HTTPD Docker
//
// Set Docker addresses
//
$HTTPD_HOST_NAME = 'httpd';
$HTTPD_HOST_ADDR = gethostbyname($HTTPD_HOST_NAME);
// PHP Docker
$PHP_HOST_NAME = 'php';
$PHP_HOST_ADDR = gethostbyname($PHP_HOST_NAME);
$PHP_HOST_NAME = 'php';
$PHP_HOST_ADDR = gethostbyname($PHP_HOST_NAME);
// MySQL Docker
$MYSQL_HOST_NAME = 'db';
$MYSQL_HOST_ADDR = gethostbyname($MYSQL_HOST_NAME);
$MYSQL_ROOT_PASS = $ENV['MYSQL_ROOT_PASSWORD'];
// MySQL Connection variables
$MY_MYSQL_ERR = NULL;
$MY_MYSQL_LINK = NULL;
//
// Load files
//
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Logger.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Docker.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Mysql.php';
//
// Instantiate Basics
//
$Logger = \devilbox\Logger::getInstance();
$Docker = \devilbox\Docker::getInstance();
$MySQL = \devilbox\Mysql::getInstance('root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), $MYSQL_HOST_ADDR);
// VirtualHost DNS check
// Temporarily disable due to:
// https://github.com/cytopia/devilbox/issues/8
$ENABLE_VHOST_DNS_CHECK = FALSE;
require $MY_DIR . DIRECTORY_SEPARATOR . 'include' . DIRECTORY_SEPARATOR .'functions.php';
if (isset($CONNECT) && $CONNECT) {
$MY_MYSQL_LINK = my_mysql_connect($MY_MYSQL_ERR);
}
$ENABLE_VHOST_DNS_CHECK = false;

View File

@ -1,11 +1,10 @@
<?php
$CONNECT = TRUE;
require '../config.php';
if (isset($_GET['size'])) {
echo getDBSize($_GET['size']);
echo $MySQL->getDBSize($_GET['size']);
} elseif (isset($_GET['table'])) {
echo getTableCount($_GET['table']);
echo $MySQL->getTableCount($_GET['table']);
} else {
echo '0';
}

View File

@ -2,7 +2,9 @@
require '../config.php';
if (isset($_GET['valid'])) {
echo checkVirtualHost($_GET['valid']);
echo $Docker->PHP_checkVirtualHost($_GET['valid']);
exit();
} else {
echo '';
exit();
}

View File

@ -4,10 +4,6 @@ html, body {
font-size: 14px;
}
td {
word-break: break-word;
}
/* Sticky footer styles
@ -111,4 +107,8 @@ nav.navbar {
-------------------------------------------------- */
tr.subject {
cursor: pointer;
}
td.break-word {
word-break: break-word;
}

View File

@ -1,4 +1,4 @@
<?php $CONNECT = TRUE; require '../config.php'; ?>
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
@ -28,7 +28,7 @@
</th>
</thead>
<tbody>
<?php foreach (getDatabases() as $name => $keys): ?>
<?php foreach ($MySQL->getDatabases() as $name => $keys): ?>
<tr>
<td><?php echo $name;?></td>
<td><?php echo $keys['charset'];?></td>

View File

@ -0,0 +1,50 @@
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php require '../include/head.php'; ?>
</head>
<body>
<?php require '../include/navigation.php'; ?>
<div class="container">
<h1>Devilbox Debug</h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<?php $errors = $Logger->getAll(); ?>
<?php if ($errors === false): ?>
<p>Writing to logfile is not possible. Errors will be sent as mail instead. Check the mail section.</p>
<?php else: ?>
<?php $total = count($errors); ?>
<table class="table table-striped">
<thead class="thead-inverse">
<tr>
<th>#</th>
<th>Errors (<?php echo $total;?>)</th>
</tr>
</thead>
<tbody>
<?php for ($i=($total-1); $i>=0; --$i): ?>
<tr>
<td><?php echo ($i+1);?></td>
<td><code><?php echo $errors[$i];?></code></td>
</tr>
<?php endfor; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
</div><!-- /.container -->
<?php require '../include/footer.php'; ?>
</body>
</html>

View File

@ -1,4 +1,4 @@
<?php $CONNECT = TRUE; require '../config.php'; ?>
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
@ -39,7 +39,7 @@
<div class="bg-danger">
<div>
<div>
<h3><?php echo getHttpVersion();?></h3>
<h3><?php echo $Docker->HTTPD_version();?></h3>
</div>
</div>
</div>
@ -56,7 +56,7 @@
<div class="bg-info">
<div>
<div>
<h3><?php echo getPHPVersion(); ?></h3>
<h3><?php echo $Docker->PHP_version(); ?></h3>
</div>
</div>
</div>
@ -73,7 +73,7 @@
<div class="bg-warning">
<div>
<div>
<h3><?php echo getMySQLVersion();?></h3>
<h3><?php echo $Docker->MySQL_version();?></h3>
</div>
</div>
</div>
@ -130,36 +130,34 @@
<tr>
<th>Custom config</th>
<td>
<?php foreach (scandir('/etc/php-custom.d') as $file): ?>
<?php if (preg_match('/.*\.ini$/', $file) === 1): ?>
<?php echo $file.'<br/>';?>
<?php endif; ?>
<?php foreach ($Docker->PHP_custom_config_files() as $file): ?>
<?php echo $file.'<br/>';?>
<?php endforeach; ?>
</td>
</tr>
<tr>
<?php $error; $valid = php_has_valid_mysql_socket($error); ?>
<?php $error; $valid = $Docker->PHP_has_valid_mysql_socket($error); ?>
<th>MySQL socket</th>
<td class="<?php echo !$valid ? 'bg-danger' : '';?>">
<?php echo !$valid ? 'Error<br/><sub>'.$error.'</sub>' : $ENV['MYSQL_SOCKET_PATH']; ?>
<?php echo !$valid ? 'Error<br/><sub>'.$error.'</sub>' : $Docker->getEnv('MYSQL_SOCKET_PATH'); ?>
</td>
</tr>
<tr>
<?php $err; $valid = my_mysql_connection_test($err, 'localhost'); ?>
<?php $err; $valid = \devilbox\Mysql::testConnection($err, 'root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), 'localhost'); ?>
<th>MySQL test</th>
<td class="<?php echo !$valid ? 'bg-danger' : '';?>">
<?php echo $valid ? '<span class="bg-success">OK</span> localhost:3306' : 'Failed: localhost:3306<br/><sub>'.$err.'</sub>'; ?>
</td>
</tr>
<tr>
<?php $err; $valid = my_mysql_connection_test($err, '127.0.0.1'); ?>
<?php $err; $valid = \devilbox\Mysql::testConnection($err, 'root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), '127.0.0.1'); ?>
<th>MySQL test</th>
<td class="<?php echo !$valid ? 'bg-danger' : '';?>">
<?php echo $valid ? '<span class="bg-success">OK</span> 127.0.0.1:3306' : 'Failed: 127.0.0.1:3306<br/><sub>'.$err.'</sub>'; ?>
</td>
</tr>
<tr>
<?php $err; $valid = my_mysql_connection_test($err, $MYSQL_HOST_ADDR); ?>
<?php $err; $valid = \devilbox\Mysql::testConnection($err, 'root', $Docker->getEnv('MYSQL_ROOT_PASSWORD'), $MYSQL_HOST_ADDR); ?>
<th>MySQL test</th>
<td class="<?php echo !$valid ? 'bg-danger' : '';?>">
<?php echo $valid ? '<span class="bg-success">OK</span> '.$MYSQL_HOST_ADDR.':3306' : 'Failed: '.$MYSQL_HOST_ADDR.':3306<br/><sub>'.$err.'</sub>'; ?>
@ -168,43 +166,46 @@
<tr>
<th>Postfix</th>
<td><?php echo $ENV['ENABLE_MAIL'] ? '<span class="bg-success">OK</span> Enabled' : '<span class="bg-danger">No</span> Disabled';?></td>
<td><?php echo $Docker->getEnv('ENABLE_MAIL') ? '<span class="bg-success">OK</span> Enabled' : '<span class="bg-danger">No</span> Disabled';?></td>
</tr>
<tr>
<th>Xdebug enabled</th>
<td>
<?php if ($ENV['PHP_XDEBUG_ENABLE'] == ini_get('xdebug.remote_enable')): ?>
<?php echo ini_get('xdebug.remote_enable') == 1 ? 'Yes' : ini_get('xdebug.remote_enable'); ?>
<?php $Xdebug = ($Docker->getEnv('PHP_XDEBUG_ENABLE') == 0) ? '' : $Docker->getEnv('PHP_XDEBUG_ENABLE'); ?>
<?php if ($Xdebug == $Docker->PHP_config('xdebug.remote_enable')): ?>
<?php echo $Docker->PHP_config('xdebug.remote_enable') == 1 ? 'Yes' : 'No'; ?>
<?php else: ?>
<?php echo '.env file setting differs from custom php .ini file<br/>'; ?>
<?php echo 'Effective setting: '.ini_get('xdebug.remote_enable'); ?>
<?php endif; ?>
</td>
</tr>
<tr>
<th>Xdebug remote</th>
<td>
<?php if ($ENV['PHP_XDEBUG_REMOTE_HOST'] == ini_get('xdebug.remote_host')): ?>
<?php echo ini_get('xdebug.remote_host'); ?>
<?php else: ?>
<?php echo '.env file setting differs from custom php .ini file<br/>'; ?>
<?php echo 'Effective setting: '.ini_get('xdebug.remote_host'); ?>
<?php endif; ?>
</td>
</tr>
<tr>
<th>Xdebug Port</th>
<td>
<?php if ($ENV['PHP_XDEBUG_REMOTE_PORT'] == ini_get('xdebug.remote_port')): ?>
<?php echo ini_get('xdebug.remote_port'); ?>
<?php else: ?>
<?php echo '.env file setting differs from custom php .ini file<br/>'; ?>
<?php echo 'Effective setting: '.ini_get('xdebug.remote_port'); ?>
<?php echo 'Effective setting: '.$Docker->PHP_config('xdebug.remote_enable'); ?>
<?php endif; ?>
</td>
</tr>
<?php if ($Xdebug):?>
<tr>
<th>Xdebug remote</th>
<td>
<?php if ($Docker->getEnv('PHP_XDEBUG_REMOTE_HOST') == $Docker->PHP_config('xdebug.remote_host')): ?>
<?php echo $Docker->PHP_config('xdebug.remote_host'); ?>
<?php else: ?>
<?php echo '.env file setting differs from custom php .ini file<br/>'; ?>
<?php echo 'Effective setting: '.$Docker->PHP_config('xdebug.remote_host'); ?>
<?php endif; ?>
</td>
</tr>
<tr>
<th>Xdebug Port</th>
<td>
<?php if ($Docker->getEnv('PHP_XDEBUG_REMOTE_PORT') == $Docker->PHP_config('xdebug.remote_port')): ?>
<?php echo $Docker->PHP_config('xdebug.remote_port'); ?>
<?php else: ?>
<?php echo '.env file setting differs from custom php .ini file<br/>'; ?>
<?php echo 'Effective setting: '.$Docker->PHP_config('xdebug.remote_port'); ?>
<?php endif; ?>
</td>
</tr>
<?php endif; ?>
@ -230,11 +231,11 @@
</tr>
<tr>
<th>MySQL socket</th>
<td><?php echo getMySQLConfigByKey('socket'); ?></td>
<td><?php echo $Docker->MySQL_config('socket'); ?></td>
</tr>
<tr>
<th>MySQL datadir</th>
<td><?php echo getMySQLConfigByKey('datadir'); ?></td>
<td><?php echo $Docker->MySQL_config('datadir'); ?></td>
</tr>
</tbody>
</table>
@ -273,7 +274,7 @@
<tbody>
<tr>
<th>Document Root</th>
<td><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?></td>
<td><?php echo $Docker->getEnv('HOST_PATH_TO_WWW_DOCROOTS');?></td>
</tr>
<tr>
<th>Log directory</th>
@ -297,7 +298,7 @@
<tbody>
<tr>
<th>Document Root</th>
<td><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?></td>
<td><?php echo $Docker->getEnv('HOST_PATH_TO_WWW_DOCROOTS');?></td>
</tr>
<tr>
<th>Custom config</th>
@ -329,7 +330,7 @@
<tbody>
<tr>
<th>MySQL datadir</th>
<td><?php echo $ENV['HOST_PATH_TO_MYSQL_DATADIR'];?></td>
<td><?php echo $Docker->getEnv('HOST_PATH_TO_MYSQL_DATADIR');?></td>
</tr>
<tr>
<th>MySQL socket</th>

View File

@ -1,4 +1,4 @@
<?php $CONNECT = TRUE; require '../config.php'; ?>
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
@ -27,15 +27,15 @@
<table class="table table-striped">
<thead class="thead-inverse">
<tr>
<th style="word-break: normal;">Variable</th>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<?php foreach (getMySQLConfig() as $key => $val): ?>
<?php foreach ($Docker->MySQL_config() as $key => $val): ?>
<tr>
<td style="word-break: normal;"><?php echo $key;?></td>
<td><?php echo $val;?></td>
<td><?php echo $key;?></td>
<td class="break-word"><code><?php echo $val;?></code></td>
</tr>
<?php endforeach; ?>
</tbody>

View File

@ -16,7 +16,7 @@
<div class="row">
<div class="col-md-12">
<?php $vHosts = getVirtualHosts(); ?>
<?php $vHosts = $Docker->PHP_getVirtualHosts(); ?>
<?php if ($vHosts): ?>
<table class="table table-striped">
<thead class="thead-inverse">
@ -38,7 +38,7 @@
<?php foreach ($vHosts as $vHost): ?>
<tr>
<td><?php echo $vHost['name'];?></td>
<td><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?>/<?php echo $vHost['name'];?>/htdocs</td>
<td><?php echo $Docker->getEnv('HOST_PATH_TO_WWW_DOCROOTS');?>/<?php echo $vHost['name'];?>/htdocs</td>
<td class="text-xs-center text-xs-small" id="valid-<?php echo $vHost['name'];?>">&nbsp;&nbsp;&nbsp;</td>
<td id="href-<?php echo $vHost['name'];?>"><?php echo $filler;?></td>
</tr>
@ -48,8 +48,8 @@
</table>
<?php else: ?>
<h4>No projects here.</h4>
<p>Simply create a folder in <strong><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?></strong> (on your host computer - not inside the docker).</p>
<p><strong>Example:</strong><br/><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?>/my_project</p>
<p>Simply create a folder in <strong><?php echo $Docker->getEnv('HOST_PATH_TO_WWW_DOCROOTS');?></strong> (on your host computer - not inside the docker).</p>
<p><strong>Example:</strong><br/><?php echo $Docker->getEnv('HOST_PATH_TO_WWW_DOCROOTS');?>/my_project</p>
<?php endif;?>
</div>
</div>
@ -84,7 +84,7 @@
} else {
el_valid.className += ' bg-success';
el_valid.innerHTML = 'OK';
el_href.innerHTML = '<a target="_blank" href="http://'+vhost+'.loc">'+vhost+'.loc</a>';
el_href.innerHTML = '<a target="_blank" href="http://'+vhost+'.<?php echo $Docker->getTld();?>">'+vhost+'.<?php echo $Docker->getTld();?></a>';
}
}
};

View File

@ -2,13 +2,12 @@
<div class="container">
<ul class="nav navbar-nav">
<li class="nav-item nav-link">Render time: <?php echo round((microtime(true) - $TIME_START), 2); ?> sec</li>
<li class="nav-item float-xs-right"><a class="nav-link" href="/credits.php"><code>Credits</code></a></li>
<li class="nav-item float-xs-right"><a class="nav-link" href="https://github.com/cytopia/devilbox"><code>Github</code></a></li>
<li class="nav-item float-xs-right"><a class="nav-link" href="/credits.php"><code>Credits</code></a></li>
<li class="nav-item float-xs-right"><a class="nav-link" href="/debug.php"><code>Debug</code></a></li>
</div>
</nav>
<?php if ($GLOBALS['MY_MYSQL_LINK']) { my_mysqli_close($GLOBALS['MY_MYSQL_LINK']); } ?>
<script src="/vendor/jquery/jquery.min.js"></script>
<?php /*

View File

@ -1,488 +0,0 @@
<?php
/**
* Executes shell commands on the PHP-FPM Host
*
* @param string $cmd [description]
* @param string $output [description]
* @return integer
*/
function my_exec($cmd, &$output = '')
{
// Clean output
$output = '';
exec($cmd, $output, $exit_code);
return $exit_code;
}
/**
* Connect to database
*
* @param [type] $err [description]
* @param [type] $host [description]
* @param [type] $pass [description]
* @param [type] $user [description]
* @return [type] [description]
*/
function my_mysql_connection_test(&$err, $host = NULL, $pass = NULL, $user = NULL)
{
$err = FALSE;
if ($host === NULL) {
$host = $GLOBALS['MYSQL_HOST_ADDR'];
}
if ($pass === NULL) {
$pass = $GLOBALS['MYSQL_ROOT_PASS'];
}
if ($user === NULL) {
$user = 'root';
}
if (!($link = @mysqli_connect($host, $user, $pass))) {
$err = 'Failed to connect: ' .mysqli_connect_error();
return FALSE;
}
mysqli_close($link);
return TRUE;
}
/**
* Connect to database
*
* @param [type] $err [description]
* @param [type] $host [description]
* @param [type] $pass [description]
* @param [type] $user [description]
* @return [type] [description]
*/
function my_mysql_connect(&$err, $pass = NULL, $user = NULL)
{
if ($pass === NULL) {
$pass = $GLOBALS['MYSQL_ROOT_PASS'];
}
if ($user === NULL) {
$user = 'root';
}
if (!($link = @mysqli_connect('localhost', $user, $pass))) {
$err = 'Failed to connect: ' .mysqli_connect_error();
if (!($link = @mysqli_connect('127.0.0.1', $user, $pass))) {
$err = 'Failed to connect: ' .mysqli_connect_error();
if (!($link = @mysqli_connect($GLOBALS['MYSQL_HOST_ADDR'], $user, $pass))) {
$err = 'Failed to connect: ' .mysqli_connect_error();
return FALSE;
}
}
}
$err = FALSE;
return $link;
}
/**
* Close Database connection
*
* @param [type] $link [description]
* @return [type] [description]
*/
function my_mysqli_close($link) {
if (is_object($link)) {
return mysqli_close($link);
}
return FALSE;
}
/**
* Query Database
*
* @param [type] $err [description]
* @param [type] $link [description]
* @param [type] $query [description]
* @param [type] $callback [description]
* @return [type] [description]
*/
function my_mysqli_select(&$err, $link, $query, $callback = NULL)
{
if (!$link) {
return FALSE;
}
if (!($result = mysqli_query($link, $query))) {
$err = mysqli_error($link);
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;
}
/********************************************************************************
*
* M Y S Q L F U N C T I O N S
*
********************************************************************************/
/**
* Get all MySQL Databases.
* @return mixed Array of name => size
*/
function getDatabases() {
$error;
$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
WHERE
S.SCHEMA_NAME != 'mysql' AND
S.SCHEMA_NAME != 'performance_schema' AND
S.SCHEMA_NAME != 'information_schema'";
$databases = my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
return $databases ? $databases : array();
}
/**
* Get Database size in Megabytes
* @param [type] $db_name [description]
* @return [type] [description]
*/
function getDBSize($db_name) {
$error;
$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 = '".$db_name."';";
$size = my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
return $size ? $size : 0;
}
/**
* Get Number of Tables per Database
* @param [type] $db_name [description]
* @return [type] [description]
*/
function getTableCount($db_name) {
$error;
$callback = function ($row, &$data) {
$data = $row['count'];
};
$sql = "SELECT
COUNT(*) AS 'count'
FROM
information_schema.TABLES AS T
WHERE
T.TABLE_SCHEMA = '".$db_name."';";
$count = my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
return $count ? $count : 0;
}
/**
* Read out MySQL Server variables
*
* @param [type] $key [description]
* @return [type] [description]
*/
function getMySQLConfigByKey($key) {
$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 = my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
if (!is_array($val)) {
return $val;
} else if (is_array($val) && $val) {
return print_r($val, TRUE);
} else {
return '';
}
}
function getMySQLConfig() {
$callback = function ($row, &$data) {
$key = $row['Variable_name'];
$val = $row['Value'];
$data[$key] = $val;
};
$sql = 'SHOW VARIABLES;';
$configs = my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
return $configs ? $configs : array();
}
function php_has_valid_mysql_socket(&$error) {
global $ENV;
if (!$ENV['MOUNT_MYSQL_SOCKET_TO_LOCALDISK']) {
$error = 'Socket mount not enabled.';
return FALSE;
}
if (!file_exists($ENV['MYSQL_SOCKET_PATH'])) {
$error = 'Socket file not found.';
return FALSE;
}
//if (getMySQLConfigByKey('socket') != $ENV['MYSQL_SOCKET_PATH']) {
// $error = 'Mounted from mysql:'.$ENV['MYSQL_SOCKET_PATH']. ', but socket is in mysql:'.getMySQLConfigByKey('socket');
// return FALSE;
//}
$error = '';
return TRUE;
}
function is_valid_dir($path) {
return (is_dir($path) || (is_link($path) && is_dir(readlink($path))));
}
function getVirtualHosts()
{
$docRoot = '/shared/httpd';
$vhosts = array();
if ($handle = opendir($docRoot)) {
while (false !== ($directory = readdir($handle))) {
if (is_valid_dir($docRoot . DIRECTORY_SEPARATOR . $directory) && $directory != '.' && $directory != '..') {
$vhosts[] = array(
'name' => $directory,
'domain' => $directory.'.loc',
'href' => 'http://' . $directory.'.loc'
);
}
}
}
return $vhosts;
}
function checkVirtualHost($vhost)
{
global $ENV;
$docRoot = '/shared/httpd';
$htdocs = $docRoot.DIRECTORY_SEPARATOR.$vhost.DIRECTORY_SEPARATOR.'htdocs';
$domain = $vhost.'.loc';
$url = 'http://'.$domain;
$error = array();
// 1. Check htdocs folder
if (!is_valid_dir($htdocs)) {
$error[] = 'Missing <strong>htdocs</strong> directory in: <strong>'.$ENV['HOST_PATH_TO_WWW_DOCROOTS'].'/'.$vhost.'/</strong>';
}
if ($GLOBALS['ENABLE_VHOST_DNS_CHECK']) {
// 2. Check /etc/resolv DNS entry
$output;
if (my_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 VirtualHosts
* @return [type] [description]
*/
function getVhosts() {
global $ENV;
$docRoot = '/shared/httpd';
$vhosts = array();
if ($handle = opendir($docRoot)) {
while (false !== ($directory = readdir($handle))) {
if (is_valid_dir($docRoot . DIRECTORY_SEPARATOR . $directory) && $directory != '.' && $directory != '..') {
$output;
$domain = $directory.'.loc';
$url = 'http://'.$domain;
$htdocs_ok = is_valid_dir($docRoot.DIRECTORY_SEPARATOR.$directory.DIRECTORY_SEPARATOR.'htdocs');
$dns_ok = my_exec('getent hosts '.$domain, $output) == 0 ? TRUE : FALSE;
$dns_ip = '';
if (isset($output[0])) {
$tmp = explode(' ', $output[0]);
if (isset($tmp[0])) {
$dns_ip = $tmp[0];
}
}
$vhosts[] = array(
'name' => $directory,
'htdocs' => $htdocs_ok,
'dns_ok' => $dns_ok,
'dns_ip' => $dns_ip,
'domain' => $directory.'.loc',
'href' => 'http://' . $directory.'.loc'
);
}
}
}
return $vhosts;
}
/********************************************************************************
*
* G E T V E R S I O N
*
********************************************************************************/
/**
* Get HTTPD Version
* @return [type] [description]
*/
function getHttpVersion() {
preg_match('/\w+\/[.0-9]+/i', $_SERVER['SERVER_SOFTWARE'], $matches);
if (isset($matches[0])) {
return $matches[0];
} else {
return 'Unknown Webserver';
}
}
/**
* Get MySQL Version
* @return [type] [description]
*/
function getMySQLVersion() {
$name = getMySQLConfigByKey('version_comment');
$version = getMySQLConfigByKey('version');
if (!$name && !$version) {
return 'Unknown Version';
}
return $name . ' ' . $version;
}
function getPHPVersion() {
return 'PHP ' . phpversion() .' (' . php_sapi_name().')';
}
/********************************************************************************
*
* T E S T M Y S Q L C O N N E C T I O N
*
********************************************************************************/
function testMySQLLocalhost() {
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect('localhost', 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via localhost socket';
}
function testMySQLLocalIp() {
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect('127.0.0.1', 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via 127.0.0.1';
}
function testMySQLRemotelIp() {
global $MYSQL_HOST_ADDR;
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect($MYSQL_HOST_ADDR, 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via '.$MYSQL_HOST_ADDR;
}

View File

@ -27,7 +27,7 @@
<!-- CSS/JS -->
<link href="/vendor/bootstrap/bootstrap.min.css" rel="stylesheet">
<?php if (isset($FONT_AWESOME)): ?>
<?php if (isset($FONT_AWESOME) && $FONT_AWESOME): ?>
<link href="/vendor/font-awesome/font-awesome.min.css" rel="stylesheet">
<?php endif; ?>
<link href="/assets/css/custom.css" rel="stylesheet">

View File

@ -0,0 +1,398 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
* @requires devilbox::Mysql
*/
class Docker
{
/*********************************************************************************
*
* Statics
*
*********************************************************************************/
/**
* $this Singleton instance
* @var Object|null
*/
protected static $instance = null;
/**
* Singleton Instance getter.
*
* @return object|null
*/
public static function getInstance()
{
if (!isset(static::$instance)) {
static::$instance = new static();
}
return static::$instance;
}
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* Array of docker environment variables
* @var mixed[]
*/
private $_env = array();
/**
* Domain suffix.
*
* @var string
*/
private $_tld = 'loc';
/**
* Document root path in PHP docker
* @var string
*/
private $_doc_root = '/shared/httpd';
/*********************************************************************************
*
* Construct/Destructor
*
*********************************************************************************/
/**
* Private Constructor, so nobody can call it.
* Use singleton getInstance() instead.
*/
private function __construct()
{
// Do not call me
// Translate Docker environmental variables to $ENV
exec('env', $output);
foreach ($output as $var) {
$tmp = explode('=', $var);
$this->_env[$tmp[0]] = $tmp[1];
}
}
/*********************************************************************************
*
* Public functions
*
*********************************************************************************/
/**
* Get Docker environment variables from docker-compose.yml
* @param string $variable Variable name
* @return string Variable value
*/
public function getEnv($variable)
{
if (!isset($this->_env[$variable])) {
$Logger = \devilbox\Logger::getInstance();
$logger->error('Docker environment variable not found: '.$variable);
return null;
}
return $this->_env[$variable];
}
/**
* Get tld suffix.
*
* @return string
*/
public function getTld()
{
return $this->_tld;
}
/*********************************************************************************
*
* PHP Docker functions
*
*********************************************************************************/
/**
* Get PHP Version.
*
* @return string PHP version string
*/
public function PHP_version()
{
return 'PHP ' . phpversion() .' (' . php_sapi_name().')';
}
/**
* Read out PHP Server configuration by variable
*
* @param string|null $key Config key name
* @return string|mixed[]
*/
public function PHP_config($key = null)
{
// Get all configs as array
if ($key === null) {
return ini_get_all();
} else {
return ini_get($key);
}
}
/**
* Return an array of custom mounted PHP config files.
*
* @return string[]
*/
public function PHP_custom_config_files()
{
$files = array();
foreach (scandir('/etc/php-custom.d') as $file) {
if (preg_match('/.*\.ini$/', $file) === 1) {
$files[] = $file;
}
}
return $files;
}
/**
* Check if mounted MySQL socket is valid inside PHP Docker.
*
* @param string $error Reference to error message.
* @return boolean
*/
public function PHP_has_valid_mysql_socket(&$error)
{
if (!$this->getEnv('MOUNT_MYSQL_SOCKET_TO_LOCALDISK')) {
$error = 'Socket mount not enabled.';
return false;
}
if (!file_exists($this->getEnv('MYSQL_SOCKET_PATH'))) {
$error = 'Socket file not found.';
return false;
}
//if (getMySQLConfigByKey('socket') != $ENV['MYSQL_SOCKET_PATH']) {
// $error = 'Mounted from mysql:'.$ENV['MYSQL_SOCKET_PATH']. ', but socket is in mysql:'.getMySQLConfigByKey('socket');
// return FALSE;
//}
$error = '';
return true;
}
/**
* Get all mass virtual Hosts by directories
*
* @return mixed[]
*/
public function PHP_getVirtualHosts()
{
$docRoot = $this->_doc_root;
$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->_tld,
'href' => 'http://' . $directory . '.' . $this->_tld
);
}
}
}
return $vhosts;
}
/**
* Check single mass virtual host
*
* @param string $vhost Virtual Host name
* @return string Errors
*/
public function PHP_checkVirtualHost($vhost)
{
$docRoot = $this->_doc_root;
$htdocs = $docRoot . DIRECTORY_SEPARATOR . $vhost . DIRECTORY_SEPARATOR . 'htdocs';
$domain = $vhost . '.' . $this->_tld;
$url = 'http://'.$domain;
$error = array();
// 1. Check htdocs folder
if (!$this->_is_valid_dir($htdocs)) {
$error[] = 'Missing <strong>htdocs</strong> directory in: <strong>'.$this->getEnv('HOST_PATH_TO_WWW_DOCROOTS').'/'.$vhost.'/</strong>';
}
if ($GLOBALS['ENABLE_VHOST_DNS_CHECK']) {
// 2. Check /etc/resolv DNS entry
$output;
if ($this->_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 '';
}
}
/*********************************************************************************
*
* MySQL Docker functions
*
*********************************************************************************/
/**
* Get MySQL Version.
*
* @return string MySQL version string.
*/
public function MySQL_version()
{
$name = $this->MySQL_config('version_comment');
$version = $this->MySQL_config('version');
if (!$name && !$version) {
return 'Unknown Version';
}
return $name . ' ' . $version;
}
/**
* Read out MySQL Server configuration by variable
*
* @param string|null $key Config key name
* @return string|mixed[]
*/
public function MySQL_config($key = null)
{
// Get all configs as array
if ($key === null) {
$callback = function ($row, &$data) {
$key = $row['Variable_name'];
$val = $row['Value'];
$data[$key] = $val;
};
$sql = 'SHOW VARIABLES;';
$configs = \devilbox\Mysql::getInstance()->select($sql, $callback);
return $configs ? $configs : array();
} 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 = \devilbox\Mysql::getInstance()->select($sql, $callback);
if (is_array($val) && $val) {
return array_values($val)[0];
} else {
return $val;
}
}
}
/*********************************************************************************
*
* HTTPD Docker functions
*
*********************************************************************************/
/**
* Get HTTPD Version
*
* @return string HTTPD server version string.
*/
public function HTTPD_version()
{
preg_match('/\w+\/[.0-9]+/i', $_SERVER['SERVER_SOFTWARE'], $matches);
if (isset($matches[0])) {
return $matches[0];
} else {
return 'Unknown Webserver';
}
}
/*********************************************************************************
*
* 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))));
}
/**
* Executes shell commands on the PHP-FPM Host
*
* @param string $cmd Command
* @param string $output Reference to output
* @return integer
*/
private function _exec($cmd, &$output = '')
{
// Clean output
$output = '';
exec($cmd, $output, $exit_code);
return $exit_code;
}
}

View File

@ -0,0 +1,157 @@
<?php
namespace devilbox;
/**
* Log devilbox intranet errors.
* If logging is not possible, it will generate emails
* that are handled by mail.php
*/
/**
* This is going to log into the PHP docker's /tmp directory
*/
class Logger
{
/*********************************************************************************
*
* Statics
*
*********************************************************************************/
/**
* Mysql instance
* @var Mysql|null
*/
protected static $instance = null;
/**
* Singleton Instance getter.
*
* @return object|null
*/
public static function getInstance()
{
if (!isset(static::$instance)) {
static::$instance = new static();
}
return static::$instance;
}
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* File pointer.
* @var resource
*/
private $_fp = null;
/**
* Logfile path
* @var string
*/
private $_logfile = '/tmp/devilbox-intranet/error.log';
/*********************************************************************************
*
* Construct/Destructor
*
*********************************************************************************/
/**
* Private Constructor, so nobody can call it.
* Use singleton getInstance() instead.
*/
private function __construct()
{
// Silence errors
error_reporting(0);
$logdir = dirname($this->_logfile);
// Create log directory if it does not exist
if (!is_dir($logdir)) {
if (!mkdir($logdir, 0777, true)) {
$this->error('Cannot create log directory: '. $logdir);
}
}
// Open logfile in append mode
if (!($this->_fp = fopen($this->_logfile, 'a+'))) {
$this->error('Error opening logfile: '. $this->_logfile);
}
// Re-enable error reporting
error_reporting(-1);
}
/**
* Destructor - closes logfile
*/
public function __destruct()
{
if ($this->_fp) {
fclose($this->_fp);
}
}
/*********************************************************************************
*
* Public functions
*
*********************************************************************************/
/**
* Log errors
* @param string $message The message to log
*/
public function error($message)
{
$mail_body = $message."\r\n";
if (!$this->_fp) {
return mail('apache@localhost', 'devilbox error', $mail_body);
}
$message = date('Y-m-d H:i') . "\n" . $message;
$message = str_replace("\n", '<br/>', $message);
$message = $message . "\n";
if (fwrite($this->_fp, $message) === false) {
return mail('apache@localhost', 'devilbox error', $mail_body);
}
}
/**
* Get all logged messages as array.
*
* @return false|mixed[] Array of error messages or false if logfile is not writeable
*/
public function getAll()
{
$lines = array();
if ($this->_fp) {
rewind($this->_fp);
while (($buffer = fgets($this->_fp)) !== false) {
$lines[] = $buffer;
}
return $lines;
}
return false;
}
}

View File

@ -31,7 +31,7 @@ class Mail
*
* @param string $mboxPath Path to mbox file.
*/
function __construct($mboxPath)
public function __construct($mboxPath)
{
$this->_Mbox = new \Mail_Mbox($mboxPath);
$this->_Mbox->open();
@ -41,7 +41,7 @@ class Mail
/**
* Destructor
*/
function __destruct()
public function __destruct()
{
$this->_Mbox->close();
}

View File

@ -0,0 +1,318 @@
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
class Mysql
{
/*********************************************************************************
*
* Statics
*
*********************************************************************************/
/**
* Mysql instance
* @var Mysql|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 MySQL 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 MySQL username
* @param string $pass MySQL password
* @param string $host MySQL hostname
* @return boolean
*/
public static function testConnection(&$err, $user, $pass, $host)
{
$err = false;
// Silence errors and try to connect
error_reporting(0);
$link = mysqli_connect($host, $user, $pass);
error_reporting(-1);
if (mysqli_connect_errno()) {
$err = 'Failed to connect: ' .mysqli_connect_error();
return false;
}
mysqli_close($link);
return true;
}
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* MySQL 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
*/
public function __construct($user, $pass, $host)
{
// Silence errors and try to connect
error_reporting(0);
$link = mysqli_connect($host, $user, $pass);
error_reporting(-1);
if (mysqli_connect_errno()) {
$this->_connect_error = 'Failed to connect: ' .mysqli_connect_error();
$this->_connect_errno = mysqli_connect_errno();
\devilbox\Logger::getInstance()->error($this->_connect_error);
} else {
$this->_link = $link;
}
}
/**
* Destructor
*/
public function __destruct()
{
if ($this->_link) {
mysqli_close($this->_link);
}
}
/*********************************************************************************
*
* MySQL 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) {
\devilbox\Logger::getInstance()->error('MySQL error, link is no resource in select()');
return false;
}
if (!($result = mysqli_query($this->_link, $query))) {
$this->_error = mysqli_error($this->_link);
$this->_errno = mysqli_errno($this->_link);
\devilbox\Logger::getInstance()->error($this->_error);
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
WHERE
S.SCHEMA_NAME != 'mysql' AND
S.SCHEMA_NAME != 'performance_schema' AND
S.SCHEMA_NAME != 'information_schema'";
$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;
}
/*********************************************************************************
*
* 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;
}
}

View File

@ -5,13 +5,40 @@ namespace devilbox;
class Sort
{
/**
* Default sort name
* @var string
*/
private $_default_sort;
/**
* Default order name
* @var string
*/
private $_default_order;
/**
* Array of allowed sort names
* @var string[]
*/
private $_allowedSorts;
/**
* Array of allowed order names
* @var string[]
*/
private $_allowedOrders;
/**
* Name of $_GET key for current sort
* @var string
*/
private $_GET_sort;
/**
* Name of $_GET key for current order
* @var string
*/
private $_GET_order;
@ -23,7 +50,7 @@ class Sort
* @param mixed[] $allowedOrders Array of allowed orders
* @param mixed[] $GET_sortKeys Array of sort/order $_GET key names
*/
function __construct($defaults, $allowedSorts, $allowedOrders, $GET_sortKeys)
public function __construct($defaults, $allowedSorts, $allowedOrders, $GET_sortKeys)
{
// Default sort/order
$this->_default_sort = $defaults['sort'];