Home › Toolset Professional Support › [Resolved] add_post_meta with serialized array
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | - |
- | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | - |
Supporter timezone: Europe/London (GMT+00:00)
This topic contains 12 replies, has 2 voices.
Last updated by quentinN 1 year, 6 months ago.
Assisted by: Nigel.
Hello,
I insert via the add_post_meta() function some information in my custom posts. Everything works fine for the classic fields however, I have 3 checkboxes that I would like to fill as well but the code in the DB seems serialized?
I would like to use :
add_post_meta($ID_post, 'wpcf-format-de-l-evenement', $Array_Events);
Can you tell me how to do this?
Sincerely,
Quentin NORMNAD
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Quentin
The storage format for checkboxes fields is complicated, and while you can output checkboxes fields using types shortcodes or the types_render API function, there is no official API support for setting checkboxes programmatically.
I wrote an unofficial API function to allow setting/getting checkboxes options which I will share below, together with some examples of how to use it.
Please review and try to use that instead of the core add_post_meta function.
/** * Unofficial API function to check/uncheck checkboxes options * * @param int $post_id * @param string $field // slug of checkboxes field * @param string $option // title of checkbox option to manipulate * @param string $action : 'check' | 'uncheck' | 'value' (default, returns current value) * * Important: assumes recommended checkboxes setting of save nothing to database when unchecked */ function ts_checkboxes( $post_id, $field, $option, $action = 'value' ){ if ( isset($post_id) && isset($field) && isset($option) ){ $field_settings = types_get_field( $field ); $field_options = $field_settings['data']['options']; // Locate the option key $key = array_search( $option, array_column( $field_options, 'title' ) ); $keys = array_keys( $field_options ); $option_key = $keys[$key]; // Get the current post meta value $meta = get_post_meta( $post_id, 'wpcf-'.$field, true ); // If action = 'value' just return the value if ( $action == 'value' && isset( $meta[$option_key] ) ){ return $meta[$option_key][0]; } else { // Remove the existing key if it exists (i.e. uncheck) // because recommended setting is to save nothing when unchecked unset( $meta[$option_key] ); // If $checked == true then add back the key + value if ( $action == 'check' ){ $meta[$option_key] = array($field_options[$option_key]['set_value']); } update_post_meta( $post_id, 'wpcf-'.$field, $meta ); } } }
Examples of how to then use this function would be:
// 1. Get the value of the option "Second checkbox" of a checkboxes field "Available options" from the current post: global $post; $value = ts_checkboxes( $post->ID, 'Available options', 'Second checkbox' ); // 2. set the same option as checked global $post; ts_checkboxes( $post->ID, 'Available options', 'Second checkbox', 'check' ); // 3. set the same option as unchecked global $post; ts_checkboxes( $post->ID, 'Available options', 'Second checkbox', 'uncheck' );
Hopefully you can follow that and adapt the examples to your needs.
Hi Nigel, Thanks for your help again !
I've tried your code : something doesn't seem to work.
When I mill your function by injecting the values:
$post_id = 1200
$field = wpcf-event-format
$option = 'Workshop'
$action = 'check'
The function executes well (no stoppage) until the end but my page (ID = 1200) still does not have the 'Workshop' box checked in the 'event-format'.
When I echo 'update_post_meta' before inserting, I get: update_post_meta( 1200, wpcf-event-format, A );
It looks like the variable $meta (= A) forgets to take information into account (at least the famous $option = 'Workshop')..
And a print_r($meta); give me too the 'A' ..
So something goes wrong next to the line $meta = get_post_meta( $post_id, $field, true );
Can you help me ?
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Sorry, I think my example cases are misleading, as field should be the slug of the checkboxes field, and in my examples I used the name.
In your case you have used 'wpcf-event-format' for $field, which is the postmeta key, not the field slug, which would be "event-format".
So if you want to programmatically set the "Workshop" option of that event format checkboxes field for the post ID = 1200, you would use
$post_id = 1200; $field = 'event-format'; $option = 'Workshop'; $action = 'check'; ts_checkboxes( $post_id, $field, $option, $action );
Can you test that and check it works?
Hello Nigel,
Actually I had initially tried with only the normal slug before doing a test with the meta key (and changing 2-3 lines in your function).
I've just tried again like the initial one and still nothing.
I still have: update_post_meta( 1214, format-de-l-evenement, A );
as result with the famous $meta = 'A
🙁
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Where you added the line print_r($meta); what does it output?
What happens when you try a literal example, not using your main function, i.e. what happens with
ts_checkboxes( 1214, 'format-de-l-evenement', 'Atelier', 'check' );
Does that not work?
I always have: print_r($meta) = A
The "ts_checkboxes( 1214, 'format-of-event', 'Atelier', 'check' );" did not check the multiple checkbox Atelier
Screenshots :
hidden link
hidden link
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
I re-tested this on my own site again and it works fine, every time, it's not clear why it wouldn't be working on your site.
Where you added the print_r($meta) statement for debugging, can you move that to immediately after the line $meta = get_post_meta( $post_id, 'wpcf-'.$field, true );
What does it show then when you are running this again:
ts_checkboxes( 1214, 'format-de-l-evenement', 'Atelier', 'check' );
(Note in your last reply you used "format-of-event"; I assume that's not what you used in your actual test.)
Hello Nigel,
Thank you for your time.
It still doesn't work 🙁
The print_r(meta) still returns only 'A'.
I will try to tell you more:
Your initial function doesn't work on my code (maybe that's where there's something to unblock..) --> the function abruptly stopped when executing the line "unset( $meta[$option_key] );"
As this line was about (according to your comment on the code) the case of an already existing key (which is not the case here since the custom field is by default empty at the creation of a new page.) I had voluntarily removed it and the code continued its execution until the end.
2 things then :
- The print_r(meta) always returns only 'A', even with your initial function (which seems normal since this line is above the unset( $meta[$option_key] );)
- The unset( $meta[$option_key] ); line doesn't seem to work and blocks the function in its execution.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
OK, I think you must be running PHP 8.x which is more strict about applying unset.
I've updated the code to handle the case when there is no existing value for the field so that it works okay in PHP 8+ as well as in PHP 7 (and I tested with PHP 8.1).
/** * Unofficial API function to check/uncheck checkboxes options * * @param int $post_id * @param string $field // slug of checkboxes field * @param string $option // title of checkbox option to manipulate * @param string $action : 'check' | 'uncheck' | 'value' (default, returns current value) * * Important: assumes recommended checkboxes setting of save nothing to database when unchecked */ function ts_checkboxes( $post_id, $field, $option, $action = 'value' ){ if ( isset($post_id) && isset($field) && isset($option) ){ $field_settings = types_get_field( $field ); $field_options = $field_settings['data']['options']; // Locate the option key $key = array_search( $option, array_column( $field_options, 'title' ) ); $keys = array_keys( $field_options ); $option_key = $keys[$key]; // Get the current post meta value $meta = get_post_meta( $post_id, 'wpcf-'.$field, true ); if ( !is_array($meta) ){ $meta = []; } // If action = 'value' just return the value if ( $action == 'value' && isset( $meta[$option_key] ) ){ return $meta[$option_key][0]; } else { // Remove the existing key if it exists (i.e. uncheck) // because recommended setting is to save nothing when unchecked unset( $meta[$option_key] ); // If $checked == true then add back the key + value if ( $action == 'check' ){ $meta[$option_key] = array($field_options[$option_key]['set_value']); } update_post_meta( $post_id, 'wpcf-'.$field, $meta ); } } }
Great!
Indeed, the problem is solved with your arrangement for PhP 8.0.
My ts_checkboxes( $ID_post_cree, 'format-de-l-evenement', 'Atelier', 'check' ); works perfectly.
I have one more thing to deal with... the arrays.
Indeed, I sometimes have several boxes checked. These boxes are input type="checkbox" name="format-event[]"
So I would like to call the function :
ts_checkboxes( $ID_post_cree, 'format-de-l-evenement', $_POST['format-event'] , 'check' );
But apparently it doesn't work... the echo shows me :
update_post_meta( 1230, format-de-l-evenement, Array );
The array is not perfectly integrated... do you have a suggestion?
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
The function ts_checkboxes is intended to update one option at a time, so if you have an array of options in the $_POST object then you would need to loop over them with a foreach loop and call ts_checkboxes for each option.
Hello Nigel,
It's fine, everything is working properly now.
Thank you very much for your help, once again very valuable.
Have a nice day,
Quentin