10up / distributor

Share content between your websites.
https://distributorplugin.com
GNU General Public License v2.0
628 stars 155 forks source link

Deprecation notice (PHP 8.1 and above) in PullListTable when distributed posts are not allowed to be edited #1164

Closed lakrisgubben closed 3 weeks ago

lakrisgubben commented 9 months ago

Describe the bug

On the "pulled" list in the PullListTable view (/wp-admin/admin.php?page=pull&status=pulled), the following deprecation notice is thrown (if running php 8.1 or above) for each post in the list if the current user cannot edit that post: Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /wp-includes/formatting.php on line 4494

The issue is that the Edit link is added to the list table (here: https://github.com/10up/distributor/blob/develop/includes/classes/PullListTable.php#L370) without a check for if the current user can edit that post. This results in the call to get_edit_post_link returning null and passing that to esc_url triggers the deprecation notice above.

On our setup we don't allow the pulled posts to be edited so we have a filter kind of like this to make sure they're not:

add_filter(
    'map_meta_cap',
    static function( array $caps, string $cap, int $user_id, array $args ): array {
        if ( 'edit_post' === $cap ) {
            $post = get_post( $args[0] );
            if (
                ! is_null( $post )
                && get_post_meta( $post->ID, 'dt_original_blog_id', true )
            ) {
                $caps   = [];
                $caps[] = 'do_not_allow';
            }
        }
        return $caps;
    },
    10,
    4
);

The easiest fix for this is probably to change these lines https://github.com/10up/distributor/blob/develop/includes/classes/PullListTable.php#L368-L373 to something like:

if ( ! empty( $new_post ) ) {
    $actions = [ 'view' => '<a href="' . esc_url( get_permalink( $new_post_id ) ) . '">' . esc_html__( 'View', 'distributor' ) . '</a>' ];
    if ( current_user_can( 'edit_post', $new_post_id ) ) {
        $actions['edit'] = '<a href="' . esc_url( get_edit_post_link( $new_post_id ) ) . '">' . esc_html__( 'Edit', 'distributor' ) . '</a>';
    }
}

Happy to make a PR if y'all deem it worthwhile. :)

Steps to Reproduce

  1. Make sure your site runs PHP 8.1 or above
  2. Add a filter like the one above on map_meta_cap so that the current user is not allowed to edit distributed posts.
  3. Pull a post
  4. Go to the list of pulled posts with WP_DEBUG set to true
  5. You'll see the deprecation notice

Screenshots, screen recording, code snippet

No response

Environment information

No response

WordPress information

No response

Code of Conduct