Make WordPress Core

Opened 8 years ago

Last modified 3 years ago

#37645 new defect (bug)

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

Reported by: enchiridion's profile Enchiridion Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.5
Component: Query 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 8 years ago.

Download all attachments as: .zip

Change History (6)

@Enchiridion
8 years ago

#1 @ocean90
8 years ago

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

#2 @boonebgorges
8 years 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
8 years 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
8 years 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.

#5 @SergeyBiryukov
3 years ago

  • Component changed from General to Query

Related: #17737

Note: See TracTickets for help on using tickets.