Initial commit
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled

This commit is contained in:
chorblack
2026-03-07 11:19:25 +08:00
commit e75f275ef4
4484 changed files with 645480 additions and 0 deletions

201
Stat/Plugin.php Normal file
View File

@@ -0,0 +1,201 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 页面浏览次数统计插件 【<a href="https://github.com/typecho-fans/plugins" target="_blank">TF</a>社区维护版】
*
* @package Stat
* @author 羽中, Jozhn, Hanny
* @version 1.0.4
* @dependence 17.10.30-*
* @link https://github.com/typecho-fans/plugins/tree/master/Stat
*
* version 1.0.4 at 2020-07-08
* 增加计数输出和忽略重复访问功能
* 增加排行输出可指定分类ID与类型
*
* version 1.0.3 at 2018-08-24
* 修复PDO下数据表检测失败的错误
*
* 历史版本
* version 1.0.2 at 2010-07-03
* 终于支持前台调用了
* 接口支持Typecho 0.8的计数
* 增加SQLite的支持
* version 1.0.1 at 2010-01-02
* 修改安装出错处理
* 修改安装时默认值错误
* version 1.0.0 at 2009-12-12
* 实现浏览次数统计的基本功能
*/
class Stat_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
$info = Stat_Plugin::sqlInstall();
Typecho_Plugin::factory('Widget_Archive')->singleHandle = array('Stat_Plugin', 'singleHandle');
Typecho_Plugin::factory('Widget_Archive')->select = array('Stat_Plugin', 'selectHandle');
/* 模版调用钩子 */
Typecho_Plugin::factory('Widget_Archive')->callStat = array('Stat_Plugin', 'outputStat');
/* 输出排行支持4种参数如: <?php $this->rank(
'源码含{link}{title}',
'类型如post/page/attachment',
'分类或标签mid用逗号隔开',
条目数
); ?> */
Typecho_Plugin::factory('Widget_Archive')->callRank = array('Stat_Plugin', 'outputRank');
return _t($info);
}
//SQL创建
public static function sqlInstall()
{
$db = Typecho_Db::get();
$type = explode('_', $db->getAdapterName());
$type = array_pop($type);
$prefix = $db->getPrefix();
try {
$select = $db->select('table.contents.views')->from('table.contents');
$db->query($select, Typecho_Db::READ);
return '检测到统计字段,插件启用成功';
} catch (Typecho_Db_Exception $e) {
$code = $e->getCode();
if(('Mysql' == $type && ('42S22'==$code || 1054 == $code)) ||
('SQLite' == $type && ('HY000' == $code || 1 == $code))) {
try {
if ('Mysql' == $type) {
$db->query("ALTER TABLE `".$prefix."contents` ADD `views` INT( 10 ) NOT NULL DEFAULT '0' COMMENT '页面浏览次数';");
} else if ('SQLite' == $type) {
$db->query("ALTER TABLE `".$prefix."contents` ADD `views` INT( 10 ) NOT NULL DEFAULT '0'");
} else {
throw new Typecho_Plugin_Exception('不支持的数据库类型:'.$type);
}
return '建立统计字段,插件启用成功';
} catch (Typecho_Db_Exception $e) {
$code = $e->getCode();
if(('Mysql' == $type && ('42S21'==$code || 1060 == $code)) ) {
return '统计字段已经存在,插件启用成功';
}
throw new Typecho_Plugin_Exception('统计插件启用失败。错误号:'.$code);
}
}
throw new Typecho_Plugin_Exception('数据表检测失败,统计插件启用失败。错误号:'.$code);
}
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @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){}
/**
* 插件实现方法
*
* @access public
* @return void
*/
public static function outputStat($widget)
{
$db = Typecho_Db::get();
$row = $db->fetchRow($db->select('views')->from('table.contents')->where('cid = ?', $widget->cid));
echo $row['views'];
}
public static function viewStat($cid)
{
$name = '__StatViews';
$cids = Json::decode(Typecho_Cookie::get($name), true);
if (!empty($cids) && in_array($cid, $cids)) {
return;
} else {
if (!$cids) $cids = array();
array_push($cids, $cid);
Typecho_Cookie::set($name, Json::encode($cids), time()+60*60); //默认60分钟可自行修改
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
$sql = "UPDATE `".$prefix."contents` SET `views` = `views` + 1 WHERE `cid` = ".intval($cid).";";
$db->query($sql);
}
}
public static function selectHandle($archive)
{
$db = Typecho_Db::get();
$options = Typecho_Widget::widget('Widget_Options');
return $db->select('*')->from('table.contents')->where('table.contents.status = ?', 'publish')
->where('table.contents.created < ?', $options->gmtTime);
}
public static function singleHandle($select, $archive)
{
Stat_Plugin::viewStat($select->stack[0]['cid']);
}
public static function outputRank($widget, array $params)
{
$db = Typecho_Db::get();
$items = $db->fetchAll($db->select('table.metas.mid')->from('table.metas')
->where('table.metas.type = ?', 'category'));
foreach ($items as $item) {
$all[] = $item['mid'];
}
$format = !empty($params[0]) && is_string($params[0]) ? $params[0] : '<li><a href="{link}">{title}</a></li>';
$type = !empty($params[1]) && is_string($params[1]) ? $params[1] : 'post';
$category = !empty($params[2]) && is_string($params[2]) ? $params[2] : 'ALL';
$limit = !empty($params[3]) && is_numeric($params[3]) ? $params[3] : 10;
if ($type == 'post') {
$select = $db->select()->from('table.contents')
->join('table.relationships', 'table.relationships.cid = table.contents.cid',Typecho_Db::INNER_JOIN)
->where('table.contents.status = ?', 'publish')
->where('table.relationships.mid in ('.($category=='ALL' ? implode(',', $all) : $category).')')
->order('views', Typecho_Db::SORT_DESC)
->limit($limit);
} else {
$select = $db->select()->from('table.contents')
->where('table.contents.status = ?', 'publish')
->where('table.contents.type = ?', ''.$type.'')
->order('views', Typecho_Db::SORT_DESC)
->limit($limit);
}
$posts = $db->fetchAll($select);
foreach ($posts as $post) {
$value = Typecho_Widget::widget('Widget_Abstract_Contents')->push($post);
echo str_replace(array('{link}','{title}'), array($value['permalink'], $value['title']), $format);
}
}
}

