mirror of
https://github.com/devcode-it/openstamanager.git
synced 2025-02-07 03:03:43 +01:00
Base per controllo di intergità del database
This commit is contained in:
parent
859a6dca82
commit
7bc18666f6
1
.gitignore
vendored
1
.gitignore
vendored
@ -90,6 +90,7 @@ REVISION
|
|||||||
.php_cs.cache
|
.php_cs.cache
|
||||||
manifest.json
|
manifest.json
|
||||||
checksum.json
|
checksum.json
|
||||||
|
database.json
|
||||||
|
|
||||||
/tests/_log/*
|
/tests/_log/*
|
||||||
/tests/_temp/*
|
/tests/_temp/*
|
||||||
|
@ -10,13 +10,7 @@
|
|||||||
],
|
],
|
||||||
"homepage": "https://www.openstamanager.com/",
|
"homepage": "https://www.openstamanager.com/",
|
||||||
"authors": [{
|
"authors": [{
|
||||||
"name": "Fabio Lovato",
|
"name": "DevCode s.n.c",
|
||||||
"email": "info@openstamanager.com"
|
|
||||||
}, {
|
|
||||||
"name": "Fabio Piovan",
|
|
||||||
"email": "info@openstamanager.com"
|
|
||||||
}, {
|
|
||||||
"name": "Luca Salvà",
|
|
||||||
"email": "info@openstamanager.com"
|
"email": "info@openstamanager.com"
|
||||||
}],
|
}],
|
||||||
"type": "project",
|
"type": "project",
|
||||||
|
15
gulpfile.js
15
gulpfile.js
@ -370,6 +370,7 @@ function release(done) {
|
|||||||
glob([
|
glob([
|
||||||
'**/*',
|
'**/*',
|
||||||
'!checksum.json',
|
'!checksum.json',
|
||||||
|
'!database.json',
|
||||||
'!.idea/**',
|
'!.idea/**',
|
||||||
'!.git/**',
|
'!.git/**',
|
||||||
'!node_modules/**',
|
'!node_modules/**',
|
||||||
@ -417,6 +418,20 @@ function release(done) {
|
|||||||
checksumFile.close();
|
checksumFile.close();
|
||||||
archive.file('checksum.json', {});
|
archive.file('checksum.json', {});
|
||||||
|
|
||||||
|
// Aggiunta del file per il controllo di integrità del database
|
||||||
|
archive.append(shell.exec(`php -r '
|
||||||
|
error_reporting(0);
|
||||||
|
$skip_permissions = true;
|
||||||
|
include_once __DIR__."/core.php";
|
||||||
|
$info = Update::getDatabaseStructure();
|
||||||
|
$response = json_encode($info);
|
||||||
|
echo $response;
|
||||||
|
'`, {
|
||||||
|
silent: true
|
||||||
|
}).stdout, {
|
||||||
|
name: 'database.json'
|
||||||
|
});
|
||||||
|
|
||||||
// Aggiunta del commit corrente nel file REVISION
|
// Aggiunta del commit corrente nel file REVISION
|
||||||
archive.append(shell.exec('git rev-parse --short HEAD', {
|
archive.append(shell.exec('git rev-parse --short HEAD', {
|
||||||
silent: true
|
silent: true
|
||||||
|
@ -58,7 +58,7 @@ foreach ($checksum as $file => $md5) {
|
|||||||
// Schermata di visualizzazione degli errori
|
// Schermata di visualizzazione degli errori
|
||||||
if (!empty($errors)) {
|
if (!empty($errors)) {
|
||||||
echo '
|
echo '
|
||||||
<p>'.tr("Segue l'elenco dei file che presentano checksum diverso rispetto a quello regitrato nella versione ufficiale").'.</p>
|
<p>'.tr("Segue l'elenco dei file che presentano checksum diverso rispetto a quello registrato nella versione ufficiale").'.</p>
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_', [
|
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_', [
|
||||||
|
163
modules/aggiornamenti/database.php
Normal file
163
modules/aggiornamenti/database.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
function integrity_diff($expected, $current)
|
||||||
|
{
|
||||||
|
foreach ($expected as $key => $value) {
|
||||||
|
if (array_key_exists($key, $current) && is_array($value)) {
|
||||||
|
if (!is_array($current[$key])) {
|
||||||
|
$difference[$key] = $value;
|
||||||
|
} else {
|
||||||
|
$new_diff = integrity_diff($value, $current[$key]);
|
||||||
|
if (!empty($new_diff)) {
|
||||||
|
$difference[$key] = $new_diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (!array_key_exists($key, $current) || $current[$key] != $value) {
|
||||||
|
$difference[$key] = [
|
||||||
|
'current' => $current[$key],
|
||||||
|
'expected' => $value,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !isset($difference) ? [] : $difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = basename(__FILE__);
|
||||||
|
$effettua_controllo = filter('effettua_controllo');
|
||||||
|
|
||||||
|
// Schermata di caricamento delle informazioni
|
||||||
|
if (empty($effettua_controllo)) {
|
||||||
|
echo '
|
||||||
|
<div id="righe_controlli">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-info" id="box-loading">
|
||||||
|
<i class="fa fa-spinner fa-spin"></i> '.tr('Caricamento in corso').'...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var content = $("#righe_controlli");
|
||||||
|
var loader = $("#box-loading");
|
||||||
|
$(document).ready(function () {
|
||||||
|
loader.show();
|
||||||
|
|
||||||
|
content.html("");
|
||||||
|
content.load("'.$structure->fileurl($file).'?effettua_controllo=1", function() {
|
||||||
|
loader.hide();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = file_get_contents(DOCROOT.'/database.json');
|
||||||
|
$data = json_decode($contents, true);
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
echo '
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<i class="fa fa-warning"></i> '.tr('Impossibile effettuare controlli di integrità in assenza del file _FILE_', [
|
||||||
|
'_FILE_' => '<b>database.json</b>',
|
||||||
|
]).'.
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controllo degli errori
|
||||||
|
$info = Update::getDatabaseStructure();
|
||||||
|
$results = integrity_diff($data, $info);
|
||||||
|
|
||||||
|
// Schermata di visualizzazione degli errori
|
||||||
|
if (!empty($results)) {
|
||||||
|
echo '
|
||||||
|
<p>'.tr("Segue l'elenco delle tabelle del database che presentano una struttura diversa rispetto a quella prevista nella versione ufficiale del gestionale").'.</p>
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<i class="fa fa-warning"></i>
|
||||||
|
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_', [
|
||||||
|
'_FILE_' => '<b>database.json</b>',
|
||||||
|
]).'.
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
foreach ($results as $table => $errors) {
|
||||||
|
echo '
|
||||||
|
<h3>'.$table.'</h3>';
|
||||||
|
|
||||||
|
if (array_key_exists('current', $errors) && $errors['current'] == null) {
|
||||||
|
echo '
|
||||||
|
<p>'.tr('Tabella assente').'</p>';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$foreign_keys = $errors['foreign_keys'] ?: [];
|
||||||
|
unset($errors['foreign_keys']);
|
||||||
|
|
||||||
|
if (!empty($errors)) {
|
||||||
|
echo '
|
||||||
|
<table class="table table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>'.tr('Colonna').'</th>
|
||||||
|
<th>'.tr('Conflitto').'</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
foreach ($errors as $name => $diff) {
|
||||||
|
echo '
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
'.$name.'
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
'.json_encode($diff).'
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</tbody>
|
||||||
|
</table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($foreign_keys)) {
|
||||||
|
echo '
|
||||||
|
<table class="table table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>'.tr('Foreign keys').'</th>
|
||||||
|
<th>'.tr('Conflitto').'</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
foreach ($foreign_keys as $name => $diff) {
|
||||||
|
echo '
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
'.$name.'
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
'.json_encode($diff).'
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</tbody>
|
||||||
|
</table>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo '
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle"></i> '.tr('Il database non presenta problemi di integrità').'.
|
||||||
|
</div>';
|
||||||
|
}
|
@ -117,7 +117,11 @@ function update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checksum(button) {
|
function checksum(button) {
|
||||||
openModal("'.tr('Controllo di integrità').'", "'.$module->fileurl('checksum.php').'?id_module='.$id_module.'");
|
openModal("'.tr('Controllo dei file').'", "'.$module->fileurl('checksum.php').'?id_module='.$id_module.'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function database(button) {
|
||||||
|
openModal("'.tr('Controllo del database').'", "'.$module->fileurl('database.php').'?id_module='.$id_module.'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(button) {
|
function search(button) {
|
||||||
@ -170,12 +174,16 @@ function search(button) {
|
|||||||
<div class="box box-warning">
|
<div class="box box-warning">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">
|
<h3 class="box-title">
|
||||||
'.tr("Verifica l'integrità dell'intallazione").' <span class="tip" title="'.tr("Verifica l'integrità della tua installazione attraverso un controllo sui checksum dei file").'."><i class="fa fa-question-circle-o"></i></span>
|
'.tr("Verifica l'integrità dell'intallazione").' <span class="tip" title="'.tr("Verifica l'integrità della tua installazione attraverso un controllo sui checksum dei file e sulla struttura del database").'."><i class="fa fa-question-circle-o"></i></span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<button type="button" class="btn btn-primary btn-block" onclick="checksum(this)">
|
<button type="button" class="btn btn-primary btn-block" onclick="checksum(this)">
|
||||||
<i class="fa fa-list-alt"></i> '.tr('Controlla').'
|
<i class="fa fa-list-alt"></i> '.tr('Controlla file').'
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-info btn-block" onclick="database(this)">
|
||||||
|
<i class="fa fa-database"></i> '.tr('Controlla database').'
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -302,6 +302,71 @@ class Update
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce un riepilogo sulla struttura delle tabelle del gestionale.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getDatabaseStructure()
|
||||||
|
{
|
||||||
|
// Tabelle registrate per il gestionale
|
||||||
|
$tables = include DOCROOT.'/update/tables.php';
|
||||||
|
|
||||||
|
$database = database();
|
||||||
|
$database_name = $database->getDatabaseName();
|
||||||
|
|
||||||
|
$info = [];
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
if ($database->tableExists($table)) {
|
||||||
|
// Individuazione delle colonne per la tabella
|
||||||
|
$query = 'SHOW COLUMNS FROM `'.$table.'` IN `'.$database_name.'`';
|
||||||
|
$columns_found = $database->fetchArray($query);
|
||||||
|
|
||||||
|
// Organizzazione delle colonne per nome
|
||||||
|
$columns = [];
|
||||||
|
foreach ($columns_found as $column) {
|
||||||
|
$column = array_change_key_case($column);
|
||||||
|
$name = $column['field'];
|
||||||
|
unset($column['field']);
|
||||||
|
|
||||||
|
$columns[$name] = $column;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individuazione delle chiavi esterne della tabella
|
||||||
|
$fk_query = 'SELECT
|
||||||
|
CONSTRAINT_NAME AS `name`,
|
||||||
|
COLUMN_NAME AS `column`,
|
||||||
|
REFERENCED_TABLE_NAME AS `referenced_table`,
|
||||||
|
REFERENCED_COLUMN_NAME AS `referenced_column`
|
||||||
|
FROM information_schema.KEY_COLUMN_USAGE
|
||||||
|
WHERE TABLE_NAME = '.prepare($table).'
|
||||||
|
AND TABLE_SCHEMA = '.prepare($database_name).'
|
||||||
|
AND REFERENCED_TABLE_SCHEMA = '.prepare($database_name);
|
||||||
|
$fks_found = $database->fetchArray($fk_query);
|
||||||
|
|
||||||
|
// Organizzazione delle chiavi esterne per nome
|
||||||
|
$fks = [];
|
||||||
|
foreach ($fks_found as $fk) {
|
||||||
|
$fk = array_change_key_case($fk);
|
||||||
|
$name = $fk['name'];
|
||||||
|
unset($fk['name']);
|
||||||
|
|
||||||
|
$fks[$name] = $fk;
|
||||||
|
}
|
||||||
|
|
||||||
|
$info[$table] = array_merge($columns, [
|
||||||
|
'foreign_keys' => $fks,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user