You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
517 lines
19 KiB
PHTML
517 lines
19 KiB
PHTML
8 months ago
|
<?php
|
||
|
/**
|
||
|
* The SERP preview functionality, in the metabox.
|
||
|
*
|
||
|
* @since 0.9.0
|
||
|
* @package RankMath
|
||
|
* @subpackage RankMath\Admin
|
||
|
* @author Rank Math <support@rankmath.com>
|
||
|
*/
|
||
|
|
||
|
namespace RankMath\Admin;
|
||
|
|
||
|
use RankMath\CMB2;
|
||
|
use RankMath\Helper;
|
||
|
use RankMath\Helpers\Param;
|
||
|
use RankMath\Rewrite;
|
||
|
use RankMath\Schema\DB;
|
||
|
|
||
|
defined( 'ABSPATH' ) || exit;
|
||
|
|
||
|
/**
|
||
|
* Serp_Preview class.
|
||
|
*/
|
||
|
class Serp_Preview {
|
||
|
|
||
|
/**
|
||
|
* Display SERP preview.
|
||
|
*/
|
||
|
public function display() {
|
||
|
$method = 'get_' . CMB2::current_object_type() . '_data';
|
||
|
$data = $this->$method();
|
||
|
if ( 'post' === CMB2::current_object_type() && Helper::is_module_active( 'rich-snippet' ) ) {
|
||
|
$snippet_preview = $this->get_snippet_html();
|
||
|
}
|
||
|
$favicon = esc_url( get_site_icon_url( 16 ) );
|
||
|
if ( empty( $favicon ) ) {
|
||
|
$favicon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR4AWL4//8/RRjO8Iucx+noO0MWUDo16FYABMGP6ZfUcRnWtm27jVPbtm3bttuH2t3eFPcY9pLz7NxiLjCyVd87pKnHyqXyxtCs8APd0rnyxiu4qSeA3QEDrAwBDrT1s1Rc/OrjLZwqVmOSu6+Lamcpp2KKMA9PH1BYXMe1mUP5qotvXTywsOEEYHXxrY+3cqk6TMkYpNr2FeoY3KIr0RPtn9wQ2unlA+GMkRw6+9TFw4YTwDUzx/JVvARj9KaedXRO8P5B1Du2S32smzqUrcKGEyA+uAgQjKX7zf0boWHGfn71jIKj2689gxp7OAGShNcBUmLMPVjZuiKcA2vuWHHDCQxMCz629kXAIU4ApY15QwggAFbfOP9DhgBJ+nWVJ1AZAfICAj1pAlY6hCADZnveQf7bQIwzVONGJonhLIlS9gr5mFg44Xd+4S3XHoGNPdJl1INIwKyEgHckEhgTe1bGiFY9GSFBYUwLh1IkiJUbY407E7syBSFxKTszEoiE/YdrgCEayDmtaJwCI9uu8TKMuZSVfSa4BpGgzvomBR/INhLGzrqDotp01ZR8pn/1L0JN9d9XNyx0AAAAAElFTkSuQmCC';
|
||
|
}
|
||
|
$snippet_type = isset( $snippet_preview['type'] ) ? $snippet_preview['type'] : '';
|
||
|
$desktop_preview = isset( $snippet_preview['desktop'] ) ? $snippet_preview['desktop'] : '';
|
||
|
$mobile_preview = isset( $snippet_preview['mobile'] ) ? $snippet_preview['mobile'] : '';
|
||
|
?>
|
||
|
<div class="serp-preview desktop-preview serp-<?php echo esc_attr( $snippet_type ); ?>">
|
||
|
|
||
|
<div class="serp-preview-title" data-title="<?php esc_attr_e( 'Preview', 'rank-math' ); ?>" data-desktop="<?php esc_attr_e( 'Desktop Preview', 'rank-math' ); ?>" data-mobile="<?php esc_attr_e( 'Mobile Preview', 'rank-math' ); ?>">
|
||
|
<div class="alignright">
|
||
|
<a href="#" class="button button-secondary button-small rank-math-select-device device-desktop" data-device="desktop"><span class="rm-icon rm-icon-desktop"></span></a>
|
||
|
<a href="#" class="button button-secondary button-small rank-math-select-device device-mobile" data-device="mobile"><span class="rm-icon rm-icon-mobile"></span></a>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="serp-preview-wrapper">
|
||
|
<div class="serp-preview-bg">
|
||
|
<div class="serp-preview-input">
|
||
|
<input type="text" value="Rank Math" disabled />
|
||
|
<span class="serp-search">
|
||
|
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg>
|
||
|
</span>
|
||
|
<span class="serp-mic"></span>
|
||
|
</div>
|
||
|
<div class="serp-preview-menus">
|
||
|
<ul>
|
||
|
<li class="current"> <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgweiIvPjxwYXRoIGZpbGw9IiMzNEE4NTMiIGQ9Ik0xMCAydjJhNiA2IDAgMCAxIDYgNmgyYTggOCAwIDAgMC04LTh6Ii8+PHBhdGggZmlsbD0iI0VBNDMzNSIgZD0iTTEwIDRWMmE4IDggMCAwIDAtOCA4aDJjMC0zLjMgMi43LTYgNi02eiIvPjxwYXRoIGZpbGw9IiNGQkJDMDQiIGQ9Ik00IDEwSDJhOCA4IDAgMCAwIDggOHYtMmMtMy4zIDAtNi0yLjY5LTYtNnoiLz48cGF0aCBmaWxsPSIjNDI4NUY0IiBkPSJNMjIgMjAuNTlsLTUuNjktNS42OUE3Ljk2IDcuOTYgMCAwIDAgMTggMTBoLTJhNiA2IDAgMCAxLTYgNnYyYzEuODUgMCAzLjUyLS42NCA0Ljg4LTEuNjhsNS42OSA1LjY5TDIyIDIwLjU5eiIvPjwvc3ZnPgo=" alt="" data-atf="1"> All</li>
|
||
|
<li><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"></path><path d="M14 13l4 5H6l4-4 1.79 1.78L14 13zm-6.01-2.99A2 2 0 0 0 8 6a2 2 0 0 0-.01 4.01zM22 5v14a3 3 0 0 1-3 2.99H5c-1.64 0-3-1.36-3-3V5c0-1.64 1.36-3 3-3h14c1.65 0 3 1.36 3 3zm-2.01 0a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h7v-.01h7a1 1 0 0 0 1-1V5z"></path></svg> Images</li>
|
||
|
<li><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 0h24v24H0z" fill="none"></path><path clip-rule="evenodd" d="M10 16.5l6-4.5-6-4.5v9zM5 20h14a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1zm14.5 2H5a3 3 0 0 1-3-3V4.4A2.4 2.4 0 0 1 4.4 2h15.2A2.4 2.4 0 0 1 22 4.4v15.1a2.5 2.5 0 0 1-2.5 2.5z" fill-rule="evenodd"></path></svg> Videos</li>
|
||
|
<li><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"></path><path d="M12 11h6v2h-6v-2zm-6 6h12v-2H6v2zm0-4h4V7H6v6zm16-7.22v12.44c0 1.54-1.34 2.78-3 2.78H5c-1.64 0-3-1.25-3-2.78V5.78C2 4.26 3.36 3 5 3h14c1.64 0 3 1.25 3 2.78zM19.99 12V5.78c0-.42-.46-.78-1-.78H5c-.54 0-1 .36-1 .78v12.44c0 .42.46.78 1 .78h14c.54 0 1-.36 1-.78V12zM12 9h6V7h-6v2z"></path></svg> News</li>
|
||
|
<li><svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></svg> More</li>
|
||
|
</ul>
|
||
|
<ul class="menus-right">
|
||
|
<li>Settings</li>
|
||
|
<li>Tools</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="serp-preview-result-stats">
|
||
|
About 43,700,000 results (0.32 seconds)
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="serp-preview-body">
|
||
|
<div class="serp-url-wrapper">
|
||
|
<img src="<?php echo $favicon; // phpcs:ignore ?>" width="16" height="16" class="serp-favicon" />
|
||
|
<span class="serp-url" data-baseurl="<?php echo trailingslashit( substr( $data['url'], 0, strrpos( $data['url'], '/' ) ) ); ?>" data-format="<?php echo esc_attr( $data['permalink_format'] ); ?>" data-empty-title="<?php esc_attr_e( 'Click to enter permalink', 'rank-math' ); ?>"><?php echo esc_url( $data['permalink'] ); ?></span>
|
||
|
</div>
|
||
|
<h5 class="serp-title" data-format="<?php echo esc_attr( $data['title_format'] ); ?>" data-empty-title="<?php esc_attr_e( 'Click to enter custom title', 'rank-math' ); ?>"></h5>
|
||
|
|
||
|
<p class="serp-description" data-format="<?php echo esc_attr( $data['desc_format'] ); ?>" data-empty-title="<?php esc_attr_e( 'Click to enter custom meta description', 'rank-math' ); ?>"></p>
|
||
|
|
||
|
<?php
|
||
|
if ( 'event' !== $snippet_type ) {
|
||
|
echo $desktop_preview; // phpcs:ignore
|
||
|
}
|
||
|
|
||
|
if ( 'event' === $snippet_type ) {
|
||
|
echo $desktop_preview; // phpcs:ignore
|
||
|
}
|
||
|
|
||
|
echo $mobile_preview; // phpcs:ignore
|
||
|
?>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<div class="serp-preview-noindex">
|
||
|
<h3><?php esc_html_e( 'Noindex robots meta is enabled', 'rank-math' ); ?></h3>
|
||
|
<p><?php esc_html_e( 'This page will not appear in search results. You can disable noindex in the Advanced tab.', 'rank-math' ); ?></p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get post data for SERP preview.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_post_data() {
|
||
|
global $post;
|
||
|
setup_postdata( $post );
|
||
|
|
||
|
$post_type = Helper::get_post_type();
|
||
|
$title_format = Helper::get_settings( "titles.pt_{$post_type}_title" );
|
||
|
$desc_format = Helper::get_settings( "titles.pt_{$post_type}_description" );
|
||
|
$title_format = $title_format ? $title_format : '%title%';
|
||
|
|
||
|
// Get the permalink.
|
||
|
list( $permalink_format ) = get_sample_permalink( $post->ID, null, null );
|
||
|
|
||
|
$permalink = $permalink_format;
|
||
|
if ( 'publish' === $post->post_status || 'attachment' === $post->post_type ) {
|
||
|
$permalink = get_permalink( $post );
|
||
|
} elseif ( 'auto-draft' === $post->post_status && 'post' === $post->post_type ) {
|
||
|
$post_temp = $post;
|
||
|
$post_temp->post_status = 'publish';
|
||
|
$permalink = get_permalink( $post_temp, true );
|
||
|
$permalink_format = $permalink;
|
||
|
$post_temp->post_status = 'auto-draft';
|
||
|
} else {
|
||
|
$permalink = str_replace( [ '%pagename%', '%postname%' ], ( $post->post_name ? $post->post_name : sanitize_title( $post->post_title ) ), $permalink_format );
|
||
|
}
|
||
|
|
||
|
$url = untrailingslashit( esc_url( $permalink ) );
|
||
|
|
||
|
return compact( 'title_format', 'desc_format', 'url', 'permalink', 'permalink_format' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get term data for SERP preview.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_term_data() {
|
||
|
global $taxnow, $wp_rewrite;
|
||
|
|
||
|
$term_id = Param::request( 'tag_ID', 0, FILTER_VALIDATE_INT );
|
||
|
$term = get_term( $term_id, $taxnow, OBJECT, 'edit' );
|
||
|
$taxonomy = get_taxonomy( $term->taxonomy );
|
||
|
|
||
|
$title_format = Helper::get_settings( "titles.tax_{$term->taxonomy}_title" );
|
||
|
$desc_format = Helper::get_settings( "titles.tax_{$term->taxonomy}_description" );
|
||
|
$title_format = $title_format ? $title_format : '%term%';
|
||
|
|
||
|
// Get the permalink.
|
||
|
$permalink = untrailingslashit( esc_url( get_term_link( $term_id, $term->taxonomy ) ) );
|
||
|
$termlink = $wp_rewrite->get_extra_permastruct( $term->taxonomy );
|
||
|
|
||
|
// Pretty permalinks disabled.
|
||
|
if ( empty( $termlink ) ) {
|
||
|
$permalink_format = $permalink;
|
||
|
} else {
|
||
|
$termlink = str_replace( $this->get_home_url(), '', $permalink );
|
||
|
$termlink = str_replace( $term->slug, '%postname%', $termlink );
|
||
|
$permalink_format = $this->get_home_url( user_trailingslashit( $termlink, 'category' ) );
|
||
|
}
|
||
|
|
||
|
$url = untrailingslashit( esc_url( $permalink ) );
|
||
|
|
||
|
return compact( 'title_format', 'desc_format', 'url', 'permalink', 'permalink_format' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Home URL based on the language if Polylang plugin is active.
|
||
|
*
|
||
|
* @param string $path Optional. Path relative to the home URL. Default empty.
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
private function get_home_url( $path = '' ) {
|
||
|
if ( ! function_exists( 'pll_home_url' ) ) {
|
||
|
return Helper::get_home_url( $path );
|
||
|
}
|
||
|
|
||
|
return trailingslashit( pll_home_url() ) . $path;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get user data for SERP preview.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_user_data() {
|
||
|
global $user_id, $wp_rewrite;
|
||
|
|
||
|
$title_format = Helper::get_settings( 'titles.author_archive_title' );
|
||
|
$desc_format = Helper::get_settings( 'titles.author_archive_description' );
|
||
|
$title_format = $title_format ? $title_format : '%author%';
|
||
|
|
||
|
Rewrite::change_author_base();
|
||
|
$permalink = untrailingslashit( esc_url( get_author_posts_url( $user_id ) ) );
|
||
|
$link = $wp_rewrite->get_author_permastruct();
|
||
|
$permalink_format = empty( $link ) ? $permalink : $this->get_author_permalink( $link );
|
||
|
$url = untrailingslashit( esc_url( $permalink ) );
|
||
|
|
||
|
return compact( 'title_format', 'desc_format', 'url', 'permalink', 'permalink_format' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get user permalink
|
||
|
*
|
||
|
* @param string $link Permalink structure.
|
||
|
* @return string
|
||
|
*/
|
||
|
private function get_author_permalink( $link ) {
|
||
|
$link = str_replace( '%author%', '%postname%', $link );
|
||
|
return home_url( user_trailingslashit( $link ) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Snippet HTML for SERP preview.
|
||
|
*/
|
||
|
private function get_snippet_html() {
|
||
|
$snippet_data = $this->get_snippet_data();
|
||
|
if ( ! $snippet_data || empty( $snippet_data['data'] ) ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$data = $snippet_data['data'];
|
||
|
$rating = isset( $data['rating'] ) ? $data['rating'] : '';
|
||
|
$rating_count = isset( $data['rating_count'] ) ? $data['rating_count'] : '';
|
||
|
unset( $data['rating'] );
|
||
|
unset( $data['rating_count'] );
|
||
|
|
||
|
if ( isset( $data['price'] ) && isset( $data['currency'] ) ) {
|
||
|
$data['price'] = $data['currency'] . ' ' . $data['price'];
|
||
|
unset( $data['currency'] );
|
||
|
}
|
||
|
|
||
|
$html = [
|
||
|
'type' => $snippet_data['type'],
|
||
|
'desktop' => $this->get_desktop_preview( $data, $rating, $rating_count ),
|
||
|
'mobile' => $this->get_mobile_preview( $data, $rating, $rating_count ),
|
||
|
];
|
||
|
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get desktop preview.
|
||
|
*
|
||
|
* @param array $data Snippet data array.
|
||
|
* @param int $rating Ratings.
|
||
|
* @param int $rating_count Rating count.
|
||
|
* @return string
|
||
|
*/
|
||
|
private function get_desktop_preview( $data, $rating, $rating_count ) {
|
||
|
$preview = '';
|
||
|
$labels = [
|
||
|
'price_range' => esc_html__( 'Price range: ', 'rank-math' ),
|
||
|
'calories' => esc_html__( 'Calories: ', 'rank-math' ),
|
||
|
];
|
||
|
|
||
|
if ( $rating ) {
|
||
|
$preview .= $this->get_ratings( $rating );
|
||
|
/* translators: total reviews */
|
||
|
$preview .= '<span class="serp-rating-label">' . sprintf( esc_html__( 'Rating: %s', 'rank-math' ), esc_html( $rating ) ) . '</span>';
|
||
|
if ( $rating_count ) {
|
||
|
/* translators: total reviews */
|
||
|
$preview .= '<span class="serp-review-count"> - ' . sprintf( esc_html__( '%s reviews', 'rank-math' ), esc_html( $rating_count ) ) . '</span>';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
foreach ( $data as $key => $value ) {
|
||
|
if ( ! $value || in_array( $key, [ 'min', 'max' ], true ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( ! in_array( $key, [ 'event_date', 'event_place', 'event_name' ], true ) ) {
|
||
|
$preview .= '<span class="separator"> - </span>';
|
||
|
}
|
||
|
|
||
|
$preview .= '<span class="serp-' . $key . '">';
|
||
|
if ( isset( $labels[ $key ] ) ) {
|
||
|
$preview .= $labels[ $key ];
|
||
|
}
|
||
|
|
||
|
$preview .= $value;
|
||
|
|
||
|
$preview .= '</span>';
|
||
|
}
|
||
|
|
||
|
return '<div class="serp-snippet-data">' . $preview . '</div>';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get mobile preview.
|
||
|
*
|
||
|
* @param array $data Snippet data array.
|
||
|
* @param int $rating Ratings.
|
||
|
* @param int $rating_count Rating count.
|
||
|
* @return string
|
||
|
*/
|
||
|
private function get_mobile_preview( $data, $rating, $rating_count ) {
|
||
|
$labels = [
|
||
|
'price' => esc_html__( 'Price', 'rank-math' ),
|
||
|
'price_range' => esc_html__( 'Price range', 'rank-math' ),
|
||
|
'time' => esc_html__( 'Cooking time', 'rank-math' ),
|
||
|
'calories' => esc_html__( 'Calories', 'rank-math' ),
|
||
|
'in_stock' => esc_html__( 'In Stock', 'rank-math' ),
|
||
|
'event_date' => esc_html__( 'Date', 'rank-math' ),
|
||
|
'event_place' => esc_html__( 'Location', 'rank-math' ),
|
||
|
];
|
||
|
|
||
|
$preview = '';
|
||
|
if ( $rating ) {
|
||
|
$preview .= '<span class="inner-wrapper">';
|
||
|
$preview .= '<span class="serp-mobile-label">';
|
||
|
$preview .= esc_html__( 'Rating', 'rank-math' );
|
||
|
$preview .= '</span>';
|
||
|
$preview .= '<span class="serp-rating-count">' . esc_html( $rating ) . '</span>';
|
||
|
|
||
|
$preview .= $this->get_ratings( $rating );
|
||
|
|
||
|
if ( $rating_count ) {
|
||
|
$preview .= '<span class="serp-review-count">(' . esc_html( $rating_count ) . ')</span>';
|
||
|
}
|
||
|
|
||
|
$preview .= '</span>';
|
||
|
}
|
||
|
|
||
|
foreach ( $data as $key => $value ) {
|
||
|
if ( ! $value || in_array( $key, [ 'event_name', 'min', 'max' ], true ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$preview .= '<span class="inner-wrapper">';
|
||
|
|
||
|
if ( isset( $labels[ $key ] ) ) {
|
||
|
$preview .= '<span class="serp-mobile-label">';
|
||
|
$preview .= $labels[ $key ];
|
||
|
$preview .= '</span>';
|
||
|
}
|
||
|
|
||
|
if ( 'in_stock' !== $key ) {
|
||
|
$preview .= '<span class="serp-' . $key . '">' . esc_html( $value ) . '</span>';
|
||
|
}
|
||
|
|
||
|
$preview .= '</span>';
|
||
|
}
|
||
|
|
||
|
return '<div class="serp-snippet-mobile">' . $preview . '</div>';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Star Ratings.
|
||
|
*
|
||
|
* @param int $rating Rating count.
|
||
|
*/
|
||
|
private function get_ratings( $rating ) {
|
||
|
$html = '';
|
||
|
$rating = $rating * 20;
|
||
|
|
||
|
for ( $i = 1; $i <= 5; $i++ ) {
|
||
|
$html .= '<span class="dashicons dashicons-star-filled"></span>';
|
||
|
}
|
||
|
|
||
|
$html .= '<div class="serp-result" style="width:' . $rating . '%;">';
|
||
|
for ( $i = 1; $i <= 5; $i++ ) {
|
||
|
$html .= '<span class="dashicons dashicons-star-filled"></span>';
|
||
|
}
|
||
|
|
||
|
return '<span class="serp-rating serp-desktop-rating"><div class="serp-star-rating">' . $html . '</div></div></span>';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Snippet Data for SERP preview.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_snippet_data() {
|
||
|
global $post;
|
||
|
setup_postdata( $post );
|
||
|
|
||
|
$schemas = array_filter(
|
||
|
DB::get_schemas( $post->ID ),
|
||
|
function( $schema ) {
|
||
|
return ! empty( $schema['metadata']['isPrimary'] );
|
||
|
}
|
||
|
);
|
||
|
if ( empty( $schemas ) ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get rich snippet.
|
||
|
$schema = current( $schemas );
|
||
|
$snippet = strtolower( $schema['@type'] );
|
||
|
$method = "get_{$snippet}_data";
|
||
|
|
||
|
return [
|
||
|
'type' => $snippet,
|
||
|
'data' => method_exists( $this, $method ) ? $this->$method( $schema ) : $this->get_ratings_data( $schema ),
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get WooCommerce Product schema data.
|
||
|
*
|
||
|
* @param array $schema Schema Data.
|
||
|
* @return array Preview Schema Data.
|
||
|
*/
|
||
|
private function get_woocommerceproduct_data( $schema ) {
|
||
|
if ( ! Helper::is_woocommerce_active() ) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
global $post;
|
||
|
$product = wc_get_product( $post->ID );
|
||
|
return [
|
||
|
'price' => $product->get_price(),
|
||
|
'currency' => get_woocommerce_currency_symbol(),
|
||
|
'in_stock' => 'outofstock' === $product->get_stock_status() ? esc_html__( 'Out of stock', 'rank-math' ) : __( 'In stock', 'rank-math' ),
|
||
|
'rating' => $product->get_average_rating(),
|
||
|
'rating_count' => (string) $product->get_rating_count(),
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Product schema data.
|
||
|
*
|
||
|
* @param array $schema Schema Data.
|
||
|
* @return array Preview Schema Data.
|
||
|
*/
|
||
|
private function get_product_data( $schema ) {
|
||
|
$offers = [];
|
||
|
if ( isset( $schema['offers'] ) ) {
|
||
|
$offers = [
|
||
|
'price' => isset( $schema['offers']['price'] ) ? $schema['offers']['price'] : '',
|
||
|
'currency' => isset( $schema['offers']['priceCurrency'] ) ? $schema['offers']['priceCurrency'] : '',
|
||
|
'in_stock' => isset( $schema['offers']['availability'] ) && 'SoldOut' === $schema['offers']['availability'] ? esc_html__( 'Out of stock', 'rank-math' ) : esc_html__( 'In stock', 'rank-math' ),
|
||
|
];
|
||
|
}
|
||
|
|
||
|
return \array_merge(
|
||
|
$offers,
|
||
|
$this->get_ratings_data( $schema )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Event schema data.
|
||
|
*
|
||
|
* @param array $schema Schema Data.
|
||
|
* @return array Preview Schema Data.
|
||
|
*/
|
||
|
private function get_event_data( $schema ) {
|
||
|
global $post;
|
||
|
$address = '';
|
||
|
if ( ! empty( $schema['location']['address'] ) ) {
|
||
|
unset( $schema['location']['address']['@type'] );
|
||
|
$address = implode( ', ', array_filter( $schema['location']['address'] ) );
|
||
|
}
|
||
|
|
||
|
return \array_merge(
|
||
|
[
|
||
|
'event_name' => Helper::replace_vars( $schema['name'], $post ),
|
||
|
'event_date' => ! empty( $schema['startDate'] ) ? date_i18n( 'j M Y', $schema['startDate'] ) : '',
|
||
|
'event_place' => $address,
|
||
|
],
|
||
|
$this->get_ratings_data( $schema )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Recipe schema data.
|
||
|
*
|
||
|
* @param array $schema Schema Data.
|
||
|
* @return array Preview Schema Data.
|
||
|
*/
|
||
|
private function get_recipe_data( $schema ) {
|
||
|
return \array_merge(
|
||
|
[
|
||
|
'time' => ! empty( $schema['totalTime'] ) ? $schema['totalTime'] : '',
|
||
|
'calories' => ! empty( $schema['nutrition'] ) && ! empty( $schema['nutrition']['calories'] ) ? $schema['nutrition']['calories'] : '',
|
||
|
],
|
||
|
$this->get_ratings_data( $schema )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Ratings schema data.
|
||
|
*
|
||
|
* @param array $schema Schema Data.
|
||
|
* @return array Preview Schema Data.
|
||
|
*/
|
||
|
private function get_ratings_data( $schema ) {
|
||
|
$review = isset( $schema['review'] ) && isset( $schema['review']['reviewRating']['ratingValue'] ) ? $schema['review']['reviewRating'] : '';
|
||
|
if ( empty( $review ) ) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
'rating' => $review['ratingValue'],
|
||
|
'min' => ! empty( $review['worstRating'] ) ? $review['worstRating'] : 1,
|
||
|
'max' => ! empty( $review['bestRating'] ) ? $review['bestRating'] : 5,
|
||
|
];
|
||
|
}
|
||
|
}
|