84
Stat/README.md Normal file
View File

@@ -0,0 +1,84 @@
<a href="https://typecho-fans.github.io">
<img src="https://typecho-fans.github.io/text-logo.svg" alt="TF Logo" title="Typecho Fans开源作品社区" align="right" height="100" />
</a>
Stat v1.0.4 - 社区维护版
======================
<h4 align="center">—— 老牌文章浏览计数器插件,首创单页句柄机制支持附件,现已加入模板输出钩子。</h4>
<p align="center">
<a href="#使用说明">使用说明</a> •
<a href="#版本历史">版本历史</a> •
<a href="#贡献作者">贡献作者</a> •
<a href="#附注链接">附注/链接</a> •
<a href="#授权协议">授权协议</a>
</p>
---
## 使用说明
<table>
<tr>
<td>
###### 通过挂载单页句柄实现不依赖模板输出的计数功能除文章外独立页面甚至附件页面均可作用。新版可忽略1小时内重复访问增加输出函数并支持参数定制。
**使用方法**
##### 1. 下载本插件,放在 `usr/plugins/` 目录中,确保文件夹名为 Stat
##### 2. 激活插件,即可自动添加计数字段并按访问自增;
##### 3. 需输出当前文章计数数字可在模板文件如post.php中添加`<?php $this->stat(); ?>`
##### 4. 需输出文章排行列表可在模板文件如sidebar.php中添加`<?php $this->rank(); ?>`。
**注意事项**
* ##### 以上排行列表输出函数内支持用英文逗号隔开4种参数`$this->rank( "源码规则", "页面类型", "分类或标签mid", "数目" )`,赋值如下表:
|参数|可用值|缺省值|说明|
|---|:---:|:---:|:---:|
|源码规则|任意Html代码<br/>{title}即文章标题<br/>{link}为文章地址|`<li><a href="{link}">{title}</a></li>`|每条输出源码格式|
|页面类型|post<br/>page<br/>attachment|post<br/>(文章)|可排行页面或附件|
|分类或标签mid|整数<br/>(多个可用,隔开)|ALL<br/>(所有)|仅对文章类型有效|
|数目|整数|10|总共输出文章条数|
* ##### 查看分类标签mid方法后台进入管理-分类或标签页面,点击分类名称或编辑标签,地址栏?后即会显示mid等于的值。
</td>
</tr>
</table>
## 版本历史
* v1.0.4 (20-07-08 [@jzwalk](https://github.com/jzwalk))
* 增加计数输出和忽略重复访问功能;
* 增加排行输出可指定分类ID与类型。
* v1.0.3 (18-08-24 [@jozhn](https://github.com/jozhn))
* 修复PDO下数据表检测失败的错误。
* v1.0.2 (10-07-03 [@Hanny](http://www.imhan.com))
* 终于支持前台调用了;
* 接口支持Typecho 0.8的计数;
* 增加SQLite的支持。
* v1.0.1 (10-01-02 [@Hanny](http://www.imhan.com))
* 修改安装出错处理;
* 修改安装时默认值错误。
* v1.0.0 (09-12-12 [@Hanny](http://www.imhan.com))
* 实现浏览次数统计的基本功能。
## 贡献作者
[![jzwalk](https://avatars1.githubusercontent.com/u/252331?v=3&s=100)](https://github.com/jzwalk) | [![jozhn](https://avatars1.githubusercontent.com/u/19300336?v=3&s=100)](https://github.com/jozhn) | [![Hanny](https://secure.gravatar.com/avatar/?d=mp&s=100)](http://www.imhan.com)
:---:|:---:|:---:
[jzwalk](https://github.com/jzwalk) (2020) | [jozhn](https://github.com/jozhn) (2018) | [Hanny](http://www.imhan.com) (2009)
## 附注/链接
* [微调版(jozhn)](https://github.com/jozhn/Stat-for-Typecho) - 修复激活报错。
* [原版](http://www.imhan.com/typecho) - 实现浏览计数功能。
本插件最初仅为测试用未实现任何输出,可与[Attachment](https://github.com/typecho-fans/plugins/tree/master/Attachment)搭配统计附件下载。
另有基于本作句柄机制的二次开发版[TeStat](https://github.com/jiangmuzi/TeStat)可供参考。
## 授权协议
TF目录下的社区维护版作品如果没有明确声明默认采用与Typecho相同的[GPLv2](https://github.com/typecho/typecho/blob/master/LICENSE.txt)开源协议。(要求提及出处,保持开源并注明修改。)
> Stat原作未附协议声明原作者保留所有权利。 © [Hanny](http://www.imhan.com)