新建插件文件夹和css文件夹,代码一直有问题,都迭代4.0了,🤣🤣,代码如下:
<?php
/**
* Plugin Name: 网站数据统计小工具
* Description: 显示网站运行时间、文章、评论、友链等统计信息
* Version: 4.0
* Author: QingZhao
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class Site_Statistics_Widget extends WP_Widget {
private $page_views_option = 'site_statistics_page_views';
private $plugin_version = '4.0';
// 构造函数
public function __construct() {
parent::__construct(
'site_statistics_widget',
'网站数据统计',
array('description' => '显示网站运行时间、文章、评论、友链等统计信息')
);
// 注册样式表
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
// 初始化访问量统计
add_action('init', array($this, 'init_page_views'));
// 初始化会话
add_action('init', array($this, 'init_session'));
// 添加内联样式
add_action('wp_head', array($this, 'add_inline_styles'));
}
// 注册前端样式
public function enqueue_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
// 使用文件修改时间作为版本号,确保缓存更新
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_version = file_exists($css_file) ? filemtime($css_file) : $this->plugin_version;
// 添加缓存清除版本
$cache_version = get_option('site_statistics_css_version', 0);
if ($cache_version) {
$css_version = $cache_version;
}
wp_enqueue_style(
'site-statistics-style',
plugins_url('css/style.css', __FILE__),
array(),
$css_version
);
}
}
// 添加内联样式确保覆盖
public function add_inline_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
echo '<style>
.site-statistics {
background: #ffffff !important;
border: 1px solid #eaeaea !important;
border-radius: 8px !important;
padding: 20px !important;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05) !important;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
font-size: 13px !important;
line-height: 1.5 !important;
color: #333 !important;
}
.site-statistics .stat-item {
background: transparent !important;
background-image: none !important;
}
.site-statistics .stat-main,
.site-statistics .stat-details,
.site-statistics .stat-info {
border-bottom: 1px dashed #e0e0e0 !important;
}
.site-statistics .stat-row,
.site-statistics .info-row {
border-bottom: 1px dashed #f0f0f0 !important;
}
.site-statistics .footer-time {
background: #f9f9f9 !important;
border: 1px solid #eaeaea !important;
}
.site-statistics * {
background-image: none !important;
}
</style>';
}
}
// 初始化会话
public function init_session() {
if (!session_id() && !headers_sent()) {
session_start();
}
}
// 初始化访问量
public function init_page_views() {
$page_views = get_option($this->page_views_option);
if ($page_views === false) {
update_option($this->page_views_option, 0);
}
}
// 前端显示
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$this->display_statistics($instance);
echo $args['after_widget'];
}
// 后台表单
public function form($instance) {
// 设置默认值
$defaults = array(
'title' => '网站数据统计',
'start_date' => date('Y-m-d'),
'guestbook_page_id' => '',
'admin_user_id' => '',
'initial_views' => '0',
'timezone_offset' => '0'
);
// 显示选项默认值
$display_defaults = array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
// 合并所有默认值
$all_defaults = array_merge($defaults, $display_defaults);
// 确保所有字段都有值
$instance = wp_parse_args((array) $instance, $all_defaults);
// 获取所有用户
$users = get_users(array(
'orderby' => 'display_name',
'order' => 'ASC'
));
// 获取所有页面
$pages = get_pages();
// 获取当前访问量
$current_views = get_option($this->page_views_option, 0);
// 显示当前服务器时间
$current_server_time = date('Y-m-d H:i:s');
$server_timezone = date_default_timezone_get();
// 获取CSS文件信息
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_mtime = file_exists($css_file) ? date('Y-m-d H:i:s', filemtime($css_file)) : '文件不存在';
?>
<div class="site-statistics-admin">
<!-- 基础设置 -->
<div class="admin-section">
<h4>基本设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">标题:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
type="text" value="<?php echo esc_attr($instance['title']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('start_date')); ?>">网站起始日期:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('start_date')); ?>"
name="<?php echo esc_attr($this->get_field_name('start_date')); ?>"
type="date" value="<?php echo esc_attr($instance['start_date']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>">站长账号:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('admin_user_id')); ?>">
<option value="">-- 选择站长账号 --</option>
<?php foreach ($users as $user): ?>
<option value="<?php echo $user->ID; ?>" <?php selected($instance['admin_user_id'], $user->ID); ?>>
<?php echo esc_html($user->display_name); ?> (<?php echo esc_html($user->user_login); ?>)
</option>
<?php endforeach; ?>
</select>
</p>
</div>
<!-- 时间设置 -->
<div class="admin-section">
<h4>时间设置</h4>
<div style="background: #f5f5f5; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>时间信息:</strong><br>
服务器时间:<?php echo $current_server_time; ?><br>
时区:<?php echo $server_timezone; ?> (UTC<?php echo date('P'); ?>)
</p>
</div>
<p>
<label for="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>">时区校正(小时):</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>"
name="<?php echo esc_attr($this->get_field_name('timezone_offset')); ?>"
type="number" value="<?php echo esc_attr($instance['timezone_offset']); ?>"
step="0.5" min="-12" max="14">
<small>格式:数字,如 8, -5, 10.5, -8.5</small>
</p>
<div style="background: #e8f5e8; padding: 8px; border-radius: 4px; margin-top: 8px;">
<small>
<strong>校正说明:</strong><br>
如果显示时间比实际早,请设置为正数(如:10.5)<br>
如果显示时间比实际晚,请设置为负数(如:-10.5)
</small>
</div>
</div>
<!-- 显示控制 -->
<div class="admin-section">
<h4>显示控制</h4>
<div class="display-controls">
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_runtime')); ?>"
value="1" <?php checked($instance['show_runtime'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>">
显示运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_articles')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_articles')); ?>"
value="1" <?php checked($instance['show_articles'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_articles')); ?>">
显示文章数量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_wordcount')); ?>"
value="1" <?php checked($instance['show_wordcount'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>">
显示字数统计
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_comments')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_comments')); ?>"
value="1" <?php checked($instance['show_comments'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_comments')); ?>">
显示文章评论
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_links')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_links')); ?>"
value="1" <?php checked($instance['show_links'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_links')); ?>">
显示邻居友链
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_guestbook')); ?>"
value="1" <?php checked($instance['show_guestbook'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>">
显示好友留言
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_rundays')); ?>"
value="1" <?php checked($instance['show_rundays'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>">
显示详细运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_pageviews')); ?>"
value="1" <?php checked($instance['show_pageviews'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>">
显示页面访问量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_login_time')); ?>"
value="1" <?php checked($instance['show_login_time'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>">
显示最后登录时间
</label>
</p>
</div>
</div>
<!-- 数据设置 -->
<div class="admin-section">
<h4>数据设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>">留言板页面:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('guestbook_page_id')); ?>">
<option value="">-- 无留言板 --</option>
<?php foreach ($pages as $page): ?>
<option value="<?php echo $page->ID; ?>" <?php selected($instance['guestbook_page_id'], $page->ID); ?>>
<?php echo esc_html($page->post_title); ?>
</option>
<?php endforeach; ?>
</select>
</p>
<p>
<label>当前访问量:</label>
<span style="font-weight: bold; color: #333;"><?php echo number_format($current_views); ?> 次</span>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('initial_views')); ?>">设置访问量:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('initial_views')); ?>"
name="<?php echo esc_attr($this->get_field_name('initial_views')); ?>"
type="number" value="<?php echo esc_attr($instance['initial_views']); ?>" min="0" step="1">
<small>设置后点击"保存"生效</small>
</p>
</div>
<!-- CSS信息 -->
<div class="admin-section">
<h4>样式信息</h4>
<div style="background: #f0f8ff; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>CSS文件信息:</strong><br>
CSS最后修改:<?php echo $css_mtime; ?><br>
如果样式未更新:<br>
1. 按Ctrl+F5强制刷新<br>
2. <a href="<?php echo admin_url('options-general.php?page=site-statistics&action=clear_cache'); ?>" style="color: #0073aa;">点击清除CSS缓存</a>
</p>
</div>
</div>
</div>
<style>
.site-statistics-admin {
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 15px;
background: #fafafa;
}
.admin-section {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #e0e0e0;
}
.admin-section:last-child {
border-bottom: none;
margin-bottom: 0;
}
.admin-section h4 {
margin: 0 0 12px 0;
color: #333;
font-size: 14px;
}
.display-controls p {
margin-bottom: 8px;
}
</style>
<?php
}
// 更新设置
public function update($new_instance, $old_instance) {
$instance = array();
// 基础设置
$instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
$instance['start_date'] = !empty($new_instance['start_date']) ? sanitize_text_field($new_instance['start_date']) : date('Y-m-d');
$instance['guestbook_page_id'] = isset($new_instance['guestbook_page_id']) ? intval($new_instance['guestbook_page_id']) : '';
$instance['admin_user_id'] = isset($new_instance['admin_user_id']) ? intval($new_instance['admin_user_id']) : '';
$instance['initial_views'] = isset($new_instance['initial_views']) ? intval($new_instance['initial_views']) : 0;
$instance['timezone_offset'] = isset($new_instance['timezone_offset']) ? floatval($new_instance['timezone_offset']) : 0;
// 显示选项
$instance['show_runtime'] = isset($new_instance['show_runtime']) ? 1 : 0;
$instance['show_articles'] = isset($new_instance['show_articles']) ? 1 : 0;
$instance['show_wordcount'] = isset($new_instance['show_wordcount']) ? 1 : 0;
$instance['show_comments'] = isset($new_instance['show_comments']) ? 1 : 0;
$instance['show_links'] = isset($new_instance['show_links']) ? 1 : 0;
$instance['show_guestbook'] = isset($new_instance['show_guestbook']) ? 1 : 0;
$instance['show_rundays'] = isset($new_instance['show_rundays']) ? 1 : 0;
$instance['show_pageviews'] = isset($new_instance['show_pageviews']) ? 1 : 0;
$instance['show_login_time'] = isset($new_instance['show_login_time']) ? 1 : 0;
// 更新访问量
if ($instance['initial_views'] > 0) {
$current_views = get_option($this->page_views_option, 0);
if ($instance['initial_views'] > $current_views) {
update_option($this->page_views_option, $instance['initial_views']);
}
}
return $instance;
}
// 显示统计数据
private function display_statistics($instance) {
// 确保显示选项存在且正确
$instance = wp_parse_args((array) $instance, array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
));
// 获取数据
$data = $this->get_statistics_data($instance);
// 如果没有设置站长,强制不显示登录时间
if (empty($instance['admin_user_id'])) {
$instance['show_login_time'] = 0;
}
?>
<div class="site-statistics">
<!-- 主要统计 -->
<?php if ($instance['show_runtime'] || $instance['show_articles']): ?>
<div class="stat-main">
<?php if ($instance['show_runtime']): ?>
<div class="stat-item">
<div class="stat-label">运行时间</div>
<div class="stat-value"><?php echo $data['runtime']['years']; ?> 年</div>
</div>
<?php endif; ?>
<?php if ($instance['show_articles']): ?>
<div class="stat-item">
<div class="stat-label">文章数量</div>
<div class="stat-value"><?php echo $data['post_count']; ?> 篇</div>
<?php if ($instance['show_wordcount']): ?>
<div class="stat-sub"><?php echo number_format($data['wordcount'] / 10000, 1); ?> 万字</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 详细统计 -->
<?php if (($instance['show_comments'] && $data['article_comments'] > 0) ||
($instance['show_links'] && $data['bookmarks_count'] > 0) ||
($instance['show_guestbook'] && $data['guestbook_comments'] > 0)): ?>
<div class="stat-details">
<?php if ($instance['show_comments'] && $data['article_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">文章评论</span>
<span class="detail-value"><?php echo $data['article_comments']; ?> 条</span>
</div>
<?php endif; ?>
<?php if ($instance['show_links'] && $data['bookmarks_count'] > 0): ?>
<div class="stat-row">
<span class="detail-label">邻居友链</span>
<span class="detail-value"><?php echo $data['bookmarks_count']; ?> 个</span>
</div>
<?php endif; ?>
<?php if ($instance['show_guestbook'] && $data['guestbook_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">好友留言</span>
<span class="detail-value"><?php echo $data['guestbook_comments']; ?> 条</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 运行信息 -->
<?php if ($instance['show_rundays'] || $instance['show_pageviews']): ?>
<div class="stat-info">
<?php if ($instance['show_rundays']): ?>
<div class="info-row">
<span class="info-label">网站运行</span>
<span class="info-value">
<?php echo $data['runtime']['years']; ?>年
<?php echo $data['runtime']['months']; ?>月
<?php echo $data['runtime']['days']; ?>天
</span>
</div>
<?php endif; ?>
<?php if ($instance['show_pageviews']): ?>
<div class="info-row">
<span class="info-label">页面访问</span>
<span class="info-value"><?php echo number_format($data['page_views']); ?> 次</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 站长信息 -->
<?php if ($instance['show_login_time'] && !empty($data['last_login'])): ?>
<div class="stat-footer">
<div class="footer-label">站长最后登录</div>
<div class="footer-time"><?php echo $data['last_login']; ?></div>
</div>
<?php endif; ?>
</div>
<?php
}
// 获取统计数据
private function get_statistics_data($instance) {
$data = array();
// 文章数据
$data['post_count'] = wp_count_posts()->publish;
$data['wordcount'] = $this->calculate_wordcount();
// 评论数据
$data['article_comments'] = $this->get_article_comments_count();
$data['guestbook_comments'] = $this->get_guestbook_comments_count($instance);
// 友链数据
$data['bookmarks_count'] = $this->get_bookmarks_count();
// 运行时间
$data['runtime'] = $this->calculate_runtime($instance['start_date']);
// 页面访问量
$data['page_views'] = $this->get_page_views();
// 最后登录时间
if (!empty($instance['admin_user_id'])) {
$data['last_login'] = $this->get_admin_last_login($instance);
} else {
$data['last_login'] = '';
}
return $data;
}
// 计算字数
private function calculate_wordcount() {
static $wordcount = null;
if ($wordcount === null) {
global $wpdb;
$result = $wpdb->get_var(
"SELECT SUM(
LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', '')) + 1
) as wordcount
FROM {$wpdb->posts}
WHERE post_type = 'post'
AND post_status = 'publish'"
);
$wordcount = $result ? intval($result) : 0;
}
return $wordcount;
}
// 获取文章评论数量
private function get_article_comments_count() {
global $wpdb;
$count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
return $count ? intval($count) : 0;
}
// 获取留言板评论数量
private function get_guestbook_comments_count($instance) {
if (empty($instance['guestbook_page_id'])) {
return 0;
}
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*)
FROM {$wpdb->comments}
WHERE comment_approved = '1'
AND comment_post_ID = %d",
$instance['guestbook_page_id']
));
return $count ? intval($count) : 0;
}
// 获取友情链接数量
private function get_bookmarks_count() {
$bookmarks = get_bookmarks(array('hide_invisible' => 1));
return count($bookmarks);
}
// 计算运行时间
private function calculate_runtime($start_date) {
try {
$start = new DateTime($start_date);
$now = new DateTime();
$interval = $start->diff($now);
return array(
'years' => $interval->y,
'months' => $interval->m,
'days' => $interval->d
);
} catch (Exception $e) {
return array('years' => 0, 'months' => 0, 'days' => 0);
}
}
// 获取页面访问量
private function get_page_views() {
return get_option($this->page_views_option, 0);
}
// 获取站长最后登录时间
private function get_admin_last_login($instance) {
$admin_id = $instance['admin_user_id'];
if (empty($admin_id)) {
return '';
}
// 获取时区偏移量
$timezone_offset = isset($instance['timezone_offset']) ? floatval($instance['timezone_offset']) : 0;
// 方法1:从专用字段获取
$last_login = get_user_meta($admin_id, 'site_stats_last_login_corrected', true);
// 方法2:如果没有专用字段,从普通字段获取并校正
if (empty($last_login)) {
$last_login_raw = get_user_meta($admin_id, 'last_login', true);
if (!empty($last_login_raw)) {
// 应用时区校正
$last_login = $this->apply_timezone_correction($last_login_raw, $timezone_offset);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
// 方法3:从会话获取
if (empty($last_login)) {
$session_tokens = get_user_meta($admin_id, 'session_tokens', true);
if (!empty($session_tokens) && is_array($session_tokens)) {
$last_login_time = 0;
foreach ($session_tokens as $session) {
if (isset($session['login']) && $session['login'] > $last_login_time) {
$last_login_time = $session['login'];
}
}
if ($last_login_time > 0) {
$last_login = $this->apply_timezone_correction(
date('Y-m-d H:i:s', $last_login_time),
$timezone_offset
);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
}
return !empty($last_login) ? $last_login : '暂无记录';
}
// 应用时区校正
private function apply_timezone_correction($time_string, $offset_hours) {
try {
// 解析时间
$datetime = new DateTime($time_string);
// 应用时区偏移
if ($offset_hours != 0) {
$interval = DateInterval::createFromDateString(abs($offset_hours) . ' hours');
if ($offset_hours > 0) {
$datetime->add($interval);
} else {
$datetime->sub($interval);
}
}
// 返回格式化的时间
return $datetime->format('Y-m-d H:i:s');
} catch (Exception $e) {
return $time_string;
}
}
}
// 注册小工具
function register_site_statistics_widget() {
register_widget('Site_Statistics_Widget');
}
add_action('widgets_init', 'register_site_statistics_widget');
// 记录页面访问量
function site_statistics_count_page_view() {
// 不记录后台访问
if (is_admin()) {
return;
}
// 不记录爬虫
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
$bots = array('bot', 'spider', 'crawl', 'scrape', 'slurp', 'curl', 'wget', 'python', 'java');
foreach ($bots as $bot) {
if (strpos($user_agent, $bot) !== false) {
return;
}
}
}
// 使用会话防止重复计数(24小时)
if (!isset($_SESSION['site_stats_last_count'])) {
$_SESSION['site_stats_last_count'] = time();
} else {
if (time() - $_SESSION['site_stats_last_count'] < 86400) {
return;
}
}
// 增加访问量
$current_views = get_option('site_statistics_page_views', 0);
update_option('site_statistics_page_views', $current_views + 1);
// 更新最后计数时间
$_SESSION['site_stats_last_count'] = time();
}
add_action('wp', 'site_statistics_count_page_view');
// 记录用户最后登录时间
function site_statistics_record_last_login($user_login, $user) {
if ($user && $user->ID) {
// 存储当前时间
$current_time = current_time('mysql');
// 存储到专用字段
update_user_meta($user->ID, 'last_login', $current_time);
// 清除校正后的缓存
delete_user_meta($user->ID, 'site_stats_last_login_corrected');
}
}
add_action('wp_login', 'site_statistics_record_last_login', 10, 2);
// 添加快捷码支持
function site_statistics_shortcode($atts) {
$atts = shortcode_atts(array(
'title' => ''
), $atts);
ob_start();
echo '<div class="site-statistics-shortcode">';
if (!empty($atts['title'])) {
echo '<h3>' . esc_html($atts['title']) . '</h3>';
}
// 创建默认实例
$instance = array(
'title' => '',
'start_date' => '2002-04-20',
'guestbook_page_id' => '',
'admin_user_id' => 1,
'initial_views' => 0,
'timezone_offset' => 0,
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
$widget = new Site_Statistics_Widget();
$widget->display_statistics($instance);
echo '</div>';
return ob_get_clean();
}
add_shortcode('site_statistics', 'site_statistics_shortcode');
// 添加管理菜单
function site_statistics_add_admin_menu() {
add_options_page(
'网站统计设置',
'网站统计',
'manage_options',
'site-statistics',
'site_statistics_admin_page'
);
}
add_action('admin_menu', 'site_statistics_add_admin_menu');
// 管理页面
function site_statistics_admin_page() {
if (!current_user_can('manage_options')) {
return;
}
// 处理表单提交
if (isset($_POST['action'])) {
if ($_POST['action'] === 'reset_views' && check_admin_referer('site_stats_reset')) {
update_option('site_statistics_page_views', 0);
echo '<div class="notice notice-success"><p>访问量已重置为0</p></div>';
} elseif ($_POST['action'] === 'set_views' && check_admin_referer('site_stats_set')) {
$views = intval($_POST['page_views']);
update_option('site_statistics_page_views', $views);
echo '<div class="notice notice-success"><p>访问量已设置为 ' . number_format($views) . '</p></div>';
} elseif ($_POST['action'] === 'clear_login_cache' && check_admin_referer('site_stats_clear_cache')) {
// 清除所有用户的登录时间缓存
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key = 'site_stats_last_login_corrected'");
echo '<div class="notice notice-success"><p>已清除登录时间缓存</p></div>';
} elseif ($_POST['action'] === 'clear_css_cache' && check_admin_referer('site_stats_clear_css_cache')) {
// 清除CSS缓存
update_option('site_statistics_css_version', time());
echo '<div class="notice notice-success"><p>CSS缓存已清除,请刷新页面查看新样式</p></div>';
}
}
// 获取统计数据
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
?>
<div class="wrap">
<h1>网站统计设置</h1>
<div class="site-stats-admin-page">
<div class="stats-overview">
<h2>统计数据概览</h2>
<table class="widefat">
<tr>
<td><strong>页面访问量</strong></td>
<td><?php echo number_format($page_views); ?> 次</td>
</tr>
<tr>
<td><strong>文章总数</strong></td>
<td><?php echo $post_count; ?> 篇</td>
</tr>
<tr>
<td><strong>文章评论</strong></td>
<td><?php echo $comment_count; ?> 条</td>
</tr>
<tr>
<td><strong>友情链接</strong></td>
<td><?php echo $bookmarks_count; ?> 个</td>
</tr>
</table>
</div>
<div class="stats-controls">
<h2>访问量控制</h2>
<form method="post" style="margin-bottom: 20px;">
<?php wp_nonce_field('site_stats_set'); ?>
<input type="hidden" name="action" value="set_views">
<p>
<label for="page_views">设置访问量:</label>
<input type="number" name="page_views" value="<?php echo $page_views; ?>" class="regular-text">
<input type="submit" value="设置" class="button button-primary">
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_reset'); ?>
<input type="hidden" name="action" value="reset_views">
<p>
<input type="submit" value="重置访问量为0" class="button button-secondary"
onclick="return confirm('确定要重置访问量吗?这将无法恢复!');">
</p>
</form>
<h2>缓存管理</h2>
<form method="post" style="margin-bottom: 15px;">
<?php wp_nonce_field('site_stats_clear_cache'); ?>
<input type="hidden" name="action" value="clear_login_cache">
<p>
<input type="submit" value="清除登录时间缓存" class="button">
<small>如果登录时间显示不正确,请清除缓存后重新登录</small>
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_clear_css_cache'); ?>
<input type="hidden" name="action" value="clear_css_cache">
<p>
<input type="submit" value="清除CSS样式缓存" class="button">
<small>如果样式没有更新,请清除CSS缓存</small>
</p>
</form>
</div>
</div>
<div class="stats-info">
<h3>使用说明</h3>
<ul>
<li><strong>时区校正:</strong>如果显示的时间比实际时间早,请设置为正数(如:10.5)</li>
<li><strong>显示控制:</strong>取消勾选的项目将不会在前台显示</li>
<li><strong>文章评论:</strong>只统计文章(post类型)的评论,不包括页面和其他类型</li>
<li><strong>好友留言:</strong>需要选择留言板页面才能统计</li>
<li><strong>站长登录:</strong>需要选择站长账号才能显示</li>
<li><strong>访问量:</strong>自动过滤爬虫,同一会话24小时内只计数一次</li>
<li><strong>样式问题:</strong>如果样式未更新,请清除CSS缓存或按Ctrl+F5强制刷新</li>
</ul>
</div>
</div>
<style>
.site-stats-admin-page {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 20px 0;
}
.stats-overview table {
width: 100%;
border-collapse: collapse;
}
.stats-overview td {
padding: 10px;
border-bottom: 1px solid #eee;
}
.stats-controls form {
background: #f9f9f9;
padding: 15px;
border-radius: 4px;
margin-bottom: 15px;
}
.stats-info ul {
list-style: disc;
margin-left: 20px;
}
.stats-info li {
margin-bottom: 5px;
}
@media (max-width: 768px) {
.site-stats-admin-page {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// 添加仪表板小工具
function site_statistics_dashboard_widget() {
wp_add_dashboard_widget(
'site_statistics_dashboard',
'网站统计概览',
'site_statistics_dashboard_content'
);
}
add_action('wp_dashboard_setup', 'site_statistics_dashboard_widget');
function site_statistics_dashboard_content() {
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
echo '<div style="padding: 10px;">';
echo '<p><strong>总访问量:</strong>' . number_format($page_views) . ' 次</p>';
echo '<p><strong>文章总数:</strong>' . $post_count . ' 篇</p>';
echo '<p><strong>文章评论:</strong>' . $comment_count . ' 条</p>';
echo '<p><strong>友链数量:</strong>' . $bookmarks_count . ' 个</p>';
echo '</div>';
}
// 在插件激活时设置时区相关选项
function site_statistics_activate() {
// 确保访问量选项存在
if (false === get_option('site_statistics_page_views')) {
update_option('site_statistics_page_views', 0);
}
// 确保CSS版本选项存在
if (false === get_option('site_statistics_css_version')) {
update_option('site_statistics_css_version', 0);
}
}
register_activation_hook(__FILE__, 'site_statistics_activate');
// 添加清除缓存链接到插件列表
function site_statistics_plugin_action_links($links) {
$settings_link = '<a href="' . admin_url('options-general.php?page=site-statistics') . '">设置</a>';
$cache_link = '<a href="' . admin_url('options-general.php?page=site-statistics&action=clear_cache') . '">清除缓存</a>';
array_unshift($links, $cache_link);
array_unshift($links, $settings_link);
return $links;
}
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'site_statistics_plugin_action_links');<?php
/**
* Plugin Name: 网站数据统计小工具
* Description: 显示网站运行时间、文章、评论、友链等统计信息
* Version: 4.0
* Author: 您的名称
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class Site_Statistics_Widget extends WP_Widget {
private $page_views_option = 'site_statistics_page_views';
private $plugin_version = '4.0';
// 构造函数
public function __construct() {
parent::__construct(
'site_statistics_widget',
'网站数据统计',
array('description' => '显示网站运行时间、文章、评论、友链等统计信息')
);
// 注册样式表
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
// 初始化访问量统计
add_action('init', array($this, 'init_page_views'));
// 初始化会话
add_action('init', array($this, 'init_session'));
// 添加内联样式
add_action('wp_head', array($this, 'add_inline_styles'));
}
// 注册前端样式
public function enqueue_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
// 使用文件修改时间作为版本号,确保缓存更新
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_version = file_exists($css_file) ? filemtime($css_file) : $this->plugin_version;
// 添加缓存清除版本
$cache_version = get_option('site_statistics_css_version', 0);
if ($cache_version) {
$css_version = $cache_version;
}
wp_enqueue_style(
'site-statistics-style',
plugins_url('css/style.css', __FILE__),
array(),
$css_version
);
}
}
// 添加内联样式确保覆盖
public function add_inline_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
echo '<style>
.site-statistics {
background: #ffffff !important;
border: 1px solid #eaeaea !important;
border-radius: 8px !important;
padding: 20px !important;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05) !important;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
font-size: 13px !important;
line-height: 1.5 !important;
color: #333 !important;
}
.site-statistics .stat-item {
background: transparent !important;
background-image: none !important;
}
.site-statistics .stat-main,
.site-statistics .stat-details,
.site-statistics .stat-info {
border-bottom: 1px dashed #e0e0e0 !important;
}
.site-statistics .stat-row,
.site-statistics .info-row {
border-bottom: 1px dashed #f0f0f0 !important;
}
.site-statistics .footer-time {
background: #f9f9f9 !important;
border: 1px solid #eaeaea !important;
}
.site-statistics * {
background-image: none !important;
}
</style>';
}
}
// 初始化会话
public function init_session() {
if (!session_id() && !headers_sent()) {
session_start();
}
}
// 初始化访问量
public function init_page_views() {
$page_views = get_option($this->page_views_option);
if ($page_views === false) {
update_option($this->page_views_option, 0);
}
}
// 前端显示
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$this->display_statistics($instance);
echo $args['after_widget'];
}
// 后台表单
public function form($instance) {
// 设置默认值
$defaults = array(
'title' => '网站数据统计',
'start_date' => date('Y-m-d'),
'guestbook_page_id' => '',
'admin_user_id' => '',
'initial_views' => '0',
'timezone_offset' => '0'
);
// 显示选项默认值
$display_defaults = array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
// 合并所有默认值
$all_defaults = array_merge($defaults, $display_defaults);
// 确保所有字段都有值
$instance = wp_parse_args((array) $instance, $all_defaults);
// 获取所有用户
$users = get_users(array(
'orderby' => 'display_name',
'order' => 'ASC'
));
// 获取所有页面
$pages = get_pages();
// 获取当前访问量
$current_views = get_option($this->page_views_option, 0);
// 显示当前服务器时间
$current_server_time = date('Y-m-d H:i:s');
$server_timezone = date_default_timezone_get();
// 获取CSS文件信息
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_mtime = file_exists($css_file) ? date('Y-m-d H:i:s', filemtime($css_file)) : '文件不存在';
?>
<div class="site-statistics-admin">
<!-- 基础设置 -->
<div class="admin-section">
<h4>基本设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">标题:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
type="text" value="<?php echo esc_attr($instance['title']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('start_date')); ?>">网站起始日期:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('start_date')); ?>"
name="<?php echo esc_attr($this->get_field_name('start_date')); ?>"
type="date" value="<?php echo esc_attr($instance['start_date']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>">站长账号:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('admin_user_id')); ?>">
<option value="">-- 选择站长账号 --</option>
<?php foreach ($users as $user): ?>
<option value="<?php echo $user->ID; ?>" <?php selected($instance['admin_user_id'], $user->ID); ?>>
<?php echo esc_html($user->display_name); ?> (<?php echo esc_html($user->user_login); ?>)
</option>
<?php endforeach; ?>
</select>
</p>
</div>
<!-- 时间设置 -->
<div class="admin-section">
<h4>时间设置</h4>
<div style="background: #f5f5f5; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>时间信息:</strong><br>
服务器时间:<?php echo $current_server_time; ?><br>
时区:<?php echo $server_timezone; ?> (UTC<?php echo date('P'); ?>)
</p>
</div>
<p>
<label for="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>">时区校正(小时):</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>"
name="<?php echo esc_attr($this->get_field_name('timezone_offset')); ?>"
type="number" value="<?php echo esc_attr($instance['timezone_offset']); ?>"
step="0.5" min="-12" max="14">
<small>格式:数字,如 8, -5, 10.5, -8.5</small>
</p>
<div style="background: #e8f5e8; padding: 8px; border-radius: 4px; margin-top: 8px;">
<small>
<strong>校正说明:</strong><br>
如果显示时间比实际早,请设置为正数(如:10.5)<br>
如果显示时间比实际晚,请设置为负数(如:-10.5)
</small>
</div>
</div>
<!-- 显示控制 -->
<div class="admin-section">
<h4>显示控制</h4>
<div class="display-controls">
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_runtime')); ?>"
value="1" <?php checked($instance['show_runtime'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>">
显示运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_articles')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_articles')); ?>"
value="1" <?php checked($instance['show_articles'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_articles')); ?>">
显示文章数量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_wordcount')); ?>"
value="1" <?php checked($instance['show_wordcount'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>">
显示字数统计
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_comments')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_comments')); ?>"
value="1" <?php checked($instance['show_comments'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_comments')); ?>">
显示文章评论
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_links')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_links')); ?>"
value="1" <?php checked($instance['show_links'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_links')); ?>">
显示邻居友链
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_guestbook')); ?>"
value="1" <?php checked($instance['show_guestbook'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>">
显示好友留言
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_rundays')); ?>"
value="1" <?php checked($instance['show_rundays'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>">
显示详细运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_pageviews')); ?>"
value="1" <?php checked($instance['show_pageviews'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>">
显示页面访问量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_login_time')); ?>"
value="1" <?php checked($instance['show_login_time'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>">
显示最后登录时间
</label>
</p>
</div>
</div>
<!-- 数据设置 -->
<div class="admin-section">
<h4>数据设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>">留言板页面:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('guestbook_page_id')); ?>">
<option value="">-- 无留言板 --</option>
<?php foreach ($pages as $page): ?>
<option value="<?php echo $page->ID; ?>" <?php selected($instance['guestbook_page_id'], $page->ID); ?>>
<?php echo esc_html($page->post_title); ?>
</option>
<?php endforeach; ?>
</select>
</p>
<p>
<label>当前访问量:</label>
<span style="font-weight: bold; color: #333;"><?php echo number_format($current_views); ?> 次</span>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('initial_views')); ?>">设置访问量:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('initial_views')); ?>"
name="<?php echo esc_attr($this->get_field_name('initial_views')); ?>"
type="number" value="<?php echo esc_attr($instance['initial_views']); ?>" min="0" step="1">
<small>设置后点击"保存"生效</small>
</p>
</div>
<!-- CSS信息 -->
<div class="admin-section">
<h4>样式信息</h4>
<div style="background: #f0f8ff; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>CSS文件信息:</strong><br>
CSS最后修改:<?php echo $css_mtime; ?><br>
如果样式未更新:<br>
1. 按Ctrl+F5强制刷新<br>
2. <a href="<?php echo admin_url('options-general.php?page=site-statistics&action=clear_cache'); ?>" style="color: #0073aa;">点击清除CSS缓存</a>
</p>
</div>
</div>
</div>
<style>
.site-statistics-admin {
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 15px;
background: #fafafa;
}
.admin-section {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #e0e0e0;
}
.admin-section:last-child {
border-bottom: none;
margin-bottom: 0;
}
.admin-section h4 {
margin: 0 0 12px 0;
color: #333;
font-size: 14px;
}
.display-controls p {
margin-bottom: 8px;
}
</style>
<?php
}
// 更新设置
public function update($new_instance, $old_instance) {
$instance = array();
// 基础设置
$instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
$instance['start_date'] = !empty($new_instance['start_date']) ? sanitize_text_field($new_instance['start_date']) : date('Y-m-d');
$instance['guestbook_page_id'] = isset($new_instance['guestbook_page_id']) ? intval($new_instance['guestbook_page_id']) : '';
$instance['admin_user_id'] = isset($new_instance['admin_user_id']) ? intval($new_instance['admin_user_id']) : '';
$instance['initial_views'] = isset($new_instance['initial_views']) ? intval($new_instance['initial_views']) : 0;
$instance['timezone_offset'] = isset($new_instance['timezone_offset']) ? floatval($new_instance['timezone_offset']) : 0;
// 显示选项
$instance['show_runtime'] = isset($new_instance['show_runtime']) ? 1 : 0;
$instance['show_articles'] = isset($new_instance['show_articles']) ? 1 : 0;
$instance['show_wordcount'] = isset($new_instance['show_wordcount']) ? 1 : 0;
$instance['show_comments'] = isset($new_instance['show_comments']) ? 1 : 0;
$instance['show_links'] = isset($new_instance['show_links']) ? 1 : 0;
$instance['show_guestbook'] = isset($new_instance['show_guestbook']) ? 1 : 0;
$instance['show_rundays'] = isset($new_instance['show_rundays']) ? 1 : 0;
$instance['show_pageviews'] = isset($new_instance['show_pageviews']) ? 1 : 0;
$instance['show_login_time'] = isset($new_instance['show_login_time']) ? 1 : 0;
// 更新访问量
if ($instance['initial_views'] > 0) {
$current_views = get_option($this->page_views_option, 0);
if ($instance['initial_views'] > $current_views) {
update_option($this->page_views_option, $instance['initial_views']);
}
}
return $instance;
}
// 显示统计数据
private function display_statistics($instance) {
// 确保显示选项存在且正确
$instance = wp_parse_args((array) $instance, array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
));
// 获取数据
$data = $this->get_statistics_data($instance);
// 如果没有设置站长,强制不显示登录时间
if (empty($instance['admin_user_id'])) {
$instance['show_login_time'] = 0;
}
?>
<div class="site-statistics">
<!-- 主要统计 -->
<?php if ($instance['show_runtime'] || $instance['show_articles']): ?>
<div class="stat-main">
<?php if ($instance['show_runtime']): ?>
<div class="stat-item">
<div class="stat-label">运行时间</div>
<div class="stat-value"><?php echo $data['runtime']['years']; ?> 年</div>
</div>
<?php endif; ?>
<?php if ($instance['show_articles']): ?>
<div class="stat-item">
<div class="stat-label">文章数量</div>
<div class="stat-value"><?php echo $data['post_count']; ?> 篇</div>
<?php if ($instance['show_wordcount']): ?>
<div class="stat-sub"><?php echo number_format($data['wordcount'] / 10000, 1); ?> 万字</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 详细统计 -->
<?php if (($instance['show_comments'] && $data['article_comments'] > 0) ||
($instance['show_links'] && $data['bookmarks_count'] > 0) ||
($instance['show_guestbook'] && $data['guestbook_comments'] > 0)): ?>
<div class="stat-details">
<?php if ($instance['show_comments'] && $data['article_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">文章评论</span>
<span class="detail-value"><?php echo $data['article_comments']; ?> 条</span>
</div>
<?php endif; ?>
<?php if ($instance['show_links'] && $data['bookmarks_count'] > 0): ?>
<div class="stat-row">
<span class="detail-label">邻居友链</span>
<span class="detail-value"><?php echo $data['bookmarks_count']; ?> 个</span>
</div>
<?php endif; ?>
<?php if ($instance['show_guestbook'] && $data['guestbook_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">好友留言</span>
<span class="detail-value"><?php echo $data['guestbook_comments']; ?> 条</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 运行信息 -->
<?php if ($instance['show_rundays'] || $instance['show_pageviews']): ?>
<div class="stat-info">
<?php if ($instance['show_rundays']): ?>
<div class="info-row">
<span class="info-label">网站运行</span>
<span class="info-value">
<?php echo $data['runtime']['years']; ?>年
<?php echo $data['runtime']['months']; ?>月
<?php echo $data['runtime']['days']; ?>天
</span>
</div>
<?php endif; ?>
<?php if ($instance['show_pageviews']): ?>
<div class="info-row">
<span class="info-label">页面访问</span>
<span class="info-value"><?php echo number_format($data['page_views']); ?> 次</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 站长信息 -->
<?php if ($instance['show_login_time'] && !empty($data['last_login'])): ?>
<div class="stat-footer">
<div class="footer-label">站长最后登录</div>
<div class="footer-time"><?php echo $data['last_login']; ?></div>
</div>
<?php endif; ?>
</div>
<?php
}
// 获取统计数据
private function get_statistics_data($instance) {
$data = array();
// 文章数据
$data['post_count'] = wp_count_posts()->publish;
$data['wordcount'] = $this->calculate_wordcount();
// 评论数据
$data['article_comments'] = $this->get_article_comments_count();
$data['guestbook_comments'] = $this->get_guestbook_comments_count($instance);
// 友链数据
$data['bookmarks_count'] = $this->get_bookmarks_count();
// 运行时间
$data['runtime'] = $this->calculate_runtime($instance['start_date']);
// 页面访问量
$data['page_views'] = $this->get_page_views();
// 最后登录时间
if (!empty($instance['admin_user_id'])) {
$data['last_login'] = $this->get_admin_last_login($instance);
} else {
$data['last_login'] = '';
}
return $data;
}
// 计算字数
private function calculate_wordcount() {
static $wordcount = null;
if ($wordcount === null) {
global $wpdb;
$result = $wpdb->get_var(
"SELECT SUM(
LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', '')) + 1
) as wordcount
FROM {$wpdb->posts}
WHERE post_type = 'post'
AND post_status = 'publish'"
);
$wordcount = $result ? intval($result) : 0;
}
return $wordcount;
}
// 获取文章评论数量
private function get_article_comments_count() {
global $wpdb;
$count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
return $count ? intval($count) : 0;
}
// 获取留言板评论数量
private function get_guestbook_comments_count($instance) {
if (empty($instance['guestbook_page_id'])) {
return 0;
}
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*)
FROM {$wpdb->comments}
WHERE comment_approved = '1'
AND comment_post_ID = %d",
$instance['guestbook_page_id']
));
return $count ? intval($count) : 0;
}
// 获取友情链接数量
private function get_bookmarks_count() {
$bookmarks = get_bookmarks(array('hide_invisible' => 1));
return count($bookmarks);
}
// 计算运行时间
private function calculate_runtime($start_date) {
try {
$start = new DateTime($start_date);
$now = new DateTime();
$interval = $start->diff($now);
return array(
'years' => $interval->y,
'months' => $interval->m,
'days' => $interval->d
);
} catch (Exception $e) {
return array('years' => 0, 'months' => 0, 'days' => 0);
}
}
// 获取页面访问量
private function get_page_views() {
return get_option($this->page_views_option, 0);
}
// 获取站长最后登录时间
private function get_admin_last_login($instance) {
$admin_id = $instance['admin_user_id'];
if (empty($admin_id)) {
return '';
}
// 获取时区偏移量
$timezone_offset = isset($instance['timezone_offset']) ? floatval($instance['timezone_offset']) : 0;
// 方法1:从专用字段获取
$last_login = get_user_meta($admin_id, 'site_stats_last_login_corrected', true);
// 方法2:如果没有专用字段,从普通字段获取并校正
if (empty($last_login)) {
$last_login_raw = get_user_meta($admin_id, 'last_login', true);
if (!empty($last_login_raw)) {
// 应用时区校正
$last_login = $this->apply_timezone_correction($last_login_raw, $timezone_offset);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
// 方法3:从会话获取
if (empty($last_login)) {
$session_tokens = get_user_meta($admin_id, 'session_tokens', true);
if (!empty($session_tokens) && is_array($session_tokens)) {
$last_login_time = 0;
foreach ($session_tokens as $session) {
if (isset($session['login']) && $session['login'] > $last_login_time) {
$last_login_time = $session['login'];
}
}
if ($last_login_time > 0) {
$last_login = $this->apply_timezone_correction(
date('Y-m-d H:i:s', $last_login_time),
$timezone_offset
);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
}
return !empty($last_login) ? $last_login : '暂无记录';
}
// 应用时区校正
private function apply_timezone_correction($time_string, $offset_hours) {
try {
// 解析时间
$datetime = new DateTime($time_string);
// 应用时区偏移
if ($offset_hours != 0) {
$interval = DateInterval::createFromDateString(abs($offset_hours) . ' hours');
if ($offset_hours > 0) {
$datetime->add($interval);
} else {
$datetime->sub($interval);
}
}
// 返回格式化的时间
return $datetime->format('Y-m-d H:i:s');
} catch (Exception $e) {
return $time_string;
}
}
}
// 注册小工具
function register_site_statistics_widget() {
register_widget('Site_Statistics_Widget');
}
add_action('widgets_init', 'register_site_statistics_widget');
// 记录页面访问量
function site_statistics_count_page_view() {
// 不记录后台访问
if (is_admin()) {
return;
}
// 不记录爬虫
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
$bots = array('bot', 'spider', 'crawl', 'scrape', 'slurp', 'curl', 'wget', 'python', 'java');
foreach ($bots as $bot) {
if (strpos($user_agent, $bot) !== false) {
return;
}
}
}
// 使用会话防止重复计数(24小时)
if (!isset($_SESSION['site_stats_last_count'])) {
$_SESSION['site_stats_last_count'] = time();
} else {
if (time() - $_SESSION['site_stats_last_count'] < 86400) {
return;
}
}
// 增加访问量
$current_views = get_option('site_statistics_page_views', 0);
update_option('site_statistics_page_views', $current_views + 1);
// 更新最后计数时间
$_SESSION['site_stats_last_count'] = time();
}
add_action('wp', 'site_statistics_count_page_view');
// 记录用户最后登录时间
function site_statistics_record_last_login($user_login, $user) {
if ($user && $user->ID) {
// 存储当前时间
$current_time = current_time('mysql');
// 存储到专用字段
update_user_meta($user->ID, 'last_login', $current_time);
// 清除校正后的缓存
delete_user_meta($user->ID, 'site_stats_last_login_corrected');
}
}
add_action('wp_login', 'site_statistics_record_last_login', 10, 2);
// 添加快捷码支持
function site_statistics_shortcode($atts) {
$atts = shortcode_atts(array(
'title' => ''
), $atts);
ob_start();
echo '<div class="site-statistics-shortcode">';
if (!empty($atts['title'])) {
echo '<h3>' . esc_html($atts['title']) . '</h3>';
}
// 创建默认实例
$instance = array(
'title' => '',
'start_date' => '2002-04-20',
'guestbook_page_id' => '',
'admin_user_id' => 1,
'initial_views' => 0,
'timezone_offset' => 0,
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
$widget = new Site_Statistics_Widget();
$widget->display_statistics($instance);
echo '</div>';
return ob_get_clean();
}
add_shortcode('site_statistics', 'site_statistics_shortcode');
// 添加管理菜单
function site_statistics_add_admin_menu() {
add_options_page(
'网站统计设置',
'网站统计',
'manage_options',
'site-statistics',
'site_statistics_admin_page'
);
}
add_action('admin_menu', 'site_statistics_add_admin_menu');
// 管理页面
function site_statistics_admin_page() {
if (!current_user_can('manage_options')) {
return;
}
// 处理表单提交
if (isset($_POST['action'])) {
if ($_POST['action'] === 'reset_views' && check_admin_referer('site_stats_reset')) {
update_option('site_statistics_page_views', 0);
echo '<div class="notice notice-success"><p>访问量已重置为0</p></div>';
} elseif ($_POST['action'] === 'set_views' && check_admin_referer('site_stats_set')) {
$views = intval($_POST['page_views']);
update_option('site_statistics_page_views', $views);
echo '<div class="notice notice-success"><p>访问量已设置为 ' . number_format($views) . '</p></div>';
} elseif ($_POST['action'] === 'clear_login_cache' && check_admin_referer('site_stats_clear_cache')) {
// 清除所有用户的登录时间缓存
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key = 'site_stats_last_login_corrected'");
echo '<div class="notice notice-success"><p>已清除登录时间缓存</p></div>';
} elseif ($_POST['action'] === 'clear_css_cache' && check_admin_referer('site_stats_clear_css_cache')) {
// 清除CSS缓存
update_option('site_statistics_css_version', time());
echo '<div class="notice notice-success"><p>CSS缓存已清除,请刷新页面查看新样式</p></div>';
}
}
// 获取统计数据
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
?>
<div class="wrap">
<h1>网站统计设置</h1>
<div class="site-stats-admin-page">
<div class="stats-overview">
<h2>统计数据概览</h2>
<table class="widefat">
<tr>
<td><strong>页面访问量</strong></td>
<td><?php echo number_format($page_views); ?> 次</td>
</tr>
<tr>
<td><strong>文章总数</strong></td>
<td><?php echo $post_count; ?> 篇</td>
</tr>
<tr>
<td><strong>文章评论</strong></td>
<td><?php echo $comment_count; ?> 条</td>
</tr>
<tr>
<td><strong>友情链接</strong></td>
<td><?php echo $bookmarks_count; ?> 个</td>
</tr>
</table>
</div>
<div class="stats-controls">
<h2>访问量控制</h2>
<form method="post" style="margin-bottom: 20px;">
<?php wp_nonce_field('site_stats_set'); ?>
<input type="hidden" name="action" value="set_views">
<p>
<label for="page_views">设置访问量:</label>
<input type="number" name="page_views" value="<?php echo $page_views; ?>" class="regular-text">
<input type="submit" value="设置" class="button button-primary">
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_reset'); ?>
<input type="hidden" name="action" value="reset_views">
<p>
<input type="submit" value="重置访问量为0" class="button button-secondary"
onclick="return confirm('确定要重置访问量吗?这将无法恢复!');">
</p>
</form>
<h2>缓存管理</h2>
<form method="post" style="margin-bottom: 15px;">
<?php wp_nonce_field('site_stats_clear_cache'); ?>
<input type="hidden" name="action" value="clear_login_cache">
<p>
<input type="submit" value="清除登录时间缓存" class="button">
<small>如果登录时间显示不正确,请清除缓存后重新登录</small>
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_clear_css_cache'); ?>
<input type="hidden" name="action" value="clear_css_cache">
<p>
<input type="submit" value="清除CSS样式缓存" class="button">
<small>如果样式没有更新,请清除CSS缓存</small>
</p>
</form>
</div>
</div>
<div class="stats-info">
<h3>使用说明</h3>
<ul>
<li><strong>时区校正:</strong>如果显示的时间比实际时间早,请设置为正数(如:10.5)</li>
<li><strong>显示控制:</strong>取消勾选的项目将不会在前台显示</li>
<li><strong>文章评论:</strong>只统计文章(post类型)的评论,不包括页面和其他类型</li>
<li><strong>好友留言:</strong>需要选择留言板页面才能统计</li>
<li><strong>站长登录:</strong>需要选择站长账号才能显示</li>
<li><strong>访问量:</strong>自动过滤爬虫,同一会话24小时内只计数一次</li>
<li><strong>样式问题:</strong>如果样式未更新,请清除CSS缓存或按Ctrl+F5强制刷新</li>
</ul>
</div>
</div>
<style>
.site-stats-admin-page {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 20px 0;
}
.stats-overview table {
width: 100%;
border-collapse: collapse;
}
.stats-overview td {
padding: 10px;
border-bottom: 1px solid #eee;
}
.stats-controls form {
background: #f9f9f9;
padding: 15px;
border-radius: 4px;
margin-bottom: 15px;
}
.stats-info ul {
list-style: disc;
margin-left: 20px;
}
.stats-info li {
margin-bottom: 5px;
}
@media (max-width: 768px) {
.site-stats-admin-page {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// 添加仪表板小工具
function site_statistics_dashboard_widget() {
wp_add_dashboard_widget(
'site_statistics_dashboard',
'网站统计概览',
'site_statistics_dashboard_content'
);
}
add_action('wp_dashboard_setup', 'site_statistics_dashboard_widget');
function site_statistics_dashboard_content() {
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
echo '<div style="padding: 10px;">';
echo '<p><strong>总访问量:</strong>' . number_format($page_views) . ' 次</p>';
echo '<p><strong>文章总数:</strong>' . $post_count . ' 篇</p>';
echo '<p><strong>文章评论:</strong>' . $comment_count . ' 条</p>';
echo '<p><strong>友链数量:</strong>' . $bookmarks_count . ' 个</p>';
echo '</div>';
}
// 在插件激活时设置时区相关选项
function site_statistics_activate() {
// 确保访问量选项存在
if (false === get_option('site_statistics_page_views')) {
update_option('site_statistics_page_views', 0);
}
// 确保CSS版本选项存在
if (false === get_option('site_statistics_css_version')) {
update_option('site_statistics_css_version', 0);
}
}
register_activation_hook(__FILE__, 'site_statistics_activate');
// 添加清除缓存链接到插件列表
function site_statistics_plugin_action_links($links) {
$settings_link = '<a href="' . admin_url('options-general.php?page=site-statistics') . '">设置</a>';
$cache_link = '<a href="' . admin_url('options-general.php?page=site-statistics&action=clear_cache') . '">清除缓存</a>';
array_unshift($links, $cache_link);
array_unshift($links, $settings_link);
return $links;
}
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'site_statistics_plugin_action_links');<?php
/**
* Plugin Name: 网站数据统计小工具
* Description: 显示网站运行时间、文章、评论、友链等统计信息
* Version: 4.0
* Author: 您的名称
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class Site_Statistics_Widget extends WP_Widget {
private $page_views_option = 'site_statistics_page_views';
private $plugin_version = '4.0';
// 构造函数
public function __construct() {
parent::__construct(
'site_statistics_widget',
'网站数据统计',
array('description' => '显示网站运行时间、文章、评论、友链等统计信息')
);
// 注册样式表
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
// 初始化访问量统计
add_action('init', array($this, 'init_page_views'));
// 初始化会话
add_action('init', array($this, 'init_session'));
// 添加内联样式
add_action('wp_head', array($this, 'add_inline_styles'));
}
// 注册前端样式
public function enqueue_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
// 使用文件修改时间作为版本号,确保缓存更新
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_version = file_exists($css_file) ? filemtime($css_file) : $this->plugin_version;
// 添加缓存清除版本
$cache_version = get_option('site_statistics_css_version', 0);
if ($cache_version) {
$css_version = $cache_version;
}
wp_enqueue_style(
'site-statistics-style',
plugins_url('css/style.css', __FILE__),
array(),
$css_version
);
}
}
// 添加内联样式确保覆盖
public function add_inline_styles() {
if (is_active_widget(false, false, $this->id_base, true)) {
echo '<style>
.site-statistics {
background: #ffffff !important;
border: 1px solid #eaeaea !important;
border-radius: 8px !important;
padding: 20px !important;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05) !important;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
font-size: 13px !important;
line-height: 1.5 !important;
color: #333 !important;
}
.site-statistics .stat-item {
background: transparent !important;
background-image: none !important;
}
.site-statistics .stat-main,
.site-statistics .stat-details,
.site-statistics .stat-info {
border-bottom: 1px dashed #e0e0e0 !important;
}
.site-statistics .stat-row,
.site-statistics .info-row {
border-bottom: 1px dashed #f0f0f0 !important;
}
.site-statistics .footer-time {
background: #f9f9f9 !important;
border: 1px solid #eaeaea !important;
}
.site-statistics * {
background-image: none !important;
}
</style>';
}
}
// 初始化会话
public function init_session() {
if (!session_id() && !headers_sent()) {
session_start();
}
}
// 初始化访问量
public function init_page_views() {
$page_views = get_option($this->page_views_option);
if ($page_views === false) {
update_option($this->page_views_option, 0);
}
}
// 前端显示
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$this->display_statistics($instance);
echo $args['after_widget'];
}
// 后台表单
public function form($instance) {
// 设置默认值
$defaults = array(
'title' => '网站数据统计',
'start_date' => date('Y-m-d'),
'guestbook_page_id' => '',
'admin_user_id' => '',
'initial_views' => '0',
'timezone_offset' => '0'
);
// 显示选项默认值
$display_defaults = array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
// 合并所有默认值
$all_defaults = array_merge($defaults, $display_defaults);
// 确保所有字段都有值
$instance = wp_parse_args((array) $instance, $all_defaults);
// 获取所有用户
$users = get_users(array(
'orderby' => 'display_name',
'order' => 'ASC'
));
// 获取所有页面
$pages = get_pages();
// 获取当前访问量
$current_views = get_option($this->page_views_option, 0);
// 显示当前服务器时间
$current_server_time = date('Y-m-d H:i:s');
$server_timezone = date_default_timezone_get();
// 获取CSS文件信息
$css_file = plugin_dir_path(__FILE__) . 'css/style.css';
$css_mtime = file_exists($css_file) ? date('Y-m-d H:i:s', filemtime($css_file)) : '文件不存在';
?>
<div class="site-statistics-admin">
<!-- 基础设置 -->
<div class="admin-section">
<h4>基本设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">标题:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
type="text" value="<?php echo esc_attr($instance['title']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('start_date')); ?>">网站起始日期:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('start_date')); ?>"
name="<?php echo esc_attr($this->get_field_name('start_date')); ?>"
type="date" value="<?php echo esc_attr($instance['start_date']); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>">站长账号:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('admin_user_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('admin_user_id')); ?>">
<option value="">-- 选择站长账号 --</option>
<?php foreach ($users as $user): ?>
<option value="<?php echo $user->ID; ?>" <?php selected($instance['admin_user_id'], $user->ID); ?>>
<?php echo esc_html($user->display_name); ?> (<?php echo esc_html($user->user_login); ?>)
</option>
<?php endforeach; ?>
</select>
</p>
</div>
<!-- 时间设置 -->
<div class="admin-section">
<h4>时间设置</h4>
<div style="background: #f5f5f5; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>时间信息:</strong><br>
服务器时间:<?php echo $current_server_time; ?><br>
时区:<?php echo $server_timezone; ?> (UTC<?php echo date('P'); ?>)
</p>
</div>
<p>
<label for="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>">时区校正(小时):</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('timezone_offset')); ?>"
name="<?php echo esc_attr($this->get_field_name('timezone_offset')); ?>"
type="number" value="<?php echo esc_attr($instance['timezone_offset']); ?>"
step="0.5" min="-12" max="14">
<small>格式:数字,如 8, -5, 10.5, -8.5</small>
</p>
<div style="background: #e8f5e8; padding: 8px; border-radius: 4px; margin-top: 8px;">
<small>
<strong>校正说明:</strong><br>
如果显示时间比实际早,请设置为正数(如:10.5)<br>
如果显示时间比实际晚,请设置为负数(如:-10.5)
</small>
</div>
</div>
<!-- 显示控制 -->
<div class="admin-section">
<h4>显示控制</h4>
<div class="display-controls">
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_runtime')); ?>"
value="1" <?php checked($instance['show_runtime'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_runtime')); ?>">
显示运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_articles')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_articles')); ?>"
value="1" <?php checked($instance['show_articles'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_articles')); ?>">
显示文章数量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_wordcount')); ?>"
value="1" <?php checked($instance['show_wordcount'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_wordcount')); ?>">
显示字数统计
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_comments')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_comments')); ?>"
value="1" <?php checked($instance['show_comments'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_comments')); ?>">
显示文章评论
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_links')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_links')); ?>"
value="1" <?php checked($instance['show_links'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_links')); ?>">
显示邻居友链
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_guestbook')); ?>"
value="1" <?php checked($instance['show_guestbook'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_guestbook')); ?>">
显示好友留言
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_rundays')); ?>"
value="1" <?php checked($instance['show_rundays'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_rundays')); ?>">
显示详细运行时间
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_pageviews')); ?>"
value="1" <?php checked($instance['show_pageviews'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_pageviews')); ?>">
显示页面访问量
</label>
</p>
<p>
<input type="checkbox"
id="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>"
name="<?php echo esc_attr($this->get_field_name('show_login_time')); ?>"
value="1" <?php checked($instance['show_login_time'], 1); ?>>
<label for="<?php echo esc_attr($this->get_field_id('show_login_time')); ?>">
显示最后登录时间
</label>
</p>
</div>
</div>
<!-- 数据设置 -->
<div class="admin-section">
<h4>数据设置</h4>
<p>
<label for="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>">留言板页面:</label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('guestbook_page_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('guestbook_page_id')); ?>">
<option value="">-- 无留言板 --</option>
<?php foreach ($pages as $page): ?>
<option value="<?php echo $page->ID; ?>" <?php selected($instance['guestbook_page_id'], $page->ID); ?>>
<?php echo esc_html($page->post_title); ?>
</option>
<?php endforeach; ?>
</select>
</p>
<p>
<label>当前访问量:</label>
<span style="font-weight: bold; color: #333;"><?php echo number_format($current_views); ?> 次</span>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('initial_views')); ?>">设置访问量:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('initial_views')); ?>"
name="<?php echo esc_attr($this->get_field_name('initial_views')); ?>"
type="number" value="<?php echo esc_attr($instance['initial_views']); ?>" min="0" step="1">
<small>设置后点击"保存"生效</small>
</p>
</div>
<!-- CSS信息 -->
<div class="admin-section">
<h4>样式信息</h4>
<div style="background: #f0f8ff; padding: 10px; border-radius: 4px; margin-bottom: 10px;">
<p style="margin: 0; font-size: 12px;">
<strong>CSS文件信息:</strong><br>
CSS最后修改:<?php echo $css_mtime; ?><br>
如果样式未更新:<br>
1. 按Ctrl+F5强制刷新<br>
2. <a href="<?php echo admin_url('options-general.php?page=site-statistics&action=clear_cache'); ?>" style="color: #0073aa;">点击清除CSS缓存</a>
</p>
</div>
</div>
</div>
<style>
.site-statistics-admin {
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 15px;
background: #fafafa;
}
.admin-section {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #e0e0e0;
}
.admin-section:last-child {
border-bottom: none;
margin-bottom: 0;
}
.admin-section h4 {
margin: 0 0 12px 0;
color: #333;
font-size: 14px;
}
.display-controls p {
margin-bottom: 8px;
}
</style>
<?php
}
// 更新设置
public function update($new_instance, $old_instance) {
$instance = array();
// 基础设置
$instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
$instance['start_date'] = !empty($new_instance['start_date']) ? sanitize_text_field($new_instance['start_date']) : date('Y-m-d');
$instance['guestbook_page_id'] = isset($new_instance['guestbook_page_id']) ? intval($new_instance['guestbook_page_id']) : '';
$instance['admin_user_id'] = isset($new_instance['admin_user_id']) ? intval($new_instance['admin_user_id']) : '';
$instance['initial_views'] = isset($new_instance['initial_views']) ? intval($new_instance['initial_views']) : 0;
$instance['timezone_offset'] = isset($new_instance['timezone_offset']) ? floatval($new_instance['timezone_offset']) : 0;
// 显示选项
$instance['show_runtime'] = isset($new_instance['show_runtime']) ? 1 : 0;
$instance['show_articles'] = isset($new_instance['show_articles']) ? 1 : 0;
$instance['show_wordcount'] = isset($new_instance['show_wordcount']) ? 1 : 0;
$instance['show_comments'] = isset($new_instance['show_comments']) ? 1 : 0;
$instance['show_links'] = isset($new_instance['show_links']) ? 1 : 0;
$instance['show_guestbook'] = isset($new_instance['show_guestbook']) ? 1 : 0;
$instance['show_rundays'] = isset($new_instance['show_rundays']) ? 1 : 0;
$instance['show_pageviews'] = isset($new_instance['show_pageviews']) ? 1 : 0;
$instance['show_login_time'] = isset($new_instance['show_login_time']) ? 1 : 0;
// 更新访问量
if ($instance['initial_views'] > 0) {
$current_views = get_option($this->page_views_option, 0);
if ($instance['initial_views'] > $current_views) {
update_option($this->page_views_option, $instance['initial_views']);
}
}
return $instance;
}
// 显示统计数据
private function display_statistics($instance) {
// 确保显示选项存在且正确
$instance = wp_parse_args((array) $instance, array(
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
));
// 获取数据
$data = $this->get_statistics_data($instance);
// 如果没有设置站长,强制不显示登录时间
if (empty($instance['admin_user_id'])) {
$instance['show_login_time'] = 0;
}
?>
<div class="site-statistics">
<!-- 主要统计 -->
<?php if ($instance['show_runtime'] || $instance['show_articles']): ?>
<div class="stat-main">
<?php if ($instance['show_runtime']): ?>
<div class="stat-item">
<div class="stat-label">运行时间</div>
<div class="stat-value"><?php echo $data['runtime']['years']; ?> 年</div>
</div>
<?php endif; ?>
<?php if ($instance['show_articles']): ?>
<div class="stat-item">
<div class="stat-label">文章数量</div>
<div class="stat-value"><?php echo $data['post_count']; ?> 篇</div>
<?php if ($instance['show_wordcount']): ?>
<div class="stat-sub"><?php echo number_format($data['wordcount'] / 10000, 1); ?> 万字</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 详细统计 -->
<?php if (($instance['show_comments'] && $data['article_comments'] > 0) ||
($instance['show_links'] && $data['bookmarks_count'] > 0) ||
($instance['show_guestbook'] && $data['guestbook_comments'] > 0)): ?>
<div class="stat-details">
<?php if ($instance['show_comments'] && $data['article_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">文章评论</span>
<span class="detail-value"><?php echo $data['article_comments']; ?> 条</span>
</div>
<?php endif; ?>
<?php if ($instance['show_links'] && $data['bookmarks_count'] > 0): ?>
<div class="stat-row">
<span class="detail-label">邻居友链</span>
<span class="detail-value"><?php echo $data['bookmarks_count']; ?> 个</span>
</div>
<?php endif; ?>
<?php if ($instance['show_guestbook'] && $data['guestbook_comments'] > 0): ?>
<div class="stat-row">
<span class="detail-label">好友留言</span>
<span class="detail-value"><?php echo $data['guestbook_comments']; ?> 条</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 运行信息 -->
<?php if ($instance['show_rundays'] || $instance['show_pageviews']): ?>
<div class="stat-info">
<?php if ($instance['show_rundays']): ?>
<div class="info-row">
<span class="info-label">网站运行</span>
<span class="info-value">
<?php echo $data['runtime']['years']; ?>年
<?php echo $data['runtime']['months']; ?>月
<?php echo $data['runtime']['days']; ?>天
</span>
</div>
<?php endif; ?>
<?php if ($instance['show_pageviews']): ?>
<div class="info-row">
<span class="info-label">页面访问</span>
<span class="info-value"><?php echo number_format($data['page_views']); ?> 次</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 站长信息 -->
<?php if ($instance['show_login_time'] && !empty($data['last_login'])): ?>
<div class="stat-footer">
<div class="footer-label">站长最后登录</div>
<div class="footer-time"><?php echo $data['last_login']; ?></div>
</div>
<?php endif; ?>
</div>
<?php
}
// 获取统计数据
private function get_statistics_data($instance) {
$data = array();
// 文章数据
$data['post_count'] = wp_count_posts()->publish;
$data['wordcount'] = $this->calculate_wordcount();
// 评论数据
$data['article_comments'] = $this->get_article_comments_count();
$data['guestbook_comments'] = $this->get_guestbook_comments_count($instance);
// 友链数据
$data['bookmarks_count'] = $this->get_bookmarks_count();
// 运行时间
$data['runtime'] = $this->calculate_runtime($instance['start_date']);
// 页面访问量
$data['page_views'] = $this->get_page_views();
// 最后登录时间
if (!empty($instance['admin_user_id'])) {
$data['last_login'] = $this->get_admin_last_login($instance);
} else {
$data['last_login'] = '';
}
return $data;
}
// 计算字数
private function calculate_wordcount() {
static $wordcount = null;
if ($wordcount === null) {
global $wpdb;
$result = $wpdb->get_var(
"SELECT SUM(
LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', '')) + 1
) as wordcount
FROM {$wpdb->posts}
WHERE post_type = 'post'
AND post_status = 'publish'"
);
$wordcount = $result ? intval($result) : 0;
}
return $wordcount;
}
// 获取文章评论数量
private function get_article_comments_count() {
global $wpdb;
$count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
return $count ? intval($count) : 0;
}
// 获取留言板评论数量
private function get_guestbook_comments_count($instance) {
if (empty($instance['guestbook_page_id'])) {
return 0;
}
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*)
FROM {$wpdb->comments}
WHERE comment_approved = '1'
AND comment_post_ID = %d",
$instance['guestbook_page_id']
));
return $count ? intval($count) : 0;
}
// 获取友情链接数量
private function get_bookmarks_count() {
$bookmarks = get_bookmarks(array('hide_invisible' => 1));
return count($bookmarks);
}
// 计算运行时间
private function calculate_runtime($start_date) {
try {
$start = new DateTime($start_date);
$now = new DateTime();
$interval = $start->diff($now);
return array(
'years' => $interval->y,
'months' => $interval->m,
'days' => $interval->d
);
} catch (Exception $e) {
return array('years' => 0, 'months' => 0, 'days' => 0);
}
}
// 获取页面访问量
private function get_page_views() {
return get_option($this->page_views_option, 0);
}
// 获取站长最后登录时间
private function get_admin_last_login($instance) {
$admin_id = $instance['admin_user_id'];
if (empty($admin_id)) {
return '';
}
// 获取时区偏移量
$timezone_offset = isset($instance['timezone_offset']) ? floatval($instance['timezone_offset']) : 0;
// 方法1:从专用字段获取
$last_login = get_user_meta($admin_id, 'site_stats_last_login_corrected', true);
// 方法2:如果没有专用字段,从普通字段获取并校正
if (empty($last_login)) {
$last_login_raw = get_user_meta($admin_id, 'last_login', true);
if (!empty($last_login_raw)) {
// 应用时区校正
$last_login = $this->apply_timezone_correction($last_login_raw, $timezone_offset);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
// 方法3:从会话获取
if (empty($last_login)) {
$session_tokens = get_user_meta($admin_id, 'session_tokens', true);
if (!empty($session_tokens) && is_array($session_tokens)) {
$last_login_time = 0;
foreach ($session_tokens as $session) {
if (isset($session['login']) && $session['login'] > $last_login_time) {
$last_login_time = $session['login'];
}
}
if ($last_login_time > 0) {
$last_login = $this->apply_timezone_correction(
date('Y-m-d H:i:s', $last_login_time),
$timezone_offset
);
update_user_meta($admin_id, 'site_stats_last_login_corrected', $last_login);
}
}
}
return !empty($last_login) ? $last_login : '暂无记录';
}
// 应用时区校正
private function apply_timezone_correction($time_string, $offset_hours) {
try {
// 解析时间
$datetime = new DateTime($time_string);
// 应用时区偏移
if ($offset_hours != 0) {
$interval = DateInterval::createFromDateString(abs($offset_hours) . ' hours');
if ($offset_hours > 0) {
$datetime->add($interval);
} else {
$datetime->sub($interval);
}
}
// 返回格式化的时间
return $datetime->format('Y-m-d H:i:s');
} catch (Exception $e) {
return $time_string;
}
}
}
// 注册小工具
function register_site_statistics_widget() {
register_widget('Site_Statistics_Widget');
}
add_action('widgets_init', 'register_site_statistics_widget');
// 记录页面访问量
function site_statistics_count_page_view() {
// 不记录后台访问
if (is_admin()) {
return;
}
// 不记录爬虫
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
$bots = array('bot', 'spider', 'crawl', 'scrape', 'slurp', 'curl', 'wget', 'python', 'java');
foreach ($bots as $bot) {
if (strpos($user_agent, $bot) !== false) {
return;
}
}
}
// 使用会话防止重复计数(24小时)
if (!isset($_SESSION['site_stats_last_count'])) {
$_SESSION['site_stats_last_count'] = time();
} else {
if (time() - $_SESSION['site_stats_last_count'] < 86400) {
return;
}
}
// 增加访问量
$current_views = get_option('site_statistics_page_views', 0);
update_option('site_statistics_page_views', $current_views + 1);
// 更新最后计数时间
$_SESSION['site_stats_last_count'] = time();
}
add_action('wp', 'site_statistics_count_page_view');
// 记录用户最后登录时间
function site_statistics_record_last_login($user_login, $user) {
if ($user && $user->ID) {
// 存储当前时间
$current_time = current_time('mysql');
// 存储到专用字段
update_user_meta($user->ID, 'last_login', $current_time);
// 清除校正后的缓存
delete_user_meta($user->ID, 'site_stats_last_login_corrected');
}
}
add_action('wp_login', 'site_statistics_record_last_login', 10, 2);
// 添加快捷码支持
function site_statistics_shortcode($atts) {
$atts = shortcode_atts(array(
'title' => ''
), $atts);
ob_start();
echo '<div class="site-statistics-shortcode">';
if (!empty($atts['title'])) {
echo '<h3>' . esc_html($atts['title']) . '</h3>';
}
// 创建默认实例
$instance = array(
'title' => '',
'start_date' => '2002-04-20',
'guestbook_page_id' => '',
'admin_user_id' => 1,
'initial_views' => 0,
'timezone_offset' => 0,
'show_runtime' => 1,
'show_articles' => 1,
'show_wordcount' => 1,
'show_comments' => 1,
'show_links' => 1,
'show_guestbook' => 1,
'show_rundays' => 1,
'show_pageviews' => 1,
'show_login_time' => 1
);
$widget = new Site_Statistics_Widget();
$widget->display_statistics($instance);
echo '</div>';
return ob_get_clean();
}
add_shortcode('site_statistics', 'site_statistics_shortcode');
// 添加管理菜单
function site_statistics_add_admin_menu() {
add_options_page(
'网站统计设置',
'网站统计',
'manage_options',
'site-statistics',
'site_statistics_admin_page'
);
}
add_action('admin_menu', 'site_statistics_add_admin_menu');
// 管理页面
function site_statistics_admin_page() {
if (!current_user_can('manage_options')) {
return;
}
// 处理表单提交
if (isset($_POST['action'])) {
if ($_POST['action'] === 'reset_views' && check_admin_referer('site_stats_reset')) {
update_option('site_statistics_page_views', 0);
echo '<div class="notice notice-success"><p>访问量已重置为0</p></div>';
} elseif ($_POST['action'] === 'set_views' && check_admin_referer('site_stats_set')) {
$views = intval($_POST['page_views']);
update_option('site_statistics_page_views', $views);
echo '<div class="notice notice-success"><p>访问量已设置为 ' . number_format($views) . '</p></div>';
} elseif ($_POST['action'] === 'clear_login_cache' && check_admin_referer('site_stats_clear_cache')) {
// 清除所有用户的登录时间缓存
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key = 'site_stats_last_login_corrected'");
echo '<div class="notice notice-success"><p>已清除登录时间缓存</p></div>';
} elseif ($_POST['action'] === 'clear_css_cache' && check_admin_referer('site_stats_clear_css_cache')) {
// 清除CSS缓存
update_option('site_statistics_css_version', time());
echo '<div class="notice notice-success"><p>CSS缓存已清除,请刷新页面查看新样式</p></div>';
}
}
// 获取统计数据
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
?>
<div class="wrap">
<h1>网站统计设置</h1>
<div class="site-stats-admin-page">
<div class="stats-overview">
<h2>统计数据概览</h2>
<table class="widefat">
<tr>
<td><strong>页面访问量</strong></td>
<td><?php echo number_format($page_views); ?> 次</td>
</tr>
<tr>
<td><strong>文章总数</strong></td>
<td><?php echo $post_count; ?> 篇</td>
</tr>
<tr>
<td><strong>文章评论</strong></td>
<td><?php echo $comment_count; ?> 条</td>
</tr>
<tr>
<td><strong>友情链接</strong></td>
<td><?php echo $bookmarks_count; ?> 个</td>
</tr>
</table>
</div>
<div class="stats-controls">
<h2>访问量控制</h2>
<form method="post" style="margin-bottom: 20px;">
<?php wp_nonce_field('site_stats_set'); ?>
<input type="hidden" name="action" value="set_views">
<p>
<label for="page_views">设置访问量:</label>
<input type="number" name="page_views" value="<?php echo $page_views; ?>" class="regular-text">
<input type="submit" value="设置" class="button button-primary">
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_reset'); ?>
<input type="hidden" name="action" value="reset_views">
<p>
<input type="submit" value="重置访问量为0" class="button button-secondary"
onclick="return confirm('确定要重置访问量吗?这将无法恢复!');">
</p>
</form>
<h2>缓存管理</h2>
<form method="post" style="margin-bottom: 15px;">
<?php wp_nonce_field('site_stats_clear_cache'); ?>
<input type="hidden" name="action" value="clear_login_cache">
<p>
<input type="submit" value="清除登录时间缓存" class="button">
<small>如果登录时间显示不正确,请清除缓存后重新登录</small>
</p>
</form>
<form method="post">
<?php wp_nonce_field('site_stats_clear_css_cache'); ?>
<input type="hidden" name="action" value="clear_css_cache">
<p>
<input type="submit" value="清除CSS样式缓存" class="button">
<small>如果样式没有更新,请清除CSS缓存</small>
</p>
</form>
</div>
</div>
<div class="stats-info">
<h3>使用说明</h3>
<ul>
<li><strong>时区校正:</strong>如果显示的时间比实际时间早,请设置为正数(如:10.5)</li>
<li><strong>显示控制:</strong>取消勾选的项目将不会在前台显示</li>
<li><strong>文章评论:</strong>只统计文章(post类型)的评论,不包括页面和其他类型</li>
<li><strong>好友留言:</strong>需要选择留言板页面才能统计</li>
<li><strong>站长登录:</strong>需要选择站长账号才能显示</li>
<li><strong>访问量:</strong>自动过滤爬虫,同一会话24小时内只计数一次</li>
<li><strong>样式问题:</strong>如果样式未更新,请清除CSS缓存或按Ctrl+F5强制刷新</li>
</ul>
</div>
</div>
<style>
.site-stats-admin-page {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 20px 0;
}
.stats-overview table {
width: 100%;
border-collapse: collapse;
}
.stats-overview td {
padding: 10px;
border-bottom: 1px solid #eee;
}
.stats-controls form {
background: #f9f9f9;
padding: 15px;
border-radius: 4px;
margin-bottom: 15px;
}
.stats-info ul {
list-style: disc;
margin-left: 20px;
}
.stats-info li {
margin-bottom: 5px;
}
@media (max-width: 768px) {
.site-stats-admin-page {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// 添加仪表板小工具
function site_statistics_dashboard_widget() {
wp_add_dashboard_widget(
'site_statistics_dashboard',
'网站统计概览',
'site_statistics_dashboard_content'
);
}
add_action('wp_dashboard_setup', 'site_statistics_dashboard_widget');
function site_statistics_dashboard_content() {
$page_views = get_option('site_statistics_page_views', 0);
$post_count = wp_count_posts()->publish;
global $wpdb;
$comment_count = $wpdb->get_var(
"SELECT COUNT(*)
FROM {$wpdb->comments} c
INNER JOIN {$wpdb->posts} p ON c.comment_post_ID = p.ID
WHERE c.comment_approved = '1'
AND p.post_type = 'post'
AND p.post_status = 'publish'"
);
$bookmarks_count = count(get_bookmarks(array('hide_invisible' => 1)));
echo '<div style="padding: 10px;">';
echo '<p><strong>总访问量:</strong>' . number_format($page_views) . ' 次</p>';
echo '<p><strong>文章总数:</strong>' . $post_count . ' 篇</p>';
echo '<p><strong>文章评论:</strong>' . $comment_count . ' 条</p>';
echo '<p><strong>友链数量:</strong>' . $bookmarks_count . ' 个</p>';
echo '</div>';
}
// 在插件激活时设置时区相关选项
function site_statistics_activate() {
// 确保访问量选项存在
if (false === get_option('site_statistics_page_views')) {
update_option('site_statistics_page_views', 0);
}
// 确保CSS版本选项存在
if (false === get_option('site_statistics_css_version')) {
update_option('site_statistics_css_version', 0);
}
}
register_activation_hook(__FILE__, 'site_statistics_activate');
// 添加清除缓存链接到插件列表
function site_statistics_plugin_action_links($links) {
$settings_link = '<a href="' . admin_url('options-general.php?page=site-statistics') . '">设置</a>';
$cache_link = '<a href="' . admin_url('options-general.php?page=site-statistics&action=clear_cache') . '">清除缓存</a>';
array_unshift($links, $cache_link);
array_unshift($links, $settings_link);
return $links;
}
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'site_statistics_plugin_action_links');
/* 高级简约风格 - 网站数据统计小工具 v4.0 */
.site-statistics {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 13px;
line-height: 1.5;
color: #333;
background: #ffffff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
border: 1px solid #eaeaea;
}
/* 主要统计区域 */
.site-statistics .stat-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .stat-item {
flex: 1;
text-align: center;
padding: 0 10px;
}
.site-statistics .stat-item:first-child {
text-align: left;
}
.site-statistics .stat-item:last-child {
text-align: right;
}
.site-statistics .stat-label {
font-size: 12px;
color: #666;
font-weight: 500;
margin-bottom: 4px;
display: block;
}
.site-statistics .stat-value {
font-size: 18px;
font-weight: 600;
color: #222;
margin-bottom: 3px;
line-height: 1.2;
}
.site-statistics .stat-sub {
font-size: 11px;
color: #888;
font-weight: normal;
}
/* 详细统计行 */
.site-statistics .stat-details {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .stat-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px dashed #f0f0f0;
}
.site-statistics .stat-row:last-child {
border-bottom: none;
}
.site-statistics .detail-label {
color: #555;
font-size: 13px;
font-weight: 500;
}
.site-statistics .detail-value {
color: #222;
font-weight: 600;
font-size: 13px;
font-feature-settings: "tnum";
}
/* 信息区域 */
.site-statistics .stat-info {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .info-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 7px 0;
border-bottom: 1px dashed #f0f0f0;
}
.site-statistics .info-row:last-child {
border-bottom: none;
}
.site-statistics .info-label {
color: #555;
font-size: 13px;
font-weight: 500;
}
.site-statistics .info-value {
color: #222;
font-weight: 600;
font-size: 13px;
text-align: right;
font-feature-settings: "tnum";
}
/* 底部区域 */
.site-statistics .stat-footer {
padding-top: 15px;
text-align: center;
}
.site-statistics .footer-label {
font-size: 11px;
color: #777;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
font-weight: 600;
}
.site-statistics .footer-time {
font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
font-size: 12px;
color: #444;
background: #f9f9f9;
padding: 8px 12px;
border-radius: 4px;
border: 1px solid #eaeaea;
line-height: 1.4;
font-weight: 500;
font-feature-settings: "tnum";
}
/* 短码样式 */
.site-statistics-shortcode {
max-width: 350px;
margin: 0 auto;
}
.site-statistics-shortcode h3 {
text-align: center;
color: #222;
margin-bottom: 18px;
font-size: 16px;
font-weight: 600;
padding-bottom: 10px;
border-bottom: 1px solid #eaeaea;
}
/* 响应式设计 */
@media (max-width: 480px) {
.site-statistics {
padding: 16px;
font-size: 12px;
}
.site-statistics .stat-main {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.site-statistics .stat-item {
text-align: left !important;
padding: 0;
width: 100%;
}
.site-statistics .stat-item:first-child,
.site-statistics .stat-item:last-child {
text-align: left !important;
}
.site-statistics .stat-value {
font-size: 16px;
}
.site-statistics .footer-time {
font-size: 11px;
padding: 6px 10px;
}
.site-statistics-shortcode {
max-width: 100%;
}
}
/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
.site-statistics {
background: #1a1a1a;
border-color: #333;
color: #e0e0e0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.site-statistics .stat-main,
.site-statistics .stat-details,
.site-statistics .stat-info {
border-color: #333;
}
.site-statistics .stat-row,
.site-statistics .info-row {
border-color: #2a2a2a;
}
.site-statistics .stat-label,
.site-statistics .detail-label,
.site-statistics .info-label {
color: #aaa;
}
.site-statistics .stat-value,
.site-statistics .detail-value,
.site-statistics .info-value {
color: #fff;
}
.site-statistics .stat-sub {
color: #888;
}
.site-statistics .footer-label {
color: #999;
}
.site-statistics .footer-time {
background: #222;
border-color: #333;
color: #ccc;
}
.site-statistics-shortcode h3 {
color: #fff;
border-color: #444;
}
}
/* 动画效果 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.site-statistics {
animation: fadeInUp 0.3s ease-out;
}
/* 确保无渐变背景 */
.site-statistics .stat-item,
.site-statistics .footer-time {
background: transparent !important;
background-image: none !important;
}
/* 清除所有可能继承的渐变样式 */
.site-statistics * {
background-image: none !important;
}/* 高级简约风格 - 网站数据统计小工具 v4.0 */
.site-statistics {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 13px;
line-height: 1.5;
color: #333;
background: #ffffff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
border: 1px solid #eaeaea;
}
/* 主要统计区域 */
.site-statistics .stat-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .stat-item {
flex: 1;
text-align: center;
padding: 0 10px;
}
.site-statistics .stat-item:first-child {
text-align: left;
}
.site-statistics .stat-item:last-child {
text-align: right;
}
.site-statistics .stat-label {
font-size: 12px;
color: #666;
font-weight: 500;
margin-bottom: 4px;
display: block;
}
.site-statistics .stat-value {
font-size: 18px;
font-weight: 600;
color: #222;
margin-bottom: 3px;
line-height: 1.2;
}
.site-statistics .stat-sub {
font-size: 11px;
color: #888;
font-weight: normal;
}
/* 详细统计行 */
.site-statistics .stat-details {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .stat-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px dashed #f0f0f0;
}
.site-statistics .stat-row:last-child {
border-bottom: none;
}
.site-statistics .detail-label {
color: #555;
font-size: 13px;
font-weight: 500;
}
.site-statistics .detail-value {
color: #222;
font-weight: 600;
font-size: 13px;
font-feature-settings: "tnum";
}
/* 信息区域 */
.site-statistics .stat-info {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px dashed #e0e0e0;
}
.site-statistics .info-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 7px 0;
border-bottom: 1px dashed #f0f0f0;
}
.site-statistics .info-row:last-child {
border-bottom: none;
}
.site-statistics .info-label {
color: #555;
font-size: 13px;
font-weight: 500;
}
.site-statistics .info-value {
color: #222;
font-weight: 600;
font-size: 13px;
text-align: right;
font-feature-settings: "tnum";
}
/* 底部区域 */
.site-statistics .stat-footer {
padding-top: 15px;
text-align: center;
}
.site-statistics .footer-label {
font-size: 11px;
color: #777;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
font-weight: 600;
}
.site-statistics .footer-time {
font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
font-size: 12px;
color: #444;
background: #f9f9f9;
padding: 8px 12px;
border-radius: 4px;
border: 1px solid #eaeaea;
line-height: 1.4;
font-weight: 500;
font-feature-settings: "tnum";
}
/* 短码样式 */
.site-statistics-shortcode {
max-width: 350px;
margin: 0 auto;
}
.site-statistics-shortcode h3 {
text-align: center;
color: #222;
margin-bottom: 18px;
font-size: 16px;
font-weight: 600;
padding-bottom: 10px;
border-bottom: 1px solid #eaeaea;
}
/* 响应式设计 */
@media (max-width: 480px) {
.site-statistics {
padding: 16px;
font-size: 12px;
}
.site-statistics .stat-main {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.site-statistics .stat-item {
text-align: left !important;
padding: 0;
width: 100%;
}
.site-statistics .stat-item:first-child,
.site-statistics .stat-item:last-child {
text-align: left !important;
}
.site-statistics .stat-value {
font-size: 16px;
}
.site-statistics .footer-time {
font-size: 11px;
padding: 6px 10px;
}
.site-statistics-shortcode {
max-width: 100%;
}
}
/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
.site-statistics {
background: #1a1a1a;
border-color: #333;
color: #e0e0e0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.site-statistics .stat-main,
.site-statistics .stat-details,
.site-statistics .stat-info {
border-color: #333;
}
.site-statistics .stat-row,
.site-statistics .info-row {
border-color: #2a2a2a;
}
.site-statistics .stat-label,
.site-statistics .detail-label,
.site-statistics .info-label {
color: #aaa;
}
.site-statistics .stat-value,
.site-statistics .detail-value,
.site-statistics .info-value {
color: #fff;
}
.site-statistics .stat-sub {
color: #888;
}
.site-statistics .footer-label {
color: #999;
}
.site-statistics .footer-time {
background: #222;
border-color: #333;
color: #ccc;
}
.site-statistics-shortcode h3 {
color: #fff;
border-color: #444;
}
}
/* 动画效果 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.site-statistics {
animation: fadeInUp 0.3s ease-out;
}
/* 确保无渐变背景 */
.site-statistics .stat-item,
.site-statistics .footer-time {
background: transparent !important;
background-image: none !important;
}
/* 清除所有可能继承的渐变样式 */
.site-statistics * {
background-image: none !important;
}
无图无真相~~
哈哈,可以去知影燕博客看看效果,友链界面