3

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!

  • @adrianthedev was right. Go to ```wp_posts``` DB table and look at the structure and check the **length**. I [limited](https://secure.php.net/manual/en/function.substr.php) ```post_name``` length: substr( $row['url'], 0, 199 ) – J. Doe Dec 24 '18 at 13:50

3 Answers3

9

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.

Gerald Schneider
  • 17,416
  • 9
  • 60
  • 78
  • Thank you! It's a very effective method – Iván Rodríguez Torres Apr 07 '16 at 11:12
  • Ended up in this same spot after debugging all the way to process_fields. My database is in ISO-8859-1 and I couldn't really set the PDO constructor to be charset=utf8mb4, My solution was right at the moment before calling wp_insert_post or wp_update_post I did this to the array $post_update_array = array( 'ID' => $post_id, 'post_title' => mb_convert_encoding($post->post_title, 'UTF-8', 'auto'), 'post_content' => mb_convert_encoding($post->post_content, 'UTF-8', auto), 'post_category' => $categories_ids ); – Gubatron May 05 '20 at 09:13
2

I had a similar problem and the cause of it was that the post_status parameter was more than 20 characters long.

https://codex.wordpress.org/Post_Status

Hope it helps!

adrianthedev
  • 626
  • 1
  • 11
  • 21
1

Make sure the encoding of the data being updated matches. In my case I needed to convert ISO-8859-1 data into UTF-8 multibyte on the array you pass to wp_update_post or wp_insert_post

$post_update_array = array(
'ID' => $post_id,
'post_title' => mb_convert_encoding($post->post_title, 'UTF-8', 'auto'),
'post_content' => mb_convert_encoding($post->post_content, 'UTF-8', 'auto'),
'post_category' => $categories_ids

);

Gubatron
  • 6,222
  • 5
  • 35
  • 37