Location: PHPKode > scripts > DBNavigator > dbnavigator/DBNavigator.php
<?php

/** Questo file contiene la classe DBNavigator che necessita delle classi HTMLForm, PageNavigator e del file functions.inc.php
 *  
 *	@author Michele Castellucci <hide@address.com>  
 */


	
/** Questa classe consente in generale di gestire tabelle di database in modo automatico in modo simile a quanto fa phpMyAdmin ma in maniera più orientata all'utente.
  * Le funzionalità principali sono
  * (1) visualizzare il contenuto di una o piu' tabelle eventulmente collegate con dei Join in maniera tabellare in stile phpMyAdmin,
  *	(2) ricercare record su campi di ricerca definiti tramite {@link setSearchField()},
  *	(3) modificare un record specifico col metodo {@link go_only_for_form()} o un record scelto dalla visualizzazione tabellare 
  *	con un form costruito automaticamente in base alla definizione dei campi della tabella del database ed anche con 
  * definizioni aggiuntive tramite i metodi {@link setMailField()} , {@link setFileField()} , {@link setPhotoField()} , {@link setPasswordField()}. 
  * 
  * @author Michele Castellucci <hide@address.com>
  */	
	

class DBNavigator
{

	/// ------ INSTANCE VARIABLES  ------ ///
	

	/** La query passata al costruttore della classe
	  * @var string */ 
	var $query="";
	
	/** Il nome della tabella principale
	  * @see setPrimaryTable
	  * @var string */ 
	var $originalPrimaryTable="";
	
	/** Il nome dell'alias della tabella principale
	  * @see setPrimaryTable
	  * @var string */ 
	var $primaryTable="";
	
	/**  Il nome della chiave primaria della tabella principale 
	  *  @var string */ 
	var $originalPrimaryKey="";
	
	/**  Il nome dell'alias (definito dalla query) della chiave primaria della tabella principale 
	  *  @var string */ 
	var $primaryKey="";
	
	/**  Il nome generico singolare di ogni riga della tabella
	  *  @see setRowName()
	  *  @var string */ 
	var $rowName="";
	
	/**  Informazioni sull'ordinamento: ordinamento di default, ordinamento corrente, desc corrente
	  *  da applicare alla query
	  *  @see setDefaultOrd()
	  *  @var string */ 
	var $orderInfo=array();
	
	/**  Contiene le definizioni dei campi della/e tabella/e richiamate dalla query
	  *  @see scanTable()
	  *  @var array */ 
	var $field=array();
	
	/**  Contiene informazioni sui campi di altre tabelle collegati alla tabella principale
	  *  @see scanTable()
	  *  @var array */ 
	var $externalData=array();
	
	/**  Contiene i nomi dei campi della tabella principale impostati come indirizzi email.
	  *  A tali campi verrà applicata una validazione Javascript e PHP nel form generato in fase di modifica/inserimento
	  *  @see setMailField()
	  *  @var array */
	var $mailField=array();
	
	/**  Contiene i nomi dei campi della tabella principale impostati come password.
	  *  A tali campi verrà applicata una validazione Javascript e PHP nel form generato in fase di modifica/inserimento
	  *  @see setPasswordField()
	  *  @var array */
	var $passwordField=array();
	
	/**  Contiene i nomi dei campi della tabella principale impostati come immagini
	  *  A tali campi verrà applicata una validazione Javascript e PHP nel form generato in fase di modifica/inserimento
	  *  Essa consente in particolare di inserire solo file GIF, JPG, PNG
	  *  @see setPhotoField()
	  *  @var array */
	var $photoField=array('_Resize_'=>"","_KeepOriginal_"=>"");
	
	/**  Contiene i nomi dei campi della tabella principale impostati come file
	  *  A tali campi verrà applicata una validazione Javascript e PHP nel form generato in fase di modifica/inserimento
	  *  @see setPhotoField()
	  *  @var array */
	var $fileField=array();
	
	/**  Contiene il percorso relativo della directory in cui salvare immagini e file
	  *  @see setFilePath()
	  *  @var string */
	var $filePath="";
	
	/**  Contiene il codice esadecimale del colore da applicare come sfondo all'intestazione della tabella di visualizzazione dei dati
	  *  @see setTableBGColor()
	  *  @var string */
	var $tableHeaderBGColor="#CCCCCC";
	
	/**  Contiene il codice esadecimale del colore da applicare come sfondo al corpo della tabella di visualizzazione dei dati
	  *  @see setTableBGColor() 
	  *  @var string */
	var $tableBGColor="#AFEAB9";
	
	/**  Valore di margin (cellspacing) della tabella di visualizzazione dati
	  *  @see setTableCellSpacing() 
	  *  @var int */
	var $tableCS=3;
	
	/**  Indica se mostrare o meno la chiave primaria della tabella principale
	  *  @see hidePrimaryKey()
	  *  @var boolean */ 
	var $hidePrimaryKey=false;
	
	/** Indica se e' consentito eliminare record dalla tabella
      * Questa variabile può essere un array che indica gli id dei record di cui è consentita l'eliminazione	
	  * @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
	  * @var boolean */ 
	var $canDelete=false;
	
	/** Indica se e' consentito modificare record dalla tabella
      * Questa variabile può essere un array che indica gli id dei record di cui è consentita la modifica
	  * @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
	  * @var boolean */ 
	var $canEdit=false;
	
	/** Indica se e' consentito inserire record nella tabella
	  * @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
	  * @var boolean */ 
	var $canInsert=false;
	
	
	/** Indica se e' consentito visualizzare i record dalla tabella per la stampa
	  * Se abilitata, viene stampato aggiunto un tasto che apre una nuova finestra contenente i soli dati del record. 
	  * @see canEdit(),canEditDelete()
	  * @var boolean */ 
	var $canViewForPrint=false;
	
	
	/**  Contiene un array contenente i nomi delle 4 classi del foglio di stile da applicare a link e celle della tabella
	  *  1) classe CSS per le celle 'normali' contenenti dati
	  *  2) classe CSS per le celle contenenti i tasti di modifica/insermento
	  *  3) classe CSS per le celle della prima riga della tabella contenenti le intestazioni
	  *  4) classe CSS per le celle contenenti i link aggiunti tramite  {@link addLinkCol()}
	  *  @see setTableStyle() 
	  *  @var array */
	var $style=array('TD'=>'','fieldLink'=>'','headerTD'=>'','editDeleteTD'=>'');

	
	/**  Contiene i nomi (gia' inseriti nel tag: class="nome_classe") delle classi del foglio di stile da applicare a link e celle della tabella.
	  *  @see setTableStyle(),$style 
	  *  @var array */
	var $classTag=array('TD'=>'','fieldLink'=>'','headerTD'=>'','editDeleteTD'=>'');
	
	/**  Contiene un array dove ogni elemento è un array contenete informazioni sulle colonne link aggiuntive 
	  *  stampate nella tabella di visualizzazione dati aggiunte con {@link addLinkCol()}.
	  *  Ad esempio se il link apre una nuova pagina, mantiene gli argomenti GET o viene determinato solo su determinate condizioni
	  *  @see addDataCol(),addLinkCol(),addFreeCol()
	  *  @var array */ 
	var $linkCol=array();
	
	/**  Contiene un array dove ogni elemento è un array contenete informazioni sulle colonne di dati aggiuntive 
	  *  stampate nella tabella di visualizzazione dati aggiunte con {@link addDataCol()}.
	  *  @see addDataCol(),addLinkCol(),addFreeCol()
	  *  @var array */ 
	var $dataCol=array();
	
	/**  Contiene un array dove ogni elemento è un array contenete informazioni sulle colonne "libere" aggiuntive 
	  *  stampate nella tabella di visualizzazione dati aggiunte con {@link addFreeCol()}.
	  *  @see addDataCol(),addLinkCol(),addFreeCol()
	  *  @var array */ 
	var $freeCol=array();
	
	/**  Contiene i nomi dei campi da rimuovere nel form di inserimento/modifica.
	  *  tali campi non potranno quindi essere modificati/inseriti
	  *  @see removeInput()
	  *  @var array */ 
	var $removeInput=array();
	
	/**  Contiene i nomi dei campi da rimuovere nella tabella di visualizzazione dati standard
	  *  tali campi non saranno visibili in visualizzazione ma potranno essere modificati/inseriti
	  *  @see removeDisplaying()
	  *  @var array */ 
	var $removeDisplaying=array();
	
	/**  Contiene la lista dei campi definiti come campi di ricerca
	  *  @see setSearchField()
	  *  @var array */ 
	var $searchField=array();
	
	/**  Indica se il form di ricerca è stato stampato o meno
	  *  @see search_form()
	  *  @var boolean */ 
	var $search_form_printed=false;
	
	/**  Contiene informazioni sulla cancellazione di righe ricorsiva e linkata ad un'altra tabella
	  *  @see setDeleteRecursive()
	  *  @var array */ 
	var $deleteRecursive=array();
	
	/**  Contiene una istanza della classe HTMLForm che costruisce il form di inserimento/modifica dei record
	  *  @see DBNavigator(),buildForm()
	  *  @var HTMLForm */ 
	var $editForm;
	
	/**  Contiene i 3 nomi delle classi del foglio di stile da associare agli input dell' HTMLForm
	  *  1) classe CSS per textbox/select 
	  *  2) classe CSS per pulsanti 
	  *  3) classe CSS per textarea e textarea con iframe 
	  *  @see setClassForFormInput()
	  *  @var array */ 
	var $classForFormInput=array("inputs"=>"mini","buttons"=>"mini_btn","textareas"=>"mini_txa");
	
	/**  Contiene l'intestazione indicata manualmente del form di inserimento/modifica
	  *  @see setFormHeading()
	  *  @var string */ 
	var $formHeading="";
	
	/**  Indica se visualizzare tutti i record su una pagina (senza paginazione) o meno
	  *  @see showAllElements()
	  *  @var boolean */ 
	var $showAll=false;
	
	/**  Contiene il percorso delle immagini da usare nella visualizzazione tabellare per i tasti (nuovo,stampa,modifica,elimina)
	  *  e degli script (javascript) necessari per la classe.
	  *  @see setImagesAndScriptsPath(), DBNavigator()
	  *  @var string */ 
	var $imagesAndScriptsPath="";
	
	/**  Indica se è stato già richiamato il metodo scanTable (deve essere richiamato una volta sola)
	  *  @see scanTable()
	  *  @var boolean */ 
	var $tableScanned=false;
	
	/**  Contiene i due valori percentuali della dimensione delle 2 colonne del form di inserimento/modifica
	  *  @see setFormWidth()
	  *  @var array */ 
	var $formWidth=array();
	
	/**  Contiene il numero di righe della tabella considerando anche gli eventuali parametri di ricerca correnti
	  *  @see get_rowsNum(), set_rowsNum()
	  *  @var int */ 
	var $rowsNum;
	
	/**  Contiene le stringhe di testo usate all'interno della classe nella lingua impostata  
	  *  @see setLanguage()
	  *  @var array */ 
	var $lang=array();
	

	/**  Indica il numero di caratteri oltre il quale tagliare il valore di un campo nella visualizzazione tabellare
	  *  @see setTextCutLength()
	  *  @var int */ 	
	var $cutLength=150;

	/**  Indica il numero di default di record per pagina da visualizzare
	  *  @see setResultsPerPage()
	  *  @var int */ 		
	var $resultsPerPage=10;

	/**  Indica se visualizzare record senza effettuare una ricerca
	  *  @see setViewResultWithoutSearch()
	  *  @var boolean */ 		
	var $viewResults=true;

	/**  Indica se visualizzare tutte le opzioni degli input SELECT nel form di ricerca 
	  *  indipendentemente dalla presenza del database di record con quei valori
	  *  @see setViewAllSearchOptions()
	  *  @var boolean */ 	
	var $viewAllSearchOptions=false;

	/**  Raccoglie il codice Javascript che sarà inseritò all'interno del metodo window.onload 
	  *  @var string */ 		
	var $JS_onLoad="";

	/**  Indica se utilizzare la tecnologia AJAX per la navigazione (ordinamento/modifica/inserimento)
	  *  @see useAjax()
	  *  @var boolean */ 		
	var $useAjax=false;				
	
	/** Indica se e' consentita la modifica multipla e la mofica contemporanea dei record 
	  * @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
	  * @var boolean */ 			
	var $canMultipleEditDelete=true;

	/** Contiene un array di due elementi di cui il primo è la data più bassa disponibile, il secondo la più alta
	  * Le date sono selezionabili nel form di inserimento/modifica per i campi definiti DATE nella tabella del database
	  * @see setDateInterval
	  * @var array */ 				
	var $dateInterval=array();

	/** Contiene un array di due elementi corrispondenti al path assoluto (elemento con chiave 'absolute') 
	  * e relativo (elemento con chiave 'relative') dal quale la textarea HTML (con IFRAME) cerca le immagini da inserire sulla textarea stessa.
	  * @see setHTMLTextareaParams()
	  * @var array */ 			
	var $HTMLTextareaParams=array();


	/** Contiene tutte le condizioni (indicate manualmente) per cui una riga deve essere evidenziata
	  * La condizione è una stringa contenente un'espressione booleana PHP.
	  * @see setHighlighting()
	  * @var array */ 		 	
	var $highlighting=array();
	
	/** Contiene le impostazioni riguardanti gli input radio
	  * @see setRadioSettings()
	  * @var array */ 		 	
	var $radioSettings=array('maxOptions'=>8,'maxOptionsInOneLine'=>3);

	/** Contiene le impostazioni riguardanti le checkbox
	  * @see setCheckboxesSettings()
	  * @var array */ 		 	
	var $checkboxesSettings=array('maxCheckboxes'=>10,'multipleSelectSize'=>15);		

	/** Contiene il nome della funzione aggiuntiva da eseguire alla cancellazione di un record
	  * @see setExtraDeletingFunction()
	  * @var string */ 		 	
	var $extraDeletingFunction='';		


	/// ------ INSTANCE METHODS  ------ ///


	/**  Imposta una funzione aggiuntiva da eseguire alla cancellazione di un record che deve accettare un parametro 
	  *  contenente un array associativo (ricavato da mysql_fetch_array()) contenente i dati del record da cancellare.
	  *  @param string Il nome della funzione */ 	
	function setExtraDeletingFunction($function){$this->extraDeletingFunction=$function;}	

	/**  Imposta l'utilizzo della tecnologia AJAX per la navigazione (ordinamento/modifica/inserimento) 
	  *  @param boolean Abilita o meno Ajax */ 	
	function useAjax($bool){$this->useAjax=$bool;}	

	/** Imposta i paramtri da passare alla classe Adv_TextArea (textarea HTML con IFRAME) tra cui il percorso dal quale la textarea cerca le immagini da poter inserire nel testo.
	  * @param array Deve contenere un array di due elementi corrispondenti al path assoluto (elemento con chiave 'absolute') e relativo (elemento con chiave 'relative')
	  * ,un elemento con chiave selectFont contenente true per i font predefiniti o un array di nomi di font
	  * ,un elemento con chiave fontSize contenente true per le grandezze in pixel predefinite (da 8 a 23) o un array di due elementi con chiave start ed end contenenti la grandezza minima e massima abilitata
	  * ,un elemento con chiave bodyStyleOrCSS contenente le regole CSS da inserire nell'attributo style del body dell'iframe oppure l'url del foglio di stile .css */ 		
	function setHTMLTextareaParams($arr){ $this->HTMLTextareaParams=$arr; }

	/**  Modifica il numero di default di elementi per pagina da stampare nella visualizzazione dati 
	  *  @param int Numero di risultati per pagina di default desiderati */ 	
	function setResultsPerPage($rpp) { $this->resultsPerPage=$rpp; }

	/**  Imposta la lingua per le stringhe di testo usate dalla classe sono disponibili testi in italiano e inglese
	  *  @param string Nome della lingua. Attualmente sono supportati solo 'english' e 'italian' */ 	
	function setLanguage($lang)
	{
		$lang=strtolower($lang);		
		$this->lang['languageName']=$lang;

		if ($lang=='english')
		{
			$this->lang['edit']="Edit";
			$this->lang['delete']="Delete";
			$this->lang['print']="Print";
			$this->lang['reallyDelete']="Really delete this {$this->rowName} ?";
			$this->lang['insertNew']="Insert new {$this->rowName}";	
			$this->lang['searchOn']="Search for {$this->rowName} according to...";
			$this->lang['ifSelected']="If selected";
			$this->lang['selectAll']="Select all";
			$this->lang['unselectAll']="Unselect all";
			$this->lang['reallyDeleteMultiple']="Really delete selected objects ?";	
			$this->lang['editRecord']="Edit data {$this->rowName}";
			$this->lang['backToData']="Back to general data display";		
			$this->lang['editing']="Editing";
			$this->lang['of']="of";
			$this->lang['select']="Select";	
			$this->lang['errorSended']="Information about error have been sended via e-amil to the admin.";	
			$this->lang['errorFileConflict']="Selected file has a name used by another, rename it.";
			$this->lang['errorKeyConflict']="Inserted data is already present in the archive (value must be unique)";
			$this->lang['errorFormatConflict']="Inserted data isn't in the correct format";
			$this->lang['errorWrongVerCode']="Verify code is wrong";
			$this->lang['errorWrongPassword']="Old inserted value is not correct";	
			$this->lang['find']="Find";
			$this->lang['confirmData']="Confirm data";
			$this->lang['all']="All";
			$this->lang['noImage']="No image";
			$this->lang['noFile']="No file";
			$this->lang['current']="Current";		
			$this->lang['noResults']="No results";	
			$this->lang['errorFileTooBig']="Selected file is too big for upload";	
			$this->lang['from']="from";
			$this->lang['to']="to";
			$this->lang['goBack']="Go back";
			$this->lang['warningRecordOccupied']="Warning: another user (administrator) is modifying selected record.<br /><br />
												  Wait on this page for the automatic access to the record or"; 
			$this->lang['ascendingOrder']="Ascending order";
			$this->lang['descendantOrder']="Descendant order";
			$this->lang['multipleEditingHeading']="CONTEMPORARY EDITING FOR *** ELEMENTS";
			$this->lang['fieldEnablingPanelHeading']="Uncheck fields that you don't want to edit for selected elements";
			$this->lang['errorAvailability']="One or more selected elements is assigned to another user, retry";
			$this->lang['recordHasBeenDeleted']="This element has been deleted";

			 									  				
		}else
		{
			$this->lang['edit']="Modifica";
			$this->lang['delete']="Elimina";
			$this->lang['print']="Stampa";
			$this->lang['reallyDelete']="Eliminare veramente questo/a {$this->rowName} ?";
			$this->lang['insertNew']="Inserisci nuovo/a {$this->rowName}";	
			$this->lang['searchOn']="Ricerca {$this->rowName} in base a...";
			$this->lang['ifSelected']="Se selezionati";
			$this->lang['selectAll']="Seleziona tutti";
			$this->lang['unselectAll']="Deseleziona tutti";
			$this->lang['reallyDeleteMultiple']="Eliminare veramente gli oggetti selezionati ?";	
			$this->lang['editRecord']="Modifica dati {$this->rowName}";
			$this->lang['backToData']="Torna alla visualizzazione generale dei dati";
			$this->lang['editing']="Modifica";
			$this->lang['of']="di";
			$this->lang['select']="Selezionare";
			$this->lang['errorSended']="i dati relativi dell'errore sono stati inviati via mail all'amministratore.";	
			$this->lang['errorFileConflict']="Il file selezionato ha un nome utilizzato da un altro file, rinominarlo";
			$this->lang['errorKeyConflict']="il dato inserito è già presente nell'archivio (il valore deve essere univoco)";
			$this->lang['errorFormatConflict']="il dato inserito non è nel formato corretto";
			$this->lang['errorWrongVerCode']="Il codice di verifica è errato";
			$this->lang['errorWrongPassword']="il vecchio valore inserito non è corretto";			
			$this->lang['find']="Cerca";
			$this->lang['confirmData']="Conferma dati";		
			$this->lang['all']="Tutti";
			$this->lang['noImage']="Nessuna immagine";
			$this->lang['noFile']="Nessun file";
			$this->lang['current']="Corrente";
			$this->lang['noResults']="Nessun risultato";
			$this->lang['errorFileTooBig']="Il file selezionato è troppo grande per eseguire l'upload";
			$this->lang['from']="da";
			$this->lang['to']="a";
			$this->lang['goBack']="Torna indietro";
			$this->lang['warningRecordOccupied']="Attenzione: Un altro utente (amministratore) sta modificando il record selezionato.<br /><br />
												  Attendi su questa pagina l'accesso automatico al record oppure"; 
			$this->lang['ascendingOrder']="Ordine ascendente";
			$this->lang['descendantOrder']="Ordine discendente";
			$this->lang['multipleEditingHeading']="MODIFICA CONTEMPORANEA A *** ELEMENTI";
			$this->lang['fieldEnablingPanelHeading']="Selezionare i campi che si desidera modificare per gli elementi selezionati";
			$this->lang['errorAvailability']="Uno o più dei record selezionati è assegnato ad un altro utente, ritentare";	
			$this->lang['recordHasBeenDeleted']="Questo elemento è stato eliminato";											  
		}
		$this->editForm->setlanguage($this->lang['languageName']);
	}

	  
	/**  Imposta una condizione per cui determinate righe devono evidenziarsi
	  *  @param string stringa di 'condizione' contenente una espressione booleana PHP che sarà valutata tramite eval(). 
	  *	 Nell'espressione ci si può riferire al campo X di ogni record con {{{X}}}. Ad esempio "{{{status}}}=='active'" 
	  *  @param string stringa contenente tutti gli attributi delle celle delle righe per cui si verifica l'evidenziazione ad esempio 'class="foo" style="color:#F00"' */ 	
	function setHighlighting($condition,$TDAttributes) { $this->highlighting[]=array('condition'=>$condition,'TDAttributes'=>$TDAttributes); }
	
	/**  Imposta l'intestazione della colonna di 'modifica record' ad $heading nella tabella di visualizzazione dei dati */
	function setEditColHeading($heading) {$this->lang['edit']=$heading;}
	
	/**  Imposta l'intestazione della colonna di 'elimina record' ad $heading nella tabella di visualizzazione dei dati */
	function setDeleteColHeading($heading) {$this->lang['delete']=$heading;}
	
	/**  Imposta l'intestazione della colonna di 'visualizza per stampa' ad $heading nella tabella di visualizzazione dei dati */
	function setPrintColHeading($heading) {$this->lang['print']=$heading;}
	
