From 78484220feb2a34474c71c8f9f2fc6a1fc1881d0 Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Thu, 31 Aug 2017 10:09:06 +0200 Subject: [PATCH] Bugfix generale Risoluzione delle problematiche incontate con l'installazione del software su Aruba con versione di MySQL non aggiornata. Aggiunto sistema automatico di completamento dei campi per l'API, con disattivazione del severzio automatica per MySQL < 5.6.5. --- call.php | 4 +- editor.php | 2 +- include/update.php | 13 +-- lib/classes/API.php | 39 +++++++-- lib/classes/Database.php | 12 ++- lib/classes/Update.php | 3 + modules/dashboard/edit.php | 31 ++++--- update/2_3.php | 173 +++++++++++-------------------------- update/2_3.sql | 8 +- update/api.php | 122 ++++++++++++++++++++++++++ 10 files changed, 250 insertions(+), 157 deletions(-) create mode 100644 update/api.php diff --git a/call.php b/call.php index 418a0be1b..d6887baea 100644 --- a/call.php +++ b/call.php @@ -10,8 +10,8 @@ if (isset($id_record)) { $posizione .= ', '.$id_record; } -$dbo->query('UPDATE zz_semaphores SET updated_at = NOW() WHERE id_utente = '.prepare($_SESSION['idutente']).' AND posizione = '.prepare($posizione)); -$dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated_at, INTERVAL '.(get_var('Timeout notifica di presenza (minuti)') * 2).' SECOND) <= NOW()'); +$dbo->query('UPDATE zz_semaphores SET updated = NOW() WHERE id_utente = '.prepare($_SESSION['idutente']).' AND posizione = '.prepare($posizione)); +$dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated, INTERVAL '.(get_var('Timeout notifica di presenza (minuti)') * 2).' SECOND) <= NOW()'); $datas = $dbo->fetchArray('SELECT DISTINCT * FROM zz_semaphores INNER JOIN zz_users ON zz_semaphores.id_utente=zz_users.idutente WHERE id_utente != '.prepare($_SESSION['idutente']).' AND posizione = '.prepare($posizione)); $result = []; diff --git a/editor.php b/editor.php index 1fe727cf6..9ab807b7b 100755 --- a/editor.php +++ b/editor.php @@ -29,7 +29,7 @@ include $docroot.'/actions.php'; $advanced_sessions = get_var('Attiva notifica di presenza utenti sul record'); if ($advanced_sessions) { $dbo->query('DELETE FROM zz_semaphores WHERE id_utente='.prepare($_SESSION['idutente']).' AND posizione='.prepare($id_module.', '.$id_record)); - $dbo->query('INSERT INTO zz_semaphores (id_utente, posizione) VALUES ('.prepare($_SESSION['idutente']).', '.prepare($id_module.', '.$id_record).')'); + $dbo->query('INSERT INTO zz_semaphores (id_utente, posizione, updated) VALUES ('.prepare($_SESSION['idutente']).', '.prepare($id_module.', '.$id_record).', NOW())'); echo '
diff --git a/include/update.php b/include/update.php index 955b5782c..d0fc18847 100644 --- a/include/update.php +++ b/include/update.php @@ -3,7 +3,7 @@ include_once __DIR__.'/../core.php'; $updateRate = 20; -$scriptValue = $updateRate * 3; +$scriptValue = $updateRate * 5; /* * Aggiornamento tramite AJAX @@ -205,19 +205,20 @@ if (filter('action') == 'do_update') { $total = 0; $updates = Update::getTodos(); + foreach ($updates as $update) { - if ($update['sql'] && $update['done'] !== 0) { + if ($update['sql'] && (!empty($update['done']) || is_null($update['done']))) { $queries = readSQLFile(DOCROOT.$update['directory'].$update['filename'].'.sql', ';'); $total += count($queries); + + if (intval($update['done']) > 1) { + $total -= intval($update['done']) - 2; + } } if ($update['script']) { $total += $scriptValue; } - - if ($update['done'] > 1) { - $total -= $update['done'] - 2; - } } echo ' diff --git a/lib/classes/API.php b/lib/classes/API.php index a00d7d18d..c6fe6bc08 100644 --- a/lib/classes/API.php +++ b/lib/classes/API.php @@ -32,6 +32,10 @@ class API extends \Util\Singleton 'code' => 500, 'message' => 'Errore del server', ], + 'incompatible' => [ + 'code' => 503, + 'message' => 'Servizio non disponibile', + ], ]; /** @@ -217,13 +221,14 @@ class API extends \Util\Singleton public static function error($error) { $keys = array_keys(self::$status); - $error = (in_array($error, $keys)) ? $error : end($keys); + $error = (in_array($error, $keys)) ? $error : 'serverError'; - http_response_code(self::$status[$error]['code']); + $code = self::$status[$error]['code']; + + http_response_code($code); return self::response([ - 'status' => self::$status[$error]['code'], - 'message' => self::$status[$error]['message'], + 'status' => $code, ]); } @@ -278,9 +283,21 @@ class API extends \Util\Singleton */ public static function response($array) { + if (!self::isCompatible()) { + $array = [ + 'status' => self::$status['incompatible']['code'], + ]; + } + if (empty($array['status'])) { $array['status'] = self::$status['ok']['code']; - $array['message'] = self::$status['ok']['message']; + } + + if (empty($array['message'])) { + $codes = array_column(self::$status, 'code'); + $messages = array_column(self::$status, 'message'); + + $array['message'] = $messages[array_search($array['status'], $codes)]; } $flags = JSON_FORCE_OBJECT; @@ -318,4 +335,16 @@ class API extends \Util\Singleton { return (array) json_decode(file_get_contents('php://input'), true); } + + /** + * Controlla se il database è compatibile con l'API. + * + * @return bool + */ + public static function isCompatible() + { + $database = Database::getConnection(); + + return version_compare($database->getMySQLVersion(), '5.6.5') >= 0; + } } diff --git a/lib/classes/Database.php b/lib/classes/Database.php index c57c4fd54..8edcca715 100644 --- a/lib/classes/Database.php +++ b/lib/classes/Database.php @@ -62,14 +62,20 @@ class Database extends Util\Singleton if (!empty($this->host) && !empty($this->database_name)) { try { - $this->pdo = new \DebugBar\DataCollector\PDO\TraceablePDO(new PDO( + $this->pdo = new PDO( 'mysql:host='.$this->host.(!empty($this->port) ? ';port='.$this->port : '').';dbname='.$this->database_name, $this->username, $this->password, $this->option - )); + ); - $this->query("SET NAMES '".$this->charset."'"); + // Fix per problemi di compatibilità delle password MySQL 4.1+ (da versione precedente) + $this->query('SET SESSION old_passwords = 0'); + //$this->query('SET PASSWORD = PASSWORD('.$this->prepare($this->password).')'); + + $this->pdo = new \DebugBar\DataCollector\PDO\TraceablePDO($this->pdo); + + //$this->query("SET NAMES '".$this->charset."'"); $this->query("SET sql_mode = ''"); } catch (PDOException $e) { if ($e->getCode() == 1049 || $e->getCode() == 1044) { diff --git a/lib/classes/Update.php b/lib/classes/Update.php index 4eaaa172a..12eee94b7 100644 --- a/lib/classes/Update.php +++ b/lib/classes/Update.php @@ -234,6 +234,9 @@ class Update $database->query('UPDATE `updates` SET `done` = 0 WHERE id = '.prepare($update['id'])); + // Normalizzazione dei campi per l'API + self::executeScript(DOCROOT.'/update/api.php'); + // Esecuzione script release if (!empty($update['script']) && file_exists($file.'.php')) { self::executeScript($file.'.php'); diff --git a/modules/dashboard/edit.php b/modules/dashboard/edit.php index cfc16f4cb..c104f1cd3 100644 --- a/modules/dashboard/edit.php +++ b/modules/dashboard/edit.php @@ -282,7 +282,7 @@ $qp = "SELECT id, idcontratto, richiesta, data_richiesta, 'intervento' AS ref, ( UNION SELECT id, idcontratto, '', data_scadenza, 'ordine', (SELECT descrizione FROM in_tipiintervento WHERE idtipointervento='ODS') AS tipointervento FROM co_ordiniservizio WHERE idcontratto IN( SELECT id FROM co_contratti WHERE idstato IN(SELECT id FROM co_staticontratti WHERE pianificabile = 1) ) AND idintervento IS NULL ORDER BY data_richiesta ASC"; $rsp = $dbo->fetchArray($qp); -if(!empty($rsp)){ +if (!empty($rsp)) { echo '
'; @@ -291,24 +291,23 @@ if(!empty($rsp)){ echo '
'; -if(!empty($rsp)){ +if (!empty($rsp)) { echo '
'; } - $vista = get_var('Vista dashboard'); if ($vista == 'mese') { $def = 'month'; @@ -459,6 +458,9 @@ if (get_var('Abilitare orario lavorativo') == '1') { setTimeout("$('#mini-loader').hide()", 1000); } }, + drop: function(date, jsEvent, ui, resourceId) { data = moment(date).format("YYYY-MM-DD"); ora_dal = moment(date).format("HH:mm"); @@ -466,17 +468,18 @@ if (get_var('Abilitare orario lavorativo') == '1') { var name = ($(this).data('ref') == 'ordine') ? 'idordineservizio' : 'idcontratto_riga'; - launch_modal('', globals.rootdir + '/add.php?id_module=&data='+data+'&orario_inizio='+ora_dal+'&orario_fine='+ora_al+'&ref=dashboard&idcontratto=' + $(this).data('idcontratto') + '&' + name + '=' + $(this).data('id'), 1); - $(this).remove(); - }, + + $('#bs-popup').on('hidden.bs.modal', function () { + $('#calendar').fullCalendar('refetchEvents'); + }); + }, + select: function(start, end, allDay) { data = moment(start).format("YYYY-MM-DD"); ora_dal = moment(start).format("HH:mm"); diff --git a/update/2_3.php b/update/2_3.php index aa00801f6..976b9a3c3 100644 --- a/update/2_3.php +++ b/update/2_3.php @@ -1,109 +1,5 @@ = 0; -foreach ($tables as $table) { - if ($latest_ver) { - $database->query('ALTER TABLE `'.$table.'` ADD (`created_at` timestamp DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); - } else { - $database->query('ALTER TABLE `'.$table.'` ADD (`created_at` timestamp DEFAULT NULL, `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); - $database->query('UPDATE '.$table.' SET created_at = updated_at'); - - // Trigger per l'inizializzazione automatica di created_at - $database->query('CREATE TRIGGER '.$table.'_creation BEFORE INSERT ON '.$table.' FOR EACH ROW SET NEW.created_at = CURRENT_TIMESTAMP'); - } -} - /* * Inserimento valori di default */ @@ -149,28 +45,28 @@ $database->query("UPDATE my_impianto_componenti SET contenuto = REPLACE(REPLACE( // Fix per la presenza della Foreign Key in in_interventi_tecnici $fk = $database->fetchArray('SELECT TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA = '.prepare($database->getDatabaseName())." AND REFERENCED_TABLE_NAME = 'in_interventi' AND CONSTRAINT_NAME = 'in_interventi_tecnici_ibfk_1'"); -if(!empty($fk)){ - $database->query("ALTER TABLE `in_interventi_tecnici` DROP FOREIGN KEY `in_interventi_tecnici_ibfk_1`"); +if (!empty($fk)) { + $database->query('ALTER TABLE `in_interventi_tecnici` DROP FOREIGN KEY `in_interventi_tecnici_ibfk_1`'); } -$database->query("ALTER TABLE `in_interventi` DROP PRIMARY KEY, CHANGE `idintervento` `codice` varchar(25) NOT NULL UNIQUE, ADD PRIMARY KEY (`id`)"); -$database->query("DROP INDEX primary_key ON `in_interventi`"); -$database->query("UPDATE `in_interventi_tecnici` SET `idintervento` = (SELECT `id` FROM `in_interventi` WHERE `in_interventi`.`codice` = `in_interventi_tecnici`.`idintervento`)"); -$database->query("ALTER TABLE `in_interventi_tecnici` CHANGE `idintervento` `idintervento` varchar(25)"); +$database->query('ALTER TABLE `in_interventi` DROP PRIMARY KEY, CHANGE `idintervento` `codice` varchar(25) NOT NULL UNIQUE, ADD PRIMARY KEY (`id`)'); +$database->query('DROP INDEX primary_key ON `in_interventi`'); +$database->query('UPDATE `in_interventi_tecnici` SET `idintervento` = (SELECT `id` FROM `in_interventi` WHERE `in_interventi`.`codice` = `in_interventi_tecnici`.`idintervento`)'); +$database->query('ALTER TABLE `in_interventi_tecnici` CHANGE `idintervento` `idintervento` varchar(25)'); $database->query("UPDATE `in_interventi_tecnici` SET `idintervento` = NULL WHERE `idintervento` = 0 OR `idintervento` = ''"); -$database->query("ALTER TABLE `in_interventi_tecnici` CHANGE `idintervento` `idintervento` int(11), ADD FOREIGN KEY (`idintervento`) REFERENCES `in_interventi`(`id`) ON DELETE CASCADE"); +$database->query('ALTER TABLE `in_interventi_tecnici` CHANGE `idintervento` `idintervento` int(11), ADD FOREIGN KEY (`idintervento`) REFERENCES `in_interventi`(`id`) ON DELETE CASCADE'); // Fix dei timestamp delle tabelle mg_prodotti, mg_movimenti, zz_logs e zz_files -$database->query('UPDATE `mg_prodotti` SET `created_at` = `data`, `updated_at` = `data`'); +$database->query('UPDATE `mg_prodotti` SET `created_at` = `data`'); $database->query('ALTER TABLE `mg_prodotti` DROP `data`'); -$database->query('UPDATE `mg_movimenti` SET `created_at` = `data`, `updated_at` = `data`'); +$database->query('UPDATE `mg_movimenti` SET `created_at` = `data`'); $database->query('ALTER TABLE `mg_movimenti` DROP `data`'); -$database->query('UPDATE `zz_logs` SET `created_at` = `timestamp`, `updated_at` = `timestamp`'); +$database->query('UPDATE `zz_logs` SET `created_at` = `timestamp`'); $database->query('ALTER TABLE `zz_logs` DROP `timestamp`'); -$database->query('UPDATE `zz_files` SET `created_at` = `data`, `updated_at` = `data`'); +$database->query('UPDATE `zz_files` SET `created_at` = `data`'); $database->query('ALTER TABLE `zz_files` DROP `data`'); /* @@ -227,17 +123,46 @@ foreach ($files as $file) { // File .html dei moduli di default // Per un problema sulla lunghezza massima del path su glob è necessario dividere le cartelle dei moduli di default da pulire $dirs = [ - 'aggiornamenti,anagrafiche,articoli,automezzi,backup', - 'beni,categorie,causali,contratti,dashboard', - 'ddt,fatture,gestione_componenti,interventi,iva', - 'listini,misure,my_impianti,opzioni,ordini,pagamenti', - 'partitario,porti,preventivi,primanota,scadenzario', - 'stati_intervento,tecnici_tariffe,tipi_anagrafiche,tipi_intervento', - 'utenti,viste,voci_servizio,zone', + 'aggiornamenti', + 'anagrafiche', + 'articoli', + 'automezzi', + 'backup', + 'beni', + 'categorie', + 'causali', + 'contratti', + 'dashboard', + 'ddt', + 'fatture', + 'gestione_componenti', + 'interventi', + 'iva', + 'listini', + 'misure', + 'my_impianti', + 'opzioni', + 'ordini', + 'pagamenti', + 'partitario', + 'porti', + 'preventivi', + 'primanota', + 'scadenzario', + 'stati_intervento', + 'tecnici_tariffe', + 'tipi_anagrafiche', + 'tipi_intervento', + 'utenti', + 'viste', + 'voci_servizio', + 'zone', ]; -foreach ($dirs as $dir) { - $files = glob($docroot.'/modules/{'.$dir.'}/*.html', GLOB_BRACE); +$pieces = array_chunk($tables, 5); + +foreach ($pieces as $piece) { + $files = glob($docroot.'/modules/{'.implode(',', $piece).'}/*.html', GLOB_BRACE); foreach ($files as $file) { unlink($file); } diff --git a/update/2_3.sql b/update/2_3.sql index 9c7816a90..c9832e063 100644 --- a/update/2_3.sql +++ b/update/2_3.sql @@ -375,7 +375,8 @@ INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`) VALU -- Aggiunta tabella per le sessioni avanazate CREATE TABLE IF NOT EXISTS `zz_semaphores` ( `id_utente` int(11) NOT NULL, - `posizione` varchar(255) NOT NULL + `posizione` varchar(255) NOT NULL, + `updated` datetime ) ENGINE=InnoDB; -- Aggiornamento zz_modules @@ -668,7 +669,7 @@ ALTER TABLE `zz_plugins` ADD FOREIGN KEY (`idmodule_from`) REFERENCES `zz_module ALTER TABLE `zz_users` CHANGE `idutente` `idutente` int(11) NOT NULL AUTO_INCREMENT, ADD FOREIGN KEY (`idgruppo`) REFERENCES `zz_groups`(`id`) ON DELETE CASCADE; -- Aggiunta di chiavi esterne in zz_logs -ALTER TABLE `zz_logs` DROP `password`, CHANGE `idutente` `idutente` int(11); +ALTER TABLE `zz_logs` DROP `password`, CHANGE `idutente` `idutente` int(11), CHANGE `timestamp` `timestamp` datetime; UPDATE `zz_logs` SET `idutente` = NULL WHERE `idutente` = 0; ALTER TABLE `zz_logs` ADD FOREIGN KEY (`idutente`) REFERENCES `zz_users`(`idutente`) ON DELETE CASCADE; @@ -950,3 +951,6 @@ ALTER TABLE `or_righe_ordini` CHANGE `data_evasione` `data_evasione` date; -- ALTER TABLE `my_componenti_interventi` ADD PRIMARY KEY (`id_intervento`, `id_componente`); -- ALTER TABLE `my_impianti_interventi` ADD PRIMARY KEY (`idintervento`, `idimpianto`); + +UPDATE `zz_widgets` SET `query` = 'SELECT CONCAT_WS(" ", REPLACE(REPLACE(REPLACE(FORMAT(SUM(qta),2), ",", "#"), ".", ","), "#", "."), "unità") AS dato FROM mg_articoli WHERE qta>0' WHERE `name` = 'Articoli in magazzino'; +UPDATE `zz_widgets` SET `query` = 'SELECT CONCAT_WS(" ", REPLACE(REPLACE(REPLACE(FORMAT(SUM(prezzo_acquisto*qta),2), ",", "#"), ".", ","), "#", "."), "€") AS dato FROM mg_articoli WHERE qta>0' WHERE `name` = 'Valore magazzino'; diff --git a/update/api.php b/update/api.php new file mode 100644 index 000000000..2f79aff39 --- /dev/null +++ b/update/api.php @@ -0,0 +1,122 @@ +getDatabaseName()).' AND + T.TABLE_NAME IN('.implode(',', $implode).") AND + NOT EXISTS ( + SELECT table_name + FROM INFORMATION_SCHEMA.COLUMNS C + WHERE + C.TABLE_SCHEMA = T.TABLE_SCHEMA AND + C.TABLE_NAME = T.TABLE_NAME AND + C.COLUMN_NAME = '|field|')"; + + $created_at = $database->fetchArray(str_replace('|field|', 'created_at', $query)); + foreach ($created_at as $table) { + $database->query('ALTER TABLE `'.$table['table_name'].'` ADD `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP'); + } + + if (API::isCompatible()) { + $updated_at = $database->fetchArray(str_replace('|field|', 'updated_at', $query)); + foreach ($updated_at as $table) { + $database->query('ALTER TABLE `'.$table['table_name'].'` `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'); + } + } +}