diff --git a/.gitignore b/.gitignore
index 5103fdefe..4f9e9cea7 100755
--- a/.gitignore
+++ b/.gitignore
@@ -90,6 +90,7 @@ REVISION
.php_cs.cache
manifest.json
checksum.json
+database.json
/tests/_log/*
/tests/_temp/*
diff --git a/composer.json b/composer.json
index 41e025384..83c171618 100755
--- a/composer.json
+++ b/composer.json
@@ -10,13 +10,7 @@
],
"homepage": "https://www.openstamanager.com/",
"authors": [{
- "name": "Fabio Lovato",
- "email": "info@openstamanager.com"
- }, {
- "name": "Fabio Piovan",
- "email": "info@openstamanager.com"
- }, {
- "name": "Luca Salvà",
+ "name": "DevCode s.n.c",
"email": "info@openstamanager.com"
}],
"type": "project",
diff --git a/gulpfile.js b/gulpfile.js
index c18ce6578..63498181f 100755
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -370,6 +370,7 @@ function release(done) {
glob([
'**/*',
'!checksum.json',
+ '!database.json',
'!.idea/**',
'!.git/**',
'!node_modules/**',
@@ -417,6 +418,20 @@ function release(done) {
checksumFile.close();
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
archive.append(shell.exec('git rev-parse --short HEAD', {
silent: true
diff --git a/modules/aggiornamenti/checksum.php b/modules/aggiornamenti/checksum.php
index bb8d97e45..ac328303d 100644
--- a/modules/aggiornamenti/checksum.php
+++ b/modules/aggiornamenti/checksum.php
@@ -58,7 +58,7 @@ foreach ($checksum as $file => $md5) {
// Schermata di visualizzazione degli errori
if (!empty($errors)) {
echo '
-
'.tr("Segue l'elenco dei file che presentano checksum diverso rispetto a quello regitrato nella versione ufficiale").'.
+'.tr("Segue l'elenco dei file che presentano checksum diverso rispetto a quello registrato nella versione ufficiale").'.
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_', [
diff --git a/modules/aggiornamenti/database.php b/modules/aggiornamenti/database.php
new file mode 100644
index 000000000..cf0dbe1d8
--- /dev/null
+++ b/modules/aggiornamenti/database.php
@@ -0,0 +1,163 @@
+ $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 '
+
+
+
+
+
+ '.tr('Caricamento in corso').'...
+
+
+';
+
+ return;
+}
+
+$contents = file_get_contents(DOCROOT.'/database.json');
+$data = json_decode($contents, true);
+
+if (empty($data)) {
+ echo '
+
+ '.tr('Impossibile effettuare controlli di integrità in assenza del file _FILE_', [
+ '_FILE_' => 'database.json ',
+ ]).'.
+
';
+
+ return;
+}
+
+// Controllo degli errori
+$info = Update::getDatabaseStructure();
+$results = integrity_diff($data, $info);
+
+// Schermata di visualizzazione degli errori
+if (!empty($results)) {
+ echo '
+
'.tr("Segue l'elenco delle tabelle del database che presentano una struttura diversa rispetto a quella prevista nella versione ufficiale del gestionale").'.
+
+
+ '.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_', [
+ '_FILE_' => 'database.json ',
+ ]).'.
+
';
+
+ foreach ($results as $table => $errors) {
+ echo '
+
'.$table.' ';
+
+ if (array_key_exists('current', $errors) && $errors['current'] == null) {
+ echo '
+
'.tr('Tabella assente').'
';
+ continue;
+ }
+
+ $foreign_keys = $errors['foreign_keys'] ?: [];
+ unset($errors['foreign_keys']);
+
+ if (!empty($errors)) {
+ echo '
+
+
+
+ '.tr('Colonna').'
+ '.tr('Conflitto').'
+
+
+
+ ';
+
+ foreach ($errors as $name => $diff) {
+ echo '
+
+
+ '.$name.'
+
+
+ '.json_encode($diff).'
+
+ ';
+ }
+
+ echo '
+
+
';
+ }
+
+ if (!empty($foreign_keys)) {
+ echo '
+
+
+
+ '.tr('Foreign keys').'
+ '.tr('Conflitto').'
+
+
+
+ ';
+
+ foreach ($foreign_keys as $name => $diff) {
+ echo '
+
+
+ '.$name.'
+
+
+ '.json_encode($diff).'
+
+ ';
+ }
+
+ echo '
+
+
';
+ }
+ }
+} else {
+ echo '
+
+ '.tr('Il database non presenta problemi di integrità').'.
+
';
+}
diff --git a/modules/aggiornamenti/edit.php b/modules/aggiornamenti/edit.php
index fd7a38ab7..329123dc5 100755
--- a/modules/aggiornamenti/edit.php
+++ b/modules/aggiornamenti/edit.php
@@ -117,7 +117,11 @@ function update() {
}
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) {
@@ -170,12 +174,16 @@ function search(button) {
- '.tr('Controlla').'
+ '.tr('Controlla file').'
+
+
+
+ '.tr('Controlla database').'
diff --git a/src/Update.php b/src/Update.php
index 4d833fac8..fbe41d860 100755
--- a/src/Update.php
+++ b/src/Update.php
@@ -302,6 +302,71 @@ class Update
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;
}
/**