Subject: File (Attachment) size and validation in web
Try this. Long back I got this from some site. BUT It is for Lotus Notes client.
1 - Limit the allowable size of attachments (total size in this case, not file by file) to any specific document
2 - Since it can take an eternity to attach a file that may ultimately be disallowed (the longer the eternity, the greater the liklihood it will be refused), we ideally want to check the size of a file BEFORE it is attached to a document. This translates into the need to check the filesize of a file at the file system level.
3 - Preserve whatever user-friendliness that already exists in the attachment process (I know “What user-friendliness?”). In short, when we attach files, the open file dialog should continue to open to the directory we last accessed, and not always back to the Notes Data directory.
Steps:
1 - Create a subform called “Attachments”
2 - Put the following code in the Global Declarations:
Dim ws As NotesUIWorkspace
Dim Session As NotesSession
Dim db As NotesDatabase
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim GlobalSaveFlag As Integer 'will be used to check whether document was actually saved later on
Declare Function NEMGetFile Lib “NNOTESWS” Alias “NEMGetFile” _
( zero As Integer, Byval filename As String, Byval filter As String, Byval title As String ) As Integer
3 - Put this function in the subform globals:
Function LocalBrowse(title As String, default As String, filter As String) As String
Dim filename As String*1024
filename = default
If filter = “” Then filter = “All Files|.|”
status% = NEMGetFile(0, filename, filter, title)
Select Case status%
Case 0 : LocalBrowse = “” ’ cancelled
Case 1 : LocalBrowse = Trim$(filename)
Case Else : Error 1000, “Error &H” & Hex$(status%) & " in LocalBrowse"
End Select
End Function
4 - PostOpen Event:
'Need to initialize several global variables
Set ws = New NotesUIWorkspace
Set Session = New NotesSession
Set db = Session.currentdatabase
Set uidoc = Source
Set doc = uidoc.document
5 - PostRecalc (@Functions instead of script)
@If(AttachFileName = “”; @Return(“”); “”);
@Command([EditGotoField]; “Attachments”);
@Command( [EditInsertFileAttachment] ; AttachFileName ; “0” );
FIELD AttachFileName := “”;
6 - QuerySave:
Dim DBProfile As NotesDocument 'optional - if you want to be able to configure your size limit
Dim SizeLimit as Long
GlobalSaveFlag = Continue ’ So that if anything else modifies Continue, it is detected.
Set DBProfile = db.GetProfileDocument(“DBSettings”) 'This is my generic DB Profile, but you can use whatever you want here
'Either use this Profile Document somehow to store the limit, or hard code the limit (in bytes) here
SizeLimit = DBProfile.AttachSizeLimit(0)
'SizeLimit = 1048576 '1 MB
'Let’s add up the total size of existing attachments to see if it exceeds our limit
'This script should only be necessary if a user was sneeky and used a traditional “Attach”
'command from the file menu instead of the buttons for selecting a file
If doc.AttachmentSizeTotal(0) > SizeLimit Then
Msgbox "You have exceeded the 1 MB limit on attachments. " & Chr(10) & Chr(10) & _
“Please remove attachments or compress your file(s).” , 16, “Attachment Error”
Continue = False
Exit Sub
Else
Continue = True
End If
7 - QueryClose:
'Reset the AttachFileName field if we’ve left it filled and have saved the document
'Probably redundant but just in case
If GlobalSaveFlag = True And doc.AttachFileName(0) <> “” Then
doc.AttachFileName = “”
Call doc.Save(True, False)
End If
8 - Create a button labeled “Attach File” with the following lotuscript:
Sub Click(Source As Button)
Dim NewFilename As String
Dim currentpath As String
Dim DBProfile As NotesDocument
Dim verLen As Long
Dim SizeLimit as Long
Set DBProfile = db.GetProfileDocument(“DBSettings”) 'This is my generic DB Profile, but you can use whatever you want here
'Either create this Profile Document somehow to store the limit, or hard code the limit (in bytes) here
SizeLimit = DBProfile.AttachSizeLimit(0)
'SizeLimit = 1048576 '1 MB
NewFilename = LocalBrowse(“Attach File”, “”, “”)
doc.AttachFileName = NewFileName
currentpath = Strleftback(NewFilename, "")
'This will reset the default browse directory to the one just searched
Call Session.SetEnvironmentVar( “FileDlgDirectory” , currentpath)
verLen& = Filelen(doc.AttachFileName(0)) 'the FileLen function is the real trick to all this
'Let’s add up the total size of existing attachments AND the new file selected to see if it exceeds our limit
If (verLen& + doc.AttachmentSizeTotal(0)) > SizeLimit Then
Msgbox "This file will exceed the 1 MB limit on attachments. " & Chr(10) & Chr(10) & _
“Please remove attachments or compress your file(s).” , 16, “Attachment Error”
doc.AttachFileName = “”
Else
doc.AttachmentSizeTotal = doc.AttachmentSizeTotal(0) + verLen&
End If
Call uidoc.Refresh 'triggers the postrecalc event which will complete the attachment process
End Sub
9 - Create an editable text field called “AttachFileName”. Don’t enter any formulas, and hide the field from view.
10 - Create a hidden, computed number field called “AttachmentSizeTotal” with the following formula:
REM “Do not truly recalculate this field if we're in the middle of an attachment process”;
tmp := @If(AttachFileName = “”; @Sum(@AttachmentLengths); AttachmentSizeTotal);
@If(@IsError(tmp); 0; tmp)
11 - Now create the actual Rich Text field that will store the attachments. Call this editable field “Attachments”, and deselect the “show field delimiters” checkbox (this will allow you to make it “look” like a computed field to users and help prevent them from doing the normal “File - Attach…” routine that would subvert our goals.
That’s all you need to do. Simple huh? :-). Assuming you’ve done it all correctly (and that I’ve described it correctly), the user should be able to use our button to select a file for attachment, and continue to click it until they’ve selected a file that will put them over the limit. At that point, the attachment operation will stop and they will see a warning message. So, the next time, your users try to attach a 100MB file, they won’t have to wait until after lunch to find out they did a bad thing. If they somehow manage to attach files that exceed the limit using the normal “File - Attach…” approach, the querysave will catch that situation. So to recap, the three main “breakthroughs” in this approach are as follows:
1 - Use of the NEMGetFile API function to call a normal Open File dialog
2 - Writing a value for the most recent directory to the FileDlgDirectory environment variable in the Notes.ini
3 - Using the FileLen function to check the size of a file in the user’s file system, given the filepath as input