⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comments.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
📖 第 1 页 / 共 3 页
字号:
# Copyright 2001-2005 Six Apart.# SCRiPTMAFiA 2005 - THE DiRTY HANDS ON YOUR SCRiPTS## $Id: Comments.pm 10599 2005-03-22 20:39:23Z bchoate $package MT::App::Comments;use strict;use MT::App;@MT::App::Comments::ISA = qw( MT::App );use MT::Comment;use MT::Util qw( remove_html encode_html decode_url );use MT::Entry qw(:constants);use MT::Author qw(:constants);my $COMMENTER_COOKIE_NAME = "tk_commenter";sub init {    my $app = shift;    $app->SUPER::init(@_) or return;    $app->add_methods(        preview => \&preview,        post => \&post,        view => \&view,        handle_sign_in => \&handle_sign_in,        cmtr_name_js => \&commenter_name_js,        red => \&do_red,    );    $app->{default_mode} = 'view';    $app->{charset} = $app->{cfg}->PublishCharset;    my $q = $app->{query};    ## We don't really have a __mode parameter, because we have to    ## use named submit buttons for Preview and Post. So we hack it.    if ($q->param('post')) {        $q->param('__mode', 'post');    } elsif ($q->param('preview')) {        $q->param('__mode', 'preview');    }    $app;}## $app->_get_commenter_session()## Creates a commenter record based on the cookies in the $app, if# one already exists corresponding to the browser's session.## Returns a pair ($session_key, $commenter) where $session_key is the# key to the MT::Session object (as well as the cookie value) and# $commenter is an MT::Author record. Both values are undef when no# session is active.#sub _get_commenter_session {    my $app = shift;    my $q = $app->{query};        my $session_key;        my %cookies = $app->cookies();    if (!$cookies{$COMMENTER_COOKIE_NAME}) {        return (undef, undef);    }    $session_key = $cookies{$COMMENTER_COOKIE_NAME}->value() || "";    $session_key =~ y/+/ /;    require MT::Session;    my $sess_obj = MT::Session->load({ id => $session_key });    my $timeout = $app->{cfg}->CommentSessionTimeout;    if (!$sess_obj || ($sess_obj->start() + $timeout < time))    {        $session_key = undef;                # blotto the cookie        my %dead_kookee = (-name => $COMMENTER_COOKIE_NAME,                           -value => '',                           -path => '/',                           -expires => '-10y');        $app->bake_cookie(%dead_kookee);        my %dead_name_kookee = (-name => "commenter_name",                                -value => '',                                -path => '/',                                -expires => '-10y');        $app->bake_cookie(%dead_name_kookee);        $sess_obj->remove() if ($sess_obj);        $sess_obj = undef;        return (undef, undef);    } else {        # session is valid!        return ($session_key, MT::Author->load({name => $sess_obj->name,                                                type=>MT::Author::COMMENTER}));    }}sub do_red {    my $app = shift;    my $q = $app->{query};    my $id = $q->param('id') or return $app->error("No id");    my $comment = MT::Comment->load($id)        or return $app->error("No such comment");    my $uri = encode_html($comment->url);    return <<HTML;<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html><head><title>Redirecting...</title><meta name="robots" content="noindex, nofollow"><script type="text/javascript">window.onload = function() { document.location = '$uri'; };</script></head><body><p><a href="$uri">Click here</a> if you are not redirected</p></body></html>HTML}# _builtin_throttle is the builtin throttling code# others can be added by plugins# a filtering callback must return true or false; true#    means OK, false means filter it out.sub _builtin_throttle {    my $eh = shift;    my $app = shift;    my ($entry) = @_;    my $throttle_period = $app->{cfg}->ThrottleSeconds;    my $user_ip = $app->remote_ip;    return 1 if ($throttle_period <= 0);    # Disabled by ThrottleSeconds 0    require MT::Util;    my @ts = MT::Util::offset_time_list(time - $throttle_period,                                        $entry->blog_id);    my $from = sprintf("%04d%02d%02d%02d%02d%02d",                       $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0]);    require MT::Comment;        if (MT::Comment->count({ ip => $user_ip,                             created_on => [$from],                             blog_id => $entry->blog_id},                           {range => {created_on => 1} }))    {        return 0;                          # Put a collar on that puppy.    }    @ts = MT::Util::offset_time_list(time - $throttle_period * 10 - 1,                                     $entry->blog_id);    $from = sprintf("%04d%02d%02d%02d%02d%02d",                    $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0]);    my $count =  MT::Comment->count({ ip => $user_ip,                                      created_on => [$from],                                      blog_id => $entry->blog_id },                                    { range => {created_on => 1} });    if ($count >= 8)    {        require MT::IPBanList;        my $ipban = MT::IPBanList->new();        $ipban->blog_id($entry->blog_id);        $ipban->ip($user_ip);        $ipban->save();        $ipban->commit();        $app->log("IP $user_ip banned because comment rate " .                  "exceeded 8 comments in " .                  10 * $throttle_period . " seconds.\n");        require MT::Mail;        my $author = $entry->author;        $app->set_language($author->preferred_language)            if $author && $author->preferred_language;                my $blog = MT::Blog->load($entry->blog_id);        if ($author && $author->email) {            my %head = ( To => $author->email,                         From => $app->{cfg}->EmailAddressMain,                         Subject =>                         '[' . $blog->name . '] ' .                         $app->translate("IP Banned Due to Excessive Comments"));            my $charset = $app->{cfg}->PublishCharset || 'iso-8859-1';            $head{'Content-Type'} = qq(text/plain; charset="$charset");            my $body = $app->translate('_THROTTLED_COMMENT_EMAIL',                                       $blog->name, 10 * $throttle_period,                                       $user_ip, $user_ip);            require Text::Wrap;            $Text::Wrap::cols = 72;            $body = Text::Wrap::wrap('', '', $body);            MT::Mail->send(\%head, $body);        }        return 0;    }    return 1;}sub post {    my $app = shift;    my $q = $app->{query};    return do_preview($app, $q, @_) if $app->request_method() ne 'POST';    my $entry_id = $q->param('entry_id')        or return $app->error("No entry_id");    require MT::Entry;    my $entry = MT::Entry->load($entry_id)        or return $app->error($app->translate(            "No such entry '[_1]'.", scalar $q->param('entry_id')));    return $app->error($app->translate(                       "No such entry '[_1]'.", scalar $q->param('entry_id')))        if $entry->status != RELEASE;    require MT::IPBanList;    my $iter = MT::IPBanList->load_iter({ blog_id => $entry->blog_id });    while (my $ban = $iter->()) {        my $banned_ip = $ban->ip;        if ($app->remote_ip =~ /$banned_ip/) {            return $app->handle_error($app->translate(                                      "You are not allowed to post comments."));        }    }    MT->add_callback('CommentThrottleFilter', 1, undef,                     \&MT::App::Comments::_builtin_throttle);    # Run all the Comment-throttling callbacks    my $passed_filter = MT->run_callbacks('CommentThrottleFilter',                                          $app, $entry);    $passed_filter ||        return $app->handle_error($app->translate("_THROTTLED_COMMENT"),                                  "403 Throttled");    if (my $state = $q->param('comment_state')) {        require MT::Serialize;        my $ser = MT::Serialize->new($app->{cfg}->Serializer);        $state = $ser->unserialize(pack 'H*', $state);        $state = $$state;        for my $f (keys %$state) {            $q->param($f, $state->{$f});        }    }    unless ($entry->allow_comments eq '1') {        return $app->handle_error($app->translate(            "Comments are not allowed on this entry."));    }    require MT::Blog;    my $blog = MT::Blog->load($entry->blog_id);    if (!$q->param('text')) {       return $app->handle_error($app->translate("Comment text is required."));    }    my ($comment, $commenter) = _make_comment($app, $entry);    if (!$blog->allow_unreg_comments) {        if (!$commenter) {            return $app->handle_error($app->translate(                                      "Registration is required."))        }    }    if (!$blog->allow_anon_comments &&         (!$comment->author || !$comment->email)) {        return $app->handle_error($app->translate(                           "Name and email address are required."));    }    if ($blog->allow_unreg_comments()) {        $comment->email($q->param('email')) unless $comment->email();    }    if ($comment->email) {        require MT::Util;        if (my $fixed = MT::Util::is_valid_email($comment->email)) {            $comment->email($fixed);        } elsif ($comment->email =~ /^[0-9A-F]{40}$/i) {            # It's a FOAF-style mbox hash; accept it if blog config says to.            return $app->handle_error("A real email address is required")                if ($blog->require_comment_emails());        } else {            return $app->handle_error($app->translate(                "Invalid email address '[_1]'", $comment->email));        }    }    if ($comment->url) {        require MT::Util;        if (my $fixed = MT::Util::is_valid_url($comment->url, 'stringent')) {            $comment->url($fixed);        } else {            return $app->handle_error($app->translate(                "Invalid URL '[_1]'", $comment->url));        }    }        return $app->handle_error($app->errstr()) unless $comment;    ## Here comes the fancy logic for deciding whether or not the    ## comment appears.    if ($commenter) {        # First, auto-approve if necessary.        if (!$blog->manual_approve_commenters &&            ($commenter->status($entry->blog_id) == PENDING))        {            $commenter->approve($entry->blog_id);        }        # If the commenter is approved, publish the comment.        if ($commenter->status($blog->id) == APPROVED) {            $comment->visible(1);        }    } else {        # We don't have a commenter object, but the user wasn't booted        # so unless moderation is on, we can publish the comment.        unless ($blog->moderate_unreg_comments) {            $comment->visible(1);        }    }    # Form a link to the comment    my $comment_link;    if (!$q->param('static')) {        my $url = $app->base . $app->uri;        $url .= '?entry_id=' . $q->param('entry_id');        $url .= '&static=0&arch=1' if ($q->param('arch'));        $comment_link = $url;    } else {        my $static = $q->param('static');        if ($static eq '1') {            # I think what we really want is the individual archive.            $comment_link = $entry->permalink;        } else {            $comment_link = $static . '#' . $comment->id;        }    }    my $not_declined = 1;    if (!$commenter || $commenter->status($blog->id) != BLOCKED)    {        # Before saving this comment, check whether this commenter has        # placed any other comments on the entry's author's other entries.        # (on any other entries by the same author as this one)                my $commenter_has_comment = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -