白荼日记 - PHP https://blog.iletter.top/index.php/tag/PHP/ zh-CN Sun, 27 Jul 2025 02:32:00 +0800 Sun, 27 Jul 2025 02:32:00 +0800 typecho给后台admin界面添加图标分析 https://blog.iletter.top/index.php/archives/406.html https://blog.iletter.top/index.php/archives/406.html Sun, 27 Jul 2025 02:32:00 +0800 DelLevin 觉得后台admin空荡荡的,索性加个图表自己魔改一下下。以下是完整的index.php

微信图片_20250727022229.png

<?php
include 'common.php';
include 'header.php';
include 'menu.php';

$stat = \Widget\Stat::alloc();
?>
<div class="main">
    <div class="container typecho-dashboard">
        <?php include 'page-title.php'; ?>
        <div class="row typecho-page-main">
            <div class="col-mb-12 welcome-board" role="main">
                <p><?php _e('目前有 <em>%s</em> 篇文章, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
                        $stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
                    <!--<br><?php _e('点击下面的链接快速开始:'); ?></p>-->

                <ul id="start-link" class="clearfix">
                    <?php if ($user->pass('contributor', true)): ?>
                        <li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
                        <?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
                            <li>
                                <a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
                                <span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
                            </li>
                        <?php elseif ($stat->myWaitingCommentsNum > 0): ?>
                            <li>
                                <a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
                                <span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
                            </li>
                        <?php endif; ?>
                        <?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?>
                            <li>
                                <a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
                                <span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
                            </li>
                        <?php elseif ($stat->mySpamCommentsNum > 0): ?>
                            <li>
                                <a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
                                <span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
                            </li>
                        <?php endif; ?>
                        <?php if ($user->pass('administrator', true)): ?>
                            <li><a href="<?php $options->adminUrl('manage-posts.php'); ?>"><?php _e('文章管理'); ?></a></li>
                            <!--<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>-->
                            <li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
                            <li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a>
                            </li>
                        <?php endif; ?>
                    <?php endif; ?>
                    <!--<li><a href="<?php $options->adminUrl('profile.php'); ?>"><?php _e('更新我的资料'); ?></a></li>-->
                </ul>
            </div>
            

            

            <div class="col-mb-12 col-tb-4" role="complementary">
                <section class="latest-link">
                    <h3><?php _e('最近发布的文章'); ?></h3>
                    <?php \Widget\Contents\Post\Recent::alloc('pageSize=10')->to($posts); ?>
                    <ul>
                        <?php if ($posts->have()): ?>
                            <?php while ($posts->next()): ?>
                                <li>
                                    <span><?php $posts->date('n.j'); ?></span>
                                    <a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
                                </li>
                            <?php endwhile; ?>
                        <?php else: ?>
                            <li><em><?php _e('暂时没有文章'); ?></em></li>
                        <?php endif; ?>
                    </ul>
                </section>
            </div>

            <div class="col-mb-12 col-tb-4" role="complementary">
                <section class="latest-link">
                    <h3><?php _e('最近得到的回复'); ?></h3>
                    <ul>
                        <?php \Widget\Comments\Recent::alloc('pageSize=10')->to($comments); ?>
                        <?php if ($comments->have()): ?>
                            <?php while ($comments->next()): ?>
                                <li>
                                    <span><?php $comments->date('n.j'); ?></span>
                                    <a href="<?php $comments->permalink(); ?>"
                                       class="title"><?php $comments->author(false); ?></a>:
                                    <?php $comments->excerpt(35, '...'); ?>
                                </li>
                            <?php endwhile; ?>
                        <?php else: ?>
                            <li><?php _e('暂时没有回复'); ?></li>
                        <?php endif; ?>
                    </ul>
                </section>
            </div>
            

            <!--<div class="col-mb-12 col-tb-4" role="complementary">-->
            <!--    <section class="latest-link">-->
            <!--        <h3><?php _e('官方最新日志'); ?></h3>-->
            <!--        <div id="typecho-message">-->
            <!--            <ul>-->
            <!--                <li><?php _e('读取中...'); ?></li>-->
            <!--            </ul>-->
            <!--        </div>-->
            <!--    </section>-->
            <!--</div>-->

                        <!-- 图表显示区域 -->
            <div class="col-mb-12 welcome-board">
                <h3 style="color:black"><?php _e('文章统计数据'); ?></h3>
                <div style="display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 20px;">
                    <!-- 月度发布图表 -->
                    <div style="flex: 1; min-width: 400px;">
                        <canvas id="monthlyPostChart" height="300"></canvas>
                    </div>
                    <!-- 状态分布图表 -->
                    <div style="flex: 1; min-width: 300px;">
                        <canvas id="statusChart" height="300"></canvas>
                    </div>
                </div>
                <div style="display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 20px;">
                    <!-- 分类文章统计 -->
                    <div style="flex: 1; min-width: 400px;">
                        <canvas id="categoryChart" height="300"></canvas>
                    </div>
                    <!-- 标签文章统计 -->
                    <div style="flex: 1; min-width: 400px;">
                        <canvas id="tagChart" height="300"></canvas>
                    </div>
                </div>
            </div>
                               
            
            
        </div>
    </div>
</div>

<?php
include 'copyright.php';
include 'common-js.php';
?>

<script src="https://blog.iletter.top/usr/blog_img/chart.js"></script>
<script>
  $(document).ready(function() {
    <?php
    // ==================== PHP 数据计算部分 ====================
    
    // 1. 月度文章统计数据
    $db = Typecho_Db::get();
    
    // 月度文章统计
    $select = $db->select()
        ->from('table.contents')
        ->where('type = ?', 'post')
        ->where('status = ?', 'publish');
    $posts = $db->fetchAll($select);
    
    $monthlyData = [];
    $monthLabels = [];
    $currentYear = date('Y');
    $currentMonth = date('n');
    
    // 初始化最近12个月的数据
    for ($i = 11; $i >= 0; $i--) {
        $year = $currentYear;
        $month = $currentMonth - $i;
        if ($month <= 0) {
            $month += 12;
            $year--;
        }
        $key = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT);
        $monthlyData[$key] = 0;
        $monthLabels[$key] = $year . '年' . $month . '月';
    }
    
    // 统计实际数据
    foreach ($posts as $post) {
        $created = $post['created'];
        $year = date('Y', $created);
        $month = date('m', $created);
        $key = $year . '-' . $month;
        
        if (isset($monthlyData[$key])) {
            $monthlyData[$key]++;
        }
    }
    
    // 2. 文章状态统计
    $published = $db->fetchObject($db->select(['COUNT(*)' => 'count'])
        ->from('table.contents')
        ->where('type = ?', 'post')
        ->where('status = ?', 'publish'))->count;
        
    $draft = $db->fetchObject($db->select(['COUNT(*)' => 'count'])
        ->from('table.contents')
        ->where('type = ?', 'post_draft')
        ->where('status = ?', 'publish'))->count;
        
        
    // 3. 分类文章统计
    $categories = $db->fetchAll($db->select()->from('table.metas')->where('type = ?', 'category'));
    $categoryData = [];
    $categoryLabels = [];
    
    foreach ($categories as $category) {
        $count = $db->fetchObject($db->select(['COUNT(*)' => 'count'])
            ->from('table.relationships')
            ->where('mid = ?', $category['mid']))->count;
        
        if ($count > 0) { // 只显示有文章的分类
            $categoryLabels[] = $category['name'];
            $categoryData[] = (int)$count;
        }
    }
    
    // 4. 标签文章统计 (取前10个)
    $tags = $db->fetchAll($db->select()->from('table.metas')->where('type = ?', 'tag'));
    $tagData = [];
    $tagLabels = [];
    
    foreach ($tags as $tag) {
        $count = $db->fetchObject($db->select(['COUNT(*)' => 'count'])
            ->from('table.relationships')
            ->where('mid = ?', $tag['mid']))->count;
        
        if ($count > 0) {
            $tagLabels[] = $tag['name'];
            $tagData[] = (int)$count;
        }
    }
    
    // 按数量排序,取前10个
    array_multisort($tagData, SORT_DESC, $tagLabels);
    $topTagLabels = array_slice($tagLabels, 0, 10);
    $topTagData = array_slice($tagData, 0, 10);
    
    // 准备图表数据
    $chartMonthlyData = [
        'labels' => array_values($monthLabels),
        'values' => array_values($monthlyData)
    ];
    
    $chartStatusData = [
        'published' => (int)$published,
        'draft' => (int)$draft
    ];
    
    $chartCategoryData = [
        'labels' => $categoryLabels,
        'values' => $categoryData
    ];
    
    $chartTagData = [
        'labels' => $topTagLabels,
        'values' => $topTagData
    ];
    ?>
    
    // ==================== JavaScript 图表渲染部分 ====================
    
    // 1. 月度文章图表
    var monthlyData = <?php echo json_encode($chartMonthlyData); ?>;
    if (monthlyData.labels && monthlyData.labels.length > 0) {
        var ctx1 = document.getElementById('monthlyPostChart').getContext('2d');
        new Chart(ctx1, {
            type: 'line',
            data: {
                labels: monthlyData.labels,
                datasets: [{
                    label: '每月发文数',
                    data: monthlyData.values,
                    borderColor: 'rgb(75, 192, 192)',
                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
                    tension: 0.1,
                    fill: true
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            precision: 0
                        }
                    }
                },
                plugins: {
                    title: {
                        display: true,
                        text: '月度文章发布趋势'
                    }
                }
            }
        });
    }
    
    // 2. 文章状态图表
    var statusData = <?php echo json_encode($chartStatusData); ?>;
    if (statusData) {
        var ctx2 = document.getElementById('statusChart').getContext('2d');
        new Chart(ctx2, {
            type: 'doughnut',
            data: {
                labels: ['已发布', '草稿'],
                datasets: [{
                    data: [statusData.published, statusData.draft],
                    backgroundColor: [
                        'rgba(75, 192, 192, 0.8)',
                        'rgba(255, 205, 86, 0.8)',
                    ],
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: true,
                        text: '文章状态分布'
                    },
                    legend: {
                        position: 'bottom'
                    }
                }
            }
        });
    }
    
    // 3. 分类文章图表
    var categoryData = <?php echo json_encode($chartCategoryData); ?>;
    if (categoryData.labels && categoryData.labels.length > 0) {
        var ctx3 = document.getElementById('categoryChart').getContext('2d');
        new Chart(ctx3, {
            type: 'bar',
            data: {
                labels: categoryData.labels,
                datasets: [{
                    label: '文章数量',
                    data: categoryData.values,
                    backgroundColor: 'rgba(153, 102, 255, 0.8)',
                    borderColor: 'rgba(153, 102, 255, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            precision: 0
                        }
                    }
                },
                plugins: {
                    title: {
                        display: true,
                        text: '各分类文章数量'
                    }
                }
            }
        });
    }
    
    // 4. 标签文章图表
    var tagData = <?php echo json_encode($chartTagData); ?>;
    if (tagData.labels && tagData.labels.length > 0) {
        var ctx4 = document.getElementById('tagChart').getContext('2d');
        new Chart(ctx4, {
            type: 'bar',
            data: {
                labels: tagData.labels,
                datasets: [{
                    label: '文章数量',
                    data: tagData.values,
                    backgroundColor: 'rgba(255, 159, 64, 0.8)',
                    borderColor: 'rgba(255, 159, 64, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            precision: 0
                        }
                    }
                },
                plugins: {
                    title: {
                        display: true,
                        text: '热门标签文章数量 (前10)'
                    }
                }
            }
        });
    }
});
</script>

