*/ namespace RankMathPro\Sitemap; use RankMath\KB; use RankMath\Helper; use RankMath\Traits\Hooker; use RankMath\Sitemap\Router; use RankMath\Sitemap\Cache_Watcher; defined( 'ABSPATH' ) || exit; /** * Video_Sitemap class. */ class Video_Sitemap { use Hooker; /** * The Constructor. */ public function __construct() { if ( is_admin() ) { $this->filter( 'rank_math/settings/sitemap', 'add_settings', 11 ); new Video_Metabox(); } if ( ! $this->can_add_sitemap() ) { return; } $this->filter( 'rank_math/sitemap/providers', 'add_provider' ); $this->filter( 'rank_math/sitemap/video_urlset', 'xml_urlset' ); $this->filter( 'rank_math/sitemap/xsl_video', 'sitemap_xsl' ); $this->filter( 'rank_math/sitemap/video_stylesheet_url', 'stylesheet_url' ); $this->filter( 'rank_math/sitemap/video_sitemap_url', 'sitemap_url', 10, 2 ); $this->action( 'transition_post_status', 'status_transition', 10, 3 ); } /** * Add module settings into general optional panel. * * @param array $tabs Array of option panel tabs. * * @return array */ public function add_settings( $tabs ) { $sitemap_url = Router::get_base_url( 'video-sitemap.xml' ); $tabs['video-sitemap'] = [ 'icon' => 'rm-icon rm-icon-video', 'title' => esc_html__( 'Video Sitemap', 'rank-math-pro' ), 'desc' => wp_kses_post( sprintf( __( 'Video Sitemaps give search engines information about video content on your site. More information: Video Sitemaps', 'rank-math-pro' ), KB::get( 'video-sitemap', 'Options Panel Sitemap Video' ) ) ), 'file' => dirname( __FILE__ ) . '/settings-video.php', /* translators: Video Sitemap Url */ 'after_row' => '

' . sprintf( esc_html__( 'Your Video Sitemap index can be found here: %s', 'rank-math-pro' ), '' . $sitemap_url . '' ) . '

', ]; return $tabs; } /** * Add video sitemap provider. * * @param array $providers Sitemap provider registry. */ public function add_provider( $providers ) { $providers[] = new \RankMathPro\Sitemap\Video_Provider(); return $providers; } /** * Produce XML output for video urlset. * * @return string */ public function xml_urlset() { return '' . "\n"; } /** * Stylesheet Url for video. * * @return string */ public function stylesheet_url() { $stylesheet_url = preg_replace( '/(^http[s]?:)/', '', Router::get_base_url( 'video-sitemap.xsl' ) ); return ''; } /** * Stylesheet for Video Sitemap. * * @param string $title Title for stylesheet. */ public function sitemap_xsl( $title ) { require_once 'sitemap-xsl.php'; } /** * Build the `` tag for a given URL. * * @param array $url Array of parts that make up this entry. * @param Renderer $renderer Sitemap renderer class object. * @return string */ public function sitemap_url( $url, $renderer ) { $output = $renderer->newline( '', 1 ); $output .= $renderer->newline( '' . $renderer->encode_url_rfc3986( htmlspecialchars( $url['loc'] ) ) . '', 2 ); if ( ! empty( $url['videos'] ) ) { foreach ( $url['videos'] as $video ) { $date = null; if ( ! empty( $video['publication_date'] ) ) { // Create a DateTime object date in the correct timezone. $date = $renderer->timezone->format_date( $video['publication_date'] ); } $output .= $renderer->newline( '', 2 ); $output .= $renderer->add_cdata( $video['title'], 'video:title', 3 ); $output .= empty( $date ) ? '' : $renderer->newline( '' . htmlspecialchars( $date ) . '', 3 ); $output .= $renderer->add_cdata( $video['description'], 'video:description', 3 ); if ( ! empty( $video['player_loc'] ) ) { $output .= $renderer->newline( '' . esc_url( $video['player_loc'] ) . '', 3 ); } foreach ( [ 'thumbnail_loc', 'content_loc' ] as $prop ) { if ( empty( $video[ $prop ] ) ) { continue; } /** * Filter the video content and thumbnail location: * - rank_math/sitemap/video/thumbnail_loc * - rank_math/sitemap/video/content_loc */ $value = $this->do_filter( "sitemap/video/{$prop}", $video[ $prop ] ); $output .= $renderer->newline( "" . esc_url( $value ) . "", 3 ); } if ( ! empty( $video['tags'] ) ) { $tags = explode( ', ', $video['tags'] ); foreach ( $tags as $tag ) { $output .= $renderer->add_cdata( $tag, 'video:tag', 3 ); } } if ( ! empty( $video['rating'] ) ) { $output .= $renderer->newline( '' . absint( $video['rating'] ) . '', 3 ); } if ( ! empty( $video['duration'] ) ) { $output .= $renderer->newline( '' . esc_html( $video['duration'] ) . '', 3 ); } $output .= $renderer->newline( '' . $video['family_friendly'] . '', 3 ); $output .= $renderer->newline( '' . ent2ncr( esc_html( get_the_author_meta( 'display_name', $url['author'] ) ) ) . '', 3 ); $output .= $renderer->newline( '', 2 ); } } $output .= $renderer->newline( '', 1 ); /** * Filters the output for the sitemap url tag. * * @param string $output The output for the sitemap url tag. * @param array $url The sitemap url array on which the output is based. */ return $this->do_filter( 'sitemap_url', $output, $url ); } /** * Whether to add Video Sitemap. * * @return booleans */ private function can_add_sitemap() { if ( ! Helper::get_settings( 'sitemap.hide_video_sitemap' ) || current_user_can( 'manage_options' ) ) { return true; } return isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/bot|crawl|slurp|spider|mediapartners/i', $_SERVER['HTTP_USER_AGENT'] ); } /** * Invalidate News Sitemap cache when a scheduled post is published. * * @param string $new_status New Status. * @param string $old_status Old Status. * @param object $post Post Object. */ public function status_transition( $new_status, $old_status, $post ) { if ( $old_status === $new_status || 'publish' !== $new_status ) { return; } $post_types = (array) Helper::get_settings( 'sitemap.video_sitemap_post_type', [] ); if ( ! in_array( $post->post_type, $post_types, true ) ) { return; } if ( false === Helper::is_post_indexable( $post->ID ) ) { return; } Cache_Watcher::invalidate( 'video' ); } }