<?php
/**
* Libreria di funzioni RPC. 
* Queste funzioni sono richiamata tendenzialmente dal file {@link rpc.php} per eseguire 
* chiamate al database dalle maschere. 
* Sono presenti inoltre alcune funzioni di utilit�.
* 
* @package VFront
* @subpackage Function-Libraries
* @author Mario Marcello Verona <marcelloverona@gmail.com>
* @copyright 2007-2010 M.Marcello Verona
* @version 0.96 $Id: func.rpc_query.php 880 2010-12-14 12:43:47Z marciuz $
* @license http://www.gnu.org/licenses/gpl.html GNU Public License
*/




/**
 * Funzione per la codifica in javascript di caratteri speciali nelle url
 *
 * @param string $str
 * @return string encoded
 */
function urldecode_js($str){
	
	$str=urldecode($str);
	
	$find=array("%u201C","%u201D",
				"%u2019",
				"%u2013");
	
	$replace=array("\"","\"",
					"\\'",
					"-");
					
	return str_replace($find,$replace,$str);
	
	
}



/**
 * Funzione di modifica di un record. 
 * Restituisce l'SQL per la modifica
 *
 * @param array $_dati
 * @param array $_pk
 * @param string $tabella
 * @return string SQL
 */
function rpc_query_update($_dati,$_pk,$tabella=""){
	
	global  $vmsql, $vmreg, $db1;
	
	$sql = "UPDATE $tabella SET ";
	
	foreach($_dati as $k=>$val){
		
		$val_hidden = variabili_campi($val);
		
		if($val_hidden!=false){
			$val=$val_hidden;
		}
		
		$val=urldecode_js($val);
		
		$sql.="\n $k='".$vmsql->escape($val)."',";
	}
	
	$sql = substr($sql,0,-1);
	
	if(count($_pk)<=0){
		return false;
	}
	else{
		
		$sql.="\n WHERE ";
		
		foreach($_pk as $k=>$val){
			
			
					
			$sql.="$k='".$vmsql->escape($val)."' \n AND ";
		}
	}
	
	$sql = substr($sql,0,-4);
	
	$sql.= ($db1['dbtype']=='mysql') ? " LIMIT 1" : "";
	
	rpc_debug($sql);
	
	return $sql;
}


/**
 * Funzione di inserimento nuovo record. 
 * Restituisce l'SQL per l'inserimento.
 *
 * @param array $_dati
 * @param string $tabella
 * @return string SQL
 */
function rpc_query_insert($_dati,$tabella){
	
	global  $vmsql, $vmreg;
	
	$campi="";
	
	$valori="";
	
	foreach ($_dati as $k=>$val){
		
		$campi.="$k,";
		
		//imposto gli eventuali hidden
		if(variabili_campi($val)!=false) $val = variabili_campi($val);
		
		$val=urldecode($val);
		
		$valori.="'".$vmsql->escape($val)."',";
	}
	
	$campi = substr($campi,0,-1);
	$valori = substr($valori,0,-1);
	
	$sql = "INSERT INTO $tabella ($campi) VALUES ($valori)";
	
	return $sql;
}



/**
 * Funzione di preparazione query di cancellazione record mediante la maschera di VFront. 
 * La funzione � richimata via chiamata esterna Javascript e restituisce il codice SQL.
 *
 * @param array $_pk
 * @param string $tabella
 * @return string SQL
 */
function rpc_query_delete($_pk,$tabella){
	
	global $db1,  $vmsql, $vmreg;
	
	$campi="";
	
	$valori="";

	$condizione='';
	
	foreach ($_pk as $k=>$val){
		
		$condizione.=" $k='".$vmsql->escape($val)."' AND";
	}
	
	$condizione=substr($condizione,0,-3);
	
	$sql = "DELETE FROM $tabella WHERE $condizione";
	
	if($db1['dbtype']=='mysql') $sql.=" LIMIT 1";
	
	return $sql;
}

/**
 * Ricerca mediante la maschera di VFront 
 * La funzione � richimata via chiamata esterna Javascript
 * e restituisce gli ID dei record trovati
 *
 * @param array $_dati
 * @param string $tabella
 * @return array
 */
