WordPress.org

Make WordPress Core

Opened 23 months ago

Last modified 17 months ago

#37645 new defect (bug)

Changes made to certain is_*() functions generates PHP Notices when arrays or objects are present

Reported by: Enchiridion Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.5
Component: General Keywords: has-patch
Focuses: Cc:

Description

The patch added by #35902 can generate PHP Array to string conversion notices if an array is passed that contains sub-arrays or objects that don't implement __toString().

The supplied patch applies the strval conversion taking those special conditions into account.

Functions affected: is_attachment() is_author() is_category() is_tag() is_page() is_single()

I came across this using plugin I built which adds custom data, in the form of an array, to the WP_Post object for my templates to use. When strval is run (by post_class() calling is_attachment()) it throws notices when it comes across the arrays.

Attachments (1)

37645.patch (3.2 KB) - added by Enchiridion 23 months ago.

Download all attachments as: .zip

Change History (5)

@Enchiridion
23 months ago

#1 @ocean90
23 months ago

  • Keywords has-patch added
  • Version changed from trunk to 4.5

#2 @boonebgorges
17 months ago

Hi @Enchiridion - Thanks for the ticket, and many apologies for the silence. I missed the ticket when it originally came through.

Looking closely at your issue: It seems to me that the problem is not #35902 [36625], but was only surfaced by that change. The real problem is that WP_Post objects are not a valid input for is_attachment(). The is_*() functions are meant to test whether the current *query* is for an attachment, NOT the current *post*; the optional $attachment parameter is an ID, slug, or array of IDs or slugs. get_body_class() is, as far as I can see, the only place where WP passes a post object into an is_*() function.

It looks like the introduction of the clause is_attachment( $post ) to get_body_class() in [27622] was probably by mistake. It should probably just be is_attachment(). @wonderboymusic - Can you cast your mind back to 2014 to verify?

#3 @wonderboymusic
17 months ago

@boonebgorges it seems to me IMHO that hydrated objects should be fine, and, when objects are passed, the calls to array_map() should act on get_object_vars( $obj ) instead of (array) $sir_mixed_a_lot.

Perhaps a "helper" method:

function data_to_array( $data ) {
  if ( is_object( $data ) ) {
      return array_map( 'strval', get_object_vars( $data ) );
  }
  return array_map( 'strval', (array) $data );
}

#4 @boonebgorges
17 months ago

@wonderboymusic Thanks. I agree that hydrated objects are fine, and the idea of a helper method for this sort of thing seems OK to me. I guess my point is that this specific use of is_attachment() is not semantically correct: is_attachment() means "the current query is for attachments" (ie WP_Query( 'post_type=attachment' )), and not "the current post is an attachment". For the latter, and in the case of get_post_class(), 'attachment' === $post->post_type seems like it's what's actually intended.

Note: See TracTickets for help on using tickets.