4

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

9

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);
  • 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 Jul 7 '17 at 12:46
  • 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 Jul 7 '17 at 12:50
  • 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 Jul 7 '17 at 12:52
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, they are a work in progress by the looks of things.

In particular you'll probably want to look at the Plugin Development - Services 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 :)

  • 2
    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 Jun 27 '17 at 15:10
  • 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 Jun 28 '17 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.