Viewing 8 replies - 1 through 8 (of 8 total)
  • Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    If it is, it’s something we haven’t tried to implement at all, since meta box values are generally intended to be saved as post meta, and using the prefix_postmeta table makes all of the data accessible to the WP core API without any hassle. The closest that we come to something besides prefix_postmeta/prefix_usermeta would be the options table.

    (I realize this is an old question, but putting my response here in case someone else finds it looking for the same info.)

    I have done this by using the cmb2_override_meta_save, cmb2_override_meta_remove, cmb2_override_meta_value filters to override the getting/setting of the values.

    The issue I’m having (and how I stumbled upon this old question) is that filter is called for each individual field rather than once for the custom post type. So it’s a lot of database calls that could be done in a single SELECT or UPDATE/INSERT call.

    Sometimes the postmeta table isn’t the best place to store custom post type data. A single row for each post’s data instead of a row for every piece of data makes querying much more efficient if you need to do something other than just display the post type’s content.

    Plugin Author Justin Sternberg

    (@jtsternberg)

    If you wanted to do the reads/writes/deletes with one SELECT/UPDATE/INSERT/DELETE, you could certainly do it. Without out getting into the nitty-gritty, Take a look at the network-theme-options example, as it’s doing something very similar: https://github.com/WebDevStudios/CMB2-Snippet-Library/blob/master/options-and-settings-pages/network-options-cmb.php

    Thanks! I’ll have to look through that code deeper. I thought the options were saved in a single database transaction because they were stored as a single column of serialized data via something WP was doing.

    Ah! I think the cmb2_save_{$object_type}_fields hook is what I need.

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Some field types get saved as serialized data, but not all of them, if I recall right.

    Okay I have this working (without multiple database calls). Here’s is some pseudocode of how I did it:

    Because my plugin is currently not written with classes, I used a global variable. A class variable would probably be better.

    For the retrieval of the data, I didn’t change anything, because on the first call to the database, the results are cached so each subsequent field just pulls from the cache.

    For the saving of the data, I did it in two steps.

    The first step saves the updated data to the global variable on CMB2’s override hook in an array of ( post_meta_field_id => value ). Some of my fields are saved in a custom table, and some are saved using WordPress’ tables via CMB2 (mainly, repeated groups). So I have a check for if the field is part of the custom table or not.

    The 2nd step is triggered through WP’s save_post hook to actually save to the database, from the global variable I created.

    add_filter('cmb2_override_meta_remove', 'your_save_meta_data_function', 10, 2);
     add_filter('cmb2_override_meta_save', 'your_save_meta_data_function', 10, 2);
     function your_save_meta_data_function( $override, $a ) {
    // if not the right post type, return what we got in
    	if ( get_post_type() != 'your_post_type' ) {
    		return $override;
    	}
    
    	// v3.1 by adding meta_remove filter, now this is sometimes called without the value element
    	// add the element as blank text
    	// this is necessary (vs just exiting the function) because otherwise if a field is left blank
    	// it won't get saved as such without the meta_remove filter
    	if (!array_key_exists('value', $a)) {
    		$a['value'] = null;
    	}
    
            // if not a field for the custom table, just return
            // what we got in and let CMB2 handle saving it.
    	global $mbdb_edit_book;
    	if ( in_custom_table( $a['field_id'] ) ) {
    		$mbdb_edit_book[$a['field_id']] = $a['value'];
    		return 'override';
    	} else {
    		return $override;
    	}
    }
    
    // set priority to 20 to ensure it runs after CMB2's hook
    add_action('save_post', 'you_save_custom_table_function', 20);
    function you_save_custom_table_function( $post_id ) {
    	if (!get_post_type() == 'your_post_type') {
    		return;
    	}
    
    	// save custom database fields to database
    	global $mbdb_edit_book;
    
            // this translates post meta field ids to column names,
            // sanitizes the data, and ultimately calls wpdb->update or insert
    	save_custom_post( $mbdb_edit_book, $post_id );
    
    }
    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Cool

Viewing 8 replies - 1 through 8 (of 8 total)

The topic ‘Custom database table’ is closed to new replies.