文章目录
-
- 在当今信息爆炸的时代,网络传媒类WordPress站点每天产生大量内容,包括新闻、专题报道、视频内容等。这些内容如果没有良好的归档机制,很快就会淹没在信息海洋中,导致资源浪费和用户体验下降。 柔性内容智能归档插件旨在解决以下核心问题: 自动化内容分类与标签管理 智能识别内容时效性和相关性 动态调整归档策略 提升站点内容可发现性和SEO表现 本教程将带领您从零开始开发一个完整的智能归档插件,包含完整的代码实现和详细注释。
- 首先,我们需要创建插件的基本文件结构: <?php /** * Plugin Name: 柔性内容智能归档插件 * Plugin URI: https://yourwebsite.com/ * Description: 为网络传媒WordPress站点提供智能内容归档功能 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later * Text Domain: flexible-content-archiver */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('FCA_VERSION', '1.0.0'); define('FCA_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('FCA_PLUGIN_URL', plugin_dir_url(__FILE__)); // 初始化插件 class FlexibleContentArchiver { private static $instance = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->init_hooks(); } private function init_hooks() { // 激活/停用钩子 register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); // 初始化 add_action('init', array($this, 'init')); // 管理界面 add_action('admin_menu', array($this, 'add_admin_menu')); // 内容处理钩子 add_action('save_post', array($this, 'process_content_on_save'), 10, 3); // 定时任务 add_action('fca_daily_archiving', array($this, 'daily_archiving_task')); } public function activate() { // 创建必要的数据库表 $this->create_database_tables(); // 设置默认选项 $this->set_default_options(); // 设置定时任务 if (!wp_next_scheduled('fca_daily_archiving')) { wp_schedule_event(time(), 'daily', 'fca_daily_archiving'); } flush_rewrite_rules(); } public function deactivate() { // 清理定时任务 wp_clear_scheduled_hook('fca_daily_archiving'); flush_rewrite_rules(); } // 其他方法将在后续部分实现 } // 启动插件 FlexibleContentArchiver::get_instance(); ?>
- 智能归档的核心是内容分析,我们需要设计数据库表来存储分析结果: <?php /** * 创建插件所需的数据库表 */ private function create_database_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $table_name = $wpdb->prefix . 'fca_content_analysis'; $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id bigint(20) NOT NULL AUTO_INCREMENT, post_id bigint(20) NOT NULL, relevance_score float DEFAULT 0, category_suggestion varchar(255), tags_suggestion text, archive_status varchar(50) DEFAULT 'active', last_analyzed datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY post_id (post_id), KEY archive_status (archive_status) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } /** * 内容分析核心类 */ class ContentAnalyzer { /** * 分析文章内容并返回建议 * @param int $post_id 文章ID * @return array 分析结果 */ public static function analyze_post($post_id) { $post = get_post($post_id); if (!$post) { return false; } $analysis = array( 'relevance_score' => self::calculate_relevance_score($post), 'category_suggestion' => self::suggest_categories($post), 'tags_suggestion' => self::extract_keywords($post), 'archive_priority' => self::determine_archive_priority($post) ); return $analysis; } /** * 计算内容相关性分数 * @param WP_Post $post 文章对象 * @return float 相关性分数(0-1) */ private static function calculate_relevance_score($post) { $score = 0.5; // 基础分数 // 1. 基于发布时间计算时效性 $post_age = (time() - strtotime($post->post_date)) / (3600 * 24); $timeliness = max(0, 1 - ($post_age / 365)); // 一年内线性衰减 // 2. 基于评论互动计算活跃度 $comment_count = get_comments_number($post->ID); $engagement = min(1, $comment_count / 100); // 每100评论得1分,最高1分 // 3. 基于浏览量计算热度 $views = get_post_meta($post->ID, 'post_views', true) ?: 0; $popularity = min(1, $views / 10000); // 每1万浏览量得1分 // 加权计算最终分数 $score = ($timeliness * 0.4) + ($engagement * 0.3) + ($popularity * 0.3); return round($score, 3); } /** * 智能推荐分类 * @param WP_Post $post 文章对象 * @return array 推荐分类ID数组 */ private static function suggest_categories($post) { $suggestions = array(); // 获取现有分类 $current_categories = wp_get_post_categories($post->ID, array('fields' => 'ids')); // 基于内容关键词匹配分类 $content = $post->post_title . ' ' . $post->post_content; $keywords = self::extract_keywords_from_text($content); $all_categories = get_categories(array('hide_empty' => false)); foreach ($all_categories as $category) { $category_score = 0; // 检查分类名称是否包含关键词 foreach ($keywords as $keyword) { if (stripos($category->name, $keyword) !== false) { $category_score += 1; } } // 检查分类描述是否包含关键词 foreach ($keywords as $keyword) { if (stripos($category->description, $keyword) !== false) { $category_score += 0.5; } } if ($category_score > 0) { $suggestions[$category->term_id] = $category_score; } } // 按分数排序并返回前3个 arsort($suggestions); return array_slice(array_keys($suggestions), 0, 3, true); } /** * 从文本中提取关键词 * @param string $text 文本内容 * @return array 关键词数组 */ private static function extract_keywords_from_text($text) { // 移除HTML标签 $text = wp_strip_all_tags($text); // 中文分词处理(简化版,实际应使用专业分词库) if (preg_match('/[x{4e00}-x{9fa5}]/u', $text)) { // 中文处理:按常见分隔符分割 $words = preg_split('/[s,,。!!??;;::""']+/u', $text); } else { // 英文处理:按单词分割 $words = str_word_count($text, 1); } // 移除停用词 $stop_words = array('的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这', 'the', 'and', 'a', 'an', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by'); $words = array_diff($words, $stop_words); // 统计词频 $word_freq = array_count_values($words); // 按频率排序并返回前10个关键词 arsort($word_freq); return array_slice(array_keys($word_freq), 0, 10, true); } } ?>
- <?php /** * 归档策略引擎 */ class ArchivingStrategy { /** * 根据分析结果确定归档优先级 * @param WP_Post $post 文章对象 * @return string 归档优先级 */ public static function determine_archive_priority($post) { $analysis = ContentAnalyzer::analyze_post($post->ID); $score = $analysis['relevance_score']; if ($score < 0.3) { return 'high'; // 高优先级归档 } elseif ($score < 0.6) { return 'medium'; // 中等优先级 } else { return 'low'; // 低优先级,保持活跃 } } /** * 执行归档操作 * @param int $post_id 文章ID * @param string $strategy 归档策略 */ public static function archive_post($post_id, $strategy = 'smart') { $post = get_post($post_id); if (!$post) { return false; } switch ($strategy) { case 'smart': self::smart_archive($post); break; case 'move_to_category': self::move_to_archive_category($post); break; case 'change_status': self::change_post_status($post); break; default: self::smart_archive($post); } // 更新分析记录 self::update_analysis_record($post_id, 'archived'); return true; } /** * 智能归档策略 * @param WP_Post $post 文章对象 */ private static function smart_archive($post) { $analysis = ContentAnalyzer::analyze_post($post->ID); // 根据分数决定归档方式 if ($analysis['relevance_score'] < 0.2) { // 分数极低:移动到归档分类并取消置顶 self::move_to_archive_category($post); unstick_post($post->ID); } elseif ($analysis['relevance_score'] < 0.4) { // 分数较低:仅移动到归档分类 self::move_to_archive_category($post); } else { // 分数尚可:仅添加归档标签 self::add_archive_tag($post); } } /** * 移动到归档分类 * @param WP_Post $post 文章对象 */ private static function move_to_archive_category($post) { // 获取或创建归档分类 $archive_category = get_category_by_slug('archive'); if (!$archive_category) { $archive_category = wp_create_category('归档内容'); } // 设置文章分类(保留原有分类,增加归档分类) $current_categories = wp_get_post_categories($post->ID, array('fields' => 'ids')); $current_categories[] = $archive_category->term_id; wp_set_post_categories($post->ID, $current_categories); // 添加自定义字段标记 update_post_meta($post->ID, '_fca_archived', true); update_post_meta($post->ID, '_fca_archived_date', current_time('mysql')); } /** * 添加归档标签 * @param WP_Post $post 文章对象 */ private static function add_archive_tag($post) { // 获取或创建归档标签 $archive_tag = get_term_by('slug', 'archived', 'post_tag'); if (!$archive_tag) { $archive_tag = wp_insert_term('已归档', 'post_tag', array('slug' => 'archived')); } // 添加标签 wp_set_post_tags($post->ID, '已归档', true); // 添加自定义字段标记 update_post_meta($post->ID, '_fca_tagged_archive', true); } } ?>
- <?php /** * 添加管理菜单 */ public function add_admin_menu() { add_menu_page( '智能归档设置', '内容归档', 'manage_options', 'fca-settings', array($this, 'render_settings_page'), 'dashicons-archive', 30 ); add_submenu_page( 'fca-settings', '归档分析报告', '分析报告', 'manage_options', 'fca-analytics', array($this, 'render_analytics_page') ); add_submenu_page( 'fca-settings', '批量归档操作', '批量操作', 'manage_options', 'fca-batch', array($this, 'render_batch_page') ); } /** * 渲染设置页面 */ public function render_settings_page() { ?> <div class="wrap"> <h1>柔性内容智能归档设置</h1> <form method="post" action="options.php"> <?php settings_fields('fca_settings_group'); do_settings_sections('fca-settings'); submit_button(); ?> </form> <div class="fca-status-box"> <h3>系统状态</h3> <p>已分析文章: <?php echo $this->get_analyzed_count(); ?> 篇</p> <p>已归档文章: <?php echo $this->get_archived_count(); ?> 篇</p> <p>下次自动归档: <?php echo date('Y-m-d H:i:s', wp_next_scheduled('fca_daily_archiving')); ?></p> </div> </div> <?php } /** * 初始化设置选项 */ public function init() { // 注册设置 register_setting('fca_settings_group', 'fca_auto_archive'); register_setting('fca_settings_group', 'fca_relevance_threshold'); register_setting('fca_settings_group', 'fca_excluded_categories'); // 添加设置部分 add_settings_section( 'fca_main_section', '归档策略设置', null, 'fca-settings' ); // 自动归档选项 add_settings_field( 'fca_auto_archive', '启用自动归档', array($this, 'render_auto_archive_field'), 'fca-settings', 'fca_main_section' ); // 相关性阈值选项 add_settings_field( 'fca_relevance_threshold', '归档相关性阈值', array($this, 'render_threshold_field'), 'fca-settings', 'fca_main_section' ); } /** * 渲染自动归档字段 */ public function render_auto_archive_field() { $option = get_option('fca_auto_archive', '1'); ?> <input type="checkbox" name="fca_auto_archive" value="1" <?php checked(1, $option); ?> /> <label>启用每日自动归档(推荐)</label> <p class="description">系统将每天自动分析并归档低相关性内容</p> <?php } /** * 渲染阈值字段 */ public function render_threshold_field() { $option = get_option('fca_relevance_threshold', '0.3'); ?> <input type="range" name="fca_relevance_threshold" min="0" max="1" step="0.05" value="<?php echo esc_attr($option); ?>" oninput="this.nextElementSibling.value = this.value" /> <output><?php echo esc_attr($option); ?></output> <p class="description">相关性分数低于此值的内容将被自动归档(0-1,值越小越严格)</p> <?php } ?>
- <?php /** * 每日归档任务 */ public function daily_archiving_task() { global $wpdb; // 检查是否启用自动归档 if (!get_option('fca_auto_archive', '1')) { return; } $threshold = floatval(get_option('fca_relevance_threshold', '0.3')); // 获取需要归档的文章 $query = new WP_Query(array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 50, 'meta_query' => array( 'OR' => array( array( 'key' => '_fca_archived', 'compare' => 'NOT EXISTS' ), array( 'key' => '_fca_archived', 'value' => '1', 'compare' => '!=' ) ) ), 'date_query' => array( array( 'before' => date('Y-m-d', strtotime('-30 days')), 'inclusive' => true, ) ) )); $archived_count = 0; if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); $post_id = get_the_ID(); // 分析文章 $analysis = ContentAnalyzer::analyze_post($post_id); // 检查是否达到归档阈值 if ($analysis['relevance_score'] < $threshold) { // 执行归档 ArchivingStrategy::archive_post($post_id, 'smart'); $archived_count++; // 记录日志 $this->log_archiving_action($post_id, 'auto', $analysis['relevance_score']); } // 更新分析记录 $this->update_analysis_record($post_id, $analysis); } wp_reset_postdata(); } // 发送通知(可选) if ($archived_count > 0) { $this->send_admin_notification($archived_count); } } /** 更新分析记录 */ private function update_analysis_record($post_id, $analysis) { global $wpdb; $table_name = $wpdb->prefix . 'fca_content_analysis'; // 检查记录是否存在 $existing = $wpdb->get_var($wpdb->prepare( "SELECT id FROM $table_name WHERE post_id = %d", $post_id )); $data = array( 'post_id' => $post_id, 'relevance_score' => $analysis['relevance_score'], 'category_suggestion' => implode(',', $analysis['category_suggestion']), 'tags_suggestion' => implode(',', $analysis['tags_suggestion']), 'last_analyzed' => current_time('mysql') ); if ($existing) { $wpdb->update($table_name, $data, array('post_id' => $post_id)); } else { $wpdb->insert($table_name, $data); } } /** 批量归档处理 */ public function process_batch_archiving($post_ids, $strategy = 'smart') { $results = array( 'success' => 0, 'failed' => 0, 'details' => array() ); foreach ($post_ids as $post_id) { try { $success = ArchivingStrategy::archive_post($post_id, $strategy); if ($success) { $results['success']++; $results['details'][] = array( 'post_id' => $post_id, 'status' => 'success', 'message' => '文章已成功归档' ); } else { $results['failed']++; $results['details'][] = array( 'post_id' => $post_id, 'status' => 'failed', 'message' => '归档失败' ); } } catch (Exception $e) { $results['failed']++; $results['details'][] = array( 'post_id' => $post_id, 'status' => 'error', 'message' => $e->getMessage() ); } } return $results; } /** 渲染批量操作页面 */ public function render_batch_page() { // 处理批量操作请求 if (isset($_POST['fca_batch_action']) && check_admin_referer('fca_batch_action')) { $post_ids = isset($_POST['post_ids']) ? array_map('intval', $_POST['post_ids']) : array(); $strategy = isset($_POST['archive_strategy']) ? sanitize_text_field($_POST['archive_strategy']) : 'smart'; if (!empty($post_ids)) { $results = $this->process_batch_archiving($post_ids, $strategy); echo '<div class="notice notice-success"><p>'; echo sprintf('批量归档完成!成功:%d,失败:%d', $results['success'], $results['failed']); echo '</p></div>'; } } // 查询可归档的文章 $query = new WP_Query(array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 100, 'meta_query' => array( array( 'key' => '_fca_archived', 'compare' => 'NOT EXISTS' ) ), 'orderby' => 'date', 'order' => 'ASC' )); ?> <div class="wrap"> <h1>批量归档操作</h1> <form method="post" action=""> <?php wp_nonce_field('fca_batch_action'); ?> <div class="fca-batch-controls"> <h3>选择归档策略</h3> <select name="archive_strategy"> <option value="smart">智能归档(推荐)</option> <option value="move_to_category">移动到归档分类</option> <option value="change_status">更改文章状态</option> </select> <button type="button" class="button" id="fca-select-all">全选</button> <button type="button" class="button" id="fca-deselect-all">取消全选</button> <input type="submit" name="fca_batch_action" class="button button-primary" value="执行批量归档" onclick="return confirm('确定要归档选中的文章吗?')"> </div> <table class="wp-list-table widefat fixed striped"> <thead> <tr> <th class="check-column"><input type="checkbox" id="fca-check-all"></th> <th>文章标题</th> <th>发布日期</th> <th>相关性分数</th> <th>建议操作</th> </tr> </thead> <tbody> <?php if ($query->have_posts()): ?> <?php while ($query->have_posts()): $query->the_post(); ?> <?php $post_id = get_the_ID(); $analysis = ContentAnalyzer::analyze_post($post_id); $priority = ArchivingStrategy::determine_archive_priority(get_post($post_id)); ?> <tr> <td><input type="checkbox" name="post_ids[]" value="<?php echo $post_id; ?>"></td> <td> <strong><?php the_title(); ?></strong> <div class="row-actions"> <a href="<?php echo get_edit_post_link(); ?>">编辑</a> | <a href="<?php the_permalink(); ?>" target="_blank">查看</a> </div> </td> <td><?php echo get_the_date(); ?></td> <td> <div class="fca-score-indicator"> <div class="fca-score-bar" style="width: <?php echo $analysis['relevance_score'] * 100; ?>%"></div> <span class="fca-score-text"><?php echo round($analysis['relevance_score'], 3); ?></span> </div> </td> <td> <?php $action_text = ''; $action_class = ''; switch ($priority) { case 'high': $action_text = '立即归档'; $action_class = 'fca-high-priority'; break; case 'medium': $action_text = '建议归档'; $action_class = 'fca-medium-priority'; break; case 'low': $action_text = '保持活跃'; $action_class = 'fca-low-priority'; break; } ?> <span class="fca-action-badge <?php echo $action_class; ?>"> <?php echo $action_text; ?> </span> </td> </tr> <?php endwhile; ?> <?php else: ?> <tr> <td colspan="5">没有找到需要归档的文章。</td> </tr> <?php endif; ?> </tbody> </table> </form> </div> <script> jQuery(document).ready(function($) { // 全选/取消全选功能 $('#fca-check-all').on('change', function() { $('input[name="post_ids[]"]').prop('checked', this.checked); }); $('#fca-select-all').on('click', function() { $('input[name="post_ids[]"]').prop('checked', true); $('#fca-check-all').prop('checked', true); }); $('#fca-deselect-all').on('click', function() { $('input[name="post_ids[]"]').prop('checked', false); $('#fca-check-all').prop('checked', false); }); }); </script> <style> .fca-score-indicator { position: relative; height: 20px; background: #f0f0f0; border-radius: 3px; overflow: hidden; } .fca-score-bar { height: 100%; background: linear-gradient(90deg, #dc3232, #ffb900, #46b450); transition: width 0.3s ease; } .fca-score-text { position: absolute; top: 0; left: 0; right: 0; text-align: center; line-height: 20px; font-size: 12px; font-weight: bold; color: #000; } .fca-action-badge { display: inline-block; padding: 3px 8px; border-radius: 3px; font-size: 12px; font-weight: bold; } .fca-high-priority { background: #dc3232; color: white; } .fca-medium-priority { background: #ffb900; color: #000; } .fca-low-priority { background: #46b450; color: white; } </style> <?php wp_reset_postdata(); }?> ## 七、前端展示与短代码支持 <?php/** 添加快捷短代码支持 */ public function init() { // ... 之前的初始化代码 ... // 注册短代码 add_shortcode('archive_content', array($this, 'render_archive_shortcode')); // 添加小工具 add_action('widgets_init', array($this, 'register_widgets')); } /** 归档内容短代码 */ public function render_archive_shortcode($atts) { $atts = shortcode_atts(array( 'category' => 'archive', 'limit' => 10, 'show_date' => true, 'layout' => 'list' ), $atts, 'archive_content'); $query_args = array( 'post_type' => 'post', 'posts_per_page' => intval($atts['limit']), 'category_name' => sanitize_text_field($atts['category']), 'post_status' => 'publish' ); $archive_query = new WP_Query($query_args); if (!$archive_query->have_posts()) { return '<p>暂无归档内容。</p>'; } ob_start(); if ($atts['layout'] === 'grid') { echo '<div class="fca-archive-grid">'; while ($archive_query->have_posts()) { $archive_query->the_post(); ?> <div class="fca-archive-item"> <h4><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4> <?php if ($atts['show_date']): ?> <span class="fca-archive-date"><?php echo get_the_date(); ?></span> <?php endif; ?> <div class="fca-archive-excerpt"> <?php echo wp_trim_words(get_the_excerpt(), 20); ?> </div> </div> <?php } echo '</div>'; } else { echo '<ul class="fca-archive-list">'; while ($archive_query->have_posts()) { $archive_query->the_post(); ?> <li> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> <?php if ($atts['show_date']): ?> <span class="fca-archive-date">(<?php echo get_the_date(); ?>)</span> <?php endif; ?> </li> <?php } echo '</ul>'; } wp_reset_postdata(); return ob_get_clean(); } /** 注册归档小工具 */ public function register_widgets() { register_widget('FCA_Archive_Widget'); } /** 归档小工具类 */ class FCA_Archive_Widget extends WP_Widget { public function __construct() { parent::__construct( 'fca_archive_widget', '智能归档内容', array('description' => '显示智能归档的文章列表') ); } public function widget($args, $instance) { echo $args['before_widget']; $title = !empty($instance['title']) ? $instance['title'] : '归档内容'; $limit = !empty($instance['limit']) ? $instance['limit'] : 5; echo $args['before_title'] . esc_html($title) . $args['after_title']; // 查询归档内容 $query = new WP_Query(array( 'post_type' => 'post', 'posts_per_page' => $limit, 'meta_query' => array( array( 'key' => '_fca_archived', 'value' => '1', 'compare' => '=' ) ), 'orderby' => 'meta_value', 'meta_key' => '_fca_archived_date', 'order' => 'DESC' )); if ($query->have_posts()) { echo '<ul class="fca-widget-list">'; while ($query->have_posts()) { $query->the_post(); echo '<li>'; echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a>'; echo '<br><small>' . get_the_date() . '</small>'; echo '</li>'; } echo '</ul>'; } else { echo '<p>暂无归档内容。</p>'; } wp_reset_postdata(); echo $args['after_widget']; } public function form($instance) { $title = !empty($instance['title']) ? $instance['title'] : '归档内容'; $limit = !empty($instance['limit']) ? $instance['limit'] : 5; ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>">标题:</label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>"> </p> <p> <label for="<?php echo $this->get_field_id('limit'); ?>">显示数量:</label> <input class="tiny-text" id="<?php echo $this->get_field_id('limit'); ?>" name="<?php echo $this->get_field_name('limit'); ?>" type="number" step="1" min="1" max="20" value="<?php echo esc_attr($limit); ?>"> </p> <?php } public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : ''; $instance['limit'] = !empty($new_instance['limit']) ? intval($new_instance['limit']) : 5; return $instance; } }?> ## 八、插件优化与扩展建议 ### 8.1 性能优化建议 <?php/** 添加缓存机制 */ class FCACache { private static $cache_group = 'fca_analysis'; public static function get_analysis($post_id) { $cached = wp_cache_get($post_id, self::$cache_group); if (false !== $cached) { return $cached; } // 从数据库获取 global $wpdb; $table_name = $wpdb->prefix . 'fca_content_analysis'; $result = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $table_name WHERE post_id = %d", $post_id ), ARRAY_A); if ($result) { wp_cache_set($post_id, $result, self::$cache_group, 3600); // 缓存1小时 } return $result; } public static function clear_cache($post_id = null) { if ($post_id) { wp_cache_delete($post_id, self::$cache_group); } else { wp_cache_flush(); } } } /** 添加索引优化查询 */ private function optimize_database() { global $wpdb; $table_name = $wpdb->prefix . 'fca_content_analysis'; // 添加复合索引 $wpdb->query("ALTER TABLE $table_name ADD INDEX idx_score_status (relevance_score, archive_status)
在当今信息爆炸的时代,网络传媒类WordPress站点每天产生大量内容,包括新闻、专题报道、视频内容等。这些内容如果没有良好的归档机制,很快就会淹没在信息海洋中,导致资源浪费和用户体验下降。
柔性内容智能归档插件旨在解决以下核心问题:
- 自动化内容分类与标签管理
- 智能识别内容时效性和相关性
- 动态调整归档策略
- 提升站点内容可发现性和SEO表现
本教程将带领您从零开始开发一个完整的智能归档插件,包含完整的代码实现和详细注释。
首先,我们需要创建插件的基本文件结构:
<?php
/**
* Plugin Name: 柔性内容智能归档插件
* Plugin URI: https://yourwebsite.com/
* Description: 为网络传媒WordPress站点提供智能内容归档功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: flexible-content-archiver
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('FCA_VERSION', '1.0.0');
define('FCA_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FCA_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class FlexibleContentArchiver {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('init', array($this, 'init'));
// 管理界面
add_action('admin_menu', array($this, 'add_admin_menu'));
// 内容处理钩子
add_action('save_post', array($this, 'process_content_on_save'), 10, 3);
// 定时任务
add_action('fca_daily_archiving', array($this, 'daily_archiving_task'));
}
public function activate() {
// 创建必要的数据库表
$this->create_database_tables();
// 设置默认选项
$this->set_default_options();
// 设置定时任务
if (!wp_next_scheduled('fca_daily_archiving')) {
wp_schedule_event(time(), 'daily', 'fca_daily_archiving');
}
flush_rewrite_rules();
}
public function deactivate() {
// 清理定时任务
wp_clear_scheduled_hook('fca_daily_archiving');
flush_rewrite_rules();
}
// 其他方法将在后续部分实现
}
// 启动插件
FlexibleContentArchiver::get_instance();
?>
智能归档的核心是内容分析,我们需要设计数据库表来存储分析结果:
<?php
/**
* 创建插件所需的数据库表
*/
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'fca_content_analysis';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
post_id bigint(20) NOT NULL,
relevance_score float DEFAULT 0,
category_suggestion varchar(255),
tags_suggestion text,
archive_status varchar(50) DEFAULT 'active',
last_analyzed datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY post_id (post_id),
KEY archive_status (archive_status)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
/**
* 内容分析核心类
*/
class ContentAnalyzer {
/**
* 分析文章内容并返回建议
* @param int $post_id 文章ID
* @return array 分析结果
*/
public static function analyze_post($post_id) {
$post = get_post($post_id);
if (!$post) {
return false;
}
$analysis = array(
'relevance_score' => self::calculate_relevance_score($post),
'category_suggestion' => self::suggest_categories($post),
'tags_suggestion' => self::extract_keywords($post),
'archive_priority' => self::determine_archive_priority($post)
);
return $analysis;
}
/**
* 计算内容相关性分数
* @param WP_Post $post 文章对象
* @return float 相关性分数(0-1)
*/
private static function calculate_relevance_score($post) {
$score = 0.5; // 基础分数
// 1. 基于发布时间计算时效性
$post_age = (time() - strtotime($post->post_date)) / (3600 * 24);
$timeliness = max(0, 1 - ($post_age / 365)); // 一年内线性衰减
// 2. 基于评论互动计算活跃度
$comment_count = get_comments_number($post->ID);
$engagement = min(1, $comment_count / 100); // 每100评论得1分,最高1分
// 3. 基于浏览量计算热度
$views = get_post_meta($post->ID, 'post_views', true) ?: 0;
$popularity = min(1, $views / 10000); // 每1万浏览量得1分
// 加权计算最终分数
$score = ($timeliness * 0.4) + ($engagement * 0.3) + ($popularity * 0.3);
return round($score, 3);
}
/**
* 智能推荐分类
* @param WP_Post $post 文章对象
* @return array 推荐分类ID数组
*/
private static function suggest_categories($post) {
$suggestions = array();
// 获取现有分类
$current_categories = wp_get_post_categories($post->ID, array('fields' => 'ids'));
// 基于内容关键词匹配分类
$content = $post->post_title . ' ' . $post->post_content;
$keywords = self::extract_keywords_from_text($content);
$all_categories = get_categories(array('hide_empty' => false));
foreach ($all_categories as $category) {
$category_score = 0;
// 检查分类名称是否包含关键词
foreach ($keywords as $keyword) {
if (stripos($category->name, $keyword) !== false) {
$category_score += 1;
}
}
// 检查分类描述是否包含关键词
foreach ($keywords as $keyword) {
if (stripos($category->description, $keyword) !== false) {
$category_score += 0.5;
}
}
if ($category_score > 0) {
$suggestions[$category->term_id] = $category_score;
}
}
// 按分数排序并返回前3个
arsort($suggestions);
return array_slice(array_keys($suggestions), 0, 3, true);
}
/**
* 从文本中提取关键词
* @param string $text 文本内容
* @return array 关键词数组
*/
private static function extract_keywords_from_text($text) {
// 移除HTML标签
$text = wp_strip_all_tags($text);
// 中文分词处理(简化版,实际应使用专业分词库)
if (preg_match('/[x{4e00}-x{9fa5}]/u', $text)) {
// 中文处理:按常见分隔符分割
$words = preg_split('/[s,,。!!??;;::""']+/u', $text);
} else {
// 英文处理:按单词分割
$words = str_word_count($text, 1);
}
// 移除停用词
$stop_words = array('的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这', 'the', 'and', 'a', 'an', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by');
$words = array_diff($words, $stop_words);
// 统计词频
$word_freq = array_count_values($words);
// 按频率排序并返回前10个关键词
arsort($word_freq);
return array_slice(array_keys($word_freq), 0, 10, true);
}
}
?>
<?php
/**
* 归档策略引擎
*/
class ArchivingStrategy {
/**
* 根据分析结果确定归档优先级
* @param WP_Post $post 文章对象
* @return string 归档优先级
*/
public static function determine_archive_priority($post) {
$analysis = ContentAnalyzer::analyze_post($post->ID);
$score = $analysis['relevance_score'];
if ($score < 0.3) {
return 'high'; // 高优先级归档
} elseif ($score < 0.6) {
return 'medium'; // 中等优先级
} else {
return 'low'; // 低优先级,保持活跃
}
}
/**
* 执行归档操作
* @param int $post_id 文章ID
* @param string $strategy 归档策略
*/
public static function archive_post($post_id, $strategy = 'smart') {
$post = get_post($post_id);
if (!$post) {
return false;
}
switch ($strategy) {
case 'smart':
self::smart_archive($post);
break;
case 'move_to_category':
self::move_to_archive_category($post);
break;
case 'change_status':
self::change_post_status($post);
break;
default:
self::smart_archive($post);
}
// 更新分析记录
self::update_analysis_record($post_id, 'archived');
return true;
}
/**
* 智能归档策略
* @param WP_Post $post 文章对象
*/
private static function smart_archive($post) {
$analysis = ContentAnalyzer::analyze_post($post->ID);
// 根据分数决定归档方式
if ($analysis['relevance_score'] < 0.2) {
// 分数极低:移动到归档分类并取消置顶
self::move_to_archive_category($post);
unstick_post($post->ID);
} elseif ($analysis['relevance_score'] < 0.4) {
// 分数较低:仅移动到归档分类
self::move_to_archive_category($post);
} else {
// 分数尚可:仅添加归档标签
self::add_archive_tag($post);
}
}
/**
* 移动到归档分类
* @param WP_Post $post 文章对象
*/
private static function move_to_archive_category($post) {
// 获取或创建归档分类
$archive_category = get_category_by_slug('archive');
if (!$archive_category) {
$archive_category = wp_create_category('归档内容');
}
// 设置文章分类(保留原有分类,增加归档分类)
$current_categories = wp_get_post_categories($post->ID, array('fields' => 'ids'));
$current_categories[] = $archive_category->term_id;
wp_set_post_categories($post->ID, $current_categories);
// 添加自定义字段标记
update_post_meta($post->ID, '_fca_archived', true);
update_post_meta($post->ID, '_fca_archived_date', current_time('mysql'));
}
/**
* 添加归档标签
* @param WP_Post $post 文章对象
*/
private static function add_archive_tag($post) {
// 获取或创建归档标签
$archive_tag = get_term_by('slug', 'archived', 'post_tag');
if (!$archive_tag) {
$archive_tag = wp_insert_term('已归档', 'post_tag', array('slug' => 'archived'));
}
// 添加标签
wp_set_post_tags($post->ID, '已归档', true);
// 添加自定义字段标记
update_post_meta($post->ID, '_fca_tagged_archive', true);
}
}
?>
<?php
/**
* 归档策略引擎
*/
class ArchivingStrategy {
/**
* 根据分析结果确定归档优先级
* @param WP_Post $post 文章对象
* @return string 归档优先级
*/
public static function determine_archive_priority($post) {
$analysis = ContentAnalyzer::analyze_post($post->ID);
$score = $analysis['relevance_score'];
if ($score < 0.3) {
return 'high'; // 高优先级归档
} elseif ($score < 0.6) {
return 'medium'; // 中等优先级
} else {
return 'low'; // 低优先级,保持活跃
}
}
/**
* 执行归档操作
* @param int $post_id 文章ID
* @param string $strategy 归档策略
*/
public static function archive_post($post_id, $strategy = 'smart') {
$post = get_post($post_id);
if (!$post) {
return false;
}
switch ($strategy) {
case 'smart':
self::smart_archive($post);
break;
case 'move_to_category':
self::move_to_archive_category($post);
break;
case 'change_status':
self::change_post_status($post);
break;
default:
self::smart_archive($post);
}
// 更新分析记录
self::update_analysis_record($post_id, 'archived');
return true;
}
/**
* 智能归档策略
* @param WP_Post $post 文章对象
*/
private static function smart_archive($post) {
$analysis = ContentAnalyzer::analyze_post($post->ID);
// 根据分数决定归档方式
if ($analysis['relevance_score'] < 0.2) {
// 分数极低:移动到归档分类并取消置顶
self::move_to_archive_category($post);
unstick_post($post->ID);
} elseif ($analysis['relevance_score'] < 0.4) {
// 分数较低:仅移动到归档分类
self::move_to_archive_category($post);
} else {
// 分数尚可:仅添加归档标签
self::add_archive_tag($post);
}
}
/**
* 移动到归档分类
* @param WP_Post $post 文章对象
*/
private static function move_to_archive_category($post) {
// 获取或创建归档分类
$archive_category = get_category_by_slug('archive');
if (!$archive_category) {
$archive_category = wp_create_category('归档内容');
}
// 设置文章分类(保留原有分类,增加归档分类)
$current_categories = wp_get_post_categories($post->ID, array('fields' => 'ids'));
$current_categories[] = $archive_category->term_id;
wp_set_post_categories($post->ID, $current_categories);
// 添加自定义字段标记
update_post_meta($post->ID, '_fca_archived', true);
update_post_meta($post->ID, '_fca_archived_date', current_time('mysql'));
}
/**
* 添加归档标签
* @param WP_Post $post 文章对象
*/
private static function add_archive_tag($post) {
// 获取或创建归档标签
$archive_tag = get_term_by('slug', 'archived', 'post_tag');
if (!$archive_tag) {
$archive_tag = wp_insert_term('已归档', 'post_tag', array('slug' => 'archived'));
}
// 添加标签
wp_set_post_tags($post->ID, '已归档', true);
// 添加自定义字段标记
update_post_meta($post->ID, '_fca_tagged_archive', true);
}
}
?>
<?php
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'智能归档设置',
'内容归档',
'manage_options',
'fca-settings',
array($this, 'render_settings_page'),
'dashicons-archive',
30
);
add_submenu_page(
'fca-settings',
'归档分析报告',
'分析报告',
'manage_options',
'fca-analytics',
array($this, 'render_analytics_page')
);
add_submenu_page(
'fca-settings',
'批量归档操作',
'批量操作',
'manage_options',
'fca-batch',
array($this, 'render_batch_page')
);
}
/**
* 渲染设置页面
*/
public function render_settings_page() {
?>
<div class="wrap">
<h1>柔性内容智能归档设置</h1>
<form method="post" action="options.php">
<?php
settings_fields('fca_settings_group');
do_settings_sections('fca-settings');
submit_button();
?>
</form>
<div class="fca-status-box">
<h3>系统状态</h3>
<p>已分析文章: <?php echo $this->get_analyzed_count(); ?> 篇</p>
<p>已归档文章: <?php echo $this->get_archived_count(); ?> 篇</p>
<p>下次自动归档: <?php echo date('Y-m-d H:i:s', wp_next_scheduled('fca_daily_archiving')); ?></p>
</div>
</div>
<?php
}
/**
* 初始化设置选项
*/
public function init() {
// 注册设置
register_setting('fca_settings_group', 'fca_auto_archive');
register_setting('fca_settings_group', 'fca_relevance_threshold');
register_setting('fca_settings_group', 'fca_excluded_categories');
// 添加设置部分
add_settings_section(
'fca_main_section',
'归档策略设置',
null,
'fca-settings'
);
// 自动归档选项
add_settings_field(
'fca_auto_archive',
'启用自动归档',
array($this, 'render_auto_archive_field'),
'fca-settings',
'fca_main_section'
);
// 相关性阈值选项
add_settings_field(
'fca_relevance_threshold',
'归档相关性阈值',
array($this, 'render_threshold_field'),
'fca-settings',
'fca_main_section'
);
}
/**
* 渲染自动归档字段
*/
public function render_auto_archive_field() {
$option = get_option('fca_auto_archive', '1');
?>
<input type="checkbox" name="fca_auto_archive" value="1" <?php checked(1, $option); ?> />
<label>启用每日自动归档(推荐)</label>
<p class="description">系统将每天自动分析并归档低相关性内容</p>
<?php
}
/**
* 渲染阈值字段
*/
public function render_threshold_field() {
$option = get_option('fca_relevance_threshold', '0.3');
?>
<input type="range" name="fca_relevance_threshold" min="0" max="1" step="0.05"
value="<?php echo esc_attr($option); ?>"
oninput="this.nextElementSibling.value = this.value" />
<output><?php echo esc_attr($option); ?></output>
<p class="description">相关性分数低于此值的内容将被自动归档(0-1,值越小越严格)</p>
<?php
}
?>
<?php
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'智能归档设置',
'内容归档',
'manage_options',
'fca-settings',
array($this, 'render_settings_page'),
'dashicons-archive',
30
);
add_submenu_page(
'fca-settings',
'归档分析报告',
'分析报告',
'manage_options',
'fca-analytics',
array($this, 'render_analytics_page')
);
add_submenu_page(
'fca-settings',
'批量归档操作',
'批量操作',
'manage_options',
'fca-batch',
array($this, 'render_batch_page')
);
}
/**
* 渲染设置页面
*/
public function render_settings_page() {
?>
<div class="wrap">
<h1>柔性内容智能归档设置</h1>
<form method="post" action="options.php">
<?php
settings_fields('fca_settings_group');
do_settings_sections('fca-settings');
submit_button();
?>
</form>
<div class="fca-status-box">
<h3>系统状态</h3>
<p>已分析文章: <?php echo $this->get_analyzed_count(); ?> 篇</p>
<p>已归档文章: <?php echo $this->get_archived_count(); ?> 篇</p>
<p>下次自动归档: <?php echo date('Y-m-d H:i:s', wp_next_scheduled('fca_daily_archiving')); ?></p>
</div>
</div>
<?php
}
/**
* 初始化设置选项
*/
public function init() {
// 注册设置
register_setting('fca_settings_group', 'fca_auto_archive');
register_setting('fca_settings_group', 'fca_relevance_threshold');
register_setting('fca_settings_group', 'fca_excluded_categories');
// 添加设置部分
add_settings_section(
'fca_main_section',
'归档策略设置',
null,
'fca-settings'
);
// 自动归档选项
add_settings_field(
'fca_auto_archive',
'启用自动归档',
array($this, 'render_auto_archive_field'),
'fca-settings',
'fca_main_section'
);
// 相关性阈值选项
add_settings_field(
'fca_relevance_threshold',
'归档相关性阈值',
array($this, 'render_threshold_field'),
'fca-settings',
'fca_main_section'
);
}
/**
* 渲染自动归档字段
*/
public function render_auto_archive_field() {
$option = get_option('fca_auto_archive', '1');
?>
<input type="checkbox" name="fca_auto_archive" value="1" <?php checked(1, $option); ?> />
<label>启用每日自动归档(推荐)</label>
<p class="description">系统将每天自动分析并归档低相关性内容</p>
<?php
}
/**
* 渲染阈值字段
*/
public function render_threshold_field() {
$option = get_option('fca_relevance_threshold', '0.3');
?>
<input type="range" name="fca_relevance_threshold" min="0" max="1" step="0.05"
value="<?php echo esc_attr($option); ?>"
oninput="this.nextElementSibling.value = this.value" />
<output><?php echo esc_attr($option); ?></output>
<p class="description">相关性分数低于此值的内容将被自动归档(0-1,值越小越严格)</p>
<?php
}
?>
<?php
/**
* 每日归档任务
*/
public function daily_archiving_task() {
global $wpdb;
// 检查是否启用自动归档
if (!get_option('fca_auto_archive', '1')) {
return;
}
$threshold = floatval(get_option('fca_relevance_threshold', '0.3'));
// 获取需要归档的文章
$query = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 50,
'meta_query' => array(
<?php
/**
* 每日归档任务
*/
public function daily_archiving_task() {
global $wpdb;
// 检查是否启用自动归档
if (!get_option('fca_auto_archive', '1')) {
return;
}
$threshold = floatval(get_option('fca_relevance_threshold', '0.3'));
// 获取需要归档的文章
$query = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 50,
'meta_query' => array(
'OR' => array(
array(
'key' => '_fca_archived',
'compare' => 'NOT EXISTS'
),
array(
'key' => '_fca_archived',
'value' => '1',
'compare' => '!='
)
)
),
'date_query' => array(
array(
'before' => date('Y-m-d', strtotime('-30 days')),
'inclusive' => true,
)
)
));
$archived_count = 0;
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
// 分析文章
$analysis = ContentAnalyzer::analyze_post($post_id);
// 检查是否达到归档阈值
if ($analysis['relevance_score'] < $threshold) {
// 执行归档
ArchivingStrategy::archive_post($post_id, 'smart');
$archived_count++;
// 记录日志
$this->log_archiving_action($post_id, 'auto', $analysis['relevance_score']);
}
// 更新分析记录
$this->update_analysis_record($post_id, $analysis);
}
wp_reset_postdata();
}
// 发送通知(可选)
if ($archived_count > 0) {
$this->send_admin_notification($archived_count);
}
}
/**
- 更新分析记录
*/
private function update_analysis_record($post_id, $analysis) {
global $wpdb;
$table_name = $wpdb->prefix . 'fca_content_analysis';
// 检查记录是否存在
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name WHERE post_id = %d",
$post_id
));
$data = array(
'post_id' => $post_id,
'relevance_score' => $analysis['relevance_score'],
'category_suggestion' => implode(',', $analysis['category_suggestion']),
'tags_suggestion' => implode(',', $analysis['tags_suggestion']),
'last_analyzed' => current_time('mysql')
);
if ($existing) {
$wpdb->update($table_name, $data, array('post_id' => $post_id));
} else {
$wpdb->insert($table_name, $data);
}
}
/**
- 批量归档处理
*/
public function process_batch_archiving($post_ids, $strategy = 'smart') {
$results = array(
'success' => 0,
'failed' => 0,
'details' => array()
);
foreach ($post_ids as $post_id) {
try {
$success = ArchivingStrategy::archive_post($post_id, $strategy);
if ($success) {
$results['success']++;
$results['details'][] = array(
'post_id' => $post_id,
'status' => 'success',
'message' => '文章已成功归档'
);
} else {
$results['failed']++;
$results['details'][] = array(
'post_id' => $post_id,
'status' => 'failed',
'message' => '归档失败'
);
}
} catch (Exception $e) {
$results['failed']++;
$results['details'][] = array(
'post_id' => $post_id,
'status' => 'error',
'message' => $e->getMessage()
);
}
}
return $results;
}
/**
- 渲染批量操作页面
*/
public function render_batch_page() {
// 处理批量操作请求
if (isset($_POST['fca_batch_action']) && check_admin_referer('fca_batch_action')) {
$post_ids = isset($_POST['post_ids']) ? array_map('intval', $_POST['post_ids']) : array();
$strategy = isset($_POST['archive_strategy']) ? sanitize_text_field($_POST['archive_strategy']) : 'smart';
if (!empty($post_ids)) {
$results = $this->process_batch_archiving($post_ids, $strategy);
echo '<div class="notice notice-success"><p>';
echo sprintf('批量归档完成!成功:%d,失败:%d', $results['success'], $results['failed']);
echo '</p></div>';
}
}
// 查询可归档的文章
$query = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 100,
'meta_query' => array(
array(
'key' => '_fca_archived',
'compare' => 'NOT EXISTS'
)
),
'orderby' => 'date',
'order' => 'ASC'
));
?>
<div class="wrap">
<h1>批量归档操作</h1>
<form method="post" action="">
<?php wp_nonce_field('fca_batch_action'); ?>
<div class="fca-batch-controls">
<h3>选择归档策略</h3>
<select name="archive_strategy">
<option value="smart">智能归档(推荐)</option>
<option value="move_to_category">移动到归档分类</option>
<option value="change_status">更改文章状态</option>
</select>
<button type="button" class="button" id="fca-select-all">全选</button>
<button type="button" class="button" id="fca-deselect-all">取消全选</button>
<input type="submit" name="fca_batch_action"
class="button button-primary" value="执行批量归档"
onclick="return confirm('确定要归档选中的文章吗?')">
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th class="check-column"><input type="checkbox" id="fca-check-all"></th>
<th>文章标题</th>
<th>发布日期</th>
<th>相关性分数</th>
<th>建议操作</th>
</tr>
</thead>
<tbody>
<?php if ($query->have_posts()): ?>
<?php while ($query->have_posts()): $query->the_post(); ?>
<?php
$post_id = get_the_ID();
$analysis = ContentAnalyzer::analyze_post($post_id);
$priority = ArchivingStrategy::determine_archive_priority(get_post($post_id));
?>
<tr>
<td><input type="checkbox" name="post_ids[]" value="<?php echo $post_id; ?>"></td>
<td>
<strong><?php the_title(); ?></strong>
<div class="row-actions">
<a href="<?php echo get_edit_post_link(); ?>">编辑</a> |
<a href="<?php the_permalink(); ?>" target="_blank">查看</a>
</div>
</td>
<td><?php echo get_the_date(); ?></td>
<td>
<div class="fca-score-indicator">
<div class="fca-score-bar" style="width: <?php echo $analysis['relevance_score'] * 100; ?>%"></div>
<span class="fca-score-text"><?php echo round($analysis['relevance_score'], 3); ?></span>
</div>
</td>
<td>
<?php
$action_text = '';
$action_class = '';
switch ($priority) {
case 'high':
$action_text = '立即归档';
$action_class = 'fca-high-priority';
break;
case 'medium':
$action_text = '建议归档';
$action_class = 'fca-medium-priority';
break;
case 'low':
$action_text = '保持活跃';
$action_class = 'fca-low-priority';
break;
}
?>
<span class="fca-action-badge <?php echo $action_class; ?>">
<?php echo $action_text; ?>
</span>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5">没有找到需要归档的文章。</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</form>
</div>
<script>
jQuery(document).ready(function($) {
// 全选/取消全选功能
$('#fca-check-all').on('change', function() {
$('input[name="post_ids[]"]').prop('checked', this.checked);
});
$('#fca-select-all').on('click', function() {
$('input[name="post_ids[]"]').prop('checked', true);
$('#fca-check-all').prop('checked', true);
});
$('#fca-deselect-all').on('click', function() {
$('input[name="post_ids[]"]').prop('checked', false);
$('#fca-check-all').prop('checked', false);
});
});
</script>
<style>
.fca-score-indicator {
position: relative;
height: 20px;
background: #f0f0f0;
border-radius: 3px;
overflow: hidden;
}
.fca-score-bar {
height: 100%;
background: linear-gradient(90deg, #dc3232, #ffb900, #46b450);
transition: width 0.3s ease;
}
.fca-score-text {
position: absolute;
top: 0;
left: 0;
right: 0;
text-align: center;
line-height: 20px;
font-size: 12px;
font-weight: bold;
color: #000;
}
.fca-action-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.fca-high-priority { background: #dc3232; color: white; }
.fca-medium-priority { background: #ffb900; color: #000; }
.fca-low-priority { background: #46b450; color: white; }
</style>
<?php
wp_reset_postdata();
}
?>
## 七、前端展示与短代码支持
<?php
/**
- 添加快捷短代码支持
*/
public function init() {
// ... 之前的初始化代码 ...
// 注册短代码
add_shortcode('archive_content', array($this, 'render_archive_shortcode'));
// 添加小工具
add_action('widgets_init', array($this, 'register_widgets'));
}
/**
- 归档内容短代码
*/
public function render_archive_shortcode($atts) {
$atts = shortcode_atts(array(
'category' => 'archive',
'limit' => 10,
'show_date' => true,
'layout' => 'list'
), $atts, 'archive_content');
$query_args = array(
'post_type' => 'post',
'posts_per_page' => intval($atts['limit']),
'category_name' => sanitize_text_field($atts['category']),
'post_status' => 'publish'
);
$archive_query = new WP_Query($query_args);
if (!$archive_query->have_posts()) {
return '<p>暂无归档内容。</p>';
}
ob_start();
if ($atts['layout'] === 'grid') {
echo '<div class="fca-archive-grid">';
while ($archive_query->have_posts()) {
$archive_query->the_post();
?>
<div class="fca-archive-item">
<h4><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4>
<?php if ($atts['show_date']): ?>
<span class="fca-archive-date"><?php echo get_the_date(); ?></span>
<?php endif; ?>
<div class="fca-archive-excerpt">
<?php echo wp_trim_words(get_the_excerpt(), 20); ?>
</div>
</div>
<?php
}
echo '</div>';
} else {
echo '<ul class="fca-archive-list">';
while ($archive_query->have_posts()) {
$archive_query->the_post();
?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
<?php if ($atts['show_date']): ?>
<span class="fca-archive-date">(<?php echo get_the_date(); ?>)</span>
<?php endif; ?>
</li>
<?php
}
echo '</ul>';
}
wp_reset_postdata();
return ob_get_clean();
}
/**
- 注册归档小工具
*/
public function register_widgets() {
register_widget('FCA_Archive_Widget');
}
/**
- 归档小工具类
*/
class FCA_Archive_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'fca_archive_widget',
'智能归档内容',
array('description' => '显示智能归档的文章列表')
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
$title = !empty($instance['title']) ? $instance['title'] : '归档内容';
$limit = !empty($instance['limit']) ? $instance['limit'] : 5;
echo $args['before_title'] . esc_html($title) . $args['after_title'];
// 查询归档内容
$query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => $limit,
'meta_query' => array(
array(
'key' => '_fca_archived',
'value' => '1',
'compare' => '='
)
),
'orderby' => 'meta_value',
'meta_key' => '_fca_archived_date',
'order' => 'DESC'
));
if ($query->have_posts()) {
echo '<ul class="fca-widget-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<li>';
echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
echo '<br><small>' . get_the_date() . '</small>';
echo '</li>';
}
echo '</ul>';
} else {
echo '<p>暂无归档内容。</p>';
}
wp_reset_postdata();
echo $args['after_widget'];
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : '归档内容';
$limit = !empty($instance['limit']) ? $instance['limit'] : 5;
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">标题:</label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"
name="<?php echo $this->get_field_name('title'); ?>"
type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('limit'); ?>">显示数量:</label>
<input class="tiny-text" id="<?php echo $this->get_field_id('limit'); ?>"
name="<?php echo $this->get_field_name('limit'); ?>"
type="number" step="1" min="1" max="20"
value="<?php echo esc_attr($limit); ?>">
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
$instance['limit'] = !empty($new_instance['limit']) ? intval($new_instance['limit']) : 5;
return $instance;
}
}
?>
## 八、插件优化与扩展建议
### 8.1 性能优化建议
<?php
/**
- 添加缓存机制
*/
class FCACache {
private static $cache_group = 'fca_analysis';
public static function get_analysis($post_id) {
$cached = wp_cache_get($post_id, self::$cache_group);
if (false !== $cached) {
return $cached;
}
// 从数据库获取
global $wpdb;
$table_name = $wpdb->prefix . 'fca_content_analysis';
$result = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name WHERE post_id = %d",
$post_id
), ARRAY_A);
if ($result) {
wp_cache_set($post_id, $result, self::$cache_group, 3600); // 缓存1小时
}
return $result;
}
public static function clear_cache($post_id = null) {
if ($post_id) {
wp_cache_delete($post_id, self::$cache_group);
} else {
wp_cache_flush();
}
}
}
/**
- 添加索引优化查询
*/
private function optimize_database() {
global $wpdb;
$table_name = $wpdb->prefix . 'fca_content_analysis';
// 添加复合索引
$wpdb->query("ALTER TABLE $table_name ADD INDEX idx_score_status (relevance_score, archive_status)


