Make WordPress Core

Opened 2 years ago

Closed 9 days ago

Last modified 7 days ago

#58789 closed defect (bug) (wontfix)

Not countable. row_actions @ /wp-admin/includes/class-wp-list-table.php

Reported by: nate1's profile Nate1 Owned by:
Milestone: Priority: normal
Severity: major Version: 6.2
Component: Administration Keywords: has-patch has-unit-tests needs-testing
Focuses: Cc:

Description (last modified by sabernhardt)

Commonly getting not countable for the users lists, across many sites not sure of the source of the issue, but easy solution seems to be to modify.

/wp-admin/includes/class-wp-list-table.php

protected function row_actions( $actions, $always_visible = false ) 
++ if(!isset($actions)) { return ''; }

$action_count = count( $actions );
if ( ! $action_count ) {
return '';
}

Change History (9)

#1 @sabernhardt
2 years ago

  • Component changed from General to Administration
  • Description modified (diff)
  • Keywords needs-patch added

I think the problem might come from the user_row_actions filter returning false or an empty string, and then the $actions variable would be set but uncountable. Maybe row_actions() could check is_countable instead.

$action_count = is_countable( $actions ) ? count( $actions ) : 0;

#2 @Nate1
2 years ago

Provided is_countable handles NULL as well as false and empty strings then that will work well. The isset call has been applied to resolve the issue on PHP 8.1.X instances I've observed.

This ticket was mentioned in PR #6801 on WordPress/wordpress-develop by @m1r0.


18 months ago
#3

  • Keywords has-patch has-unit-tests added; needs-patch removed

#4 @m1r0
18 months ago

  • Keywords needs-testing added

Hey! 👋🙂 Here's a quick PR fixing this.

#5 @tyxla
9 days ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

This is a classic example of over-defensive programming.

The first argument of the user_row_actions filter is documented to accept only arrays of strings, so anything else we pass is invalid. See https://developer.wordpress.org/reference/hooks/user_row_actions/

There are a bunch of other instances in WordPress that we can intentionally break by passing a different type, for example:

https://github.com/WordPress/wordpress-develop/blob/0d33b5cac36a5b83bb6cf8fed0d88d820b22c39d/src/wp-includes/class-wp-query.php#L4955-L4957

From my perspective, triggering an error in that instance is reasonable because otherwise, we might actually be concealing a potential type error.

I'm going to close this as "wontfix".

Thank you for your work on it, everyone!

#6 @westonruter
8 days ago

A better solution may be to cast the return value of the user_row_actions filter to an array. Or else, if the returned value is not an array, set $actions to an empty array.

#8 @tyxla
7 days ago

A better solution may be to cast the return value of the user_row_actions filter to an array.

We discussed this (working on the patch together during the WordCamp Sofia contributor day), but just casting won't work; casting false to an array will result in an array with a single false element:

<?php
print_r((array)'false');

// Array
// (
//     [0] => false
// )

Converting to an empty array seems like a good solution, but I'm still of the same opinion: there are other places in core where we're not doing this, and if we start doing it, it's too defensive, when documentation is already in place about the argument types of those filters.

#9 @westonruter
7 days ago

I think the yet better solution here would be to add typing information to apply_filters() as proposed in #51525. This would be a holistic approach.

I'm kinda concerned with having to use a different function to apply filters, though. It would be ideal if the type could be extracted from the existing apply_filters() calls from the associated docblock, but that would be complicated and perhaps not performant.

Note: See TracTickets for help on using tickets.