Ok, this is the translated (with very minor additions) version of the admin action to delete spam from Wikini that GmBowen linked to on the ProgrammingHelp in RichardBerg's request for help fixing his site after a spambot attack.

I've changed all the actual variables and documentation to English, and added a couple of order by clauses to clean up the display page. Other than that, it's all his.

Caveat: I haven't been able to try this out all the way; it loads the first form (where you input the IP or username of the spammer) and the second page listing all the page revisions attributed to that IP or username just fine, but I haven't tested it any further because the only installation I have up right now is live. :\ Maybe it could be tried on the beta site?

There's no authentication to make sure it's an admin doing the deleting, so I would suggest using it only on a secured page where you're the only person with access to it, and then I'd delete the function and action page when you're done.

But hey, it's a starting point! :)

Save this as actions/deletespam.php (up to you, I suppose *g*)

<?php
// Charles NĂ©pote 2005
// License GPL.
// Version 0.1 du 22/01/2005.
// Translated to English and minor changes by MovieLady 1/23/2005

echo    "\n<!-- == Action erase spam ============================= -->\n";
echo    "<style type=\"text/css\">",
    "p { margin: 0; }",
    ".action_erasespam { background-color: yellow; }",
    "</style>\n";

// Display the form to enter the spammer's ID or IP address
if(!isset($_REQUEST['spammer']))
{
    echo    "<div class=\"action_erasespam\">\n",
        "<form method=\"get\" action=\"". $this->Href() . "\" name=\"selection\">\n",
        "<fieldset>\n",
        "<legend>Revert spammed pages to previous version</legend>\n",
        "<input type=\"hidden\" name=\"wiki\" value=\"" . $this->GetPageTag() . "\" />\n",
        "<p>Name of the user: <input name=\"spammer\" /> ",
        "<button value=\"Valider\">Submit</button></p>\n",
        "</fieldset>\n",
        "</form>\n",
        "</div>\n";
}

// Results page and form to select which histories to erase
// added order by time ascending to the sql statement to clean up the display list --ML
else if(!isset($_REQUEST['erase']))
{
    // Select all the current pages revised by this user
    $request =
        "select *
        from "
.$this->config["table_prefix"]."pages
        where user = '"
. $_REQUEST['spammer'] . "' and latest = 'Y' order by time asc";
    $pagesFromSpammer = $this->LoadAll($request);
   
    // Display the list of pages that have been vandalized
    echo    "<div class=\"action_erasespam\">\n";
    echo    "<p>Clean up the pages vandalized by " . $_REQUEST['spammer'] . "</p>\n";
    echo    "<form method=\"get\" action=\"". $this->Href() . "\">\n",
        "<input type=\"hidden\" name=\"wiki\" value=\"" . $this->GetPageTag() . "\" />\n";
    foreach ($pagesFromSpammer as $i => $page)
    {
        echo    "<p><input name=\"" . $page["tag"] . "\" type=\"checkbox\">",
            "(", $page["time"], ") ",
            "(",$this->ComposeLinkToPage($page["tag"], "revisions", "history", 0),") ",
            $this->ComposeLinkToPage($page["tag"], "", "", 0),
            " . . . . ",$this->Format($page["user"]),"</p>\n" ;
    }
    echo    "<input type=\"hidden\" name=\"spammer\" value=\"" . $_REQUEST['spammer'] . "\" />\n";
    echo    "<input type=\"hidden\" name=\"erase\" value=\"yes\" />\n";
    echo    "<p><button value=\"Valider\">Delete the selected page revisions</button></p>\n";
    echo    "</form>\n";
    echo    "</div>\n";
}

//
else
{
    $deletedPages = "";
   
    // Select all the current pages revised by this user
    // added order by time ascending to the sql statement to clean up the display list --ML
    $request1 =
        "select *
        from "
.$this->config["table_prefix"]."pages
        where user = '"
. $_REQUEST['spammer'] . "' and latest = 'Y' order by time asc";
    $pagesFromSpammer = $this->LoadAll($request1);
   
    // For each selected page
    foreach ($pagesFromSpammer as $i => $page)
    {
        // If the box is checked (marking that version of the page as having been spammed)
        if (isset($_REQUEST[$page["tag"]]))
        {
            $requestPageBefore =
                "select * " .
                "from " . $this->config["table_prefix"] . "pages " .
                "where tag = '" . $page["tag"] . "' " .
                "and time < '" . $page["time"] . "' " .
                "order by `time` desc limit 1";
            $pageBefore = $this->LoadSingle($requestPageBefore);
            if (!empty($pageBefore))
            {
                // Delete the selected page history
                $requestDelete =
                    "delete from " . $this->config["table_prefix"] . "pages " .
                    "where id = '" . $page["id"] . "' and tag = '" . $page["tag"] . "' " .
                    "limit 1";
                $this->Query($requestDelete);
                //echo "$$$$$$$$$$$$$$";
                $deletedPages .= $page["tag"] . " ";

                // Make the previous revision the latest version
                $makeLatest =
                    "update " . $this->config["table_prefix"] . "pages " .
                    "set latest = 'Y' where id = '" . $pageBefore["id"] . "' and tag = '" . $page["tag"] . "' " .
                    "limit 1";
                $this->Query($makeLatest);
            }
        }
    }
    echo    "<div class=\"action_erasespam\">\n";
    echo    "Pages deleted&nbsp;: ", $this->Format($deletedPages), "\n";
    echo    "</div>\n\n";
}

?>


Ok, now in /wakka.php, you need to add the following (after backing up the file!):

         function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1)
              {
                      if (!$text) $text = $tag;
                      $text = htmlentities($text);
                      if ($_SESSION["linktracking"] && $track)
                              $this->TrackLinkTo($tag);
                      return '<a href="'.$this->href($method, $tag).'">'.$text.'</a>';
              }


I added it right after where "function Link" closed and before the commented out "function PregPageLink" - it was about line 475.

So, there's the jumping off point.

Ahem, I published a 0.5 version with much improvements. I will think about your remarks. I plan to finish the action in about 2 or 3 weeks ; with : -- CharlesNepote


To do list


(Some of which is already done, but needs a little adjusting or testing)
  1. Encorporate the admin-access-only code
  2. Expand this so it:
    1. brings up all of the pages that have been altered by the user
    2. marks them as current or previous version, and
      1. if it's a history page, just delete it
      2. if it's the most recent version of the page, delete the page and mark the previous version of the page as the current version
  3. Add a tick box that selects all the pages for ease of mass spam removal


CategoryUserContributions
There are 2 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki