Whatever message this page gives is out now! Go check it out!

cffile action = "upload"

Last update:
May 18, 2026

Description

Moves a file received in an upload to a directory on the server.

Syntax

<cffile 
action = "upload" 
allowedExtensions="comma-separated list of file extensions"
destination = "full pathname" 
fileField = "form field" 
accept = "MIME type|file type" 
attributes = "file attribute or list" 
mode = "permission" 
nameConflict = "behavior" 
result = "result name"
strict="true|false"
ContinueOnError = "true|false"
Errors = "variable in which the file upload errors will be stored">

See also

History

ColdFusion (2018 release) Update 3, ColdFusion (2016 release) Update 10, ColdFusion 11 Update 18: Added the attribute allowedExtensions.
ColdFusion 10: Added the attribute strict. See the History section of the main  cffile  tag page.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
allowedExtensionsOptional 
A comma-separated list of file extensions, which will be allowed for upload.
For example, .png, .jpg, or, .jpeg.
You can use "*" (star) to allow all files, except where you specify the MIME type in the accept attribute.
Values specified in the attribute allowedExtensions override the list of blocked extensions in the server or application settings.
destination
Required
 Pathname of directory in which to upload the file. If not an absolute path (starting with a drive letter and a colon, or a forward or backward slash), it is relative to the ColdFusion temporary directory, which is returned by the GetTempDirectory function.
