Uploading files to a webserver enabled with Active FoxPro Pages is a combination of actually three parts:
- HTML interface presented to the client to upload any kind of data.
- Data send back to the server
- A mechanism on the server to process the sent data
In this article we are going to look at every single step of the whole procedure.
Upload form
Technically HTML allows sending any kind of data back to the server via POST requests. A client can generate the POST request on its own - like done with the AFP 3 Client component or for simplicity the web site offers a standard HTML web formular with the ability to upload files - along with normal input fields.
So, we'll take a look at the web form - provided by the following interface:
<form method="POST" name="upload"
action="<%? Session.Url()%>"
enctype="multipart/form-data">
<input type="file" name="filename"> <br>
<input type="submit" value=" Go >> ">
</form>
The result of this AFP code produces a HTML form with one textbox - and 'Browse' button - and one Submit button to send the data back to the server. We're using Session.Url() as action to process the data by the same AFP document that generated this form. An alternative would be to use Request.ServerVariables("PATH_INFO") - which provides the same information.
Data to send back to the server
In theory, any data located in the directory system of the client's machine could be send to the server. There might be conversion issues with Mac systems - I was told...
Processing sent data on the server
That's actually the interesting part of this article...
Here's the source code of an AFP sample document that offers on the one hand a presentation of any kind of images - in this case logos - and on the other hand it provides an upload interface to submit new logos:
<%
*// Upload sample
*// Logo-Contest for AFP FAQ
*//
*// A - Image galerie that presents accepted logos.
*// B - Storeing sent data as file in a specified directory and
*// with additional information in an 'upload' table.
*// C- Drop a mail to the webmaster about new entry.
Local lcLogoText, lcUploadPath, lnColumn, lnColumnCount
Store "" To lcLogoText, lcUploadPath
Store 0 To lnColumn, lnColumnCount
*// Definitions
lcLogoText = FileToStr("logo.inc.htm")
lcUploadPath = Addbs(File.FullPath("images\logos"))
lcUrlPath = "/images/logos/"
lnColumnCount = 3
*// Process any inputs via POST request - form submission.
If Request.ServerVariables("REQUEST_METHOD") == "POST"
lcFilename = JustFname(Request.MultiPart("image", "filename"))
If Not Empty(m.lcFilename)
lcFilePath = m.lcUploadPath + m.lcFilename
lcFileUrl = m.lcUrlPath + m.lcFilename
lcUniqueId = Sys(2007, Session.SessionID()) + ;
Sys(2007, Transform(Seconds()))
liUniqueId = Int(Val(m.lcUniqueId))
lcLastIP = Request.ServerVariables("REMOTE_ADDR")
lcAuthor = Alltrim(Request.Form("author"))
lcEmail = Alltrim(Request.Form("email"))
lcFile = Request.Form("image")
*// Insert new upload into 'logo' table
Insert Into ;
logo ( ;
UniqueID, ;
LastUpdate, ;
Author, ;
Email, ;
Filename, ;
LastIP, ;
CntView, ;
Status) ;
Values ( ;
m.liUniqueId, ;
Datetime(), ;
m.lcAuthor, ;
m.lcEmail, ;
m.lcFileUrl, ;
m.lcLastIP, ;
1, 0)
*// Store the file physically.
If File(m.lcFilePath)
lcFilePath = m.lcUploadPath + Sys(2015) + "_" + m.lcFilename
EndIf
StrToFile(m.lcFile, m.lcFilePath, 0)
*// Send notification.
lcRecipient = "joki@afpfaq.de"
lcSubject = "AFP FAQ - Neues Logo '" + ;
m.lcFilename + "' von " + ;
m.lcAuthor
lcBody = "Neues Logo eingestellt..."
SendMail(m.lcRecipient, m.lcSubject, m.lcBody)
*// give user feedback
Response.Write( [Thank you for your submission!] )
Response.Write( [<p>] )
EndIf
EndIf
*// Get already accepted logos and present them on the page.
Select * ;
From logo ;
Into Cursor _logo ;
Where Status == 1 ;
Order By logo.lastupdate Asc
Response.Write( "<h3>Logo Contest</h3>" )
Response.Write( m.lcLogoText )
Response.Write( [<p>] )
Response.Write( "<h3>Logo Overview</h3>" )
Response.Write( "<table><tr><td>" )
Select "_logo"
Scan
lnColumn = lnColumn + 1
Scatter Memo Memvar
Response.Write( [<div align="center"><img src="] + m.Filename + ;
[" alt="] + JustFname(m.Filename) + [">] + ;
[<br>] + JustFname(m.Filename) + [</div>] )
Response.Write( [</td>] + ;
Iif(Mod(m.lnColumn, m.lnColumnCount) == 0, "</tr><tr>", "") + ;
[<td>] )
EndScan
USE In "_logo"
Response.Write( [</td></tr></table><p>] )
*// Upload section
Response.Write( "<h3>Logo Upload</h3>" )
Response.Write( [<p> <p>] )
Response.Write( [<form action="] + ;
Session.Url() + ;
[" method="POST" enctype="multipart/form-data">] + ;
[<input type="text" name="author">] + ;
[<input type="text" name="email">] + ;
[<input type="file" name="image">] + ;
[<input type="submit" name="submit" value="Logo senden">] + ;
[</form>])
%>
Please remember, that's only sample code - no design contest.
The live sample is here.
Maximum upload size has currently a limit of approx. 8 MB and you shouldn't store any data uploads without checks.
Final words
Uploading files or data in general to a remote system is anytime a combination of multiple elements in the whole process. Here we have seen that HTML provides the Upload interface inside the client's browser, AFP handles sent data and interacts with the system's directories. Additionally the webmaster is informed about this new upload.
So, in this scenario Active FoxPro Pages are only part of the whole upload process - and they're doing their part very well and fast - as usual! *g*
Enjoy the AFP FAQ, JoKi