: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
function wp_review_add_admin_columns() {
$post_types = get_post_types( array( 'public' => true ), 'names' );
$excluded_post_types = apply_filters( 'wp_review_excluded_post_types', array( 'attachment' ) );
$allowed_post_types = array_diff( $post_types, $excluded_post_types );
foreach ( $allowed_post_types as $key => $value ) {
// Add post list table column.
add_filter( 'manage_' . $value . '_posts_columns', 'wp_review_post_list_column' );
// Post list table column content.
add_action( 'manage_' . $value . '_posts_custom_column', 'wp_review_post_list_column_content', 10, 2 );
add_action( 'init', 'wp_review_add_admin_columns' );
* Adds posts list columns.
* @param array $columns Posts list columns.
function wp_review_post_list_column( $columns ) {
$columns['wp_review_rating'] = __( 'Rating', 'wp-review' );
* Shows posts list column content.
* @param string $column_name Column name.
* @param int $post_id Post ID.
function wp_review_post_list_column_content( $column_name, $post_id ) {
if ( 'wp_review_rating' === $column_name ) {
$total = get_post_meta( $post_id, 'wp_review_total', true );
'bar_text_color_from' => 'inactive_color',
echo wp_review_rating( $total, $post_id, $args );
echo '<span class="no-rating">' . __( 'No Rating', 'wp-review' ) . '</span>';
* Ignores migrate notice.
function wp_review_migrate_notice_ignore() {
$user_id = $current_user->ID;
/* If user clicks to ignore the notice, add that to their user meta */
if ( isset( $_GET['wp_review_migrate_notice_ignore'] ) && '1' == $_GET['wp_review_migrate_notice_ignore'] ) {
add_user_meta( $user_id, 'wp_review_migrate_notice_ignore', 'true', true );
add_action( 'admin_init', 'wp_review_migrate_notice_ignore' );
function wp_review_migrate_notice() {
global $wpdb, $current_user;
$user_id = $current_user->ID;
if ( get_user_meta( $user_id, 'wp_review_migrate_notice_ignore' ) ) {
$has_migrated = get_option( 'wp_review_has_migrated', false );
$current_blog_id = get_current_blog_id();
$migrated_rows = get_option( 'wp_review_migrated_rows', 0 );
if ( ! $has_migrated && $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->base_prefix}mts_wp_reviews'" ) == "{$wpdb->base_prefix}mts_wp_reviews" ) {
// Table exists and not migrated (fully) yet.
$total_rows = $wpdb->get_var( 'SELECT COUNT(*) FROM ' . $wpdb->base_prefix . 'mts_wp_reviews WHERE blog_id = ' . $current_blog_id ); // WPCS: unprepared SQL ok.
$rows_left = $total_rows - $migrated_rows;
<div class="updated notice-info wp-review-notice">
// translators: settings link.
printf( __( 'Thank you for updating WP Review Pro. Your existing user ratings will show up after importing them in %s.', 'wp-review' ), '<a href="' . admin_url( 'options-general.php?page=wp-review-pro%2Fadmin%2Foptions.php#migrate' ) . '">' . __( 'Settings > WP Review Pro > Migrate Ratings', 'wp-review' ) . '</a>' );
<a class="notice-dismiss" href="<?php echo esc_url( add_query_arg( 'wp_review_migrate_notice_ignore', '1' ) ); ?>"></a>
add_action( 'admin_notices', 'wp_review_migrate_notice' );
* @param array $review Review data.
function wp_review_get_schema( $review ) {
if ( 'none' === $review['schema'] ) {
$nesting_mode = apply_filters( 'wp_review_schema_nesting_mode', 'type' );// type, rating, none.
// Force rating nesting in certain types ( weird results in testing tool otherwise ).
if ( in_array( $review['schema'], apply_filters( 'wp_review_schema_force_nested_rating_types', array( 'Movie', 'Book' ) ), true ) ) {
$nesting_mode = 'rating';
// If type requires nested aggregateRating don't nest it in aggregateRating.
if ( in_array( $review['schema'], apply_filters( 'wp_review_schema_force_nested_user_rating_types', array( 'SoftwareApplication', 'Recipe' ) ), true ) && in_array( $review['rating_schema'], array( 'visitors', 'comments' ), true ) ) {
$nesting_mode = 'rating';
switch ( $nesting_mode ) {
case 'type': // schema.org typed element ( Movie, Recipe, etc) nested in review/aggregateRating type.
if ( in_array( $review['rating_schema'], array( 'visitors', 'comments' ), true ) ) {
$output .= wp_review_get_schema_user_rating( $review, true );
$output .= wp_review_get_schema_review_rating( $review, true );
case 'rating': // review/aggregateRating type nested in specific type ( Movie, Recipe, etc).
$output .= wp_review_get_schema_type( $review, true );
case 'none': // separated reviewed item type ( Movie, Recipe, etc) and review/aggregateRating.
$output .= wp_review_get_schema_type( $review );
if ( in_array( $review['rating_schema'], array( 'visitors', 'comments' ), true ) ) {
$output .= wp_review_get_schema_user_rating( $review );
$output .= wp_review_get_schema_review_rating( $review );
return apply_filters( 'wp_review_get_schema', $output, $review );
* @param array $review Review data.
* @param bool $nested_rating Is nested rating or not.
function wp_review_get_schema_type( $review, $nested_rating = false ) {
if ( empty( $review['schema'] ) || 'Thing' === $review['schema'] || ! isset( $review['schema_data'] ) ) {
'@context' => 'http://schema.org',
'@type' => $review['schema'],
$ldjson_data = wp_review_get_ldjson_data( $review['schema'], $review['schema_data'][ $review['schema'] ], $review );
$schemas = wp_review_schema_types();
$fields = isset( $schemas[ $review['schema'] ] ) && isset( $schemas[ $review['schema'] ]['fields'] ) ? $schemas[ $review['schema'] ]['fields'] : array();
foreach ( $fields as $key => $data ) {
if ( ! empty( $data['omit'] ) ) {
$name = ! empty( $data['custom_name'] ) ? strip_tags( $data['custom_name'] ) : $data['name'];
if ( isset( $review['schema_data'][ $review['schema'] ][ $name ] ) && ! empty( $review['schema_data'][ $review['schema'] ][ $name ] ) ) {
if ( isset( $data['multiline'] ) && $data['multiline'] ) {
$review['schema_data'][ $review['schema'] ][ $name ] = preg_split( '/\r\n|[\r\n]/', $review['schema_data'][ $review['schema'] ][ $name ] );
if ( isset( $data['part_of'] ) ) {
$args[ $data['part_of'] ]['@type'] = $data['@type'];
if ( 'image' === $data['type'] ) {
$args[ $data['part_of'] ][ $name ] = $review['schema_data'][ $review['schema'] ][ $name ]['url'];
} elseif ( in_array( $name, apply_filters( 'wp_reviev_schema_ISO_8601_duration_items', array( 'prepTime', 'cookTime', 'totalTime', 'duration' ) ) ) ) { // phpcs:ignore
$args[ $data['part_of'] ][ $name ] = 'PT' . $review['schema_data'][ $review['schema'] ][ $name ];
$args[ $data['part_of'] ][ $name ] = $review['schema_data'][ $review['schema'] ][ $name ];
if ( 'image' === $data['type'] ) {
$args[ $name ] = $review['schema_data'][ $review['schema'] ][ $name ]['url'];
} elseif ( in_array( $name, apply_filters( 'wp_reviev_schema_ISO_8601_duration_items', array( 'prepTime', 'cookTime', 'totalTime', 'duration' ) ) ) ) { // phpcs:ignore
$args[ $name ] = 'PT' . $review['schema_data'][ $review['schema'] ][ $name ];
$args[ $name ] = $review['schema_data'][ $review['schema'] ][ $name ];
// Nested aggregateRating is required in some types ( SoftwareApplication, Recipe ).
$force_user_rating = in_array( $review['schema'], apply_filters( 'wp_review_schema_force_nested_user_rating_types', array( 'SoftwareApplication', 'Recipe' ) ), true );
if ( $force_user_rating ) {
if ( $review['user_review'] || $review['comments_review'] ) {
$aggregate_rating = wp_review_get_schema_nested_user_rating_args( $review );
if ( ! empty( $aggregate_rating ) ) {
$args['aggregateRating'] = $aggregate_rating;
if ( 'author' === $review['rating_schema'] ) {
$review_rating = wp_review_get_schema_nested_review_args( $review );
if ( ! empty( $review_rating ) ) {
$args['review'] = $review_rating;
} elseif ( $nested_rating ) {
if ( in_array( $review['rating_schema'], array( 'visitors', 'comments' ), true ) ) {
if ( $review['user_review'] || $review['comments_review'] ) {
$aggregate_rating = wp_review_get_schema_nested_user_rating_args( $review );
if ( ! empty( $aggregate_rating ) ) {
$args['aggregateRating'] = $aggregate_rating;
$review_rating = wp_review_get_schema_nested_review_args( $review );
if ( ! empty( $review_rating ) ) {
$args['review'] = $review_rating;
if ( 'Product' === $review['schema'] ) {
// Product type recommends both review and aggregateRating.
if ( empty( $args['review'] ) ) {
$review_rating = wp_review_get_schema_nested_review_args( $review );
if ( ! empty( $review_rating ) ) {
$args['review'] = $review_rating;
if ( empty( $args['aggregateRating'] ) ) {
$aggregate_rating = wp_review_get_schema_nested_user_rating_args( $review );
if ( ! empty( $aggregate_rating ) ) {
$args['aggregateRating'] = $aggregate_rating;
if ( 'Recipe' === $review['schema'] ) {
if ( isset( $args['video'] ) && ( empty( $args['video']['name'] ) || empty( $args['video']['description'] ) || empty( $args['video']['thumbnailUrl'] ) || empty( $args['video']['uploadDate'] ) ) ) {
$args = apply_filters( 'wp_review_get_schema_type_args', $args, $review, $nested_rating );
$output = '<script type="application/ld+json">' . PHP_EOL;
$output .= wp_json_encode( $args, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) . PHP_EOL;
$output .= '</script>' . PHP_EOL;
return apply_filters( 'wp_review_get_schema_type', $output, $args, $review, $nested_rating );
* Gets schema for review rating.
* @param array $review Review data.
* @param bool $nested_item Is nested item or not.
function wp_review_get_schema_review_rating( $review, $nested_item = false ) {
if ( ! $nested_item && in_array( $review['schema'], apply_filters( 'wp_review_schema_force_nested_user_rating_types', array( 'SoftwareApplication', 'Recipe' ) ) ) ) {
return; // Requires nested aggregateRating.
$rating_types = wp_review_get_rating_types();
$item_reviewed = wp_review_get_schema_nested_item_args( $review );
'name' => esc_html( wp_review_get_reviewed_item_name( $review ) ),
'@context' => 'http://schema.org',
'itemReviewed' => $item_reviewed,
'ratingValue' => $review['total'],
'bestRating' => $rating_types[ $review['type'] ]['max'],
'name' => esc_html( $review['author'] ),
'reviewBody' => esc_html( $review['desc'] ),
$args = apply_filters( 'wp_review_get_schema_review_rating_args', $args, $review );
$output = '<script type="application/ld+json">' . PHP_EOL;
$output .= wp_json_encode( $args, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) . PHP_EOL;
$output .= '</script>' . PHP_EOL;
return apply_filters( 'wp_review_get_schema_review_rating', $output, $args, $review );
* Gets schema for user rating.
* @param array $review Review data.
* @param bool $nested_item Is nested item or not.
function wp_review_get_schema_user_rating( $review, $nested_item = false ) {
if ( ! $nested_item && in_array( $review['schema'], apply_filters( 'wp_review_schema_force_nested_user_rating_types', array( 'SoftwareApplication', 'Recipe' ) ) ) ) {
return; // Requires nested aggregateRating.
$rating_types = wp_review_get_rating_types();
$item_reviewed = wp_review_get_schema_nested_item_args( $review );
'name' => esc_html( wp_review_get_reviewed_item_name( $review ) ),
if ( 'comments' === $review['rating_schema'] ) {
$comment_reviews = mts_get_post_comments_reviews( $review['post_id'] );
$total = $comment_reviews['rating'];
$count = $comment_reviews['count'];
$total = $review['user_review_total'];
$count = $review['user_review_count'];
if ( 0 < (int) $count ) {
'@context' => 'http://schema.org',
'@type' => 'aggregateRating',
'itemReviewed' => $item_reviewed,
'bestRating' => $rating_types[ $review['user_review_type'] ]['max'],
$args = apply_filters( 'wp_review_get_schema_user_rating_args', $args, $review );
if ( ! empty( $args ) ) {
$output .= '<script type="application/ld+json">' . PHP_EOL;
$output .= wp_json_encode( $args, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) . PHP_EOL;
$output .= '</script>' . PHP_EOL;
return apply_filters( 'wp_review_get_schema_user_rating', $output, $args, $review );
* Gets reviewed item name.
* @param array $review Review data.
function wp_review_get_reviewed_item_name( $review ) {
$item_reviewed = empty( $review['heading'] ) ? get_the_title( $review['post_id'] ) : esc_html( $review['heading'] );
if ( ! empty( $review['schema'] ) && 'Thing' !== $review['schema'] ) {
if ( isset( $review['schema_data'][ $review['schema'] ]['name'] ) && ! empty( $review['schema_data'][ $review['schema'] ]['name'] ) ) {
$item_reviewed = $review['schema_data'][ $review['schema'] ]['name'];
return apply_filters( 'wp_review_get_reviewed_item_name', $item_reviewed, $review );
* Gets schema nested user rating args.
* @param array $review Review data.
function wp_review_get_schema_nested_user_rating_args( $review ) {
$rating_types = wp_review_get_rating_types();
if ( 'comments' === $review['rating_schema'] ) {
$comment_reviews = mts_get_post_comments_reviews( $review['post_id'] );
$comments_review_total = $comment_reviews['rating'];
$comments_review_count = $comment_reviews['count'];
if ( 0 < (int) $comments_review_count ) {
'@type' => 'aggregateRating',
'ratingValue' => wp_review_normalize_rating_value( $comments_review_total ),
'bestRating' => $rating_types[ $review['user_review_type'] ]['max'],
'ratingCount' => $comments_review_count,
if ( 0 < (int) $review['user_review_count'] ) {
'@type' => 'aggregateRating',
'ratingValue' => wp_review_normalize_rating_value( $review['user_review_total'] ),
'bestRating' => $rating_types[ $review['user_review_type'] ]['max'],
'ratingCount' => $review['user_review_count'],
return apply_filters( 'wp_review_get_schema_nested_user_rating_args', $args, $review );
* Gets schema nested review args.
* @param array $review Review data.
function wp_review_get_schema_nested_review_args( $review ) {
if ( ! boolval( $review['total'] ) ) {
return apply_filters( 'wp_review_get_schema_nested_review_args', array(), $review );
$rating_types = wp_review_get_rating_types();
'ratingValue' => wp_review_normalize_rating_value( $review['total'] ),
'bestRating' => $rating_types[ $review['type'] ]['max'],
'name' => esc_html( $review['author'] ),
'reviewBody' => esc_html( $review['desc'] ),
return apply_filters( 'wp_review_get_schema_nested_review_args', $args, $review );
* Gets schema nested item args.
* @param array $review Review data.
function wp_review_get_schema_nested_item_args( $review ) {
'@type' => $review['schema'],
$schema_data = ! empty( $review['schema_data'][ $review['schema'] ] ) ? $review['schema_data'][ $review['schema'] ] : array();
$ldjson_data = wp_review_get_ldjson_data( $review['schema'], $schema_data, $review );
$schemas = wp_review_schema_types();
$fields = isset( $schemas[ $review['schema'] ] ) && isset( $schemas[ $review['schema'] ]['fields'] ) ? $schemas[ $review['schema'] ]['fields'] : array();
if ( is_array( $fields ) && ! empty( $fields ) ) {
foreach ( $fields as $key => $data ) {
if ( ! empty( $data['omit'] ) ) {
if ( isset( $schema_data[ $data['name'] ] ) && ! empty( $schema_data[ $data['name'] ] ) ) {
$value = $schema_data[ $data['name'] ];
$name = ! empty( $data['custom_name'] ) ? strip_tags( $data['custom_name'] ) : $data['name'];