feat: 新增AI SEO助手插件,支持自动生成SEO内容和导航主题适配

添加完整的AI SEO助手WordPress插件,主要功能包括:
- 集成Dify API自动生成SEO优化的标题、描述和关键词
- 支持导航主题的自定义字段适配
- 提供管理界面设置API和文章类型支持
- 包含前端SEO标签自动应用功能
- 添加详细的测试和调试功能
This commit is contained in:
2025-08-13 18:52:35 +08:00
commit 1ae6823bd5
9 changed files with 2536 additions and 0 deletions

View File

@@ -0,0 +1,503 @@
<?php
/**
* Plugin Name: AI SEO 助手
* Plugin URI: https://ckk.photo8.site/Photo8/wordpress-plugins
* Description: 使用AI自动生成SEO TDK内容的WordPress插件集成Dify API
* Version: 1.0.7
* Author: SnowZ
* License: GPL v2 or later
* Text Domain: ai-seo-generator
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('AI_SEO_PLUGIN_URL', plugin_dir_url(__FILE__));
define('AI_SEO_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('AI_SEO_VERSION', '1.0.0');
// 加载安装脚本
require_once AI_SEO_PLUGIN_PATH . 'install.php';
// 加载测试功能(仅在管理后台)
if (is_admin()) {
require_once AI_SEO_PLUGIN_PATH . 'test/api-test.php';
}
/**
* 主插件类
*/
class AiSeoGenerator {
/**
* 构造函数 - 初始化插件
*/
public function __construct() {
add_action('init', array($this, 'init'));
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
}
/**
* 插件初始化
*/
public function init() {
// 加载文本域
load_plugin_textdomain('ai-seo-generator', false, dirname(plugin_basename(__FILE__)) . '/languages');
// 添加管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 添加编辑页面的meta box
add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
// 保存文章时的钩子
add_action('save_post', array($this, 'save_post_meta'));
// 添加AJAX处理
add_action('wp_ajax_generate_seo_content', array($this, 'ajax_generate_seo_content'));
// 加载管理页面样式和脚本
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
// 前端钩子 - 修改页面标题和meta标签
add_filter('wp_title', array($this, 'custom_wp_title'), 10, 2);
add_action('wp_head', array($this, 'add_meta_tags'));
}
/**
* 插件激活时执行
*/
public function activate() {
// 创建数据库表或设置默认选项
$this->create_options();
}
/**
* 插件停用时执行
*/
public function deactivate() {
// 清理工作
}
/**
* 创建默认选项
*/
private function create_options() {
add_option('ai_seo_api_key', '');
add_option('ai_seo_api_url', '');
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_options_page(
'AI SEO Generator 设置',
'AI SEO Generator',
'manage_options',
'ai-seo-generator',
array($this, 'admin_page')
);
// 添加测试页面子菜单
add_submenu_page(
'options-general.php',
'AI SEO 测试',
'AI SEO 测试',
'manage_options',
'ai-seo-test',
array($this, 'test_page')
);
}
/**
* 管理页面内容
* 处理设置保存包括API配置和支持的文章类型
*/
public function admin_page() {
if (isset($_POST['submit'])) {
// 保存API设置
update_option('ai_seo_api_key', sanitize_text_field($_POST['api_key']));
update_option('ai_seo_api_url', esc_url_raw($_POST['api_url']));
// 保存支持的文章类型设置
$supported_post_types = array();
if (isset($_POST['supported_post_types']) && is_array($_POST['supported_post_types'])) {
// 获取所有公开的post类型进行验证
$all_post_types = get_post_types(array('public' => true), 'names');
foreach ($_POST['supported_post_types'] as $post_type) {
$post_type = sanitize_text_field($post_type);
// 只保存有效的公开post类型
if (in_array($post_type, $all_post_types)) {
$supported_post_types[] = $post_type;
}
}
}
// 如果没有选择任何类型默认支持post和page
if (empty($supported_post_types)) {
$supported_post_types = array('post', 'page');
}
update_option('ai_seo_supported_post_types', $supported_post_types);
echo '<div class="notice notice-success"><p>设置已保存!支持的文章类型:' . implode(', ', $supported_post_types) . '</p></div>';
}
$api_key = get_option('ai_seo_api_key', '');
$api_url = get_option('ai_seo_api_url', '');
include AI_SEO_PLUGIN_PATH . 'admin/settings.php';
}
/**
* 测试页面内容
*/
public function test_page() {
if (!class_exists('AiSeoApiTest')) {
echo '<div class="wrap"><h1>测试功能不可用</h1><p>测试类未加载。</p></div>';
return;
}
echo '<div class="wrap">';
echo '<h1>🧪 AI SEO Generator 测试</h1>';
echo '<p>此页面用于测试API连接和功能验证。</p>';
if (isset($_POST['run_test'])) {
$tester = new AiSeoApiTest();
echo $tester->generate_test_report();
} else {
echo '<form method="post">';
echo '<p><button type="submit" name="run_test" class="button button-primary">🚀 运行测试</button></p>';
echo '</form>';
echo '<div class="ai-seo-test-info">';
echo '<h3>测试内容包括:</h3>';
echo '<ul>';
echo '<li>✅ API连接测试</li>';
echo '<li>✅ SEO内容生成测试</li>';
echo '<li>✅ 系统环境检查</li>';
echo '<li>✅ 插件配置验证</li>';
echo '</ul>';
echo '</div>';
}
echo '</div>';
}
/**
* 添加meta boxes到编辑页面
* 支持所有公开的post类型包括自定义post类型
*/
public function add_meta_boxes() {
// 获取所有公开的post类型
$post_types = get_post_types(array('public' => true), 'names');
// 从设置中获取支持的post类型如果没有设置则使用所有公开类型
$supported_post_types = get_option('ai_seo_supported_post_types', $post_types);
// 确保支持的类型都是公开的
$supported_post_types = array_intersect($supported_post_types, $post_types);
// 为每个支持的post类型添加meta box
foreach ($supported_post_types as $post_type) {
add_meta_box(
'ai-seo-generator',
'AI SEO Generator',
array($this, 'meta_box_callback'),
$post_type,
'normal',
'high'
);
}
}
/**
* Meta box回调函数
*/
public function meta_box_callback($post) {
wp_nonce_field('ai_seo_meta_box', 'ai_seo_meta_box_nonce');
$seo_title = get_post_meta($post->ID, '_ai_seo_title', true);
$seo_description = get_post_meta($post->ID, '_ai_seo_description', true);
$seo_keywords = get_post_meta($post->ID, '_ai_seo_keywords', true);
include AI_SEO_PLUGIN_PATH . 'admin/meta-box.php';
}
/**
* 保存文章meta数据
*/
public function save_post_meta($post_id) {
if (!isset($_POST['ai_seo_meta_box_nonce']) || !wp_verify_nonce($_POST['ai_seo_meta_box_nonce'], 'ai_seo_meta_box')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['ai_seo_title'])) {
update_post_meta($post_id, '_ai_seo_title', sanitize_text_field($_POST['ai_seo_title']));
}
if (isset($_POST['ai_seo_description'])) {
update_post_meta($post_id, '_ai_seo_description', sanitize_textarea_field($_POST['ai_seo_description']));
}
if (isset($_POST['ai_seo_keywords'])) {
update_post_meta($post_id, '_ai_seo_keywords', sanitize_text_field($_POST['ai_seo_keywords']));
}
}
/**
* 加载管理页面脚本和样式
*/
public function enqueue_admin_scripts($hook) {
if ('post.php' == $hook || 'post-new.php' == $hook || 'settings_page_ai-seo-generator' == $hook) {
wp_enqueue_script('ai-seo-admin', AI_SEO_PLUGIN_URL . 'assets/admin.js', array('jquery'), AI_SEO_VERSION, true);
wp_enqueue_style('ai-seo-admin', AI_SEO_PLUGIN_URL . 'assets/admin.css', array(), AI_SEO_VERSION);
wp_localize_script('ai-seo-admin', 'aiSeoAjax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ai_seo_nonce')
));
}
}
/**
* AJAX处理生成SEO内容
* 增强错误处理和调试信息
*/
public function ajax_generate_seo_content() {
// 增加PHP执行时间限制防止长时间AI生成被中断
set_time_limit(180); // 设置为3分钟
check_ajax_referer('ai_seo_nonce', 'nonce');
$post_id = intval($_POST['post_id']);
$post = get_post($post_id);
if (!$post) {
wp_send_json_error('文章不存在');
return;
}
$content = $post->post_content;
$title = $post->post_title;
// 读取导航主题的自定义字段
$sites_link = get_post_meta($post_id, '_sites_link', true);
$sites_describe = get_post_meta($post_id, '_sites_sescribe', true);
// 构建完整的内容信息,包含自定义字段
$full_content = $content;
if (!empty($sites_link)) {
$full_content .= "\n\n网站链接: " . $sites_link;
}
if (!empty($sites_describe)) {
$full_content .= "\n\n网站描述: " . $sites_describe;
}
// 记录请求信息
error_log('AI SEO Request - Post ID: ' . $post_id . ', Title: ' . $title . ', Sites Link: ' . $sites_link . ', Sites Describe: ' . $sites_describe);
// 调用AI API生成SEO内容
$seo_data = $this->generate_seo_with_ai($title, $full_content);
if ($seo_data && is_array($seo_data)) {
// 记录成功信息
error_log('AI SEO Success: ' . json_encode($seo_data));
wp_send_json_success($seo_data);
} else {
// 记录失败信息
error_log('AI SEO Failed: seo_data = ' . var_export($seo_data, true));
wp_send_json_error('生成SEO内容失败请查看错误日志获取详细信息');
}
}
/**
* 调用AI API生成SEO内容
* 增强调试和错误处理功能
*/
private function generate_seo_with_ai($title, $content) {
$api_key = get_option('ai_seo_api_key');
$api_url = get_option('ai_seo_api_url');
// 记录配置信息
error_log('AI SEO Config - API URL: ' . $api_url . ', API Key: ' . (empty($api_key) ? 'Empty' : 'Set'));
if (empty($api_key) || empty($api_url)) {
error_log('AI SEO Error: API Key or URL not configured');
return false;
}
// 检测是否包含导航网站信息
$is_navigation_site = (strpos($content, '网站链接:') !== false || strpos($content, '网站描述:') !== false);
if ($is_navigation_site) {
$prompt = "请根据以下导航网站信息生成SEO优化的标题(Title)、描述(Description)和关键词(Keywords)。这是一个网站导航页面,请重点关注网站的功能、特色和用途:\n\n标题:{$title}\n\n内容:" . wp_strip_all_tags($content) . "\n\n请针对导航类网站的特点生成吸引用户点击的SEO内容。以JSON格式返回包含title、description、keywords字段。";
} else {
$prompt = "请根据以下文章标题和内容生成SEO优化的标题(Title)、描述(Description)和关键词(Keywords)\n\n标题:{$title}\n\n内容:" . wp_strip_all_tags($content) . "\n\n请以JSON格式返回包含title、description、keywords字段。";
}
$request_body = array(
'inputs' => array(),
'query' => $prompt,
'response_mode' => 'blocking',
'user' => 'wordpress-user'
);
// 记录请求信息
error_log('AI SEO Request Body: ' . json_encode($request_body));
$response = wp_remote_post($api_url . '/chat-messages', array(
'headers' => array(
'Authorization' => 'Bearer ' . $api_key,
'Content-Type' => 'application/json'
),
'body' => json_encode($request_body),
'timeout' => 120 // 增加超时时间到120秒2分钟
));
if (is_wp_error($response)) {
error_log('AI SEO WP Error: ' . $response->get_error_message());
return false;
}
$response_code = wp_remote_retrieve_response_code($response);
error_log('AI SEO Response Code: ' . $response_code);
$body = wp_remote_retrieve_body($response);
// 记录原始响应
error_log('AI SEO Raw Response: ' . $body);
if (empty($body)) {
error_log('AI SEO Error: Empty response body');
return false;
}
$data = json_decode($body, true);
$json_error = json_last_error();
if ($json_error !== JSON_ERROR_NONE) {
error_log('AI SEO JSON Error: ' . json_last_error_msg());
return false;
}
error_log('AI SEO Parsed Data: ' . json_encode($data));
// 方法1: 检查是否直接返回了SEO数据结构
if (isset($data['title'], $data['description'], $data['keywords'])) {
error_log('AI SEO: Found direct SEO data structure');
return array(
'title' => $data['title'],
'description' => $data['description'],
'keywords' => $data['keywords']
);
}
// 方法2: 检查answer字段中的JSON数据
if (isset($data['answer'])) {
$answer = $data['answer'];
error_log('AI SEO: Found answer field: ' . $answer);
// 尝试直接解析answer作为JSON
$seo_data = json_decode($answer, true);
if ($seo_data && isset($seo_data['title'], $seo_data['description'], $seo_data['keywords'])) {
error_log('AI SEO: Successfully parsed answer as JSON');
return $seo_data;
}
// 尝试从answer中提取JSON字符串
preg_match('/\{.*\}/s', $answer, $matches);
if (!empty($matches[0])) {
error_log('AI SEO: Extracted JSON from answer: ' . $matches[0]);
$seo_data = json_decode($matches[0], true);
if ($seo_data && isset($seo_data['title'], $seo_data['description'], $seo_data['keywords'])) {
error_log('AI SEO: Successfully parsed extracted JSON');
return $seo_data;
}
}
}
// 方法3: 检查data字段中的内容
if (isset($data['data'])) {
$data_content = $data['data'];
error_log('AI SEO: Found data field: ' . json_encode($data_content));
if (is_array($data_content) && isset($data_content['title'], $data_content['description'], $data_content['keywords'])) {
error_log('AI SEO: Successfully found SEO data in data field');
return $data_content;
}
}
error_log('AI SEO: No valid SEO data found in response');
return false;
}
/**
* 自定义页面标题
*/
public function custom_wp_title($title, $sep) {
if (is_single() || is_page()) {
global $post;
$custom_title = get_post_meta($post->ID, '_ai_seo_title', true);
if (!empty($custom_title)) {
return $custom_title;
}
}
return $title;
}
/**
* 添加meta标签到页面头部
* 使用Open Graph标签避免与WordPress默认meta标签冲突
*/
public function add_meta_tags() {
if (is_single() || is_page()) {
global $post;
$seo_title = get_post_meta($post->ID, '_ai_seo_title', true);
$description = get_post_meta($post->ID, '_ai_seo_description', true);
$keywords = get_post_meta($post->ID, '_ai_seo_keywords', true);
// 输出Open Graph标题
if (!empty($seo_title)) {
echo '<meta property="og:title" content="' . esc_attr($seo_title) . '">' . "\n";
}
// 输出Open Graph描述
if (!empty($description)) {
echo '<meta property="og:description" content="' . esc_attr($description) . '">' . "\n";
}
// 保留keywords标签Open Graph没有对应标签
if (!empty($keywords)) {
echo '<meta name="keywords" content="' . esc_attr($keywords) . '">' . "\n";
}
// 添加其他常用的Open Graph标签
echo '<meta property="og:type" content="article">' . "\n";
echo '<meta property="og:url" content="' . esc_url(get_permalink($post->ID)) . '">' . "\n";
// 如果文章有特色图片添加og:image
if (has_post_thumbnail($post->ID)) {
$thumbnail_url = get_the_post_thumbnail_url($post->ID, 'large');
echo '<meta property="og:image" content="' . esc_url($thumbnail_url) . '">' . "\n";
}
}
}
}
// 初始化插件
new AiSeoGenerator();
?>