首页 / 教程文章 / 网络传媒柔性内容分发的WordPress插件开发教程

网络传媒柔性内容分发的WordPress插件开发教程

网络传媒柔性内容分发的WordPress插件开发教程

引言:柔性内容分发的重要性

在当今网络传媒环境中,内容分发不再局限于简单的"一对多"广播模式。柔性内容分发能够根据用户特征、行为数据、设备类型和上下文环境,智能地调整内容呈现方式,从而提升用户体验和内容传播效果。对于WordPress站点来说,开发一个灵活的柔性内容分发插件,可以帮助内容创作者更精准地触达目标受众。

本教程将引导您开发一个完整的WordPress柔性内容分发插件,包含用户画像分析、内容智能匹配和动态渲染等功能。

插件基础架构设计

首先,我们需要创建插件的基本结构。在WordPress的wp-content/plugins/目录下创建一个新文件夹flexible-content-distribution

<?php
/**
 * Plugin Name: 柔性内容分发系统
 * Plugin URI: https://yourwebsite.com/
 * Description: 基于用户画像的智能内容分发插件
 * Version: 1.0.0
 * Author: 您的名字
 * License: GPL v2 or later
 * Text Domain: flexible-content-distribution
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('FCD_VERSION', '1.0.0');
define('FCD_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FCD_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
class FlexibleContentDistribution {
    
    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('plugins_loaded', array($this, 'init'));
    }
    
    public function activate() {
        // 创建必要的数据库表
        $this->create_tables();
        
        // 设置默认选项
        $this->set_default_options();
        
        // 刷新重写规则
        flush_rewrite_rules();
    }
    
    public function deactivate() {
        // 清理临时数据
        delete_transient('fcd_user_profiles_cache');
        
        // 刷新重写规则
        flush_rewrite_rules();
    }
    
    public function init() {
        // 加载文本域
        load_plugin_textdomain('flexible-content-distribution', false, dirname(plugin_basename(__FILE__)) . '/languages');
        
        // 加载模块
        $this->load_modules();
    }
    
    private function create_tables() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        $table_name = $wpdb->prefix . 'fcd_user_profiles';
        
        $sql = "CREATE TABLE IF NOT EXISTS $table_name (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            user_id bigint(20) NOT NULL,
            device_type varchar(50),
            location varchar(100),
            interests text,
            reading_history text,
            last_updated datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY user_id (user_id)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
    
    private function set_default_options() {
        $default_options = array(
            'enable_user_tracking' => true,
            'content_matching_algorithm' => 'hybrid',
            'default_content_strategy' => 'popular',
            'cache_duration' => 3600
        );
        
        add_option('fcd_settings', $default_options);
    }
    
    private function load_modules() {
        // 加载核心模块
        require_once FCD_PLUGIN_DIR . 'includes/class-user-profile.php';
        require_once FCD_PLUGIN_DIR . 'includes/class-content-matcher.php';
        require_once FCD_PLUGIN_DIR . 'includes/class-content-renderer.php';
        
        // 加载管理界面
        if (is_admin()) {
            require_once FCD_PLUGIN_DIR . 'admin/class-admin-settings.php';
        }
    }
}

// 启动插件
FlexibleContentDistribution::get_instance();
?>

用户画像系统开发

用户画像是柔性内容分发的核心。我们需要收集和分析用户数据来创建个性化画像。

<?php
// 文件路径: includes/class-user-profile.php

class FCD_User_Profile {
    
    private $user_id;
    private $profile_data;
    
    public function __construct($user_id = null) {
        $this->user_id = $user_id ?: get_current_user_id();
        $this->load_profile();
    }
    
    /**
     * 加载用户画像数据
     */
    private function load_profile() {
        global $wpdb;
        
        if ($this->user_id <= 0) {
            $this->profile_data = $this->get_anonymous_profile();
            return;
        }
        
        $table_name = $wpdb->prefix . 'fcd_user_profiles';
        
        // 尝试从数据库获取
        $profile = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_name WHERE user_id = %d",
            $this->user_id
        ));
        
        if ($profile) {
            $this->profile_data = $this->parse_profile_data($profile);
        } else {
            $this->profile_data = $this->create_new_profile();
        }
        
        // 更新用户行为数据
        $this->update_reading_history();
    }
    
    /**
     * 为匿名用户创建基础画像
     */
    private function get_anonymous_profile() {
        $device_type = $this->detect_device();
        $location = $this->estimate_location();
        
        return array(
            'user_id' => 0,
            'device_type' => $device_type,
            'location' => $location,
            'interests' => array(),
            'reading_history' => array(),
            'user_type' => 'anonymous'
        );
    }
    
    /**
     * 检测用户设备类型
     */
    private function detect_device() {
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        if (preg_match('/(mobile|android|iphone|ipad)/i', $user_agent)) {
            return 'mobile';
        } elseif (preg_match('/(tablet|ipad)/i', $user_agent)) {
            return 'tablet';
        } else {
            return 'desktop';
        }
    }
    
    /**
     * 估计用户地理位置
     */
    private function estimate_location() {
        // 注意:在实际应用中,您需要遵守GDPR等隐私法规
        // 这里使用简化版本,实际应使用IP地理定位服务
        
        $ip = $_SERVER['REMOTE_ADDR'] ?? '';
        
        // 简单示例:根据IP前几位判断(实际项目请使用专业服务)
        if (strpos($ip, '192.168.') === 0) {
            return 'local';
        }
        
        // 默认返回未知
        return 'unknown';
    }
    
    /**
     * 更新用户阅读历史
     */
    private function update_reading_history() {
        if (is_single() && !is_admin()) {
            $post_id = get_the_ID();
            $category_ids = wp_get_post_categories($post_id);
            
            if (!isset($this->profile_data['reading_history'])) {
                $this->profile_data['reading_history'] = array();
            }
            
            // 添加当前文章到阅读历史
            $this->profile_data['reading_history'][] = array(
                'post_id' => $post_id,
                'timestamp' => current_time('timestamp'),
                'categories' => $category_ids
            );
            
            // 保持最近50条记录
            if (count($this->profile_data['reading_history']) > 50) {
                $this->profile_data['reading_history'] = array_slice(
                    $this->profile_data['reading_history'], 
                    -50
                );
            }
            
            // 更新兴趣标签
            $this->update_interests($category_ids);
            
            // 保存到数据库(如果是注册用户)
            $this->save_profile();
        }
    }
    
    /**
     * 根据阅读历史更新兴趣标签
     */
    private function update_interests($category_ids) {
        if (!isset($this->profile_data['interests'])) {
            $this->profile_data['interests'] = array();
        }
        
        foreach ($category_ids as $cat_id) {
            $cat_name = get_cat_name($cat_id);
            
            if (isset($this->profile_data['interests'][$cat_id])) {
                $this->profile_data['interests'][$cat_id]['weight'] += 1;
                $this->profile_data['interests'][$cat_id]['last_seen'] = current_time('timestamp');
            } else {
                $this->profile_data['interests'][$cat_id] = array(
                    'name' => $cat_name,
                    'weight' => 1,
                    'last_seen' => current_time('timestamp')
                );
            }
        }
        
        // 归一化权重(保持总和为100)
        $total_weight = array_sum(array_column($this->profile_data['interests'], 'weight'));
        if ($total_weight > 0) {
            foreach ($this->profile_data['interests'] as $cat_id => $interest) {
                $this->profile_data['interests'][$cat_id]['normalized_weight'] = 
                    ($interest['weight'] / $total_weight) * 100;
            }
        }
    }
    
    /**
     * 获取用户兴趣标签
     */
    public function get_top_interests($limit = 5) {
        if (empty($this->profile_data['interests'])) {
            return array();
        }
        
        $interests = $this->profile_data['interests'];
        
        // 按权重排序
        uasort($interests, function($a, $b) {
            return $b['normalized_weight'] <=> $a['normalized_weight'];
        });
        
        // 返回前N个兴趣
        return array_slice($interests, 0, $limit, true);
    }
    
    /**
     * 保存用户画像到数据库
     */
    public function save_profile() {
        global $wpdb;
        
        if ($this->user_id <= 0) {
            return false; // 不保存匿名用户数据
        }
        
        $table_name = $wpdb->prefix . 'fcd_user_profiles';
        
        $data = array(
            'user_id' => $this->user_id,
            'device_type' => $this->profile_data['device_type'],
            'location' => $this->profile_data['location'],
            'interests' => json_encode($this->profile_data['interests']),
            'reading_history' => json_encode($this->profile_data['reading_history']),
            'last_updated' => current_time('mysql')
        );
        
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM $table_name WHERE user_id = %d",
            $this->user_id
        ));
        
        if ($existing) {
            $wpdb->update($table_name, $data, array('user_id' => $this->user_id));
        } else {
            $wpdb->insert($table_name, $data);
        }
        
        return true;
    }
}
?>

