The question:
How do I save each option in a multiple select menu as it’s own meta_key + meta_value pair?
This is the basic multiple select menu. Note: multiple select menus allow you to select more than one option.
<select name="products[]" multiple>
<option value="1">Product One</option>
<option value="2">Product Two</option>
<option value="3">Product Three</option>
.... etc
</select>
The bit of code inside the save_post
function that I need help with.
if ( isset( $_POST[ 'products' ] ) ) {
foreach ( $_POST[ 'products' ] as $product ) {
// this would just keep adding the products as separate meta keys, which is what I want, but I need to modify it so it deletes them when they are unselected.
add_post_meta( $post_id, 'products', $product, false );
}
}
I’d like each option to be it’s own meta key and value pair and not a serialized array. If the multiple select menu is updated I’d like old values no longer selected to be removed from the postmeta table with delete_post_meta
.
For example, the wp_postmeta table would look like this:
post_id meta_key meta_value
45 products 2
63 products 3
12 products 1
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
Try this inside save_post
but please note the code is not tested
$old = get_post_meta($post_id, 'products');
$new = isset ( $_POST['products'] ) ? $_POST['products'] : array();
if ( empty ($new) ) {
// no products selected: completely delete alla meta values for the post
delete_post_meta($post_id, 'products');
} else {
$already = array();
if ( ! empty($old) ) {
foreach ($old as $value) {
if ( ! in_array($value, $new) ) {
// this value was selected, but now it isn't so delete it
delete_post_meta($post_id, 'products', $value);
} else {
// this value already saved, we can skip it from saving
$already[] = $value;
}
}
}
// we don't save what already saved
$to_save = array_diff($new, $already);
if ( ! empty($to_save) ) {
foreach ( $to_save as $product ) {
add_post_meta( $post_id, 'products', $product);
}
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0