function rpc_query_search($_dati,$tabella){
	
	global  $vmsql, $vmreg, $db1;
	
	if(count($_dati)==0){
		return null;
	}
	
	
	$orderby = prendi_orderby($tabella,$_SESSION['gid']);
	
	$condizione='';
	
	foreach ($_dati as $k=>$val){
		
		$val=trim($val);
		
		if(strlen($val)>0){
			
			// sperimentale... uso degli asterischi
			if(preg_match('!\*|%!',$val)){
				
				$val=str_replace("*","%",$val);
				$condizione.=" $k LIKE '".$vmsql->escape($val)."' AND";
			}
			else{
				
				$condizione.=" $k='".$vmsql->escape($val)."' AND";
			}
		}			
	}
	
	$condizione=substr($condizione,0,-3);
	
	// PRENDI LA CHIAVE PRIMARIA DELLA TABELLA
	
	$campoPK = prendi_PK($tabella);
	
	
	$sql = "SELECT $campoPK FROM $tabella WHERE $condizione ORDER BY $orderby, $campoPK ";
	
	$query = $vmsql->query($sql);
	
	$n_record = $vmsql->num_rows($query);
	
	list($IDs) = $vmsql->fetch_row_all($query,true);
	
	rpc_debug($sql);
	
	return $IDs;
	
}



/**
 * Funzione RPC per la duplicazione di un record
 *
 * @param array $_pk
 * @param string $tabella
 * @return mixed
 */
function rpc_query_insert_duplicato($_pk,$tabella="",$oid_sub="",$duplica_allegati=0,$duplica_link=0){
	
	global  $vmsql, $vmreg, $db1;
	
	// prendi i campi
	list($info_tabella)=prendi_colonne_frontend($tabella,'column_name',false);
	
	list($campo_id, $val_id) = each($_pk);
	
	
	for($i=0;$i<count($info_tabella);$i++){
		if($info_tabella[$i]!=$campo_id)  $campi[]=$info_tabella[$i];
	}
	
	if(count($info_tabella)>count($campi)){

		// test campo numerico
		if(!campo_is_numeric($tabella,$campo_id)){
			
			$val_id="'".$vmsql->escape($val_id)."'";
		}
		
		
		
		// ... vai avanti
		$sql="INSERT INTO $tabella (".implode(",",$campi).") 
			SELECT ".implode(",",$campi)." FROM $tabella WHERE ".$campo_id."=".$val_id."";
		
		rpc_debug($sql);
		
		$test=$vmsql->query_try($sql,false);
		
		$insert_id = (int) $vmsql->insert_id($tabella,$campo_id);
		
		
		// TODO: duplicazione dei dati delle sottomaschere
		
		if($insert_id>0 && strlen(trim($oid_sub))>0){
			
			$duplicazione_sub_test=array();
			
			// sottomaschere da duplicare:
			$oid_sub=str_replace("_", "," ,substr($oid_sub,0,-1));
			
			// prendi le info sottomaschere
			$sql_sub="SELECT * FROM {$db1['frontend']}{$db1['sep']}registro_submask WHERE id_submask in ($oid_sub)";
			
			$q_sub = $vmsql->query($sql_sub);
			
			while($RS_sub=$vmsql->fetch_assoc($q_sub)){
				
				// SQL per i campi NON auto_increment da prendere
				$sql_campi="SELECT sc.column_name 
							FROM {$db1['frontend']}{$db1['sep']}registro_submask_col AS sc
										 WHERE id_submask=".$RS_sub['id_submask']." AND sc.extra!='auto_increment'";
				
				$q_campi_sub=$vmsql->query($sql_campi);
				
				list($lista_campi)=$vmsql->fetch_row_all($q_campi_sub,true);
				
				$duplicazione_sub_test[] = duplica_record_sottomaschera($RS_sub['nome_tabella'],$lista_campi,$RS_sub['campo_fk_sub'],$val_id,$insert_id);
			}
			
			
			
			rpc_debug($sql_sub);
			
		}
		
		
		// DUPLICAZIONE DEGLI ALLEGATI
		if($duplica_allegati){
			
			$test_allegati=duplica_allegati($tabella,$val_id,$insert_id);
		}
		
		
		
		// DUPLICAZIONE DEi LINK
		if($duplica_link){
			
			$test_link=duplica_link($tabella,$val_id,$insert_id);
		}
		
		
		
		return $test."|".$insert_id;
	}
	
	// altrimenti...
	
	return -1;
}



