Make WordPress Core

Opened 9 years ago

Closed 9 years ago

#32781 closed defect (bug) (fixed)

Customizer Menus: Debug Notices

Reported by: johnjamesjacoby's profile johnjamesjacoby Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 4.3 Priority: normal
Severity: normal Version: 4.3
Component: Customize Keywords: has-patch commit
Focuses: Cc:

Description

Since r32806, I'm seeing this in my customizer:

Notice: Undefined property: stdClass::$fallback_cb in /srv/www/wordpress-develop/src/wp-includes/nav-menu-template.php on line 311

Using a pretty standard approach to menus:

wp_nav_menu( array(
	'theme_location' => 'primary',
	'container'      => false,
	'menu_class'     => 'nav navbar-nav',
	'walker'         => new Bootstrap_Nav_Menu(),
	'fallback_cb'    => '' // @todo
) );

This worked without a debug notice previous to r32806.

Attachments (4)

32781.diff (648 bytes) - added by adamsilverstein 9 years ago.
Add explicit check for isset( $args->fallback_cb ) before using
32781.2.diff (1.1 KB) - added by adamsilverstein 9 years ago.
Better reset for ! can_partial_refresh
32781.3.diff (1.6 KB) - added by westonruter 9 years ago.
32781.4.diff (2.2 KB) - added by westonruter 9 years ago.

Download all attachments as: .zip

Change History (20)

#1 follow-up: @johnjamesjacoby
9 years ago

The cause appears to be:

WP_Customize_Nav_Menus::filter_wp_nav_menu_args();

It's unsetting both the fallback_cb and walker arguments via a filter to wp_nav_menu_args.

Currently in wp_nav_menu(), all object variables are assumed to be at least set. I see two potential fixes:

  • Change the unset()'s in WP_Customize_Nav_Menus::filter_wp_nav_menu_args(); to empty strings so they remain set
  • Wrap all object variable checks in wp_nav_menu() in isset() or ! empty() to avoid notices

I think for sure the second of the above two fixes should happen anyways, since (as usual) we cannot trust any object to ever have any variables set in any scope thanks to filters and nothing being immutable. I think the first of these two fixes should sufficiently address the original intentions.

Tangent: we're starting to use 1000 as if it were some kind of WP_MAX_FILTER_PRIORITY, particularly in overrides done for the Customizer (though 9999 is used in some other places.) Should we actually define these priorities somewhere?

Last edited 9 years ago by johnjamesjacoby (previous) (diff)

#2 @celloexpressions
9 years ago

  • Component changed from Menus to Customize

@westonruter: thoughts here?

@adamsilverstein
9 years ago

Add explicit check for isset( $args->fallback_cb ) before using

#3 @adamsilverstein
9 years ago

  • Keywords has-patch dev-feedback added

In attachment:

  • Add an explicit check for isset( $args->fallback_cb ), fixing a PHP notice in the customizer.

@johnjamesjacoby - I added the isset check and verified that this corrects the notice you were seeing (using your test snippet). I didn't want to change the unsset part - concerned that may affect things elsewhere. Also, I didn’t address the unset walker argument (or any other potentially uncheck variables).

#4 in reply to: ↑ 1 @SergeyBiryukov
9 years ago

Replying to johnjamesjacoby:

Currently in wp_nav_menu(), all object variables are assumed to be at least set. I see two potential fixes:

  • Change the unset()'s in WP_Customize_Nav_Menus::filter_wp_nav_menu_args(); to empty strings so they remain set
  • Wrap all object variable checks in wp_nav_menu() in isset() or ! empty() to avoid notices

I think I'd prefer the first option in this ticket's scope.

#5 @westonruter
9 years ago

I agree. Instead of doing unset it should assign the properties to empty strings, which should be in line with the default values.

#6 @adamsilverstein
9 years ago

Ok, thanks for the feedback.

I will expand the patch!

@adamsilverstein
9 years ago

Better reset for ! can_partial_refresh

#7 @adamsilverstein
9 years ago

In 32781.2.diff:

  • When can_partial_refresh is false, reset 'walker' and 'fallback_cb' args to their default blank string values, instead of unsetting them, avoiding PHP notices.
  • Add an explicit check for isset( $args->fallback_cb ), fixing a PHP notice in the customizer, because we really should check that variables exist before using them, always.

#8 @westonruter
9 years ago

  • Keywords dev-feedback removed

@westonruter
9 years ago

#9 @westonruter
9 years ago

We've also been noticing this sometimes:

PHP Notice: Undefined index: echo in /srv/www/wp/wp-includes/class-wp-customize-nav-menus.php on line 756

So 32781.3.diff adds empty checks on the array keys to prevent undefined index notices.

#10 @SergeyBiryukov
9 years ago

  • Owner set to SergeyBiryukov
  • Resolution set to fixed
  • Status changed from new to closed

In 33035:

Customizer: Avoid PHP notices after [32806].

props adamsilverstein, westonruter.
fixes #32781.

#11 @SergeyBiryukov
9 years ago

In 33043:

Update test_filter_wp_nav_menu_args() after [33035].

see #32781.

@westonruter
9 years ago

#12 @westonruter
9 years ago

  • Keywords needs-testing added
  • Resolution fixed deleted
  • Status changed from closed to reopened

The fix here introduces an unexpected side-effect: any supplied fallback_cb or walker gets clobbered in the preview, even though partial refresh is disabled. This is wrong. We disable partial refresh for the very reason that a non-serializable fallback_cb or walker gets defined in the first place, so these should remain in effect in the preview when a full page refresh is then done.

See 32781.4.diff.

#13 @westonruter
9 years ago

  • Keywords commit added; needs-testing removed

Patch was tested in #32894 (comment), although not specifically the problem with notices.

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


9 years ago

This ticket was mentioned in Slack in #core by westonruter. View the logs.


9 years ago

#16 @westonruter
9 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 33131:

Customizer: Prevent loss of walker and fallback_cb args for wp_nav_menu.

These args only need to be cleared out when exported to JavaScript, when they are not JSON-serializable. So the filter now clears these when gathering args for exporting to JS, but otherwise now leaves the original values to be passed through to wp_nav_menu().

Fixes #32781.

Note: See TracTickets for help on using tickets.