XF 2.1 Upload image file via <xf:form />

asprin

Active member
So I've set upload="true" on the form tag

I'm wondering if there is a pre-defined tag (similar to xf:textboxrow, xf:selectrow etc) which builds the UI for allowing a user to upload a file.

Or does it have to be done via the plain old input type="file" tag?

Also since this form will be part of the addon, what is the recommended place to store it? I'm thinking of storing the file on the filesystem and putting the path of the file in the database.

Are there any reference tutorials/code that I can look into?
 
Solution
You want to use the xf file system adapter to move the files, as it will handle external storage for you. If you're planning to make the file web accessible, it should go into data/, otherwise internal

asprin

Active member
A small update since I posted this. I seem to be getting a success response using XF2 code. But not able to figure out where the file is actually stored.

HTML:
<xf:form action="{{ link('xxxx/yyyy') }}" autocomplete="off" upload="true" class="block" ajax="true">
    <xf:upload name="upload" accept=".jpeg,.jpg,.png" />
</xf:form>

PHP:
if($this->isPost())
{
    $upload = $this->request->getFile('upload', false, false);          
    if($upload)
    {
        return $this->error("SUCCESS"); // getting this in the popup
        // but where is the file?
        // do not see anything in the data or internal_data folders
    }
    else
    {
        return $this->error(\XF::phrase('asp_sk_not_valid_file'));
    }  
}
 
Last edited:

Lukas W.

Well-known member
Your $upload variable holds everything you need. The file is stored in your temporary directory. You'll have to transfer it to a different place if you intend to keep it, otherwise it'll be deleted.
 

asprin

Active member
Your $upload variable holds everything you need. The file is stored in your temporary directory. You'll have to transfer it to a different place if you intend to keep it, otherwise it'll be deleted.
Got it!

So I'll have to do something like this:
PHP:
move_upload_file(<get tmp location from $upload>, 'destination/path/to/file');

Any recommendation as to where I should be moving it to? This form will be part of the addon, but I'm assuming it shouldn't go into the addon folder.

data/myaddonfolder/<uploaded_filename> or internal_data/myaddonfolder/<uploaded_filename> sounds good?
 

Lukas W.

Well-known member
You want to use the xf file system adapter to move the files, as it will handle external storage for you. If you're planning to make the file web accessible, it should go into data/, otherwise internal
 
Solution

asprin

Active member
You want to use the xf file system adapter to move the files, as it will handle external storage for you. If you're planning to make the file web accessible, it should go into data/, otherwise internal
So is the following approach good enough? This is working fine when tested. Only concern is the hardcoded usage of :// in the destination path. I was wondering if that is acceptable or if an alternative is available.

PHP:
$dataDir = \XF::app()->config('externalDataPath');
$upload = $this->request->getFile('upload', false);
if($upload)           
{
    $dataDir .= '://myFolder/'.$upload->getFileName();
    \XF\Util\File::copyFileToAbstractedPath($upload->getTempFile(), $dataDir);
    return true;
}

@asprin is this the way the handle uploads separate from XF:Attachment entity? Are you storing the metadata about the uploaded file in a custom table?
No idea mate. I'm learning as I develop. So there's a lot of things I'm not privy to.
 
Top