# # 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 # # Trackback close... invisible ok. # but recieve ping... Bug!! muuuu.... # 2008.04.18 modified # # ----------------------------------------------------- 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); #------ Auto Trackback Close ------ # if MySQL 4.0.4 >= Your version, can't do this module. my $query = "UPDATE mt_entry,mt_trackback SET mt_entry.entry_allow_pings=0,mt_trackback.trackback_is_disabled = 1 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 .= ' && mt_trackback.trackback_entry_id=mt_entry.entry_id'; $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