"container"]);
echo UI::h('h1', [], [
UI::h('a', ['href'=>"index.php"], "SE"),
" » ",
" Status systemu procesy5"
]);
try {
DB::getPDO();
$this->runPostTask(); // _postTask = $this->"{$_POST['_postTask']}PostTask"()
$this->viewStatusDatabase();
if (in_array(User::get('ADM_ADMIN_LEVEL'), ['0', '1'])) {
$this->viewStatusUsers();
}
// UI::table([
// 'caption' => 'Baza danych',
// 'rows' => DB::getPDO()->fetchAll(" SHOW VARIABLES ")
// ]);
} catch (Exception $e) {
UI::alert('danger', $e->getMessage());
}
UI::endTag('div');// .container
UI::dol();
}
function runPostTask() {
if ($postTask = V::get('_postTask', '', $_REQUEST)) {
DBG::log($args, 'array', "exec '{$postTask}'");
if (!method_exists($this, "{$postTask}PostTask")) throw new Exception("Post Task not exists!");
ob_start();
$this->{"{$postTask}PostTask"}($args);
$outputPostTask = ob_get_clean();
if ($outputPostTask) {
echo UI::h('details', [], [
UI::h('summary', [], "Wynik '{$postTask}' (rozwiń)"),
$outputPostTask,
]);
}
}
}
public function viewStatusDatabase() {
$dbEvents = DB::getPDO()->fetchFirst(" SHOW VARIABLES WHERE VARIABLE_NAME = 'event_scheduler' ");
// DBG::nicePrint($dbEvents, '$dbEvents');
// [Variable_name] => event_scheduler
// [Value] => ON
$aclObjectCacheExists = false;
$objectStorage = SchemaFactory::loadDefaultObject('SystemObject');
$aclCacheTableName = $objectStorage->getRootTableName();
if ($aclCacheTableName) {
try {
$totalObjects = DB::getPDO()->fetchValue("select count(*) as cnt from `{$aclCacheTableName}`");
if ($totalObjects > 0) $aclObjectCacheExists = true;
} catch (Exception $e) {
DBG::log($e);
}
}
DBG::log($objectStorage, 'array', "\$objectStorage");
DBG::log($objectStorage->getRootTableName(), 'array', "\$objectStorage->getRootTableName()");
Lib::loadClass('RefConfig');
$totalToUpdateRef = RefConfig::getToUpdateTotal();
UI::table([
'caption' => UI::h('b', ['style' => "color:#000"], [
"Baza danych",
" ",
UI::hButtonPost("sprawdź tabele", [
'class' => "btn btn-xs btn-default",
'data' => [
'_postTask' => 'checkDatabaseTables',
]
]),
]),
'rows' => [
[
'nazwa' => "Event Scheduler (generowanie Grafika, itp.)",
'wartość' => ('ON' == $dbEvents['Value'])
? UI::h('span', ['class' => "label label-success"], "ON")
: UI::h('span', ['class' => "label label-danger"], "OFF"),
'#' => UI::hButtonPost("Włącz", [
'class' => "btn btn-xs btn-default",
'data' => [
'_postTask' => 'fixEventSheduler',
]
])
],
[
'nazwa' => "System obiektów (xsd)",
'wartość' => ($aclObjectCacheExists)
? UI::h('span', ['class' => "label label-success"], "ON")
: UI::h('span', ['class' => "label label-danger"], "OFF"),
'#' => UI::hButtonPost("Aktualizuj cache", [
'class' => "btn btn-xs btn-default",
'data' => [
'_postTask' => 'updateObjectCache'
]
])
],
[
'nazwa' => "Tabela z relacjami (REF)",
'wartość' => ($totalToUpdateRef)
? UI::h('span', ['class' => "label label-danger"], "wymaga aktualizacji ({$totalToUpdateRef})")
: UI::h('span', ['class' => "label label-success"], "akualne"),
'#' => UI::hButtonPost("Aktualizuj tabele relacyjne", [
'class' => "btn btn-xs btn-default",
'data' => [
'_postTask' => 'updateRefTables'
]
])
],
]
]);
}
public function fixEventShedulerPostTask() {
DB::getPDO()->execSql(" SET GLOBAL event_scheduler='ON' ");
}
public function updateObjectCachePostTask() {
DBG::log("updateObjectCachePostTask...");
SchemaFactory::loadDefaultObject('SystemSource')->updateCache();
SchemaFactory::loadDefaultObject('SystemObject')->updateCache();
// SchemaFactory::loadDefaultObject('SystemObjectField')->updateCache(); // TODO: require loop by acl objects
UI::alert('info', "Lista obiketów zaktualizowana");
}
function updateRefTablesPostTask() {
Lib::loadClass('RefConfig');
DBG::log("DBG:updateRefTablesPostTask...");
$toUpdateStep = 10;
$baseRefOffset = V::get('baseref_offset', 0, $_POST, 'int');
$backRefOffset = V::get('backref_offset', 0, $_POST, 'int');
$todoBaseRefOffset = $baseRefOffset;
$todoBackRefOffset = $backRefOffset;
$baseRefToUpdate = RefConfig::getToUpdateItems();
DBG::log($baseRefToUpdate, 'array', "DBG:updateRefTablesPostTask \$baseRefToUpdate");
if ($baseRefOffset > count($baseRefToUpdate)) {
$backRefToUpdate = RefConfig::getToUpdateItems('backRef');
$listBackRefConf = array_slice($backRefToUpdate, $backRefOffset, $toUpdateStep);
DBG::log($listBackRefConf, 'array', "DBG:updateRefTablesPostTask \$listBackRefConf ({$backRefOffset}, {$toUpdateStep})");
self::_updateRefTables($listBackRefConf);
$todoBackRefOffset = $backRefOffset + $toUpdateStep;
} else {
$listBaseRefConf = array_slice($baseRefToUpdate, $baseRefOffset, $toUpdateStep);
DBG::log($listBaseRefConf, 'array', "DBG:updateRefTablesPostTask \$listBaseRefConf ({$baseRefOffset}, {$toUpdateStep})");
self::_updateRefTables($listBaseRefConf);
$todoBaseRefOffset = $baseRefOffset + $toUpdateStep;
}
$totalToUpdateRef = RefConfig::getToUpdateTotal();
echo ($totalToUpdateRef)
? UI::h('div', [ 'class' => 'alert alert-warning'], [
"Uwaga: Struktura tabel z relacjami częściowo zaktualizowana. Pozostało {$totalToUpdateRef}. ",
UI::hButtonPost("Uruchom dla kolejnych", [
'class' => "btn btn-xs btn-default",
'data' => [
'_postTask' => 'updateRefTables',
'baseref_offset' => $todoBaseRefOffset,
'backref_offset' => $todoBackRefOffset,
]
])
])
: UI::h('div', [ 'class' => 'alert alert-info' ], "Struktura tabel z relacjami zaktualizowana");
}
static function _updateRefTables($listRefConf) {
Lib::loadClass('RefConfig');
// $listRefConf = array_slice($listRefConf, 0, 10);
$totalTableSkippedNotAcl = 0;
$totalTableSkippedMissingAclType = 0;
$totalTableSkippedFieldNotFound = 0;
DBG::nicePrint($listRefConf, '$listRefConf');
foreach ($listRefConf as $refConf) {
try {
UI::alert('info', "Aktualizuje ['{$refConf['ID']}'] od '{$refConf['ROOT_OBJECT_NS']}' do '{$refConf['CHILD_NAME']}' ...");
RefConfig::getRefConfig($refConf['ROOT_OBJECT_NS'], $refConf['CHILD_NAME'], $refConf['CHILD_NS']);
} catch (\Exception $e) {
DBG::log($e);
if ('Ref allowed only for AntAcl objects' === $e->getMessage()) {
$totalTableSkippedNotAcl++;
} else if ('Field ' === substr($e->getMessage(), 0, strlen('Field ')) && false !== strpos($e->getMessage(), 'not found')) {
$totalTableSkippedFieldNotFound++;
} else if ("Not Implemented acl type ''" === substr($e->getMessage(), 0, strlen("Not Implemented acl type ''"))) {
$totalTableSkippedMissingAclType++;
}
UI::alert('danger', "Problem z aktualizacją tabeli z relacjami ['{$refConf['ID']}'] od '{$refConf['ROOT_OBJECT_NS']}' do '{$refConf['CHILD_NAME']}'");
}
}
if ($totalTableSkippedNotAcl) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedNotAcl} tabeli z relajami - obiekty różnego typu od 'Acl'");
if ($totalTableSkippedFieldNotFound) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedFieldNotFound} tabeli z relajami - pola 'do' nie istnieją");
if ($totalTableSkippedMissingAclType) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedMissingAclType} tabeli z relajami - brak typu obiektu (Instance config)");
}
public function viewStatusUsers() {
$nowMinus3Months = date("Y-m-d", mktime(0,0,0, date('m') - 1, date('d'), date('Y')));
$sesUsers = DB::getPDO()->fetchAll("
select c.ID, c.CONF_KEY, c.CONF_VAL
from CRM_CONFIG c
where c.CONF_KEY like 'acl_user_%_%_cache_update'
and c.CONF_VAL > '{$nowMinus3Months}'
");
$sesUsers = array_reduce( $sesUsers, function ($ret, $record) {
// $format = "acl_user_{ID_USERS}_{ID_PROCES}_cache_update";
list($idUser, $idProces) = explode('_', substr($record['CONF_KEY'], strlen('acl_user_'), -1 * strlen('_cache_update')));
if (!array_key_exists($idUser, $ret)) {
$ret[$idUser] = [
'idUser' => $idUser,
'lastUpdateAclCache' => $record['CONF_VAL'],
'log' => []
];
} else {
$ret[$idUser]['lastUpdateAclCache'] = ($record['CONF_VAL'] > $ret[$idUser]['lastUpdateAclCache'])
? $record['CONF_VAL']
: $ret[$idUser]['lastUpdateAclCache'];
}
$ret[$idUser]['log'][] = [ 'ID_PROCES' => $idProces, 'data' => $record['CONF_VAL'] ];
return $ret;
}, [] );
$sesUsers = array_map(function ($sesGroup) {
return [
'idUser' => $sesGroup['idUser'],
'user' => DB::getPDO()->fetchValue("select u.ADM_ACCOUNT from ADMIN_USERS u where u.ID = {$sesGroup['idUser']}"),
'lastUpdateAclCache' => $sesGroup['lastUpdateAclCache'],
'log' => UI::h('span', [ 'style' => "color:#bbb" ], implode('
', array_map(function ($log) {
return ($log['ID_PROCES'] > 0)
? "Filtr procesu {$log['ID_PROCES']} uruchomiony {$log['data']}"
: "Filtr ogólny uruchomiony {$log['data']}";
}, $sesGroup['log']))),
];
}, $sesUsers);
usort($sesUsers, function ($ua, $ub) {
$a = $ua['lastUpdateAclCache'];
$b = $ub['lastUpdateAclCache'];
return ($a === $b)
? 0
: ( ($a < $b)
? 1
: -1
) ;
});
if ('0' == User::get('ADM_ADMIN_LEVEL')) {
$sesUsers = array_map(function ($row) {
$row['#'] = UI::h('div', [ 'style' => "display:inline-block", 'class' => "activateUserDebugBtn" . ( DBG::hasUserDebug($row['idUser'], User::getID()) ? ' active' : '' ) ], [
UI::h('label', ['style' => "padding-right:6px; font-weight:normal"], "Debug"),
UI::hButtonAjax("Włącz", "activateUserDebug", [
'class' => "btn btn-xs btn-default activateUserDebugBtn-activate",
'href' => $this->getLink('startUserDebugAjax'),
'data' => [ 'idUser' => $row['idUser'], 'do' => 'activate' ]
]),
UI::hButtonAjax("Wyłącz", "activateUserDebug", [
'class' => "btn btn-xs btn-default activateUserDebugBtn-deactivate",
'href' => $this->getLink('startUserDebugAjax'),
'data' => [ 'idUser' => $row['idUser'], 'do' => 'deactivate' ]
]),
]);
return $row;
}, $sesUsers);
}
UI::table([
'caption' => UI::h('b', ['style' => "color:#000"], "Ostatnie logowania do aplikacji") . " (update acl cache)", // TODO: Aktualnie zalogowani użytkownicy
'rows' => $sesUsers
]);
echo UI::h('style', ['type' => "text/css"], "
.activateUserDebugBtn .activateUserDebugBtn-activate { display:inline }
.activateUserDebugBtn .activateUserDebugBtn-deactivate { display:none }
.activateUserDebugBtn.active .activateUserDebugBtn-activate { display:none }
.activateUserDebugBtn.active .activateUserDebugBtn-deactivate { display:inline }
");
echo UI::h('script', ['src'=>"static/vendor.js?_v=b636cab1", 'type'=>"text/javascript"]);
echo UI::h('script', [], "
(function (global) {
if (!global.p5VendorJs.React) throw 'Missing p5VendorJs.React'
if (!global.p5VendorJs.ReactDOM) throw 'Missing p5VendorJs.ReactDOM'
if (!global.p5VendorJs.ToggleButton) throw 'Missing p5VendorJs.ToggleButton'
if (!global.fetch) throw 'Missing global.fetch'
var React = global.p5VendorJs.React
var ReactDOM = global.p5VendorJs.ReactDOM
var h = React.createElement
function convertToReactToggle(n, activateBtn, deactivateBtn, isActive) {
var toggleReact = document.createElement('div')
toggleReact.style.display = 'inline-block'
n.parentNode.insertBefore(toggleReact, n.nextSibling)
deactivateBtn.style.display = 'none'
activateBtn.style.display = 'none'
function reactToggleBtnOnToggle(value) {
if (value) {
deactivateBtn.onclick()
} else {
activateBtn.onclick()
}
render_reactToggleBtn(!value)
}
function render_reactToggleBtn(state) {
ReactDOM.render(
h(global.p5VendorJs.ToggleButton, {
value: state,
onToggle: reactToggleBtnOnToggle
})
, toggleReact
)
}
render_reactToggleBtn(isActive)
}
var toggles = document.querySelectorAll('.activateUserDebugBtn')
for (var i = 0; i < toggles.length; i++) {
var btns = toggles[i].querySelectorAll('a')
if (2 !== btns.length) contiune;
var activateBtn = btns[0]
var deactivateBtn = btns[1]
convertToReactToggle(toggles[i], activateBtn, deactivateBtn, toggles[i].classList.contains('active'))
}
})(window)
");
UI::hButtonAjaxOnResponse("activateUserDebug", /* payload, n */ "
p5UI__notifyAjaxCallback(payload)
// console.log('activateUserDebug :: payload', payload)
if ('success' !== payload.type) return false
if (payload.body && 'active' in payload.body) {
if (payload.body.active) {
n.parentNode.classList.add('active')
} else {
n.parentNode.classList.remove('active')
}
}
");
}
public function startUserDebugAjaxAction() {
Response::sendTryCatchJson(array($this, 'startUserDebugAjax'), $_POST);
}
public function startUserDebugAjax($args) {
if ('0' !== (string)User::get('ADM_ADMIN_LEVEL')) throw new Exception("Access Denied");
$idUser = V::get('idUser', 0, $args);
if ($idUser <= 0) throw new Exception("Missing idUser");
$do = V::get('do', 0, $args);
if (!in_array($do, ['activate', 'deactivate'])) throw new Exception("Missing do");
$hasDebug = DBG::hasUserDebug($idUser, User::getID());
switch ($do) {
case 'activate': DBG::startUserDebug($idUser, User::getID()); break;
case 'deactivate': DBG::stopUserDebug($idUser, User::getID()); break;
}
return [
'type' => 'success',
'__args' => $args,
'__$hasDebug' => $hasDebug,
'body' => [
'active' => DBG::hasUserDebug($idUser, User::getID())
]
];
}
function checkDatabaseTablesPostTask() {
$pdo = DB::getPDO();
// DBG::nicePrint($pdo, "DB Info");
// DBG::nicePrint(get_class_methods($pdo), "pdo methods");
$tblName = V::get('_fixTable', '', $_POST);
if (!empty($tblName)) {
$sqlTableName = DB::getPDO()->identifierQuote($tblName);
$fixReturn = DB::getPDO()->fetchAll(" repair table {$sqlTableName} ");
echo UI::hTable([ 'caption' => "Naprawa tabeli '{$tblName}':", 'rows' => $fixReturn ]);
$lastFixRow = end($fixReturn);
if ('OK' === V::get('Msg_text', '', $lastFixRow)) {
UI::alert('success', "Naprawiono tabelę '{$tblName}'");
} else {
UI::alert('danger', "Nie udało się naprawić tabeli '{$tblName}'");
}
}
$listTables = DB::getPDO()->fetchValuesList("
select TABLE_NAME
from INFORMATION_SCHEMA.TABLES
where TABLE_SCHEMA = :db_name
and TABLE_TYPE = 'BASE TABLE'
", [
':db_name' => DB::getPDO()->getDatabaseName(),
]);
DBG::nicePrint($listTables, "all tables");
// $listTables = array_slice($listTables, 0, 10); // TODO: DBG
UI::table([
'rows' => array_map(function ($tblName) {
$fixTableBtn = UI::hButtonPost("napraw tabele", [
'class' => "btn btn-xs btn-primary",
'data' => [
'_postTask' => 'checkDatabaseTables',
'_fixTable' => $tblName,
]
]);
return [
'table' => $tblName,
'status' => UI::h('details', [ 'open' => '' ], [
UI::h('summary', [], [
"check table `{$tblName}`",
" ",
$fixTableBtn,
]),
UI::hTable([ 'rows' => DB::getPDO()->fetchAll(" check table `{$tblName}` ") ]),
]),
];
}, $listTables)
]);
}
}