ExpressionEngine channel API – files
I have recently been trying to insert channel data directly into an ExpressionEngine site using their API. The situation is a little better than that of my previous post regarding members as there is an API there for you to use. There are still some gotchas to the process tho. The most troublesome so far has been when the channel has a file field on it.In this post i’ll cover how to add the path to a file when inserting data without the need to have POST’d the data.
To begin, if you look at the data stored for an existing entry with a file in the channel_data table in your EE database you will see that it is stored in the format:
So your first attempt at uploading the data you would probably try moving the image file to the correct directory then inserting the previous string with the correct directory id and field id. Like so:
N.b. You can get the directory ids from the upload_prefs table and the field ids from the channel_fields table.
Doing that however results in the following:
It looks like the Channel API inserts the directory id itself and as we didn’t pass it we get an empty string. Checking out the Publish form with Firebug we see that in addition to the field_id_24 field it is sending a field called field_id_24_directory containing the directory id to store the image in. The next attempt now looks something like this:
$this->EE->api->instantiate(array('channel_entries', 'channel_categories', 'channel_fields'));
$data['field_id_24'] = $filename;
$data['field_id_24_directory'] = $dir_id;
$this->EE->api_channel_entries->submit_new_entry($channel_id, $data);
The still doesn’t work as you are left with this:
So you are passing all of the correct data but for some reason the directory id isn’t being recognised. After a lot of digging the trail eventually leads to the File fieldtype class’ save method. which i will reproduce in full:
{
if ($data != '')
{
$directory = 'field_id_'.$this->field_id.'_directory';
$directory = $this->EE->input->post($directory);
return '{filedir_'.$directory.'}'.$data;
}
}
Do you see the problem? After the Channel API being perfectly happy to run with data that you provide it rather than resorting to checking the $_POST variables the file fieldtype lets us down by requiring that the directory id is set in the POST data. Now we know what the problem is we can fix it, in a fairly hacky way. Our next and final attempt would look something like this:
$this->EE->api->instantiate(array('channel_entries', 'channel_categories', 'channel_fields'));
$data['field_id_24'] = $filename;
$_POST['field_id_24_directory'] = $dir_id;
$this->EE->api_channel_entries->submit_new_entry($channel_id, $data);
And thats it, we have successfully added an image to a channel entry without needing to POST the data through a form, the only side affect is that we are left feeling slightly dirty about our code.