Create entry with newly-uploaded asset programatically I'm trying to do something very simple - but I've yet to find documentation to cover this basic scenario.

I'm writing a plugin. In a controller, I want to create a new entry, and assign an uploaded file to an Assets field on the entry.

I can create an entry using the example code:

$entry = new EntryModel();
$entry-&gt;getContent()-&gt;title = 'Title of thing';
// set some custom fields
craft()-&gt;entries-&gt;saveEntry($entry);


One of the fields is an Assets type; I have image data in a variable - I want to create an asset and associate it to the relevant property of the entry.
Assets fields are capable of storing newly uploaded files into assets folders, and then automatically relating them to the entry (making this feature possible).

When you’re saving the entry yourself rather than using the entries/saveEntry controller action, there are two things you need to do in order to take advantage of this feature:


Make sure your form is set up correctly.

The form should be submitting with a POST request, and encoding with multipart/form-data:

&lt;form method="post" enctype="multipart/form-data"&gt;


And the file input needs to have an input name based on the Assets field’s handle:

&lt;input type="file" name="fields[myAssetsFieldHandle]"&gt;

Your controller needs to tell the entry where to find the uploaded file.

You can do this with setContentFromPost() if you want all custom field values in the POST data to be assigned to the entry automatically, or setContentPostLocation() if you want to assign the custom field values to the entry manually.

setContentFromPost() example:

$entry = new EntryModel();
$entry-&gt;getContent()-&gt;title = 'My New Entry';

// Look through $_POST['fields'] for any custom field values
// and assign them to the entry's content automatically
$entry-&gt;setContentFromPost('fields');

craft()-&gt;entries-&gt;saveEntry($entry);


setContentPostLocation() example:

$entry = new EntryModel();
$entry-&gt;getContent()-&gt;title = 'My New Entry';

// Assign the custom field values manually
$entry-&gt;getContent()-&gt;summary = craft()-&gt;request-&gt;getPost('fields.summary');
$entry-&gt;getContent()-&gt;body = craft()-&gt;request-&gt;getPost('fields.body');

// Tell the entry where these custom fields are coming from in the POST data
// so that the Assets field will know where to look for an uploaded file
$entry-&gt;setContentPostLocation('fields');

craft()-&gt;entries-&gt;saveEntry($entry);



Alternatively, you can manually store the uploaded file into an asset folder using AssetsService::insertFileByLocalPath(), get the resulting file ID, and assign that file ID directly onto the Assets field.

$fileIds = array();

$uploadedFile = UploadedFile::getInstanceByName('fields.myAssetsFieldHandle');

if ($uploadedFile)
{
    $response = craft()-&gt;assets-&gt;insertFileByLocalPath(
        $uploadedFile-&gt;tempName,
        $uploadedFile-&gt;name,
        $folderId,
        AssetConflictResolution::KeepBoth
    );

    if ($response-&gt;isSuccess())
    {
        $fileIds[] = $response-&gt;getDataItem('fileId');
    }
}

$entry = new EntryModel();
$entry-&gt;getContent()-&gt;title = 'My New Entry';

// Assign the custom field values manually
$entry-&gt;getContent()-&gt;summary = craft()-&gt;request-&gt;getPost('fields.summary');
$entry-&gt;getContent()-&gt;body = craft()-&gt;request-&gt;getPost('fields.body');
$entry-&gt;getContent()-&gt;myAssetsFieldHandle = $fileIds;

craft()-&gt;entries-&gt;saveEntry($entry);


Note that in this approach, the name of the file input doesn’t matter, since you’re the one that’s telling UploadedFile where to look for it in $_FILES.