Make WordPress Core

Opened 9 years ago

Closed 9 years ago

#34148 closed defect (bug) (fixed)

PHP notice in class WP_List_Table using register_column_headers (_WP_List_Table_Compat)

Reported by: hax's profile Hax Owned by: wonderboymusic's profile wonderboymusic
Milestone: 4.4 Priority: normal
Severity: normal Version: 4.3
Component: Administration Keywords: has-patch
Focuses: administration Cc:

Description

If you use the register_column_headers function, it creates a new instance of the _WP_List_Table_Compat class.

_WP_List_Table_Compat::get_column_info() method returns an array with 3 values. Line 114 file /wp-admin/includes/list-table.php

WP_List_Table::print_column_headers() method uses the $this->get_column_info() method which expects 4 values. Line 993 file /wp-admin/includes/class-wp-list-table.php

Debug returns the fallowing notice
Notice: Undefined offset: 3 in /wp-admin/includes/class-wp-list-table.php on line 993

Attachments (2)

34148.patch (556 bytes) - added by tyxla 9 years ago.
_WP_List_Table_Compat::get_column_info() - now supports the 4th primary column parameter
34148.2.diff (565 bytes) - added by danielbachhuber 9 years ago.

Download all attachments as: .zip

Change History (17)

#1 @jeremyfelt
9 years ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 4.4
  • Version changed from 4.3.1 to 4.3

Hi @Hax, thanks for the report!

It looks like this was introduced in [33016], when $primary was added to the expected data from get_column_info().

#2 @tyxla
9 years ago

We can use the first non-cb column logic in WP_List_Table::get_default_primary_column_name() to fetch the default primary column for the _WP_List_Table_Compat instances. Patch coming up.

@tyxla
9 years ago

_WP_List_Table_Compat::get_column_info() - now supports the 4th primary column parameter

#3 @tyxla
9 years ago

  • Keywords has-patch added; needs-patch removed

#4 @wonderboymusic
9 years ago

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

In 34897:

List Tables: in _WP_List_Table_Compat::get_column_info(), also return $primary, which is expected since [33016].

Props tyxla.
Fixes #34148.

#5 @JustinSainton
9 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

Happy to open a new ticket if necessary, but r34897, which closed this ticket, seems insufficient. Alternatively, I'm just doing something wrong.

Having encountered the bug, exactly as reported initially, and now running the latest nightly, I get this PHP warning instead:

Warning: Invalid argument supplied for foreach() in /srv/www/wordpress-default/wp-admin/includes/class-wp-list-table.php on line 907

Line 907 is where $columns is looped through inside the get_default_primary_column_name() method. That variable here is $this->get_columns(), which returns NULL on a backtrace inside of the get_default_primary_column_name().

When I check the backtrace inside of _WP_List_Table_Compat->get_columns(), it looks like this method actually runs twice, as it returns two backtraces. The first returns the expected array of columns. The second returns NULL. Below are the backtraces with the first few layers (which are identical) removed.

string(583) "print_column_headers, WP_List_Table->print_column_headers, _WP_List_Table_Compat->get_column_info, get_column_headers, apply_filters('manage_wpsc_purchase_log_item_details_columns'), call_user_func_array, _WP_List_Table_Compat->get_columns" array(7) { ["title"]=> string(4) "Name" ["sku"]=> string(3) "SKU" ["quantity"]=> string(8) "Quantity" ["price"]=> string(5) "Price" ["shipping"]=> string(13) "Item Shipping" ["tax"]=> string(8) "Item Tax" ["total"]=> string(10) "Item Total" } 

string(525) "print_column_headers, WP_List_Table->print_column_headers, _WP_List_Table_Compat->get_column_info, WP_List_Table->get_default_primary_column_name, _WP_List_Table_Compat->get_columns" NULL 


Warning: Invalid argument supplied for foreach() in /srv/www/wordpress-default/wp-admin/includes/class-wp-list-table.php on line 907

Still dinking around to see what I can find and potentially resolve here - as mentioned, it's entirely possible we're just doing something wrong (something, of course, aside from even using register/print_column_headers())

