#
# MTCloseComments - A Plug-In for Movable Type
# by Alan M. Carroll
# http://blog.thought-mesh.net
#
# Version 1.0.3
# 21 Apr, 2004
#
# See the readme or POD for details, installation instructions, and
# license information.
#
# Copyright (c) 2003 Alan M. Carroll
#
# ----------------------------------------------------
# The function to except is added.
#
# By debizoh.
# 2008.04.06
#
# Adding Trackback autoclose.
# 2008.04.07
#
# -----------------------------------------------------
package MT::Plugin::CloseComments;
use strict;
use vars qw($VERSION);
$VERSION = "1.0.3";
# Movable Type plug-in interface:
eval {require MT::Template::Context}; # Test to see if we're running in MT.
unless ($@) {
require MT::Template::Context;
import MT::Template::Context;
MT::Template::Context->add_tag( CloseComments => \&Execute);
}
# Return our version
sub Version {
return $VERSION;
}
# Close comments.
sub Execute {
my $ctx = shift; # MT context object
my $attrs = shift; # atttributes on the tag
my $zret = ''; # default return is empty string
my $delta; # "old" threshold
my $blog = $ctx->stash('blog'); # which weblog we're operating on
my $debug = $attrs->{debug};
# See if oldness was specifically stated
if (exists $attrs->{old} && $attrs->{old} =~ m/[[:digit:]]+/) {
$delta = $attrs->{old};
} else { # Nothing specific, pick it out of the blog config
if ($blog) {
$delta = $blog->days_on_index()+1;
} else { # problem - not specified and can't find blog either
return $debug ? "CloseComments - No valid 'old' attribute specified and weblog setting unavailable" : '';
}
}
my $inactive = $attrs->{inactive};
$inactive = undef unless $inactive && $inactive =~ m/[[:digit:]]+/;
# Close the comments
if ($delta) {
my $driver = MT::Object->driver();
# ----------------------------------------------------
# The function to except is added.
#
# By debizoh.
# 2008.04.06
# sample
# 'blogid' => [ 0,1,2 ],
# -----------------------------------------------------
my %except_entries = (
1 => [ 0 ],
);
my $except_entries_sql;
if ($driver =~ m/::DBI::/) {
my $db = $driver->{dbh}; # connection to the SQL backend
if ($db) {
if ($blog)
{
my $except_entries_bid = $blog->id();
foreach ( @{$except_entries{$except_entries_bid}} )
{
if ($except_entries_sql)
{
$except_entries_sql .= ' And ';
}
$except_entries_sql .= ' entry_id != ' . $_;
}
}
my $query = "UPDATE mt_entry SET entry_allow_comments=0 WHERE TO_DAYS(NOW()) - TO_DAYS(entry_created_on) >= $delta && entry_allow_comments=1";
$query .= " && TO_DAYS(NOW()) - TO_DAYS(entry_modified_on) >= $inactive" if $inactive;
$query .= " && entry_blog_id=" . $blog->id() if $blog;
$query .= ' && ' . $except_entries_sql if $except_entries_sql;
$query .= ";";
my $result = $db->do($query);
my $query = "UPDATE mt_entry SET entry_allow_pings=0 WHERE TO_DAYS(NOW()) - TO_DAYS(entry_created_on) >= $delta && entry_allow_pings=1";
$query .= " && TO_DAYS(NOW()) - TO_DAYS(entry_modified_on) >= $inactive" if $inactive;
$query .= " && entry_blog_id=" . $blog->id() if $blog;
$query .= ' && ' . $except_entries_sql if $except_entries_sql;
$query .= ";";
my $result = $db->do($query);
if ($result) {
if ($debug) {
$result = int($result);
$zret = "Closed comments on $result posts $delta days or older";
$zret .= " and inactive at least $inactive days" if $inactive;
$zret .= "
Query: " . $query if $debug =~ 'q';
}
} elsif ($debug) {
$zret = "CloseComments - Query returned NIL.
" . $query;
}
} elsif ($debug) {
$zret = "CloseComments - No connection to DB";
}
} elsif ($debug) {
$zret = 'CloseComments - Unable to close comments on a ' . $driver . ' based persistent store';
}
} elsif ($debug) {
$zret = 'CloseComments - No oldness value specified or configured';
}
return $zret;
}
1;
__END__
=pod
=head1 Name
B
=head1 Synopsis
When executed this tag will change all open comments to closed comments on posts that
are too old. This is controlled by an attribute on the tag or by the number of days for
the main index.
=head1 Description
MTCloseComments executes an SQL query that closes comments for posts for entries that
were created more than a certain number of days ago and have open comments. This should
be sufficiently fast that it can be done every time the main index template is executed.
The attributes recognized by MTCloseComments are
=over
=item old
If the C attribute is set to a numeric value then comments are closed for posts
more than that many days old. If the attribute is not present then the tag looks up
number of days for posts on the main index from the weblog configuration and posts older
than that have their comments closed.
=item inactive
This prohibits closing comments on posts that have recently modified. A post must have been
unmodified more than the number of days specified by this attribute to have its comments
closed. The default value is 0 which effectively disables the test.
=item debug
If this attribute is used with a non-empty string, then debug output will be generated.
This will describe the successful operation of the plugin (parameters, number of comments
closed) or one of a variety of error conditions. If the debug value contains the letter
'q' and no errors occur then the literal query string will be placed in the output.
=back
The tag only closes comments for posts for which comments are open. Posts for which comments
are disallowed are not closed.
While this tag normally generates no output, if you set the attribute C to a value
then it will generate text in all cases with either details on its actions or failures.
=head2 Example
C<< >>
Close comments for posts more than 21 days old.
C<< >>
Close comments for posts that are too old to appear on the main index.
C<< >>
Close comments for posts that are not on the front page and have been inactive for at
least three days.
C<< >>
Close comments for posts at least 7 days old and inactive for three or more days.
=head1 Installation
=head2 Movable Type
MTCloseComments works with Movable Type version 2.6 or later.
=over 4
=item 1.
Copy the "MTCloseComments.pl" file into your Movable Type "plugins" directory.
The "plugins" directory should be in the same directory as "mt.cgi"; if it
doesn't already exist, use your FTP program to create it. Your
installation should look like this:
(mt home)/plugins/MTCloseComments.pl
=item 2.
The best way to activate MTCloseComments on your weblog is to edit
your main index template and put the C tag somewhere in
the template. The actual location is irrelevant since the tag doesn't
generate output. For efficiency reasons the tag should not be placed inside
any container tags so that it is executed only once while building the
main index.
=item 3.
(Optional) In the standard MT distribute, the modified value of a post is changed only by directly
editing the post. To make posting a comment update the post modification time (which is
used by C) you must add a line to C around line 106.
$comment->url(remove_html($url));
$comment->text($q->param('text'));
$comment->save;
$entry->save; # <-- ADD THIS LINE
$app->rebuild_indexes( Blog => $blog )
=back
=head1 Caveats
=over
=item *
MTCloseComments only works with SQL (MySQL, Postgress) based weblogs.
=item *
Requires MT 2.63 or better.
=item *
In terms of performance, the first time this query executes it will be slow.
It is much faster when it is only closing comments on a few posts. In my timings
on a weblog wth ~500 posts it took 900 ms the first time and 9 ms on
subsequent runs closing 2-3 posts.
=item *
If you put the C tag in your main index you need to set the
C attribute to at least one in order to be able to open comments on
old posts. Without that then the comments on the post will be closed by the
rebuilding process during the save after the comment state is modified.
=item *
There are some issues with weblogs that do not always serve comments dynamically
in relation to the use of the C tag. MTCloseComments
does B rebuild any pages and so static pages using this tag will B be
updated to remove the "Post a comment" form. However, if a user attempts to post
a comment they will not be able to do so, they will just be annoyingly mislead on
viewing the post. A full rebuild will clear up any such posts.
It would be very difficult
to fix this problem with this design because it would create dependency cycles where
the rebuild of a post would trigger the rebuild of the main index which (via C)
would trigger the rebuild of the post again.
=back
=head1 Bugs
To file bug reports or feature requests (other than topics listed in the
Caveats section above) please send email to:
close-comments@thought-mesh.net
You should add the C attribute to the tag and retrieve the output, or the error
message you get from MT when rebuilding.
=head1 Version History
=over
=item Version 1.0.0
19 Oct 2003 - Initial Beta Release
=item Version 1.0.1
12 Nov 2003 -
=over
=item *
Fixed bug where not using the "inactive" attribute caused an error message.
=item *
Updated document for "debug" attribute.
=item *
Added some better error checking.
=back
=item Version 1.0.2
18 Apr 2004 -
=over
=item *
Fixed bug where all Weblogs would be operated on. Only the current weblog
has its comments closed.
=back
=item Version 1.0.3
21 Apr 2004 -
=over
=item *
Added additional debug checks for the result of the DB query.
=item *
Moved the conversion of the DB results to an C in to the debug clause
because the conversion result is only used in that case.
=back
=back
=head1 Author
Alan M. Carroll
http://thought-mesh.net
=head1 Additional Credits
=head1 Copyright and License
Copyright (c) 2003 Alan M. Carroll
(http://thought-mesh.net/)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "MTCloseComments" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is"
and any express or implied warranties, including, but not limited to, the
implied warranties of merchantability and fitness for a particular purpose
are disclaimed. In no event shall the copyright owner or contributors be
liable for any direct, indirect, incidental, special, exemplary, or
consequential damages (including, but not limited to, procurement of
substitute goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability, whether in
contract, strict liability, or tort (including negligence or otherwise)
arising in any way out of the use of this software, even if advised of the
possibility of such damage.
=cut