Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#50432 closed defect (bug) (duplicate)

set_screen_options filter broken in 5.4.2

Reported by: nemi5150's profile nemi5150 Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.4.2
Component: Administration Keywords:
Focuses: Cc:


My screen options stopped working in my plugin. When I change the value of the 'per_page' value I have setup it never gets saved to the user meta. I traced this to the misc.php core file where it looks like someone added some code in 5.4.2 to the 'default' switch condition. There is an if block in there that runs correctly with my filter added, but then the next block of code always executes and wipes out the returned value with 'false' so nothing ever gets saved to the user metadata. The bad code starts at line 688 in misc.php

Change History (2)

#1 @SergeyBiryukov
4 years ago

  • Component changed from General to Administration
  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Hi there, welcome to WordPress Trac!

Thanks for the report, we're already tracking this issue in #50392.

As a workaround until the issue is fixed, I'd recommend switching to the newer set_screen_option_{$option} filter, which should work as expected.

#2 @cyberplayer
4 years ago

Yes, I also have the same issue.

I think it does not make sense to use the set_screen_option_{$option} filter since this function is listening to POST action.

If we have to use the filter, then we must make another POST action listening code.




My problem occurs because I use dynamic screen option name when the set_screen_option filter is executed.

I can't directly use set_screen_option_{$option} filter because I never knew what my {$option} is. It was dynamically generated when my page is loaded. I need to get the $option first before I can use the new filter.

The solution is :

  1. I changed all of my screen option name by adding "_page" at the end of the strings.
  2. That way my function can get in to set-screen-option filter hook that only applied to options ending with '_page' (since 5.4.2)
  3. Inside the function I could call the set_screen_option_{$option} filter because by that time I knew the {$option} value.
  4. I use anonymous function to return $value that I've got from set-screen-option filter.

This is the snippet looks like :

add_filter('set-screen-option', 'set_screen_option_filter', 10, 3); // fired before admin_menu hook

function set_screen_option_filter($status, $option, $value) {

	if($this->get_current_page_table() === false) return $status; // $status = false (default from WP)
	$current_active_page = $this->get_current_active_page(); // method dipanggil lagi, karena admin_menu belum dieksekusi
	$args_option = $current_active_page['page_slug']."_".$current_active_page['page_type']."_screen_option_page";
	$args_option = str_replace("-", "_", $args_option);
	if($args_option === $option) {
		add_filter("set_screen_option_{$option}", function($status, $option, $value2) use($value) { return $value; }, 10, 3);
		return $value;

		return $status;
} // end of function

Last edited 4 years ago by cyberplayer (previous) (diff)
Note: See TracTickets for help on using tickets.