2018-06-27 14:25:19 +02:00
< ? php
2020-09-07 15:04:06 +02:00
/*
* OpenSTAManager : il software gestionale open source per l ' assistenza tecnica e la fatturazione
2021-01-20 15:08:51 +01:00
* Copyright ( C ) DevCode s . r . l .
2020-09-07 15:04:06 +02:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2018-06-27 14:25:19 +02:00
// Apache
$modules = [
2018-09-17 18:11:39 +02:00
'mod_rewrite' => [
'server' => 'HTTP_MOD_REWRITE' ,
'description' => tr ( 'Fornisce un sistema di riscrittura URL basato su regole predefinite' ),
],
2023-12-20 13:03:44 +01:00
'mod_mime' => [
'server' => 'text/javascript mjs' ,
'description' => tr ( 'Consente di associare i tipi di file ai tipi di contenuto corretti.' ),
],
2018-06-27 14:25:19 +02:00
];
2024-02-22 01:09:14 +01:00
$sapi_name = php_sapi_name ();
2024-02-22 17:12:35 +01:00
$php_interface = '' ;
2024-05-23 11:36:25 +02:00
$php_interface = match ( true ) {
str_contains ( $sapi_name , 'apache' ) => 'apache' ,
str_contains ( $sapi_name , 'fpm-fcgi' ) => 'fpm-fcgi' ,
str_contains ( $sapi_name , 'fpm' ) => 'fpm' ,
str_contains ( $sapi_name , 'cgi-fcgi' ) => 'cgi-fcgi' ,
str_contains ( $sapi_name , 'cgi' ) => 'cgi' ,
str_contains ( $sapi_name , 'cli' ) => 'cli' ,
str_contains ( $sapi_name , 'embed' ) => 'embed' ,
str_contains ( $sapi_name , 'litespeed' ) => 'litespeed' ,
str_contains ( $sapi_name , 'isapi' ) => 'isapi' ,
default => 'n.d.' ,
};
2024-02-22 15:58:03 +01:00
2018-09-17 18:11:39 +02:00
if ( function_exists ( 'apache_get_modules' )) {
2018-09-14 11:13:38 +02:00
$available_modules = apache_get_modules ();
}
2018-06-27 14:25:19 +02:00
$apache = [];
2018-09-17 18:11:39 +02:00
foreach ( $modules as $name => $values ) {
$description = $values [ 'description' ];
2024-02-22 17:03:37 +01:00
2018-09-17 18:11:39 +02:00
$status = isset ( $available_modules ) ? in_array ( $name , $available_modules ) : $_SERVER [ $values [ 'server' ]] == 'On' ;
2018-06-27 14:25:19 +02:00
2024-02-22 17:03:37 +01:00
if ( $name == 'mod_mime' && $php_interface != 'apache' ) {
2024-04-08 15:44:33 +02:00
$headers = get_headers (( ! empty ( $config [ 'redirectHTTPS' ]) && ! isHTTPS ( true )) ? 'https://' : 'http://' . $_SERVER [ 'HTTP_HOST' ] . $_SERVER [ 'REQUEST_URI' ], true );
2024-02-22 01:09:14 +01:00
if ( isset ( $headers [ 'Content-Type' ])) {
$status = 1 ;
2024-02-22 17:03:37 +01:00
} else {
2024-02-22 01:09:14 +01:00
$status = 0 ;
}
}
2018-06-27 14:25:19 +02:00
$apache [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
'type' => tr ( 'Modulo' ),
];
}
2024-01-15 15:30:45 +01:00
// PHP
2018-06-27 14:25:19 +02:00
$settings = [
2022-02-07 13:36:31 +01:00
'php_version' => [
2022-02-07 14:41:06 +01:00
'type' => 'version' ,
2024-08-19 15:25:11 +02:00
'description' => '8.1.x - 8.3.x' ,
'minimum' => '8.1.0' ,
2024-05-13 17:26:12 +02:00
'maximum' => '8.3.99' ,
2022-02-07 13:36:31 +01:00
],
2018-06-27 14:25:19 +02:00
'zip' => [
'type' => 'ext' ,
'description' => tr ( 'Permette di leggere e scrivere gli archivi compressi ZIP e i file al loro interno' ),
],
2018-06-27 18:58:50 +02:00
'mbstring' => [
'type' => 'ext' ,
'description' => tr ( 'Permette di gestire i caratteri dello standard UTF-8' ),
],
2018-06-27 14:25:19 +02:00
'pdo_mysql' => [
'type' => 'ext' ,
'description' => tr ( 'Permette di effettuare la connessione al database MySQL' ),
],
2018-12-14 12:58:40 +01:00
'dom' => [
'type' => 'ext' ,
'description' => tr ( 'Permette la gestione dei file standard per la Fatturazione Elettronica' ),
],
'xsl' => [
'type' => 'ext' ,
'description' => tr ( 'Permette di visualizzazione grafica della Fattura Elettronica' ),
],
2018-06-27 14:25:19 +02:00
'openssl' => [
'type' => 'ext' ,
2018-12-14 12:58:40 +01:00
'description' => tr ( " Permette l'utilizzo di funzioni crittografiche simmetriche e asimmetriche " ),
2018-06-27 14:25:19 +02:00
],
'intl' => [
'type' => 'ext' ,
2018-12-14 12:58:40 +01:00
'description' => tr ( " Permette l'automazione della conversione dei numeri " ),
2018-06-27 14:25:19 +02:00
],
2018-12-14 12:58:40 +01:00
'curl' => [
2018-10-02 18:21:27 +02:00
'type' => 'ext' ,
2018-12-14 12:58:40 +01:00
'description' => tr ( 'Permette la comunicazione con servizi esterni' ),
2018-10-02 18:21:27 +02:00
],
2018-06-27 14:25:19 +02:00
'soap' => [
'type' => 'ext' ,
'description' => tr ( 'Permette la comunicazione con servizi esterni, quali il database europeo delle Partite IVA (facoltativo)' ),
],
2020-10-28 17:35:52 +01:00
'gd' => [
'type' => 'ext' ,
'description' => tr ( 'Permette la creazione dell\'immagine della firma per il rapportino d\'intervento (facoltativo)' ),
],
2022-10-06 10:41:35 +02:00
'fileinfo' => [
'type' => 'ext' ,
'description' => tr ( 'Permette la creazione dell\'immagine della firma per il rapportino d\'intervento (facoltativo)' ),
],
2018-06-27 14:25:19 +02:00
2024-01-15 15:30:45 +01:00
// 'display_errors' => [
2018-10-02 18:21:27 +02:00
// 'type' => 'value',
// 'description' => true,
2024-01-15 15:30:45 +01:00
// ],
2023-07-17 17:51:11 +02:00
'allow_url_fopen' => [
'type' => 'value' ,
'description' => 1 ,
],
2023-08-04 14:54:28 +02:00
2018-06-27 14:25:19 +02:00
'upload_max_filesize' => [
'type' => 'value' ,
2019-05-24 21:49:15 +02:00
'description' => '>32M' ,
2018-06-27 14:25:19 +02:00
],
2022-02-10 10:42:04 +01:00
2018-06-27 14:25:19 +02:00
'post_max_size' => [
'type' => 'value' ,
2019-05-24 21:49:15 +02:00
'description' => '>32M' ,
2018-06-27 14:25:19 +02:00
],
2022-02-07 13:36:31 +01:00
2022-02-10 10:42:04 +01:00
'max_input_vars' => [
'type' => 'value' ,
'description' => '>5000' ,
],
2024-01-06 19:34:00 +01:00
'exec' => [
'type' => 'function' ,
'description' => tr ( 'Permette di importare file con estensione .p7m' ),
],
2018-06-27 14:25:19 +02:00
];
$php = [];
foreach ( $settings as $name => $values ) {
$description = $values [ 'description' ];
2022-02-07 14:41:06 +01:00
if ( $values [ 'type' ] == 'version' ) {
2022-02-07 13:36:31 +01:00
$description = tr ( 'Valore consigliato: _VALUE_ (Valore attuale: _PHP_VERSION_)' , [
'_VALUE_' => $description ,
'_PHP_VERSION_' => phpversion (),
]);
2023-08-04 14:54:28 +02:00
$status = (( version_compare ( phpversion (), $values [ 'minimum' ], '>=' ) && version_compare ( phpversion (), $values [ 'maximum' ], '<=' )) ? 1 : 0 );
2022-02-07 13:36:31 +01:00
} elseif ( $values [ 'type' ] == 'ext' ) {
2018-06-27 14:25:19 +02:00
$status = extension_loaded ( $name );
2024-01-06 19:34:00 +01:00
} elseif ( $values [ 'type' ] == 'function' ) {
2024-01-10 15:08:26 +01:00
$status = (( function_exists ( $name ) && is_callable ( $name )) ? 1 : 0 );
2018-06-27 14:25:19 +02:00
} else {
$ini = str_replace ([ 'k' , 'M' ], [ '000' , '000000' ], ini_get ( $name ));
$real = str_replace ([ 'k' , 'M' ], [ '000' , '000000' ], $description );
2020-10-29 16:48:37 +01:00
if ( string_starts_with ( $real , '>' )) {
2018-06-27 14:25:19 +02:00
$status = $ini >= substr ( $real , 1 );
2020-10-29 16:48:37 +01:00
} elseif ( string_starts_with ( $real , '<' )) {
2018-06-27 14:25:19 +02:00
$status = $ini <= substr ( $real , 1 );
} else {
$status = ( $real == $ini );
}
if ( is_bool ( $description )) {
$description = ! empty ( $description ) ? 'On' : 'Off' ;
} else {
$description = str_replace ([ '>' , '<' ], '' , $description );
}
2018-10-30 22:19:15 +01:00
$description = tr ( 'Valore consigliato: _VALUE_ (Valore attuale: _INI_)' , [
2024-03-22 15:52:24 +01:00
'_VALUE_' => $description ,
'_INI_' => ini_get ( $name ),
2018-06-27 14:25:19 +02:00
]);
}
2023-08-04 14:54:28 +02:00
if ( $values [ 'type' ] == 'ext' ) {
$type = tr ( 'Estensione' );
} elseif ( $values [ 'type' ] == 'version' ) {
$type = tr ( 'Versione' );
2024-01-06 19:34:00 +01:00
} elseif ( $values [ 'type' ] == 'function' ) {
$type = tr ( 'Funzione' );
2024-01-10 15:08:26 +01:00
} else {
2023-08-04 14:54:28 +02:00
$type = tr ( 'Impostazione' );
2022-02-07 14:41:06 +01:00
}
2018-06-27 14:25:19 +02:00
$php [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
'type' => $type ,
];
}
2022-02-07 14:41:06 +01:00
// MySQL
2023-08-04 14:54:28 +02:00
if ( $database -> isInstalled ()) {
2024-03-15 13:17:23 +01:00
if ( method_exists ( $database , 'isMySQL' )) {
$db = [
'mysql_version' => [
'type' => 'version' ,
'warning' => $database -> isMySQL () ? false : true ,
'description' => $database -> isMySQL () ? '5.7.x - 8.0.x' : '10.x' ,
'minimum' => $database -> isMySQL () ? '5.7.0' : '10.1.0' ,
2024-04-09 14:45:37 +02:00
'maximum' => $database -> isMySQL () ? '8.3.99' : '10.6.99' ,
2024-03-15 13:17:23 +01:00
],
2024-03-22 15:52:24 +01:00
2024-03-15 13:17:23 +01:00
'sort_buffer_size' => [
'type' => 'value' ,
'description' => '>2M' ,
],
];
} else {
$db = [
'sort_buffer_size' => [
'type' => 'value' ,
'description' => '>2M' ,
],
];
}
2022-12-05 17:44:20 +01:00
2022-12-05 19:18:31 +01:00
/* foreach ( App :: getConfig ()[ 'db_options' ] as $n => $v ){
2023-08-04 14:54:28 +02:00
2022-12-05 17:44:20 +01:00
switch ( $n ){
case 'sort_buffer_size' :
$db [ $n ] = [
'type' => 'value' ,
2022-12-08 00:11:55 +01:00
'description' => '>2M' ,
2022-12-05 17:44:20 +01:00
];
break ;
}
2023-08-04 14:54:28 +02:00
} */
2022-03-10 17:29:24 +01:00
}
2022-02-07 14:41:06 +01:00
2024-03-15 10:47:24 +01:00
$mysql = [];
2022-02-07 14:41:06 +01:00
foreach ( $db as $name => $values ) {
$description = $values [ 'description' ];
2022-12-05 17:44:20 +01:00
if ( $values [ 'type' ] == 'version' ) {
2023-08-04 14:54:28 +02:00
$type = tr ( 'Versione' );
2022-12-05 17:44:20 +01:00
$description = tr ( 'Valore consigliato: _VALUE_ (Valore attuale: _MYSQL_VERSION_)' , [
'_VALUE_' => $description ,
'_MYSQL_VERSION_' => $database -> getMySQLVersion (),
]);
2023-08-04 14:54:28 +02:00
$status = (( version_compare ( $database -> getMySQLVersion (), $values [ 'minimum' ], '>=' ) && version_compare ( $database -> getMySQLVersion (), $values [ 'maximum' ], '<=' )) ? 1 : 0 );
2024-03-03 12:29:42 +01:00
2024-03-22 15:52:24 +01:00
if ( $values [ 'warning' ] && $status == 1 ) {
2024-03-03 12:29:42 +01:00
$status = 0 ;
2024-03-22 15:52:24 +01:00
$description .= '. <i class="fa fa-exclamation-triangle text-danger" ></i><b> ' . tr ( 'Al momento MariaDB _MYSQL_VERSION_ non è completamente supportato, si consiglia di passare a MySQL.' , [ '_MYSQL_VERSION_' => $database -> getMySQLVersion ()]) . '</b>' ;
2024-03-03 12:29:42 +01:00
}
2023-08-04 14:54:28 +02:00
} else {
$type = tr ( 'Impostazione' );
2022-12-05 17:44:20 +01:00
2024-01-15 15:30:45 +01:00
// Vedo se riesco a recuperare l'impostazione dalle variabili di sessione o globali di mysql
2022-12-05 18:51:41 +01:00
$rs_session_variabile = $dbo -> fetchArray ( 'SHOW SESSION VARIABLES LIKE ' . prepare ( $name ));
$rs_global_variabile = $dbo -> fetchArray ( 'SHOW GLOBAL VARIABLES LIKE ' . prepare ( $name ));
2023-08-04 14:54:28 +02:00
if ( ! empty ( $rs_session_variabile [ 0 ][ 'Value' ])) {
2022-12-08 00:11:55 +01:00
$inc = $rs_session_variabile [ 0 ][ 'Value' ];
2023-08-04 14:54:28 +02:00
} elseif ( ! empty ( $rs_global_variabile [ 0 ][ 'Value' ])) {
2022-12-08 00:11:55 +01:00
$inc = $rs_global_variabile [ 0 ][ 'Value' ];
2023-08-04 14:54:28 +02:00
} else {
2022-12-05 18:51:41 +01:00
$inc = str_replace ([ 'k' , 'M' ], [ '000' , '000000' ], App :: getConfig ()[ 'db_options' ][ $name ]);
2023-08-04 14:54:28 +02:00
}
2022-12-05 17:44:20 +01:00
$real = str_replace ([ 'k' , 'M' ], [ '000' , '000000' ], $description );
if ( string_starts_with ( $real , '>' )) {
$status = $inc >= substr ( $real , 1 );
} elseif ( string_starts_with ( $real , '<' )) {
$status = $inc <= substr ( $real , 1 );
} else {
$status = ( $real == $inc );
}
if ( is_bool ( $description )) {
$description = ! empty ( $description ) ? 'On' : 'Off' ;
} else {
$description = str_replace ([ '>' , '<' ], '' , $description );
}
2022-12-05 18:51:41 +01:00
$description = tr ( 'Valore consigliato: _VALUE_ (Valore attuale: _INC_)' , [
2024-03-22 15:52:24 +01:00
'_VALUE_' => $description ,
'_INC_' => Util\FileSystem :: formatBytes ( $inc ),
2022-12-05 17:44:20 +01:00
]);
}
2022-02-07 14:41:06 +01:00
$mysql [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
2022-12-05 17:44:20 +01:00
'type' => $type ,
2022-02-07 14:41:06 +01:00
];
}
2018-06-27 14:25:19 +02:00
// Percorsi di servizio
2022-11-28 19:37:24 +01:00
$dirs_to_check = [
2018-06-27 14:25:19 +02:00
'files' => tr ( 'Necessario per il salvataggio di file inseriti dagli utenti' ),
2022-11-08 18:28:52 +01:00
'files/temp' => tr ( 'Necessario per la generazione delle stampe' ),
2018-06-27 14:25:19 +02:00
'logs' => tr ( 'Necessario per la gestione dei file di log' ),
];
$directories = [];
2022-11-28 19:37:24 +01:00
foreach ( $dirs_to_check as $name => $description ) {
2024-06-05 16:48:49 +02:00
$status = is_writable ( base_dir () . DIRECTORY_SEPARATOR . $name );
2024-06-25 09:40:41 +02:00
2018-06-27 14:25:19 +02:00
$directories [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
'type' => tr ( 'Cartella' ),
];
}
2022-11-28 19:37:24 +01:00
// File di servizio
$files_to_check = [
2023-03-10 13:00:39 +01:00
'manifest.json' => tr ( 'Necessario per l\'aggiunta a schermata home da terminale (creato al termine della configurazione)' ),
2024-03-02 02:52:30 +01:00
'mariadb_10_x.json' => tr ( 'Necessario per il controllo integrità con database MariaDB 10.x' ),
'mysql_5_7.json' => tr ( 'Necessario per il controllo integrità con database MySQL 5.7.x' ),
'mysql.json' => tr ( 'Necessario per il controllo integrità con database MySQL 8.0.x' ),
2022-11-28 19:37:24 +01:00
'checksum.json' => tr ( 'Necessario per il controllo integrità dei files del gestionale' ),
2024-01-18 20:40:52 +01:00
'settings.json' => tr ( 'Necessario per il controllo delle impostazioni del gestionale' ),
2022-11-28 19:37:24 +01:00
];
$files = [];
foreach ( $files_to_check as $name => $description ) {
2024-01-19 18:04:08 +01:00
$status = is_readable ( base_dir () . DIRECTORY_SEPARATOR . $name );
2022-11-28 19:37:24 +01:00
$files [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
'type' => tr ( 'File' ),
];
}
2023-07-17 17:51:11 +02:00
// Configurazioni OSM
$config_to_check = [
'lang' => [
'type' => 'value' ,
'operator' => 'strcmp' ,
'value_to_check' => '|lang|' ,
'suggested_value' => 'it_IT' ,
'section' => '' ,
],
'timestamp' => [
'type' => 'value' ,
'operator' => 'strcmp' ,
'value_to_check' => '|timestamp|' ,
'suggested_value' => 'd/m/Y H:i' ,
'section' => 'formatter' ,
],
'date' => [
'type' => 'value' ,
'operator' => 'strcmp' ,
'value_to_check' => '|date|' ,
'suggested_value' => 'd/m/Y' ,
'section' => 'formatter' ,
],
'time' => [
'type' => 'value' ,
'operator' => 'strcmp' ,
'value_to_check' => '|time|' ,
'suggested_value' => 'H:i' ,
'section' => 'formatter' ,
2023-08-04 14:54:28 +02:00
],
2023-07-17 17:51:11 +02:00
];
$config = [];
2023-08-04 14:54:28 +02:00
foreach ( $config_to_check as $name => $values ) {
2023-07-17 17:51:11 +02:00
$type = $values [ 'type' ];
if ( $type == 'value' ) {
$description = tr ( 'Valore consigliato: _SUGGESTED_ (Valore attuale: _ACTUAL_)' , [
'_SUGGESTED_' => $values [ 'suggested_value' ],
2024-04-08 15:44:33 +02:00
'_ACTUAL_' => ( ! empty ( $values [ 'section' ]) ? $ { $values [ 'section' ]}[ $name ] : ${$name} ),
2023-07-17 17:51:11 +02:00
]);
}
2024-04-08 15:44:33 +02:00
$status = ( $values [ 'operator' ]( ! empty ( $values [ 'section' ]) ? $ { $values [ 'section' ]}[ $name ] : ${$name} , $values [ 'value_to_check' ]) ? 1 : 0 );
2023-08-04 14:54:28 +02:00
2023-07-17 17:51:11 +02:00
$config [] = [
'name' => $name ,
'description' => $description ,
'status' => $status ,
'type' => tr ( 'Configurazione' ),
];
}
2018-06-27 14:25:19 +02:00
$requirements = [
2024-02-22 15:58:03 +01:00
tr ( 'Apache (_INTERFACE_)' , [
2024-03-22 15:52:24 +01:00
'_INTERFACE_' => $php_interface ,
2024-02-22 01:09:14 +01:00
]) => $apache ,
2022-02-07 13:36:31 +01:00
tr ( 'PHP (_VERSION_ _SUPPORTED_)' , [
2018-06-27 14:25:19 +02:00
'_VERSION_' => phpversion (),
2024-05-16 18:02:50 +02:00
'_SUPPORTED_' => (( version_compare ( phpversion (), $settings [ 'php_version' ][ 'minimum' ], '>=' ) && version_compare ( phpversion (), $settings [ 'php_version' ][ 'maximum' ], '<=' )) ? '' : '<small> <span class="right badge badge-danger" ><i class="fa fa-warning"></i> ' . tr ( 'versioni supportate:' ) . ' ' . $settings [ 'php_version' ][ 'description' ] . '</small></small>' ),
2018-06-27 14:25:19 +02:00
]) => $php ,
2024-03-02 02:52:30 +01:00
tr ( 'DBMS (_TYPE_)' , [
2024-03-15 13:17:23 +01:00
'_TYPE_' => method_exists ( $database , 'getType' ) ? $database -> getType () : '' ,
2024-03-22 15:52:24 +01:00
]) => $mysql ,
2018-06-27 14:25:19 +02:00
tr ( 'Percorsi di servizio' ) => $directories ,
2022-11-28 19:37:24 +01:00
tr ( 'File di servizio' ) => $files ,
2023-07-17 17:51:11 +02:00
tr ( 'Configurazioni' ) => $config ,
2018-06-27 14:25:19 +02:00
];
2023-08-04 14:54:28 +02:00
if ( ! $database -> isInstalled () || empty ( $mysql )) {
2024-03-15 10:47:24 +01:00
unset ( $requirements [ tr ( 'DBMS (_TYPE_)' , [
'_TYPE_' => $database -> getType (),
2024-03-22 15:52:24 +01:00
])]);
2022-03-10 17:29:24 +01:00
}
2018-06-27 14:25:19 +02:00
// Tabelle di riepilogo
foreach ( $requirements as $key => $values ) {
$statuses = array_column ( $values , 'status' );
$general_status = true ;
foreach ( $statuses as $status ) {
$general_status &= $status ;
}
echo '
2024-08-07 09:34:28 +02:00
< div class = " card card-outline card-'.( $general_status ? 'success collapsed-card' : 'danger').' " >
2024-05-16 18:02:50 +02:00
< div class = " card-header with-border " >
< h3 class = " card-title " > '.$key.' </ h3 > ' ;
2018-06-27 14:25:19 +02:00
if ( $general_status ) {
echo '
2024-05-16 18:02:50 +02:00
< div class = " card-tools pull-right " >
2024-08-07 09:34:28 +02:00
< button type = " button " class = " btn btn-tool " data - card - widget = " collapse " >
2018-06-27 14:25:19 +02:00
< i class = " fa fa-plus " ></ i >
</ button >
</ div > ' ;
}
echo '
</ div >
2024-05-16 18:02:50 +02:00
< div class = " card-body no-padding " >
2018-06-27 14:25:19 +02:00
< table class = " table " > ' ;
foreach ( $values as $value ) {
echo '
< tr class = " '.( $value['status'] ? 'success' : 'danger').' " >
< td style = " width: 10px " >< i class = " fa fa-'.( $value['status'] ? 'check' : 'times').' " ></ i ></ td >
2022-11-28 19:37:24 +01:00
< td style = " width: 120px " > '.$value[' type '].' </ td >
2023-12-27 14:43:10 +01:00
< td style = " width: 300px " > '.$value[' name '].' </ td >
2018-06-27 14:25:19 +02:00
< td > '.$value[' description '].' </ td >
</ tr > ' ;
}
echo '
</ table >
</ div >
</ div > ' ;
}