Save values from a pre_post_update

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 );