<script>
$(document).ready(function () {
        var ul = $('#typecho-message ul'), cache = window.sessionStorage,
            html = cache ? cache.getItem('feed') : '',
            update = cache ? cache.getItem('update') : '';

        if (!!html) {
            ul.html(html);
        } else {
            html = '';
            $.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
                for (var i = 0; i < o.length; i++) {
                    var item = o[i];
                    html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
                        + '</a></li>';
                }

                ul.html(html);
                cache.setItem('feed', html);
            }, 'json');
        }

        function applyUpdate(update) {
            if (update.available) {
                $('<div class="update-check message error"><p>'
                    + '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
                    + '<strong><a href="' + update.link + '" target="_blank">'
                    + '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
                    .insertAfter('.typecho-page-title').effect('highlight');
            }
        }

        if (!!update) {
            applyUpdate($.parseJSON(update));
        } else {
            $.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
                applyUpdate(o);
                cache.setItem('update', resp.responseText);
            }, 'json');
        }
    });


              

</script>
<?php include 'footer.php'; ?>

其他插件推荐:
[post cid="405" /]

]]>
0 https://blog.iletter.top/index.php/archives/406.html#comments https://blog.iletter.top/index.php/feed/tag/PHP/
为typecho博客添加Gotify插件通知 https://blog.iletter.top/index.php/archives/405.html https://blog.iletter.top/index.php/archives/405.html Sun, 27 Jul 2025 02:05:00 +0800 DelLevin 受限于typecho博客没有通知,自己写了一个博客有评论就通知的gotify插件,脚本使用之前的python改的。这是效果

