Make WordPress Core

Opened 6 years ago

Closed 6 years ago

#45812 closed defect (bug) (invalid)

WP_Customize_Setting sanitize_callback is given 2 parameters; PHP warning and validation fail

Reported by: marclarr's profile marclarr Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.4
Component: Customize Keywords: close
Focuses: Cc:

Description

While working on a custom control for the Customizer I ran into the following issue. Please see the code below regarding my setup, which is a multi-setting control.

The Issue

When trying to save the setting(s) the sanitize_callback fails with the following PHP error_log info: "PHP Warning: floatval() expects exactly 1 parameter, 2 given in .../wp-includes/class-wp-hook.php on line 286". The parameters passed to the callback are 1) the input value and 2) the customize manager object. The customizer also isn't saving the value due to a validation fail with the following error notice: "Invalid value".

System Info

I'm running WP 5.0.2 (Multisite) locally using PHP 7.2.8 on MAMP. No plugins are activated on the site. I'm making use of PHP namespaces and the customize settings/controls are registered from within an abstract class via a static method.

<?php
// The below PHP is applied via:
// add_action( 'customize_register', __CLASS__ . '::_register_controls' );

$wp_customize->add_setting(
    'nt-theme[site-width]',
    array(
        'default' => '1200',
        'transport' => 'postMessage',
        // This fails:
        'sanitize_callback' => 'floatval',
        // This works:
        // 'sanitize_callback' => function( $val, $wp_customize ) {
        //     return floatval( $val );
        // },
    )
);

$wp_customize->add_setting(
    'nt-theme[site-width-unit]',
    array(
        'default' => 'px',
        'transport' => 'postMessage',
        // 'sanitize_callback' => 'wp_strip_all_tags',   
    )
);

$wp_customize->add_control(
    new CSS_Length_Customize_Control(
        $wp_customize,
        'nt-theme-site-width',
        array(
            'priority'    => 10,
            'section'     => 'nt-theme-site-layout',
            'label'       => esc_html__("Site Width", 'nt-theme'),
            'description' => esc_html__("The maximum width of the site within the browser window.", 'nt-theme'),
            'units'       => ['px', '%'],
            'settings'    => [
                'default' => 'nt-theme[site-width]', 
                'unit'    => 'nt-theme[site-width-unit]',
            ],
            'input_attrs' => [
                'min' => 0,
                'step' => 0.1,
            ],
        )
    )
);

Change History (6)

#1 @joyously
6 years ago

Why is this worthy of a ticket?
The callback is actually sent the value and the control object (not the manager object). Isn't the error you see valid, since the function you supplied had only one parameter?

#2 @marclarr
6 years ago

Hi @joyously, Many/most sanitation functions only accept only one parameter and [the docs offer examples](https://developer.wordpress.org/themes/customize-api/customizer-objects/) that are using functions that accept only one parameter. I have worked with the customize API in the past and didn't run into this issue. It appears I'm doing everything correctly, yet I receive errors this time around.

Last edited 6 years ago by marclarr (previous) (diff)

#3 @marclarr
6 years ago

To clarify the 2nd parameter passed to the sanitize_callback is an instance of WP_Customize_Setting.

Version 0, edited 6 years ago by marclarr (next)

#4 @dlh
6 years ago

  • Keywords close added
  • Version changed from 5.0.2 to 3.4

Welcome to Trac, @marclarr!

sanitize_hex_color() and other user-defined functions support variable argument lengths, but I don't believe that internal PHP functions do, hence the warning.

Like @joyously, I'm not sure I see a bug here. It's a bit inconvenient to have to use the closure to call floatval(), but I think it's the only way to do so if passed as the sanitize_callback given that floatval() is an internal function.

Alternatively, rather than passing floatval as a sanitize_callback, hook floatval into the dynamic customize_sanitize_{$id} filter in your own code and instruct the filter to pass only 1 argument instead of 2.

#34659 addresses a similar issue in the REST API. If an approach is found there, perhaps it could be adopted in the Customizer as well.

#5 @marclarr
6 years ago

Hey @dlh, I see. Thanks for clearing this up! And yep, no bug here.

#6 @dlh
6 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.