/**
 * Funzione di duplicazione record
 *
 * @param string $tabella_sub
 * @param array $elenco_campi
 * @param string $campo_fk
 * @param string $valore_fk
 * @param int|string $nuovo_valore
 * @return bool
 */
function duplica_record_sottomaschera($tabella_sub,$elenco_campi,$campo_fk,$valore_fk,$nuovo_valore){
	
	global  $vmsql, $vmreg, $db1;
	
	$elenco=array();
	
	for($i=0;$i<count($elenco_campi);$i++){
		
		if($elenco_campi[$i] != $campo_fk) {
			$elenco[]=$elenco_campi[$i];
		}
	}
	
	$sql="INSERT INTO ".$tabella_sub. " ($campo_fk, ".implode(",",$elenco).") 
	(SELECT '$nuovo_valore', ".implode("," , $elenco)." FROM $tabella_sub WHERE $campo_fk='$valore_fk') ";
	
	rpc_debug($sql);
	$test=$vmsql->query_try($sql,false);
	
	return $test;
}



/**
 * Funzione di duplicazione (su richiesta) degli allegati collegati ad un record. 
 * Duplica i record informativi su DB e fa una copia fisica dei file 
 *
 * @param string $tabella
 * @param int $id_old
 * @param int $id_new
 * @return int
 */
function duplica_allegati($tabella,$id_old,$id_new){
	
	global  $vmsql, $vmreg, $db1;
	
	$matrice_att=prendi_allegati($tabella,$id_old);
	
	$ok=false;
	
	if(count($matrice_att)>0){
		
		$ok=0;
		
		// copia i file 
		for($i=0;$i<count($matrice_att);$i++){
			
			$q0=$vmsql->query("BEGIN");
			
			// copia via SQL
			$q=$vmsql->query("INSERT INTO "._TABELLA_ALLEGATO." (tipoentita, codiceentita, autoreall, lastdata, nomefileall)
							VALUES ('$tabella',
							$id_new, 
							'".$vmsql->escape($_SESSION['user']['nome']." ".$_SESSION['user']['cognome'])."', 
							'".date("Y-m-d H:i:s")."', '".$matrice_att[$i]['nomefileall']."')"
							);
							
			// se ha inserito il record
			if($vmsql->affected_rows($q)==1){
				
				$id_new_attach=$vmsql->insert_id(_TABELLA_ALLEGATO,'codiceallegato');
				
				// copia il file
				if(copy(_PATH_ATTACHMENT."/".$matrice_att[$i]['codiceallegato'].".dat",_PATH_ATTACHMENT."/".$id_new_attach.".dat")){
					$q2=$vmsql->query("COMMIT");
					$ok++;
				}
				else{
					$q2=$vmsql->query("ROLLBACK");
				}
				
			}
		}
	}
	
	if($ok===false){
		
		return 0;
	}
	else if($ok!=count($matrice_att)){
		return -1;
	}
	else {
		return $ok;
	}
	
}


/**
 * Funzione di duplicazione (su richiesta) dei link collegati ad un record.
 *
 * @param string $tabella
 * @param int $id_old
 * @param int $id_new
 * @return int
 */