消息通知#208px #433px

<?php

namespace TypechoPlugin\GotifyNotify;

use Typecho\Plugin\PluginInterface;
use Typecho\Widget\Helper\Form;
use Typecho\Widget\Helper\Form\Element\Text;
// use Typecho\Widget\Helper\Form\Element\Radio; // 不再需要 Radio 元素
use Widget\Options;
use Typecho\Plugin\Exception as PluginException;
use Typecho\Widget\Exception as WidgetException;
use Typecho\Db\Exception as DbException;
use Utils;

if (!defined('__TYPECHO_ROOT_DIR__')) {
    exit;
}

/**
 * 当用户评论时通过 Gotify 发送通知
 *
 * @package GotifyNotify
 * @author 白荼
 * @version 1.3.0
 * @link https://gotify.net
 */
class Plugin implements PluginInterface
{
    /**
     * 激活插件方法
     *
     * @access public
     * @return void
     * @throws PluginException
     */
    public static function activate()
    {
        // 监听评论完成事件 - 触发服务调用
        \Typecho\Plugin::factory('Widget_Feedback')->finishComment = __CLASS__ . '::requestService';
        \Typecho\Plugin::factory('Widget_Comments_Edit')->finishComment = __CLASS__ . '::requestService';

        // 注册异步调用服务
        \Typecho\Plugin::factory('Widget_Service')->sendGotify = __CLASS__ . '::sendGotify';
    }

