<p>Assets fields are capable of storing newly uploaded files into assets folders, and then automatically relating them to the entry (making <a href="http://buildwithcraft.com/docs/assets-fields#uploading-files-from-front-end-entry-forms">this feature</a> possible).</p>

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

<ol>
<li><p><strong>Make sure your form is set up correctly.</strong></p>

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

<pre class="lang-html prettyprint-override"><code>&lt;form method="post" enctype="multipart/form-data"&gt;
</code></pre>

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

<pre class="lang-html prettyprint-override"><code>&lt;input type="file" name="fields[myAssetsFieldHandle]"&gt;
</code></pre></li>
<li><p><strong>Your controller needs to tell the entry where to find the uploaded file.</strong></p>

<p>You can do this with <a href="http://buildwithcraft.com/classreference/models/BaseElementModel#setContentFromPost-detail">setContentFromPost()</a> if you want all custom field values in the POST data to be assigned to the entry automatically, or <a href="http://buildwithcraft.com/classreference/models/BaseElementModel#setContentPostLocation-detail">setContentPostLocation()</a> if you want to assign the custom field values to the entry manually.</p>

<p>setContentFromPost() example:</p>

<pre class="lang-php prettyprint-override"><code>$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);
</code></pre>

<p>setContentPostLocation() example:</p>

<pre class="lang-php prettyprint-override"><code>$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);
</code></pre></li>
</ol>

<p>Alternatively, you can manually store the uploaded file into an asset folder using <a href="http://buildwithcraft.com/classreference/services/AssetsService#insertFileByLocalPath-detail">AssetsService::insertFileByLocalPath()</a>, get the resulting file ID, and assign that file ID directly onto the Assets field.</p>

<pre class="lang-php prettyprint-override"><code>$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);
</code></pre>

<p>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.</p>

CC BY-SA 3.0
2014-10-16T14:20:45.963Z
I was using insertFileByLocalPath, as I'm not taking input from a form (it's handling data from an API) - but the bit that I couldn't find documented was that I needed to set the assets field with an array of file IDs (which I already had from a call to getDataItem('fileId') on the response from insertFileByLocalPath). It probably seems incredibly basic - but I just couldn't find documentation or an example which showed this.
Tom
CC BY-SA 3.0
2014-10-16T14:59:05.853Z
@Tom Yeah, I think this calls for us adding a new section to all the field type pages in the docs, explaining how their data should be formatted when saving elements, and also showing an example HTML form and PHP code.
Brandon Kelly
CC BY-SA 3.0
2014-10-16T15:02:06.200Z
@Tom Also hope you don’t mind that I edited your question to focus on the file being uploaded. It wasn’t entirely clear whether it was getting uploaded or not (thanks for the clarification), but I figured freshly-uploaded files are the majority use case, and answering that question kills both birds with one stone.
Brandon Kelly
CC BY-SA 3.0
2014-10-17T15:58:55.730Z
Just to update on this; sometimes this comes back with the error: "Integrity constraint violation: 1048 Column 'targetId' cannot be null. The SQL statement executed was: INSERT INTO `craft_relations`..." But not consistently. Any ideas?
Tom
CC BY-SA 3.0
2014-10-17T17:25:40.307Z
@Tom You’re probably passing some blank values into the relation field’s array value.
Brandon Kelly
CC BY-SA 3.0
2014-12-17T18:56:18.257Z
@Tom, I am getting that same error anytime I upload a file that has a filename equal to one we've already uploaded.
coffe4u
CC BY-SA 3.0
2014-12-17T21:12:55.247Z
@coffe4u Are you on the latest version of Craft? If so can you please email support@buildwithcraft.com with those details?
Brandon Kelly
CC BY-SA 3.0
2014-10-16T13:18:29.357Z
2014-10-16T13:30:51.463Z
2014-10-16T13:30:51.463Z
Brandon Kelly
<p>I'm trying to do something very simple - but I've yet to find documentation to cover this basic scenario.</p>

<p>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.</p>

<p>I can create an entry using the example code:</p>

<pre class="lang-php prettyprint-override"><code>$entry = new EntryModel();
$entry-&gt;getContent()-&gt;title = 'Title of thing';
// set some custom fields
craft()-&gt;entries-&gt;saveEntry($entry);
</code></pre>

<p>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.</p>

<plugin-development><entries><assets>
Create entry with newly-uploaded asset programatically
# Create entry with newly-uploaded asset programatically

(Asked by: username_0 on 2014-10-16)

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->getContent()->title = 'Title of thing';
// set some custom fields
craft()->entries->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.

**Tags:** plugin-development, entries, assets

---

## 1 answers

### Answer by username_1 on 2014-10-16. Score: 7 | Accepted answer

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:


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


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->getContent()->title = 'My New Entry';

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

craft()->entries->saveEntry($entry);

setContentPostLocation() example:
$entry = new EntryModel();
$entry->getContent()->title = 'My New Entry';

// Assign the custom field values manually
$entry->getContent()->summary = craft()->request->getPost('fields.summary');
$entry->getContent()->body = craft()->request->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->setContentPostLocation('fields');

craft()->entries->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()->assets->insertFileByLocalPath(
        $uploadedFile->tempName,
        $uploadedFile->name,
        $folderId,
        AssetConflictResolution::KeepBoth
    );

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

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

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

craft()->entries->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.

> **Comments:**
> **username_0**: I was using insertFileByLocalPath, as I'm not taking input from a form (it's handling data from an API) - but the bit that I couldn't find documented was that I needed to set the assets field with an array of file IDs (which I already had from a call to getDataItem('fileId') on the response from insertFileByLocalPath). It probably seems incredibly basic - but I just couldn't find documentation or an example which showed this.  
> **username_1**: @Tom Yeah, I think this calls for us adding a new section to all the field type pages in the docs, explaining how their data should be formatted when saving elements, and also showing an example HTML form and PHP code.  
> **username_1**: @Tom Also hope you don’t mind that I edited your question to focus on the file being uploaded. It wasn’t entirely clear whether it was getting uploaded or not (thanks for the clarification), but I figured freshly-uploaded files are the majority use case, and answering that question kills both birds with one stone.  
> **username_0**: Just to update on this; sometimes this comes back with the error: "Integrity constraint violation: 1048 Column 'targetId' cannot be null. The SQL statement executed was: INSERT INTO `craft_relations`..." But not consistently. Any ideas?  
> **username_1**: @Tom You’re probably passing some blank values into the relation field’s array value.  
> **username_2**: @Tom, I am getting that same error anytime I upload a file that has a filename equal to one we've already uploaded.  
> **username_1**: @coffe4u Are you on the latest version of Craft? If so can you please email support@buildwithcraft.com with those details?  

---