智能内容匹配算法

有了用户画像后,我们需要开发内容匹配算法,根据用户特征推荐最合适的内容。

<?php
// 文件路径: includes/class-content-matcher.php

class FCD_Content_Matcher {
    
    private $user_profile;
    private $algorithm;
    
    public function __construct($user_profile = null) {
        $this->user_profile = $user_profile ?: new FCD_User_Profile();
        $this->algorithm = get_option('fcd_settings')['content_matching_algorithm'] ?? 'hybrid';
    }
    
    /**
     * 获取推荐内容
     */
    public function get_recommended_posts($limit = 5, $exclude_ids = array()) {
        switch ($this->algorithm) {
            case 'interest_based':
                return $this->get_interest_based_posts($limit, $exclude_ids);
            case 'collaborative':
                return $this->get_collaborative_posts($limit, $exclude_ids);
            case 'hybrid':
            default:
                return $this->get_hybrid_recommendations($limit, $exclude_ids);
        }
    }
    
    /**
     * 基于兴趣的内容推荐
     */
    private function get_interest_based_posts($limit, $exclude_ids) {
        $interests = $this->user_profile->get_top_interests(3);
        
        if (empty($interests)) {
            return $this->get_fallback_posts($limit, $exclude_ids);
        }
        
        $interest_ids = array_keys($interests);
        
        $args = array(
            'post_type' => 'post',
            'posts_per_page' => $limit * 2, // 获取更多以便筛选
            'category__in' => $interest_ids,
            'post__not_in' => $exclude_ids,
            'orderby' => 'date',
            'order' => 'DESC',
            'meta_query' => array(
                array(
                    'key' => '_thumbnail_id',
                    'compare' => 'EXISTS' // 优先推荐有特色图片的文章
                )
            )
        );
        
        $posts = get_posts($args);
        
        // 按兴趣权重排序
        usort($posts, function($a, $b) use ($interests) {
            $a_cats = wp_get_post_categories($a->ID);
            $b_cats = wp_get_post_categories($b->ID);
            
            $a_score = $this->calculate_interest_score($a_cats, $interests);
            $b_score = $this->calculate_interest_score($b_cats, $interests);
            
            return $b_score <=> $a_score;
        });
        
        return array_slice($posts, 0, $limit);
    }
    
