Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Data Model Questions /

File upload field walkthrough?


Reply


4 Posts   5000 Views

Avatar
Judge

Community Member, 79 Posts

24 February 2010 at 11:17pm

Edited: 24/02/2010 11:19pm

I wonder if anyone can help walk though implementing a file upload with me? Hopefully it will help others and fill in a few gaps in the documentation.

Basically this is where I would like to get to:

The database model is:

Resumes --< Documents +-- Files

So Resumes can have many Documents. Each Document can have one File.

All files will stored under assets in a date-stamped folder:

resumes/YYYY/MM/DD/filename

The datestamp itself is not important, but it helps spread the files over a multiple directories. The resumes folder will not be directly accessible - users always have to go through a page to ensure they have permission before they are able to access an uploaded file (generally a user can only access files that are attached to a Resume that they own, but some may be set to be publicly accessible - that's a detail for later).

Users can upload a file or replace an existing file. Users cannot browse the file directories to attach existing files or move files around between Documents.

For now I just want this working inside a default ModelAdmin page, so privileges are not really the issue at this stage.

That should cover the use-case, but I'll add anything I think of to this initial post.

Avatar
Judge

Community Member, 79 Posts

24 February 2010 at 11:33pm

Edited: 24/02/2010 11:40pm

This is the approach I have tried so far:

class ResumeDocument extends DataObject {
static $db = array('Notes' => 'Text');

static $has_one = array(
'Resume' => 'Resume', // The master record.
'Document' => 'File', // The uploaded file.
);

function getCMSFiled() {
$fields = parent::getCMSFields();

$FileField = new FileField('Document', 'Upload Resume Document');

// Set the directory.
$FileField->setFolderName('resumes/' . date('Y/m/d'));

// Add this upload field to the form.
$fields->replaceField('Document', $FileField);

return $fileds;
}
}

This will create a DocumentID column in the database. The update form for this Document in the admin screens then provides a browse field allowing a file to be uploaded. Submitting the form will upload the file, place it in the directory structure (creating the directories as needed - very nice) and save the ID of the File in the DocumentID column.

That is okay so far, except that when I go back into the record, there is no indication of the file that is attached.

However, if I change the name of the field from"Document" to "DocumentID" (or even remove the getCMSFields method completely, leaving SS to put in its own default file browser) then the FileField is displayed as an AJAX-enabled uploader. This good *except* that now the server-side options are ignored; the file is uploaded to the "Uploads" root folder and not into the specified directory structure. The user is also given the ability to browse the server to attach a new file.

So - is there anything in between these two extremes? Can a file be uploaded into the right place, by being processed through this model (and consequently allowing upload privileges to be managed here too, in the same place)?

I also wonder about the security of the AJAX file browser. If it does not go through my model to do its browsing, then does that mean all files in the assets folder are completely open to browsing to any third party sending the appropriate requests to the application? Even if htaccess blocks the folder, is there still a means for them to browse the structure and file names?

Avatar
Judge

Community Member, 79 Posts

26 February 2010 at 12:39am

Edited: 26/02/2010 12:40am

One thing that confuses me:

The FileField form field has a warning at the top:

CAUTION: Doesn't work in the CMS due to ajax submission, please use {@link FileIFrameField} instead.

However, when I use it, it does not have any AJAX in it. It is just a plain out file upload field with a browse button.

When I use the FileIFrameField it *does* use AJAX. It incorporates the FileField basic field within it, but then wraps a few layers of iframe, and an AJAX file browser around it.

The thing that confuses me is how it works. I cannot see how FileIFrameField invokes all that AJAX. Where does it come from? Also why the warning in FileField? Is it an old warning that no longer applies, or is it just that my system is not actually working as it should? If I use it, expecting there to be no AJAX, will I get a surprise after a future upgrade to the SS core when the AJAX suddenly starts working? Or perhaps my using it "in the CMS" (whatever that means - in the admin back end? In the front end?) the AJAX is being automatically disabled?

-- Jason

Avatar
timwjohn

Community Member, 98 Posts

1 December 2010 at 10:24pm

For anyone that stumbles here, there's a new(ish) set of file upload fields by the reverend Uncle Cheese, called Uploadify. Use them for all your file upload needs: http://www.leftandmain.com/silverstripe-modules/2010/08/26/two-new-modules-uploadify-and-postale/