init_json_filters(). */ public function __construct( &$plugin ) { $this->p =& $plugin; if ( $this->p->debug->enabled ) { $this->p->debug->mark(); } $this->p->util->add_plugin_filters( $this, array( 'json_data_https_schema_org_thing' => 5, ), $prio = 20000 ); } /* * Automatically include a review property based on the Open Graph review meta tags. * * $page_type_id is false and $is_main is true when called as part of a collection page part. * * The Schema standard provides 'aggregateRating' and 'review' properties for these types: * * Brand * CreativeWork * Event * Offer * Organization * Place * Product * Service * * Unfortunately Google allows the 'aggregateRating' property only for these types: * * Book * Course * Event * HowTo (includes Recipe) * LocalBusiness * Movie * Product * SoftwareApplication * * And the 'review' property only for these types: * * Book * Course * CreativeWorkSeason * CreativeWorkSeries * Episode * Event * Game * HowTo (includes Recipe) * LocalBusiness * MediaObject * Movie * MusicPlaylist * MusicRecording * Organization * Product * SoftwareApplication */ public function filter_json_data_https_schema_org_thing( $json_data, $mod, $mt_og, $page_type_id, $is_main ) { if ( $this->p->debug->enabled ) { $this->p->debug->mark(); } $json_ret = array(); $all_reviews = array(); $og_type = isset( $mt_og[ 'og:type' ] ) ? $mt_og[ 'og:type' ] : false; /* * Move any existing properties (from shortcodes, for example) so we can filter them and add new ones. */ if ( isset( $json_data[ 'review' ] ) ) { if ( isset( $json_data[ 'review' ][ 0 ] ) ) { // Has an array of types. $all_reviews = $json_data[ 'review' ]; } elseif ( ! empty( $json_data[ 'review' ] ) ) { $all_reviews[] = $json_data[ 'review' ]; // Markup for a single type. } unset( $json_data[ 'review' ] ); } /* * Only pull values from meta tags if this is the main entity markup. */ if ( $is_main && $og_type ) { if ( ! empty( $mt_og[ $og_type . ':reviews' ] ) && is_array( $mt_og[ $og_type . ':reviews' ] ) ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'adding ' . count( $mt_og[ $og_type . ':reviews' ] ) . ' product reviews from mt_og' ); } foreach ( $mt_og[ $og_type . ':reviews' ] as $mt_review ) { $single_review = WpssoSchema::get_data_itemprop_from_assoc( $mt_review, array( 'url' => 'review:url', 'dateCreated' => 'review:created_time', 'dateModified' => 'review:updated_time', 'name' => 'review:title', 'description' => 'review:description', 'text' => 'review:text', ) ); if ( ! empty( $mt_review[ 'review:rating:value' ] ) ) { $single_review[ 'reviewRating' ] = WpssoSchema::get_schema_type_context( 'https://schema.org/Rating', WpssoSchema::get_data_itemprop_from_assoc( $mt_review, array( 'ratingValue' => 'review:rating:value', 'worstRating' => 'review:rating:worst', 'bestRating' => 'review:rating:best', ) ) ); } if ( ! empty( $mt_review[ 'review:author:name' ] ) ) { $single_review[ 'author' ] = WpssoSchema::get_schema_type_context( 'https://schema.org/Person', WpssoSchema::get_data_itemprop_from_assoc( $mt_review, array( 'url' => 'review:author:url', 'name' => 'review:author:name', ) ) ); } if ( ! empty( $mt_review[ 'review:image' ] ) ) { WpssoSchema::add_images_data_mt( $single_review[ 'image' ], $mt_review[ 'review:image' ] ); } if ( ! empty( $mt_review[ 'review:video' ] ) ) { WpssoSchema::add_videos_data_mt( $single_review[ 'video' ], $mt_review[ 'review:video' ] ); } /* * If we have a comment ID then add any replies to the comment. */ if ( ! empty( $mt_review[ 'review:id' ] ) ) { $replies_added = WpssoSchemaSingle::add_comment_reply_data( $single_review[ 'comment' ], $mod, $mt_review[ 'review:id' ] ); if ( ! $replies_added ) { unset( $single_review[ 'comment' ] ); } /* * Update the @id string based on $json_ret[ 'url' ], $type_id, and $comment_id values. */ WpssoSchema::update_data_id( $single_review, array( $type_id = 'review', $mt_review[ 'review:id' ] ) ); } /* * Add the complete review. */ $all_reviews[] = WpssoSchema::get_schema_type_context( 'https://schema.org/Review', $single_review ); } } } $json_ret[ 'review' ] = apply_filters( 'wpsso_json_prop_https_schema_org_review', $all_reviews, $mod, $mt_og, $page_type_id, $is_main ); /* * Return if nothing to do. */ if ( empty( $json_ret[ 'review' ] ) && empty( $json_data[ 'review' ] ) ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'exiting early: no reviews' ); } unset( $json_ret[ 'review' ], $json_data[ 'review' ] ); return WpssoSchema::return_data_from_filter( $json_data, $json_ret, $is_main ); } /* * Make sure reviews are allowed by Google for this Schema type. */ if ( ! $this->p->schema->allow_review( $page_type_id ) ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'cannot add review to page type id ' . $page_type_id ); } unset( $json_ret[ 'review' ], $json_data[ 'review' ] ); if ( $this->p->notice->is_admin_pre_notices() ) { $page_type_url = $this->p->schema->get_schema_type_url( $page_type_id ); $notice_msg = sprintf( __( 'Reviews for this markup have been ignored - Google does not allow reviews for the Schema %2$s type.', 'wpsso' ), 'https://developers.google.com/search/docs/data-types/review-snippet', $page_type_url ); $this->p->notice->warn( $notice_msg ); } } return WpssoSchema::return_data_from_filter( $json_data, $json_ret, $is_main ); } } }