Miglioramento della documentazione del codice

Miglioramento della documentazione del codice nelle classi dedicata alla generazione dell'input HTML.
Aggiunto supporto agli array in formato JSON nel campo "values" dei select.
Aggiunto redirect automatico nel file _controller.php_: se specificati $id_record e $id_module indirizza al file _editor.php_.
This commit is contained in:
Thomas Zilio 2018-01-12 16:23:26 +01:00
parent f8132abfc1
commit 965d467d7d
13 changed files with 335 additions and 103 deletions

View File

@ -21,7 +21,7 @@ session_write_close();
// Permesso di accesso all'API da ogni dispositivo // Permesso di accesso all'API da ogni dispositivo
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
// Attenzione: al momento l'API permette la lettura di tutte le tabelle rpesenti nel database (non limitate a quelle del progetto). // Attenzione: al momento l'API permette la lettura di tutte le tabelle presenti nel database (non limitate a quelle del progetto)
try { try {
// Controlli sulla chiave di accesso // Controlli sulla chiave di accesso
@ -30,21 +30,33 @@ try {
// Lettura delle informazioni // Lettura delle informazioni
$request = API::getRequest(); $request = API::getRequest();
// Gestione della richiesta
$method = $_SERVER['REQUEST_METHOD']; $method = $_SERVER['REQUEST_METHOD'];
switch ($method) { switch ($method) {
// Richiesta PUT (modifica elementi)
case 'PUT': case 'PUT':
$result = $api->update($request); $result = $api->update($request);
break; break;
// Richiesta POST (creazione elementi)
case 'POST': case 'POST':
$result = $api->create($request); $result = $api->create($request);
break; break;
// Richiesta GET (ottenimento elementi)
case 'GET': case 'GET':
// Risorsa specificata
if (!empty($request)) { if (!empty($request)) {
$result = $api->retrieve($request); $result = $api->retrieve($request);
} else { }
// Risorsa non specificata (lista delle risorse disponibili)
else {
$result = API::response(API::getResources()['retrieve']); $result = API::response(API::getResources()['retrieve']);
} }
break; break;
// Richiesta DELETE (eliminazione elementi)
case 'DELETE': case 'DELETE':
$result = $api->delete($request); $result = $api->delete($request);
break; break;
@ -55,4 +67,5 @@ try {
$result = API::error('serverError'); $result = API::error('serverError');
} }
// Stampa dei risultati
echo $result; echo $result;

View File

@ -2,6 +2,12 @@
include_once __DIR__.'/core.php'; include_once __DIR__.'/core.php';
if (!empty($id_record) && !empty($id_module)) {
redirect(ROOTDIR.'/editor.php?id_module='.$id_module.'&id_record='.$id_record);
} elseif (empty($id_module)) {
redirect(ROOTDIR.'/index.php');
}
if (file_exists($docroot.'/include/custom/top.php')) { if (file_exists($docroot.'/include/custom/top.php')) {
include $docroot.'/include/custom/top.php'; include $docroot.'/include/custom/top.php';
} else { } else {
@ -87,7 +93,7 @@ echo '
redirectOperation($id_module, $id_record); redirectOperation($id_module, $id_record);
/** /*
* Widget laterali. * Widget laterali.
*/ */
// Controllo se ho widget per il lato destro dello schermo, altrimenti non creo la colonna di destra // Controllo se ho widget per il lato destro dello schermo, altrimenti non creo la colonna di destra
@ -96,11 +102,10 @@ redirectOperation($id_module, $id_record);
if (isMobile()) { if (isMobile()) {
$extra_where = " OR location = 'controller_top'"; $extra_where = " OR location = 'controller_top'";
} else { } else {
$extra_where = ""; $extra_where = '';
} }
$result_widgets = $dbo->fetchArray('SELECT `id`, `location`, `class` FROM `zz_widgets` WHERE `id_module`='.prepare($id_module)." AND (`location`='controller_right' ".$extra_where.' ) AND `enabled`=1 ORDER BY `order` ASC');
$result_widgets = $dbo->fetchArray('SELECT `id`, `location`, `class` FROM `zz_widgets` WHERE `id_module`='.prepare($id_module)." AND (`location`='controller_right' ".$extra_where." ) AND `enabled`=1 ORDER BY `order` ASC");
if (count($result_widgets) > 0) { if (count($result_widgets) > 0) {
echo ' echo '
<div class="col-md-12">'; <div class="col-md-12">';

View File

@ -50,7 +50,7 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
<div class="row"> <div class="row">
<div class="col-md-2"> <div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Quantità'); ?>", "name": "qta", "required": 1, "value": "$qta$", "readonly": 1, "decimals": "qta|undefined" ]} {[ "type": "number", "label": "<?php echo tr('Quantità'); ?>", "name": "qta", "required": 1, "value": "$qta$", "readonly": 1, "decimals": "qta", "min-value": "undefined" ]}
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
{[ "type": "checkbox", "label": "<?php echo tr('Modifica manualmente quantità'); ?>", "name": "qta_manuale", "value": 0, "help": "<?php echo tr('Seleziona per modificare manualmente la quantità'); ?>", "placeholder": "<?php echo tr('Quantità manuale'); ?>" ]} {[ "type": "checkbox", "label": "<?php echo tr('Modifica manualmente quantità'); ?>", "name": "qta_manuale", "value": 0, "help": "<?php echo tr('Seleziona per modificare manualmente la quantità'); ?>", "placeholder": "<?php echo tr('Quantità manuale'); ?>" ]}
@ -70,7 +70,7 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "value": "$threshold_qta$", "decimals": "qta|undefined" ]} {[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "value": "$threshold_qta$", "decimals": "qta", "min-value": "undefined" ]}
</div> </div>
<?php <?php
@ -298,13 +298,12 @@ $elementi = $dbo->fetchArray('SELECT `co_documenti`.`id`, `co_documenti`.`data`,
SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione` AS tipo_documento, `dt_tipiddt`.`dir` FROM `dt_ddt` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` WHERE `dt_ddt`.`id` IN (SELECT `idddt` FROM `dt_righe_ddt` WHERE `idarticolo` = '.prepare($id_record).') UNION SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione` AS tipo_documento, `dt_tipiddt`.`dir` FROM `dt_ddt` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` WHERE `dt_ddt`.`id` IN (SELECT `idddt` FROM `dt_righe_ddt` WHERE `idarticolo` = '.prepare($id_record).') UNION
SELECT `co_preventivi`.`id`, `co_preventivi`.`data_bozza`, `co_preventivi`.`numero`, 0 AS numero_esterno , "Preventivo" AS tipo_documento, 0 AS dir FROM `co_preventivi` WHERE `co_preventivi`.`id` IN (SELECT `idpreventivo` FROM `co_righe_preventivi` WHERE `idarticolo` = '.prepare($id_record).') ORDER BY `data`'); SELECT `co_preventivi`.`id`, `co_preventivi`.`data_bozza`, `co_preventivi`.`numero`, 0 AS numero_esterno , "Preventivo" AS tipo_documento, 0 AS dir FROM `co_preventivi` WHERE `co_preventivi`.`id` IN (SELECT `idpreventivo` FROM `co_righe_preventivi` WHERE `idarticolo` = '.prepare($id_record).') ORDER BY `data`');
if (!empty($elementi)) { if (!empty($elementi)) {
echo ' echo '
<div class="alert alert-warning"> <div class="alert alert-warning">
<p>'.tr('_NUM_ altr_I_ document_I_ collegat_I_', [ <p>'.tr('_NUM_ altr_I_ document_I_ collegat_I_', [
'_NUM_' => count($elementi), '_NUM_' => count($elementi),
'_I_' => (count($elementi)>1) ? tr('i') : tr('o') '_I_' => (count($elementi) > 1) ? tr('i') : tr('o'),
]).':</p> ]).':</p>
<ul>'; <ul>';

View File

@ -41,7 +41,7 @@ foreach ($rs as $key => $value) {
echo ' echo '
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{[ "type": "select", "label": "'.tr('Intervento').'", "name": "idintervento", "required": 1, "values": "json='.substr(str_replace('"', '\"', json_encode($rs)), 2, -2).'", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.descrizione); $(\'#prezzo\').val($data.prezzo);\"" ]} {[ "type": "select", "label": "'.tr('Intervento').'", "name": "idintervento", "required": 1, "values": '.json_encode($rs).', "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.descrizione); $(\'#prezzo\').val($data.prezzo);\"" ]}
</div> </div>
</div>'; </div>';

View File

@ -144,7 +144,7 @@ if (!empty($rs)) {
// Q.tà da evadere // Q.tà da evadere
echo ' echo '
<td> <td>
{[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "extra" : "onkeyup=\"ricalcola_subtotale_riga('.$i.');\"", "decimals": "qta|0" ]} {[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "extra" : "onkeyup=\"ricalcola_subtotale_riga('.$i.');\"", "decimals": "qta", "min-value": "0" ]}
</td>'; </td>';
// Subtotale // Subtotale

View File

@ -88,6 +88,7 @@ class HTMLBuilder
*/ */
public static function replace($html) public static function replace($html)
{ {
// Gestione dei manager generici
preg_match_all('/'.preg_quote(self::$open['manager']).'(.+?)'.preg_quote(self::$close['manager']).'/is', $html, $managers); preg_match_all('/'.preg_quote(self::$open['manager']).'(.+?)'.preg_quote(self::$close['manager']).'/is', $html, $managers);
foreach ($managers[0] as $value) { foreach ($managers[0] as $value) {
@ -99,6 +100,7 @@ class HTMLBuilder
$html = str_replace($value, !empty($result) ? $result : $value, $html); $html = str_replace($value, !empty($result) ? $result : $value, $html);
} }
// Gestione del formato di input HTML semplificato
preg_match_all('/'.preg_quote(self::$open['handler']).'(.+?)'.preg_quote(self::$close['handler']).'/is', $html, $handlers); preg_match_all('/'.preg_quote(self::$open['handler']).'(.+?)'.preg_quote(self::$close['handler']).'/is', $html, $handlers);
foreach ($handlers[0] as $value) { foreach ($handlers[0] as $value) {
@ -155,10 +157,10 @@ class HTMLBuilder
{ {
$string = '{'.substr($string, strlen(self::$open[$type]), -strlen(self::$close[$type])).'}'; $string = '{'.substr($string, strlen(self::$open[$type]), -strlen(self::$close[$type])).'}';
// Fix per contenuti con newline integrate // Fix per contenuti con newline integrati
$string = str_replace(["\n", "\r"], ['\\n', '\\r'], $string); $string = str_replace(["\n", "\r"], ['\\n', '\\r'], $string);
$json = (array) json_decode($string, true, 2); $json = (array) json_decode($string, true);
return $json; return $json;
} }
@ -212,7 +214,7 @@ class HTMLBuilder
// Attributi normali // Attributi normali
foreach ($json as $key => $value) { foreach ($json as $key => $value) {
$values[trim($key)] = trim($value); $values[trim($key)] = is_string($value) ? trim($value) : $value;
} }
// Valori particolari // Valori particolari

View File

@ -3,33 +3,50 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Gestione dell'input di tipo "checkbox".
*
* @since 2.3 * @since 2.3
*/ */
class ChoicesHandler implements HandlerInterface class ChoicesHandler implements HandlerInterface
{ {
public function handle(&$values, &$extras) public function handle(&$values, &$extras)
{ {
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras); $result = $this->{$values['type']}($values, $extras);
return $result; return $result;
} }
/**
* Gestione dell'input di tipo "checkbox".
* Esempio: {[ "type": "checkbox", "label": "Checkbox di test", "placeholder": "Test", "name": "checkbox", "value": "1" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function checkbox(&$values, &$extras) protected function checkbox(&$values, &$extras)
{ {
unset($values['class'][0]); unset($values['class'][0]);
// Restrizione dei valori permessi
$values['value'] = (empty($values['value']) || $values['value'] == 'off') ? false : true; $values['value'] = (empty($values['value']) || $values['value'] == 'off') ? false : true;
// Gestione della proprietà "checked"
if (!empty($values['value']) && !in_array('checked', $extras)) { if (!empty($values['value']) && !in_array('checked', $extras)) {
$extras[] = 'checked'; $extras[] = 'checked';
} }
// Gestione della proprietà "readonly"
if (in_array('readonly', $extras)) { if (in_array('readonly', $extras)) {
$extras[] = 'disabled'; $extras[] = 'disabled';
} }
$values['placeholder'] = (isset($values['placeholder'])) ? $values['placeholder'] : $values['label']; // Gestione dei placeholder
$values['placeholder'] = isset($values['placeholder']) ? $values['placeholder'] : $values['label'];
// Generazione del codice HTML
$result .= ' $result .= '
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"> <span class="input-group-addon">

View File

@ -3,6 +3,8 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Gestione dell'input di tipo "timestamp", "date" e "time".
*
* @since 2.3 * @since 2.3
*/ */
class DateHandler implements HandlerInterface class DateHandler implements HandlerInterface
@ -10,26 +12,34 @@ class DateHandler implements HandlerInterface
public function handle(&$values, &$extras) public function handle(&$values, &$extras)
{ {
// Impostazione alla data corrente se il contenuto corrisponde a "now" // Impostazione alla data corrente se il contenuto corrisponde a "now"
if ($values['value'] == '-now-') { $detect = [
$values['value'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']); 'value',
} 'max-date',
'min-date',
if ($values['max-date'] == '-now-') { ];
$values['max-date'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']); foreach ($detect as $attr) {
} if ($values[$attr] == '-now-') {
$values[$attr] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
if ($values['min-date'] == '-now-') { }
$values['min-date'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
} }
// Restrizione dei valori permessi
// Timestamp
if ($values['type'] == 'timestamp' && \Translator::getFormatter()->isStandardTimestamp($values['value'])) { if ($values['type'] == 'timestamp' && \Translator::getFormatter()->isStandardTimestamp($values['value'])) {
$values['value'] = \Translator::timestampToLocale($values['value']); $values['value'] = \Translator::timestampToLocale($values['value']);
} elseif ($values['type'] == 'date' && \Translator::getFormatter()->isStandardDate($values['value'])) { }
// Data
elseif ($values['type'] == 'date' && \Translator::getFormatter()->isStandardDate($values['value'])) {
$values['value'] = \Translator::dateToLocale($values['value']); $values['value'] = \Translator::dateToLocale($values['value']);
} elseif ($values['type'] == 'time' && \Translator::getFormatter()->isStandardTime($values['value'])) { }
// Orario
elseif ($values['type'] == 'time' && \Translator::getFormatter()->isStandardTime($values['value'])) {
$values['value'] = \Translator::timeToLocale($values['value']); $values['value'] = \Translator::timeToLocale($values['value']);
} }
// Controllo sulla correttezza sintattica del valore impostato
if (!( if (!(
($values['type'] == 'timestamp' && \Translator::getFormatter()->isFormattedTimestamp($values['value'])) || ($values['type'] == 'timestamp' && \Translator::getFormatter()->isFormattedTimestamp($values['value'])) ||
($values['type'] == 'date' && \Translator::getFormatter()->isFormattedDate($values['value'])) || ($values['type'] == 'date' && \Translator::getFormatter()->isFormattedDate($values['value'])) ||
@ -38,10 +48,12 @@ class DateHandler implements HandlerInterface
$values['value'] = ''; $values['value'] = '';
} }
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras); $result = $this->{$values['type']}($values, $extras);
$values['type'] = 'text'; $values['type'] = 'text';
// Generazione del codice HTML di default
if (empty($result)) { if (empty($result)) {
$result = ' $result = '
<input |attr|>'; <input |attr|>';
@ -50,6 +62,15 @@ class DateHandler implements HandlerInterface
return $result; return $result;
} }
/**
* Gestione dell'input di tipo "timestamp".
* Esempio: {[ "type": "timestamp", "label": "Timestamp di test", "name": "timestamp", "value": "2018-01-01 12:00:30" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function timestamp(&$values, &$extras) protected function timestamp(&$values, &$extras)
{ {
$values['class'][] = 'text-center'; $values['class'][] = 'text-center';
@ -57,6 +78,15 @@ class DateHandler implements HandlerInterface
$values['class'][] = 'timestamp-mask'; $values['class'][] = 'timestamp-mask';
} }
/**
* Gestione dell'input di tipo "date".
* Esempio: {[ "type": "date", "label": "Data di test", "name": "date", "value": "2018-01-01" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function date(&$values, &$extras) protected function date(&$values, &$extras)
{ {
$values['class'][] = 'text-center'; $values['class'][] = 'text-center';
@ -64,6 +94,15 @@ class DateHandler implements HandlerInterface
$values['class'][] = 'date-mask'; $values['class'][] = 'date-mask';
} }
/**
* Gestione dell'input di tipo "time".
* Esempio: {[ "type": "time", "label": "Orario di test", "name": "time", "value": "12:00:30" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function time(&$values, &$extras) protected function time(&$values, &$extras)
{ {
$values['class'][] = 'text-center'; $values['class'][] = 'text-center';

View File

@ -3,37 +3,98 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Gestione dell'input di tipo "text", "file", "password", "email", "number", "textarea" e "hidden".
*
* @since 2.3 * @since 2.3
*/ */
class DefaultHandler implements HandlerInterface class DefaultHandler implements HandlerInterface
{ {
public function handle(&$values, &$extras) public function handle(&$values, &$extras)
{ {
// Delega della gestione al metodo specifico per il tipo di input richiesto
if (in_array($values['type'], get_class_methods($this))) { if (in_array($values['type'], get_class_methods($this))) {
$result = $this->{$values['type']}($values, $extras); $result = $this->{$values['type']}($values, $extras);
} else { }
// Caso non previsto
else {
$result = $this->custom($values, $extras); $result = $this->custom($values, $extras);
} }
return $result; return $result;
} }
/**
* Gestione dell'input di tipo non altrimenti previsto.
* Esempio: {[ "type": "undefined", "label": "Custom di test", "placeholder": "Test", "name": "custom", "value": "custom" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function custom(&$values, &$extras)
{
// Generazione del codice HTML
return '
<span |attr|>|value|</span>';
}
/**
* Gestione dell'input di tipo "text".
* Esempio: {[ "type": "text", "label": "Text di test", "placeholder": "Test", "name": "text" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function text(&$values, &$extras) protected function text(&$values, &$extras)
{ {
// Generazione del codice HTML
return ' return '
<input |attr|>'; <input |attr|>';
} }
/**
* Gestione dell'input di tipo "file".
* Esempio: {[ "type": "file", "label": "File di test", "placeholder": "Test", "name": "file" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function file(&$values, &$extras) protected function file(&$values, &$extras)
{ {
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras); return $this->text($values, $extras);
} }
/**
* Gestione dell'input di tipo "password".
* Esempio: {[ "type": "password", "label": "Password di test", "placeholder": "Test", "name": "password" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function password(&$values, &$extras) protected function password(&$values, &$extras)
{ {
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras); return $this->text($values, $extras);
} }
/**
* Gestione dell'input di tipo "hidden".
* Esempio: {[ "type": "hidden", "label": "Hidden di test", "placeholder": "Test", "name": "hidden" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function hidden(&$values, &$extras) protected function hidden(&$values, &$extras)
{ {
$original = $values; $original = $values;
@ -44,54 +105,81 @@ class DefaultHandler implements HandlerInterface
$values['name'] = $original['name']; $values['name'] = $original['name'];
$values['class'] = []; $values['class'] = [];
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras); return $this->text($values, $extras);
} }
/**
* Gestione dell'input di tipo "email".
* Esempio: {[ "type": "email", "label": "Email di test", "placeholder": "Test", "name": "email" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function email(&$values, &$extras) protected function email(&$values, &$extras)
{ {
$values['class'][] = 'email-mask'; $values['class'][] = 'email-mask';
$values['type'] = 'text'; $values['type'] = 'text';
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras); return $this->text($values, $extras);
} }
/**
* Gestione dell'input di tipo "number".
* Esempio: {[ "type": "number", "label": "Number di test", "placeholder": "Test", "name": "number" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function number(&$values, &$extras) protected function number(&$values, &$extras)
{ {
$values['class'][] = 'inputmask-decimal'; $values['class'][] = 'inputmask-decimal';
$values['value'] = !empty($values['value']) ? $values['value'] : 0; $values['value'] = !empty($values['value']) ? $values['value'] : 0;
// Gestione della precisione (numero specifico, oppure "qta" per il valore previsto nell'impostazione "Cifre decimali per quantità").
$decimals = null; $decimals = null;
if (isset($values['decimals'])) { if (isset($values['decimals'])) {
if (is_numeric($values['decimals'])) { if (is_numeric($values['decimals'])) {
$decimals = $values['decimals']; $decimals = $values['decimals'];
} elseif (starts_with($values['decimals'], 'qta')) { } elseif (starts_with($values['decimals'], 'qta')) {
$parts = explode('|', $values['decimals']); // Se non è previsto un valore minimo, lo imposta a 1
$values['min-value'] = isset($parts[1]) ? $parts[1] : 1; $values['min-value'] = isset($values['min-value']) ? $values['min-value'] : 1;
$decimals = \Settings::get('Cifre decimali per quantità'); $decimals = \Settings::get('Cifre decimali per quantità');
$values['decimals'] = $decimals; $values['decimals'] = $decimals;
} }
} }
// Controllo sulla correttezza sintattica del valore impostato
$values['value'] = (\Translator::getFormatter()->isStandardNumber($values['value'])) ? \Translator::numberToLocale($values['value'], $decimals) : $values['value']; $values['value'] = (\Translator::getFormatter()->isStandardNumber($values['value'])) ? \Translator::numberToLocale($values['value'], $decimals) : $values['value'];
$values['type'] = 'text'; $values['type'] = 'text';
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras); return $this->text($values, $extras);
} }
protected function custom(&$values, &$extras) /**
{ * Gestione dell'input di tipo "textarea".
return ' * Esempio: {[ "type": "textarea", "label": "Textarea di test", "placeholder": "Test", "name": "textarea" ]}.
<span |attr|>|value|</span>'; *
} * @param array $values
* @param array $extras
*
* @return string
*/
protected function textarea(&$values, &$extras) protected function textarea(&$values, &$extras)
{ {
$values['class'][] = 'autosize'; $values['class'][] = 'autosize';
// Generazione del codice HTML
return ' return '
<textarea |attr|>|value|</textarea>'; <textarea |attr|>|value|</textarea>';
} }

View File

@ -3,10 +3,19 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Intefaccia utilizzata per interagire con la classe HTMLBuilder.
* *
* @since 2.3 * @since 2.3
*/ */
interface HandlerInterface interface HandlerInterface
{ {
/**
* Gestore pubblico, liberamente implementabile per la creazione del codice HTML.
*
* @param array $values
* @param array $extras
*
* @return string
*/
public function handle(&$values, &$extras); public function handle(&$values, &$extras);
} }

View File

@ -3,33 +3,49 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Gestione dell'input di tipo "image".
*
* @since 2.3 * @since 2.3
*/ */
class MediaHandler implements HandlerInterface class MediaHandler implements HandlerInterface
{ {
public function handle(&$values, &$extras)
{
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras);
return $result;
}
/** /**
* @since 2.3 * Gestione dell'input di tipo "image".
* Esempio: {[ "type": "image", "label": "Immagine di test", "name": "image", "class": "img-thumbnail", "value": "image_path" ]}.
* *
* @param array $values * @param array $values
* @param array $extras * @param array $extras
* *
* @return string * @return string
*/ */
public function handle(&$values, &$extras) public function image(&$values, &$extras)
{ {
unset($values['class'][0]); unset($values['class'][0]);
// Form upload // Valore non imposato
if (empty($values['value'])) { if (empty($values['value'])) {
$values['type'] = 'file'; $values['type'] = 'file';
// Generazione del codice HTML
return ' return '
<input |attr|>'; <input |attr|>';
} else { }
// Valore presente
// Visualizzazione dell'immagine e della relativa spunta per la cancellazione // Visualizzazione dell'immagine e della relativa spunta per la cancellazione
else {
$values['class'][] = 'img-thumbnail'; $values['class'][] = 'img-thumbnail';
$values['class'][] = 'img-responsive'; $values['class'][] = 'img-responsive';
// Generazione del codice HTML
return ' return '
<img src="|value|" |attr|><br> <img src="|value|" |attr|><br>
<label> <label>

View File

@ -3,16 +3,21 @@
namespace HTMLBuilder\Handler; namespace HTMLBuilder\Handler;
/** /**
* Gestione dell'input di tipo "select".
*
* @since 2.3 * @since 2.3
*/ */
class SelectHandler implements HandlerInterface class SelectHandler implements HandlerInterface
{ {
public function handle(&$values, &$extras) public function handle(&$values, &$extras)
{ {
$values['class'][] = (!empty($values['ajax-source'])) ? 'superselectajax' : 'superselect'; // Individuazione della classe per la corretta gestione JavaScript
$values['class'][] = !empty($values['ajax-source']) ? 'superselectajax' : 'superselect';
$values['data-source'] = (!empty($values['ajax-source'])) ? $values['ajax-source'] : ''; // Individuazione della richiesta AJAX (se presente)
$values['data-source'] = !empty($values['ajax-source']) ? $values['ajax-source'] : '';
// Individuazione e gestione dei valori tramite array
$values['value'] = explode(',', $values['value']); $values['value'] = explode(',', $values['value']);
if (count($values['value']) === 1 && strlen($values['value'][0]) === 0) { if (count($values['value']) === 1 && strlen($values['value'][0]) === 0) {
$values['value'] = []; $values['value'] = [];
@ -25,16 +30,19 @@ class SelectHandler implements HandlerInterface
$values['value'] = (array) $values['value']; $values['value'] = (array) $values['value'];
// Inizializzazione del codice HTML
$result = ' $result = '
<select |attr|>'; <select |attr|>';
// Delega della generazione del codice HTML in base alle caratteristiche del formato
// Gestione delle richieste AJAX (se il campo "ajax-source" è impostato)
if (!empty($values['ajax-source'])) { if (!empty($values['ajax-source'])) {
if (!empty($values['value']) || is_numeric($values['value'])) { if (!empty($values['value']) || is_numeric($values['value'])) {
$result .= $this->select2($values['ajax-source'], $values['value']); $result .= $this->select2($values['ajax-source'], $values['value']);
} }
} }
// Generazione <select> da query // Gestione del select da query specifica (se il campo "values" è impostato a "query=SQL")
elseif (preg_match_all('/^query=(.+?)$/', $values['values'], $matches)) { elseif (preg_match_all('/^query=(.+?)$/', $values['values'], $matches)) {
$result .= ' $result .= '
<option></option>'; <option></option>';
@ -42,21 +50,23 @@ class SelectHandler implements HandlerInterface
$result .= $this->selectQuery($matches[1][0], $values['value']); $result .= $this->selectQuery($matches[1][0], $values['value']);
} }
// Generazione <select> da JSON // Gestione del select dal formato JSON parziale (valori singoli)
// esempio creazione select con opzioni: Maschio, Femmina, Unisex
// {[ "type": "select", "label": "Sesso", "name": "sesso", "values": "list=\"\": \"\", \"M\": \"Maschio\", \"F\": \"Femmina\", \"U\": \"Unisex\"", "value": "$sesso$" ]}
elseif (preg_match_all('/^list=(.+?)$/', $values['values'], $matches)) { elseif (preg_match_all('/^list=(.+?)$/', $values['values'], $matches)) {
$result .= ' $result .= '
<option></option>'; <option></option>';
$result .= $this->selectList(json_decode('{'.$matches[1][0].'}', true), $values); $result .= $this->selectList(json_decode('{'.$matches[1][0].'}', true), $values);
} elseif (preg_match_all('/^json=(.+?)$/', $values['values'], $matches)) { }
// Gestione del select dal formato JSON completo, convertito in array
elseif (is_array($values['values'])) {
$result .= ' $result .= '
<option></option>'; <option></option>';
$result .= $this->selectJSON(json_decode('[{'.$matches[1][0].'}]', true), $values['value']); $result .= $this->selectArray($values['values'], $values['value']);
} }
// Impostazione del placeholder
$values['placeholder'] = !empty($values['placeholder']) ? $values['placeholder'] : '- '.tr("Seleziona un'opzione").' -'; $values['placeholder'] = !empty($values['placeholder']) ? $values['placeholder'] : '- '.tr("Seleziona un'opzione").' -';
$values['data-placeholder'] = $values['placeholder']; $values['data-placeholder'] = $values['placeholder'];
@ -65,11 +75,13 @@ class SelectHandler implements HandlerInterface
$result .= ' $result .= '
</select>'; </select>';
// Gestione delle proprietà "disabled" e "readonly"
if (in_array('disabled', $extras) || in_array('readonly', $extras)) { if (in_array('disabled', $extras) || in_array('readonly', $extras)) {
$result .= ' $result .= '
<script>$("#'.$values['id'].'").prop("disabled", true);</script>'; <script>$("#'.$values['id'].'").prop("disabled", true);</script>';
} }
// Ulteriore gestione della proprietà "readonly" (per rendere il select utilizzabile dopo il submit)
if (in_array('readonly', $extras) && empty($values['ajax-source'])) { if (in_array('readonly', $extras) && empty($values['ajax-source'])) {
$result .= ' $result .= '
<select class="hide" name="'.prepareToField($values['name']).'"'.((in_array('multiple', $extras)) ? ' multiple' : '').'>'; <select class="hide" name="'.prepareToField($values['name']).'"'.((in_array('multiple', $extras)) ? ' multiple' : '').'>';
@ -86,9 +98,18 @@ class SelectHandler implements HandlerInterface
return $result; return $result;
} }
/**
* Gestione dell'input di tipo "select" con richieste AJAX (nome della richiesta indicato tramite attributo "ajax-source").
* Esempio: {[ "type": "select", "label": "Select di test", "name": "test", "ajax-source": "test" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function select2($op, $elements) protected function select2($op, $elements)
{ {
// Richiamo alla pagina ajax_select.php per aggiungere il valore iniziale al select // Richiamo del file dedicato alle richieste AJAX per ottenere il valore iniziale del select
ob_start(); ob_start();
$dbo = \Database::getConnection(); $dbo = \Database::getConnection();
include DOCROOT.'/ajax_select.php'; include DOCROOT.'/ajax_select.php';
@ -127,7 +148,16 @@ class SelectHandler implements HandlerInterface
return $result; return $result;
} }
protected function selectJSON($array, $values) /**
* Gestione dell'input di tipo "select" basato su un array associativo.
* Esempio: {[ "type": "select", "name": "tipo", "values": [{"id":"M","text":"Maschio"},{"id":"F","text":"Femmina"},{"id":"U","text":"Unisex"}], "value": "U", "placeholder": "Non specificato" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectArray($array, $values)
{ {
$prev = ''; $prev = '';
foreach ($array as $element) { foreach ($array as $element) {
@ -150,7 +180,9 @@ class SelectHandler implements HandlerInterface
$attributes[] = 'style="background:'.$element['_bgcolor_'].'; color:'.color_inverse($element['_bgcolor_']).';"'; $attributes[] = 'style="background:'.$element['_bgcolor_'].'; color:'.color_inverse($element['_bgcolor_']).';"';
} }
$exclude = ['optgroup']; $exclude = [
'optgroup',
];
// Leggo ulteriori campi oltre a id e descrizione per inserirli nell'option nella forma "data-nomecampo1", "data-nomecampo2", ecc // Leggo ulteriori campi oltre a id e descrizione per inserirli nell'option nella forma "data-nomecampo1", "data-nomecampo2", ecc
foreach ($element as $key => $value) { foreach ($element as $key => $value) {
if (!in_array($key, $exclude)) { if (!in_array($key, $exclude)) {
@ -165,6 +197,15 @@ class SelectHandler implements HandlerInterface
return $result; return $result;
} }
/**
* Gestione dell'input di tipo "select" basato su una query specifica.
* Esempio: {[ "type": "select", "label": "Select di test", "name": "select", "values": "query=SELECT id, name as text FROM table" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectQuery($query, $values) protected function selectQuery($query, $values)
{ {
$result = ''; $result = '';
@ -173,27 +214,30 @@ class SelectHandler implements HandlerInterface
$array = $database->fetchArray($query); $array = $database->fetchArray($query);
return $this->selectJSON($array, $values); return $this->selectArray($array, $values);
} }
/**
* Gestione dell'input di tipo "select" basato su una lista parzialmente JSON.
* Esempio: {[ "type": "select", "label": "Sesso", "name": "sesso", "values": "list=\"\": \"Non specificato\", \"M\": \"Maschio\", \"F\": \"Femmina\", \"U\": \"Unisex\"", "value": "M" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectList($datas, &$values) protected function selectList($datas, &$values)
{ {
$result = ''; $array = [];
foreach ($datas as $key => $value) { foreach ($datas as $key => $value) {
if (!empty($key)) { if (!empty($key)) {
$attributes = []; $array[] = ['id' => $key, 'text' => $value];
if (in_array($key, $values['value'])) {
$attributes[] = 'selected';
}
$result .= '
<option value="'.prepareToField($key).'" '.implode(' ', $attributes).'>'.$value.'</option>';
} elseif (empty($values['placeholder'])) { } elseif (empty($values['placeholder'])) {
$values['placeholder'] = $value; $values['placeholder'] = $value;
} }
} }
return $result; return $this->selectArray($array, $values['value']);
} }
} }

View File

@ -135,7 +135,7 @@ class HTMLWrapper implements WrapperInterface
$value = (empty($pieces[2]) || !in_array($pieces[2], array_column($choices, 'id'))) ? 'UNT' : $pieces[2]; $value = (empty($pieces[2]) || !in_array($pieces[2], array_column($choices, 'id'))) ? 'UNT' : $pieces[2];
if ($type == 'untprc') { if ($type == 'untprc') {
$result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "value": "'.prepareToField($value).'", "values": "json='.substr(str_replace('"', '\"', json_encode($choices)), 2, -2).'", "class": "no-search" ]}'; $result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "value": "'.prepareToField($value).'", "values": '.json_encode($choices).', "class": "no-search" ]}';
$result = \HTMLBuilder\HTMLBuilder::replace($result); $result = \HTMLBuilder\HTMLBuilder::replace($result);
} }