Answers.Body: <p>I finally figured out how to upload an asset, however I still don't understand why the <code>insertFileByLocalPath</code> has been removed.</p>
  
  <pre><code>/**
   * @param UploadedFile $uploadedFile
   * @param int $folderId
   * @return Asset
   * @throws BadRequestHttpException
   * @throws UploadFailedException
   */
  protected static function uploadNewAsset(UploadedFile $uploadedFile, $folderId) {
  
  
      if (empty($folderId)) {
          throw new BadRequestHttpException('No target destination provided for uploading');
      }
  
      if ($uploadedFile === null) {
          throw new BadRequestHttpException('No file was uploaded');
      }
  
      $assets = Craft::$app-&gt;getAssets();
  
      if ($uploadedFile-&gt;getHasError()) {
          throw new UploadFailedException($uploadedFile-&gt;error);
      }
  
      // Move the uploaded file to the temp folder
      if (($tempPath = $uploadedFile-&gt;saveAsTempFile()) === false) {
          throw new UploadFailedException(UPLOAD_ERR_CANT_WRITE);
      }
  
      if (empty($folderId)) {
          throw new BadRequestHttpException('The target destination provided for uploading is not valid');
      }
  
      $folder = $assets-&gt;findFolder(['id' =&gt; $folderId]);
  
      if (!$folder) {
          throw new BadRequestHttpException('The target folder provided for uploading is not valid');
      }
  
      // Check the permissions to upload in the resolved folder.
      $filename = Assets::prepareAssetName($uploadedFile-&gt;name);
  
      $asset = new Asset();
      $asset-&gt;tempFilePath = $tempPath;
      $asset-&gt;filename = $filename;
      $asset-&gt;newFolderId = $folder-&gt;id;
      $asset-&gt;volumeId = $folder-&gt;volumeId;
      $asset-&gt;avoidFilenameConflicts = true;
      $asset-&gt;setScenario(Asset::SCENARIO_CREATE);
  
      $result = Craft::$app-&gt;getElements()-&gt;saveElement($asset);
  
      return $asset;
  }
  </code></pre>
  
  <p>and then in my controller I can simply use</p>
  
  <pre><code>$service-&gt;uploadImage(UploadedFile::getInstanceByName('photo'), 1);
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-07T12:46:56.003Z
Answers.Text: insertFileByLocalPath() was a casualty of a lot of element save refactoring. Basically in Craft 3, we want all element saves to go through craft\services\Elements::saveElement().
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-07T12:50:20.043Z
Answers.Text: Fair enough, any plans to add helper methods like above to make it easier for people to use? The code above isn't the most intuitive.
Answers.UserDisplayName: SteveEdson
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-07T12:52:27.557Z
Answers.Text: I don't think so, as it only helps a pretty narrow use case. What if someone wants to set content on the asset? etc.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-28T08:30:47.653Z
Answers.LastActivityDate: 2017-06-28T08:30:47.653Z
Answers.UserDisplayName: SteveEdson
Answers.Body: <p>Not an actual answer to your question, but more of a pointer in the general direction.  </p>
  
  <p>Docs for Craft 3 can be found <a href="https://github.com/craftcms/docs/" rel="nofollow noreferrer">on Github</a>, they are a work in progress by the looks of things.</p>
  
  <p>In particular you'll probably want to look at the <a href="https://github.com/craftcms/docs/blob/master/en/services.md" rel="nofollow noreferrer">Plugin Development - Services</a> section.</p>
  
  <p>Now together with the above docs, and a fresh install of Craft 3 itself, you should be able to find what you are looking for in the <code>Assets</code> Service. Which you'll find in the following location of you install:</p>
  
  <p><code>craft/vendor/craftcms/cms/src/services/Assets.php</code></p>
  
  <p>The <code>saveAsset</code> method looks like it might be a good candidate for what you are doing.</p>
  
  <p>Hopefully that should help a little bit. </p>
  
  <p>Just so you know, I'm not being deliberately vague. I'm only just starting to look into Craft 3 and was having a browse around the source code myself and it looked like it might help :) </p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-27T15:10:07.967Z
Answers.Text: Thanks, I appreciate the help. I'll update my question when I get home, I've since figured out how to save an uploaded asset, and I've written a helper method for it. It seems very complicated though, so I'm still wondering where the previous helper method from Craft 2 disappeared to.
Answers.UserDisplayName: SteveEdson
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-28T08:33:17.733Z
Answers.Text: I've added an answer with my code for uploading a new asset. (Did it as a new answer since code in comments doesn't work)
Answers.UserDisplayName: SteveEdson
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-27T14:30:33.257Z
Answers.LastActivityDate: 2017-06-27T14:37:01.483Z
Answers.LastEditDate: 2017-06-27T14:37:01.483Z
Answers.UserDisplayName: Steve Holland
Body: <p>I've found various answers on how to upload assets via PHP for Craft 2, however nothing for Craft 3.</p>
  
  <p>All answers use the method:</p>
  
  <pre><code>craft()-&gt;assets-&gt;insertFileByLocalPath()
  </code></pre>
  
  <p>E.g: <a href="https://craftcms.stackexchange.com/questions/5104/how-to-upload-an-asset-from-a-front-end-form">How to upload an asset from a front-end form</a></p>
  
  <p>I was wondering what the equivalent is for Craft 3.</p>
  
  <p>Thanks</p>
  
