How to upload Images to custom Tailor model with PHP?

I’m creating a October v3 website. I have a custom Tailor model: Game with a boxart field

fields:
  boxart:
    type: mediafinder
    mode: image
    maxFiles: 1

I’m writing a page that gets games from an API that has the image url of a game. I want to download that image and store it in OctoberCMS. So far I have this, but I can’t figure out how to save the image in the correct folder for the media finder and how to link it to the model

<?php
use Tailor\Models\EntryRecord;
use Illuminate\Support\Facades\Storage;

function onSaveGame()
{
    $game = EntryRecord::inSection('Games\Game');
    $title = input('name')
    $boxart = input('image_url');

    $data = file_get_contents($boxart);
    $extension = substr($boxart, strrpos($boxart, '.'));
    $fname = 'uploads/games/'.$id.'-'.str_slug($title).$extension;

    Storage::put($fname, $data);
    $game->boxart = [$fname];
     
    $game->save();
}
?>

This save the file in my Storage folder, but the file is not available in the MediaFinder and the linked image does not work either.

Found a workable solution

  1. Change the type of the boxart to fileupload
fields:
    boxart:
        label: Afbeelding
        type: fileupload
        mode: image
        maxFiles: 1
  1. Use the System\Models\File static method fromUrl
function onSaveGame ()
{
    $game = EntryRecord::inSection('Games\Game');
    $game->title = input('name')
    $url = input('image_url');

    // *** THE MAGIC CODE ***
    $file = new System\Models\File;
    $file->fromUrl($url);
    $game->boxart()->add($file);
     
    $game->save();
}
1 Like

Thanks for reporting your solution. We have improved the documentation related to this.


Uploading to Models

When working with models that are configured to use file attachments, including Tailor models that use the File upload widget, you save file uploads directly on the model.

The simplest approach is to set the attribute on the model directly using the files() helper. This supports singular and multiple file uploads.

function onUploadFiles()
{
    $model = new MyModel;

    $model->avatar = files('single_file');

    $model->save();

    // ...

    Flash::success('File saved');
}

You may also set the attribute to a System\Models\File model object directly for various use cases.

$model->avatar = (new File)->fromFile('/path/to/somefile.jpg');

$model->avatar = (new File)->fromData('Some content', 'sometext.txt');

$model->avatar = (new File)->fromUrl('https://example.tld/path/to/avatar.jpg');
2 Likes

Nice solution. Is this also possible with a mediafinder-field instead of a fileupload-field?