If the destination you specify does not exist, ColdFusion creates a file with the specified destination name. For example, if you specify the destination, C:\XYZ, ColdFusion creates a file XYZ in the C: drive.
fileField
Optional
Name of form field used to select the file. Do not use number signs (#) to specify the field name. If omitted, it defaults to the name of the first file field submitted.
accept
Optional
Limits the MIME types to accept. It is a comma-delimited list. For example, the following code permits JPEG and Microsoft Word file uploads:"image/jpg,application/msword".
When strict="true"
If the mime type is specified in the accept attribute, the file does not get uploaded if the extension is blocked in the server or application settings.
When strict="false"
If you provide a file extension in the attribute accept, the extension overrides the blocked extension list in the server or application settings. The file then gets uploaded.
If you provide a MIME type in the attribute accept, and the extension of the file you are trying to upload is blocked in the Administrator/Application-level settings, the file does not get uploaded.
For example,
  • If you have blocked file type CFM in the ColdFusion Administrator and specified accept=".cfm" in the tag, and when you try uploading a CFM file, the file gets uploaded.
  • If you have blocked file type CFM in the ColdFusion Administrator and specified accept=”text/x-coldfusion” in the tag, and when you try uploading a CFM file, the file gets blocked.
Values specified in the attribute allowedExtensions overrides the list of blocked extensions in the server or application settings.
attributes
Optional
Applies to Windows. A comma-delimited list of attributes to set on the file.

If omitted, the file's attributes are maintained .Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal (if you use this option with other attributes, it is overridden by them)
mode
Optional
Applies only to UNIX and Linux. Permissions. Octal values of chmod command. Assigned to owner , group, and other, respectively, for example:
  • 644: assigns read/write permission to owner ; read permission to group and other.
  • 777: assigns read/write/execute permission to all.
nameConflict
Optional
Error
Action to take if filename is the same as that of a file in the directory.
  • Error: file is not saved. ColdFusion stops processing the page and returns an error.
  • Skip: file is not saved. This option permits custom behavior based on file properties.
  • Overwrite: replaces file .
  • MakeUnique: forms a unique filename for the upload; name is stored in the file object variable serverFile.
result
Optional
Lets you specify a name for the variable in which cffile returns the result (or status) parameters. If you do not specify a value for this attribute, cffile uses the prefix cffile . For more information, see Usage.
strict
Optional
true
strict="false"
If you provide a file extension in the attribute accept, the extension overrides the blocked extension list in the server or application settings. The file then gets uploaded.
If you provide a MIME type in the attribute accept, and the extension of the file you are trying to upload is blocked in the Administrator/Application-level settings, the file does not get uploaded.
For example,
  • If you have blocked file type CFM in the ColdFusion Administrator and specified accept=".cfm" in the tag, and when you try uploading a CFM file, the file gets uploaded.
  • If you have blocked file type CFM in the ColdFusion Administrator and specified accept=”text/x-coldfusion” in the tag, and when you try uploading a CFM file, the file gets blocked.
strict="true"
If the mime type is specified in the accept attribute, the file does not get uploaded if the extension is blocked in the server or application settings.
For example, if you have blocked file type CFM in the ColdFusion Administrator and specified accept=”text/x-coldfusion” and strict=”true”, and you try uploading a cfm file, the file does not get uploaded.
Values specified in the attribute allowedExtensions overrides the list of blocked extensions in the server or application settings.
ContinueOnErrorOptionalFalse
By default, when uploading a file fails, the remaining files will not be uploaded. If this value is set to true, file upload continues even after encountering an upload error. A file upload error happens due to the following reasons:
1. Empty file

2. Invalid file type

3. Invalid MIME or extension

4. File already exists
In the case of an upload failure, the error details will be stored in the errors attribute.
ErrorsOptionalcffile .uploadAllErrors
The name of the variable in which the file upload errors will be stored. Errors will be populated in the specified variable name when continueOnError is true .After the file upload is completed, this tag creates an array of structures that contains upload failure information for each upload failure.
The upload failure information error structure contains the following fields:
  • REASON - The reason for the failure
  • DETAIL - File upload failure detail
  • MESSAGE - A detailed message depicting the failure
  • CLIENTFILE - Name of the file uploaded from the client's system
  • CLIENTFILEEXT - Extension of the uploaded file on the client system (without a period)
  • CLIENTFILENAME - Name of the uploaded file on the client system (without an extension)
  • INVALID_FILE_TYPE - If the file mime type or extension is not in the specified accept attribute. If the reason is INVALID_FILE_TYPE, two additional keys will be available in the structure.
    • ACCEPT: list of mime types or file extensions given in the tag
    • MIMETYPE: mime type of the uploaded file
  • EMPTY_FILE - If the uploaded file is an empty file
  • FILE_EXISTS - If any file with the given name already exists in the destination and the overwritepolicy is error .
  • DEST - The destination where file is copied
  • FORM_FILE_NOT_FOUND - If the uploaded file is not found on the server
Warning:
If you upload a file with zero bytes, there is no exception. Instead, the file gets uploaded to the server. By default, uploading an empty file will not produce an error. You can, however, disallow this by changing the property, coldfusion.file.upload.disallowemptyfileupload, to TRUE.

Usage

After a file upload is completed, you can get status information using file upload parameters. To refer to parameters, use either the cffile prefix or, if you specified an alternate name in the result attribute, the name you specified there. For example, if you did not specify a name in the result attribute, access the fileExisted parameter as #cffile.fileExisted#. If you set the result attribute to myResult, however, access fileExisted as #myResult.fileExisted#. Status parameters can be used anywhere that other ColdFusion parameters can be used. When you use a cfform tag or an HTML form tag to submit the form with the file to be uploaded, specify enctype="multipart/form-data" in the tag, as shown in the example for this tag. By default, ColdFusion sends the form with the encoding type of application/x-www-form-urlencoded, which causes an error in the cffile tag.
Note:
The result attribute allows functions or CFCs that get called from multiple pages at the same time to avoid overwriting the results of one call with another.
Note:
The file prefix is deprecated, in favor of the cffile prefix. Do not use the file prefix in new applications.
Note:
If your page is uploading a file that was selected on a form or was otherwise sent to your page via a multipart/form-data HTTP message, you can determine the approximate size of the file by checking the value of the CGI.content_length variable. This variable includes the file length plus the length of any other request content.
The following file upload status parameters are available after an upload:
Parameter
Description
attemptedServerFile
Initial name ColdFusion used when attempting to save a file
clientDirectory
Directory location of the file uploaded from the client's system
clientFile
Name of the file uploaded from the client's system
clientFileExt
Extension of the uploaded file on the client system (without a period)
clientFileName
Name of the uploaded file on the client system (without an extension)
contentSubType
MIME content subtype of the saved file
contentType
MIME content type of the saved file
dateLastAccessed
Date and time the uploaded file was last accessed
fileExisted
Whether the file existed with the same path (yes or no)
fileSize
Size of the uploaded file in bytes
fileWasAppended
Whether ColdFusion appended uploaded file to a file (yes or no)
fileWasOverwritten
Whether ColdFusion overwrote a file (yes or no)
fileWasRenamed
Whether uploaded file renamed to avoid a name conflict (yes or no)
fileWasSaved
Whether ColdFusion saves a file (yes or no)
oldFileSize
Size of a file that was overwritten in the file upload operation
serverDirectory
Directory of the file saved on the server
serverFile
Filename of the file saved on the server
serverFileExt
Extension of the uploaded file on the server (without a period)
serverFileName
Name of the uploaded file on the server (without an extension)
timeCreated
Time the uploaded file was created
timeLastModified
Date and time of the last modification to the uploaded file
Note:
File status parameters are read-only. They are set to the results of the most recent cffile operation. If two cffile tags execute, the results of the second overwrite the first, unless you have specified a different result variable in the result attribute.

Example

The following example creates a unique filename, if there is a name conflict when the file is uploaded on Windows:
<!--- Windows Example ---> 
<!--- Check to see if the Form variable exists. ---> 
<cfif isDefined("Form.FileContents") > 
<!--- If TRUE, upload the file. ---> 
<cffile action = "upload" 
fileField = "FileContents" 
destination = "c:\files\upload\" 
accept = "text/html" 
nameConflict = "MakeUnique"> 
<cfelse> 
<!--- If FALSE, show the Form. ---> 
<form method="post" action=<cfoutput>#cgi.script_name#</cfoutput> 
name="uploadForm" enctype="multipart/form-data"> 
<input name="FileContents" type="file"> 
<br> 
<input name="submit" type="submit" value="Upload File"> 
</form> 
</cfif>
Example with attribute allowedExtensions.
<cffile 
        action="upload"  
        destination="#expandpath(".")#" 
        nameconflict="MakeUnique" 
        accept="image/png, image/gif" 
        allowedextensions=".png, .gif" 
        strict="true"  
        continueonerror="true"
>

Real-world uses of the cffile action="upload" attribute

Employee document upload

Human Resources departments in modern organizations need a centralized system to collect, store, and manage critical employee documentation throughout the employment lifecycle. This includes onboarding materials, performance reviews, certifications, and compliance-related documents that must be securely stored and easily retrievable for audits or employee requests.
Problem statement
  • Manual document collection via email attachments creates version control issues and security risks
  • Inconsistent file naming conventions make documents difficult to locate and organize
  • Large file sizes can overwhelm email systems and create storage inefficiencies
  • Lack of upload validation allows corrupt or inappropriate file formats into the system
Solution
The action="upload" attribute implements a secure HR document upload system that accepts only PDF and Word documents with a 5MB size limit to ensure compatibility with document management systems. The solution automatically generates unique filenames to prevent overwrites, provides detailed upload status reporting for transparency, and tracks comprehensive metadata including file size, upload timestamp, and whether files were renamed due to conflicts, giving HR staff complete visibility into the document submission process.
<cfset maxFileSize = 5242880><!--- 5MB in bytes --->
<cfset uploadStatus = {}>

<!--- Check if file was submitted --->
<cfif structKeyExists(form, "employeeDocument")>
    <cftry>
        <!--- Upload the file --->
        <cffile 
            action="upload" 
            fileField="employeeDocument" 
            destination="#expandPath('./uploads/employees/')#" 
            nameConflict="makeUnique"
            accept="application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            result="uploadResult"
            mode="644">
        
        <!--- Validate file size after upload --->
        <cfif uploadResult.fileSize GT maxFileSize>
            <!--- Delete the uploaded file if too large --->
            <cfif fileExists("#uploadResult.serverDirectory#/#uploadResult.serverFile#")>
                <cffile action="delete" file="#uploadResult.serverDirectory#/#uploadResult.serverFile#">
            </cfif>
            <cfset uploadStatus.success = false>
            <cfset uploadStatus.message = "File size exceeds 5MB limit. Please upload a smaller file.">
        <cfelse>
            <!--- Process successful upload --->
            <cfset uploadStatus.success = true>
            <cfset uploadStatus.originalFileName = uploadResult.clientFile>
            <cfset uploadStatus.savedFileName = uploadResult.serverFile>
            <cfset uploadStatus.fileSize = numberFormat(uploadResult.fileSize / 1024, "0.00")>
            <cfset uploadStatus.uploadDate = dateTimeFormat(now(), "yyyy-mm-dd HH:nn:ss")>
            
            <!--- Log to database (simulated) --->
            <cfset uploadStatus.message = "Document uploaded successfully">
            
            <!--- If file was renamed due to conflict --->
            <cfif uploadResult.fileWasRenamed>
                <cfset uploadStatus.warning = "File was renamed to avoid naming conflict">
            </cfif>
        </cfif>
        
        <cfcatch type="any">
            <cfset uploadStatus.success = false>
            <cfset uploadStatus.message = "Upload failed: #cfcatch.message#">
        </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <title>Employee Document Upload</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        .form-container { background: #f5f5f5; padding: 20px; border-radius: 8px; }
        .success { background: #d4edda; color: #155724; padding: 15px; border-radius: 5px; margin: 20px 0; }
        .error { background: #f8d7da; color: #721c24; padding: 15px; border-radius: 5px; margin: 20px 0; }
        .warning { background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px; margin: 10px 0; }
        .form-group { margin-bottom: 15px; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input[type="file"] { padding: 10px; width: 100%; box-sizing: border-box; }
        button { background: #007bff; color: white; padding: 12px 30px; border: none; 
                 border-radius: 5px; cursor: pointer; font-size: 16px; }
        button:hover { background: #0056b3; }
        .info-box { background: #e7f3ff; padding: 15px; border-left: 4px solid #007bff; margin-bottom: 20px; }
        .detail-row { padding: 5px 0; border-bottom: 1px solid #ddd; }
    </style>
</head>
<body>
    <h1>📄 Employee Document Upload</h1>
    
    <div class="info-box">
        <strong>Accepted Formats:</strong> PDF, DOC, DOCX<br>
        <strong>Maximum Size:</strong> 5 MB
    </div>
    
    <!--- Display upload status --->
    <cfif structKeyExists(uploadStatus, "success")>
        <cfif uploadStatus.success>
            <div class="success">
                <h3>✓ #uploadStatus.message#</h3>
                <div class="detail-row"><strong>Original Filename:</strong> #uploadStatus.originalFileName#</div>
                <div class="detail-row"><strong>Saved As:</strong> #uploadStatus.savedFileName#</div>
                <div class="detail-row"><strong>File Size:</strong> #uploadStatus.fileSize# KB</div>
                <div class="detail-row"><strong>Upload Time:</strong> #uploadStatus.uploadDate#</div>
                <cfif structKeyExists(uploadStatus, "warning")>
                    <div class="warning">⚠ #uploadStatus.warning#</div>
                </cfif>
            </div>
        <cfelse>
            <div class="error">
                <strong>✗ Upload Failed</strong><br>
                #uploadStatus.message#
            </div>
        </cfif>
    </cfif>
    
    <div class="form-container">
        <h2>Upload Employee Document</h2>
        <form method="post" enctype="multipart/form-data">
            <div class="form-group">
                <label for="employeeDocument">Select Document:</label>
                <input type="file" name="employeeDocument" id="employeeDocument" required>
            </div>
            <div class="form-group">
                <button type="submit">Upload Document</button>
            </div>
        </form>
    </div>
    
    <p style="color: #666; font-size: 12px; margin-top: 20px;">
        <strong>Note for CFFiddle:</strong> This demonstrates upload validation and status reporting. 
        Actual file system operations may be restricted in the sandbox environment.
    </p>
</body>
</html>

Social media platform- User profile management

Social media and professional networking platforms require robust profile image upload functionality that balances user experience with security. Profile pictures are often the first impression users make, and the upload process must be smooth while protecting the platform from malicious files disguised as images that could compromise system security or expose other users to threats.
Problem statement
  • Malicious users may attempt to upload executable files disguised with image extensions (.jpg.exe)
  • Large image files slow down page load times and consume excessive storage and bandwidth
  • MIME type spoofing allows attackers to bypass basic file type validation
  • Multiple profile pictures per user create confusion about which image is current
Solution
The action="upload" attribute implements strict security validation using both MIME type checking and extension whitelisting in strict mode, ensuring only legitimate JPG, PNG, and GIF images are accepted. The system enforces a 2MB size limit for optimal performance, automatically renames uploaded files based on user ID for easy retrieval, and uses overwrite mode to ensure users maintain only one current profile picture.
<cfset maxImageSize = 2097152><!--- 2MB limit for images --->
<cfset userId = randRange(1000, 9999)><!--- Simulated user session --->
<cfset uploadResult = {}>

<cfif structKeyExists(form, "profileImage")>
    <cftry>
        <!--- Upload with strict security settings --->
        <cffile 
            action="upload" 
            fileField="profileImage" 
            destination="#expandPath('./uploads/profiles/')#" 
            nameConflict="overwrite"
            accept="image/jpeg,image/png,image/gif"
            allowedExtensions=".jpg,.jpeg,.png,.gif"
            strict="true"
            result="fileUpload">
        
        <!--- Validate file size after upload --->
        <cfif fileUpload.fileSize GT maxImageSize>
            <!--- Delete the uploaded file if too large --->
            <cfif fileExists("#fileUpload.serverDirectory#/#fileUpload.serverFile#")>
                <cffile action="delete" file="#fileUpload.serverDirectory#/#fileUpload.serverFile#">
            </cfif>
            <cfset uploadResult.status = "error">
            <cfset uploadResult.message = "Image size must be under 2MB">
        <cfelse>
            <!--- Rename file to user-specific name --->
            <cfset newFileName = "user_#userId#_profile.#fileUpload.serverFileExt#">
            <cffile 
                action="rename"
                source="#fileUpload.serverDirectory#/#fileUpload.serverFile#"
                destination="#fileUpload.serverDirectory#/#newFileName#">
            
            <!--- Build success response --->
            <cfset uploadResult.status = "success">
            <cfset uploadResult.message = "Profile image updated successfully!">
            <cfset uploadResult.fileName = newFileName>
            <cfset uploadResult.fileSize = numberFormat(fileUpload.fileSize / 1024, "0.00")>
            <cfset uploadResult.imageType = fileUpload.contentType>
            <cfset uploadResult.originalName = fileUpload.clientFile>
            <cfset uploadResult.wasOverwritten = fileUpload.fileWasOverwritten>
        </cfif>
        
        <cfcatch type="any">
            <cfset uploadResult.status = "error">
            <cfif findNoCase("invalid MIME type", cfcatch.message)>
                <cfset uploadResult.message = "Invalid file type. Please upload a valid image (JPG, PNG, or GIF)">
            <cfelseif findNoCase("extension", cfcatch.message)>
                <cfset uploadResult.message = "File extension not allowed. Only .jpg, .png, and .gif files are accepted">
            <cfelse>
                <cfset uploadResult.message = "Upload error: #cfcatch.message#">
            </cfif>
        </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <title>Profile Image Upload</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
               background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
               min-height: 100vh; padding: 20px; }
        .container { max-width: 500px; margin: 50px auto; background: white; 
                     border-radius: 15px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); overflow: hidden; }
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
                  color: white; padding: 30px; text-align: center; }
        .header h1 { font-size: 24px; margin-bottom: 5px; }
        .header p { opacity: 0.9; font-size: 14px; }
        .content { padding: 30px; }
        .profile-preview { text-align: center; margin-bottom: 25px; }
        .avatar { width: 120px; height: 120px; border-radius: 50%; border: 4px solid #667eea; 
                  background: #f0f0f0; display: inline-flex; align-items: center; 
                  justify-content: center; font-size: 48px; }
        .upload-area { border: 2px dashed #667eea; border-radius: 10px; padding: 30px; 
                       text-align: center; background: #f8f9ff; margin-bottom: 20px; }
        .upload-area:hover { background: #f0f3ff; }
        input[type="file"] { display: none; }
        .file-label { background: #667eea; color: white; padding: 12px 25px; 
                      border-radius: 25px; cursor: pointer; display: inline-block; 
                      transition: all 0.3s; }
        .file-label:hover { background: #5568d3; transform: translateY(-2px); }
        button { width: 100%; background: #764ba2; color: white; padding: 15px; 
                 border: none; border-radius: 8px; font-size: 16px; cursor: pointer; 
                 font-weight: bold; transition: all 0.3s; }
        button:hover { background: #653a8c; transform: translateY(-2px); 
                       box-shadow: 0 5px 15px rgba(118,75,162,0.3); }
        .alert { padding: 15px; border-radius: 8px; margin-bottom: 20px; }
        .alert-success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
        .alert-error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
        .detail { display: flex; justify-content: space-between; padding: 10px 0; 
                  border-bottom: 1px solid #eee; }
        .detail:last-child { border-bottom: none; }
        .detail strong { color: #667eea; }
        .info-text { color: #666; font-size: 13px; text-align: center; margin-top: 15px; }
        .badge { display: inline-block; padding: 3px 10px; border-radius: 12px; 
                 font-size: 11px; font-weight: bold; }
        .badge-new { background: #28a745; color: white; }
        .badge-replaced { background: #ffc107; color: #000; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>👤 Profile Image Upload</h1>
            <p>User ID: #userId#</p>
        </div>
        
        <div class="content">
            <div class="profile-preview">
                <div class="avatar">
                    <cfif structKeyExists(uploadResult, "status") AND uploadResult.status EQ "success">
                        📸
                    <cfelse>
                        👤
                    </cfif>
                </div>
            </div>
            
            <!--- Display upload results --->
            <cfif structKeyExists(uploadResult, "status")>
                <cfif uploadResult.status EQ "success">
                    <div class="alert alert-success">
                        <strong>✓ #uploadResult.message#</strong>
                        <div style="margin-top: 15px;">
                            <div class="detail">
                                <span>Saved As:</span>
                                <strong>#uploadResult.fileName#</strong>
                            </div>
                            <div class="detail">
                                <span>Original Name:</span>
                                <span>#uploadResult.originalName#</span>
                            </div>
                            <div class="detail">
                                <span>File Size:</span>
                                <span>#uploadResult.fileSize# KB</span>
                            </div>
                            <div class="detail">
                                <span>Image Type:</span>
                                <span>#uploadResult.imageType#</span>
                            </div>
                            <div class="detail">
                                <span>Status:</span>
                                <cfif uploadResult.wasOverwritten>
                                    <span class="badge badge-replaced">REPLACED</span>
                                <cfelse>
                                    <span class="badge badge-new">NEW</span>
                                </cfif>
                            </div>
                        </div>
                    </div>
                <cfelse>
                    <div class="alert alert-error">
                        <strong>✗ Upload Failed</strong><br>
                        #uploadResult.message#
                    </div>
                </cfif>
            </cfif>
            
            <form method="post" enctype="multipart/form-data">
                <div class="upload-area">
                    <p style="margin-bottom: 15px; color: #667eea; font-weight: bold;">
                        📁 Choose Your Profile Image
                    </p>
                    <label for="profileImage" class="file-label">Select Image File</label>
                    <input type="file" name="profileImage" id="profileImage" accept="image/jpeg,image/png,image/gif" required>
                    <p class="info-text">JPG, PNG or GIF • Max 2MB</p>
                </div>
                
                <button type="submit">🚀 Upload Profile Image</button>
            </form>
            
            <p class="info-text" style="margin-top: 20px;">
                <strong>Security Features:</strong> MIME type validation, extension whitelist, 
                size limits enforced
            </p>
        </div>
    </div>
</body>
</html>

Invoice processing and management

Accounts Payable departments in enterprise organizations process thousands of vendor invoices monthly, requiring a system that maintains regulatory compliance, supports automated OCR processing for data extraction, and provides complete audit trails for financial reviews. The system must handle batch uploads efficiently while ensuring every transaction is documented for SOX compliance, tax audits, and dispute resolution.
Problem statement
  • Manual invoice entry is time-consuming and error-prone, delaying payment processing
  • Multiple file formats complicate automated OCR and data extraction workflows
  • One failed upload in a batch shouldn't halt processing of the remaining valid invoices
  • Lack of audit trails creates compliance risks during financial audits
  • File tampering concerns require proof of document integrity
Solution
The action="upload" attribute implements a compliance-focused invoice processing system that accepts only PDF format for OCR compatibility and uses continueOnError mode to process entire batches even when individual files fail validation.
<cfset uploadResults = []>
<cfset batchSummary = {
    totalAttempted = 0,
    successful = 0,
    failed = 0,
    totalSize = 0
}>

<cfif structKeyExists(form, "invoiceFile")>
    <!--- Handle single or multiple file uploads --->
    <cfset fileCount = 1>
    
    <cftry>
        <!--- Upload invoice with strict validation --->
        <cffile 
            action="upload" 
            fileField="invoiceFile" 
            destination="#expandPath('./uploads/invoices/')#" 
            nameConflict="makeUnique"
            accept="application/pdf"
            allowedExtensions=".pdf"
            strict="true"
            continueOnError="true"
            result="uploadData">
        
        <cfset batchSummary.totalAttempted++>
        
        <!--- Check if upload was successful --->
        <cfif uploadData.fileWasSaved>
            <!--- Generate invoice tracking number --->
            <cfset invoiceId = "INV-#dateFormat(now(), 'yyyymmdd')#-#randRange(1000, 9999)#">
            
            <!--- Create audit record --->
            <cfset auditRecord = {
                status = "success",
                invoiceId = invoiceId,
                originalFileName = uploadData.clientFile,
                savedFileName = uploadData.serverFile,
                fileSize = uploadData.fileSize,
                uploadTimestamp = now(),
                uploadedBy = "system_user",
                fileHash = hash(uploadData.serverFile, "MD5"),
                wasRenamed = uploadData.fileWasRenamed
            }>
            
            <cfset arrayAppend(uploadResults, auditRecord)>
            <cfset batchSummary.successful++>
            <cfset batchSummary.totalSize += uploadData.fileSize>
        <cfelse>
            <!--- Handle failed upload --->
            <cfset errorRecord = {
                status = "failed",
                originalFileName = form.invoiceFile,
                errorMessage = "File was not saved - validation failed",
                timestamp = now()
            }>
            <cfset arrayAppend(uploadResults, errorRecord)>
            <cfset batchSummary.failed++>
        </cfif>
        
        <cfcatch type="any">
            <!--- Log error but continue processing --->
            <cfset batchSummary.totalAttempted++>
            <cfset errorRecord = {
                status = "error",
                originalFileName = "Unknown",
                errorMessage = cfcatch.message,
                errorDetail = cfcatch.detail,
                timestamp = now()
            }>
            <cfset arrayAppend(uploadResults, errorRecord)>
            <cfset batchSummary.failed++>
        </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <title>Invoice Processing System</title>
    <style>
        body { font-family: 'Arial', sans-serif; background: #f4f4f4; padding: 20px; }
        .container { max-width: 900px; margin: 0 auto; background: white; 
                     border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.1); }
        .header { background: #2c3e50; color: white; padding: 25px; border-radius: 10px 10px 0 0; }
        .header h1 { margin: 0; font-size: 28px; }
        .header p { margin: 5px 0 0 0; opacity: 0.8; }
        .content { padding: 30px; }
        .summary-cards { display: grid; grid-template-columns: repeat(3, 1fr); 
                         gap: 15px; margin-bottom: 30px; }
        .card { background: #ecf0f1; padding: 20px; border-radius: 8px; text-align: center; }
        .card.success { background: #d5f4e6; border-left: 4px solid #27ae60; }
        .card.error { background: #fadbd8; border-left: 4px solid #e74c3c; }
        .card.info { background: #d6eaf8; border-left: 4px solid #3498db; }
        .card h3 { margin: 0 0 10px 0; font-size: 32px; color: #2c3e50; }
        .card p { margin: 0; color: #7f8c8d; font-size: 14px; }
        .upload-form { background: #f8f9fa; padding: 25px; border-radius: 8px; 
                       border: 2px solid #dee2e6; margin-bottom: 30px; }
        .form-group { margin-bottom: 15px; }
        label { display: block; margin-bottom: 8px; font-weight: bold; color: #2c3e50; }
        input[type="file"] { padding: 10px; width: 100%; border: 1px solid #ccc; 
                             border-radius: 5px; background: white; }
        button { background: #27ae60; color: white; padding: 12px 30px; border: none; 
                 border-radius: 5px; cursor: pointer; font-size: 16px; font-weight: bold; }
        button:hover { background: #229954; }
        .audit-trail { margin-top: 30px; }
        .audit-trail h2 { color: #2c3e50; margin-bottom: 20px; padding-bottom: 10px; 
                          border-bottom: 2px solid #3498db; }
        .audit-record { background: #f8f9fa; padding: 15px; border-radius: 8px; 
                        margin-bottom: 15px; border-left: 4px solid #3498db; }
        .audit-record.failed { border-left-color: #e74c3c; background: #fadbd8; }
        .audit-detail { display: grid; grid-template-columns: 200px 1fr; gap: 10px; 
                        font-size: 14px; margin-top: 10px; }
        .audit-detail strong { color: #2c3e50; }
        .status-badge { display: inline-block; padding: 4px 12px; border-radius: 12px; 
                        font-size: 12px; font-weight: bold; text-transform: uppercase; }
        .status-badge.success { background: #27ae60; color: white; }
        .status-badge.failed { background: #e74c3c; color: white; }
        .requirements { background: #fff3cd; padding: 15px; border-radius: 5px; 
                        border-left: 4px solid #ffc107; margin-bottom: 20px; }
        .requirements ul { margin: 10px 0; padding-left: 20px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🧾 Invoice Processing System</h1>
            <p>Vendor Invoice Upload & Audit Trail Management</p>
        </div>
        
        <div class="content">
            <!--- Display batch summary if uploads were processed --->
            <cfif batchSummary.totalAttempted GT 0>
                <div class="summary-cards">
                    <div class="card info">
                        <h3>#batchSummary.totalAttempted#</h3>
                        <p>Total Attempted</p>
                    </div>
                    <div class="card success">
                        <h3>#batchSummary.successful#</h3>
                        <p>Successfully Processed</p>
                    </div>
                    <div class="card error">
                        <h3>#batchSummary.failed#</h3>
                        <p>Failed Uploads</p>
                    </div>
                </div>
                
                <cfif batchSummary.successful GT 0>
                    <div style="background: #d5f4e6; padding: 15px; border-radius: 5px; margin-bottom: 20px;">
                        <strong>✓ Batch Processing Complete</strong><br>
                        Total data uploaded: #numberFormat(batchSummary.totalSize / 1024, "0.00")# KB<br>
                        Processing time: #dateTimeFormat(now(), "HH:nn:ss")#
                    </div>
                </cfif>
            </cfif>
            
            <div class="requirements">
                <strong>📋 Invoice Upload Requirements:</strong>
                <ul>
                    <li>File Format: PDF only (for OCR processing compatibility)</li>
                    <li>Strict validation enforced for security compliance</li>
                    <li>Automatic unique naming to prevent duplicates</li>
                    <li>Complete audit trail maintained for all uploads</li>
                </ul>
            </div>
            
            <div class="upload-form">
                <h2 style="margin-top: 0; color: #2c3e50;">📤 Upload New Invoice</h2>
                <form method="post" enctype="multipart/form-data">
                    <div class="form-group">
                        <label for="invoiceFile">Select PDF Invoice:</label>
                        <input type="file" name="invoiceFile" id="invoiceFile" 
                               accept="application/pdf,.pdf" required>
                    </div>
                    <button type="submit">Process Invoice Upload</button>
                </form>
            </div>
            
            <!--- Display audit trail --->
            <cfif arrayLen(uploadResults) GT 0>
                <div class="audit-trail">
                    <h2>📊 Upload Audit Trail</h2>
                    
                    <cfloop array="#uploadResults#" index="record">
                        <div class="audit-record <cfif record.status NEQ 'success'>failed</cfif>">
                            <div>
                                <span class="status-badge #record.status#">#record.status#</span>
                                <cfif record.status EQ "success">
                                    <strong style="margin-left: 10px; color: #2c3e50;">
                                        Invoice ID: #record.invoiceId#
                                    </strong>
                                </cfif>
                            </div>
                            
                            <div class="audit-detail">
                                <cfif record.status EQ "success">
                                    <strong>Original Filename:</strong>
                                    <span>#record.originalFileName#</span>
                                    
                                    <strong>Stored As:</strong>
                                    <span>#record.savedFileName#</span>
                                    
                                    <strong>File Size:</strong>
                                    <span>#numberFormat(record.fileSize / 1024, "0.00")# KB</span>
                                    
                                    <strong>Upload Timestamp:</strong>
                                    <span>#dateTimeFormat(record.uploadTimestamp, "yyyy-mm-dd HH:nn:ss")#</span>
                                    
                                    <strong>File Hash (MD5):</strong>
                                    <span style="font-family: monospace; font-size: 11px;">#record.fileHash#</span>
                                    
                                    <strong>Uploaded By:</strong>
                                    <span>#record.uploadedBy#</span>
                                    
                                    <strong>Filename Modified:</strong>
                                    <span>#yesNoFormat(record.wasRenamed)#</span>
                                <cfelse>
                                    <strong>Error:</strong>
                                    <span style="color: #e74c3c;">#record.errorMessage#</span>
                                    
                                    <strong>Timestamp:</strong>
                                    <span>#dateTimeFormat(record.timestamp, "yyyy-mm-dd HH:nn:ss")#</span>
                                    
                                    <cfif structKeyExists(record, "errorDetail")>
                                        <strong>Details:</strong>
                                        <span style="font-size: 12px;">#record.errorDetail#</span>
                                    </cfif>
                                </cfif>
                            </div>
                        </div>
                    </cfloop>
                </div>
            </cfif>
            
            <div style="margin-top: 30px; padding: 15px; background: #ecf0f1; border-radius: 5px; font-size: 12px; color: #7f8c8d;">
                <strong>Note:</strong> All invoice uploads are logged for compliance and audit purposes. 
                The continueOnError setting ensures batch processing continues even if individual files fail validation.
            </div>
        </div>
    </div>
</body>
</html>

Customer support ticketing system

Customer support operations rely heavily on visual aids and technical files to diagnose and resolve issues efficiently. Users need the ability to attach screenshots showing errors, log files containing diagnostic data, PDF documentation, and compressed archives of multiple related files. The system must handle diverse file types while organizing attachments by ticket for quick reference by support agents resolving customer issues.
Problem statement
  • Support agents waste time requesting additional information when attachments are unclear or missing
  • Restricting to single file types prevents users from submitting the necessary diagnostic files
  • Large attachment files overwhelm email systems and storage infrastructure
  • Unorganized attachments make it difficult to locate relevant files for specific tickets
  • Manual file categorization is time-consuming for support staff reviewing tickets
Solution
The "upload" action implements a versatile attachment system that supports multiple file formats, including images (JPG, PNG, GIF), documents (PDF), logs (TXT, LOG), and archives (ZIP), with a maximum size of 10MB, accommodating most troubleshooting scenarios. The solution automatically categorizes and assigns visual icons to each file type based on MIME detection, organizes all attachments by unique ticket ID for efficient retrieval, and provides detailed upload reporting with file metadata.
<cfset ticketId = "TKT-#dateFormat(now(), 'yyyymmdd')#-#randRange(100, 999)#">
<cfset maxAttachmentSize = 10485760><!--- 10MB --->
<cfset uploadReport = {
    ticketId = ticketId,
    attachments = [],
    errors = []
}>

<cfif structKeyExists(form, "attachment")>
    <cftry>
        <!--- Upload attachment --->
        <cffile 
            action="upload" 
            fileField="attachment" 
            destination="#expandPath('./uploads/tickets/#ticketId#/')#" 
            nameConflict="makeUnique"
            accept="image/jpeg,image/png,image/gif,application/pdf,text/plain,application/zip,application/x-zip-compressed"
            allowedExtensions=".jpg,.jpeg,.png,.gif,.pdf,.txt,.log,.zip"
            result="fileResult"
            mode="644">
        
        <!--- Validate file size after upload --->
        <cfif fileResult.fileSize GT maxAttachmentSize>
            <!--- Delete the uploaded file if too large --->
            <cfif fileExists("#fileResult.serverDirectory#/#fileResult.serverFile#")>
                <cffile action="delete" file="#fileResult.serverDirectory#/#fileResult.serverFile#">
            </cfif>
            <cfset arrayAppend(uploadReport.errors, {
                type = "size",
                message = "File exceeds 10MB limit",
                size = numberFormat(fileResult.fileSize / 1048576, "0.00") & " MB"
            })>
        <cfelse>
            <!--- Build attachment record --->
            <cfset attachmentInfo = {
                fileName = fileResult.serverFile,
                originalName = fileResult.clientFile,
                fileSize = fileResult.fileSize,
                mimeType = fileResult.contentType,
                extension = fileResult.serverFileExt,
                uploadedAt = now(),
                wasRenamed = fileResult.fileWasRenamed,
                status = "uploaded"
            }>
            
            <!--- Determine file category --->
            <cfswitch expression="#fileResult.contentSubType#">
                <cfcase value="jpeg,png,gif">
                    <cfset attachmentInfo.category = "Screenshot">
                    <cfset attachmentInfo.icon = "🖼️">
                </cfcase>
                <cfcase value="pdf">
                    <cfset attachmentInfo.category = "Document">
                    <cfset attachmentInfo.icon = "📄">
                </cfcase>
                <cfcase value="plain">
                    <cfset attachmentInfo.category = "Log File">
                    <cfset attachmentInfo.icon = "📝">
                </cfcase>
                <cfcase value="zip,x-zip-compressed">
                    <cfset attachmentInfo.category = "Archive">
                    <cfset attachmentInfo.icon = "📦">
                </cfcase>
                <cfdefaultcase>
                    <cfset attachmentInfo.category = "Other">
                    <cfset attachmentInfo.icon = "📎">
                </cfdefaultcase>
            </cfswitch>
            
            <cfset arrayAppend(uploadReport.attachments, attachmentInfo)>
        </cfif>
        
        <cfcatch type="any">
            <cfset arrayAppend(uploadReport.errors, {
                type = "upload",
                message = cfcatch.message,
                detail = cfcatch.detail
            })>
        </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <title>Support Ticket Attachments</title>
    <style>
        * { box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; 
               background: #f0f2f5; margin: 0; padding: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .ticket-header { background: white; padding: 25px; border-radius: 10px; 
                         box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 20px; }
        .ticket-id { font-size: 24px; color: #1c1e21; margin: 0 0 5px 0; }
        .ticket-meta { color: #65676b; font-size: 14px; }
        .upload-section { background: white; padding: 25px; border-radius: 10px; 
                          box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 20px; }
        .upload-zone { border: 2px dashed #dadde1; border-radius: 8px; padding: 40px; 
                       text-align: center; background: #f7f8fa; margin-bottom: 20px; }
        .upload-zone:hover { border-color: #1877f2; background: #e7f3ff; }
        input[type="file"] { display: none; }
        .file-label { background: #1877f2; color: white; padding: 12px 24px; 
                      border-radius: 6px; cursor: pointer; display: inline-block; 
                      font-weight: 600; transition: all 0.2s; }
        .file-label:hover { background: #166fe5; }
        button { background: #42b72a; color: white; padding: 12px 24px; border: none; 
                 border-radius: 6px; font-size: 15px; font-weight: 600; cursor: pointer; 
                 width: 100%; transition: all 0.2s; }
        button:hover { background: #36a420; }
        .attachments-list { background: white; padding: 25px; border-radius: 10px; 
                            box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
        .attachment-item { display: flex; align-items: center; padding: 15px; 
                           background: #f7f8fa; border-radius: 8px; margin-bottom: 10px; 
                           border-left: 4px solid #1877f2; }
        .attachment-icon { font-size: 32px; margin-right: 15px; }
        .attachment-info { flex: 1; }
        .attachment-name { font-weight: 600; color: #1c1e21; margin-bottom: 5px; }
        .attachment-meta { font-size: 13px; color: #65676b; }
        .badge { display: inline-block; padding: 3px 8px; border-radius: 4px; 
                 font-size: 11px; font-weight: 600; margin-left: 8px; }
        .badge-category { background: #e4e6eb; color: #050505; }
        .badge-renamed { background: #fff3cd; color: #856404; }
        .alert { padding: 15px; border-radius: 8px; margin-bottom: 15px; }
        .alert-success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
        .alert-error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
        .supported-formats { background: #e7f3ff; padding: 15px; border-radius: 8px; 
                             border-left: 4px solid #1877f2; margin-bottom: 20px; }
        .supported-formats h4 { margin: 0 0 10px 0; color: #1877f2; }
        .format-grid { display: grid; grid-template-columns: repeat(2, 1fr); 
                       gap: 8px; font-size: 14px; }
        .format-item { padding: 8px; background: white; border-radius: 4px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="ticket-header">
            <h1 class="ticket-id">🎫 Support Ticket: #ticketId#</h1>
            <div class="ticket-meta">
                Created: #dateTimeFormat(now(), "mmmm d, yyyy 'at' h:nn tt")# | 
                Status: <strong>Open</strong>
            </div>
        </div>
        
        <!--- Display upload results --->
        <cfif arrayLen(uploadReport.attachments) GT 0>
            <div class="alert alert-success">
                <strong>✓ Attachment Uploaded Successfully</strong><br>
                Your file has been attached to this support ticket and our team will review it.
            </div>
        </cfif>
        
        <cfif arrayLen(uploadReport.errors) GT 0>
            <div class="alert alert-error">
                <strong>✗ Upload Error</strong><br>
                <cfloop array="#uploadReport.errors#" index="error">
                    #error.message#
                    <cfif structKeyExists(error, "size")>
                        (File size: #error.size#)
                    </cfif>
                    <cfif structKeyExists(error, "detail")>
                        <br><small>#error.detail#</small>
                    </cfif>
                </cfloop>
            </div>
        </cfif>
        
        <div class="upload-section">
            <h2 style="margin-top: 0; color: #1c1e21;">📎 Add Attachment</h2>
            
            <div class="supported-formats">
                <h4>Supported File Types:</h4>
                <div class="format-grid">
                    <div class="format-item">🖼️ Images: JPG, PNG, GIF</div>
                    <div class="format-item">📄 Documents: PDF</div>
                    <div class="format-item">📝 Logs: TXT, LOG</div>
                    <div class="format-item">📦 Archives: ZIP</div>
                </div>
                <p style="margin: 10px 0 0 0; font-size: 13px; color: #65676b;">
                    Maximum file size: 10 MB
                </p>
            </div>
            
            <form method="post" enctype="multipart/form-data">
                <div class="upload-zone">
                    <p style="font-size: 18px; color: #65676b; margin-bottom: 15px;">
                        Drop a file or click to browse
                    </p>
                    <label for="attachment" class="file-label">Choose File</label>
                    <input type="file" name="attachment" id="attachment" 
                           accept=".jpg,.jpeg,.png,.gif,.pdf,.txt,.log,.zip" required>
                </div>
                <button type="submit">📤 Upload Attachment</button>
            </form>
        </div>
        
        <!--- Display attachments list --->
        <cfif arrayLen(uploadReport.attachments) GT 0>
            <div class="attachments-list">
                <h2 style="margin-top: 0; color: #1c1e21;">Attached Files</h2>
                
                <cfloop array="#uploadReport.attachments#" index="attachment">
                    <div class="attachment-item">
                        <div class="attachment-icon">#attachment.icon#</div>
                        <div class="attachment-info">
                            <div class="attachment-name">
                                #attachment.originalName#
                                <span class="badge badge-category">#attachment.category#</span>
                                <cfif attachment.wasRenamed>
                                    <span class="badge badge-renamed">RENAMED</span>
                                </cfif>
                            </div>
                            <div class="attachment-meta">
                                <strong>Saved as:</strong> #attachment.fileName# | 
                                <strong>Size:</strong> #numberFormat(attachment.fileSize / 1024, "0.00")# KB | 
                                <strong>Type:</strong> #attachment.mimeType# | 
                                <strong>Uploaded:</strong> #timeFormat(attachment.uploadedAt, "h:nn tt")#
                            </div>
                        </div>
                    </div>
                </cfloop>
            </div>
        </cfif>
        
        <div style="margin-top: 20px; padding: 15px; background: white; border-radius: 10px; 
                    box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 13px; color: #65676b;">
            <strong>📝 Note:</strong> All attachments are automatically organized by ticket ID 
            (#ticketId#) and stored securely. Files are scanned for security before being made 
            available to support staff.
        </div>
    </div>
</body>
</html>

Share this page

Was this page helpful?
We're glad. Tell us how this page helped.
We're sorry. Can you tell us what didn't work for you?
Thank you for your feedback. Your response will help improve this page.

On this page