Skip Navigation

[Resolved] Update checkboxes field with PHP

This support ticket is created 2 years, 6 months ago. There's a good chance that you are reading advice that it now obsolete.

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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 6 replies, has 2 voices.

Last updated by stefanoT-2 2 years, 6 months ago.

Assisted by: Christian Cox.

Author
Posts
#2156333

I need to update a "checkboxes" custom field using PHP but I'm facing some difficulties.

I found this guide here: https://toolset.com/documentation/customizing-sites-using-php/updating-types-fields-using-php/

My problem is that I don't know the format to use with the function "update_post_meta".

For example: I have a custom field "wpcf-example", type checkboxes, with values "1", "2", "3", "4", and "5".
I need to save the values "1", "2" and "3". How do I save those values to the custom filed "wpcf-example"?

Thank you.

#2156385

Hi, checkboxes groups fields manipulation with PHP is a bit more complex than other custom field values because the values of checkboxes groups fields are stored in a serialized data format. To update their values with PHP, we have an unofficial API function available.

/**
 * 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 );		
		}
    }
}

This function requires you use the option "Save nothing to the database when unchecked" in the checkboxes field settings. To use the function to programmatically check or uncheck some checkbox options, see the following examples:

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

Feel free to let me know if you have questions about using this unofficial API.

#2156805
balcone-terrazzo configuration.jpg
wrong value in database.jpg

Hi, thanks for the function but I have some issues.

I added a "if" on line 35 on the function because I was getting an error when I saved the field to a newly created post.

if ( isset( $meta[$option_key] ) ) {
    unset( $meta[$option_key] );
}

This solved the issue.

Now the function works but it does not save the desired value.

My custom field is "balcone-terrazzo" and has three possible values: "Balcone", "Terrazzo", "Terrazzo abitabile". This is how I wrote the function:

ts_checkboxes( 20948, 'balcone-terrazzo', 'Balcone', 'check' );

I was expecting the value "Balcone" to be checked, but it wasn't. I checked the database and I found out that the custom field has been saved, but it's value is "A" (see screenshot).

I confirm that the field has the option "When unchecked, don't save anything to the database" (see screenshot).

#2157687

You mentioned earlier in your examples that the individual checkboxes values were 1, 2, 3, 4, and 5. Is that the case here for the balcone-terrazzo field checkboxes? If not, can you open those checkboxes options settings and take another screenshot so I can see the configurations for each checkboxes option?

#2157979
balcone terrazzo values.jpg

For the field "balcone-terrazzo" the values are the same as the titles. The first one was a generic example, sorry.

#2158883
Screen Shot 2021-09-02 at 5.11.19 PM.png

Hello, sorry for the delay. I've been experimenting a bit and I'm trying to figure out the best solution here. I think to some extent it depends on how the posts are created. For example, a new post created in wp-admin (while Toolset Types is active) or a post created in Toolset Forms should automatically include an empty serialized data structure as the value of the Balcone o Terrazzo checkboxes group field. For every post, there should be an entry in the postmeta table with the key "wpcf-balcone-terrazzo", and the value would be an empty serialized structure, represented like this:

a:0:{}

I'm attaching a screenshot showing that in my database for your reference.

When that value exists in the db, there should be no need for the code modification you made earlier:

if ( isset( $meta[$option_key] ) ) {
    unset( $meta[$option_key] );
}

In fact, when I added that same code in my local environment and tried manipulating some posts, I began seeing the value of "A" that you mentioned before. I think the best solution is to first ensure that all new posts are created with the wpcf-balcone-terrazzo key present in postmeta, and the value set as an empty serialized data structure. If you're creating posts programmatically with PHP, that means you should also set the empty serialized structure programmatically as well. You can do that by passing an empty array into update_post_meta:

update_post_meta(12345, 'wpcf-balcone-terrazzo', array());

...where 12345 is the new post ID.

Thoughts?

#2159337

Thank you very much, that was the issue.

I removed my "IF" statement from you function and I now create the empty custom field before running "ts_checkboxes" for each value I want to check. The fields save correctly and show in wp-admin with the checked values.

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.