    /**
     * 计算文章兴趣匹配分数
     */
    private function calculate_interest_score($post_categories, $user_interests) {
        $score = 0;
        
        foreach ($post_categories as $cat_id) {
            if (isset($user_interests[$cat_id])) {
                $score += $user_interests[$cat_id]['normalized_weight'];
            }
        }
        
        return $score;
    }
    
    /**
     * 协同过滤推荐(简化版)
     */
    private function get_collaborative_posts($limit, $exclude_ids) {
        // 注意:完整协同过滤需要大量用户数据
        // 这里实现一个简化版本
        
        global $wpdb;
        
        // 获取与当前用户兴趣相似的其他用户
        $similar_users = $this->find_similar_users(5);
        
        if (empty($similar_users)) {
            return $this->get_fallback_posts($limit, $exclude_ids);
        }
        
        $user_ids = implode(',', $similar_users);
        
        // 获取这些用户阅读过但当前用户未读的文章
        $query = "
            SELECT DISTINCT p.ID, p.post_title, COUNT(up.user_id) as read_count
            FROM {$wpdb->posts} p
            INNER JOIN {$wpdb->prefix}fcd_user_profiles up 
                ON JSON_CONTAINS(up.reading_history, CAST(p.ID AS JSON), '$')
            WHERE p.post_type = 'post'
            AND p.post_status = 'publish'
            AND up.user_id IN ($user_ids)
            AND p.ID NOT IN (
                SELECT DISTINCT JSON_EXTRACT(reading_history, '$[*].post_id')
                FROM {$wpdb->prefix}fcd_user_profiles
                WHERE user_id = %d
            )
            GROUP BY p.ID
            ORDER BY read_count DESC
            LIMIT %d
        ";
        
        $results = $wpdb->get_results($wpdb->prepare(
            $query, 
            $this->user_profile->user_id, 
            $limit
        ));
        
        return $results;
    }
    
