📄 comments.pm
字号:
if ($commenter) { my $other_comment=MT::Comment->load({commenter_id=>$commenter->id}); if ($other_comment) { my $other_entry =MT::Entry->load({author_id => $entry->author_id}, {join=>['MT::Comment', 'entry_id', {commenter_id=>$commenter->id},{}]}); $commenter_has_comment = !!$other_entry; } } if ($not_declined = MT->run_callbacks('CommentFilter', $app, $comment)) { $comment->save; $blog->touch; $blog->save; if ($comment->visible) { # Rebuild the entry synchronously so that if the user gets # redirected to the indiv. page it will be up-to-date. $app->rebuild_entry( Entry => $entry ) or return $app->error($app->translate( "Rebuild failed: [_1]", $app->errstr)); } # Index rebuilds and notifications are done in the background. MT::Util::start_background_task(sub { if ($comment->visible) { $app->rebuild_indexes( Blog => $blog ) or return $app->errtrans("Rebuild failed: [_1]", $app->errstr); } my $send_notfn_email = 0; if (!$commenter) { $send_notfn_email = !$comment->visible(); } else { $send_notfn_email = !$commenter_has_comment && !$comment->visible(); } if ($blog->email_new_comments || $send_notfn_email) { $app->_send_comment_notification($comment, $comment_link, $entry, $blog); } }); } } MT::Util::start_background_task( sub { _expire_sessions($app->{cfg}->CommentSessionTimeout) }); if (!$comment->visible || !$not_declined) { return $app->preview('pending'); } else { return $app->redirect($comment_link); }}## $app->_make_comment($entry)## _make_comment creates an MT::Comment record attached to the $entry,# based on the query information in $app (It neeeds the whole app object# so it can get the user's IP). Also creates an MT::Author record# representing the person who placed the comment, if necessary.## Always returns a pair ($comment, $commenter). The latter is undef if# there is no commenter for the session (or if there is no active# session).## Validation of the comment data is left to the caller.#sub _make_comment { my ($app, $entry) = @_; my $q = $app->{query}; my $nick = $q->param('author'); my $email = $q->param('email'); my ($session, $commenter) = $app->_get_commenter_session(); if ($commenter) { $nick = $commenter->nickname(); $email = $commenter->email(); } my $url = $q->param('url') || ($commenter ? $commenter->url() : ''); my $comment = MT::Comment->new; if ($commenter) { $comment->commenter_id($commenter->id); } $comment->ip($app->remote_ip); $comment->blog_id($entry->blog_id); $comment->entry_id($entry->id); $comment->author(remove_html($nick)); $comment->email(remove_html($email)); $comment->url(MT::Util::is_valid_url($url, 'stringent')); $comment->text($q->param('text')); return ($comment, $commenter);}sub _send_comment_notification { my $app = shift; my ($comment, $comment_link, $entry, $blog) = @_; require MT::Mail; my $author = $entry->author; $app->set_language($author->preferred_language) if $author && $author->preferred_language; my $from_addr = $comment->email || $app->{cfg}->EmailAddressMain || $author->email; use MT::Util qw(is_valid_email); if (!is_valid_email($from_addr)) { $from_addr = $app->{cfg}->EmailAddressMain || $author->email; } if ($author && $author->email) { my %head = ( To => $author->email, From => $from_addr, Subject => '[' . $blog->name . '] ' . $app->translate("New Comment Posted to '[_1]'", $entry->title) ); my $charset = $app->{cfg}->PublishCharset || 'iso-8859-1'; $head{'Content-Type'} = qq(text/plain; charset="$charset"); my $base = $app->base . $app->path . $app->{cfg}->AdminScript; my %param = ( blog_name => $blog->name, entry_id => $entry->id, entry_title => $entry->title, view_url => $comment_link, edit_url => $base . '?__mode=view&blog_id=' . $blog->id . '&_type=comment&id=' . $comment->id, ban_url => $base . '?__mode=save&_type=banlist&blog_id=' . $blog->id . '&ip=' . $comment->ip, comment_ip => $comment->ip, comment_name => $comment->author, (is_valid_email($comment->email)? (comment_email => $comment->email):()), comment_url => $comment->url, comment_text => $comment->text, unapproved => !$comment->visible(), ); my $body = MT->build_email('new-comment.tmpl', \%param); MT::Mail->send(\%head, $body) or return $app->handle_error(MT::Mail->errstr()); }}sub preview { my $app = shift; do_preview($app, $app->{query}, @_) }sub _make_commenter { my $app = shift; my %params = @_; require MT::Author; my $cmntr = MT::Author->load({ name => $params{name}, type => MT::Author::COMMENTER }); if (!$cmntr) { $cmntr = MT::Author->new(); $cmntr->set_values({email => $params{email}, name => $params{name}, nickname => $params{nickname}, password => "(none)", type => MT::Author::COMMENTER, url => $params{url}, }); $cmntr->save(); } else { $cmntr->set_values({email => $params{email}, nickname => $params{nickname}, password => "(none)", type => MT::Author::COMMENTER, url => $params{url}, }); $cmntr->save(); } return $cmntr;}sub _expire_sessions { my ($timeout) = @_; require MT::Session; my @old_sessions = MT::Session->load({start => [0, time() - $timeout]}, {range => {start => 1}}); foreach (@old_sessions) { $_->remove() || die "couldn't remove sessions because " . $_->errstr(); }}sub _make_commenter_session { my $app = shift; my ($session_key, $email, $name, $nick) = @_; my %kookee = (-name => $COMMENTER_COOKIE_NAME, -value => $session_key, -path => '/', -expires => '+1h'); $app->bake_cookie(%kookee); my %name_kookee = (-name => "commenter_name", -value => $nick, -path => '/', -expires => '+1h'); $app->bake_cookie(%name_kookee); require MT::Session; my $sess_obj = MT::Session->new(); $sess_obj->id($session_key); $sess_obj->email($email); $sess_obj->name($name); $sess_obj->start(time); $sess_obj->kind("SI"); $sess_obj->save() or return $app->error("The login could not be confirmed because of a database error (" . $sess_obj->errstr() . ")"); return $session_key;}my $SIG_WINDOW = 60 * 10; # ten minute handoff between TP and MTsub _validate_signature { my $app = shift; my ($sig_str, %params) = @_; # the DSA sig parameter is composed of the two pieces of the # real DSA sig, packed in Base64, separated by a colon.# my ($r, $s) = split /:/, decode_url($sig_str); my ($r, $s) = split /:/, $sig_str; $r =~ s/ /+/g; $s =~ s/ /+/g; $params{email} =~ s/ /+/g; require MIME::Base64; import MIME::Base64 qw(decode_base64); use MT::Util qw(bin2dec); $r = bin2dec(decode_base64($r)); $s = bin2dec(decode_base64($s)); my $sig = {'s' => $s, 'r' => $r}; my $timer = time; require MT::Util; import MT::Util ('dsa_verify'); my $msg; if ($app->{cfg}->TypeKeyVersion eq '1.1') { $msg = ($params{email} . "::" . $params{name} . "::" . $params{nick} . "::" . $params{ts} . "::" . $params{token}); } else { $msg = ($params{email} . "::" . $params{name} . "::" . $params{nick} . "::" . $params{ts}); } my $dsa_key; require MT::Session; $dsa_key = eval { MT::Session->load({id => 'KY', kind => 'KY'}); } || undef; if ($dsa_key) { if ($dsa_key->start() < time - 24 * 60 * 60) { $dsa_key = undef; } $dsa_key = $dsa_key->data if $dsa_key; } if ( ! $dsa_key ) { # Load the override key $dsa_key = $app->{cfg}->get('SignOnPublicKey'); } # Load the DSA key from the RegKeyURL my $key_location = $app->{cfg}->RegKeyURL; if (!$dsa_key && $key_location) { require LWP::UserAgent; my $ua = new LWP::UserAgent(timeout => 15); my $req = new HTTP::Request(GET => $key_location); my $resp = $ua->request($req); return $app->error("Couldn't get public key from url provided") unless $resp->is_success(); # TBD: Check the content-type $dsa_key = $resp->content(); require MT::Session; my $key_cache = new MT::Session(); my @chs = ('a' .. 'z', '0' .. '9'); $key_cache->set_values({id => 'KY', data => $dsa_key, kind => 'KY', start => time}); $key_cache->save(); } if (!$dsa_key) { return $app->error($app->translate( "No public key could be found to validate registration.")); } my ($p) = $dsa_key =~ /p=([0-9a-f]*)/i; my ($q) = $dsa_key =~ /q=([0-9a-f]*)/i; my ($g) = $dsa_key =~ /g=([0-9a-f]*)/i; my ($pub_key) = $dsa_key =~ /pub_key=([0-9a-f]*)/i; $dsa_key = {p=>$p, q=>$q, g=>$g, pub_key=>$pub_key}; my $valid = dsa_verify(Key => $dsa_key, Signature => $sig, Message => $msg); $timer = time - $timer; MT::log("TypeKey signature verif'n returned " . ($valid ? "VALID" : "INVALID") . " in " . $timer. " seconds " . "verifying [$msg] with [$sig_str]\n") unless $valid; MT::log("The TypeKey signature is out of date (" . ($params{ts} - time) . "). Ensure that your server's clock is correct\n") unless ($params{ts} - time < $SIG_WINDOW); return ($valid && $params{ts} + $SIG_WINDOW >= time);}sub _handle_sign_in { my $app = shift; my $q = $app->{query}; my ($weblog) = @_; if ($q->param('logout')) { my %cookies = $app->cookies(); my $cookie_val = ($cookies{$COMMENTER_COOKIE_NAME} ? $cookies{$COMMENTER_COOKIE_NAME}->value() : ""); #my ($email, $session) = split(/::/, $cookie_val) if $cookie_val; my $session = $cookie_val; require MT::Session; my $sess_obj = MT::Session->load({id => $session }); $sess_obj->remove() if ($sess_obj); my %kookee = (-name => $COMMENTER_COOKIE_NAME, -value => '', -path => '/',
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -