<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://wiredgeek.com" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
 <title>code</title>
 <link>http://wiredgeek.com/taxonomy/term/241</link>
 <description>The taxonomy view with a depth of 0.</description>
 <language>en</language>
<item>
 <title>Mass comment deletion</title>
 <link>http://wiredgeek.com/node/707</link>
 <description>  &lt;div class=&quot;content&quot;&gt;
  &lt;p&gt;
I recently upgraded to Drupal 5.2 from 4.7 and during the upgrade I made rather unfortunate mistake. I switched from using the &lt;a href=&quot;http://drupal.org/project/captcha&quot;&gt;captcha&lt;/a&gt; &lt;a href=&quot;http://drupal.org/project/captcha&quot;&gt;module&lt;/a&gt; on &lt;a href=&quot;http://drupal.org&quot;&gt;drupal.org&lt;/a&gt; to using the &lt;a href=&quot;http://heine.familiedeelstra.com/mycaptcha-download&quot;&gt;mycaptcha&lt;/a&gt; &lt;a href=&quot;http://heine.familiedeelstra.com/mycaptcha-download&quot;&gt;module&lt;/a&gt; on &lt;a href=&quot;http://heine.familiedeelstra.com/&quot;&gt;Heine&#039;s&lt;/a&gt; &lt;a href=&quot;http://heine.familiedeelstra.com/&quot;&gt;website.&lt;/a&gt; This wasn&#039;t the mistake though. My mistake was that although I had successfully switched over the modules I had misconfigured (i.e didn&#039;t turn on) the mycaptcha module. This left my website vulnerable to spambots although not entirely vulnerable because I do use the wonderful &lt;a href=&quot;http://drupal.org/project/spam&quot;&gt;spam&lt;/a&gt; &lt;a href=&quot;http://drupal.org/project/spam&quot;&gt;module&lt;/a&gt; in conjunction with &lt;a href=&quot;http://heine.familiedeelstra.com/mycaptcha-download&quot;&gt;mycaptcha&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
In less than a week my site had over 1,000 spam messages that made it through the spam module (several thousand caught). Most of these comments didn&#039;t contain URLs and had some &amp;quot;comment&amp;quot; that consisted of gibberish; which is why they passed through the &lt;a href=&quot;http://drupal.org/project/spam&quot;&gt;spam&lt;/a&gt; module. Fortunately for me the spambots hit my site a few time with high spam injections(300+) at each visit. Almost all of them came from a similar IP address. Since the comment module grabs the IP address or Hostname of the person leaving the comment I only had to write a few simple SQL queries to isolate all of the spam comments. 
&lt;/p&gt;
&lt;p&gt;
I then used the code below to wipe out hundreds of spam comments with each run.  
&lt;/p&gt;
&lt;pre&gt;
$sql = &amp;quot;SELECT cid, subject, comment from comments WHERE subject LIKE &#039;%s&#039; AND hostname LIKE &#039;%s&#039; AND name LIKE &#039;%s&#039;&amp;quot;; 
$subject = &amp;quot;&amp;quot;;
$hostname = &amp;quot;81.177%&amp;quot;;
$name = &#039;Anonymous&#039;;
$results = db_query($sql, $subject, $hostname, $name);
print &amp;quot;Deleting &amp;quot;. db_num_rows($results) . &amp;quot; Comments 
&amp;quot;;
while($result = db_fetch_array($results)){
$comment = _comment_load($result[&#039;cid&#039;]);
_comment_delete_thread($comment);
unset($comment);
}
&lt;/pre&gt;
&lt;p&gt;
When writing this little snippet I found it interesting that there is no public API call for deleting comments similar to &lt;a href=&quot;http://api.drupal.org/api/function/node_delete/5&quot;&gt;node_delete()&lt;/a&gt;. The function &lt;a href=&quot;http://api.drupal.org/api/function/comment_delete/5&quot;&gt;comment_delete()&lt;/a&gt; exists but it only returns the form &#039;comment_confirm_delete&#039;. Although I could have used &lt;a href=&quot;http://api.drupal.org/api/function/drupal_execute/5&quot;&gt;drupal_execute()&lt;/a&gt; to properly fill in and execute the comment_confirm_delete form I found it a bit silly, especially since I knew the cid (comment ID) and I simply wanted to delete it. Heck I could&#039;ve just did a &amp;quot;DELETE FROM comments WHERE cid = %d&amp;quot; and been done with it but that&#039;s not &amp;quot;clean&amp;quot;.  
&lt;/p&gt;
&lt;p&gt;
So instead of grabbing the form, researching its elements and writing some quick &lt;a href=&quot;http://api.drupal.org/api/file/forms_api_reference.html/5&quot;&gt;FAPI code&lt;/a&gt; I opened up  comment.module found the &amp;quot;private&amp;quot; function _comment_delete_thread(). It required a comment object so I also found the, again private, function _comment_load. They work similiar to &lt;a href=&quot;http://api.drupal.org/api/function/node_load/5&quot;&gt;node_load&lt;/a&gt; and &lt;a href=&quot;http://api.drupal.org/api/function/node_delete/5&quot;&gt;node_delete&lt;/a&gt; so with these two functions I was on my way to being spam free again! 
&lt;/p&gt;
&lt;p&gt;
Now the question is why are _comment_delete_thread() and _comment_load() private?
&lt;/p&gt;
&lt;br class=&quot;clear&quot; /&gt;  &lt;/div&gt;
</description>
 <comments>http://wiredgeek.com/node/707#comments</comments>
 <category domain="http://wiredgeek.com/taxonomy/term/241">code</category>
 <category domain="http://wiredgeek.com/taxonomy/term/14">drupal</category>
 <category domain="http://wiredgeek.com/taxonomy/term/22">spam</category>
 <pubDate>Mon, 13 Aug 2007 00:04:55 +0000</pubDate>
 <dc:creator>Jacob Redding</dc:creator>
 <guid isPermaLink="false">707 at http://wiredgeek.com</guid>
</item>
</channel>
</rss>