function duplica_link($tabella,$id_old,$id_new){
	
	global  $vmsql, $vmreg, $db1;
	
	$matrice_link=prendi_link($tabella,$id_old);
	
	$ok=false;
	
	if(count($matrice_link)>0){
		
		$ok=0;
		
		// copia i file 
		for($i=0;$i<count($matrice_link);$i++){
			
			// copia via SQL
			$q=$vmsql->query("INSERT INTO "._TABELLA_LINK." (tipoentita, codiceentita, link, lastdata, descrizione)
							VALUES ('$tabella',
							$id_new, 
							'".$vmsql->escape($matrice_link[$i]['link'])."', 
							'".date("Y-m-d H:i:s")."', 
							'".$matrice_link[$i]['descrizione']."')"
							);
							
			// se ha inserito il record
			if($vmsql->affected_rows($q)==1) $ok++;
		}
	}
	
	if($ok===false){
		
		return 0;
	}
	else if($ok!=count($matrice_link)){
		return -1;
	}
	else {
		return $ok;
	}
}




###############################################################################################
#
#	FUNZIONI RPC per le sottomaschere
#
###############################################################################################


/**
 * Funzione di modifica dei record delle sottomaschere. 
 * Restituisce codice SQL
 *
 * @param array $_dati
 * @param string $_str_pk_indipendente
 * @param string $tabella
 * @param string $hash_campo
 * @return string SQL
 */
function rpc_sub_query_update($_dati,$_str_pk_indipendente,$tabella,$hash_campo=''){
	
	global  $vmsql, $vmreg, $db1;
	
	
	$sql_out=array();
	
	if(!is_array($_dati)){
		
		return null;
	}
	
	
	$sql_auto="SELECT c.column_name 
						 FROM {$db1['frontend']}{$db1['sep']}registro_col c , {$db1['frontend']}{$db1['sep']}registro_tab t
						 WHERE c.extra='auto_increment'
						 AND t.gid=0
						 AND t.id_table=c.id_table
						 AND t.table_name='$tabella'";
	
	// Cerca eventuali campi Autoincrement:
	$q_auto=$vmreg->query($sql_auto);
	
	if($vmreg->num_rows($q_auto)>0){
		list($campo_auto_inc) = $vmreg->fetch_row($q_auto);
	}
	else{
		$campo_auto_inc='';
	}
	
	
	
	foreach($_dati as $k=>$arval){
		
	
		$buffer_string="";
		$campi='';
		$valori='';
		$campo='';
		$valore='';
		$campo_pk_indip="";
		$valore_pk_indip="";
		
		
		
		
			
		$hash_campo_obj=(isset($hash_campo[$k])) ? unserialize(base64_decode($hash_campo[$k])) : null;
		
		
		// NUOVO DATO
		if(!isset($hash_campo[$k])){
			
			
			foreach($arval as $campo=>$valore){
				
				// non mettere i campi auto_increment se ci dovessero essere
				if($campo!=$campo_auto_inc){
					
					$campi.=$campo.",";
					
					if($db1['dbtype']=='postgres' && campo_is_numeric($tabella,$campo)){
						$valori.= $vmsql->escape($valore).",";
					}
					else{
						$valori.="'".$vmsql->escape($valore)."',";
					}
				}
			}
			
			
			list($campo_pk_indip,$valore_pk_indip) = explode("=",$_str_pk_indipendente);

			// accodo i dati della pk indipendente se non � auto_increment
			if($campo_pk_indip!=$campo_auto_inc){
				$campi.=$campo_pk_indip;
				$valori.=$valore_pk_indip;
			}
			else{
				$campi=substr($campi,0,-1);
				$valori=substr($valori,0,-1);
			}
			
			$buffer_string="INSERT INTO $tabella ($campi) VALUES ($valori)";
			
		}	//-- fine INSERT
		
		
		
		// DATO DA MODIFICARE
		else{
			
				if(is_array($hash_campo) && count($hash_campo_obj)>0){
				
					$WHERE='WHERE 1=1 ';
					
					foreach($hash_campo_obj as $campo_h=>$valore_h){
						
						if($valore_h!=''){
							if($db1['dbtype']=='postgres' && campo_is_numeric($tabella,$campo_h)){
								$WHERE.=" AND $campo_h=".$vmsql->escape($valore_h);
							}
							else{
								$WHERE.=" AND $campo_h='".$vmsql->escape($valore_h)."'";
							}
						
						}
						else{
							
							$WHERE.=" AND ($campo_h IS NULL OR $campo_h='')";
						}
					}
				}
				
				// PREVENGO LA CREAZIONE DI UN UPDATE SENZA CONDIZIONI
				else return '';
				
				
				$buffer_string="UPDATE $tabella SET ";
				
				foreach($arval as $campo=>$valore){
					
					if($db1['dbtype']=='postgres' && campo_is_numeric($tabella,$campo)){
						$buffer_string.=" $campo=".$vmsql->escape($valore).",";
					}
					else{
						$buffer_string.=" $campo='".$vmsql->escape($valore)."',";
					}
				}
				
				$buffer_string=substr($buffer_string,0,-1);
				
				if(!isset($WHERE) || $WHERE=='WHERE 1=1 '){
					return '';
				}
				
				$buffer_string.=" $WHERE ";
			
			
		} //-- fine UPDATE
		
		
		$sql_out[]=$buffer_string;
		
		
	
	} // -- fine ciclo
	
	
	return $sql_out;
	
}


