Example Code

Working with the Customizer API.

Setting added (example) like so:

    $wp_customize->add_setting( 'theme_oenology_options[' . $option_parameter['name'] . ']', array(
        'default'           => $option_parameter['default'],
        'type'              => 'option',
        'sanitize_callback' => 'oenology_sanitize_' . $option_parameter['sanitize']
    ) );

Control added (example) like so:

        $wp_customize->add_control( 
            'oenology_' . $option_parameter['name'], 
            $customizer_control_parameters 
        );

Note: $customizer_control_parameters is an array defined elsewhere. For select-type controls (select, radio, radio-image, etc.) it includes a 'choices' key.

Sanitize callback defined (example) like so:

function oenology_sanitize_select( $input ) {
    return sanitize_key( $input );
}

Everything works flawlessly in the Customizer. The control is displayed, the setting is configurable, and the sanitization works.

Problem

All good so far, but it would be better to whitelist the setting against pre-defined choices in $wp_customize->add_control(). Let’s use the second parameter passed to 'sanitize_callback', $setting, to get the 'choices' defined in the control!

Core reference:

return apply_filters( "customize_sanitize_{$this->id}", $value, $this );

Solution Attempts

function oenology_sanitize_select( $input, $setting ) {
    $input = sanitize_key( $input );
    $choices = array(); // See below
    return ( array_key_exists( $input, $choices ) ? $input : $setting->default );
}

Problem: using either of the two methods below does not return the array of choices passed to $wp_customize->add_control():

  1. Using $wp_customize global object:

    global $wp_customize;
    $control = $wp_customize->get_control( $setting->id );
    $choices = $control->choices;
    
  2. Using $setting->manager object:

    $choices = $setting->manager->get_control( $setting->id )->choices;
    

In both cases, get_control( $setting->id ) returns a null, instead of an object.

Question

How do I get 'choices' from $wp_customize->get_control(), using the $this object passed to "customize_sanitize_{$this->id}"?

1 Answer
1

This is correct:

$control = $setting->manager->get_control($setting->id);
$choices = $control->choices;

However, in your example, $setting->id will be theme_oenology_options[name].

So, get_control('theme_oenology_options[name]') will return null because there’s no control with that name. You gave the control the id of oenology_name instead.

I always give the same ID to settings and their matching controls for that reason.

Leave a Reply

Your email address will not be published. Required fields are marked *