<?php
/** @author Michele Castellucci <ghiaccio84@gmail.com> */
/** This class allows to manage the operation on a MYSQL database, building a graphic interface
* in automatic manner (a way like to phpMyAdmin) with a * great range of configurations. <br />
*
* Essentially, the data an object DBNavigator can work on, are indicated with a normal query SQL.
* Throught a <b> testual scanning of the query</b>, are pointed out the involved tables, the data types
* of the selected fields and the eventual relations between fields of differentes tables (joined by JOIN).
*
* Other information which are not directly locatabled by the databes structure can be pointed out
* by using {@link setMailField()} , {@link setFileField()} , {@link setImageField()} ,
* {@link setPasswordField()}, {@link setNumericStringField()} and {@link setMonthYearField()} methods.
* <br /><br />
*
* The HTML contents automatically generated can be graphically personalized by creating
* your own papers in CSS style and associating
* the styles using function {@link setTableRowStyle()} , {@link setTableCellStyle()}, {@link setTableBorderStyles()}
* ,{@link addTableContainer()} and {@link setClassForFormInput()} .
* <br /><br />
*
* You can choose to open the AJAX form through the {@link useAjax()} method to obtain improvements in the graphic interface
* related to utilization and speed.
* <br /><br />
*
* The interaction main functionality with DBNavigator database are:
* <ul>
*
* <li> <b>INSERTION/EDITING</b><br /><br />
* an appropriate form HTML is automatically built including all the necessary validations
* of the fields both the server side and the client side (javascript).<br /><br />
*
* It is possible to use DBNavigator simply for a single insertion through {@link go_only_for_form()} method
* (EX: forum registration).
*
* Specifying a rescue path, is managed the memorization of generic files or images.
* Moreover, in the case of image alterations, is automatically shown a preview inside the form.
*
* In the case of password, the form will include the additional input for the re-typing.
* Those passwords will be memorized using the MD5 coding.
*
* Gaining access to the object{@link HTMLForm} member of DBNavigator through the method {@link getEditForm()},
* it is possible <b>to further personalize ulteriormente the form HTML</b>.<br />
* For example you can add to the form a simple anti-hacking verifying code(<b>immagine CAPTCHA</b>)<br />
* otherwise to replace the format HTML of default with another as long as that you will incorporate that format in a class PHP
* that will extend the abstact class {@link TextEditorContainer} (see the method {@link getEditForm()} for further details).<br /><br />
*
* Simultaneus alterations made by some users are blocked through a simple workings of <b>mutua esclusione</b> on the record.
* <br /><br />
*
* MYSQL FIEDS ON HTML EDIT INTERFACE<br /><br />
* Here it is a mapping between MySql fields and HTML inputs binded in an automatic way during the building process of edit interface:<br /><br />
* <ul>
* <li>CHAR/VARCHAR : text input. On this field can be used
* {@link setMailField()} , {@link setFileField()} , {@link setImageField()} ,
* {@link setPasswordField()}, {@link setNumericStringField()}.</li>
* <li>DATE : 3 select input (day, month, year). On this field can be used {@link setMonthYearField()}</li>
* <li>INT/BIGINT : text input with validation check about integer number format</li>
* <li>DOUBLE : text input with validation check about double number format</li>
* <li>ENUM : radio input or select input if there are many possible values</li>
* <li>SET : checkboxes or select input with multiple choose if there are many possible values</li>
* <li>TEXT/TINYTEXT : textarea input</li>
* <li>MEDIUMTEXT/LONGTEXT : HTML formatter. See {@link getEditForm()} to change the default.</li>
* <li>EXTERNAL KEYS WITH INTEGER TYPE: select input that allow to choose one record of the externat table</li>
* </ul>
* <br /><br />
*
* </li>
*
* <li> <b>DISPLAYING </b><br /><br />
* the subject matter of the selected field is shown through an HTML table or in a way completely definable by the class user.
*
* You can choose to enable or not the possibility to insert ({@link canInsert()}), alterate ({@link canEdit()})
* or eliminate elements. In this case the necessary interface is added to the table.
*
* Using the standard table visualization, it is possible to add special additional line through functions
* {@link addDataCol()}, {@link addLinkCol()}, {@link addFreeCol()} and {@link addSwitchCol()}.<br />
* It is important the function {@link addLinkCol()} to allow to link every record to an inside page where are managed data related
* to that single record. Typical is the example where the inside page uses another DBNavigator to manage data memorized in the database
* in relation 1 a n.
*
* In table form, the web page user can order data in growing or decreasing form for each visualized field.
* The default disposition has not to be indicated in the query but through the {@link setDefaultOrd()} method.
* <br /><br />
* </li>
*
* <li> <b>SPECIAL ACTIONS </b><br /><br />
* Through the form {@link canMultipleEditDelete()} can be enabled the possibility to make special actions.<br />
* These actions are based on the general table of visualization, which will include the checkbox (checkbox) for an underwhole selection
* of the visualized elements.<br /><br />
*
* The <b>elimination of the party</b> allows to eliminate in a single step all the selected.<br />
* The <b>modification sequential</b> allows to alterate one by one the selected elements,
* without choosing the following one at each modification.<br />
* The <b>modification simultaneous</b> is very special action which allows to alterate only some fields selected by the user.
* The alteration of these fields is made on the elements previously selected.
* <br /><br />
* </li>
*
* <li> <b>DATA SEARCHS</b><br /><br />
*
* The class owns a mechanism which allows to define some fields such as searching fields using
* the method {@link setSearchField()}.<br /><br />
*
* Using the information proceeds from the <b>textual scanning of the initial query</b>, is
* automatically set up the graphic interface in the way to let the user make a search
* with the suitable checks, based on the type of the field to be searched.<br /><br />
*
* For researches on textual fields, the search field is furnished with a useful system of automatic auto-finishing
* based on Ajax (<b>AJAX based auto-complete suggestions</b>).<br />
* this way are suggested the texts limited in the database to make researches easier and faster. * <br /><br />
*
* Another additional functionality is related to the exportation of data which can be applied to the entire set of data or
* to an underwhole locked up by researching criteria.<br />
* Data can be exported in CSV format simple or in format
* <b>XML compatible with the browsing by Microsoft Excel ed OpenOffice Calc</b>.
*
* </li>
* </ul>
*
* <br /><br />
* <b>REQUIRED METHODS</b><br /><br />
* The class is started up with the method {@link go()} or with {@link go_only_for_form()}<br /><br />
*
* The compulsory and necessary method to be recalled is {@link setPrimaryTable()}.<br />
* For the method {@link go()} is <b>compulsory to recall</b> also methods {@link setDefaultOrd()} and {@link setRowName()}.<br />
* Besides if you use methods {@link setImageField()} and/or {@link setFileField()} is compulsory to recall {@link setFilePath()}.
*
* <br /><br /><b>MIND OUT!</b> ________________________________________________________________<br />
* The class need a PHP version 5 configurated within <b>magic_quotes_gpc = On</b>.<br />
* If you can't have it, try <code>ini_set("magic_quotes_gpc" , "On");</code>
* in every script that is expected to do some database modification using DBNavigator.<br />
* ________________________________________________________________________________<br /><br /><br />
*
*
*
* <br /><br />*************************** <b>ITALIAN DOC.</b>***************************<br />
*
*
* Questa classe consente di gestire le operazioni su di un database MYSQL, costruendo un'intefaccia grafica
* in modo automatico (in modo simile a phpMyAdmin) con una vasta gamma di configurazioni.<br />
*
* Fondamentalmente, i dati su cui può lavorare un oggetto DBNavigator, vengono indicati tramite una normale query SQL.
* Attraverso una <b>scansione testuale della query</b>, vengono rilevate le tabelle coinvolte, i tipi dei
* dati dei campi selezionati e le eventuali relazioni tra i campi di tabelle diverse (unite da un JOIN).
*
* Altre informazioni non reperibili direttamente dalla struttura del database possono essere indicate
* tramite i metodi {@link setMailField()} , {@link setFileField()} , {@link setImageField()} ,
* {@link setPasswordField()}, {@link setNumericStringField()} e {@link setMonthYearField()}.
* <br /><br />
*
* I contenuti HTML generati automaticamente possono essere personalizzati graficamente tramite creando
* i propri fogli di stile CSS ed associando
* gli stili tramite le funzioni {@link setTableRowStyle()} , {@link setTableCellStyle()}, {@link setTableBorderStyles()}
* ,{@link addTableContainer()} e {@link setClassForFormInput()} .
* <br /><br />
*
* Si può scegliere di attivare la modalità AJAX attraverso il metodo {@link useAjax()} per ottenere miglioramenti dell'interfaccia grafica
* in termini di usabilità e velocità.
* <br /><br />
*
* Le funzionalità principali di interazione con il database di DBNavigator sono:
* <br /><br />
* <ul>
*
* <li> <b>INSERIMENTO/MODIFICA</b><br /><br />
* viene costruito automaticamente un form HTML appropriato con incluse le necessarie validazioni
* dei campi sia lato server che lato client (javascript).<br /><br />
*
* E' possibile usare DBNavigator semplicemente per un inserimento singolo attraverso il metodo {@link go_only_for_form()}
* (ES: registrazione ad un forum).<br /><br />
*
* Specificando un path di salvataggio, viene gestita la memorizzazione di file generici o immagini.
* Inoltre nel caso di modifiche ad immagini, viene automaticamente mostrata una preview all'interno del form.<br /><br />
*
* Nel caso di password, il form conterrà l'input aggiuntivo per la ri-digitazione. Tali passord verranno memorizzate
* utilizzando la codifica MD5.<br /><br />
*
* Accedendo all'oggetto {@link HTMLForm} membro di DBNavigator tramite il metodo {@link getEditForm()},
* è possibile <b>personalizzare ulteriormente il form HTML</b>.<br />
* Ad esempio si può aggiungere al form un semplice codice di verifica anti-hacking (<b>immagine CAPTCHA</b>)<br />
* oppure sostituire il formattatore HTML di default con un altro a patto che si inglobi tale formattatore in una classe PHP
* che estenda la classe astratta {@link TextEditorContainer} (si veda il metodo {@link getEditForm()} per ulteriori dettagli).<br /><br />
*
* Modifiche simultanee da parte di più utenti vengono bloccate attraverso un semplice meccanismo di <b>mutua esclusione</b> sui record.
* <br /><br />
*
* CAMPI MYSQL SU INTERFACCIA HTML DI MODIFICA<br /><br />
* Ecco una corrispondenza tra i campi MySql ed i controlli HTML automaticamente associati nella costruzione dell'interfaccia di modifica:<br /><br />
* <ul>
* <li>CHAR/VARCHAR : text input. Su questo tipo di campo è possibile usare
* {@link setMailField()} , {@link setFileField()} , {@link setImageField()} ,
* {@link setPasswordField()}, {@link setNumericStringField()}.</li>
* <li>DATE : 3 select input (giorno,mese,anno). Su questo tipo di campo è possibile usare {@link setMonthYearField()}</li>
* <li>INT/BIGINT : text input con validazione di controllo per il formato numero intero</li>
* <li>DOUBLE : text input con validazione di controllo per il formato numero con virgola</li>
* <li>ENUM : radio input oppure select input se i valori possibili sono molti</li>
* <li>SET : checkboxes oppure select input a scelta multipla se i valori possibili sono molti</li>
* <li>TEXT/TINYTEXT : textarea input</li>
* <li>MEDIUMTEXT/LONGTEXT : formattatore HTML. Vedere {@link getEditForm()} per cambiare qullo di default </li>
* <li>CHIAVI ESTERNE DI TIPO NUMERICO: select input che consentira di scegliere uno dei record della tabella esterna</li>
* </ul>
*
* <br /><br />
* </li>
*
*
* <li> <b>VISUALIZZAZIONE </b><br /><br />
* Viene mostrato il contenuto dei campi selezionati attraverso una tabella HTML oppure
* in maniera completamente definibile dall'utente della classe.<br /><br />
*
* Si può scegliere di abilitare o meno la possibilità di inserire ({@link canInsert()}), modificare({@link canEdit()})
* o eliminare ({@link canDelete()}) elementi. In questo caso viene aggiunta alla tabella l'interfaccia necessaria.<br /><br />
*
* Usando la visualizzazione tabellare standard, è possibile aggiungere delle colonne speciali aggiuntive tramite le funzioni
* {@link addDataCol()}, {@link addLinkCol()}, {@link addFreeCol()} e {@link addSwitchCol()}.<br />
* E' importante la funzione {@link addLinkCol()} per permettere di linkare ogni record ad una pagina interna in cui si gestiscono dati relativi
* a quel singolo record. Tipico è esempio in cui la pagina interna usa un altro DBNavigator per poter gestire dati memorizzati nel database
* in relazione 1 a n.<br /><br />
*
*
* In modalità tabellare, l'utente della pagina web ha la possibilità di ordinare i dati in modalità crescente o decescente per ogni campo visualizzato.
* L'ordinamento di default non deve essere indicato nella query ma attraverso il metodo {@link setDefaultOrd()}
* <br /><br />
* </li>
*
* <li> <b>AZIONI SPECIALI </b><br /><br />
* Tramite il metodo {@link canMultipleEditDelete()} può essere abilitata la possibilità di compiere azioni di speciali.<br />
* Queste azioni si basano sulla tabella generale di visualizzazione, che conterrà delle caselle di scelta (checkbox) per la selezione di un sottoinsieme
* degli elementi visualizzati.<br /><br />
*
* L' <b>eliminazione di gruppo</b> permette di eliminare in solo passo tutti gli elementi selezionati.<br />
* La <b>modifica sequenziale</b> permette di modificare uno alla volta gli elementi selezionati,
* senza dover scegliere il successivo ad ogni modifica.<br />
* La<b> modifica simultanea</b> è un'azione molto particolare che permette di modificare solo alcuni campi scelti dall'utente.
* La modifica di questi campi viene effettuata sugli elementi selezionati in precedenza.
* <br /><br />
* </li>
*
* <li> <b>RICERCHE TRA I DATI</b><br /><br />
*
* La classe possiede un meccanismo che permette di definire alcuni campi come campi di ricerca utilizzando
* il metodo {@link setSearchField()}.<br /><br />
*
* Utilizzando le informazioni ricavate dalla <b>scansione testuale della query</b> iniziale, viene
* predisposta automaticamente l'interfaccia grafica in modo tale da consentire all'utente di effettuare una ricerca
* con gli adeguati controlli, in base al tipo di campo da ricercare.<br /><br />
*
* Per ricerche su campi testuali, il campo di ricerca viene corredato da un'utile sistema di auto-completamento automatico
* basato su Ajax (<b>AJAX based auto-complete suggestions</b>).<br />
* Vengono così suggeriti i testi che sono contenuti nel database per facilitare e velocizzare le ricerche. * <br /><br />
*
* Un'altra funzionalità aggiuntiva riguarda l'esportazione dei dati che può essere applicata all'intero set di dati oppure
* ad un sottoinsieme vincolato da parametri di ricerca.<br />
* I dati possono essere esportati in formato CSV semplice oppure in formato
* <b>XML compatibile per la lettura da parte di Microsoft Excel ed OpenOffice Calc</b>.
*
* </li>
* </ul>
*
* <br /><br />
* <b>METODI NECESSARI</b><br /><br />
* La classe viene attivata col metodo {@link go()} oppure con {@link go_only_for_form()}<br /><br />
*
* Il metodo obbligatoriamente necessario da richiamare è {@link setPrimaryTable()}.<br />
* Per il metodo {@link go()} è <b>obbligario richiamare</b> anche i metodi {@link setDefaultOrd()} e {@link setRowName()}.<br />
* Inoltre se si usano i metodi {@link setImageField()} e/o {@link setFileField()} è obbligatorio richiamare {@link setFilePath()}.
*
*
*
* <br /><br /><b>NOTA IMPORTANTE</b> ____________________________________________________________<br />
* La classe ha bisogno di PHP versione 5 configurata con <b>magic_quotes_gpc = On</b>.<br />
* If you can't have it, try <code>ini_set("magic_quotes_gpc" , "On");</code>
* in every script that is expected to do some database modification using DBNavigator.
* _________________________________________________________________________________<br /><br /><br />
*
* @author Michele Castellucci <ghiaccio84@gmail.com>
*/
class DBNavigator
{
/// ------ INSTANCE VARIABLES ------ ///
/** La query SQL di costruzione della classe
* @var string */
private $query="";
/** Il nome della tabella principale tra quelle presenti nella query SQL di costruzione
* @see setPrimaryTable
* @var string */
private $originalPrimaryTable="";
/** Il nome dell'alias della tabella principale
* @see setPrimaryTable
* @var string */
private $primaryTable="";
/** Il nome della chiave primaria della tabella principale
* @var string */
private $originalPrimaryKey="";
/** Il nome dell'alias (definito dalla query) della chiave primaria della tabella principale
* @var string */
private $primaryKey="";
/** Il nome generico singolare di ogni riga della tabella
* @see setRowName()
* @var string */
private $rowName="";
/** Informazioni sull'ordinamento: ordinamento di default, ordinamento corrente, desc corrente
* da applicare alla query
* @see setDefaultOrd()
* @var string */
private $orderInfo=array();
/** Contiene le definizioni dei campi della/e tabella/e richiamate dalla query
* @see scanTable()
* @var array */
private $field=array();
/** Contiene informazioni sui campi di altre tabelle collegati alla tabella principale
* @see scanTable()
* @var array */
private $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 */
private $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 */
private $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 */
private $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 */
private $fileField=array();
/** Contiene il percorso relativo della directory in cui salvare immagini e file
* @see setFilePath()
* @var string */
private $filePath="";
/** Contiene il codice esadecimale del colore da applicare come sfondo all'intestazione della tabella di visualizzazione dei dati
* @see setTableRowStyle()
* @var string */
private $tableHeaderCSS="";
/** Contiene il codice esadecimale del colore da applicare come sfondo al corpo della tabella di visualizzazione dei dati
* @see setTableRowStyle()
* @var string */
private $tableRowContentCSS="";
/** Valore di margin (cellspacing) della tabella di visualizzazione dati
* @see setTableCellSpacing()
* @var int */
private $tableCS=3;
/** Indica se mostrare o meno la chiave primaria della tabella principale
* @see hidePrimaryKey()
* @var boolean */
private $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 */
private $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 */
private $canEdit=false;
/** Indica se e' consentito inserire record nella tabella
* @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
* @var boolean */
private $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 */
private $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 */
private $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 */
private $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(),addSwitchCol()
* @var array */
private $linkCol=array();
/** Contiene un array dove ogni elemento corrisponde ad un attributo che ha due possibili valori
* Ogni elemento corrispondente all'attributo possiede a sua volta informazioni sulle due immagini da associare ai due valori sull'interfaccia.
* @see addDataCol(),addLinkCol(),addFreeCol(),addSwitchCol()
* @var array */
private $switchCol=array();
/** Contiene un array dove ogni elemento è un array contenente informazioni sulle colonne di dati aggiuntive
* stampate nella tabella di visualizzazione dati aggiunte con {@link addDataCol()}.
* @see addDataCol(),addLinkCol(),addFreeCol(),addSwitchCol()
* @var array */
private $dataCol=array();
/** Contiene un array dove ogni elemento è un array contenente informazioni sulle colonne "libere" aggiuntive
* stampate nella tabella di visualizzazione dati aggiunte con {@link addFreeCol()}.
* @see addDataCol(),addLinkCol(),addFreeCol(),addSwitchCol()
* @var array */
private $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 */
private $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 */
private $removeDisplaying=array();
/** Contiene la lista dei campi definiti come campi di ricerca
* @see setSearchField()
* @var array */
private $searchField=array();
/** Indica se il form di ricerca è stato stampato o meno
* @see search_form()
* @var boolean */
private $search_form_printed=false;
/** Contiene informazioni sulla cancellazione di righe ricorsiva e linkata ad un'altra tabella
* @see setDeleteRecursive()
* @var array */
private $deleteRecursive=array();
/** Contiene una istanza della classe HTMLForm che costruisce il form di inserimento/modifica dei record
* @see DBNavigator(),buildForm()
* @var HTMLForm */
private $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 */
private $classForFormInput=array("inputs"=>"mini","buttons"=>"mini_btn","textareas"=>"mini_txa");
/** Contiene l'intestazione indicata manualmente del form di inserimento/modifica
* @see setFormHeading()
* @var string */
private $formHeading="";
/** Indica se visualizzare tutti i record su una pagina (senza paginazione) o meno
* @see showAllElements()
* @var boolean */
private $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 */
private $imagesAndScriptsPath="";
/** Indica se è stato già richiamato il metodo scanTable (deve essere richiamato una volta sola)
* @see scanTable()
* @var boolean */
private $tableScanned=false;
/** Contiene i due valori percentuali della dimensione delle 2 colonne del form di inserimento/modifica
* @see setFormWidth()
* @var array */
private $formWidth=array();
/** Contiene il numero di righe della tabella considerando anche gli eventuali parametri di ricerca correnti
* @see get_rowsNum(), set_rowsNum()
* @var int */
private $rowsNum;
/** Contiene le stringhe di testo usate all'interno della classe nella lingua impostata
* @see setLanguage()
* @var array */
private $lang=array();
/** Indica il numero di caratteri oltre il quale tagliare il valore di un campo nella visualizzazione tabellare
* @see setTextCutLength()
* @var int */
private $cutLength=150;
/** Indica il numero di default di record per pagina da visualizzare
* @see setResultsPerPage()
* @var int */
private $resultsPerPage=10;
/** Indica se visualizzare record senza effettuare una ricerca
* @see setViewResultWithoutSearch()
* @var boolean */
private $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 */
private $viewAllSearchOptions=false;
/** Raccoglie il codice Javascript che sarà inseritò all'interno del metodo window.onload
* @var string */
private $JS_onLoad="";
/** Indica se utilizzare la tecnologia AJAX per la navigazione (ordinamento/modifica/inserimento)
* @see useAjax()
* @var boolean */
private $useAjax=false;
/** Indica se e' consentita la modifica multipla e la mofica contemporanea dei record
* @see canDelete(),canEditDelete(),canMultipleEditDelete(),canInsert()
* @var boolean */
private $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 */
private $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 */
private $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 */
private $highlighting=array();
/** Contiene le impostazioni riguardanti gli input radio
* @see setRadioSettings()
* @var array */
private $radioSettings=array('maxOptions'=>8,'maxOptionsInOneLine'=>3);
/** Contiene le impostazioni riguardanti le checkbox
* @see setCheckboxesSettings()
* @var array */
private $checkboxesSettings=array('maxCheckboxes'=>10,'multipleSelectSize'=>15);
/** Contiene il nome della funzione aggiuntiva da eseguire alla cancellazione di un record
* @see setExtraDeletingFunction()
* @var string */
private $extraDeletingFunction='';
/** Contiene la massima dimensione espressa in pixel che una immagine può avere, per altezza o larghezza, nella visualizzazione generale dei dati
* @see setImageScaleDimension()
* @var int */
private $imageScaleDim=70;
/** Contiene un nome che descriva il set di dati considerato
* @see setDatasetName()
* @var String */
private $datasetName="";
/** Contiene i valori relativi all'abilitazione/disabilitazione degli elementi appartenenti all'interfaccia di navigazione tra pagine.
* @see setPageBrowsing()
* @var array */
private $pageBrowsingConfig=array('bylink'=>true,'byselect'=>true,'selectrpp'=>true,'navigationPanelCSS'=>'');
/** Contiene i nomi delle classi css che sono abbinati ai div contenitori esterni della tabella di visualizzazione generale dei dati
* @see addTableContainer()
* @var array */
private $tableContainer=array();
/** Contiene i nomi delle classi css che sono abbinati alla celle esterne della tabella (ai bordi)
* @see setTableBorderStyles()
* @var array */
private $tableBorderStyle=array();
/** Contiene un oggetto TextEditorContainer che rappresenta il formattatore di testo HTML usato nei form
* @see HTMLForm.setHTMLtextEditor()
* @var TextEditorContainer */
private $HTMLtextEditor=false;
/** Indica se mostrare le preview delle immagini nella tabella generale.
* @var boolean */
private $imageIcon=false;
/// ------------------------------- ///
/// ------ INSTANCE METHODS ------ ///
/// ------------------------------- ///
/** @return string the name of the table definded as primary <br /><br />ITALIAN:<br /> il nome della tabella definita come primaria */
function getPrimaryTable() { return $this->originalPrimaryTable; }
/** Enables or closes down the visualization of the elements belonging to the interface of navigation between pages
*
* <br /><br />ITALIAN:<br />
* Abilita o disabilità la visualizzazione degli elementi appartenenti all'interfaccia di navigazione tra pagine.
*
* @param bool enables the navigation between pages like a link for each page
* <br /><br />ITALIAN:<br /> abilita la navigazione tra pagine sotto forma di link per ogni pagina
*
* @param bool enables the navigation between pages like a square of selection containing all the pages to jump to
* <br /><br />ITALIAN:<br /> abilita la navigazione tra pagine sotto forma di una casella di selezione contenente tutte le pagine a cui saltare
*
* @param bool if true enables the selection of results for pages
* <br /><br />ITALIAN:<br /> abilita la selezione di risultati per pagine
*
* @param string is the name of the class CSS for the container of all navigation checks
* <br /><br />ITALIAN:<br /> nome della classe CSS per il contenitore di tutti i controlli di navigazione
*/
function setPageBrowsingConfig($bylink,$byselect,$selectrpp,$navigationPanelCSS='')
{
$this->pageBrowsingConfig=array('bylink'=>$bylink,'byselect'=>$byselect,'selectrpp'=>$selectrpp,'navigationPanelCSS'=>$navigationPanelCSS);
}
/** Comes back the class that builds the form HTML.<br />
* This method can be used to modify the behaviour of that object.<br />
* For example you can add a CAPCTHA code<br />
* <code> $DBNavigator->getEditForm()->addVerificationCode().</code> <br />
* or modify the class wich builds the test format
* <code> $DBNavigator->getEditForm()->setHTMLtextEditor(new MY_HTML_FORMATTER_CLASS()).</code> <br />
* MY_HTML_FORMATTER_CLASS must upgrade the interface {@link TextEditorContainer}
*
* <br /><br />ITALIAN:<br />
* Ritorna la classe che costruisce il form HTML.<br />
* Questo metodo può essere usato per modificare il comportamento di tale oggetto.<br />
* Ad esempio si può aggiungere un codice CAPCTHA:<br />
* <code> $DBNavigator->getEditForm()->addVerificationCode().</code> <br />
* o modificare la classe che costruisce il formattatore testi HTML :<br />
* <code> $DBNavigator->getEditForm()->setHTMLtextEditor(new MY_HTML_FORMATTER_CLASS()).</code> <br />
* MY_HTML_FORMATTER_CLASS deve implementare l'interfaccia {@link TextEditorContainer}
*
* @see HTMLForm::setHTMLtextEditor(), TextEditorContainer*/
function getEditForm()
{
return $this->editForm;
}
/** Sets up the names of CSS classes to combine to outside cells of the table of data visualization.
* This allows to realize a border graphically elaborated to the general table of data.
*
* <br /><br />ITALIAN:<br />
* Imposta i nomi delle classi css da abbinare alle celle esterne della tabella di visualizzazione dati.
* Questo consente di realizzare un bordo graficamente elaborato alla tabella generale dei dati.
*
* @param string CSS class for the left superior corner cell of the table of data visualization
* <br /><br />ITALIAN:<br /> classe CSS per la cella dell' angolo superiore sinistro della tabella di visualizzazione dati.
*
* @param string CSS class for cells of the superior corner of the table of data visualization
* <br /><br />ITALIAN:<br />classe CSS per le celle del bordo superiore della tabella di visualizzazione dati.
*
* @param string CSS class for the right superior corner cell of the table of data visualization
* <br /><br />ITALIAN:<br /> per la cella dell' angolo superiore destro della tabella di visualizzazione dati.
*
* @param string CSS class for right border cells of the table of data visualization
* <br /><br />ITALIAN:<br /> per le celle del bordo destro della tabella di visualizzazione dati.
*
* @param string CSS class for the right inferior corner cell of the table of data visualization
* <br /><br />ITALIAN:<br /> per la cella dell' angolo inferiore destro della tabella di visualizzazione dati.
*
* @param string CSS class for inferior berder cells of the table of data visualization
* <br /><br />ITALIAN:<br /> per le celle del bordo inferiore della tabella di visualizzazione dati.
*
* @param string CSS class for the left inferior border cell of the table of data visualization
* <br /><br />ITALIAN:<br /> per la cella dell' angolo inferiore sinistro della tabella di visualizzazione dati.
*
* @param string CSS class for left border cells of the table of data visualization
* <br /><br />ITALIAN:<br /> per le celle del bordo sinistro della tabella di visualizzazione dati.
*/
function setTableBorderStyles($topsx,$top,$topdx,$dx,$botdx,$bot,$botsx,$sx)
{
$this->tableBorderStyle['topsx']=$topsx;
$this->tableBorderStyle['top']=$top;
$this->tableBorderStyle['topdx']=$topdx;
$this->tableBorderStyle['dx']=$dx;
$this->tableBorderStyle['botdx']=$botdx;
$this->tableBorderStyle['bot']=$bot;
$this->tableBorderStyle['botsx']=$botsx;
$this->tableBorderStyle['sx']=$sx;
}
/** Adds a div container for the table of general data visualization.
* This container can be added to beauty purposes to apply with properties CSS.
*
* <br /><br />ITALIAN:<br />
* Aggiunge un div contenitore per la tabella di visualizzazione generali dei dati.
* Questo contenitore può essere aggiunto per finalità estetiche da applicare con proprietà CSS.
*
* @param string the name of the CSS class to combine to div container.
* <br /><br />ITALIAN:<br /> il nome della classe CSS da abbinare al div contenitore.
*/
function addTableContainer($cssclass)
{
$this->tableContainer[]=$cssclass;
}
/** Enables or closes down the visualization of elements which compose the navigation interface related to the breakdown into pages of the elements
*
* <br /><br />ITALIAN:<br />
* Abilita o disabilita la visualizzazione degli elementi che compongono l'interfaccia di navigazione relativa alla suddivisione in pagine degli elementi.
*
* @param boolean enables/closes down the visualization of page choice through link
* <br /><br />ITALIAN:<br /> abilita/disabilita la visualizzazione della scelta pagine tramite link
*
* @param boolean enables/closes down the visualization of page choice through a selection square
* <br /><br />ITALIAN:<br /> abilita/disabilita la visualizzazione della scelta pagine tramite casella di selezione
*
* @param boolean enables/closes down the visualization of the choice of the number of results for page
* <br /><br />ITALIAN:<br /> abilita/disabilita la visualizzazione della scelta del numero di risultati per pagina
*/
function setPageBrowsing($byselect,$bylink,$selectrpp)
{
$this->pageBrowsingConfig['byselect']=$byselect;
$this->pageBrowsingConfig['bylink']=$bylink;
$this->pageBrowsingConfig['selectrpp']=$selectrpp;
}
/** Sets up a name which identify the data set considered.
* That value is actually used to build the {@link PageNavigator} embedded object.
*
* <br /><br />ITALIAN:<br />
* Imposta un nome identificativo del set di dati considerato.
* Tale valore è attualmente utilizzato per la costruzione dell'oggetto interno {@link PageNavigator}.
*
* @param String name to identify, and for example students, products, invoices, books, etc.
* <br /><br />ITALIAN:<br /> nome identificativo, ed esempio studenti, prodotti, fatture, libri ecc.
*/
function setDatasetName($val){$this->datasetName=$val;}
/**
* @param int represents the maxim pixel dimension with which an image is shownin preview in the table of visualization of general data <br />
* The image is therefore visualized in the way to be contained in a square box of this dimension: <br />
* The biggest dimension of the image takes up the indicated value while the other one is proportionally browsed.
*
* <br /><br />ITALIAN:<br />
* rappresenta la massima dimensione in pixel con cui una immagine viene mostrata in preview nella tabella visualizzazione generale dei dati.<br />
* L'immagine viene quindi visualizzata in modo da essere contenuta in un box quadrato di questa dimensione: <br />
* la dimensione più grande dell'immagine assume il valore indicato mentre l'altra viene scalata in modo proporzionale.
*/
function setImageScaleDimension($val){$this->imageScaleDim=$val;}
/** @param function the name of a function to be performed at the record cancellation and applied on the same record
* This way to act is equivalent to a trigger SQL of type ON DELETE. <br />
* The function must accept a parameter conaining an associative array (obtained from mysql_fetch_array())
* containing the record fields to be deleted.
* <br /><br />ITALIAN:<br />
* il nome di una funzione da eseguire alla cancellazione di un record e applicata sul record stesso.<br />
* Questo modo di agire è acquivalente ad un trigger SQL di tipo ON DELETE. <br />
* La funzione deve accettare un parametro contenente un array associativo (ricavato da mysql_fetch_array())
* contenente i campi del record da cancellare.
*/
function setExtraDeletingFunction($function){$this->extraDeletingFunction=$function;}
/** @param boolean Enable or disable the using of Ajax technology for data browsing
* <br /><br />ITALIAN:<br /> Abilita o meno l'utilizzo della tecnologia AJAX per la navigazione tra i dati */
function useAjax($bool){$this->useAjax=$bool;}
/** Sets up the parameters to go to class {@link TextEditorContainer}.
*
* <br /><br />ITALIAN:<br />
* Imposta i parametri da passare alla classe {@link TextEditorContainer} (textarea HTML)
*
* @param mixed it depends on the {@link TextEditorContainer} object used. See the doc. for default class (AdvTextarea): {@link Adv_TextArea::setParams()}
* <br /><br />ITALIAN:<br />
* dipende dall'oggetto {@link TextEditorContainer} usato. Vedere la doc. per la classe di default (AdvTextarea): {@link Adv_TextArea::setParams()}
*
* @see Adv_TextArea::setParams(), TextEditorContainer::setParams()
*/
function setHTMLTextareaParams($arr){ $this->HTMLTextareaParams=$arr; }
/** @param int number of default of elements for page to print in the data visualization
* <br /><br />ITALIAN:<br /> numero di default di elementi per pagina da stampare nella visualizzazione dati */
function setResultsPerPage($rpp) { $this->resultsPerPage=$rpp; }
/** @param string Name of the language to be used for the file texts shown by the class.<br />
* italian and english texts are availavable. Values to be used are 'english' or 'italian'
* <br /><br />ITALIAN:<br />
* Nome della lingua da usare per i di testo mostrati dalla classe.<br />
* sono disponibili testi in italiano e inglese. I valori da usare sono 'english' o 'italian'. */
function setLanguage($lang)
{
$lang=strtolower($lang);
$this->lang['languageName']=$lang;
if ($lang=='english')
{
$this->lang['selection']="Selection";
$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['fieldEnablingControlHeading']="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['selection']="Selezione";
$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['fieldEnablingControlHeading']="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']);
}
/** Sets up a state which stated lined must be highlighted
*
* <br /><br />ITALIAN:<br />
* Imposta una condizione per cui determinate righe devono evidenziarsi
*
* @param string boolean PHP expression which will be valuted through eval().<br />
* In the expression you can refer to the field X of every record with {{{X}}}. For example "{{{status}}}=='active'"
*
* <br /><br />ITALIAN:<br /> espressione booleana PHP che sarà valutata tramite eval(). <br />
* Nell'espressione ci si può riferire al campo X di ogni record con {{{X}}}. Ad esempio "{{{status}}}=='active'"
* This parameter is for example of type: 'class="foo" style="color:#F00"'
*
* @param string string containing the definition of the cells tag (their attributes) which containing
* data of the element founded to be highlighted in the table of data general visualization
*
* <br /><br />ITALIAN:<br /> stringa contenente la definizione dei tag delle celle (i loro attributi) che contengono
* i dati dell'elemento rilevato come da evidenziare nella tabella di visualizzazione genrale.
* Questo paramentro è ad esempio del tipo: 'class="foo" style="color:#F00"'
*/
function setHighlighting($condition,$TDAttributes) { $this->highlighting[]=array('condition'=>$condition,'TDAttributes'=>$TDAttributes); }
/** @param string text of heading for the action of 'record modify' in thye table of data visualization
* <br /><br />ITALIAN:<br /> testo di intestazione per l'azione di 'modifica record' nella tabella di visualizzazione dei dati */
function setEditColHeading($heading) {$this->lang['edit']=$heading;}
/** @param string text of heading for the action of 'delete record' in the table of data visualization
* <br /><br />ITALIAN:<br /> testo di intestazione per l'azione di 'elimina record' nella tabella di visualizzazione dei dati */
function setDeleteColHeading($heading) {$this->lang['delete']=$heading;}
/** @param string text of heading for the action of 'print visualization' in the table of data visualization
* <br /><br />ITALIAN:<br /> testo di intestazione per l'azione di 'visualizzazione per la stampa' nella tabella di visualizzazione dei dati */
function setPrintColHeading($heading) {$this->lang['print']=$heading;}
/** @param string text of heading for the action of 'record insertion'
* <br /><br />ITALIAN:<br /> testo di intestazione per l'azione di 'insermento record */
function setInsertNewHeading($heading) {$this->lang['insertNew']=$heading;}
/** @param string text of heading for the box of data research
* <br /><br />ITALIAN:<br /> testo di intestazione per il box di ricerca dati */
function setSearchHeading($searchHeading) {$this->lang['searchOn']=$searchHeading;}
/** @param string entry text shown when the research doesn't get results
* <br /><br />ITALIAN:<br /> testo sentinella mostrato quando la ricerca non produce risultati */
function setNoResultString($str) {$this->lang['noResults']=$str;}
/** Sets up the heading keys of modification/elimination multiple of records in the table of data visualization
* <br /><br />ITALIAN:<br /> Imposta le 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;
}
/** @param string text of heading for the action of selection in the table of data visualization
* <br /><br />ITALIAN:<br /> testo di intestazione per l'azione di selezione nella tabella di visualizzazione dei dati */
function setActionColumnHeader($str) {$this->lang['actionColumnHeader']=$str;}
/** Sets up the break of selectionable dates in the form of insertion/modification for the fields defined DATE in the table of database
* <br /><br />ITALIAN:<br /> Imposta l'intervallo di date selezionabili nel form di inserimento/modifica per i campi definiti DATE nella tabella del database
*
* @param int The lowest date which you want to make available <br /><br />ITALIAN:<br /> La data più bassa che si vuole rendere disponibile
* @param int The higher date you want to make available <br /><br />ITALIAN:<br /> 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;
}
/** Sets up the two dimension in lenght percentual of the form of record insertion/modification .<br />
* The sum of the two values must be 100(%)
*
* <br /><br />ITALIAN:<br />
* Imposta le 2 dimensioni in percentuale di larghezza del form di inserimento/modifica record.<br />
* La somma dei due valori deve essere 100(%)
*
* @param int
* @param int */
function setFormWidth($w1,$w2) {$this->formWidth=array($w1,$w2);}
/** @param string text of the 'submit' key present in the formof insertion/modification
<br /><br />ITALIAN:<br /> testo del tasto di 'submit' presente nei form di inserimento/modifica */
function setConfirmFormMsg($m)
{
if ($m!="")
{
$this->lang['confirmData']=addslashes(str_replace(array("\r","\n")," ",$m)); //eliminate the return back from the beginning <br /><br />ITALIAN:<br /> elimina ritorni a capo
}
}
/** @param string alert message of confirmation for a record elimination
* <br /><br />ITALIAN:<br /> 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)); //eliminate the return back from the beginning <br /><br />ITALIAN:<br /> elimina ritorni a capo
}
}
/** Used to obtain a string which describes the actual state of the class
* This can be useful to make printing actions or other ones in regard to the actual state of the class
* For example <code> if ($OBJ->status=='inserting') echo 'inserting user message';</code>
*
* <br /><br />ITALIAN:<br />
* Serve ad ottenere una stringa che descrive lo stato attuale della classe.<br />
* Questo può essere utile per poter effettuare azioni di stampa o altro rispetto allo stato attuale della classe.<br />
* Ad esempio <code> if ($OBJ->status=='inserting') echo 'inserting user message';</code>
*
* @return string String containing one of these values: inserting, editing, deleting, editingMany, viewing
* <br /><br />ITALIAN:<br /> 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 unused <br /><br />ITALIAN:<br /> 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';
}
/** @param string name of the field set up as a password.<br />
* The field will be published with two fields during the insertion phase (password repeat password)
* and 3 fields during the modification phase (old password, new password, repeat new password). <br />
* Besides all this data will be memorized usig the MD5 coding.
*
* <br /><br />ITALIAN:<br />
* nome del campo impostato come una password.<br />
* Il campo 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).<br />
* Inoltre questi dati saranno memorizzati usando la codifica MD5.
*
*/
function setPasswordField($field) {$this->passwordField[$field]="yes";}
/** @param boolean means if in the visualization table must be visualized all records without paging
* <br /><br />ITALIAN:<br /> indica se nella tabella di visualizzazione devono essere visualizzati TUTTI i record senza paginazione */
function showAllElements($all=true) {$this->showAll=$all;}
/** @param string heading of the insert/modification form <br /><br />ITALIAN:<br /> intestazione del form di inserimento/modifica
* @param string text of the link on the way back to the table of general data visualization <br /><br />ITALIAN:<br /> testo del link di ritorno alla tabella di visualizzazione generale dei dati */
function setFormHeading($heading,$backLink="")
{
$this->formHeading=$heading;
$this->lang['backToData']=$backLink==""?$this->lang['backToData']:$backLink;
}
/** sets up a linked and/or recursive deletion for records.<br /><br />
* His effect can be equivalent to the integrity constraint ON DELETE CASCADE but this method will also delete files, stored in the server,
* wich are related to the deleted records.
*
* <br /><br />ITALIAN:<br />
* Imposta la cancellazione linkata e/o ricorsiva dei record.<br /><br />
* Il suo effetto può essere ecquivalente al vincolo di integrità referenziale ON DELETE CASCADE ma questo metodo eliminerà anche i file, memorizzati
* sul server, che sono collegati ai record eliminati.
*
* @param string name of the field with which is considered the autojoin of the main table on itself.
* <br /><br />ITALIAN:<br />nome del campo con cui si considera l'autojoin della tabella principale su se stessa.
*
* @param DBNavigator DBNavigator object where is a join between its own main table
* and the main table of DBNavigator on which is recalled this method.
* For join is meant a join in the costruction query.
* <br /><br />ITALIAN:<br /> oggetto DBNavigator in cui c'è un join tra la propria tabella principale.
* e la tabella principale del DBNavigator su cui si richiama questo metodo.
* Per join si intende un join nelle query di costruzione.
*
* @param string warning message to be visualized when you want to eliminate a record that will cause
* the cancellation of other records because of the application of this method.
* <br /><br />ITALIAN:<br />messaggio di avvertimento da visualizzare quando si vuole eliminare un record che provocherà
* la cancellazione di altri record a causa dell'applicazione di questo metodo.
*/
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);
}
/** @param string name of the field that won't be published in the form of insertion/modification
* <br /><br />ITALIAN:<br /> nome del campo che non potrà essere editato nel form di inserimento/modifica.
* @see removeDisplaying() */
function removeInput($inputName){$this->removeInput[$inputName]="yes";}
/**
* Sets up the fields of the table which musn't be shown in the general data visualization specifying the names.<br />
* This method accepts a VARIABLE NUMBER OF ARGUMENTS.
*
* <br /><br />ITALIAN:<br />
* Imposta i campi della tabella che non devono essere mostrati nella visualizzazione generale dei dati specificandone i nomi.<br />
* Questo metodo accetta un NUMERO VARIABILE DI ARGOMENTI.
*/
function removeDisplaying()
{
$arg=func_get_args();
foreach ($arg as $val)
if (is_string($val))
$this->removeDisplaying[$val]="yes";
}
/** @param string name of the field that won't be published in the form multiple modification
* <br /><br />ITALIAN:<br /> nome del campo che non potrà essere editato nel form di modifica multipla. .*/
function removeMultipleEditingInput($inputName){$this->removeMultipleEditingInput[$inputName]="yes";}
/**
* Set up fields to be search fields, giving their names.<br /><br />
*
* The first parameter is a string like "tablename.fieldname" while the second (optional or to be left blank)
* is a string that specifies the name to be visualized in the search form of search fot that field.
* If indicated without the name of the table, the field will be considered relative to an aggregation sql like COUNT(*) AS fieldname
* and in researches will be insert between HAVING clauses.<br /><br/>
*
* This method accept a VARIABLE NUMBER OF ARGUMENTS: the two topics can be repeated in pair
* setSearchField(F1a,F1b,F2a,F2b,F3a,....)
*
* <br /><br />ITALIAN:<br />
* Imposta i campi come campi di ricerca specificandone i nomi.<br /><br />
*
* Il primo parametro è una stringa del tipo "nometabella.nomecampo" mentre il secondo (opzionale o da lasciare vuoto)
* è una stringa che specifica il nome da visualizzare nel form di ricerca per tale campo il campo.
* Se indicato 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.<br /><br />
*
* Questo metodo accetta un NUMERO VARIABILE DI ARGOMENTI: i due argomenti possono essere ripetuti a coppie
* setSearchField(F1a,F1b,F2a,F2b,F3a,....)
*
*/
function setSearchField()
{
$func_args=func_get_args();
$i=$j=0;
$bool=true;
foreach ($func_args as $key=>$val) //costruisco l'array con i parametri della funzione
{
switch ($j)
{
case 0: $arg[$i]['fullField']=$val; break;
case 1: $arg[$i]['alias']=$val; break;
case 2: $arg[$i]['domainType']=$val; break;
case 3: $arg[$i]['domainValue']=$val; break;
}
$j++;
if ($j==4)
{
$i++; //indice dell'array di memorizzazione
$j=0; //indice della scansione dei 4 settaggi
}
}
foreach ($arg as $key=>$val)
{
$exp=explode(".",$val['fullField']);
if (count($exp)==1)//clause su funzioni di aggregazione sql come COUNT(*), CONCAT(....
{
$arg[$key]['field']=$exp[0];
$arg[$key]['table']="Having";
}else
{
$arg[$key]['table']=$exp[0]; //viene cambiato se presente alias
$arg[$key]['field']=$exp[1];
}
$arg[$key]['table_alias']=$arg[$key]['table'];
if (isset($val['alias']) && $val['alias']!="") $arg[$key]['field_alias']=$val['alias'];
else
//if (is_int(strpos($this->query," ".$fullField." AS "))) //CERCA l'[ALIAS DEL CAMPO] !!!!
if (preg_match("/ {$val['fullField']} AS( |\\n|\\r|\\r\\n)/",$this->query,$pattern)!=false)
{
//$exp=explode(" ".$fullField." AS ",$this->query);
$exp=explode($pattern[0],$this->query);
$exp2=preg_split("/(,| ){1}/",$exp[1]);
$arg[$key]['field_alias']=$exp2[0];
}
else $arg[$key]['field_alias'] = $arg[$key]['field'];
if (strpos($this->query," AS ".$arg[$key]['table']." ")!=false) //CERCA l'[ALIAS DELLA TABELLA] per modificare eventualmente table_alias!!!!
{
$exp=explode(" AS ".$arg[$key]['table']." ",$this->query);
$exp2=explode(" ",$exp[0]);
$arg[$key]['table']=$exp2[count($exp2)-1];
} //////////////////////////////////////////////////////////////////////////////////
}
/*/////////////////////N O T E////////////////////////////////////////////////////////////
Il formato di $fullField 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)
{
$field=$arg[0]['field'];
$field_alias=$arg[0]['field_alias'];
$table=$arg[0]['table'];
$table_alias=$arg[0]['table_alias'];
$fullField=$arg[0]['fullField'];
$domainType=$arg[0]['domainType'];
$domainValue=$arg[0]['domainValue'];
}
else
for ($i=0; $i < count($arg) ; $i++)
{
$field[]=$arg[$i]['field'];
$field_alias[]=$arg[$i]['field_alias'];
$table[]=$arg[$i]['table'];
$table_alias[]=$arg[$i]['table_alias'];
$fullField[]=$arg[$i]['fullField'];
$domainType[]=$arg[$i]['domainType'];
$domainValue[]=$arg[$i]['domainValue'];
}
$this->searchField[]=array('field'=>$field,'field_alias'=>$field_alias,'table'=>$table,'table_alias'=>$table_alias,'fullField'=>$fullField,
'domainType'=>$domainType,'domainValue'=>$domainValue);
}
/** Removes all fields set up like researching fields
* <br /><br />ITALIAN:<br /> Rimuove tutti i campi impostati come campi di ricerca */
function clearSearchFields() {$this->searchField=array();}
/** @param mixed String or string array where ther're no HTML entities
* <br /><br />ITALIAN:<br /> Stringa o array di stringhe in cui non ci sono entità HTML
* @return mixed the initial value with which the appropariate characters are replaced with HTML entities ('&' , '>' e '<')
* <br /><br />ITALIAN:<br /> Il valore iniziale in cui i caratteri appropriati vengono sostituiti da entità HTML ('&' , '>' e '<') */
private function convertSpecialChars($value)
{
if (is_array($value))
foreach($value as $key=>$val)
{
$value[$key]=str_replace("&","&",$value[$key]);
$value[$key]=str_replace(">",">" ,$value[$key]);
$value[$key]=str_replace("<","<" ,$value[$key]);
}
else
{
$value=str_replace("&","&",$value);
$value=str_replace(">",">" ,$value);
$value=str_replace("<","<" ,$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.
*
* <br /><br />ITALIAN:<br />
* Adds a column named $colName at data general visualization table.
* That column will have as icon $image and will link at the current page if not specified the parameter $page.
*
* @param string intestazione della colonna <br /><br />ITALIAN:<br /> heading of the column
* @param string name of the GET parameter to which will be assigned the id of each record
* <br /><br />ITALIAN:<br /> nome del parametro GET a cui sarà assegnato l'id di ogni record
* @param string path of the icon image <br /><br />ITALIAN:<br />percorso dell'immagine icona
* @param boolean indicates if the linked page will have to keep the sunbjects GET of the page
* <br /><br />ITALIAN:<br /> indica se la pagina linkata dovrà mantenere gli argomenti GET della pagina.
* @param boolean indicates if the linking page will have to open up in a new window.
* <br /><br />ITALIAN:<br /> indica se la pagina linkata dovrà aprirsi in una nuova finestra.
* @param mixed string that indicates the linking page. false value indicates the current page
* <br /><br />ITALIAN:<br /> stringa indicante la pagina linkata. il valore false indica la pagina corrente
* @param string contains a booleana expression PHP that will be evalueted as condition of the visualization link. Works as {@link setHighlighting()}
* <br /><br />ITALIAN:<br />
* contiene un'espressione booleana PHP che sarà valutata come condizione di visualizzazione del link. Funziona come {@link setHighlighting()}
* @param array contains all field names of the selection SQL where to apply the link in the visualization table.
* <br /><br />ITALIAN:<br /> 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);
}
/**
* Adds a column named $colName at data general visualization table.
* The column corresponds to an attribute in two possible values and the interface will contain the link that will allow to change the value
* The link will be active on the image that is shown and that corresponds to the current value of the attribute
*
* <br /><br />ITALIAN:<br />
* Aggiunge una colonna nominata $colName alla tabella della visualizzazione generale dei dati.
* La colonna corrisponde ad un attributo a due possibili valori e l'interfaccia conterrà un link che permetterà di cambiarne il valore.
* Il link sarà attivo sull'immagine che viene mostrata e che corrisponde al valore corrente dell'attributo
*
* @param string name of the field of two values <br /><br />ITALIAN:<br /> nome del campo a due valori
* @param string path of the image corresponding to the first value of the attribute
* <br /><br />ITALIAN:<br /> path dell'immagine corrispondente al primo valore dell'attributo
* @param string path of the image corresponding to the second value of the attribute
* <br /><br />ITALIAN:<br /> path dell'immagine corrispondente al secondo valore dell'attributo
*/
function addSwitchCol($colName,$image1,$image2)
{
$this->switchCol[$colName]=array('image1'=>$image1,'image2'=>$image2);
}
/**
* Avoids to show the contents of the field $field in the general visualization table.<br />
* At the place of the contents, is shown a state flage that is an image which simply indicates if the field
* is empty or not.
* The application in fields set up like images causes the not visualization of the preview.
*
* <br /><br />ITALIAN:<br />
* Evita di mostrare il contenuto del campo $field nella tabella di visualizzazione generale.<br />
* Al posto del contenuto, viene mostrato un indicatore di stato ovvero una immagine che segnala semplicemente se il campo
* è vuoto oppure no.
* L'Applicazione a campi impostati come immagini ne causa la non visualizzazione della preview.
*
* @param string the path containing the image that indicates on the field there's an image (the field is full)
* <br /><br />ITALIAN:<br /> il path contenente l'immagine che indica che sul campo è presente una immagine (il campo è pieno)
* @param string the path containing the image that indicates on the field there's not an image (the field is empty)
* <br /><br />ITALIAN:<br /> il path contenente l'immagine che indica che sul campo non è presente una immagine (il campo è vuoto)
*/
function setFieldStatusIndicator($field,$on,$off)
{
$this->imageIcon[$field]=array('on'=>$on,'off'=>$off);
}
/**
* Adds a column named $colName at the data general visualization table.
* That column will have as contents the HTML contained in the parameter $content in which you'll can refer to the current id
* with the string '%current_row_id%'.
*
* <br /><br />ITALIAN:<br />
* 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 heading of the column <br /><br />ITALIAN:<br /> intestazione della colonna
* @param string HTML code (with eventual Javascript) of each cell. %current_row_id% is replaced with the id of each record
* <br /><br />ITALIAN:<br />codice 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);
}
/**
* Adds a column named $colName at the data general visualization table.
* That column will contain the data got executing the query $query where will have to be present the string '%current_row_id%'
* indicating the id of the current record.
* That query could be the type defined as $type. Available types are:<br /><br />
*
* - LINKED_RECORDS simply performs the query which will tipically apply the join with other
* tables, unically visualizing the first selected field for each resulting string (lines separated by a back return)<br /><br />
*
* - RECURSIVE will execute the query in the resorting way through the method {@link query_ricorsiva()} counting the number
* of record resortively selected and visualizing that numeric value in the column.<br />
* This type of query is tipically used to count elements memorized in tree structures.<br /><br />
*
* - CALCULATION asks that the subject query is an array. <br />
* In particular each element of that array will have to be an array of two elements with key 'operand' and 'query'.
* operand is a string of a character containing a mathematic operator of PHP (+,-,*,/),
*query is the query that will have to have a numeric field as first field (also here %current_row_id% will be replaced with the current id).
* The class will find the way to execute all the query contained in the array and to link together with their own operand operator. Visualizing the final result
* Notice: you can obtain the same result applying sub-queries (subqueries) to the select of initail query.
*
*
* <br /><br />ITALIAN:<br />
*
* Aggiunge una colonna nominata $colName alla tabella della visualizzazione generale dei dati.
* Tale colonna conterrà 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:<br /><br />
*
* - LINKED_RECORDS esegue 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)<br /><br />
*
* - RECURSIVE eseguira la query in modo ricorsivo tramite il metodo {@link query_ricorsiva()} contando il numero
* di record ricorsivamente selezionati e visualizzando tale valore numerico nella colonna.<br />
* Questo tipo di query è tipicamente usato per contare elementi memorizzati in strutture ad albero.<br /><br />
*
* - CALCULATION richiede che l'argomento query sia un array. <br />
* 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 heading of the column <br /><br />ITALIAN:<br /> intestazione della colonna
* @param string query containing the string %current_row_id% which is replaced with the id of each record
* <br /><br />ITALIAN:<br /> query contenente la stringa %current_row_id% che viene sostituita dall'id di ogni record
* @param string query type <br /><br />ITALIAN:<br /> tipo della query
*/
function addDataCol($colName,$query,$type)
{
$this->dataCol[]=array('colName'=>$colName,'query'=>$query,'type'=>strtoupper($type));
}
/** @param boolean Enables/closes down the possibility of multiple modifications/eliminations and contemporary modifications.<br />
* That set is effectively relevant if the modification and elimination is enabled trough {@link canEdit()} e {@link canDelete()}
* <br /><br />ITALIAN:<br />
* Abilita/disabilita la possibilità di modifiche/eliminazioni multiple e modifiche contemporanee.<br />
* Tale impostazione ha effettivamente rilevanza se è abilitata la modificazione ed eliminazione tramite {@link canEdit()} e {@link canDelete()}
*/
function canMultipleEditDelete($apply){$this->canMultipleEditDelete=$apply;}
/** @param int number of the maximum characters to be visualized for each field in the general visualization table
* <br /><br />ITALIAN:<br /> numero di caratteri massimi da visualizzare per ogni campo nella tabella di visualizzazione generale */
function setTextCutLength($cutLength=150){$this->cutLength=$cutLength;}
/** @param boolean indicates if the record visualization must happen even without any research. Default is true.
* <br /><br />ITALIAN:<br /> indica se la visualizzazione dei record deve avvenire anche senza effettuare alcuna ricerca. Di default è true
*/
function setViewResultWithoutSearch($bool){$this->viewResults=$bool;}
/** @param boolean indicates if visualize all the possible options in the input SELECT of the researching form
* independently from the presence of the record database with those values or without
* <br /><br />ITALIAN:<br />
* indica se visualizzare tutte le opzioni possibile negli input SELECT dei form di ricerca
* indipendentemente dalla presenza del database di record con quei valori o meno
*/
function setViewAllSearchOptions($bool){$this->viewAllSearchOptions=$bool;}
/** @param string path where you can find all the script and images requires from the class.
* The path is searched automatically in pre-defined runs at the moment of an object installation of the class
* but if files are not in those paths, is necessary to recall this method.
* <br /><br />ITALIAN:<br />
* path in cui si trovano tutti gli script ed immagini richieste dalla classe.
* Il path viene cercato automaticamente in dei percorsi predefiniti al momento dell'instanziazione di un oggetto della classe (nel costruttore)
* ma se i file non si trovano in tali path, è necessario richiamare questo metodo.
*/
function setImagesAndScriptsPath($path){ $this->imagesAndScriptsPath=$path; }
/**
* Sets up the maximum number of radio options that can have a fixed choice field as first paramenter, and
* the maximum number of radio options that can have in just one line, as second.
* A field which has a number of elements greater than the fisrt parameter, will be published with a select input (instead of radio).
* A field which has a number of elements greater than the second parameter, will be visualized with a radio option for each line.
*
* <br /><br />ITALIAN:<br />
* 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 maximum number of options that can have a fixed choice field
* <br /><br />ITALIAN:<br /> numero massimo di opzioni che può avere un campo a scelta fissa
* @param int maximum number of options that can have an input radio in just one line
* <br /><br />ITALIAN:<br /> 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;
}
/**
* Sets up the maximum number of checkbox for a multiple choice field (SET) as a first parameter, and
* the dimension (number of elements) that will have the multiple choice select if the number of elements of the field exceeds
* the first parameter.
*
* <br /><br />ITALIAN:<br />
* 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 maximum number of checkbox that can have a multiple choice field
* <br /><br />ITALIAN:<br /> numero massimo di checkbox che può avere un campo a scelta multipla
* @param int dimension (number of elements) that will have the multiple choice select which replaces the checkbox in the case of excess
* <br /><br />ITALIAN:<br /> 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;
}
/**
* Accepts a query of construction of the object that must contain all necessary join with which will make the following elaborations.
* Besides creates a table called 'busy_records' which serves
* to manage the conflicts of mutual exclusion in the simultaneous record modifications. <br />
* That table is used for all instances DBNavigator.
*
* On edit mode, if the query have some join, an input will be added to associate one of the external table records.
* The <b>first field</b> of the external table in the construction query will be displayied in the form for the
* the selection of one external record.
*
* <br /><br />ITALIAN:<br />
* Accetta una query di costruzione dell'oggetto che deve comprendere tutti i join necessari con cui si faranno le successive elaborazioni. <br />
* Inoltre crea una tabella chiamata 'busy_records' che serve
* a gestire i conflitti di mutua esclusione sulle modifiche simultanee ai record. <br />
* Tale tabella è usata per tutte le istanze di DBNavigator.
*
* In modalità di modifica, se la query di costruzione presenta dei join, verrà inserito in input che permetta di associare uno dei record
* della tabella esterna. Il campo visualizzato nel form per la selezione di quest'ultimo sarà <b>il primo campo</b> della tabella esterna
* presente nella query di costruzione.
*
* @param string Main query.<br />
* WARNING, is assumed that the main query contains ALL the key words SQL
* in capital (SELECT,FROM,WHERE,HAVING,AS...) while in the internal subqueries (subqueries), if present,
* the key words must be all small letters. <br />
* besides is assumed that the query doesn't contain the clause ORDER BY,
* the regulation field must be set up trough the apposite method {@link setDefaultOrd()}
*
* <br /><br />ITALIAN:<br />
* query principale.<br />
* ATTENZIONE, si assume che la query principale contenga TUTTE le parole chiave SQL
* in maiuscolo (SELECT,FROM,WHERE,HAVING,AS...) mentre 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 {@link 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('webedit/classes/DBNavigator.js'))
$this->imagesAndScriptsPath='webedit/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->PP=new HTMLPostProcessor();
$this->ajaxCall=false;
}
/** @param string name of a database table to be considered as the main between the present ones in the construction query of the object
* <br /><br />ITALIAN:<br /> nome di una tabella del database da considerarsi come principale tra quelle presenti nella
* query di costruzione dell'oggetto */
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;
//***********ESECUZIONE SWITCH PRECEDENTI*******************
if (isset($_GET["switch_field_{$this->originalPrimaryTable}"]))
{
/* die("UPDATE {$this->originalPrimaryTable}
SET ".$_GET["switch_field_{$this->originalPrimaryTable}"]."=".$_GET["switch_value_{$this->originalPrimaryTable}"]."
WHERE id=".$_GET["switch_id_{$this->originalPrimaryTable}"]);*/
mysql_query("UPDATE {$this->originalPrimaryTable}
SET ".$_GET["switch_field_{$this->originalPrimaryTable}"]."=".$_GET["switch_value_{$this->originalPrimaryTable}"]."
WHERE id=".$_GET["switch_id_{$this->originalPrimaryTable}"]) or die(mysql_error());
unset($_GET["switch_id_{$this->originalPrimaryTable}"]);
unset($_GET["switch_field_{$this->originalPrimaryTable}"]);
unset($_GET["switch_value_{$this->originalPrimaryTable}"]);
}
$result=mysql_query("SHOW FULL FIELDS FROM ".$this->originalPrimaryTable);
while($row=mysql_fetch_array($result))
{
switch($row['Comment'])
{
case 'mail': $this->setMailField($row['Field']); break;
case 'numericString': $this->setNumericStringField($row['Field']); break;
case 'file': $this->setFileField($row['Field']); break; //non usato qui xkè c'è il campo nella tab di configurazione
//case 'photo': $DBN->setFileField($row['Field']); break;
case 'DATE_MY': $this->setMonthYearField($row['Field']); break;
}
}
}
/**
* Method which serves exclusively for the AJAX script of background that questions the database to have a list of suggestions
* in the form textbox of research and in the one of contemporaneus modification in more records
*
* <br /><br />ITALIAN:<br />
* Metodo che serve esclusivamente 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
*/
private 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));
}
/** @param string contents of the clause ORDER BY to be added at the main query to order data
* <br /><br />ITALIAN:<br /> contenuto della clausola ORDER BY da aggiungere alla query principale per ordinare i dati */
function setDefaultOrd($defaultOrd) {$this->orderInfo['defaultOrd']=$defaultOrd;} //NECESSARIA
/** @param string generic name with which to refer to record.<br /> Example: insert new BOOK, modify BOOK.
* <br /><br />ITALIAN:<br /> nome generico con cui ci si riferisce ai record.<br />Esempio: Inserisci nuovo LIBRO, Modifica LIBRO.
*/
function setRowName($rowName) //NECESSARIA
{
$this->rowName=$rowName;
}
/** @param boolean indicates if to show or not the primary key of the main table in the data visualization table.
* <br /><br />ITALIAN:<br /> Indica se mostrare o meno la chiave primaria della tabella principale nella tabella di visualizzazione dei dati.
*/
function hidePrimaryKey($boolean) {$this->hidePrimaryKey=$boolean;}
/** @param string name of the field of the main table considered as containing an email address. <br />
* In the modification/insertion form will be apply a validation that verifies the right format of the typed values.
*
* <br /><br />ITALIAN:<br />
* nome del campo della tabella principale considerato come contenente un indirizzo email. <br />
* Nei form di modifica/inserimento verrà applicata una validazione che verifica il formato corretto dei valori digitati.
*/
function setMailField($field) {$this->mailField[$field]="yes";}
/** @param string name of the field in the main table considered as containing an information month-year.<br />
* In the modification/insertion form will be created an interface that will allow to insert month and year trough selection cells.<br />
* The indicated field must be like type DATE and the information on the day will be ignored.
* <br /><br />ITALIAN:<br />
* nome del campo della tabella principale considerato come contenente un'informazione mese-anno. <br />
* Nei form di modifica/inserimento verrà creata una interfaccia che permetta di inserire mese ed anno tramite caselle di selezione.<br />
* Il campo indicato deve essere di tipo DATE e l'informazione sul giorno verrà ignorata.
*/
function setMonthYearField($field) {$this->monthYearField[$field]="yes";}
/** @param string name of the field of the main table considered as containing numeric strings
* In the modification/insertion form will be apply then a validation that will allow to type just numbers
* <br /><br />ITALIAN:<br />
* nome del campo della tabella principale considerato come contenente stringhe numeriche.
* Nei form di modifica/inserimento verrà quindi applicata una validazione che consente la digitazione di soli numeri.
*/
function setNumericStringField($field) {$this->numericStringField[$field]="yes";}
/** @param mixed names of a field or an array of field names of tables where are memorized images names present in the filesystem of the server.<br />
* In the modification/insertion form will be build an appropriate interface ( FILE input + image preview). <br />
* The validation will allow the insertion of file of image type for the web ( GIF, JPEG, PNG ).
* <br /><br />ITALIAN:<br />
* nome di un campo o array di nomi di campo di tabelle in cui sono memorizzati nomi di immagini, presenti nel filesystem del server.<br />
* Nei form di modifica/inserimento verrà costruita l'interfaccia appropriata ( FILE input + image preview). <br />
* La validazione consentirà l'inserimento di file di tipo immagine per il web ( GIF, JPEG, PNG ).
*
*
* @param mixed the value false indicates that the image will not be reduced. <br />
* A numeric value indicates the size in pixel for which will happen the reduction.
* <br /><br />ITALIAN:<br />
* il valore false indica che l'immagine non verrà ridimensionata. <br />
* Un valore numerico indica la dimensione in pixel per cui avverrà il redimensionamento.
*
* @param boolean Indicates if the original image sent must be saved <br /><br />ITALIAN:<br /> Indica se l'immagine originale inviata deve essere salvata.
*
* @see setFileNameCriteria()
*/
function setImageField($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;
$this->PP->setResizeImageDimension($this->photoField['_Resize_']);
$this->PP->keepOriginalImages($this->photoField['_KeepOriginal_']);
}
/** @see setImageField
* @deprecated */
function setPhotoField($field,$resizeImg=false,$keepOriginal=false) { $this->setImageField($field,$resizeImg,$keepOriginal); }
/** @param mixed name of a field or array of field names in tables where are memorized file names, present in the filesystem of the server.<br />
* In the modification/insertion form will be build the appropriate interface ( FILE input ). <br />
* <br /><br />ITALIAN:<br />
* nome di un campo o array di nomi di campo di tabelle in cui sono memorizzati nomi di file, presenti nel filesystem del server.<br />
* Nei form di modifica/inserimento verrà costruita l'interfaccia appropriata ( FILE input ). <br />
*
* @see setFileNameCriteria()
*/
function setFileField($field)
{
if (is_array($field))
foreach ($field as $f)
$this->fileField[$f]=false;
else
$this->fileField[$field]=false;
}
/**
* Use this function is right just if there are specified the fields that refer to the files
* trough the functions {@link setFileField()} and {@link setImageField()}
*
* <br /><br />ITALIAN:<br />
* Usare questa funzione ha senso solo se si sono specificati i campi che si riferiscono ai file
* tramite le funzioni {@link setFileField()} e {@link setImageField()}
*
* @param string the saving path of all files managed by theinside of the filesystem of the server.
* <br /><br />ITALIAN:<br />
* il path di salvataggio di tutti i file gestiti all'interno del filesystem del server.
*
*
* @see setFileNameCriteria()
*/
function setFilePath($path)
{
$this->filePath=$path;
$this->PP->setFileSavePath($path);
}
/** @param string A symbolic string that represent the format to be used for file names while saving them into the server. Symbols are:<br />
* <b>*tb*</b> Main table name.<br />
* <b>*pk*</b> Primary key name in the main table.<br />
* <b>*cn*</b> Name of the field binded to the file to save.<br />
* <b>*fn*</b> Name of the original uploaded file.<br />
* <b>*ext*</b> Extension of the original uploaded file.<br /><br />
*
* Default is <b>*tb*_*pk*_*cn*.*ext*</b> which allow to upload as many file as you want without name conflicts.<br />
* Alternatively, to hold the original file name, use <b>*fn*.*ext*</b>
*
* <br /><br />ITALIAN:<br />
* una stringa simbolica che rappresenta il formato del nome del file da salvare. I simboli sono:<br />
* <b>*tb*</b> nome della tabella principale.<br />
* <b>*pk*</b> nome della chiave primaria nella tabella principale.<br />
* <b>*cn*</b> nome della campo della tabella principale associato al file da salvare.<br />
* <b>*fn*</b> nome del file originale.<br />
* <b>*ext*</b> estensione del file originale.<br /><br />
*
* L'impostazione di default è <b>*tb*_*pk*_*cn*.*ext*</b> in modo che non possano
* mai avvenire conflitti sui nomi dei file.<br />
* Alternativamente, per mantenere l'esatto nome originale del file, usare <b>*fn*.*ext*</b>
*
* @see setFileField(), setImageField(),setFilePath() */
function setFileNameCriteria($path)
{
$this->PP->setFileNameCriteria($path);
}
/** @param string name of the CSS class to apply to the heading lines (tag TR) of the data visualization table
* <br /><br />ITALIAN:<br /> nome della classe CSS da applicare alle righe (tag TR) di intestazione della tabella di visualizzazione dei dati
* @param string name of the CSS class to apply to the internal lines in the data visualization table
* <br /><br />ITALIAN:<br /> nome della classe CSS da applicare alle righe interne della tabella di visualizzazione dei dati */
function setTableRowStyle($val1,$val2)
{
$this->tableHeaderCSS=$val1;
$this->tableRowContentCSS=$val2;
}
/** @param int the 'cellspacing' of the data visualization table <br /><br />ITALIAN:<br /> il 'cellspacing' della tabella di visualizzazione dei dati */
function setTableCellSpacing($CS) {$this->tableCS=$CS;}
/** @param int the 'cellpadding' of the data visualization table <br /><br />ITALIAN:<br /> il 'cellpadding' della tabella di visualizzazione dei dati */
function setTableCellPadding($CS) {$this->tableCP=$CS;}
/** @param string name of the class CSS to apply to intern cells (tag TD) of the data visualization table
* <br /><br />ITALIAN:<br />
* nome della classe CSS da applicare alle celle interne (tag TD) della tabella di visualizzazione dei dati
* @param string name of the class CSS to apply to cells (tag TD) of the table which contains the buttons related to actions on each line
* <br /><br />ITALIAN:<br />
* nome della classe CSS da applicare alle celle (tag TD) della tabella che contengono i pulsanti relativi alle azioni su ogni riga
* @param string name of the class CSS to apply to heading cells (tag TD) of the data visualization table
* <br /><br />ITALIAN:<br />
* nome della classe CSS da applicare alle celle di intestazione (tag TD) della tabella di visualizzazione dei dati
* @param string name of the class CSS to apply to links which are added inside the table, through the method {@link addLinkCol()}
* <br /><br />ITALIAN:<br />
* nome della classe CSS da applicare ai link, che vengono aggiunti all'interno della tabella, tramite il metodo {@link addLinkCol()}
*/
function setTableCellStyle($TD,$editDeleteTD,$headerTD,$fieldLink="")
{
if ($TD) {$this->style['TD']=$TD; $this->classTag['TD']=" class=\"".$TD."\"";}
if ($editDeleteTD) {$this->style['editDeleteTD']=$editDeleteTD; $this->classTag['editDeleteTD']=" class=\"".$editDeleteTD."\"";}
if ($headerTD) {$this->style['headerTD']=$headerTD; $this->classTag['headerTD']=" class=\"".$headerTD."\"";}
if ($fieldLink) {$this->style['fieldLink']=$fieldLink; $this->classTag['fieldLink']=" class=\"".$fieldLink."\"";}
}
/** @see setTableCellStyle()
* @deprecated */
function setTableStyle($TD,$editDeleteTD,$headerTD,$fieldLink="") { $this->setTableCellStyle($TD,$editDeleteTD,$headerTD,$fieldLink=""); }
/** @param string name of the class CSS to apply to input of the form (tag INPUT).
* <br /><br />ITALIAN:<br /> nome della classe CSS da applicare agli input dei form (tag INPUT).
* @param string name of the class CSS to apply to form buttons.
* <br /><br />ITALIAN:<br /> nome della classe CSS da applicare ai pulsanti dei form.
* @param string name of the class CSS to apply to the simple textarea of the form
* <br /><br />ITALIAN:<br /> nome della classe CSS da applicare alle textarea semplici dei form (tag TEXTAREA).*/
function setClassForFormInput($forInputs,$forButtons="",$forTareas="")
{
$this->classForFormInput['inputs']=$forInputs;
if ($forButtons) $this->classForFormInput['buttons']=$forButtons;
if ($forTareas) $this->classForFormInput['textareas']=$forTareas;
}
/** @param mixed Indicates if is allowed to eliminate record from the table (true/false)
* or you can give an array of numeric id for which is allowed that action.
* <br /><br />ITALIAN:<br />
* Indica se e' consentito eliminare record dalla tabella (true/false)
* oppure si può fornire un array di id numerici per i quali è consentita tale azione.
*
* @see canEditDelete(),canEdit(),canInsert() */
function canDelete($boolean_or_id_array){$this->canDelete=$boolean_or_id_array;}
/** @param mixed Indicates if is allowed to modify record from the table (true/false)
* or you can give an array of numeric id for which is allowed that action.
* <br /><br />ITALIAN:<br />
* Indica se e' consentito modificare record dalla tabella (true/false)
* oppure si può fornire un array di id numerici per i quali è consentita tale azione.
*
* @see canEditDelete(),canDelete(),canInsert() */
function canEdit($boolean_or_id_array) {$this->canEdit=$boolean_or_id_array;}
/** @param boolean Indicates if is allowed to insert record from the table (true/false)
* <br /><br />ITALIAN:<br />
* Indica se e' consentito inserire record dalla tabella (true/false)
*
* @see canEditDelete(),canDelete(),canInsert() */
function canInsert($boolean) {$this->canInsert=$boolean;}
/** @param boolean Indicates if is allowed to eliminate and midify record from the table (true/false)
* <br /><br />ITALIAN:<br />
* Indica se e' consentito eliminare e modificare record dalla tabella (true/false)
*
* @see canEditDelete(),canDelete(),canInsert() */
function canEditDelete($boolean){$this->canEdit=$boolean;$this->canDelete=$boolean;}
/** @param boolean Indicates if is allowed the exportation of data in format CSV and XML for Excel/OpenOffice
* <br /><br />ITALIAN:<br />
* Indica se e' consentita l'esportazione dei dati in formato CSV ed XML per Excel/OpenOffice
*/
function canExport($boolean){$this->canExport=$boolean;}
/** @param boolean Indicates if is allowed to singly visualize record of the table for printing
* <br /><br />ITALIAN:<br />
* Indica se e' consentito visualizzare singolarmente i record dalla tabella per la stampa
*
* @see canEditDelete(),canDelete()
*/
function canViewForPrint($boolean) {$this->canViewForPrint=$boolean;}
/** @param string an SQL query<br /><br />ITALIAN:<br />una query SQL
* @param string an SQL boolean <br /><br />ITALIAN:<br />una condizione booleana SQL
* @return string la query originaria con la condizione $cond aggiunta tra le clausola WHERE della query $query
* <br /><br />ITALIAN:<br /> the originary query with the condition $cond added between the clause WHERE of the query $query
*/
static 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;
}
/** @param string an SQL query<br /><br />ITALIAN:<br />una query SQL
* @param string an SQL boolean <br /><br />ITALIAN:<br />una condizione booleana SQL
* @return string la query originaria con la condizione $cond aggiunta tra le clausola HAVING della query $query
* <br /><br />ITALIAN:<br /> the originary query with the condition $cond added between the clause HAVING of the query $query
*/
static 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;
}
/** @param mixed the value true indicates if to insert the default image or is possible to indicate the path of another image
* <br /><br />ITALIAN:<br />
* il valore true indica se inserire l'immagine di default altrimenti è possibile indicare il path di un'altra immagine
* @param mixed the value true indicates if to use the default text as heading or is possible to indicate another text
* <br /><br />ITALIAN:<br />
* il valore true indica se usare il testo di default come intestazione altrimenti è possibile indicare un altro testo
* @return string the HTML code which includes the insertion button of a new element (made by an image and an heading)
* <br /><br />ITALIAN:<br />
* il codice HTML che comprende il tasto di inserimento di un nuovo elemento (costituito da immagine più didascalia)
*/
function printAddRowButton($image=true,$heading=true)
{
//echo $this->status();
if ($this->status()!='viewing' && !$this->useAjax) return false;
if (!$this->canInsert) return false;
if ($image===true) $image=$this->imagesAndScriptsPath."new.gif";
if ($heading===true) $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)."&edit_{$this->originalPrimaryTable}=0#{$this->originalPrimaryTable}_anchor";
return "<a href=\"{$href}\"><img style=\"vertical-align:middle;border:none;\" src=\"".$image."\" alt=\"\" title=\"{$this->lang['insertNew']}\" /> {$heading}</a>";
}
/** @param mixed the value true indicates if to insert the default image or is possible to indicate the path of another image
* <br /><br />ITALIAN:<br />
* il valore true indica se inserire l'immagine di default altrimenti è possibile indicare il path di un'altra immagine
* @param mixed the value true indicates if to use the default text as heading or is possible to indicate another text
* <br /><br />ITALIAN:<br />
* il valore true indica se usare il testo di default come intestazione altrimenti è possibile indicare un altro testo
* @return string the HTML code which includes the exportation button in CSV format (made by an image and an heading)
* <br /><br />ITALIAN:<br />
* il codice HTML che comprende il tasto di esportazione dati in formato CSV (costituito da immagine più didascalia)
*/
function printCsvDownloadButton($image=true,$heading=true)
{
//echo $this->status();
if ($this->status()!='viewing' && !$this->useAjax) return false;
if (!$this->canExport) return false;
if ($image===true) $image=$this->imagesAndScriptsPath."csv.gif";
if ($heading===true) $heading="Download ".str_replace("_"," ",$this->originalPrimaryTable)." CSV";
return "
<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>";
}
/** @param mixed the value true indicates if to insert the default image or is possible to indicate the path of another image
* <br /><br />ITALIAN:<br />
* il valore true indica se inserire l'immagine di default altrimenti è possibile indicare il path di un'altra immagine
* @param mixed the value true indicates if to use the default text as heading or is possible to indicate another text
* <br /><br />ITALIAN:<br />
* il valore true indica se usare il testo di default come intestazione altrimenti è possibile indicare un altro testo
* @return string the HTML code which includes the exportation button in XML format (made by an image and an heading)
* <br /><br />ITALIAN:<br />
* il codice HTML che comprende il tasto di esportazione dati in formato XML (costituito da immagine più didascalia)
*/
function printExcelXmlDownloadButton($image=true,$heading=true)
{
//echo $this->status();
if ($this->status()!='viewing' && !$this->useAjax) return false;
if (!$this->canExport) return false;
if ($image===true) $image=$this->imagesAndScriptsPath."excel_xml.gif";
if ($heading===true) $heading="Download ".str_replace("_"," ",$this->originalPrimaryTable)." XML for Excel/OpenOffice";
return "
<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>";
}
private 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);
}
}
private 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);
}
}
private 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;
}
private 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');
}
private 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); //settaggio preciso di field->type creato DA mysql_fetch_field A query SHOW FIELDS from...
//corrispondenza mysql_f_fields/query : string/enum('x','y') , blob/text-longtext , double/real , string/varchar(xx)
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"
|| substr($row_field['Type'],0,7)=="varchar" )
)
{
$field->type=$row_field['Type'];
break;
}
}
$field->type=str_replace("varchar","string",$field->type); //al posto di varchar(100) si mette string(100);
//echo $field->name." - ".$field->type."<br />";
//////////////////////////////////////////////////////////////////////////
/* 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);
//----------------------------------settaggio dei tipi (domini) dei parametri di ricerca e delle intestazioni
foreach($this->searchField as $key=>$data)
{
if ( (!isset($data['domainType']) || $data['domainType']=='') && !is_array($data['field']) ) //se non indicato manualmente viene rilevato il dominio
{
$domainType='';
$domainValue='';
if ($data['table']==$this->originalPrimaryTable)
{
//metto nell'array associativo i dati dei campi di ogni tabella interessata
if (!isset($tableDesc[$data['table']])) //ogni volta che ne trovo una, la chiave è il nome del campo
{
$result=mysql_query("DESCRIBE {$data['table']}");
while($row=mysql_fetch_array($result))
{
$tableDesc[$data['table']][$row['Field']]=$row;
}
}
if (isset($tableDesc[$data['table']][$data['field']]) )//campo semplice della tabella in questione....
{
$FieldType=$tableDesc[$data['table']][$data['field']]['Type'];
if (strstr($FieldType,"enum") || strstr($FieldType,"set") ) //guarda se è enum
{
$domainType='list';
$domainValue=$this->getEnumSetValue($FieldType);
}
if (strstr($FieldType,"date")) //guarda se è una data
{
$domainType='date';
$domainValue=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']]);
$domainValue[$row[$data['field']]]=$exp[2]."/".$exp[1]."/".$exp[0];
}
}
if ( strstr($FieldType,"bigint") || strstr($FieldType,"int")
|| strstr($FieldType,"float") || strstr($FieldType,"double") ) //guarda se è un numero
{
$domainType='numeric';
$domainValue=false; //non utilizzato..
}
//else .....domainType==''....text!
}
}
else
if ($data['table']!=$this->originalPrimaryTable && $data['table']!="Having") // @------ TABELLA ESTERNA
{
$domainType='list';
$domainValue=array();
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 />");
while ($row=mysql_fetch_array($result))
if ($row[$data['field']]) $domainValue[$row[$data['field']]]=$row[$data['field']];
}
else // x default campi definiti come risultato di funzioni (nella clausola having della query) vengono interfacciate con ricerca numerica
if ($data['table']=="Having")
{
$domainType='numeric';
$domainValue=false; //non utilizzato..
}
// altri casi....credo non ci siano....se non rientra nei casi sopra, l'interfaccia è di testo libero
$this->searchField[$key]['domainType']=$domainType;
$this->searchField[$key]['domainValue']=$domainValue;
}
////////////// solo qui viene cercato e memorizzato il valore (value) assunto da ogni campo di ricerca ///////////////////////
///*************************** settaggio della tipologia del campo di ricerca (1234) usato solo per costruire la query ******************
if (!is_array($data['field'])) //ricerca 'normale'
{
$get_index=$data['table_alias']."_".$data['field']."_src_".$this->originalPrimaryTable;
if (isset($_GET[$get_index]) )
{
if (is_array($_GET[$get_index]))
{
$data['value']=array();
foreach($_GET[$get_index] as $multiple=>$val)
$data['value'][]=trim(stripslashes($val));
$this->searchField[$key]['tipo_ricerca']='1'; //ricerca vincolata (select o radio)
}
else
if ( substr(trim(stripslashes($_GET[$get_index])),0,1)=='"'
&& substr(trim(stripslashes($_GET[$get_index])),strlen(trim(stripslashes($_GET[$get_index])))-1,1)=='"' )
{
$data['value']=trim(stripslashes($_GET[$get_index]));
$this->searchField[$key]['tipo_ricerca']='2'; //ricerca libera di una FRASE con - davanti
}
else
{
$data['value']=isset($_GET[$get_index])?trim(stripslashes($_GET[$get_index])):"";
$this->searchField[$key]['tipo_ricerca']='3'; //ricerca libera con una parola
/*in questo ramo rientra anche la ricerca di un campo aggregato che viene cercato nella whery con un like (considerato testo semplice)*/
}
}
else if (isset($_GET[$get_index."_start"]) ) //&& isset($_GET[$get_index."_end"])) ------ se c'è start c'è end
{
$data['value']['start']=$data['value']['end']="";
if (is_numeric($_GET[$get_index."_start"]) || preg_match("/^\d{4}-\d{2}-\d{2}$/",$_GET[$get_index."_start"]))
$data['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"]))
$data['value']['end']=trim($_GET[$get_index."_end"]);
$this->searchField[$key]['tipo_ricerca']='4'; //ricerca numerica (...intervalli)
}
else
continue; ////nessuna ricerca ancora effettuata
}
else // //più campi di ricerca con un unico testo
{
$get_index="";
foreach ($data['field'] as $val)
$get_index.=$val."_";
$get_index.="src_".$this->originalPrimaryTable;
$data['value']=isset($_GET[$get_index])?trim(stripslashes($_GET[$get_index])):"";
$this->searchField[$key]['tipo_ricerca']='3';
}
if (is_array($data['value']))
{
foreach ($data['value'] as $k=>$v)
$data['value'][$k]=addslashes($this->convertSpecialChars($v));
}
else
$data['value']=addslashes($this->convertSpecialChars($data['value']));
$this->searchField[$key]['value']=$data['value']; // SALVATAGGIO FINALE !
// MEMO: il value è utilizzato per costruire il form di ricerca (necessario stripslashes) e per fare le condizioni della query SQL
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
private 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("ghiaccio84@gmail.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>";
}
private 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);
}
}
private 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>
";
}
/**
* This is the special function that runs the execution of DBNavigator in the way of sinlge insertion or single modification.<br /><br />
* It must be recalled after the methods of configuration set...and that arouses the printing of the adeguate form HTML.
* Storing data/files at the moment of the form completion by the user, is managed automatically
* reproducing a confirmation page.
*
* <br /><br />ITALIAN:<br />
* Questa è la speciale funzione che avvia l'esecuzione di DBNavigator in modalità di singolo inserimento o singola modifica.<br /><br />
* Deve essere richiamata dopo i metodi di configurazione set... e provoca la stampa dell'adeguato form HTML.
* Il salvataggio dei dati/files al momento del completamento del form da parte dell'utente, viene gestito automaticamente
* riportando una pagina di conferma.
*
* @param int the numeric id of the record to be modified or zero (false) if that is an insertion
* <br /><br />ITALIAN:<br />
* l'id numerico del record da modificare oppure zero (false) se si tratta di un inserimento
*
* @param string the text HTML to visualize in the confirmation page following the form completion
* <br /><br />ITALIAN:<br />
* il testo HTML da visualizzare nella pagina di conferma successiva al completamento del form
*
* @param function name of a function php without paramenters that is recalled after the insertion or the modification
* (empty string if you don't want to use any function).<br />
* The use of this functionality has an impact similar to the one of a trigger SQL of type AFTER UPDATE/INSERT. <br />
* <br /><br />ITALIAN:<br />
* nome di una funzione php senza paramentri che viene richiamata dopo l'inserimento o la modifica
* (stringa vuota se non si vuole usare alcuna funzione).<br />
* L'uso di questa funzionalità ha un effetto simile a quello di un trigger SQL di tipo AFTER UPDATE/INSERT. <br />
*
*
* @param array makes up a data structure which serves to make substitutions in the code HTML generated by the class.<br />
* The array must be associative: each element has KEY equal to the text to be replaced and equal VALUE to the text of replacement.<br />
* Like key you can also use a text which will contain a regular expression causing the substitution of text parts
* in match with the expression ( parsed by preg_replace() ).
* <br /><br />ITALIAN:<br />
* costituisce una struttura dati che serve ad effettuare delle sostituzioni nel codice HTML generato dalla classe.<br />
* L'array deve essere associativo: ogni elemento ha CHIAVE uguale al testo da sostituire e VALORE uguale al testo di rimpiazzo.<br />
* Come chiave si può anche usare un testo che contenga una regular espression causando la sostituzione delle parti di testo
* in match con l'espressione ( valutata dalla funzione preg_replace() ).
*/
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
}
private 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)
{
$esitoPP=$this->PP->act($this->originalPrimaryTable,"frm_{$this->originalPrimaryTable}_submit",$this->originalPrimaryKey);
}
if (isset($password_error) || $esitoPP!=1 || $availability_error==true) //errore
{
if (isset($password_error))
{
$error_code='wrong_pwd';
$error_field=$password_error;
}else if ($esitoPP!=1) //0 non può essere perchè c'è un if all'inizio che controlla il submit_button
{
$error_code=$esitoPP[0];
$error_field=$esitoPP[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!="")
{
//if (is_callable(array($after_query_function,'doIt'),true)) //passato un oggetto
//if (is_callable($after_query_function,false))
if (is_object($after_query_function)) //passato un oggetto
$after_query_function->doIt(); //si richiama il metodo doIt();
else
$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>";
}
}
}
}
/**
* This is the special function that runs the execution of DBNavigator in full mode.<br /><br />
* It must be recalled after the methods of configuration set...and arouses the visualization af the whole interface of
* research, modification, insertion, ecc. and the automatic management of all the correspondent actions.
*
* <br /><br />ITALIAN:<br />
* Questa è la speciale funzione che avvia l'esecuzione di DBNavigator in modalità di singolo inserimento o singola modifica.<br /><br />
* Deve essere richiamata dopo i metodi di configurazione set... e provoca la visualizzazione di tutta l'interfaccia di
* ricerca, modifica, inserimento ecc. e la gestione automatica di tutte le azioni corrispondenti.
*
* @param function name of a function php without paramenters that is recalled after the insertion or the modification
* (empty string if you don't want to use any function).<br />
* The use of this functionality has an impact similar to the one of a trigger SQL of type AFTER UPDATE/INSERT. <br />
* <br /><br />ITALIAN:<br />
* nome di una funzione php senza paramentri che viene richiamata dopo l'inserimento o la modifica
* (stringa vuota se non si vuole usare alcuna funzione).<br />
* L'uso di questa funzionalità ha un effetto simile a quello di un trigger SQL di tipo AFTER UPDATE/INSERT. <br />
*
* @param boolean indicates if to print the navigation interface even over the table between the pages where are divided records.
* By default that interface is printed just under the table of elements visualization.
* <br /><br />ITALIAN:<br />
* indica se stampare anche sopra la tabella l'interfaccia di navigazione tra le pagine su cui sono suddivisi i record.
* Di default tale interfaccia è stampata solo sotto la tabella di visualizzazione elementi.
*
* @param function name of a functione to be used for data visualization. If you specify that function, that will be used to show
* the data instead of the default table.<br />
* The function must accept a paramenter that represents the set of data gived by mysql_query().
* The set of data already contains just the elements to visualize on the current page therefore you don't have to worry about
* paging elements on many HTML pages, which is anyway automatically managed by the class.
* Inside the function it is possible to tell as global the instance variable of DBNavigator object and invoke
* on that methods {@link getEditLink()} and {@link getDeleteLink()} that allow you to get HTML code about
* links of insertion/modification on each record of data set.
* <br /><br />ITALIAN:<br />
* nome di una funzione da usare per la visualizzazione dei dati. Se si specifica tale funzione, essa verrà usata per mostrare
* i dati invece della tabella di default.<br />
* La funzione deve accettare un parametro che rappresenta il set di dati restituito da mysql_query().
* Il set di dati contiene già i soli elementi da visualizzare sulla pagina corrente quindi non ci si deve preoccupare della
* paginazione degli elementi sulle varie pagine HTML, questo verrà comunque gestita automaticamente dalla classe.
* All'interno della funzione è possibile dichiarare come global la variabile di istanza dell'oggetto DBNavigator e richiamare
* su di essa i metodi {@link getEditLink()} e {@link getDeleteLink()} che permettono di ottenere il codice HTML relativo
* ai link di inserimento/modifica su ogni record del set di dati.
*
*
* @param array makes up a data structure which serves to make substitutions in the code HTML generated by the class.<br />
* The array must be associative: each element has KEY equal to the text to be replaced and equal VALUE to the text of replacement.<br />
* Like key you can also use a text which will contain a regular expression causing the substitution of text parts
* in match with the expression ( parsed by preg_replace() ).
* <br /><br />ITALIAN:<br />
* costituisce una struttura dati che serve ad effettuare delle sostituzioni nel codice HTML generato dalla classe.<br />
* L'array deve essere associativo: ogni elemento ha CHIAVE uguale al testo da sostituire e VALORE uguale al testo di rimpiazzo.<br />
* Come chiave si può anche usare un testo che contenga una regular espression causando la sostituzione delle parti di testo
* in match con l'espressione ( valutata dalla funzione preg_replace() ).
*
* @see getEditLink(), getDeleteLink()
*
*/
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}\">» {$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
}
private 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;
}
/**
* This method allows to obtain the code HTML relative to the form of elements research.<br />
* The form is automatically printed at the recall of function {@link go()} while
* if you recall this method the automatic print won't be executed.
*
* Naturally the form can be obtained if there are defined the searching fields
* through the method {@link setSearchField()}.<br />
*
* <br /><br />ITALIAN:<br />
* Questo metodo permette di ottenere il codice HTML relativo al form di ricerca elementi.<br />
* Il form viene automaticamente stampato al richiamo della funzione {@link go()} mentre
* se si richiama questo metodo la stampa automatica non viene eseguita.<br /><br />
*
* Naturalmente il form può essere ottenuto se sono stati definiti dei campi di ricerca
* tramite il metodo {@link setSearchField()}.<br />
*
* @param boolean indicates if to print the heading fields of the form over the checks instead of beside
* <br /><br />ITALIAN:<br />
* indica se stampare le intestazioni dei campi del form sopra i controlli invece che a fianco
* @return string the HTML code relative to the form of elements research. <br /><br />ITALIAN:<br /> il codice HTML relativo al form di ricerca elementi.
*/
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);
if ($this->HTMLtextEditor!=false)
$HF->setHTMLTextEditor($this->HTMLtextEditor);
$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
|| $name=="fieldList"
)
continue;
$HF->addInput("hidden",$name,stripslashes($value));
}
foreach($this->searchField as $key=>$data)
{
//////sulla
if (is_array($data['value']))
{
foreach ($data['value'] as $k=>$v)
$data['value'][$k]=stripslashes($v);
}
else
$data['value']=stripslashes($data['value']);
// ************************************************************************************************
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['field'])) //NUOVO CASO PARTICOLARE : PIU' CAMPI DI RICERCA x un testo solo
// è il primo if xkè qui l'interfaccia diventa una textbox indipendentemente dai campi !
{
$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
////////////////////////////////////////////////////////// AGGIUNTA degli INPUT di interfaccia nel form ri ricerca ///////
if ($data['domainType']=='list') // @ RADIO o SELECT (con selezione multipla)
{
$numValues=count($data['domainValue']);
if ($numValues==0 || $numValues==1)
{
$type='select';
$data['domainValue']=array(''=>"<em>{$this->lang['noResults']}</em>");
$param='';
}
else
if ($numValues==2)
{
$type='radio';
$data['domainValue']=array_merge(array(''=>"<em>{$this->lang['all']}</em>"), $data['domainValue']);
$param=true; //radio su una sola riga
}
else //per consentire scelte multiple di ricerca sul campo
{
$type='select';
$data['domainValue']=array_merge(array(''=>"» {$this->lang['all']}"), $data['domainValue']);
if ($numValues<8)
$param=$numValues;
else
$param=8;
}
$HF->addInput($type,"{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$data['domainValue'],
$heading,$param,$data['value'],false,$this->classForFormInput['inputs']);
}
else if ($data['domainType']=='date') // @------ INTERVALLO DATE! -- ricerca intervalli con input aggiunto 'manualmente' (senz addinput() di htmlform)
{
/* $HF->addInput("select","{$data['table_alias']}_{$data['field']}_src_".$this->originalPrimaryTable,$data['domainValue'],$heading,true,$data['value'],false,$this->classForFormInput['inputs']);
*/
$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 ($data['domainValue'] 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 ($data['domainValue'] as $k=>$v)
{
$inputs.="<option value=\"{$k}\" ".($current_end==$k?"selected=\"selected\"":"").">{$v}</option>
";
}
$inputs.="
</select>";
$HF->addExternalContent($inputs);
}
else
if ($data['domainType']=='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']:"")."\" />
");
}
else // @------ dato semplice - textbox
{
if ($data['table']!="Having") //!!!!!!! Non ci sono suggerimenti ai campi generati da funzioni di aggregazione
$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;
}
private function get_queryWithSearchConditions()
{
/////////////--- print_r($this->searchField); ///// DEBUGGGGGGGGGGGGGGGGGGGGGGGGG
foreach($this->searchField as $x)
{
// controllo valori vuoti
if ( (is_array($x['value']) && implode('',$x['value'])=="") || $x['value']=="" ) continue;
//(ri)trasformo in array anche i parameteri dei campi di ricerca 'singoli' - field_alias non necessario
//.......ridondante
if (!is_array($x['field']))
{
$x['field']=array($x['field']);
$x['field_alias']=array($x['field_alias']);
$x['table']=array($x['table']);
$x['table_alias']=array($x['table_alias']);
$x['domainType']=array($x['domainType']);
$x['domainValue']=array($x['domainValue']);
$x['fullField']=array($x['fullField']);
}
//print_r($x);
$current_condition=array();
//per ogni campo coinvolto in una condizione di ricerca esegue il codice sotto: i dati generali (tipo,value) sono direttamente su $x
//mentre i sottocompi sono nell'array $x['field']
for ( $k=0 ; $k < count($x['field']) ; $k++ ) ///potevo contare anche qualcos'altro
{
$first_condition_for_search_field=true;
//I CAMPI su funzioni aggregate seguono lo stesso trattamento degli altri
switch ($x['tipo_ricerca'])
{
case "1": //tante parole 'vincolate'
$or=array();
foreach($x['value'] as $multiple=>$val)
{
if ($val=="") continue;
/* $val_escape=str_replace(array("%","_"),array("\%","\_"),$val);
$or[]=" (
{$x['fullField'][$k]} LIKE \"{$val_escape},%\"
OR
{$x['fullField'][$k]} LIKE \"%,{$val_escape},%\"
OR
{$x['fullField'][$k]} LIKE \"%,{$val_escape}\"
OR
{$x['fullField'][$k]} = \"{$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[]=" {$x['fullField'][$k]} 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($x['value'],2,strlen($x['value'])-4);//
$current_condition[]="{$x['fullField'][$k]} =\"".$value."\"";
break;
case "3": // tante parole 'libere'
$founded=false;
$word=preg_split("/[^\\w'\"]/",stripslashes($x['value']),-1,PREG_SPLIT_NO_EMPTY);
//print_r($word);
$atLeastOneLongWord=false;
foreach ($word as $w) if (strlen($w)>3) {$atLeastOneLongWord=true;break;}
//if (strlen($x['value'])>3)
if ($atLeastOneLongWord && $x['table'][$k]!='Having')
{
$result=mysql_query("DESCRIBE {$this->originalPrimaryTable}");
while ($row=mysql_fetch_array($result))
{
if ($row['Field']==$x['field'][$k] && $row['Key']=='MUL') //cerca l'indice FULLTEXT
{
$current_condition[]="MATCH({$x['fullField'][$k]}) AGAINST (\"{$x['value']}\")";
//ordina in base alla rilevanza dei risultati
if (isset($this->orderInfo['currentOrd']))
$this->orderInfo['currentOrd'].=", MATCH({$x['fullField'][$k]}) AGAINST (\"{$x['value']}\") DESC";
else
$this->orderInfo['currentOrd']=" MATCH({$x['fullField'][$k]}) AGAINST (\"{$x['value']}\") DESC";
$this->orderInfo['currentDesc']="";
$founded=true;
break;
}
}
}
if (!$founded)//campo non fulltext, oppure tutte parole <= 3
{
$or=array();
$i=0;
$x['value']=str_replace(array("%","_"),array("\%","\_"),$x['value']);
if (
(strpos($x['value']," ")==0 && strlen($x['value'])<3) //una parola < di 3 caratteri
||
$atLeastOneLongWord==false //frasi senza parole >3
)
{
$or[]=" {$x['fullField'][$k]} LIKE \"{$x['value']}%\" "; //solo record che iniziano con..parola%
$cicli=0;
}
else
if (strpos($x['value']," ")==0) // una parola > 3 caratteri
$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(" ",$x['value']);
while(count($data_value)>0)//cicla finche l'array è pieno
{
$or[$i]=" {$x['fullField'][$k]} LIKE \"";
foreach($data_value as $key=>$val)
{
$or[$i].="%{$val}"; //con spazi o senza? - con gli spazi non trova i codici
}
$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);
// print_r($or);
}
break;
case "4": //intervalli numerici
$exp=array();
if (isset($x['value']['start']) && $x['value']['start']!="") $exp[]="{$x['fullField'][$k]}>=\"{$x['value']['start']}\"";
if (isset($x['value']['end']) && $x['value']['end']!="") $exp[]="{$x['fullField'][$k]}<=\"{$x['value']['end']}\"";
$current_condition[]=implode(" AND ",$exp);
break;
}
}//end foreach 2
if (count($current_condition)>0) //scelta della condizione messa su WHERE o su HAVING
{
$textual_current_condition=" (".implode(" OR ",$current_condition).") ";
$allHaving=true;
foreach($x['table'] as $val)
if ($val!="Having")
{
$allHaving=false;
break;
}
if ($allHaving)
{
$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; ///// DEBUGGGGGGGGGGGGGGGGGGGGGGGGG
return $query;
}
/** @return int the number of rows resulting from the construction query of the object with the actual research parameters
* <br /><br />ITALIAN:<br />
* il numero di righe risultante dalla chiamata alla query di costruzione dell'oggetto con gli attuali parametri di ricerca.
*/
function get_rowsNum()
{
$this->scanTable();
$this->set_rowsNum();
return $this->rowsNum;
}
/** @return string the construction query of the object with the actual research parameters
* <br /><br />ITALIAN:<br />la query di costruzione dell'oggetto con gli attuali parametri di ricerca.*/
function getFullQuery()
{
$this->scanTable();
$this->set_rowsNum();
return $this->query;
}
private 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));
////////////////////////////////////
}
}
/** @param int id of a record<br /><br />ITALIAN:<br /> id di un record
* @return string the HTML code of the button/link relative to the interface starting of element modification
* <br /><br />ITALIAN:<br />
* il codice HTML del tasto/link relativo all'attivazione dell'interfaccia di modifica dell'elemento
* @see go()
*/
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;vertical-align:baseline;margin:4px\" /></a>";
else return "";
}
/** @param int id of a record<br /><br />ITALIAN:<br /> id di un record
* @return string the HTML code of the button/link relative to starting of the element elimination procedure
* <br /><br />ITALIAN:<br />
* il codice HTML del tasto/link relativo all'attivazione della procedura di eliminazione dell'elemento
* @see go() */
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;vertical-align:baseline;margin:4px\" /></a>";
else return "";
}
private 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;
}
}
private 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']}&{$col['arg']}={$row[$this->primaryKey]}$qs#{$this->originalPrimaryTable}_anchor\" >".$text."</a>";
}
else return false;
}
private 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->datasetName);
$this->query.=$PN->getLimit();
$PN->setlanguage($this->lang['languageName']);
$PN->setImagesPath($this->imagesAndScriptsPath);
if ($this->pageBrowsingConfig['byselect']==true)
$nav1=$PN->show_page_browsing(false);
if ($this->pageBrowsingConfig['bylink']==true)
$nav2=$PN->show_page_browsing(true);
if ($this->pageBrowsingConfig['selectrpp']==true)
$rpp=$PN->show_RPP_browsing();
if ($nav1 || $nav2 || $rpp)
{
$navigation.= "<br />";
$navigation.= "<div class=\"".$this->pageBrowsingConfig['navigationPanelCSS']."\" 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)."\" />";
}
}
$cont="";
foreach($this->tableContainer as $css)
{
$cont="<div class=\"".$css."\">".$cont; //i div applicati in lista dal primo impostato fino all'ultimo
}
$print.=$cont;
$print.= "<table border=\"0\" cellpadding=\"{$this->tableCP}\" cellspacing=\"{$this->tableCS}\"
style=\"width:100%;\" summary=\"Tabella riepilogativa di ogni {$this->rowName}\">";
$temp=array();
if ($this->canEdit===true || is_array($this->canEdit))
$temp[]=$this->lang['edit'];
if ($this->canDelete===true || is_array($this->canDelete))
$temp[]=$this->lang['delete'];
if ($multipleContext)
$temp[]=$this->lang['selection'];
$headerrow="";
if (count($temp)==0) //non si possono fare azioni
{
$columns=0;
$NOACTION=true;
}
else
{
if (!isset($this->lang['actionColumnHeader']))
$actionColumnHeader=strtolower(implode(" / ",$temp));
else
$actionColumnHeader=$this->lang['actionColumnHeader'];
$headerrow.= "<td{$this->classTag['headerTD']}>".$actionColumnHeader."</td>"; //colonna di intestazione seleziona/modifica/elimina
$columns=1;
}
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
$columns++;
$headerrow.= "<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}&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}&desc_{$this->originalPrimaryTable}=DESC".buildQueryString("ord_".$this->originalPrimaryTable,"desc_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable,"del_".$this->originalPrimaryTable)."#{$this->originalPrimaryTable}_anchor";
}
$headerrow.=$show." ";// $show."<br />"; ////
//link di ordinamento disattivati per default...
$asc_atagopen="<a href=\"{$href_1}\">";
$asc_atagclose="</a>";
$asc_im_postfix="off";
$desc_atagopen="<a href=\"{$href_2}\">";
$desc_atagclose="</a>";
$desc_im_postfix="off";
if ($current_field->def==$this->orderInfo['currentOrd']) //colonna ordinata
{
//....modifica solo le variabili del campo ordinato (o asc o desc)
if ($this->orderInfo['currentDesc']=="DESC")
{
$desc_atagopen="";
$desc_atagclose="";
$desc_im_postfix="on";
}
else // ASC
{
$asc_atagopen="";
$asc_atagclose="";
$asc_im_postfix="on";
}
}
$headerrow.= $asc_atagopen."<img style=\"vertical-align:bottom;border:none;\" src=\"{$this->imagesAndScriptsPath}asc_{$asc_im_postfix}.gif\" alt=\"{$this->lang['ascendingOrder']}\" title=\"{$this->lang['ascendingOrder']}\" />". $asc_atagclose.
$desc_atagopen."<img style=\"vertical-align:bottom;border:none;\" src=\"{$this->imagesAndScriptsPath}desc_{$desc_im_postfix}.gif\" alt=\"{$this->lang['descendantOrder']}\" title=\"{$this->lang['descendantOrder']}\" />". $desc_atagclose;
//////////////////////////////////////
$headerrow.= "</td>";
}
foreach ($this->dataCol as $col) {$columns++; $headerrow.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>";} //stampa colonne aggiuntive
if ($this->canViewForPrint) {$columns++; $headerrow.= "<td{$this->classTag['headerTD']}>{$this->lang['print']}</td>";}
foreach ($this->linkCol as $col) {$columns++; $headerrow.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>";} //stampa colonne aggiuntive
foreach ($this->freeCol as $col) {$columns++; $headerrow.= "<td{$this->classTag['headerTD']}>{$col['colName']}</td>";} //stampa colonne aggiuntive
////////////////--------------------------------------------------------------------------------------------------
$print.= "<tr class=\"{$this->tableHeaderCSS}\">";
if (count($this->tableBorderStyle)>0) // ..riga dedicata alle celle del bordo
{
$print.= "
<td class=\"".$this->tableBorderStyle['topsx']."\"></td>
{$headerrow}
<td class=\"".$this->tableBorderStyle['topdx']."\"></td>
";
}
else
$print.= "{$headerrow}";
$print.= "</tr>";
//**************************************TABELLA*********************
while ($row=mysql_fetch_array($result))
{
$print.= "<tr class=\"{$this->tableRowContentCSS}\">";
// ..celle del bordo
// ..celle del bordo
if (count($this->tableBorderStyle)>0) // ..riga dedicata alle celle del bordo
$print.= "<td class=\"".$this->tableBorderStyle['sx']."\"></td>";
//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 (!$NOACTION ) $print.= $openEditDeleteTD; //-----------colonna coi link modifica/elimina/selezione
if ($multipleContext)
{
$print.="<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]}\" style=\"margin:4px\" /> ";
}
if ($this->canEdit===true || is_array($this->canEdit))
{
$editLink=$this->getEditLink($row[$this->primaryKey]);
if ($editLink!="")
$print.=$editLink;
}
if ($this->canDelete===true || is_array($this->canDelete))
{
$deleteLink=$this->getDeleteLink($row[$this->primaryKey]);
if ($deleteLink!="")
$print.=$deleteLink;
}
$print.= "</td>"; //-----------------------------fine colonna
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
///....................VISUALIZZAZIONE VALORI --- variabile $fieldText ...................................................
if (is_array($this->imageIcon[$current_field->name])) //preview dell'immagine sulla tabella
{
if ($row[$current_field->name]=='')
$fieldText="<img src=\"".$this->imageIcon[$current_field->name]['off']."\" alt=\"\" style=\"border:none\" />";
else
{
$fieldText="<img src=\"".$this->imageIcon[$current_field->name]['on']."\" alt=\"\" style=\"border:none\" />";
//caso di file...stesso controllo fatto sotto
if (isset($this->fileField[$current_field->name]) && $current_field->table==$this->originalPrimaryTable )
$fieldText="<a href=\"{$this->filePath}/{$row[$current_field->name]}\" >".$fieldText."</a>";
}
}
else if (isset($this->switchCol[$current_field->name])) //------ campo impostato come SWITCH (a 2 valori)
{
$value=array();
foreach($this->getEnumSetValue($current_field->type) as $val=>$val2)
{
$value[]=$val;
}// l'array value contenente i valori ordininati
$is_on = $row[$current_field->name]==$value[0] ? "1" : "2" ;
$is_off = $row[$current_field->name]==$value[0] ? "2" : "1" ;
$fieldText="<a href=\"{$_SERVER['PHP_SELF']}?switch_field_{$this->originalPrimaryTable}=".$current_field->name.
"&switch_id_{$this->originalPrimaryTable}=".$row["id"].
"&switch_value_{$this->originalPrimaryTable}=".$is_off. //uso del valore indice
"&".buildQueryString("del_".$this->originalPrimaryTable,"edit_".$this->originalPrimaryTable).
"#{$this->originalPrimaryTable}_anchor\">";
$current_value_image = $this->switchCol[$current_field->name]['image'.$is_on];
if (file_exists($current_value_image))
$fieldText.="<img style=\"vertical-align:top;border:none;\" src=\"".$current_value_image
."\" alt=\"".$row[$current_field->name]."\" title=\"".$row[$current_field->name]."\" />";
else
$fieldText.=$row[$current_field->name];
$fieldText.="</a>";
}
else
switch($TYPE[0])
{
case "date":
$exp=explode("-",$row[$current_field->def]);
if (isset($this->monthYearField[$current_field->name]))
$fieldText= "{$exp[1]}/{$exp[0]}";
else
$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="";
$fname=$this->filePath."/$small".$row[$current_field->name];
if (file_exists($fname))
{
if (!is_array($this->imageIcon[$current_field->name])) //preview dell'immagine sulla tabella
$fieldText= "<img src=\"".$fname."\" alt=\"\"
style=\"".getImageResizedValues($fname,$this->imageScaleDim,$this->imageScaleDim)."\" />";
else//array
$fieldText= "<img src=\"".$this->imageIcon[$current_field->name]['on']."\" alt=\"\" />";
}
else
$fieldText=$fname." :immagine non trovata";
}
else
{
if (!is_array($this->imageIcon)) //preview dell'immagine sulla tabella
$fieldText="<em>{$this->lang['noImage']}</em>";
else
$fieldText= "<img src=\"".$this->imageIcon[$current_field->name]['off']."\" alt=\"\" />";
}
}
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>";
}
}
}
}
$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.="• ".$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>
</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>";
}
// ..celle del bordo
if (count($this->tableBorderStyle)>0) // ..riga dedicata alle celle del bordo
$print.= "<td class=\"".$this->tableBorderStyle['dx']."\"></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
if (count($this->tableBorderStyle)>0) // ..riga dedicata alle celle del bordo
{
$print.= "<tr>
<td colspan=\"1\" class=\"".$this->tableBorderStyle['botsx']."\"></td>
<td colspan=\"".$columns."\" class=\"".$this->tableBorderStyle['bot']."\"></td>
<td colspan=\"1\" class=\"".$this->tableBorderStyle['botdx']."\"></td>
</tr>
";
}
$print.= "</table>";
foreach($this->tableContainer as $css)
{
$print.="</div>";
}
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 style=\"margin-top:10px\" 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>
";
}
}
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;
}
private 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;
}
private 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;
}
}
private function buildForm($id=null,$replace_array=null,$show_back_link=true)
{
//print_r($this->field);
//print_r($this->externalData);
$print="";
$fieldEnablingControl="";
$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();")."\">» {$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 ( intval($this->photoField['_Resize_'])!=0 && $this->photoField['_KeepOriginal_']) //origin.+miniatura: crea il link per l'originale
{
$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 //solo immagine O solo miniatura
{
$pre= $this->photoField['_KeepOriginal_'] ? "" : "small_" ;
$print.="<img src=\"{$this->filePath}/{$pre}{$row[$field]}\"
style=\"".getImageResizedValues($this->filePath."/".$pre.$row[$field],130,130)."\"
alt=\"{$pre}{$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();")."\">» {$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; //
$maxlength=explode("(",$current_field->type); //eg. field.type='string(100)'
$maxlength=substr($maxlength[1],0,-1);
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))
,$maxlength,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) $fieldEnablingControl.= $this->getFieldEnablingControl('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 -- prima era l'explode con ('
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":
if (isset($this->monthYearField[$current_field->name]))
$t="DATE_MY";
else
$t="DATE";
$added=$this->editForm->addInput($t,"$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)
$fieldEnablingControl.= $this->getFieldEnablingControl('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)),$maxlength,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;
$fieldEnablingControl.= $this->getFieldEnablingControl('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)
$fieldEnablingControl.= $this->getFieldEnablingControl('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)
$fieldEnablingControl.= $this->getFieldEnablingControl('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)
$fieldEnablingControl.= $this->getFieldEnablingControl($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)
$fieldEnablingControl.= $this->getFieldEnablingControl($type,$current_field->name,$current_field->def,count($value));
break;
}//end switch
}//end if
} //end foreach
if ($fieldEnablingControl!="") //intestazione
$print.="<div style=\"border-top:1px solid #DDD;border-bottom:1px solid #DDD;padding:6px 0px;
margin-bottom:6px;font-weight:bolder;font-size:larger;font-style:italic\">
{$this->lang['fieldEnablingControlHeading']}</div>";
$editForm_string = $this->editForm->buildForm($this->lang['confirmData'],$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;
if ($fieldEnablingControl!="") //codice javascript ---deve essere messo DOPO il form altrimenti la rilevazione
$print.=$fieldEnablingControl; // dello stato della textarea HTML non riesce perchè deve ancora inizializzarsi
return $print;
}
//serve per identificare i valori dell'ENUM/SET
private 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;
}
private function getFieldEnablingControl($type,$name,$heading,$length=null)
{
$JSDisable="";
if ($this->ajaxCall) $JSDisable="change_{$name}_status();";
else $this->JS_onLoad.="
change_{$name}_status();
";
//stato: abilitato. link per disabilitare la modifica sul campo
$enableCode="
a.style.color='#C00';
a.innerHTML='[ <img style=\"border:0px\" src=\"".$this->imagesAndScriptsPath."delete.png\" /> DO NOT Edit ] ';
";
//stato: disabilitato. link per abilitare la modifica sul campo
$disableCode="
a.style.color='#060';
a.innerHTML='[ <img style=\"border:0px\" src=\"".$this->imagesAndScriptsPath."edit.png\" /> EDIT ] ' ;
";
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;
container = el1.parentNode.parentNode.previousSibling.previousSibling;
//alert(container.innerHTML);
if (el1.style.display=='none')
{
el1.disabled=false;
el2.disabled=false;
el3.disabled=false;
el1.style.display='block';
el2.style.display='block';
el3.style.display='block';
{$enableCode}
}
else
{
el1.disabled=true;
el2.disabled=true;
el3.disabled=true;
el1.style.display='none';
el2.style.display='none';
el3.style.display='none';
{$disableCode}
}
";
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}');
}
container = el.parentNode;
//alert(el.parentNode.getElementsByTagName('div')[0].innerHTML);
if (elDoc.designMode=='off')
{
elDoc.designMode='on';
el.style.height='auto';
//el.parentNode.getElementsByTagName('div')[0].style.visibility='visible';
{$enableCode}
}
else
{
elDoc.designMode='off';
el.style.height='0px';
///el.parentNode.getElementsByTagName('div')[0].style.visibility='hidden';
{$disableCode}
}
";
break;
case 'TEXTAREA':
$JSFunctionBody= "
var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name};
container = el.parentNode;
if (el.style.display=='none')
{
el.disabled=false;
el.style.display='block';
//aggiungo all'input che indica i campi da modificare
{$enableCode}
}
else
{
el.disabled=true;
el.style.display='none';
{$disableCode}
}
";
break;
case 'TEXT':
case 'SELECT':
$JSFunctionBody= "
var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name};
container = el.parentNode.previousSibling.previousSibling;
if (el.style.display=='none')
{
el.disabled=false;
el.style.display='block';
//aggiungo all'input che indica i campi da modificare
{$enableCode}
}
else
{
el.disabled=true;
el.style.display='none';
{$disableCode}
}
";
break;
case 'RADIO':
$JSFunctionBody="
var el=document.getElementById('frm_{$this->originalPrimaryTable}').{$name};
container = el[0].parentNode.parentNode.parentNode.childNodes[1];
if (el[0].disabled==true)
{
for (i=0;i<el.length;i++) el[i].disabled=false;
el[0].parentNode.parentNode.style.visibility='visible';
{$enableCode}
}
else
{
for (i=0;i<el.length;i++) el[i].disabled=true;
el[0].parentNode.parentNode.style.visibility='hidden';
{$disableCode}
}
";
break;
case 'CHECKBOX':
$JSFunctionBody="
var el=document.getElementById('frm_{$this->originalPrimaryTable}').elements['{$name}[0]'];
container = el.parentNode.parentNode.parentNode.childNodes[1];
if (el.disabled==true)
{
for (i=0;i<{$length};i++)
document.getElementById('frm_{$this->originalPrimaryTable}').elements['{$name}['+i+']'].disabled=false;
el.parentNode.parentNode.style.visibility='visible';
{$enableCode}
}
else
{
for (i=0;i<{$length};i++)
document.getElementById('frm_{$this->originalPrimaryTable}').elements['{$name}['+i+']'].disabled=true;
el.parentNode.parentNode.style.visibility='hidden';
{$disableCode}
}
";
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);
var a=document.createElement('a'); //il nuovo elemento link che fa lo switch...
{$JSFunctionBody}
a.style.fontWeight='Bold';
a.style.textDecoration='none';
a.href='javascript:change_{$name}_status()';
div=document.createElement('div');
div.appendChild(a);
old = container.replaceChild(div,container.firstChild);
if ( old.innerHTML.indexOf('<a')==0) //c'è il link come primo elemento
div.appendChild(old.lastChild);
else //prima sostituzione ...metto l'etichetta in fondo
div.appendChild(old);
}
{$JSDisable}
-->
</script>
";
}
private 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>";
}
private 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"," "),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 &
//considerare l'uso di <![CDATA[BROWNIES<> & CO.]]> invece di BROWNIES>< & CO.
}
$print.="<Cell>
<Data ss:Type=\"".$datatype."\">".$row[$key]."</Data>
</Cell>";
}
$print.='
</Row>
';
}
$print.='
</Table>
</ss:Worksheet>
</Workbook>';
}
die( $print );
}
private 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;
}
}
?>
|