Change content before writing to database

I’ve searched around but I can’t quite pin down the answer for this. I am attempting to use the content of a custom field as post_data and save it to the database as such when a post is created or updated. I need to do this in order to make a frontend posting solution work out using the plugin Advanced Custom Fields.

I think I need something like this:

Read More
function tsv_content_save_pre( $post_id ){
            global $post;
            $tsvpost = get_post($post_id);
            $tsvifempty = $tsvpost->post_content; //The "real" post_content
            $tsvcontent = get_field('article_content'); //The custom content

            if ($tsvifempty == NULL) { //Check if the "real" post content has anything in it first.

        $tsvargs = array('post_content' => $tsvcontent);
        wp_update_post ($tsvargs);

            }       
    }
        add_filter('content_save_pre'  , 'tsv_content_save_pre'  );

But I’m stuck there. I’m not a plugin developer so filters and such are hard for me to navigate. Can anyone help get me pointed in the right direction?

Thanks in advance.

Related posts

Leave a Reply

3 comments

  1. First, content_save_pre is a very old hook. Adam Brown has a warning that:

    This hook does not occur in the most recent version of WordPress
    (3.5). Do not use it. It is deprecated. You should look at the list of
    “related hooks” below to see if you can figure out what replaced it.

    I would suggest a solution similar to one I proposed for a question asking about restricting status changes based on content word count.

    Following your code very closely, the solution should look like this:

    function cmeta_as_content_wpse_92012($data){
      if (!empty($data['post_content'])) {
        $tsvcontent = get_field('article_content'); //The custom content
        $data['post_content'] = $tsvcontent;
      }
      return $data;
    }
    add_action('wp_insert_post_data','cmeta_as_content_wpse_92012');
    

    But I have concerns:

    1. I don’t know if get_field will work in that context
    2. If I have found the right docs for get_field it looks like the function pulls data from the database, so it isn’t going to do you any good for updating a post– well, unless you update the post and the postmeta and then run another query to alter the post data, which seems profligate. And your question does specify “before writing to database”.

    So instead of the above, I think I would parse the $_POST data directly.

    function cmeta_as_content_wpse_92012($data){
      global $_POST;
      if (!empty($data['post_content']) && !empty($_POST['meta'])) {
        foreach ($_POST['meta'] as $v) {
          if ('article_content' == $v['key']) {
            $data['post_content'] = wp_kses( $v['value'] ); // The custom content
          }
        }
      }
      // var_dump($_POST,$data); die; // debugging
      return $data; 
    }
    add_action('wp_insert_post_data','cmeta_as_content_wpse_92012',1);
    

    Still more caveats:

    1. I can’t remember at which step WordPress applies its own filters, so I applied wp_kses
    2. Item #1 may be overkill
    3. Item #1 may not be the particular validation function you want
    4. If there are multiple custom meta fields with the same key– article_content— the last one, and only the last one, will be used.
  2. I think you need to have a post ID in your arguments array. From the doc:

    Filling out the ID field is not strictly necessary but without it
    there is little point to using the function.

    $tsvargs = array(
    'ID'                => $post_id,
    'post_modified'     => date("Y-m-d H:i:s"),
    'post_modified_gmt' => date("Y-m-d H:i:s"),
    'post_content'      => $tsvcontent
    );
    $post_id = wp_update_post($tsvargs);
    if ($post_id == 0) {
        // handle error here
    }
    
  3. OK, via WPQuestions.com I was able to get someone to figure this out. It requires 2 functions, 1 to handle posting on the front-end and another to handle posting on the back-end. Because ACF uses a custom function called acf/save_post instead of WP native save_post there was some extra work involved.

    Here is the final working solution:

        //Save ACF field as post_content for back-end
    add_action('save_post', 'change_content');
    
    function change_content($post_id) {
    
            $post_content = get_post_meta($post_id,'article_content',true);
    
    
    
            $my_post = array();
    
                    $my_post['ID'] = $post_id;
    
                    $my_post['post_content'] = $post_content;
    
    remove_action('save_post', 'change_content');
    
                        wp_update_post( $my_post );
    
    add_action('save_post', 'change_content');
    
        }
    
    //Save ACF field as post_content for front-end
    
    add_action('acf/save_post', 'change_content_frontend');
    
    function change_content_frontend($post_id) {
    
            $post_content = get_post_meta($post_id,'article_content',true);
    
    
    
            $my_post = array();
    
                    $my_post['ID'] = $post_id;
    
                    $my_post['post_content'] = $post_content;
    
    remove_action('acf/save_post', 'change_content_frontend');
    
                        wp_update_post( $my_post );
    
    add_action('acf/save_post', 'change_content_frontend');
    
        }
    

    Hopefully this helps someone trying to do something similar!