diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index 0c5e21bde3..8df48e6a0c 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -1108,7 +1108,10 @@ class WP_List_Table { */ protected function get_column_info() { // $_column_headers is already set / cached. - if ( isset( $this->_column_headers ) && is_array( $this->_column_headers ) ) { + if ( + isset( $this->_column_headers ) && + is_array( $this->_column_headers ) + ) { /* * Backward compatibility for `$_column_headers` format prior to WordPress 4.3. * @@ -1116,12 +1119,18 @@ class WP_List_Table { * column headers property. This ensures the primary column name is included * in plugins setting the property directly in the three item format. */ + if ( 4 === count( $this->_column_headers ) ) { + return $this->_column_headers; + } + $column_headers = array( array(), array(), array(), $this->get_primary_column_name() ); foreach ( $this->_column_headers as $key => $value ) { $column_headers[ $key ] = $value; } - return $column_headers; + $this->_column_headers = $column_headers; + + return $this->_column_headers; } $columns = get_column_headers( $this->screen ); diff --git a/tests/phpunit/tests/admin/wpListTable.php b/tests/phpunit/tests/admin/wpListTable.php new file mode 100644 index 0000000000..c07d7579c8 --- /dev/null +++ b/tests/phpunit/tests/admin/wpListTable.php @@ -0,0 +1,107 @@ +setAccessible( true ); + $column_headers->setValue( $list_table, $headers ); + + $column_info = new ReflectionMethod( $list_table, 'get_column_info' ); + $column_info->setAccessible( true ); + + $this->assertSame( $expected, $column_info->invoke( $list_table ), 'The actual columns did not match the expected columns' ); + $this->assertSame( $expected_hook_count, $hook->get_call_count(), 'The hook was not called the expected number of times' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_should_only_add_primary_column_when_needed() { + /* + * `WP_Post_Comments_List_Table` overrides `get_column_info()` rather than + * use the default `WP_List_Table::get_column_info()`. Therefore it is + * untested. + */ + $list_primary_columns = array( + 'WP_Application_Passwords_List_Table' => 'name', + 'WP_Comments_List_Table' => 'author', + 'WP_Links_List_Table' => 'name', + 'WP_Media_List_Table' => 'title', + 'WP_MS_Sites_List_Table' => 'blogname', + 'WP_MS_Themes_List_Table' => 'name', + 'WP_MS_Users_List_Table' => 'username', + 'WP_Plugin_Install_List_Table' => '', + 'WP_Plugins_List_Table' => 'name', + 'WP_Posts_List_Table' => 'title', + 'WP_Privacy_Data_Export_Requests_List_Table' => 'email', + 'WP_Privacy_Data_Removal_Requests_List_Table' => 'email', + 'WP_Terms_List_Table' => 'name', + 'WP_Theme_Install_List_Table' => '', + 'WP_Themes_List_Table' => '', + 'WP_Users_List_Table' => 'username', + ); + + $datasets = array(); + + foreach ( $list_primary_columns as $list_class => $primary_column ) { + $datasets[ $list_class . ' - three columns' ] = array( + 'list_class' => $list_class, + 'headers' => array( 'First', 'Second', 'Third' ), + 'expected' => array( 'First', 'Second', 'Third', $primary_column ), + 'expected_hook_count' => 1, + ); + + $datasets[ $list_class . ' - four columns' ] = array( + 'list_class' => $list_class, + 'headers' => array( 'First', 'Second', 'Third', 'Fourth' ), + 'expected' => array( 'First', 'Second', 'Third', 'Fourth' ), + 'expected_hook_count' => 0, + ); + } + + /* + * `WP_MS_Themes_List_Table` and `WP_Plugins_List_Table` override the + * `get_primary_column_name()` method rather than use the default + * `WP_List_Table::get_primary_column_name()`. Neither include the + * `list_table_primary_column` hook. + */ + $datasets['WP_MS_Themes_List_Table - three columns']['expected_hook_count'] = 0; + $datasets['WP_Plugins_List_Table - three columns']['expected_hook_count'] = 0; + + return $datasets; + } +}