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:
<form method="post" enctype="multipart/form-data">
And the file input needs to have an input name based on the Assets field’s handle:
<input type="file" name="fields[myAssetsFieldHandle]">
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.