This plugin will allow the use of a SWFUploadField object as a substitute for a FileField in the CMS or on any custom form on your website. SWFUpload is an open source project that enables the use of Flash-based uploading through Javascript. The use of Flash for uploading brings many rich features to uploading including:
Silverstripe 2.2 or later
Place the swfupload folder in the Silverstripe root and run a /db/build?flush=1 ( /dev/build in 2.3 or later)
The primary class responsible for generating a SWFUpload field on a form. Subclass of FormField.
A class of static functions used to configure the javascript object for SWFUpload. For more information, see configuration.
A subclass of FileIFrameField used to bring SWFUpload features into the CMS.
A series of callback functions that are triggered by a wide variety of events events in the SWFUpload object.
In this example, we'll add a file upload to the CMS edit form of a page with a File associated with it. Let's exclude all files but PDFs.
static $has_one = array ('BigFile' => 'File'); public function getCMSFields() { SWFUploadConfig::addFileType('pdf'); $fields = parent::getCMSFields(); $fields->addFieldToTab("Root.Content.File", new SWFUploadFileIFrameField('BigFile','Upload a file')); return $fields; }
That's all there is to it! If you're attaching large files to a page, this is particularly useful because it will display a progress bar for the upload.
In this example, we'll use a SWFUploadField to support attaching a cover letter and resume to a job application form. The only file types we'll accept for the cover letter and resume are PDF and DOC.
/mysite/code/ResumeForm.php
class ResumeForm_Controller extends PageController { public function ResumeForm() { SWFUploadConfig::addFileTypes(array( 'pdf','doc' )); return new Form( $this, "ResumeForm", new FieldSet( new TextField('Name'), new TextField('Email'), new SWFUploadField( "ResumeForm", "Resume", "Upload your cover letter and resume (pdf or doc format)", array ( 'file_upload_limit' => '2', 'required' => 'true' ) ) ), new FieldSet( new FormAction('doResumeSubmit','Apply now') ) ); } }
For the most part, this form looks like most other contact forms except for a few extra functions to configure and create the SWFUploadField.
First, we talk to the SWFUploadConfig class to add the allowed file types. Without this function, the SWFUploadField will accept all file types.
The SWFUploadField constructor takes four arguments in this example.
The form will now instantiate an asynchronous Flash upload on submit. Now we need to write a script to tell the server how to handle the incoming files. By default, SWFUploadField will execute the handleswfupload() function on the current controller.
/mysite/code/ResumeForm.php
public function handleswfupload() { if(isset($_FILES['swfupload_file']) && is_array($_FILES['swfupload_file'])) echo Folder::findOrMake('Resumes')->addUploadToFolder($_FILES['swfupload_file']); else echo ' '; }
SWFUpload sends the file in an array named swfupload_file. (This can be changed in SWFUploadConfig). We get a Folder object and add the incoming file to the Folder. We must return the ID of the file to SWFUpload. Fortunately, the addUploadToFolder() returns the most recent generated database ID, so this works perfectly.
In the case of an error, we return a single space to the SWFUpload object.
Now the form will execute its action doResumeSubmit. In handling the form post, we need to be aware of the files that were uploaded so we can do something with them, such as send an email to an admin.
/mysite/code/ResumeForm.php
public function doResumeSubmit($data,$form) { if(isset($_POST['uploaded_files']) && is_array($_POST['uploaded_files'])) { $email = new Email( $data['Email'], "admin@example.com", "New Resume Form" ); $body = "<p>Attahed are the resume and cover letter of " . $data['Name'] . ".</p>"; $body .= "<p>Download them from here:</p>"; foreach($_POST['uploaded_files'] as $id) { $file = DataObject::get_by_id("File",$id); $body .= "<a href='$file->URL'>$file->Title</a><br />"; } $email->body = $body; $email->send(); Director::redirect($this->Link('success')); } }
The $_POST['uploaded_files'] array contains all the IDs of the files that were uploaded through the form. We loop through them and attach them to the email one by one.
The SWFUploadField takes many parameters to configure its functionality and appearance. Fortunately, most of these are rarely, if ever, modified.
To change a default value of any SWFUpload configuration parameter, just edit /swfupload/_config.php and change the values of any key/value pair passed to the SWFUploadConfig::Configure() function.
The SWFUploadConfig class can be accessed anytime before a SWFUploadField is instantiated to update the configuration. Some common updates have helper functions including:
For all other configuration updates, use SWFUploadConfig::set_var('var','value').
Any of these key value pairs can be updated on the construction of a SWFUploadField object. For example:
$my_swfupload = new SWFUploadField("ResumeForm","Resume","Upload your resume", array( 'post_params' => array('Foo' => 'Bar'), 'file_upload_limit' => '2' ));
| Parameter name | Default Value | Purpose |
|---|---|---|
| form_name | none | Provides a javascript hook for the form containing a SWFUPloadField |
| upload_url | The handleswfupload() action on the current controller | The script that will run when SWFUpload finishes uploading to the server. Handles the file upload. |
| file_destination_path | none | DEPRECATED |
| file_post_name | swfupload_file | Name of the array that is passed to the server in $_FILES |
| post_params | empty | A javascript object of key/value pairs that will be sent to the upload_url in a $_POST array |
| file_size_limit | The upload_max_filesize setting in php.ini | Files larger than this number (in kilobytes) are not allowed |
| file_types_list | *.* | Files allowed to be uploaded through the SWFUploadField |
| file_types_description | none | Describe the types of files allowed, e.g. only images |
| browse_button_text | Browse… | Text that appears on the browse button |
| file_upload_limit | 100 | Maximum number of files that can be uploaded |
| file_queue_limit | 100 | Maximum number of files allowed in the upload queue DEPRECATED |
| required | false | If set to true (as a string), the submit button will not appear until valid files have been selected |
| swfupload_loaded_handler | swfUploadLoaded | This Javascript function will fire when the Flash object has been loaded successfully. |
| file_dialog_start_handler | fileDialogStart | This Javascript function will fire when the dialog box is opened to browse files |
| file_queued_handler | fileQueued | This Javascript function will fire when a file has been successfully put into the queue |
| file_queue_error_handler | fileQueueError | Thie Javascript function will fire when a file has been put into the queue erroneously. |
| file_dialog_complete_handler | fileDialogComplete | This Javascript function will fire when a file has been selected from the dialog box |
| upload_start_handler | uploadStart | This Javascript event will fire when the upload begins. |
| upload_progress_handler | uploadProgress | This Javascript event will fire when a progress update is received from the Flash upload API. |
| upload_error_handler | uploadError | This Javascript event will fire when an upload results in a server error |
| upload_success_handler | uploadSuccess | This Javascript event will fire when an upload has successfully reached the server |
| upload_complete_handler | uploadComplete | This Javascript event will fire when the upload has been successfully processed by the server |
| flash_url | Absolute path to /swfupload/javascript/swfupload.swf | Path to the Flash file that runs SWFUpload |
| swfupload_element_id | flashUI | ID of the field that will contain the SWFUpload Flash object |
| degraded_element_id | degradedUI | ID of the field that will handle the file upload if Flash is not supported |
| progress_target | fsUploadProgress | ID of the field that will contain the progress bar during uploading |
| upload_successful | false | Boolean for whether the upload is complete |
| button_image_url | Absolute path to /swfupload/images/XPButtonNoText_160x22.png | Image of the browse button. Must be an image for Flash 10 compatibility |
| button_width | 160 | Width of the browse button in pixels |
| button_height | 22 | Height of the browse button in pixels |
| button_text_style | .button { font-family: Helvetica, Arial, sans-serif; font-size: 12px; } | CSS used to style the button |
| button_text_top_padding | 4 | Padding on the top of the button |
| button_text_left_padding | 5 | Padding on the left of the button |
| debug | false | If set to true (as a string), an informative debugging window with tracing will appear near the SWFUploadField. |
If your SWFUploadField isn't running properly, the first thing you should do is activate debug mode by running
SWFUploadConfig::set_var('debug','true');
before you instantiate your SWFUploadField. You may also add 'debug' ⇒ 'true' to your array of configuration parameters in the SWFUploadField constructor.
The debug mode will provide tracing and verbose error reporting.
This is by far the most common issue with SWFUpload. It is almost always caused by a PHP error on the server, but because Flash will not report PHP errors, only HTTP errors, all we know is that there's a 500 error, which is not very helpful. Fortunately, there's a system in place for debugging this. It's a little tedious, but the good news is, as more errors get debugged, the more stable this module becomes.
First, edit your _config.php and add:
SWFUploadConfig::debug();
This will force the upload script to alert what the server returns in the handleswfupload() method and it will not advance to the form.
For an optimal testing environment, if you're using Firefox, right click on the popup window and select “View frame in new tab.” This will allow you to refresh the screen quickly for each iteration of your testing.
Please use comments for notes, tips and corrections about the described
functionality.
Use the Silverstripe Forum to
ask questions.