Skip to content

Commit

Permalink
Taxonomy: Restrict term edit link generation in `WP_Terms_List_Table:…
Browse files Browse the repository at this point in the history
…:handle_row_actions()`.

This changeset restricts edit term link generation if the user lacks the `edit_term` cap in order to prevent PHP 8.1+ deprecations shown when a user lacks this 
capability and `get_edit_term_link()` returns null.

Props thelovekesh, jrf.
Fixes #59336.





git-svn-id: https://develop.svn.wordpress.org/trunk@56631 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
audrasjb committed Sep 20, 2023
1 parent 669d11f commit 1113b2d
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/wp-admin/includes/class-wp-terms-list-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -474,18 +474,18 @@ protected function handle_row_actions( $item, $column_name, $primary ) {
$taxonomy = $this->screen->taxonomy;
$uri = wp_doing_ajax() ? wp_get_referer() : $_SERVER['REQUEST_URI'];

$edit_link = add_query_arg(
'wp_http_referer',
urlencode( wp_unslash( $uri ) ),
get_edit_term_link( $tag, $taxonomy, $this->screen->post_type )
);

$actions = array();

if ( current_user_can( 'edit_term', $tag->term_id ) ) {
$actions['edit'] = sprintf(
'<a href="%s" aria-label="%s">%s</a>',
esc_url( $edit_link ),
esc_url(
add_query_arg(
'wp_http_referer',
urlencode( wp_unslash( $uri ) ),
get_edit_term_link( $tag, $taxonomy, $this->screen->post_type )
)
),
/* translators: %s: Taxonomy term name. */
esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $tag->name ) ),
__( 'Edit' )
Expand Down
88 changes: 88 additions & 0 deletions tests/phpunit/tests/admin/wpTermsListTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

/**
* @group admin
*
* @covers WP_Terms_List_Table
*/
class Tests_Admin_WpTermsListTable extends WP_UnitTestCase {

/**
* List table.
*
* @var WP_Terms_List_Table $terms_list_table
*/
private $terms_list_table;

private static $admin_id;
private static $author_id;
private static $term_object;

const CATEGORY_TAXONOMY = 'category';

public static function set_up_before_class() {
parent::set_up_before_class();

self::$admin_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
self::$author_id = self::factory()->user->create( array( 'role' => 'author' ) );

self::$term_object = self::factory()->term->create_and_get( array( 'taxonomy' => self::CATEGORY_TAXONOMY ) );

require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-terms-list-table.php';
}

public function set_up() {
parent::set_up();

$this->terms_list_table = new WP_Terms_List_Table();
}

/**
* Call an inaccessible (private or protected) method.
*
* @param object|string $object Object instance or class string to call the method of.
* @param string $method_name Name of the method to call.
* @param array $args Optional. Array of arguments to pass to the method.
* @return mixed Return value of the method call.
* @throws ReflectionException If the object could not be reflected upon.
*/
private function call_inaccessible_method( $object, $method_name, $args = array() ) {
$method = ( new ReflectionClass( $object ) )->getMethod( $method_name );
$method->setAccessible( true );
return $method->invokeArgs( $object, $args );
}

/**
* @covers WP_Terms_List_Table::handle_row_actions()
*
* @ticket 59336
*/
public function test_handle_row_actions_as_author() {
wp_set_current_user( self::$author_id );

$actions = $this->call_inaccessible_method( $this->terms_list_table, 'handle_row_actions', array( self::$term_object, 'title', 'title' ) );

$this->assertStringContainsString( '<div class="row-actions">', $actions, 'Row actions should be displayed.' );
$this->assertStringContainsString( 'View', $actions, 'View action should be displayed to the author.' );
$this->assertStringNotContainsString( 'Edit', $actions, 'Edit action should not be displayed to the author.' );
$this->assertStringNotContainsString( 'Delete', $actions, 'Delete action should not be displayed to the author.' );
}

/**
* @covers WP_Terms_List_Table::handle_row_actions()
*
* @ticket 59336
*/
public function test_handle_row_actions_as_admin() {
wp_set_current_user( self::$admin_id );

$actions = $this->call_inaccessible_method( $this->terms_list_table, 'handle_row_actions', array( self::$term_object, 'title', 'title' ) );

$this->assertStringContainsString( '<div class="row-actions">', $actions, 'Row actions should be displayed.' );
$this->assertStringContainsString( 'View', $actions, 'View action should be displayed to the admin.' );
$this->assertStringContainsString( 'Edit', $actions, 'Edit action should be displayed to the admin.' );
$this->assertStringContainsString( 'Delete', $actions, 'Delete action should be displayed to the admin.' );
$this->assertStringContainsString( admin_url( 'term.php' ), $actions, 'Edit term link should be displayed to the admin.' );
}
}

0 comments on commit 1113b2d

Please sign in to comment.