1471 lines
52 KiB
PHP
1471 lines
52 KiB
PHP
<?php
|
||
/**
|
||
* 回想
|
||
*
|
||
* @package ThoughtsPlugin
|
||
* @author 石头厝
|
||
* @version 1.3.8
|
||
* @link https://www.shitoucuo.com
|
||
*/
|
||
class ThoughtsPlugin_Plugin implements Typecho_Plugin_Interface
|
||
{
|
||
/**
|
||
* 激活插件方法
|
||
*/
|
||
public static function activate()
|
||
{
|
||
// 创建感想表
|
||
$db = Typecho_Db::get();
|
||
$prefix = $db->getPrefix();
|
||
|
||
$sql = "CREATE TABLE IF NOT EXISTS `{$prefix}thoughts` (
|
||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||
`cid` int(10) unsigned NOT NULL COMMENT '文章ID',
|
||
`authorId` int(10) unsigned NOT NULL COMMENT '用户ID',
|
||
`created` int(10) unsigned DEFAULT 0 COMMENT '创建时间',
|
||
`text` text COMMENT '感想内容',
|
||
`status` varchar(16) DEFAULT 'approved' COMMENT '状态',
|
||
PRIMARY KEY (`id`),
|
||
KEY `cid` (`cid`),
|
||
KEY `authorId` (`authorId`),
|
||
KEY `created` (`created`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||
|
||
try {
|
||
$db->query($sql);
|
||
} catch (Exception $e) {
|
||
throw new Typecho_Plugin_Exception('创建感想表失败: ' . $e->getMessage());
|
||
}
|
||
|
||
// 挂载hook
|
||
Typecho_Plugin::factory('Widget_Feedback')->comment = array(__CLASS__, 'processComment');
|
||
Typecho_Plugin::factory('Widget_Archive')->footer = array(__CLASS__, 'footer');
|
||
Typecho_Plugin::factory('Widget_Archive')->header = array(__CLASS__, 'header');
|
||
Typecho_Plugin::factory('Widget_Feedback')->content = array(__CLASS__, 'renderCheckbox');
|
||
|
||
return _t('感想插件已激活,请进行配置');
|
||
}
|
||
|
||
/**
|
||
* 禁用插件方法
|
||
*/
|
||
public static function deactivate()
|
||
{
|
||
return _t('感想插件已禁用');
|
||
}
|
||
|
||
/**
|
||
* 插件配置方法
|
||
*/
|
||
public static function config(Typecho_Widget_Helper_Form $form)
|
||
{
|
||
$label = new Typecho_Widget_Helper_Form_Element_Text(
|
||
'label_text',
|
||
NULL,
|
||
'发布为感想',
|
||
_t('勾选框标签文字'),
|
||
_t('显示在勾选框旁边的文字')
|
||
);
|
||
$form->addInput($label->addRule('required', _t('标签文字不能为空')));
|
||
|
||
// 添加前端卡片默认状态设置
|
||
$default_state = new Typecho_Widget_Helper_Form_Element_Radio(
|
||
'default_state',
|
||
array(
|
||
'collapsed' => '默认收起',
|
||
'expanded' => '默认展开'
|
||
),
|
||
'collapsed',
|
||
_t('感想卡片默认状态'),
|
||
_t('选择感想列表在前端的默认显示状态')
|
||
);
|
||
$form->addInput($default_state);
|
||
|
||
// 独立页面配置
|
||
$page_per_page = new Typecho_Widget_Helper_Form_Element_Text(
|
||
'page_per_page',
|
||
NULL,
|
||
'20',
|
||
_t('独立页面每页显示数量'),
|
||
_t('独立页面每页显示的感想数量')
|
||
);
|
||
$form->addInput($page_per_page->addRule('isInteger', _t('请输入整数')));
|
||
}
|
||
|
||
/**
|
||
* 个人用户的配置方法
|
||
*/
|
||
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
|
||
|
||
/**
|
||
* 处理评论提交 - 彻底拦截版
|
||
*/
|
||
public static function processComment($comment, $post)
|
||
{
|
||
$request = Typecho_Request::getInstance();
|
||
|
||
// 检查是否勾选了发布为感想
|
||
if ($request->isPost() && $request->get('thoughts') == '1') {
|
||
// 只有管理员可以发布感想
|
||
$user = Typecho_Widget::widget('Widget_User');
|
||
if ($user->hasLogin() && $user->pass('administrator', true)) {
|
||
|
||
// 保存到感想表
|
||
$db = Typecho_Db::get();
|
||
$insert = $db->insert('table.thoughts')
|
||
->rows(array(
|
||
'cid' => $comment['cid'],
|
||
'authorId' => $comment['authorId'],
|
||
'created' => $comment['created'],
|
||
'text' => $comment['text'],
|
||
'status' => 'approved'
|
||
));
|
||
|
||
$insertId = $db->query($insert);
|
||
|
||
// 关键:直接输出结果并终止,完全拦截Typecho的评论处理
|
||
self::outputSuccessResponse($post);
|
||
}
|
||
}
|
||
|
||
return $comment;
|
||
}
|
||
|
||
/**
|
||
* 输出成功响应并终止
|
||
*/
|
||
private static function outputSuccessResponse($post)
|
||
{
|
||
// 清空可能的输出缓冲区
|
||
if (ob_get_level()) {
|
||
ob_end_clean();
|
||
}
|
||
|
||
// 设置正确的Content-Type
|
||
header('Content-Type: text/html; charset=utf-8');
|
||
|
||
// 构建返回URL
|
||
$returnUrl = $post->permalink . '#thoughts';
|
||
|
||
// 输出包含JavaScript的简单HTML页面
|
||
echo '<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>发布成功</title>
|
||
<script>
|
||
alert("🎉 感想发布成功!");
|
||
window.location.href = "' . htmlspecialchars($returnUrl) . '";
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<p>感想发布成功,正在返回文章页面...</p>
|
||
<p>如果页面没有自动跳转,请<a href="' . htmlspecialchars($returnUrl) . '">点击这里</a></p>
|
||
</body>
|
||
</html>';
|
||
|
||
// 立即终止执行,防止Typecho继续处理
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* 在评论表单中渲染勾选框
|
||
*/
|
||
public static function renderCheckbox($content, $class)
|
||
{
|
||
// 只在文章页面且是管理员显示
|
||
if ($class->request->is('post') && self::isAdmin()) {
|
||
$options = Helper::options()->plugin('ThoughtsPlugin');
|
||
$labelText = $options->label_text ?: '发布为感想';
|
||
|
||
$checkbox = '<div class="thought-checkbox" style="margin: 15px 0; padding: 10px; background: #f8f9fa; border-radius: 4px;">';
|
||
$checkbox .= '<label style="display: flex; align-items: center; cursor: pointer; font-weight: normal;">';
|
||
$checkbox .= '<input type="checkbox" name="thoughts" value="1" style="margin-right: 8px;"> ';
|
||
$checkbox .= htmlspecialchars($labelText);
|
||
$checkbox .= '</label>';
|
||
$checkbox .= '</div>';
|
||
|
||
// 插入到评论框之前
|
||
$content = preg_replace('/(<textarea[^>]*name="text"[^>]*>)/i', $checkbox . '$1', $content);
|
||
}
|
||
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* 在页面头部添加CSS - 美化版
|
||
*/
|
||
public static function header()
|
||
{
|
||
// 判断是否在独立页面中
|
||
$isThoughtsPage = false;
|
||
|
||
if (isset($_GET['thoughts_page']) ||
|
||
(isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], 'thoughts') !== false)) {
|
||
$isThoughtsPage = true;
|
||
}
|
||
|
||
// 独立页面CSS - 美化版
|
||
if ($isThoughtsPage) {
|
||
echo '<style>
|
||
/* 整体容器 */
|
||
.thoughts-page-container {
|
||
max-width: 900px;
|
||
margin: 0 auto;
|
||
padding: 30px 20px;
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||
line-height: 1.6;
|
||
color: #333;
|
||
}
|
||
|
||
/* 页面头部 */
|
||
.thoughts-page-header {
|
||
margin-bottom: 50px;
|
||
text-align: center;
|
||
padding-bottom: 30px;
|
||
border-bottom: 3px solid #4a6cf7;
|
||
position: relative;
|
||
}
|
||
|
||
.thoughts-page-header:after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: -3px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 100px;
|
||
height: 3px;
|
||
background: linear-gradient(90deg, #4a6cf7, #6b8eff);
|
||
}
|
||
|
||
.dark .thoughts-page-header h1{background:.rgb(10 12 25 / var(--tw-bg-opacity);)}
|
||
|
||
.thoughts-page-header h1 {
|
||
color: #2d3748;
|
||
margin-bottom: 15px;
|
||
font-size: 2.5em;
|
||
font-weight: 700;
|
||
letter-spacing: -0.5px;
|
||
background: linear-gradient(135deg, #4a6cf7 0%, #6b8eff 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
|
||
.thoughts-page-header .subtitle {
|
||
color: #718096;
|
||
font-size: 1.2em;
|
||
font-weight: 300;
|
||
}
|
||
|
||
/* 感想总数徽章 */
|
||
.thoughts-total-count {
|
||
display: inline-block;
|
||
background: linear-gradient(135deg, #4a6cf7, #6b8eff);
|
||
color: white;
|
||
padding: 2px 10px;
|
||
border-radius: 30px;
|
||
font-size: 13px;
|
||
margin-left: 15px;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.thoughts-total-count:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 20px rgba(74, 108, 247, 0.4);
|
||
}
|
||
|
||
/* 感想卡片 */
|
||
.thoughts-page-item {
|
||
margin-bottom: 35px;
|
||
padding: 30px;
|
||
background: white;
|
||
border-radius: 15px;
|
||
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.08);
|
||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.thoughts-page-item:before {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 5px;
|
||
height: 100%;
|
||
background: linear-gradient(to bottom, #4a6cf7, #6b8eff);
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.thoughts-page-item:hover {
|
||
transform: translateY(-8px);
|
||
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
|
||
border-color: rgba(74, 108, 247, 0.2);
|
||
}
|
||
|
||
.thoughts-page-item:hover:before {
|
||
width: 8px;
|
||
}
|
||
|
||
/* 感想元信息 */
|
||
.thoughts-page-meta {
|
||
margin-bottom: 25px;
|
||
font-size: 1em;
|
||
color: #4a5568;
|
||
line-height: 1.8;
|
||
padding-bottom: 15px;
|
||
border-bottom: 1px solid rgba(226, 232, 240, 0.8);
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 20px;
|
||
}
|
||
|
||
.thoughts-page-meta .date {
|
||
color: #4a6cf7;
|
||
font-weight: 600;
|
||
font-size: 1.05em;
|
||
padding: 6px 12px;
|
||
background: rgba(74, 108, 247, 0.1);
|
||
border-radius: 8px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.thoughts-page-meta .date:before {
|
||
content: "📅";
|
||
margin-right: 8px;
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
.thoughts-page-meta .user {
|
||
color: #ed64a6;
|
||
font-weight: 600;
|
||
font-size: 1.05em;
|
||
padding: 6px 12px;
|
||
background: rgba(237, 100, 166, 0.1);
|
||
border-radius: 8px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.thoughts-page-meta .user:before {
|
||
content: "👤";
|
||
margin-right: 8px;
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
.thoughts-page-meta .article {
|
||
color: #38b2ac;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.thoughts-page-meta a {
|
||
color: #38b2ac;
|
||
text-decoration: none;
|
||
border-bottom: 2px dotted #38b2ac;
|
||
font-weight: 600;
|
||
padding: 2px 0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.thoughts-page-meta a:hover {
|
||
color: #319795;
|
||
border-bottom: 2px solid #319795;
|
||
}
|
||
|
||
/* 感想内容区域 */
|
||
.thoughts-page-content {
|
||
color: #2d3748;
|
||
line-height: 1.8;
|
||
padding: 25px;
|
||
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
||
border-radius: 12px;
|
||
border-left: 4px solid #cbd5e0;
|
||
font-size: 1.1em;
|
||
position: relative;
|
||
}
|
||
|
||
.thoughts-page-content:before {
|
||
content: "💭";
|
||
position: absolute;
|
||
top: -15px;
|
||
left: -15px;
|
||
background: white;
|
||
width: 30px;
|
||
height: 30px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
|
||
font-size: 1em;
|
||
}
|
||
|
||
.thoughts-page-content strong {
|
||
color: #4a5568;
|
||
display: block;
|
||
margin-bottom: 15px;
|
||
font-size: 1.15em;
|
||
font-weight: 600;
|
||
padding-left: 25px;
|
||
position: relative;
|
||
}
|
||
|
||
.thoughts-page-content strong:before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 15px;
|
||
height: 2px;
|
||
background: #4a6cf7;
|
||
}
|
||
|
||
/* 分页样式 */
|
||
.thoughts-pagination {
|
||
margin-top: 60px;
|
||
text-align: center;
|
||
padding-top: 40px;
|
||
border-top: 2px solid #e2e8f0;
|
||
}
|
||
|
||
.thoughts-pagination a,
|
||
.thoughts-pagination span {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 12px 20px;
|
||
margin: 0 6px;
|
||
border: 2px solid #e2e8f0;
|
||
border-radius: 10px;
|
||
text-decoration: none;
|
||
color: #4a5568;
|
||
background: white;
|
||
font-weight: 600;
|
||
transition: all 0.3s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||
min-width: 45px;
|
||
height: 45px;
|
||
}
|
||
|
||
.thoughts-pagination a:hover {
|
||
background: linear-gradient(135deg, #4a6cf7, #6b8eff);
|
||
color: white;
|
||
border-color: #4a6cf7;
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 8px 20px rgba(74, 108, 247, 0.3);
|
||
}
|
||
|
||
.thoughts-pagination .current {
|
||
background: linear-gradient(135deg, #4a6cf7, #6b8eff);
|
||
color: white;
|
||
border-color: #4a6cf7;
|
||
box-shadow: 0 5px 15px rgba(74, 108, 247, 0.3);
|
||
}
|
||
|
||
.thoughts-pagination .extend {
|
||
padding: 12px 25px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
|
||
.thoughts-pagination .extend:hover {
|
||
background: linear-gradient(135deg, #ed64a6, #f687b3);
|
||
border-color: #ed64a6;
|
||
}
|
||
|
||
/* 空状态 */
|
||
.thoughts-empty-page {
|
||
text-align: center;
|
||
padding: 100px 40px;
|
||
color: #718096;
|
||
font-size: 1.3em;
|
||
background: white;
|
||
border-radius: 20px;
|
||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
|
||
border: 2px dashed #e2e8f0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.thoughts-empty-page:hover {
|
||
border-color: #4a6cf7;
|
||
transform: translateY(-5px);
|
||
}
|
||
|
||
.thoughts-empty-page .icon {
|
||
font-size: 5em;
|
||
margin-bottom: 30px;
|
||
opacity: 0.2;
|
||
display: inline-block;
|
||
animation: float 3s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes float {
|
||
0%, 100% { transform: translateY(0); }
|
||
50% { transform: translateY(-10px); }
|
||
}
|
||
|
||
.thoughts-empty-page p {
|
||
margin: 0;
|
||
font-size: 1.2em;
|
||
color: #4a5568;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.thoughts-empty-page .empty-action {
|
||
margin-top: 30px;
|
||
display: inline-block;
|
||
padding: 12px 30px;
|
||
background: linear-gradient(135deg, #4a6cf7, #6b8eff);
|
||
color: white;
|
||
text-decoration: none;
|
||
border-radius: 30px;
|
||
font-weight: 600;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.thoughts-empty-page .empty-action:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 25px rgba(74, 108, 247, 0.4);
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 992px) {
|
||
.thoughts-page-container {
|
||
padding: 25px 15px;
|
||
}
|
||
|
||
.thoughts-page-header h1 {
|
||
font-size: 2.2em;
|
||
}
|
||
|
||
.thoughts-page-item {
|
||
padding: 25px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.thoughts-page-content {
|
||
padding: 20px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.thoughts-page-container {
|
||
padding: 20px 15px;
|
||
}
|
||
|
||
.thoughts-page-header {
|
||
margin-bottom: 40px;
|
||
padding-bottom: 25px;
|
||
}
|
||
|
||
.thoughts-page-header h1 {
|
||
font-size: 1.8em;
|
||
}
|
||
|
||
.thoughts-page-header .subtitle {
|
||
font-size: 1em;
|
||
}
|
||
|
||
.thoughts-page-item {
|
||
padding: 20px;
|
||
margin-bottom: 25px;
|
||
}
|
||
|
||
.thoughts-page-meta {
|
||
font-size: 0.95em;
|
||
gap: 15px;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.thoughts-page-meta .date,
|
||
.thoughts-page-meta .user {
|
||
font-size: 1em;
|
||
}
|
||
|
||
.thoughts-page-content {
|
||
padding: 18px;
|
||
font-size: 1em;
|
||
}
|
||
|
||
.thoughts-page-content strong {
|
||
font-size: 1.1em;
|
||
}
|
||
|
||
.thoughts-pagination a,
|
||
.thoughts-pagination span {
|
||
padding: 10px 16px;
|
||
margin: 0 4px;
|
||
font-size: 0.9em;
|
||
min-width: 40px;
|
||
height: 40px;
|
||
}
|
||
|
||
.thoughts-pagination .extend {
|
||
padding: 10px 20px;
|
||
}
|
||
|
||
.thoughts-empty-page {
|
||
padding: 60px 25px;
|
||
}
|
||
|
||
.thoughts-empty-page .icon {
|
||
font-size: 4em;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.thoughts-page-header h1 {
|
||
font-size: 1.6em;
|
||
}
|
||
|
||
.thoughts-page-item {
|
||
padding: 18px;
|
||
}
|
||
|
||
.thoughts-page-meta {
|
||
gap: 12px;
|
||
}
|
||
|
||
.thoughts-page-content {
|
||
padding: 16px;
|
||
}
|
||
|
||
.thoughts-pagination a,
|
||
.thoughts-pagination span {
|
||
padding: 8px 12px;
|
||
margin: 0 3px;
|
||
min-width: 35px;
|
||
height: 35px;
|
||
}
|
||
|
||
.thoughts-total-count {
|
||
margin-left: 10px;
|
||
padding: 6px 15px;
|
||
font-size: 0.85em;
|
||
}
|
||
}
|
||
|
||
/* 动画效果 */
|
||
@keyframes fadeInUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.thoughts-page-item {
|
||
animation: fadeInUp 0.6s ease-out;
|
||
animation-fill-mode: both;
|
||
}
|
||
|
||
.thoughts-page-item:nth-child(1) { animation-delay: 0.1s; }
|
||
.thoughts-page-item:nth-child(2) { animation-delay: 0.2s; }
|
||
.thoughts-page-item:nth-child(3) { animation-delay: 0.3s; }
|
||
.thoughts-page-item:nth-child(4) { animation-delay: 0.4s; }
|
||
.thoughts-page-item:nth-child(5) { animation-delay: 0.5s; }
|
||
.thoughts-page-item:nth-child(n+6) { animation-delay: 0.6s; }
|
||
</style>';
|
||
}
|
||
|
||
// 文章页面的原有样式保持不变,添加展开收起样式(使用更独特的类名)
|
||
if (Typecho_Widget::widget('Widget_Archive')->is('single')) {
|
||
echo '<style>
|
||
/* 感想列表容器 */
|
||
.thoughts-list-container {
|
||
padding: 18px 24px;
|
||
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
|
||
border-radius: 10px;
|
||
border: 1px solid #e1e8ed;
|
||
}
|
||
|
||
.dark .thoughts-list-container{background:rgb(10 12 25 / 1); border: 0px solid #e1e8ed;}
|
||
|
||
/* 标题区域 */
|
||
.thoughts-header {
|
||
margin-top: 0;
|
||
margin-bottom: 0;
|
||
color: #FFF;
|
||
font-size: 18px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items:center;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
font-weight:600;
|
||
}
|
||
|
||
/* 感想条数背景色 */
|
||
.dark .thoughts-count-badge {color:rgb(156 163 175 / var(--tw-text-opacity))!important;}
|
||
.thoughts-count-badge {
|
||
background-color: rgba(255, 255, 255, 0.2);
|
||
color: white;
|
||
padding: 4px 8px;
|
||
border-radius: 12px;
|
||
font-size: 13px;
|
||
margin-left: 8px;
|
||
}
|
||
.dark .thoughts-toggle-btn {color:rgb(156 163 175 / var(--tw-text-opacity))!important;}
|
||
/* 切换按钮 */
|
||
.thoughts-toggle-btn {
|
||
font-size: 0.8em;
|
||
color: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
padding: 4px 10px;
|
||
border-radius: 4px;
|
||
transition: all 0.3s ease;
|
||
font-weight: normal;
|
||
border: none;
|
||
cursor: pointer;
|
||
}
|
||
.thoughts-toggle-btn .toggle-arrow {
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
transition: transform 0.3s ease;
|
||
display: inline-block;
|
||
}
|
||
|
||
.thoughts-toggle-btn.expanded .toggle-arrow {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
/* 内容区域 */
|
||
.thoughts-items-wrapper {
|
||
transition: all 0.3s ease;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.thoughts-items-wrapper.collapsed {
|
||
max-height: 0;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
}
|
||
|
||
.thoughts-items-wrapper.expanded {
|
||
max-height: 5000px;
|
||
opacity: 1;
|
||
visibility: visible;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
/* 感想项 */
|
||
.dark .thought-item{
|
||
background-color:rgb(15 23 42 / 1);
|
||
}
|
||
.thought-item {
|
||
margin-bottom: 20px;
|
||
padding: 15px;
|
||
background: white;
|
||
border-radius: 6px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||
}
|
||
|
||
.thought-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.thought-meta {
|
||
margin-bottom: 10px;
|
||
font-size: 0.9em;
|
||
color: #7f8c8d;
|
||
}
|
||
|
||
.thought-meta span {
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.thought-meta .thought-date {
|
||
color: #3498db;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.thought-meta .thought-user {
|
||
color: #e74c3c;
|
||
}
|
||
|
||
.thought-content {
|
||
color: #34495e;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.thought-content p {
|
||
margin: 0;
|
||
}
|
||
|
||
/* 评论框勾选框 */
|
||
.thought-checkbox {
|
||
margin: 15px 0;
|
||
padding: 10px;
|
||
background: #f8f9fa;
|
||
border-radius: 4px;
|
||
border: 1px solid #ddd;
|
||
}
|
||
|
||
.thought-checkbox label {
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
font-weight: normal;
|
||
margin: 0;
|
||
}
|
||
|
||
.thought-checkbox input[type="checkbox"] {
|
||
margin-right: 8px;
|
||
width: 16px;
|
||
height: 16px;
|
||
}
|
||
|
||
/* 空状态 */
|
||
.thoughts-empty-state {
|
||
text-align: center;
|
||
color: #95a5a6;
|
||
font-style: italic;
|
||
padding: 20px;
|
||
}
|
||
</style>';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 在页面底部添加JS和自动渲染感想(改为始终自动插入)
|
||
*/
|
||
public static function footer()
|
||
{
|
||
if (!Typecho_Widget::widget('Widget_Archive')->is('single')) {
|
||
return;
|
||
}
|
||
|
||
// 获取感想HTML
|
||
$thoughtsHtml = self::renderThoughts();
|
||
|
||
// 如果有感想数据,始终自动插入(不再检查配置)
|
||
if ($thoughtsHtml) {
|
||
// 由于删除了位置设置,使用默认位置:文章内容之后
|
||
$position = 'after_post';
|
||
|
||
// 获取配置中的默认状态
|
||
$options = Helper::options()->plugin('ThoughtsPlugin');
|
||
$defaultState = isset($options->default_state) ? $options->default_state : 'collapsed';
|
||
$defaultIsExpanded = ($defaultState === 'expanded');
|
||
|
||
$js = '<script>
|
||
(function() {
|
||
// 使用立即执行函数避免全局污染
|
||
var thoughtsHtml = ' . json_encode($thoughtsHtml) . ';
|
||
var position = "' . $position . '";
|
||
var defaultExpanded = ' . ($defaultIsExpanded ? 'true' : 'false') . ';
|
||
|
||
document.addEventListener("DOMContentLoaded", function() {
|
||
var targetElement = null;
|
||
|
||
// 始终使用"文章内容之后"的位置
|
||
targetElement = document.querySelector(".post-content, .entry-content, .post-body");
|
||
|
||
if (targetElement) {
|
||
var div = document.createElement("div");
|
||
div.innerHTML = thoughtsHtml;
|
||
targetElement.parentNode.insertBefore(div, targetElement.nextSibling);
|
||
}
|
||
|
||
// 初始化感想列表展开收起功能
|
||
initThoughtsToggle(defaultExpanded);
|
||
|
||
// 锚点跳转
|
||
if (window.location.hash === "#thoughts") {
|
||
setTimeout(function() {
|
||
var thoughtsEl = document.querySelector(".thoughts-list-container");
|
||
if (thoughtsEl) {
|
||
thoughtsEl.scrollIntoView({ behavior: "smooth" });
|
||
// 跳转到感想列表时自动展开
|
||
expandThoughts();
|
||
}
|
||
}, 300);
|
||
}
|
||
});
|
||
|
||
// 初始化感想列表展开收起功能
|
||
function initThoughtsToggle(isExpandedByDefault) {
|
||
var thoughtsContainer = document.querySelector(".thoughts-list-container");
|
||
if (!thoughtsContainer) return;
|
||
|
||
// 确保只初始化一次
|
||
if (thoughtsContainer.dataset.initialized === "true") return;
|
||
thoughtsContainer.dataset.initialized = "true";
|
||
|
||
var header = thoughtsContainer.querySelector(".thoughts-header");
|
||
var itemsWrapper = thoughtsContainer.querySelector(".thoughts-items-wrapper");
|
||
|
||
if (!header || !itemsWrapper) {
|
||
console.log("找不到感想列表的元素");
|
||
return;
|
||
}
|
||
|
||
// 创建切换按钮(如果不存在)
|
||
var toggleBtn = header.querySelector(".thoughts-toggle-btn");
|
||
if (!toggleBtn) {
|
||
toggleBtn = document.createElement("button");
|
||
toggleBtn.className = "thoughts-toggle-btn " + (isExpandedByDefault ? "expanded" : "collapsed");
|
||
toggleBtn.innerHTML = \'<span class="toggle-arrow">\' + (isExpandedByDefault ? "↑" : "↓") + \'</span> <span class="toggle-text"></span>\';
|
||
header.appendChild(toggleBtn);
|
||
}
|
||
|
||
// 根据配置设置默认状态
|
||
if (isExpandedByDefault) {
|
||
itemsWrapper.className = "thoughts-items-wrapper expanded";
|
||
toggleBtn.className = "thoughts-toggle-btn expanded";
|
||
} else {
|
||
itemsWrapper.className = "thoughts-items-wrapper collapsed";
|
||
toggleBtn.className = "thoughts-toggle-btn collapsed";
|
||
}
|
||
|
||
// 绑定标题点击事件
|
||
header.addEventListener("click", function(e) {
|
||
if (e.target.closest(".thoughts-toggle-btn")) return;
|
||
toggleThoughts();
|
||
});
|
||
|
||
// 绑定按钮点击事件
|
||
toggleBtn.addEventListener("click", function(e) {
|
||
e.stopPropagation();
|
||
toggleThoughts();
|
||
});
|
||
|
||
// 保存引用
|
||
thoughtsContainer._thoughtsToggle = {
|
||
header: header,
|
||
itemsWrapper: itemsWrapper,
|
||
toggleBtn: toggleBtn
|
||
};
|
||
}
|
||
|
||
// 切换展开收起状态
|
||
function toggleThoughts() {
|
||
var thoughtsContainer = document.querySelector(".thoughts-list-container");
|
||
if (!thoughtsContainer || !thoughtsContainer._thoughtsToggle) return;
|
||
|
||
var itemsWrapper = thoughtsContainer._thoughtsToggle.itemsWrapper;
|
||
var toggleBtn = thoughtsContainer._thoughtsToggle.toggleBtn;
|
||
|
||
if (itemsWrapper.classList.contains("collapsed")) {
|
||
expandThoughts();
|
||
} else {
|
||
collapseThoughts();
|
||
}
|
||
}
|
||
|
||
// 展开感想列表
|
||
function expandThoughts() {
|
||
var thoughtsContainer = document.querySelector(".thoughts-list-container");
|
||
if (!thoughtsContainer || !thoughtsContainer._thoughtsToggle) return;
|
||
|
||
var itemsWrapper = thoughtsContainer._thoughtsToggle.itemsWrapper;
|
||
var toggleBtn = thoughtsContainer._thoughtsToggle.toggleBtn;
|
||
|
||
itemsWrapper.className = "thoughts-items-wrapper expanded";
|
||
toggleBtn.className = "thoughts-toggle-btn expanded";
|
||
if (toggleBtn.querySelector(".toggle-arrow")) {
|
||
toggleBtn.querySelector(".toggle-arrow").textContent = "↑";
|
||
}
|
||
}
|
||
|
||
// 收起感想列表
|
||
function collapseThoughts() {
|
||
var thoughtsContainer = document.querySelector(".thoughts-list-container");
|
||
if (!thoughtsContainer || !thoughtsContainer._thoughtsToggle) return;
|
||
|
||
var itemsWrapper = thoughtsContainer._thoughtsToggle.itemsWrapper;
|
||
var toggleBtn = thoughtsContainer._thoughtsToggle.toggleBtn;
|
||
|
||
itemsWrapper.className = "thoughts-items-wrapper collapsed";
|
||
toggleBtn.className = "thoughts-toggle-btn collapsed";
|
||
if (toggleBtn.querySelector(".toggle-arrow")) {
|
||
toggleBtn.querySelector(".toggle-arrow").textContent = "↓";
|
||
}
|
||
}
|
||
})();
|
||
</script>';
|
||
|
||
echo $js;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取感想列表(删除数量限制,改为全部显示)
|
||
*/
|
||
public static function getThoughts($cid = null)
|
||
{
|
||
if (!$cid) {
|
||
$widget = Typecho_Widget::widget('Widget_Archive');
|
||
$cid = $widget->cid;
|
||
}
|
||
|
||
if (!$cid) return array();
|
||
|
||
$db = Typecho_Db::get();
|
||
|
||
$select = $db->select()
|
||
->from('table.thoughts')
|
||
->where('cid = ?', $cid)
|
||
->where('status = ?', 'approved')
|
||
->order('created', Typecho_Db::SORT_DESC);
|
||
// 删除limit限制,改为全部显示
|
||
|
||
return $db->fetchAll($select);
|
||
}
|
||
|
||
/**
|
||
* 显示感想列表的HTML(有数据才显示)
|
||
*/
|
||
public static function renderThoughts($cid = null)
|
||
{
|
||
if (!$cid) {
|
||
$widget = Typecho_Widget::widget('Widget_Archive');
|
||
$cid = $widget->cid;
|
||
}
|
||
|
||
if (!$cid) return '';
|
||
|
||
// 获取感想数据(全部显示)
|
||
$thoughts = self::getThoughts($cid);
|
||
|
||
// 如果没有感想数据,返回空字符串(不显示任何内容)
|
||
if (empty($thoughts)) {
|
||
return '';
|
||
}
|
||
|
||
// 获取感想条数
|
||
$thoughtsCount = count($thoughts);
|
||
|
||
$db = Typecho_Db::get();
|
||
|
||
// 构建正确的HTML结构
|
||
$html = '<div class="thoughts-list-container" id="thoughts">';
|
||
$html .= '<div class="thoughts-header">';
|
||
$html .= '<h3><!--📖 -->回读感想<span class="thoughts-count-badge">' . $thoughtsCount . '条</span></h3>';
|
||
$html .= '</div>';
|
||
|
||
$html .= '<div class="thoughts-items-wrapper collapsed">';
|
||
|
||
foreach ($thoughts as $thought) {
|
||
// 获取用户信息
|
||
$user = $db->fetchRow($db->select()
|
||
->from('table.users')
|
||
->where('uid = ?', $thought['authorId']));
|
||
|
||
$date = date('Y年m月d日 H:i', $thought['created']);
|
||
|
||
// 优先显示昵称
|
||
if ($user) {
|
||
$username = !empty($user['screenName']) ? $user['screenName'] : $user['name'];
|
||
} else {
|
||
$username = '匿名用户';
|
||
}
|
||
|
||
$html .= '<div class="thought-item">';
|
||
$html .= '<div class="thought-meta">';
|
||
$html .= '<span class="thought-date">' . $date . '</span>';
|
||
$html .= '<span class="thought-user">' . htmlspecialchars($username) . '</span>';
|
||
$html .= '<span class="thought-action">回读本文</span>';
|
||
$html .= '</div>';
|
||
$html .= '<div class="thought-content">';
|
||
$html .= '<p><strong>写下感想:</strong>' . nl2br(htmlspecialchars($thought['text'])) . '</p>';
|
||
$html .= '</div>';
|
||
$html .= '</div>';
|
||
}
|
||
|
||
$html .= '</div>';
|
||
$html .= '</div>';
|
||
|
||
return $html;
|
||
}
|
||
|
||
/**
|
||
* 获取所有感想(用于独立页面)
|
||
*/
|
||
public static function getAllThoughts($limit = 20, $offset = 0)
|
||
{
|
||
$db = Typecho_Db::get();
|
||
|
||
$select = $db->select()
|
||
->from('table.thoughts')
|
||
->where('status = ?', 'approved')
|
||
->order('created', Typecho_Db::SORT_DESC);
|
||
|
||
// 应用分页限制
|
||
if ($limit > 0) {
|
||
$select->limit($limit);
|
||
}
|
||
|
||
if ($offset > 0) {
|
||
$select->offset($offset);
|
||
}
|
||
|
||
return $db->fetchAll($select);
|
||
}
|
||
|
||
/**
|
||
* 获取感想总数
|
||
*/
|
||
public static function getTotalThoughtsCount()
|
||
{
|
||
$db = Typecho_Db::get();
|
||
$select = $db->select('COUNT(*) as count')
|
||
->from('table.thoughts')
|
||
->where('status = ?', 'approved');
|
||
|
||
$result = $db->fetchRow($select);
|
||
return $result ? intval($result['count']) : 0;
|
||
}
|
||
|
||
/**
|
||
* 获取文章信息(修复链接生成)
|
||
*/
|
||
public static function getPostInfo($cid)
|
||
{
|
||
$db = Typecho_Db::get();
|
||
$select = $db->select('title', 'slug', 'type')
|
||
->from('table.contents')
|
||
->where('cid = ?', $cid)
|
||
->where('type = ?', 'post')
|
||
->where('status = ?', 'publish');
|
||
|
||
$result = $db->fetchRow($select);
|
||
|
||
if ($result) {
|
||
// 正确构建文章URL
|
||
$result['url'] = Typecho_Common::url(
|
||
Typecho_Router::url('post', $result),
|
||
Helper::options()->index
|
||
);
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 渲染独立页面内容 - 修复分页404问题(删除文章页感想分页功能)
|
||
*/
|
||
public static function renderThoughtsPage($page = 1, $perPage = null)
|
||
{
|
||
if (!$perPage) {
|
||
$options = Helper::options()->plugin('ThoughtsPlugin');
|
||
$perPage = $options->page_per_page ? intval($options->page_per_page) : 20;
|
||
}
|
||
|
||
$page = max(1, intval($page));
|
||
$offset = ($page - 1) * $perPage;
|
||
|
||
// 获取感想数据
|
||
$thoughts = self::getAllThoughts($perPage, $offset);
|
||
$total = self::getTotalThoughtsCount();
|
||
$totalPages = ceil($total / $perPage);
|
||
|
||
// 如果请求的页码超过总页数,显示最后一页
|
||
if ($page > $totalPages && $totalPages > 0) {
|
||
$page = $totalPages;
|
||
$offset = ($page - 1) * $perPage;
|
||
$thoughts = self::getAllThoughts($perPage, $offset);
|
||
}
|
||
|
||
$db = Typecho_Db::get();
|
||
|
||
$html = '<div class="thoughts-page-container">';
|
||
$html .= '<div class="thoughts-page-header">';
|
||
$html .= '<h1>全部感想<span class="thoughts-total-count">' . $total . ' 条</span></h1>';
|
||
|
||
if ($totalPages > 1) {
|
||
$html .= '<div class="subtitle">第 ' . $page . ' 页,共 ' . $totalPages . ' 页</div>';
|
||
} else {
|
||
$html .= '<div class="subtitle">按时间倒序排列,每次思考都值得被记录</div>';
|
||
}
|
||
|
||
$html .= '</div>';
|
||
|
||
if (empty($thoughts)) {
|
||
$html .= '<div class="thoughts-empty-page">
|
||
<div class="icon">📝</div>
|
||
<p>暂时还没有感想记录</p>
|
||
<p>去文章中发表你的第一个感想吧!</p>
|
||
<a href="' . Helper::options()->index . '" class="empty-action">浏览文章</a>
|
||
</div>';
|
||
} else {
|
||
// 显示当前页数据范围
|
||
$startNum = $offset + 1;
|
||
$endNum = min($offset + count($thoughts), $total);
|
||
|
||
if ($totalPages > 1) {
|
||
$html .= '<div style="text-align: center; margin-bottom: 20px; color: #718096; font-size: 0.95em;">
|
||
显示第 ' . $startNum . ' - ' . $endNum . ' 条感想,按时间倒序排列
|
||
</div>';
|
||
}
|
||
|
||
foreach ($thoughts as $index => $thought) {
|
||
// 获取用户信息
|
||
$user = $db->fetchRow($db->select()
|
||
->from('table.users')
|
||
->where('uid = ?', $thought['authorId']));
|
||
|
||
// 获取文章信息
|
||
$post = self::getPostInfo($thought['cid']);
|
||
|
||
// 优先显示昵称
|
||
if ($user) {
|
||
$username = !empty($user['screenName']) ? $user['screenName'] : $user['name'];
|
||
} else {
|
||
$username = '匿名用户';
|
||
}
|
||
|
||
// 文章标题和链接
|
||
if ($post) {
|
||
$postTitle = $post['title'];
|
||
$postUrl = $post['url'];
|
||
} else {
|
||
$postTitle = '文章已被删除';
|
||
$postUrl = '#';
|
||
}
|
||
|
||
$html .= '<div class="thoughts-page-item">';
|
||
$html .= '<div class="thoughts-page-meta">';
|
||
$html .= '<span class="date">' . date('Y年m月d日 H:i', $thought['created']) . '</span>';
|
||
$html .= '<span class="user">' . htmlspecialchars($username) . '</span>';
|
||
$html .= '<span class="article">阅读了《<a href="' . htmlspecialchars($postUrl) . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($postTitle) . '</a>》</span>';
|
||
$html .= '</div>';
|
||
$html .= '<div class="thoughts-page-content">';
|
||
$html .= '<strong>发布感想内容为:</strong>';
|
||
$html .= nl2br(htmlspecialchars($thought['text']));
|
||
$html .= '</div>';
|
||
$html .= '</div>';
|
||
}
|
||
|
||
// 分页 - 修复:使用JavaScript处理分页而不是URL参数(保留独立页面分页)
|
||
if ($totalPages > 1) {
|
||
$html .= '<div class="thoughts-pagination">';
|
||
|
||
// 上一页
|
||
if ($page > 1) {
|
||
$html .= '<a href="javascript:void(0)" onclick="goToPage(' . ($page - 1) . ')" class="extend" title="上一页">← 上一页</a>';
|
||
}
|
||
|
||
// 页码
|
||
$startPage = max(1, $page - 2);
|
||
$endPage = min($totalPages, $page + 2);
|
||
|
||
// 如果当前页靠近开头,显示更多后面的页码
|
||
if ($startPage == 1) {
|
||
$endPage = min($totalPages, $startPage + 4);
|
||
}
|
||
|
||
// 如果当前页靠近结尾,显示更多前面的页码
|
||
if ($endPage == $totalPages) {
|
||
$startPage = max(1, $endPage - 4);
|
||
}
|
||
|
||
for ($i = $startPage; $i <= $endPage; $i++) {
|
||
if ($i == $page) {
|
||
$html .= '<span class="current">' . $i . '</span>';
|
||
} else {
|
||
$html .= '<a href="javascript:void(0)" onclick="goToPage(' . $i . ')">' . $i . '</a>';
|
||
}
|
||
}
|
||
|
||
// 下一页
|
||
if ($page < $totalPages) {
|
||
$html .= '<a href="javascript:void(0)" onclick="goToPage(' . ($page + 1) . ')" class="extend" title="下一页">下一页 →</a>';
|
||
}
|
||
|
||
$html .= '</div>';
|
||
|
||
// 添加JavaScript处理分页
|
||
$html .= '<script>
|
||
function goToPage(page) {
|
||
if (page < 1) page = 1;
|
||
// 使用AJAX加载分页内容
|
||
loadPageContent(page);
|
||
}
|
||
|
||
function loadPageContent(page) {
|
||
// 显示加载状态
|
||
var container = document.querySelector(".thoughts-page-container");
|
||
if (!container) return;
|
||
|
||
container.style.opacity = "0.7";
|
||
container.style.pointerEvents = "none";
|
||
|
||
// 获取当前URL(去掉可能的page参数)
|
||
var currentUrl = window.location.pathname;
|
||
|
||
// 使用AJAX加载内容
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open("GET", currentUrl + "?thoughts_page=1&page=" + page, true);
|
||
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
||
|
||
xhr.onreadystatechange = function() {
|
||
if (xhr.readyState === 4) {
|
||
container.style.opacity = "1";
|
||
container.style.pointerEvents = "auto";
|
||
|
||
if (xhr.status === 200) {
|
||
// 解析HTML,只替换内容部分
|
||
var parser = new DOMParser();
|
||
var doc = parser.parseFromString(xhr.responseText, "text/html");
|
||
var newContent = doc.querySelector(".thoughts-page-container");
|
||
|
||
if (newContent) {
|
||
container.innerHTML = newContent.innerHTML;
|
||
|
||
// 更新URL(不刷新页面)
|
||
if (page === 1) {
|
||
history.pushState({page: page}, "", currentUrl);
|
||
} else {
|
||
history.pushState({page: page}, "", currentUrl + "?page=" + page);
|
||
}
|
||
|
||
// 滚动到顶部
|
||
window.scrollTo({top: 0, behavior: "smooth"});
|
||
|
||
// 重新绑定分页事件
|
||
bindPaginationEvents();
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
xhr.send();
|
||
}
|
||
|
||
function bindPaginationEvents() {
|
||
// 重新绑定分页链接的点击事件
|
||
var pageLinks = document.querySelectorAll(".thoughts-pagination a[onclick]");
|
||
pageLinks.forEach(function(link) {
|
||
var oldOnClick = link.getAttribute("onclick");
|
||
link.removeAttribute("onclick");
|
||
link.addEventListener("click", function(e) {
|
||
e.preventDefault();
|
||
eval(oldOnClick);
|
||
});
|
||
});
|
||
}
|
||
|
||
// 初始化绑定
|
||
document.addEventListener("DOMContentLoaded", function() {
|
||
bindPaginationEvents();
|
||
|
||
// 处理浏览器前进后退
|
||
window.addEventListener("popstate", function(event) {
|
||
if (event.state && event.state.page) {
|
||
loadPageContent(event.state.page);
|
||
}
|
||
});
|
||
});
|
||
</script>';
|
||
}
|
||
}
|
||
|
||
$html .= '</div>';
|
||
return $html;
|
||
}
|
||
|
||
/**
|
||
* 检查当前用户是否为管理员
|
||
*/
|
||
public static function isAdmin()
|
||
{
|
||
$user = Typecho_Widget::widget('Widget_User');
|
||
return $user->hasLogin() && $user->pass('administrator', true);
|
||
}
|
||
|
||
/**
|
||
* 获取感想数量
|
||
*/
|
||
public static function getThoughtsCount($cid = null)
|
||
{
|
||
if (!$cid) {
|
||
$widget = Typecho_Widget::widget('Widget_Archive');
|
||
$cid = $widget->cid;
|
||
}
|
||
|
||
if (!$cid) return 0;
|
||
|
||
$db = Typecho_Db::get();
|
||
$select = $db->select('COUNT(*) as count')
|
||
->from('table.thoughts')
|
||
->where('cid = ?', $cid)
|
||
->where('status = ?', 'approved');
|
||
|
||
$result = $db->fetchRow($select);
|
||
return $result ? intval($result['count']) : 0;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 助手类,用于模板中调用
|
||
*/
|
||
class ThoughtsPlugin
|
||
{
|
||
/**
|
||
* 显示感想列表(文章页)
|
||
*/
|
||
public static function showThoughts($cid = null)
|
||
{
|
||
return ThoughtsPlugin_Plugin::renderThoughts($cid);
|
||
}
|
||
|
||
/**
|
||
* 显示独立页面(全部感想)- 修复分页参数传递
|
||
*/
|
||
public static function showThoughtsPage($page = 1, $perPage = null)
|
||
{
|
||
// 设置标记让CSS生效
|
||
$_GET['thoughts_page'] = true;
|
||
|
||
// 优先从URL参数获取页码(解决Typecho路由问题)
|
||
if (isset($_GET['page']) && is_numeric($_GET['page'])) {
|
||
$page = max(1, intval($_GET['page']));
|
||
}
|
||
|
||
return ThoughtsPlugin_Plugin::renderThoughtsPage($page, $perPage);
|
||
}
|
||
|
||
/**
|
||
* 检查是否是管理员
|
||
*/
|
||
public static function isAdmin()
|
||
{
|
||
return ThoughtsPlugin_Plugin::isAdmin();
|
||
}
|
||
|
||
/**
|
||
* 获取感想数量(单篇文章)
|
||
*/
|
||
public static function getCount($cid = null)
|
||
{
|
||
return ThoughtsPlugin_Plugin::getThoughtsCount($cid);
|
||
}
|
||
|
||
/**
|
||
* 获取感想总数(全部)
|
||
*/
|
||
public static function getTotalCount()
|
||
{
|
||
return ThoughtsPlugin_Plugin::getTotalThoughtsCount();
|
||
}
|
||
|
||
/**
|
||
* 获取感想列表数据
|
||
*/
|
||
public static function getList($cid = null)
|
||
{
|
||
// 删除limit参数,改为全部显示
|
||
return ThoughtsPlugin_Plugin::getThoughts($cid);
|
||
}
|
||
} |