: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
'key' => 'wp_review_type',
'value' => '1', // See https://core.trac.wordpress.org/ticket/23268 for more information.
'compare' => 'NOT EXISTS',
'key' => 'wp_review_type',
if ( 'none' === wp_review_option( 'review_type' ) || ! wp_review_option( 'review_type' ) ) {
'key' => 'wp_review_type',
$query_args['meta_query'] = $meta_query;
* Filters reviews query args.
* @param array $query_args Query args.
* @param array $options Options.
$query_args = apply_filters( 'wp_review_reviews_query_args', $query_args, $options );
$query = new WP_Query( $query_args );
if ( empty( $options['no_cache'] ) ) {
set_transient( $key, $query, wp_review_transient_expired_time() );
* Shows ajax pagination for reviews.
* @param int $page Current page.
* @param int $last_page Last page.
function wp_review_ajax_pagination( $page, $last_page ) {
<div class="reviews-pagination" data-page="<?php echo intval( $page ); ?>">
<?php if ( $page > 1 ) : ?>
<a href="#" class="previous"><span><?php esc_html_e( '« Previous', 'wp-review' ); ?></span></a>
<?php if ( $page != $last_page ) : ?>
<a href="#" class="next"><span><?php esc_html_e( 'Next »', 'wp-review' ); ?></span></a>
* @param float $value Rating value.
* @param array $args Custom attributes.
function wp_review_star_rating( $value, $args = array() ) {
'value' => floatval( $value ),
$template = mts_get_template_path( 'star', 'star-output' );
function wp_review_spinner() {
echo '<span class="animate-spin fa fa-spinner"></span>';
* Rates a post by visitor
* Should be used in AJAX handler.
* @param int $post_id Post ID.
* @param array $rating_data {
* @type float $total Rating total.
* @type string $type Rating type.
* @type array $features Features rating data, key is feature ID and value is rating value.
function wp_review_visitor_rate( $post_id, $rating_data ) {
$rating_data = wp_parse_args(
if ( ! $rating_data['total'] ) {
echo wp_json_encode( $output );
$type = wp_review_get_post_user_review_type( $post_id );
$rating_type = wp_review_get_rating_type_data( $type );
echo wp_json_encode( $output );
if ( $rating_data['type'] && $type !== $rating_data['type'] ) {
echo wp_json_encode( $output );
if ( ! empty( $rating_data['features'] ) && is_array( $rating_data['features'] ) ) {
foreach ( $rating_data['features'] as $key => $value ) {
$rating_data['features'][ $key ] = $value;
$user_id = is_user_logged_in() ? get_current_user_id() : 0;
$review = $rating_data['total'];
$uip = wp_review_get_user_ip();
if ( ! function_exists( 'wp_review_comment_duplicate_trigger' ) ) {
* Shows comment duplicate message.
* @param array $commentdata Comment data.
function wp_review_comment_duplicate_trigger( $commentdata ) {
$post_reviews = mts_get_post_reviews( $commentdata['comment_post_ID'] );
$output['status'] = 'fail';
$output['error'] = 'duplicate';
$output['rating_total'] = $post_reviews['rating'];
$output['rating_count'] = $post_reviews['count'];
$output['html'] = wp_review_rating( $post_reviews['rating'], $commentdata['comment_post_ID'], array( 'user_rating' => true ) );
echo wp_json_encode( $output );
add_action( 'comment_duplicate_trigger', 'wp_review_comment_duplicate_trigger' );
// Don't allow higher rating than max.
if ( $review > $rating_type['max'] ) {
$review = $rating_type['max'];
! wp_review_has_reviewed( $post_id, $user_id, $uip, WP_REVIEW_COMMENT_TYPE_VISITOR ) &&
( $user_id || ! wp_review_option( 'registered_only' ) )
// Translators: rating value text.
$comment_content = sprintf( __( 'Visitor Rating: %s', 'wp-review' ), sprintf( $rating_type['value_text'], $review ) );
if ( ! empty( $rating_data['features'] ) && is_array( $rating_data['features'] ) ) {
$features = wp_review_get_review_items( $post_id );
foreach ( $rating_data['features'] as $feature_id => $value ) {
$comment_content .= sprintf(
! empty( $features[ $feature_id ] ) ? esc_html( $features[ $feature_id ]['wp_review_item_title'] ) : '',
$approve_comment = wp_review_option( 'approve_ratings', true );
$approve_comment = 'false' !== $approve_comment;
if ( is_user_logged_in() ) {
$insert = wp_insert_comment(
'comment_type' => WP_REVIEW_COMMENT_TYPE_VISITOR,
'comment_post_ID' => $post_id,
'comment_author_IP' => $uip,
'comment_content' => $comment_content,
'comment_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
'comment_date' => current_time( 'mysql' ),
'comment_date_gmt' => current_time( 'mysql', 1 ),
'comment_approved' => $approve_comment,
if ( update_comment_meta( $insert, WP_REVIEW_VISITOR_RATING_METAKEY, $review ) ) {
if ( ! empty( $rating_data['features'] ) ) {
update_comment_meta( $insert, WP_REVIEW_COMMENT_FEATURES_RATING_METAKEY, $rating_data['features'] );
$output['status'] = 'ok';
if ( ! empty( $rating_data['features'] ) ) {
$reviews = wp_review_get_post_feature_reviews( $post_id, true );
$output['html'] = wp_review_get_review_box( $post_id );
$output['reviews'] = $reviews;
$post_reviews = mts_get_post_reviews( $post_id, true );
$output['html'] = wp_review_rating( $post_reviews['rating'], $post_id, array( 'user_rating' => true ) );
$output['rating_total'] = $post_reviews['rating'];
$output['rating_count'] = $post_reviews['count'];
if ( ! $approve_comment ) {
$output['awaiting_moderation'] = __( 'Your rating is awaiting moderation.', 'wp-review' );
echo wp_json_encode( $output );
wp_delete_comment( $insert );
$post_reviews = mts_get_post_reviews( $post_id );
$output['status'] = 'fail';
$output['error'] = 'db_error';
$output['rating_total'] = $post_reviews['rating'];
$output['rating_count'] = $post_reviews['count'];
$output['html'] = wp_review_rating( $post_reviews['rating'], $post_id, array( 'user_rating' => true ) );
echo wp_json_encode( $output );
function wp_review_schema_types() {
$default = include WP_REVIEW_INCLUDES . 'schemas.php';
return apply_filters( 'wp_review_schema_types', $default );
* Gets supported schema types.
function wp_review_get_supported_schema_types() {
if ( is_null( $result ) ) {
$schemas = wp_review_schema_types();
foreach ( $schemas as $key => $value ) {
if ( empty( $value['deprecated'] ) ) {
$supported[ $key ] = $value;
* Gets deprecated schema types.
function wp_review_get_deprecated_schema_types() {
if ( is_null( $result ) ) {
$schemas = wp_review_schema_types();
$result = wp_list_filter( $schemas, array( 'deprecated' => true ) );
* Checks if there are any posts use deprecated schema type.
function wp_review_has_deprecated_schema_posts() {
'update_post_term_cache' => false,
'ignore_sticky_posts' => true,
'cache_results' => false,
'key' => 'wp_review_schema',
'value' => array( 'Article', 'Painting', 'Place', 'Thing', 'WebSite' ),
'key' => 'wp_review_schema',
'compare' => 'NOT EXISTS',
return $query->have_posts();
* Checks if a schema type is deprecated or not.
* @param string $type Schema type.
function wp_review_schema_is_deprecated( $type ) {
$deprecated = wp_review_get_deprecated_schema_types();
return ! empty( $deprecated[ $type ] );
* @param string $type Schema type name.
function wp_review_get_schema_type_data( $type ) {
$types = wp_review_schema_types();
if ( ! isset( $types ) ) {
* @param array $schema Schema data.
function wp_review_get_schema_fields( $schema ) {
if ( empty( $schema['fields'] ) ) {
return (array) $schema['fields'];
* Converts multiline text to list.
* @param string $str Multiline string.
function wp_review_nl2list( $str ) {
$lines = explode( "\n", $str );
return '<li>' . implode( '</li><li>', $lines ) . '</li>';
* Shows Google Place Review schema.
* @param array $review Review data.
* @param array $place Place data.
function wp_review_google_place_review_schema( $review, $place ) {
'@context' => 'http://schema.org',
'reviewBody' => $review['text'],
'name' => $review['author_name'],
'url' => $review['author_url'],
'image' => $review['profile_photo_url'],
'@type' => 'LocalBusiness',
'name' => $place['name'],
'ratingValue' => $review['rating'],
* Allow changing schema markup for Google place review.
* @param array $markup Schema markup.
* @param array $review Review data.
* @param array $place Place data.
$markup = apply_filters( 'wp_review_google_place_review_schema_markup', $markup, $review, $place );
printf( '<script type="application/ld+json">%s</script>', wp_json_encode( $markup ) );
* @param array $business Business data.
function wp_review_yelp_schema( $business ) {
'@context' => 'http://schema.org',
'@type' => 'LocalBusiness',
'name' => $business['name'],
'url' => $business['url'],
'image' => $business['image_url'],
'address' => implode( ', ', $business['location']['display_address'] ),
'priceRange' => $business['price'],
'telephone' => $business['phone'],
'aggregateRating' => array(
'@type' => 'AggregateRating',
'ratingValue' => $business['rating'],
'ratingCount' => $business['review_count'],
* Allow changing schema markup for Yelp.
* @param array $markup Schema markup.
* @param array $business Business data.
$markup = apply_filters( 'wp_review_yelp_schema_markup', $markup, $business );
printf( '<script type="application/ld+json">%s</script>', wp_json_encode( $markup ) );
* Shows Yelp review schema.
* @param array $review Review data.
* @param array $business Business data.