Upload file from plugin's Controller to a non-Assets folder I have a plugin Controller that accepts a POSTed form, including an uploaded file. If I make an Assets Source I can successfully save the file into its folder like this:

$file = UploadedFile::getInstanceByName('myFieldName');

$folder = craft()-&gt;assets-&gt;findFolder(array(
    'sourceId' =&gt; 3, // My Asset Source's ID.
));

$response = craft()-&gt;assets-&gt;insertFileByLocalPath(
    $file-&gt;getTempName(), // Local path to file.
    $file-&gt;getName(), // Name file should be given when saved.
    $folder-&gt;id,
    AssetConflictResolution::KeepBoth
);

if ($response-&gt;isSuccess()) {
    ...


However, I want to upload the file to a folder that's not an Asset Source - for security reasons I don't want these particular files to be visible in any way in the CMS. Is there a way to do this, eg, by using a filepath rather than an Asset Source?

(I'm also not sure how to validate the file, in terms of its file extension, size, etc. I can see how to do this in Yii but I'm not sure how to do it having uploaded the file as above.)
Ahh, a bit of fiddling and poking around later...

$file = UploadedFile::getInstanceByName('myFieldName');
$fileName = AssetsHelper::cleanAssetName($file-&gt;getName());

// Make fileName uniqueish by adding a timestamp to it.
$fileParts = explode(".", $fileName);
$extension = array_pop($fileParts);
$fileName = join(".", $fileParts) .'_'. time() .'.'. $extension;

$filePath = '/path/to/my/folder/' . $fileName;

$response = $file-&gt;saveAs($filePath);


Seems to work OK!

The unique filename stuff seems not entirely great. Might be better to see if the file exists first, and if so, make a new name.

Just need to work out how to validate my Model now...

UPDATE: Oh, that was quick. So now I do:

$post = craft()-&gt;request-&gt;getPost();
$myModel = MyForm_FilesModel::populateModel($post);

// All the file-handling stuff as above.

$myModel-&gt;myAttribute = $file;

if ($myModel-&gt;validate()) {
    ...


Where my model is something like:

&lt;?php
namespace Craft;

class MyForm_FilesModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array(
            'myAttribute' =&gt; array(AttributeType::Name),
        );
    }

    public function rules()
    {
        return array(
            array('UploadPassport', 'file',
            'allowEmpty' =&gt; false,
            'maxFiles' =&gt; 1,
            'maxSize' =&gt; 5 * 1000000, // 5MB
            'tooLarge' =&gt; 'Sorry, the maximum file size is 5MB',
            'types' =&gt; array('jpg', 'png', 'pdf'),
            'wrongType' =&gt; 'Files must be one of jpg, png or pdf',
            'message' =&gt; 'Please upload a file'),
        );
    }
}


(The defineAttributes() stuff feels very wrong, as this isn't a proper Craft model - I'm not saving any of this as an Entry etc defined in the Craft Admin. But I can't see how else to make this stuff work.)