*/ 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'] : ''; ?>
  • All
  • Images
  • Videos
  • News
  • More
About 43,700,000 results (0.32 seconds) 

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 .= '' . sprintf( esc_html__( 'Rating: %s', 'rank-math' ), esc_html( $rating ) ) . ''; if ( $rating_count ) { /* translators: total reviews */ $preview .= ' - ' . sprintf( esc_html__( '%s reviews', 'rank-math' ), esc_html( $rating_count ) ) . ''; } } 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 .= ' - '; } $preview .= ''; if ( isset( $labels[ $key ] ) ) { $preview .= $labels[ $key ]; } $preview .= $value; $preview .= ''; } return '
' . $preview . '
'; } /** * 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 .= ''; $preview .= ''; $preview .= esc_html__( 'Rating', 'rank-math' ); $preview .= ''; $preview .= '' . esc_html( $rating ) . ''; $preview .= $this->get_ratings( $rating ); if ( $rating_count ) { $preview .= '(' . esc_html( $rating_count ) . ')'; } $preview .= ''; } foreach ( $data as $key => $value ) { if ( ! $value || in_array( $key, [ 'event_name', 'min', 'max' ], true ) ) { continue; } $preview .= ''; if ( isset( $labels[ $key ] ) ) { $preview .= ''; $preview .= $labels[ $key ]; $preview .= ''; } if ( 'in_stock' !== $key ) { $preview .= '' . esc_html( $value ) . ''; } $preview .= ''; } return '
' . $preview . '
'; } /** * Get Star Ratings. * * @param int $rating Rating count. */ private function get_ratings( $rating ) { $html = ''; $rating = $rating * 20; for ( $i = 1; $i <= 5; $i++ ) { $html .= ''; } $html .= '
'; for ( $i = 1; $i <= 5; $i++ ) { $html .= ''; } return '
' . $html . '
'; } /** * 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, ]; } }