Typecho下Unique Page浏览计数插件
Typecho下Unique Page浏览计数插件
前面文章分享了网友的Page View插件,Views, 但是因为本人网站其实大部分时间都是自己在访问,因此基于PV的访问可能更多的是自己的访问量,对于后续网站检索的数据无法真实体现。故而在此基础上修改了一种基于Unique Page的浏览计数方法。
实现原理
相对于PV每一次文章内容也被浏览会增加一次计数,这里的UV则是根据客户端访问IP计数,每篇文章每一个IP在同一天的多次访问只记为1,最后相加显示之和便是文章的UV数。
代码
<?php
/**
* Typecho 版 Unique Views
*
* @package UViews
* @author Ray Lei
* @version 0.0.1
* @update: 2018.04.09
* @link http://raylei.cn/
*/
class UViews_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('UViews_Plugin', 'viewsCounter');
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
//如果已启用过该插件则不在修改数据库
//SELECT * FROM `typecho_options` where name = 'plugins' and value like '%UViews_Plugin%'
$result = $db->fetchRow($db->select()->from('table.options')->where('name=?', 'plugins')->where('value like ?', '%UViews_Plugin%'));
if (empty($result)) {
$db->query('create table typecho_content_views(
id int primary key auto_increment,
cid int, ip varchar(32),
views int,
lastViewDate datetime
);');
}
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form){}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
// Function to get the client ip address
public static function get_client_ip_env() {
$ipaddress = '';
if (getenv('HTTP_CLIENT_IP'))
$ipaddress = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$ipaddress = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$ipaddress = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
/**
* 加入 beforeRender
*
* @access public
* @return void
*/
public static function viewsCounter()
{
// 访问计数
if (Typecho_Widget::widget('Widget_Archive')->is('single')) {
$db = Typecho_Db::get();
$cid = Typecho_Widget::widget('Widget_Archive')->cid;
$row = $db->fetchRow($db->select('ip, views, lastViewDate')->from('table.content_views')->where('cid = ?', $cid)->where('ip= ?', UViews_Plugin::get_client_ip_env()));
//如果不存在,则新增,否则根据访问时间来更新计数和上次访问时间
if (empty($row)) {
$insert = $db->insert('table.content_views')->rows(array('ip' =>UViews_Plugin::get_client_ip_env() , 'cid'=>$cid,'views'=>1, 'lastViewDate'=> date("Y-m-d H:i:s")));
$insertret = $db->query($insert);
}else{
$date = new DateTime($row["lastViewDate"]);
if(date("Y-m-d") != $date->format('Y-m-d'))
$db->query($db->update('table.content_views')->rows(array('views'=>(int)$row['views']+1, 'lastViewDate'=>date('Y-m-d H:i:s')))->where('cid=?', $cid));
else
$db->query($db->update('table.content_views')->rows(array('lastViewDate'=>date('Y-m-d H:i:s')))->where('cid=?', $cid));
}
}
}
/**
* 输出访问次数
*
* 语法: UViews_Plugin::theViews();
* 输出: '访问: xx,xxx 次'
*
* 语法: UViews_Plugin::theViews('有 ', ' 次点击');
* 输出: '有 xx,xxx 次点击'
*
* @access public
* @param string $before 前字串
* @param string $after 后字串
* @param bool $echo 是否显示 (0 用于运算,不显示)
* @return string
*/
public static function theViews($before = '(UV)访问: ', $after = ' 次', $echo = 1)
{
$db = Typecho_Db::get();
$cid = Typecho_Widget::widget('Widget_Archive')->cid;
$row = $db->fetchRow($db->select(array('sum(views)' => 'ViewCount'))->from('table.content_views')->where('cid = ?', $cid));
if ($echo)
echo $before, number_format($row['ViewCount']), $after;
else
return $row['ViewCount'];
}
}
插件的使用方法:将上述代码命名为Plugin.php, 在usr/Plugins/下新建UViews文件夹,然后上传该文件;
后续操作见之前Views插件介绍文章: Typecho文章浏览次数统计插件设置.
最后,在需要使用访问计数的地方添加如下代码即可:
<?php UViews_Plugin::theViews(); ?>