From b11f641f247e92dffbb3882c4847d3bc9fc8650b Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Fri, 1 Sep 2017 12:55:48 +0200 Subject: [PATCH] Risoluzione di alcuni bug Risoluzione di alcuni bug individuati e miglioramento della performance dell'aggiornamento. --- lib/classes/Database.php | 16 ++- .../HTMLBuilder/Wrapper/WrapperInterface.php | 1 + lib/functions.js | 10 +- modules/dashboard/ajaxreq.php | 112 +++++++++--------- modules/dashboard/edit.php | 92 +++++++------- modules/interventi/actions.php | 6 +- modules/interventi/add.php | 11 +- update/2_3.php | 2 +- update/2_3.sql | 4 + update/api.php | 37 ++---- 10 files changed, 151 insertions(+), 140 deletions(-) diff --git a/lib/classes/Database.php b/lib/classes/Database.php index acb4a95dd..e815006f1 100644 --- a/lib/classes/Database.php +++ b/lib/classes/Database.php @@ -48,6 +48,8 @@ class Database extends Util\Singleton */ protected function __construct($server, $username, $password, $database_name, $charset = null, $option = [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]) { + global $debug; + if (is_array($server)) { $host = $server['host']; $port = !empty($server['port']) ? $server['port'] : null; @@ -71,15 +73,21 @@ class Database extends Util\Singleton if (!empty($this->host) && !empty($this->database_name)) { try { - $this->pdo = new \DebugBar\DataCollector\PDO\TraceablePDO(new PDO( + $pdo = new PDO( 'mysql:host='.$this->host.(!empty($this->port) ? ';port='.$this->port : '').';dbname='.$this->database_name, $this->username, $this->password, $this->option - )); + ); - if (empty($this->charset) && version_compare($this->getMySQLVersion(), '5.5.3') >= 0) { - $this->charset = 'utf8mb4'; + if (!empty($debug)) { + $pdo = new \DebugBar\DataCollector\PDO\TraceablePDO($pdo); + } + + $this->pdo = $pdo; + + if (empty($this->charset)) { + $this->charset = version_compare($this->getMySQLVersion(), '5.5.3') >= 0 ? 'utf8mb4' : 'utf8'; } // Fix per problemi di compatibilità delle password MySQL 4.1+ (da versione precedente) diff --git a/lib/classes/HTMLBuilder/Wrapper/WrapperInterface.php b/lib/classes/HTMLBuilder/Wrapper/WrapperInterface.php index fd55cd807..74b291f87 100644 --- a/lib/classes/HTMLBuilder/Wrapper/WrapperInterface.php +++ b/lib/classes/HTMLBuilder/Wrapper/WrapperInterface.php @@ -3,6 +3,7 @@ namespace HTMLBuilder\Wrapper; /** + * Interfaccia di base per la gestione della struttura HTML contenente gli input effettivi (generati dai tag di input). * * @since 2.3 */ diff --git a/lib/functions.js b/lib/functions.js index b46f39628..505e576ac 100644 --- a/lib/functions.js +++ b/lib/functions.js @@ -443,6 +443,7 @@ function start_datatables() { order: [], lengthChange: false, scrollY: "50vh", + stateSave: true, }); } }); @@ -468,6 +469,11 @@ function start_datatables() { } }) + // Fix per l'URL encoding + search.forEach(function (value, index, array) { + search[array[index]] = decodeURIComponent(array[value]); + }) + var res = []; $this.find("th").each(function () { var id = $(this).attr('id').replace("th_", ""); @@ -495,15 +501,13 @@ function start_datatables() { scrollY: "60vh", scrollX: '100%', retrieve: true, + stateSave: true, columnDefs: [{ searchable: false, orderable: false, width: '1%', className: 'select-checkbox', targets: 0 - }, { - 'max-width': '20%', - targets: '_all' }], select: { style: 'multi', diff --git a/modules/dashboard/ajaxreq.php b/modules/dashboard/ajaxreq.php index e9e4391af..d5ec84cc8 100644 --- a/modules/dashboard/ajaxreq.php +++ b/modules/dashboard/ajaxreq.php @@ -12,7 +12,12 @@ switch (get('op')) { $start = get('start'); $end = get('end'); - $query = "SELECT in_interventi_tecnici.idintervento, colore, in_interventi_tecnici.id, idtecnico, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, (SELECT colore FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS colore_tecnico, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente FROM in_interventi_tecnici INNER JOIN (in_interventi LEFT OUTER JOIN in_statiintervento ON in_interventi.idstatointervento=in_statiintervento.idstatointervento) ON in_interventi_tecnici.idintervento=in_interventi.id WHERE in_interventi_tecnici.orario_inizio >= ".prepare($startend)." AND in_interventi_tecnici.orario_fine <= ".prepare($end)." AND idtecnico IN(".implode(',', $_SESSION['dashboard']['idtecnici']).') AND (in_interventi.idstatointervento IN('.implode(',', $_SESSION['dashboard']['idstatiintervento']).") OR in_interventi.idstatointervento='') AND in_interventi_tecnici.idtipointervento IN(".implode(',', $_SESSION['dashboard']['idtipiintervento']).') '.Modules::getAdditionalsQuery('Interventi'); + $stati = (array) $_SESSION['dashboard']['idstatiintervento']; + $stati[] = prepare(''); + + $tipi = (array) $_SESSION['dashboard']['idtipiintervento']; + + $query = 'SELECT in_interventi_tecnici.idintervento, colore, in_interventi_tecnici.id, idtecnico, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, (SELECT colore FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS colore_tecnico, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente FROM in_interventi_tecnici INNER JOIN (in_interventi LEFT OUTER JOIN in_statiintervento ON in_interventi.idstatointervento=in_statiintervento.idstatointervento) ON in_interventi_tecnici.idintervento=in_interventi.id WHERE in_interventi_tecnici.orario_inizio >= '.prepare($start).' AND in_interventi_tecnici.orario_fine <= '.prepare($end).' AND idtecnico IN('.implode(',', $_SESSION['dashboard']['idtecnici']).') AND in_interventi.idstatointervento IN('.implode(',', $stati).') AND in_interventi_tecnici.idtipointervento IN('.implode(',', $tipi).') '.Modules::getAdditionalsQuery('Interventi'); $rs = $dbo->fetchArray($query); $n = count($rs); @@ -29,10 +34,9 @@ switch (get('op')) { { "id": "'.$rs[$i]['idintervento'].'", "idtecnico":"'.$rs[$i]['idtecnico'].'", - "orario":"1", - "title":"Int. '.$rs[$i]['idintervento'].'\\n'.addslashes($rs[$i]['cliente']).'
\\n'._('Tecnici').': '.addslashes($rs[$i]['nome_tecnico']).'", - "start": "'.date('Y-m-d H:i', strtotime($rs[$i]['orario_inizio'])).'", - "end": "'.date('Y-m-d H:i', strtotime($rs[$i]['orario_fine'])).'", + "title":"Int. '.$rs[$i]['idintervento'].''.addslashes($rs[$i]['cliente']).'
'._('Tecnici').': '.addslashes($rs[$i]['nome_tecnico']).'", + "start": "'.$rs[$i]['orario_inizio'].'", + "end": "'.$rs[$i]['orario_fine'].'", "url":"'.$rootdir.'/editor.php?id_module='.Modules::getModule('Interventi')['id'].'&id_record='.$rs[$i]['idintervento'].'", "backgroundColor":"'.$rs[$i]['colore'].'", "textColor":"'.color_inverse($rs[$i]['colore']).'", @@ -81,55 +85,57 @@ switch (get('op')) { $query = 'SELECT in_interventi_tecnici.idintervento, in_interventi.id, idtecnico, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, (SELECT colore FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS colore FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE in_interventi.id='.prepare($id).' '.Modules::getAdditionalsQuery('Interventi'); $rs = $dbo->fetchArray($query); - $tecnici = []; - foreach ($rs as $r) { - $tecnici[] = $r['nome_tecnico'].' ('.Translator::timestampToLocale($r['orario_inizio']).' - '.Translator::timeToLocale($r['orario_fine']).')'; + if (!empty($rs)) { + $tecnici = []; + foreach ($rs as $r) { + $tecnici[] = $r['nome_tecnico'].' ('.Translator::timestampToLocale($r['orario_inizio']).' - '.Translator::timeToLocale($r['orario_fine']).')'; + } + + // Lettura dati intervento + $query = 'SELECT *, idstatointervento AS parent_idstato, idtipointervento AS parent_idtipo, (SELECT descrizione FROM in_statiintervento WHERE idstatointervento=parent_idstato) AS stato, (SELECT descrizione FROM in_tipiintervento WHERE idtipointervento=parent_idtipo) AS tipo, (SELECT nomesede FROM an_sedi WHERE id=idsede) AS sede, (SELECT idzona FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS idzona FROM in_interventi LEFT JOIN an_anagrafiche ON in_interventi.idanagrafica=an_anagrafiche.idanagrafica WHERE in_interventi.id='.prepare($id).' '.Modules::getAdditionalsQuery('Interventi'); + $rs = $dbo->fetchArray($query); + + $desc_tipointervento = $rs[0]['tipo']; + + $tooltip_text = ''._('Numero intervento').': '.$id.'
'; + $tooltip_text .= ''._('Ragione sociale').': '.nl2br($rs[0]['ragione_sociale']).'
'; + + if (!empty($rs[0]['telefono'] != '')) { + $tooltip_text .= ''._('Telefono').': '.nl2br($rs[0]['telefono']).'
'; + } + + if (!empty($rs[0]['cellulare'])) { + $tooltip_text .= ''._('Cellulare').': '.nl2br($rs[0]['cellulare']).'
'; + } + + if (!empty($rs[0]['indirizzo']) || !empty($rs[0]['citta']) || !empty($rs[0]['provincia'])) { + $tooltip_text .= ''._('Indirizzo').': '.nl2br($rs[0]['indirizzo'].' '.$rs[0]['citta'].' ('.$rs[0]['provincia'].')').'
'; + } + + if (!empty($rs[0]['note'])) { + $tooltip_text .= ''._('Note').': '.nl2br($rs[0]['note']).'
'; + } + + $tooltip_text .= ''._('Data richiesta').': '.Translator::timestampToLocale($rs[0]['data_richiesta']).'
'; + + $tooltip_text .= ''._('Tipo intervento').': '.nl2br($desc_tipointervento).'
'; + + $tooltip_text .= ''._('Tecnici').': '.implode(', ', $tecnici).'
'; + + if ($rs[0]['richiesta'] != '') { + $tooltip_text .= ''._('Richiesta').': '.nl2br($rs[0]['richiesta']).'
'; + } + + if ($rs[0]['descrizione'] != '') { + $tooltip_text .= ''._('Descrizione').': '.nl2br($rs[0]['descrizione']).'
'; + } + + if ($rs[0]['informazioniaggiuntive'] != '') { + $tooltip_text .= ''._('Informazioni aggiuntive').': '.nl2br($rs[0]['informazioniaggiuntive']).'
'; + } + + echo $tooltip_text; } - // Lettura dati intervento - $query = 'SELECT *, idstatointervento AS parent_idstato, idtipointervento AS parent_idtipo, (SELECT descrizione FROM in_statiintervento WHERE idstatointervento=parent_idstato) AS stato, (SELECT descrizione FROM in_tipiintervento WHERE idtipointervento=parent_idtipo) AS tipo, (SELECT nomesede FROM an_sedi WHERE id=idsede) AS sede, (SELECT idzona FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS idzona FROM in_interventi LEFT JOIN an_anagrafiche ON in_interventi.idanagrafica=an_anagrafiche.idanagrafica WHERE in_interventi.id='.prepare($id).' '.Modules::getAdditionalsQuery('Interventi'); - $rs = $dbo->fetchArray($query); - - $desc_tipointervento = $rs[0]['tipo']; - - $tooltip_text = ''._('Numero intervento').': '.$id.'
'; - $tooltip_text .= ''._('Ragione sociale').': '.nl2br($rs[0]['ragione_sociale']).'
'; - - if (!empty($rs[0]['telefono'] != '')) { - $tooltip_text .= ''._('Telefono').': '.nl2br($rs[0]['telefono']).'
'; - } - - if (!empty($rs[0]['cellulare'])) { - $tooltip_text .= ''._('Cellulare').': '.nl2br($rs[0]['cellulare']).'
'; - } - - if (!empty($rs[0]['indirizzo']) || !empty($rs[0]['citta']) || !empty($rs[0]['provincia'])) { - $tooltip_text .= ''._('Indirizzo').': '.nl2br($rs[0]['indirizzo'].' '.$rs[0]['citta'].' ('.$rs[0]['provincia'].')').'
'; - } - - if (!empty($rs[0]['note'])) { - $tooltip_text .= ''._('Note').': '.nl2br($rs[0]['note']).'
'; - } - - $tooltip_text .= ''._('Data richiesta').': '.Translator::timestampToLocale($rs[0]['data_richiesta']).'
'; - - $tooltip_text .= ''._('Tipo intervento').': '.nl2br($desc_tipointervento).'
'; - - $tooltip_text .= ''._('Tecnici').': '.implode(', ', $tecnici).'
'; - - if ($rs[0]['richiesta'] != '') { - $tooltip_text .= ''._('Richiesta').': '.nl2br($rs[0]['richiesta']).'
'; - } - - if ($rs[0]['descrizione'] != '') { - $tooltip_text .= ''._('Descrizione').': '.nl2br($rs[0]['descrizione']).'
'; - } - - if ($rs[0]['informazioniaggiuntive'] != '') { - $tooltip_text .= ''._('Informazioni aggiuntive').': '.nl2br($rs[0]['informazioniaggiuntive']).'
'; - } - - echo $tooltip_text; - break; } diff --git a/modules/dashboard/edit.php b/modules/dashboard/edit.php index 2043d92c2..df81f20c8 100644 --- a/modules/dashboard/edit.php +++ b/modules/dashboard/edit.php @@ -423,7 +423,7 @@ if ($vista == 'mese') { var calendar = $('#calendar').fullCalendar({ locale: globals.locale, ', - selectable: true, lazyFetching: true, selectHelper: true, - editable: true, eventLimit: false, // allow "more" link when too many events allDaySlot: false, - droppable: true, loading: function(isLoading, view) { if(isLoading) { - //setTimeout("$('#tiny-loader').show()", 10); - $('#tiny-loader').fadeIn(); + $('#tiny-loader').fadeIn(); } else { - //setTimeout("$('#tiny-loader').hide()", 10); - $('#tiny-loader').hide(); + $('#tiny-loader').hide(); } }, + droppable: true, drop: function(date, jsEvent, ui, resourceId) { data = moment(date).format("YYYY-MM-DD"); ora_dal = moment(date).format("HH:mm"); @@ -478,49 +474,20 @@ if (Modules::getPermission($id_module) == 'rw') { $('#calendar').fullCalendar('refetchEvents'); }); }, - + selectable: true, select: function(start, end, allDay) { data = moment(start).format("YYYY-MM-DD"); ora_dal = moment(start).format("HH:mm"); ora_al = moment(end).format("HH:mm"); - - launch_modal('', globals.rootdir + '/add.php?id_module=&ref=dashboard&data='+data+'&orario_inizio='+ora_dal+'&orario_fine='+ora_al, 1 ); - + launch_modal('', globals.rootdir + '/add.php?id_module=&ref=dashboard&data='+data+'&orario_inizio='+ora_dal+'&orario_fine='+ora_al, 1 ); $('#calendar').fullCalendar('unselect'); }, - events: { - url: globals.rootdir + "/modules/dashboard/ajaxreq.php?op=get_current_month", - type: 'GET', - error: function() { - alert(''); - } - }, - eventResize: function(event,dayDelta,minuteDelta,revertFunc) { - $.get(globals.rootdir + "/modules/dashboard/ajaxreq.php?op=update_intervento&id="+event.id+"&timeStart="+moment(event.start).format("YYYY-MM-DD HH:mm")+"&timeEnd="+moment(event.end).format("YYYY-MM-DD HH:mm"), function(data,response){ - if( response=="success" ){ - data = $.trim(data); - if(data != "ok"){ - alert(data); - $('#calendar').fullCalendar('refetchEvents'); - revertFunc(); - } - else{ - return false; - } - } - }); - }, - eventDrop: function(event,dayDelta,minuteDelta,revertFunc) { + + editable: true, + eventDrop: function(event,dayDelta,minuteDelta,revertFunc) { $.get(globals.rootdir + "/modules/dashboard/ajaxreq.php?op=update_intervento&id="+event.id+"&timeStart="+moment(event.start).format("YYYY-MM-DD HH:mm")+"&timeEnd="+moment(event.end).format("YYYY-MM-DD HH:mm"), function(data,response){ if( response=="success" ){ data = $.trim(data); @@ -535,11 +502,31 @@ if (Modules::getPermission($id_module) == 'rw') { } }); }, + eventResize: function(event,dayDelta,minuteDelta,revertFunc) { + $.get(globals.rootdir + "/modules/dashboard/ajaxreq.php?op=update_intervento&id="+event.id+"&timeStart="+moment(event.start).format("YYYY-MM-DD HH:mm")+"&timeEnd="+moment(event.end).format("YYYY-MM-DD HH:mm"), function(data,response){ + if( response=="success" ){ + data = $.trim(data); + if(data != "ok"){ + alert(data); + $('#calendar').fullCalendar('refetchEvents'); + revertFunc(); + } + else{ + return false; + } + } + }); + }, + eventAfterRender: function(event, element) { //alert(element.find('.fc-event-title').html(); element.find('.fc-title').html(event.title); - + $.get(globals.rootdir + "/modules/dashboard/ajaxreq.php?op=get_more_info&id="+event.id+"&timeStart="+moment(event.start).format("YYYY-MM-DD HH:mm")+"&timeEnd="+moment(event.end).format("YYYY-MM-DD HH:mm"), function(data,response){ if( response=="success" ){ data = $.trim(data); @@ -565,9 +552,20 @@ if (Modules::getPermission($id_module) == 'rw') { } } }); - +} + ?> + events: { + url: globals.rootdir + "/modules/dashboard/ajaxreq.php?op=get_current_month", + type: 'GET', + success: function(data) { + console.log(data); + }, + error: function() { + alert(''); + } } }); } diff --git a/modules/interventi/actions.php b/modules/interventi/actions.php index 4e6a36aa1..20567d9a5 100644 --- a/modules/interventi/actions.php +++ b/modules/interventi/actions.php @@ -182,6 +182,7 @@ switch (post('op')) { break; case 'add': + /* $codice = post('codice'); // Controlli sul codice @@ -196,8 +197,11 @@ switch (post('op')) { $_SESSION['warnings'][] = str_replace('_NUM_', "'".$codice."'", _('Numero intervento _NUM_ saltato perchè già esistente!')); $_SESSION['warnings'][] = str_replace('_NUM_', "'".$new_codice."'", _('Nuovo numero intervento calcolato _NUM_')); } + */ + $formato = get_var('Formato codice intervento'); - $codice = $new_codice; + $rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE concat("", codice * 1) = codice AND LENGTH(codice) = '.strlen($formato).' ORDER BY CAST(codice AS SIGNED) DESC LIMIT 1'); + $codice = get_next_code($rs[0]['codice'], 1, $formato); // Informazioni di base $idpreventivo = post('idpreventivo'); diff --git a/modules/interventi/add.php b/modules/interventi/add.php index 34ecd84bb..e9ed232c8 100644 --- a/modules/interventi/add.php +++ b/modules/interventi/add.php @@ -97,7 +97,6 @@ if (empty($new_codice)) {
- @@ -156,19 +155,19 @@ if (empty($new_codice)) {
-
+ -
+
{[ "type": "date", "label": "", "name": "data_richiesta", "required": 1, "value": "-now-" ]}
-
+
{[ "type": "date", "label": "", "name": "data", "required": 1, "value": "" ]}
-
+
{[ "type": "select", "label": "", "name": "idzona", "values": "query=SELECT id, nome AS descrizione FROM an_zone ORDER BY nome", "value": "" ]}
diff --git a/update/2_3.php b/update/2_3.php index 976b9a3c3..013078da7 100644 --- a/update/2_3.php +++ b/update/2_3.php @@ -159,7 +159,7 @@ $dirs = [ 'zone', ]; -$pieces = array_chunk($tables, 5); +$pieces = array_chunk($dirs, 5); foreach ($pieces as $piece) { $files = glob($docroot.'/modules/{'.implode(',', $piece).'}/*.html', GLOB_BRACE); diff --git a/update/2_3.sql b/update/2_3.sql index 3c959d209..35e63801d 100644 --- a/update/2_3.sql +++ b/update/2_3.sql @@ -952,5 +952,9 @@ 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`); +-- Fix di alcuni problemi con le query dei widget 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'; + +-- Fix per le sessioni di lavoro dei tecnici precedenti +UPDATE `in_interventi_tecnici` SET `idtipointervento` = (SELECT `idtipointervento` FROM `in_interventi` WHERE `idintervento` = `in_interventi`.`id`) WHERE `idtipointervento` = ''; diff --git a/update/api.php b/update/api.php index 2f79aff39..ce26e66fe 100644 --- a/update/api.php +++ b/update/api.php @@ -90,33 +90,20 @@ $tables = [ 'zz_semaphores', ]; -$pieces = array_chunk($tables, 10); +foreach ($tables as $table) { + if ($database->fetchNum('SHOW TABLES WHERE `Tables_in_'.$database->getDatabaseName().'` = '.prepare($table))) { + $query = 'SHOW COLUMNS FROM '.$table.' FROM '.$database->getDatabaseName()." WHERE Field='|field|'"; -foreach ($pieces as $piece) { - $implode = []; - foreach ($piece as $table) { - $implode[] = prepare($table); - } + $created_at = $database->fetchArray(str_replace('|field|', 'created_at', $query)); + if (empty($created_at)) { + $database->query('ALTER TABLE `'.$table.'` ADD `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP'); + } - $query = 'SELECT table_name FROM INFORMATION_SCHEMA.TABLES T WHERE T.TABLE_SCHEMA = '.prepare($database->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'); + if (API::isCompatible()) { + $updated_at = $database->fetchArray(str_replace('|field|', 'updated_at', $query)); + if (empty($updated_at)) { + $database->query('ALTER TABLE `'.$table.'` ADD `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'); + } } } }