<?php
namespace wpbuddy\rich_snippets\pro;
use wpbuddy\rich_snippets\Rich_Snippet;
if ( ! defined( 'ABSPATH' ) ) {
exit;
} // Exit if accessed directly
/**
* Class WooCommerce_Model.
*
* Recognizes the WooCommerce plugin and provides new fields.
*
* @package wpbuddy\rich_snippets
*
* @since 2.2.0
*/
final class WooCommerce_Model {
/**
* @param $values
*
* @return mixed
*/
public static function internal_subselect( $values ) {
if ( ! function_exists( 'WC' ) ) {
return $values;
}
$values['http://schema.org/AggregateRating'][] = array(
'id' => 'woocommerce_rating',
'label' => esc_html_x( 'WooCommerce: Product Rating', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'rating' ),
);
$values['http://schema.org/Rating'][] = array(
'id' => 'woocommerce_rating',
'label' => esc_html_x( 'WooCommerce: Product Rating', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'rating' ),
);
$values['http://schema.org/AggregateRating'][] = array(
'id' => 'woocommerce_review_rating',
'label' => esc_html_x( 'WooCommerce: Product Review Rating', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'review_rating' ),
);
$values['http://schema.org/Rating'][] = array(
'id' => 'woocommerce_review_rating',
'label' => esc_html_x( 'WooCommerce: Product Review Rating', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'review_rating' ),
);
$values['http://schema.org/Text'][] = array(
'id' => 'woocommerce_sku',
'label' => esc_html_x( 'WooCommerce: Stock Keeping Unit', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sku' ),
);
$values['http://schema.org/Text'][] = array(
'id' => 'woocommerce_currency_code',
'label' => esc_html_x( 'WooCommerce: Currency Code', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'currency_code' ),
);
$values['http://schema.org/Offer'][] = array(
'id' => 'woocommerce_offers',
'label' => esc_html_x( 'WooCommerce: Offers', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'offers' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_height',
'label' => esc_html_x( 'WooCommerce: Product Height', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'height' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_width',
'label' => esc_html_x( 'WooCommerce: Product Width', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'width' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_length',
'label' => esc_html_x( 'WooCommerce: Product Length', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'length' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_weight',
'label' => esc_html_x( 'WooCommerce: Product Weight', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'weight' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'textfield_woocommerce_product_attribute',
'label' => esc_html_x( 'WooCommerce: Product attribute', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'attribute' ),
);
$values['http://schema.org/Integer'][] = $values['http://schema.org/URL'][] = array(
'id' => 'textfield_woocommerce_product_attribute',
'label' => esc_html_x( 'WooCommerce: Product attribute', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'attribute' ),
);
$values['http://schema.org/Review'][] = array(
'id' => 'woocommerce_reviews',
'label' => esc_html_x( 'WooCommerce: Product reviews', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'reviews' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_price',
'label' => esc_html_x( 'WooCommerce: Product Price', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'price' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_sales_price',
'label' => esc_html_x( 'WooCommerce: Product Sales Price', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sales_price' ),
);
$values['http://schema.org/ItemAvailability'][] = array(
'id' => 'woocommerce_availability',
'label' => esc_html_x( 'WooCommerce: Availability', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'availability' ),
);
$values['http://schema.org/Date'][] = array(
'id' => 'woocommerce_sales_end_date',
'label' => esc_html_x( 'WooCommerce: Sales End Date', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sales_end_date' ),
);
$values['http://schema.org/Date'][] = array(
'id' => 'woocommerce_sales_start_date',
'label' => esc_html_x( 'WooCommerce: Sales Start Date', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sales_start_date' ),
);
$values['http://schema.org/DateTime'][] = array(
'id' => 'woocommerce_sales_end_datetime',
'label' => esc_html_x( 'WooCommerce: Sales End Date and Time', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sales_end_datetime' ),
);
$values['http://schema.org/DateTime'][] = array(
'id' => 'woocommerce_sales_start_date',
'label' => esc_html_x( 'WooCommerce: Sales Start Date and Time', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'sales_start_datetime' ),
);
$values['http://schema.org/Integer'][] = array(
'id' => 'woocommerce_stock_number',
'label' => esc_html_x( 'WooCommerce: Stock Number', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'stock_number' ),
);
$values['http://schema.org/Text'][] = array(
'id' => 'woocommerce_weight_unit',
'label' => esc_html_x( 'WooCommerce: Weight Unit', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'weight_unit' ),
);
$values['http://schema.org/Text'][] = $values['http://schema.org/Thing'][] = array(
'id' => 'textfield_woocommerce_product_attribute',
'label' => esc_html_x( 'WooCommerce: Product attribute', 'subselect field', 'rich-snippets-schema' ),
'method' => array( '\wpbuddy\rich_snippets\pro\WooCommerce_Model', 'attribute' ),
);
return $values;
}
/**
* Returns the value of the current rating.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.2.0
*
*/
public static function rating( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( ! $product instanceof \WC_Product ) {
$rating_value = 0;
$rating_count = 0;
} else {
$rating_value = floatval( $product->get_average_rating( 'raw' ) );
$rating_count = floatval( $product->get_rating_count( 'raw' ) );
}
# force SNIP to not include aggregateRating at all because there are no ratings
# This is because rating_count cannot be zero for Googles Structured Data Tester
if ( $rating_count <= 0 ) {
return '';
}
$rating_snippet = new Rich_Snippet();
$rating_snippet->type = 'AggregateRating';
$rating_snippet->set_props( array(
array(
'name' => 'ratingCount',
'value' => $rating_count,
),
array(
'name' => 'bestRating',
'value' => 5,
),
array(
'name' => 'ratingValue',
'value' => $rating_value,
),
array(
'name' => 'worstRating',
'value' => $rating_count <= 0 ? 0 : 1, # worstRating must be 0 if ratingCount is 0
),
) );
$rating_snippet->prepare_for_output();
return $rating_snippet;
}
/**
* Returns the value of the current review rating.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.6.0
*
*/
public static function review_rating( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( ! $product instanceof \WC_Product ) {
$rating_value = 0;
$review_count = 0;
} else {
$rating_value = floatval( $product->get_average_rating( 'raw' ) );
$review_count = floatval( $product->get_review_count( 'raw' ) );
}
# force SNIP to not include aggregateRating at all because there are no ratings
# This is because review_count cannot be zero for Googles Structured Data Tester
if ( $review_count <= 0 ) {
return '';
}
$rating_snippet = new Rich_Snippet();
$rating_snippet->type = 'AggregateRating';
$rating_snippet->set_props( array(
array(
'name' => 'reviewCount',
'value' => $review_count,
),
array(
'name' => 'bestRating',
'value' => 5,
),
array(
'name' => 'ratingValue',
'value' => $rating_value,
),
array(
'name' => 'worstRating',
'value' => $review_count <= 0 ? 0 : 1, # worstRating must be 0 if ratingCount is 0
),
) );
$rating_snippet->prepare_for_output();
return $rating_snippet;
}
/**
* Returns the value of the current SKU.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.2.0
*
*/
public static function sku( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
return (string) $product->get_sku( 'raw' );
}
return '';
}
/**
* Returns the weight unit.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.11.0
*
*/
public static function weight_unit( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return (string) get_option( 'woocommerce_weight_unit' );
}
/**
* Returns the products end sales date.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.11.0
*
*/
public static function sales_end_date( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
$not_on_sale_time = (string) date_i18n( 'Y-m-d', strtotime( 'NOW + 1 year' ) );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
if ( $product->is_on_sale() && $product->get_date_on_sale_to() ) {
return date_i18n( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() );
}
}
return $not_on_sale_time;
}
/**
* Returns the products end sales datetime.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.11.0
*
*/
public static function sales_end_datetime( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return date_i18n( 'c', strtotime( self::sales_end_date( $val, $rich_snippet, $meta_info ) ) );
}
/**
* Returns the products start sales date.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.11.0
*
*/
public static function sales_start_date( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
$not_on_sale_time = (string) date_i18n( 'Y-m-d', strtotime( 'NOW - 1 DAY' ) );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
if ( $product->is_on_sale() && $product->get_date_on_sale_from() ) {
return date_i18n( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() );
}
}
return $not_on_sale_time;
}
/**
* Returns the products start sales date and time.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.11.0
*
*/
public static function sales_start_datetime( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return date_i18n( 'c', strtotime( self::sales_start_date( $val, $rich_snippet, $meta_info ) ) );
}
/**
* Returns the value of the current product price
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return float|string
* @since 2.11.0
*
*/
public static function price( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
$tax_display_mode = (string) get_option( 'woocommerce_tax_display_shop', '' );
if ( 'incl' === $tax_display_mode ) {
$price = wc_get_price_including_tax( $product, [ 'price' => $product->get_price() ] );
} else {
$price = wc_get_price_excluding_tax( $product, [ 'price' => $product->get_price() ] );
}
return wc_format_decimal( $price, wc_get_price_decimals() );
}
return '';
}
/**
* Returns the value of the current products availability.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return float|string
* @since 2.11.0
*/
public static function availability( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return self::get_availability( intval( $meta_info['current_post_id'] ) );
}
/**
* @param int $product_id
*
* @return string
* @since 2.15.2
*/
public static function get_availability( int $product_id ): string {
$product = wc_get_product( $product_id );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
switch ( $product->get_stock_status() ) {
case 'onbackorder':
return 'http://schema.org/PreOrder';
case 'instock':
if ( function_exists( 'wc_get_low_stock_amount' ) && 'yes' === get_option( 'woocommerce_manage_stock' ) && $product->managing_stock() ) {
$low_stock_amount = intval( wc_get_low_stock_amount( $product ) );
$stock_quantity = $product->get_stock_quantity( 'edit' );
if ( $stock_quantity <= $low_stock_amount ) {
if ( (bool) get_option( 'wpb_rs/setting/wc_availability_use_preorder', false ) ) {
return 'http://schema.org/PreOrder';
} else {
return 'http://schema.org/LimitedAvailability';
}
}
}
return 'http://schema.org/InStock';
case 'outofstock':
return 'http://schema.org/OutOfStock';
}
}
return '';
}
/**
* Returns the value of the current product sales price.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return float|string
* @since 2.11.0
*
*/
public static function sales_price( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
$tax_display_mode = (string) get_option( 'woocommerce_tax_display_shop', '' );
if ( 'incl' === $tax_display_mode ) {
$price = wc_get_price_including_tax( $product, [ 'price' => $product->get_sale_price() ] );
} else {
$price = wc_get_price_excluding_tax( $product, [ 'price' => $product->get_sale_price() ] );
}
return wc_format_decimal( $price, wc_get_price_decimals() );
}
return '';
}
/**
* Returns the value of the stock number.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
* @since 2.11.0
*
*/
public static function stock_number( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
$stock = $product->get_manage_stock( 'edit' );
$obj = new \stdClass();
$obj->{'@context'} = 'http://schema.org';
$obj->{'@type'} = 'Offer';
$obj->value = $stock;
return $obj;
}
return new \stdClass();
}
/**
* Returns the currency code.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return float|string
* @since 2.11.0
*
*/
public static function currency_code( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return get_woocommerce_currency();
}
/**
* Returns the offer for a WooCommerce product.
*
* @param int $post_id
*
* @return \stdClass
* @since 2.2.0
*
*/
private static function offer( $post_id ) {
/**
* @var \WC_Product_Variation
*/
$product = wc_get_product( $post_id );
if ( ! ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) ) {
return new \stdClass();
}
$obj = new \stdClass();
$obj->{'@context'} = 'http://schema.org';
$obj->{'@type'} = 'Offer';
$obj->availability = self::get_availability( intval( $post_id ) );
$obj->priceCurrency = get_woocommerce_currency();
$obj->price = wc_format_decimal( $product->get_price(), wc_get_price_decimals() );
$obj->url = $product->get_permalink();
$sale_date = $product->get_date_on_sale_to( 'raw' );
if ( ! $sale_date instanceof \DateTime ) {
# If there is no sales date create a fake date to avoid Googles warnings
# @see https://rich-snippets.io/offers-pricevaliduntil-recommended/
$obj->priceValidUntil = (string) date_i18n( 'c', strtotime( 'NOW + 1 year' ) );
} else {
$obj->priceValidUntil = $sale_date->date( 'c' );
}
return $obj;
}
/**
* Returns a snippet of all offers.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
*
* @since 2.2.0
*/
public static function offers( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
$product = wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product_Variable ) {
$lowest = $product->get_variation_price( 'min', false );
$highest = $product->get_variation_price( 'max', false );
$tax_display_mode = (string) get_option( 'woocommerce_tax_display_shop', '' );
if ( 'incl' === $tax_display_mode ) {
$lowest = wc_get_price_including_tax( $product, [ 'price' => $lowest ] );
$highest = wc_get_price_including_tax( $product, [ 'price' => $highest ] );
} else {
$lowest = wc_get_price_excluding_tax( $product, [ 'price' => $lowest ] );
$highest = wc_get_price_excluding_tax( $product, [ 'price' => $highest ] );
}
if ( $lowest === $highest ) {
return self::offer( $meta_info['current_post_id'] );
} else {
$obj = new \stdClass();
$obj->{'@context'} = 'http://schema.org';
$obj->{'@type'} = 'AggregateOffer';
$obj->lowPrice = wc_format_decimal( $lowest, wc_get_price_decimals() );
$obj->highPrice = wc_format_decimal( $highest, wc_get_price_decimals() );
$obj->priceCurrency = get_woocommerce_currency();
$obj->offerCount = count( $product->get_children() );
$obj->url = $product->get_permalink();
return $obj;
}
} elseif ( $product instanceof \WC_Product ) {
return self::offer( $meta_info['current_post_id'] );
}
return new \stdClass();
}
/**
* Returns the height of a product.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
* @since 2.2.0
*
*/
public static function height( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return self::get_product_quantitive_snippet( $meta_info['current_post_id'], 'height' );
}
/**
* Returns the width of a product.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
* @since 2.2.0
*
*/
public static function width( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return self::get_product_quantitive_snippet( $meta_info['current_post_id'], 'width' );
}
/**
* Returns the length of a product.
*
* @param mixed $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
* @since 2.19.0
*/
public static function length( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return self::get_product_quantitive_snippet( $meta_info['current_post_id'], 'length' );
}
/**
* Get WooCommerce product dimension as a snippet.
*
* @param int $product_id
* @param string $prop width|height|weight
*
* since 2.2.0
*
* @return \stdClass
*/
private static function get_product_quantitive_snippet( $product_id, $prop ) {
$product = wc_get_product( $product_id );
$item = new \stdClass();
if ( ! is_subclass_of( $product, 'WC_Data', false ) ) {
return $item;
}
$item->{'@context'} = 'http://schema.org';
$item->{'@type'} = 'QuantitativeValue';
$item->value = method_exists( $product, 'get_' . $prop ) ? $product->{'get_' . $prop}() : '';
$item->value = floatval( $item->value );
$item->unitCode = 'weight' === $prop ? get_option( 'woocommerce_weight_unit' ) : get_option( 'woocommerce_dimension_unit' );
return $item;
}
/**
* Returns the eight of a product.
*
* @param $val
* @param \wpbuddy\rich_snippets\Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass
* @since 2.2.0
*
*/
public static function weight( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
return self::get_product_quantitive_snippet( $meta_info['current_post_id'], 'weight' );
}
/**
* Reads a product attribute from WooCommerce (serialized data).
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return string
* @since 2.5.0
*
*/
public static function attribute( $val, Rich_Snippet $rich_snippet, array $meta_info ) {
if ( ! function_exists( '\wc_get_product' ) ) {
return '';
}
if ( ! is_scalar( $val ) ) {
return '';
}
if ( empty( $val ) ) {
return '';
}
$product = \wc_get_product( $meta_info['current_post_id'] );
if ( $product instanceof \WC_Product || is_subclass_of( $product, 'WC_Product', false ) ) {
return $product->get_attribute( $val );
}
return '';
}
/**
* Outputs product reviews from WooCommerce.
*
* @param $val
* @param Rich_Snippet $rich_snippet
* @param array $meta_info
*
* @return \stdClass[]
* @since 2.7.0
*
*/
public static function reviews( $val, Rich_Snippet $rich_snippet, array $meta_info ): array {
if ( ! function_exists( '\wc_get_product' ) ) {
return [];
}
/**
* @var \WP_Comment[] $comments
*/
$args = [
'post_id' => $meta_info['current_post_id'],
'include_unapproved' => false,
'number' => 5,
'type' => 'review',
'meta_query' => array(
'city_clause' => array(
'key' => 'rating',
'compare' => 'EXISTS',
),
),
];
/**
* Get comments filter for WooCommerce products.
*
* Allows to filter the comment arguments when WooCommerce product comments are loaded.
*
* @hook wpbuddy/rich_snippets/woocommerce/reviews/args
*
* @param {array} $args The arguments.
* @returns {array} The modified arguments.
*
* @since 2.7.0
*/
$comments = get_comments( apply_filters( 'wpbuddy/rich_snippets/woocommerce/reviews/args', $args ) );
if ( ! is_array( $comments ) || count( $comments ) <= 0 ) {
return [];
}
$reviews = [];
foreach ( $comments as $comment ) {
$review = new \stdClass();
$review->{'@context'} = 'http://schema.org';
$review->{'@type'} = 'Review';
$review->author = new \stdClass();
$review->author->{'@context'} = 'http://schema.org';
$review->author->{'@type'} = 'Person';
$review->author->name = $comment->comment_author;
$review->reviewRating = new \stdClass();
$review->reviewRating->{'@context'} = 'http://schema.org';
$review->reviewRating->{'@type'} = 'Rating';
$review->reviewRating->bestRating = 5;
$review->reviewRating->worstRating = 1;
$review->reviewRating->ratingValue = max( 1, absint( get_comment_meta( $comment->comment_ID, 'rating', true ) ) );
$review->reviewBody = strip_tags( $comment->comment_content );
$review->datePublished = date_i18n( 'c', strtotime( $comment->comment_date ) );
$reviews[] = $review;
}
return $reviews;
}
/**
* Adds new loop fields to the dropdown.
*
* @param array $values
*
* @return array
* @since 2.12.0
*
*/
public static function wc_loop_fields( $values ) {
if ( function_exists( 'WC' ) ) {
$values['variable_products'] = __( 'Variable products (WooCommerce)', 'rich-snippets-schema' );
}
return $values;
}
/**
* Returns the loop items.
*
* @param array $items
* @param Rich_Snippet $snippet
* @param int $post_id
*
* @return array
* @since 2.12.0
*
*/
public static function loop_items( $items, $snippet, $post_id ) {
if ( ! function_exists( 'WC' ) ) {
return $items;
}
if ( 'variable_products' !== $snippet->get_loop_type() ) {
return $items;
}
$product = wc_get_product( $post_id );
if ( $product instanceof \WC_Product_Simple ) {
return [
$product->get_id() => $product
];
}
if ( $product instanceof \WC_Product_Variable || $product instanceof \WC_Product_Grouped ) {
$ids = $product->get_children();
if ( empty( $ids ) ) {
return $items;
}
$products = get_posts( [
'include' => $ids,
'post_type' => [ 'product_variation', 'product' ]
] );
if ( ! is_array( $products ) ) {
return $items;
}
if ( count( $products ) <= 0 ) {
return $items;
}
$products = array_combine( wp_list_pluck( $products, 'ID' ), $products );
return $products;
}
return $items;
}
}