La logica che gestisce l'aggiornamento del record deve occuparsi di due cose: 1) aggiornare il file dell'immagine sul server e 2) aggiornare il record nel database. Come per il file di inserimento, inserisci un controllo che il form sia stato inviato.
8. all'inizio del file aggiornamento.cfm controlla se è definita la variabile form.ALBUM_TITOLO:
<!--- aggiornamento.cfm: permette di aggiornare gli album --->
<cfif isDefined('form.ALBUM_TITOLO')>
<!--- Qui andrà la parte per aggiornare il file e il record --->
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
Se si invia una nuova immagine la variabile form.ALBUM_IMG non sarà certamente vuota.
9. Aggiungi il <cffile> che esegue l'upload della nuova immagine e imposta la variabile form.ALBUM_IMG con il nome del file trasferito.
<!--- aggiornamento.cfm: permette di aggiornare gli album --->
<cfif isDefined('form.ALBUM_TITOLO')>
<cfif form.ALBUM_IMG NEQ "">
<!--- Esegue l'upload della nuova immagine sul server --->
<cffile action="upload" filefield="ALBUM_IMG" destination="C:CFusionMXwwwrootdiscotecaalbum" nameconflict="makeunique">
<cfset form.ALBUM_IMG = cffile.ServerFile>
</cfif>
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
Nel caso in cui form.ALBUM_IMG sia vuoto, significa che non è stata inviata nessuna nuova immagine e che il nome dell'immagine deve essere uguale a quello vecchio. La variabile form.ALBUM_IMG dovrà essere impostata uguale a form.vecchiaImmagine.
10. Inserisci in un <cfelse> il <cfset> che associ alla variabile form.ALBUM_IMG il valore della variabile form.vecchiaImmagine:
<!--- aggiornamento.cfm: permette di aggiornare gli album --->
<cfif isDefined('form.ALBUM_TITOLO')>
<cfif form.ALBUM_IMG NEQ "">
<!--- Esegue l'upload della nuova immagine sul server --->
<cffile action="upload" filefield="ALBUM_IMG" destination="C:CFusionMXwwwrootdiscotecaalbum" nameconflict="makeunique">
<cfset form.ALBUM_IMG = cffile.ServerFile>
<cfelse>
<cfset form.ALBUM_IMG = form.vecchiaImmagine>
</cfif>
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
E il vecchio file dell'immagine? Non ci serve più. Quindi è opportuno eliminarlo dal server, usando l'attributo action="delete" di <cffile>. Il nome del vecchio file proviene dal campo hidden "vecchiaImmagine".
11. Inserisci il <cffile> prima di eseguire l'upload (il nome del file caricato potrebbe infatti essere lo stesso di quello che viene eliminato). Poiché il record da aggiornare potrebbe non avere alcuna immagine, è bene includere un <cfif> che verifichi che la variabile "vecchiaImmagine" non sia vuota.
<!--- aggiornamento.cfm: permette di aggiornare gli album --->
<cfif isDefined('form.ALBUM_TITOLO')>
<cfif form.ALBUM_IMG NEQ "">
<!--- Elimina la vecchia immagine dal server --->
<cfif form.vecchiaImmagine NEQ "">
<cffile action="delete" file="C:CFusionMXwwwrootdiscotecaalbum#form.vecchiaImmagine#">
</cfif>
<!--- Esegue l'upload della nuova immagine sul server --->
<cffile action="upload" filefield="ALBUM_IMG" destination="C:CFusionMXwwwrootdiscotecaalbum" nameconflict="makeunique">
<cfset form.ALBUM_IMG = cffile.ServerFile>
<cfelse>
<cfset form.ALBUM_IMG = form.vecchiaImmagine>
</cfif>
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
Per eseguire l'aggiornamento di un record nel database si può utilizzare il tag <cfupdate>. Come per <cfinsert>, negli attributi dobbiamo specificare il data source name da utilizzare, la tabella da aggiornare e i campi del modulo da cui provengono le informazioni aggiornate.
12. Inserisci il tag <cfupdate>. Nei campi formfields, dobbiamo inserire questa volta anche ID_ALBUM, che serve a <cfupdate> per capire qual è il record da aggiornare.
<!--- aggiornamento.cfm: permette di aggiornare gli album --->
<cfif isDefined('form.ALBUM_TITOLO')>
<cfif form.ALBUM_IMG NEQ "">
<!--- Elimina la vecchia immagine dal server --->
<cfif form.vecchiaImmagine NEQ "">
<cffile action="delete" file="C:CFusionMXwwwrootdiscotecaalbum#form.vecchiaImmagine#">
</cfif>
<!--- Esegue l'upload della nuova immagine sul server --->
<cffile action="upload" filefield="ALBUM_IMG" destination="C:CFusionMXwwwrootdiscotecaalbum" nameconflict="makeunique">
<cfset form.ALBUM_IMG = cffile.ServerFile>
<cfelse>
<cfset form.ALBUM_IMG = form.vecchiaImmagine>
</cfif>
<!--- Aggiorna il record ID_ALBUM nella tabella ALBUM del datasource discoteca --->
<cfupdate datasource="discoteca" tablename="ALBUM" formfields="ID_ALBUM,ALBUM_TITOLO,ALBUM_AUTORE,ALBUM_ETICH, ALBUM_DESCR,ALBUM_GENERE,ALBUM_IMG">
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
Il tag <cfupdate> esegue un UPDATE via SQL e riconosce i campi della tabella da aggiornare, in base al nome dei campi del modulo di inserimento: per questo motivo, abbiamo dovuto creare il modulo utilizzando gli stessi nomi dei campi del database.
Naturalmente, anziché usare <cfupdate> avremmo potuto scrivere "a mano" la stringa di SQL, che avremmo passato al solito tag <cfquery>. Il <cfquery> corrispondente al <cfupdate> è in questo caso:
<cfquery name="updateRecord" datasource="discoteca">
UPDATE ALBUM
SET ALBUM_TITOLO = '#form.ALBUM_TITOLO#',
ALBUM_AUTORE = '#form.ALBUM_AUTORE#',
ALBUM_ETICH = '#form.ALBUM_ETICH#',
ALBUM_DESCR = '#form.ALBUM_DESCR#',
ALBUM_GENERE = '#form.ALBUM_GENERE#',
ALBUM_IMG = '#form.ALBUM_IMG#'
WHERE ID_ALBUM = #form.ID_ALBUM#
</cfquery>
Se avessimo usato <cfquery> anziché <cfupdate> non avremmo avuto bisogno di chiamare i campi del modulo come quelli del database.
Una volta eseguito <cfupdate>, la query successiva getAlbum prende nuovamente le informazioni dal database per compilare il modulo. Queste informazioni sono filtrate in base alla variabile url.id, che però non è definita quando inviamo il form. ColdFusion ritornerebbe quindi un errore.
Si può dare il valore ad una variabile quando essa non è definita utilizzando <cfparam>. Analogamente a <cfset>, <cfparam> crea una variabile. A differenza di <cfset>, la variabile viene creata solo quando essa non è definita.
13. Aggiungi dopo <cfupdate> il tag <cfparam> per definire la variabile "url.id" con il valore di "form.album_id".
........
<!--- Aggiorna il record ID_ALBUM nella tabella ALBUM del datasource discoteca --->
<cfupdate datasource="discoteca" tablename="ALBUM" formfields="ID_ALBUM,ALBUM_TITOLO,ALBUM_AUTORE,ALBUM_ETICH,
ALBUM_DESCR,ALBUM_GENERE,ALBUM_IMG">
<!--- Assegna il valore dell'album_id alla variabile url.id --->
<cfparam name="url.id" default="#form.album_id#" type="numeric">
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery> ........
<cfparam> contiene tre attributi: "name" per indicare il nome della variabile, "default" per indicare il valore che essa deve avere, e "type" - opzionale - che specifica di che tipo deve essere la variabile. L'attributo "default" rende bene l'idea su come funziona <cfparam>: esso associa ad una variabile un valore "predefinito" nel caso essa non sia ancora stata definita.
14. Dopo <cfparam>, definisci una variabile che contenga il messaggio dell'avvenuto aggiornamento:
........
<!--- Aggiorna il record ID_ALBUM nella tabella ALBUM del datasource discoteca --->
<cfupdate datasource="discoteca" tablename="ALBUM" formfields="ID_ALBUM,ALBUM_TITOLO,ALBUM_AUTORE,ALBUM_ETICH,
ALBUM_DESCR,ALBUM_GENERE,ALBUM_IMG">
<!--- Assegna il valore dell'album_id alla variabile url.id --->
<cfparam name="url.id" default="#form.id_album#" type="numeric">
<!--- Dichiarazione di una variabile per confermare l'aggiornamento --->
<cfset aggiornamentoOK = 'L''album ' & form.ALBUM_TITOLO & ' è stato aggiornato.'>
</cfif>
<cfquery name="getAlbum" datasource="discoteca">
SELECT * FROM ALBUM
WHERE ID_ALBUM = #url.id#
</cfquery>
Come puoi notare, dovendo mettere un'apice nella stringa "aggiornamentoOK" - abbiamo dovuto ripeterlo due volte. In CFML l'apice indica l'inizio e la fine di una stringa, per evitare che il carattere venga interpretato in questo modo va raddoppiato. Poiché per indicare le stringhe si può usare il doppio apice ("), avremmo anche potuto scrivere:
<cfset aggiornamentoOK = "L'album " & form.ALBUM_TITOLO & " è stato aggiornato.">
evitando così di raddoppiare l'apice singolo.
Il raddoppiamento vale anche per il simbolo #: all'interno dei tag CFML, ad esempio <cfoutput>, viene interpretato come inizio di una variabile. Per evitare che questo accada, è sufficiente raddoppiarlo. Ad esempio, per stampare il cancelletto in un <cfoutput> dovremo scrivere:
<cfoutput>
Questo è un cancelletto inserito in un cfoutput: ##.
</cfoutput>
Il carattere "&" serve per concatenare più stringhe tra loro, anche nel caso esse siano contenute in variabili. Scrivendo
'L''album ' & form.ALBUM_TITOLO & ' è stato aggiornato.'
abbiamo creato una stringa che include il valore della variabile form.ALBUM_TITOLO.
15. Tornando al nostro file aggiornamento.cfm, visualizziamo il contenuto della variabile "aggiornamentoOK" prima del titolo della pagina:
...........
<!--- Visualizza il messaggio se è avvenuto l'aggiornamento --->
<cfif isDefined('aggiornamentoOK')>
<cfoutput><p>#aggiornamentoOK#</p></cfoutput>
</cfif>
<p class="titolo">Aggiornamento dell'album</p>
<cfoutput>
<cfform action="aggiornamento.cfm" enctype="multipart/form-data">
<input type="hidden" name="ID_ALBUM" value="#getAlbum.ID_ALBUM#">
<input type="hidden" name="vecchiaImmagine" value="#getAlbum.ALBUM_IMG#">
<table>
<tr>
<td> ...........
La pagina per l'aggiornamento dei record è così terminata. Se vuoi confrontare il file aggiornamento.cfm con quello che ho realizzato io puoi scaricarlo da qui.