Last updated on 9月 16th, 2025 at 09:15 下午

2025年9月16日 更新,感谢ai,用豆包修复了一下,好用了,代码如下

<?php
/*
Plugin Name:    Popular Clicks Extended - modified by dex
Plugin URI:     http://github.com/dexzhou/yourls-popular-clicks-extended
Description:    Paul Vaughan (http://github.com/vaughany/yourls-popular-clicks-extended) created this tool 8 years ago, but it didn't work well with time offsets. Now just modify line 18 and it will work, although it's not tied to the "definition('YOURLS_HOURS_OFFSET','+8')" in the user/config.php. I'm not a programmer and just modified it with an AI tool. Only the admin page was corrected to show records with the right time;  other items on the plugin page were not modified.
Version:        0.3
Release date:   2018-05-10
Author:         Paul Vaughan
Author URI:     http://github.com/vaughany/
*/
if ( !defined ('YOURLS_ABSPATH') ) { die(); }
define ( "PCE_DEBUG", false );
define ( "PCE_SEP", ' | ' );
define ( "PCE_REL_VER",  '0.3' );
define ( "PCE_REL_DATE", '2018-05-10' );
define ( "PCE_REPO", 'https://github.com/vaughany/yourls-popular-clicks-extended' );
// e.g. UTC+8 =(8*60*60=28800 s),input 8* 60 *60 below
define( "PCE_OFFSET", 8 * 60 * 60 );
define( "PCE_BLACKLIST", "" );
yourls_add_action( 'plugins_loaded', 'vaughany_pce_init' );
yourls_add_action( 'admin_page_after_table', 'vaughany_pce_recenthits' );

function vaughany_pce_init() {
    yourls_register_plugin_page( 'vaughany_pce', 'Popular Clicks Extended', 'vaughany_pce_display_page' );
}

function vaughany_pce_show_last_period( $period, $rows, $desc ) {
    global $ydb;
    if ( !is_int( $rows ) || $rows == 0 || $rows == null ) {
        $rows = 20;
    }
    $since = date( 'Y-m-d H:i:s', ( time() - $period + PCE_OFFSET ) );
$sql = "SELECT a.shorturl AS shorturl, COUNT(*) AS clicks, b.url AS longurl, b.title as title
        FROM " . YOURLS_DB_TABLE_LOG . " a, " . YOURLS_DB_TABLE_URL . " b
        WHERE a.shorturl = b.keyword
            AND DATE_ADD(a.click_time, INTERVAL :offset SECOND) >= :since  -- 新增时区偏移
        GROUP BY a.shorturl
        ORDER BY COUNT(*) DESC, shorturl ASC
        LIMIT :rows;";
    // 关键修改:添加 offset 绑定参数(值为 PCE_OFFSET)
    $binds = ['since' => $since, 'rows' => $rows, 'offset' => PCE_OFFSET];
    if ( PCE_DEBUG ) {
        echo '<p style="color: #f00;">(' . $sql . ')</p>';
    }
    if ( $results = $ydb->fetchObjects( $sql, $binds ) ) {
        $out = vaughany_pce_render_results( $results );
    } else {
        $out = '<p>No results for the chosen time period.</p>';
    }
    echo '<h3>Popular clicks for the last ' . $desc . ":</h3>";
    if (PCE_DEBUG) {
        echo '<p style="color: #f00;">(Period from ' . $since . ' to now.)</p>';
    }
    echo $out;
}

