<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>

CC BY-SA 3.0
2017-07-07T12:46:56.003Z
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().
Brandon Kelly
CC BY-SA 3.0
2017-07-07T12:50:20.043Z
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.
SteveEdson
CC BY-SA 3.0
2017-07-07T12:52:27.557Z
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.
Brandon Kelly
CC BY-SA 3.0
2017-06-28T08:30:47.653Z
2017-06-28T08:30:47.653Z
SteveEdson
<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>

CC BY-SA 3.0
2017-06-27T15:10:07.967Z
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.
SteveEdson
CC BY-SA 3.0
2017-06-28T08:33:17.733Z
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)
SteveEdson
CC BY-SA 3.0
2017-06-27T14:30:33.257Z
2017-06-27T14:37:01.483Z
2017-06-27T14:37:01.483Z
Steve Holland
<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>

<assets><php><craft3>
How do I upload an asset in Craft 3, via PHP
# 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
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)  

---