    /**
     * 混合推荐算法
     */
    private function get_hybrid_recommendations($limit, $exclude_ids) {
        $interest_posts = $this->get_interest_based_posts(ceil($limit * 0.7), $exclude_ids);
        $collaborative_posts = $this->get_collaborative_posts(ceil($limit * 0.3), $exclude_ids);
        
        $all_posts = array_merge($interest_posts, $collaborative_posts);
        
        // 去重
        $unique_posts = array();
        foreach ($all_posts as $post) {
            $unique_posts[$post->ID] = $post;
        }
        
        // 随机排序以避免总是相同的顺序
        shuffle($unique_posts);
        
        return array_slice($unique_posts, 0, $limit);
    }
    
    /**
     * 备用推荐(当个性化推荐不足时)
     */
    private function get_fallback_posts($limit, $exclude_ids) {
        $args = array(
            'post_type' => 'post',
            'posts_per_page' => $limit,
            'post__not_in' => $exclude_ids,
            'orderby' => 'rand',
            'meta_key' => '_fcd_popularity',
            'order' => 'DESC'
        );
        
        return get_posts($args);
    }
}
?>

动态内容渲染器

最后,我们需要开发内容渲染器,根据用户设备和上下文动态调整内容呈现。

<?php
// 文件路径: includes/class-content-renderer.php

class FCD_Content_Renderer {
    
    private $user_profile;
    private $content_matcher;
    
