We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

Trying to use api_channel_entries -> submit_new_entry? Good luck! ;)

Development and Programming

Chuck Liddell's avatar
Chuck Liddell
57 posts
15 years ago
Chuck Liddell's avatar Chuck Liddell

This post is part rant, part reference, and is intended to help out any poor souls that might be trying to use the submit_new_entry() function of api_channel_entries.

As far as I can tell (and please correct me if I’m wrong) if called from a custom module the function in its current state will not work. At all.

Now before you get up in arms, allow me to do the following:

1) Explain myself, and show you why it doesn’t work 2) Show you how you CAN make it work (no bitching without backing it up, right?) 3) Provide references to some other poor souls that have struggled with this

There are actually three separate issues that are at the heart of the problem with submit_new_entry:

1) documentation is inconsistent and incorrect 2) channel_id handling is awkward and inconsistent 3) required fields are incorrectly handled

Let’s go through them one at a time:

1. Documentation The User Guide states that submit_new_entry needs “a title, an entry date, and data for all required custom fields”, and provides the following example code:

$data = array( 
  'title' => 'Breaking News Story!',
  'entry_date' => '1256953732',
  'field_id_6' => 'Some data', 
  'field_id_19' => 'More data'
); 

if ($this->EE->api_channel_entries->submit_new_entry(4, $data) === FALSE) 
{ 
  show_error('An Error Occurred Creating the Entry'); 
}

Helpful? Yes. Accurate? No. Actually there are a few more required parameters that are not mentioned in the docs (but fewer than you might think).

Two additional fields are required (for now) in your $data array, both of which have been filed as bugs in the Bug Tracker: channel_id and ping_servers.

$data[‘channel_id’] should be set to the actual channel_id you are trying to access. That first parameter in submit_new_entry( channel_id, data )? Yeaaahh that’s not actually used. Oops.

$data[‘ping_servers’] = array() will get you around this bug for now

2. Channel ID Submit_new_entries( channel_id, data ) doesn’t actually pay attention to what you pass for the first parameter or use it to submit the entry. Instead, it looks in your data array for a channel_id keyed entry. This is doubly confusing because you wonder 1) why is my parameter being ignored and 2) why am I getting this strange error ‘Could not create/update entry. Missing api parameter.’ (hint: you didn’t pass data[‘channel_id’]).

Just another random example of channel_id awkwardness is the beginning of the _fetch_channel_preferences function:

