languages = $languages;
$this->mapping = $mapping;
$this->router = $router;
}
/**
* Register hooks.
*
* @return void
*/
public function init() {
add_action( 'wp_head', array( $this, 'output_hreflang' ), 2 );
add_action( 'wp_head', array( $this, 'output_canonical' ), 3 );
add_filter( 'wp_sitemaps_posts_query_args', array( $this, 'sitemap_query_args' ), 10, 2 );
}
/**
* Output hreflang alternates.
*
* @return void
*/
public function output_hreflang() {
if ( is_admin() || ! is_singular() ) {
return;
}
$post_id = get_queried_object_id();
$root_id = $this->mapping->get_root_id( $post_id );
$all = $this->languages->get_all();
$default = $this->languages->get_default_code();
$has_self = false;
foreach ( $all as $code => $language ) {
$url = '';
if ( $code === $default ) {
$url = get_permalink( $root_id );
} else {
$translation_id = $this->mapping->get_ready_translation_id( $root_id, $code );
if ( $translation_id ) {
$url = get_permalink( $translation_id );
}
}
if ( ! $url ) {
continue;
}
$has_self = true;
printf(
'' . "\n",
esc_attr( str_replace( '_', '-', $code ) ),
esc_url( $url )
);
}
if ( $has_self ) {
printf(
'' . "\n",
esc_url( get_permalink( $root_id ) )
);
}
}
/**
* Output canonical for translated pages.
*
* @return void
*/
public function output_canonical() {
if ( is_admin() || ! is_singular() ) {
return;
}
$post_id = get_queried_object_id();
if ( ! $post_id ) {
return;
}
printf( '' . "\n", esc_url( get_permalink( $post_id ) ) );
}
/**
* Keep default sitemap from listing translation drafts/private content.
*
* Published translations remain in the normal sitemap with their prefixed URLs
* because permalink filters are applied by core sitemap generation.
*
* @param array $args Query args.
* @param string $post_type Post type.
* @return array
*/
public function sitemap_query_args( $args, $post_type ) {
if ( ! in_array( $post_type, array( 'page', 'post', 'product' ), true ) ) {
return $args;
}
$args['post_status'] = array( 'publish' );
return $args;
}
}