WC_Structured_Data::generate_product_data() │ public │ WC 1.0
Generates Product structured data.
Hooked into woocommerce_single_product_summary hook.
Method of the class: WC_Structured_Data{}
Hooks from the method
Return
null
. Nothing (null).
Usage
$WC_Structured_Data = new WC_Structured_Data(); $WC_Structured_Data->generate_product_data( $product );
- $product(WC_Product)
- Product data .
Default: null)
WC_Structured_Data::generate_product_data() WC Structured Data::generate product data code WC 9.7.1
public function generate_product_data( $product = null ) { if ( ! is_object( $product ) ) { global $product; } if ( ! is_a( $product, 'WC_Product' ) ) { return; } $shop_name = get_bloginfo( 'name' ); $shop_url = home_url(); $currency = get_woocommerce_currency(); $permalink = get_permalink( $product->get_id() ); $image = wp_get_attachment_url( $product->get_image_id() ); $markup = array( '@type' => 'Product', '@id' => $permalink . '#product', // Append '#product' to differentiate between this @id and the @id generated for the Breadcrumblist. 'name' => wp_kses_post( $product->get_name() ), 'url' => $permalink, 'description' => wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) ), ); if ( $image ) { $markup['image'] = $image; } // Declare SKU or fallback to ID. if ( $product->get_sku() ) { $markup['sku'] = $product->get_sku(); } else { $markup['sku'] = $product->get_id(); } // Prepare GTIN and load it if it's valid. $gtin = $this->prepare_gtin( $product->get_global_unique_id() ); if ( $this->is_valid_gtin( $gtin ) ) { $markup['gtin'] = $gtin; } if ( '' !== $product->get_price() ) { // Assume prices will be valid until the end of next year, unless on sale and there is an end date. $price_valid_until = gmdate( 'Y-12-31', time() + YEAR_IN_SECONDS ); if ( $product->is_type( ProductType::VARIABLE ) ) { $lowest = $product->get_variation_price( 'min', false ); $highest = $product->get_variation_price( 'max', false ); if ( $lowest === $highest ) { $markup_offer = array( '@type' => 'Offer', 'priceSpecification' => array( array( '@type' => 'UnitPriceSpecification', 'price' => wc_format_decimal( $lowest, wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $price_valid_until, ), ), ); } else { $markup_offer = array( '@type' => 'AggregateOffer', 'lowPrice' => wc_format_decimal( $lowest, wc_get_price_decimals() ), 'highPrice' => wc_format_decimal( $highest, wc_get_price_decimals() ), 'offerCount' => count( $product->get_children() ), ); if ( $product->is_on_sale() ) { $children = array_map( 'wc_get_product', $product->get_children() ); $lowest_child_sale_price = $highest; foreach ( $children as $child ) { $child_sale_price = $child->get_sale_price(); if ( empty( $child_sale_price ) || (int) $child_sale_price > (int) $lowest_child_sale_price ) { continue; } $lowest_child_sale_price = $child_sale_price; $date_on_sale_to = $child->get_date_on_sale_to(); $sale_price_valid_until = $date_on_sale_to ? gmdate( 'Y-m-d', $date_on_sale_to->getTimestamp() ) : null; } $markup_offer['priceSpecification'] = array( array( '@type' => 'UnitPriceSpecification', 'priceType' => 'https://schema.org/SalePrice', 'price' => wc_format_decimal( $lowest_child_sale_price, wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $sale_price_valid_until ?? $price_valid_until, ), ); } } } elseif ( $product->is_type( ProductType::GROUPED ) ) { $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); $children = array_filter( array_map( 'wc_get_product', $product->get_children() ), 'wc_products_array_filter_visible_grouped' ); $price_function = 'incl' === $tax_display_mode ? 'wc_get_price_including_tax' : 'wc_get_price_excluding_tax'; foreach ( $children as $child ) { if ( '' !== $child->get_regular_price() ) { $child_prices[] = $price_function( $child, array( 'price' => $child->get_regular_price() ) ); } if ( '' !== $child->get_sale_price() ) { $child_sale_prices[] = $price_function( $child, array( 'price' => $child->get_sale_price() ) ); } } if ( empty( $child_prices ) ) { $min_price = 0; } else { $min_price = min( $child_prices ); } if ( empty( $child_sale_prices ) ) { $min_sale_price = 0; } else { $min_sale_price = min( $child_sale_prices ); } $unit_price_specification = array( '@type' => 'UnitPriceSpecification', 'price' => wc_format_decimal( $min_price, wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $price_valid_until, ); if ( $product->is_on_sale() && $min_price !== $min_sale_price ) { // `priceType` should only be specified in prices which are not the current offer. // https://developers.google.com/search/docs/appearance/structured-data/merchant-listing#sale-pricing-example $unit_price_specification['priceType'] = 'https://schema.org/ListPrice'; } $markup_offer = array( '@type' => 'Offer', 'priceSpecification' => array( $unit_price_specification, ), ); if ( $product->is_on_sale() && $min_price !== $min_sale_price ) { if ( $product->get_date_on_sale_to() ) { $sale_price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ); } $markup_offer['priceSpecification'][] = array( '@type' => 'UnitPriceSpecification', 'price' => wc_format_decimal( $min_sale_price, wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $sale_price_valid_until ?? $price_valid_until, ); } } else { $unit_price_specification = array( '@type' => 'UnitPriceSpecification', 'price' => wc_format_decimal( $product->get_regular_price(), wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $price_valid_until, ); if ( $product->is_on_sale() ) { // `priceType` should only be specified in prices which are not the current offer. // https://developers.google.com/search/docs/appearance/structured-data/merchant-listing#sale-pricing-example $unit_price_specification['priceType'] = 'https://schema.org/ListPrice'; } $markup_offer = array( '@type' => 'Offer', 'priceSpecification' => array( $unit_price_specification, ), ); if ( $product->is_on_sale() ) { if ( $product->get_date_on_sale_to() ) { $sale_price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ); } $markup_offer['priceSpecification'][] = array( '@type' => 'UnitPriceSpecification', 'price' => wc_format_decimal( $product->get_sale_price(), wc_get_price_decimals() ), 'priceCurrency' => $currency, 'valueAddedTaxIncluded' => wc_prices_include_tax(), 'validThrough' => $sale_price_valid_until ?? $price_valid_until, ); } } if ( $product->is_in_stock() ) { $stock_status_schema = ( 'onbackorder' === $product->get_stock_status() ) ? 'BackOrder' : 'InStock'; } else { $stock_status_schema = 'OutOfStock'; } $markup_offer += array( 'priceValidUntil' => $sale_price_valid_until ?? $price_valid_until, 'availability' => 'http://schema.org/' . $stock_status_schema, 'url' => $permalink, 'seller' => array( '@type' => 'Organization', 'name' => $shop_name, 'url' => $shop_url, ), ); if ( ( ! empty( $markup_offer['price'] ) || ! empty( $markup_offer['lowPrice'] ) || ! empty( $markup_offer['highPrice'] ) ) && empty( $markup_offer['priceCurrency'] ) ) { $markup_offer['priceCurrency'] = $currency; } $markup['offers'] = array( apply_filters( 'woocommerce_structured_data_product_offer', $markup_offer, $product ) ); } if ( $product->get_rating_count() && wc_review_ratings_enabled() ) { $markup['aggregateRating'] = array( '@type' => 'AggregateRating', 'ratingValue' => $product->get_average_rating(), 'reviewCount' => $product->get_review_count(), ); // Markup 5 most recent rating/review. $comments = get_comments( array( 'number' => 5, 'post_id' => $product->get_id(), 'status' => 'approve', 'post_status' => 'publish', 'post_type' => 'product', 'parent' => 0, 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query array( 'key' => 'rating', 'type' => 'NUMERIC', 'compare' => '>', 'value' => 0, ), ), ) ); if ( $comments ) { $markup['review'] = array(); foreach ( $comments as $comment ) { $markup['review'][] = array( '@type' => 'Review', 'reviewRating' => array( '@type' => 'Rating', 'bestRating' => '5', 'ratingValue' => get_comment_meta( $comment->comment_ID, 'rating', true ), 'worstRating' => '1', ), 'author' => array( '@type' => 'Person', 'name' => get_comment_author( $comment ), ), 'reviewBody' => get_comment_text( $comment ), 'datePublished' => get_comment_date( 'c', $comment ), ); } } } // Check we have required data. if ( empty( $markup['aggregateRating'] ) && empty( $markup['offers'] ) && empty( $markup['review'] ) ) { return; } $this->set_data( apply_filters( 'woocommerce_structured_data_product', $markup, $product ) ); }