function vaughany_pce_show_specific_period( $period, $type, $rows, $desc ) {
    global $ydb;
    if ( !is_int($rows) || $rows == 0 || $rows == null ) {
        $rows = 20;
    }
    if ( $type == 'hour' ) {
        $from   = $period . ':00:00';
        $to     = $period . ':59:59';
    } else if ( $type == 'day' ) {
        $from   = $period . ' 00:00:00';
        $to     = $period . ' 23:59:59';
    } else if ( $type == 'week' ) {
        $from   = $period . ' 00:00:00';
        $to     = date( 'Y-m-d', strtotime( $period . ' + 6 days', time() + PCE_OFFSET ) ) . ' 23:59:59';
    } else if ( $type == 'month' ) {
        $from   = $period . '-01 00:00:00';
        $to     = date( 'Y-m-d', strtotime( $period . '-' . date( 't', strtotime( $from, time() + PCE_OFFSET ) ), time() + PCE_OFFSET ) ) . ' 23:59:59';
    } else if ( $type == 'year' ) {
        $from   = $period . '-01-01 00:00:00';
        $to     = $period . '-12-31 23:59:59';
    } else {
        $from   = '1970-01-01 00:00:00';
        $to     = date( 'Y-m-d H:i:s', 2147483647 );
    }
    // 关键修改:为 click_time 叠加 UTC+8 偏移(DATE_ADD 函数)
    $sql = "SELECT a.shorturl AS shorturl, COUNT(*) AS clicks, b.url AS longurl, b.title as title
        FROM " . YOURLS_DB_TABLE_LOG . " a, " . YOURLS_DB_TABLE_URL . " b
        WHERE a.shorturl = b.keyword
            AND DATE_ADD(a.click_time, INTERVAL :offset SECOND) >= :from  -- 新增时区偏移
            AND DATE_ADD(a.click_time, INTERVAL :offset SECOND) <= :to    -- 新增时区偏移
        GROUP BY a.shorturl
        ORDER BY COUNT(*) DESC, shorturl ASC
        LIMIT :rows;";
    // 关键修改:添加 offset 绑定参数(值为 PCE_OFFSET)
    $binds = ['from' => $from, 'to' => $to, 'rows' => $rows, 'offset' => PCE_OFFSET];
    if ( PCE_DEBUG ) {
        echo '<p style="color: #f00;">(' . $sql . ")</p>";
    }
    if ( $results = $ydb->fetchObjects( $sql, $binds ) ) {
        $out = vaughany_pce_render_results( $results );
    } else {
        $out = '<p>No results for the chosen time period.</p>';
    }
    echo '<h3>Popular clicks for ' . $desc . ":</h3>";
    if ( PCE_DEBUG ) {
        echo '<p style="color: #f00;">(Period from ' . $from . ' to ' . $to . ".)</p>";
    }
    echo $out;
}

function vaughany_pce_render_results( $results ) {
    $total = 0;
    $out = '<table>';
    $out .= '<tr><th>Hits</th><th>Short URL</th><th>Website</th></tr>';
    foreach ( $results as $result ) {
        $total += $result->clicks;
        $out .= '<tr>';
        $out .= '<td>' . $result->clicks . '</td>';
        $out .= '<td><a href="' . YOURLS_SITE . '/' . $result->shorturl . '+" target="blank">' . $result->shorturl . '</a></td>';
        $out .= '<td><a href="' . $result->longurl . '" target="blank">' . $result->title . '</a></td>';
    }
    $out .= '</table>';
    return $out;
}

function vaughany_show_log( $rows = 20) {
    global $ydb;
    if ( !is_int($rows) || $rows == 0 || $rows == null || $rows == '' ) {
        $rows = 20;
    }
    // 关键修改:查询时将 click_time 转换为 UTC+8 时间(DATE_ADD 函数)
    $sql = "SELECT DATE_ADD(a.click_time, INTERVAL :offset SECOND) AS click_time,  -- 新增时区偏移
                   a.ip_address, 
                   a.country_code, 
                   a.referrer, 
                   a.shorturl AS shorturl, 
                   b.url AS longurl, 
                   b.title as title
        FROM " . YOURLS_DB_TABLE_LOG . " a, " . YOURLS_DB_TABLE_URL . " b
        WHERE a.shorturl = b.keyword
        ORDER BY a.click_time DESC  -- 按原时间排序(不影响)
        LIMIT :rows;";
    // 关键修改:添加 offset 绑定参数
    $binds = ['rows' => $rows, 'offset' => PCE_OFFSET];
    if ( PCE_DEBUG ) {
        echo '<p style="color: #f00;">(' . $sql . ")</p>" . PHP_EOL;
    }
    if ( $results = $ydb->fetchObjects( $sql, $binds ) ) {
        $out = '<ol>';
        foreach ( $results as $result ) {
            $out .= '<li>';
            $out .= $result->click_time . PCE_SEP;  // 此时显示的已是 UTC+8 时间
            $out .= $result->country_code . PCE_SEP;
            $out .= $result->ip_address . PCE_SEP;
            $out .= $result->referrer . PCE_SEP;
            $out .= 'click  <a href="' . YOURLS_SITE . '/' . $result->shorturl . '+" target="blank">' . $result->shorturl . '</a> / ';
            $out .= 'to <a href="' . $result->longurl . '" target="blank">' . $result->title . '</a>' . PCE_SEP;
            $out .= '</li>';
        }
        $out .= "</ol>" . PHP_EOL;
    } else {
        $out = '<p>No logs to display.</p>' . PHP_EOL;
    }
    echo $out;
}

