<?php
class ZP_Seo_Sitemap_Do_Sitemap {
private $sitemap_prefix; // Changed from constant to a variable
private $max_items_per_sitemap;
const SITEMAP_ZPTHEME = 'zptheme_sitemap'; // 定义常量用于AJAX动作前缀
function __construct() {
// 获取配置项
$settings = get_option('zptheme_seo_sitemap_settings', array());
$this->sitemap_prefix = isset($settings['sitemap_prefix']) ? $settings['sitemap_prefix'] : 'sitemap'; // 默认值为'sitemap'
$this->max_items_per_sitemap = isset($settings['max_items']) ? (int)$settings['max_items'] : 2000; // 默认值为2000
// 注册AJAX处理钩子
add_action('wp_ajax_' . self::SITEMAP_ZPTHEME . '_do_sitemap', array($this, 'ajax_do_sitemap'));
add_action('wp_ajax_' . self::SITEMAP_ZPTHEME . '_delete_sitemap', array($this, 'ajax_delete_sitemap'));
add_action('transition_post_status', array($this, 'publish_do_xml'), 999, 3);
// 在后台添加脚本
add_action('admin_footer', array($this, 'sitemap_jquery'));
}
// 输出前端JavaScript
public function sitemap_jquery() {
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#generate-sitemap').click(function(){
$('#sitemap-progress').html('<?php _e('正在生成,请稍后...', 'textdomain'); ?>');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: '<?php echo self::SITEMAP_ZPTHEME; ?>_do_sitemap',
nonce: '<?php echo wp_create_nonce(self::SITEMAP_ZPTHEME . '_do_sitemap'); ?>'
},
success: function(res) {
$('#sitemap-progress').html('');
$('.wrap').prepend(res);
location.reload(); // 刷新显示最新文件信息
},
error: function() {
$('#sitemap-progress').html('<div class="error"><?php _e('请求失败,请重试', 'textdomain'); ?></div>');
}
});
});
$('#delete-sitemap').click(function(){
if(!confirm('<?php _e('确定要删除所有Sitemap文件吗?', 'textdomain'); ?>')) return;
$('#sitemap-progress').html('<?php _e('正在删除,请稍后...', 'textdomain'); ?>');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: '<?php echo self::SITEMAP_ZPTHEME; ?>_delete_sitemap',
nonce: '<?php echo wp_create_nonce(self::SITEMAP_ZPTHEME . '_delete_sitemap'); ?>'
},
success: function(res) {
$('#sitemap-progress').html('');
$('.wrap').prepend(res);
location.reload();
}
});
});
});
</script>
<?php
}
// AJAX生成Sitemap
public function ajax_do_sitemap() {
check_ajax_referer(self::SITEMAP_ZPTHEME . '_do_sitemap', 'nonce');
try {
$this->clean_old_sitemaps();
$this->generate_all_sitemaps();
$this->submit_sitemap_to_engines();
$this->show_success_message();
} catch (Exception $e) {
$this->show_error_message($e->getMessage());
}
wp_die();
}
// 生成所有类型Sitemap
private function generate_all_sitemaps() {
$this->generate_post_sitemaps();
$this->generate_taxonomy_sitemaps();
$this->generate_index_sitemap();
}
// 生成文章类型Sitemap
private function generate_post_sitemaps() {
$post_types = $this->get_enabled_post_types();
foreach ($post_types as $post_type) {
$posts = $this->query_posts($post_type);
$chunks = array_chunk($posts, $this->max_items_per_sitemap);
foreach ($chunks as $index => $chunk) {
$this->generate_post_sitemap($post_type, $chunk, $index + 1);
}
}
}
// 查询指定文章类型的文章
private function query_posts($post_type) {
$args = [
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => -1, // 获取所有文章
'orderby' => 'modified',
'order' => 'DESC',
'fields' => 'ids', // 只获取ID以提高性能
];
$query = new WP_Query($args);
if ($query->have_posts()) {
return $query->posts;
}
return [];
}
// 生成单个文章类型Sitemap
private function generate_post_sitemap($post_type, $posts, $page_num = 1) {
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">';
foreach ($posts as $post_id) {
$post = get_post($post_id);
$xml .= '<url>';
$xml .= '<loc>' . esc_url(get_permalink($post)) . '</loc>';
$xml .= '<lastmod>' . mysql2date('c', $post->post_modified_gmt) . '</lastmod>';
$xml .= '<changefreq>' . $this->get_change_frequency($post) . '</changefreq>';
$xml .= '<priority>' . $this->get_priority($post) . '</priority>';
// 添加图片
if ($this->include_images()) {
foreach ($this->get_post_images($post->ID) as $image) {
$xml .= '<image:image><image:loc>' . esc_url($image) . '</image:loc></image:image>';
}
}
$xml .= '</url>';
}
$xml .= '</urlset>';
$filename = $this->sitemap_prefix . "-posts-{$post_type}-{$page_num}.xml";
$this->save_sitemap($filename, $xml);
}
// 生成分类法Sitemap
private function generate_taxonomy_sitemaps() {
$taxonomies = $this->get_enabled_taxonomies();
foreach ($taxonomies as $taxonomy) {
$terms = get_terms(['taxonomy' => $taxonomy, 'hide_empty' => false]);
$chunks = array_chunk($terms, $this->max_items_per_sitemap);
foreach ($chunks as $index => $chunk) {
$this->generate_taxonomy_sitemap($taxonomy, $chunk, $index + 1);
}
}
}
// 生成单个分类法Sitemap
private function generate_taxonomy_sitemap($taxonomy, $terms, $page_num = 1) {
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
foreach ($terms as $term) {
$xml .= '<url>';
$xml .= '<loc>' . esc_url(get_term_link($term)) . '</loc>';
$xml .= '<lastmod>' . current_time('c') . '</lastmod>';
$xml .= '<changefreq>weekly</changefreq>';
$xml .= '<priority>0.5</priority>';
$xml .= '</url>';
}
$xml .= '</urlset>';
$filename = $this->sitemap_prefix . "-taxonomy-{$taxonomy}-{$page_num}.xml";
$this->save_sitemap($filename, $xml);
}
// 生成索引Sitemap
private function generate_index_sitemap() {
$files = glob(ABSPATH . $this->sitemap_prefix . '*.xml');
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemapindex/0.9">';
foreach ($files as $file) {
if (strpos($file, 'index') !== false) continue;
$xml .= '<sitemap>';
$xml .= '<loc>' . home_url('/' . basename($file)) . '</loc>';
$xml .= '<lastmod>' . date('c', filemtime($file)) . '</lastmod>';
$xml .= '</sitemap>';
}
$xml .= '</sitemapindex>';
$this->save_sitemap($this->sitemap_prefix . '.xml', $xml);
}
// 提交Sitemap到搜索引擎
private function submit_sitemap_to_engines() {
$sitemap_url = home_url('/' . $this->sitemap_prefix . '.xml');
// Google Ping
wp_remote_get('https://www.google.com/webmasters/tools/ping?sitemap=' . urlencode($sitemap_url));
// Bing Ping
wp_remote_get('https://www.bing.com/webmaster/ping.aspx?sitemap=' . urlencode($sitemap_url));
// 百度提交
$settings = get_option('zptheme_seo_sitemap_settings', array());
if (!empty($settings['baidu_token'])) {
$api_url = "http://data.zz.baidu.com/urls?site=" . urlencode(home_url()) . "&token={$settings['baidu_token']}";
$response = wp_remote_post($api_url, [
'body' => implode("\n", $this->get_all_urls()),
'headers' => ['Content-Type' => 'text/plain']
]);
}
}
// 获取所有URL
private function get_all_urls() {
$urls = [];
$files = glob(ABSPATH . $this->sitemap_prefix . '*.xml');
foreach ($files as $file) {
if (strpos($file, 'index') !== false) continue;
$xml = simplexml_load_file($file);
foreach ($xml->url as $url) {
$urls[] = (string)$url->loc;
}
}
return $urls;
}
// 保存Sitemap文件
private function save_sitemap($filename, $content) {
$file = ABSPATH . $filename;
if (!is_writable(ABSPATH)) {
throw new Exception(__('网站根目录不可写,请检查权限!', 'textdomain'));
}
if (file_put_contents($file, $content) === false) {
throw new Exception(sprintf(__('无法写入文件:%s,请检查权限!', 'textdomain'), $filename));
}
}
// 清理旧的Sitemap文件
private function clean_old_sitemaps() {
$files = glob(ABSPATH . $this->sitemap_prefix . '*.xml');
foreach ($files as $file) {
if (is_file($file)) unlink($file);
}
}
// 获取启用的文章类型
private function get_enabled_post_types() {
$settings = get_option('zptheme_seo_sitemap_settings', array());
return isset($settings['post_types']) ? (array)$settings['post_types'] : ['post', 'page'];
}
// 获取启用的分类法
private function get_enabled_taxonomies() {
$settings = get_option('zptheme_seo_sitemap_settings', array());
return isset($settings['taxonomies']) ? (array)$settings['taxonomies'] : ['category', 'post_tag'];
}
// 是否包含图片
private function include_images() {
$settings = get_option('zptheme_seo_sitemap_settings', array());
return isset($settings['include_images']);
}
// 获取文章中的图片
private function get_post_images($post_id) {
$images = [];
$content = get_post_field('post_content', $post_id);
preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $content, $matches);
if (!empty($matches[1])) {
$images = $matches[1];
}
return array_map([$this, 'normalize_image_url'], $images);
}
// 标准化图片URL
private function normalize_image_url($url) {
if (strpos($url, 'http') !== 0) {
$url = home_url($url);
}
return $url;
}
// 获取更新频率
private function get_change_frequency($post) {
$diff = time() - strtotime($post->post_modified_gmt);
if ($diff < 86400) return 'daily';
if ($diff < 604800) return 'weekly';
return 'monthly';
}
// 获取优先级
private function get_priority($post) {
if (is_front_page($post->ID)) return '1.0';
if ($post->post_type === 'page') return '0.8';
return '0.6';
}
// AJAX删除Sitemap
public function ajax_delete_sitemap() {
check_ajax_referer(self::SITEMAP_ZPTHEME . '_delete_sitemap', 'nonce');
$this->clean_old_sitemaps();
$this->show_success_message(__('Sitemap文件已成功删除', 'textdomain'));
wp_die();
}
// 显示成功消息
private function show_success_message($message = '') {
$message = $message ?: __('Sitemap生成成功!', 'textdomain');
echo '<div class="notice notice-success"><p>' . $message . '</p></div>';
}
// 显示错误消息
private function show_error_message($message) {
echo '<div class="notice notice-error"><p>' . $message . '</p></div>';
}
// 文章发布时自动更新Sitemap
public function publish_do_xml($new_status, $old_status, $post) {
$settings = get_option('zptheme_seo_sitemap_settings', array());
if (isset($settings['auto_update']) && $new_status === 'publish') {
try {
$this->generate_all_sitemaps();
$this->submit_sitemap_to_engines();
} catch (Exception $e) {
error_log('自动更新Sitemap失败:' . $e->getMessage());
}
}
}
/**
* 获取 Sitemap 文件路径
*
* @return string Sitemap 文件的完整路径
*/
static function get_sitemap_file() {
$settings = get_option('zptheme_seo_sitemap_settings', array()); // 使用正确的选项名称
$sitemap = isset($settings['sitemap_file']) ? $settings['sitemap_file'] : 'sitemap'; // 修正选项键名
$file = ABSPATH . $sitemap . '.xml';
return $file;
}
/**
* 显示 Sitemap 文件消息
*/
static function xml_notice() {
$file = self::get_sitemap_file();
if (file_exists($file)) {
$size = @filesize($file);
date_default_timezone_set(get_option('timezone_string'));
$time = date('Y-m-d H:i:s', @filemtime($file));
$notice = '<div id="setting-error-settings_updated" class="updated settings-error notice notice-success is-dismissible">';
$notice .= '<p style="color:green;">Sitemap 文件已生成,大小:<strong>' . number_format($size / 1024, 2) . 'KB</strong>,生成时间:<strong>' . $time . '</strong>。</p>';
$notice .= '<p>Sitemap 地址:<a href="' . esc_url(home_url('/' . basename($file))) . '" target="_blank">' . esc_url(home_url('/' . basename($file))) . '</a></p>';
$notice .= '</div>';
} else {
$notice = '<div id="setting-error-settings_updated" class="error settings-error notice notice-error is-dismissible">';
$notice .= '<p>Sitemap 文件未找到,请点击“生成 Sitemap”按钮创建。</p>';
$notice .= '</div>';
}
echo $notice;
}
}
new ZP_Seo_Sitemap_Do_Sitemap ();
版权声明:原创作品,未经允许不得转载,否则将追究法律责任。
本站资源有的自互联网收集整理,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
本文链接:源头网https://www.58588885.com/24864.html
许可协议:《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
本站资源有的自互联网收集整理,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
本文链接:源头网https://www.58588885.com/24864.html
许可协议:《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权