#6 @wonderboymusic
9 years ago

@JustinSainton check this after [35565] ?

#7 @JustinSainton
9 years ago

Unfortunately, no. Still getting the same exact error.

I don't think it will help seeing how we're implementing register/print_column_headers, but just in case: print_column_headers, register_column_headers.

Heading out for a bit, but I'll check in on this again later - let me know if a backtrace would be helpful (it's pretty much the same as before).

#8 @wonderboymusic
9 years ago

  • Owner wonderboymusic deleted
  • Status changed from reopened to assigned

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


9 years ago

#10 @JustinSainton
9 years ago

Per @danielbachhuber's request, steps to replicate:

1) register column headers on a page, via register_column_headers()
2) Attempt to print those column headers, via print_column_headers()
3) Note that it works fine in 4.3.1. It prints the column headers as expected.
4) In trunk, currently, it prints the column headers, but is preceded by this warning: Warning: Invalid argument supplied for foreach() in /srv/www/wordpress-default/wp-admin/includes/class-wp-list-table.php on line 907

Here's a dumb little gist to replicate the issue (on media settings page, just for fun.)

https://gist.github.com/JustinSainton/37326773b4c3ac3c94db

#11 follow-up: @JustinSainton
9 years ago

I'm not sure if this is the best/right solution, but modifying the $_columns property in the _WP_List_Table_Compat class to default to an array, rather than NULL, seems to fix the issue.

@danielbachhuber, thoughts on that?

#12 in reply to: ↑ 11 @danielbachhuber
9 years ago

Replying to JustinSainton:

I'm not sure if this is the best/right solution, but modifying the $_columns property in the _WP_List_Table_Compat class to default to an array, rather than NULL, seems to fix the issue.

@danielbachhuber, thoughts on that?

Could fix it. So far I've tracked it down to WP_List_Table::get_default_primary_column_name() being called in trunk, but not in 4.3. I don't yet know why this is the case.

#13 @danielbachhuber
9 years ago

Here's the backtrace:

#0 WP_List_Table->get_default_primary_column_name() called at [/srv/www/wordpress-develop.dev/src/wp-admin/includes/list-table.php:113] #1 _WP_List_Table_Compat->get_column_info() called at [/srv/www/wordpress-develop.dev/src/wp-admin/includes/class-wp-list-table.php:1080] #2 WP_List_Table->print_column_headers(1) called at [/srv/www/wordpress-develop.dev/src/wp-admin/includes/list-table.php:80] #3 print_column_headers(random-test-headers) called at [/srv/www/wordpress-develop.dev/src/wp-content/mu-plugins/poc-column-headers.php:11] #4 {closure}() #5 call_user_func_array(Closure Object (), Array ([0] => )) called at [/srv/www/wordpress-develop.dev/src/wp-includes/plugin.php:525] #6 do_action(admin_notices) called at [/srv/www/wordpress-develop.dev/src/wp-admin/admin-header.php:250] #7 include(/srv/www/wordpress-develop.dev/src/wp-admin/admin-header.php) called at [/srv/www/wordpress-develop.dev/src/wp-admin/options-media.php:38]

#14 @danielbachhuber
9 years ago

34148.2.diff produces as local as possible of a fix for the error notice. But, I don’t fully grok the impact of not having a primary column identified when there are no columns. In my limited testing locally, it seemed to have no impact on the display of the table headers.

Ultimately, the nature of the problem is that core is trying to get a default “primary column” when none are registered. register_column_headers() just registers the headers, not any columns, so there’s no columns for core to choose from.

#15 @wonderboymusic
9 years ago

  • Owner set to wonderboymusic
  • Resolution set to fixed
  • Status changed from assigned to closed

In 35698:

List Tables: Fix PHP error notice when $columns is null

Use of register_column_headers() and print_column_headers() creates a _WP_List_Table_Compat without any columns. When the List Table object doesn't have any columns, there's naturally no primary column.

Props danielbachhuber.
Fixes #34148.

Note: See TracTickets for help on using tickets.