function vaughany_pce_recenthits() {
    echo vaughany_show_log();
}

function vaughany_pce_display_page() {
    yourls_e( '<h2>Popular Clicks Extended</h2>' );
    yourls_e( '<p>This report shows the most popular clicks for the selected time periods as of ' . date( 'jS F Y, g:ia', time() + PCE_OFFSET ) . '.</p>' );
    yourls_e( '<p>Legend: <em>Position. Clicks' . PCE_SEP . 'Short URL' . PCE_SEP . 'Page</em></p>' );
    echo "<hr>" ;
?>
<div id="tabs">
    <div class="wrap_unfloat">
        <ul id="headers" class="toggle_display stat_tab">
            <li class="selected"><a href="#stat_tab_stats"><h2>'Period'</h2></a></li>
            <li><a href="#stat_tab_location"><h2>Last 'Period'</h2></a></li>
            <li><a href="#stat_tab_sources"><h2>Something Else</h2></a></li>
            <li><a href="#stat_tab_share"><h2>Settings</h2></a></li>
        </ul>
    </div>
    <div id="stat_tab_stats" class="tab">
        <p>Content coming soon.</p>
    <?php echo vaughany_pce_this_period() ?>
    </div>
    <div id="stat_tab_location" class="tab">
        <p>Content coming soon.</p>
    <?php echo vaughany_pce_last_period() ?>
    </div>
    <div id="stat_tab_sources" class="tab">
        <p>Content coming soon.</p>
    <?php echo vaughany_pce_something() ?>
    </div>
    <div id="stat_tab_share" class="tab">
    <p>Probably a form or something.</p>
    </div>
</div>
<?php
    echo "<hr>" ;
    yourls_e( '<h2>Popular clicks for &quot;<em>period</em>&quot;</h2>' );
    vaughany_pce_show_specific_period( date( 'Y-m-d H', time() + PCE_OFFSET ), 'hour', null, 'this hour (' . date( 'jS F Y, ga', time() + PCE_OFFSET ) . ' to ' . date( 'ga', strtotime( '+ 1 hour', time() + PCE_OFFSET ) ) . ') (so far)' );
    vaughany_pce_show_specific_period( date( 'Y-m-d H', strtotime( '- 1 hour', time() + PCE_OFFSET ) ), 'hour', null, 'the previous hour (' . date( 'jS F Y, ga', strtotime( '- 1 hour', time() + PCE_OFFSET ) ) . ' to ' . date( 'ga', time() + PCE_OFFSET ) . ')' );
    vaughany_pce_show_specific_period( date( 'Y-m-d', time() + PCE_OFFSET ), 'day', null, 'today (' . date( 'jS F Y', time() + PCE_OFFSET ) . ') (so far)' );
    vaughany_pce_show_specific_period( date( 'Y-m-d', strtotime( '- 1 day', time() + PCE_OFFSET ) ), 'day', null, 'yesterday (' . date( 'jS F Y', strtotime( '- 1 day', time() + PCE_OFFSET ) ) . ')' );
    vaughany_pce_show_specific_period( date( 'Y-m-d', strtotime( 'monday this week', time() + PCE_OFFSET ) ), 'week', null, 'this week (beginning ' . date( 'jS F Y', strtotime( 'monday this week', time() + PCE_OFFSET ) ) . ') (so far)' );
    vaughany_pce_show_specific_period( date( 'Y-m-d', strtotime( 'monday this week - 7 days', time() + PCE_OFFSET ) ), 'week', null, 'last week  (beginning ' . date( 'jS F Y', strtotime( 'monday this week - 7 days', time() + PCE_OFFSET ) ) . ')' );
    vaughany_pce_show_specific_period( date( 'Y-m', time() + PCE_OFFSET ), 'month', null, 'this month (' . date( 'F Y', time() + PCE_OFFSET ) . ') (so far)' );
    vaughany_pce_show_specific_period( date( 'Y-m', strtotime( '- 1 month', time() + PCE_OFFSET ) ), 'month', null, 'last month (' . date( 'F Y', strtotime( '- 1 month', time() + PCE_OFFSET ) ) . ')' );
    vaughany_pce_show_specific_period( date( 'Y', time() + PCE_OFFSET ), 'year', null, 'this year (' . date( 'Y', time() + PCE_OFFSET ) . ') (so far)');
    vaughany_pce_show_specific_period( date( 'Y', strtotime( '- 1 year', time() + PCE_OFFSET ) ), 'year', null, 'last year (' . date('Y', strtotime( '- 1 year', time() + PCE_OFFSET ) ) . ')' );
    echo "<hr>";
    yourls_e( '<h2>Popular clicks for the last &quot;<em>period</em>&quot;</h2>' );
    vaughany_pce_show_last_period( 60 * 5,                  null, '5 minutes');
    vaughany_pce_show_last_period( 60 * 30,                 null, '30 minutes');
    vaughany_pce_show_last_period( 60 * 60,                 null, 'hour');
    vaughany_pce_show_last_period( 60 * 60 * 6,             null, '6 hours');
    vaughany_pce_show_last_period( 60 * 60 * 12,            null, '12 hours');
    vaughany_pce_show_last_period( 60 * 60 * 24,            null, '24 hours');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 2,        null, '2 days');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 7,        null, 'week');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 14,       null, '2 weeks');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 30,       null, 'month');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 60,       null, '2 months');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 90,       null, '3 months');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 180,      null, '6 months');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 365,      null, 'year');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 365 * 2,  null, '2 years');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 365 * 3,  null, '3 years');
    vaughany_pce_show_last_period( 60 * 60 * 24 * 365 * 4,  null, '4 years');
    vaughany_pce_show_last_period( time(),                  null, 'billion years');
    echo "<hr>";
    yourls_e( '<h2>Recently used short links</h2>' );
    vaughany_show_log();
    echo "<hr>";
    if ( PCE_DEBUG ) {
        echo '<p style="color: #f00;">';
        echo 'Last monday: ' . date( 'Y-m-d', strtotime( 'last monday', time() + PCE_OFFSET ) ) . "<br>" . PHP_EOL;
        echo 'Monday before: ' . date( 'Y-m-d', strtotime( 'last monday - 7 days', time() + PCE_OFFSET ) ) . "<br>" . PHP_EOL;
        echo 'Last month: ' . date( 'Y-m', strtotime( '- 1 month', time() + PCE_OFFSET ) ) . "<br>" . PHP_EOL;
        echo '32-bit max Unix int: ' . date( 'Y-m-d H:i:s', 2147483647) . PHP_EOL;
        echo '</p>';
    }
    echo '<p>This plugin by <a href="https://github.com/vaughany/">Paul Vaughan</a>, version ' . PCE_REL_VER . ' (' . PCE_REL_DATE .
        '), heavily inspired by <a href="https://github.com/miconda/yourls">Popular Clicks</a>, is <a href="' . PCE_REPO .
        '">available on GitHub</a> (<a href="' . PCE_REPO . '/issues">file a bug here</a>).</p>' . PHP_EOL;
}

 

 


2023年7月20日 更新:再次测试了一下,不好用了。此文作废


Popular Clicks Extended是短连接程序YOURLS的一款插件,可以在首页底部显示最近被访问的链接统计数据,很方便,但是时区显示有问题。

已经在config.php文件里面添加了 define( 'YOURLS_HOURS_OFFSET', '+8');

也尝试了time zones插件,;

但是Popular Clicks Extended 本身有bug,时区没有偏移,始终是UTC0。

最后在nginx里面设置一下,就可以了

方法:

打开宝塔面板-网站-配置文件,找到 location /

在下面的{}里面添加 autoindex_localtime on; (注意:nginx显示的文件时间默认为GMT时间。使用上面的代码之后后,显示的文件时间为服务器时间.)

保存即可

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据