Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-08-28T15:26:26.523Z
Answers.LastActivityDate: 2015-08-28T15:42:51.600Z
Answers.LastEditDate: 2015-08-28T15:42:51.600Z
Answers.UserDisplayName: Phil Gyford
Body: <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>
  
Tags: <plugin-development><upload><files>
Title: Upload file from plugin's Controller to a non-Assets folder
ThreadText: # 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:
  
  ```php
  $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](http://www.yiiframework.com/wiki/56/#hh12) 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...
  
  ```php
  $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](https://github.com/pixelandtonic/Craft-Release/blob/a2683e81f67eb7e90dd753f0e9b0163abfd6a334/app/assetsourcetypes/LocalAssetSourceType.php#L354).
  
  Just need to work out how to validate my Model now...
  
  **UPDATE:** Oh, that was quick. So now I do:
  
  ```php
  $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:
  
  ```php
  <?php
  namespace Craft;
  
  class MyForm_FilesModel extends BaseModel
  {
      protected function defineAttributes()
      {
          return array(
              'myAttribute' => 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.)
  
  
  ---
  
  