    public function __construct() {
        $this->user_profile = new FCD_User_Profile();
<?php
// 文件路径: includes/class-content-renderer.php

class FCD_Content_Renderer {
    
    private $user_profile;
    private $content_matcher;
    
    public function __construct() {
        $this->user_profile = new FCD_User_Profile();
        $this->content_matcher = new FCD_Content_Matcher($this->user_profile);
        
        // 注册短代码
        add_shortcode('flexible_content', array($this, 'render_flexible_content_shortcode'));
        
        // 在文章内容中自动插入相关内容
        add_filter('the_content', array($this, 'auto_insert_related_content'), 20);
        
        // 注册小工具
        add_action('widgets_init', array($this, 'register_widgets'));
    }
    
    /**
     * 渲染柔性内容分发区块
     */
    public function render_flexible_content($args = array()) {
        $defaults = array(
            'title' => '为您推荐',
            'limit' => 5,
            'layout' => $this->detect_best_layout(),
            'show_excerpt' => true,
            'show_thumbnail' => true,
            'cache_duration' => 3600
        );
        
        $args = wp_parse_args($args, $defaults);
        
        // 生成缓存键
        $cache_key = 'fcd_content_' . md5(serialize($args) . $this->user_profile->user_id);
        
        // 尝试从缓存获取
        $cached_content = get_transient($cache_key);
        if ($cached_content !== false) {
            return $cached_content;
        }
        
        // 获取推荐内容
        $exclude_ids = is_single() ? array(get_the_ID()) : array();
        $recommended_posts = $this->content_matcher->get_recommended_posts($args['limit'], $exclude_ids);
        
        if (empty($recommended_posts)) {
            return '<p class="fcd-no-content">暂无推荐内容</p>';
        }
        
        // 根据布局渲染内容
        $output = $this->render_by_layout($recommended_posts, $args);
        
        // 缓存结果
        set_transient($cache_key, $output, $args['cache_duration']);
        
        return $output;
    }
    
    /**
     * 检测最佳布局
     */
    private function detect_best_layout() {
        $device_type = $this->user_profile->device_type;
        
        switch ($device_type) {
            case 'mobile':
                return 'list_compact';
            case 'tablet':
                return 'grid_2col';
            default:
                return 'grid_3col';
        }
    }
    
    /**
     * 根据布局渲染内容
     */
    private function render_by_layout($posts, $args) {
        $layout_method = 'render_' . $args['layout'];
        
        if (method_exists($this, $layout_method)) {
            return $this->$layout_method($posts, $args);
        }
        
        // 默认使用网格布局
        return $this->render_grid_3col($posts, $args);
    }
    
    /**
     * 渲染紧凑列表布局(适合移动端)
     */
    private function render_list_compact($posts, $args) {
        $output = '<div class="fcd-container fcd-layout-list-compact">';
        
        if (!empty($args['title'])) {
            $output .= '<h3 class="fcd-title">' . esc_html($args['title']) . '</h3>';
        }
        
        $output .= '<div class="fcd-list">';
        
        foreach ($posts as $post) {
            $output .= $this->render_list_item($post, $args);
        }
        
        $output .= '</div></div>';
        
        return $output;
    }
    
    /**
     * 渲染网格布局(适合桌面端)
     */
    private function render_grid_3col($posts, $args) {
        $output = '<div class="fcd-container fcd-layout-grid-3col">';
        
        if (!empty($args['title'])) {
            $output .= '<h3 class="fcd-title">' . esc_html($args['title']) . '</h3>';
        }
        
        $output .= '<div class="fcd-grid">';
        
        foreach ($posts as $post) {
            $output .= $this->render_grid_item($post, $args);
        }
        
        $output .= '</div></div>';
        
        return $output;
    }
    
    /**
     * 渲染列表项
     */
    private function render_list_item($post, $args) {
        $permalink = get_permalink($post->ID);
        $title = get_the_title($post->ID);
        $excerpt = $args['show_excerpt'] ? $this->get_adaptive_excerpt($post) : '';
        
        $output = '<div class="fcd-list-item">';
        
        if ($args['show_thumbnail']) {
            $thumbnail = $this->get_adaptive_thumbnail($post->ID);
            if ($thumbnail) {
                $output .= '<div class="fcd-thumbnail">';
                $output .= '<a href="' . esc_url($permalink) . '">' . $thumbnail . '</a>';
                $output .= '</div>';
            }
        }
        
        $output .= '<div class="fcd-content">';
        $output .= '<h4 class="fcd-post-title"><a href="' . esc_url($permalink) . '">' . esc_html($title) . '</a></h4>';
        
        if ($excerpt) {
            $output .= '<div class="fcd-excerpt">' . $excerpt . '</div>';
        }
        
        // 显示相关性标签
        $relevance = $this->calculate_relevance_label($post);
        if ($relevance) {
            $output .= '<span class="fcd-relevance-label">' . esc_html($relevance) . '</span>';
        }
        
        $output .= '</div></div>';
        
        return $output;
    }
    
    /**
     * 渲染网格项
     */
    private function render_grid_item($post, $args) {
        $permalink = get_permalink($post->ID);
        $title = get_the_title($post->ID);
        $excerpt = $args['show_excerpt'] ? $this->get_adaptive_excerpt($post) : '';
        
        $output = '<div class="fcd-grid-item">';
        
        if ($args['show_thumbnail']) {
            $thumbnail = $this->get_adaptive_thumbnail($post->ID);
            if ($thumbnail) {
                $output .= '<div class="fcd-thumbnail">';
                $output .= '<a href="' . esc_url($permalink) . '">' . $thumbnail . '</a>';
                $output .= '</div>';
            }
        }
        
        $output .= '<div class="fcd-content">';
        $output .= '<h4 class="fcd-post-title"><a href="' . esc_url($permalink) . '">' . esc_html($title) . '</a></h4>';
        
        if ($excerpt) {
            $output .= '<div class="fcd-excerpt">' . $excerpt . '</div>';
        }
        
        $output .= '</div></div>';
        
        return $output;
    }
    
    /**
     * 获取自适应摘要(根据设备调整长度)
     */
    private function get_adaptive_excerpt($post) {
        $excerpt_length = $this->user_profile->device_type === 'mobile' ? 60 : 100;
        
        if (!empty($post->post_excerpt)) {
            $excerpt = $post->post_excerpt;
        } else {
            $excerpt = wp_strip_all_tags($post->post_content);
        }
        
        $excerpt = wp_trim_words($excerpt, $excerpt_length, '...');
        
        return '<p>' . esc_html($excerpt) . '</p>';
    }
    
    /**
     * 获取自适应缩略图(根据设备调整尺寸)
     */
    private function get_adaptive_thumbnail($post_id) {
        $device_type = $this->user_profile->device_type;
        
        switch ($device_type) {
            case 'mobile':
                $size = 'medium';
                break;
            case 'tablet':
                $size = 'medium_large';
                break;
            default:
                $size = 'large';
        }
        
        if (has_post_thumbnail($post_id)) {
            return get_the_post_thumbnail($post_id, $size, array(
                'class' => 'fcd-thumb-img',
                'loading' => 'lazy',
                'alt' => get_the_title($post_id)
            ));
        }
        
        // 如果没有特色图片,返回默认图片
        return '<img src="' . FCD_PLUGIN_URL . 'assets/default-thumbnail.jpg" 
                class="fcd-thumb-img fcd-default-thumb" 
                alt="' . esc_attr__('默认缩略图', 'flexible-content-distribution') . '">';
    }
    
    /**
     * 计算相关性标签
     */
    private function calculate_relevance_label($post) {
        // 这里可以根据用户画像和文章特征的匹配度返回标签
        // 例如:"与您兴趣高度匹配"、"热门内容"、"最新发布"等
        
        $post_date = get_the_date('U', $post->ID);
        $days_old = (current_time('timestamp') - $post_date) / DAY_IN_SECONDS;
        
        if ($days_old < 3) {
            return '最新发布';
        }
        
        // 检查是否是热门内容
        $views = get_post_meta($post->ID, 'post_views_count', true);
        if ($views > 1000) {
            return '热门内容';
        }
        
        return '';
    }
    
    /**
     * 短代码处理函数
     */
    public function render_flexible_content_shortcode($atts) {
        $atts = shortcode_atts(array(
            'title' => '为您推荐',
            'limit' => 5,
            'layout' => 'auto',
            'show_excerpt' => true,
            'show_thumbnail' => true
        ), $atts, 'flexible_content');
        
        if ($atts['layout'] === 'auto') {
            unset($atts['layout']);
        }
        
        return $this->render_flexible_content($atts);
    }
    
    /**
     * 自动在文章内容后插入相关内容
     */
    public function auto_insert_related_content($content) {
        if (!is_single() || !is_main_query()) {
            return $content;
        }
        
        $settings = get_option('fcd_settings', array());
        if (empty($settings['auto_insert_content'])) {
            return $content;
        }
        
        $related_content = $this->render_flexible_content(array(
            'title' => $settings['related_content_title'] ?? '相关推荐',
            'limit' => $settings['related_content_limit'] ?? 3,
            'layout' => 'list_compact'
        ));
        
        return $content . $related_content;
    }
    
    /**
     * 注册小工具
     */
    public function register_widgets() {
        require_once FCD_PLUGIN_DIR . 'includes/class-fcd-widget.php';
        register_widget('FCD_Flexible_Content_Widget');
    }
}

// 初始化渲染器
new FCD_Content_Renderer();
?>

管理界面开发

为了让网站管理员能够配置插件,我们需要开发一个管理界面。

<?php
// 文件路径: admin/class-admin-settings.php

class FCD_Admin_Settings {
    
    private $settings_page;
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_init', array($this, 'register_settings'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    }
    
    /**
     * 添加管理菜单
     */
    public function add_admin_menu() {
        $this->settings_page = add_menu_page(
            '柔性内容分发设置',
            '内容分发',
            'manage_options',
            'fcd-settings',
            array($this, 'render_settings_page'),
            'dashicons-share',
            30
        );
        
        // 添加子菜单
        add_submenu_page(
            'fcd-settings',
            '用户画像分析',
            '用户画像',
            'manage_options',
            'fcd-user-profiles',
            array($this, 'render_user_profiles_page')
        );
        
        add_submenu_page(
            'fcd-settings',
            '内容匹配统计',
            '匹配统计',
            'manage_options',
            'fcd-analytics',
            array($this, 'render_analytics_page')
        );
    }
    
    /**
     * 注册设置选项
     */
    public function register_settings() {
        register_setting('fcd_settings_group', 'fcd_settings', array(
            'sanitize_callback' => array($this, 'sanitize_settings')
        ));
        
        // 基本设置部分
        add_settings_section(
            'fcd_basic_settings',
            '基本设置',
            array($this, 'render_basic_settings_section'),
            'fcd-settings'
        );
        
        add_settings_field(
            'enable_user_tracking',
            '启用用户追踪',
            array($this, 'render_enable_user_tracking_field'),
            'fcd-settings',
            'fcd_basic_settings'
        );
        
        add_settings_field(
            'content_matching_algorithm',
            '内容匹配算法',
            array($this, 'render_algorithm_field'),
            'fcd-settings',
            'fcd_basic_settings'
        );
        
        // 显示设置部分
        add_settings_section(
            'fcd_display_settings',
            '显示设置',
            array($this, 'render_display_settings_section'),
            'fcd-settings'
        );
        
        add_settings_field(
            'auto_insert_content',
            '自动插入相关内容',
            array($this, 'render_auto_insert_field'),
            'fcd-settings',
            'fcd_display_settings'
        );
        
        add_settings_field(
            'related_content_title',
            '相关内容标题',
            array($this, 'render_related_title_field'),
            'fcd-settings',
            'fcd_display_settings'
        );
    }
    
    /**
     * 清理设置数据
     */
    public function sanitize_settings($input) {
        $sanitized = array();
        
        // 清理布尔值
        $sanitized['enable_user_tracking'] = isset($input['enable_user_tracking']) ? 1 : 0;
        $sanitized['auto_insert_content'] = isset($input['auto_insert_content']) ? 1 : 0;
        
        // 清理算法选择
        $allowed_algorithms = array('interest_based', 'collaborative', 'hybrid');
        $sanitized['content_matching_algorithm'] = in_array($input['content_matching_algorithm'], $allowed_algorithms) 
            ? $input['content_matching_algorithm'] 
            : 'hybrid';
        
        // 清理文本字段
        $sanitized['related_content_title'] = sanitize_text_field($input['related_content_title'] ?? '相关推荐');
        $sanitized['related_content_limit'] = absint($input['related_content_limit'] ?? 3);
        
        return $sanitized;
    }
    
    /**
     * 渲染设置页面
     */
    public function render_settings_page() {
        if (!current_user_can('manage_options')) {
            return;
        }
        
        ?>
        <div class="wrap">
            <h1><?php echo esc_html(get_admin_page_title()); ?></h1>
            
            <form action="options.php" method="post">
                <?php
                settings_fields('fcd_settings_group');
                do_settings_sections('fcd-settings');
                submit_button('保存设置');
                ?>
            </form>
            
            <div class="fcd-admin-info">
                <h3>插件使用说明</h3>
                <p>1. 在文章或页面中使用短代码 <code>[flexible_content]</code> 显示推荐内容</p>
                <p>2. 可以通过小工具区域添加"柔性内容分发"小工具</p>
                <p>3. 支持的自定义参数:title, limit, layout, show_excerpt, show_thumbnail</p>
                <p>示例:<code>[flexible_content title="猜你喜欢" limit="4" layout="grid_2col"]</code></p>
            </div>
        </div>
        <?php
    }
    
    /**
     * 渲染用户画像页面
     */
    public function render_user_profiles_page() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'fcd_user_profiles';
        $profiles = $wpdb->get_results("SELECT * FROM $table_name ORDER BY last_updated DESC LIMIT 50");
        
        ?>
        <div class="wrap">
            <h1>用户画像分析</h1>
            
            <div class="fcd-stats-summary">
                <div class="fcd-stat-box">
                    <h3>总用户画像数</h3>
                    <p><?php echo $wpdb->get_var("SELECT COUNT(*) FROM $table_name"); ?></p>
                </div>
                <div class="fcd-stat-box">
                    <h3>今日活跃用户</h3>
                    <p><?php echo $wpdb->get_var($wpdb->prepare(
                        "SELECT COUNT(DISTINCT user_id) FROM $table_name WHERE DATE(last_updated) = %s",
                        current_time('Y-m-d')
                    )); ?></p>
                </div>
            </div>
            
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th>用户ID</th>
                        <th>设备类型</th>
                        <th>位置</th>
                        <th>兴趣标签</th>
                        <th>最后更新</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($profiles as $profile): ?>
                    <tr>
                        <td>
                            <?php 
                            $user = get_user_by('id', $profile->user_id);
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5803.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部