- new "ESI monitoring" UI dialog, closed #748
- new "Redis monitoring" UI on `/setup` page, closed #745 - improved request handling for 3rd party APIs (ESI, SSO, GitHub) see [exodus4d/pathfinder_esi/README.md](https://github.com/exodus4d/pathfinder_esi/blob/b5d4b19/README.md) - improved `/setup` page, new actions for clear cache/Redis data
This commit is contained in:
@@ -167,9 +167,6 @@ class Setup extends Controller {
|
||||
// js view (file)
|
||||
$f3->set('tplJsView', 'setup');
|
||||
|
||||
// set render functions (called within template)
|
||||
$f3->set('cacheType', $this->getCacheType($f3));
|
||||
|
||||
// simple counter (called within template)
|
||||
$counter = [];
|
||||
$f3->set('tplCounter', function(string $action = 'increment', string $type = 'default', $val = 0) use (&$counter){
|
||||
@@ -187,19 +184,6 @@ class Setup extends Controller {
|
||||
echo \Template::instance()->render( Config::getPathfinderData('view.index') );
|
||||
}
|
||||
|
||||
/**
|
||||
* get Cache backend type for F3
|
||||
* @param \Base $f3
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheType(\Base &$f3) : string {
|
||||
$cacheType = $f3->get('CACHE');
|
||||
if(strpos($cacheType, 'redis') !== false){
|
||||
$cacheType = 'redis';
|
||||
}
|
||||
return $cacheType;
|
||||
}
|
||||
|
||||
/**
|
||||
* main setup route handler
|
||||
* works as dispatcher for setup functions
|
||||
@@ -229,47 +213,63 @@ class Setup extends Controller {
|
||||
case 'exportTable':
|
||||
$this->exportTable($params['model']);
|
||||
break;
|
||||
case 'clearCache':
|
||||
$this->clearCache($f3);
|
||||
case 'clearFiles':
|
||||
$this->clearFiles((string)$params['path']);
|
||||
break;
|
||||
case 'flushRedisDb':
|
||||
$this->flushRedisDb((string)$params['host'], (int)$params['port'], (int)$params['db']);
|
||||
break;
|
||||
case 'invalidateCookies':
|
||||
$this->invalidateCookies($f3);
|
||||
break;
|
||||
}
|
||||
|
||||
// set template data ----------------------------------------------------------------
|
||||
// set environment information
|
||||
$f3->set('environmentInformation', $this->getEnvironmentInformation($f3));
|
||||
// ============================================================================================================
|
||||
// Template data
|
||||
// ============================================================================================================
|
||||
|
||||
// set server information
|
||||
// Server -----------------------------------------------------------------------------------------------------
|
||||
// Server information
|
||||
$f3->set('serverInformation', $this->getServerInformation($f3));
|
||||
|
||||
// set requirement check information
|
||||
$f3->set('checkRequirements', $this->checkRequirements($f3));
|
||||
// Pathfinder directory config
|
||||
$f3->set('directoryConfig', $this->getDirectoryConfig($f3));
|
||||
|
||||
// set php config check information
|
||||
$f3->set('checkPHPConfig', $this->checkPHPConfig($f3));
|
||||
|
||||
// set system config check information
|
||||
// Server environment variables
|
||||
$f3->set('checkSystemConfig', $this->checkSystemConfig($f3));
|
||||
|
||||
// set map default config
|
||||
// Environment ------------------------------------------------------------------------------------------------
|
||||
// Server requirement
|
||||
$f3->set('checkRequirements', $this->checkRequirements($f3));
|
||||
|
||||
// PHP config
|
||||
$f3->set('checkPHPConfig', $this->checkPHPConfig($f3));
|
||||
|
||||
// Settings ---------------------------------------------------------------------------------------------------
|
||||
// Pathfinder environment config
|
||||
$f3->set('environmentInformation', $this->getEnvironmentInformation($f3));
|
||||
|
||||
// Pathfinder map default config
|
||||
$f3->set('mapsDefaultConfig', $this->getMapsDefaultConfig($f3));
|
||||
|
||||
// set database connection information
|
||||
// Database ---------------------------------------------------------------------------------------------------
|
||||
// Database config
|
||||
$f3->set('checkDatabase', $this->checkDatabase($f3, $fixColumns));
|
||||
|
||||
// set socket information
|
||||
// Redis ------------------------------------------------------------------------------------------------------
|
||||
// Redis information
|
||||
$f3->set('checkRedisInformation', $this->checkRedisInformation($f3));
|
||||
|
||||
// Socket -----------------------------------------------------------------------------------------------------
|
||||
// WebSocket information
|
||||
$f3->set('socketInformation', $this->getSocketInformation());
|
||||
|
||||
// set index information
|
||||
// Administration ---------------------------------------------------------------------------------------------
|
||||
// Index information
|
||||
$f3->set('indexInformation', $this->getIndexData($f3));
|
||||
|
||||
// set cache size
|
||||
$f3->set('cacheSize', $this->getCacheData($f3));
|
||||
|
||||
// set Redis config check information
|
||||
$f3->set('checkRedisConfig', $this->checkRedisConfig($f3));
|
||||
// Filesystem (cache) size
|
||||
$f3->set('checkDirSize', $this->checkDirSize($f3));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,6 +290,9 @@ class Setup extends Controller {
|
||||
'database' => [
|
||||
'icon' => 'fa-database'
|
||||
],
|
||||
'cache' => [
|
||||
'icon' => 'fa-hdd'
|
||||
],
|
||||
'socket' => [
|
||||
'icon' => 'fa-exchange-alt'
|
||||
],
|
||||
@@ -306,7 +309,7 @@ class Setup extends Controller {
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function getEnvironmentInformation(\Base $f3){
|
||||
protected function getEnvironmentInformation(\Base $f3) : array {
|
||||
$environmentData = [];
|
||||
// exclude some sensitive data (e.g. database, passwords)
|
||||
$excludeVars = [
|
||||
@@ -346,7 +349,7 @@ class Setup extends Controller {
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function getServerInformation(\Base $f3){
|
||||
protected function getServerInformation(\Base $f3) : array {
|
||||
$serverInfo = [
|
||||
'time' => [
|
||||
'label' => 'Time',
|
||||
@@ -389,15 +392,90 @@ class Setup extends Controller {
|
||||
return $serverInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* get information for used directories
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function getDirectoryConfig(\Base $f3) : array {
|
||||
$directoryData = [
|
||||
'TEMP' => [
|
||||
'label' => 'TEMP',
|
||||
'value' => $f3->get('TEMP'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Temporary folder for pre compiled templates.',
|
||||
'chmod' => Util::filesystemInfo($f3->get('TEMP'))['chmod']
|
||||
],
|
||||
'CACHE' => [
|
||||
'label' => 'CACHE',
|
||||
'value' => $f3->get('CACHE'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Cache backend. Support for Redis, Memcache, APC, WinCache, XCache and a filesystem-based (default) cache.',
|
||||
'chmod' => ((Config::parseDSN($f3->get('CACHE'), $confCache)) && $confCache['type'] == 'folder') ?
|
||||
Util::filesystemInfo((string)$confCache['folder'])['chmod'] : ''
|
||||
],
|
||||
'API_CACHE' => [
|
||||
'label' => 'API_CACHE',
|
||||
'value' => $f3->get('API_CACHE'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Cache backend for API related cache data. Support for Redis and a filesystem-based (default) cache.',
|
||||
'chmod' => ((Config::parseDSN($f3->get('API_CACHE'), $confCacheApi)) && $confCacheApi['type'] == 'folder') ?
|
||||
Util::filesystemInfo((string)$confCacheApi['folder'])['chmod'] : ''
|
||||
],
|
||||
'LOGS' => [
|
||||
'label' => 'LOGS',
|
||||
'value' => $f3->get('LOGS'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Folder for pathfinder logs (e.g. cronjob-, error-logs, ...).',
|
||||
'chmod' => Util::filesystemInfo($f3->get('LOGS'))['chmod']
|
||||
],
|
||||
'UI' => [
|
||||
'label' => 'UI',
|
||||
'value' => $f3->get('UI'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Folder for public accessible resources (templates, js, css, images,..).',
|
||||
'chmod' => Util::filesystemInfo($f3->get('UI'))['chmod']
|
||||
],
|
||||
'AUTOLOAD' => [
|
||||
'label' => 'AUTOLOAD',
|
||||
'value' => $f3->get('AUTOLOAD'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Autoload folder for PHP files.',
|
||||
'chmod' => Util::filesystemInfo($f3->get('AUTOLOAD'))['chmod']
|
||||
],
|
||||
'FAVICON' => [
|
||||
'label' => 'FAVICON',
|
||||
'value' => $f3->get('FAVICON'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Folder for Favicons.',
|
||||
'chmod' => Util::filesystemInfo($f3->get('FAVICON'))['chmod']
|
||||
],
|
||||
'HISTORY' => [
|
||||
'label' => 'HISTORY [optional]',
|
||||
'value' => Config::getPathfinderData('history.log'),
|
||||
'check' => true,
|
||||
'tooltip' => 'Folder for log history files. (e.g. change logs for maps).',
|
||||
'chmod' => Util::filesystemInfo(Config::getPathfinderData('history.log'))['chmod']
|
||||
],
|
||||
'CONFIG' => [
|
||||
'label' => 'CONFIG PATH [optional]',
|
||||
'value' => implode(' ', (array)$f3->get('CONF')),
|
||||
'check' => true,
|
||||
'tooltip' => 'Folder for custom *.ini files. (e.g. when overwriting of default values in app/*.ini)'
|
||||
]
|
||||
];
|
||||
|
||||
return $directoryData;
|
||||
}
|
||||
|
||||
/**
|
||||
* check all required backend requirements
|
||||
* (Fat Free Framework)
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function checkRequirements(\Base $f3){
|
||||
protected function checkRequirements(\Base $f3) : array {
|
||||
|
||||
// server type ------------------------------------------------------------------
|
||||
$serverData = self::getServerData(0);
|
||||
|
||||
$checkRequirements = [
|
||||
@@ -516,7 +594,7 @@ class Setup extends Controller {
|
||||
$modNotFoundMsg = 'Module status can not be identified. '
|
||||
. 'This can happen if PHP runs as \'FastCGI\'. Please check manual! ';
|
||||
|
||||
// mod_rewrite check ------------------------------------------------------------
|
||||
// mod_rewrite check --------------------------------------------------------------------------------------
|
||||
$modRewriteCheck = false;
|
||||
$modRewriteVersion = 'disabled';
|
||||
$modRewriteTooltip = false;
|
||||
@@ -539,7 +617,7 @@ class Setup extends Controller {
|
||||
'tooltip' => $modRewriteTooltip
|
||||
];
|
||||
|
||||
// mod_headers check ------------------------------------------------------------
|
||||
// mod_headers check --------------------------------------------------------------------------------------
|
||||
$modHeadersCheck = false;
|
||||
$modHeadersVersion = 'disabled';
|
||||
$modHeadersTooltip = false;
|
||||
@@ -572,6 +650,11 @@ class Setup extends Controller {
|
||||
* @return array
|
||||
*/
|
||||
protected function checkPHPConfig(\Base $f3): array {
|
||||
$memoryLimit = (int)ini_get('memory_limit');
|
||||
$maxInputVars = (int)ini_get('max_input_vars');
|
||||
$maxExecutionTime = (int)ini_get('max_execution_time'); // 0 == infinite
|
||||
$htmlErrors = (int)ini_get('html_errors');
|
||||
|
||||
$phpConfig = [
|
||||
'exec' => [
|
||||
'label' => 'exec()',
|
||||
@@ -583,29 +666,29 @@ class Setup extends Controller {
|
||||
'memoryLimit' => [
|
||||
'label' => 'memory_limit',
|
||||
'required' => $f3->get('REQUIREMENTS.PHP.MEMORY_LIMIT'),
|
||||
'version' => ini_get('memory_limit'),
|
||||
'check' => ini_get('memory_limit') >= $f3->get('REQUIREMENTS.PHP.MEMORY_LIMIT'),
|
||||
'version' => $memoryLimit,
|
||||
'check' => $memoryLimit >= $f3->get('REQUIREMENTS.PHP.MEMORY_LIMIT'),
|
||||
'tooltip' => 'PHP default = 64MB.'
|
||||
],
|
||||
'maxInputVars' => [
|
||||
'label' => 'max_input_vars',
|
||||
'required' => $f3->get('REQUIREMENTS.PHP.MAX_INPUT_VARS'),
|
||||
'version' => ini_get('max_input_vars'),
|
||||
'check' => ini_get('max_input_vars') >= $f3->get('REQUIREMENTS.PHP.MAX_INPUT_VARS'),
|
||||
'version' => $maxInputVars,
|
||||
'check' => $maxInputVars >= $f3->get('REQUIREMENTS.PHP.MAX_INPUT_VARS'),
|
||||
'tooltip' => 'PHP default = 1000. Increase it in order to import larger maps.'
|
||||
],
|
||||
'maxExecutionTime' => [
|
||||
'label' => 'max_execution_time',
|
||||
'required' => $f3->get('REQUIREMENTS.PHP.MAX_EXECUTION_TIME'),
|
||||
'version' => ini_get('max_execution_time'),
|
||||
'check' => ini_get('max_execution_time') >= $f3->get('REQUIREMENTS.PHP.MAX_EXECUTION_TIME'),
|
||||
'version' => $maxExecutionTime,
|
||||
'check' => !$maxExecutionTime || $maxExecutionTime >= $f3->get('REQUIREMENTS.PHP.MAX_EXECUTION_TIME'),
|
||||
'tooltip' => 'PHP default = 30. Max execution time for PHP scripts.'
|
||||
],
|
||||
'htmlErrors' => [
|
||||
'label' => 'html_errors',
|
||||
'required' => $f3->get('REQUIREMENTS.PHP.HTML_ERRORS'),
|
||||
'version' => (int)ini_get('html_errors'),
|
||||
'check' => (bool)ini_get('html_errors') == (bool)$f3->get('REQUIREMENTS.PHP.HTML_ERRORS'),
|
||||
'version' => $htmlErrors,
|
||||
'check' => (bool)$htmlErrors == (bool)$f3->get('REQUIREMENTS.PHP.HTML_ERRORS'),
|
||||
'tooltip' => 'Formatted HTML StackTrace on error.'
|
||||
],
|
||||
[
|
||||
@@ -640,70 +723,209 @@ class Setup extends Controller {
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function checkRedisConfig(\Base $f3): array {
|
||||
protected function checkRedisInformation(\Base $f3): array {
|
||||
$redisConfig = [];
|
||||
if($this->getCacheType($f3) === 'redis'){
|
||||
// we need to access the "protected" member $ref from F3´s Cache class
|
||||
// to get access to the underlying Redis() class
|
||||
$ref = new \ReflectionObject($cache = \Cache::instance());
|
||||
$prop = $ref->getProperty('ref');
|
||||
$prop->setAccessible(true);
|
||||
|
||||
if(
|
||||
extension_loaded('redis') &&
|
||||
class_exists('\Redis')
|
||||
){
|
||||
// collection of DSN specific $conf array (host, port, db,..)
|
||||
$dsnData = [];
|
||||
|
||||
/**
|
||||
* @var $redis \Redis
|
||||
* get client information for a Redis client
|
||||
* @param \Redis $client
|
||||
* @param array $conf
|
||||
* @return array
|
||||
*/
|
||||
$redis = $prop->getValue($cache);
|
||||
$getClientInfo = function(\Redis $client, array $conf) : array {
|
||||
$redisInfo = [
|
||||
'dsn' => [
|
||||
'label' => 'DNS',
|
||||
'value' => $conf['host'] . ':' . $conf['port']
|
||||
],
|
||||
'connected' => [
|
||||
'label' => 'status',
|
||||
'value' => $client->isConnected()
|
||||
]
|
||||
];
|
||||
|
||||
$redisServerInfo = (array)$redis->info('SERVER');
|
||||
$redisMemoryInfo = (array)$redis->info('MEMORY');
|
||||
$redisStatsInfo = (array)$redis->info('STATS');
|
||||
return $redisInfo;
|
||||
};
|
||||
|
||||
$redisConfig = [
|
||||
'redisVersion' => [
|
||||
'label' => 'redis_version',
|
||||
'required' => number_format((float)$f3->get('REQUIREMENTS.REDIS.VERSION'), 1, '.', ''),
|
||||
'version' => $redisServerInfo['redis_version'],
|
||||
'check' => version_compare( $redisServerInfo['redis_version'], $f3->get('REQUIREMENTS.REDIS.VERSION'), '>='),
|
||||
'tooltip' => 'Redis server version'
|
||||
],
|
||||
'maxMemory' => [
|
||||
'label' => 'maxmemory',
|
||||
'required' => $this->convertBytes($f3->get('REQUIREMENTS.REDIS.MAX_MEMORY')),
|
||||
'version' => $this->convertBytes($redisMemoryInfo['maxmemory']),
|
||||
'check' => $redisMemoryInfo['maxmemory'] >= $f3->get('REQUIREMENTS.REDIS.MAX_MEMORY'),
|
||||
'tooltip' => 'Max memory limit for Redis'
|
||||
],
|
||||
'usedMemory' => [
|
||||
'label' => 'used_memory',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory']),
|
||||
'check' => $redisMemoryInfo['used_memory'] < $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Current memory used by Redis'
|
||||
],
|
||||
'usedMemoryPeak' => [
|
||||
'label' => 'used_memory_peak',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory_peak']),
|
||||
'check' => $redisMemoryInfo['used_memory_peak'] <= $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Peak memory used by Redis'
|
||||
],
|
||||
'maxmemoryPolicy' => [
|
||||
'label' => 'maxmemory_policy',
|
||||
'required' => $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'version' => $redisMemoryInfo['maxmemory_policy'],
|
||||
'check' => $redisMemoryInfo['maxmemory_policy'] == $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'tooltip' => 'How Redis behaves if \'maxmemory\' limit reached'
|
||||
],
|
||||
'evictedKeys' => [
|
||||
'label' => 'evicted_keys',
|
||||
'version' => $redisStatsInfo['evicted_keys'],
|
||||
'check' => !(bool)$redisStatsInfo['evicted_keys'],
|
||||
'tooltip' => 'Number of evicted keys due to maxmemory limit'
|
||||
],
|
||||
'dbSize' . $redis->getDbNum() => [
|
||||
'label' => 'Size DB (' . $redis->getDbNum() . ')',
|
||||
'version' => $redis->dbSize(),
|
||||
'check' => $redis->dbSize() > 0,
|
||||
'tooltip' => 'Keys found in DB (' . $redis->getDbNum() . ') [Cache DB]'
|
||||
]
|
||||
/**
|
||||
* get status information for a Redis client
|
||||
* @param \Redis $client
|
||||
* @return array
|
||||
*/
|
||||
$getClientStats = function(\Redis $client) use ($f3) : array {
|
||||
$redisStats = [];
|
||||
|
||||
if($client->isConnected()){
|
||||
$redisServerInfo = (array)$client->info('SERVER');
|
||||
$redisMemoryInfo = (array)$client->info('MEMORY');
|
||||
$redisStatsInfo = (array)$client->info('STATS');
|
||||
|
||||
$redisStats = [
|
||||
'redisVersion' => [
|
||||
'label' => 'redis_version',
|
||||
'required' => number_format((float)$f3->get('REQUIREMENTS.REDIS.VERSION'), 1, '.', ''),
|
||||
'version' => $redisServerInfo['redis_version'],
|
||||
'check' => version_compare( $redisServerInfo['redis_version'], $f3->get('REQUIREMENTS.REDIS.VERSION'), '>='),
|
||||
'tooltip' => 'Redis server version'
|
||||
],
|
||||
'maxMemory' => [
|
||||
'label' => 'maxmemory',
|
||||
'required' => $this->convertBytes($f3->get('REQUIREMENTS.REDIS.MAX_MEMORY')),
|
||||
'version' => $this->convertBytes($redisMemoryInfo['maxmemory']),
|
||||
'check' => $redisMemoryInfo['maxmemory'] >= $f3->get('REQUIREMENTS.REDIS.MAX_MEMORY'),
|
||||
'tooltip' => 'Max memory limit for Redis'
|
||||
],
|
||||
'usedMemory' => [
|
||||
'label' => 'used_memory',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory']),
|
||||
'check' => $redisMemoryInfo['used_memory'] < $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Current memory used by Redis'
|
||||
],
|
||||
'usedMemoryPeak' => [
|
||||
'label' => 'used_memory_peak',
|
||||
'version' => $this->convertBytes($redisMemoryInfo['used_memory_peak']),
|
||||
'check' => $redisMemoryInfo['used_memory_peak'] <= $redisMemoryInfo['maxmemory'],
|
||||
'tooltip' => 'Peak memory used by Redis'
|
||||
],
|
||||
'maxmemoryPolicy' => [
|
||||
'label' => 'maxmemory_policy',
|
||||
'required' => $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'version' => $redisMemoryInfo['maxmemory_policy'],
|
||||
'check' => $redisMemoryInfo['maxmemory_policy'] == $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
|
||||
'tooltip' => 'How Redis behaves if \'maxmemory\' limit reached'
|
||||
],
|
||||
'evictedKeys' => [
|
||||
'label' => 'evicted_keys',
|
||||
'version' => $redisStatsInfo['evicted_keys'],
|
||||
'check' => !(bool)$redisStatsInfo['evicted_keys'],
|
||||
'tooltip' => 'Number of evicted keys due to maxmemory limit'
|
||||
],
|
||||
[
|
||||
'label' => 'Databases'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $redisStats;
|
||||
};
|
||||
|
||||
/**
|
||||
* get database status for current selected db
|
||||
* @param \Redis $client
|
||||
* @param string $tag
|
||||
* @return array
|
||||
*/
|
||||
$getDatabaseStatus = function(\Redis $client, string $tag) : array {
|
||||
$redisDatabases = [];
|
||||
if($client->isConnected()){
|
||||
$dbNum = $client->getDbNum();
|
||||
$dbSize = $client->dbSize();
|
||||
$redisDatabases = [
|
||||
'db_' . $dbNum => [
|
||||
'label' => '<i class="fas fa-fw fa-database"></i> db(' . $dbNum . ') : ' . $tag,
|
||||
'version' => $dbSize . ' keys',
|
||||
'check' => $dbSize > 0,
|
||||
'tooltip' => 'Keys in db(' . $dbNum . ')',
|
||||
'task' => [
|
||||
[
|
||||
'action' => http_build_query([
|
||||
'action' => 'flushRedisDb',
|
||||
'host' => $client->getHost(),
|
||||
'port' => $client->getPort(),
|
||||
'db' => $dbNum
|
||||
]) . '#pf-setup-cache',
|
||||
'label' => 'Flush',
|
||||
'icon' => 'fa-trash',
|
||||
'btn' => 'btn-danger' . (($dbSize > 0) ? '' : ' disabled')
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $redisDatabases;
|
||||
};
|
||||
|
||||
/**
|
||||
* build (modify) $redisConfig with DNS $conf data
|
||||
* @param array $conf
|
||||
*/
|
||||
$buildRedisConfig = function(array $conf) use (&$redisConfig, $getClientInfo, $getClientStats, $getDatabaseStatus){
|
||||
if($conf['type'] == 'redis'){
|
||||
// is Redis -> group all DNS by host:port
|
||||
$client = new \Redis();
|
||||
|
||||
try{
|
||||
$client->connect($conf['host'], $conf['port'], 0.3);
|
||||
if(isset($conf['db'])) {
|
||||
$client->select($conf['db']);
|
||||
}
|
||||
|
||||
$conf['db'] = $client->getDbNum();
|
||||
}catch(\RedisException $e){
|
||||
// connection failed
|
||||
}
|
||||
|
||||
if(!array_key_exists($uid = $conf['host'] . ':' . $conf['port'], $redisConfig)){
|
||||
$redisConfig[$uid] = $getClientInfo($client, $conf);
|
||||
$redisConfig[$uid]['status'] = $getClientStats($client) + $getDatabaseStatus($client, $conf['tag']);
|
||||
}elseif(!array_key_exists($uidDb = 'db_' . $conf['db'], $redisConfig[$uid]['status'])){
|
||||
$redisConfig[$uid]['status'] += $getDatabaseStatus($client, $conf['tag']);
|
||||
}else{
|
||||
$redisConfig[$uid]['status'][$uidDb]['label'] .= '; ' . $conf['tag'];
|
||||
}
|
||||
|
||||
$client->close();
|
||||
}
|
||||
};
|
||||
|
||||
// potential Redis caches ---------------------------------------------------------------------------------
|
||||
$redisCaches = [
|
||||
'CACHE' => $f3->get('CACHE'),
|
||||
'API_CACHE' => $f3->get('API_CACHE')
|
||||
];
|
||||
|
||||
foreach($redisCaches as $tag => $dsn){
|
||||
if(Config::parseDSN($dsn, $conf)){
|
||||
$conf['tag'] = $tag;
|
||||
$dsnData[] = $conf;
|
||||
}
|
||||
}
|
||||
|
||||
// if Session handler is also Redis -> add this as well ---------------------------------------------------
|
||||
// -> the DSN format is not the same, convert URL format into DSN
|
||||
if(
|
||||
strtolower(session_module_name()) == 'redis' &&
|
||||
($parts = parse_url(strtolower(session_save_path())))
|
||||
){
|
||||
// parse URL parameters
|
||||
parse_str((string)$parts['query'], $params);
|
||||
|
||||
$conf = [
|
||||
'type' => 'redis',
|
||||
'host' => $parts['host'],
|
||||
'port' => $parts['port'],
|
||||
'db' => !empty($params['database']) ? (int)$params['database'] : 0,
|
||||
'tag' => 'SESSION'
|
||||
];
|
||||
$dsnData[] = $conf;
|
||||
}
|
||||
|
||||
// sort all $dsnData by 'db' number -----------------------------------------------------------------------
|
||||
usort($dsnData, function($a, $b){
|
||||
return $a['db'] <=> $b['db'];
|
||||
});
|
||||
|
||||
foreach($dsnData as $conf){
|
||||
$buildRedisConfig($conf);
|
||||
}
|
||||
}
|
||||
|
||||
return $redisConfig;
|
||||
@@ -989,14 +1211,14 @@ class Setup extends Controller {
|
||||
$changedIndex = false;
|
||||
$addConstraints = [];
|
||||
|
||||
// set (new) column information -------------------------------------------------------
|
||||
// set (new) column information -----------------------------------------------------------
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['exists'] = true;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['currentType'] = $currentColType;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['currentNullable'] = $hasNullable;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['currentIndex'] = $hasIndex;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['currentUnique'] = $hasUnique;
|
||||
|
||||
// check constraint -------------------------------------------------------------------
|
||||
// check constraint -----------------------------------------------------------------------
|
||||
if(isset($fieldConf['constraint'])){
|
||||
// add or update constraints
|
||||
foreach((array)$fieldConf['constraint'] as $constraintData){
|
||||
@@ -1022,7 +1244,7 @@ class Setup extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// check type changed -----------------------------------------------------------------
|
||||
// check type changed ---------------------------------------------------------------------
|
||||
if(
|
||||
$fieldConf['type'] !== 'JSON' &&
|
||||
!$schema->isCompatible($fieldConf['type'], $currentColType)
|
||||
@@ -1033,14 +1255,14 @@ class Setup extends Controller {
|
||||
$tableStatusCheckCount++;
|
||||
}
|
||||
|
||||
// check if column nullable changed ---------------------------------------------------
|
||||
// check if column nullable changed -------------------------------------------------------
|
||||
if( $currentNullable != $fieldConf['nullable']){
|
||||
$changedNullable = true;
|
||||
$columnStatusCheck = false;
|
||||
$tableStatusCheckCount++;
|
||||
}
|
||||
|
||||
// check if column index changed ------------------------------------------------------
|
||||
// check if column index changed ----------------------------------------------------------
|
||||
$indexUpdate = false;
|
||||
$indexKey = (bool)$hasIndex;
|
||||
$indexUnique = (bool)$hasUnique;
|
||||
@@ -1054,7 +1276,7 @@ class Setup extends Controller {
|
||||
$indexKey = (bool)$fieldConf['index'];
|
||||
}
|
||||
|
||||
// check if column unique changed -----------------------------------------------------
|
||||
// check if column unique changed ---------------------------------------------------------
|
||||
if($currentColIndexData['unique'] != $fieldConf['unique']){
|
||||
$changedUnique = true;
|
||||
$columnStatusCheck = false;
|
||||
@@ -1064,7 +1286,7 @@ class Setup extends Controller {
|
||||
$indexUnique = (bool)$fieldConf['unique'];
|
||||
}
|
||||
|
||||
// build table with changed columns ---------------------------------------------------
|
||||
// build table with changed columns -------------------------------------------------------
|
||||
if(!$columnStatusCheck || !$foreignKeyStatusCheck){
|
||||
|
||||
if(!$columnStatusCheck ){
|
||||
@@ -1106,7 +1328,7 @@ class Setup extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// set (new) column information -------------------------------------------------------
|
||||
// set (new) column information -----------------------------------------------------------
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['changedType'] = $changedType;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['changedNullable'] = $changedNullable;
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['changedUnique'] = $changedUnique;
|
||||
@@ -1360,7 +1582,7 @@ class Setup extends Controller {
|
||||
[
|
||||
'action' => 'clearIndex',
|
||||
'label' => 'Clear',
|
||||
'icon' => 'fa-times',
|
||||
'icon' => 'fa-trash',
|
||||
'btn' => 'btn-danger'
|
||||
],[
|
||||
'action' => 'buildIndex',
|
||||
@@ -1473,39 +1695,96 @@ class Setup extends Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* get cache folder size as string
|
||||
* get cache folder size
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function getCacheData(\Base $f3){
|
||||
protected function checkDirSize(\Base $f3) : array {
|
||||
// limit shown cache size. Reduce page load on big cache. In Bytes
|
||||
$maxBytes = 10 * 1024 * 1024; // 10MB
|
||||
$dirTemp = (string)$f3->get('TEMP');
|
||||
$cacheDsn = (string)$f3->get('CACHE');
|
||||
Config::parseDSN($cacheDsn, $conf);
|
||||
// if 'CACHE' is e.g. redis=... -> show default dir for cache
|
||||
$dirCache = $conf['type'] == 'folder' ? $conf['folder'] : $dirTemp . 'cache/';
|
||||
|
||||
// get all cache -----------------------------------------------------------------------------------------
|
||||
$cacheFilesAll = Search::getFilesByMTime( $f3->get('TEMP') );
|
||||
$dirAll = [
|
||||
'TEMP' => [
|
||||
'label' => 'Temp dir',
|
||||
'path' => $dirTemp
|
||||
],
|
||||
'CACHE' => [
|
||||
'label' => 'Cache dir',
|
||||
'path' => $dirCache
|
||||
]
|
||||
];
|
||||
|
||||
$maxHitAll = false;
|
||||
$bytesAll = 0;
|
||||
foreach($cacheFilesAll as $filename => $file) {
|
||||
$bytesAll += $file->getSize();
|
||||
}
|
||||
|
||||
// get data cache -----------------------------------------------------------------------------------------
|
||||
$cacheFilesData = Search::getFilesByMTime( $f3->get('TEMP') . 'cache/' );
|
||||
$bytesData = 0;
|
||||
foreach($cacheFilesData as $filename => $file) {
|
||||
$bytesData += $file->getSize();
|
||||
foreach($dirAll as $key => $dirData){
|
||||
$maxHit = false;
|
||||
$bytes = 0;
|
||||
$files = Search::getFilesByMTime($dirData['path']);
|
||||
foreach($files as $filename => $file) {
|
||||
$bytes += $file->getSize();
|
||||
if($bytes > $maxBytes){
|
||||
$maxHit = $maxHitAll = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$bytesAll += $bytes;
|
||||
|
||||
$dirAll[$key]['size'] = ($maxHit ? '>' : '') . $this->convertBytes($bytes);
|
||||
$dirAll[$key]['task'] = [
|
||||
[
|
||||
'action' => http_build_query([
|
||||
'action' => 'clearFiles',
|
||||
'path' => $dirData['path']
|
||||
]),
|
||||
'label' => 'Delete files',
|
||||
'icon' => 'fa-trash',
|
||||
'btn' => 'btn-danger' . (($bytes > 0) ? '' : ' disabled')
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'all' => $this->convertBytes($bytesAll),
|
||||
'data' => $this->convertBytes($bytesData),
|
||||
'template' => $this->convertBytes($bytesAll - $bytesData)
|
||||
'sizeAll' => ($maxHitAll ? '>' : '') . $this->convertBytes($bytesAll),
|
||||
'dirAll' => $dirAll
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all cached files
|
||||
* @param \Base $f3
|
||||
* clear directory
|
||||
* @param string $path
|
||||
*/
|
||||
protected function clearCache(\Base $f3){
|
||||
$f3->clear('CACHE');
|
||||
protected function clearFiles(string $path){
|
||||
$files = Search::getFilesByMTime($path);
|
||||
foreach($files as $filename => $file){
|
||||
/**
|
||||
* @var $file \SplFileInfo
|
||||
*/
|
||||
if($file->isFile()){
|
||||
if($file->isWritable()){
|
||||
unlink($file->getRealPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all key in a specific Redis database
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $db
|
||||
*/
|
||||
protected function flushRedisDb(string $host, int $port, int $db = 0){
|
||||
$client = new \Redis();
|
||||
$client->connect($host, $port, 0.3);
|
||||
$client->select($db);
|
||||
$client->flushDB();
|
||||
$client->close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user