4

I have two fields in wp_posts table that wp_update_post() seems to be unable to change. I'm trying to use the following code:

$echo $group_access;
$echo $tag_list;
$my_post = array(
      'ID'           => 12095, 
      'post_title'   => 'Test Title',
      'post_content' => 'Test Content',     
      'group_access' => $group_access,
      'tag_list'     => $tag_list,
  );
// Update the post into the database
$post_id = wp_update_post( $my_post, true );

if (is_wp_error($post_id)) {
    $errors = $post_id->get_error_messages();
    foreach ($errors as $error) {
        echo $error;
    }
}

The $group_access and $tag_list variables echo the correct values. The post_title and post_content update correctly. group_access and tag_list do not update, and there is no error either.

Naturally, I've checked the table and group_access and tag_list are the correct column headers.

I'm baffled why it doesn't work. Is wp_update_post() unable to change columns that are not part of the default WP install? Is it possibly a datatype thing (e.g. I should be passing an array or integer, but I'm passing a string)?

3

You are correct; WordPress will not update custom database columns using wp_update_post() or wp_insert_post(). Instead of creating custom database columns, consider using post meta and/or taxonomy APIs.

If you must altar the wp_posts table, you will need to update your custom columns on your own and you may run into issues with various other plugins who don't take the custom database columns into account.

  • Ok, so it will not update because they are custom made columns. That's good to know. Is there no workaround with a different function or something? I didn't create these columns; a plugin I depend heavily on created and uses them, so I don't really have a choice in that. I'm still very much a WP novice. What are taxonomy API's? – fredsbend Mar 3 '17 at 22:18
  • Check out register_taxonomy() for taxonomies. Taxonomies are good for storing values that are repeated (for example, car model, car year). Meta data is better for things like phone numbers, but bear in mind that meta queries are significantly slower than taxonomy queries. Since a plugin is involved here, you should contact the developers of the plugin for advice on how to proceed as this is out of scope for WPSE. The plugin may have its own API. – Dave Romsey Mar 3 '17 at 22:27
  • Oh, boy, have I been in contact with the plugin developers! At great length too! Part of the problem is I'm at novice level, so I may have been or still am asking the wrong questions. Thanks, so far. I have doubts that there's no way to do this, but +1 for answering and helping. – fredsbend Mar 3 '17 at 22:32
  • You got it! I'd imagine that they have some way of updating these columns that you can likely leverage yourself. Try exploring their code using a search tool such as grep to locate one of the column strings such as group_access. This should point you in the right direction. Good luck! – Dave Romsey Mar 3 '17 at 22:38
  • I guess I may have too. It's a very extensive plugin. Through the gui, I can update these fields, but that's one post at a time. My final goal here is to be able to update hundreds of posts at once with with a csv. I'm so close ... – fredsbend Mar 3 '17 at 22:44
3

wp_insert_post_data fires almost immediately before the post data is inserted into the database. The only thing that happens after this is that the $data is wp_unslash(). You should be able to use this filter to compare the $postarr you sent wp_update_post with the $postarr that is passed to this filter. If the two are different, then you can format the $data before it's inserted into the database.

I quickly mocked this up. Haven't tested it, but it should work with minor modifications.

In class-wpse-258786.php:

class wpse_258786 {
  protected $postarr;
  public function __construct( $postarr ) {
    $this->postarr = $postarr;
  }
  public function insert_post_data( $data, $postarr ) {
    //* Make sure this is added each time before each post
    remove_action( 'wp_insert_post_data', [ $this , 'insert_post_data' ] , 10 );

    if( $postarr !== $this->postarr ) {
      //* Format the $data to insert into table
    }
    return $data;
  }
}

in your-file.php

include_once( PATH_TO . 'class-wpse-258786.php' );

...

$echo $group_access;
$echo $tag_list;
$my_post = array(
      'ID'           => 12095, 
      'post_title'   => 'Test Title',
      'post_content' => 'Test Content',     
      'group_access' => $group_access,
      'tag_list'     => $tag_list,
  );

//* Filter the post data before inserting into database
add_action( 'wp_insert_post_data',
  [ new wpse_258786( $my_post ), 'insert_post_data' ], 10, 2 );

// Update the post into the database
$post_id = wp_update_post( $my_post, true );

Edit to add: What I would do would be to place the class in a separate file, include it once, and then add the filter to the class. Then right before you wp_update_post() add the filter with the post data in the constructor. When the hook fires, then you can remove the filter to make sure it doesn't fire more than once.

In response to your comment, you could use $wpdb, and in fact, that's how wp_insert_post() does it. The great thing about using the wp_insert_post() abstraction is that it introduces a lot of action and filter hooks that we can use to modify the data before it's entered into the database. Check out the wp_insert_post() function on trac.

  • Thank you for the answer. Would this be a similar suggestion as offered here? This would actually update wp_posts table with the fields I'm trying to target? – fredsbend Mar 3 '17 at 22:54
  • Yes. Both answers are using the wp_insert_post_data filter to change the $data immediately before it's saved to the database. – Nathan Johnson Mar 3 '17 at 22:59
  • Ok, so where do I place this class code? It doesn't look like I can just drop it where I was working in the code in my question. – fredsbend Mar 3 '17 at 23:01
  • It seems I can use wpdb class to make the updates. Does that seem right? – fredsbend Mar 3 '17 at 23:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.