From 7b589c530c84dc41f56b905adbc6bad140ad572c Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Fri, 19 Jul 2019 15:23:00 +0200 Subject: [PATCH] Aggiornamento API --- api/index.php | 50 +-- config/namespaces.php | 6 + core.php | 11 +- modules/aggiornamenti/api/retrieve.php | 64 --- modules/anagrafiche/api/create.php | 22 - modules/anagrafiche/api/delete.php | 20 - modules/anagrafiche/api/retrieve.php | 63 --- modules/anagrafiche/api/update.php | 28 -- modules/anagrafiche/api/v1/Anagrafiche.php | 106 +++++ modules/anagrafiche/src/Anagrafica.php | 7 + modules/articoli/api/retrieve.php | 12 - modules/articoli/api/v1/Articoli.php | 20 + .../api/{create.php => v1/Movimenti.php} | 16 +- modules/fatture/edit.php | 2 +- modules/interventi/api/create.php | 79 ---- modules/interventi/api/delete.php | 26 -- modules/interventi/api/retrieve.php | 130 ------ modules/interventi/api/update.php | 135 ------ modules/interventi/api/v1/Articoli.php | 49 +++ modules/interventi/api/v1/Firma.php | 20 + modules/interventi/api/v1/Interventi.php | 91 ++++ modules/interventi/api/v1/Sessioni.php | 50 +++ modules/interventi/api/v1/Sync.php | 167 +++++++ modules/stati_contratto/api/retrieve.php | 22 - .../stati_contratto/api/v1/StatiContratti.php | 27 ++ modules/stati_intervento/api/retrieve.php | 22 - .../api/v1/StatiInterventi.php | 28 ++ modules/stati_preventivo/api/retrieve.php | 22 - .../api/v1/StatiPreventivi.php | 27 ++ modules/stato_servizi/actions.php | 5 +- .../api/{retrieve.php => v1/FolderSize.php} | 40 +- .../tipi_intervento/api/v1/TipiInterventi.php | 23 + modules/utenti/api/create.php | 50 --- modules/utenti/api/v1/Login.php | 43 ++ modules/utenti/api/v1/Logout.php | 25 ++ plugins/exportFE/src/Interaction.php | 4 +- plugins/importFE/src/Interaction.php | 4 +- plugins/receiptFE/src/Interaction.php | 4 +- src/API.php | 410 ------------------ .../create.php => src/API/Common/Allegato.php | 23 +- src/API/Exceptions/InternalError.php | 9 + src/API/Exceptions/ResourceNotFound.php | 9 + src/API/Exceptions/ServiceError.php | 9 + src/API/Exceptions/Unauthorized.php | 9 + src/API/Interfaces/CreateInterface.php | 8 + src/API/Interfaces/DeleteInterface.php | 8 + src/API/Interfaces/RetrieveInterface.php | 8 + src/API/Interfaces/UpdateInterface.php | 8 + src/API/Manager.php | 193 +++++++++ src/API/Response.php | 247 +++++++++++ .../Connection.php => src/API/Services.php | 4 +- src/Auth.php | 6 +- src/Models/ApiResource.php | 12 + src/Models/User.php | 11 + update/2_4_11.php | 29 ++ update/2_4_11.sql | 42 ++ update/api.php | 2 +- update/tables.php | 1 + 58 files changed, 1366 insertions(+), 1202 deletions(-) delete mode 100644 modules/aggiornamenti/api/retrieve.php delete mode 100644 modules/anagrafiche/api/create.php delete mode 100644 modules/anagrafiche/api/delete.php delete mode 100644 modules/anagrafiche/api/retrieve.php delete mode 100644 modules/anagrafiche/api/update.php create mode 100644 modules/anagrafiche/api/v1/Anagrafiche.php delete mode 100644 modules/articoli/api/retrieve.php create mode 100644 modules/articoli/api/v1/Articoli.php rename modules/articoli/api/{create.php => v1/Movimenti.php} (57%) delete mode 100644 modules/interventi/api/create.php delete mode 100644 modules/interventi/api/delete.php delete mode 100644 modules/interventi/api/retrieve.php delete mode 100644 modules/interventi/api/update.php create mode 100644 modules/interventi/api/v1/Articoli.php create mode 100644 modules/interventi/api/v1/Firma.php create mode 100644 modules/interventi/api/v1/Interventi.php create mode 100644 modules/interventi/api/v1/Sessioni.php create mode 100644 modules/interventi/api/v1/Sync.php delete mode 100644 modules/stati_contratto/api/retrieve.php create mode 100644 modules/stati_contratto/api/v1/StatiContratti.php delete mode 100644 modules/stati_intervento/api/retrieve.php create mode 100644 modules/stati_intervento/api/v1/StatiInterventi.php delete mode 100644 modules/stati_preventivo/api/retrieve.php create mode 100644 modules/stati_preventivo/api/v1/StatiPreventivi.php rename modules/stato_servizi/api/{retrieve.php => v1/FolderSize.php} (52%) create mode 100644 modules/tipi_intervento/api/v1/TipiInterventi.php delete mode 100644 modules/utenti/api/create.php create mode 100644 modules/utenti/api/v1/Login.php create mode 100644 modules/utenti/api/v1/Logout.php delete mode 100644 src/API.php rename modules/aggiornamenti/api/create.php => src/API/Common/Allegato.php (51%) create mode 100644 src/API/Exceptions/InternalError.php create mode 100644 src/API/Exceptions/ResourceNotFound.php create mode 100644 src/API/Exceptions/ServiceError.php create mode 100644 src/API/Exceptions/Unauthorized.php create mode 100644 src/API/Interfaces/CreateInterface.php create mode 100644 src/API/Interfaces/DeleteInterface.php create mode 100644 src/API/Interfaces/RetrieveInterface.php create mode 100644 src/API/Interfaces/UpdateInterface.php create mode 100644 src/API/Manager.php create mode 100644 src/API/Response.php rename plugins/exportFE/src/Connection.php => src/API/Services.php (96%) create mode 100644 src/Models/ApiResource.php create mode 100644 update/2_4_11.php diff --git a/api/index.php b/api/index.php index 815e7d4b3..5bf3dc75a 100644 --- a/api/index.php +++ b/api/index.php @@ -5,7 +5,7 @@ function serverError() $error = error_get_last(); if ($error['type'] == E_ERROR) { ob_end_clean(); - echo API::error('serverError'); + echo Response::error('serverError'); } } @@ -22,61 +22,21 @@ session_write_close(); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS'); -// Attenzione: al momento l'API permette la lettura di tutte le tabelle presenti nel database (non limitate a quelle del progetto) +use API\Response; try { - // Controlli sulla chiave di accesso - $api = new API(); - - // Lettura delle informazioni - $request = API::getRequest(); - - // Gestione della richiesta - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - // Richiesta PUT (modifica elementi) - case 'PUT': - $response = $api->update($request); - break; - - // Richiesta POST (creazione elementi) - case 'POST': - $response = $api->create($request); - break; - - // Richiesta GET (ottenimento elementi) - case 'GET': - // Risorsa specificata - if (count($request) > 1) { - $response = $api->retrieve($request); - } - - // Risorsa non specificata (lista delle risorse disponibili) - else { - $response = API::response([ - 'resources' => array_keys(API::getResources()['retrieve']), - ]); - } - break; - - // Richiesta DELETE (eliminazione elementi) - case 'DELETE': - $response = $api->delete($request); - break; - } -} catch (InvalidArgumentException $e) { - $response = API::error('unauthorized'); + $response = Response::manage(); } catch (Exception $e) { // Log dell'errore $logger = logger(); $logger->addRecord(\Monolog\Logger::ERROR, $e); - $response = API::error('serverError'); + $response = Response::error('serverError'); } // Richiesta OPTIONS (controllo da parte del dispositivo) if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { - $response = API::error('ok'); + $response = Response::error('ok'); } json_decode($response); diff --git a/config/namespaces.php b/config/namespaces.php index 974ca80a2..e00ca261e 100644 --- a/config/namespaces.php +++ b/config/namespaces.php @@ -17,6 +17,12 @@ return [ 'modules/interventi' => 'Modules\Interventi', 'modules/pagamenti' => 'Modules\Pagamenti', 'modules/statistiche' => 'Modules\Statistiche', + 'modules/utenti' => 'Modules\Utenti', + 'modules/stato_servizi' => 'Modules\StatoServizi', + 'modules/stati_intervento' => 'Modules\StatiIntervento', + 'modules/stati_preventivo' => 'Modules\StatiPreventivo', + 'modules/stati_contratto' => 'Modules\StatiContratto', + 'modules/stato_servizi' => 'Modules\StatoServizi', 'modules/tipi_intervento' => 'Modules\TipiIntervento', 'plugins/exportFE' => 'Plugins\ExportFE', 'plugins/importFE' => 'Plugins\ImportFE', diff --git a/core.php b/core.php index cab7c3788..c9f46becd 100644 --- a/core.php +++ b/core.php @@ -28,6 +28,9 @@ $namespaces = require_once __DIR__.'/config/namespaces.php'; foreach ($namespaces as $path => $namespace) { $loader->addPsr4($namespace.'\\', __DIR__.'/'.$path.'/custom/src'); $loader->addPsr4($namespace.'\\', __DIR__.'/'.$path.'/src'); + + $loader->addPsr4($namespace.'\\API\\', __DIR__.'/'.$path.'/custom/api'); + $loader->addPsr4($namespace.'\\API\\', __DIR__.'/'.$path.'/api'); } // Individuazione dei percorsi di base @@ -60,7 +63,7 @@ use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\StreamHandler; $handlers = []; -if (!API::isAPIRequest()) { +if (!API\Response::isAPIRequest()) { // File di log di base (logs/error.log, logs/setup.log) $handlers[] = new StreamHandler($docroot.'/logs/error.log', Monolog\Logger::ERROR); $handlers[] = new StreamHandler($docroot.'/logs/setup.log', Monolog\Logger::EMERGENCY); @@ -124,7 +127,7 @@ Monolog\ErrorHandler::register($logger, [], Monolog\Logger::ERROR, Monolog\Logge $dbo = $database = database(); /* SESSIONE */ -if (!API::isAPIRequest()) { +if (!API\Response::isAPIRequest()) { // Sicurezza della sessioni ini_set('session.use_trans_sid', '0'); ini_set('session.use_only_cookies', '1'); @@ -162,7 +165,7 @@ $revision = Update::getRevision(); /* ACCESSO E INSTALLAZIONE */ // Controllo sulla presenza dei permessi di accesso basilari -$continue = $dbo->isInstalled() && !Update::isUpdateAvailable() && (Auth::check() || API::isAPIRequest()); +$continue = $dbo->isInstalled() && !Update::isUpdateAvailable() && (Auth::check() || API\Response::isAPIRequest()); if (!empty($skip_permissions)) { Permissions::skip(); @@ -179,7 +182,7 @@ if (!$continue && getURLPath() != slashes(ROOTDIR.'/index.php') && !Permissions: /* INIZIALIZZAZIONE GENERALE */ // Operazione aggiuntive (richieste non API) -if (!API::isAPIRequest()) { +if (!API\Response::isAPIRequest()) { // Impostazioni di Content-Type e Charset Header header('Content-Type: text/html; charset=UTF-8'); diff --git a/modules/aggiornamenti/api/retrieve.php b/modules/aggiornamenti/api/retrieve.php deleted file mode 100644 index 83d69c679..000000000 --- a/modules/aggiornamenti/api/retrieve.php +++ /dev/null @@ -1,64 +0,0 @@ -= '.prepare($updated) : ''; - - $excluded = explode(',', setting('Tabelle escluse per la sincronizzazione API automatica')); - - // Attenzione: query specifica per MySQL - $datas = $dbo->fetchArray("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA=".prepare($db_name)); - if (!empty($datas)) { - foreach ($datas as $data) { - if (!in_array($data['TABLE_NAME'], $excluded)) { - $response[$data['TABLE_NAME']] = $dbo->fetchArray('SELECT * FROM '.$data['TABLE_NAME'].$custom_where); - } - } - } - break; - - // Attualmente vengono considerate solo le tabelle che eseguono l'eliminazione fisica della riga - case 'deleted': - $excluded = explode(',', setting('Tabelle escluse per la sincronizzazione API automatica')); - - // Attenzione: query specifica per MySQL - $datas = $dbo->fetchArray("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA=".prepare($db_name)); - if (!empty($datas)) { - foreach ($datas as $data) { - $table_name = $data['TABLE_NAME']; - - // Ottiene il nome della colonna di tipo AUTO_INCREMENT della tabella - $column = $dbo->fetchArray('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '.prepare($table_name)." AND EXTRA LIKE '%AUTO_INCREMENT%' AND TABLE_SCHEMA = ".prepare($db_name))[0]['COLUMN_NAME']; - - if (!in_array($table_name, $excluded) && !empty($column)) { - // Ottiene il valore successivo della colonna di tipo AUTO_INCREMENT - $auto_inc = $dbo->fetchArray('SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '.prepare($table_name).' AND TABLE_SCHEMA = '.prepare($db_name))[0]['AUTO_INCREMENT']; - - // Ottiene i vuoti all'interno della sequenza AUTO_INCREMENT - $steps = $dbo->fetchArray('SELECT (t1.'.$column.' + 1) as start, (SELECT MIN(t3.'.$column.') - 1 FROM '.$table_name.' t3 WHERE t3.'.$column.' > t1.'.$column.') as end FROM '.$table_name.' t1 WHERE NOT EXISTS (SELECT t2.'.$column.' FROM '.$table_name.' t2 WHERE t2.'.$column.' = t1.'.$column.' + 1) ORDER BY start'); - - $total = []; - foreach ($steps as $step) { - if ($step['end'] == null) { - $step['end'] = $auto_inc - 1; - } - - if ($step['end'] >= $step['start']) { - $total = array_merge($total, range($step['start'], $step['end'])); - } - } - - $response[$table_name] = $total; - } - } - } - - break; -} - -/* -return [ - 'updates', - 'deleted', -]; -*/ diff --git a/modules/anagrafiche/api/create.php b/modules/anagrafiche/api/create.php deleted file mode 100644 index 8003d98f0..000000000 --- a/modules/anagrafiche/api/create.php +++ /dev/null @@ -1,22 +0,0 @@ -fetchArray('SELECT codice FROM an_anagrafiche ORDER BY CAST(codice AS SIGNED) DESC LIMIT 0, 1'); - $codice = Util\Generator::generate(setting('Formato codice anagrafica'), $rs[0]['codice']); - - // Inserisco l'anagrafica - $dbo->insert('an_anagrafiche', [ - 'ragione_sociale' => $request['data']['ragione_sociale'], - 'codice' => $codice, - ]); - - // Inserisco il rapporto dell'anagrafica (cliente, tecnico, ecc) - $dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $dbo->lastInsertedID()], ['idtipoanagrafica' => (array) $request['data']['tipi']]); - - break; -} - -return [ - 'add_anagrafica', -]; diff --git a/modules/anagrafiche/api/delete.php b/modules/anagrafiche/api/delete.php deleted file mode 100644 index 805a34d19..000000000 --- a/modules/anagrafiche/api/delete.php +++ /dev/null @@ -1,20 +0,0 @@ -fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Azienda'")[0]['idtipoanagrafica']; - - $anagrafica = $dbo->fetchArray('SELECT an_tipianagrafiche.idtipoanagrafica FROM an_tipianagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche.idtipoanagrafica=an_tipianagrafiche_anagrafiche.idtipoanagrafica WHERE idanagrafica='.prepare($request['id'])); - $tipi = array_column($anagrafica, 'idtipoanagrafica'); - - // Se l'anagrafica non è l'azienda principale, la disattivo - if (!in_array($id_azienda, $tipi)) { - $dbo->query('UPDATE an_anagrafiche SET deleted_at = NOW() WHERE idanagrafica = '.prepare($request['id'])); - } - - break; -} - -return [ - 'delete_anagrafica', -]; diff --git a/modules/anagrafiche/api/retrieve.php b/modules/anagrafiche/api/retrieve.php deleted file mode 100644 index aaf4458b5..000000000 --- a/modules/anagrafiche/api/retrieve.php +++ /dev/null @@ -1,63 +0,0 @@ -update('an_anagrafiche', [ - 'ragione_sociale' => $request['data']['ragione_sociale'], - 'piva' => $request['data']['piva'], - 'codice_fiscale' => $request['data']['codice_fiscale'], - 'indirizzo' => $request['data']['indirizzo'], - 'citta' => $request['data']['citta'], - 'provincia' => $request['data']['provincia'], - 'id_nazione' => $request['data']['id_nazione'], - 'telefono' => $request['data']['telefono'], - 'fax' => $request['data']['fax'], - 'cellulare' => $request['data']['cellulare'], - 'email' => $request['data']['email'], - ], ['idanagrafica' => $request['id']]); - - // Inserisco il rapporto dell'anagrafica (cliente, tecnico, ecc) - $dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $request['id']], ['idtipoanagrafica' => (array) $request['data']['tipi']]); - - break; -} - -return [ - 'update_anagrafica', -]; diff --git a/modules/anagrafiche/api/v1/Anagrafiche.php b/modules/anagrafiche/api/v1/Anagrafiche.php new file mode 100644 index 000000000..a8e143552 --- /dev/null +++ b/modules/anagrafiche/api/v1/Anagrafiche.php @@ -0,0 +1,106 @@ +id, $query); + + return [ + 'query' => $query, + ]; + } + + public function create($request) + { + $ragione_sociale = $request['data']['ragione_sociale']; + $id_tipo = (array) $request['data']['tipi']; + + $anagrafica = Anagrafica::build($ragione_sociale, null, null, $id_tipo); + $id_record = $anagrafica->id; + + return [ + 'id' => $id_record, + ]; + } + + public function delete($request) + { + $anagrafica = Anagrafica::find($request['id']); + + $result = $anagrafica->delete(); + } + + public function update($request) + { + $data = $request['data']; + + $anagrafica = Anagrafica::find($request['id']); + + $anagrafica->ragione_sociale = $data['ragione_sociale']; + $anagrafica->piva = $data['piva']; + $anagrafica->codice_fiscale = $data['codice_fiscale']; + $anagrafica->indirizzo = $data['indirizzo']; + $anagrafica->citta = $data['citta']; + $anagrafica->provincia = $data['provincia']; + $anagrafica->id_nazione = $data['id_nazione']; + $anagrafica->telefono = $data['telefono']; + $anagrafica->fax = $data['fax']; + $anagrafica->cellulare = $data['cellulare']; + $anagrafica->email = $data['email']; + + $anagrafica->tipologie = (array) $data['tipi']; + + $anagrafica->save(); + } +} diff --git a/modules/anagrafiche/src/Anagrafica.php b/modules/anagrafiche/src/Anagrafica.php index e3aef1aa2..7361823e0 100644 --- a/modules/anagrafiche/src/Anagrafica.php +++ b/modules/anagrafiche/src/Anagrafica.php @@ -261,6 +261,13 @@ class Anagrafica extends Model return $this; } + public function delete() + { + if (!$this->isAzienda()) { + return parent::delete(); + } + } + // Metodi statici /** diff --git a/modules/articoli/api/retrieve.php b/modules/articoli/api/retrieve.php deleted file mode 100644 index 01dddf2ac..000000000 --- a/modules/articoli/api/retrieve.php +++ /dev/null @@ -1,12 +0,0 @@ - $query, + ]; + } +} diff --git a/modules/articoli/api/create.php b/modules/articoli/api/v1/Movimenti.php similarity index 57% rename from modules/articoli/api/create.php rename to modules/articoli/api/v1/Movimenti.php index 780a20a57..8ccc29b60 100644 --- a/modules/articoli/api/create.php +++ b/modules/articoli/api/v1/Movimenti.php @@ -1,17 +1,17 @@ movimenta($data['qta'], $data['descrizione'], $data['data'], true); - - break; + } } - -return [ - 'movimento_articolo', -]; diff --git a/modules/fatture/edit.php b/modules/fatture/edit.php index 58c74e1c0..c7edafd72 100644 --- a/modules/fatture/edit.php +++ b/modules/fatture/edit.php @@ -126,7 +126,7 @@ if (empty($record['is_fiscale'])) { - {[ "type": "select", "label": "", "name": "codice_stato_fe", "required": 0, "values": "query=SELECT codice as id, CONCAT_WS(' - ',codice,descrizione) as text FROM fe_stati_documento", "value": "$codice_stato_fe$", "disabled": , "class": "unblockable", "help": "" ]} + {[ "type": "select", "label": "", "name": "codice_stato_fe", "required": 0, "values": "query=SELECT codice as id, CONCAT_WS(' - ',codice,descrizione) as text FROM fe_stati_documento", "value": "$codice_stato_fe$", "disabled": , "class": "unblockable", "help": "" ]} diff --git a/modules/interventi/api/create.php b/modules/interventi/api/create.php deleted file mode 100644 index a868cff06..000000000 --- a/modules/interventi/api/create.php +++ /dev/null @@ -1,79 +0,0 @@ -fetchArray('SELECT codice FROM in_interventi WHERE codice=(SELECT MAX(CAST(codice AS SIGNED)) FROM in_interventi) AND codice LIKE '.prepare($template).' ORDER BY codice DESC LIMIT 0,1'); - $codice = Util\Generator::generate($formato, $rs[0]['codice']); - - if (empty($codice)) { - $rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice LIKE '.prepare($template).' ORDER BY codice DESC LIMIT 0,1'); - - $codice = Util\Generator::generate($formato, $rs[0]['codice']); - } - - if (!empty($codice) && !empty($data['id_anagrafica']) && !empty($data['id_tipo_intervento'])) { - // Salvataggio modifiche intervento - $dbo->insert('in_interventi', [ - 'idanagrafica' => $data['id_anagrafica'], - 'idclientefinale' => 0, - 'idstatointervento' => $data['id_stato_intervento'], - 'idtipointervento' => $data['id_tipo_intervento'], - 'idsede' => 0, - - 'codice' => $codice, - 'data_richiesta' => $data['data_richiesta'], - 'richiesta' => $data['richiesta'], - 'descrizione' => $data['descrizione'], - 'informazioniaggiuntive' => $data['informazioni_aggiuntive'], - ]); - - $response['id'] = $dbo->lastInsertedID(); - $response['codice'] = $codice; - - /* - $start = date('Y-m-d H:i:s'); - $end = date('Y-m-d H:i:s', strtotime('+1 hour', strtotime($start))); - - add_tecnico($response['id'], $user['idanagrafica'], $start, $end); - */ - } - - break; - - case 'sessione': - $data = $request['data']; - - add_tecnico($data['id_intervento'], $user['idanagrafica'], $data['orario_inizio'], $data['orario_fine']); - - break; - - case 'articolo_intervento': - $data = $request['data']; - - $originale = ArticoloOriginale::find($data['id_articolo']); - $intervento = Intervento::find($data['id_intervento']); - $articolo = Articolo::build($intervento, $originale); - - $articolo->qta = $data['qta']; - $articolo->um = $data['um']; - - $articolo->save(); - - break; -} - -return [ - 'intervento', - 'sessione', - 'articolo_intervento', -]; diff --git a/modules/interventi/api/delete.php b/modules/interventi/api/delete.php deleted file mode 100644 index 256b7e2ed..000000000 --- a/modules/interventi/api/delete.php +++ /dev/null @@ -1,26 +0,0 @@ -query('DELETE FROM `in_interventi_tecnici` WHERE `idintervento` = :id_intervento AND `idtecnico` = :id_tecnico', [ - ':id_intervento' => $request['id_intervento'], - ':id_tecnico' => $user['idanagrafica'], - ]); - - break; - - case 'articoli_intervento': - $dbo->query('DELETE FROM `mg_articoli_interventi` WHERE `idintervento` = :id_intervento', [ - ':id_intervento' => $request['id_intervento'], - ]); - - // TODO: prevedere la modifica di quantità! - // TODO: prevedere causali - - break; -} - -return [ - 'sessioni_intervento', - //'articoli_intervento', -]; diff --git a/modules/interventi/api/retrieve.php b/modules/interventi/api/retrieve.php deleted file mode 100644 index db6289519..000000000 --- a/modules/interventi/api/retrieve.php +++ /dev/null @@ -1,130 +0,0 @@ -query('UPDATE in_interventi_tecnici SET summary = (SELECT ragione_sociale FROM an_anagrafiche INNER JOIN in_interventi ON an_anagrafiche.idanagrafica=in_interventi.idanagrafica WHERE in_interventi.id=in_interventi_tecnici.idintervento) WHERE summary IS NULL'); - $dbo->query('UPDATE in_interventi_tecnici SET uid = id WHERE uid IS NULL'); - - // Individuazione degli interventi - $query = 'SELECT in_interventi_tecnici.id AS idriga, in_interventi_tecnici.idintervento, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente, richiesta, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, summary FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE DATE(orario_inizio) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 3 MONTH AND deleted_at IS NULL'; - - if (!empty($user['idanagrafica'])) { - $query .= ' AND in_interventi_tecnici.idtecnico = '.prepare($user['idanagrafica']); - } - - $rs = $dbo->fetchArray($query); - - $response['custom'] = ''; - - $response['custom'] .= "BEGIN:VCALENDAR\n"; - $response['custom'] .= 'VERSION:'.Update::getVersion()."\n"; - $response['custom'] .= "PRODID:-// OpenSTAManager\n"; - - foreach ($rs as $r) { - $richiesta = str_replace("\r\n", "\n", $r['richiesta']); - $richiesta = str_replace("\r", "\n", $richiesta); - $richiesta = str_replace("\n", '\\n', $richiesta); - - $r['summary'] = str_replace("\r\n", "\n", $r['summary']); - - $response['custom'] .= "BEGIN:VEVENT\n"; - $response['custom'] .= 'UID:'.$r['idriga']."\n"; - $response['custom'] .= 'DTSTAMP:'.date('Ymd').'T'.date('His')."\n"; - //$response['custom'] .= 'ORGANIZER;CN='.$azienda.':MAILTO:'.$email."\n"; - $response['custom'] .= 'DTSTART:'.date('Ymd', strtotime($r['orario_inizio'])).'T'.date('His', strtotime($r['orario_inizio']))."\n"; - $response['custom'] .= 'DTEND:'.date('Ymd', strtotime($r['orario_fine'])).'T'.date('His', strtotime($r['orario_fine']))."\n"; - $response['custom'] .= 'SUMMARY:'.html_entity_decode($r['summary'])."\n"; - $response['custom'] .= 'DESCRIPTION:'.html_entity_decode($richiesta, ENT_QUOTES, 'UTF-8')."\n"; - $response['custom'] .= "END:VEVENT\n"; - } - - $response['custom'] .= "END:VCALENDAR\n"; - - break; - - // Elenco interventi per l'applicazione (recupero sempre tutti gli interventi che non vengono chiusi) - case 'interventi': - // Periodo per selezionare interventi - $today = date('Y-m-d'); - $period_end = date('Y-m-d', strtotime($today.' +7 days')); - $period_start = date('Y-m-d', strtotime($today.' -2 months')); - - $query = "SELECT `in_interventi`.`id`, - `in_interventi`.`codice`, - `in_interventi`.`data_richiesta`, - `in_interventi`.`richiesta`, - `in_interventi`.`descrizione`, - `in_interventi`.`idtipointervento`, - `in_interventi`.`idanagrafica`, - `in_interventi`.`idsede`, - `in_interventi`.`idstatointervento`, - `in_interventi`.`informazioniaggiuntive`, - `in_interventi`.`idclientefinale`, - `in_interventi`.`firma_file`, - IF(firma_data = '0000-00-00 00:00:00', '', firma_data) AS `firma_data`, - `in_interventi`.firma_nome, - (SELECT GROUP_CONCAT(CONCAT(my_impianti.matricola, ' - ', my_impianti.nome) SEPARATOR ', ') FROM (my_impianti_interventi INNER JOIN my_impianti ON my_impianti_interventi.idimpianto=my_impianti.id) WHERE my_impianti_interventi.idintervento = `in_interventi`.`id`) AS `impianti`, - (SELECT MAX(`orario_fine`) FROM `in_interventi_tecnici` WHERE `in_interventi_tecnici`.`idintervento` = `in_interventi`.`id`) AS `data`, - (SELECT GROUP_CONCAT(DISTINCT ragione_sociale SEPARATOR ', ') FROM `in_interventi_tecnici` INNER JOIN `an_anagrafiche` ON `in_interventi_tecnici`.`idtecnico` = `an_anagrafiche`.`idanagrafica` WHERE `in_interventi_tecnici`.`idintervento` = `in_interventi`.`id`) AS `tecnici`, - `in_statiintervento`.`colore` AS `bgcolor`, - `in_statiintervento`.`descrizione` AS `stato`, - `in_interventi`.`idtipointervento` AS `tipo` - FROM `in_interventi` - INNER JOIN `in_statiintervento` ON `in_interventi`.`idstatointervento` = `in_statiintervento`.`idstatointervento` - INNER JOIN `an_anagrafiche` ON `in_interventi`.`idanagrafica` = `an_anagrafiche`.`idanagrafica` - LEFT JOIN `an_sedi` ON `in_interventi`.`idsede` = `an_sedi`.`id` - WHERE EXISTS(SELECT `orario_fine` FROM `in_interventi_tecnici` WHERE `in_interventi_tecnici`.`idintervento` = `in_interventi`.`id` AND `orario_fine` BETWEEN :period_start AND :period_end)"; - - // TODO: rimosse le seguenti clausole - - // WHERE `in_interventi`.idstatointervento IN(SELECT idstatointervento FROM in_statiintervento WHERE app_download=1) - // nel database ufficiale manca in_statiintervento.app_download - - // AND `in_interventi_tecnici`.`idtecnico`='".$tecnico[0]['idanagrafica']."' - // nell'inner join con in_interventi_tecnici -> ad oggi 16-05-2018 non gestisco ancora idtecnico - - $parameters = [ - ':period_end' => $period_end, - ':period_start' => $period_start, - ]; - - break; - - // Elenco sessioni dell'intervento per l'applicazione - case 'sessioni_intervento': - $query = 'SELECT id, idintervento AS id_intervento, orario_inizio, orario_fine FROM in_interventi_tecnici WHERE `idintervento` = :id_intervento'; - - // TODO: rimosse seguenti clausole: - - // WHERE `in_interventi`.idstatointervento IN(SELECT idstatointervento FROM in_statiintervento WHERE app_download=1) - // nel database ufficiale manca in_statiintervento.app_download - - $parameters = [ - ':id_intervento' => $request['id_intervento'], - ]; - - if ($user['gruppo'] == 'Tecnici') { - $query .= ' AND `idtecnico` = :id_tecnico'; - $parameters[':id_tecnico'] = $user['idanagrafica']; - } - - break; - - // Elenco articoli dell'intervento per l'applicazione - case 'articoli_intervento': - $query = 'SELECT id, idarticolo AS id_articolo, idintervento AS id_intervento, qta, created_at as data FROM mg_articoli_interventi WHERE `idintervento` = :id_intervento'; - - $parameters = [ - ':id_intervento' => $request['id_intervento'], - ]; - - break; -} - -return [ - 'sync', - 'interventi', - 'sessioni_intervento', - 'articoli_intervento', -]; diff --git a/modules/interventi/api/update.php b/modules/interventi/api/update.php deleted file mode 100644 index 04de7836c..000000000 --- a/modules/interventi/api/update.php +++ /dev/null @@ -1,135 +0,0 @@ -query('UPDATE in_interventi_tecnici SET summary = (SELECT ragione_sociale FROM an_anagrafiche INNER JOIN in_interventi ON an_anagrafiche.idanagrafica=in_interventi.idanagrafica WHERE in_interventi.id=in_interventi_tecnici.idintervento) WHERE summary IS NULL'); - $dbo->query('UPDATE in_interventi_tecnici SET uid = id WHERE uid IS NULL'); - - // Interpretazione degli eventi - $idtecnico = $user['idanagrafica']; - - $response = API::getRequest(true); - - $ical = new iCalEasyReader(); - $events = $ical->load($response); - - foreach ($events['VEVENT'] as $event) { - $description = $event['DESCRIPTION']; - - // Individuazione idriga di in_interventi_tecnici - if (str_contains($event['UID'], '-')) { - $idriga = 'NEW'; - } else { - $idriga = $event['UID']; - } - - // Timestamp di inizio - $orario_inizio = DateTime::createFromFormat('Ymd\\THi', $event['DTSTART'])->format(Intl\Formatter::getStandardFormats()['timestamp']); - - // Timestamp di fine - $orario_fine = DateTime::createFromFormat('Ymd\\THi', $event['DTEND'])->format(Intl\Formatter::getStandardFormats()['timestamp']); - - // Descrizione - $richiesta = $event['DESCRIPTION']; - $richiesta = str_replace('\\r\\n', "\n", $richiesta); - $richiesta = str_replace('\\n', "\n", $richiesta); - - $summary = trim($event['SUMMARY']); - $summary = str_replace('\\r\\n', "\n", $summary); - $summary = str_replace('\\n', "\n", $summary); - - // Nuova attività - if ($idriga == 'NEW') { - $rs_copie = $dbo->fetchArray('SELECT * FROM in_interventi_tecnici WHERE uid = '.prepare($event['UID'])); - - if (!empty($rs_copie)) { - $idintervento = $rs_copie[0]['idintervento']; - - $dbo->update('in_interventi_tecnici', [ - 'orario_inizio' => $orario_inizio, - 'orario_fine' => $orario_fine, - 'summary' => $summary, - ], [ - 'uid' => $event['UID'], - 'idtecnico' => $idtecnico, - ]); - - $dbo->query('UPDATE in_interventi SET richiesta='.prepare($richiesta).', oggetto='.prepare($summary).' WHERE idintervento = (SELECT idintervento FROM in_interventi_tecnici WHERE idintervento = '.prepare($idintervento).' AND idtecnico = '.prepare($idtecnico).' LIMIT 0,1)'); - - $idriga = $rs_copie[0]['id']; - } else { - $idintervento = get_new_idintervento(); - $stato = $dbo->fetchArray("SELECT * FROM in_statiintervento WHERE descrizione = 'Chiamata'"); - - $dbo->insert('in_interventi', [ - 'idintervento' => $idintervento, - 'idanagrafica' => setting('Azienda predefinita'), - 'data_richiesta' => Carbon::now(), - 'richiesta' => $richiesta, - 'idtipointervento' => 0, - 'idstatointervento' => $stato['idstatointerventoWIP'], - 'oggetto' => $summary, - ]); - - $dbo->insert('in_interventi', [ - 'idintervento' => $idintervento, - 'idtecnico' => $idtecnico, - 'orario_inizio' => $orario_inizio, - 'orario_fine' => $orario_fine, - 'summary' => $summary, - 'uid' => $event['UID'], - ]); - - $idriga = $dbo->lastInsertedID(); - } - } - - // Modifica attività esistente - else { - $dbo->update('in_interventi_tecnici', [ - 'orario_inizio' => $orario_inizio, - 'orario_fine' => $orario_fine, - 'summary' => $summary, - ], [ - 'id' => $idriga, - 'idtecnico' => $idtecnico, - ]); - - $query = 'UPDATE in_interventi SET richiesta='.prepare($richiesta).', oggetto='.prepare($summary).' WHERE idintervento = (SELECT idintervento FROM in_interventi_tecnici WHERE id = '.prepare($idriga).' AND idtecnico = '.prepare($idtecnico).' LIMIT 0,1)'; - $dbo->query($query); - } - } - - break; - - case 'intervento': - $data = $request['data']; - - $dbo->update('in_interventi', [ - 'idstatointervento' => $data['id_stato_intervento'], - 'descrizione' => $data['descrizione'], - 'informazioniaggiuntive' => $data['informazioni_aggiuntive'], - ], ['id' => $data['id']]); - - break; - - case 'firma_intervento': - $data = $request['data']; - - $dbo->update('in_interventi', [ - 'firma_file' => $data['firma_file'], - 'firma_data' => $data['firma_data'], - 'firma_nome' => $data['firma_nome'], - ], ['id' => $data['id']]); - - break; -} - -return [ - 'sync', - 'intervento', - 'firma_intervento', -]; diff --git a/modules/interventi/api/v1/Articoli.php b/modules/interventi/api/v1/Articoli.php new file mode 100644 index 000000000..fd066cabc --- /dev/null +++ b/modules/interventi/api/v1/Articoli.php @@ -0,0 +1,49 @@ + $request['id_intervento'], + ]; + + return [ + 'query' => $query, + 'parameters' => $parameters, + ]; + } + + public function create($request) + { + $data = $request['data']; + + $originale = ArticoloOriginale::find($data['id_articolo']); + $intervento = Intervento::find($data['id_intervento']); + $articolo = Articolo::build($intervento, $originale); + + $articolo->qta = $data['qta']; + $articolo->um = $data['um']; + + $articolo->save(); + } + + public function delete($request) + { + $database = database(); + + $database->query('DELETE FROM `mg_articoli_interventi` WHERE `idintervento` = :id_intervento', [ + ':id_intervento' => $request['id_intervento'], + ]); + } +} diff --git a/modules/interventi/api/v1/Firma.php b/modules/interventi/api/v1/Firma.php new file mode 100644 index 000000000..b28d4d2ab --- /dev/null +++ b/modules/interventi/api/v1/Firma.php @@ -0,0 +1,20 @@ +update('in_interventi', [ + 'firma_file' => $data['firma_file'], + 'firma_data' => $data['firma_data'], + 'firma_nome' => $data['firma_nome'], + ], ['id' => $data['id']]); + } +} diff --git a/modules/interventi/api/v1/Interventi.php b/modules/interventi/api/v1/Interventi.php new file mode 100644 index 000000000..8cc147f44 --- /dev/null +++ b/modules/interventi/api/v1/Interventi.php @@ -0,0 +1,91 @@ + $period_end, + ':period_start' => $period_start, + ]; + + return [ + 'query' => $query, + 'parameters' => $parameters, + ]; + } + + public function create($request) + { + $data = $request['data']; + + $anagrafica = Anagrafica::find($data['id_anagrafica']); + $tipo = TipoSessione::find($data['id_tipo_intervento']); + $stato = Stato::find($data['id_stato_intervento']); + + $intervento = Intervento::build($anagrafica, $tipo, $stato, $data['data_richiesta']); + + $intervento->richiesta = $data['richiesta']; + $intervento->descrizione = $data['descrizione']; + $intervento->informazioniaggiuntive = $data['informazioni_aggiuntive']; + $intervento->save(); + + return [ + 'id' => $intervento->id, + 'codice' => $intervento->codice, + ]; + } + + public function update($request) + { + $data = $request['data']; + + $intervento = Intervento::find($data['id']); + + $intervento->idstatointervento = $data['id_stato_intervento']; + $intervento->descrizione = $data['descrizione']; + $intervento->informazioniaggiuntive = $data['informazioni_aggiuntive']; + $intervento->save(); + } +} diff --git a/modules/interventi/api/v1/Sessioni.php b/modules/interventi/api/v1/Sessioni.php new file mode 100644 index 000000000..941ddae82 --- /dev/null +++ b/modules/interventi/api/v1/Sessioni.php @@ -0,0 +1,50 @@ +getUser(); + + $query = 'SELECT id, idtecnico AS id_tecnico, idintervento AS id_intervento, orario_inizio, orario_fine FROM in_interventi_tecnici WHERE `idintervento` = :id_intervento'; + + $parameters = [ + ':id_intervento' => $request['id_intervento'], + ]; + + if ($user['gruppo'] == 'Tecnici') { + $query .= ' AND `idtecnico` = :id_tecnico'; + $parameters[':id_tecnico'] = $user['idanagrafica']; + } + + return [ + 'query' => $query, + 'parameters' => $parameters, + ]; + } + + public function create($request) + { + $user = auth()->getUser(); + $data = $request['data']; + + add_tecnico($data['id_intervento'], $user['idanagrafica'], $data['orario_inizio'], $data['orario_fine']); + } + + public function delete($request) + { + $database = database(); + $user = auth()->getUser(); + + $database->query('DELETE FROM `in_interventi_tecnici` WHERE `idintervento` = :id_intervento AND `idtecnico` = :id_tecnico', [ + ':id_intervento' => $request['id_intervento'], + ':id_tecnico' => $user['idanagrafica'], + ]); + } +} diff --git a/modules/interventi/api/v1/Sync.php b/modules/interventi/api/v1/Sync.php new file mode 100644 index 000000000..aa45628dd --- /dev/null +++ b/modules/interventi/api/v1/Sync.php @@ -0,0 +1,167 @@ +getUser(); + + // Normalizzazione degli interventi a database + $database->query('UPDATE in_interventi_tecnici SET summary = (SELECT ragione_sociale FROM an_anagrafiche INNER JOIN in_interventi ON an_anagrafiche.idanagrafica=in_interventi.idanagrafica WHERE in_interventi.id=in_interventi_tecnici.idintervento) WHERE summary IS NULL'); + $database->query('UPDATE in_interventi_tecnici SET uid = id WHERE uid IS NULL'); + + // Individuazione degli interventi + $query = 'SELECT in_interventi_tecnici.id AS idriga, in_interventi_tecnici.idintervento, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente, richiesta, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, summary FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE DATE(orario_inizio) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 3 MONTH AND deleted_at IS NULL'; + + if ($user->anagrafica->isTipo('Tecnico')) { + $query .= ' AND in_interventi_tecnici.idtecnico = '.prepare($user['idanagrafica']); + } + + $rs = $database->fetchArray($query); + + $result = ''; + + $result .= "BEGIN:VCALENDAR\n"; + $result .= 'VERSION:'.Update::getVersion()."\n"; + $result .= "PRODID:-// OpenSTAManager\n"; + + foreach ($rs as $r) { + $richiesta = str_replace("\r\n", "\n", $r['richiesta']); + $richiesta = str_replace("\r", "\n", $richiesta); + $richiesta = str_replace("\n", '\\n', $richiesta); + + $r['summary'] = str_replace("\r\n", "\n", $r['summary']); + + $result .= "BEGIN:VEVENT\n"; + $result .= 'UID:'.$r['idriga']."\n"; + $result .= 'DTSTAMP:'.date('Ymd').'T'.date('His')."\n"; + //$result .= 'ORGANIZER;CN='.$azienda.':MAILTO:'.$email."\n"; + $result .= 'DTSTART:'.date('Ymd', strtotime($r['orario_inizio'])).'T'.date('His', strtotime($r['orario_inizio']))."\n"; + $result .= 'DTEND:'.date('Ymd', strtotime($r['orario_fine'])).'T'.date('His', strtotime($r['orario_fine']))."\n"; + $result .= 'SUMMARY:'.html_entity_decode($r['summary'])."\n"; + $result .= 'DESCRIPTION:'.html_entity_decode($richiesta, ENT_QUOTES, 'UTF-8')."\n"; + $result .= "END:VEVENT\n"; + } + + $result .= "END:VCALENDAR\n"; + + return [ + 'custom' => $result, + ]; + } + + public function update($request) + { + $database = database(); + $user = auth()->getUser(); + + // Normalizzazione degli interventi a database + $database->query('UPDATE in_interventi_tecnici SET summary = (SELECT ragione_sociale FROM an_anagrafiche INNER JOIN in_interventi ON an_anagrafiche.idanagrafica=in_interventi.idanagrafica WHERE in_interventi.id=in_interventi_tecnici.idintervento) WHERE summary IS NULL'); + $database->query('UPDATE in_interventi_tecnici SET uid = id WHERE uid IS NULL'); + + // Interpretazione degli eventi + $idtecnico = $user['idanagrafica']; + + $response = API\Response::getRequest(true); + + $ical = new iCalEasyReader(); + $events = $ical->load($response); + + foreach ($events['VEVENT'] as $event) { + $description = $event['DESCRIPTION']; + + // Individuazione idriga di in_interventi_tecnici + if (str_contains($event['UID'], '-')) { + $idriga = 'NEW'; + } else { + $idriga = $event['UID']; + } + + // Timestamp di inizio + $orario_inizio = DateTime::createFromFormat('Ymd\\THi', $event['DTSTART'])->format(Intl\Formatter::getStandardFormats()['timestamp']); + + // Timestamp di fine + $orario_fine = DateTime::createFromFormat('Ymd\\THi', $event['DTEND'])->format(Intl\Formatter::getStandardFormats()['timestamp']); + + // Descrizione + $richiesta = $event['DESCRIPTION']; + $richiesta = str_replace('\\r\\n', "\n", $richiesta); + $richiesta = str_replace('\\n', "\n", $richiesta); + + $summary = trim($event['SUMMARY']); + $summary = str_replace('\\r\\n', "\n", $summary); + $summary = str_replace('\\n', "\n", $summary); + + // Nuova attività + if ($idriga == 'NEW') { + $rs_copie = $database->fetchArray('SELECT * FROM in_interventi_tecnici WHERE uid = '.prepare($event['UID'])); + + if (!empty($rs_copie)) { + $idintervento = $rs_copie[0]['idintervento']; + + $database->update('in_interventi_tecnici', [ + 'orario_inizio' => $orario_inizio, + 'orario_fine' => $orario_fine, + 'summary' => $summary, + ], [ + 'uid' => $event['UID'], + 'idtecnico' => $idtecnico, + ]); + + $database->query('UPDATE in_interventi SET richiesta='.prepare($richiesta).', oggetto='.prepare($summary).' WHERE idintervento = (SELECT idintervento FROM in_interventi_tecnici WHERE idintervento = '.prepare($idintervento).' AND idtecnico = '.prepare($idtecnico).' LIMIT 0,1)'); + + $idriga = $rs_copie[0]['id']; + } else { + $idintervento = get_new_idintervento(); + $stato = $database->fetchArray("SELECT * FROM in_statiintervento WHERE descrizione = 'Chiamata'"); + + $database->insert('in_interventi', [ + 'idintervento' => $idintervento, + 'idanagrafica' => setting('Azienda predefinita'), + 'data_richiesta' => Carbon::now(), + 'richiesta' => $richiesta, + 'idtipointervento' => 0, + 'idstatointervento' => $stato['idstatointerventoWIP'], + 'oggetto' => $summary, + ]); + + $database->insert('in_interventi', [ + 'idintervento' => $idintervento, + 'idtecnico' => $idtecnico, + 'orario_inizio' => $orario_inizio, + 'orario_fine' => $orario_fine, + 'summary' => $summary, + 'uid' => $event['UID'], + ]); + + $idriga = $database->lastInsertedID(); + } + } + + // Modifica attività esistente + else { + $database->update('in_interventi_tecnici', [ + 'orario_inizio' => $orario_inizio, + 'orario_fine' => $orario_fine, + 'summary' => $summary, + ], [ + 'id' => $idriga, + 'idtecnico' => $idtecnico, + ]); + + $query = 'UPDATE in_interventi SET richiesta='.prepare($richiesta).', oggetto='.prepare($summary).' WHERE idintervento = (SELECT idintervento FROM in_interventi_tecnici WHERE id = '.prepare($idriga).' AND idtecnico = '.prepare($idtecnico).' LIMIT 0,1)'; + $database->query($query); + } + } + } +} diff --git a/modules/stati_contratto/api/retrieve.php b/modules/stati_contratto/api/retrieve.php deleted file mode 100644 index 1790ece16..000000000 --- a/modules/stati_contratto/api/retrieve.php +++ /dev/null @@ -1,22 +0,0 @@ - 'id', - ]; - - if (empty($where['deleted_at'])) { - $where['deleted_at'] = null; - } - - break; -} - -return [ - 'stati_contratto', -]; diff --git a/modules/stati_contratto/api/v1/StatiContratti.php b/modules/stati_contratto/api/v1/StatiContratti.php new file mode 100644 index 000000000..ee2dc1f4b --- /dev/null +++ b/modules/stati_contratto/api/v1/StatiContratti.php @@ -0,0 +1,27 @@ + $select, + 'table' => $table, + ]; + } +} diff --git a/modules/stati_intervento/api/retrieve.php b/modules/stati_intervento/api/retrieve.php deleted file mode 100644 index 7ff7c4db8..000000000 --- a/modules/stati_intervento/api/retrieve.php +++ /dev/null @@ -1,22 +0,0 @@ - 'idstatointervento', - ]; - - if (empty($where['deleted_at'])) { - $where['deleted_at'] = null; - } - - break; -} - -return [ - 'stati_intervento', -]; diff --git a/modules/stati_intervento/api/v1/StatiInterventi.php b/modules/stati_intervento/api/v1/StatiInterventi.php new file mode 100644 index 000000000..247b57258 --- /dev/null +++ b/modules/stati_intervento/api/v1/StatiInterventi.php @@ -0,0 +1,28 @@ + 'idstatointervento', + ]; + + $where = $request['where']; + if (empty($where['deleted_at'])) { + $where['deleted_at'] = null; + } + + return [ + 'select' => $select, + 'table' => $table, + ]; + } +} diff --git a/modules/stati_preventivo/api/retrieve.php b/modules/stati_preventivo/api/retrieve.php deleted file mode 100644 index af31f366f..000000000 --- a/modules/stati_preventivo/api/retrieve.php +++ /dev/null @@ -1,22 +0,0 @@ - 'id', - ]; - - if (empty($where['deleted_at'])) { - $where['deleted_at'] = null; - } - - break; -} - -return [ - 'stati_preventivo', -]; diff --git a/modules/stati_preventivo/api/v1/StatiPreventivi.php b/modules/stati_preventivo/api/v1/StatiPreventivi.php new file mode 100644 index 000000000..185ee2372 --- /dev/null +++ b/modules/stati_preventivo/api/v1/StatiPreventivi.php @@ -0,0 +1,27 @@ + $select, + 'table' => $table, + ]; + } +} diff --git a/modules/stato_servizi/actions.php b/modules/stato_servizi/actions.php index 47963ff3c..efa879034 100644 --- a/modules/stato_servizi/actions.php +++ b/modules/stato_servizi/actions.php @@ -155,12 +155,13 @@ switch (filter('op')) { $dirs = [ $backup_dir => tr('Backup'), - 'files' => tr('Allegati'), - 'logs' => tr('Logs'), + DOCROOT.'/files' => tr('Allegati'), + DOCROOT.'/logs' => tr('Logs'), ]; foreach ($dirs as $dir => $description) { $size = FileSystem::folderSize($dir); + $results[] = [ 'description' => $description, 'size' => $size, diff --git a/modules/stato_servizi/api/retrieve.php b/modules/stato_servizi/api/v1/FolderSize.php similarity index 52% rename from modules/stato_servizi/api/retrieve.php rename to modules/stato_servizi/api/v1/FolderSize.php index 4be73dbd3..5ae29dd42 100644 --- a/modules/stato_servizi/api/retrieve.php +++ b/modules/stato_servizi/api/v1/FolderSize.php @@ -1,29 +1,36 @@ tr('Backup'), - 'files' => tr('Allegati'), - 'logs' => tr('Logs'), + DOCROOT.'/files' => tr('Allegati'), + DOCROOT.'/logs' => tr('Logs'), ]; } else { $array = explode(',', $dirs); foreach ($array as $key => $value) { $dirs = [ - $value => $key, + DOCROOT.'/'.$value => $key, ]; } } - $tot_byte_size = 0; + $results = []; + $total = 0; foreach ($dirs as $dir => $description) { $size = FileSystem::folderSize($dir); @@ -33,16 +40,15 @@ switch ($resource) { 'formattedSize' => FileSystem::formatBytes($size), ]; - $tot_byte_size += $size; + $total += $size; } - $results[count($dirs)]['totalbyte'] = $tot_byte_size; + $response = [ + 'dirs' => $results, + 'size' => $total, + 'formattedSize' => FileSystem::formatBytes($total), + ]; - $response = $results; - - break; + return $response; + } } - -return [ - 'folder_size', -]; diff --git a/modules/tipi_intervento/api/v1/TipiInterventi.php b/modules/tipi_intervento/api/v1/TipiInterventi.php new file mode 100644 index 000000000..69cf93f82 --- /dev/null +++ b/modules/tipi_intervento/api/v1/TipiInterventi.php @@ -0,0 +1,23 @@ + 'idtipointervento', + ]; + + return [ + 'select' => $select, + 'table' => $table, + ]; + } +} diff --git a/modules/utenti/api/create.php b/modules/utenti/api/create.php deleted file mode 100644 index 55f690ca3..000000000 --- a/modules/utenti/api/create.php +++ /dev/null @@ -1,50 +0,0 @@ -attempt($request['username'], $request['password'])) { - $user = auth()->getUser(); - $token = auth()->getToken(); - - // Informazioni da restituire tramite l'API - $response['user'] = $dbo->fetchOne('SELECT `ragione_sociale`, `codice`, `piva`, `codice_fiscale`, `indirizzo`, `citta`, `provincia`, (SELECT `nome` FROM `an_nazioni` WHERE `an_nazioni`.`id` = `an_anagrafiche`.`id_nazione`) AS nazione, `telefono`, `fax`, `cellulare`, `an_anagrafiche`.`email` FROM `zz_users` LEFT JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica` WHERE `id` = :id', [ - ':id' => $user['id'], - ]); - - $response['token'] = $token; - $response['group'] = $user['gruppo']; - $response['google_maps_token'] = setting('Google Maps API key'); - - $response['version'] = Update::getVersion(); - } else { - $response = [ - 'status' => API::getStatus()['unauthorized']['code'], - ]; - - // Se è in corso un brute-force, aggiunge il timeout - if (Auth::isBrute()) { - $response['timeout'] = Auth::getBruteTimeout(); - } - } - - break; - - // Operazione di logout - case 'logout': - if (!empty($request['token']) && !empty($user)) { - // Cancellazione della chiave - $database->query('DELETE FROM `zz_tokens` WHERE `token` = '.prepare($request['token']).' AND `id_utente` = '.prepare($user['id'])); - } else { - $response = [ - 'status' => API::getStatus()['unauthorized']['code'], - ]; - } - - break; -} - -return [ - 'login', - 'logout', -]; diff --git a/modules/utenti/api/v1/Login.php b/modules/utenti/api/v1/Login.php new file mode 100644 index 000000000..6838fe91b --- /dev/null +++ b/modules/utenti/api/v1/Login.php @@ -0,0 +1,43 @@ +attempt($request['username'], $request['password'])) { + $user = auth()->getUser(); + $token = auth()->getToken(); + + // Informazioni da restituire tramite l'API + $response['user'] = $database->fetchOne('SELECT `ragione_sociale`, `codice`, `piva`, `codice_fiscale`, `indirizzo`, `citta`, `provincia`, (SELECT `nome` FROM `an_nazioni` WHERE `an_nazioni`.`id` = `an_anagrafiche`.`id_nazione`) AS nazione, `telefono`, `fax`, `cellulare`, `an_anagrafiche`.`email` FROM `zz_users` LEFT JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica` WHERE `id` = :id', [ + ':id' => $user['id'], + ]); + + $response['token'] = $token; + $response['group'] = $user['gruppo']; + $response['google_maps_token'] = setting('Google Maps API key'); + + $response['version'] = Update::getVersion(); + } else { + $response = [ + 'status' => API\Response::getStatus()['unauthorized']['code'], + ]; + + // Se è in corso un brute-force, aggiunge il timeout + if (Auth::isBrute()) { + $response['timeout'] = Auth::getBruteTimeout(); + } + } + + return $response; + } +} diff --git a/modules/utenti/api/v1/Logout.php b/modules/utenti/api/v1/Logout.php new file mode 100644 index 000000000..5a0852e2f --- /dev/null +++ b/modules/utenti/api/v1/Logout.php @@ -0,0 +1,25 @@ +getUser(); + + if (!empty($request['token']) && !empty($user)) { + // Cancellazione della chiave + $database->query('DELETE FROM `zz_tokens` WHERE `token` = '.prepare($request['token']).' AND `id_utente` = '.prepare($user['id'])); + } else { + $response = [ + 'status' => API\Response::getStatus()['unauthorized']['code'], + ]; + } + + return $response; + } +} diff --git a/plugins/exportFE/src/Interaction.php b/plugins/exportFE/src/Interaction.php index ad1b97981..f7f251291 100644 --- a/plugins/exportFE/src/Interaction.php +++ b/plugins/exportFE/src/Interaction.php @@ -2,12 +2,14 @@ namespace Plugins\ExportFE; +use API\Services; + /** * Classe per l'interazione con API esterne. * * @since 2.4.3 */ -class Interaction extends Connection +class Interaction extends Services { public static function sendXML($id_record) { diff --git a/plugins/importFE/src/Interaction.php b/plugins/importFE/src/Interaction.php index 03b87cbe6..e95ce4a31 100644 --- a/plugins/importFE/src/Interaction.php +++ b/plugins/importFE/src/Interaction.php @@ -2,14 +2,14 @@ namespace Plugins\ImportFE; -use Plugins\ExportFE\Connection; +use API\Services; /** * Classe per l'interazione con API esterne. * * @since 2.4.3 */ -class Interaction extends Connection +class Interaction extends Services { public static function listToImport() { diff --git a/plugins/receiptFE/src/Interaction.php b/plugins/receiptFE/src/Interaction.php index fe3013db3..35d7ce576 100644 --- a/plugins/receiptFE/src/Interaction.php +++ b/plugins/receiptFE/src/Interaction.php @@ -2,14 +2,14 @@ namespace Plugins\ReceiptFE; -use Plugins\ExportFE\Connection; +use API\Services; /** * Classe per l'interazione con API esterne. * * @since 2.4.3 */ -class Interaction extends Connection +class Interaction extends Services { public static function getReceiptList() { diff --git a/src/API.php b/src/API.php deleted file mode 100644 index c8470abf6..000000000 --- a/src/API.php +++ /dev/null @@ -1,410 +0,0 @@ - [ - 'code' => 200, - 'message' => 'OK', - ], - 'internalError' => [ - 'code' => 400, - 'message' => "Errore interno dell'API", - ], - 'unauthorized' => [ - 'code' => 401, - 'message' => 'Non autorizzato', - ], - 'notFound' => [ - 'code' => 404, - 'message' => 'Non trovato', - ], - 'externalError' => [ - 'code' => 409, - 'message' => 'Errore in un servizio esterno', - ], - 'serverError' => [ - 'code' => 500, - 'message' => 'Errore del server', - ], - 'incompatible' => [ - 'code' => 503, - 'message' => 'Servizio non disponibile', - ], - ]; - - /** - * @throws InvalidArgumentException - */ - public function __construct() - { - if (!Auth::check() && self::getRequest()['resource'] != 'login') { - throw new InvalidArgumentException(); - } - } - - /** - * Gestisce le richieste di informazioni riguardanti gli elementi esistenti. - * - * @param array $request - * - * @return string - */ - public function retrieve($request) - { - $user = Auth::user(); - - // Controllo sulla compatibilità dell'API - if (!self::isCompatible()) { - return self::response([ - 'status' => self::$status['incompatible']['code'], - ]); - } - - $response = []; - - $table = ''; - $select = '*'; - $where = []; - $order = []; - $parameters = []; - - // Selezione personalizzata - $select = !empty($request['display']) ? explode(',', substr($request['display'], 1, -1)) : $select; - - // Ricerca personalizzata - $values = isset($request['filter']) ? (array) $request['filter'] : []; - foreach ($values as $key => $value) { - // Rimozione delle parentesi - $value = substr($value, 1, -1); - - // Individuazione della tipologia (array o string) - $where[$key] = str_contains($value, ',') ? explode(',', $value) : $value; - } - - // Ordinamento personalizzato - $values = isset($request['order']) ? (array) $request['order'] : []; - foreach ($values as $value) { - $pieces = explode('|', $value); - $order[] = empty($pieces[1]) ? $pieces[0] : [$pieces[0] => $pieces[1]]; - } - - // Paginazione automatica dell'API - $page = isset($request['page']) ? (int) $request['page'] : 0; - $length = setting('Lunghezza pagine per API'); - - $dbo = $database = database(); - - $kind = 'retrieve'; - $resources = self::getResources()[$kind]; - $resource = $request['resource']; - - try { - if (in_array($resource, array_keys($resources))) { - // Esecuzione delle operazioni personalizzate - $filename = DOCROOT.'/modules/'.$resources[$resource].'/api/'.$kind.'.php'; - include $filename; - } elseif ( - !in_array($resource, explode(',', setting('Tabelle escluse per la sincronizzazione API automatica'))) - && $database->tableExists($resource) - ) { - $table = $resource; - - // Individuazione della colonna AUTO_INCREMENT per l'ordinamento automatico - if (empty($order)) { - $column = $database->fetchArray('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '.prepare($table)." AND EXTRA LIKE '%AUTO_INCREMENT%' AND TABLE_SCHEMA = ".prepare($database->getDatabaseName())); - - if (!empty($column)) { - $order[] = $column[0]['COLUMN_NAME']; - } - } - } else { - return self::error('notFound'); - } - - // Generazione automatica delle query - if (!empty($table)) { - // Date di interesse - if (!empty($request['upd'])) { - $where['#updated_at'] = 'updated_at >= '.prepare($request['upd']); - } - if (!empty($request['crd'])) { - $where['#created_at'] = 'created_at >= '.prepare($request['crd']); - } - - // Query per ottenere le informazioni - $query = $database->select($table, $select, $where, $order, [], true); - - foreach ($where as $key => $value) { - $parameters[] = $value; - } - } - - if (!empty($query)) { - $response['records'] = $database->fetchArray($query.' LIMIT '.($page * $length).', '.$length, $parameters); - $count = $database->fetchNum($query, $parameters); - - $response['total-count'] = $count; - $response['pages'] = ceil($count / $length); - } - } catch (PDOException $e) { - // Log dell'errore - $logger = logger(); - $logger->addRecord(\Monolog\Logger::ERROR, $e); - - return self::error('internalError'); - } - - return self::response($response); - } - - /** - * Gestisce le richieste di creazione nuovi elementi. - * - * @param array $request - * - * @return string - */ - public function create($request) - { - return $this->fileRequest($request, 'create'); - } - - /** - * Gestisce le richieste di aggiornamento di elementi esistenti. - * - * @param array $request - * - * @return string - */ - public function update($request) - { - return $this->fileRequest($request, 'update'); - } - - /** - * Gestisce le richieste di eliminazione di elementi esistenti. - * - * @param array $request - * - * @return string - */ - public function delete($request) - { - return $this->fileRequest($request, 'delete'); - } - - /** - * Genera i contenuti di risposta nel caso si verifichi un errore. - * - * @param string|int $error - * - * @return string - */ - public static function error($error) - { - $keys = array_keys(self::$status); - $error = (in_array($error, $keys)) ? $error : 'serverError'; - - $code = self::$status[$error]['code']; - - http_response_code($code); - - return self::response([ - 'status' => $code, - ]); - } - - /** - * Restituisce l'elenco delle risorse disponibili per l'API, suddivise per categoria. - * - * @return array - */ - public static function getResources() - { - if (!is_array(self::$resources)) { - $resources = []; - - $operations = AJAX::find('api/{retrieve,create,update,delete}.php', false); - - foreach ($operations as $operation) { - // Individua la tipologia e il modulo delle operazioni - $path = explode('/api/', $operation)[0]; - $module = explode('modules/', $path)[1]; - $kind = basename($operation, '.php'); - - $resources[$kind] = isset($resources[$kind]) ? (array) $resources[$kind] : []; - - // Individuazione delle operazioni - $api = include $operation; - $api = is_array($api) ? array_unique($api) : []; - - $keys = array_keys($resources[$kind]); - - // Registrazione delle operazioni individuate - $results = []; - foreach ($api as $value) { - $value .= in_array($value, $keys) ? $module : ''; - $results[$value] = $module; - } - - // Salvataggio delle operazioni - $resources[$kind] = array_merge($resources[$kind], $results); - } - - self::$resources = $resources; - } - - return self::$resources; - } - - /** - * Formatta i contenuti della risposta secondo il formato JSON. - * - * @param array $array - * - * @return string - */ - public static function response($array) - { - if (empty($array['custom'])) { - // Aggiunta dello status di default - if (empty($array['status'])) { - $array['status'] = self::$status['ok']['code']; - } - - // Aggiunta del messaggio in base allo status - 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; - // Beautify forzato dei risultati - if (get('beautify') !== null) { - $flags |= JSON_PRETTY_PRINT; - } - - $result = json_encode($array, $flags); - } else { - $result = $array['custom']; - } - - return $result; - } - - /** - * Restituisce l'elenco degli stati dell'API. - * - * @return array - */ - public static function getStatus() - { - return self::$status; - } - - /** - * Controlla se la richiesta effettuata è rivolta all'API. - * - * @return bool - */ - public static function isAPIRequest() - { - return getURLPath() == slashes(ROOTDIR.'/api/index.php'); - } - - /** - * Restituisce i parametri specificati dalla richiesta. - * - * @param bool $raw - * - * @return array - */ - public static function getRequest($raw = false) - { - $request = []; - - if (self::isAPIRequest()) { - $request = file_get_contents('php://input'); - - if (empty($raw)) { - $request = (array) json_decode($request, true); - $request = Filter::sanitize($request); - - // Fallback per input standard vuoto (richiesta da browser o upload file) - if (empty($request)) { // $_SERVER['REQUEST_METHOD'] == 'GET' - $request = Filter::getGET(); - } - - if (empty($request['token'])) { - $request['token'] = ''; - } - } - } - - return $request; - } - - /** - * Controlla se il database è compatibile con l'API. - * - * @return bool - */ - public static function isCompatible() - { - $database = database(); - - return version_compare($database->getMySQLVersion(), '5.6.5') >= 0; - } - - /** - * Gestisce le richieste in modo generalizzato, con il relativo richiamo ai file specifici responsabili dell'operazione. - * - * @param array $request - * - * @return string - */ - protected function fileRequest($request, $kind) - { - $user = Auth::user(); - $response = []; - - // Controllo sulla compatibilità dell'API - if (!self::isCompatible()) { - return self::response([ - 'status' => self::$status['incompatible']['code'], - ]); - } - - $resources = self::getResources()[$kind]; - $resource = $request['resource']; - - if (!in_array($resource, array_keys($resources))) { - return self::error('notFound'); - } - - // Database - $dbo = $database = database(); - - $database->beginTransaction(); - - // Esecuzione delle operazioni - $filename = DOCROOT.'/modules/'.$resources[$resource].'/api/'.$kind.'.php'; - include $filename; - - $database->commitTransaction(); - - return self::response($response); - } -} diff --git a/modules/aggiornamenti/api/create.php b/src/API/Common/Allegato.php similarity index 51% rename from modules/aggiornamenti/api/create.php rename to src/API/Common/Allegato.php index 2f967a0df..44df0f3ad 100644 --- a/modules/aggiornamenti/api/create.php +++ b/src/API/Common/Allegato.php @@ -1,7 +1,15 @@ $request['id'], ]); - $response['filename'] = $upload; - - break; + return[ + 'filename' => $upload, + ]; + } } - -return [ - 'allegato', -]; diff --git a/src/API/Exceptions/InternalError.php b/src/API/Exceptions/InternalError.php new file mode 100644 index 000000000..f852fd388 --- /dev/null +++ b/src/API/Exceptions/InternalError.php @@ -0,0 +1,9 @@ +where('type', $type) + ->where('resource', $resource) + ->first(); + + $this->resource = $resource; + $this->type = $type; + } + + public function manage($request) + { + $type = $this->type; + + $database = database(); + $database->beginTransaction(); + + $response = $this->{$type}($request); + + $database->commitTransaction(); + + return $response; + } + + /** + * Gestisce le richieste di informazioni riguardanti gli elementi esistenti. + * + * @param array $request + * + * @return string + */ + public function retrieve($request) + { + $user = Auth::user(); + + $select = '*'; + $where = []; + $order = []; + + // Selezione personalizzata + $select = !empty($request['display']) ? explode(',', substr($request['display'], 1, -1)) : $select; + + // Ricerca personalizzata + $values = isset($request['filter']) ? (array) $request['filter'] : []; + foreach ($values as $key => $value) { + // Rimozione delle parentesi + $value = substr($value, 1, -1); + + // Individuazione della tipologia (array o string) + $where[$key] = str_contains($value, ',') ? explode(',', $value) : $value; + } + + // Ordinamento personalizzato + $values = isset($request['order']) ? (array) $request['order'] : []; + foreach ($values as $value) { + $pieces = explode('|', $value); + $order[] = empty($pieces[1]) ? $pieces[0] : [$pieces[0] => $pieces[1]]; + } + + // Paginazione automatica dell'API + $page = isset($request['page']) ? (int) $request['page'] : 0; + $length = setting('Lunghezza pagine per API'); + + $data = array_merge($request, [ + 'user' => $user, + 'select' => $select, + 'where' => $where, + 'order' => $order, + 'page' => $page, + 'length' => $length, + ]); + + $response = $this->getResponse($data); + $parameters = $response['parameters']; + $table = $response['table']; + $query = $response['query']; + + try { + $database = database(); + + // Generazione automatica delle query + if (!empty($table)) { + // Date di interesse + if (!empty($request['upd'])) { + $where['#updated_at'] = 'updated_at >= '.prepare($request['upd']); + } + if (!empty($request['crd'])) { + $where['#created_at'] = 'created_at >= '.prepare($request['crd']); + } + + // Query per ottenere le informazioni + $query = $database->select($table, $select, $where, $order, [], true); + + foreach ($where as $key => $value) { + $parameters[] = $value; + } + } + + if (!empty($query)) { + $response = []; + + $response['records'] = $database->fetchArray($query.' LIMIT '.($page * $length).', '.$length, $parameters); + $count = $database->fetchNum($query, $parameters); + + $response['total-count'] = $count; + $response['pages'] = intval(ceil($count / $length)); + } + } catch (PDOException $e) { + // Log dell'errore + $logger = logger(); + $logger->addRecord(\Monolog\Logger::ERROR, $e); + + throw new InternalError(); + } + + return $response; + } + + /** + * Gestisce le richieste di creazione nuovi elementi. + * + * @param array $request + * + * @return string + */ + public function create($request) + { + return $this->getResponse($request); + } + + /** + * Gestisce le richieste di aggiornamento di elementi esistenti. + * + * @param array $request + * + * @return string + */ + public function update($request) + { + return $this->getResponse($request); + } + + /** + * Gestisce le richieste di eliminazione di elementi esistenti. + * + * @param array $request + * + * @return string + */ + public function delete($request) + { + return $this->getResponse($request); + } + + public function getResponse($request) + { + $class = $this->resource->class; + + if (!class_exists($class)) { + throw new ResourceNotFound(); + } + + $object = new $class(); + $method = $this->type; + + $response = $object->{$method}($request); + + return $response; + } +} diff --git a/src/API/Response.php b/src/API/Response.php new file mode 100644 index 000000000..19f1e8c64 --- /dev/null +++ b/src/API/Response.php @@ -0,0 +1,247 @@ + [ + 'code' => 200, + 'message' => 'OK', + ], + 'internalError' => [ + 'code' => 400, + 'message' => "Errore interno dell'API", + ], + 'unauthorized' => [ + 'code' => 401, + 'message' => 'Non autorizzato', + ], + 'notFound' => [ + 'code' => 404, + 'message' => 'Non trovato', + ], + 'externalError' => [ + 'code' => 409, + 'message' => 'Errore in un servizio esterno', + ], + 'serverError' => [ + 'code' => 500, + 'message' => 'Errore del server', + ], + 'incompatible' => [ + 'code' => 503, + 'message' => 'Servizio non disponibile', + ], + ]; + + public static function manage() + { + // Gestione della richiesta + $method = $_SERVER['REQUEST_METHOD']; + $type = null; + switch ($method) { + // Richiesta PUT (modifica elementi) + case 'PUT': + $type = 'update'; + break; + + // Richiesta POST (creazione elementi) + case 'POST': + $type = 'create'; + break; + + // Richiesta GET (ottenimento elementi) + case 'GET': + $type = 'retrieve'; + break; + + // Richiesta DELETE (eliminazione elementi) + case 'DELETE': + $type = 'delete'; + break; + } + + $request = self::getRequest(); + $version = $request['version'] ?: 'v1'; + + // Controllo sull'accesso + if (!Auth::check() && $request['resource'] != 'login') { + return self::response([ + 'status' => self::$status['unauthorized']['code'], + ]); + } + + // Controllo sulla compatibilità dell'API + if (!self::isCompatible()) { + return self::response([ + 'status' => self::$status['incompatible']['code'], + ]); + } + + try { + $manager = new Manager($request['resource'], $type, $version); + + if ($type == 'retrieve' && empty($request['resource'])) { + $resources = self::getResources($type, $version)->toArray(); + $list = array_column($resources, 'resource') ?: []; + + return self::response([ + 'resources' => $list, + ]); + } + + $response = $manager->manage($request); + } catch (ResourceNotFound $e) { + return self::error('notFound'); + } catch (InternalError $e) { + return self::error('internalError'); + } catch (ServiceError $e) { + return self::error('externalError'); + } + + return self::response($response); + } + + /** + * Genera i contenuti di risposta nel caso si verifichi un errore. + * + * @param string|int $error + * + * @return string + */ + public static function error($error) + { + $keys = array_keys(self::$status); + $error = (in_array($error, $keys)) ? $error : 'serverError'; + + $code = self::$status[$error]['code']; + + http_response_code($code); + + return self::response([ + 'status' => $code, + ]); + } + + /** + * Formatta i contenuti della risposta secondo il formato JSON. + * + * @param array $array + * + * @return string + */ + public static function response($array) + { + if (empty($array['custom'])) { + // Aggiunta dello status di default + if (empty($array['status'])) { + $array['status'] = self::$status['ok']['code']; + } + + // Aggiunta del messaggio in base allo status + 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; + // Beautify forzato dei risultati + if (get('beautify') !== null) { + $flags |= JSON_PRETTY_PRINT; + } + + $result = json_encode($array, $flags); + } else { + $result = $array['custom']; + } + + return $result; + } + + /** + * Restituisce l'elenco degli stati dell'API. + * + * @return array + */ + public static function getStatus() + { + return self::$status; + } + + /** + * Controlla se la richiesta effettuata è rivolta all'API. + * + * @return bool + */ + public static function isAPIRequest() + { + return getURLPath() == slashes(ROOTDIR.'/api/index.php'); + } + + /** + * Restituisce i parametri specificati dalla richiesta. + * + * @param bool $raw + * + * @return array + */ + public function getRequest($raw = false) + { + $request = []; + + if (self::isAPIRequest()) { + $request = file_get_contents('php://input'); + + if (empty($raw)) { + $request = (array) json_decode($request, true); + $request = Filter::sanitize($request); + + // Fallback per input standard vuoto (richiesta da browser o upload file) + if (empty($request)) { // $_SERVER['REQUEST_METHOD'] == 'GET' + $request = Filter::getGET(); + } + + if (empty($request['token'])) { + $request['token'] = ''; + } + } + } + + return $request; + } + + /** + * Controlla se il database è compatibile con l'API. + * + * @return bool + */ + public static function isCompatible() + { + $database = database(); + + return version_compare($database->getMySQLVersion(), '5.6.5') >= 0; + } + + protected static function getResources($type, $version) + { + $resources = Resource::where('version', $version)->where('type', $type)->get(); + + return $resources; + } +} diff --git a/plugins/exportFE/src/Connection.php b/src/API/Services.php similarity index 96% rename from plugins/exportFE/src/Connection.php rename to src/API/Services.php index 76386146c..726f4ea3a 100644 --- a/plugins/exportFE/src/Connection.php +++ b/src/API/Services.php @@ -1,6 +1,6 @@ isInstalled()) { // Controllo dell'accesso da API - if (API::isAPIRequest()) { - $token = API::getRequest()['token']; + if (API\Response::isAPIRequest()) { + $token = API\Response::getRequest()['token']; $user = $database->fetchArray('SELECT `id_utente` FROM `zz_tokens` WHERE `enabled` = 1 AND `token` = :token', [ ':token' => $token, @@ -232,7 +232,7 @@ class Auth extends \Util\Singleton session_unset(); session_regenerate_id(); - if (!API::isAPIRequest()) { + if (!API\Response::isAPIRequest()) { flash()->clearMessages(); } } diff --git a/src/Models/ApiResource.php b/src/Models/ApiResource.php new file mode 100644 index 000000000..9e1df3389 --- /dev/null +++ b/src/Models/ApiResource.php @@ -0,0 +1,12 @@ +hasMany(Log::class, 'id_utente'); } + public function anagrafica() + { + return $this->belongsTo(Anagrafica::class, 'idanagrafica'); + } + + public function image() + { + return $this->belongsTo(Upload::class, 'image_file_id'); + } + public function modules() { return $this->group->modules(); diff --git a/update/2_4_11.php b/update/2_4_11.php new file mode 100644 index 000000000..f4d6f1f08 --- /dev/null +++ b/update/2_4_11.php @@ -0,0 +1,29 @@ + $value) { + $files[$key] = realpath(DOCROOT.'/'.$value); +} + +delete($files); diff --git a/update/2_4_11.sql b/update/2_4_11.sql index 5ee38a654..a779d4c36 100644 --- a/update/2_4_11.sql +++ b/update/2_4_11.sql @@ -70,3 +70,45 @@ UPDATE `co_righe_documenti` INNER JOIN `co_righe_preventivi` ON `co_righe_docume -- Aggiunta foto utente ALTER TABLE `zz_users` ADD `image_file_id` int(11); UPDATE `zz_modules` SET `enabled` = 1 WHERE `name` = 'Utenti e permessi'; + +-- Aggiornamento sistema API +CREATE TABLE IF NOT EXISTS `zz_api_resources` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `version` varchar(15) NOT NULL, + `type` ENUM('create', 'retrieve', 'update', 'delete'), + `resource` varchar(255) NOT NULL, + `class` varchar(255) NOT NULL, + `enabled` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +DELETE FROM `zz_settings` WHERE `nome` = 'Tabelle escluse per la sincronizzazione API automatica'; + +INSERT INTO `zz_api_resources` (`id`, `version`, `type`, `resource`, `class`, `enabled`) VALUES +(NULL, 'v1', 'create', 'allegato', 'Api\\Common\\Allegato', '1'), +(NULL, 'v1', 'retrieve', 'anagrafiche', 'Modules\\Anagrafiche\\API\\v1\\Anagrafiche', '1'), +(NULL, 'v1', 'create', 'anagrafica', 'Modules\\Anagrafiche\\API\\v1\\Anagrafiche', '1'), +(NULL, 'v1', 'update', 'anagrafica', 'Modules\\Anagrafiche\\API\\v1\\Anagrafiche', '1'), +(NULL, 'v1', 'delete', 'anagrafica', 'Modules\\Anagrafiche\\API\\v1\\Anagrafiche', '1'), +(NULL, 'v1', 'create', 'movimento_articolo', 'Modules\\Articoli\\API\\v1\\Movimenti', '1'), +(NULL, 'v1', 'retrieve', 'articoli', 'Modules\\Articoli\\API\\v1\\Articoli', '1'), +(NULL, 'v1', 'create', 'login', 'Modules\\Utenti\\API\\v1\\Login', '1'), +(NULL, 'v1', 'create', 'logout', 'Modules\\Utenti\\API\\v1\\Logout', '1'), +(NULL, 'v1', 'retrieve', 'folder_size', 'Modules\\StatoServizi\\API\\v1\\FolderSize', '1'), +(NULL, 'v1', 'retrieve', 'tipi_intervento', 'Modules\\TipiIntervento\\API\\v1\\TipiInterventi', '1'), +(NULL, 'v1', 'retrieve', 'stati_intervento', 'Modules\\StatiIntervento\\API\\v1\\StatiInterventi', '1'), +(NULL, 'v1', 'retrieve', 'stati_preventivo', 'Modules\\StatiPreventivo\\API\\v1\\StatiPreventivi', '1'), +(NULL, 'v1', 'retrieve', 'stati_contratto', 'Modules\\StatiContratto\\API\\v1\\StatiContratti', '1'), +(NULL, 'v1', 'retrieve', 'tipi_intervento', 'Modules\\Interventi\\API\\v1\\Interventi', '1'), +(NULL, 'v1', 'retrieve', 'interventi', 'Modules\\Interventi\\API\\v1\\Interventi', '1'), +(NULL, 'v1', 'create', 'intervento', 'Modules\\Interventi\\API\\v1\\Interventi', '1'), +(NULL, 'v1', 'update', 'intervento', 'Modules\\Interventi\\API\\v1\\Interventi', '1'), +(NULL, 'v1', 'update', 'firma_intervento', 'Modules\\Interventi\\API\\v1\\Firma', '1'), +(NULL, 'v1', 'retrieve', 'sync', 'Modules\\Interventi\\API\\v1\\Sync', '1'), +(NULL, 'v1', 'update', 'sync', 'Modules\\Interventi\\API\\v1\\Sync', '1'), +(NULL, 'v1', 'retrieve', 'sessioni_intervento', 'Modules\\Interventi\\API\\v1\\Sessioni', '1'), +(NULL, 'v1', 'create', 'sessione_intervento', 'Modules\\Interventi\\API\\v1\\Sessioni', '1'), +(NULL, 'v1', 'update', 'sessione_intervento', 'Modules\\Interventi\\API\\v1\\Sessioni', '1'), +(NULL, 'v1', 'retrieve', 'articoli_intervento', 'Modules\\Interventi\\API\\v1\\Articoli', '1'), +(NULL, 'v1', 'create', 'articolo_intervento', 'Modules\\Interventi\\API\\v1\\Articoli', '1'); + diff --git a/update/api.php b/update/api.php index 0779a5ea6..ee08e6e6c 100644 --- a/update/api.php +++ b/update/api.php @@ -16,7 +16,7 @@ foreach ($tables as $table) { $database->query('ALTER TABLE `'.$table.'` ADD `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP'); } - if (API::isCompatible()) { + if (API\Response::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'); diff --git a/update/tables.php b/update/tables.php index 15d6d49b3..78d403cc7 100644 --- a/update/tables.php +++ b/update/tables.php @@ -78,6 +78,7 @@ return [ 'or_righe_ordini', 'or_statiordine', 'or_tipiordine', + 'zz_api_resources', 'zz_currencies', 'zz_documenti', 'zz_documenti_categorie',