Search code examples
phpwordpresscsvgenesis

Wordpress - db_insert_error when using insert_post


I'm currently using a CSV file, which is auto-updated daily, to create or update Wordpress posts for a client's website. The CSV has headers for the listing's address, city, state, etc., and each row is another listing. Currently, there are about 220 properties in the CSV. All but three of them are getting created as posts, but 3 of them aren't, and I'm getting a WP_Error like so -->

 WP_Error { 
       "errors"=> array{ ["db_insert_error"]=> 
                array{ [0]=> "Could not insert post into the database" }}
       "error_data"=> array { } 
       "ID"=> int(0) 
       "filter"=> "raw"
 }

I know that the plugin at least works since all the others are getting posted, but it seems that these three for some reason are getting this error. They don't have any special characters in them or other data that would differentiate them from the other rows. Here's my array and code I'm using to create the new post:

$new_post = array(
        'post_title'   => $title,
        'post_content' => wpautop(convert_chars($data['csv_post_post'])),
        'post_status'  => $opt_draft,
        'post_type'    => 'listing',
        'post_date'    => $this->parse_date($data['csv_post_date']),
        'post_excerpt' => '....',
        'post_name'    => $data['csv_post_slug'],
        'post_author'  => $this->get_auth_id($data['csv_post_author']),
        'tax_input'    => $this->get_taxonomies($data),
        'post_parent'  => $data['csv_post_parent'],
);
$pricecheck = trim($data['_listing_price']);

Where $title is a pre-joined string of the address, city, and state.

if (!get_page_by_title( $new_post['post_title'], 'OBJECT', 'listing') && $pricecheck != "") {
    $id = wp_insert_post($new_post, true);
}

I know that none of the above fields or variables are empty, and it gets to wp_insert_post() fine, but it won't insert. Any help would be greatly appreciated!


Solution

  • I got a similar problem today so I'll share what lead me to the solution (the solution might be different for you, but the way will help).

    I got the same error message with absolutely no helpful text, so I dug into the WordPress source code and started debugging.

    The error is thrown in only one place in wp_insert_post(), when $wpdb->insert() returns false:

    if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
        if ( $wp_error ) {
            return new WP_Error('db_insert_error', __('Could not insert post into the database'), $wpdb->last_error);
        } else {
            return 0;
        }
    }
    

    $wpdb->insert() makes some sanity checks before doing the insert, using process_fields() in wp-includes/wp-db.php.

    protected function process_fields( $table, $data, $format ) {
        $data = $this->process_field_formats( $data, $format );
        if ( false === $data ) {
            return false;
        }
    
        $data = $this->process_field_charsets( $data, $table );
        if ( false === $data ) {
            return false;
        }
    
        $data = $this->process_field_lengths( $data, $table );
        if ( false === $data ) {
            return false;
        }
    
        $converted_data = $this->strip_invalid_text( $data );
    
        if ( $data !== $converted_data ) {
            return false;
        }
    
        return $data;
    }
    

    I started adding var_dump($data) between each check and the following if-clause to see where the error came from.

    In my case the problem was after the strip_invalid_text() call, which lead me to the cause of my problem:

    I was reading the data to insert from a different database and it came in the wrong encoding. After adding charset=utf8mb4 to my PDO constructor all data was in utf8 and the wp_insert_post() worked instantly.

    It is hard to say what caused the problem in your case, it could be a wrong charset, a wrong format, a field that's too long ... WordPress doesn't really discloses what's the problem. To find it you really have to look closely.