/**
 * Funzione per la cancellazione di un record in sottomaschera. 
 * Restituisce il codice SQL
 *
 * @param string $tabella
 * @param string $hash
 * @return string SQL
 */
function rpc_sub_query_delete($tabella,$hash){

	global $vmsql;
	
	for($i=0;$i<count($hash);$i++){
		
		$hash_campo_obj=unserialize(base64_decode($hash[$i]));
		
		$WHERE='WHERE 1=1 ';
		
		if(is_array($hash_campo_obj)){
		
			foreach($hash_campo_obj as $campo_h=>$valore_h){
				
				if($valore_h!=''){
				
					$WHERE.=" AND $campo_h='".$vmsql->escape($valore_h)."'";
				
				}
				else{
					
					$WHERE.=" AND ($campo_h='".$vmsql->escape($valore_h)."' OR $campo_h IS NULL)";
				}
			}
		}
		
		
	
		$sql_out[]="DELETE FROM $tabella $WHERE ";
	}
	
	return $sql_out;
	
}



/**
 * Funzione di cancellazione di un allegato di un record.
 *
 * @param string $tabella
 * @param int $id
 * @return bool
 */
function rpc_delete_attach($tabella,$id){
	
	
	global  $vmreg, $db1;
	
	$sql_att="SELECT codiceallegato FROM "._TABELLA_ALLEGATO." WHERE codiceentita='$id' AND tipoentita='$tabella'";
	
	$q_att = $vmreg->query($sql_att);
	
	list($array_codice_allegati)=$vmreg->fetch_row_all($q_att,true);

	$test_del_fs=null;
	$test_del=null;

	for($i=0;$i<count($array_codice_allegati);$i++){
		
		// elimino dal filesystem
		$test_del_fs=@unlink(_PATH_ATTACHMENT."/".$array_codice_allegati[$i].".dat");
		
		// elimino dal db
		$sql_del="DELETE FROM "._TABELLA_ALLEGATO." WHERE codiceallegato=".$array_codice_allegati[$i]." LIMIT 1";
//		rpc_debug($sql_del);
		$test_del=$vmreg->query($sql_del);
		
		
	}
	
	 return ($test_del_fs && $test_del) ? true:false;
}



/**
 * Funzione di cancellazione di un link di una scheda.
 *
 * @param string $tabella
 * @param int $id
 * @return bool
 */
function rpc_delete_link($tabella,$id){
	
	global $vmreg, $db1;
	
	$sql_link = "SELECT codicelink FROM "._TABELLA_LINK." WHERE codiceentita='$id' AND tipoentita='$tabella'";
	
	$test_del=null;
	
	$q_link = $vmreg->query($sql_link);
	
	list($array_codice_link)=$vmreg->fetch_row_all($q_link,true);
	
	for($i=0;$i<count($array_codice_link);$i++){
		
		// elimino dal db
		$sql_del="DELETE FROM "._TABELLA_LINK." WHERE codicelink=".$array_codice_link[$i]." LIMIT 1";
//		rpc_debug($sql_del);
		$test_del=$vmreg->query($sql_del);
		
	}
	
	 return $test_del;
	
}



?>