Question

I have looked around for an answer here but I didn't find exactly what I'm looking for so I give this a try:

  • I'm creating a plugin.
  • I've created a custom post type
  • I've created a metabox associated to this CPT
  • In this metabox I have a a lot of form elements (From these values in the metabox I want to create new content for the current post (It's here I'm having an issue))

I'm using this: (it's a class based plugin)

 //I'm using this hook because then I can retrieve the values of $_POST from the metabox
 add_action( 'pre_post_update', array( $this, 'save_csvtohtml_settings'), 10, 3 );


 public function save_csvtohtml_settings( $post_ID, $current_data ) 
 {        
     //I want some values from $_POST to be used to create a new content
     //in the actual post

     //Example:
     //$_POST['frm_source_files'] = 'bundeslander_staple.csv';
     //$current_data['post_content'] = 'bundeslander_staple.csv';

     $current_data['post_content'] = $_POST['frm_source_files'];
         
     //Because this is a pre post update, I don't want to do 
     //a "save post" here (then I think it will mess up?)    
     return $current_data; //Wouldn't it be nice if this worked? :-)
 }
  1. Am I using the correct hook? (pre_post_update)
  2. How do I change content value in db - to the generated value ($_POST['frm_source_files']) from my form in my metabox?

I know the actual hook is executed (save_csvtohtml_settings()) .

Yes, I know that I could save a lot of metadata values from my form but I'm only interested in the actual generated content. In my scenario it would be unnecessary to save every single value into the database.


I've also tried this:

function ... {
...
....
add_filter( 'wp_insert_post_data' ,  array( $this, 'save_csvtohtml_settings') 
, '99', 2 );                
----
}

public function save_csvtohtml_settings( $post_ID, $current_data ) 
{                     
    //Generate shortcode from settings form (in metabox)       
     $shortcode = '[csvtohtml_create ';            
     $shortcode_attributes = [];
     
     foreach( $_POST as $p_key => $p_item )
     {                   
         if (substr($p_key, 0, 4) == 'frm_') {
             if (mb_strlen($p_item) > 0) 
             {
                 $attribute = substr($p_key,4);                        
                 $shortcode_attributes[] = substr($p_key,4) . '="' . $p_item . '"';
             }
         }    
     }
     $shortcode .= implode(' ', $shortcode_attributes);
     
     $shortcode .= ']';

      
     $current_data['post_content'] = $shortcode;
   

    // Change post content to the generated code (from current attributes)
    //This changes in array $current_data but does not save the actual post
    return $current_data;
}
Was it helpful?

Solution

The second attempt is closer to the result, as it is filer, not action, and you can return proper data. But code has several mistakes, I have fixed them.

The proper number of parameters for the filter is 3. The first parameter is $data which should be modified and returned. It is the standard behaviour for any filter in WordPress.

The priority must by an integer and does not need to be set to 99. I use standard 10.

Here is the tested working code:

/**
 * Filters slashed post data just before it is inserted into the database.
 *
 * @param array $data                An array of slashed, sanitized, and processed post data.
 * @param array $postarr             An array of sanitized (and slashed) but otherwise unmodified post data.
 * @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed post data as
 *                                   originally passed to wp_insert_post().
 *
 * @return array
 */
public function save_csvtohtml_settings( $data, $postarr, $unsanitized_postarr ) {
    // Generate shortcode from settings form (in metabox).
    $shortcode            = '[csvtohtml_create ';
    $shortcode_attributes = [];

    foreach ( $_POST as $p_key => $p_item ) {
        if ( ( strpos( $p_key, 'frm_' ) === 0 ) && '' !== $p_item ) {
            $attribute              = substr( $p_key, 4 );
            $shortcode_attributes[] = substr( $p_key, 4 ) . '="' . $p_item . '"';
        }
    }
    $shortcode .= implode( ' ', $shortcode_attributes );
    $shortcode .= ']';

    $data['post_content'] = $shortcode;

    return $data;
}

add_filter( 'wp_insert_post_data', array( $this, 'save_csvtohtml_settings'), 10, 3 );
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top