<p>Ahh, a bit of fiddling and poking around later...</p>

<pre class="lang-php prettyprint-override"><code>$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);
</code></pre>

<p>Seems to work OK!</p>

<p>The unique filename stuff seems not entirely great. Might be better to see if the file exists first, and if so, <a href="https://github.com/pixelandtonic/Craft-Release/blob/a2683e81f67eb7e90dd753f0e9b0163abfd6a334/app/assetsourcetypes/LocalAssetSourceType.php#L354" rel="noreferrer">make a new name</a>.</p>

<p>Just need to work out how to validate my Model now...</p>

<p><strong>UPDATE:</strong> Oh, that was quick. So now I do:</p>

<pre class="lang-php prettyprint-override"><code>$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()) {
    ...
</code></pre>

<p>Where my model is something like:</p>

<pre class="lang-php prettyprint-override"><code>&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'),
        );
    }
}
</code></pre>

<p>(The <code>defineAttributes()</code> 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.)</p>

CC BY-SA 3.0
2015-08-28T15:26:26.523Z
2015-08-28T15:42:51.600Z
2015-08-28T15:42:51.600Z
Phil Gyford
<p>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:</p>

<pre class="lang-php prettyprint-override"><code>$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()) {
    ...
</code></pre>

<p>However, I want to upload the file to a folder that's <em>not</em> 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?</p>

<p>(I'm also not sure how to validate the file, in terms of its file extension, size, etc. I can see <a href="http://www.yiiframework.com/wiki/56/#hh12" rel="nofollow">how to do this in Yii</a> but I'm not sure how to do it having uploaded the file as above.)</p>

<plugin-development><upload><files>
Upload file from plugin's Controller to a non-Assets folder
# Upload file from plugin's Controller to a non-Assets folder

(Asked by: username_0 on 2015-08-28)

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()->assets->findFolder(array(
    'sourceId' => 3, // My Asset Source's ID.
));

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

if ($response->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.)

**Tags:** plugin-development, upload, files


---

## 1 answers

### Answer by username_0 on 2015-08-28. Score: 6 | Accepted answer

Ahh, a bit of fiddling and poking around later...
$file = UploadedFile::getInstanceByName('myFieldName');
$fileName = AssetsHelper::cleanAssetName($file->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->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()->request->getPost();
$myModel = MyForm_FilesModel::populateModel($post);

// All the file-handling stuff as above.

$myModel->myAttribute = $file;

if ($myModel->validate()) {
    ...

Where my model is something like:
 array(AttributeType::Name),
        );
    }

    public function rules()
    {
        return array(
            array('UploadPassport', 'file',
            'allowEmpty' => false,
            'maxFiles' => 1,
            'maxSize' => 5 * 1000000, // 5MB
            'tooLarge' => 'Sorry, the maximum file size is 5MB',
            'types' => array('jpg', 'png', 'pdf'),
            'wrongType' => 'Files must be one of jpg, png or pdf',
            'message' => '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.)


---

