/* ------------------------- FUNZIONI di servizio ---------------------- */
function is_404() {
global $DATI, $is_404;
if($is_404 === TRUE) return TRUE;
if($DATI['indi_404'] === 1) return TRUE;
return FALSE;
}
function random_color_part() {
return str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
}
function random_color() {
return random_color_part() . random_color_part() . random_color_part();
}
// funzione by tux per controllare se siamo loggati come tnx, da usare quando si personalizzazno gli editfields
// function isLoggedAdminTnx($groupId = null) {
// }
function indi_redirect($link, $tipo=null, $extra=null) {
if($GLOBALS["CONF"]["chi_sono"] == "noi" && $GLOBALS['CONF']['force_no_redirect'] == "SI"){
//disattivo il redirect se devo vedere degli errori a video
trigger_error("Disattivato redirect per visualizzare l'errore (SOLO TNX), dovevo andare a: ".$link);
return;
}
if($tipo == "meta"){
$time = is_null($extra)?'0':$extra;
$link = indi_htmlentities($link);
if(!$time){
indiObCleanAll();
if($GLOBALS["DATI"]['sito'] == 'ordinalo') indi_log("Headers al meta redirect: ".implode("|", headers_list()));
die("
");
}
else{
$GLOBALS['DATI']['head:'] = "VIS";
return true;
}
}
session_write_close();//provato a mettere dopo gli altri header per la sessione pagamento che salta su ordinalo con auth_login_stay_on_page
if($tipo == "permanent") header("HTTP/1.1 301 Moved Permanently");
header("Location: ".$link);
// if($GLOBALS["DATI"]['sito'] == 'ordinalo') indi_log("Headers al redirect: ".implode("|", headers_list()));
die();
}
function indi_redirect_permanent_pagina($pagina, $lingua=null, $agg=null) {
return indi_redirect_permanent(genera_link($pagina, $lingua, $agg));
}
function indi_redirect_permanent($link) {
return indi_redirect($link, "permanent");
}
function indi_redirect_premanent($link){//compatibilità nome fail
return indi_redirect_permanent($link);
}
function indi_redirect_meta($link) {
return indi_redirect($link, "meta");
}
function indi_redirect_pagina($pagina=null, $lingua=null, $agg=null, $ancora=null, $tipo="") {
return indi_redirect(str_replace("&","&",$GLOBALS['CONF']['redirects_genera_link']($pagina, $lingua, $agg, $ancora)), $tipo);
}
function indi_redirect_pagina_permanent($pagina, $lingua=null, $agg=null, $ancora=null){
return indi_redirect_pagina($pagina, $lingua, $agg, $ancora, "permanent");
}
function indi_redirect_pagina_meta($pagina, $lingua=null, $agg=null, $ancora=null){
return indi_redirect_pagina($pagina, $lingua, $agg, $ancora, "meta");
}
function indi_redirect_agg($pagina=null, $lingua=null, $agg=null){
return indi_redirect(genera_link_agg($pagina, $lingua, $agg));
}
/* -------------------------- gestione azioni / filtri e sovrascritture ------------------------------------
vedi anche: http://demo.tnx.it/test/it/action/
Funzionamento:
In pratica ci sono dei punti chiamati hook, sui quali si puo' registrare una funzione tramite indi_add_action e questa viene eseguita in quello specifico punto.
Caratteristiche:
- Aggiunta hook
indi_do_action(NOME_HOOK);
- Esecuzione funzione su hook, possibili anche funzioni multiple sullo stesso hook con gestione della priorità, non obb. (default 10)
indi_add_action(HOOK, NOME_FUNZIONE, PRIORITA);
- Possibilità di rimuovere una funzione legata ad un hook specifico
indi_remove_action(NOME_FUNZIONE);
Esempio:
indi_add_action("pre_template","_funzione_da_eseguire");
function _funzione_da_eseguire() {
//codice funzione
}
Esempio futuro nel caso di PHP >= 5.3 con l' utilizzo di funzioni anonime
indi_add_action("pre_template", _funzione_da_eseguire() {
//codice funzione
});
Lista di hook base del core di indi
pre_conf
post_conf
post_setup
pre_menu
post_menu
pre_routing
post_routing
pre_module
post_module
pre_include
post_include
pre_template
post_template
post_output
*/
$ACTIONS = array();
function indiCallCached($func, $args){
$key = serialize(func_get_args());
if(!$GLOBALS['indiCallCachedCache'][$key]) $GLOBALS['indiCallCachedCache'][$key] = call_user_func_array($func, $args);
return $GLOBALS['indiCallCachedCache'][$key];
}
function indi_add_action($hook, $func, $pri = 10) {
global $ACTIONS;
$pri = (int) $pri; //converto in interno
$new = array('hook' => $hook,'func' => $func, 'pri' => $pri,'called'=>0);
$ACTIONS['hook'][$hook][$pri][] = $func; //array hook
$ACTIONS['func'][$func] = $new; //array info funzioni
$ACTIONS['count']++; //contatore globale chiamata funzione
//ordino in base alle chiavi
if($ACTIONS['count']) ksort($ACTIONS['hook'][$hook],SORT_NUMERIC);
//$ACTIONS[$hook][$pri] =
}
//rimuovo la funzione
function indi_remove_action($func) {
global $ACTIONS;
if($GLOBALS["CONF"]["DEBUG"] == "SI" or is_tnx_locale()) d_info("Rimuovo hook: '$hook'","indi_remove_action($hook)");
if(is_array($ACTIONS['func'][$func])) unset($ACTIONS['func'][$func]);
else d_err("Non esiste funzione '$func' da rimuovere!","indi_remove_action($func)");
}
//esegue le varie funzioni se presenti
function indi_do_action($hook,$parametri=array()) {
global $ACTIONS;
//salvo azione
if($ACTIONS && (!is_array($ACTIONS['hook']) || !is_array($ACTIONS))) {
trigger_error("Qui ci sarà un fatal!");
}
if(is_array($ACTIONS['hook'][$hook])) {
foreach($ACTIONS['hook'][$hook] as $action) {
foreach($action as $func) {
//debug
if($GLOBALS["CONF"]["DEBUG"] == "SI" or is_tnx_locale()) d_info("Eseguo funzione: '$func'","indi_do_action($hook)");
//logging da fare
//controllo che l' la funzione non sia stata rimossa da indi_remove_action()
if(is_array($ACTIONS['func'][$func])) {
if( function_exists($func) ) {
$ACTIONS['current_action'] = $func;
$ACTIONS['current_hook'] = $hook;
call_user_func_array($func,$parametri);
$ACTIONS['log'][] = $hook." -> ".$func."()";
$ACTIONS['func'][$func]['called']++;
} else {
d_err("Non esiste la funzione: '$func'","indi_do_action($hook)");
}
}
}
}
return TRUE;
} else {
//non faccio niente
return TRUE;
}
}
/*
#######
BLOCCHI
#######
I blocchi sono include di file fisici richiamabili tramite una funzione, e danno la possibilità di avere una funzione wrapper (che avvolge) il codice di visualizzazione di di un sito
- Prevede l' uso di file fisico che permette quindi un integrazione rapida, un riutilizzo facile del codice, e un maggior controllo del codice stesso.
- A differenza di una funzione il codice di un blocco puo' essere copiato e incollato su un codice preesistente, questo permette un riutilizzo del codice all' esterno del blocco.
- La possibilità di parametrizzazione ne consente un utilizzo piu' vasto come una funzione e quindi un riutilizzo maggiore rispetto ad un include.
- La bunzione blocco usa la cattura dell' output, quindi è possibile scriverci come se fosse un vero include
- Import automatico variabili globali come un include ma a differenza di un include le variabili rimangono locali come in una funzione.
- Possibilità di integrazione tramite ajax con log e controllo errori
impostazioni globali (indi.inc.php / template / menu / pagina)
---------------------------------------------------------------------
Sono variabili di configurazione globali, ereditate da tutti i blocchi:
$CONF['block_include_dir'] = NULL; //(cartella o cartelle nelle quali cercare i blocchi) stringa separata da , o array
$CONF['block_cache'] = "NO"; [NO|SI|numero_in_secondi > 0] //attiva la cache per tutti i blocchi, default vedi sotto
//$CONF['block_cache_time'] = 60*60*2; //variabile globale per il tempo della cache del blocco, default uguale a $CONF['indi_apc_time'] (30 min)
$CONF['block_cache_key'] = NULL; //variabile globale per invialidare la cache di tutti i blocchi contemporaneamente
$CONF['block_cache_all'] = true|false; //cache tutti i blocchi di default (non usato se non per debug)
============================================
block( NOME_FILE, PARAMETRI, ABSOLUTE );
============================================
NOME_FILE
------------------------
E' il nome del file con o senza estensione, puo' contenere variabili di template automaticamente sostituite, si possono specificare piu' file contemporaneamente, l' ordine di ricerca in squenza, il file è cercato all' interno della directory $CONF[block_include_dir]
es:
block("mappa");
block("mappa.php");
block("mappa-{pagina},mappa"); //Cerca il blocco "mappa-{pagina}", se non viene trovato include il blocco "mappa"
PARAMETRI
----------------------------
Si possono specificare sia come ARRAY o come stringa (sintassi come quelli di un url)
es:
block("mappa-box",array("gps"=>"43,12")) //sintassi con array
block("mappa-box","gps=43,12") //sintassi alternativa con stringa tipo url
PARAMETRI riservati
----------------------------
- $block_param['cache'] [NO|SI|numero_in_secondi > 0] //attiva la cache per tutti i blocchi, se specificato un numero questo indica il numero di secondi es: 60
- $block_param['cache_key'] //key per la cache del blocco
- $block_param['param_import'] //array aggiuntivo di parametri, per evitare l' array merge
ABSOLUTE / alias: block_absolute( NOME, PARAMETRI );
-------------------------------------------------------------
Puo assumere valore TRUE / FALSE, di default è FALSE
Se impostato a TRUE viene ignorato il parametro $CONF[block_include_dir], e l' inclusione è realizzata partendo dalla root del sito, e' quindi necessario specificare il path relativo completo
es:
block_absolute("_pagine/mappa.inc.php")
variabili impostabili internamente al blocco
-------------------------------------------------------------
- $block_return // forza il return del blocco, senno' di default torna l' output, ATTENDIONE dentro al blocco non e' permesso tornare niente con la direttiva 'return'!
- $block_id [block_id] //id random univoco del blocco, "bid_".md5(mt_rand(1,1000000))
- $block_name o [block_name] //nome del file del blocco senza ".php" finale,
- $block_file_inc //nome del file con estensione completa
============================================
block_ajax( NOME, PARAMETRI);
============================================
Stessa sintassi della funzione block(), ma include il blocco tramite ajax
"ajax_loading" => '', //immagine di loading
"ajax_pagina" => "ajax", // pagina usata dal genera_link alla quale arriva la richiesta ajax
"ajax_action" => "block", // la pagina ajax_pagina viene richiamata con il seguende parametro action=ajax_action
"ajax_timeout" => 10000, // timeout ajax dopo il quale la richiesta Abortisce
"ajax_delay" => 10000, // ritardo nella chiamata ajax
"ajax_class" => NULL, // classe aggiuntiva specifica
"ajax_id" => NULL, // id alternativo nel caso di blocchi ripetuti
*/
/* variabili globali blocchi
mettere tutto in un array
*/
$BLOCK = array();
$_block_include_dir_array = array();
$_block_include_dir_array_ordinato = array();
$_block_included = array();
$_block_included_ajax = array();
$_block_included_name = array();
$_block_included_log = array();
$_block_included_current = NULL;
$_block_included_prev = NULL;
$_block_included_parent = NULL; /* da fare */
$_block_included_structure_level = 0;
$_block_included_structure_level_old = 0;
$_block_included_count = 0;
function block_add_dir($dir, $priorita = 10){
global $_block_include_dir_array, $_block_include_dir_array_ordinato, $BLOCK;
if(!is_array($_block_include_dir_array[$dir])) {
$_block_include_dir_array[$dir] = $priorita;
$_block_include_dir_array_ordinato[$priorita][] = $dir;
ksort($_block_include_dir_array_ordinato,SORT_NUMERIC);
}
//array ordinato
$BLOCK['dir'] = array();
foreach($_block_include_dir_array_ordinato as $k => $v){
foreach($v as $kk => $vv){
$BLOCK['dir'][] = $vv;
}
}
return true;
}
function block_include_dir(){
global $BLOCK;
return (array) $BLOCK['dir'];
}
/* alias di block include */
function block() {
$param = func_get_args();
return call_user_func_array("block_include", $param);
}
/* DAusa un percorso assoluto per includere il blocco */
function block_absolute() {
$param = func_get_args();
return call_user_func_array("block_include", $param,true);
}
/* usa un percorso assoluto per includere il blocco */
function block_include_absolute() {
$param = func_get_args();
return call_user_func_array("block_include", $param,true);
}
function block_log() {
}
/* crea un div come placeholder html per la chiamata ajax che andrà poi a sostituire il contenuto */
function block_ajax() {
if($GLOBALS["DATI"]["deferAllScript"]) trigger_error("non usare block_ajax() con deferAllScript perchè usa un valore random che genererebbe infiniti files");
//parametri specifici ajax
$param_ajax = array(
"ajax" => "1",
"ajax_loading" => '', /* immagine di loading */
"ajax_pagina" => "ajax",
"ajax_action" => "block",
"ajax_timeout" => 10000,
"ajax_delay" => 0,
"ajax_class" => NULL,
"ajax_id" => NULL,
"ajax_type" => "GET",
);
//id univoco se non specificato */
if(!$_block_ajax_id) $_block_ajax_id = "ajax_bid_".md5(mt_rand(1,1000000));
else $_block_ajax_id = $param_ajax['id'];
//parametri originali
$param_func_orig = func_get_args();
//log chiamate ajax pagina
$GLOBALS['_block_included_ajax'][$_block_ajax_id] = $param_func_orig;
//serializzo la richiesta originale
$_block_ajax_serialize_param = http_build_query($param_func_orig);
//$_block_ajax_serialize_param = http_build_str($param_func);
//aggiungo parametri ajax
$param_func[0] = $param_func_orig[0];
$param_func[1] = array_merge((array)$param_ajax,(array)$param_func_orig[1]);
//javascript con logging e report errori in locale
if(is_tnx_locale()) $_ajax_error = 'if(error1.status != 200) {console.log(error1); $("#'.$_block_ajax_id.'").html("
';
}
else console_log("OutputDatiCache attiva: ".$cacheKey);
indiOutputDatiCacheMerge($cacheData[1], $cacheData[2]);
}
return $html;
}
function indiOutputDatiCache($cacheKey, $time, $outputFunction){
//controllo se c'è una versione in cache, se c'è viene restituito l'html e vengono sincronizzate le modifiche a $DATI
$return = indiOutputDatiCacheGet($cacheKey);
if(!$return){
//attivo la registrazione delle modifiche a $DATI
indiOutputDatiCachePrepareSet();
//dopo il prepare non devo modificare direttamente $DATI, ma usare le funzioni:
//datiAdd($chiave, $valore, $forzaSovrascrittura = false) e datiGet($chiave)
$return = $outputFunction();
//salvo in cache l'html e le modifiche a $DATI, viene anche fatto un controllo per eventuali modifiche dirette a $DATI
indiOutputDatiCacheSet($cacheKey, $return, $time);
}
//mando in output l'html
return $return;
}
function array_map_recursive($callback, $array){
return filter_var($array, FILTER_CALLBACK, array('options' => $callback));
}
function array_diff_assoc_recursive($array1, $array2){//array_diff_recursive
foreach($array1 as $key => $value){
if(is_array($value)){
if(!isset($array2[$key]))
{
$difference[$key] = $value;
}
elseif(!is_array($array2[$key]))
{
$difference[$key] = $value;
}
else
{
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if($new_diff != FALSE)
{
$difference[$key] = $new_diff;
}
}
}
elseif((!isset($array2[$key]) || $array2[$key] != $value) && !($array2[$key]===null && $value===null))
{
$difference[$key] = $value;
}
}
return !isset($difference) ? false : $difference;
}
// se non c'e' APC tento di usare xcache
if( !function_exists( 'apc_store' ) ) {
function apc_exists( $k ) {
return indiSiteCacheIsset($k);
}
function apc_store( $k , $d , $t = 0) {
// fare eventuale workaround per valori NULL
//if($d === NULL) d_err("apc_store() wrapper, errore non si puo' salvare un valore NULL! ","indi_cache");
//if($d === NULL) $d = "NULL";
if($d === null) return false;
return indiSiteCacheSet( $k , $d , $t );
}
// in xcache_get non c'e' un modo per sapere il risultato (secondo parametro)
function apc_fetch( $k , &$r=NULL) {
if(func_num_args() > 1) $r = indiSiteCacheIsset($k );
// ritorno false x compatibilità visti che apc_fetch torna false se non c'e' il valore
// viene da se che non si puo' salvare un valore nullo, metto un warning in apc_store
$ret = indiSiteCacheGet($k);
if($ret === NULL) return FALSE;
//if($ret === "NULL") return NULL;
else return $ret;
}
function apc_delete( $k ) {
return indiSiteCacheUnset( $k );
}
}
function indi_apc_store($key, $value, $time = 0){//solo per uniformare i nomi
return apc_store($key, $value, $time);
}
function indi_apc_fetch($cache_key){
if(!$_GET['no_cache']) return apc_fetch($cache_key);
return false;
}
/* -------------------------- CACHE FILESYSTEM ------------------------------------
Cache permanente su filesystem:
- indi_filecache_store($chiave, $valore, $scadenza = 0)
- indi_filecache_fetch($chiave,&$success)
- indi_filecache_delete($chiave)
- indi_filecache_exists($chiave)
ATTENZIONE:
- Chiave non puo' essere nulla
- Non immagazzinare valori booleani nella cache, oppure usare il secondo parametro della funzione indi_cache_fetch() per avere l' esito del risultato
ESEMPIO:
http://demo.tnx.it/test/it/cache/
*/
function indi_filecache_info($chiave, $ext = ".txt", $func = "md5") {
global $CONF;
$_custom_cache_dir = indi_basepath().$CONF['dir_indi']."cache";
if(!is_dir($_custom_cache_dir)) {
if(mkdir($_custom_cache_dir)) {
// bloccaAccessiConHtaccess($_custom_cache_dir);
indi_log("indi_filecache_init()");
d_info("indi_filecache_init","indi_cache");
} else {
d_err("indi_filecache_init() non riesco a creare la cartella '$_custom_cache_dir'","indi_cache");
}
}
return $_custom_cache_dir."/".$func($chiave).$ext;
}
function bloccaAccessiConHtaccess($dir) {
$file = $dir."/.htaccess";
if(!is_file($file)) file_put_contents($file, "Require all denied");
}
function indi_filecache_init() {
trigger_error("funzione rimossa");
}
function indi_filecache_delete($chiave) {
//nome del file
$_custom_cache_file = indi_filecache_info($chiave);
d_info("indi_get_cache_file($chiave): Cancello file '$_custom_cache_file'","indi_cache");
return unlink($_custom_cache_file);
}
function indi_filecache_exists($chiave) {
indi_filecache_fetch($chiave,$stato);
return $stato;
}
function indi_filecache_add($chiave, $valore, $scadenza = 0) {
indi_filecache_fetch($chiave,$stato);
if($stato == TRUE) {
return FALSE;
} else {
return indi_filecache_store($chiave,$valore,$scadenza);
}
}
//salva sempre
function indi_filecache_store($chiave, $valore, $scadenza = 0) {
//nome del file
$_custom_cache_file = indi_filecache_info($chiave);
$out = file_put_contents($_custom_cache_file, serialize(array($valore,$chiave,$scadenza)));
if($out === FALSE) {
d_err("indi_set_cache_file($chiave,VALORE,$scadenza): errore creazione file di cache","indi_filecache");
return FALSE;
}
else d_info("indi_filecache_store($chiave): Scrivo file '$_custom_cache_file'","indi_cache");
return TRUE;
}
function indi_filecache_fetch($chiave, &$success = NULL) {
$_custom_cache_file = indi_filecache_info($chiave);
if(is_file($_custom_cache_file)) {
$out = unserialize(file_get_contents($_custom_cache_file));
$creazione = (int) filemtime($_custom_cache_file);
$chiave_stored = $out[1];
$scadenza = (int) $out[2];
//se non è scaduto ed è la stessa chiave
if($chiave_stored == $chiave and ($scadenza === 0 or ($creazione + $scadenza > time()))) {
d_info("indi_filecache_fetch($chiave): Leggo file '$_custom_cache_file'","indi_cache");
$success = TRUE;
return $out[0];
//se scaduto, cancello ?? da fare con garbage collector ?
} else {
indi_filecache_delete($chiave);
$success = FALSE;
return FALSE;
}
}
$success = FALSE;
return FALSE;
}
function indiSiteFileCachePath($key){
return indi_filecache_info($key, ".php", "indiSoloAlfanumerici");
}
//https://medium.com/@dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad
function indiSiteFileCacheSet($key, $val, $expire = 0){
$path = indiSiteFileCachePath($key);
if(gettype($val) == "object" && !method_exists($val, "__set_state")){
// $val = str_replace('stdClass::__set_state', '(object)', $val);
trigger_error("Per cachare un oggetto definire metodo statico __set_state (oppure convertire in array)");
return false;
}
$tmp = $path . uniqid('', true) . '.tmp';// Write to temp file first to ensure atomicity
file_put_contents($tmp, '', LOCK_EX);
rename($tmp, $path);
return touch($path, time()+($expire?$expire:86400*365));
}
function indiSiteFileCacheGet($key, &$success = null){
if($path = indiSiteFileCacheIsset($key)){
include $path;
if(isset($val)){
$success = true;
return $val;
}
else{
$success = false;
return;
}
}
else{
$success = false;
return;
}
}
function indiSiteFileCacheIsset($key){
$path = indiSiteFileCachePath($key);
if(!is_file($path)) return;
else if(filemtime($path) < time()){
unlink($path);
return;
}
else return $path;
}
/* -------------------------- less ------------------------------------ */
function less_generate_output_exist($path){
global $DATI;
if($DATI['less_evita_generazioni_contemporanee']){
$i = 0;
$sleep = 0.5;
$max = 10;
$maxI = $max / $sleep;
while(!filesize($path)){
usleep($sleep*1000000);
clearstatcache();//filesize cacha
if($i++ > $maxI){
trigger_error("Sto aspettando da $max secondi less_generate_output, carico la pagina e cancello il file, controllare $path");
unlink($path);//verrà rigenerato e non dovrebbe essere possibile più generare che sia generato un file di 0 byte
return;//non deve arrivare al touch sotto!
}
}
}
touch($path);//aggiorno data per il nostro script che cancella i css vecchi
}
//risparmio memoria se metto dentro funzione
function less_generate_output($lessSrc, $fullPath) {
global $DATI;
//creo il file prima di generare il contenuto per evitare di fare una doppia generazione in caso di visite contemporanee
//attenzione: è necessario chiamare anche less_generate_output_exist per non caricare la pagina fino a che la generazione del file css non è completata
//altrimenti il browser carica il file vuoto e sopratutto lo tiene in cache per l'intera sessione (nostro cache header per i css)
if($DATI['less_evita_generazioni_contemporanee']) touch($fullPath);
// sleep(1);
if($DATI['dove_sono'] == 'loc') $lesstime = -microtime(true);
//if($GLOBALS["DATI"]['sito'] == "sito_turismo_new" and is_online()) include_once($GLOBALS["DATI"]['dir_lib'].'lessphp-0.3.4/lessc.inc.php');
//else include_once($GLOBALS["DATI"]['dir_lib'].'lessphp-latest/lessc.inc.php');
include_once($GLOBALS["DATI"]['dir_lib'].'lessphp-latest/lessc.inc.php');
//include_once($GLOBALS["DATI"]['dir_lib'].'less.php-master/lessc.inc.php');
//include_once($GLOBALS["DATI"]['dir_lib'].'lessphp2.0/lessc.inc.php');
d_info("Include","LESS","INDI");
$less = new lessc();
try {
if($GLOBALS["CONF"]["DEBUG"] == "SI") {
$less_time = indi_time();
d_info("compile","LESS","INDI");
d_info("baseurl=".indi_baseurl(),"LESS","INDI");
d_info("cdn_baseurl=".indi_cdn_baseurl(),"LESS","INDI");
}
//Psso alcune variabili globali di indi x include css
$less->setVariables(
array(
"baseurl" => "'".indi_baseurl()."'",
"cdn_baseurl" => "'".indi_cdn_baseurl()."'"
)
);
if($GLOBALS["CONF"]["DEBUG"] == "SI") {
d_info("DATI[less_import_dir]=".$GLOBALS["DATI"]["less_import_dir"],"LESS","INDI");
}
if($GLOBALS["DATI"]["less_import_dir"]) $less->setImportDir($GLOBALS["DATI"]["less_import_dir"]) ;
$less_out = trim($less->compile($lessSrc));
//fix per CDN
$less_out = str_replace("http://demo.tnx.it/cdn/",$GLOBALS["DATI"]['cdn_baseurl'],$less_out);
//debug e log
$less_time = round((indi_time()-$less_time)*10)/10;
$less_size = strlen($less_out);
if($GLOBALS["CONF"]["DEBUG"] == "SI") {
indi_log("Size: ".$less_size,"LESS","INDI");
d_info("End compile ($less_time)","LESS","INDI");
}
indi_log("less_generate_output: LESS Compilo e salvo ($less_time, $less_size, $fullPath, $DATI[indi_device])");
if($DATI['minifyCss']){
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Minify.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/CSS.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/JS.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Exception.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Exceptions/BasicException.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Exceptions/FileImportException.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Exceptions/IOException.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/ConverterInterface.php';
require_once $GLOBALS["DATI"]['libPath'] . '/minify/src/Converter.php';
$minifier = new MatthiasMullie\Minify\CSS($sourcePath);
$minifier->add($less_out);
$less_out = trim($minifier->minify());
}
// $less_out .= "\n/*"."http".(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 's' : '')."://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']."*/";
if(!$less_out && $DATI['less_evita_generazioni_contemporanee']){
// print '
//
' .$fullPath . '
//
' . $lessSrc . '
//
'. $less_out . '
//
';
// die;
trigger_error_to_email("marco@tnx.it", "La compilazione less non ha generato output per $fullPath (usa ?lessSeparateDebug=1 per controllo sorgenti)");
$less_out = '/*';
}
if($_GET['lessSeparateDebug']){
echo "OUTPUT:\n".$less_out;
}
$return = file_put_contents($fullPath, $less_out);
// if($DATI['dove_sono'] == 'loc') console_log("rigenerato ".array_pop(explode("/", $fullPath))." in ".round(($lesstime+microtime(true))*1000)."ms");
return $return;
} catch (Exception $ex) {
d_err("less->parse ERROR: ".$ex->getMessage()." (aggiungi ?debugtnx=1&no_less_cache=1 per vedere il file che sto provando a compilare)");
if($_GET['debugtnx']){
echo '
';
die;
}
return false;
}
}
function indiRemoveEmoji($text) {
$clean_text = "";
// Match Emoticons
$regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
$clean_text = preg_replace($regexEmoticons, '', $text);
// Match Miscellaneous Symbols and Pictographs
$regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
$clean_text = preg_replace($regexSymbols, '', $clean_text);
// Match Transport And Map Symbols
$regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
$clean_text = preg_replace($regexTransport, '', $clean_text);
// Match Miscellaneous Symbols
$regexMisc = '/[\x{2600}-\x{26FF}]/u';
$clean_text = preg_replace($regexMisc, '', $clean_text);
// Match Dingbats
$regexDingbats = '/[\x{2700}-\x{27BF}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
// Match Flags
$regexDingbats = '/[\x{1F1E6}-\x{1F1FF}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
// Others
$regexDingbats = '/[\x{1F910}-\x{1F95E}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
$regexDingbats = '/[\x{1F980}-\x{1F991}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
$regexDingbats = '/[\x{1F9C0}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
$regexDingbats = '/[\x{1F9F9}]/u';
$clean_text = preg_replace($regexDingbats, '', $clean_text);
return $clean_text;
}
/* -------------------------- FILESYSTEM ------------------------------------ */
//trova estensione di un file, da gestire caso estensione nulla
function indi_estensione_file ($f)
{
$ext = substr($f, strrpos($f,".") + 1);
return strtolower($ext);
}
//ripulisce da caratteri strani un nome di file
function indi_pulisci_nome_file($file) {
$dir = pathinfo($file,PATHINFO_DIRNAME);
if($dir) $dir .= "/";
$file = pathinfo($file,PATHINFO_BASENAME);
$file = preg_replace("/[^a-z0-9\s_\-\.]/i", "",$file);
return $dir.$file;
}
//ripulisce il nome di un file
function indi_nome_file($file) {
return pathinfo($file,PATHINFO_FILENAME);
}
//cancella una cartella e tutto il suo contenuto, controlare la ricorsione
function indi_del_dir($dirname) {
if (is_dir($dirname))
{
if ($handle = @opendir($dirname))
{
while (($file = readdir($handle)) !== false)
{
if ($file != "." && $file != "..")
{
$fullpath = $dirname . '/' . $file;
/*
if (is_dir($fullpath))
{
remove($fullpath);
@rmdir($fullpath);
}
else
{
@unlink($fullpath);
}
*/
unlink($fullpath);
}
}
closedir($handle);
rmdir($dirname);
return TRUE;
}
} return FALSE;
}
//---nuove sub ver > 5
/* -------------------------- RETE ------------------------------------ */
//controlla se un IP e' un una lista RBL
function indi_ip_in_rbl($ip, $server, $timeout=1) {
d_info("Inizio","indi_ip_in_rbl($ip,$server)","INDI");
$response = array();
$host = implode(".", array_reverse(explode('.', $ip))).'.'.$server.'.';
$cmd = sprintf('nslookup -type=A -timeout=%d %s 2>&1', $timeout, escapeshellarg($host));
exec($cmd, $response);
d_info("Fine","indi_ip_in_rbl","INDI");
// The first 3 lines (0-2) of output are not the DNS response
for ($i=3; $iread())){
$fullPath = $path."/".$entry;
if(is_file($fullPath) && (!$regexp || preg_match($regexp, $entry)) && (!$maxAge || ((time()-filectime($fullPath)) > $maxAge))){
unset($fullPath);
}
}
$d->close();
}
function indi_redirect_with_session($url){
indi_redirect(indi_session_duplicate_url($url));
}
function indi_session_duplicate_url($url){
$_SESSION['tokenSessioneIndi'] = mt_rand();
$_SESSION['tokenSessioneIndiScandenza'] = time() + 30;
$url .= strpos($url, "?") !== false ? "&" : "?";
return $url . "token=" . $_SESSION['tokenSessioneIndi'] . "&sessionId=" . session_id();
}
function indi_session_destroy(){
$GLOBALS['indi_session_start'] = false;
session_destroy();
}
//funzione per start sessione una sola volta
function indi_session_start(){
global $CONF, $indiRedirectDaFare;
if($CONF["SESS"] == "SI" and !isset($_REQUEST["no_sess"])) {
if(!$GLOBALS['indi_session_start']){
$name = ini_get("session.name");
$path = indi_cookie_path();
$validaToken = false;
//impostavo manualmente il session id per swfupload in area protetta (problema sicurezza forse)
// if (isset($_POST["PHPSESSID"])) {
// trigger_error("Uso di swfupload o tentativo di hack sessione");
// session_id($_POST["PHPSESSID"]);
// }
if($_GET['sessionId'] && $_GET['token']){
session_id($_GET["sessionId"]);
$validaToken = $_GET['token'];
}
if(isset($_REQUEST["sessioneStampa"])){//deve essere passato come parametro standard (&sessioneStampa=) perchè scatta prima del parsing dei parametri della rewrite (ricordarsi anche di chiudere prima la sessione se è una server su server altrimenti si blocca tutto in attesa del termine della prima richiesta)
session_id($_REQUEST["sessioneStampa"]);
}
d_info("indi_session_start 1","INFO","INDI");
/**************************************************************************************************/
/******************* tenere in sync con admin_tnx (controller->constructClasses()) ****************/
/**************************************************************************************************/
if($CONF['SESSIONI_IN_CARTELLA_INDI'] || $CONF['DURATA_SESSIONE']){//
//inizializzazione creazione cartella e .htaccess, una volta sola
$custom_session_dir = $CONF['path_base'].$CONF['dir_indi']."sessions";//tenere in sync con app_controller > constructClasses
if(!is_dir($custom_session_dir)) {
mkdir($custom_session_dir);
// bloccaAccessiConHtaccess($custom_session_dir);
}
ini_set("session.save_path", $custom_session_dir);//separo le sessioni di questo sito dagli altri per far funzionare il gc
//15/2/2018 TESTATO CHE IL GARBAGE COLLECTOR "GIRA" NELLA DIRECTORY CUSTOM
// indiPulisciDirectory($custom_session_dir, $CONF['DURATA_SESSIONE']?$CONF['DURATA_SESSIONE']:86400, "/sess.*/");
/* paramtri default php (non c'è bisogno di risettarli):
ini_set("session.gc_probability", 1);//frequenza gc: 1 volta...
ini_set("session.gc_divisor", 100); //...ogni 100 visite
ini_set("session.gc_maxlifetime", 1440); //durata standard
*/
//cecca 06/02/2024 , no in realtà è disabilitato per default, quindi riabilito
ini_set("session.gc_probability", 1);//frequenza gc: 1 volta...
ini_set("session.gc_divisor", 100); //...ogni 100 visite
}
d_info("indi_session_start 2","INFO","INDI");
if($CONF['DURATA_SESSIONE']){
ini_set('session.cookie_lifetime', $CONF['DURATA_SESSIONE']); //allungo la vita del cookie
if($_COOKIE[$name]) setcookie($name, $_COOKIE[$name], time()+$CONF['DURATA_SESSIONE'], $path);//rinnovo il cookie se c'è già
ini_set('session.gc_maxlifetime', $CONF['DURATA_SESSIONE']); //allungo la vita del file di sessione
if(session_status() == PHP_SESSION_ACTIVE) session_regenerate_id();//se la sessione è già partita risetta il cookie con i nuovi parametri
}
//tipo di cache di sessione
// indi_session_cache("SI");
ini_set('session.cookie_path', $path);
d_info("indi_session_start 3","INFO","INDI");
/*******************************************************************************************************/
/******************* FINE tenere in sync con admin_tnx (controller->constructClasses()) ****************/
/*******************************************************************************************************/
if(!preg_match("/^[a-z0-9\-]+$/i", $_COOKIE[$name])) @session_start();//carlo: sopprimo errore perchè a volte ci sono utenti col cookie vuoto, forse qualche programma per privacy aggiuntiva oppure anche roba del tipo [PHPSESSID] => A2~me7eme011lrkefsn3s8gnvm324
else session_start();
d_info("indi_session_start 4","INFO","INDI");
if($validaToken){
$errore = false;
if($validaToken != $_SESSION['tokenSessioneIndi']){
$errore = "non autorizzato";
}
else if(time() > $_SESSION['tokenSessioneIndiScandenza']){
$errore = "scaduto";
}
if($errore){
trigger_error("Tentativo di passaggio sessione tra siti ".$errore);
indi_session_destroy();
return false;
}
unset($_SESSION['tokenSessioneIndi']);
$indiRedirectDaFare = array(null, null, array('sessionId'=>'', 'token'=>''));
}
d_info("indi_session_start 5","INFO","INDI");
if(session_name() != "PHPSESSID") indi_log("session_name:".session_name());
$GLOBALS['indi_session_start'] = true;
}
}
}
//imposta la cache della sessione e in generale | public | private_no_expire
//???? da parametrizzare 30 minuti
function indi_session_cache($STATO="NO"){
// if($GLOBALS[indi_session_start]) {
if($STATO != "SI"){
session_cache_limiter('nocache');
} else {
//disabilito cache
session_cache_limiter('private');
session_cache_expire(30);
}
// session_write_close();
session_start();
// }
}
//funzione che gestiche gli header di cache, richiamata nell' index1.1
function indi_cache_header() {
global $DATI;
if($DATI['indi_cache_header'] == "AUTO") {
//default
$DATI['indi_cache_header'] = "cache_default";
//se c'e' un post
// if(count($_POST) > 0) {
//$DATI['indi_cache_header'] = "cache_form";
//d($_POST);
// }
//se sono autenticato o se ho roba nel carrello no cache sempre
//per ora non importarebbe con il cache_default che aggiorna sempre
if($DATI['auth'] == "SI" or count($_SESSION['indicarr']) > 0) {
$DATI['indi_cache_header'] = "cache_no";
}
}
if($DATI['indi_cache_header'] == "cache_default") {
header("Expires: ");
header("Pragma: ");
// header("Cache-Control: private");
header("Cache-Control: private, pre-check=0");
// header("Cache-Control: private, max-age=600, pre-check=600");
}
//tolgo gli header
elseif($DATI['indi_cache_header'] == "cache_reset") {
//tolgo la roba
header("Pragma: ");
header("Expires: ");
header("Cache-Control: ");
}
//abilito cache
elseif($DATI['indi_cache_header'] == "cache_si") {
header("Expires: ");
header("Pragma: ");
header("Cache-Control: private, max-age=600, pre-check=600");
}
elseif($DATI['indi_cache_header'] == "cache_for_prefetch") {//attivata dalla paginazione di indi, serve per firefox, vedi indi_prefetch
header("Expires: ");
header("Pragma: ");
header("Cache-Control: private, max-age=300, pre-check=300");
}
//abilito cache
elseif($DATI['indi_cache_header'] == "cache_form") {//non sembra essere usata
//header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("Expires: ");
header("Pragma: ");
header("Cache-Control: private, max-age=300, pre-check=300");
}
//disabilito cache
elseif($DATI['indi_cache_header'] == "cache_no") {
header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
//header("Cache-Control: private, pre-check=0");
} else {
d_err("indi_cache_header:no_defined","INDI");
}
}
//session_cache_limiter('private');
//???riesumo la sessione da dentro la pagina in test
function indi_session_resume(){
ini_set("session.use_cookies", false);
$name = ini_get("session.name");
if(trim($_COOKIE[$name]))//aggiunto carlo, spesso è vuoto e arrivano errori
session_id($_COOKIE[$name]);
session_start();
}
function indi_404_and_redirect(){
global $DATI;
indi_404();
indi_redirect_pagina($DATI["pagina_def"], null, null, null, "meta");//uso il meta tag altrimenti lo status è 302 e non 404
}
//funzione richiamata manualmente o in automatico dalla pagina 404
function indi_404() {
global $CONF,$DATI;
if($_GET['debug404']){
echo '
';
die;
}
//eseguo una volta sola
if(!$DATI['indi_404']) {
//non loggo favicon e robots
if(
!stristr($_SERVER['REQUEST_URI'],"favicon.ico")
and
!stristr($_SERVER['REQUEST_URI'],"robots.txt")
){
//loggo il resto
indi_log_file("ERRORE - 404 - $CONF[url_richiesto]");
}
$DATI['indi_404'] = 1;
if (function_exists(indi_404_personalizzata)) indi_404_personalizzata();
header ("HTTP/1.0 404 Not Found");
//prevengo indicizzazione
$DATI["meta_noindex"] = "SI";
//se non sono richieste di pagine esce
/*
$ext = indi_estensione_file($_SERVER['REQUEST_URI']);
if(
$ext == "js" or
$ext == "css" or
$ext == "jpg" or
$ext == "jpeg" or
$ext == "png" or
$ext == "gif" or
$ext == "ico" or
$ext == "txt" or
$ext == "asp" or
$ext == "doc" or
$ext == "pdf"
) exit();
*/
//eventualmente esco e visualizzo messaggio con torna alla home page
//print "
Pagina non trovata
".htmlentities($CONF["baseurl2"].$_SERVER['REQUEST_URI']);
//if($CONF["dove_sono"] == "rem" and ($_SESSION["amministrazioneIndi"] != "1" or $_REQUEST["amministrazioneIndi"] != "1")) indi_debug_email(null,"INDI 404 [".$CONF["baseurl2"].$_SERVER['REQUEST_URI']."]");
}
}
/* -------------------------- ------------------------------------ */
//ritorna vero se chi sta visitando è uno spider
if($GLOBALS['tnxBoot'] != "admin_tnx"){
function preg_match_spider($string){
//questa stringa è anche negli alias del server .bashrc
preg_match_all('/ngx_lua|lua-resty|crawler|googleimageproxy|awariobot|pingdom|paracrawl|vagabondo|semrushbot|yandex|bing|hopperbot|admantx|ecosia|duckduckgo|toscrawler|speedy_spider|httrack|msnbot|almaden|becomebot|link-checker-pro|ia_archiver|archive_crawler|exabot|googlebot|google|surveybot|zyborg|w3c-checklink|checklink|linkwalker|webcr|yahoo|slurp|naverbot|dloader|converacrawler|w3c_validator|innerprisebot|innerprise|topicspy|poodle predictor|ichiro|link checker pro|grub-client|gigabot|psbot|mj12bot|nextgensearchbot|tutorgigbot|gaisbot|xenu link sleuth|turnitinbot|iconsurf|zoe indexer|ahrefsbot|zoominfobot|bingbot|ccbot|dotbot|yandexbot|applebot|baiduspider|datanyze|zoombot|mojeekbot|the knowledge ai|crawler|blexbot|qwantify/i', $string, $result);
return $result[0][0];
}
function is_spider(){
$return = indi_get_cache("is_spider");
if($return === NULL){
$return =
preg_match_spider($_SERVER["HTTP_USER_AGENT"])
// || substr($_SERVER["HTTP_REFERER"], -6) == ".best/"//a gennaio 2020 visto che c'è un bot che non si presenta come tale, riconoscibile perchè ha referrer svariati domini .best inesistenti (ad es "http://amaryllidaceae.best/"), su mtp fa il 34% delle visite, quasi nessuna invece su tutto il resto dei siti nello stesso giorno (0,3%)
;
indi_set_cache("is_spider", $return);
}
return $return;
}
function string4js($string, $delimiter = '"'){
return $delimiter.str_replace(array($delimiter, "\n", "\r"), array('\\'.$delimiter, " "), $string).$delimiter;
}
function trimAfter($string, $limit = 40, $suffix = " […]"){
$string = strip_tags($string);
if(strlen($string) > $limit) return substr($string, 0, $limit).$suffix;
else return $string;
}
//htmlentities ricorsivo ibrido tra print_r e htmlentities
function html_r($data, $recursive = 1){
if($recursive) for($j=0; $j<$recursive; $j++) $prefix .= " ";
if(is_array($data) || is_object($data)){
$return .= is_array($data) ? "Array" : "Object";
$return .= " $prefix(
";
foreach($data as $i=>$string){
$return .= $prefix."[$i] => ".html_r($string, $recursive+1);
}
return $return." $prefix) ";
}
else{
return htmlentities($data)." ";
}
}
function array_to_jsObj($array){//converte un array php in un oggetto js
if(!$array) return "{\n}";//l'invio serve per non far fare la sostiuzione a indi come se fosse una variabile
$elements = array();
foreach($array as $nome=>$value){
$element = "'".$nome."'".':';
if(is_bool($element)) $element .= $value;
else $element .= '"'.text4flash($value).'"';
$elements[] = $element;
}
return "{".implode(",", $elements)."}";
}
}
//se la pagina e' richiesta da javascript in ajax
function is_ajax(){
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return TRUE;
} else {
return FALSE;
}
/* vecchia versione
if(stristr($GLOBALS['_SERVER']['HTTP_X_REQUESTED_WITH'],"XMLHttpRequest"))return TRUE;
else return FALSE;
*/
}
//funzione deprecata usare sempre indi_is_locale
function is_locale(){
if(indi_location() == 'loc') return true;
return false;
}
//funzione deprecata usare sempre indi_is_online
function is_online(){
if(indi_location() == 'rem') return true;
else return false;
}
//funziona solo in locale
function is_tnx_locale(){
if(strpos($_SERVER['REMOTE_ADDR'], "192.168.0") === 0) return true;
else return false;
}
function is_tnx(){
$return = indi_get_cache("is_tnx");
if($return === NULL) {
$return = is_tnx_raw(); //è dentro index1.1
}
return indi_set_cache("is_tnx",$return);
}
function is_cecca(){
if ($_SERVER["REMOTE_ADDR"] == "192.168.0.115") return true;
return false;
}
function indi_location(){
//imposto dove sono
//return 'rem';
//if (strstr($_SERVER['SERVER_NAME'],'demo.tnx.it') or strstr($_SERVER['SERVER_ADDR'],'192.168.0.105') ) {
if (
$_SERVER['SERVER_ADDR'] == '192.168.0.105'
|| preg_match("/demo[\d]*\.tnx\.it/", $_SERVER['SERVER_NAME'])
|| substr($_SERVER['SERVER_NAME'], -11) == 'demo.tnx.it'
) {
return 'loc';
} else {
return 'rem';
}
}
//controlla se il sito e' in produzione, ovvero sul dominio indi.tnx.it di test oppure no
function indi_is_production() {
//cecca - aggiunto test su vari domini test per non indicizzare $CONF["meta_noindex"] = AUTO
//if(indi_is_online() and stristr($_SERVER['SERVER_NAME'],$GLOBALS["CONF"]["dominio_test_online"]) == false) {
if(indi_is_online() and !indi_is_dominio_test()) {
return true;
} else {
return false;
}
}
function indi_is_dominio_test() {
return in_array($_SERVER['SERVER_NAME'], $GLOBALS["CONF"]["domini_test_online"]);
}
//controlla se siamo nel sito base o no
function indi_is_base() {
if($GLOBALS["CONF"]['sito'] == $GLOBALS["CONF"]['sito_base']) {
return true;
} else {
return false;
}
}
function indi_is_locale(){
if($GLOBALS['CONF']['dove_sono'] == 'loc') return true;
return false;
}
function indi_is_online(){
if($GLOBALS['CONF']['dove_sono'] == 'rem') return true;
else return false;
}
//aggiunge http:// se non c'e'
function indi_fix_url($url) {
return "http://".str_ireplace("http://","",$url);
}
/* piu' veloce e con timeout, torna l' IP da un nome con timeout */
function indi_get_addr_from_host($host, $timeout = 3, $force_whois = false) {
$query = `nslookup -timeout=$timeout -retry=1 $host`;
if(preg_match('/\nAddress: (.*)\n/', $query, $matches)) return trim($matches[1]);
return FALSE;
}
/* ritorna la nazione fronendo l' ip ne codice 2 cifre STANDARD es: IT */
function indi_get_nazione_from_ip($ip = null) {
global $CONF;
//GEOIP
if(!$ip) $ip = $_SERVER['REMOTE_ADDR'];
//se non e' un IP
if(!filter_var($ip, FILTER_VALIDATE_IP)) {
if(!$ip = indi_get_addr_from_host($ip)) return FALSE;
}
// $force_whois = true;
//cecca 05/09/2016 geoip maxmind - http://dev.maxmind.com/geoip/legacy/geolite/
if ($force_whois) {
//vecchia versione con whois
//trovare quando privato
// if(explode(".",$ip != 4) and !stristr($ip,"192.168.") and !stristr($ip,"127.0.")) {
if(count(explode(".",$ip)) == 4 and !stristr($ip,"192.168.") and !stristr($ip,"127.0.")) {
$ret = shell_exec ("whois ".escapeshellcmd($ip));
indi_log("indi_get_nazione_from_ip($ip) WHOIS \n $ret");
} else return FALSE;
$ret = preg_split("/Country:/i",$ret);
$ret = explode("\n",$ret[1]);
if(strlen(trim($ret[0])) == "2") return trim($ret[0]);
else return FALSE;
} else {
//trovare quando privato
// if(explode(".",$ip != 4) and !stristr($ip,"192.168.") and !stristr($ip,"127.0.")) {
if(count(explode(".",$ip)) == 4 and !stristr($ip,"192.168.") and !stristr($ip,"127.0.")) {
if (!function_exists("geoip_open")) {
//indi_log("indi_get_nazione_from_ip($ip) include di " . $CONF["dir_lib"] . "GeoIP/geoip.inc");
include($CONF["dir_lib"] . "GeoIP/geoip.inc");
}
if (function_exists("geoip_open")) {
$gi = geoip_open($CONF["dir_lib"] . "GeoIP/GeoIP.dat", GEOIP_STANDARD);
$geo_code = geoip_country_code_by_addr($gi, $ip);
$geo_name = geoip_country_name_by_addr($gi, $ip);
geoip_close($gi);
//indi_log("indi_get_nazione_from_ip($ip) GeoIP $geo_code $geo_name");
if (strlen($geo_code) == "2") return $geo_code;
} else {
echo "function_exists geoip_open false";die;
}
return FALSE;
} else {
indi_log("indi_get_nazione_from_ip($ip) Errore ip non valido");
return FALSE;
}
}
}
function indi_get_geocoding($indirizzo, $output = "array", $accetta_partial_match = true, $params = null) {
global $DATI;
//https://developers.google.com/maps/faq#languagesupport
if(is_null($params)) $params = "language=".$GLOBALS['LANG3TO2'][$DATI['lang']];
if($params) $params = '&'.$params;
$url = "https://maps.googleapis.com/maps/api/geocode/json?key=".$DATI["google_maps_api_key_server_to_server"]."&address=".rawurlencode($indirizzo).$params;
// console_log($url);
if($res = file_get_contents($url)) {
$RES = json_decode($res,true);
if($output == "json") return $RES;
if($RES["status"] == "OK"){
$return = [];
foreach($RES["results"] as $arr){
//https://developers.google.com/maps/documentation/geocoding/requests-geocoding?hl=it
if($arr['partial_match'] && !$accetta_partial_match) continue;
if(isset($arr['partial_match']) /* query "modena" non c'è */ && !$arr['partial_match'] && $arr['geometry']['location_type'] == 'APPROXIMATE'){
trigger_error("Indirizzo APPROXIMATE, ma partial_match=false: ".$url);
}
$r = array(
"indirizzo_formattato" => $arr["formatted_address"],
"latitudine" => $arr["geometry"]["location"]["lat"],
"longitudine" => $arr["geometry"]["location"]["lng"],
"types" => $arr["types"]
);
foreach($arr['address_components'] as $ac){
if(in_array('postal_code', $ac['types'])){
$r['cap'] = preg_replace("/[^\d]+/", "", $ac['long_name']);
//pulisco la voce perchè è capitato che:
//ci fosse la scritta "CAP: 10136" (5/2025): https://maps.googleapis.com/maps/api/geocode/json?language=ita®ion=it&key=AIzaSyCEXyYGcdo7YQc-idxl-UwcyQQU5VM2uTo&address=Corso%20Orbassano%20132%2CTorino%2C%20TO%2CItaly
//ci fosse il numero civico come postal_code (al 7/2024 funziona=: https://maps.googleapis.com/maps/api/geocode/json?language=ita®ion=it&key=AIzaSyCEXyYGcdo7YQc-idxl-UwcyQQU5VM2uTo&address=via%20Acconcia%20parco%20ancar%2031%2CCapodrise%2C%20CE%2CItaly
}
}
$return[] = $r;
}
return $return;
}
}
return FALSE;
}
//indi_file_get_content / indi_url_get_content
//funzione wrapepr fi file_get_contents(), per scaricare dati remoti con timeout e logging
//alias
function indi_file_get_contents($url,$context=NULL,$timeout=NULL) {
return indi_url_get_content($url,$context,$timeout);
}
function indi_url_get_content($url,$context=NULL,$timeout=NULL) {
//log start
indi_log("indi_url_get_content: START (url:$url, timeout:$timeout)");
//timeout
if($timeout) {
$old_timeout = ini_get("default_socket_timeout"); //60 secondi è il default
ini_set("default_socket_timeout", $timeout);
}
//scarico
$content = @file_get_contents($url,FALSE,$context);//gestisco l'errore in maniera estesa sotto
//$http_response_header è disponibile anche fuori da questa funzione
//controllo errori
if($content === FALSE) {
indi_log("indi_url_get_content: ERROR (url:$url, timeout:$timeout), size(".strlen($content)."), header(".$http_response_header['0'].")");
//info aggiuntive
d_err("Impossibile scaricare $url ($http_response_header[0])");//.print_r($http_response_header, true);
if($_GET['debug_http_response_header']){
echo '