Tags: <assets><php><craft3>
Title: How do I upload an asset in Craft 3, via PHP
ThreadText: # How do I upload an asset in Craft 3, via PHP
  
  (Asked by: username_0 on 2017-06-26)
  
  I've found various answers on how to upload assets via PHP for Craft 2, however nothing for Craft 3.
  
  All answers use the method:
  
  ```
  craft()->assets->insertFileByLocalPath()
  
  ```
  
  E.g: [How to upload an asset from a front-end form](https://craftcms.stackexchange.com/questions/5104/how-to-upload-an-asset-from-a-front-end-form)
  
  I was wondering what the equivalent is for Craft 3.
  
  Thanks
  
  **Tags:** assets, php, craft3
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2017-06-28. Score: 13
  
  I finally figured out how to upload an asset, however I still don't understand why the `insertFileByLocalPath` has been removed.
  
  ```
  /**
   * @param UploadedFile $uploadedFile
   * @param int $folderId
   * @return Asset
   * @throws BadRequestHttpException
   * @throws UploadFailedException
   */
  protected static function uploadNewAsset(UploadedFile $uploadedFile, $folderId) {
  
      if (empty($folderId)) {
          throw new BadRequestHttpException('No target destination provided for uploading');
      }
  
      if ($uploadedFile === null) {
          throw new BadRequestHttpException('No file was uploaded');
      }
  
      $assets = Craft::$app->getAssets();
  
      if ($uploadedFile->getHasError()) {
          throw new UploadFailedException($uploadedFile->error);
      }
  
      // Move the uploaded file to the temp folder
      if (($tempPath = $uploadedFile->saveAsTempFile()) === false) {
          throw new UploadFailedException(UPLOAD_ERR_CANT_WRITE);
      }
  
      if (empty($folderId)) {
          throw new BadRequestHttpException('The target destination provided for uploading is not valid');
      }
  
      $folder = $assets->findFolder(['id' => $folderId]);
  
      if (!$folder) {
          throw new BadRequestHttpException('The target folder provided for uploading is not valid');
      }
  
      // Check the permissions to upload in the resolved folder.
      $filename = Assets::prepareAssetName($uploadedFile->name);
  
      $asset = new Asset();
      $asset->tempFilePath = $tempPath;
      $asset->filename = $filename;
      $asset->newFolderId = $folder->id;
      $asset->volumeId = $folder->volumeId;
      $asset->avoidFilenameConflicts = true;
      $asset->setScenario(Asset::SCENARIO_CREATE);
  
      $result = Craft::$app->getElements()->saveElement($asset);
  
      return $asset;
  }
  
  ```
  
  and then in my controller I can simply use
  
  ```
  $service->uploadImage(UploadedFile::getInstanceByName('photo'), 1);
  
  ```
  
  > **Comments:**
  > **username_1**: insertFileByLocalPath() was a casualty of a lot of element save refactoring. Basically in Craft 3, we want all element saves to go through craft\services\Elements::saveElement().  
  > **username_0**: Fair enough, any plans to add helper methods like above to make it easier for people to use? The code above isn't the most intuitive.  
  > **username_1**: I don't think so, as it only helps a pretty narrow use case. What if someone wants to set content on the asset? etc.  
  
  ---
  
  ### Answer by username_2 on 2017-06-27. Score: 1
  
  Not an actual answer to your question, but more of a pointer in the general direction.
  
  Docs for Craft 3 can be found [on Github](https://github.com/craftcms/docs/), they are a work in progress by the looks of things.
  
  In particular you'll probably want to look at the [Plugin Development - Services](https://github.com/craftcms/docs/blob/master/en/services.md) section.
  
  Now together with the above docs, and a fresh install of Craft 3 itself, you should be able to find what you are looking for in the `Assets` Service. Which you'll find in the following location of you install:
  
  `craft/vendor/craftcms/cms/src/services/Assets.php`
  
  The `saveAsset` method looks like it might be a good candidate for what you are doing.
  
  Hopefully that should help a little bit.
  
  Just so you know, I'm not being deliberately vague. I'm only just starting to look into Craft 3 and was having a browse around the source code myself and it looked like it might help :)
  
  > **Comments:**
  > **username_0**: Thanks, I appreciate the help. I'll update my question when I get home, I've since figured out how to save an uploaded asset, and I've written a helper method for it. It seems very complicated though, so I'm still wondering where the previous helper method from Craft 2 disappeared to.  
  > **username_0**: I've added an answer with my code for uploading a new asset. (Did it as a new answer since code in comments doesn't work)  
  
  ---
  
  