    /**
     * 禁用插件方法
     *
     * @access public
     * @return void
     * @throws PluginException
     */
    public static function deactivate()
    {
        // 通常不需要显式移除
    }

    /**
     * 获取插件配置面板
     *
     * @param Form $form 配置面板
     * @access public
     * @return void
     */
    public static function config(Form $form)
    {
        // Gotify 服务器地址
        $serverUrl = new Text('serverUrl', NULL, '', _t('Gotify 服务器地址'), _t('例如: http://your-gotify-server.com'));
        $form->addInput($serverUrl->addRule('required', _t('Gotify 服务器地址不能为空')));

        // 应用 Token
        $appToken = new Text('appToken', NULL, '', _t('应用 Token'), _t('在 Gotify 中创建应用后获得的 Token'));
        $form->addInput($appToken->addRule('required', _t('应用 Token 不能为空')));

        // 通知标题
        $title = new Text('title', NULL, '博客有新评论', _t('通知标题'), _t('收到新评论时的推送标题'));
        $form->addInput($title);

        // 消息优先级 (Priority) - 使用 Text 输入框
        $priority = new Text('priority', NULL, '1', _t('消息优先级'), _t('设置 Gotify 消息的优先级 (自己在Gorify的定义)'));
        $form->addInput($priority);

        // 移除了 "是否启用" 的配置选项,插件默认启用
    }

