文章目录[隐藏]
网络传媒柔性用户行为分析与内容推荐WordPress插件教程
概述:柔性用户行为分析在内容推荐中的价值
在当今信息爆炸的时代,网络传媒平台面临着巨大的挑战:如何从海量内容中为用户精准推荐他们真正感兴趣的信息?传统的用户行为分析往往基于刚性规则和简单标签,而柔性用户行为分析则通过多维数据采集和智能算法,实现更加人性化、动态化的内容推荐。
本教程将指导您开发一个WordPress插件,该插件能够收集用户行为数据,分析用户偏好,并基于分析结果智能推荐相关内容。这种"柔性"分析不仅考虑用户的点击和浏览历史,还会结合停留时间、滚动深度、互动频率等多种因素,形成全面的用户画像。
插件架构设计
我们的插件将分为三个主要模块:
- 用户行为数据采集模块
- 行为分析与用户画像构建模块
- 智能内容推荐模块
<?php
/**
* 柔性用户行为分析与内容推荐WordPress插件
* 主插件文件:flexible-user-analysis-recommendation.php
*
* @package Flexible_User_Analysis_Recommendation
* @version 1.0.0
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('FUAR_VERSION', '1.0.0');
define('FUAR_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FUAR_PLUGIN_URL', plugin_dir_url(__FILE__));
/**
* 主插件类
*/
class Flexible_User_Analysis_Recommendation {
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('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
}
// 插件激活时执行
public function activate() {
$this->create_database_tables();
$this->set_default_options();
}
// 插件停用时执行
public function deactivate() {
// 清理临时数据
}
// 初始化
public function init() {
// 加载模块
require_once FUAR_PLUGIN_DIR . 'includes/class-data-collector.php';
require_once FUAR_PLUGIN_DIR . 'includes/class-user-analyzer.php';
require_once FUAR_PLUGIN_DIR . 'includes/class-content-recommender.php';
// 初始化模块
new FUAR_Data_Collector();
new FUAR_User_Analyzer();
new FUAR_Content_Recommender();
}
// 创建数据库表
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'fuar_user_behavior';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) DEFAULT NULL,
session_id varchar(64) NOT NULL,
post_id bigint(20) NOT NULL,
behavior_type varchar(50) NOT NULL,
behavior_value text,
duration int(11) DEFAULT 0,
scroll_depth int(11) DEFAULT 0,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY post_id (post_id),
KEY behavior_type (behavior_type),
KEY session_id (session_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 创建用户画像表
$profile_table = $wpdb->prefix . 'fuar_user_profiles';
$sql_profile = "CREATE TABLE IF NOT EXISTS $profile_table (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) UNIQUE,
interest_tags text,
category_preferences text,
author_preferences text,
avg_read_duration int(11) DEFAULT 0,
preferred_post_length varchar(50),
last_updated datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id)
) $charset_collate;";
dbDelta($sql_profile);
}
// 设置默认选项
private function set_default_options() {
$default_options = array(
'tracking_enabled' => true,
'min_read_duration' => 10, // 秒
'recommendation_count' => 5,
'exclude_categories' => array(),
'analysis_interval' => 'daily'
);
add_option('fuar_settings', $default_options);
}
// 添加管理菜单
public function add_admin_menu() {
add_menu_page(
'柔性用户分析',
'用户分析',
'manage_options',
'fuar-dashboard',
array($this, 'display_dashboard'),
'dashicons-chart-line',
30
);
add_submenu_page(
'fuar-dashboard',
'分析设置',
'设置',
'manage_options',
'fuar-settings',
array($this, 'display_settings_page')
);
}
// 显示仪表板
public function display_dashboard() {
include FUAR_PLUGIN_DIR . 'admin/dashboard.php';
}
// 显示设置页面
public function display_settings_page() {
include FUAR_PLUGIN_DIR . 'admin/settings.php';
}
// 加载前端脚本
public function enqueue_frontend_scripts() {
if (!is_admin()) {
wp_enqueue_script(
'fuar-frontend',
FUAR_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
FUAR_VERSION,
true
);
// 传递数据到JavaScript
wp_localize_script('fuar-frontend', 'fuar_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('fuar_tracking_nonce'),
'post_id' => get_the_ID(),
'user_id' => get_current_user_id()
));
}
}
}
// 初始化插件
Flexible_User_Analysis_Recommendation::get_instance();
?>
用户行为数据采集模块实现
数据采集是柔性分析的基础。我们需要收集多种用户行为数据,而不仅仅是简单的点击。
<?php
/**
* 用户行为数据采集类
* 文件:includes/class-data-collector.php
*/
class FUAR_Data_Collector {
public function __construct() {
// 添加AJAX处理钩子
add_action('wp_ajax_fuar_track_behavior', array($this, 'track_behavior'));
add_action('wp_ajax_nopriv_fuar_track_behavior', array($this, 'track_behavior'));
// 添加文章内容过滤器,插入跟踪代码
add_filter('the_content', array($this, 'add_tracking_to_content'));
}
/**
* 跟踪用户行为
*/
public function track_behavior() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'fuar_tracking_nonce')) {
wp_die('安全验证失败');
}
global $wpdb;
$table_name = $wpdb->prefix . 'fuar_user_behavior';
// 获取数据
$user_id = intval($_POST['user_id']);
$post_id = intval($_POST['post_id']);
$behavior_type = sanitize_text_field($_POST['behavior_type']);
$behavior_value = sanitize_text_field($_POST['behavior_value']);
$duration = intval($_POST['duration']);
$scroll_depth = intval($_POST['scroll_depth']);
// 生成或获取会话ID
$session_id = $this->get_session_id();
// 插入数据
$wpdb->insert(
$table_name,
array(
'user_id' => $user_id,
'session_id' => $session_id,
'post_id' => $post_id,
'behavior_type' => $behavior_type,
'behavior_value' => $behavior_value,
'duration' => $duration,
'scroll_depth' => $scroll_depth,
'created_at' => current_time('mysql')
),
array('%d', '%s', '%d', '%s', '%s', '%d', '%d', '%s')
);
wp_send_json_success(array('message' => '行为已记录'));
}
/**
* 获取或创建会话ID
*/
private function get_session_id() {
if (isset($_COOKIE['fuar_session_id'])) {
return $_COOKIE['fuar_session_id'];
}
$session_id = wp_generate_uuid4();
setcookie('fuar_session_id', $session_id, time() + (86400 * 30), '/'); // 30天有效期
return $session_id;
}
/**
* 在文章内容中添加跟踪代码
*/
public function add_tracking_to_content($content) {
if (!is_single() || is_admin()) {
return $content;
}
// 只在文章类型为post时添加
if ('post' !== get_post_type()) {
return $content;
}
$tracking_code = '
<script type="text/javascript">
jQuery(document).ready(function($) {
var startTime = new Date();
var maxScroll = 0;
var postId = ' . get_the_ID() . ';
var userId = ' . get_current_user_id() . ';
// 跟踪滚动深度
$(window).scroll(function() {
var scrollPercent = ($(window).scrollTop() / ($(document).height() - $(window).height())) * 100;
if (scrollPercent > maxScroll) {
maxScroll = scrollPercent;
}
});
// 页面卸载时发送数据
$(window).on("beforeunload", function() {
var endTime = new Date();
var duration = Math.round((endTime - startTime) / 1000); // 转换为秒
// 发送数据到服务器
$.ajax({
url: fuar_ajax.ajax_url,
type: "POST",
data: {
action: "fuar_track_behavior",
nonce: fuar_ajax.nonce,
user_id: userId,
post_id: postId,
behavior_type: "page_view",
behavior_value: "阅读完成",
duration: duration,
scroll_depth: Math.round(maxScroll)
}
});
});
// 跟踪点击行为
$("a").on("click", function() {
var linkText = $(this).text().substring(0, 100);
$.ajax({
url: fuar_ajax.ajax_url,
type: "POST",
data: {
action: "fuar_track_behavior",
nonce: fuar_ajax.nonce,
user_id: userId,
post_id: postId,
behavior_type: "link_click",
behavior_value: linkText,
duration: 0,
scroll_depth: Math.round(maxScroll)
}
});
});
});
</script>';
return $content . $tracking_code;
}
}
?>
用户行为分析与画像构建
收集到数据后,我们需要分析这些数据并构建用户画像。
<?php
/**
* 用户行为分析类
* 文件:includes/class-user-analyzer.php
*/
class FUAR_User_Analyzer {
private $analysis_cache = array();
public function __construct() {
// 定期分析用户行为
add_action('fuar_daily_analysis', array($this, 'daily_analysis'));
// 安排定时任务
if (!wp_next_scheduled('fuar_daily_analysis')) {
wp_schedule_event(time(), 'daily', 'fuar_daily_analysis');
}
}
/**
* 每日分析任务
*/
public function daily_analysis() {
$this->analyze_user_behavior();
$this->update_user_profiles();
}
/**
* 分析用户行为
*/
private function analyze_user_behavior() {
global $wpdb;
$behavior_table = $wpdb->prefix . 'fuar_user_behavior';
$profile_table = $wpdb->prefix . 'fuar_user_profiles';
// 获取所有需要分析的用户
$users = $wpdb->get_results("
SELECT DISTINCT user_id
FROM $behavior_table
WHERE user_id IS NOT NULL
AND user_id != 0
");
foreach ($users as $user) {
$user_id = $user->user_id;
// 分析用户兴趣标签
$interest_tags = $this->analyze_interest_tags($user_id);
// 分析分类偏好
$category_prefs = $this->analyze_category_preferences($user_id);
// 分析作者偏好
$author_prefs = $this->analyze_author_preferences($user_id);
// 分析平均阅读时长
$avg_duration = $this->calculate_average_duration($user_id);
// 分析偏好的文章长度
$preferred_length = $this->analyze_preferred_length($user_id);
// 更新或插入用户画像
$wpdb->replace(
$profile_table,
array(
'user_id' => $user_id,
'interest_tags' => json_encode($interest_tags, JSON_UNESCAPED_UNICODE),
'category_preferences' => json_encode($category_prefs, JSON_UNESCAPED_UNICODE),
'author_preferences' => json_encode($author_prefs, JSON_UNESCAPED_UNICODE),
'avg_read_duration' => $avg_duration,
'preferred_post_length' => $preferred_length,
'last_updated' => current_time('mysql')
),
array('%d', '%s', '%s', '%s', '%d', '%s', '%s')
);
}
}
/**
* 分析用户兴趣标签
*/
private function analyze_interest_tags($user_id) {
global $wpdb;
$behavior_table = $wpdb->prefix . 'fuar_user_behavior';
// 获取用户阅读的文章
$posts = $wpdb->get_results($wpdb->prepare("
SELECT DISTINCT post_id
FROM $behavior_table
WHERE user_id = %d
AND behavior_type = 'page_view'
AND duration > 30
ORDER BY created_at DESC
LIMIT 50
", $user_id));
$all_tags = array();
foreach ($posts as $post) {
$tags = wp_get_post_tags($post->post_id);
foreach ($tags as $tag) {
if (!isset($all_tags[$tag->name])) {
$all_tags[$tag->name] = 0;
}
$all_tags[$tag->name]++;
}
}
// 按频率排序并返回前10个标签
arsort($all_tags);
return array_slice($all_tags, 0, 10, true);
}
/**
* 分析分类偏好
*/
private function analyze_category_preferences($user_id) {
global $wpdb;
$behavior_table = $wpdb->prefix . 'fuar_user_behavior';
$categories = $wpdb->get_results($wpdb->prepare("
SELECT t.name, COUNT(*) as count
FROM $behavior_table b
INNER JOIN {$wpdb->term_relationships} tr ON b.post_id = tr.object_id
INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
WHERE b.user_id = %d
AND tt.taxonomy = 'category'
AND b.behavior_type = 'page_view'
AND b.duration > 10
GROUP BY t.term_id
ORDER BY count DESC
LIMIT 5
", $user_id));
$preferences = array();
foreach ($categories as $cat) {
$preferences[$cat->name] = intval($cat->count);
}
return $preferences;
}
/**
* 计算平均阅读时长
*/
private function calculate_average_duration($user_id) {
global $wpdb;
$behavior_table = $wpdb->prefix . 'fuar_user_behavior';
$avg = $wpdb->get_var($wpdb->prepare("
SELECT AVG(duration)
FROM $behavior_table
WHERE user_id = %d
AND behavior_type = 'page_view'
AND duration > 5
AND duration < 1800
", $user_id));
return intval($avg);
}
/**
* 更新用户画像
*/
private function update_user_profiles() {
// 这里可以添加更复杂的画像更新逻辑
// 例如:衰减旧数据、季节性调整等
}
}
?>
智能内容推荐模块
基于用户画像,我们可以实现智能内容推荐。
<?php
/**
智能内容推荐模块实现
基于用户画像,我们可以实现智能内容推荐。
<?php
/**
* 智能内容推荐类
* 文件:includes/class-content-recommender.php
*/
class FUAR_Content_Recommender {
private $recommendation_cache = array();
public function __construct() {
// 添加推荐内容短码
add_shortcode('fuar_recommendations', array($this, 'recommendations_shortcode'));
// 在文章底部自动添加推荐
add_filter('the_content', array($this, 'auto_add_recommendations'), 20);
// 添加小工具
add_action('widgets_init', array($this, 'register_widget'));
}
/**
* 推荐内容短码
*/
public function recommendations_shortcode($atts) {
$atts = shortcode_atts(array(
'count' => 5,
'user_id' => get_current_user_id(),
'title' => '为您推荐',
'layout' => 'grid'
), $atts, 'fuar_recommendations');
$recommendations = $this->get_recommendations(
intval($atts['user_id']),
intval($atts['count'])
);
if (empty($recommendations)) {
return $this->get_fallback_recommendations(intval($atts['count']));
}
ob_start();
?>
<div class="fuar-recommendations-container">
<h3 class="fuar-recommendations-title"><?php echo esc_html($atts['title']); ?></h3>
<div class="fuar-recommendations-layout-<?php echo esc_attr($atts['layout']); ?>">
<?php foreach ($recommendations as $post): ?>
<div class="fuar-recommendation-item">
<a href="<?php echo get_permalink($post->ID); ?>" class="fuar-recommendation-link">
<?php if (has_post_thumbnail($post->ID)): ?>
<div class="fuar-recommendation-thumbnail">
<?php echo get_the_post_thumbnail($post->ID, 'medium'); ?>
</div>
<?php endif; ?>
<h4 class="fuar-recommendation-heading"><?php echo esc_html($post->post_title); ?></h4>
<div class="fuar-recommendation-excerpt">
<?php echo wp_trim_words(get_the_excerpt($post->ID), 20); ?>
</div>
<div class="fuar-recommendation-meta">
<span class="fuar-recommendation-date">
<?php echo get_the_date('', $post->ID); ?>
</span>
<span class="fuar-recommendation-match">
匹配度: <?php echo isset($post->match_score) ? round($post->match_score * 100) . '%' : '高'; ?>
</span>
</div>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* 获取个性化推荐
*/
public function get_recommendations($user_id, $count = 5) {
$cache_key = 'fuar_recs_' . $user_id . '_' . $count;
// 检查缓存
if (isset($this->recommendation_cache[$cache_key])) {
return $this->recommendation_cache[$cache_key];
}
// 获取用户画像
$user_profile = $this->get_user_profile($user_id);
// 如果用户没有画像或未登录,返回热门内容
if (empty($user_profile) || $user_id == 0) {
$recommendations = $this->get_popular_posts($count);
$this->recommendation_cache[$cache_key] = $recommendations;
return $recommendations;
}
// 解析用户偏好
$interest_tags = json_decode($user_profile->interest_tags, true);
$category_prefs = json_decode($user_profile->category_preferences, true);
$author_prefs = json_decode($user_profile->author_preferences, true);
$avg_duration = $user_profile->avg_read_duration;
// 构建推荐查询
$recommendations = $this->query_recommendations(
$interest_tags,
$category_prefs,
$author_prefs,
$avg_duration,
$count,
$user_id
);
// 如果推荐不足,补充热门内容
if (count($recommendations) < $count) {
$additional = $this->get_popular_posts($count - count($recommendations), $recommendations);
$recommendations = array_merge($recommendations, $additional);
}
$this->recommendation_cache[$cache_key] = $recommendations;
return $recommendations;
}
/**
* 查询推荐内容
*/
private function query_recommendations($interest_tags, $category_prefs, $author_prefs, $avg_duration, $count, $exclude_user_id) {
global $wpdb;
$posts_table = $wpdb->posts;
$postmeta_table = $wpdb->postmeta;
$term_relationships = $wpdb->term_relationships;
$term_taxonomy = $wpdb->term_taxonomy;
$terms = $wpdb->terms;
$behavior_table = $wpdb->prefix . 'fuar_user_behavior';
// 构建查询
$query = "
SELECT p.*,
(
-- 标签匹配得分
(SELECT COUNT(*) * 3
FROM $term_relationships tr2
INNER JOIN $term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id
INNER JOIN $terms t2 ON tt2.term_id = t2.term_id
WHERE tr2.object_id = p.ID
AND tt2.taxonomy = 'post_tag'
AND t2.name IN ('" . implode("','", array_keys($interest_tags)) . "')
) +
-- 分类匹配得分
(SELECT COUNT(*) * 2
FROM $term_relationships tr3
INNER JOIN $term_taxonomy tt3 ON tr3.term_taxonomy_id = tt3.term_taxonomy_id
INNER JOIN $terms t3 ON tt3.term_id = t3.term_id
WHERE tr3.object_id = p.ID
AND tt3.taxonomy = 'category'
AND t3.name IN ('" . implode("','", array_keys($category_prefs)) . "')
) +
-- 阅读时长适配得分
(CASE
WHEN (LENGTH(p.post_content) / 2000) BETWEEN ($avg_duration - 30) AND ($avg_duration + 30) THEN 2
ELSE 0
END) -
-- 惩罚已读文章
(SELECT COUNT(*) * 5
FROM $behavior_table b
WHERE b.post_id = p.ID
AND b.user_id = $exclude_user_id
)
) as match_score
FROM $posts_table p
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
AND p.post_date > DATE_SUB(NOW(), INTERVAL 90 DAY)
";
// 排除用户最近看过的文章
$query .= $wpdb->prepare("
AND p.ID NOT IN (
SELECT post_id
FROM $behavior_table
WHERE user_id = %d
AND created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)
LIMIT 20
)
", $exclude_user_id);
$query .= " ORDER BY match_score DESC, p.post_date DESC LIMIT " . ($count * 3);
$results = $wpdb->get_results($query);
// 计算最终得分并排序
foreach ($results as $post) {
$post->final_score = $this->calculate_final_score($post, $interest_tags, $category_prefs);
}
// 按最终得分排序
usort($results, function($a, $b) {
return $b->final_score <=> $a->final_score;
});
return array_slice($results, 0, $count);
}
/**
* 计算最终推荐得分
*/
private function calculate_final_score($post, $interest_tags, $category_prefs) {
$score = $post->match_score;
// 获取文章标签
$post_tags = wp_get_post_tags($post->ID, array('fields' => 'names'));
// 根据用户兴趣标签权重调整得分
foreach ($post_tags as $tag) {
if (isset($interest_tags[$tag])) {
$score += $interest_tags[$tag] * 0.5;
}
}
// 考虑文章热度(评论数、浏览量)
$comment_count = get_comments_number($post->ID);
$score += min($comment_count * 0.1, 5);
// 考虑文章新鲜度(最近发布加分)
$post_age = (time() - strtotime($post->post_date)) / (24 * 3600);
if ($post_age < 7) {
$score += (7 - $post_age) * 0.5;
}
return $score;
}
/**
* 获取用户画像
*/
private function get_user_profile($user_id) {
global $wpdb;
if ($user_id == 0) {
return null;
}
$table_name = $wpdb->prefix . 'fuar_user_profiles';
return $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name WHERE user_id = %d",
$user_id
));
}
/**
* 获取热门文章作为备选推荐
*/
private function get_popular_posts($count, $exclude_posts = array()) {
$exclude_ids = array();
foreach ($exclude_posts as $post) {
$exclude_ids[] = $post->ID;
}
$args = array(
'post_type' => 'post',
'posts_per_page' => $count,
'post_status' => 'publish',
'post__not_in' => $exclude_ids,
'orderby' => 'comment_count',
'order' => 'DESC',
'date_query' => array(
array(
'after' => '30 days ago'
)
)
);
$query = new WP_Query($args);
return $query->posts;
}
/**
* 获取备选推荐(当个性化推荐不足时)
*/
private function get_fallback_recommendations($count) {
// 多种备选策略
$strategies = array(
'popular' => $this->get_popular_posts($count),
'recent' => $this->get_recent_posts($count),
'editor_pick' => $this->get_editor_picks($count)
);
// 随机选择一种策略
$strategy_key = array_rand($strategies);
return $strategies[$strategy_key];
}
/**
* 获取最近文章
*/
private function get_recent_posts($count) {
$args = array(
'post_type' => 'post',
'posts_per_page' => $count,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
);
$query = new WP_Query($args);
return $query->posts;
}
/**
* 获取编辑精选
*/
private function get_editor_picks($count) {
$args = array(
'post_type' => 'post',
'posts_per_page' => $count,
'post_status' => 'publish',
'meta_key' => '_fuar_editor_pick',
'meta_value' => '1',
'orderby' => 'rand'
);
$query = new WP_Query($args);
// 如果编辑精选不足,补充热门文章
if ($query->post_count < $count) {
$additional = $this->get_popular_posts($count - $query->post_count, $query->posts);
return array_merge($query->posts, $additional);
}
return $query->posts;
}
/**
* 自动在文章底部添加推荐
*/
public function auto_add_recommendations($content) {
if (!is_single() || !is_main_query()) {
return $content;
}
$settings = get_option('fuar_settings', array());
$auto_add = isset($settings['auto_add_recommendations']) ? $settings['auto_add_recommendations'] : true;
if ($auto_add && in_the_loop()) {
$recommendations = $this->recommendations_shortcode(array(
'count' => isset($settings['recommendation_count']) ? $settings['recommendation_count'] : 5,
'title' => '您可能感兴趣的内容'
));
$content .= $recommendations;
}
return $content;
}
/**
* 注册小工具
*/
public function register_widget() {
register_widget('FUAR_Recommendations_Widget');
}
}
/**
* 推荐小工具类
*/
class FUAR_Recommendations_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'fuar_recommendations_widget',
'个性化内容推荐',
array('description' => '根据用户行为显示个性化内容推荐')
);
}
public function widget($args, $instance) {
$title = apply_filters('widget_title', $instance['title']);
$count = isset($instance['count']) ? intval($instance['count']) : 5;
echo $args['before_widget'];
if (!empty($title)) {
echo $args['before_title'] . $title . $args['after_title'];
}
$recommender = new FUAR_Content_Recommender();
$recommendations = $recommender->get_recommendations(get_current_user_id(), $count);
if (!empty($recommendations)) {
echo '<ul class="fuar-widget-recommendations">';
foreach ($recommendations as $post) {
echo '<li class="fuar-widget-item">';
echo '<a href="' . get_permalink($post->ID) . '" class="fuar-widget-link">';
echo '<span class="fuar-widget-title">' . esc_html($post->post_title) . '</span>';
if (isset($post->match_score) && $post->match_score > 0) {
echo '<span class="fuar-widget-match">' . round($post->match_score) . '分</span>';
}
echo '</a>';
echo '</li>';
}
echo '</ul>';
}
echo $args['after_widget'];
}
public function form($instance) {
$title = isset($instance['title']) ? $instance['title'] : '为您推荐';
$count = isset($instance['count']) ? $instance['count'] : 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('count'); ?>">显示数量:</label>
<input class="tiny-text" id="<?php echo $this->get_field_id('count'); ?>"
name="<?php echo $this->get_field_name('count'); ?>" type="number"
value="<?php echo esc_attr($count); ?>" min="1" max="10" />
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = sanitize_text_field($new_instance['title']);
$instance['count'] = intval($new_instance['count']);
return $instance;
}
}
?>
前端JavaScript跟踪代码
/**
* 前端行为跟踪JavaScript
* 文件:assets/js/frontend.js
*/
(function($) {
'use strict';
// 用户行为跟踪器
var FUARTracker = {
// 初始化
init: function() {
this.trackPageView();
this.trackReadingBehavior();
this.trackInteractiveElements();
this.trackSocialShares();
},
// 跟踪页面浏览
trackPageView: function() {
var startTime = new Date();
var maxScroll = 0;
var isActive = true;
// 跟踪滚动深度
$(window).scroll(function() {
var scrollPercent = ($(window).scrollTop() / ($(document).height() - $(window).height())) * 100;
if (scrollPercent > maxScroll) {
maxScroll = scrollPercent;
}
});
// 跟踪用户活跃状态
var activityTimer;
$(document).on('mousemove keydown scroll touchstart', function() {
isActive = true;
clearTimeout(activityTimer);
activityTimer = setTimeout(function() {
isActive = false;
}, 30000); // 30秒无活动视为不活跃
});
// 页面卸载时发送数据


