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

api_channel_entries->submit_new_entry(3, $data) adds all custom fields! :(

Development and Programming

Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

So I’m trying to use api_channel_entries->submit_new_entry but whatever I do, I nothing works because the function adds all 10 custom field’s I have on my system (When this particular CHANNEL (id = 3) has NO custom fields.

The fields are then checked if it is required, then errors pop up.

Array
(
    [channel_id] => 3
    [title] => Sanford_Marketing Corp.
    [url_title] => sanford_marketing_corp
    [entry_date] => 1282051313
    [field_id_1] =>
    [field_id_2] => 
    [field_id_3] => 
    [field_id_4] => 
    [field_id_5] => 
    [field_id_6] => 
    [field_id_7] => 
    [field_id_8] => 
    [field_id_9] => 
    [field_id_10] => 
    [expiration_date] => 0
    [comment_expiration_date] => 0
    [author_id] => 1
    [status] => open
)

Help! been stuck for a while now.

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

Quick question:

is this a bug or is EE supposed to add all the fields_id_x’s in the $data array ?

thanks,

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

is

$this->EE->api_channel_fields->fetch_custom_channel_fields()

supposed to get ALL custom fields when run inside submit_new_entry?

<pre><code> if ( ! isset($this->EE->api_channel_fields) OR ! isset($this->EE->api_channel_fields->settings)) {

            $this->instantiate('channel_fields');
            $this->EE->api_channel_fields->fetch_custom_channel_fields();
        }[/code]

or the ones only associated with the current channel?

because it’s getting all field_id’s from channel_fields table.

anybody? :(

       
Chuck Liddell's avatar
Chuck Liddell
57 posts
15 years ago
Chuck Liddell's avatar Chuck Liddell
is
$this->EE->api_channel_fields->fetch_custom_channel_fields()
supposed to get ALL custom fields when run inside submit_new_entry?

What do you mean by “inside” submit_new_entry? Can you paste a code example, please?

fetch_custom_channel_fields() pulls all custom fields, not just the ones for a particular channel.

If you’re in doubt about how something behaves or what exactly it does, and the documentation doesn’t make it clear, I always suggest going to the source (code).

expressionengine/libraries/api/api_channel_fields.php, LINE 140:

function fetch_custom_channel_fields()
  {
    $this->EE->db->select('field_id, field_type, field_name, site_id, field_settings');
    $query = $this->EE->db->get('channel_fields');

There’s the exact query that is run by fetch_custom_fields().

Now if you wanted different behavior you’ll probably want to just write your own query.

Here is that same query but modified to handle a specific channel id:

$channel_id = 2;

$this->EE->db->select('field_id, field_type, field_name, site_id, field_settings');
$this->EE->db->from('channel_fields');
$this->EE->db->join('channels', 'channels.field_group = channel_fields.group_id');
$this->EE->db->where( 'channel_id', $channel_id );

$query = $this->db->get();

Now this new query won’t return the identical structure that fetch_custom_fields() does because fetch_custom_fields() does a bit of re-arranging and processing of the returned results before it hands them off to you.

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng
Hmm I tested my code out and it worked fine. I created a channel with no custom fields (also no custom field group), and was able to successfully call submit_new_entry. Basically the call was: submit_new_entry($channel_id, array(‘title’=>‘Test’)); Actually that call isn’t entirely accurate. There are a number of other fields that should always be included in your data array. ‘channel_id’=>$channelid, ‘entry_date’=>time(), ‘url_title’=>’‘, ‘ping_errors’=>FALSE, ‘ping_servers’=>array(), ‘revision_post’=>$_POST Which makes my true call to submit_new_entry look like this: submit_new_entry($channel_id, array( ‘title’=>‘Test’, ‘channel_id’=>$channel_id, ‘entry_date’=>time(), ‘url_title’=>’‘, ‘ping_errors’=>FALSE, ‘ping_servers’=>array(), ‘revision_post’=>$_POST)); Are you including those extra fields in your data array?

I did have some of those. I didn’t have revision_post => $_POST. (i will try it though)

the thing is, I’m accessing this code directly and not via a submit form so there is no $_POST. just a whole bunch of data I’m trying to create channel items with (from an XML file of data I’m importing)

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

@chuck

thanks for confirming that the function should return all channel fields from the table.

       
jimdoescode's avatar
jimdoescode
19 posts
15 years ago
jimdoescode's avatar jimdoescode

You don’t have to use the $_POST array for that field just any array with the data you wish to add will do. I think it is more for a reference purpose, though I haven’t dug in to the code to confirm this.

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

@jim

The code that is being run

$this->EE->load->library('api');
            $this->EE->api->instantiate('channel_entries');
            $data = array(
                'title'            => 'Breaking News Story!',
                'url_title'        =>    'test',
                'entry_date'        => time(),
                'channel_id'        => '3',
                'ping_errors'        => FALSE,
                'ping_servers'        => array(),
            );
            
            $data['revision_post']    = $data;
            
            if ($this->EE->api_channel_entries->submit_new_entry(3, $data) === FALSE)
            {
                show_error('An Error Occurred Creating the Entry');
            }

I have tried having the required fields in but I get the same results.

RESULTS:

Array
(
    [title] => Breaking News Story!
    [url_title] => test
    [entry_date] => 1282150856
    [channel_id] => 3
    [ping_errors] => 
    [ping_servers] => Array
        (
        )

    [revision_post] => Array
        (
            [title] => Breaking News Story!
            [url_title] => test
            [entry_date] => 1282150856
            [channel_id] => 3
            [ping_errors] => 
            [ping_servers] => Array
                (
                )

        )

    [field_id_1] => 
    [field_id_2] => 
    [field_id_3] => 
    [field_id_4] => 
    [field_id_5] => 
    [field_id_7] => 
    [field_id_8] => 
    [field_id_9] => 
    [field_id_10] => 
    [expiration_date] => 0
    [comment_expiration_date] => 0
    [author_id] => 1
    [status] => open
)

errorsArray
(
    [Date Generated] => The following field is required:
    [Proprietary Document Identifier] => The following field is required:
    [Company] => The following field is required:
    [Branch] => The following field is required:
    [Partner Product ID] => The following field is required:
    [Unit] => The following field is required:
)

Edited api_channel_entries code which has some “

" tags in to print out the errors.

<pre>/**
     * Submit New Entry
     *
     * Handles entry submission from an arbitrary, authenticated source
     *
     * @access    public
     * @param    int
     * @param    array
     * @return    mixed
     */
    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);


        // We break out the third party data here
        $this->_fetch_module_data($data, $mod_data);        

        $this->_check_for_data_errors($data);
        
        echo '<pre>';
        print_r($data);
        echo '</pre>

<p>’;
        echo ‘</p>

<pre>errors';
        print_r($this->errors);
        echo '</pre>

<p>’;</p>

<pre><code>    // Lets make sure those went smoothly

    if (count($this->errors) > 0)
    {
        return FALSE;
    }


—- Code cut off —-</pre>

The _base_prep method that’s actually the problem

function _base_prep(&$data)
    {    
        // Language Files
        if ($this->EE->config->item('site_pages') !== FALSE)
        {
            $this->EE->lang->loadfile('pages');
        }
        
        $this->EE->lang->loadfile〈'admin_content');
        
        // Sanity Check
        if ( ! is_array($data) OR ! isset($data['channel_id']) OR ! is_numeric($data['channel_id']))
        {
            show_error($this->EE->lang->line('invalid_api_parameter'〉);
        }

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

        // Is this user allowed to post here?
        $this->_cache['assigned_channels'] = $this->EE->functions->fetch_assigned_channels();
        
        if ( ! in_array($this->channel_id, $this->_cache['assigned_channels']))
        {
            show_error($this->EE->lang->line('unauthorized_for_this_channel'));
        }
        
        // Make sure all the fields have a key in our data array even
        // if no data was sent

        if ($this->autosave === FALSE)
        {
            
            if ( ! isset($this->EE->api_channel_fields) OR ! isset($this->EE->api_channel_fields->settings))
            {
                $this->instantiate('channel_fields');
                $this->EE->api_channel_fields->fetch_custom_channel_fields();
            }
            
            $field_ids = array_keys($this->EE->api_channel_fields->settings);
            
            foreach($field_ids as $id)
            {
            

            
                if (is_numeric($id))
                {
                    $id = 'field_id_'.$id;
                }

                if ( ! isset($data[$id]))
                {
                    $data[$id] = '';
                }
            }
            
        }
        // Helpers
        $this->EE->load->helper('text');
        $this->EE->load->helper('custom_field');
        return TRUE;
    }[/code]


Because I don't have api_channel_fields or api_channel_fields->settings set, the following code is run which adds ALL the custom_fields to the &$data array
[code]           if ( ! isset($this->EE->api_channel_fields) OR ! isset($this->EE->api_channel_fields->settings))
            {
                $this->instantiate('channel_fields');
                $this->EE->api_channel_fields->fetch_custom_channel_fields();
            }
       
jimdoescode's avatar
jimdoescode
19 posts
15 years ago
jimdoescode's avatar jimdoescode

You have

'field_id_6' => 'Some Data',

Does that mean you have added custom fields to your channel now?

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

sorry, no, that was me trying out something. but no, no required fields on this channel.

       
jimdoescode's avatar
jimdoescode
19 posts
15 years ago
jimdoescode's avatar jimdoescode

Is it feasible to delete the channel and make a new one? I would try that, or at least try a different channel and see if you get the same results. Maybe somehow the fields got messed up in the db and think they belong to a channel that they don’t belong to.

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

I actually get the exact same errors because it’s requiring all required custom fields, regardless of the channel it’s assigned to (for that matter, how DOES EE know which custom fields are assigned to which channel?)

       
jimdoescode's avatar
jimdoescode
19 posts
15 years ago
jimdoescode's avatar jimdoescode

It uses the exp_channel_fields table. Look in there and see if anything is out of the ordinary.

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

I wonder, how do i properly setup $this->api_channel_fields->settings so i can bypass the whole if statement that runs fetch_custom_channel_fields?

       
Jayson Ng's avatar
Jayson Ng
67 posts
15 years ago
Jayson Ng's avatar Jayson Ng

I might also mention that I’m working on the front end of ExpressionEngine - from the documentation, I found this comment in api_channel_fields file.

// If we started with a field_id, but we’re not on the frontend // (which means fetch_custom_channel_fields didn’t get called), // we need to make sure we have the proper field name.

which leads me to believe it was designed to run fetch_custom_channel_fields() when accessed from the frontend. But this causes the mentioned problem on my current project.

as of a few hours ago, I have bypassed this problem of mine by loading api_channel_fields before running the submit_new_entry method.

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

        if($this->EE->input->post('begin_import'))
        {


            $data = array(
                'title'            => 'Breaking News Story!',
                'url_title'        =>    'test',
                'entry_date'        => time(),
                'channel_id'        => '3',
                'ping_errors'        => FALSE,
                'ping_servers'        => array(),
            );
            
            $data['revision_post']    = $data;
            
            if ($this->EE->api_channel_entries->submit_new_entry(3, $data) === FALSE)
            {
                show_error('An Error Occurred Creating the Entry');
            }

This results to the channel entry successfully getting inserted, but $this->EE->api_channel_fields->settings are empty and I’m not sure if there are any consequences to that.

       

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.