    /**
     * 个人用户的配置面板
     *
     * @param Form $form
     * @access public
     * @return void
     */
    public static function personalConfig(Form $form)
    {
        // 个人配置通常为空
    }

    /**
     * 评论通知回调 - 触发异步服务
     * 这个方法在评论完成后被调用
     *
     * @access public
     * @param $comment (Widget_Comments_Edit 或 Widget_Feedback 的实例)
     * @return void
     * @throws PluginException
     */
    public static function requestService($comment)
    {
        // 检查评论对象是否有效
        if (!isset($comment->coid) || !$comment->have()) {
             error_log("GotifyNotify: Invalid comment object received in requestService.");
             return;
        }

        $coid = $comment->coid;
        $options = Options::alloc()->plugin('GotifyNotify');

        // 移除了对 $options->enable 的检查,插件默认启用

        // 检查必要配置
        if (empty($options->serverUrl) || empty($options->appToken)) {
             error_log("GotifyNotify: Missing server URL or app token, skipping notification for comment ID {$coid}.");
            return;
        }

        // 调用 Widget_Service 中注册的异步方法
        // 将评论 ID 传递给异步服务
        try {
             error_log("GotifyNotify: Calling async service for comment ID {$coid}.");
            Utils\Helper::requestService('sendGotify', $coid);
        } catch (\Exception $e) {
             error_log("GotifyNotify: Failed to call async service for comment ID {$coid}. Error: " . $e->getMessage());
        }
    }

    /**
     * 异步发送 Gotify 通知
     * 这个方法由 Widget_Service 调用
     *
     * @param integer $coid 评论ID
     * @access public
     * @return void
     * @throws WidgetException
     * @throws DbException
     */
    public static function sendGotify(int $coid)
    {
         error_log("GotifyNotify Service: Starting to process comment ID {$coid}.");

        // 获取插件配置
        $options = Options::alloc()->plugin('GotifyNotify');

        // 移除了对 $options->enable 的检查,插件默认启用

        // 重新获取评论对象
        try {
            $commentWidget = Utils\Helper::widgetById('comments', $coid);
        } catch (WidgetException $e) {
             error_log("GotifyNotify Service: Failed to get comment widget for ID {$coid}. Error: " . $e->getMessage());
            return;
        }

        if (!$commentWidget->have()) {
             error_log("GotifyNotify Service: Comment widget is empty for ID {$coid}.");
            return;
        }

        // 检查必要配置
        if (empty($options->serverUrl) || empty($options->appToken)) {
             error_log("GotifyNotify Service: Missing configuration for comment ID {$coid}.");
            return;
        }

        try {
            // 构造通知内容
            $title = $options->title ?: '博客有新评论';
            $message = self::buildMessage($commentWidget); // 传入 widget 对象
            // 获取优先级设置
            $priority = $options->priority ?? '1'; // 默认优先级为 1

             error_log("GotifyNotify Service: Prepared message for comment ID {$coid}. Title: {$title}, Priority: {$priority}");

            // 发送通知,传入优先级
            self::sendGotifyMessage($options->serverUrl, $options->appToken, $title, $message, $priority);
             error_log("GotifyNotify Service: Successfully sent notification for comment ID {$coid}.");

        } catch (\Exception $e) {
            // 记录详细错误信息
             error_log("GotifyNotify Service: Failed to send notification for comment ID {$coid}. Error: " . $e->getMessage());
             error_log("GotifyNotify Service: Stack trace: " . $e->getTraceAsString());
        }
    }