function _fetch_channel_preferences($channel_id = FALSE)
    {
        // Add another api
        $this->instantiate('channel_structure');
        
        if ( ! $channel_id)
        {
            $channel_id = $this->channel_id;
        }
        
        $query = $this->EE->api_channel_structure->get_channel_info($this->channel_id);

(look at the last line carefully)

It’s a good thing $this->channel_id was already set on line 895:

$this->channel_id = $data['channel_id'];

Wait a minute…I thought I didn’t have to put channel id inside $data?

See what I mean?

3. Required Fields

The main problem that stops us dead in our tracks is that when submit_new_entry is called it pulls a list of every custom field in the database, and then checks to make sure that we have included all of those fields that are required.

This doesn’t make much sense. For a specific channel you really only want the custom fields that are required FOR THAT CHANNEL. Not all channels.

So how do I actually get the damn thing working? My boss wants this yesterday.

Good question. Here are two approaches, one is a hack (but doesn’t require modifying any EE files) and one is an actual fix (requires changes to api_channel_entries).

       
Chuck Liddell's avatar
Chuck Liddell
57 posts
15 years ago
Chuck Liddell's avatar Chuck Liddell

Approach #1 - The Hack

Approach #1 is fine unless you are using any custom fields or module fields that require FieldType processing when they are saved to the db. The FieldType save() functions for each field will not be called using this approach.

Here is the code you need for approach #1:

$this->EE->load->library('api');
$this->EE->api->instantiate('channel_entries');

// This ensures $api_channel_fields->settings = array(),
// which we need so that the myriad field ids that base_prep
// dumps into $data will not trigger required field errors.
// They're not required if we don't KNOW they're required, right? :wink:
$this->EE->api->instantiate('channel_fields');
      
      $data = array (
        'title'       => 'Your Awesome Title',
        'channel_id'  => '1', // circumvents bug #13483
        'entry_date'  => time(),
         'ping_servers'=>array() // circumvents bug #14008
         // any additional custom fields this channel requires
         // in the format 'field_id_4' => 'some value'
      );
      
      if ($this->EE->api_channel_entries->submit_new_entry( 1, $data) === FALSE) 
      { 
        $errors = $this->EE->api_channel_entries->errors;
         show_error('An Error Occurred Creating the Entry: <pre>' . print_r( $errors, true ) . '</pre>

<p>’);
      }
</pre>

       
Chuck Liddell's avatar
Chuck Liddell
57 posts
15 years ago
Chuck Liddell's avatar Chuck Liddell

Approach #2 - The Fix

You’ll have to edit api_channel_fields.php if you want to actually fix these problems. Below are the changes you need to make, in before and after code blocks.

BEFORE: Starts on line 78. We set channel id and we move up _fetch_channel_preferences so base_prep can use its results.

function submit_new_entry($channel_id, $data)
    {
        $this->data =& $data;
        $mod_data = array();
        
        $this->_initialize(array('channel_id', 'entry_id', 'autosave'));

        if ( ! $this->_base_prep($data))
        {
            return FALSE;
        }

        if ($this->trigger_hook('entry_submission_start') === TRUE)
        {
            return TRUE;
        }
        
        // Data cached by base_prep is only needed for updates - toss it
        
        $this->_cache = array();
        
        $this->_fetch_channel_preferences();
        $this->_do_channel_switch($data);

AFTER:

function submit_new_entry($channel_id, $data)
    {
        $this->data =& $data;
        $mod_data = array();

        $this->_initialize(array('channel_id', 'entry_id', 'autosave'));

          $data['channel_id'] = $channel_id; // otherwise we break _base_prep() dependency needed by update_entry()
          $this->EE->load->helper( 'text_helper' ); // needed for ascii_to_entities in _fetch_channel_preferences()
        $this->_fetch_channel_preferences( $channel_id ); // this moves up so we can use c_prefs in _base_prep()

        if ( ! $this->_base_prep($data))
        {
            return FALSE;
        }

        if ($this->trigger_hook('entry_submission_start') === TRUE)
        {
            return TRUE;
        }
        
        // Data cached by base_prep is only needed for updates - toss it
        
        $this->_cache = array();
        
        $this->_do_channel_switch($data);

BEFORE: Starts on line 170. Fixes bug #14008.

if (count($data['ping_servers']) > 0)

AFTER:

if ( isset($data['ping_servers']) && count($data['ping_servers']) > 0)

BEFORE: Starts on line 958. Fixes bug #14009, and also allows us to pull the field_group for this channel (which we can use to pull the correct custom fields).

$query = $this->EE->api_channel_structure->get_channel_info($this->channel_id);

foreach(array('channel_url', 'rss_url', 'deft_status', 'comment_url', 'comment_system_enabled', 'enable_versioning', 'max_revisions') as $key)
        {
            $this->c_prefs[$key] = $query->row($key);
        }

AFTER:

$query = $this->EE->api_channel_structure->get_channel_info($channel_id);

foreach(array('channel_url', 'rss_url', 'deft_status', 'comment_url', 'comment_system_enabled', 'enable_versioning', 'max_revisions', 'field_group') as $key)
        {
            $this->c_prefs[$key] = $query->row($key);
        }

BEFORE: Starts on line 916. Part of the fix to prevent required fields from other channels throwing errors. The original code pulls every single custom field id out of the database, the replacement code only pulls field ids for fields from the channel being published to.

$field_ids = array_keys($this->EE->api_channel_fields->settings);

AFTER:

$field_ids = array();
$field_query = $this->EE->channel_model->get_channel_fields($this->c_prefs['field_group'], array('field_id'));
if( $field_query->num_rows() > 0 )
{
  foreach( $field_query->result_array() as $channel_field )
    $field_ids[] = $channel_field['field_id'];
}

References: BugTracker:// ffurger reports secret required channel id bug BugTracker:// Jayson Ng reports required fields bug BugTracker:// Jayson Ng reports incorrect documentation on required fields BugTracker:// ping_servers should not be required BugTracker:// _fetch_channel_preferences ignores passed parameter Forum:// Jayson Ng discussion on incorrectly handled required fields Forum:// ender discussion on incorrectly handled required fields Forum:// ffurger discussion on secret channel id requirement

       
Chuck Liddell's avatar
Chuck Liddell
57 posts
15 years ago
Chuck Liddell's avatar Chuck Liddell

Update: Looks like all of the issues I have mentioned here are marked ‘Fixed for next release’ in the Bug Tracker, so hopefully if you’re running a version later than 2.1 20100810 you shouldn’t have to worry about any of this anymore!

       
Cyborg's avatar
Cyborg
22 posts
15 years ago
Cyborg's avatar Cyborg

Thank you for this information! Stopped me for loosing more hours!

       
leonardteo's avatar
leonardteo
32 posts
15 years ago
leonardteo's avatar leonardteo

Thank you, this solved a LOT of problems. The documentation should be updated for anyone still banging their heads about this issue.

Leonard

       
chichilatte's avatar
chichilatte
43 posts
15 years ago
chichilatte's avatar chichilatte

thanks chuck!!

       
Darren Miller's avatar
Darren Miller
103 posts
15 years ago
Darren Miller's avatar Darren Miller

I’ve just created a module to batch-import channel entries from a CSV and also ran into some of the problems noted above.

This was for a site running 2.1.0 build 20100810 - we’re not in a position to upgrade to the latest build as yet - so some of this may be solved. But in case this helps anyone I have a slightly simpler fix for the custom field validation problem.

First thing - role your own validation to ensure data is correct. Then, instantiate the API as follows:

$this->EE->load->library('api');
$this->EE->api->instantiate('channel_entries');

$this->EE->api->instantiate('channel_fields');
$this->EE->api_channel_fields->settings = array();

And you’ll no longer get the pointless nags about irrelevant custom fields.

It’s probably a bit heavy handed but it does the trick.

       
chichilatte's avatar
chichilatte
43 posts
15 years ago
chichilatte's avatar chichilatte

Ah yes! I did notice there were fields being processed from previous api_channel_entries calls. Was wondering how to clear them, thanks!

       
Vinny D's avatar
Vinny D
2 posts
15 years ago
Vinny D's avatar Vinny D
Approach #2 - The Fix —————————————————— You’ll have to edit api_channel_fields.php if you want to actually fix these problems. Below are the changes you need to make, in before and after code blocks.

For those EE newbies like me, you actually need to edit api_channel_entries.php to make Chuck’s referenced changes.

The fixes seem to work really well, but don’t play nicely with some extensions like Playa and Matrix. Content is submitted properly, though. [EDIT: Darren’s reco appears to have removed most of the nag messages. Little more troubleshooting on my end to do. Thanks!]

Thank you!

       

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.