	/**  Imposta l'intestazione del tasto di inserimento di un nuovo record */
	function setInsertNewHeading($heading) {$this->lang['insertNew']=$heading;}
	
	/**  Imposta l'intestazioni del box di ricerca */
	function setSearchHeading($searchHeading) {$this->lang['searchOn']=$searchHeading;}
	
	/**  Imposta la stringa mostrata in assenza di risultati */
	function setNoResultString($str) {$this->lang['noResults']=$str;}
	
	/**  Imposta l'intestazione dei tasti di modifica/eliminazione multipla dei record nella tabella di visualizzazione dei dati*/
	function setMultipleEditDeleteHeading($ifSelected,$selectAll,$unselectAll,$alertOnDelete) 
	{
		$this->lang['ifSelected']=$ifSelected;
		$this->lang['selectAll']=$selectAll;
		$this->lang['unselectAll']=$unselectAll;
		$this->lang['reallyDeleteMultiple']=$alertOnDelete;
	}
	
	
	/** Imposta l'intervallo di date selezionabili nel form di inserimento/modifica per i campi definiti DATE nella tabella del database
	  * @param int La data più bassa che si vuole rendere disponibile 
	  * @param int La data più alta che si vuole rendere disponibile  */ 	
	function setDateInterval($bottom,$top)
	{
		$bottomFirst=$bottom{0};
		if ($bottomFirst=="+")
		$this->dateInterval[0]=date("Y")+(int)(substr($bottom,1));
		else
		if ($bottomFirst=="-")
		$this->dateInterval[0]=date("Y")-(int)(substr($bottom,1));
		else
		$this->dateInterval[0]=$bottom;
	
		$topFirst=$top{0};
		if ($topFirst=="+")
		$this->dateInterval[1]=date("Y")+(int)(substr($top,1));
		else
		if ($topFirst=="-")
		$this->dateInterval[1]=date("Y")-(int)(substr($top,1));
		else
		$this->dateInterval[1]=$top;
		
	}
	
	/**  Imposta le 2 dimensioni percentuali di larghezza del form di inserimento/modifica record */
	function setFormWidth($w1,$w2) {$this->formWidth=array($w1,$w2);}
	
	/**  Imposta il messaggio alert di conferma per l'eliminazione di un record */
	function setAlertOnDelete($alert)
	{
		if ($alert!="")
		{
			$this->lang['reallyDelete']=addslashes(str_replace(array("\r","\n")," ",$alert)); //elimina ritorni a capo
		}
	}
	
	/**  Serve ad ottenere una stringa che descrive lo stato attuale della classe.
	  *  @return string Stringa contenente uno di questi valori: inserting, editing, deleting, editingMany, viewing */
	function status()
	{
	
		$pm='_'.$this->originalPrimaryTable;
		
		if (isset($_GET['edit'.$pm]) && $_GET['edit'.$pm]=="") unset($_GET['edit'.$pm]);//get inutilizzato
	
		if (isset($_GET['del'.$pm]))	return 'deleting';
	
		
		if (isset($_POST['edit'.$pm]) && $_POST['edit'.$pm]==='0') return 'inserting';
		if (isset($_POST['edit'.$pm]) && $_POST['edit'.$pm]==='1') return 'editing';
		
		if (isset($_GET['edit'.$pm]))
		{
			if ($_GET['edit'.$pm]==='0') return 'inserting';
							else return 'editing';	 
		}
		
		if (isset($_GET['action'.$pm]) && isset($_GET['selected'.$pm]) && count($_GET['selected'.$pm])!=0)
		{
			if ($_GET['action'.$pm]=='editMany') return 'editingMany';
			if ($_GET['action'.$pm]=='edit')     return 'editing';
			if ($_GET['action'.$pm]=='delete')   return 'deleting';
		}
		
		return 'viewing';
	}
	
	
	/** imposta $field come campo password, sarà editabile con 2 campi in fase di inserimento (password,ripeti password)
	  * e 3 campi in fase di modifica (vecchia password,nuova password,ripeti nuova password). La password sarà codificata con md5
	  */
	function setPasswordField($field) {$this->passwordField[$field]="yes";}
	
	/** indica se nella tabella di visualizzazione devono essere visualizzati TUTTI i record senza paginazione */
	function showAllElements($all=true) {$this->showAll=$all;}
	
	/** imposta l'intestazione del form di inserimento modifica ad $heading e $backLink come  */
	function setFormHeading($heading,$backLink="")
	{
		$this->formHeading=$heading;
		$this->lang['backToData']=$backLink==""?$this->lang['backToData']:$backLink;
	}
	
	/** imposta le classi del foglio di stile da applicare ai tag input($forInputs) ai pulsanti submit($forButtons) ed alle textarea($forTareas)  */
	function setClassForFormInput($forInputs,$forButtons="",$forTareas="")
	{
		$this->classForFormInput['inputs']=$forInputs;
		if ($forButtons) $this->classForFormInput['buttons']=$forButtons;
		if ($forTareas) $this->classForFormInput['textareas']=$forTareas;
	}
	
	/** imposta la cancellazione linkata e/o ricorsiva dei record. 
	  *	$chiave_collegata_a_se_stessa è il campo con cui si effettua un 'autojoin' nella tabella principale.
	  * $DBNavigator_esterno è una istanza della classe DBNavigator in cui c'è un join tra la sua tabella principale
	  * e la tabella principale del DBNavigator corrente. Per join si intende un join nelle query si selezione dei dati.
	  * $alert è invece il messaggio di avvertimento addizionale da visualizzare quando si tenta di eliminare il record in cui
	  * teoricamente si dovrebbero spiegare gli effetti della cancellazione linkata e/o ricorsiva.  
	  */
	function setDeleteRecursive($chiave_collegata_a_se_stessa,$DBNavigator_esterno=false,$alert="")
	{
		if ($chiave_collegata_a_se_stessa) $this->deleteRecursive['key'][]=$chiave_collegata_a_se_stessa;
		if ($DBNavigator_esterno) $this->deleteRecursive['DBNavigator'][]=$DBNavigator_esterno;
		if ($alert!="") $this->setAlertOnDelete($alert);
	}
	
	/** Indica che il campo della tabella con nome $inputName nel form di inserimento/modifica non potrà essere editato. */
	function removeInput($inputName){$this->removeInput[$inputName]="yes";}
	
	/** Imposta i campi della tabella che non devono essere mostrati nella visualizzazione generale dei dati. 
	  * @param string nome del campo 1 da non visualizzare 
	  * @param string nome del campo 2 da non visualizzare 
	  * @param string nome del campo N da non visualizzare */
	function removeDisplaying()
	{
		$arg=func_get_args();
		foreach ($arg as $val)
			if (is_string($val))
				$this->removeDisplaying[$val]="yes";
		
	}
	
	/** Indica che il campo della tabella con nome $inputName nel form di modifica multipla non potrà essere editato. */
	function removeMultipleEditingInput($inputName){$this->removeMultipleEditingInput[$inputName]="yes";}
	
	
	/** Imposta il campo $table_and_field come campo di ricerca(fornito come nometabella.nomecampo oppure nomecampo)
		Se fornito senza il nome della tabella, il campo sarà considerato relativo ad una di aggregazione sql come COUNT(*) AS nomecampo
		e nelle ricerche sarà inserito tra le clausole having.
		$_alias imposta invece l'alias del campo manualmente. Se non indicato invece, l'alias verrà cercato automaticamente
		nella query SQL  
	*/
	function setSearchField()
	{
		$func_args=func_get_args();
		
		$i=0;
		$bool=true;
		foreach ($func_args as $key=>$val) //costruisco l'array con i parametri della funzione
		{
			if ($bool)
			{
				$arg[$i]['table_and_field']=$val;
			}
			else
			{
				$arg[$i]['alias']=$val;
				++$i;
			}
			
			$bool=!$bool;
			
		}
		
		$i=0;
		foreach ($arg as $val)
		{	
			
			$exp=explode(".",$val['table_and_field']);
				
			if (count($exp)==1)//clause su funzioni di aggregazione sql come COUNT(*), CONCAT(.... 
			{
				$field[$i]=$exp[0]; 
				$table[$i]="Having";
			}else
			{
				$table[$i]=$exp[0]; //viene cambiato se presente alias
				$field[$i]=$exp[1];
			}	
			
			$table_alias[$i]=$table[$i]; 
				
		
			if (isset($val['alias']) && $val['alias']!="") $field_alias[$i]=$val['alias'];
			else
			//if (is_int(strpos($this->query," ".$table_and_field." AS "))) //CERCA l'[ALIAS DEL CAMPO] !!!!
			if (preg_match("/ {$val['table_and_field']} AS( |\\n|\\r|\\r\\n)/",$this->query,$pattern)!=false)
			{
				//$exp=explode(" ".$table_and_field." AS ",$this->query);
				$exp=explode($pattern[0],$this->query);
				$exp2=preg_split("/(,| ){1}/",$exp[1]);
				$field_alias[$i]=$exp2[0];	
			}
			else $field_alias[$i]=$field[$i];
		
			if (strpos($this->query," AS ".$table[$i]." ")!=false) //CERCA l'[ALIAS DELLA TABELLA] !!!!
			{
				$exp=explode(" AS ".$table[$i]." ",$this->query);
				$exp2=explode(" ",$exp[0]);
				$table[$i]=$exp2[count($exp2)-1];						
			} //////////////////////////////////////////////////////////////////////////////////
			
			++$i;
		}
		
		/*/////////////////////N  O  T  E////////////////////////////////////////////////////////////
			
			Il formato di $table_and_field deve essere 
			- tabella.campo    
			- alias_tabella.campo
			
			ricavare l'alias DEL CAMPO serve solo a fini di visualizzazione in quanto 
			---> le condizioni where ed having nella query non si devono riferire all'alias di un campo 
				
		*/////////////////////////////////////////////////
			
		if (count($arg)==1)
		{
			
			$get_index=$table_alias[0]."_".$field[0]."_src_".$this->originalPrimaryTable;
		
			
			if (isset($_GET[$get_index]) && is_array($_GET[$get_index])) 
			{
				foreach($_GET[$get_index] as $multiple=>$val)
				$value[]=trim(stripslashes($val));
				$tipo_ricerca="1"; //ricerca vincolata (select o radio)			
			}
			else 
			if (isset($_GET[$get_index]) 
				&& substr(trim(stripslashes($_GET[$get_index])),0,1)=='"' 
				&& substr(trim(stripslashes($_GET[$get_index])),strlen(trim(stripslashes($_GET[$get_index])))-1,1)=='"' 
				)
			
			{

				$value=trim(stripslashes($_GET[$get_index]));
				$tipo_ricerca="2"; //ricerca libera di una FRASE con - davanti			
		
			}
			else 
			if (isset($_GET[$get_index."_start"]) && isset($_GET[$get_index."_end"]))
			{ 
				$value['start']=$value['end']="";

				if (is_numeric($_GET[$get_index."_start"]) || preg_match("/^\d{4}-\d{2}-\d{2}$/",$_GET[$get_index."_start"]))
					$value['start']=trim($_GET[$get_index."_start"]);

				if (is_numeric($_GET[$get_index."_end"]) || preg_match("/^\d{4}-\d{2}-\d{2}$/",$_GET[$get_index."_end"]))
					$value['end']=trim($_GET[$get_index."_end"]);
				
				$tipo_ricerca="4";  //ricerca numerica (...intervalli)
			}	
			else 
			{ 
				$value=isset($_GET[$get_index])?trim(stripslashes($_GET[$get_index])):"";		
				$tipo_ricerca="3";  //ricerca libera con una parola
			}
	
			$this->searchField[]=array('field'=>$field[0],'field_alias'=>$field_alias[0],'value'=>$this->convertSpecialChars($value),'table'=>$table[0],'table_alias'=>$table_alias[0],'tipo'=>$tipo_ricerca);
		}
		else // //più campi di ricerca con un unico testo
		{
			$get_index="";
			foreach ($field as $val)
			$get_index.=$val."_";
			 
			$get_index.="src_".$this->originalPrimaryTable;
			$value=isset($_GET[$get_index])?trim(stripslashes($_GET[$get_index])):"";
	
			$this->searchField[]=array('field'=>$field,'field_alias'=>$field_alias,'value'=>$this->convertSpecialChars($value),'table'=>$table,'table_alias'=>$table_alias,'tipo'=>3);
	
		}		
		
	}
	
	/** Rimuove tutti i campi impostati come campi di ricerca */
	function clearSearchFields() {$this->searchField=array();}
	
	/** Accetta una stringa e un'array di stringe e ritorna lo stesso valore
	  * in cui '&amp;' , '&gt;' e '&lt;' sono sostituite con le corrispondenti enttà HTML.
	  * Questo riflette il modo di inserire nel database questi caratteri, effettuato da insertIntoDBFromPost (file HTMLForm.php) 
	  * @param mixed Stringa o array di stringhe in cui non ci sono entità HTML 
	  * @return mixed Il valore iniziale in cui i caratteri appropriati vengono sostituiti da entità HTML */
	function convertSpecialChars($value)
	{	
		if (is_array($value))
		foreach($value as $key=>$val)
		{
			$value[$key]=str_replace("&","&amp;",$value[$key]);
			$value[$key]=str_replace(">","&gt;" ,$value[$key]);
			$value[$key]=str_replace("<","&lt;" ,$value[$key]);
		}
		else 
		{
			$value=str_replace("&","&amp;",$value);
			$value=str_replace(">","&gt;" ,$value);
			$value=str_replace("<","&lt;" ,$value);
		}
	
		return $value;
	
	}
	
	/** Aggiunge una colonna nominata $colName alla tabella della visualizzazione generale dei dati.
	  * Tale colonna avrà come icona $image e linkerà alla pagina corrente se non specificato il parametro $page con
	  *	l'argomento GET $arg che avrà il valore dell'id del record.
	  *
	  *	@param string intestazione della colonna
	  *	@param string nome del parametro GET a cui sarà assegnato l'id di ogni record  
	  *	@param string percorso dell'immagine icona
	  *	@param boolean indica se la pagina linkata dovrà mantenere gli argomenti GET della pagina.
	  *	@param boolean indica se la pagina linkata dovrà aprirsi in una nuova finestra.
	  *	@param mixed stringa indicante la pagina linkata.false indica la pagina corrente
	  *	@param string contiene un'espressione booleana PHP che sarà valutata come condizione di visualizzazione del link. Funziona come {@link setHighlighting()}
	  *	@param array contiene tutti i nomi dei campi della selezione SQL a cui applicare il link nella tabella di visualizzazione. */
	function addLinkCol($colName,$arg,$image,$keepGet='',$newWindow=false,$page='',$condition="",$fieldToLink=false)
	{
		if ($page=='') $page=$_SERVER['PHP_SELF'];
		$this->linkCol[]=array('colName'=>$colName,'arg'=>$arg,'image'=>$image,"keepGet"=>$keepGet,"newWindow"=>$newWindow,"page"=>$page,"condition"=>$condition
		,'fieldToLink'=>$fieldToLink);
	}
	
	/** Aggiunge una colonna nominata $colName alla tabella della visualizzazione generale dei dati.
	  * Tale colonna avrà come contenuto l'HTML contenuto nel paramentro $content in cui ci si potrà riferire all'id corrente 
	  * con la stringa '%current_row_id%'.
	  *	@param string intestazione della colonna
	  *	@param string HTML (con eventuale Javascript) di ogni cella. %current_row_id% viene sostituito dall'id di ogni record  */
	function addFreeCol($colName,$content)
	{
		$this->freeCol[]=array('colName'=>$colName,'content'=>$content);
	}
	
	/** Aggiunge una colonna nominata $colName alla tabella della visualizzazione generale dei dati.
	  * Tale colonna conterra dei dati ottenuti eseguendo la query $query in cui dovrà essere presente la stringa '%current_row_id%'
	  * indicante l'id del record corrente.
	  * Tale query potrà essere del tipo definito in &type. I tipi disponibili sono elecanti sotto.
	  *
	  * Il tipo RECURSIVE eseguira la query in modo ricorsivo tramite il metodo {@link query_ricorsiva()} contanto il numero
	  * di record ricorsivamente selezionati e visualizzando tale valore nella colonna (numerico).
	  *
	  * Il tipo LINKED_RECORDS invece eseguira semplicemente la query che tipicamente applicherà dei join con altre
	  * tabelle, visualizzando unicamente il primo campo selezionato per ogni riga risultante (righe separate da un ritorno a capo)
	  *
	  * Il tipo CALCULATION richiede che l'argomento query sia un array. 
	  * In particolare ogni elemento di tale array dovrà essere a sua volta una array di due elementi con chiavi 'operand' e 'query'. 
	  * operand è una stringa di un carattere contenente un'operatore matematico di PHP (+,-,*,/), 
	  * query è la query che dovra avere un campo numerico come primo campo (anche qui %current_row_id% sarà sostituito dall'id corrente).
	  * La classe fara in modo di eseguire tutte le query contenute nell'array e concatenarle con il loro operatore operand. Visualizzando il risultato finale
	  * Nota: si può ottenere lo stesso risultato applicando delle sotto-query (subqueries) alla select della query iniziale.
	  *
	  *	@param string intestazione della colonna
	  *	@param string query contenente la stringa %current_row_id% che viene sostituita dall'id di ogni record
	  *	@param string tipo della query: RECURSIVE o LINKED_RECORDS */
	function addDataCol($colName,$query,$type)
	{
		$this->dataCol[]=array('colName'=>$colName,'query'=>$query,'type'=>strtoupper($type));
	}
	
	/** Abilita/disabilità la possibilità di modifiche/eliminazioni multiple e modifiche contemporanee.
	  * Tale impostazione ha effettivamente rilevanza se è abilitata la modificazione ed eliminazione tramite {@link canEdit()} e {@link canDelete()}
	  *	@param boolean indica e abilitare o meno la funzionalità */
	function canMultipleEditDelete($apply){$this->canMultipleEditDelete=$apply;}

	/**  Indica il numero di caratteri oltre il quale tagliare il valore di un campo nella visualizzazione tabellare
	  *  @param int numero di caratteri massimi */	
	function setTextCutLength($cutLength=150){$this->cutLength=$cutLength;}


	/**  Imposta la visualizzazione dei record anche senza effettuare o meno
	  *  @param boolean indica il comportamento da mantenere */
	function setViewResultWithoutSearch($bool){$this->viewResults=$bool;}

	/**  Indica se visualizzare tutte le opzioni degli input SELECT nel form di ricerca 
	  *  indipendentemente dalla presenza del database di record con quei valori o meno
	  *  @param boolean indica il comportamento da mantenere */	
	function setViewAllSearchOptions($bool){$this->viewAllSearchOptions=$bool;}
	
	/**  Imposta il path in cui trovare scripts (javascript) ed immagini manualmente.
	  *  Il path viene cercato automaticamente in dei percorsi predefiniti al momento dell'instanziazione di un oggetto della classe (nel costruttore).
	  *  Se il path non viene trovato è necessario richiamare questo metodo
	  *  @param string path in cui si trovano tutti gli script ed immagini richieste dalla classe */		
	function setImagesAndScriptsPath($path){ $this->imagesAndScriptsPath=$path; }


	/** Imposta il numero massimo di opzioni radio che può avere un campo a scelta fissa come primo parametro, e 
	  * il numero massimo di opzioni radio che può avere su una sola riga, come secondo.
	  * Un campo che ha un numero di elementi maggiore del primo parametro, sarà editabile con una select input (anziche dei radio).
	  * Un campo che ha un numero di elementi maggiore del secondo parametro, sarà visualizzato con una opzione radio per riga.	  
	  * @param int numero massimo di opzioni che può avere un campo a scelta fissa
	  * @param int numero massimo di opzioni che può avere un input radio su una sola riga	  
	  */ 		 	
	function setRadioSettings($maxOptions,$maxOptionsInOneLine=3)
	{
		$this->radioSettings['maxOptions']=$maxOptions;
		$this->radioSettings['maxOptionsInOneLine']=$maxOptionsInOneLine;
	}