    /**
     * 构造通知消息内容
     *
     * @param \Widget\Base\Comments $comment 评论对象
     * @return string 消息内容
     */
    private static function buildMessage($comment)
    {
        $content = '';

        if (is_object($comment) && $comment->have()) {
            // 从评论对象获取信息
            $author = $comment->author ?? '匿名用户';
            $mail = $comment->mail ?? '';
            $url = $comment->url ?? '';
            $text = $comment->text ?? '';
            // $ip = $comment->ip ?? ''; // Widget\Base\Comments 通常不直接暴露 IP

            $content = "作者: {$author}\n";
            if (!empty($mail)) {
                $content .= "邮箱: {$mail}\n";
            }
            if (!empty($url)) {
                $content .= "网站: {$url}\n";
            }
            // if (!empty($ip)) {
            //     $content .= "IP: {$ip}\n";
            // }
            $content .= "内容: {$text}\n";
            $content .= "时间: " . date('Y-m-d H:i:s', $comment->created) . "\n"; // 使用评论创建时间
            $content .= "文章: " . $comment->title . "\n"; // 文章标题
            $content .= "链接: " . $comment->permalink . "\n"; // 评论链接
        } else {
            // 兼容其他情况
            $content = "收到新评论,请登录后台查看 (评论ID: " . ($comment->coid ?? 'unknown') . ")";
        }

        return $content;
    }

    /**
     * 发送 Gotify 消息
     *
     * @param string $serverUrl Gotify 服务器地址
     * @param string $appToken 应用 Token
     * @param string $title 消息标题
     * @param string $message 消息内容
     * @param string $priority 消息优先级
     * @throws \Exception
     */
    private static function sendGotifyMessage($serverUrl, $appToken, $title, $message, $priority = '1')
    {
        // 清理 URL
        $serverUrl = rtrim($serverUrl, '/');

        // 构造请求 URL (使用查询参数传递 token)
        $url = $serverUrl . '/message';

        // 准备表单数据,包含 priority
        $data = [
            'title' => $title,
            'message' => $message,
            'priority' => $priority // 使用传入的优先级
        ];

        // 准备查询参数
        $params = ['token' => $appToken];
        $fullUrl = $url . '?' . http_build_query($params);

         error_log("GotifyNotify: Sending request to {$fullUrl}");
         error_log("GotifyNotify: POST data: " . print_r($data, true));

        // 使用 cURL 发送请求
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $fullUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  // 发送表单数据
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 根据你的服务器 SSL 配置调整
        curl_setopt($ch, CURLOPT_USERAGENT, 'Typecho GotifyNotify Plugin/1.3.0');

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

         error_log("GotifyNotify: cURL Response Code: {$httpCode}");
         error_log("GotifyNotify: cURL Response Body: {$response}");
         error_log("GotifyNotify: cURL Error (if any): {$error}");

        // 检查响应
        if ($response === false) {
            throw new \Exception('cURL error: ' . $error);
        }

        if ($httpCode >= 200 && $httpCode < 300) {
            // 成功
             error_log("GotifyNotify: Message sent successfully.");
            // 可以进一步检查返回的 JSON
            $result = json_decode($response, true);
            if (!$result) {
                 error_log("GotifyNotify: Warning - Could not decode JSON response, but HTTP status was OK.");
            }
            return; // 成功返回
        } else {
            // 失败
            throw new \Exception('HTTP error: ' . $httpCode . ', response: ' . $response);
        }
    }
}
]]>
0 https://blog.iletter.top/index.php/archives/405.html#comments https://blog.iletter.top/index.php/feed/tag/PHP/