mod' => $query->have_posts() ? $query->posts[0]->post_modified_gmt : $last_modified_gmt, ], 'term', $tax_name, ); if ( ! $item ) { continue; } $index[] = $item; } } return $index; } /** * Get set of sitemap link data. * * @param string $type Sitemap type. * @param int $max_entries Entries per sitemap. * @param int $current_page Current page of the sitemap. * @return array */ public function get_sitemap_links( $type, $max_entries, $current_page ) { $links = []; $taxonomy = get_taxonomy( $type ); $terms = $this->get_terms( $taxonomy, $max_entries, $current_page ); Sitemap::maybe_redirect( count( $this->get_terms( $taxonomy, 0, $current_page ) ), $max_entries ); foreach ( $terms as $term ) { $url = []; if ( ! Sitemap::is_object_indexable( $term, 'term' ) ) { continue; } $link = $this->get_term_link( $term ); if ( ! $link ) { continue; } $url['loc'] = $link; $url['mod'] = $this->get_lastmod( $term ); $url['images'] = ! is_null( $this->get_image_parser() ) ? $this->get_image_parser()->get_term_images( $term ) : []; /** This filter is documented at inc/sitemaps/class-post-type-sitemap-provider.php */ $url = $this->do_filter( 'sitemap/entry', $url, 'term', $term ); if ( ! empty( $url ) ) { $links[] = $url; } } return $links; } /** * Get the Image Parser. * * @return Image_Parser */ protected function get_image_parser() { if ( class_exists( 'RankMath\Sitemap\Image_Parser' ) && ! isset( self::$image_parser ) ) { self::$image_parser = new Image_Parser(); } return self::$image_parser; } /** * Get terms for taxonomy. * * @param object $taxonomy Taxonomy name. * @param int $max_entries Entries per sitemap. * @param int $current_page Current page of the sitemap. * @return false|array */ private function get_terms( $taxonomy, $max_entries, $current_page ) { $offset = $current_page > 1 ? ( ( $current_page - 1 ) * $max_entries ) : 0; $hide_empty = ! Helper::get_settings( 'sitemap.tax_' . $taxonomy->name . '_include_empty' ); // Getting terms. $terms = get_terms( [ 'taxonomy' => $taxonomy->name, 'orderby' => 'term_order', 'hide_empty' => $hide_empty, 'offset' => $offset, 'number' => $max_entries, 'exclude' => wp_parse_id_list( Helper::get_settings( 'sitemap.exclude_terms' ) ), /* * Limits aren't included in queries when hierarchical is set to true (by default). * * @link: https://github.com/WordPress/WordPress/blob/5.3/wp-includes/class-wp-term-query.php#L558-L567 */ 'hierarchical' => false, 'update_term_meta_cache' => false, 'meta_query' => [ 'relation' => 'OR', [ 'key' => 'rank_math_robots', 'value' => 'noindex', 'compare' => 'NOT LIKE', ], [ 'key' => 'rank_math_robots', 'compare' => 'NOT EXISTS', ], ], ] ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return []; } return $terms; } /** * Get term link. * * @param WP_Term $term Term object. * @return string */ private function get_term_link( $term ) { $url = get_term_link( $term, $term->taxonomy ); $canonical = Helper::get_term_meta( 'canonical_url', $term, $term->taxonomy ); if ( $canonical && $canonical !== $url ) { /* * Let's assume that if a canonical is set for this term and it's different from * the URL of this term, that page is either already in the XML sitemap OR is on * an external site, either way, we shouldn't include it here. */ return false; } return $url; } /** * Get last modified date of post by term. * * @param WP_Term $term Term object. * @return string */ public function get_lastmod( $term ) { global $wpdb; return $wpdb->get_var( $wpdb->prepare( " SELECT MAX(p.post_modified_gmt) AS lastmod FROM $wpdb->posts AS p INNER JOIN $wpdb->term_relationships AS term_rel ON term_rel.object_id = p.ID INNER JOIN $wpdb->term_taxonomy AS term_tax ON term_tax.term_taxonomy_id = term_rel.term_taxonomy_id AND term_tax.taxonomy = %s AND term_tax.term_id = %d WHERE p.post_status IN ('publish', 'inherit') AND p.post_password = '' ", $term->taxonomy, $term->term_id ) ); } }