	/** Imposta il numero massimo di checkbox per un campo a scelta multipla (SET) come primo parametro, e
	  * la dimensione (numero di elementi) che dovrà avere la select a scelta multipla se il numero di elementi del campo supera
	  * il primo paramentro.
	  * @param int numero massimo di checkbox che può avere un campo a scelta multipla
	  * @param int dimensione (numero di elementi) che dovrà avere la select a scelta multipla che rimpiazza le checkbox in caso di eccedenza
	  */ 		
	function setCheckboxesSettings($maxCheckboxes,$multipleSelectSize) 
	{ 
		$this->checkboxesSettings['maxCheckboxes']=$maxCheckboxes;
		$this->checkboxesSettings['multipleSelectSize']=$multipleSelectSize;  
	}		
	
	
	/** Il costruttore della classe accetta la query principale comprensiva di tutti i join necessari con cui si faranno le successive elaborazioni. 
	  * Il costruttore inoltre inizializza l'HTMLForm membro della classe e crea una tabella nel database 'busy_records' che servirà
	  * a gestire i conflitti di modifiche simultanee ai record (tale unica tabella è usata per tutte le tabelle gestite con DBNavigator).
      * @param string query principale. ATTENZIONE, per diminuire le elaborazioni della classe, si assume che la query principale contenga TUTTE le parole chiave SQL in maiuscolo (SELECT,FROM,WHERE,HAVING,AS...) mentre per nelle sotto-query (subqueries) interne, se presenti, le parole chiave dovranno essere tutte minuscole. Inoltre si assume che la query non contenga la clausola ORDER BY, il campo di ordinamento dovrà essere impostato tramite l'apposito metodo setDefaultOrd()
	  */	
	function DBNavigator($query)
	{
	
																						
		$this->setFormWidth(25,75);
		//se non esiste crea la tabella busy_records
		mysql_query("CREATE TABLE IF NOT EXISTS `busy_records` 
		(
		  `table_name` varchar(255) NOT NULL default '',
		  `record_id` varchar(255) NOT NULL default '',
		  `user_session_id` varchar(255) NOT NULL default '',
		  `expire_time` bigint(20) NOT NULL default '0'
		) ;");
	
		mysql_query("DELETE FROM busy_records WHERE expire_time<\"".strtotime("now")."\""); //elimina le ocupazioni 'scadute'
	
	
		//////////////
		if (file_exists('DBNavigator.js')) //cartella corrente dello script
		$this->imagesAndScriptsPath='';
		else
		if (file_exists('classes/DBNavigator.js'))
		$this->imagesAndScriptsPath='classes/';
		else
		if (file_exists('DBNavigator/DBNavigator.js'))
		$this->imagesAndScriptsPath='DBNavigator/';
		else	
		if (file_exists('writein3/classes/DBNavigator.js'))
		$this->imagesAndScriptsPath='writein3/classes/';
		//else	
		//die ("Can't find Images and Javascript libraries path");
		
		
	
	
/*		$change=array(" on "," On "," oN ");//sostituisce on in maiuscolo
		$query=str_replace($change," ON ",$query);	
		
		$change=array(" as "," As "," aS ");//sostituisce as in maiuscolo
		$query=str_replace($change," AS ",$query);	*/
		
		
		//echo($query."<br><br>");
		//$query=preg_replace("/\(SELECT(.+)\)/","SUBSELECT",$query);	///è un casino...
		//die($query);		
				
/*		$pos=strpos(strtolower($query),"group by");
		if ($pos) //sostituisce il group by in maiuscolo
		{
			$first=substr($query,0,$pos);
			$second=substr($query,$pos+8);
			$query=$first."GROUP BY".$second;	
		}
		
	
		$pos=strpos(strtolower($query),"where");
		if ($pos) //sostituisce il where in maiuscolo
		{
			$first=substr($query,0,$pos);
			$second=substr($query,$pos+5);
			$query=$first."WHERE".$second;	
		}*/
		$this->query=$query;
		$this->dateInterval[0]=date("Y")-90;
		$this->dateInterval[1]=date("Y")+30;
		$this->editForm=new HTMLForm("x","x",25,75); //creo il form a "caso" :non esiste sovraccarico dei costruttori in php4
	
		$this->ajaxCall=false;
	
	
	
	}
	
	/** Indica che $primaryTable è la tabella principale tra le tabelle presenti nella clausolo FROM della query SQL
	  * Inoltre in questo metodo viene richiamato inoltre il controllo dello script di background per l'accesso al record esclusivo
	  * e quello per l'ottenimento dei dati per i suggerimenti automatici. 
	  * E' un metodo da richiamare necessariamente.
	  * @param string nome della tabella del tatabase principale */
	function setPrimaryTable($primaryTable) //NECESSARIA
	{
		///echo $this->query;
	
		$this->originalPrimaryTable=$primaryTable;
		$this->primaryTable=$primaryTable; 
	
		if (isset($_GET[$this->originalPrimaryTable.'_suggestField'])) $this->retrieveSuggestOptions();	
	
	
		if (isset($_GET['ajaxCall_'.$this->originalPrimaryTable]))
		{
			$this->ajaxCall=true;
			unset($_GET['ajaxCall_'.$this->originalPrimaryTable]);
	
			if (isset($_GET['manage_record_availability'])) //se c'è questo get allora è uno script di background che sta eseguendo il file
			$this->manage_record_availability_AjaxCall($_GET['manage_record_availability'],isset($_GET['bookRecord'])?true:false);	
			
		}
		else
		$this->ajaxCall=false;
				
	}  

	/** Metodo che serve esclusivamente (private) per lo script AJAX di background che interroga il database per avere una lista di suggerimenti
	  * nelle textbox del form di ricerca ed in quello della modifica contemporanea a più record */
	function retrieveSuggestOptions()
	{
		ob_end_clean();
	
		$output=array();
		
		if (strlen($_GET[$this->originalPrimaryTable.'_suggestText'])>0)
		{
			$num_suggestions=ceil(8/count($_GET[$this->originalPrimaryTable.'_suggestField']));
			
			foreach($_GET[$this->originalPrimaryTable.'_suggestField'] as $field)
			{
				$_GET[$this->originalPrimaryTable.'_suggestText']=
				$this->convertSpecialChars(str_replace(array("%","_"),array("\%","\_"),addslashes($_GET[$this->originalPrimaryTable.'_suggestText'])));
				
				$query="SELECT {$this->originalPrimaryTable}.{$field} ".substr($this->query,strpos($this->query,"FROM"));
				
				if (strpos($query,"GROUP BY")!==false)
				{
					$query=substr($query,0,strpos($query,"GROUP BY"))." GROUP BY ".$field;
				}
				else
				{
					$query.=" GROUP BY {$field} ";
				}
				
				$query=$this->addWhereConditionToQuery($query,"{$this->originalPrimaryTable}.{$field} LIKE \"".$_GET[$this->originalPrimaryTable.'_suggestText']."%\"")
													   ." ORDER BY {$this->originalPrimaryTable}.{$field} LIMIT 0,{$num_suggestions}";
			
				//echo $query;
				
				$result=mysql_query($query) or die(mysql_error()."<br />".$query);
				while ($row=mysql_fetch_array($result))
				$output[]=$row[$field];
	
			}
			sort($output);//ordina i risultati
		}
		
		die(implode("-###-",$output));
	}

	/** Imposta l'ordinamento di default della tabella di visualizzazione dati.  
	  * @param string il nome del campo da inserire nell'order by della query */
	function setDefaultOrd($defaultOrd) {$this->orderInfo['defaultOrd']=$defaultOrd;}          //NECESSARIA
	
	/** Imposta il nome (generico) con cui ci si riferisce ai record. Esempio. Inserisci nuovo LIBRO, Modifica LIBRO. 
	  * @param string nome concettuale dei record */
	function setRowName($rowName) 																//NECESSARIA
	{
		$this->rowName=$rowName;
		$this->setLanguage("italian");
	}                      

	/** Indica se mostrare o meno la chiave primaria della tabella principale nella tabella di visualizzazione dei dati.  */
	function hidePrimaryKey($boolean) {$this->hidePrimaryKey=$boolean;}           

	/** Imposta $field come campo email. Nei form di modifica/inserimento verrà quindi applicata una validazione Javascript e PHP
	  * @param string nome del campo della tabella */
	function setMailField($field) {$this->mailField[$field]="yes";}

	/** Imposta $field come campo stringa contenente solo numeri (stringa numerica). 
	  * Nei form di modifica/inserimento verrà quindi applicata una validazione Javascript e PHP
	  * @param string nome del campo della tabella */
	function setNumericStringField($field) {$this->numericStringField[$field]="yes";}

	/** Imposta $field come campo immagine/foto. Nei form di modifica/inserimento verrà quindi applicata una validazione Javascript e PHP
	  * ed l'input applicato sarà di tipo FILE. La validazione consentirà l'inserimento di file di tipo immagine per il web.
	  * @param mixed stringa contenente il nome del campo della tabella oppunre un array di stringhe per indicare più campi 
	  * @param mixed false indica che l'immagine non verrà ridimensionata. Un valore numerico indica la dimensione in pixel per cui avverrà il redimensionamento. 
	  * @param boolean Indica se l'immagine originale inviate deve essere salvata. Notare che se $resizeImg è false, l'immagine originale sarà comunque salvata anche se $keepOriginal è false */
	function setPhotoField($field,$resizeImg=false,$keepOriginal=false) 
	{
		if (is_array($field))
			foreach ($field as $f)
				$this->photoField[$f]=false;
		else
			$this->photoField[$field]=false;
		//la chiave è rilevante, il valore dell'array potrebbe essere qualsiasi cosa
		
		$this->photoField['_Resize_']=$resizeImg;
		$this->photoField['_KeepOriginal_']=$keepOriginal;
	
	}
	
	function setFileField($field) {$this->fileField[$field]=false;}
	function setFilePath($path) {$this->filePath=$path;} //NECESSARIA se si usa setFileField o setPhotoField
	function setTableBGColor($headerColor,$bodyColor) 
	{
		$this->tableHeaderBGColor=$headerColor; 
		$this->tableBGColor=$bodyColor; 
	}
	function setTableCellSpacing($CS) {$this->tableCS=$CS;}
	function setTableStyle($TD,$editDeleteTD,$headerTD,$fieldLink="") 
	{
		if ($TD) {$this->style['TD']=$TD; $this->classTag['TD']=" class=\"".$TD."\"";} 
		if ($fieldLink) {$this->style['fieldLink']=$fieldLink; $this->classTag['fieldLink']=" class=\"".$fieldLink."\"";} 
		if ($headerTD) {$this->style['headerTD']=$headerTD; $this->classTag['headerTD']=" class=\"".$headerTD."\"";} 
		if ($editDeleteTD) {$this->style['editDeleteTD']=$editDeleteTD; $this->classTag['editDeleteTD']=" class=\"".$editDeleteTD."\"";} 
	}
	
	/** Indica se e' consentito eliminare record dalla tabella
	  * @param boolean $boolean booleano che imposta la variabile $canDelete
	  * @see canEditDelete(),canEdit(),canInsert() */
	function canDelete($boolean_or_id_array){$this->canDelete=$boolean_or_id_array;}
	
	/** Indica se e' consentito modificare record dalla tabella
	  * @param boolean $boolean booleano che imposta la variabile $canEdit
	  * @see canEditDelete(),canDelete(),canInsert() */
	function canEdit($boolean_or_id_array) {$this->canEdit=$boolean_or_id_array;}
	
	/** Indica se e' consentito modificare record dalla tabella
	  * @param boolean $boolean booleano che imposta la variabile $canEdit
	  * @see canEditDelete(),canDelete(),canInsert() */
	function canInsert($boolean) {$this->canInsert=$boolean;}
	
	/** Indica se e' consentito modificare ed eliminare record dalla tabella
	  * @param boolean $boolean booleano che imposta le variabili $canEdit e $canDelete
	  * @see canEditDelete(),canDelete() */
	function canEditDelete($boolean){$this->canEdit=$boolean;$this->canDelete=$boolean;}
	
	/** Indica se e' consentito l'esportazione ed il download dei dati in formato CSV ed XML per Excel/OpenOffice
	  * @param boolean $boolean booleano che imposta le variabili $canExport
	  */
	function canExport($boolean){$this->canExport=$boolean;}
	
	/** Indica se e' consentito visualizzare i record dalla tabella
	  * @param boolean $boolean booleano che imposta la variabile $canViewForPrint
	  * @see canEditDelete(),canDelete() */
	function canViewForPrint($boolean) {$this->canViewForPrint=$boolean;}
	
	function addWhereConditionToQuery($query,$cond="")
	{
		if ($cond=="") return $query;
				
				if (strstr(/*strtoupper(*/$query/*)*/,"WHERE"))
				{
					$where="AND"; 
					$exp=explode("WHERE",$query);			
					$query=$exp[0]." WHERE (".$exp[1]; //aggiunge la parentesi in tutto il where				
					$closeBracket=")"; //parentesi chiusa alla fine del where
				}
				else
				{
					$where="WHERE";
					$closeBracket="";			 
				}
				
				if (strpos($query,'GROUP BY'))
				{
					$exp=explode("GROUP BY",$query);			
					$exp[0].="{$closeBracket} $where $cond ";
					$query=implode("GROUP BY",$exp);
				}
				else 
				if (strpos($query,'ORDER BY'))
				{
					$exp=explode("ORDER BY",$query);			
					$exp[0].="{$closeBracket} $where $cond ";
					$query=implode("ORDER BY",$exp);
				}
				else 
				$query.="{$closeBracket} $where $cond ";
				
				return $query;
	}	
	
	function addHavingConditionToQuery($query,$cond="")
	{
		if ($cond=="") return $query;
					
				if (strstr(/*strtoupper(*/$query/*)*/,"HAVING"))
				$where="AND"; 
				else 
				{
					$where="HAVING";
					if (!strpos($query,'GROUP BY')) //se non c'è il group by lo inserisce
					$query.=" GROUP BY {$this->primaryTable}.{$this->originalPrimaryKey} ";
				}	
					
				if (strpos($query,'ORDER BY'))
				{
					$exp=explode("ORDER BY",$query);			
					$exp[0].=" $where $cond ";
					$query=implode("ORDER BY",$exp);
				}
				else 				
			$query.=" $where $cond ";
					
				return $query;
	}		
	
	function printAddRowButton($image=false,$heading="")
	{
		//echo $this->status();
		
		if ($this->status()!='viewing' && !$this->useAjax) return false;
		
		if (!$this->canInsert) return false;	
		
		if (!$image) $image=$this->imagesAndScriptsPath."new.gif";
		
		if (!$heading) $heading=$this->lang['insertNew'];
		
		
		
		if ($this->useAjax)
		$href="javascript:DBN_{$this->originalPrimaryTable}.buildForm(0,'')";
		else
		$href="{$_SERVER['PHP_SELF']}?".buildQueryString("del_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable)."&amp;edit_{$this->originalPrimaryTable}=0#{$this->originalPrimaryTable}_anchor";
		
		echo "<a href=\"{$href}\"><img style=\"vertical-align:middle;border:none;\" src=\"".$image."\" alt=\"\" title=\"{$this->lang['insertNew']}\" /> {$heading}</a>";
		
		
		return true;
	}
	
	function printCsvDownloadButton($image=false,$heading="")
	{
		//echo $this->status();
		
		if ($this->status()!='viewing' && !$this->useAjax) return false;
			
		if (!$this->canExport) return false;	
			
		if (!$image) $image=$this->imagesAndScriptsPath."csv.gif";
		
		if (!$heading) $heading="Download ".str_replace("_"," ",$this->originalPrimaryTable)." CSV";
		
		echo "
		<a href=\"javascript:location.href=DBN_{$this->originalPrimaryTable}.getAjaxUrl()+'&csv_{$this->originalPrimaryTable}';\">
		<img style=\"vertical-align:middle;border:none;\" src=\"".$image."\" alt=\"\" title=\"{$heading}\" />
		{$heading}
		</a>";
		
		
		return true;
	}
	
	function printExcelXmlDownloadButton($image=false,$heading="")
	{
		//echo $this->status();
		
		if ($this->status()!='viewing' && !$this->useAjax) return false;
			
		if (!$this->canExport) return false;	
			
		if (!$image) $image=$this->imagesAndScriptsPath."excel_xml.gif";
		
		if (!$heading) $heading="Download ".str_replace("_"," ",$this->originalPrimaryTable)." XML for Excel/OpenOffice";
		
		echo "
		<a href=\"javascript:location.href=DBN_{$this->originalPrimaryTable}.getAjaxUrl()+'&excel_xml_{$this->originalPrimaryTable}';\">
		<img style=\"vertical-align:middle;border:none;\" src=\"".$image."\" alt=\"\" title=\"{$heading}\" />
		{$heading}
		</a>";
		
		
		return true;
	}	
	
	
	function delete_autoJoinedRows_recursive($id,$autoJoinKey)
	{	
			$query="SELECT * FROM {$this->originalPrimaryTable} WHERE {$autoJoinKey}='$id'";
			$result=mysql_query($query) or die ("ERRORE ELIMINAZIONE RICORSIVA: {$query}");
			while ($row=mysql_fetch_array($result))  //seleziona le categorie figlie dirette
			{
				$this->delete($row['id'],true);		
			}			
	}
	
	function delete_linkedTableRows($id,&$linkedDBN)
	{	
			$linkedDBN->scanTable();
	
			foreach($linkedDBN->externalJoin as $ed) //cerca la chiave collegata alla tabella da cui cancellare ricorsivamente
			{
				foreach($ed as $value) //cerca la chiave collegata alla tabella da cui cancellare ricorsivamente
				if ($ed['ex_table']==$this->originalPrimaryTable)
				{
					$chiave_esterna=$ed['externalKey'];			
					break 2;
				}
				
			}
			

			//print_r($linkedDBN->externalData);

			if (!isset($chiave_esterna)) die("Errata nella cancellazione linkata - non è stata trovata la chiave esterna");
			
			//die(print_r($this->deleteRecursive['DBNavigator']->externalData,true)."<br>$chiave_esterna");
					
			$query="SELECT * FROM {$linkedDBN->primaryTable} WHERE $chiave_esterna='$id'"; 
			//die($query);
			$result=mysql_query($query) or die ("QUERY errata per la cancellazione linkata: ".$query);
			while ($row=mysql_fetch_array($result))
			{
				$linkedDBN->delete($row[$linkedDBN->originalPrimaryKey],true);
			}
				
	}
	
	function delete($id,$recursiveCall=false)
	{
	
		if ($this->manage_record_availability($id,false)==false) //risolve la cancellazione di un record che sta subendo modifiche
		return false;
						
		if ($recursiveCall)
		$result=mysql_query("SELECT * FROM {$this->originalPrimaryTable} WHERE {$this->originalPrimaryKey}='{$id}'");
		else
		$result=mysql_query($this->addWhereConditionToQuery($this->query," {$this->primaryTable}.{$this->originalPrimaryKey}='{$id}'"));
		
		
		
		if (mysql_num_rows($result)>0)
		{	
			$this->deleteRow($id); //cancella i dati e i file della riga corrente
			
			if (isset($this->deleteRecursive['key']) && is_array($this->deleteRecursive['key']))
			foreach($this->deleteRecursive['key'] as $autoJoinKey)
			$this->delete_autoJoinedRows_recursive($id,$autoJoinKey);
	
			if (isset($this->deleteRecursive['DBNavigator']) && is_array($this->deleteRecursive['DBNavigator']))
			foreach($this->deleteRecursive['DBNavigator'] as $linkedDBN)
			$this->delete_linkedTableRows($id,$linkedDBN);
					
		}
		
		return true;
		
			
	
	}
	
	function deleteRow($id)
	{	
				$query="SELECT * FROM {$this->originalPrimaryTable} WHERE {$this->originalPrimaryKey}='$id'";
				$result=mysql_query($query);
				$row=mysql_fetch_array($result);
				
				
				if ($this->extraDeletingFunction!='') {$f=$this->extraDeletingFunction; $f($row);}
	
				foreach ($this->photoField as $field=>$bool)
				{ 
					if ($field=="_Resize_" || $field=="_KeepOriginal_") continue; ////da sistemare......? parametri delle immagini nello stesso array
					
						
					if (file_exists($this->filePath."/".$row[$field]) && $row[$field]!="")
						unlink($this->filePath."/".$row[$field]);
					
					if (file_exists($this->filePath."/small_".$row[$field]))				
						unlink($this->filePath."/small_".$row[$field]);
				}	
				
				foreach ($this->fileField as $field=>$bool)
				{ 					
					if (file_exists($this->filePath."/".$row[$field]) && $row[$field]!="")
						unlink($this->filePath."/".$row[$field]);
					
					if (file_exists($this->filePath."/small_".$row[$field]))				
						unlink($this->filePath."/small_".$row[$field]);
				}
				
				$query="delete from {$this->originalPrimaryTable} where {$this->originalPrimaryKey}='$id'";
				mysql_query($query) or die('Eliminazione fallita');
				
				
	}
	
	
	
	function scanTable() 		//OTTIENE I DATI DELLE COLONNE DELLA QUERY////////////////////////////////
	{
		if ($this->tableScanned==true) return false; else $this->tableScanned=true;
	
	
			////ricerca alias della tabella
			if (strstr($this->query," ".$this->primaryTable." AS ")) 
			{
				
				$exp=explode(" ".$this->primaryTable." AS ",$this->query);
				$exp=explode(" ",$exp[1]);
	
				$this->primaryTable=trim($exp[0]); //inserimento dell'alias
				
			}////////////////////////////	
			
	
	/*			$result=mysql_query("SELECT * FROM {$this->originalPrimaryTable}");
				
				$i=0;
	
				while ($i < mysql_num_fields($result))//Ricerca chiave primaria
				{
					$field = mysql_fetch_field($result);
					if ($field->primary_key==1)	
					{
						
						$this->primaryKey=$field->name; 
						$this->originalPrimaryKey=$field->name;
						break;
					}
				}	*/
	
	
				$field_result=mysql_query("SHOW FIELDS FROM $this->originalPrimaryTable");
				$index_result=mysql_query("SHOW INDEX  FROM {$this->originalPrimaryTable}");
				
	
				//die($this->query);
				$result=mysql_query($this->query." LIMIT 0,1") or die("<strong>QUERY :</strong><br />".$this->query."<br /><b>ERRORE :</b><br />".mysql_error());
	
				//echo mysql_field_type($result,1);
				
				$i=0;
				while ($i < mysql_num_fields($result))
				{
					
					$field = mysql_fetch_field($result);
					/*echo "<pre>".print_r($field,true)."</pre>";*/
					$field->def=$field->name;
					//echo $this->query;
					
					
					if (preg_match("/ AS {$field->name}( |\\n|\\r|\\r\\n|,)/",$this->query,$pattern)!=false)
					{
						//print_r($pattern);
						$pos=strpos($this->query,$pattern[0]);
						
						
						$temp=str_replace(array("\n","\r"),"",substr($this->query,0,$pos)); //dall'inizio fino al nome del campo
	
						$commaPos=strrpos($temp,",");
						$pointPos=strrpos($temp,".");
						$spacePos=strrpos($temp," ");
						$max=max($commaPos,$pointPos,$spacePos);
						switch($max)
						{
							case $commaPos: $field->name=substr($temp,$commaPos+1); break;
							case $pointPos: $field->name=substr($temp,$pointPos+1); break;
							case $spacePos: $field->name=substr($temp,$spacePos+1); break;
						}
						
	/*						ADESSO IL RICONOSCIMENTO DELLA PRIMARY E' DOPO			
						if ($this->primaryKey==$field->name && $field->table==$this->primaryTable) //correzione nel caso si sia dato l'alias alla chiave primaria 		
						{
							$this->primaryKey=$field->def;		//alias
							$this->originalPrimaryKey=$field->name; //nome campo
						}
						*/
					}
					
					
					
					//-----------------Ricerca chiave primaria-------------------	
					//notare che Field->table può essere l'alias della tabella
					//
					if ($this->primaryKey=='' && $field->table==$this->primaryTable) 
					//if ($field->primary_key==1) //non affidabile con query con join
					{
						mysql_data_seek($index_result,0); 
						while ($idx=mysql_fetch_array($index_result))
						{
							if ($idx['Column_name']==$field->name && $idx['Table']==$this->originalPrimaryTable)
							{
								$this->primaryKey=$field->def; 
								$this->originalPrimaryKey=$field->name;
								break;
							}
						}
					}	
					//-------------------------------------------------------------			
									
										
					
					mysql_data_seek($field_result,0);  //distinzione precisa del tipo del campo (string->enum, blob->text,longtext)
					while ($row_field=mysql_fetch_array($field_result))
					{
						if (
							 $row_field['Field']==$field->name && 
							 ( substr($row_field['Type'],0,4)=="enum" || $field->type=='blob' || substr($row_field['Type'],0,3)=="set" )
						   )	  						
						$field->type=$row_field['Type'];
					}
				  //////////////////////////////////////////////////////////////////////////
	
	/*			echo "<pre>";
				print_r($field);
				echo "</pre>";	*/
	
														
						 if (isset($this->fileField[$field->name]))              $field->not_null=array($field->not_null==1,REGEXP_FILE);					
					else if (isset($this->photoField[$field->name]))             $field->not_null=array($field->not_null==1,REGEXP_IMAGE);															
					else if (isset($this->mailField[$field->name]))              $field->not_null=array($field->not_null==1,REGEXP_EMAIL);					
					else if (isset($this->numericStringField[$field->name]))     $field->not_null=array($field->not_null==1,REGEXP_NUMSTRING);
					else if ($field->type=="int")                                $field->not_null=array($field->not_null==1,REGEXP_NUMINT);					
					else if ($field->type=="real")                               $field->not_null=array($field->not_null==1,REGEXP_NUMREAL);
					
					else if ($field->not_null==1)
					{
						if ($field->type=="date") $field->not_null=REGEXP_DATE;
						else					  $field->not_null=REGEXP_NOTNULL; //tutti gli altri casi (anche i non contemplati)
						// string tinytext text mediumtext longtext enum set
					}
					else $field->not_null=false;
										
	
					// se  $field->table!=$this->primaryTable allora la validazione viene impostata direttamente in buildForm!!!
					
					if (isset($this->passwordField[$field->name])) {$field->type="password";}
	
	
				
					$this->field[]=$field;
					//if ($field->primary_key==1 && $field->table==$this->primaryTable) $this->primaryKey=$field->name;
					//if ($_GET['ord']==$field->name) $ord=$field->table.".".$field->name;
					if ($field->table!='' && $field->table!=$this->primaryTable) $externalData[]=array("table"=>$field->table,"field"=>$field->name,"alias"=>$field->def);
	
	
					$i++;
				}
				
				if ($this->primaryKey=='') die('CHIAVE PRIMARIA NON TROVATA - '.$this->query); 

	
		//cerca le chiavi secondarie per collegare gli id delle tabelle collegate alla principale con i campi della query 	
	
		//preg_match_all("{((ON .+\..+=.+\..+( OR .+\..+=.+\..+)+)|(ON .+\..+=.+\..+))( |\)|$)}U",$this->query,$join,PREG_SET_ORDER);	
		preg_match_all("{ON .+\..+\s?=\s?.+\..+( |\)|$|\s)}U",$this->query,$join,PREG_SET_ORDER);
	
	
		
/*		echo "<br /><pre>";
		print_r($join);	
	echo "</pre><br />";
	
		echo "<br /><pre>";
		print_r($externalData);	
	echo "</pre><br />";*/
	
		foreach ($join as $clause)
		{
			
			$clause[0]=substr($clause[0],3,strlen($clause[0])); //elimina 'ON '
	
			
			$last_char=substr($clause[0],strlen($clause[0])-1,1);
			if ($last_char==" " || $last_char==")") 
			{
				$clause[0]=substr($clause[0],0,strlen($clause[0])-1);  //elimina l'ultimo carattere se parentesi o spazio
			}
			//echo "'".$clause[0]."'<---<hr>";
			
			
			$link=explode("=",$clause[0]);
			$exp=explode(".",$link[0]);
			$table_link1=trim($exp[0]); $field_link1=trim($exp[1]);
			$exp=explode(".",$link[1]);
			$table_link2=trim($exp[0]); $field_link2=trim($exp[1]);	
			
			
			if ($table_link1==$this->primaryTable)
			{
				$ex_table=$table_link2;
				$ex_primaryKey=$field_link2;
				$externalKey=$field_link1;
			}
			else
			if ($table_link2==$this->primaryTable)
			{
				$ex_table=$table_link1;
				$ex_primaryKey=$field_link1;
				$externalKey=$field_link2;		
			}
			else continue; //(?)
	
			if (isset($externalData) && is_array($externalData))
			foreach($externalData as $key=>$val)
			{ 
	
				if ($val['table']==$ex_table)			
				{
	
					$this->externalData[]=array("ex_table"=>$val['table'],"ex_field"=>$val['field'],"ex_alias"=>$val['alias'],"ex_primaryKey"=>$ex_primaryKey,"externalKey"=>$externalKey);

		
					foreach($externalData as $key2=>$val2) //elimina altri campi collegati della stessa tabella! (perchè tanto vale solo il primo in modifica)
					{
						if ($val2['table']==$ex_table) unset($externalData[$key2]);
					}
					unset($externalData[$key]);
					break;
				}
			}
			
			///così si possono effettuare cancellazioni linkate senza selezionare alcun campo della tabella collegato nel select della query
			$this->externalJoin[]=array("ex_table"=>$ex_table,"ex_primaryKey"=>$ex_primaryKey,"externalKey"=>$externalKey);			
			///
			
		}
		//print_r($this->externalJoin);
	
	
	}
	
	function form_error_handling($error_code,$error_field)
	{
		$error_field_2=str_replace("_"," ",ucfirst($error_field));
	
		switch ($error_code)
		{
			
			case 'availability_error': //in realtà questo errore non si dovrebbe verificare MAI perchè ci sono le prenotazioni dei record modificati simultaneamente
					echo "<strong style=\"color:#F00\">{$this->lang['errorAvailability']}</strong>";
					break;
			case 'query_error':
				
				mail("hide@address.com","DBN debug: ".$_SERVER['HTTP_HOST']
				,$error_field."<br />".$_SERVER['PHP_SELF']."<br /><br /><br /><pre>".print_r($_GET,true)."</pre><br /><hr /><pre>".print_r($_POST,true)."</pre><br /><hr />
				<pre>".print_r($_FILES,true)."</pre>"
				,"Content-Type: text/html; charset=utf-8\r\n");
				
				$showed_error= "Query error: $error_field <br />{$this->lang['errorSended']}";  //mail for debug
							   echo $showed_error; break;		
						
			case 'file_conflict':$showed_error= "$error_field_2: {$this->lang['errorFileConflict']}";	
							$this->editForm->setFocused($error_field,$showed_error); break;		
			
			case 'key_conflict':    $showed_error= "$error_field_2: {$this->lang['errorKeyConflict']}";		
							$this->editForm->setFocused($error_field,$showed_error); break;		
	
			case 'format_conflict':$showed_error= "$error_field_2: {$this->lang['errorFormatConflict']}";	
							$this->editForm->setFocused($error_field,$showed_error); break;	
							
			case 'wrong_vercode':$showed_error= "$error_field_2: {$this->lang['errorWrongVerCode']}";	
							$this->editForm->setFocused($error_field,$showed_error); break;		
									
			case 'wrong_pwd':$showed_error= "$error_field_2: {$this->lang['errorWrongPassword']}"; 
						$this->editForm->setFocused($error_field."_old",$showed_error);	break;
						
			case 'file_too_big':$showed_error= "$error_field_2: {$this->lang['errorFileTooBig']}"; 
						$this->editForm->setFocused($error_field,$showed_error);	break;					
		}
		//echo $this->formHeading['heading']." <em>...errore</em>";
	}
	
	function manage_record_availability_AjaxCall($id,$bookRecord)
	{
		if (!is_array($id)) //metodo buildform AJAX
		{
			if ($this->manage_record_availability($id,$bookRecord)==true)		
			{
				die('!!!!!!');
			}
			else
			die('');
		}else //metodo delete_, multipleDelete AJAX
		{
			$occupied=false;
			
			foreach($id as $i)
			if (!$this->manage_record_availability($i,$bookRecord)) 
			$occupied=$i;
			//die('!!!!!!'.$i);
			
			if ($occupied===false)
			die('!!!!!!');
			
			//die('!!!!!!'.$occupied);
		}	
	}
	
	function commonAjaxFunctions()
	{
	
		return "
		<script type=\"text/javascript\" src=\"{$this->imagesAndScriptsPath}autosuggest.js\"></script>
		<script type=\"text/javascript\" src=\"{$this->imagesAndScriptsPath}zxml.js\"></script>
		<script type=\"text/javascript\" src=\"{$this->imagesAndScriptsPath}DBNavigator.js\"></script>
		<script type=\"text/javascript\">
		<!--
		
		var imagesAndScriptsPath='{$this->imagesAndScriptsPath}';
	
		var DBN_{$this->originalPrimaryTable}=new DBNavigator('DBN_{$this->originalPrimaryTable}','{$this->originalPrimaryTable}');
		
		-->
		</script>
		";
	
	}
	
	
	function go_only_for_form($id,$successMsg="Inserimento/modifiche effettuato/e",$after_query_function="",$replace_array=null)
	{
		$this->main($after_query_function,true);
			
		if (!$this->ajaxCall) 
			echo $this->commonAjaxFunctions()."<div id=\"{$this->originalPrimaryTable}_form_anchor\">"; //ancora
		else 
			ob_end_clean();	
		
		//print_r($_POST);
		//print_r($_FILES);
	
		if (isset($_GET['success_'.$this->originalPrimaryTable]))
		echo $successMsg;
	
		if (!isset($_GET['success_'.$this->originalPrimaryTable]))
		echo $this->buildForm($id,$replace_array,false);
	
		if ($this->ajaxCall) die('');
		else
		echo "<script type=\"text/javascript\">
			  <!--	
					if (typeof(window.onload)=='function')
					{					
						var oldonload_2_{$this->originalPrimaryTable}=window.onload;
						
						window.onload=function()
												{
													document.onmousemove=handlemousemove;
													{$this->JS_onLoad}
													oldonload_2_{$this->originalPrimaryTable}();
												}		
	
					}
					else
					window.onload=function()
											{
												document.onmousemove=handlemousemove;
												{$this->JS_onLoad}
	
											}			
			  -->
			  </script>";
	
		echo "</div>"; //fine ancora	
		
	}	
	
	
	function main($after_query_function="",$onlyForm=false)
	{
		if (!isset($this->lang['languageName'])) $this->setLanguage("italian"); //lingua predefinita
		
		//echo $this->status();
		
		$this->scanTable();
		//print_r($_GET);
		//print_r($_FILES);	
	
		if (isset($_POST["frm_{$this->originalPrimaryTable}_submit"]))
		{	
		
			foreach($this->passwordField as $field=>$unused) //GESTIONE DELLLE PASSWORDS
			if (!$this->managePassword($field))
			{
				$password_error=$field;
				break; 
			}
			
			$availability_error=false;
			if (is_array($_POST[$this->originalPrimaryKey]))//in go_only_for_form non c'è modifica multipla
			{		
				
				foreach($_POST[$this->originalPrimaryKey] as $id)
				{
					if (!$this->canEdit || (is_array($this->canEdit) && !in_array($id,$this->canEdit) ) )
					{
						$availability_error=true;
						break;
					}
					
				   if (!$this->manage_record_availability($id,false)) //al primo record che è in modifica da qualche altro, ferma la MODIFICA e prenota la modifica per il record
				   {
						
						$availability_error=true;	
						break;
				   }
				}
			}//////////////////////////////////////////////////////////////////////////
	
			if (!isset($password_error) && $availability_error!=true) //inserisce solo senza errore di password (altrimenti MODIFICA il record)
			{	
				$esito_insertIntoDBFromPOST=insertIntoDBFromPOST($this->originalPrimaryTable,"frm_{$this->originalPrimaryTable}_submit",$this->originalPrimaryKey,$this->filePath,$this->photoField['_Resize_'],$this->photoField['_KeepOriginal_']);
			}
			
			if (isset($password_error) || $esito_insertIntoDBFromPOST!=1 || $availability_error==true) //errore
			{
				if (isset($password_error))
				{
					$error_code='wrong_pwd';
					$error_field=$password_error;
				}else if ($esito_insertIntoDBFromPOST!=1) //0 non può essere perchè c'è un if all'inizio che controlla il submit_button
				{			
					$error_code=$esito_insertIntoDBFromPOST[0];
					$error_field=$esito_insertIntoDBFromPOST[1];
				}else if ($availability_error) //in go_only_for_form non c'è modifica multipla
				{
					$error_code="availability_error";
					$error_field="";
				}
				$this->form_error_handling($error_code,$error_field);
			}				
			else 
			{
				if ($after_query_function!="") $after_query_function();
				
				if ($onlyForm) 
				die("<script type=\"text/javascript\">location.href=('".$_SERVER['PHP_SELF']."?".html_entity_decode(buildQueryString())."&success_{$this->originalPrimaryTable}#{$this->originalPrimaryTable}_form_anchor');</script>"); 
	
	
				if (isset($_GET["selected_".$this->originalPrimaryTable]))//elimina il get del record modificato
				{
					if ($_GET["action_".$this->originalPrimaryTable]=='edit')
					{
						array_shift($_GET["selected_".$this->originalPrimaryTable]);			
						if (count($_GET["selected_".$this->originalPrimaryTable])==0) 
						{
							unset($_GET["sellen_".$this->originalPrimaryTable]);
							unset($_GET["action_".$this->originalPrimaryTable]);
							unset($_GET["selected_".$this->originalPrimaryTable]);
						}
					}
					else 
					if ($_GET["action_".$this->originalPrimaryTable]=='editMany')
					{
						unset($_GET["sellen_".$this->originalPrimaryTable]);
						unset($_GET["action_".$this->originalPrimaryTable]);
						unset($_GET["selected_".$this->originalPrimaryTable]);
					}
					else if ($_GET["action_".$this->originalPrimaryTable]=='del')
					$_GET["del_".$this->originalPrimaryTable]=array_shift($_GET["selected_".$this->originalPrimaryTable]);		//?? non serve?			
					
					echo "<script type=\"text/javascript\">location.href=(\"".$_SERVER['PHP_SELF']."?".html_entity_decode(buildQueryString())."#{$this->originalPrimaryTable}_anchor\");</script>"; 
	
				}else
				{
					unset($_GET["sellen_".$this->originalPrimaryTable]);
					unset($_GET["action_".$this->originalPrimaryTable]);							
					echo "<script type=\"text/javascript\">location.href=(\"".$_SERVER['PHP_SELF']."?".html_entity_decode(buildQueryString('edit_'.$this->originalPrimaryTable))."#{$this->originalPrimaryTable}_anchor\");</script>"; 
				
				}
			}
			
		}	
	}
	
	
	
	
	function go($after_query_function="",$PageNavigator_on_top=false,$viewing_data_function="",$replace_array=null)
	{
		$this->main($after_query_function,false);
		
		if (!$this->ajaxCall) 
		echo $this->commonAjaxFunctions()."<div id=\"{$this->originalPrimaryTable}_anchor\">"; //ancora
		else ob_end_clean();
		
		if (isset($_GET['csv_'.$this->originalPrimaryTable]) ) $this->export("CSV");
		else
		if (isset($_GET['excel_xml_'.$this->originalPrimaryTable]) ) $this->export("EXCEL_XML");
		else
		if (isset($_GET['view_'.$this->originalPrimaryTable]) )  
		{	
			$id=$_GET['view_'.$this->originalPrimaryTable];
			$row=mysql_fetch_array(mysql_query($this->addWhereConditionToQuery($this->query,"{$this->originalPrimaryTable}.{$this->originalPrimaryKey}='{$id}'")));
			if ($row)
			{
				ob_end_clean();
				die( $this->viewForPrint($id));
			}
			else $this->printTable($replace_array,$PageNavigator_on_top,$viewing_data_function);
					
		}
		else
		if (
			(isset($_GET['edit_'.$this->originalPrimaryTable]) && $_GET['edit_'.$this->originalPrimaryTable]!="")  
			||
			(isset($_GET['action_'.$this->originalPrimaryTable]) && $_GET['action_'.$this->originalPrimaryTable]=="edit" 
			 && count($_GET['selected_'.$this->originalPrimaryTable])>0)
			)  
		{	
	
			$head_str="";
			if (isset($_GET["action_".$this->originalPrimaryTable]))
			{
				$head_str="<span style=\"color:#FF0000;font-weight:bolder;\">
								{$this->lang['editing']} {$this->rowName} ".($_GET["sellen_".$this->originalPrimaryTable]-count($_GET["selected_".$this->originalPrimaryTable])+1)."
								{$this->lang['of']} ".$_GET["sellen_".$this->originalPrimaryTable]
						 ."</span><br /><br />"	;	
				
				$id=$_GET["selected_".$this->originalPrimaryTable][0];
										
			}
			else $id=$_GET['edit_'.$this->originalPrimaryTable];

			$row=mysql_fetch_array(mysql_query($this->addWhereConditionToQuery($this->query,"{$this->primaryTable}.{$this->originalPrimaryKey}='{$id}'")));
			
			if (
				 ( $row && ($this->canEdit===true || (is_array($this->canEdit) && in_array($row[$this->primaryKey],$this->canEdit)) ) ) 
				 || 
				 (!$row && $id==0 && $this->canInsert) 
			   ) // se è un inserimento...fragile(si assume che lo zero non verrà mai usato come chiave primaria) 
			echo $head_str.$this->buildForm($id,$replace_array,true);		
			else
			{
				if (!$row)
				{
					echo $head_str;
					
					echo "<script type=\"text/javascript\">
							<!--
								alert(\"{$this->lang['recordHasBeenDeleted']}\");
								";
		
					if (isset($_GET["action_".$this->originalPrimaryTable])) //selezione
					{
						if ($this->useAjax)
						{
							echo "  DBN_{$this->originalPrimaryTable}.selectionInfoGet=DBN_{$this->originalPrimaryTable}.selectionInfoGet.replace(
											new RegExp(\"selected_{$this->originalPrimaryTable}((%5B|\\\\[)\\\\d*(\\\\]|%5D))?=?{$id}($|&|#)\",\"g\"),'');
									DBN_{$this->originalPrimaryTable}.reloadPage();";	
						}
						else
						{
							array_shift($_GET["selected_".$this->originalPrimaryTable]);
							if (count($_GET["selected_".$this->originalPrimaryTable])==0)
							{
								unset($_GET["sellen_".$this->originalPrimaryTable]);
								unset($_GET["action_".$this->originalPrimaryTable]);		
							}	
							echo "	location.href=('".$_SERVER['PHP_SELF']."?".html_entity_decode(buildQueryString())."');";
						}
					}
					else //singolo
					{
						unset($_GET['edit_'.$this->originalPrimaryTable]);
					}
					
					echo "
							-->
						</script>"; 	
				}	
					
				if ($row || !isset($_GET["action_".$this->originalPrimaryTable])) //esegue con la selezione singola di record inesistenti e con la modifica di record
																				 //senza i privilegi necessari
				$this->printTable($replace_array,$PageNavigator_on_top,$viewing_data_function);
			
			}
			//die("Azione non consentita");
		}
		else if (isset($_GET["action_".$this->originalPrimaryTable]) && $_GET["action_".$this->originalPrimaryTable]=='editMany' && isset($_GET["selected_".$this->originalPrimaryTable])) 
		{
			
			$id=array();
			
			if ( is_array($this->canEdit) ) //impostazione id con i permessi
			{
				foreach($_GET["selected_".$this->originalPrimaryTable] as $sel)
				{
					if (in_array($sel,$this->canEdit) ) $id[]=$sel; 
				}
			}
			else	
			if ( $this->canEdit===true )
			$id=$_GET["selected_".$this->originalPrimaryTable];
			
			if ( count($id)==0 ) //nessun id autorizzato
			$this->printTable($replace_array,$PageNavigator_on_top,$viewing_data_function);
			else
			{ 
				echo $this->buildForm($id,$replace_array,true);
			}
		}
		else if (
					isset($_GET['del_'.$this->originalPrimaryTable]) 
					|| 
					(isset($_GET["action_".$this->originalPrimaryTable]) && $_GET["action_".$this->originalPrimaryTable]=='delete' && isset($_GET["selected_".$this->originalPrimaryTable]))
				)
		{
			$occupiedId='';
			$id=array();
			
			if (isset($_GET["selected_".$this->originalPrimaryTable]))
			$sel=$_GET["selected_".$this->originalPrimaryTable];
			else
			$sel=array($_GET['del_'.$this->originalPrimaryTable]);
			
			foreach($sel as $selected)
			{
				if ($this->canDelete===true || (is_array($this->canDelete) && in_array($selected,$this->canDelete) ) )
				{
				   if (!$this->manage_record_availability($selected,true)) //al primo record che è in modifica da qualche altro, ferma la cancellazione e prenota la modifica per il record
				   $occupiedId=";DBN_{$this->originalPrimaryTable}.manage_record_availability_for_editing({$selected},false)"; //uno a caso
				
				   $id[]=$selected;
				}
			}
		
		
			if (!$occupiedId)
			{
				foreach($id as $ids) $this->delete($ids); //eliminazione, andrà a successo di sicuro dopo la verifica e la prenotazione
				
				echo "
				<script type=\"text/javascript\">
				<!--
						DBN_{$this->originalPrimaryTable}.selectionInfoGet=''; //caso particolare
				-->
				</script>";
				
				if ($this->useAjax)
				{
					unset($_GET['selected_'.$this->originalPrimaryTable]);
					unset($_GET['action_'.$this->originalPrimaryTable]);
					unset($_GET['del_'.$this->originalPrimaryTable]);
					unset($_GET['selected_'.$this->originalPrimaryTable]);
					$this->printTable($replace_array,$PageNavigator_on_top,$viewing_data_function);
				}
				else
				echo "<script type=\"text/javascript\">location.href=('".$_SERVER['PHP_SELF']."?"
				.html_entity_decode(buildQueryString('selected_'.$this->originalPrimaryTable,"action_".$this->originalPrimaryTable,"sellen_".$this->originalPrimaryTable,'del_'.$this->originalPrimaryTable))."');</script>"; 		
			}
			else
			{
				$getAppend="";
				$selinfoget="&action_{$this->originalPrimaryTable}=delete";
				foreach($id as $ids) 
				{
					$getAppend.="&manage_record_availability[]=".$ids;
					$selinfoget.="&del_{$this->originalPrimaryTable}[]=".$ids;
				}						
				
				
				if ($this->useAjax)
				$href="javascript:DBN_{$this->originalPrimaryTable}.printTable()";
				else
				{
					$qs=buildQueryString("del_{$this->originalPrimaryTable}",'edit_'.$this->originalPrimaryTable,"action_{$this->originalPrimaryTable}","sellen_{$this->originalPrimaryTable}","selected_{$this->originalPrimaryTable}");
					$href=$_SERVER['PHP_SELF']."?$qs#{$this->originalPrimaryTable}_anchor";
				}
				
				//se ce n'è uno occupato termina qui
				echo "
				<script type=\"text/javascript\">
				<!--
					DBN_{$this->originalPrimaryTable}.checkAvailability=setInterval(\"DBN_{$this->originalPrimaryTable}.createHttpRequest2('&bookRecord{$getAppend}',function(){}){$occupiedId}\",3000); // rifa il controllo dopo 7 secondi																
				-->
				</script>
				<br /><div style=\"cursor:wait;font-weight:bolder;border:1px solid #FF0000;padding:3%\">
								{$this->lang['warningRecordOccupied']}
								<a href=\"{$href}\">&raquo; {$this->lang['goBack']}</a> 
								</div><br />";				
			}	
		}
		else
		{
			$this->printTable($replace_array,$PageNavigator_on_top,$viewing_data_function);
		}
		
		if ($this->ajaxCall) die('');
		else
		echo "<script type=\"text/javascript\">
			  <!--	
					if (typeof(window.onload)=='function')
					{					
						var oldonload_1_{$this->originalPrimaryTable}=window.onload;
						
						window.onload=function()
												{
													document.onmousemove=handlemousemove;
													{$this->JS_onLoad}
													oldonload_1_{$this->originalPrimaryTable}();
												}		
	
					}
					else
					window.onload=function()
											{
												document.onmousemove=handlemousemove;
												{$this->JS_onLoad}
	
											}			
			  -->
			  </script>";
		
		echo "</div>"; //fine ancora
	}
	
	function query_ricorsiva($id,$query) //conta i nodi del sottoalbero partendo da $id
	{
		$result=mysql_query(str_replace("%current_row_id%",$id,$query)); 
		$count=0;
		while ($row=mysql_fetch_array($result))
		{
			$count++;
			$return=$this->query_ricorsiva($row[0],$query); //assume che l'id della tabella della query sia il primo campo (0)
			$count+=$return;
		}
		return $count;
	}
			
	function search_form($new_line=false)
	{
		$this->scanTable();		
		$print="";
		$JS="";
	
		if (count($this->searchField)>0)///////FORM DI RICERCA///////////////////////////////////////
		{		
			$print.= "<script type=\"text/Javascript\" src=\"{$this->imagesAndScriptsPath}autosuggest.js\"></script>
						<div style=\"width:100%;\" id=\"{$this->originalPrimaryTable}_search_form\"><fieldset style=\"padding:5px;\">
						<legend><em>{$this->lang['searchOn']}</em></legend>";
			
			$horizontal_space=$new_line?8:12;
			$HF=new HTMLForm("src_{$this->originalPrimaryTable}",$_SERVER['PHP_SELF']."#".$this->originalPrimaryTable."_anchor",25,75,"Form di ricerca ".$this->rowName,"get",$horizontal_space,$new_line);	
			
			$HF->setLanguage($this->lang['languageName']);
			
			foreach($_GET as $name=>$value) //parametri vari
			{
				if (strstr($name,"_src_".$this->originalPrimaryTable) || strstr($name,"src_".$this->originalPrimaryTable."_submit") 
				|| $name=="ord_".$this->originalPrimaryTable || $name=="desc_".$this->originalPrimaryTable || $name=="Page_".$this->originalPrimaryTable  )
				continue; 
				else $HF->addInput("hidden",$name,stripslashes($value));
			}
			
			foreach($this->searchField as $key=>$data)
			{
	
				if (is_array($data['field_alias']))
				{
					$heading=array();
					
					foreach ($data['field_alias'] as $val)
					$heading[]=str_replace("_"," ",ucfirst($val));
					
					$heading=implode(",<br />",$heading);
				}
				else
				$heading=str_replace("_"," ",ucfirst($data['field_alias']));
			
				
	
				if (!is_array($data['table']) && $data['table']!="Having")
				{
					$result=mysql_query("DESCRIBE {$data['table']}"); //CONTROLLO TIPO DEL CAMPO
					while($row=mysql_fetch_array($result)) 
						if ($row['Field']==$data['field'])
						{
					
						 	if (strstr($row['Type'],"enum") || strstr($row['Type'],"set") ) //guarda se è enum
							{
								$enum_set_value=array_merge(array(''=>"&raquo; {$this->lang['all']}"), $this->getEnumSetValue($row['Type']));
								break;
							}
							
							if (strstr($row['Type'],"date")) //guarda se è una data
							{
								$date_value=array(""=>"Tutte le date");
								$result=mysql_query("SELECT {$data['field']} FROM {$this->originalPrimaryTable} GROUP BY {$data['field']}");
								while ($row=mysql_fetch_array($result))
								{
									$exp=explode("-",$row[$data['field']]);
									$date_value[$row[$data['field']]]=$exp[2]."/".$exp[1]."/".$exp[0];
								}
								break;
							}
							if (   strstr($row['Type'],"bigint") || strstr($row['Type'],"int") 
								|| strstr($row['Type'],"float") || strstr($row['Type'],"double")  )  //guarda se è un numero
							{
								$numeric=true;
								break;
							}									
						}
				}
				
				if ($data['table']=="Having") $numeric=true;
			
				if (is_array($data['field'])) //NUOVO CASO - PIU' CAMPI DI RICERCA x un testo solo
				{
					$inputName=implode("_",$data['field'])."_src_".$this->originalPrimaryTable;
					$JS.= "
						   new AutoSuggestControl('{$this->originalPrimaryTable}',document.getElementById(\"{$inputName}\"),new Array('".implode("','",$data['field'])."'));";
													
					$HF->addInput("text",$inputName,$data['value'],$heading,false,null,false,$this->classForFormInput['inputs']);		
												
				}else		
				if (isset($enum_set_value)) // @------ è un ENUM - radio....non più: uso la select con selezione multipla che è più funzionale
				{				
					$select_items=count($enum_set_value);
					if ($select_items<8)
					$select_size=$select_items;
					else
					$select_size=8;
	
					$HF->addInput("select","{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$enum_set_value,$heading,$select_size,$data['value'],false,$this->classForFormInput['inputs']);
					unset($enum_set_value);
					//$this->searchField[$key]['ricerca_libera']=false;
				}
				else if (isset($date_value)) // @------ INTERVALLO DATE! -- ricerca intervalli con input aggiunto 'manualmente' (senz addinput() di htmlform)
				{
/*					$HF->addInput("select","{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$date_value,$heading,true,$data['value'],false,$this->classForFormInput['inputs']);
					*/
					
					//$this->searchField[$key]['ricerca_libera']=false;

					$inputs="					
					<label for=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\">
						<strong>{$heading}</strong> {$this->lang['from']} 
					</label>
					
					<select class=\"{$this->classForFormInput['inputs']}\"
					   	   id=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\" 
						   name=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\">";
					
						
/*						//come caso tab esterna con opzioni limitate
						$from=strstr($this->query,"FROM");
						$group_by_pos=strpos($from,"GROUP BY");
						if ($group_by_pos)	$from=substr($from,0,$group_by_pos);
					
						$q="SELECT min({$data['table_alias']}.{$data['field']}) AS min, max({$data['table_alias']}.{$data['field']}) AS max $from";		
						mysql_query($q) or die ('errore selezione estremi date'.mysql_error());
						$row=mysql_fetch_array($result);
						
						$min=explode("-",$min); $min=$min[0];
						$max=explode("-",$max); $max=$max[0];
					
						$date=dateArray($min,$max); 
		
						foreach	 ($date as $k=>$v)
						{
							$inputs.="<option value=\"{$k}\" ".($current_start==$k?"selected=\"selected\"":"").">{$v}</option>
							";
						} 
						............................iniziato, non continuato. Per una selezione tra due date specificando gg mm aaaa sono necessari
						6 input, cioè 6 get! proviamo con 2 */
					
					$current_start=isset($data['value']['start'])?$data['value']['start']:false;
						   
					foreach	 ($date_value as $k=>$v)
					{
						$inputs.="<option value=\"{$k}\" ".($current_start==$k?"selected=\"selected\"":"").">{$v}</option>
						";
					}  
						    
					$inputs.="
					</select>						
						   
					<label for=\"{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable."_end\"> 
						{$this->lang['to']} 
					</label>
					
					<select class=\"{$this->classForFormInput['inputs']}\"
					   	   id=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_end\" 
						   name=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_end\">";

					$current_end=isset($data['value']['end'])?$data['value']['end']:false;
						   
					foreach	 ($date_value as $k=>$v)
					{
						$inputs.="<option value=\"{$k}\" ".($current_end==$k?"selected=\"selected\"":"").">{$v}</option>
						";
					}  
						    
					$inputs.="
					</select>";	

					
					$HF->addExternalContent($inputs);

					unset($date_value);
				}
				else if (isset($numeric)) /////@------ numero - ricerca intervalli con input aggiunto 'manualmente' (senz addinput() di htmlform)
				{
					$HF->addExternalContent("					
					<label for=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\">
						<strong>{$heading}</strong> {$this->lang['from']} 
					</label>
					
					<input style=\"width:70px;\" class=\"{$this->classForFormInput['inputs']}\" type=\"text\" 
						   id=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\" 
						   name=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_start\" 
						   value=\"".(isset($data['value']['start'])?$data['value']['start']:"")."\" /> 
						   
					<label for=\"{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable."_end\"> 
						{$this->lang['to']} 
					</label>
					
					<input style=\"width:70px;\" class=\"{$this->classForFormInput['inputs']}\" type=\"text\" 
						   id=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_end\"
						   name=\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}_end\"
						   value=\"".(isset($data['value']['end'])?$data['value']['end']:"")."\" /> 
					");

					unset($numeric);
					//$this->searchField[$key]['ricerca_libera']=false;
				}
	
				else // @------ tabella esterna - select			
				if ($data['table']!=$this->originalPrimaryTable && $data['table']!="Having")
				{				
					if ($this->viewAllSearchOptions)
					{
						$q="SELECT {$data['field']} FROM {$data['table']} ORDER BY {$data['field']}";				
					}
					else
					{
						$from=strstr($this->query,"FROM");
						$group_by_pos=strpos($from,"GROUP BY");
						if ($group_by_pos)	$from=substr($from,0,$group_by_pos);
					
						$q="SELECT {$data['table_alias']}.{$data['field']} $from ORDER BY {$data['table_alias']}.{$data['field']}";				
					}
					//echo $q."<hr>";
					$result=mysql_query($q) 
					or print ("<br /><br />errore query della select per la ricerca : <br /><br /> QUERY:<br /> ".$q."<br /><br />ERRORE:<br /> ".mysql_error()."<br />");
		
					//$select_value=array(""=>"Seleziona $heading");
					$select_value=array(""=>"&raquo; {$this->lang['all']}");
					
					while ($row=mysql_fetch_array($result))
					if ($row[$data['field']]) $select_value[$row[$data['field']]]=$row[$data['field']];
					
					$select_items=count($select_value);
					if ($select_items<8)
					$select_size=$select_items;
					else
					$select_size=8;
								
									
					$HF->addInput("select","{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$select_value,$heading,$select_size,$data['value'],false,$this->classForFormInput['inputs']);				
					unset($select_value);
					//$this->searchField[$key]['ricerca_libera']=false;
				}
				else // @------ dato semplice - textbox
				{ 
					if ($data['table']!="Having") //no suggerimenti ai campi che non sono parte di nessuna tabella della query
						$JS.= "
						   new AutoSuggestControl('{$this->originalPrimaryTable}',document.getElementById(\"{$data['table_alias']}_{$data['field']}_src_{$this->originalPrimaryTable}\"),'{$data['field']}');";
				
					$HF->addInput("text","{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$data['value'],$heading,false,null,false,$this->classForFormInput['inputs']);						
				}
			}
			
								$form_string = $HF->buildForm($this->lang['find'],$this->classForFormInput['buttons']);	
			if ($this->useAjax)	$form_string = str_replace("validateFunction_src_{$this->originalPrimaryTable}()","DBN_{$this->originalPrimaryTable}.search_()",$form_string);	
					   $print.= $form_string;	
			
			
			$print.= "</fieldset></div>";	
			
		}		//END FORM DI RICERCA///////////////////////////////////////////////////
	
		
		$this->search_form_printed=true;
		
		if ($this->ajaxCall)  $JS="<script type=\"text/javascript\"><!-- {$JS} --></script>";
		else {$this->JS_onLoad=$JS; $JS="";}		 
		
		return $print.$JS;
	}		
	
	function get_queryWithSearchConditions()
	{		
			//print_r($this->searchField);
	
			foreach($this->searchField as $data)
			{
				if ($data['value']=="") continue;
				if (isset($data['value']['start']) && $data['value']['start']=="" && isset($data['value']['end']) && $data['value']['end']=="") continue;
				
				if (is_array($data['value']))
				foreach ($data['value'] as $key=>$val) $data['value'][$key]=addslashes($val);
				else $data['value']=addslashes($data['value']);
				
				
				$current_condition=array();			
				
				
				$param=array();
				
				if (!is_array($data['field']))//trsformo in array anche i parameteri dei campi di ricerca 'singoli'
				{
					$data['field']=array($data['field']);
					$data['table']=array($data['table']);
					$data['table_alias']=array($data['table_alias']);												
				}
				
				
				$i=0;
				foreach ($data['field'] as $field)
				{
					if ($data['table'][$i]=="Having")
					$param[$i]['fullField']=$data['field'][$i];
					else
					$param[$i]['fullField']=$data['table_alias'][$i].".".$data['field'][$i];
				
					$param[$i]['field']=$data['field'][$i];
					$param[$i]['table']=$data['table'][$i];
					$param[$i]['table_alias']=$data['table_alias'][$i];					
					$i++;
				}

	/*			echo "<pre>";
				print_r($param);
				echo "</pre><br />-------<br />";*/
				
	
				foreach ($param as $par)
				{
				
					$first_condition_for_search_field=true;
					
/*					
					I CAMPI su funzioni aggregate seguono lo stesso trattamento degli altri
					
					if ($par['table']!="Having")
					{
					
					*/
					
						switch ($data['tipo'])
						{
							case "1": //tante parole 'vincolate'
										$or=array();
								
										foreach($data['value'] as $multiple=>$val)
										{
											if ($val=="") continue;

/*											$val_escape=str_replace(array("%","_"),array("\%","\_"),$val);
											
											$or[]=" (
														{$par['fullField']} LIKE \"{$val_escape},%\" 
														OR 
														{$par['fullField']} LIKE \"%,{$val_escape},%\"
														OR 
														{$par['fullField']} LIKE \"%,{$val_escape}\"
														OR
														{$par['fullField']} = \"{$val}\"
	
													) "; 
*/

											$val=ereg_replace('(\?|\.|\[|\]|\(|\)|\||\{|\}|\$|\^|\*)','\\\\\\0',$val);

											$val=str_replace("\\\\","\\\\\\\\",$val); //magic_quote aggiunge gli slash quindi da 1 sono 2bs che devono diventare 4bs
											
											//$val=str_replace(array('?','\\','.','[',']','(',')','|','{','}','$','^','*'),
											//		 		   array('\\\\?','\\\\\\','\\\\.','\\\\[','\\\\]','\\\\(','\\\\)','\\\\|','\\\\{','\\\\}','\\\\$','\\\\^','\\\\*'),$val);
											//echo $val;	
											
											$or[]=" {$par['fullField']} REGEXP \"^(.*,)?{$val}(,.*)?$\" ";
													
											//le condizioni sono per ricerche su SET (il campo ha tanti valori, separati da virgola)
											//solo l'ultima condizione è anche per ENUM e tab esterne (oltre che a soliti campi SET con un valore singolo)
										}
								
							
										if (is_array($or) && count($or)>0) $current_condition[]=implode(" OR ",$or);
										break;
										
							case "2": //frase (viene distinto dal caso 3 xkè + racchiusa tra virgolette doppie (ricordarsi deli slash) )
										
										$value=substr($data['value'],2,strlen($data['value'])-4);//
							
										$current_condition[]="{$par['fullField']} =\"".$value."\"";
										break;
																		
							case "3": // tante parole 'libere' 
								
										$founded=false;
										
										$word=preg_split("/[^\\w'\"]/",stripslashes($data['value']),-1,PREG_SPLIT_NO_EMPTY);
										//print_r($word);
										foreach ($word as $w) if (strlen($w)>3) {$atLeastOnForFullText=true;break;}									
										//if (strlen($data['value'])>3)
										if (isset($atLeastOnForFullText) && $par['table']!='Having')  
										{
											$result=mysql_query("DESCRIBE {$this->originalPrimaryTable}");
											while ($row=mysql_fetch_array($result))
											{
												if ($row['Field']==$par['field'] && $row['Key']=='MUL') //cerca l'indice FULLTEXT
												{
													
													
													
												
													$current_condition[]="MATCH({$par['fullField']}) AGAINST (\"{$data['value']}\")";
													//ordina in base alla rilevanza dei risultati
													
													if (isset($this->orderInfo['currentOrd']))
													$this->orderInfo['currentOrd'].=", MATCH({$par['fullField']}) AGAINST (\"{$data['value']}\") DESC";
													else
													$this->orderInfo['currentOrd']=" MATCH({$par['fullField']}) AGAINST (\"{$data['value']}\") DESC";
													
													$this->orderInfo['currentDesc']="";
													$founded=true;
													break;
												}
											}
										}
										
										if (!$founded)//campo non fulltext
										{
											$or=array();
											$i=0;
											
											$data['value']=str_replace(array("%","_"),array("\%","\_"),$data['value']);
											
											if (strpos($data['value']," ")==0) //una parola
											{
												if (strlen($data['value'])<3) //parole di 1 o 2 caretteri singole
												{
													$or[]=" {$par['fullField']} LIKE \"{$data['value']}%\" "; //solo record che iniziano con..parola%
													$cicli=0;
												}
												else
												$cicli=1; // like %parola% - cerca internamente al campo 
											}
											else 
											$cicli=2; // LIKE %par1%par2%par3% OR LIKE %par1%par2% OR LIKE %par1% OR LIKE %par2%par3% OR LIKE %par3%
											
											for($j=0;$j<$cicli;$j++)//scansione avanti e indietro
											{
												$data_value=explode(" ",$data['value']);
												
												while(count($data_value)>0)//cicla finche l'array è pieno
												{											
													$or[$i]=" {$par['fullField']} LIKE \"";
													foreach($data_value as $key=>$val)
													{
														$or[$i].="%{$val}";
													}
													$or[$i].="%\" ";
													$i++;
													
													//eliminazione elemento dall'array
													if ($j==0)//indietro
													array_pop ($data_value);
													else      //in avanti
													array_shift($data_value);
													
												}
		
											}
											if (is_array($or) && count($or)>0) $current_condition[]=implode(" OR ",$or);
											 
										}
										
										break;	
							case "4": //intervalli numerici
										
										$exp=array();
										if (isset($data['value']['start']) && $data['value']['start']!="") $exp[]="{$par['fullField']}>=\"{$data['value']['start']}\"";
										if (isset($data['value']['end'])   && $data['value']['end']!="")   $exp[]="{$par['fullField']}<=\"{$data['value']['end']}\"";
										
										
										$current_condition[]=implode(" AND ",$exp);
										break;									
						}		
							
/*					}
					else
					{
						if (!isset($having_condition))
						$having_condition=" {$par['field']} LIKE \"%{$data['value']}%\" ";			
						else
						$having_condition.=" AND {$par['field']} LIKE \"%{$data['value']}%\" ";			
					}*/
					
				}//end foreach 2
					
						
				if (count($current_condition)>0)
				{
					$textual_current_condition=" (".implode(" OR ",$current_condition).") ";
					
					if ($par['table']=='Having')
					$having_condition=isset($having_condition)?$having_condition." AND ".$textual_current_condition:$textual_current_condition;	
					else
					$where_condition=isset($where_condition)?$where_condition." AND ".$textual_current_condition:$textual_current_condition;	
				}
				//echo $where_condition;	
	
			}// end foreach 1
				
			
				
			$query=$this->query;
			
			if (isset($where_condition)) 	
			$query=$this->addWhereConditionToQuery($query,$where_condition);
			
			if (isset($having_condition)) 
			$query=$this->addHavingConditionToQuery($query,$having_condition);
			
			//echo $query;
			
			return $query;
	}		
	
	function get_rowsNum()
	{
		$this->scanTable();
		$this->set_rowsNum();
		return $this->rowsNum;
	}
	
	function getFullQuery()
	{
		$this->scanTable();
		$this->set_rowsNum();
		return $this->query;
	}
	
	function set_rowsNum()
	{
		if (!$this->rowsNum)
		{
			$this->query=$this->get_queryWithSearchConditions();
			
			///*******************AGGIUNTA CONDIZIONI ALLA QUERY E ORDINAMENTO*************************
			if (!isset($_GET['ord_'.$this->originalPrimaryTable]) && !isset($this->orderInfo['currentOrd']))
			{
				$ordinamento=explode(",",$this->orderInfo['defaultOrd']);
				if (count($ordinamento)>1) //se si ordina per più colonne ordina brutalmente
				{
					$this->orderInfo['currentOrd']=$this->orderInfo['defaultOrd'];
					$this->orderInfo['currentDesc']="";
				}else
				{			
					$exp=explode(" ",$this->orderInfo['defaultOrd']);
	
					$this->orderInfo['currentOrd']=$exp[0];					
					$this->orderInfo['currentDesc']=isset($exp[1])?strtoupper($exp[1]):""; //da ricontrollare per spazi ecc.....
				}			
			}
			else if (isset($_GET['ord_'.$this->originalPrimaryTable]))//l'ordinamento dei GET prevale sull'ordinamento della ricerca(impostato da get_queryWithSearchConditions)
			{
				
				$this->orderInfo['currentOrd']=isset($_GET['ord_'.$this->originalPrimaryTable])?$_GET['ord_'.$this->originalPrimaryTable]:"";
				$this->orderInfo['currentDesc']=isset($_GET['desc_'.$this->originalPrimaryTable])?$_GET['desc_'.$this->originalPrimaryTable]:"";
				
			}
			else if(isset($this->orderInfo['currentOrd']))
			{
	
				$this->orderInfo['currentOrd']=substr($this->orderInfo['currentOrd'],1);
			}
	
		
		
			$this->query.=" ORDER BY {$this->orderInfo['currentOrd']} {$this->orderInfo['currentDesc']} , {$this->primaryTable}.{$this->originalPrimaryKey}";//ordina anche per id nel caso ci siano match di rilevanza uguali
	
			
			//echo $this->query;
	
			//DA MODIFICARE PER LE PRESTAZIONI !!!!!!!!DANGER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			if (strstr($this->query,"HAVING")===false)
			{
				$from=substr($this->query,strpos($this->query,"FROM"));
				
				$gbpos=strpos($from,"GROUP BY");
				$obpos=strpos($from,"ORDER BY");
				
	
				
				$count_query="SELECT COUNT(DISTINCT {$this->primaryTable}.{$this->originalPrimaryKey}) AS cnt ";
	
				if ($gbpos===false && $obpos===false && $lmpos===false)
				$count_query.=$from;
				else if	(is_int($gbpos))	
				$count_query.=substr($from,0,$gbpos);
				else if	(is_int($obpos))	
				$count_query.=substr($from,0,$obpos);
				else if	(is_int($lmpos))	
				$count_query.=substr($from,0,$lmpos);
				
				$row=mysql_fetch_array(mysql_query($count_query)) or die("ERRORE QUERY CONTEGGIO RISULTATI: ".$count_query."<br /><br />".mysql_error());
				
				//echo $count_query;
				
				$rowsNum=$row['cnt'];		
				//echo $count_query."<br>";
				//echo $this->query;
				$this->rowsNum=$rowsNum;
	
			}
			else 
			$this->rowsNum=mysql_num_rows(mysql_query($this->query));
	
			////////////////////////////////////		
			
		}
	}
	
	
	function getEditLink($id)
	{
	
		if ($this->useAjax)
		$href="javascript:DBN_{$this->originalPrimaryTable}.buildForm({$id},'')";
		else
		$href="{$_SERVER['PHP_SELF']}?edit_{$this->originalPrimaryTable}={$id}".buildQueryString("del_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable)."#{$this->originalPrimaryTable}_anchor";
	
	
		if ($this->canEdit===true || (is_array($this->canEdit) && in_array($id,$this->canEdit)))  
		return "<a href=\"{$href}\"><img src=\"".$this->imagesAndScriptsPath."edit.png\" alt=\"Modifica dati {$this->rowName} {$id}\" title=\"Modifica dati {$this->rowName}\" style=\"border:0px\" /></a>";
		else return "";
	
	}
	
	function getDeleteLink($id)
	{
	
		if ($this->useAjax)
		$href="javascript:DBN_{$this->originalPrimaryTable}.delete_({$id})";
		else
		$href="{$_SERVER['PHP_SELF']}?del_{$this->originalPrimaryTable}={$id}".buildQueryString("del_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable)."#{$this->originalPrimaryTable}_anchor";
	
	
		if ($this->canDelete===true || (is_array($this->canDelete) && in_array($id,$this->canDelete)))  
		return "<a onclick=\"return confirm('{$this->lang['reallyDelete']}')\" onkeypress=\"if (this.event.keyCode!=13) return false; else return confirm('{$this->lang['reallyDelete']}')\"
				href=\"{$href}\"><img src=\"".$this->imagesAndScriptsPath."delete.png\" alt=\"Elimina {$this->rowName} {$id}\" title=\"Elimina {$this->rowName}\" style=\"border:0px\" /></a>";
		else return "";					
	
	}
	
	function isConditionSatisfied($condition,$row)
	{
		if ($condition=="") return true;
		
		//condizione semplicissima su un campo se è 0 o no //vecchio modo
		if (strpos($condition,"{{{")===false)
		{
			if ($row[$condition]<=0) return false; else return true;   
		}
		
		//condizione su una stringa da valutare tramite eval e contenente + condizioni....nome campo indicato con {{{nome_campo}}}
		if (is_int(strpos($condition,"{{{")))
		{
			preg_match_all( "/{{{([^}]+)}}}/", $condition, $field , PREG_PATTERN_ORDER );
	
			foreach($field[1] as $f)
			$condition=str_replace("{{{".$f."}}}",'$row[\''.$f.'\']',$condition);
			
			
			eval('$condition_passed=(boolean)('.$condition.');');
			if ($condition_passed) return true;	else return false;
		
		}
		
	}
	
	
	function getLinkColLink($col,$row,$text)
	{
		if ($this->isConditionSatisfied($col['condition'],$row))
		{	
			if ($col['keepGet']!='') $qs=buildQueryString($col['arg']); else $qs="";
			
			$col['page']=strpos($col['page'],"?")===false?$col['page']."?":$col['page'];
			
			if ($col['newWindow'])
			$script="onkeypress=\"if (this.event.keyCode==13) window.open(this.href); return false;\" onclick=\"window.open(this.href); return false;\"";
			else
			$script="";
			
			return "<a {$this->classTag['fieldLink']} {$script} href=\"{$col['page']}&amp;{$col['arg']}={$row[$this->primaryKey]}$qs#{$this->originalPrimaryTable}_anchor\" >".$text."</a>";
			//.<span style=\"color:{$this->tableBGColor};font-size:1px\" class=\"dot2_{$this->originalPrimaryTable}\">.</span>";
		}
		else return false;
	}	
	
	
	function printTable($replace_array=null,$PageNavigator_on_top=false,$viewing_data_function="")
	{		
			
		$print="";

		if ($this->search_form_printed==false && count($this->searchField)>0) $print.="<div style=\"width:40%\">".$this->search_form()."</div>";


		$rowsNum=$this->get_rowsNum();	
		
		
		if (!$this->viewResults)
		{
			if (isset($_GET["src_{$this->originalPrimaryTable}_submit"])) $this->viewResults=true; //controllo che ci sia il get del tasto del form di ricerca
			else
			foreach ($this->searchField as $v) //controllo che ci sia un GET di ricerca
			if (is_array($v['field']))
			{
				$idx="";
				foreach ($v['field'] as $v2)
				$idx.=$v2."_";
				if (isset($_GET["{$idx}src_{$this->originalPrimaryTable}"])) 
				{
					
					$this->viewResults=true;
					break;
				}
			}else if (isset($_GET["{$v['table_alias']}_{$v['field']}_src_{$this->originalPrimaryTable}"]))
			{
				
				$this->viewResults=true;
				break;		
			}
		}
		
		if (!$this->viewResults) 
		{
			$print=$this->brutalTextReplace($replace_array,$print);
			echo $print;		
			return false;
		}
		
		
		//print( $this->query); //DEBUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
				
		//echo $rowsNum;
	
		if ($rowsNum!=0)
		{

			$navigation='';
			if (!$this->showAll)
			{ 
				$PN=new pageNavigator($rowsNum,$this->originalPrimaryTable,$this->classForFormInput['inputs'],$this->resultsPerPage,$this->originalPrimaryTable);
				$this->query.=$PN->getLimit();
				
				$PN->setlanguage($this->lang['languageName']);
				
							
				$nav1=$PN->show_page_browsing(false);
				$nav2=$PN->show_page_browsing(true);
				$rpp=$PN->show_RPP_browsing();
				
				if ($nav1 || $nav2 || $rpp)
				{
					$navigation.= "<br />";
					$navigation.= "<div style=\"text-align:center\" id=\"{$this->originalPrimaryTable}_navigation_bottom\">";
					$navigation.= $nav1 ? $nav1."<br />" : "";
					$navigation.= $nav2 ? $nav2."<br />" : "";
					$navigation.= $rpp;			
					$navigation.= "</div>";
				}
			}
			
			if ($PageNavigator_on_top) $print.=$navigation; //NAVIGAZIONE IN UNA VARIABILE	
	

			//print( $this->query); //DEBUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
			
			$result=mysql_query($this->query) or die ($this->query." : <br /><br />".mysql_error());
											   			
	
			if ($viewing_data_function=="")
			{

				$multipleContext = $this->canMultipleEditDelete==true  && 
								   (  
									 ($this->canEdit===true || is_array($this->canEdit)) 
									 || 
									 ($this->canDelete===true || is_array($this->canDelete))
								   );
				
				//**************************************INTESTAZIONE TABELLA*********************
				
				if ($multipleContext)
				{
					$print.="<form method=\"get\" action=\"{$_SERVER['PHP_SELF']}\" id=\"frm_select_{$this->originalPrimaryTable}\">";
					foreach($_GET as $name=>$value) //parametri vari
					{
						if (strstr($name,"selected_".$this->originalPrimaryTable) || strstr($name,"action_".$this->originalPrimaryTable) || strstr($name,"sellen_".$this->originalPrimaryTable))
						continue; 
						 
						if (is_array($value))
						foreach($value as $val)
						$print.= "<input type=\"hidden\" name=\"{$name}[]\" value=\"".stripslashes($val)."\" />";
						else
						$print.= "<input type=\"hidden\" name=\"$name\" value=\"".stripslashes($value)."\" />";
					}
				}
				$print.= "<table border=\"0\"  cellpadding=\"3\" cellspacing=\"$this->tableCS\" style=\"width:100%;\" summary=\"Tabella riepilogativa di ogni {$this->rowName}\">";				
				$print.= "<tr style=\"background-color:{$this->tableHeaderBGColor}\">";
				
				if ($multipleContext) $print.= "<td{$this->classTag['headerTD']}>...</td>";
	
				$i=0;
	
				foreach ($this->field as $current_field)
				{
					
					if ($this->hidePrimaryKey==true && $current_field->def==$this->primaryKey && $current_field->table==$this->originalPrimaryTable) continue; //nasconde la chiave primaria
					
					if ($current_field->type=='password') continue; //non mostra le password
														
					if (isset($this->removeDisplaying[$current_field->name])) continue; //Salto per i dati Indicati manualmente
					
					
					
					$print.= "<td{$this->classTag['headerTD']}>";
					
					///////////////
					$show="<strong>".ucfirst(str_replace("_"," ",$current_field->def))."</strong>";
					//////////////
					
				
					
					if ($this->useAjax)
					{
						$href_1="javascript:DBN_{$this->originalPrimaryTable}.set_order('{$current_field->def}',true)";
						$href_2="javascript:DBN_{$this->originalPrimaryTable}.set_order('{$current_field->def}',false)";
					}
					else
					{
						$href_1="{$_SERVER['PHP_SELF']}?ord_{$this->originalPrimaryTable}={$current_field->def}&amp;desc_{$this->originalPrimaryTable}".buildQueryString("ord_".$this->originalPrimaryTable,"desc_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable,"del_".$this->originalPrimaryTable)."#{$this->originalPrimaryTable}_anchor";
						$href_2="{$_SERVER['PHP_SELF']}?ord_{$this->originalPrimaryTable}={$current_field->def}&amp;desc_{$this->originalPrimaryTable}=DESC".buildQueryString("ord_".$this->originalPrimaryTable,"desc_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable,"del_".$this->originalPrimaryTable)."#{$this->originalPrimaryTable}_anchor";

					}

					$print.= $show."<br />"; ////
					
					if ($current_field->def==$this->orderInfo['currentOrd']) 
					{			

						$print.= ($this->orderInfo['currentDesc']=="DESC"?"<a href=\"{$href_1}\">":"")."<img style=\"vertical-align:bottom;border:none;".($this->orderInfo['currentDesc']=="DESC"?"":"border:2px solid #333;margin-top:3px;padding:3px")."\" src=\"{$this->imagesAndScriptsPath}asc.png\"  alt=\"{$this->lang['ascendingOrder']}\" title=\"{$this->lang['ascendingOrder']}\" />".($this->orderInfo['currentDesc']=="DESC"?"</a>":"");		//immagini ordinamento			
						$print.= ($this->orderInfo['currentDesc']=="DESC"?"":"<a href=\"{$href_2}\">")."<img style=\"vertical-align:bottom;border:none;".($this->orderInfo['currentDesc']=="DESC"?"border:2px solid #333;margin-top:3px;padding:3px":"")."\" src=\"{$this->imagesAndScriptsPath}desc.png\" alt=\"{$this->lang['descendantOrder']}\" title=\"{$this->lang['descendantOrder']}\" />".($this->orderInfo['currentDesc']=="DESC"?"":"</a>");		//immagini ordinamento			
					}
					else
					{
						$print.= "<a href=\"{$href_1}\" ><img style=\"vertical-align:bottom;border:none\" src=\"{$this->imagesAndScriptsPath}asc.png\"  alt=\"{$this->lang['ascendingOrder']}\" title=\"{$this->lang['ascendingOrder']}\" /></a>";		//immagini ordinamento			
						$print.= "<a href=\"{$href_2}\" ><img style=\"vertical-align:bottom;border:none\" src=\"{$this->imagesAndScriptsPath}desc.png\"  alt=\"{$this->lang['descendantOrder']}\" title=\"{$this->lang['descendantOrder']}\" /></a>";		//immagini ordinamento			
					}
										
					$print.="<span style=\"color:{$this->tableHeaderBGColor};font-size:1px\" class=\"dot_{$this->originalPrimaryTable}\">.</span>";
					
					//////////////////////////////////////
									
					$print.= "</td>";
					
				}
				
				foreach ($this->dataCol as $col) $print.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>"; //stampa colonne aggiuntive
				if ($this->canViewForPrint) $print.= "<td{$this->classTag['headerTD']}>{$this->lang['print']}</td>";
				if ($this->canEdit===true || is_array($this->canEdit)) $print.= "<td{$this->classTag['headerTD']}>{$this->lang['edit']}</td>";
				if ($this->canDelete===true || is_array($this->canDelete)) $print.= "<td{$this->classTag['headerTD']}>{$this->lang['delete']}</td>";
				foreach ($this->linkCol as $col) $print.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>"; //stampa colonne aggiuntive
				foreach ($this->freeCol as $col) $print.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>"; //stampa colonne aggiuntive
	
				$print.= "</tr>
				";
				
				
					//**************************************TABELLA*********************				   					
	
				while ($row=mysql_fetch_array($result))
				{					
					
					$print.= "<tr style=\"background-color:{$this->tableBGColor}\">"; 
					
					//SETTAGGIO EVIDENZIAZIONE RIGHE 
					$openTD="<td{$this->classTag['TD']}>";
					$openEditDeleteTD="<td{$this->classTag['editDeleteTD']}>";					
					foreach ($this->highlighting as $hl)
					if ($this->isConditionSatisfied($hl['condition'],$row))
					{
						$openTD=$openEditDeleteTD="<td {$hl['TDAttributes']}>";
						break;
					}
					
					if ($multipleContext)
					{
					
						$print.= $openEditDeleteTD."
									<label for=\"selected_{$this->primaryTable}_{$row[$this->primaryKey]}\"></label>	
									<input id=\"selected_{$this->primaryTable}_{$row[$this->primaryKey]}\" type=\"checkbox\" name=\"selected_{$this->primaryTable}[]\" value=\"{$row[$this->primaryKey]}\" />
								  </td>";
						
					}	
					
	
					foreach ($this->field as $current_field) //per ogni colonna
					{
						if ($this->hidePrimaryKey==true && $current_field->def==$this->primaryKey && $current_field->table==$this->originalPrimaryTable) continue; //nasconde la chiave primaria	
						
						if ($current_field->type=='password') continue; //non mostra le password
						
						if (isset($this->removeDisplaying[$current_field->name])) continue; //Salto per i dati Indicati manualmente

						
						$print.=$openTD;
						

						$fieldText='';
												
						$TYPE=explode("(",$current_field->type);//serve per identificare gli ENUM
						switch($TYPE[0])
						{	
							case "date":
									$exp=explode("-",$row[$current_field->def]);
									$fieldText= "{$exp[2]}/{$exp[1]}/{$exp[0]}";
									break;
							case "datetime":
									$exp=explode(" ",$row[$current_field->def]);
									$exp2=explode("-",$exp[0]);
	
									$fieldText= "{$exp2[2]}/{$exp2[1]}/{$exp2[0]} {$exp[1]}";
									break;								
/*							case"real":
							case"int":
							case"enum":
							case"blob":	
							case"string":*/
							default: //tanto è uguale!
									 if (isset($this->photoField[$current_field->name]) && $current_field->table==$this->originalPrimaryTable)
									 {
										if ($row[$current_field->name]!="")
										{
											if ($this->photoField['_Resize_']) $small="small_"; else $small="";
											if (file_exists($this->filePath."/$small".$row[$current_field->name]))
											$fieldText= "<img src=\"".$this->filePath."/$small".$row[$current_field->name]."\" alt=\"\" />";
											else $fieldText=$row[$current_field->name].": immagine non trovata";
										} 
										else $fieldText="<em>{$this->lang['noImage']}</em>";
									 }
									 else if (isset($this->fileField[$current_field->name]) && $current_field->table==$this->originalPrimaryTable )
									 {
									 	if ($row[$current_field->name]!="")
										{
											$fieldText="<a href=\"{$this->filePath}/{$row[$current_field->name]}\" onclick=\"\">{$row[$current_field->name]}</a>";
									 	}
										else $fieldText="<em>{$this->lang['noFile']}</em>";
										
									 }else 	
									 {
									 	$fieldText=$row[$current_field->def];
										
										if (is_numeric($this->cutLength)) //taglia il testo troppo lungo eliminando i tag
										{									 										
											$fieldText=str_replace("<br />","_!_",$fieldText); 
											$fieldText=elimina_ogni_tag($fieldText);
											$fieldText=str_replace("_!_","<br />",$fieldText); 
													
			
											 
											if (strlen($fieldText)>$this->cutLength) //evitare di tagliare a meta i tags
											{
												///EVITA DI TAGLIARE UN TAG (br) A META' /////
												$cut_end=$this->cutLength;
												for($i=$this->cutLength;$i<strlen($fieldText);$i++) //cerca > dal punto in cui si taglia alla fine
												{
													if ($fieldText{$i}==">") 					   //se lo trova
													{
														for($j=$this->cutLength;$j>0;$j--) 		   //cerca < dal punto in cui si taglia fino all'inizio 
														{
															if ($fieldText{$j}=="<") 			   //se lo trova(si xkè c'è solo BR)taglia fino a lì
															{
																$cut_end=$j;
																break;
															}													
														}
														break;
													}
												}
												/////////////////////////////////////////////
												$fieldText=substr($fieldText,0,$cut_end)."<br /><strong>...[continua]</strong>";
											}
										}
										
									 }
									 break;	 
	
						}
						
						$linkTag=false;
						
						foreach ($this->linkCol as $col)  //mette il link aggiuntivo ai campi indicati
						if (is_array($col['fieldToLink']))
						foreach ($col['fieldToLink'] as $colonna)
						{
							if ($current_field->def!=$colonna) continue;
			
							$linkTag=$this->getLinkColLink($col,$row,$fieldText);
							
							break;					
						}
						
						$print .= $linkTag ? $linkTag : $fieldText;
						
						
						
						
						$print.="</td>";
					}
					
					foreach ($this->dataCol as $col)
					{
						unset($data);
						
						switch ($col['type'])
						{
							case "RECURSIVE":	   
												    $data=$this->query_ricorsiva($row[$this->primaryKey],$col['query']); 
													break;
							case "LINKED_RECORDS": 
													$linked_result=mysql_query(str_replace("%current_row_id%",$row[$this->primaryKey],$col['query']));
													
													$data='';													
													while($linked_row=mysql_fetch_array($linked_result))
													{
														$data.="&bull; ".$linked_row[0]."<br />";//un campo solo..
													}
													break;	
							case "CALCULATION":		
													$data=0;
													foreach ($col['query'] as $q)
													{
														if (!mysql_query(str_replace("%current_row_id%",$row[$this->primaryKey],$q['query']))) echo (mysql_error());
														$tot=mysql_fetch_array(mysql_query(str_replace("%current_row_id%",$row[$this->primaryKey],$q['query'])));																									
														eval('$data=$data '.$q['operand'].'$tot[0];');	//il primo campo 
													}											
													
													break;
						}
						
						$print.=$openTD."{$data}</td>";
					}			
					
					$query_string=buildQueryString("edit_".$this->originalPrimaryTable,"del_".$this->originalPrimaryTable);			
					
					if ($this->canViewForPrint)
					{
					
						$print.= $openEditDeleteTD."<a href=\"{$_SERVER['PHP_SELF']}?view_{$this->originalPrimaryTable}={$row[$this->primaryKey]}$query_string#{$this->originalPrimaryTable}_anchor\"
						onclick=\"window.open(this.href);return false;\" onkeypress=\"if (this.event.keyCode==13) {window.open(this.href);return false;} else return false;\" >
					<img src=\"".$this->imagesAndScriptsPath."print.gif\" alt=\"Visualizza dati {$this->rowName} {$row[$this->primaryKey]}\" title=\"Visualizza dati {$this->rowName}\" style=\"border:0px\" /></a>
					<span style=\"color:{$this->tableBGColor};font-size:1px\" class=\"dot2_{$this->originalPrimaryTable}\">.</span></td>";
						
					}

					if ($this->canEdit===true || is_array($this->canEdit))
					{
						$print.= $openEditDeleteTD;
						
						$editLink=$this->getEditLink($row[$this->primaryKey]);
						if ($editLink!="") $print.=$editLink."<span style=\"color:{$this->tableBGColor};font-size:1px\" class=\"dot2_{$this->originalPrimaryTable}\">.</span>";
						
					    $print.= "</td>";
					}
					
					
					if ($this->canDelete===true || is_array($this->canDelete))
					{
						$print.= $openEditDeleteTD;

						$deleteLink=$this->getDeleteLink($row[$this->primaryKey]);
						if ($deleteLink!="") $print.=$deleteLink."<span style=\"color:{$this->tableBGColor};font-size:1px\" class=\"dot2_{$this->originalPrimaryTable}\">.</span>";

					    $print.= "</td>";
					}
					
					foreach ($this->linkCol as $col)
					{
						$print.= $openEditDeleteTD;
						
						$text=file_exists($col['image'])?"<img style=\"vertical-align:top;border:none;\" src=\"{$col['image']}\" alt=\"{$col['colName']}  {$this->rowName} {$row[$this->primaryKey]}\" title=\"{$col['colName']}\" />":"{$col['colName']}  {$this->rowName}";
						
						$print.=$this->getLinkColLink($col,$row,$text);	
		
						$print.= "</td>";
					
					}	
					foreach ($this->freeCol as $col)
					{
						$print.= $openEditDeleteTD.str_replace("%current_row_id%",$row[$this->primaryKey],$col['content'])."</td>";					
					}						
										
					$print.= "</tr>";
					//$print.="<tr><td colspan=\"3\"><div style=\"visibility:visible\" id=\"form_div_{$row[$this->primaryKey]}\">".$this->buildForm($row[$this->primaryKey])."</div></td></tr>";
	
	
				} //end while
	
				$print.= "</table>";
				
				if ($multipleContext)
				{
					$print.= "
					
					
					<script type=\"text/javascript\">
					<!--
						setCheckBoxes_{$this->originalPrimaryTable}=function(val)
						{
							cb=document.forms['frm_select_{$this->originalPrimaryTable}'].elements['selected_{$this->originalPrimaryTable}[]'];
							if (typeof(cb.length)=='undefined')//solo una checkbox presente..non è un array
							cb.checked=val;
							else
							for (var i=0;i<cb.length;i++)
							cb[i].checked=val;
						}
						
						setSellen_{$this->originalPrimaryTable}=function (action)
						{
							cb=document.forms['frm_select_{$this->originalPrimaryTable}'].elements['selected_{$this->originalPrimaryTable}[]'];
							len=0;
							if (typeof(cb.length)=='undefined') //solo una checkbox presente..non è un array
							{
								if (action=='edit')
								{
									cb.checked=false;
									document.getElementById('edit_{$this->originalPrimaryTable}').value=cb.value;
								}
								len=1;
							}
							else
							{
								firstFounded=false;
								for (var i=0;i<cb.length;i++)
								{
									if (cb[i].checked==true)
									{
										len++;
										if (!firstFounded && action=='edit') //deseleziono la checkbox e imposto l'edit_ primarytable
										{
											cb[i].checked=false;
											document.getElementById('edit_{$this->originalPrimaryTable}').value=cb[i].value;
											firstFounded=true;
										}
									}
								}
							}
							document.getElementById('sellen_{$this->originalPrimaryTable}').value=len;						
						}

						getSelected_{$this->originalPrimaryTable}=function (action)
						{
							
							result=new Object();
							result.selected=Array();
							j=0;
							
							cb=document.forms['frm_select_{$this->originalPrimaryTable}'].elements['selected_{$this->originalPrimaryTable}[]'];
							len=0;
							//solo una checkbox presente..non è un array (se c'è un solo elemento nella tabella cb.value contiene l'unico id...però cb.checked è falso)
							if (typeof(cb.length)=='undefined' && typeof(cb.value)!='undefined' && cb.checked==true) 
							{
								result.selected[0]=cb.value;
							}
							else
							{
								firstFounded=false;
								for (var i=0;i<cb.length;i++)
								{
									if (cb[i].checked==true)
									{
										result.selected[j++]=cb[i].value;

									}
								}
							}

							result.action=action;
							return result;						
						}						
					-->
					</script>
					
					<img src=\"".$this->imagesAndScriptsPath."puntini_orizz.png\" alt=\"\" />{$this->lang['ifSelected']} 
					
					<input type=\"hidden\" id=\"edit_{$this->originalPrimaryTable}\" name=\"edit_{$this->originalPrimaryTable}\" />
					<input type=\"hidden\" id=\"sellen_{$this->originalPrimaryTable}\" name=\"sellen_{$this->originalPrimaryTable}\" value=\"\" />";
				

					if ($this->canEdit===true || is_array($this->canEdit))
					{
						if ($this->useAjax)
						{
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('edit'); if (data.selected.length>0) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('edit'); if (data.selected.length>0 && this.event.keyCode==13) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\"";

						}
						else
						{
							$qs="{$_SERVER['PHP_SELF']}?".buildQueryString("selected_".$this->originalPrimaryTable,"action_".$this->originalPrimaryTable,"sellen_".$this->originalPrimaryTable);
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('edit'); if (data.selected.length>0) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('edit'); if (data.selected.length>0 && this.event.keyCode==13) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\"";
						}


										
						$print.= "
						<label for=\"action_{$this->originalPrimaryTable}_1\"></label>
						<button type=\"button\" {$onclickKeyPress}>
							<img src=\"".$this->imagesAndScriptsPath."edit.png\" alt=\"{$this->lang['edit']}\" />
						</button> ";
						
						if ($this->useAjax)
						{
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('editMany'); if (data.selected.length>0) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('editMany'); if (data.selected.length>0 && this.event.keyCode==13) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\"";

						}
						else
						{
							$qs="{$_SERVER['PHP_SELF']}?".buildQueryString("selected_".$this->originalPrimaryTable,"action_".$this->originalPrimaryTable,"sellen_".$this->originalPrimaryTable);
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('editMany'); if (data.selected.length>0) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('editMany'); if (data.selected.length>0 && this.event.keyCode==13) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\"";
						}
						
						
						$print.= "
						<label for=\"action_{$this->originalPrimaryTable}_3\"></label>
						<button type=\"button\" {$onclickKeyPress}\">
							<img src=\"".$this->imagesAndScriptsPath."editMany.gif\" alt=\"\" />
						</button> ";
						
						
					}

					
					if ($this->canDelete===true || is_array($this->canDelete))
					{
					
						if ($this->useAjax)
						{
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('delete'); if (data.selected.length>0 && confirm('{$this->lang['reallyDeleteMultiple']}')) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('delete'); if (data.selected.length>0 && confirm('{$this->lang['reallyDeleteMultiple']}') && this.event.keyCode==13) DBN_{$this->originalPrimaryTable}.multipleOperation(data)\"";

						}
						else
						{
							$qs="{$_SERVER['PHP_SELF']}?".buildQueryString("selected_".$this->originalPrimaryTable,"action_".$this->originalPrimaryTable,"sellen_".$this->originalPrimaryTable);
							$onclickKeyPress="
							onclick=\"var data=getSelected_{$this->originalPrimaryTable}('delete'); if (data.selected.length>0 && confirm('{$this->lang['reallyDeleteMultiple']}')) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\" 
							onkeypress=\"var data=getSelected_{$this->originalPrimaryTable}('delete'); if (data.selected.length>0 && confirm('{$this->lang['reallyDeleteMultiple']}') && this.event.keyCode==13) location.href='{$qs}'+DBN_{$this->originalPrimaryTable}.getMultipleOperationParams(data)\"";
						}
						
						
						$print.= "
						<label for=\"action_{$this->originalPrimaryTable}_3\"></label>
						<button type=\"button\" {$onclickKeyPress}\">
							<img src=\"".$this->imagesAndScriptsPath."delete.png\" alt=\"\" />
						</button> ";
						
											
					/*
					if ($this->canDelete===true || is_array($this->canDelete))
					$print.= "					
					 <label for=\"action_{$this->originalPrimaryTable}_2\"></label>
					<button type=\"submit\" name=\"action_{$this->originalPrimaryTable}\" id=\"action_{$this->originalPrimaryTable}_2\" value=\"delete\" 
					onclick=\"setSellen_{$this->originalPrimaryTable}(this.value);return confirm('{$this->lang['reallyDeleteMultiple']}')\" onkeypress=\"if (this.event.keyCode==13) {setSellen_{$this->originalPrimaryTable}(this.value);return confirm('{$this->lang['reallyDeleteMultiple']}');} else return false;\">
						<img src=\"".$this->imagesAndScriptsPath."delete.png\" alt=\"{$this->lang['edit']}\" />
					</button> ";
					*/
					}
					
					$print.= "	
					<a href=\"javascript:setCheckBoxes_{$this->originalPrimaryTable}(true)\">{$this->lang['selectAll']}</a> | 
					<a href=\"javascript:setCheckBoxes_{$this->originalPrimaryTable}(false)\">{$this->lang['unselectAll']}</a>
					</form>	
					";
					
				}
	
/*				$print.= "
						<script type=\"text/Javascript\">
						  <!--
	 
							function getStyleProp(x,prop)
							{
								if(x.currentStyle)
									return(x.currentStyle[prop]);
								if(document.defaultView.getComputedStyle)
									return(document.defaultView.getComputedStyle(x,'')[prop]);
								return(null);
							}
	
							function getElementsByClass(classname) 
							{
								classes = new Array();
								alltags = document.getElementsByTagName('*');
								for (i=0; i<alltags.length; i++)
									if (alltags[i].className == classname) classes[classes.length] = alltags[i];
								
								return classes;
							}
						
					classes1=getElementsByClass('dot_{$this->originalPrimaryTable}');
					element1=getElementsByClass('{$this->style['headerTD']}');			
					
					if (element1[0])
					{
						bgcolor=getStyleProp(element1[0],'backgroundColor');
						for (i=0; i<classes1.length; i++)
						classes1[i].style.color=bgcolor;
					}
					
					classes2=getElementsByClass('dot2_{$this->originalPrimaryTable}');
					element2=getElementsByClass('{$this->style['editDeleteTD']}');		
									
					if (element2[0])
					{
						bgcolor2=getStyleProp(element2[0],'backgroundColor');
						for (i=0; i<classes2.length; i++)
						classes2[i].style.color=bgcolor2;
					}				
					  //-->
				</script>
					";*/
					
			}
			else
			{
			 	$print.=$viewing_data_function($result);
			}
			
			$print.=$navigation; //NAVIGAZIONE IN UNA VARIABILE			
			
		}
		else
		$print.= "<span style=\"font-size:13px;font-weight:bolder\"><em>- {$this->lang['noResults']}</em></span>";
		
		

		$print=$this->brutalTextReplace($replace_array,$print);
		
		echo $print;
	}
	
	function brutalTextReplace($replace_array,$text) 
	{
		if (!is_array($replace_array)) return $text;																	
		
		foreach($replace_array as $search=>$replace) 														
		{
			if ($search{0}=='/' && $search{strlen($search)-1}=='/')
				$text = preg_replace($search,$replace,$text); 						
			else
				$text =  str_replace($search,$replace,$text); 						
		}
		
		return $text;		
	}
	
	function manage_record_availability($id,$bookRecord)	
	{
		//session_start();
		//ob_end_clean();
		$row=mysql_fetch_array(mysql_query("SELECT * FROM busy_records WHERE table_name=\"{$this->originalPrimaryTable}\" AND record_id=\"{$id}\""));
		
		if ($row)
		{
			if ($row['user_session_id']==session_id()) //se il record è occupato dal client allora aggiorna l'expire_date
			{  
				mysql_query("UPDATE busy_records SET expire_time=\"".strtotime("+7 seconds")."\"  
				WHERE table_name=\"{$this->originalPrimaryTable}\" AND record_id=\"{$id}\" AND user_session_id=\"".session_id()."\"");		
				
				return true;
			}
			else 
			//die(print_r($row,true)); 
			return false;
		}
		else
		{
			if ($bookRecord)
			mysql_query("INSERT INTO busy_records(table_name,record_id,user_session_id,expire_time)
			VALUES (\"{$this->originalPrimaryTable}\",\"{$id}\",\"".session_id()."\",\"".strtotime("+7 seconds")."\")");
		
			return true;
		}
		
	}
		
	function buildForm($id=null,$replace_array=null,$show_back_link=true)
	{

		//print_r($this->field);
		//print_r($this->externalData);
		$print="";
		
		$fieldEnablingPanel="";


		$qs=buildQueryString("del_{$this->originalPrimaryTable}");//il del lo tolgo perchè si può accedere qui anche se si voleva eliminare un record usato
		$form_target=$_SERVER['PHP_SELF']."?$qs#{$this->originalPrimaryTable}_anchor";
	
		if ($show_back_link)
		{ 
			if ($this->useAjax) $back_href="javascript:DBN_{$this->originalPrimaryTable}.printTable()";
			else
			{
				$qs=buildQueryString("del_{$this->originalPrimaryTable}",'edit_'.$this->originalPrimaryTable,"action_{$this->originalPrimaryTable}","sellen_{$this->originalPrimaryTable}","selected_{$this->originalPrimaryTable}");
				$back_href=$_SERVER['PHP_SELF']."?$qs#{$this->originalPrimaryTable}_anchor";
			}
		}
		
		
		if (!is_array($id))
		{
		
			$row=mysql_fetch_array(mysql_query($this->addWhereConditionToQuery($this->query,"{$this->primaryTable}.{$this->originalPrimaryKey}='$id'")));
	
			//$print.= $this->addWhereConditionToQuery($this->query,"{$this->primaryTable}.{$this->primaryKey}='$id'");
			if ($row) //Modalità modifica
			{
				if ($this->manage_record_availability($id,true)==false)
				{
					return "<br /><div style=\"cursor:wait;font-weight:bolder;border:1px solid #FF0000;padding:3%\">
					{$this->lang['warningRecordOccupied']}
					<a href=\"".($show_back_link?$back_href:"javascript:history.back();")."\">&raquo; {$this->lang['goBack']}</a> 
					</div><br />
					
					<script type=\"text/javascript\">
					<!--
						DBN_{$this->originalPrimaryTable}.checkAvailability=setInterval(\"DBN_{$this->originalPrimaryTable}.manage_record_availability_for_editing($id,false)\",3000); // rifa il controllo dopo 7 secondi					
					-->
					</script>
					";
				}else
				{
				
					$print.="
					<script type=\"text/javascript\">
					<!--
						DBN_{$this->originalPrimaryTable}.checkAvailability=setInterval(\"DBN_{$this->originalPrimaryTable}.manage_record_availability_for_editing($id,true)\",3000); // rifa il controllo dopo 7 secondi																
					-->
					</script>
					";
				}

				
				$edit=1;			
		
				$formHeading=$this->lang['editRecord'];//." $id";
							
				
				if (is_array($this->photoField) || is_array($this->fileField)) //formattazione div contenitore per le immagini (e file)
				{
	
					foreach ($this->photoField as $field=>$bool)
					{ 
						if ($field=="_Resize_" || $field=="_KeepOriginal_") continue; ////da sistemare......? parametri delle immagini nello stesso array
						if ($row[$field]!="")
						{			
							if (!isset($div_flag)) //stampa il div una volta sola , solo se c'è qualcosa 
							{
								$print.= "<div style=\"position:relative;float:right;border:1px solid #000000;width:20%;padding:6px 0px 6px 6px;margin:10px 0px\">";
								$div_flag=true;
							}
							else $print.="<br /><br />";
								
							$print.="<strong>".$this->lang['current']." ".str_replace("_"," ",ucfirst($field))."</strong><br />";	
							if ($this->photoField['_Resize_'] && $this->photoField['_KeepOriginal_']) //con 2 immagini crea il link nella nuova finestra
							{
								
								$print.="<a href=\"{$this->filePath}/{$row[$field]}\" onclick=\"window.open(this.href);return false;\">";
								$print.="<img src=\"{$this->filePath}/small_{$row[$field]}\" style=\"".getImageResizedValues($this->filePath."/".$row[$field],130,130)
								.";border:none\" alt=\"{$row[$field]}\" /><br />".$row[$field]."</a><br /><br />";
														
							}else //con l'immagine piccola visualizza solo la miniatura a 130
							$print.="<img src=\"{$this->filePath}/small_{$row[$field]}\" style=\"".getImageResizedValues($this->filePath."/small_".$row[$field],130,130)
							."\" alt=\"small_{$row[$field]}\" /><br />".str_replace("_"," ",ucfirst($row[$field]));
							
							$this->photoField[$field]=true; ///
						}
					}
	
					foreach ($this->fileField as $field=>$bool)
					{ 
						if ($row[$field]!="")
						{
							if (!isset($div_flag))  //stampa il div una volta sola , solo se c'è qualcosa 
							{
								$print.= "<div style=\"position:relative;float:right;border:1px solid #000000;width:20%;padding:6px 0px 6px 6px;margin:10px 0px\">";
								$div_flag=true;
							}
							else $print.="<br /><br />";					
							
							$print.="<strong>".$this->lang['current']." ".str_replace("_"," ",ucfirst($field))."</strong>
							<a href=\"{$this->filePath}/{$row[$field]}\" onclick=\"window.open(this.href);return false;\"><strong>".
							str_replace("_"," ",ucfirst($row[$field]))."</strong></a><br /><br />";
							$this->fileField[$field]=true; ///
						}
					}
					if (isset($div_flag)) {
											$print.="</div>";
											$this->formWidth[1]-=25;
										  }
				}
			} else //INSERIMENTO
			{

				$edit=0; 
				
				$formHeading=$this->lang['insertNew'];
				
			}
		
		}
		else  //array di id
		{
			$edit=1; 
			
			$formHeading="<strong>".str_replace("***","<span style=\"color:#F00\">".count($id)."</span>",$this->lang['multipleEditingHeading'])."</strong>";
			
			$occupiedId=false;
			$jsArray=array();
			foreach($id as $ids)
			if ($this->manage_record_availability($ids,true)==false) 
			{
				$occupiedId=true;//un record occupato
			}
			
				
			//questa funzione mantiene la prenotazione dei record trovati disponibili, ed eventualmente chiama la funzione per ristampare il form
			//quando quello occupato diventa libero
			$print.="
			<script type=\"text/javascript\">
			<!--
				DBN_{$this->originalPrimaryTable}.checkAvailability=setInterval(\"DBN_{$this->originalPrimaryTable}.manage_record_availability_for_editing([".implode(',',$id)."],".($occupiedId?'false':'true').")\",3000); // rifa il controllo dopo 7 secondi																
			-->
			</script>
			";
			
			//se ce n'è uno occupato termina qui
			if ($occupiedId)
			return $print."<br /><div style=\"cursor:wait;font-weight:bolder;border:1px solid #FF0000;padding:3%\">
							{$this->lang['warningRecordOccupied']}
							<a href=\"".($show_back_link?$back_href:"javascript:history.back();")."\">&raquo; {$this->lang['goBack']}</a> 
							</div><br />";


		}
		///////////////Reinserimento valori nel form//////////////////
		///*************** S E M P R E !!!!!!!! ***************
		
		foreach ($_POST as $name=>$value) 
		{
			

			if (substr($name,strlen($name)-4,4)=="_ifr")
				$name=substr($name,0,strlen($name)-4);
			else
				$value=$this->convertSpecialChars($value);
			
			if (substr($name,strlen($name)-4,4)=="_day") {$data_generica=$value;continue;}
			if (substr($name,strlen($name)-4,4)=="_mon") {$data_generica=$value."-".$data_generica;continue;}
			if (substr($name,strlen($name)-4,4)=="_yea") {$value=$value."-".$data_generica; $name=substr($name,0,strlen($name)-4);}
					
				//campi della tabella principale
			foreach ($this->field as $current_field)
			{
				if ($current_field->name==$name)// || $current_field->def==$name)
				{
					//$row[$current_field->name]=stripslashes($value);
					if (is_array($value))
					$row[$current_field->def]=implode(",",$value);
					else
					$row[$current_field->def]=stripslashes($value);				
					continue 2;
				}
					
			}//end foreach
				
			//campi collegati
			foreach ($this->externalData as $ed)
			{
				$chiave=$ed["ex_primaryKey"];
				$chiave_esterna=$ed["externalKey"];
				$alias=$ed["ex_alias"];
					
				if ($chiave_esterna==$name)
				{
						$row[$chiave_esterna]=stripslashes($value); //???
						$row[$alias]=stripslashes($value);				
						continue 2;
				}
					
			}//end foreach				
				
		}//end foreach principale
		//print_r($_POST);
		//print_r($row);
		//print_r($this->externalData);
		/////////////////////////////////////////
		
///INTESTAZIONI FORM
			$print.="<div>";
			
			if ($this->formHeading=="")
			$print.= "<span style=\"font-size:18px;font-weight:bolder\">$formHeading</span>";
			else
			$print.= $this->formHeading;
			
			
			if ($show_back_link==true)
			$print.= "<h3><a href=\"$back_href\">".$this->lang['backToData']."</a></h3>";
			
			$print.="</div>";
//////////////
		
		$this->editForm->defineParams("frm_{$this->originalPrimaryTable}",$form_target,$this->formWidth[0],$this->formWidth[1],strip_tags($formHeading));		
			
			
		$this->editForm->addInput("hidden","edit_".$this->originalPrimaryTable,$edit);	
		

		//print_r($this->externalData);
		//print_r($this->field);

		foreach ($this->field as $current_field)
		{
			
			if (isset($this->removeInput[$current_field->name])) continue; //Salto per gli hiddenInput Indicati manualmente
			

			if (!isset($row[$current_field->def])) $row[$current_field->def]=''; //Evita i notice di indici di array non esistenti
																				//NB: ->def contiene sempre il nome dell'indice giusto(alias o nome se non c'è alias)
			//echo $current_field->name." - ".$current_field->def."<br />";


			if (is_array($id) && isset($this->removeMultipleEditingInput[$current_field->def])) continue; //
			
			if ($current_field->name==$this->originalPrimaryKey) 
			{
				$TYPE=explode("(",$current_field->type);
				if ($TYPE[0]=='string' && $edit==0) //se la chiave primaria è una stringa la fa modificare solo in inserimento -- NON TESTATO E COMPLETO
				$this->editForm->addInput("text",$this->originalPrimaryKey,$row[$current_field->name],ucfirst(str_replace("_"," ",$current_field->def)),false,false,$current_field->not_null,$this->classForFormInput[inputs]); 
				else //altrimenti se si è in modifica aggiunge un hidden
				{
					if (!is_array($id))	
					$this->editForm->addInput("hidden",$this->originalPrimaryKey,$id);
					else
					foreach ($id as $i) //array di input per gli id
					$this->editForm->addInput("hidden",$this->originalPrimaryKey."[]",$i);	
				}
				
				
				continue;
			} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			if ($current_field->table!=$this->primaryTable ) //**CAMPI COLLEGATI A TABELLE ESTERNE
			{
			
			
				////////////////////CONTROLLO ESISTENZA CAMPO COLLEGATO
				$founded=false;
				foreach($this->externalData as $key=>$val)
				{
					if ($val['ex_table']==$current_field->table && $val['ex_field']==$current_field->name && $val['ex_alias']==$current_field->def)
					{
						$founded=$key;
						break;
					}
						
				}
				if ($founded===false) continue;  //se non esiste il collegamento salta...
				
				//if (!isset($this->externalData[$current_field->table.".".$current_field->name])) continue; //se non esiste il collegamento salta...
			
				////////////////////////////////////////////////////
			
				
				if (strpos($this->query," AS ".$current_field->table." ")!=false)  //CERCA l'[ALIAS DELLA TABELLA] !!!!
				{
					$exp=explode(" AS ".$current_field->table." ",$this->query);
					$exp2=explode(" ",$exp[0]);	
					$table=$exp2[(count($exp2)-1)];
				}
				else $table=$current_field->table;
				
				//$dato_principale=$current_field->name;
				$dato_principale=$current_field->name;
				
				//echo $dato_principale;
				$chiave=$this->externalData[$founded]["ex_primaryKey"];
				$chiave_esterna=$this->externalData[$founded]["externalKey"];
				$alias=$this->externalData[$founded]["ex_alias"];
				
				$alias_show=ucfirst(str_replace("_"," ",$alias));
				
				if (isset($this->removeInput[$chiave_esterna])) continue; //Salto per gli hiddenInput Indicati manualmente
				
				$result_esterna=mysql_query("SELECT * FROM $table ORDER BY {$chiave}"); 

				
				//print_r($this->externalData);
				
				
				$value=array(""=>$this->lang['select']." ".$alias_show);
				
				$selected="";

				while ($row_esterna=mysql_fetch_array($result_esterna))
				{
					//$print.= $row[$dato_principale];
					$value[$row_esterna[$chiave]]=$row_esterna[$dato_principale];
					//echo "\$value[{$row_esterna[$chiave]}]=\$row_esterna[{$dato_principale}]";
								
					//echo "<br />if (\$row[{$alias}(\$alias)]==\$row_esterna[{$dato_principale}(\$dato_principale) oppure {$chiave}(\$chiave)]) \$selected=\$row_esterna[{$chiave}(\$chiave)]<br />";
					if ($row[$alias]==$row_esterna[$dato_principale]) $selected=$row_esterna[$chiave]; //?? ci dovrebbe essere solo il controllo sotto?
					if ($row[$alias]==$row_esterna[$chiave]) $selected=$row_esterna[$chiave]; //per il POST		
					//if ($row[$chiave_esterna]==$row_esterna[$chiave]) $selected=$row_esterna[$chiave]; //per il POST

				}		
				
				
				$dati_chiave_esterna=mysql_fetch_field(mysql_query("Select $chiave_esterna FROM $this->originalPrimaryTable"));
				$validate=$dati_chiave_esterna->not_null==1?REGEXP_NOTNULL:false; //maremma troia! gliel'assegna qui stocazzo di validazione
				
				$added=$this->editForm->addInput("select",$chiave_esterna,$value,$alias_show,false,$selected,$validate,$this->classForFormInput['inputs']);			
				
				if (is_array($id) && $added) $fieldEnablingPanel.= $this->getFieldEnablingPanelButton('SELECT',$chiave_esterna,$alias_show);
				
			}
			else //*****CAMPI DELLA TABELLA PRINCIPALE
			{
			
				if (is_array($id)) ///i campi univoci non si modificano per + record
				{
					$describe=mysql_query("DESCRIBE ".$this->originalPrimaryTable);  	
					while ($describe_field=mysql_fetch_array($describe))
					if ($describe_field['Field']==$current_field->name && $describe_field['Key']=="UNI") continue 2; //..
				}

			 		
				$TYPE=explode("('",$current_field->type);//serve per identificare gli ENUM
				
				switch($TYPE[0])
				{	
					case "password":if (is_array($id)) break;
									
									if ($edit==0)
									$this->editForm->addInsertPasswordInputs($current_field->name,ucfirst(str_replace("_"," ",$current_field->def)),$this->classForFormInput['inputs']);
									else
									$this->editForm->addChangePasswordInputs($current_field->name,ucfirst(str_replace("_"," ",$current_field->def)),$this->classForFormInput['inputs']);
									break;
					case "date":


									$added=$this->editForm->addInput("date","$current_field->name",array($this->dateInterval[0],$this->dateInterval[1]),ucfirst(str_replace("_"," ",$current_field->def)),true,$row[$current_field->def],$current_field->not_null,$this->classForFormInput['inputs']);

									if (is_array($id) && $added) 
										$fieldEnablingPanel.= $this->getFieldEnablingPanelButton('DATE',$current_field->name,$current_field->def);

															
								break;
					case"string":
					case"int": 		//print_r($current_field);			
					case"real":	
								
								if (isset($this->photoField[$current_field->name]) || isset($this->fileField[$current_field->name]))
								{
									if (is_array($id)) break; //foto non modificate in modo multiplo
									
									if (
										(isset($this->photoField[$current_field->name]) && $this->photoField[$current_field->name]==true)
										|| 
										(isset($this->fileField[$current_field->name]) && $this->fileField[$current_field->name]==true)
										)
									{
										if ($current_field->not_null[0]==true) $bool=false; else {$bool=true;} //do' la possibilità di eliminare il file 
																											//solo se non è un campo obbligatorio
										$current_field->not_null[0]=false; //in ogni caso, una volta che il file è stato caricato, non gli assegno
																			//una validazione obbligatoria nel form 
										
									} else
									$bool=false;

										
									$this->editForm->addInput("file",$current_field->name,$row[$current_field->def],ucfirst(str_replace("_"," ",$current_field->def)),$bool,false,$current_field->not_null,$this->classForFormInput['inputs']);
								}
								else 
								{
									
									$added=$this->editForm->addInput("text",$current_field->name,$row[$current_field->def],ucfirst(str_replace("_"," ",$current_field->def)),false,false,$current_field->not_null,$this->classForFormInput['inputs']);

									if (is_array($id)  && $added) 
									{
										$JS= "
										new AutoSuggestControl('{$this->originalPrimaryTable}',document.getElementById(\"{$current_field->name}\"),\"{$current_field->name}\");
										";

										if ($this->ajaxCall) $print.="<script type=\"text/javascript\"><!-- {$JS} --></script>";
										else $this->JS_onLoad.=$JS;									
										
										$fieldEnablingPanel.= $this->getFieldEnablingPanelButton('TEXT',$current_field->name,$current_field->def);
									}
								}
								
								break;
																	
					case "longtext": 
					case "mediumtext": 
									
									$added=$this->editForm->addInput("textarea",$current_field->name,$row[$current_field->def]
										  ,ucfirst(str_replace("_"," ",$current_field->def)),$this->HTMLTextareaParams,false,$current_field->not_null
										  ,$this->classForFormInput['textareas']); 

									if (is_array($id) && $added)
										$fieldEnablingPanel.= $this->getFieldEnablingPanelButton('HTML_TEXTAREA',$current_field->name,$current_field->def);

								break;		 
					
					case "text": 
					case "tinytext":   
									
									$added=$this->editForm->addInput("textarea",$current_field->name,$row[$current_field->def]
										  ,ucfirst(str_replace("_"," ",$current_field->def)),false,false,$current_field->not_null
										  ,$this->classForFormInput['textareas']); 		 

									if (is_array($id) && $added)
										$fieldEnablingPanel.= $this->getFieldEnablingPanelButton('TEXTAREA',$current_field->name,$current_field->def);	
									
								break;
					
					case"enum": 
								$heading=ucfirst(str_replace("_"," ",$current_field->def));								
								
								$value=$this->getEnumSetValue($current_field->type);
																				
								if (count($value)>$this->radioSettings['maxOptionsInOneLine']) $bool=false; else $bool=true; //su una riga o no
								
								if (count($value)>$this->radioSettings['maxOptions']) 
								{
									$type="SELECT";
									$value=array_merge(array(''=>$this->lang['select']." ".$heading), $value); //aggiungo l'intestazione
								}
								else 
								{
									$type="RADIO";									
								}
																						
								$added=$this->editForm->addInput($type,$current_field->name,$value,$heading,$bool,$row[$current_field->def]
									  ,$current_field->not_null,$this->classForFormInput['inputs']); 
								
								if (is_array($id) && $added) 
									$fieldEnablingPanel.= $this->getFieldEnablingPanelButton($type,$current_field->name,$current_field->def);										
																	
								break;		 
					
					case"set" :	
								$heading=ucfirst(str_replace("_"," ",$current_field->def));
								
								$value=$this->getEnumSetValue($current_field->type);
								
								
								if (count($value)>$this->checkboxesSettings['maxCheckboxes'])
								{
									$type="SELECT";
									/////////////$value=array_merge(array(''=>$this->lang['select']." ".$heading), $value); //aggiungo l'intestazione
									$bool=$this->checkboxesSettings['multipleSelectSize'];
								}
								else 
								{
									$type="CHECKBOX";	
									$bool=false;								
								}								

								$added=$this->editForm->addInput($type,$current_field->name,$value,$heading,$bool,explode(",",$row[$current_field->def])
									  ,$current_field->not_null,$this->classForFormInput['inputs']); 
									  								
								if (is_array($id) && $added) 
									$fieldEnablingPanel.= $this->getFieldEnablingPanelButton($type,$current_field->name,$current_field->def,count($value));																									
								
								break;		 
				
				}//end switch
			}//end if
		} //end foreach
		
		
		if ($fieldEnablingPanel!="") 
		{
			$print.="<div id=\"{$this->originalPrimaryTable}_fieldEnablingPanel\" 
						  style=\"border-top:1px solid #DDD;border-bottom:1px solid #DDD;padding:6px 0px;margin-bottom:6px\">
						<div style=\"margin-bottom:5px;font-style:italic\">{$this->lang['fieldEnablingPanelHeading']}</div>"
						.$fieldEnablingPanel.
					"</div>";
					
			$this->editForm->addExternalValidation("
			chk_arr=document.getElementById('{$this->originalPrimaryTable}_fieldEnablingPanel').getElementsByTagName('input');
			
			allUnchecked=true;
			for (i=0;i<chk_arr.length;i++)
			if (chk_arr[i].checked==true)
			{
				allUnchecked=false;
				break;
			}
			
			if (allUnchecked) 
			{
				alert('seleziona almeno un campo da modificare');
				return false;
			}",true);
		}
		
		$editForm_string = $this->editForm->buildForm("&nbsp;:: {$this->lang['confirmData']} ::&nbsp;",$this->classForFormInput['buttons']);
		
		$editForm_string = $this->brutalTextReplace($replace_array,$editForm_string);

		
		
		if ($this->useAjax)
		$editForm_string=str_replace("<form ","<form onsubmit=\"document.getElementById('img_loading_dbn').style.display='block'\"",$editForm_string);
		
		$print.= $editForm_string;

	
		//mail("hide@address.com",'aa',$print);
		return $print;
	}	
	
	//serve per identificare i valori dell'ENUM/SET
	function getEnumSetValue($typeDefinition)
	{
		$start_cut=strpos($typeDefinition,"('")+2;
		$value=substr($typeDefinition,$start_cut,-2);
		
		$temp=explode("','",$value);
		$value=array();	
		foreach($temp as $v)
		{
			$v=str_replace(array("''","\\\\",),array("'","\\"),$v);
			$value[$v]=ucfirst($v);
		}	
		return $value;							
	}

	function getFieldEnablingPanelButton($type,$name,$heading,$length=null)
	{
		$JSDisable="";
		
		if ($this->ajaxCall) $JSDisable="change_{$name}_status();";
		else $this->JS_onLoad.="
									change_{$name}_status();
								";		
													
		switch(strtoupper($type))
		{
			case 'DATE':		
								$JSFunctionBody="
												var el1=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}_day; 
												var el2=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}_mon;
												var el3=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}_yea;
												
												if (el1.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.position=='absolute')
												{
													el1.disabled=false;
													el2.disabled=false;
													el3.disabled=false;
													el1.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.position='relative';
												}
												else
												{
													el1.disabled=true;
													el2.disabled=true;
													el3.disabled=true;
													el1.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.left='-100000000px';
													el1.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.position='absolute';
													
												}
										";	
								break;	
								
			case 'HTML_TEXTAREA':
								$JSFunctionBody="
												if (document.all)
												{
													var elDoc = window.document.frames('{$name}').document;
													var el = window.document.frames('{$name}');
												}
												else
												{
													var elDoc = document.getElementById('{$name}').contentDocument;										
													var el = document.getElementById('{$name}');										
												}
												
												 
												if (el.parentNode.parentNode.style.position=='absolute')
												{
													elDoc.designMode='on';
													el.parentNode.parentNode.style.position='relative';
													
												}
												else
												{
													elDoc.designMode='off';
													el.parentNode.parentNode.style.left='-100000000px';
													el.parentNode.parentNode.style.position='absolute';
													
												}
										";	
								break;	
			case 'TEXT':
			case 'TEXTAREA':
			case 'SELECT':																		
							$JSFunctionBody= "
											var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}; 
											
											if (el.parentNode.parentNode.style.position=='absolute')
											{
												el.disabled=false;
												el.parentNode.parentNode.style.position='relative';

												//aggiungo all'input che indica i campi da modificare

											}
											else
											{																								
												el.disabled=true;
												el.parentNode.parentNode.style.left='-100000000px';
												el.parentNode.parentNode.style.position='absolute';																																		
											}											
									";
							
							break;	
							
												
			case 'RADIO':
						$JSFunctionBody="
											var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}; 
											
											if (el[0].parentNode.parentNode.style.position=='absolute')
											{
												for (i=0;i<el.length;i++) el[i].disabled=false;
												el[0].parentNode.parentNode.style.position='relative';
											}
											else
											{
												for (i=0;i<el.length;i++) el[i].disabled=true;
												el[0].parentNode.parentNode.style.left='-100000000px';
												el[0].parentNode.parentNode.style.position='absolute';
											}
									";
						break;
						
			case 'CHECKBOX':
						$JSFunctionBody="
											var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name}; 
		
											if (el.parentNode.parentNode.style.position=='absolute')
											{
												for (i=0;i<{$length};i++) 
													document.getElementById('frm_{$this->originalPrimaryTable}').elements['{$name}['+i+']'].disabled=false;
												
												el.parentNode.parentNode.style.position='relative';
											}
											else
											{
												for (i=0;i<{$length};i++) 
													document.getElementById('frm_{$this->originalPrimaryTable}').elements['{$name}['+i+']'].disabled=true;
													
												el.parentNode.parentNode.style.left='-100000000px';
												el.parentNode.parentNode.style.position='absolute';
											}										
									";
						break;
		}

		return "
				<script type=\"text/javascript\">
					<!--
						change_{$name}_status=function()
						{
							fieldList=document.getElementById('frm_{$this->originalPrimaryTable}').fieldList;
							
							if (fieldList.value.indexOf('{$name}')!=-1) //rimuovo dall'input che indica i campi da modificare
							{
								exp=fieldList.value.split(',');
								for (i=0;i<exp.length;i++)
								if (exp[i]=='{$name}')
								{
									temp=exp[exp.length-1];
									exp[exp.length-1]=exp[i];
									exp[i]=temp;
									exp.pop();
									temp=true;
									break;
								}
								fieldList.value=exp.join(',');
							}
							else //da riaggiungere il nome nella field List
								fieldList.value+=',{$name}';
							
							//alert(fieldList.value);
							
							{$JSFunctionBody}
						}
						{$JSDisable}
					-->
					</script>
					
					<input type=\"checkbox\" onchange=\"change_{$name}_status()\" /> 
														
					<strong>".ucfirst(str_replace("_"," ",$heading))."</strong><br />
					";			
		
		
	}	
	
	function viewForPrint($id=null)
	{
		$print="";

		
		$row=mysql_fetch_array(mysql_query($this->addWhereConditionToQuery($this->query,"{$this->primaryTable}.{$this->originalPrimaryKey}='$id'")));

		//$print.= $this->addWhereConditionToQuery($this->query,"{$this->primaryTable}.{$this->primaryKey}='$id'");
		if ($row) //Modalità modifica
		{
			
			
			if (is_array($this->photoField) || is_array($this->fileField)) //formattazione div contenitore per le immagini (e file)
			{

				foreach ($this->photoField as $field=>$bool)
				{ 
					if ($field=="_Resize_" || $field=="_KeepOriginal_") continue; ////da sistemare......? parametri delle immagini nello stesso array
					if ($row[$field]!="")
					{			
						if (!isset($div_flag)) //stampa il div una volta sola , solo se c'è qualcosa 
						{
							$print.= "<div style=\"position:relative;float:right;border:1px solid #000000;width:47%;padding:2% 0% 2% 2%\">";
				 			$div_flag=true;
						}
							
						if (!$this->photoField['_Resize_']) $small=""; else $small="small_";
						$print.="<h4>".ucfirst($field)." corrente</h4>";
						if ($small=="small_") $print.="<a href=\"{$this->filePath}/{$row[$field]}\" onclick=\"window.open(this.href);return false;\">";
						$print.="<img src=\"{$this->filePath}/$small{$row[$field]}\" alt=\"{$row[$field]}\" /><br />".$row[$field];
						if ($small=="small_") $print.="</a>";
						$this->photoField[$field]=true; ///
					}
				}

				foreach ($this->fileField as $field=>$bool)
				{ 
					if ($row[$field]!="")
					{
						if (!isset($div_flag))  //stampa il div una volta sola , solo se c'è qualcosa 
						{
							$print.= "<div style=\"position:relative;float:right;border:1px solid #000000;width:47%;overflow:scroll;padding:2% 0% 2% 2%\">";
				 			$div_flag=true;
						}					
						$print.="<h3>".ucfirst($field)." corrente</h3>
						<a href=\"{$this->filePath}/{$row[$field]}\" onclick=\"window.open(this.href);return false;\"><strong>{$row[$field]}</strong></a>";
						$this->fileField[$field]=true; ///
					}
				}
				if (isset($div_flag)) $print.="</div><div style=\"position:relative;float:left;width:50%\">";
			}
		} else 
		{
			die('Id errato');
		}

		$print.="
		<div style=\"font-size:15px;font-family:Arial,Verdana,sans serif\">
		<span style=\"font-size:20px\">Visualizzazione dati {$this->rowName} $id</span><br /><br />
		";


		foreach ($this->field as $current_field)
		{
			 		$TYPE=explode("(",$current_field->type);//serve per identificare gli ENUM

					switch($TYPE[0])
					{	
						case "password":$data="<em>( informazione codificata )</em>";break;
						case "date":$data=data_europea($row[$current_field->def]);break;
						case "datetime":$data=data_ora_europea($row[$current_field->def]);break;
						default:$data=$row[$current_field->def];
					}
					
					if ($data=="") $data="<em>( informazione non presente )</em>";
						
					$print.="<span style=\"font-weight:bolder;color:#000088\"><em>".ucfirst(str_replace("_"," ",$current_field->def))." : </em></span>".$data."<br /><br />";
						

		} //end foreach
		

		if (isset($div_flag))  //formattazione tabella contenitore
		{
			$print.="</div>";
		}		

		return $print."</div>";
	}	
		

	function export($type)
	{
		 
		$validField=array();
		
		foreach ($this->field as $current_field)
		{
			if (isset($this->passwordField[$current_field->def])) continue;		
			if (isset($this->photoField[$current_field->def])) continue;					
			if (isset($this->fileField[$current_field->def])) continue;	
			if ($this->hidePrimaryKey && $current_field->def==$this->originalPrimaryKey) continue;	
			
			$list[] = strtoupper(str_replace("_"," ",$current_field->def));
			$validField[] = $current_field ;			
						
		} //end foreach


		
		
		
		$result=mysql_query($this->getFullQuery()) or die ('errore query generazione CSV '.mysql_error());
		
		
		
		
		$data=array();
		$data[0]=$list;
		
		while ($row=mysql_fetch_array($result))
		{
			$data[count($data)]=array();
			
			foreach ($validField as $field)
			{
				
									
				$TYPE=explode("(",$field->type);//serve per identificare gli ENUM

				switch($TYPE[0])
				{	
					case "date":$temp=data_europea($row[$field->def]);break;
					case "datetime":$temp=data_ora_europea($row[$field->def]);break;
					default:$temp=$row[$field->def];
				}
				
				$data[count($data)-1][]=trim(
											strip_tags(str_replace(array("<br />","<br>","<BR />","<BR>","\r","\n","&nbsp;"),array(" "," "," "," "," "," "," "),$temp))
											);			
	
			} //end foreach
			
			

		}
		
		//ob_end_clean(); //l'url col quale si accede a questo codice comprende il get che attiva la modalità ajax e cancella il buffer già nella funzione go()
		
		$filename=$this->originalPrimaryTable."__".date("d_m_Y")."__".date("H_i_s");
		
		$print="";
		
		if ($type=='CSV')
		{	
			header('Content-Type: application/vnd.ms-excel; charset=utf-8');
			header("Content-Disposition: attachment; filename=\"{$filename}.txt\"");		
				
			foreach($data as $row)
			{
				foreach ($row as $key=>$data)
				$row[$key]=html_entity_decode(str_replace('"','""',$row[$key])); //escape di " con " ("")
				
				$print.='"'.implode('","' , $row)."\"\r\n";					
			}
		}
		else
		{
		
			header('Content-Type: application/vnd.ms-excel; charset=utf-8');
			header("Content-Disposition: attachment; filename=\"{$filename}.xml\"");		
		
			// è IMPORTANTE che <?xml parta al primo carattere del file sennò OO non lo vede 
			$print.="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
			
			<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" >			
				<ss:Worksheet ss:Name=\"".$this->originalPrimaryTable."\">			
					<Table ss:ExpandedColumnCount=\"".count($validField)."\">";
			
					foreach($data as $row)
					{
						$print.='
								<Row>
								';
						
						foreach ($row as $key=>$data)
						{
							if (preg_match("/^\d+((\.|,)\d+)?$/",$row[$key]))
							{
								$datatype='Number';
								$row[$key]=str_replace(',','.',$row[$key]); //la virgola non è interpretata nei numeri.
							}
							else 
							{
								$datatype='String';
								$row[$key]=preg_replace('/(&)(([^a]|$)|a([^m]|$)|am([^p]|$)|amp([^;]|$))/','$1amp;$2',$row[$key]); //per compatib.,sostit. & con &amp;
								//considerare l'uso di <![CDATA[BROWNIES<> & CO.]]> invece di BROWNIES&gt;&lt; &amp; CO.
							}
							$print.="<Cell>
										<Data ss:Type=\"".$datatype."\">".$row[$key]."</Data>
									 </Cell>";							 
						}
						
						$print.='
								</Row>
								';
						
					}
			
			$print.='			
					</Table>
				</ss:Worksheet>
			</Workbook>';
		
		}

		die( $print );
	}	
			
	



	function managePassword($field)
	{
	
			//unset($_POST[$field."_retyped"]);
			
			$old_password=isset($_POST[$field."_old"])?$_POST[$field."_old"]:"";
			unset($_POST[$field."_old"]);
			
			$new_password=isset($_POST[$field])?$_POST[$field]:"";
			unset($_POST[$field]);
	
			if ($field && $new_password!='')
			{
				if ($_POST['edit_'.$this->originalPrimaryTable]==='1')// fase di modifica dati
				{
					
					$row=mysql_fetch_array(mysql_query("SELECT {$field} FROM {$this->originalPrimaryTable} WHERE $this->originalPrimaryKey=\"".$_POST[$this->originalPrimaryKey]."\""));
					if ( md5($old_password)==$row[$field] || /*password vuota*/($old_password=='' && $row[$field]=='') )
					{
						$_POST[$field]=md5($new_password);
						return true;
					}
					else 
					{
						return false;
					}
				}else $_POST[$field]=md5($new_password); //fase di inserimento dati
			}
			
			return true;
	}
	
	

	
	
}





?>
Return current item: DBNavigator