generate_sitemap();
// Cache for 12 hours
set_transient('shadowsync_seo_sitemap_cache', $xml, 12 * HOUR_IN_SECONDS);
header('Content-Type: application/xml; charset=utf-8');
// See note above: every dynamic value is escaped in build_url().
echo $xml; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
exit;
}
private function generate_sitemap() {
$posts = get_posts([
'numberposts' => -1,
'post_status' => 'publish',
'post_type' => ['post', 'page'],
]);
$xml = '' . "\n";
$xml .= '' . "\n";
// Homepage
$xml .= $this->build_url(home_url('/'), '1.0', 'daily');
foreach ($posts as $post) {
$url = get_permalink($post->ID);
$modified = get_post_modified_time('c', true, $post->ID);
$priority = $post->post_type === 'page' ? '0.8' : '0.6';
$xml .= $this->build_url($url, $priority, 'weekly', $modified);
}
// Add public taxonomy archives
$categories = get_categories(['hide_empty' => true]);
foreach ($categories as $cat) {
$xml .= $this->build_url(get_category_link($cat->term_id), '0.5', 'weekly');
}
$xml .= '';
return $xml;
}
private function build_url($url, $priority = '0.5', $changefreq = 'weekly', $lastmod = '') {
$out = " \n";
$out .= " " . esc_url($url) . "\n";
if ($lastmod) {
$out .= " " . esc_html($lastmod) . "\n";
}
$out .= " " . esc_html($changefreq) . "\n";
$out .= " " . esc_html($priority) . "\n";
$out .= " \n";
return $out;
}
public function clear_sitemap_cache() {
delete_transient('shadowsync_seo_sitemap_cache');
}
public function flush_rewrite_rules() {
check_ajax_referer( 'shadowsync_seo_scan_nonce', 'nonce' );
ShadowSync_SEO_Security::require_admin();
flush_rewrite_rules();
wp_send_json_success(['message' => 'Sitemap rewrite rules flushed.']);
}
}