Custom database table
-
Hi to everyone,
thank you so much for the work on this plugin.Is it possible to save all the fields of a CMB2 metabox into a new custom table in WP database instead of prefix_postmeta?
Thank you in advance for the help!
-
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_valuefilters 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.
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}_fieldshook is what I need.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 ); }Cool
The topic ‘Custom database table’ is closed to new replies.